mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-13 16:02:59 +00:00
fix: clear only the mirrors after a clear-all, never discard a second time
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ca5912c8b6
commit
a1b85111de
@@ -2565,6 +2565,45 @@ describe('global AI tools', () => {
|
||||
}
|
||||
})
|
||||
|
||||
// "Clear all" deletes each row, then drops the in-tab mirrors. That second pass must not go
|
||||
// back through a live editor's discard: one that kept its draft, because it was changed after
|
||||
// the discard was asked for, would have that newer edit taken on the way past.
|
||||
it('does not discard again when clearing the mirrors after a clear-all', async () => {
|
||||
const path = 'u/admin/cleared_res'
|
||||
seedBackendDraft('resource', path, { path, value: { a: 2 } })
|
||||
let discards = 0
|
||||
registerLiveItemBridge({
|
||||
seed: () => false,
|
||||
read: () => ({ value: { path, value: { a: 3 } } }),
|
||||
refresh: () => undefined,
|
||||
noteRow: () => {},
|
||||
itemDeleted: () => Promise.resolve(),
|
||||
discard: () => {
|
||||
discards++
|
||||
return Promise.resolve('done' as const)
|
||||
},
|
||||
list: () => [{ workspace: WORKSPACE, itemKind: 'resource', path, value: { a: 3 } }]
|
||||
})
|
||||
try {
|
||||
const { removed } = await deleteGlobalDraft(WORKSPACE, 'resource', path)
|
||||
expect(removed).toBe(false)
|
||||
expect(discards).toBe(1)
|
||||
// The row is there on purpose, so the mirror pass leaves it alone entirely.
|
||||
clearGlobalDrafts(WORKSPACE, new Set([path]))
|
||||
expect(discards).toBe(1)
|
||||
} finally {
|
||||
registerLiveItemBridge({
|
||||
seed: () => false,
|
||||
read: () => undefined,
|
||||
refresh: () => undefined,
|
||||
noteRow: () => {},
|
||||
itemDeleted: () => Promise.resolve(),
|
||||
discard: () => undefined,
|
||||
list: () => []
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// A failed server delete must surface (throw), not silently report removed —
|
||||
// the same guard the write path got, applied to the delete path.
|
||||
it('deleteGlobalDraft throws when the server delete fails', async () => {
|
||||
|
||||
@@ -762,8 +762,18 @@ export async function flushGlobalDraftSaves(
|
||||
return { unflushedPaths }
|
||||
}
|
||||
|
||||
export function clearGlobalDrafts(workspace: string): void {
|
||||
/**
|
||||
* Drop the in-tab mirrors left after the rows themselves have been deleted. Only the mirrors:
|
||||
* `clear` would route to a live editor's discard, and one that kept its draft — because it was
|
||||
* changed after that discard was asked for — would have that newer edit taken on this pass,
|
||||
* undoing exactly what the first one preserved. `keep` names the paths to leave alone.
|
||||
*/
|
||||
export function clearGlobalDrafts(
|
||||
workspace: string,
|
||||
keep: ReadonlySet<string> = new Set()
|
||||
): void {
|
||||
for (const draft of UserDraft.list({ workspace, itemKinds: [...GLOBAL_DRAFT_KINDS] })) {
|
||||
UserDraft.clear(draft.itemKind, draft.path, { workspace })
|
||||
if (keep.has(draft.path)) continue
|
||||
UserDraft.forgetLocal(draft.itemKind, draft.path, { workspace })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,14 +60,24 @@
|
||||
// Delete each listed draft from the backend (the source of truth) — the
|
||||
// local clearGlobalDrafts only clears in-tab cells, leaving persisted rows.
|
||||
// Continue past a per-row failure so one bad delete doesn't strand the rest.
|
||||
// A draft an open editor kept, or one whose delete failed, is still there on purpose or
|
||||
// still to be dealt with: its mirror stays too, or the page would stop showing it.
|
||||
const kept = new Set<string>()
|
||||
for (const item of [...drafts]) {
|
||||
try {
|
||||
await deleteGlobalDraft($workspaceStore, item.type, item.path, item.triggerKind)
|
||||
const { removed } = await deleteGlobalDraft(
|
||||
$workspaceStore,
|
||||
item.type,
|
||||
item.path,
|
||||
item.triggerKind
|
||||
)
|
||||
if (!removed) kept.add(item.path)
|
||||
} catch (e) {
|
||||
console.error('Failed to clear draft', item.path, e)
|
||||
kept.add(item.path)
|
||||
}
|
||||
}
|
||||
clearGlobalDrafts($workspaceStore)
|
||||
clearGlobalDrafts($workspaceStore, kept)
|
||||
refreshDrafts()
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user