Skip to content

Commit 18513e3

Browse files
fix(ui): fix resource switching logic, multi select delete
1 parent 64cdab2 commit 18513e3

4 files changed

Lines changed: 45 additions & 45 deletions

File tree

apps/sim/app/api/copilot/chat/resources/route.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,24 +169,24 @@ export async function DELETE(req: NextRequest) {
169169
const body = await req.json()
170170
const { chatId, resourceType, resourceId } = RemoveResourceSchema.parse(body)
171171

172-
const [chat] = await db
173-
.select({ resources: copilotChats.resources })
174-
.from(copilotChats)
172+
const [updated] = await db
173+
.update(copilotChats)
174+
.set({
175+
resources: sql`COALESCE((
176+
SELECT jsonb_agg(elem)
177+
FROM jsonb_array_elements(${copilotChats.resources}) elem
178+
WHERE NOT (elem->>'type' = ${resourceType} AND elem->>'id' = ${resourceId})
179+
), '[]'::jsonb)`,
180+
updatedAt: new Date(),
181+
})
175182
.where(and(eq(copilotChats.id, chatId), eq(copilotChats.userId, userId)))
176-
.limit(1)
183+
.returning({ resources: copilotChats.resources })
177184

178-
if (!chat) {
185+
if (!updated) {
179186
return createNotFoundResponse('Chat not found or unauthorized')
180187
}
181188

182-
const existing = Array.isArray(chat.resources) ? (chat.resources as ChatResource[]) : []
183-
const key = `${resourceType}:${resourceId}`
184-
const merged = existing.filter((r) => `${r.type}:${r.id}` !== key)
185-
186-
await db
187-
.update(copilotChats)
188-
.set({ resources: sql`${JSON.stringify(merged)}::jsonb`, updatedAt: new Date() })
189-
.where(eq(copilotChats.id, chatId))
189+
const merged = Array.isArray(updated.resources) ? (updated.resources as ChatResource[]) : []
190190

191191
logger.info('Removed resource from chat', { chatId, resourceType, resourceId })
192192

apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tabs.tsx

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,15 @@ export function ResourceTabs({
180180
return () => node.removeEventListener('wheel', handler)
181181
}, [])
182182

183+
useEffect(() => {
184+
const node = scrollNodeRef.current
185+
if (!node || !activeId) return
186+
const tab = node.querySelector<HTMLElement>(
187+
`[data-resource-tab-id="${CSS.escape(activeId)}"]`
188+
)
189+
tab?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' })
190+
}, [activeId])
191+
183192
const addResource = useAddChatResource(chatId)
184193
const removeResource = useRemoveChatResource(chatId)
185194
const reorderResources = useReorderChatResources(chatId)
@@ -286,24 +295,9 @@ export function ResourceTabs({
286295
if (anchorIdRef.current && removedIds.has(anchorIdRef.current)) {
287296
anchorIdRef.current = null
288297
}
289-
// Serialize mutations so each onMutate sees the cache updated by the prior
290-
// one. Continue on individual failures so remaining removals still fire.
291-
const persistable = targets.filter((r) => !isEphemeralResource(r))
292-
if (persistable.length > 0) {
293-
void (async () => {
294-
for (const r of persistable) {
295-
try {
296-
await removeResource.mutateAsync({
297-
chatId,
298-
resourceType: r.type,
299-
resourceId: r.id,
300-
})
301-
} catch {
302-
// Individual failure — the mutation's onError already rolled back
303-
// this resource in cache. Remaining removals continue.
304-
}
305-
}
306-
})()
298+
for (const r of targets) {
299+
if (isEphemeralResource(r)) continue
300+
removeResource.mutate({ chatId, resourceType: r.type, resourceId: r.id })
307301
}
308302
},
309303
// eslint-disable-next-line react-hooks/exhaustive-deps

apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,11 @@ export function useChat(
12771277
const persistedResources = chatHistory.resources.filter((r) => r.id !== 'streaming-file')
12781278
if (persistedResources.length > 0) {
12791279
setResources(persistedResources)
1280-
setActiveResourceId(persistedResources[persistedResources.length - 1].id)
1280+
setActiveResourceId((prev) =>
1281+
prev && persistedResources.some((r) => r.id === prev)
1282+
? prev
1283+
: persistedResources[persistedResources.length - 1].id
1284+
)
12811285

12821286
for (const resource of persistedResources) {
12831287
if (resource.type !== 'workflow') continue

apps/sim/hooks/queries/tasks.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -485,21 +485,23 @@ export function useRemoveChatResource(chatId?: string) {
485485
onMutate: async ({ resourceType, resourceId }) => {
486486
if (!chatId) return
487487
await queryClient.cancelQueries({ queryKey: taskKeys.detail(chatId) })
488-
const previous = queryClient.getQueryData<TaskChatHistory>(taskKeys.detail(chatId))
489-
if (previous) {
490-
queryClient.setQueryData<TaskChatHistory>(taskKeys.detail(chatId), {
491-
...previous,
492-
resources: previous.resources.filter(
493-
(r) => !(r.type === resourceType && r.id === resourceId)
494-
),
495-
})
496-
}
497-
return { previous }
488+
const removed: TaskChatHistory['resources'] = []
489+
queryClient.setQueryData<TaskChatHistory>(taskKeys.detail(chatId), (prev) => {
490+
if (!prev) return prev
491+
const next: TaskChatHistory['resources'] = []
492+
for (const r of prev.resources) {
493+
if (r.type === resourceType && r.id === resourceId) removed.push(r)
494+
else next.push(r)
495+
}
496+
return removed.length > 0 ? { ...prev, resources: next } : prev
497+
})
498+
return { removed }
498499
},
499500
onError: (_err, _variables, context) => {
500-
if (context?.previous && chatId) {
501-
queryClient.setQueryData(taskKeys.detail(chatId), context.previous)
502-
}
501+
if (!chatId || !context?.removed.length) return
502+
queryClient.setQueryData<TaskChatHistory>(taskKeys.detail(chatId), (prev) =>
503+
prev ? { ...prev, resources: [...prev.resources, ...context.removed] } : prev
504+
)
503505
},
504506
onSettled: () => {
505507
if (chatId) {

0 commit comments

Comments
 (0)