|
3 | 3 |
|
4 | 4 | let { categories, defaultCategory, tasks, task, onSave, onClose } = $props(); |
5 | 5 |
|
| 6 | + const API_BASE = '/api'; |
| 7 | +
|
6 | 8 | let title = $state(task?.title || ''); |
7 | 9 | let description = $state(task?.description || ''); |
8 | 10 | let categoryId = $state(task?.category_id || defaultCategory?.id || 1); |
9 | 11 | let parentId = $state(task?.parent_id || null); |
10 | 12 | let titleInput; |
| 13 | + let allCategoryTasks = $state(tasks); // Tasks for the currently selected category in modal |
11 | 14 |
|
12 | 15 | // If task is a subtask, it can't change category |
13 | 16 | let isSubtask = $derived(task ? !!task.parent_id : false); |
14 | 17 |
|
15 | | - // Update category when parent changes (for new tasks with parent) |
| 18 | + // Track last known values to detect user-initiated changes |
| 19 | + let lastParentId = $state(null); |
| 20 | + let lastCategoryId = $state(null); |
| 21 | +
|
| 22 | + // Initialize tracking variables on first run |
| 23 | + $effect(() => { |
| 24 | + if (lastCategoryId === null) { |
| 25 | + lastCategoryId = categoryId; |
| 26 | + lastParentId = parentId; |
| 27 | + } |
| 28 | + }); |
| 29 | +
|
| 30 | + // Handle parent selection change |
| 31 | + $effect(() => { |
| 32 | + // User changed parent selection |
| 33 | + if (parentId !== lastParentId) { |
| 34 | + const previousParent = lastParentId; |
| 35 | + lastParentId = parentId; |
| 36 | +
|
| 37 | + if (parentId) { |
| 38 | + // Parent was selected - update category to match |
| 39 | + const parent = allCategoryTasks.find(t => t.id === parentId); |
| 40 | + if (parent && parent.category_id !== categoryId) { |
| 41 | + categoryId = parent.category_id; |
| 42 | + lastCategoryId = categoryId; |
| 43 | + } |
| 44 | + } |
| 45 | + // Parent was deselected - keep current category |
| 46 | + } |
| 47 | + }); |
| 48 | +
|
| 49 | + // Handle category change |
| 50 | + $effect(() => { |
| 51 | + // User changed category manually |
| 52 | + if (categoryId !== lastCategoryId && lastCategoryId !== null) { |
| 53 | + lastCategoryId = categoryId; |
| 54 | +
|
| 55 | + // If parent doesn't belong to new category, reset it |
| 56 | + if (parentId && !isSubtask) { |
| 57 | + const parent = allCategoryTasks.find(t => t.id === parentId); |
| 58 | + if (!parent || parent.category_id !== categoryId) { |
| 59 | + parentId = null; |
| 60 | + lastParentId = null; |
| 61 | + } |
| 62 | + } |
| 63 | + } |
| 64 | + }); |
| 65 | +
|
| 66 | + // Fetch tasks for the selected category when it changes |
16 | 67 | $effect(() => { |
17 | | - if (parentId) { |
18 | | - const parent = tasks.find(t => t.id === parentId); |
19 | | - if (parent) { |
20 | | - categoryId = parent.category_id; |
| 68 | + async function fetchCategoryTasks() { |
| 69 | + if (!isSubtask && categoryId) { |
| 70 | + const res = await fetch(`${API_BASE}/tasks?category_id=${categoryId}`); |
| 71 | + allCategoryTasks = await res.json(); |
21 | 72 | } |
22 | 73 | } |
| 74 | + fetchCategoryTasks(); |
23 | 75 | }); |
24 | 76 |
|
25 | 77 | // Helper to check if a task has subtasks |
26 | 78 | function hasSubtasks(taskId) { |
27 | | - return tasks.some(t => t.parent_id === taskId); |
| 79 | + return allCategoryTasks.some(t => t.parent_id === taskId); |
28 | 80 | } |
29 | 81 |
|
30 | 82 | // Check if current task being edited has subtasks (can't become a subtask itself) |
31 | 83 | let taskHasSubtasks = $derived(task ? hasSubtasks(task.id) : false); |
32 | 84 |
|
33 | 85 | // Get available parent tasks (top-level tasks only, excluding the task being edited) |
34 | 86 | let availableParents = $derived( |
35 | | - tasks.filter(t => |
| 87 | + allCategoryTasks.filter(t => |
36 | 88 | !t.parent_id && (!task || t.id !== task.id) && t.category_id === categoryId |
37 | 89 | ) |
38 | 90 | ); |
|
125 | 177 | id="category" |
126 | 178 | class="form-select bg-dark text-light border-secondary" |
127 | 179 | bind:value={categoryId} |
128 | | - disabled={isSubtask || !!parentId} |
| 180 | + disabled={isSubtask} |
129 | 181 | > |
130 | 182 | {#each categories as category} |
131 | 183 | <option value={category.id}>{category.name}</option> |
132 | 184 | {/each} |
133 | 185 | </select> |
134 | | - {#if isSubtask || parentId} |
| 186 | + {#if isSubtask} |
135 | 187 | <small class="text-muted d-block mt-1">Subtasks inherit their parent's category.</small> |
136 | 188 | {/if} |
137 | 189 | </div> |
|
0 commit comments