Aller au contenu principal

Subtask Editing in Focus Page: Problem and Solution

The Problem

The user was unable to edit subtasks within the "Available Tasks" list on the Focus page. While top-level tasks could be edited without issue, clicking the "Edit" button on a subtask did not open the task editor modal as expected.

The root cause was in how the TodoItemComponent handled the editing of tasks versus subtasks.

  1. Top-Level Task Editing: When the edit button on a top-level task was clicked, the component emitted an (edit) event. The parent FocusComponent would catch this event and call its openTaskEditorById() method, correctly opening the main editor modal.

  2. Subtask Editing: The component was designed to handle subtask editing differently. When the edit button on a subtask was clicked, the openEditor() method would not emit an event. Instead, it was supposed to open a separate TaskEditorComponent that was local to that specific TodoItemComponent instance.

This approach had a flaw: the local editor for subtasks was not being triggered correctly, leaving the user unable to edit them.

The Solution

The solution was to refactor the editing logic to be consistent for both tasks and subtasks, centralizing the responsibility for opening the editor in the main FocusComponent.

Here are the key changes that were implemented:

1. Created a New editSubtask Event

A new event emitter, @Output() editSubtask = new EventEmitter<string>();, was added to the TodoItemComponent. This event is specifically designed to carry the unique id of a subtask that needs to be edited.

2. Modified the openEditor() Method

The openEditor() method in todo-item.component.ts was updated. Now, instead of trying to open a local editor for subtasks, it emits the new editSubtask event, passing the subtask's ID as the payload.

// Before
if (this.isSubtask) {
// This logic was failing silently
this.editingTodo = this.todo;
this.taskEditor.open();
} else {
this.edit.emit(true);
}

// After
if (this.isSubtask) {
// Now emits a dedicated event with the subtask's ID
this.editSubtask.emit(this.todo.id);
} else {
this.edit.emit(true);
}

3. Bubbled the Event Up the Component Tree

Since subtasks can be nested, the editSubtask event needed to be "bubbled up" from the subtask's component to its parent, and so on, until it reached the FocusComponent.

  • A new onSubtaskEdit() method was added to TodoItemComponent to catch the event from a child and re-emit it from the parent.
  • The component's template was updated to connect this new method to the (editSubtask) output of the recursively rendered <app-todo-item>.

4. Centralized Handling in FocusComponent

Finally, the FocusComponent was updated to listen for the editSubtask event. It now uses the same trusted openTaskEditorById() method to handle both top-level tasks and subtasks.

<!-- In focus.component.ts template -->
<app-todo-item
...
(edit)="openTaskEditorById(task.id)"
(editSubtask)="openTaskEditorById($event)">
</app-todo-item>

Because the $event from editSubtask now contains the subtask's id, the existing editor logic works perfectly.

Why This Solution Works

  • Consistency: It eliminates the inconsistent and buggy logic for subtask editing. Both tasks and subtasks now follow the same, predictable event-driven pattern.
  • Centralization: It makes the FocusComponent the single source of truth for opening the task editor, simplifying the overall architecture and making it easier to maintain.
  • Robustness: By using a dedicated @Output() event to communicate, the solution is more robust and less prone to issues related to component lifecycle or change detection that may have been affecting the previous implementation.