mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-13 08:02:47 +00:00
fix: discard the value as of the click, not as of its turn
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
89170ab042
commit
6cbf34c045
@@ -472,8 +472,13 @@ class Entry<V> {
|
||||
}
|
||||
|
||||
discard(): Promise<DiscardOutcome> {
|
||||
// What a discard throws away is the value as of the click, like a save sends the value as
|
||||
// of the click: one typed while it waited its turn behind a save is newer than it, and
|
||||
// reverting that would drop it with nothing left to recover it from.
|
||||
const askedAt = this.edits
|
||||
return this.run(async () => {
|
||||
if (!this.loaded || this.retired) return { removed: false }
|
||||
if (this.edits !== askedAt) return { removed: false }
|
||||
if (this.origin === 'draft') {
|
||||
const kept = snapshot(this.value)
|
||||
const keptRow = this.row
|
||||
|
||||
@@ -493,6 +493,32 @@ describe('item store: origins', () => {
|
||||
expect(rows.writes).toEqual([{ path: 'u/me/r', value: null }])
|
||||
})
|
||||
|
||||
it('keeps an edit typed after a discard was asked for, while it waited its turn', async () => {
|
||||
const rows = fakeRows()
|
||||
const gate = deferred()
|
||||
const { item } = await open(
|
||||
rows,
|
||||
adapter({ deployed: deployedRes }, () => gate.promise)
|
||||
)
|
||||
item.value = { ...deployedRes, description: 'edited' }
|
||||
const saving = item.save()
|
||||
await settle()
|
||||
const discarding = item.discard()
|
||||
await settle()
|
||||
item.value = { ...deployedRes, description: 'typed after the discard' }
|
||||
gate.resolve()
|
||||
|
||||
expect(await saving).toMatchObject({ ok: true })
|
||||
// The discard is older than what is on screen: reverting to `deployed` would drop it.
|
||||
expect(await discarding).toEqual({ removed: false })
|
||||
expect(item.value).toEqual({ ...deployedRes, description: 'typed after the discard' })
|
||||
expect(item.dirty).toBe(true)
|
||||
expect(rows.writes.at(-1)).toEqual({
|
||||
path: 'u/me/r',
|
||||
value: { ...deployedRes, description: 'typed after the discard' }
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps a draft-only item an outside write put back while its delete was going', async () => {
|
||||
const rows = fakeRows()
|
||||
const draft = { ...deployedRes, description: 'only a draft' }
|
||||
|
||||
Reference in New Issue
Block a user