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:
@@ -86,8 +86,9 @@ const filtered = data.filter(t =>
|
||||
# Technical Debt
|
||||
|
||||
```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} from "./components/entity-modal.js";
|
||||
|
||||
// ── KPI sidebar ───────────────────────────────────────────────────────────────
|
||||
const _open = data.filter(t => t.status === "open" || t.status === "in_progress");
|
||||
@@ -191,16 +192,18 @@ if (_urgent.length === 0) {
|
||||
display(html`<p class="dim">No critical or high severity open items in current filter. ✓</p>`);
|
||||
} else {
|
||||
display(html`<div class="td-list">${_urgent.map(t => html`
|
||||
<div class="td-item td-sev-${t.severity}">
|
||||
<div class="td-item td-sev-${t.severity} entity-row"
|
||||
onclick=${() => openEntityModal(t, "td")}
|
||||
title="Click to view full details">
|
||||
<div class="td-item-header">
|
||||
${t.td_id ? html`<span class="td-ref">${t.td_id}</span>` : ""}
|
||||
<span class="td-sev-badge td-sev-${t.severity}">${t.severity}</span>
|
||||
<span class="td-type-badge">${t.debt_type}</span>
|
||||
<span class="td-domain">${t.domain}</span>
|
||||
${t.workstream_title ? html`<span class="td-ws">${t.workstream_title}</span>` : ""}
|
||||
${t.workstream_title ? html`<span class="td-ws" title=${t.workstream_title}>${t.workstream_title}</span>` : ""}
|
||||
</div>
|
||||
<div class="td-title">${t.title}</div>
|
||||
${t.description ? html`<div class="td-desc">${t.description.slice(0, 240)}${t.description.length > 240 ? "…" : ""}</div>` : ""}
|
||||
${t.description ? html`<div class="td-desc">${t.description.slice(0, 220)}${t.description.length > 220 ? " …" : ""}</div>` : ""}
|
||||
${t.location ? html`<div class="td-location"><code>${t.location}</code></div>` : ""}
|
||||
</div>
|
||||
`)}</div>`);
|
||||
@@ -214,17 +217,19 @@ display(_filtersForm);
|
||||
display(html`<p><strong>${filtered.length}</strong> items shown.</p>`);
|
||||
|
||||
display(html`<div class="td-list">${filtered.map(t => html`
|
||||
<div class="td-item td-status-${t.status}">
|
||||
<div class="td-item td-status-${t.status} entity-row"
|
||||
onclick=${() => openEntityModal(t, "td")}
|
||||
title="Click to view full details">
|
||||
<div class="td-item-header">
|
||||
${t.td_id ? html`<span class="td-ref">${t.td_id}</span>` : ""}
|
||||
<span class="td-sev-badge td-sev-${t.severity}">${t.severity}</span>
|
||||
<span class="td-type-badge">${t.debt_type}</span>
|
||||
<span class="td-badge td-badge-${t.status}">${t.status.replace("_", " ")}</span>
|
||||
<span class="td-domain">${t.domain}</span>
|
||||
${t.workstream_title ? html`<span class="td-ws">${t.workstream_title}</span>` : ""}
|
||||
${t.workstream_title ? html`<span class="td-ws" title=${t.workstream_title}>${t.workstream_title}</span>` : ""}
|
||||
</div>
|
||||
<div class="td-title">${t.title}</div>
|
||||
${t.description ? html`<div class="td-desc">${t.description.slice(0, 240)}${t.description.length > 240 ? "…" : ""}</div>` : ""}
|
||||
${t.description ? html`<div class="td-desc">${t.description.slice(0, 220)}${t.description.length > 220 ? " …" : ""}</div>` : ""}
|
||||
${t.location ? html`<div class="td-location"><code>${t.location}</code></div>` : ""}
|
||||
</div>
|
||||
`)}
|
||||
@@ -254,6 +259,8 @@ display(html`<div class="td-list">${filtered.map(t => html`
|
||||
/* ── TD list ──────────────────────────────────────────────────────────────── */
|
||||
.td-list { display: flex; flex-direction: column; gap: 0.5rem; }
|
||||
.td-item { border-left: 3px solid #94a3b8; border-radius: 0 6px 6px 0; background: var(--theme-background-alt); padding: 0.65rem 0.9rem; }
|
||||
.td-item.entity-row { cursor: pointer; transition: filter 0.1s; }
|
||||
.td-item.entity-row:hover { filter: brightness(0.97); }
|
||||
.td-sev-critical { border-left-color: #dc2626; }
|
||||
.td-sev-high { border-left-color: #ea580c; }
|
||||
.td-sev-medium { border-left-color: #3b82f6; }
|
||||
|
||||
Reference in New Issue
Block a user