Bug 1: "Parent task" field disappears once a parent is set, with no way to revert
frontend/src/components/TasksPanel/TasksPanel.tsx:183 gates the entire parent-task row behind:
{taskItem.parent == null && (
<div className={styles.parentRow}>
...
<select ... onChange={(event) => updateTask.mutate({ id: taskItem.id, data: { parent: ... } })}>
...
</select>
</div>
)}
Once a task has a parent, this block — label, <select>, everything — stops rendering entirely for that task's edit modal. There's no remaining UI to change the parent back to "No parent" or to a different parent; the only way out is editing the database directly.
Fix: the row (and its <select>) should always render for a task that isn't itself blocking on hasSubtasks (which already exists to prevent nesting a task that has its own children — see hasSubtasks/parentOptions a few lines above, TasksPanel.tsx:112-113). The taskItem.parent == null check should not hide the whole control; at most it affects which options make sense to offer.
Bug 2: child tasks render nested inside the parent's list item, not as independent (indented) rows
Currently, in PlayerItemList.tsx, the List's renderItem returns the parent's row and a <ul className={styles.childList}> of children's <Li>s together as one fragment (PlayerItemList.tsx:266-284):
renderItem={(item) => {
const children = getChildren?.(item);
return (
<>
{renderRow(item)}
{children?.length ? (
<ul className={styles.childList}>
{children.map((child, index) => (
<Li key={...} className={...}>{renderRow(child)}</Li>
))}
</ul>
) : null}
</>
);
}}
Since List.tsx wraps whatever renderItem returns inside a single outer <Li> per top-level item (List.tsx:91-106), the children's <ul>/<Li> end up nested inside the parent's own <li> — i.e. structurally (and visually, since the parent <Li> is a bordered/card-styled item) the children render inside the parent task's box, rather than as their own rows in the list.
Requested fix: child tasks should render as independent rows directly in the list — siblings of other top-level items, not descendants of the parent's <li> — just visually indented (e.g. via a left-margin/padding modifier class) to show the parent/child relationship.
Useful building block already exists: useTasksPanel.tsx's visibleTasks (useTasksPanel.tsx:179-182) already flattens groupedTasks into [parent, ...children, parent, ...children, ...] in display order. PlayerItemList currently discards this ordering and deliberately filters children out of topLevelDisplayItems (PlayerItemList.tsx:140-145, via childIds) so they only render nested under the parent. Switching to rendering the flat, ordered list directly — with an "is this a child, indent it" check per item instead of a parent-owns-nested-children structure — would fix this without needing a new data shape.
Scope
frontend/src/components/TasksPanel/TasksPanel.tsx (parent-field visibility)
frontend/src/components/PlayerItemList/PlayerItemList.tsx and PlayerItemList.module.scss (list rendering structure — note this component is shared by Tasks/Skills/Projects/Categories/Activities panels, so check whether getChildren is used by any panel besides Tasks before changing its contract)
frontend/src/components/TasksPanel/useTasksPanel.tsx (getChildren, visibleTasks, topLevelTasks — may no longer all be needed in their current form once rendering flattens)
Bug 1: "Parent task" field disappears once a parent is set, with no way to revert
frontend/src/components/TasksPanel/TasksPanel.tsx:183gates the entire parent-task row behind:Once a task has a parent, this block — label,
<select>, everything — stops rendering entirely for that task's edit modal. There's no remaining UI to change the parent back to "No parent" or to a different parent; the only way out is editing the database directly.Fix: the row (and its
<select>) should always render for a task that isn't itself blocking onhasSubtasks(which already exists to prevent nesting a task that has its own children — seehasSubtasks/parentOptionsa few lines above,TasksPanel.tsx:112-113). ThetaskItem.parent == nullcheck should not hide the whole control; at most it affects which options make sense to offer.Bug 2: child tasks render nested inside the parent's list item, not as independent (indented) rows
Currently, in
PlayerItemList.tsx, theList'srenderItemreturns the parent's row and a<ul className={styles.childList}>of children's<Li>s together as one fragment (PlayerItemList.tsx:266-284):Since
List.tsxwraps whateverrenderItemreturns inside a single outer<Li>per top-level item (List.tsx:91-106), the children's<ul>/<Li>end up nested inside the parent's own<li>— i.e. structurally (and visually, since the parent<Li>is a bordered/card-styled item) the children render inside the parent task's box, rather than as their own rows in the list.Requested fix: child tasks should render as independent rows directly in the list — siblings of other top-level items, not descendants of the parent's
<li>— just visually indented (e.g. via a left-margin/padding modifier class) to show the parent/child relationship.Useful building block already exists:
useTasksPanel.tsx'svisibleTasks(useTasksPanel.tsx:179-182) already flattensgroupedTasksinto[parent, ...children, parent, ...children, ...]in display order.PlayerItemListcurrently discards this ordering and deliberately filters children out oftopLevelDisplayItems(PlayerItemList.tsx:140-145, viachildIds) so they only render nested under the parent. Switching to rendering the flat, ordered list directly — with an "is this a child, indent it" check per item instead of a parent-owns-nested-children structure — would fix this without needing a new data shape.Scope
frontend/src/components/TasksPanel/TasksPanel.tsx(parent-field visibility)frontend/src/components/PlayerItemList/PlayerItemList.tsxandPlayerItemList.module.scss(list rendering structure — note this component is shared by Tasks/Skills/Projects/Categories/Activities panels, so check whethergetChildrenis used by any panel besides Tasks before changing its contract)frontend/src/components/TasksPanel/useTasksPanel.tsx(getChildren,visibleTasks,topLevelTasks— may no longer all be needed in their current form once rendering flattens)