diff --git a/e2e-tests/basic.spec.ts b/e2e-tests/basic.spec.ts index 04cf07f261..6864f66dd5 100644 --- a/e2e-tests/basic.spec.ts +++ b/e2e-tests/basic.spec.ts @@ -333,3 +333,60 @@ test('Opening a second datepicker should close the first one #7341', async ({ pa // Close date picker await page.click('a:has-text("2000-05-06 Sat").opacity-80') }) + +test('Block content should be preserved when adding a deadline via datepicker', async({page,block})=>{ + var datePicker, step; + + await createRandomPage(page) + + async function openDatePicker(kind) { + await page.keyboard.type(' /' + kind, { delay: 20 }); + await page.waitForTimeout(100) // Tolerable delay for the action menu to open + await expect(page.locator(`[data-modal-name="commands"]`)).toBeVisible(); + + await page.keyboard.press('Enter'); + await page.waitForTimeout(100) // Tolerable delay for the action menu to open + datePicker = page.locator(`[data-modal-name="date-picker"]`); + await expect(datePicker).toBeVisible(); + return datePicker; + + } + + async function validateDatePickerInput(kind, step) { + // Expect: + // previously edited block to still be in editing mode + // content of block to be complete with scheduled date (if scheduled/deadline) + await expect(await block.isEditing()).toBe(true); + + var content = page.locator('textarea >> nth=0'); + await expect(content).toContainText(step); + + if(kind == 'deadline') { + await expect(content).toContainText('DEADLINE'); + } + } + + // Select deadline today using enter key + await block.enterNext(); + step = 'Test a deadline entered using the keyboard'; + await block.mustType(step); + await openDatePicker('deadline'); + await page.keyboard.press('Enter'); + await validateDatePickerInput('deadline', step); + + // Select deadline today using mouse click on submit button + await block.enterNext(); + step = 'Test a deadline entered using the mouse'; + await block.mustType(step); + datePicker = await openDatePicker('deadline'); + await datePicker.getByText('Submit').click(); + await validateDatePickerInput('deadline', step); + + // Test date picker refocusing + await block.enterNext(); + step = 'Test a date entered using the keyboard'; + await block.mustType(step); + datePicker = await openDatePicker('date'); + await page.keyboard.press('Enter'); + await validateDatePickerInput('date', step ); +}) diff --git a/src/main/frontend/components/datetime.cljs b/src/main/frontend/components/datetime.cljs index c6c4f856e7..7f4901de3b 100644 --- a/src/main/frontend/components/datetime.cljs +++ b/src/main/frontend/components/datetime.cljs @@ -10,6 +10,7 @@ [frontend.ui :as ui] [frontend.util :as util] [frontend.mixins :as mixins] + [goog.dom :as gdom] [rum.core :as rum] [logseq.graph-parser.util.page-ref :as page-ref])) @@ -78,6 +79,13 @@ :duration "d"}))} "Add repeater"]))) +(defn restore-focus! + "Restore focus to the active input that triggered the date-picker." + [] + (when-let [input (state/get-input)] + (when-let [current-input (gdom/getElement input)] + (.focus current-input)))) + (defn- clear-timestamp! [] (reset! *timestamp default-timestamp-value) @@ -101,12 +109,15 @@ block-id (or (:block/uuid block) editing-block-id) typ (or @commands/*current-command typ)] - (if (and (state/editing?) (= editing-block-id block-id)) - (editor-handler/set-editing-block-timestamp! typ - text) + (if (= editing-block-id block-id) + (do + (editor-handler/set-editing-block-timestamp! typ + text) + (restore-focus!)) (editor-handler/set-block-timestamp! block-id typ - text)) + text) + ) (when show? (reset! show? false))) @@ -169,6 +180,8 @@ format {:command :page-ref}) (state/clear-editor-action!) - (reset! commands/*current-command nil))))}) + (reset! commands/*current-command nil) + (restore-focus!) + )))}) (when deadline-or-schedule? (time-repeater))]))