diff --git a/packages/webui/src/public/workflows.js b/packages/webui/src/public/workflows.js index 04cf3df1d..d9fb0e295 100644 --- a/packages/webui/src/public/workflows.js +++ b/packages/webui/src/public/workflows.js @@ -668,7 +668,8 @@ location.hash = `${orgHash(org)}/workflows`; } catch (error) { d.busy = false; d.confirm = false; - d.status = error.code === 'revision-conflict' ? 'Not deleted: the organization file changed this workflow since the page read it. Discard to load the current version.' : `Not deleted: ${error.message}`; + // Recheck B: Discard shows only with a pending change; without one the next read draws the current version. + d.status = error.code === 'revision-conflict' ? `Not deleted: the organization file changed this workflow since the page read it. ${changed(d) ? 'Discard to load the current version.' : 'The page shows the current version at its next read.'}` : `Not deleted: ${error.message}`; say(d.status); paint('wfg-delete'); } @@ -706,7 +707,7 @@ const refused = stepRefusal(st, e.i + 1); if (refused) return why(form, e, refused); if (e.mode === 'add') d.flow.steps.splice(e.i, 0, st); else d.flow.steps[e.i] = st; - d.edit = null; + d.edit = null; d.status = ''; select(e.i + 1); say(`${e.mode === 'add' ? 'Added' : 'Changed'} step ${e.i + 1}. Not saved yet.`); paint('wfg-save'); diff --git a/packages/webui/tests/workflows-browser.test.mjs b/packages/webui/tests/workflows-browser.test.mjs index 8c211cfd9..9b7ea502a 100644 --- a/packages/webui/tests/workflows-browser.test.mjs +++ b/packages/webui/tests/workflows-browser.test.mjs @@ -612,6 +612,7 @@ test('Save with a step form holding edits not applied refuses in words and sends assert.equal(await b.evaluate(`document.querySelector('[data-wfg-form] input[name="title"]')?.value`), 'Ship the release', 'the typed title stays'); await b.evaluate(press('[data-wfg-apply]')); await wait(`${titles}[0] === 'Ship the release'`, 'applied'); + assert.equal(await b.evaluate(`document.querySelector('[data-wfg-status]')`), null, 'Apply clears the refusal'); await b.evaluate(press('[data-wfg-save]')); await wait(`/Saved change\\./.test(${text('[data-wfg-status]')})`, 'saved'); assert.equal(st.writes.length, 1); @@ -638,6 +639,17 @@ test('Delete on a view another writer has changed is refused, not deleted over', assert.equal(st.writes[0].args.workflow, null); assert.equal(st.docs.acme.projects.site.workflows.change.description, 'Changed elsewhere.', 'the newer workflow is still in the file'); assert.ok(await b.evaluate(`${boxes}.length === 1 && !!document.querySelector('[data-wfg-unsaved]')`), 'the pending change stays'); + // With no pending change there is no Discard, so the refusal does not point at one. + await b.evaluate(press('[data-wfg-discard]')); + await wait(`${boxes}.length === 2 && !document.querySelector('[data-wfg-unsaved]')`, 'discarded'); + await b.evaluate(press('[data-wfg-delete]')); + await wait(`document.querySelector('[data-wfg-delete-yes]')`, 'confirm again'); + st.change('acme', doc => { doc.projects.site.workflows.change.description = 'Changed again.'; }); + await b.evaluate(press('[data-wfg-delete-yes]')); + await wait(`/^Not deleted/.test(${text('[data-wfg-status]')})`, 'second delete refused'); + assert.equal(await b.evaluate(text('[data-wfg-status]')), 'Not deleted: the organization file changed this workflow since the page read it. The page shows the current version at its next read.'); + assert.equal(await b.evaluate(`document.querySelector('[data-wfg-discard]')`), null); + assert.equal(st.docs.acme.projects.site.workflows.change.description, 'Changed again.'); }); test('a failed read says a pending change is kept, and it comes back when the read works', { timeout: 60000 }, async t => {