Skip to content

Commit b467bac

Browse files
committed
migrated chats to use reactquery, upgraded entire deploymodal to use reactquery instead of manual state management
1 parent 65b18d1 commit b467bac

File tree

19 files changed

+1034
-636
lines changed

19 files changed

+1034
-636
lines changed

apps/docs/tsconfig.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@
1111
"next-env.d.ts",
1212
"**/*.ts",
1313
"**/*.tsx",
14-
".next/types/**/*.ts",
1514
"content/docs/execution/index.mdx",
16-
"content/docs/connections/index.mdx",
17-
".next/dev/types/**/*.ts"
15+
"content/docs/connections/index.mdx"
1816
],
19-
"exclude": ["node_modules"]
17+
"exclude": ["node_modules", ".next"]
2018
}

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/document.tsx

Lines changed: 15 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import { ActionBar } from '@/app/workspace/[workspaceId]/knowledge/[id]/componen
4848
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
4949
import { useContextMenu } from '@/app/workspace/[workspaceId]/w/components/sidebar/hooks'
5050
import { useDocument, useDocumentChunks, useKnowledgeBase } from '@/hooks/kb/use-knowledge'
51-
import { knowledgeKeys } from '@/hooks/queries/knowledge'
51+
import { knowledgeKeys, useDocumentChunkSearchQuery } from '@/hooks/queries/knowledge'
5252

5353
const logger = createLogger('Document')
5454

@@ -313,69 +313,22 @@ export function Document({
313313
isFetching: isFetchingChunks,
314314
} = useDocumentChunks(knowledgeBaseId, documentId, currentPageFromURL)
315315

316-
const [searchResults, setSearchResults] = useState<ChunkData[]>([])
317-
const [isLoadingSearch, setIsLoadingSearch] = useState(false)
318-
const [searchError, setSearchError] = useState<string | null>(null)
319-
320-
useEffect(() => {
321-
if (!debouncedSearchQuery.trim()) {
322-
setSearchResults([])
323-
setSearchError(null)
324-
return
325-
}
326-
327-
let isMounted = true
328-
329-
const searchAllChunks = async () => {
330-
try {
331-
setIsLoadingSearch(true)
332-
setSearchError(null)
333-
334-
const allResults: ChunkData[] = []
335-
let hasMore = true
336-
let offset = 0
337-
const limit = 100
338-
339-
while (hasMore && isMounted) {
340-
const response = await fetch(
341-
`/api/knowledge/${knowledgeBaseId}/documents/${documentId}/chunks?search=${encodeURIComponent(debouncedSearchQuery)}&limit=${limit}&offset=${offset}`
342-
)
343-
344-
if (!response.ok) {
345-
throw new Error('Search failed')
346-
}
347-
348-
const result = await response.json()
349-
350-
if (result.success && result.data) {
351-
allResults.push(...result.data)
352-
hasMore = result.pagination?.hasMore || false
353-
offset += limit
354-
} else {
355-
hasMore = false
356-
}
357-
}
358-
359-
if (isMounted) {
360-
setSearchResults(allResults)
361-
}
362-
} catch (err) {
363-
if (isMounted) {
364-
setSearchError(err instanceof Error ? err.message : 'Search failed')
365-
}
366-
} finally {
367-
if (isMounted) {
368-
setIsLoadingSearch(false)
369-
}
370-
}
316+
const {
317+
data: searchResults = [],
318+
isLoading: isLoadingSearch,
319+
error: searchQueryError,
320+
} = useDocumentChunkSearchQuery(
321+
{
322+
knowledgeBaseId,
323+
documentId,
324+
search: debouncedSearchQuery,
325+
},
326+
{
327+
enabled: Boolean(debouncedSearchQuery.trim()),
371328
}
329+
)
372330

373-
searchAllChunks()
374-
375-
return () => {
376-
isMounted = false
377-
}
378-
}, [debouncedSearchQuery, knowledgeBaseId, documentId])
331+
const searchError = searchQueryError instanceof Error ? searchQueryError.message : null
379332

380333
const [selectedChunks, setSelectedChunks] = useState<Set<string>>(new Set())
381334
const [selectedChunk, setSelectedChunk] = useState<ChunkData | null>(null)

apps/sim/app/workspace/[workspaceId]/logs/components/logs-toolbar/components/notifications/components/workflow-selector/workflow-selector.tsx

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
'use client'
22

3-
import { useEffect, useMemo, useState } from 'react'
3+
import { useMemo } from 'react'
44
import { X } from 'lucide-react'
55
import { Badge, Combobox, type ComboboxOption } from '@/components/emcn'
66
import { Skeleton } from '@/components/ui'
7+
import { useWorkflows } from '@/hooks/queries/workflows'
78

89
interface WorkflowSelectorProps {
910
workspaceId: string
@@ -25,26 +26,9 @@ export function WorkflowSelector({
2526
onChange,
2627
error,
2728
}: WorkflowSelectorProps) {
28-
const [workflows, setWorkflows] = useState<Array<{ id: string; name: string }>>([])
29-
const [isLoading, setIsLoading] = useState(true)
30-
31-
useEffect(() => {
32-
const load = async () => {
33-
try {
34-
setIsLoading(true)
35-
const response = await fetch(`/api/workflows?workspaceId=${workspaceId}`)
36-
if (response.ok) {
37-
const data = await response.json()
38-
setWorkflows(data.data || [])
39-
}
40-
} catch {
41-
setWorkflows([])
42-
} finally {
43-
setIsLoading(false)
44-
}
45-
}
46-
load()
47-
}, [workspaceId])
29+
const { data: workflows = [], isPending: isLoading } = useWorkflows(workspaceId, {
30+
syncRegistry: false,
31+
})
4832

4933
const options: ComboboxOption[] = useMemo(() => {
5034
return workflows.map((w) => ({

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/a2a/a2a.tsx

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ interface A2aDeployProps {
8383
workflowNeedsRedeployment?: boolean
8484
onSubmittingChange?: (submitting: boolean) => void
8585
onCanSaveChange?: (canSave: boolean) => void
86-
onAgentExistsChange?: (exists: boolean) => void
87-
onPublishedChange?: (published: boolean) => void
86+
/** Callback for when republish status changes - depends on local form state */
8887
onNeedsRepublishChange?: (needsRepublish: boolean) => void
8988
onDeployWorkflow?: () => Promise<void>
9089
}
@@ -99,8 +98,6 @@ export function A2aDeploy({
9998
workflowNeedsRedeployment,
10099
onSubmittingChange,
101100
onCanSaveChange,
102-
onAgentExistsChange,
103-
onPublishedChange,
104101
onNeedsRepublishChange,
105102
onDeployWorkflow,
106103
}: A2aDeployProps) {
@@ -236,14 +233,6 @@ export function A2aDeploy({
236233
}
237234
}, [existingAgent, workflowName, workflowDescription])
238235

239-
useEffect(() => {
240-
onAgentExistsChange?.(!!existingAgent)
241-
}, [existingAgent, onAgentExistsChange])
242-
243-
useEffect(() => {
244-
onPublishedChange?.(existingAgent?.isPublished ?? false)
245-
}, [existingAgent?.isPublished, onPublishedChange])
246-
247236
const hasFormChanges = useMemo(() => {
248237
if (!existingAgent) return false
249238
const savedSchemes = existingAgent.authentication?.schemes || []
@@ -278,6 +267,7 @@ export function A2aDeploy({
278267

279268
const needsRepublish = existingAgent && (hasFormChanges || hasWorkflowChanges)
280269

270+
// Notify parent of republish status changes (depends on local form state)
281271
useEffect(() => {
282272
onNeedsRepublishChange?.(!!needsRepublish)
283273
}, [needsRepublish, onNeedsRepublishChange])

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/chat/chat.tsx

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ import { OutputSelect } from '@/app/workspace/[workspaceId]/w/[workflowId]/compo
2929
import {
3030
type AuthType,
3131
type ChatFormData,
32-
useChatDeployment,
33-
useIdentifierValidation,
34-
} from './hooks'
32+
useCreateChat,
33+
useDeleteChat,
34+
useUpdateChat,
35+
} from '@/hooks/queries/chats'
36+
import { useIdentifierValidation } from './hooks'
3537

3638
const logger = createLogger('ChatDeploy')
3739

@@ -45,7 +47,6 @@ interface ChatDeployProps {
4547
existingChat: ExistingChat | null
4648
isLoadingChat: boolean
4749
onRefetchChat: () => Promise<void>
48-
onChatExistsChange?: (exists: boolean) => void
4950
chatSubmitting: boolean
5051
setChatSubmitting: (submitting: boolean) => void
5152
onValidationChange?: (isValid: boolean) => void
@@ -97,7 +98,6 @@ export function ChatDeploy({
9798
existingChat,
9899
isLoadingChat,
99100
onRefetchChat,
100-
onChatExistsChange,
101101
chatSubmitting,
102102
setChatSubmitting,
103103
onValidationChange,
@@ -121,8 +121,12 @@ export function ChatDeploy({
121121

122122
const [formData, setFormData] = useState<ChatFormData>(initialFormData)
123123
const [errors, setErrors] = useState<FormErrors>({})
124-
const { deployChat } = useChatDeployment()
125124
const formRef = useRef<HTMLFormElement>(null)
125+
126+
// React Query mutations for chat operations
127+
const createChatMutation = useCreateChat()
128+
const updateChatMutation = useUpdateChat()
129+
const deleteChatMutation = useDeleteChat()
126130
const [isIdentifierValid, setIsIdentifierValid] = useState(false)
127131
const [hasInitializedForm, setHasInitializedForm] = useState(false)
128132

@@ -231,15 +235,29 @@ export function ChatDeploy({
231235
return
232236
}
233237

234-
const chatUrl = await deployChat(
235-
workflowId,
236-
formData,
237-
deploymentInfo,
238-
existingChat?.id,
239-
imageUrl
240-
)
238+
let chatUrl: string
239+
240+
if (existingChat?.id) {
241+
// Update existing chat
242+
const result = await updateChatMutation.mutateAsync({
243+
chatId: existingChat.id,
244+
workflowId,
245+
formData,
246+
imageUrl,
247+
})
248+
chatUrl = result.chatUrl
249+
} else {
250+
// Create new chat
251+
const result = await createChatMutation.mutateAsync({
252+
workflowId,
253+
formData,
254+
apiKey: deploymentInfo?.apiKey,
255+
imageUrl,
256+
})
257+
chatUrl = result.chatUrl
258+
}
241259

242-
onChatExistsChange?.(true)
260+
// Mutations handle cache invalidation, no need for onChatExistsChange
243261
onDeployed?.()
244262
onVersionActivated?.()
245263

@@ -266,18 +284,14 @@ export function ChatDeploy({
266284
try {
267285
setIsDeleting(true)
268286

269-
const response = await fetch(`/api/chat/manage/${existingChat.id}`, {
270-
method: 'DELETE',
287+
await deleteChatMutation.mutateAsync({
288+
chatId: existingChat.id,
289+
workflowId,
271290
})
272291

273-
if (!response.ok) {
274-
const error = await response.json()
275-
throw new Error(error.error || 'Failed to delete chat')
276-
}
277-
278292
setImageUrl(null)
279293
setHasInitializedForm(false)
280-
onChatExistsChange?.(false)
294+
// Mutation handles cache invalidation, no need for onChatExistsChange
281295
await onRefetchChat()
282296

283297
onDeploymentComplete?.()
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
export { type AuthType, type ChatFormData, useChatDeployment } from './use-chat-deployment'
21
export { useIdentifierValidation } from './use-identifier-validation'

0 commit comments

Comments
 (0)