Skip to content

Commit

Permalink
Merge pull request #2557 from obsidian-tasks-group/edit-created-and-done
Browse files Browse the repository at this point in the history
feat: Add editing of Created, Done and Cancelled dates in Modal
  • Loading branch information
claremacrae authored Jan 1, 2024
2 parents 7e9f420 + e7e0f3c commit 9c14800
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 52 deletions.
25 changes: 11 additions & 14 deletions docs/Editing/Create or edit Task.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ Here you can optionally give the task
[[Dates#Scheduled date|scheduled]] and
[[Dates#Start date|start]] dates.

You can also add or edit
[[Dates#Created date|created]],
[[Dates#Done date|done]] and
[[Dates#Cancelled date|cancelled]] dates.

There is a lot of flexibility here. For example:

- You can type in exact dates, such as `2022-11-28`.
Expand All @@ -83,8 +88,13 @@ There is a lot of flexibility here. For example:

Note that relative dates will be always interpreted as being in the future, because that is usually what you want. You can change this behavior by unchecking "Only future dates" if you want to enter an overdue task or experiment with the way how relative dates in the past would be interpreted in queries.

> [!Info]
> If you have enabled ‘Set created date on every added task’ in Tasks settings (and restarted Obsidian), when you create a new Task via this modal, today's date will be added automatically.
> [!released]
`Only future dates` was introduced in Tasks 1.15.0.
>
> - `Only future dates` was introduced in Tasks 1.15.0.
> - Editing of [[Dates#Created date|created]], [[Dates#Done date|done]] and [[Dates#Cancelled date|cancelled]] dates was introduced in Tasks X.Y.Z.
### Date abbreviations

Expand Down Expand Up @@ -135,19 +145,6 @@ These values cannot currently be edited in this modal.

A read-only checkbox, showing whether the task is completed.

### Created on

> [!released]
Created date was introduced in Tasks 2.0.0.

A read-only display of the task's [[Dates#Created date|created date]], if any.

If you have enabled ‘Set created date on every added task’ in Tasks settings (and restarted Obsidian), when you create a new Task via this modal, today's date will be added automatically.

### Done on

A read-only display of the task's [[Dates#Done date|done date]], if any.

## Finishing off

To close the modal and save your edits, do one of:
Expand Down
2 changes: 2 additions & 0 deletions docs/Introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ _In recent [releases](https://github.com/obsidian-tasks-group/obsidian-tasks/rel
Move the older ones down to the top of the comment block below...
-->

- X.Y.Z: 🔥 The [[Create or edit Task]] modal can now edit Created, Done and Cancelled dates
- X.Y.Z: 🔥 Add support for [[Dates#Cancelled date|cancelled dates]].
- 5.4.0: 🔥 Add [[Layout#Full Mode|'full mode']] to turn off `short mode`.
- 5.4.0: 🔥 Add any [[Grouping|'group by']] and [[Sorting|'sort by']] instructions to [[Explaining Queries|explain]] output.
- 5.4.0: 🔥 Recurrence now works well [[Recurring Tasks and Custom Statuses#When DONE is not followed by TODO or IN_PROGRESS|when DONE is not followed by TODO or IN_PROGRESS]].
Expand Down
Binary file modified docs/images/modal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
112 changes: 85 additions & 27 deletions src/ui/EditTask.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
startDateSymbol,
scheduledDateSymbol,
dueDateSymbol,
cancelledDateSymbol,
createdDateSymbol,
doneDateSymbol,
} = TASK_FORMATS.tasksPluginEmoji.taskSerializer.symbols;
let descriptionInput: HTMLTextAreaElement;
Expand All @@ -35,6 +38,7 @@
scheduledDate: string;
dueDate: string;
doneDate: string;
cancelledDate: string,
forwardOnly: boolean;
} = {
description: '',
Expand All @@ -46,20 +50,33 @@
scheduledDate: '',
dueDate: '',
doneDate: '',
cancelledDate: '',
forwardOnly: true
};
let isDescriptionValid: boolean = true;
let parsedCreated: string = '';
let parsedCreatedDate: string = '';
let isCreatedDateValid: boolean = true;
let parsedStartDate: string = '';
let isStartDateValid: boolean = true;
let parsedScheduledDate: string = '';
let isScheduledDateValid: boolean = true;
let parsedDueDate: string = '';
let isDueDateValid: boolean = true;
let parsedRecurrence: string = '';
let isRecurrenceValid: boolean = true;
let parsedDone: string = '';
let parsedDoneDate: string = '';
let isDoneDateValid: boolean = true;
let parsedCancelledDate: string = '';
let isCancelledDateValid: boolean = true;
let addGlobalFilterOnSave: boolean = false;
let withAccessKeys: boolean = true;
let formIsValid: boolean = true;
Expand Down Expand Up @@ -135,7 +152,7 @@
* @returns the parsed date string. Includes "invalid" if {@code typedDate} was invalid.
*/
function parseTypedDateForDisplay(
fieldName: 'created' | 'start' | 'scheduled' | 'due' | 'done',
fieldName: 'created' | 'start' | 'scheduled' | 'due' | 'done' | 'cancelled',
typedDate: string,
forwardDate: Date | undefined = undefined,
): string {
Expand All @@ -157,7 +174,7 @@
* @param typedDate - what the user has entered, such as '2023-01-23' or 'tomorrow'
* @returns the parsed date string. Includes "invalid" if {@code typedDate} was invalid.
*/
function parseTypedDateForDisplayUsingFutureDate(fieldName: 'start' | 'scheduled' | 'due' | 'done', typedDate: string): string {
function parseTypedDateForDisplayUsingFutureDate(fieldName: 'start' | 'scheduled' | 'due' | 'done' | 'created' | 'cancelled', typedDate: string): string {
return parseTypedDateForDisplay(
fieldName,
typedDate,
Expand All @@ -183,7 +200,7 @@
}
$: accesskey = (key: string) => withAccessKeys ? key : null;
$: formIsValid = isDueDateValid && isRecurrenceValid && isScheduledDateValid && isStartDateValid && isDescriptionValid;
$: formIsValid = isDueDateValid && isRecurrenceValid && isScheduledDateValid && isStartDateValid && isDescriptionValid && isCancelledDateValid && isCreatedDateValid && isDoneDateValid;
$: isDescriptionValid = editableTask.description.trim() !== '';
// NEW_TASK_FIELD_EDIT_REQUIRED
Expand All @@ -205,6 +222,24 @@
isDueDateValid = !parsedDueDate.includes('invalid');
}
$: {
editableTask.doneDate = doAutocomplete(editableTask.doneDate);
parsedDoneDate = parseTypedDateForDisplayUsingFutureDate('done', editableTask.doneDate);
isDoneDateValid = !parsedDoneDate.includes('invalid');
}
$: {
editableTask.createdDate = doAutocomplete(editableTask.createdDate);
parsedCreatedDate = parseTypedDateForDisplayUsingFutureDate('created', editableTask.createdDate);
isCreatedDateValid = !parsedCreatedDate.includes('invalid');
}
$: {
editableTask.cancelledDate = doAutocomplete(editableTask.cancelledDate);
parsedCancelledDate = parseTypedDateForDisplayUsingFutureDate('cancelled', editableTask.cancelledDate);
isCancelledDateValid = !parsedCancelledDate.includes('invalid');
}
$: {
isRecurrenceValid = true;
if (!editableTask.recurrenceRule) {
Expand All @@ -229,11 +264,6 @@
}
}
$: {
parsedCreated = parseTypedDateForDisplay('created', editableTask.createdDate);
parsedDone = parseTypedDateForDisplay('done', editableTask.doneDate);
}
onMount(() => {
const { provideAccessKeys } = getSettings();
withAccessKeys = provideAccessKeys;
Expand Down Expand Up @@ -268,6 +298,7 @@
scheduledDate: new TasksDate(task.scheduledDate).formatAsDate(),
dueDate: new TasksDate(task.dueDate).formatAsDate(),
doneDate: new TasksDate(task.doneDate).formatAsDate(),
cancelledDate: new TasksDate(task.cancelledDate).formatAsDate(),
forwardOnly: true,
};
setTimeout(() => {
Expand Down Expand Up @@ -311,11 +342,13 @@
}
const startDate = parseTypedDateForSaving(editableTask.startDate);
const scheduledDate = parseTypedDateForSaving(editableTask.scheduledDate);
const dueDate = parseTypedDateForSaving(editableTask.dueDate);
const cancelledDate = parseTypedDateForSaving(editableTask.cancelledDate);
const createdDate = parseTypedDateForSaving(editableTask.createdDate);
const doneDate = parseTypedDateForSaving(editableTask.doneDate);
let recurrence: Recurrence | null = null;
if (editableTask.recurrenceRule) {
recurrence = Recurrence.fromText({
Expand Down Expand Up @@ -357,11 +390,9 @@
startDate,
scheduledDate,
dueDate,
doneDate: window
.moment(editableTask.doneDate, 'YYYY-MM-DD')
.isValid()
? window.moment(editableTask.doneDate, 'YYYY-MM-DD')
: null,
doneDate,
createdDate,
cancelledDate,
});
onSubmit([updatedTask]);
Expand Down Expand Up @@ -527,22 +558,49 @@
disabled
/>
</div>
</div>

<div class="tasks-modal-section tasks-modal-dates">
<!-- --------------------------------------------------------------------------- -->
<!-- Created on -->
<!-- Created Date -->
<!-- --------------------------------------------------------------------------- -->
<div>
<span>Created on:</span>
<code>{@html parsedCreated}</code>
</div>
<label for="created">Created</label>
<input
bind:value={editableTask.createdDate}
id="created"
type="text"
class:tasks-modal-error={!isCreatedDateValid}
placeholder={datePlaceholder}
/>
<code>{createdDateSymbol} {@html parsedCreatedDate}</code>

<!-- --------------------------------------------------------------------------- -->
<!-- Done on -->
<!-- Done Date -->
<!-- --------------------------------------------------------------------------- -->
<div>
<span>Done on:</span>
<code>{@html parsedDone}</code>
</div>
<label for="done">Done</label>
<input
bind:value={editableTask.doneDate}
id="done"
type="text"
class:tasks-modal-error={!isDoneDateValid}
placeholder={datePlaceholder}
/>
<code>{doneDateSymbol} {@html parsedDoneDate}</code>

<!-- --------------------------------------------------------------------------- -->
<!-- Cancelled Date -->
<!-- --------------------------------------------------------------------------- -->
<label for="cancelled">Cancelled</label>
<input
bind:value={editableTask.cancelledDate}
id="cancelled"
type="text"
class:tasks-modal-error={!isCancelledDateValid}
placeholder={datePlaceholder}
/>
<code>{cancelledDateSymbol} {@html parsedCancelledDate}</code>
</div>

<div class="tasks-modal-section tasks-modal-buttons">
<button disabled={!formIsValid} type="submit" class="mod-cta">Apply
</button>
Expand Down
Loading

0 comments on commit 9c14800

Please sign in to comment.