@deskwork/studio 0.12.1 → 0.14.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/components/scrapbook-item.d.ts +9 -1
- package/dist/components/scrapbook-item.d.ts.map +1 -1
- package/dist/components/scrapbook-item.js +11 -2
- package/dist/components/scrapbook-item.js.map +1 -1
- package/dist/data/glossary.json +62 -0
- package/dist/lib/glossary-helper.d.ts +16 -0
- package/dist/lib/glossary-helper.d.ts.map +1 -0
- package/dist/lib/glossary-helper.js +26 -0
- package/dist/lib/glossary-helper.js.map +1 -0
- package/dist/pages/chrome.d.ts +24 -13
- package/dist/pages/chrome.d.ts.map +1 -1
- package/dist/pages/chrome.js +25 -24
- package/dist/pages/chrome.js.map +1 -1
- package/dist/pages/chrome.ts +38 -27
- package/dist/pages/content-detail.d.ts.map +1 -1
- package/dist/pages/content-detail.js +6 -5
- package/dist/pages/content-detail.js.map +1 -1
- package/dist/pages/content-detail.ts +6 -5
- package/dist/pages/content.d.ts.map +1 -1
- package/dist/pages/content.js +4 -6
- package/dist/pages/content.js.map +1 -1
- package/dist/pages/content.ts +4 -6
- package/dist/pages/dashboard/affordances.d.ts +6 -1
- package/dist/pages/dashboard/affordances.d.ts.map +1 -1
- package/dist/pages/dashboard/affordances.js +17 -2
- package/dist/pages/dashboard/affordances.js.map +1 -1
- package/dist/pages/dashboard/affordances.ts +18 -2
- package/dist/pages/dashboard/header.js +2 -2
- package/dist/pages/dashboard/header.ts +2 -2
- package/dist/pages/dashboard/section.d.ts +2 -2
- package/dist/pages/dashboard/section.d.ts.map +1 -1
- package/dist/pages/dashboard/section.js +5 -5
- package/dist/pages/dashboard/section.js.map +1 -1
- package/dist/pages/dashboard/section.ts +9 -5
- package/dist/pages/dashboard.d.ts.map +1 -1
- package/dist/pages/dashboard.js +3 -2
- package/dist/pages/dashboard.js.map +1 -1
- package/dist/pages/dashboard.ts +3 -2
- package/dist/pages/entry-review/data.d.ts +54 -0
- package/dist/pages/entry-review/data.d.ts.map +1 -0
- package/dist/pages/entry-review/data.js +116 -0
- package/dist/pages/entry-review/data.js.map +1 -0
- package/dist/pages/entry-review/decision-strip.d.ts +37 -0
- package/dist/pages/entry-review/decision-strip.d.ts.map +1 -0
- package/dist/pages/entry-review/decision-strip.js +137 -0
- package/dist/pages/entry-review/decision-strip.js.map +1 -0
- package/dist/pages/entry-review/edit-panes.d.ts +12 -0
- package/dist/pages/entry-review/edit-panes.d.ts.map +1 -0
- package/dist/pages/entry-review/edit-panes.js +28 -0
- package/dist/pages/entry-review/edit-panes.js.map +1 -0
- package/dist/pages/entry-review/edit-toolbar.d.ts +20 -0
- package/dist/pages/entry-review/edit-toolbar.d.ts.map +1 -0
- package/dist/pages/entry-review/edit-toolbar.js +46 -0
- package/dist/pages/entry-review/edit-toolbar.js.map +1 -0
- package/dist/pages/entry-review/index.d.ts +50 -0
- package/dist/pages/entry-review/index.d.ts.map +1 -0
- package/dist/pages/entry-review/index.js +219 -0
- package/dist/pages/entry-review/index.js.map +1 -0
- package/dist/pages/entry-review/marginalia.d.ts +28 -0
- package/dist/pages/entry-review/marginalia.d.ts.map +1 -0
- package/dist/pages/entry-review/marginalia.js +67 -0
- package/dist/pages/entry-review/marginalia.js.map +1 -0
- package/dist/pages/entry-review/not-found.d.ts +9 -0
- package/dist/pages/entry-review/not-found.d.ts.map +1 -0
- package/dist/pages/entry-review/not-found.js +34 -0
- package/dist/pages/entry-review/not-found.js.map +1 -0
- package/dist/pages/entry-review/outline-drawer.d.ts +12 -0
- package/dist/pages/entry-review/outline-drawer.d.ts.map +1 -0
- package/dist/pages/entry-review/outline-drawer.js +28 -0
- package/dist/pages/entry-review/outline-drawer.js.map +1 -0
- package/dist/pages/entry-review/shortcuts.d.ts +14 -0
- package/dist/pages/entry-review/shortcuts.d.ts.map +1 -0
- package/dist/pages/entry-review/shortcuts.js +36 -0
- package/dist/pages/entry-review/shortcuts.js.map +1 -0
- package/dist/pages/entry-review/version-strip.d.ts +33 -0
- package/dist/pages/entry-review/version-strip.d.ts.map +1 -0
- package/dist/pages/entry-review/version-strip.js +81 -0
- package/dist/pages/entry-review/version-strip.js.map +1 -0
- package/dist/pages/entry-review.d.ts +6 -21
- package/dist/pages/entry-review.d.ts.map +1 -1
- package/dist/pages/entry-review.js +6 -144
- package/dist/pages/entry-review.js.map +1 -1
- package/dist/pages/entry-review.ts +11 -181
- package/dist/pages/html.d.ts +2 -0
- package/dist/pages/html.d.ts.map +1 -1
- package/dist/pages/html.js +2 -0
- package/dist/pages/html.js.map +1 -1
- package/dist/pages/html.ts +4 -0
- package/dist/pages/index.d.ts.map +1 -1
- package/dist/pages/index.js +6 -10
- package/dist/pages/index.js.map +1 -1
- package/dist/pages/index.ts +6 -10
- package/dist/pages/layout.d.ts.map +1 -1
- package/dist/pages/layout.js +6 -0
- package/dist/pages/layout.js.map +1 -1
- package/dist/pages/layout.ts +7 -0
- package/dist/pages/review-scrapbook-drawer.d.ts +7 -0
- package/dist/pages/review-scrapbook-drawer.d.ts.map +1 -1
- package/dist/pages/review-scrapbook-drawer.js +45 -6
- package/dist/pages/review-scrapbook-drawer.js.map +1 -1
- package/dist/pages/review-scrapbook-drawer.ts +50 -6
- package/dist/pages/review.d.ts.map +1 -1
- package/dist/pages/review.js +168 -41
- package/dist/pages/review.js.map +1 -1
- package/dist/pages/review.ts +192 -41
- package/dist/pages/scrapbook.d.ts +7 -14
- package/dist/pages/scrapbook.d.ts.map +1 -1
- package/dist/pages/scrapbook.js +548 -192
- package/dist/pages/scrapbook.js.map +1 -1
- package/dist/pages/scrapbook.ts +588 -221
- package/dist/pages/shortform-review.d.ts +32 -0
- package/dist/pages/shortform-review.d.ts.map +1 -0
- package/dist/pages/shortform-review.js +270 -0
- package/dist/pages/shortform-review.js.map +1 -0
- package/dist/pages/shortform-review.ts +342 -0
- package/dist/pages/shortform.js +1 -1
- package/dist/pages/shortform.js.map +1 -1
- package/dist/pages/shortform.ts +1 -1
- package/dist/routes/api.d.ts +8 -0
- package/dist/routes/api.d.ts.map +1 -1
- package/dist/routes/api.js +115 -0
- package/dist/routes/api.js.map +1 -1
- package/dist/routes/entry-annotation-body.d.ts +26 -0
- package/dist/routes/entry-annotation-body.d.ts.map +1 -0
- package/dist/routes/entry-annotation-body.js +152 -0
- package/dist/routes/entry-annotation-body.js.map +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +56 -196
- package/dist/server.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,185 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Entry-
|
|
2
|
+
* Entry-keyed press-check surface — `/dev/editorial-review/entry/:entryId`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* minimal affordance set returned by `getAffordances(entry)`.
|
|
9
|
-
*
|
|
10
|
-
* The two surfaces coexist during the migration window. Once the
|
|
11
|
-
* workflow-keyed routes are retired, this becomes the canonical review
|
|
12
|
-
* surface; until then, the dashboard's per-row "review" links continue
|
|
13
|
-
* to point at the legacy route.
|
|
14
|
-
*
|
|
15
|
-
* Rendering is intentionally minimal — the goal of Task 35 is the route
|
|
16
|
-
* shape + affordance plumbing, not a fully-styled UI. Styling will land
|
|
17
|
-
* once the affordance set stabilizes against real entries.
|
|
4
|
+
* The implementation lives in the `entry-review/` directory (one
|
|
5
|
+
* module per chrome component, each under the 500-line cap). This
|
|
6
|
+
* file re-exports the public render function so the existing
|
|
7
|
+
* `server.ts` import keeps working.
|
|
18
8
|
*/
|
|
19
9
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const STAGE_PICKER_OPTIONS = [
|
|
28
|
-
'Ideas',
|
|
29
|
-
'Planned',
|
|
30
|
-
'Outlining',
|
|
31
|
-
'Drafting',
|
|
32
|
-
'Final',
|
|
33
|
-
] as const;
|
|
34
|
-
|
|
35
|
-
const CONTROL_LABELS: Readonly<Record<string, string>> = {
|
|
36
|
-
save: 'Save',
|
|
37
|
-
iterate: 'Iterate',
|
|
38
|
-
approve: 'Approve',
|
|
39
|
-
reject: 'Reject',
|
|
40
|
-
'historical-stage-dropdown': 'Historical stage',
|
|
41
|
-
'view-only': 'Read-only',
|
|
42
|
-
'fork-placeholder': 'Fork (coming)',
|
|
43
|
-
'induct-to': 'Induct to',
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
function renderControl(control: string, entry: Entry): RawHtml {
|
|
47
|
-
const label = CONTROL_LABELS[control] ?? control;
|
|
48
|
-
if (control === 'induct-to') {
|
|
49
|
-
const options = STAGE_PICKER_OPTIONS.map(
|
|
50
|
-
(s) => unsafe(html`<option value="${s}">${s}</option>`),
|
|
51
|
-
);
|
|
52
|
-
return unsafe(html`
|
|
53
|
-
<label class="er-entry-control er-entry-control--induct">
|
|
54
|
-
<span class="er-entry-control-label">${label}</span>
|
|
55
|
-
<select name="induct-to" data-entry-uuid="${entry.uuid}">
|
|
56
|
-
${options}
|
|
57
|
-
</select>
|
|
58
|
-
</label>`);
|
|
59
|
-
}
|
|
60
|
-
if (control === 'historical-stage-dropdown') {
|
|
61
|
-
const stages = Object.keys(entry.iterationByStage);
|
|
62
|
-
if (stages.length === 0) {
|
|
63
|
-
return unsafe('');
|
|
64
|
-
}
|
|
65
|
-
const options = stages.map(
|
|
66
|
-
(s) => unsafe(html`<option value="${s}">${s}</option>`),
|
|
67
|
-
);
|
|
68
|
-
return unsafe(html`
|
|
69
|
-
<label class="er-entry-control er-entry-control--history">
|
|
70
|
-
<span class="er-entry-control-label">${label}</span>
|
|
71
|
-
<select name="history-stage" data-entry-uuid="${entry.uuid}">
|
|
72
|
-
${options}
|
|
73
|
-
</select>
|
|
74
|
-
</label>`);
|
|
75
|
-
}
|
|
76
|
-
if (control === 'view-only') {
|
|
77
|
-
return unsafe(html`<span class="er-entry-control er-entry-control--readonly">${label}</span>`);
|
|
78
|
-
}
|
|
79
|
-
if (control === 'fork-placeholder') {
|
|
80
|
-
return unsafe(
|
|
81
|
-
html`<button class="er-entry-control er-entry-control--button" type="button" disabled data-control="fork">${label}</button>`,
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
return unsafe(
|
|
85
|
-
html`<button class="er-entry-control er-entry-control--button" type="button" data-control="${control}" data-entry-uuid="${entry.uuid}">${label}</button>`,
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function renderControls(entry: Entry, affordances: Affordances): RawHtml {
|
|
90
|
-
const buttons = affordances.controls.map((c) => renderControl(c, entry));
|
|
91
|
-
const className = affordances.mutable
|
|
92
|
-
? 'er-entry-controls er-entry-controls--mutable'
|
|
93
|
-
: 'er-entry-controls er-entry-controls--readonly';
|
|
94
|
-
return unsafe(html`<nav class="${className}" aria-label="Entry controls">${buttons}</nav>`);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function renderArtifact(body: string, mutable: boolean): RawHtml {
|
|
98
|
-
if (mutable) {
|
|
99
|
-
return unsafe(html`
|
|
100
|
-
<textarea class="er-entry-body" name="body" rows="24" data-mutable="true">${body}</textarea>`);
|
|
101
|
-
}
|
|
102
|
-
return unsafe(html`
|
|
103
|
-
<pre class="er-entry-body er-entry-body--readonly" data-mutable="false">${body}</pre>`);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function renderEntryReview(
|
|
107
|
-
entry: Entry,
|
|
108
|
-
artifactBody: string,
|
|
109
|
-
artifactPath: string,
|
|
110
|
-
affordances: Affordances,
|
|
111
|
-
): string {
|
|
112
|
-
const stageBadge = unsafe(
|
|
113
|
-
html`<span class="er-entry-stage" data-stage="${entry.currentStage}">${entry.currentStage}</span>`,
|
|
114
|
-
);
|
|
115
|
-
const priorBadge = entry.priorStage
|
|
116
|
-
? unsafe(html`<span class="er-entry-prior-stage">paused from ${entry.priorStage}</span>`)
|
|
117
|
-
: '';
|
|
118
|
-
const body = html`
|
|
119
|
-
<main class="er-entry-shell" data-entry-uuid="${entry.uuid}">
|
|
120
|
-
<header class="er-entry-head">
|
|
121
|
-
<p class="er-entry-kicker">Editorial Review · entry</p>
|
|
122
|
-
<h1 class="er-entry-title">${entry.title}</h1>
|
|
123
|
-
<p class="er-entry-meta">
|
|
124
|
-
${stageBadge}
|
|
125
|
-
${priorBadge}
|
|
126
|
-
<code class="er-entry-uuid">${entry.uuid}</code>
|
|
127
|
-
</p>
|
|
128
|
-
<p class="er-entry-artifact-path"><code>${artifactPath}</code></p>
|
|
129
|
-
</header>
|
|
130
|
-
${renderControls(entry, affordances)}
|
|
131
|
-
<section class="er-entry-artifact">
|
|
132
|
-
${renderArtifact(artifactBody, affordances.mutable)}
|
|
133
|
-
</section>
|
|
134
|
-
</main>`;
|
|
135
|
-
return layout({
|
|
136
|
-
title: `${entry.title} — entry review — dev`,
|
|
137
|
-
cssHrefs: ['/static/css/editorial-review.css'],
|
|
138
|
-
bodyAttrs: 'data-review-ui="entry-review"',
|
|
139
|
-
bodyHtml: body,
|
|
140
|
-
scriptModules: ['entry-review-client'],
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function renderNotFound(entryId: string, reason: string): string {
|
|
145
|
-
const body = html`
|
|
146
|
-
<main class="er-entry-shell er-entry-shell--missing">
|
|
147
|
-
<h1>Entry not found</h1>
|
|
148
|
-
<p>No sidecar matched <code>${entryId}</code>.</p>
|
|
149
|
-
<p class="er-entry-detail">${reason}</p>
|
|
150
|
-
<p><a href="/dev/editorial-studio">Back to the studio</a></p>
|
|
151
|
-
</main>`;
|
|
152
|
-
return layout({
|
|
153
|
-
title: 'Entry not found — dev',
|
|
154
|
-
cssHrefs: ['/static/css/editorial-review.css'],
|
|
155
|
-
bodyAttrs: 'data-review-ui="entry-review-missing"',
|
|
156
|
-
bodyHtml: body,
|
|
157
|
-
scriptModules: [],
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
interface EntryReviewResult {
|
|
162
|
-
status: 200 | 404;
|
|
163
|
-
html: string;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export async function renderEntryReviewPage(
|
|
167
|
-
projectRoot: string,
|
|
168
|
-
entryId: string,
|
|
169
|
-
): Promise<EntryReviewResult> {
|
|
170
|
-
let resolved;
|
|
171
|
-
try {
|
|
172
|
-
resolved = await resolveEntry(projectRoot, entryId);
|
|
173
|
-
} catch (err) {
|
|
174
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
175
|
-
return { status: 404, html: renderNotFound(entryId, reason) };
|
|
176
|
-
}
|
|
177
|
-
const affordances = getAffordances(resolved.entry);
|
|
178
|
-
const html = renderEntryReview(
|
|
179
|
-
resolved.entry,
|
|
180
|
-
resolved.artifactBody,
|
|
181
|
-
resolved.artifactPath,
|
|
182
|
-
affordances,
|
|
183
|
-
);
|
|
184
|
-
return { status: 200, html };
|
|
185
|
-
}
|
|
10
|
+
export {
|
|
11
|
+
renderEntryReviewPage,
|
|
12
|
+
type EntryReviewQuery,
|
|
13
|
+
type EntryReviewResult,
|
|
14
|
+
type EntryReviewIndexGetter,
|
|
15
|
+
} from './entry-review/index.ts';
|
package/dist/pages/html.d.ts
CHANGED
|
@@ -32,4 +32,6 @@ export declare function escapeHtml(s: string): string;
|
|
|
32
32
|
* values run through `renderValue`.
|
|
33
33
|
*/
|
|
34
34
|
export declare function html(strings: TemplateStringsArray, ...values: unknown[]): string;
|
|
35
|
+
export { gloss } from '../lib/glossary-helper.ts';
|
|
36
|
+
export type { GlossaryKey } from '../lib/glossary-helper.ts';
|
|
35
37
|
//# sourceMappingURL=html.d.ts.map
|
package/dist/pages/html.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/pages/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,wCAAwC;AACxC,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,kFAAkF;AAClF,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEzC;AAYD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO5C;AAeD;;;GAGG;AACH,wBAAgB,IAAI,CAClB,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,OAAO,EAAE,GACnB,MAAM,CAOR"}
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/pages/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,wCAAwC;AACxC,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,kFAAkF;AAClF,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEzC;AAYD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO5C;AAeD;;;GAGG;AACH,wBAAgB,IAAI,CAClB,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,OAAO,EAAE,GACnB,MAAM,CAOR;AAGD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/pages/html.js
CHANGED
package/dist/pages/html.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/pages/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,kFAAkF;AAClF,MAAM,UAAU,MAAM,CAAC,CAAS;IAC9B,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AACtB,CAAC;AAED,2CAA2C;AAC3C,SAAS,KAAK,CAAC,KAAc;IAC3B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,OAAO,IAAI,KAAK;QAChB,OAAQ,KAA4B,CAAC,KAAK,KAAK,QAAQ,CACxD,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,CAAC;SACL,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;SACzB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IACxE,IAAI,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACjF,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,yEAAyE;IACzE,mEAAmE;IACnE,kEAAkE;IAClE,OAAO,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI,CAClB,OAA6B,EAC7B,GAAG,MAAiB;IAEpB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM;YAAE,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/pages/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,kFAAkF;AAClF,MAAM,UAAU,MAAM,CAAC,CAAS;IAC9B,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AACtB,CAAC;AAED,2CAA2C;AAC3C,SAAS,KAAK,CAAC,KAAc;IAC3B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,OAAO,IAAI,KAAK;QAChB,OAAQ,KAA4B,CAAC,KAAK,KAAK,QAAQ,CACxD,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,CAAC;SACL,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;SACzB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IACxE,IAAI,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACjF,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,yEAAyE;IACzE,mEAAmE;IACnE,kEAAkE;IAClE,OAAO,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI,CAClB,OAA6B,EAC7B,GAAG,MAAiB;IAEpB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM;YAAE,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iFAAiF;AACjF,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/pages/html.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pages/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAqDtD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,SAAS,KAAK,EAAE,GACxB,KAAK,GAAG,IAAI,CAOd;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pages/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAqDtD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,SAAS,KAAK,EAAE,GACxB,KAAK,GAAG,IAAI,CAOd;AAkKD,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA8B3E"}
|
package/dist/pages/index.js
CHANGED
|
@@ -56,14 +56,10 @@ async function buildSections(ctx) {
|
|
|
56
56
|
}
|
|
57
57
|
})();
|
|
58
58
|
const longformDefaultEntry = pickDefaultLongformEntry(entries);
|
|
59
|
-
// Issue #107
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
// hint stays alongside the link so adopters still see the URL
|
|
64
|
-
// shape — `<slug>` placeholder shown in red-pencil italic. The
|
|
65
|
-
// link target is the entry-uuid keyed review route added in
|
|
66
|
-
// Task 35 (`/dev/editorial-review/entry/<uuid>`).
|
|
59
|
+
// Issue #107: III links to the most-recent in-review (or iterating)
|
|
60
|
+
// longform entry when one exists, else falls back to the dashboard's
|
|
61
|
+
// Review section anchor (`#stage-review`). The link target is the
|
|
62
|
+
// entry-keyed review route `/dev/editorial-review/entry/<uuid>`.
|
|
67
63
|
const longformLinkHref = longformDefaultEntry !== null
|
|
68
64
|
? `/dev/editorial-review/entry/${longformDefaultEntry.uuid}`
|
|
69
65
|
: '/dev/editorial-studio#stage-review';
|
|
@@ -98,9 +94,9 @@ async function buildSections(ctx) {
|
|
|
98
94
|
numeral: 'III',
|
|
99
95
|
titleHtml: 'Longform reviews',
|
|
100
96
|
titleText: 'Longform reviews',
|
|
101
|
-
route: '/dev/editorial-review/<
|
|
97
|
+
route: '/dev/editorial-review/entry/<uuid>',
|
|
102
98
|
linkHref: longformLinkHref,
|
|
103
|
-
template: { prefix: '/dev/editorial-review/', placeholder: '<
|
|
99
|
+
template: { prefix: '/dev/editorial-review/entry/', placeholder: '<uuid>' },
|
|
104
100
|
desc: 'Per-entry margin notes, decisions, iterate flow.',
|
|
105
101
|
hint: 'entry-by-entry',
|
|
106
102
|
postHint: longformDefaultEntry !== null
|
package/dist/pages/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pages/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,iFAAiF;AACjF,MAAM,wBAAwB,GAAuC,IAAI,GAAG,CAAC;IAC3E,OAAO;IACP,SAAS;IACT,WAAW;IACX,UAAU;IACV,OAAO;CACR,CAAC,CAAC;AAyCH;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAyB;IAEzB,MAAM,UAAU,GAAG,OAAO;SACvB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;SAC3D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,IAAI,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC;SAC7E,KAAK,EAAE;SACP,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1D,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC/B,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAkB;IAC7C,MAAM,OAAO,GAAqB,MAAM,CAAC,KAAK,IAAI,EAAE;QAClD,IAAI,CAAC;YACH,OAAO,MAAM,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,MAAM,oBAAoB,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC/D,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pages/index.ts"],"names":[],"mappings":"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"}
|
package/dist/pages/index.ts
CHANGED
|
@@ -102,14 +102,10 @@ async function buildSections(ctx: StudioContext): Promise<readonly IndexSection[
|
|
|
102
102
|
}
|
|
103
103
|
})();
|
|
104
104
|
const longformDefaultEntry = pickDefaultLongformEntry(entries);
|
|
105
|
-
// Issue #107
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
// hint stays alongside the link so adopters still see the URL
|
|
110
|
-
// shape — `<slug>` placeholder shown in red-pencil italic. The
|
|
111
|
-
// link target is the entry-uuid keyed review route added in
|
|
112
|
-
// Task 35 (`/dev/editorial-review/entry/<uuid>`).
|
|
105
|
+
// Issue #107: III links to the most-recent in-review (or iterating)
|
|
106
|
+
// longform entry when one exists, else falls back to the dashboard's
|
|
107
|
+
// Review section anchor (`#stage-review`). The link target is the
|
|
108
|
+
// entry-keyed review route `/dev/editorial-review/entry/<uuid>`.
|
|
113
109
|
const longformLinkHref =
|
|
114
110
|
longformDefaultEntry !== null
|
|
115
111
|
? `/dev/editorial-review/entry/${longformDefaultEntry.uuid}`
|
|
@@ -146,9 +142,9 @@ async function buildSections(ctx: StudioContext): Promise<readonly IndexSection[
|
|
|
146
142
|
numeral: 'III',
|
|
147
143
|
titleHtml: 'Longform reviews',
|
|
148
144
|
titleText: 'Longform reviews',
|
|
149
|
-
route: '/dev/editorial-review/<
|
|
145
|
+
route: '/dev/editorial-review/entry/<uuid>',
|
|
150
146
|
linkHref: longformLinkHref,
|
|
151
|
-
template: { prefix: '/dev/editorial-review/', placeholder: '<
|
|
147
|
+
template: { prefix: '/dev/editorial-review/entry/', placeholder: '<uuid>' },
|
|
152
148
|
desc: 'Per-entry margin notes, decisions, iterate flow.',
|
|
153
149
|
hint: 'entry-by-entry',
|
|
154
150
|
postHint:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/pages/layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/pages/layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,IAAI,EAAE,OAAO,CAAC;IACd,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IAC3C;;;;;OAKG;IACH,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAoDrD"}
|
package/dist/pages/layout.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { escapeHtml } from "./html.js";
|
|
6
6
|
import { clientScriptTag, viteClientTag } from "../lib/client-script.js";
|
|
7
|
+
import glossary from '../data/glossary.json' with { type: 'json' };
|
|
7
8
|
export function layout(options) {
|
|
8
9
|
const { title, cssHrefs, bodyHtml, bodyAttrs, embeddedJson, scriptModules, } = options;
|
|
9
10
|
const cssTags = cssHrefs
|
|
@@ -16,10 +17,14 @@ export function layout(options) {
|
|
|
16
17
|
return ` <script type="application/json"${idPart}${attrPart}>${escapeForScriptTag(JSON.stringify(j.data))}</script>`;
|
|
17
18
|
})
|
|
18
19
|
.join('\n');
|
|
20
|
+
// Inline glossary data into every page so the tooltip client can access it.
|
|
21
|
+
const glossaryInline = `<script>window.__GLOSSARY__ = ${JSON.stringify(glossary).replace(/</g, '\\u003c')};</script>`;
|
|
19
22
|
const hmrTag = viteClientTag();
|
|
23
|
+
const glossaryClientTag = clientScriptTag('glossary-tooltip');
|
|
20
24
|
const scriptTags = [
|
|
21
25
|
...(hmrTag ? [` ${hmrTag}`] : []),
|
|
22
26
|
...scriptModules.map((name) => ` ${clientScriptTag(name)}`),
|
|
27
|
+
` ${glossaryClientTag}`,
|
|
23
28
|
].join('\n');
|
|
24
29
|
const bodyOpen = bodyAttrs ? `<body ${bodyAttrs}>` : '<body>';
|
|
25
30
|
return `<!DOCTYPE html>
|
|
@@ -30,6 +35,7 @@ export function layout(options) {
|
|
|
30
35
|
<meta name="robots" content="noindex">
|
|
31
36
|
<title>${escapeHtml(title)}</title>
|
|
32
37
|
${cssTags}
|
|
38
|
+
${glossaryInline}
|
|
33
39
|
</head>
|
|
34
40
|
${bodyOpen}
|
|
35
41
|
${bodyHtml}
|
package/dist/pages/layout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/pages/layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/pages/layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,QAAQ,MAAM,uBAAuB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAoCnE,MAAM,UAAU,MAAM,CAAC,OAAsB;IAC3C,MAAM,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,aAAa,GACd,GAAG,OAAO,CAAC;IAEZ,MAAM,OAAO,GAAG,QAAQ;SACrB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,oCAAoC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;SACvE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,QAAQ,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;SAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,OAAO,sCAAsC,MAAM,GAAG,QAAQ,IAAI,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC;IAC1H,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,4EAA4E;IAC5E,MAAM,cAAc,GAAG,iCAAiC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,YAAY,CAAC;IAEtH,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,iBAAiB,GAAG,eAAe,CAAC,kBAAkB,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG;QACjB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9D,OAAO,iBAAiB,EAAE;KAC3B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,SAAS,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;IAE9D,OAAO;;;;;;aAMI,UAAU,CAAC,KAAK,CAAC;EAC5B,OAAO;MACH,cAAc;;IAEhB,QAAQ;EACV,QAAQ;EACR,QAAQ;EACR,UAAU;;;CAGX,CAAC;AACF,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC"}
|
package/dist/pages/layout.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { escapeHtml } from './html.ts';
|
|
7
7
|
import { clientScriptTag, viteClientTag } from '../lib/client-script.ts';
|
|
8
|
+
import glossary from '../data/glossary.json' with { type: 'json' };
|
|
8
9
|
|
|
9
10
|
export interface EmbeddedJson {
|
|
10
11
|
/** `id` attribute of the `<script type="application/json">` tag. */
|
|
@@ -62,10 +63,15 @@ export function layout(options: LayoutOptions): string {
|
|
|
62
63
|
})
|
|
63
64
|
.join('\n');
|
|
64
65
|
|
|
66
|
+
// Inline glossary data into every page so the tooltip client can access it.
|
|
67
|
+
const glossaryInline = `<script>window.__GLOSSARY__ = ${JSON.stringify(glossary).replace(/</g, '\\u003c')};</script>`;
|
|
68
|
+
|
|
65
69
|
const hmrTag = viteClientTag();
|
|
70
|
+
const glossaryClientTag = clientScriptTag('glossary-tooltip');
|
|
66
71
|
const scriptTags = [
|
|
67
72
|
...(hmrTag ? [` ${hmrTag}`] : []),
|
|
68
73
|
...scriptModules.map((name) => ` ${clientScriptTag(name)}`),
|
|
74
|
+
` ${glossaryClientTag}`,
|
|
69
75
|
].join('\n');
|
|
70
76
|
|
|
71
77
|
const bodyOpen = bodyAttrs ? `<body ${bodyAttrs}>` : '<body>';
|
|
@@ -78,6 +84,7 @@ export function layout(options: LayoutOptions): string {
|
|
|
78
84
|
<meta name="robots" content="noindex">
|
|
79
85
|
<title>${escapeHtml(title)}</title>
|
|
80
86
|
${cssTags}
|
|
87
|
+
${glossaryInline}
|
|
81
88
|
</head>
|
|
82
89
|
${bodyOpen}
|
|
83
90
|
${bodyHtml}
|
|
@@ -11,6 +11,13 @@
|
|
|
11
11
|
* directory via the index. This makes writingcontrol-shape entries
|
|
12
12
|
* (slug != fs path) list their items at the actual file location.
|
|
13
13
|
* Falls back to slug-template addressing for unbound / legacy entries.
|
|
14
|
+
*
|
|
15
|
+
* Issue #154 Dispatch D: this drawer is now a real bottom-anchored
|
|
16
|
+
* expandable drawer. The handle (header) is a clickable role=button
|
|
17
|
+
* that toggles `body[data-drawer]`; the drawer height transitions
|
|
18
|
+
* 4rem (collapsed) → 22rem (expanded). The standalone-viewer link is
|
|
19
|
+
* demoted to a small inline affordance — the primary action is now
|
|
20
|
+
* "expand the drawer" rather than "navigate away."
|
|
14
21
|
*/
|
|
15
22
|
import type { ContentIndex } from '@deskwork/core/content-index';
|
|
16
23
|
import type { CalendarEntry } from '@deskwork/core/types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-scrapbook-drawer.d.ts","sourceRoot":"","sources":["../../src/pages/review-scrapbook-drawer.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"review-scrapbook-drawer.d.ts","sourceRoot":"","sources":["../../src/pages/review-scrapbook-drawer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAYH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAOtD,OAAO,EAA4B,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAqFnE,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,aAAa,GAAG,IAAI,EAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CA6DT"}
|
|
@@ -11,13 +11,20 @@
|
|
|
11
11
|
* directory via the index. This makes writingcontrol-shape entries
|
|
12
12
|
* (slug != fs path) list their items at the actual file location.
|
|
13
13
|
* Falls back to slug-template addressing for unbound / legacy entries.
|
|
14
|
+
*
|
|
15
|
+
* Issue #154 Dispatch D: this drawer is now a real bottom-anchored
|
|
16
|
+
* expandable drawer. The handle (header) is a clickable role=button
|
|
17
|
+
* that toggles `body[data-drawer]`; the drawer height transitions
|
|
18
|
+
* 4rem (collapsed) → 22rem (expanded). The standalone-viewer link is
|
|
19
|
+
* demoted to a small inline affordance — the primary action is now
|
|
20
|
+
* "expand the drawer" rather than "navigate away."
|
|
14
21
|
*/
|
|
15
22
|
import { readFileSync } from 'node:fs';
|
|
16
23
|
import { join } from 'node:path';
|
|
17
24
|
import { listScrapbook, listScrapbookAtDir, scrapbookDirForEntry, } from '@deskwork/core/scrapbook';
|
|
18
25
|
import { resolveContentDir } from '@deskwork/core/paths';
|
|
19
26
|
import { renderEmptyScrapbookRow, renderReadOnlyScrapbookRow, scrapbookViewerUrl, } from "../components/scrapbook-item.js";
|
|
20
|
-
import { html, unsafe } from "./html.js";
|
|
27
|
+
import { html, unsafe, escapeHtml } from "./html.js";
|
|
21
28
|
/**
|
|
22
29
|
* Build an inline-text loader for the shared scrapbook-item renderer.
|
|
23
30
|
* Reads at most `maxBytes` from a file inside the scrapbook directory
|
|
@@ -48,11 +55,32 @@ function makeInlineTextLoader(ctx, site, entry, slug, index) {
|
|
|
48
55
|
}
|
|
49
56
|
function renderScrapbookDrawerItems(site, slug, items, loader) {
|
|
50
57
|
if (items.length === 0) {
|
|
51
|
-
return renderEmptyScrapbookRow();
|
|
58
|
+
return renderEmptyScrapbookRow({ site, path: slug });
|
|
52
59
|
}
|
|
53
60
|
const rows = items.map((item) => renderReadOnlyScrapbookRow({ site, path: slug }, item, { inlinePreviewLoader: loader }));
|
|
54
61
|
return unsafe(rows.map((r) => r.__raw).join(''));
|
|
55
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Build the "peek" line shown in the collapsed handle — up to 3 item
|
|
65
|
+
* filenames separated by `·`, plus a `+ N more` suffix when there are
|
|
66
|
+
* additional items. Empty scrapbook renders an inline empty-state hint
|
|
67
|
+
* so the operator still sees the surface.
|
|
68
|
+
*/
|
|
69
|
+
function renderPeek(items, secretItems) {
|
|
70
|
+
const all = [...items, ...secretItems];
|
|
71
|
+
if (all.length === 0) {
|
|
72
|
+
return '<span class="er-scrapbook-drawer-peek-empty">(empty — drop research here)</span>';
|
|
73
|
+
}
|
|
74
|
+
const shown = all
|
|
75
|
+
.slice(0, 3)
|
|
76
|
+
.map((i) => `<span>${escapeHtml(i.name)}</span>`)
|
|
77
|
+
.join('<span class="sep">·</span>');
|
|
78
|
+
const remaining = all.length - 3;
|
|
79
|
+
const suffix = remaining > 0
|
|
80
|
+
? `<span class="sep">·</span><span>+ ${remaining} more</span>`
|
|
81
|
+
: '';
|
|
82
|
+
return shown + suffix;
|
|
83
|
+
}
|
|
56
84
|
export function renderScrapbookDrawer(ctx, site, entry, slug, index) {
|
|
57
85
|
const summary = (() => {
|
|
58
86
|
try {
|
|
@@ -75,13 +103,24 @@ export function renderScrapbookDrawer(ctx, site, entry, slug, index) {
|
|
|
75
103
|
const loader = makeInlineTextLoader(ctx, site, entry, slug, index);
|
|
76
104
|
return unsafe(html `
|
|
77
105
|
<aside class="er-scrapbook-drawer" data-scrapbook-drawer aria-label="Scrapbook for this entry">
|
|
78
|
-
<header class="er-scrapbook-drawer-
|
|
79
|
-
|
|
106
|
+
<header class="er-scrapbook-drawer-handle" data-drawer-toggle role="button" tabindex="0"
|
|
107
|
+
aria-expanded="false" aria-controls="er-scrapbook-drawer-body">
|
|
108
|
+
<span class="er-scrapbook-drawer-kicker"><em>§</em> Scrapbook</span>
|
|
80
109
|
<span class="er-scrapbook-drawer-count">${total} ${total === 1 ? 'item' : 'items'}</span>
|
|
110
|
+
<span class="er-scrapbook-drawer-peek" aria-hidden="true">
|
|
111
|
+
${unsafe(renderPeek(items, secretItems))}
|
|
112
|
+
</span>
|
|
81
113
|
<a class="er-scrapbook-drawer-open" href="${scrapbookViewerUrl({ site, path: slug })}"
|
|
82
|
-
title="Open the standalone scrapbook viewer"
|
|
114
|
+
title="Open the standalone scrapbook viewer"
|
|
115
|
+
onclick="event.stopPropagation()">open viewer ↗</a>
|
|
116
|
+
<button class="er-scrapbook-drawer-toggle" type="button" data-drawer-toggle
|
|
117
|
+
aria-controls="er-scrapbook-drawer-body" tabindex="-1">
|
|
118
|
+
<span data-toggle-label>Expand</span>
|
|
119
|
+
<span class="chev" aria-hidden="true">▾</span>
|
|
120
|
+
</button>
|
|
83
121
|
</header>
|
|
84
|
-
<div class="er-scrapbook-drawer-body"
|
|
122
|
+
<div class="er-scrapbook-drawer-body" id="er-scrapbook-drawer-body"
|
|
123
|
+
role="region" aria-label="scrapbook items">
|
|
85
124
|
${renderScrapbookDrawerItems(site, slug, items, loader)}
|
|
86
125
|
${secretItems.length > 0
|
|
87
126
|
? unsafe(html `
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-scrapbook-drawer.js","sourceRoot":"","sources":["../../src/pages/review-scrapbook-drawer.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"review-scrapbook-drawer.js","sourceRoot":"","sources":["../../src/pages/review-scrapbook-drawer.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,13 @@
|
|
|
11
11
|
* directory via the index. This makes writingcontrol-shape entries
|
|
12
12
|
* (slug != fs path) list their items at the actual file location.
|
|
13
13
|
* Falls back to slug-template addressing for unbound / legacy entries.
|
|
14
|
+
*
|
|
15
|
+
* Issue #154 Dispatch D: this drawer is now a real bottom-anchored
|
|
16
|
+
* expandable drawer. The handle (header) is a clickable role=button
|
|
17
|
+
* that toggles `body[data-drawer]`; the drawer height transitions
|
|
18
|
+
* 4rem (collapsed) → 22rem (expanded). The standalone-viewer link is
|
|
19
|
+
* demoted to a small inline affordance — the primary action is now
|
|
20
|
+
* "expand the drawer" rather than "navigate away."
|
|
14
21
|
*/
|
|
15
22
|
|
|
16
23
|
import { readFileSync } from 'node:fs';
|
|
@@ -32,7 +39,7 @@ import {
|
|
|
32
39
|
scrapbookViewerUrl,
|
|
33
40
|
type InlineTextLoader,
|
|
34
41
|
} from '../components/scrapbook-item.ts';
|
|
35
|
-
import { html, unsafe, type RawHtml } from './html.ts';
|
|
42
|
+
import { html, unsafe, escapeHtml, type RawHtml } from './html.ts';
|
|
36
43
|
|
|
37
44
|
/**
|
|
38
45
|
* Build an inline-text loader for the shared scrapbook-item renderer.
|
|
@@ -79,7 +86,7 @@ function renderScrapbookDrawerItems(
|
|
|
79
86
|
loader: InlineTextLoader,
|
|
80
87
|
): RawHtml {
|
|
81
88
|
if (items.length === 0) {
|
|
82
|
-
return renderEmptyScrapbookRow();
|
|
89
|
+
return renderEmptyScrapbookRow({ site, path: slug });
|
|
83
90
|
}
|
|
84
91
|
const rows = items.map((item) =>
|
|
85
92
|
renderReadOnlyScrapbookRow(
|
|
@@ -91,6 +98,32 @@ function renderScrapbookDrawerItems(
|
|
|
91
98
|
return unsafe(rows.map((r) => r.__raw).join(''));
|
|
92
99
|
}
|
|
93
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Build the "peek" line shown in the collapsed handle — up to 3 item
|
|
103
|
+
* filenames separated by `·`, plus a `+ N more` suffix when there are
|
|
104
|
+
* additional items. Empty scrapbook renders an inline empty-state hint
|
|
105
|
+
* so the operator still sees the surface.
|
|
106
|
+
*/
|
|
107
|
+
function renderPeek(
|
|
108
|
+
items: readonly ScrapbookItem[],
|
|
109
|
+
secretItems: readonly ScrapbookItem[],
|
|
110
|
+
): string {
|
|
111
|
+
const all = [...items, ...secretItems];
|
|
112
|
+
if (all.length === 0) {
|
|
113
|
+
return '<span class="er-scrapbook-drawer-peek-empty">(empty — drop research here)</span>';
|
|
114
|
+
}
|
|
115
|
+
const shown = all
|
|
116
|
+
.slice(0, 3)
|
|
117
|
+
.map((i) => `<span>${escapeHtml(i.name)}</span>`)
|
|
118
|
+
.join('<span class="sep">·</span>');
|
|
119
|
+
const remaining = all.length - 3;
|
|
120
|
+
const suffix =
|
|
121
|
+
remaining > 0
|
|
122
|
+
? `<span class="sep">·</span><span>+ ${remaining} more</span>`
|
|
123
|
+
: '';
|
|
124
|
+
return shown + suffix;
|
|
125
|
+
}
|
|
126
|
+
|
|
94
127
|
export function renderScrapbookDrawer(
|
|
95
128
|
ctx: StudioContext,
|
|
96
129
|
site: string,
|
|
@@ -126,13 +159,24 @@ export function renderScrapbookDrawer(
|
|
|
126
159
|
|
|
127
160
|
return unsafe(html`
|
|
128
161
|
<aside class="er-scrapbook-drawer" data-scrapbook-drawer aria-label="Scrapbook for this entry">
|
|
129
|
-
<header class="er-scrapbook-drawer-
|
|
130
|
-
|
|
162
|
+
<header class="er-scrapbook-drawer-handle" data-drawer-toggle role="button" tabindex="0"
|
|
163
|
+
aria-expanded="false" aria-controls="er-scrapbook-drawer-body">
|
|
164
|
+
<span class="er-scrapbook-drawer-kicker"><em>§</em> Scrapbook</span>
|
|
131
165
|
<span class="er-scrapbook-drawer-count">${total} ${total === 1 ? 'item' : 'items'}</span>
|
|
166
|
+
<span class="er-scrapbook-drawer-peek" aria-hidden="true">
|
|
167
|
+
${unsafe(renderPeek(items, secretItems))}
|
|
168
|
+
</span>
|
|
132
169
|
<a class="er-scrapbook-drawer-open" href="${scrapbookViewerUrl({ site, path: slug })}"
|
|
133
|
-
title="Open the standalone scrapbook viewer"
|
|
170
|
+
title="Open the standalone scrapbook viewer"
|
|
171
|
+
onclick="event.stopPropagation()">open viewer ↗</a>
|
|
172
|
+
<button class="er-scrapbook-drawer-toggle" type="button" data-drawer-toggle
|
|
173
|
+
aria-controls="er-scrapbook-drawer-body" tabindex="-1">
|
|
174
|
+
<span data-toggle-label>Expand</span>
|
|
175
|
+
<span class="chev" aria-hidden="true">▾</span>
|
|
176
|
+
</button>
|
|
134
177
|
</header>
|
|
135
|
-
<div class="er-scrapbook-drawer-body"
|
|
178
|
+
<div class="er-scrapbook-drawer-body" id="er-scrapbook-drawer-body"
|
|
179
|
+
role="region" aria-label="scrapbook items">
|
|
136
180
|
${renderScrapbookDrawerItems(site, slug, items, loader)}
|
|
137
181
|
${
|
|
138
182
|
secretItems.length > 0
|