generated from coulomb/repo-seed
feat(dashboard): add entity detail modal and fixed-layout tables
Replace Inputs.table() with buildEntityTable() across workstreams and tasks pages. Add click-to-detail modal (openEntityModal) on all entity list views: workstreams, tasks, extension points, and technical debt. - New component: src/components/entity-modal.js - openEntityModal(entity, type) — full-detail overlay (Esc/click-outside to close) - buildEntityTable(rows, cols, onRowClick) — table-layout:fixed, overflow-safe wrapper - CSS injected lazily; no separate stylesheet required - Tables: table-layout:fixed keeps content within the content column; title col 32%, workstream col 14%, all cells ellipsis + title tooltip - Cards (EP, TD): onclick → modal; workstream name span gets title tooltip - Blocked task cards also wired to modal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -83,8 +83,9 @@ const filtered = data.filter(t =>
|
||||
# Tasks
|
||||
|
||||
```js
|
||||
import {injectTocTop} from "./components/toc-sidebar.js";
|
||||
import {withDocHelp} from "./components/doc-overlay.js";
|
||||
import {injectTocTop} from "./components/toc-sidebar.js";
|
||||
import {withDocHelp} from "./components/doc-overlay.js";
|
||||
import {openEntityModal, buildEntityTable} from "./components/entity-modal.js";
|
||||
|
||||
// ── KPI sidebar card ─────────────────────────────────────────────────────────
|
||||
const _open = data.filter(t => ["todo", "in_progress", "blocked"].includes(t.status));
|
||||
@@ -179,7 +180,7 @@ if (_blockedInFilter.length === 0) {
|
||||
display(html`<p class="dim">No blocked tasks in current filter. ✓</p>`);
|
||||
} else {
|
||||
display(html`<div class="task-blocked-list">${_blockedInFilter.map(t => html`
|
||||
<div class="task-blocked-item">
|
||||
<div class="task-blocked-item entity-row" onclick=${() => openEntityModal(t, "task")}>
|
||||
<div class="task-item-header">
|
||||
<span class="task-badge task-priority-${t.priority}">${t.priority}</span>
|
||||
<span class="task-context">${t.domain}</span>
|
||||
@@ -209,15 +210,19 @@ const sorted = [...filtered].sort((a, b) => {
|
||||
return (PRIORITY_ORDER[a.priority] ?? 9) - (PRIORITY_ORDER[b.priority] ?? 9);
|
||||
});
|
||||
|
||||
display(Inputs.table(sorted.map(t => ({
|
||||
Status: t.status,
|
||||
Priority: t.priority,
|
||||
Title: t.title,
|
||||
Domain: t.domain,
|
||||
Workstream: t.workstream_title,
|
||||
Assignee: t.assignee ?? "—",
|
||||
Due: t.due_date ?? "—",
|
||||
})), {rows: 25}));
|
||||
display(buildEntityTable(
|
||||
sorted,
|
||||
[
|
||||
{label: "Status", key: "status"},
|
||||
{label: "Priority", key: "priority"},
|
||||
{label: "Title", key: "title", cls: "et-title-col et-title-cell"},
|
||||
{label: "Domain", key: "domain"},
|
||||
{label: "Workstream", key: "workstream_title", cls: "et-ws-col et-ws-cell"},
|
||||
{label: "Assignee", render: t => t.assignee ?? "—"},
|
||||
{label: "Due", render: t => t.due_date ?? "—"},
|
||||
],
|
||||
t => openEntityModal(t, "task"),
|
||||
));
|
||||
```
|
||||
|
||||
<style>
|
||||
|
||||
Reference in New Issue
Block a user