@deskwork/studio 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/pages/dashboard/affordances.d.ts +19 -24
- package/dist/pages/dashboard/affordances.d.ts.map +1 -1
- package/dist/pages/dashboard/affordances.js +37 -36
- package/dist/pages/dashboard/affordances.js.map +1 -1
- package/dist/pages/dashboard/affordances.ts +41 -40
- package/dist/pages/dashboard/header.d.ts +9 -3
- package/dist/pages/dashboard/header.d.ts.map +1 -1
- package/dist/pages/dashboard/header.js +9 -29
- package/dist/pages/dashboard/header.js.map +1 -1
- package/dist/pages/dashboard/header.ts +9 -31
- package/dist/pages/dashboard/section.d.ts +42 -15
- package/dist/pages/dashboard/section.d.ts.map +1 -1
- package/dist/pages/dashboard/section.js +118 -69
- package/dist/pages/dashboard/section.js.map +1 -1
- package/dist/pages/dashboard/section.ts +120 -74
- package/dist/pages/dashboard.d.ts +23 -17
- package/dist/pages/dashboard.d.ts.map +1 -1
- package/dist/pages/dashboard.js +105 -25
- package/dist/pages/dashboard.js.map +1 -1
- package/dist/pages/dashboard.ts +107 -26
- package/dist/pages/help.js +1 -1
- package/dist/pages/help.ts +1 -1
- package/dist/pages/index.d.ts +8 -6
- package/dist/pages/index.d.ts.map +1 -1
- package/dist/pages/index.js +16 -14
- package/dist/pages/index.js.map +1 -1
- package/dist/pages/index.ts +16 -14
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +11 -0
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
|
@@ -6,37 +6,32 @@
|
|
|
6
6
|
* carry a `data-copy` payload that the existing studio client copies
|
|
7
7
|
* to the clipboard. No new backend handlers are wired here; the
|
|
8
8
|
* universal-verb skills are the canonical action path.
|
|
9
|
+
*
|
|
10
|
+
* Per DESKWORK-STATE-MACHINE.md (v5):
|
|
11
|
+
* - Verbs are stage-gated, not state-gated. The iterate button shows
|
|
12
|
+
* on stages-that-permit-edits (Ideas/Planned/Outlining/Drafting),
|
|
13
|
+
* not on Final (locked) or Published (immutable).
|
|
14
|
+
* - Revisions (the iteration counter) are bookkeeping. They do not
|
|
15
|
+
* surface in routine UI; the operator only sees them via revision
|
|
16
|
+
* history / revert flows. The previous "iteration: N" per-row
|
|
17
|
+
* display has been removed.
|
|
9
18
|
*/
|
|
10
19
|
import { type RawHtml } from '../html.ts';
|
|
11
|
-
import type { Entry
|
|
12
|
-
/**
|
|
13
|
-
* Render the reviewState badge. When the entry has no reviewState
|
|
14
|
-
* (most pre-review stages), render an em-dash placeholder so the row
|
|
15
|
-
* stays grid-aligned with sibling rows that DO carry a badge.
|
|
16
|
-
*/
|
|
17
|
-
export declare function renderReviewStateBadge(state: ReviewState | undefined): RawHtml;
|
|
18
|
-
/**
|
|
19
|
-
* Iteration count for the entry's current stage. The sidecar's
|
|
20
|
-
* `iterationByStage` records every stage the entry has touched; this
|
|
21
|
-
* surfaces the count for the stage the entry is currently in. Defaults
|
|
22
|
-
* to 0 when the bucket is missing (a brand-new entry on its first tick
|
|
23
|
-
* before any iterate has fired).
|
|
24
|
-
*/
|
|
25
|
-
export declare function iterationForCurrentStage(entry: Entry): number;
|
|
20
|
+
import type { Entry } from '@deskwork/core/schema/entry';
|
|
26
21
|
/**
|
|
27
22
|
* Build the per-row action strip. Affordances vary by stage:
|
|
28
23
|
*
|
|
29
|
-
* -
|
|
30
|
-
*
|
|
31
|
-
* copy-CLI button
|
|
32
|
-
*
|
|
33
|
-
*
|
|
24
|
+
* - Stages-that-permit-edits (Ideas / Planned / Outlining / Drafting):
|
|
25
|
+
* "open →" link, "iterate →" copy-CLI button (always; no state gate),
|
|
26
|
+
* "approve →" copy-CLI button, "cancel ⊘" copy-CLI button.
|
|
27
|
+
* - Final: "open →", "approve →" (graduates to Published; assigns a
|
|
28
|
+
* version per the operator's scheme), "cancel ⊘". NO iterate
|
|
29
|
+
* (Final locks content per the spec).
|
|
30
|
+
* - Published: "view →" (read-only review surface). Future enhancement:
|
|
31
|
+
* surface a "revise" affordance that inducts back to Drafting.
|
|
34
32
|
* - Blocked / Cancelled: "induct →" copy-CLI to bring the entry back.
|
|
35
33
|
*
|
|
36
|
-
* All non-terminal stages also get a `scrapbook ↗` link (#157)
|
|
37
|
-
* scrapbook viewer is the primary surface for entry-attached research
|
|
38
|
-
* notes / images / config / drafts and was previously unreachable
|
|
39
|
-
* from the dashboard.
|
|
34
|
+
* All non-terminal stages also get a `scrapbook ↗` link (#157).
|
|
40
35
|
*
|
|
41
36
|
* Each button's behavior is parked behind a `data-copy` attribute so
|
|
42
37
|
* the existing studio client (editorial-studio-client.ts) handles
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"affordances.d.ts","sourceRoot":"","sources":["../../../src/pages/dashboard/affordances.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"affordances.d.ts","sourceRoot":"","sources":["../../../src/pages/dashboard/affordances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,KAAK,EAAE,KAAK,EAAS,MAAM,6BAA6B,CAAC;AAEhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAkE3E"}
|
|
@@ -6,49 +6,32 @@
|
|
|
6
6
|
* carry a `data-copy` payload that the existing studio client copies
|
|
7
7
|
* to the clipboard. No new backend handlers are wired here; the
|
|
8
8
|
* universal-verb skills are the canonical action path.
|
|
9
|
+
*
|
|
10
|
+
* Per DESKWORK-STATE-MACHINE.md (v5):
|
|
11
|
+
* - Verbs are stage-gated, not state-gated. The iterate button shows
|
|
12
|
+
* on stages-that-permit-edits (Ideas/Planned/Outlining/Drafting),
|
|
13
|
+
* not on Final (locked) or Published (immutable).
|
|
14
|
+
* - Revisions (the iteration counter) are bookkeeping. They do not
|
|
15
|
+
* surface in routine UI; the operator only sees them via revision
|
|
16
|
+
* history / revert flows. The previous "iteration: N" per-row
|
|
17
|
+
* display has been removed.
|
|
9
18
|
*/
|
|
10
19
|
import { html, unsafe } from "../html.js";
|
|
11
20
|
import { scrapbookViewerUrl } from "../../components/scrapbook-item.js";
|
|
12
|
-
const REVIEW_STATE_LABEL = {
|
|
13
|
-
'in-review': 'in review',
|
|
14
|
-
iterating: 'iterating',
|
|
15
|
-
approved: 'approved',
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Render the reviewState badge. When the entry has no reviewState
|
|
19
|
-
* (most pre-review stages), render an em-dash placeholder so the row
|
|
20
|
-
* stays grid-aligned with sibling rows that DO carry a badge.
|
|
21
|
-
*/
|
|
22
|
-
export function renderReviewStateBadge(state) {
|
|
23
|
-
if (state === undefined) {
|
|
24
|
-
return unsafe('<span class="er-stamp er-stamp-none" data-review-state="none">—</span>');
|
|
25
|
-
}
|
|
26
|
-
return unsafe(html `<span class="er-stamp er-stamp-${state}" data-review-state="${state}">${REVIEW_STATE_LABEL[state]}</span>`);
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Iteration count for the entry's current stage. The sidecar's
|
|
30
|
-
* `iterationByStage` records every stage the entry has touched; this
|
|
31
|
-
* surfaces the count for the stage the entry is currently in. Defaults
|
|
32
|
-
* to 0 when the bucket is missing (a brand-new entry on its first tick
|
|
33
|
-
* before any iterate has fired).
|
|
34
|
-
*/
|
|
35
|
-
export function iterationForCurrentStage(entry) {
|
|
36
|
-
return entry.iterationByStage[entry.currentStage] ?? 0;
|
|
37
|
-
}
|
|
38
21
|
/**
|
|
39
22
|
* Build the per-row action strip. Affordances vary by stage:
|
|
40
23
|
*
|
|
41
|
-
* -
|
|
42
|
-
*
|
|
43
|
-
* copy-CLI button
|
|
44
|
-
*
|
|
45
|
-
*
|
|
24
|
+
* - Stages-that-permit-edits (Ideas / Planned / Outlining / Drafting):
|
|
25
|
+
* "open →" link, "iterate →" copy-CLI button (always; no state gate),
|
|
26
|
+
* "approve →" copy-CLI button, "cancel ⊘" copy-CLI button.
|
|
27
|
+
* - Final: "open →", "approve →" (graduates to Published; assigns a
|
|
28
|
+
* version per the operator's scheme), "cancel ⊘". NO iterate
|
|
29
|
+
* (Final locks content per the spec).
|
|
30
|
+
* - Published: "view →" (read-only review surface). Future enhancement:
|
|
31
|
+
* surface a "revise" affordance that inducts back to Drafting.
|
|
46
32
|
* - Blocked / Cancelled: "induct →" copy-CLI to bring the entry back.
|
|
47
33
|
*
|
|
48
|
-
* All non-terminal stages also get a `scrapbook ↗` link (#157)
|
|
49
|
-
* scrapbook viewer is the primary surface for entry-attached research
|
|
50
|
-
* notes / images / config / drafts and was previously unreachable
|
|
51
|
-
* from the dashboard.
|
|
34
|
+
* All non-terminal stages also get a `scrapbook ↗` link (#157).
|
|
52
35
|
*
|
|
53
36
|
* Each button's behavior is parked behind a `data-copy` attribute so
|
|
54
37
|
* the existing studio client (editorial-studio-client.ts) handles
|
|
@@ -78,7 +61,13 @@ export function renderRowActions(entry, defaultSite) {
|
|
|
78
61
|
if (isLinearActiveStage(stage)) {
|
|
79
62
|
buttons.push(html `<a class="er-btn er-btn-small" href="${reviewLink}"
|
|
80
63
|
title="open the review surface for ${entry.slug}">open →</a>`);
|
|
81
|
-
|
|
64
|
+
// Iterate — stage-gated per DESKWORK-STATE-MACHINE.md Commandment II:
|
|
65
|
+
// verbs are stage-gated, never state-gated. Iterate runs on stages
|
|
66
|
+
// that permit edits (Ideas / Planned / Outlining / Drafting); Final
|
|
67
|
+
// locks content so iterate is hidden there. The previous
|
|
68
|
+
// `reviewState === 'iterating'` gate was a Commandment II violation;
|
|
69
|
+
// removed in the v0.19 spec-conformance sweep.
|
|
70
|
+
if (stagePermitsEdits(stage)) {
|
|
82
71
|
buttons.push(html `<button class="er-btn er-btn-small er-btn-primary er-copy-btn" type="button"
|
|
83
72
|
data-copy="/deskwork:iterate ${entry.slug}"
|
|
84
73
|
title="operator clicked Iterate — run the iterate skill in Claude Code">iterate →</button>`);
|
|
@@ -121,4 +110,16 @@ function isLinearActiveStage(stage) {
|
|
|
121
110
|
stage === 'Drafting' ||
|
|
122
111
|
stage === 'Final');
|
|
123
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Stages that permit content edits (and therefore iterate). Final
|
|
115
|
+
* locks content per DESKWORK-STATE-MACHINE.md — iterate refuses there;
|
|
116
|
+
* the operator must induct backward to a stage that permits edits if
|
|
117
|
+
* they want to revise a Final entry.
|
|
118
|
+
*/
|
|
119
|
+
function stagePermitsEdits(stage) {
|
|
120
|
+
return (stage === 'Ideas' ||
|
|
121
|
+
stage === 'Planned' ||
|
|
122
|
+
stage === 'Outlining' ||
|
|
123
|
+
stage === 'Drafting');
|
|
124
|
+
}
|
|
124
125
|
//# sourceMappingURL=affordances.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"affordances.js","sourceRoot":"","sources":["../../../src/pages/dashboard/affordances.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"affordances.js","sourceRoot":"","sources":["../../../src/pages/dashboard/affordances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAGxE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAY,EAAE,WAAmB;IAChE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC;IACjC,MAAM,UAAU,GAAG,+BAA+B,KAAK,CAAC,IAAI,EAAE,CAAC;IAC/D,qEAAqE;IACrE,qEAAqE;IACrE,qEAAqE;IACrE,oEAAoE;IACpE,kCAAkC;IAClC,EAAE;IACF,oEAAoE;IACpE,4DAA4D;IAC5D,sEAAsE;IACtE,oDAAoD;IACpD,kEAAkE;IAClE,gDAAgD;IAChD,MAAM,SAAS,GAAG,kBAAkB,CAAC;QACnC,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,IAAI;KACpB,CAAC,CAAC;IAEH,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA,wCAAwC,UAAU;2CAC5B,KAAK,CAAC,IAAI,cAAc,CAAC,CAAC;QACjE,sEAAsE;QACtE,mEAAmE;QACnE,oEAAoE;QACpE,yDAAyD;QACzD,qEAAqE;QACrE,+CAA+C;QAC/C,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA;uCACgB,KAAK,CAAC,IAAI;mGACkD,CAAC,CAAC;QACjG,CAAC;QACD,kEAAkE;QAClE,+DAA+D;QAC/D,wDAAwD;QACxD,gEAAgE;QAChE,kEAAkE;QAClE,+DAA+D;QAC/D,+DAA+D;QAC/D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA;qCACgB,KAAK,CAAC,IAAI;sEACuB,CAAC,CAAC;QACpE,+DAA+D;QAC/D,qEAAqE;QACrE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA;oCACe,KAAK,CAAC,IAAI;2GAC6D,CAAC,CAAC;IAC3G,CAAC;SAAM,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA,wCAAwC,UAAU;0EACG,CAAC,CAAC;IAC1E,CAAC;SAAM,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA;oCACe,KAAK,CAAC,IAAI;wEAC0B,CAAC,CAAC;IACxE,CAAC;IAED,uDAAuD;IACvD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA;YACP,SAAS;sFACiE,CAAC,CAAC;IAEtF,OAAO,MAAM,CAAC,oCAAoC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;AAC/E,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAY;IACvC,OAAO,CACL,KAAK,KAAK,OAAO;QACjB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,WAAW;QACrB,KAAK,KAAK,UAAU;QACpB,KAAK,KAAK,OAAO,CAClB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,KAAY;IACrC,OAAO,CACL,KAAK,KAAK,OAAO;QACjB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,WAAW;QACrB,KAAK,KAAK,UAAU,CACrB,CAAC;AACJ,CAAC"}
|
|
@@ -6,55 +6,35 @@
|
|
|
6
6
|
* carry a `data-copy` payload that the existing studio client copies
|
|
7
7
|
* to the clipboard. No new backend handlers are wired here; the
|
|
8
8
|
* universal-verb skills are the canonical action path.
|
|
9
|
+
*
|
|
10
|
+
* Per DESKWORK-STATE-MACHINE.md (v5):
|
|
11
|
+
* - Verbs are stage-gated, not state-gated. The iterate button shows
|
|
12
|
+
* on stages-that-permit-edits (Ideas/Planned/Outlining/Drafting),
|
|
13
|
+
* not on Final (locked) or Published (immutable).
|
|
14
|
+
* - Revisions (the iteration counter) are bookkeeping. They do not
|
|
15
|
+
* surface in routine UI; the operator only sees them via revision
|
|
16
|
+
* history / revert flows. The previous "iteration: N" per-row
|
|
17
|
+
* display has been removed.
|
|
9
18
|
*/
|
|
10
19
|
|
|
11
20
|
import { html, unsafe, type RawHtml } from '../html.ts';
|
|
12
21
|
import { scrapbookViewerUrl } from '../../components/scrapbook-item.ts';
|
|
13
|
-
import type { Entry, Stage
|
|
14
|
-
|
|
15
|
-
const REVIEW_STATE_LABEL: Record<ReviewState, string> = {
|
|
16
|
-
'in-review': 'in review',
|
|
17
|
-
iterating: 'iterating',
|
|
18
|
-
approved: 'approved',
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Render the reviewState badge. When the entry has no reviewState
|
|
23
|
-
* (most pre-review stages), render an em-dash placeholder so the row
|
|
24
|
-
* stays grid-aligned with sibling rows that DO carry a badge.
|
|
25
|
-
*/
|
|
26
|
-
export function renderReviewStateBadge(state: ReviewState | undefined): RawHtml {
|
|
27
|
-
if (state === undefined) {
|
|
28
|
-
return unsafe('<span class="er-stamp er-stamp-none" data-review-state="none">—</span>');
|
|
29
|
-
}
|
|
30
|
-
return unsafe(html`<span class="er-stamp er-stamp-${state}" data-review-state="${state}">${REVIEW_STATE_LABEL[state]}</span>`);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Iteration count for the entry's current stage. The sidecar's
|
|
35
|
-
* `iterationByStage` records every stage the entry has touched; this
|
|
36
|
-
* surfaces the count for the stage the entry is currently in. Defaults
|
|
37
|
-
* to 0 when the bucket is missing (a brand-new entry on its first tick
|
|
38
|
-
* before any iterate has fired).
|
|
39
|
-
*/
|
|
40
|
-
export function iterationForCurrentStage(entry: Entry): number {
|
|
41
|
-
return entry.iterationByStage[entry.currentStage] ?? 0;
|
|
42
|
-
}
|
|
22
|
+
import type { Entry, Stage } from '@deskwork/core/schema/entry';
|
|
43
23
|
|
|
44
24
|
/**
|
|
45
25
|
* Build the per-row action strip. Affordances vary by stage:
|
|
46
26
|
*
|
|
47
|
-
* -
|
|
48
|
-
*
|
|
49
|
-
* copy-CLI button
|
|
50
|
-
*
|
|
51
|
-
*
|
|
27
|
+
* - Stages-that-permit-edits (Ideas / Planned / Outlining / Drafting):
|
|
28
|
+
* "open →" link, "iterate →" copy-CLI button (always; no state gate),
|
|
29
|
+
* "approve →" copy-CLI button, "cancel ⊘" copy-CLI button.
|
|
30
|
+
* - Final: "open →", "approve →" (graduates to Published; assigns a
|
|
31
|
+
* version per the operator's scheme), "cancel ⊘". NO iterate
|
|
32
|
+
* (Final locks content per the spec).
|
|
33
|
+
* - Published: "view →" (read-only review surface). Future enhancement:
|
|
34
|
+
* surface a "revise" affordance that inducts back to Drafting.
|
|
52
35
|
* - Blocked / Cancelled: "induct →" copy-CLI to bring the entry back.
|
|
53
36
|
*
|
|
54
|
-
* All non-terminal stages also get a `scrapbook ↗` link (#157)
|
|
55
|
-
* scrapbook viewer is the primary surface for entry-attached research
|
|
56
|
-
* notes / images / config / drafts and was previously unreachable
|
|
57
|
-
* from the dashboard.
|
|
37
|
+
* All non-terminal stages also get a `scrapbook ↗` link (#157).
|
|
58
38
|
*
|
|
59
39
|
* Each button's behavior is parked behind a `data-copy` attribute so
|
|
60
40
|
* the existing studio client (editorial-studio-client.ts) handles
|
|
@@ -85,7 +65,13 @@ export function renderRowActions(entry: Entry, defaultSite: string): RawHtml {
|
|
|
85
65
|
if (isLinearActiveStage(stage)) {
|
|
86
66
|
buttons.push(html`<a class="er-btn er-btn-small" href="${reviewLink}"
|
|
87
67
|
title="open the review surface for ${entry.slug}">open →</a>`);
|
|
88
|
-
|
|
68
|
+
// Iterate — stage-gated per DESKWORK-STATE-MACHINE.md Commandment II:
|
|
69
|
+
// verbs are stage-gated, never state-gated. Iterate runs on stages
|
|
70
|
+
// that permit edits (Ideas / Planned / Outlining / Drafting); Final
|
|
71
|
+
// locks content so iterate is hidden there. The previous
|
|
72
|
+
// `reviewState === 'iterating'` gate was a Commandment II violation;
|
|
73
|
+
// removed in the v0.19 spec-conformance sweep.
|
|
74
|
+
if (stagePermitsEdits(stage)) {
|
|
89
75
|
buttons.push(html`<button class="er-btn er-btn-small er-btn-primary er-copy-btn" type="button"
|
|
90
76
|
data-copy="/deskwork:iterate ${entry.slug}"
|
|
91
77
|
title="operator clicked Iterate — run the iterate skill in Claude Code">iterate →</button>`);
|
|
@@ -131,3 +117,18 @@ function isLinearActiveStage(stage: Stage): boolean {
|
|
|
131
117
|
stage === 'Final'
|
|
132
118
|
);
|
|
133
119
|
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Stages that permit content edits (and therefore iterate). Final
|
|
123
|
+
* locks content per DESKWORK-STATE-MACHINE.md — iterate refuses there;
|
|
124
|
+
* the operator must induct backward to a stage that permits edits if
|
|
125
|
+
* they want to revise a Final entry.
|
|
126
|
+
*/
|
|
127
|
+
function stagePermitsEdits(stage: Stage): boolean {
|
|
128
|
+
return (
|
|
129
|
+
stage === 'Ideas' ||
|
|
130
|
+
stage === 'Planned' ||
|
|
131
|
+
stage === 'Outlining' ||
|
|
132
|
+
stage === 'Drafting'
|
|
133
|
+
);
|
|
134
|
+
}
|
|
@@ -2,9 +2,15 @@
|
|
|
2
2
|
* Dashboard masthead + filter strip.
|
|
3
3
|
*
|
|
4
4
|
* Pipeline-redesign Task 34. The masthead reads from sidecar-derived
|
|
5
|
-
* counts (total entries
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* counts (total entries) instead of the legacy workflow store. The
|
|
6
|
+
* filter strip is a search-only row; stage chips were removed in v0.19
|
|
7
|
+
* (they were never used and added chrome noise). The collapsible stage
|
|
8
|
+
* tiles on mobile now serve the per-stage navigation role chips used to.
|
|
9
|
+
*
|
|
10
|
+
* Review-state-derived stats ("X in review", "X approved") were removed
|
|
11
|
+
* in v0.19 per operator: review state isn't user-facing data and is
|
|
12
|
+
* slated for backend removal. The masthead surfaces only stage-shape
|
|
13
|
+
* counts (date + total) now.
|
|
8
14
|
*/
|
|
9
15
|
import type { DashboardData } from './data.ts';
|
|
10
16
|
import { type RawHtml } from '../html.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../../src/pages/dashboard/header.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../../src/pages/dashboard/header.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAQxD,wBAAgB,YAAY,CAC1B,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,IAAI,GACR,OAAO,CAwBT;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAM3C"}
|
|
@@ -2,33 +2,22 @@
|
|
|
2
2
|
* Dashboard masthead + filter strip.
|
|
3
3
|
*
|
|
4
4
|
* Pipeline-redesign Task 34. The masthead reads from sidecar-derived
|
|
5
|
-
* counts (total entries
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* counts (total entries) instead of the legacy workflow store. The
|
|
6
|
+
* filter strip is a search-only row; stage chips were removed in v0.19
|
|
7
|
+
* (they were never used and added chrome noise). The collapsible stage
|
|
8
|
+
* tiles on mobile now serve the per-stage navigation role chips used to.
|
|
9
|
+
*
|
|
10
|
+
* Review-state-derived stats ("X in review", "X approved") were removed
|
|
11
|
+
* in v0.19 per operator: review state isn't user-facing data and is
|
|
12
|
+
* slated for backend removal. The masthead surfaces only stage-shape
|
|
13
|
+
* counts (date + total) now.
|
|
8
14
|
*/
|
|
9
|
-
import { DASHBOARD_STAGE_ORDER } from "./data.js";
|
|
10
15
|
import { html, unsafe } from "../html.js";
|
|
11
16
|
import { getStudioVersion } from "../../lib/version.js";
|
|
12
17
|
const MONTH_NAMES = [
|
|
13
18
|
'January', 'February', 'March', 'April', 'May', 'June',
|
|
14
19
|
'July', 'August', 'September', 'October', 'November', 'December',
|
|
15
20
|
];
|
|
16
|
-
function reviewActiveCount(data) {
|
|
17
|
-
let n = 0;
|
|
18
|
-
for (const entry of data.entries) {
|
|
19
|
-
if (entry.reviewState === 'in-review' || entry.reviewState === 'iterating')
|
|
20
|
-
n++;
|
|
21
|
-
}
|
|
22
|
-
return n;
|
|
23
|
-
}
|
|
24
|
-
function approvedCount(data) {
|
|
25
|
-
let n = 0;
|
|
26
|
-
for (const entry of data.entries) {
|
|
27
|
-
if (entry.reviewState === 'approved')
|
|
28
|
-
n++;
|
|
29
|
-
}
|
|
30
|
-
return n;
|
|
31
|
-
}
|
|
32
21
|
export function renderHeader(data, projectRoot, now) {
|
|
33
22
|
const volume = '01';
|
|
34
23
|
const issueNum = String(data.entries.length).padStart(2, '0');
|
|
@@ -51,10 +40,6 @@ export function renderHeader(data, projectRoot, now) {
|
|
|
51
40
|
<span>${issueDate}</span>
|
|
52
41
|
<span class="sep">·</span>
|
|
53
42
|
<span>${data.entries.length} on the calendar</span>
|
|
54
|
-
<span class="sep">·</span>
|
|
55
|
-
<span>${reviewActiveCount(data)} in review</span>
|
|
56
|
-
<span class="sep">·</span>
|
|
57
|
-
<span>${approvedCount(data)} approved</span>
|
|
58
43
|
</p>
|
|
59
44
|
</header>`);
|
|
60
45
|
}
|
|
@@ -63,11 +48,6 @@ export function renderFilterStrip() {
|
|
|
63
48
|
<section class="er-filter" data-filter-strip>
|
|
64
49
|
<span class="er-filter-label">Find</span>
|
|
65
50
|
<input type="search" data-filter-input placeholder="slug, title…" autocomplete="off" />
|
|
66
|
-
<span class="er-filter-label er-filter-label--gap">Stage</span>
|
|
67
|
-
<div class="er-chips" role="tablist">
|
|
68
|
-
<button class="er-chip" aria-pressed="true" data-stage-chip="all">all</button>
|
|
69
|
-
${DASHBOARD_STAGE_ORDER.map((s) => unsafe(html `<button class="er-chip" data-stage-chip="${s}">${s.toLowerCase()}</button>`))}
|
|
70
|
-
</div>
|
|
71
51
|
</section>`);
|
|
72
52
|
}
|
|
73
53
|
//# sourceMappingURL=header.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"header.js","sourceRoot":"","sources":["../../../src/pages/dashboard/header.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"header.js","sourceRoot":"","sources":["../../../src/pages/dashboard/header.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,WAAW,GAAG;IAClB,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IACtD,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU;CACjE,CAAC;AAEF,MAAM,UAAU,YAAY,CAC1B,IAAmB,EACnB,WAAmB,EACnB,GAAS;IAET,MAAM,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;IACzF,OAAO,MAAM,CAAC,IAAI,CAAA;;;aAGP,MAAM,eAAe,QAAQ;;;;;;uBAMnB,WAAW;;;4CAGU,gBAAgB,EAAE;;;cAGhD,SAAS;;cAET,IAAI,CAAC,OAAO,CAAC,MAAM;;YAErB,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,MAAM,CAAC,IAAI,CAAA;;;;eAIL,CAAC,CAAC;AACjB,CAAC"}
|
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
* Dashboard masthead + filter strip.
|
|
3
3
|
*
|
|
4
4
|
* Pipeline-redesign Task 34. The masthead reads from sidecar-derived
|
|
5
|
-
* counts (total entries
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* counts (total entries) instead of the legacy workflow store. The
|
|
6
|
+
* filter strip is a search-only row; stage chips were removed in v0.19
|
|
7
|
+
* (they were never used and added chrome noise). The collapsible stage
|
|
8
|
+
* tiles on mobile now serve the per-stage navigation role chips used to.
|
|
9
|
+
*
|
|
10
|
+
* Review-state-derived stats ("X in review", "X approved") were removed
|
|
11
|
+
* in v0.19 per operator: review state isn't user-facing data and is
|
|
12
|
+
* slated for backend removal. The masthead surfaces only stage-shape
|
|
13
|
+
* counts (date + total) now.
|
|
8
14
|
*/
|
|
9
15
|
|
|
10
16
|
import type { DashboardData } from './data.ts';
|
|
11
|
-
import { DASHBOARD_STAGE_ORDER } from './data.ts';
|
|
12
17
|
import { html, unsafe, type RawHtml } from '../html.ts';
|
|
13
18
|
import { getStudioVersion } from '../../lib/version.ts';
|
|
14
19
|
|
|
@@ -17,22 +22,6 @@ const MONTH_NAMES = [
|
|
|
17
22
|
'July', 'August', 'September', 'October', 'November', 'December',
|
|
18
23
|
];
|
|
19
24
|
|
|
20
|
-
function reviewActiveCount(data: DashboardData): number {
|
|
21
|
-
let n = 0;
|
|
22
|
-
for (const entry of data.entries) {
|
|
23
|
-
if (entry.reviewState === 'in-review' || entry.reviewState === 'iterating') n++;
|
|
24
|
-
}
|
|
25
|
-
return n;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function approvedCount(data: DashboardData): number {
|
|
29
|
-
let n = 0;
|
|
30
|
-
for (const entry of data.entries) {
|
|
31
|
-
if (entry.reviewState === 'approved') n++;
|
|
32
|
-
}
|
|
33
|
-
return n;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
25
|
export function renderHeader(
|
|
37
26
|
data: DashboardData,
|
|
38
27
|
projectRoot: string,
|
|
@@ -59,10 +48,6 @@ export function renderHeader(
|
|
|
59
48
|
<span>${issueDate}</span>
|
|
60
49
|
<span class="sep">·</span>
|
|
61
50
|
<span>${data.entries.length} on the calendar</span>
|
|
62
|
-
<span class="sep">·</span>
|
|
63
|
-
<span>${reviewActiveCount(data)} in review</span>
|
|
64
|
-
<span class="sep">·</span>
|
|
65
|
-
<span>${approvedCount(data)} approved</span>
|
|
66
51
|
</p>
|
|
67
52
|
</header>`);
|
|
68
53
|
}
|
|
@@ -72,12 +57,5 @@ export function renderFilterStrip(): RawHtml {
|
|
|
72
57
|
<section class="er-filter" data-filter-strip>
|
|
73
58
|
<span class="er-filter-label">Find</span>
|
|
74
59
|
<input type="search" data-filter-input placeholder="slug, title…" autocomplete="off" />
|
|
75
|
-
<span class="er-filter-label er-filter-label--gap">Stage</span>
|
|
76
|
-
<div class="er-chips" role="tablist">
|
|
77
|
-
<button class="er-chip" aria-pressed="true" data-stage-chip="all">all</button>
|
|
78
|
-
${DASHBOARD_STAGE_ORDER.map(
|
|
79
|
-
(s) => unsafe(html`<button class="er-chip" data-stage-chip="${s}">${s.toLowerCase()}</button>`),
|
|
80
|
-
)}
|
|
81
|
-
</div>
|
|
82
60
|
</section>`);
|
|
83
61
|
}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Single-stage section renderer.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* with a section heading (stage name + entry count) and either
|
|
6
|
-
* of rows or an empty-state placeholder.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* Each of the eight stage sections (plus the Distribution placeholder)
|
|
5
|
+
* renders with a section heading (stage name + entry count) and either
|
|
6
|
+
* a list of rows or an empty-state placeholder. Each row carries the
|
|
7
|
+
* entry's slug, title, updated-at timestamp, and stage-gated verb
|
|
8
|
+
* buttons. Per DESKWORK-STATE-MACHINE.md Commandment III, rows do NOT
|
|
9
|
+
* surface iteration counts or reviewState — those were retired in
|
|
10
|
+
* v0.19 along with the legacy reviewState concept.
|
|
11
|
+
*
|
|
12
|
+
* On mobile, each section is fronted by a collapsible tile (see
|
|
13
|
+
* `renderStageTile`); on desktop the tiles are display:none and the
|
|
14
|
+
* `<h2 class="er-section-head">` heading carries the stage name.
|
|
10
15
|
*/
|
|
11
16
|
import { type RawHtml } from '../html.ts';
|
|
12
17
|
import type { Entry, Stage } from '@deskwork/core/schema/entry';
|
|
@@ -14,27 +19,49 @@ import type { Entry, Stage } from '@deskwork/core/schema/entry';
|
|
|
14
19
|
* Render one entry as a single dashboard row. Carries inline:
|
|
15
20
|
* - slug (linked to the review surface)
|
|
16
21
|
* - title
|
|
17
|
-
* - iteration count for the entry's currentStage
|
|
18
|
-
* - reviewState badge (or an em-dash placeholder)
|
|
19
22
|
* - updatedAt timestamp
|
|
20
23
|
* - per-stage action buttons
|
|
24
|
+
*
|
|
25
|
+
* Per DESKWORK-STATE-MACHINE.md (v5): revisions (the iteration counter)
|
|
26
|
+
* are bookkeeping and do NOT surface in routine UI. The previous
|
|
27
|
+
* "iteration: N" inline display was a violation — operators see
|
|
28
|
+
* revisions only via the View History surface and revert flows.
|
|
29
|
+
* reviewState badges are likewise retired (Commandment III).
|
|
21
30
|
*/
|
|
22
31
|
export declare function renderRow(entry: Entry, index: number, defaultSite: string): RawHtml;
|
|
23
32
|
/**
|
|
24
33
|
* Render one full stage section: heading + ornaments + count + rows.
|
|
25
34
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
35
|
+
* The output is wrapped in a `.er-stage-block` div that pairs a mobile-
|
|
36
|
+
* only stage tile (the collapsible head) with the existing section. On
|
|
37
|
+
* desktop, the tile is `display: none` and the section's `<h2>` head
|
|
38
|
+
* carries the heading as before. On mobile, the section's head is hidden
|
|
39
|
+
* and the tile is shown; tapping the tile toggles a `data-collapsed`
|
|
40
|
+
* attribute on the section that hides/shows its rows. Single-expand
|
|
41
|
+
* (tapping one tile collapses the others) is handled by
|
|
42
|
+
* `dashboard/stage-tiles.ts`.
|
|
43
|
+
*
|
|
44
|
+
* Empty stages still render their tile (so the pipeline shape is visible
|
|
45
|
+
* at-rest on phone) but the empty section body itself is hidden on mobile.
|
|
46
|
+
*
|
|
47
|
+
* Empty stages on desktop render compact (just the heading, no placeholder
|
|
48
|
+
* body) — keeps the operator's sense of pipeline shape without padding
|
|
49
|
+
* the dashboard with multi-line empty placeholders for low-volume
|
|
29
50
|
* calendars (#112). The hover title still surfaces the stage's
|
|
30
51
|
* "what to run next" hint when the operator points at the heading.
|
|
31
52
|
*/
|
|
32
53
|
export declare function renderStageSection(stage: Stage, entries: readonly Entry[], defaultSite: string): RawHtml;
|
|
33
54
|
/**
|
|
34
|
-
* Render the reserved Distribution placeholder.
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
55
|
+
* Render the reserved Distribution placeholder. Distribution isn't a
|
|
56
|
+
* pipeline stage in the formal sense (no entries flow through it; it
|
|
57
|
+
* lives under its own model when shortform cross-posts arrive), but on
|
|
58
|
+
* the mobile dashboard it renders as a stage tile alongside the rest
|
|
59
|
+
* so the operator's pipeline-shape scan stays uniform — see operator
|
|
60
|
+
* feedback on 2026-05-09. The tile is `is-empty` + `disabled` until
|
|
61
|
+
* DistributionRecords land in the data layer.
|
|
62
|
+
*
|
|
63
|
+
* On desktop, the existing section + heading + placeholder text render
|
|
64
|
+
* as before; the tile is `display: none` per dashboard-mobile.css.
|
|
38
65
|
*/
|
|
39
66
|
export declare function renderDistributionPlaceholder(): RawHtml;
|
|
40
67
|
//# sourceMappingURL=section.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section.d.ts","sourceRoot":"","sources":["../../../src/pages/dashboard/section.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"section.d.ts","sourceRoot":"","sources":["../../../src/pages/dashboard/section.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAyBhE;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CA2BnF;AAgCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,SAAS,KAAK,EAAE,EACzB,WAAW,EAAE,MAAM,GAClB,OAAO,CAkCT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAsBvD"}
|