fix(tasktree): separate outline and hierarchy columns

This commit is contained in:
root
2026-07-21 10:43:19 +02:00
parent 0c978720ac
commit fe5796a67a
@@ -449,6 +449,7 @@ function syncSelectedTaskFromRoute() {
<div v-else class="tasktree-labels-canvas tasktree-detail-labels">
<section v-for="root in rootTasks" :key="root.id" class="tasktree-task-group">
<div class="tasktree-label" :data-task-id="root.id" :data-dated="Boolean(root.startAt || root.dueAt)">
<span class="tasktree-outline-ref">{{ root.outlineRef }}</span>
<button
v-if="childrenByParent.has(root.id)"
class="tasktree-disclosure"
@@ -463,7 +464,6 @@ function syncSelectedTaskFromRoute() {
</button>
<span v-else class="tasktree-disclosure-spacer" aria-hidden="true" />
<div class="tasktree-title" role="button" tabindex="0" @click="selectTaskFromTitle($event, root)" @keydown.enter="selectTask(root)">
<span class="tasktree-outline-ref">{{ root.outlineRef }}</span>
<span class="tasktree-status" :data-status="root.status" />
<MessageMarkdown class="tasktree-title-markdown" :source="displayTaskTitle(root)" />
</div>
@@ -477,6 +477,7 @@ function syncSelectedTaskFromRoute() {
@wheel="handleChildWheel($event, root.id, 'labels')"
>
<div v-for="task in visibleDescendants(root.id)" :key="task.id" class="tasktree-label" :class="task.kind" :data-task-id="task.id" :data-dated="Boolean(task.startAt || task.dueAt)">
<span class="tasktree-outline-ref">{{ task.outlineRef }}</span>
<button
v-if="childrenByParent.has(task.id)"
class="tasktree-disclosure"
@@ -491,7 +492,6 @@ function syncSelectedTaskFromRoute() {
</button>
<span v-else class="tasktree-disclosure-spacer" aria-hidden="true" />
<div class="tasktree-title" role="button" tabindex="0" @click="selectTaskFromTitle($event, task)" @keydown.enter="selectTask(task)">
<span class="tasktree-outline-ref">{{ task.outlineRef }}</span>
<span class="tasktree-status" :data-status="task.status" />
<MessageMarkdown class="tasktree-title-markdown" :source="displayTaskTitle(task)" />
</div>
@@ -620,9 +620,13 @@ function syncSelectedTaskFromRoute() {
.tasktree-label { height: 46px; border-bottom: 1px solid #edf0ef; background: #fff; padding: 0 8px; display: flex; align-items: center; color: var(--text-primary); min-width: 0; }
.tasktree-task-group > .tasktree-label { background: #f7f9f8; font-weight: 600; }
.tasktree-label:hover { background: #f2f7f5; }
.tasktree-outline-ref { box-sizing: border-box; flex: 0 0 7ch; padding-right: 8px; border-right: 1px solid #dce4e3; color: #52676d; font-family: var(--console-font-mono); font-size: 11px; font-weight: 700; line-height: 18px; text-align: right; font-variant-numeric: tabular-nums; }
.tasktree-label.subtask { padding-left: 30px; color: var(--text-secondary); }
.tasktree-label.subsubtask { padding-left: 54px; color: var(--text-secondary); }
.tasktree-outline-ref { flex: 0 0 7ch; padding-right: 6px; color: #64767b; font-family: var(--console-font-mono); font-size: 10px; font-weight: 700; line-height: 18px; text-align: right; font-variant-numeric: tabular-nums; }
.tasktree-label.subtask,
.tasktree-label.subsubtask { color: var(--text-secondary); }
.tasktree-label.subtask .tasktree-disclosure,
.tasktree-label.subtask .tasktree-disclosure-spacer { margin-left: 16px; }
.tasktree-label.subsubtask .tasktree-disclosure,
.tasktree-label.subsubtask .tasktree-disclosure-spacer { margin-left: 32px; }
.tasktree-group-label { height: 68px; padding: 9px 14px; display: grid; align-content: center; gap: 5px; cursor: pointer; }
.tasktree-group-label > span { color: var(--text-secondary); font-family: var(--console-font-mono); font-size: 10px; }
.tasktree-group-title { display: flex; min-width: 0; align-items: center; gap: 8px; color: var(--text-primary); font-size: 15px; font-weight: 700; }
@@ -631,13 +635,13 @@ function syncSelectedTaskFromRoute() {
.tasktree-disclosure-spacer { width: 24px; height: 28px; flex: 0 0 24px; }
.tasktree-disclosure { display: grid; place-items: center; padding: 0; border: 0; background: transparent; color: var(--text-secondary); cursor: pointer; }
.tasktree-disclosure:hover { color: var(--text-primary); background: var(--surface-secondary); }
.tasktree-title { display: flex; flex: 1 1 auto; align-items: center; gap: 7px; min-width: 0; height: 100%; padding: 0 4px; color: inherit; text-align: left; cursor: pointer; }
.tasktree-title { display: flex; flex: 1 1 auto; align-items: center; gap: 7px; min-width: 0; height: 100%; padding: 0 4px 0 2px; color: inherit; text-align: left; cursor: pointer; }
.tasktree-title:focus-visible { outline: 2px solid #2376c9; outline-offset: -2px; }
.tasktree-title-markdown { min-width: 0; overflow: hidden; }
.tasktree-title-markdown :deep(p) { min-width: 0; margin: 0; overflow: hidden; font: inherit; text-overflow: ellipsis; white-space: nowrap; }
.tasktree-title-markdown :deep(a) { color: #1766ad; text-decoration: underline; text-underline-offset: 2px; }
.tasktree-title-markdown :deep(code) { padding: 1px 3px; border: 1px solid var(--border-subtle); background: var(--surface-secondary); color: inherit; font-size: 0.9em; }
.tasktree-status { width: 7px; height: 7px; border-radius: 50%; background: #83909c; flex: 0 0 auto; }
.tasktree-status { width: 6px; height: 6px; border-radius: 50%; background: #83909c; flex: 0 0 auto; }
.tasktree-status[data-status="completed"] { background: #1f9d67; }
.tasktree-status[data-status="in_progress"] { background: #2376c9; }
.tasktree-status[data-status="blocked"] { background: #c73e48; }