From 90f413ce067faff123eddee114b0feb0f1219d20 Mon Sep 17 00:00:00 2001 From: Tim Bradgate Date: Sun, 14 Jun 2026 22:50:04 +0100 Subject: [PATCH] Fix cue editor modal interactions in V3 UI - Go to Page: Replace Vuelidate with a simple ref + v-model.number, so clicking OK actually navigates instead of silently failing validation - Add New Cue / Edit Cue modals: Wire BForm @submit to the existing handlers so pressing Enter submits the form (was a no-op previously) - Jump to Cue: Move modal.hide() into navigateToMatch() so selecting from a multi-match or suggestion list closes the modal (only the single-match path closed it before) - Add E2E coverage for all three fixes in specs 08 and 10 Co-Authored-By: Claude Sonnet 4.6 --- .../e2e/tests/08-show-config-cues.spec.ts | 10 ++++ .../e2e/tests/10-show-config-script.spec.ts | 49 +++++++++++++++++++ .../components/show/config/cues/CueEditor.vue | 39 ++------------- .../show/config/cues/JumpToCueModal.vue | 2 +- .../show/config/cues/ScriptLineCueEditor.vue | 4 +- 5 files changed, 67 insertions(+), 37 deletions(-) diff --git a/client-v3/e2e/tests/08-show-config-cues.spec.ts b/client-v3/e2e/tests/08-show-config-cues.spec.ts index 102b0f6c..37d96171 100644 --- a/client-v3/e2e/tests/08-show-config-cues.spec.ts +++ b/client-v3/e2e/tests/08-show-config-cues.spec.ts @@ -109,6 +109,16 @@ test('can open the Go to Page dialog in cue editor', async () => { await waitForModalClosed(page); }); +test('Go to Page submits and navigates to the requested page', async () => { + await page.click('button:has-text("Go to Page")'); + await waitForModal(page, 'Go to Page'); + await page.fill('.modal.show input[type="number"]', '1'); + await confirmModal(page); + // If the fix is working, clicking OK closes the modal; previously Vuelidate prevented this + await waitForModalClosed(page); + await expect(page.locator('p.mb-0:has-text("Current Page: 1")')).toBeVisible(); +}); + // ── Cue Counts ──────────────────────────────────────────────────────────── test('switches to Cue Counts sub-tab', async () => { diff --git a/client-v3/e2e/tests/10-show-config-script.spec.ts b/client-v3/e2e/tests/10-show-config-script.spec.ts index e2b92d04..f942e51f 100644 --- a/client-v3/e2e/tests/10-show-config-script.spec.ts +++ b/client-v3/e2e/tests/10-show-config-script.spec.ts @@ -254,6 +254,55 @@ test('edits the cue identifier', async () => { }); }); +test('can add a cue using Enter key in Add New Cue modal', async () => { + await page.locator('.add-cue-btn').first().click(); + await waitForModal(page, 'Add New Cue'); + await page.locator('.modal.show select#new-cue-type').selectOption({ index: 1 }); + await page.fill('#new-cue-ident', '003'); + // Enter key submits the form (fix: BForm @submit bound to onSubmitNew) + await page.locator('#new-cue-ident').press('Enter'); + await waitForModalClosed(page); + await expect(page.locator('.cue-button:not(.add-cue-btn)')).toHaveCount(2, { timeout: 5_000 }); +}); + +test('can edit a cue identifier using Enter key in Edit Cue modal', async () => { + // Click the second cue button (003) + await page.locator('.cue-button:not(.add-cue-btn)').last().click(); + await waitForModal(page, 'Edit Cue'); + await page.fill('#edit-cue-ident', '004'); + // Enter key submits the form (fix: BForm @submit bound to onSubmitEdit) + await page.locator('#edit-cue-ident').press('Enter'); + await waitForModalClosed(page); + await expect(page.locator('.cue-button:not(.add-cue-btn)')).toHaveCount(2, { timeout: 5_000 }); +}); + +test('Jump to Cue navigates and auto-closes the modal', async () => { + await page.click('button:has-text("Go to Cue")'); + await waitForModal(page, 'Jump to Cue'); + await page.locator('.modal.show select').selectOption({ index: 1 }); // LX type + await page.locator('.modal.show input').fill('004'); + await confirmModal(page); // Click Search + // Single exact match → navigateToMatch() now calls modal.hide() (fix) + await waitForModalClosed(page); + await expect(page.locator('.v-toast__text').filter({ hasText: /Jumped to/ })).toBeVisible({ + timeout: 5_000, + }); +}); + +test('deletes the Enter-key-added cue', async () => { + // Removes the LX 004 cue created in the Enter key test, leaving only LX 002 + await page.locator('.cue-button:not(.add-cue-btn)').last().click(); + await waitForModal(page, 'Edit Cue'); + await page.locator('.modal.show button:has-text("Delete")').click(); + await waitForModal(page, 'Delete Cue'); + await page + .locator('.modal.show') + .filter({ has: page.locator('.modal-title:has-text("Delete Cue")') }) + .locator('.modal-footer button.btn-danger') + .click(); + await expect(page.locator('.cue-button:not(.add-cue-btn)')).toHaveCount(1, { timeout: 5_000 }); +}); + test('deletes the cue', async () => { await page.locator('.cue-button:not(.add-cue-btn)').first().click(); await waitForModal(page, 'Edit Cue'); diff --git a/client-v3/src/components/show/config/cues/CueEditor.vue b/client-v3/src/components/show/config/cues/CueEditor.vue index bf179840..03e5fafd 100644 --- a/client-v3/src/components/show/config/cues/CueEditor.vue +++ b/client-v3/src/components/show/config/cues/CueEditor.vue @@ -57,22 +57,11 @@ :no-footer="changingPage" :no-close-on-backdrop="changingPage" :no-close-on-esc="changingPage" - :ok-disabled="pageV$.pageInputFormState.$invalid" @ok.prevent="goToPage" > - + - - - This is a required field, and must be greater than 0. - + @@ -83,10 +72,7 @@