dashboard: move charts to top of main content on workstreams and progress pages
workstreams: decouple filter form from display (Generators.input pattern); Status Distribution chart now renders before the filter bar and table. Dependencies section follows after. progress: Event Volume chart moved above the filter controls and table; no reactive changes needed (chart uses raw data, not filtered). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -46,32 +46,6 @@ withDocHelp(_liveEl, "/docs/live-data");
|
||||
injectTocTop("live-indicator", _liveEl);
|
||||
```
|
||||
|
||||
```js
|
||||
const authorOpts = ["(all)", ...new Set(data.map(e => e.author ?? "unknown"))].sort();
|
||||
const typeOpts = ["(all)", ...new Set(data.map(e => e.event_type))].sort();
|
||||
|
||||
const authorFilter = view(Inputs.select(authorOpts, {label: "Author"}));
|
||||
const typeFilter = view(Inputs.select(typeOpts, {label: "Event type"}));
|
||||
const sinceFilter = view(Inputs.date({label: "Since"}));
|
||||
```
|
||||
|
||||
```js
|
||||
const filtered = data.filter(e =>
|
||||
(authorFilter === "(all)" || (e.author ?? "unknown") === authorFilter) &&
|
||||
(typeFilter === "(all)" || e.event_type === typeFilter) &&
|
||||
(!sinceFilter || new Date(e.created_at) >= sinceFilter)
|
||||
);
|
||||
|
||||
display(html`<p><strong>${filtered.length}</strong> events shown (append-only, no deletions).</p>`);
|
||||
|
||||
display(Inputs.table(filtered.map(e => ({
|
||||
Time: new Date(e.created_at).toLocaleString(),
|
||||
Type: e.event_type,
|
||||
Author: e.author ?? "—",
|
||||
Summary: e.summary,
|
||||
})), {rows: 50}));
|
||||
```
|
||||
|
||||
## Event Volume (Last 30 Days)
|
||||
|
||||
```js
|
||||
@@ -105,6 +79,32 @@ display(byDay.length === 0
|
||||
);
|
||||
```
|
||||
|
||||
```js
|
||||
const authorOpts = ["(all)", ...new Set(data.map(e => e.author ?? "unknown"))].sort();
|
||||
const typeOpts = ["(all)", ...new Set(data.map(e => e.event_type))].sort();
|
||||
|
||||
const authorFilter = view(Inputs.select(authorOpts, {label: "Author"}));
|
||||
const typeFilter = view(Inputs.select(typeOpts, {label: "Event type"}));
|
||||
const sinceFilter = view(Inputs.date({label: "Since"}));
|
||||
```
|
||||
|
||||
```js
|
||||
const filtered = data.filter(e =>
|
||||
(authorFilter === "(all)" || (e.author ?? "unknown") === authorFilter) &&
|
||||
(typeFilter === "(all)" || e.event_type === typeFilter) &&
|
||||
(!sinceFilter || new Date(e.created_at) >= sinceFilter)
|
||||
);
|
||||
|
||||
display(html`<p><strong>${filtered.length}</strong> events shown (append-only, no deletions).</p>`);
|
||||
|
||||
display(Inputs.table(filtered.map(e => ({
|
||||
Time: new Date(e.created_at).toLocaleString(),
|
||||
Type: e.event_type,
|
||||
Author: e.author ?? "—",
|
||||
Summary: e.summary,
|
||||
})), {rows: 50}));
|
||||
```
|
||||
|
||||
<style>
|
||||
.live-indicator { font-size: 0.8rem; color: gray; position: relative; padding: 0.55rem 1.8rem 0.55rem 0.7rem; margin-bottom: 0.75rem; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user