Skip to content

Commit 0a536dc

Browse files
authored
Merge pull request #3186 from obsidian-tasks-group/reading-mode-date-picker
feat: Add date-picker to Reading Mode and Tasks query results
2 parents 29dd968 + 4d562a3 commit 0a536dc

6 files changed

+115
-37
lines changed

resources/sample_vaults/Tasks-Demo/Manual Testing/Smoke Testing the Tasks Plugin.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,13 @@ heading includes Rendering of Task Blocks
149149
150150
- View this file in **Reading mode**...
151151
- On the task line above:
152-
- [ ] #task ~~**left**-click on a date value, and use the date picker to select and save a different date. Check that the date is updated.~~
153-
- [ ] #task ~~**left**-click on a date value, and click outside the date picker, to confirm that the picker closes.~~
152+
- [ ] #task **left**-click on a date value, and use the date picker to select and save a different date. Check that the date is updated.
153+
- [ ] #task **left**-click on a date value, and click outside the date picker, to confirm that the picker closes.
154154
- [ ] #task **right**-click on a date value, and use the context menu to select and save a different date. Check that the date is updated.
155155
- [ ] #task **right**-click on a date value, and click outside the context menu, to confirm that the menu closes.
156156
- In the tasks search block below:
157-
- [ ] #task ~~**left**-click on a date value, and use the date picker to select and save a different date. Check that the date is updated.~~
158-
- [ ] #task ~~**left**-click on a date value, and click outside the date picker, to confirm that the picker closes.~~
157+
- [ ] #task **left**-click on a date value, and use the date picker to select and save a different date. Check that the date is updated.
158+
- [ ] #task **left**-click on a date value, and click outside the date picker, to confirm that the picker closes.
159159
- [ ] #task **right**-click on a date value, and use the context menu to select and save a different date. Check that the date is updated.
160160
- [ ] #task **right**-click on a date value, and click outside the context menu, to confirm that the menu closes.
161161
- [ ] #task **check**: Checked all above steps for **editing dates** worked
@@ -177,8 +177,8 @@ hide postpone button
177177
2. **Check** that the text in the list item is copied in to the Description field
178178
3. Type some values in to the fields
179179
4. In one of the date fields, type `tm` (including the space afterwards) and **Check** it is expanded in to `tomorrow`
180-
5. ~~In one of the date fields, left-click the calendar button, and use the context menu to select and save a date. Check that the date is saved.~~
181-
6. ~~In one of the date fields, left-click the calendar button, and click outside the date picker, to confirm that the picker closes and the modal is still usable.~~
180+
5. In one of the date fields, left-click the calendar button, and use the context menu to select and save a date. Check that the date is saved.
181+
6. In one of the date fields, left-click the calendar button, and click outside the date picker, to confirm that the picker closes and the modal is still usable.
182182
7. Hit Return or click **Apply**
183183
8. **Check** that the list item above is converted in to a task
184184
9. **Check** that values you entered in the modal have been copied in to the list item above

src/Renderer/TaskLineRenderer.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { TaskRegularExpressions } from '../Task/TaskRegularExpressions';
1111
import { StatusMenu } from '../ui/Menus/StatusMenu';
1212
import type { AllTaskDateFields } from '../DateTime/DateFieldTypes';
1313
import { defaultTaskSaver } from '../ui/Menus/TaskEditingMenu';
14+
import { promptForDate } from '../ui/Menus/DatePicker';
1415
import { splitDateText } from '../DateTime/Postponer';
1516
import { DateMenu } from '../ui/Menus/DateMenu';
1617
import { TaskFieldRenderer } from './TaskFieldRenderer';
@@ -215,11 +216,11 @@ export class TaskLineRenderer {
215216
const componentDateField = component as AllTaskDateFields;
216217

217218
// Note: The more convenient span.onClickEvent() doesn't work here, as it is not available when tests are run.
218-
// span.addEventListener('click', (ev: MouseEvent) => {
219-
// ev.preventDefault(); // suppress the default click behavior
220-
// ev.stopPropagation(); // suppress further event propagation
221-
// promptForDate(span, task, componentDateField, defaultTaskSaver);
222-
// });
219+
span.addEventListener('click', (ev: MouseEvent) => {
220+
ev.preventDefault(); // suppress the default click behavior
221+
ev.stopPropagation(); // suppress further event propagation
222+
promptForDate(span, task, componentDateField, defaultTaskSaver);
223+
});
223224

224225
span.addEventListener('contextmenu', (ev: MouseEvent) => {
225226
ev.preventDefault(); // suppress the default context menu
@@ -229,8 +230,7 @@ export class TaskLineRenderer {
229230
});
230231
span.setAttribute(
231232
'title',
232-
// `Click to edit ${splitDateText(componentDateField)}, Right-click for more options`,
233-
`Right-click to edit ${splitDateText(componentDateField)}`,
233+
`Click to edit ${splitDateText(componentDateField)}, Right-click for more options`,
234234
);
235235
}
236236
}

src/ui/Menus/DatePicker.ts

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,28 @@
11
import flatpickr from 'flatpickr';
22
import type { Task } from '../../Task/Task';
3-
import { SetTaskDate } from '../EditInstructions/DateInstructions';
3+
import { RemoveTaskDate, SetTaskDate } from '../EditInstructions/DateInstructions';
44
import type { AllTaskDateFields } from '../../DateTime/DateFieldTypes';
5+
import type { TaskSaver } from './TaskEditingMenu';
56

67
/**
78
* A calendar date picker which edits a date value in a {@link Task} object.
8-
* See also {@link openDatePicker}
99
* @param parentElement
1010
* @param task
1111
* @param dateFieldToEdit
1212
* @param taskSaver
13-
*
14-
* See also {@link openDatePicker}
1513
*/
1614
export function promptForDate(
1715
parentElement: HTMLElement,
1816
task: Task,
1917
dateFieldToEdit: AllTaskDateFields,
20-
taskSaver: (originalTask: Task, newTasks: Task | Task[]) => Promise<void>,
18+
taskSaver: TaskSaver,
2119
) {
2220
const currentValue = task[dateFieldToEdit];
2321
// TODO figure out how Today's date is determined: if Obsidian is left
2422
// running overnight, the flatpickr modal shows the previous day as Today.
2523
const fp = flatpickr(parentElement, {
2624
defaultDate: currentValue ? currentValue.format('YYYY-MM-DD') : new Date(),
25+
disableMobile: true,
2726
enableTime: false, // Optional: Enable time picker
2827
dateFormat: 'Y-m-d', // Adjust the date and time format as needed
2928
locale: {
@@ -35,10 +34,53 @@ export function promptForDate(
3534
const newTask = new SetTaskDate(dateFieldToEdit, date).apply(task);
3635
await taskSaver(task, newTask);
3736
}
38-
instance.destroy(); // Proper cleanup
37+
instance.destroy();
38+
},
39+
onReady: (_selectedDates, _dateStr, instance) => {
40+
// Add custom buttons dynamically
41+
const buttonContainer = document.createElement('div');
42+
buttonContainer.style.display = 'flex';
43+
buttonContainer.style.justifyContent = 'space-between';
44+
buttonContainer.style.marginTop = '10px';
45+
46+
// Create "Clear" button
47+
addButton(buttonContainer, instance, task, taskSaver, 'Clear', () => {
48+
return new RemoveTaskDate(dateFieldToEdit, task).apply(task);
49+
});
50+
51+
// Create "Today" button
52+
addButton(buttonContainer, instance, task, taskSaver, 'Today', () => {
53+
const today = new Date();
54+
return new SetTaskDate(dateFieldToEdit, today).apply(task);
55+
});
56+
57+
// Append the button container to the Flatpickr calendar container
58+
const calendarContainer = instance.calendarContainer;
59+
calendarContainer.appendChild(buttonContainer);
3960
},
4061
});
4162

4263
// Open the calendar programmatically
4364
fp.open();
4465
}
66+
67+
function addButton(
68+
buttonContainer: HTMLDivElement,
69+
instance: flatpickr.Instance,
70+
task: Task,
71+
taskSaver: TaskSaver,
72+
buttonName: string,
73+
applyDate: () => Task[],
74+
) {
75+
const button = document.createElement('button');
76+
button.type = 'button';
77+
button.textContent = buttonName;
78+
button.classList.add('flatpickr-button');
79+
80+
button.addEventListener('click', async () => {
81+
const newTask = applyDate();
82+
await taskSaver(task, newTask);
83+
instance.destroy();
84+
});
85+
buttonContainer.appendChild(button);
86+
}

tests/Renderer/QueryResultsRenderer.test.QueryResultsRenderer_tests_fully_populated_task.approved.html

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,34 @@
2121
<span class="task-priority" data-task-priority="medium"><span>🔼</span></span>
2222
<span class="task-recurring"><span>🔁 every day when done</span></span>
2323
<span class="task-onCompletion"><span>🏁 delete</span></span>
24-
<span class="task-created" data-task-created="past-far" title="Right-click to edit created date">
24+
<span
25+
class="task-created"
26+
data-task-created="past-far"
27+
title="Click to edit created date, Right-click for more options">
2528
<span>➕ 2023-07-01</span>
2629
</span>
27-
<span class="task-start" data-task-start="past-far" title="Right-click to edit start date">
30+
<span
31+
class="task-start"
32+
data-task-start="past-far"
33+
title="Click to edit start date, Right-click for more options">
2834
<span>🛫 2023-07-02</span>
2935
</span>
30-
<span class="task-scheduled" data-task-scheduled="past-far" title="Right-click to edit scheduled date">
36+
<span
37+
class="task-scheduled"
38+
data-task-scheduled="past-far"
39+
title="Click to edit scheduled date, Right-click for more options">
3140
<span>⏳ 2023-07-03</span>
3241
</span>
33-
<span class="task-due" data-task-due="past-far" title="Right-click to edit due date">
42+
<span class="task-due" data-task-due="past-far" title="Click to edit due date, Right-click for more options">
3443
<span>📅 2023-07-04</span>
3544
</span>
36-
<span class="task-cancelled" data-task-cancelled="past-far" title="Right-click to edit cancelled date">
45+
<span
46+
class="task-cancelled"
47+
data-task-cancelled="past-far"
48+
title="Click to edit cancelled date, Right-click for more options">
3749
<span>❌ 2023-07-06</span>
3850
</span>
39-
<span class="task-done" data-task-done="past-far" title="Right-click to edit done date">
51+
<span class="task-done" data-task-done="past-far" title="Click to edit done date, Right-click for more options">
4052
<span>✅ 2023-07-05</span>
4153
</span>
4254
<span class="task-block-link"><span>^dcf64c</span></span>

tests/Renderer/TaskLineRenderer.test.Visualise_HTML_Full_task_-_full_mode.approved.html

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,31 @@
2323
<span class="task-priority" data-task-priority="medium"><span>🔼</span></span>
2424
<span class="task-recurring"><span>🔁 every day when done</span></span>
2525
<span class="task-onCompletion"><span>🏁 delete</span></span>
26-
<span class="task-created" data-task-created="past-4d" title="Right-click to edit created date">
26+
<span
27+
class="task-created"
28+
data-task-created="past-4d"
29+
title="Click to edit created date, Right-click for more options">
2730
<span>➕ 2023-07-01</span>
2831
</span>
29-
<span class="task-start" data-task-start="past-3d" title="Right-click to edit start date">
32+
<span class="task-start" data-task-start="past-3d" title="Click to edit start date, Right-click for more options">
3033
<span>🛫 2023-07-02</span>
3134
</span>
32-
<span class="task-scheduled" data-task-scheduled="past-2d" title="Right-click to edit scheduled date">
35+
<span
36+
class="task-scheduled"
37+
data-task-scheduled="past-2d"
38+
title="Click to edit scheduled date, Right-click for more options">
3339
<span>⏳ 2023-07-03</span>
3440
</span>
35-
<span class="task-due" data-task-due="past-1d" title="Right-click to edit due date">
41+
<span class="task-due" data-task-due="past-1d" title="Click to edit due date, Right-click for more options">
3642
<span>📅 2023-07-04</span>
3743
</span>
38-
<span class="task-cancelled" data-task-cancelled="future-1d" title="Right-click to edit cancelled date">
44+
<span
45+
class="task-cancelled"
46+
data-task-cancelled="future-1d"
47+
title="Click to edit cancelled date, Right-click for more options">
3948
<span>❌ 2023-07-06</span>
4049
</span>
41-
<span class="task-done" data-task-done="today" title="Right-click to edit done date">
50+
<span class="task-done" data-task-done="today" title="Click to edit done date, Right-click for more options">
4251
<span>✅ 2023-07-05</span>
4352
</span>
4453
<span class="task-block-link"><span>^dcf64c</span></span>

tests/Renderer/TaskLineRenderer.test.Visualise_HTML_Full_task_-_short_mode.approved.html

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,33 @@
2323
<span class="task-priority" data-task-priority="medium"><span>🔼</span></span>
2424
<span class="task-recurring"><span>🔁</span></span>
2525
<span class="task-onCompletion"><span>🏁</span></span>
26-
<span class="task-created" data-task-created="past-4d" title="Right-click to edit created date">
26+
<span
27+
class="task-created"
28+
data-task-created="past-4d"
29+
title="Click to edit created date, Right-click for more options">
2730
<span></span>
2831
</span>
29-
<span class="task-start" data-task-start="past-3d" title="Right-click to edit start date"><span>🛫</span></span>
30-
<span class="task-scheduled" data-task-scheduled="past-2d" title="Right-click to edit scheduled date">
32+
<span class="task-start" data-task-start="past-3d" title="Click to edit start date, Right-click for more options">
33+
<span>🛫</span>
34+
</span>
35+
<span
36+
class="task-scheduled"
37+
data-task-scheduled="past-2d"
38+
title="Click to edit scheduled date, Right-click for more options">
3139
<span></span>
3240
</span>
33-
<span class="task-due" data-task-due="past-1d" title="Right-click to edit due date"><span>📅</span></span>
34-
<span class="task-cancelled" data-task-cancelled="future-1d" title="Right-click to edit cancelled date">
41+
<span class="task-due" data-task-due="past-1d" title="Click to edit due date, Right-click for more options">
42+
<span>📅</span>
43+
</span>
44+
<span
45+
class="task-cancelled"
46+
data-task-cancelled="future-1d"
47+
title="Click to edit cancelled date, Right-click for more options">
3548
<span></span>
3649
</span>
37-
<span class="task-done" data-task-done="today" title="Right-click to edit done date"><span></span></span>
50+
<span class="task-done" data-task-done="today" title="Click to edit done date, Right-click for more options">
51+
<span></span>
52+
</span>
3853
<span class="task-block-link"><span>^dcf64c</span></span>
3954
</span>
4055
</li>

0 commit comments

Comments
 (0)