@deskwork/studio 0.20.0 → 0.21.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deskwork/studio",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "type": "module",
5
5
  "description": "Editorial review studio — local web UI for the deskwork plugin",
6
6
  "homepage": "https://github.com/audiocontrol-org/deskwork#readme",
@@ -46,7 +46,7 @@
46
46
  "@codemirror/language": "^6.12.3",
47
47
  "@codemirror/state": "^6.6.0",
48
48
  "@codemirror/view": "^6.41.1",
49
- "@deskwork/core": "0.20.0",
49
+ "@deskwork/core": "0.21.0",
50
50
  "@hono/node-server": "^1.13.7",
51
51
  "@lezer/highlight": "^1.2.3",
52
52
  "esbuild": "^0.28.0",
@@ -1,16 +0,0 @@
1
- /**
2
- * Press-queue sidebar — the dashboard's right column.
3
- *
4
- * "Press-check" gravity: at the press, the operator wants to know what
5
- * needs their eyes RIGHT NOW, separately from the at-a-glance pipeline
6
- * view on the left. This panel surfaces every entry in active review
7
- * (`reviewState === 'in-review'`), longest-waiting first, with a soft
8
- * empty state when the press is quiet.
9
- *
10
- * Closes the long-empty right column the dashboard's `.er-layout` grid
11
- * has been declaring since the surface shipped (#158 child concern).
12
- */
13
- import { type RawHtml } from '../html.ts';
14
- import type { Entry } from '@deskwork/core/schema/entry';
15
- export declare function renderPressQueue(entries: readonly Entry[], defaultSite: string, now: Date): RawHtml;
16
- //# sourceMappingURL=press-queue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"press-queue.d.ts","sourceRoot":"","sources":["../../../src/pages/dashboard/press-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAS,MAAM,6BAA6B,CAAC;AAsEhE,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,SAAS,KAAK,EAAE,EACzB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,IAAI,GACR,OAAO,CAuBT"}
@@ -1,91 +0,0 @@
1
- /**
2
- * Press-queue sidebar — the dashboard's right column.
3
- *
4
- * "Press-check" gravity: at the press, the operator wants to know what
5
- * needs their eyes RIGHT NOW, separately from the at-a-glance pipeline
6
- * view on the left. This panel surfaces every entry in active review
7
- * (`reviewState === 'in-review'`), longest-waiting first, with a soft
8
- * empty state when the press is quiet.
9
- *
10
- * Closes the long-empty right column the dashboard's `.er-layout` grid
11
- * has been declaring since the surface shipped (#158 child concern).
12
- */
13
- import { html, unsafe } from "../html.js";
14
- import { formatRelativeTime } from '@deskwork/core/scrapbook';
15
- const STAGE_ORNAMENTS = {
16
- Ideas: '◇',
17
- Planned: '§',
18
- Outlining: '⊹',
19
- Drafting: '✎',
20
- Final: '※',
21
- Published: '✓',
22
- Blocked: '⊘',
23
- Cancelled: '✗',
24
- };
25
- /**
26
- * Filter the dashboard's entries to those currently in review and
27
- * sort longest-waiting first. The "longest waiting" axis is `updatedAt`
28
- * — every iterate / review-state-change writes to it, so the entry
29
- * whose updatedAt is oldest is the one the operator has been ignoring
30
- * longest.
31
- */
32
- function selectAwaitingItems(entries, now) {
33
- const items = [];
34
- for (const entry of entries) {
35
- if (entry.reviewState !== 'in-review')
36
- continue;
37
- const updatedAt = new Date(entry.updatedAt).getTime();
38
- items.push({ entry, waitedMs: now.getTime() - updatedAt });
39
- }
40
- items.sort((a, b) => b.waitedMs - a.waitedMs);
41
- return items;
42
- }
43
- function renderItem(item, defaultSite, now) {
44
- const { entry } = item;
45
- void defaultSite;
46
- const reviewLink = `/dev/editorial-review/entry/${entry.uuid}`;
47
- return unsafe(html `
48
- <li class="er-press-queue__item" data-stage="${entry.currentStage}">
49
- <a class="er-press-queue__link" href="${reviewLink}">
50
- <span class="er-press-queue__ornament" aria-hidden="true">${STAGE_ORNAMENTS[entry.currentStage]}</span>
51
- <span class="er-press-queue__body">
52
- <span class="er-press-queue__slug">${entry.slug}</span>
53
- <span class="er-press-queue__meta">
54
- <span class="er-press-queue__stage">${entry.currentStage}</span>
55
- <span class="er-press-queue__sep" aria-hidden="true">·</span>
56
- <span class="er-press-queue__waited">${formatRelativeTime(entry.updatedAt, now)}</span>
57
- </span>
58
- </span>
59
- </a>
60
- </li>`);
61
- }
62
- function renderEmptyState() {
63
- return unsafe(html `
64
- <div class="er-press-queue__empty">
65
- <span class="er-press-queue__empty-mark" aria-hidden="true">※</span>
66
- <p class="er-press-queue__empty-line">The press is quiet.</p>
67
- <p class="er-press-queue__empty-hint">Nothing in review.</p>
68
- </div>`);
69
- }
70
- export function renderPressQueue(entries, defaultSite, now) {
71
- const items = selectAwaitingItems(entries, now);
72
- const body = items.length === 0
73
- ? renderEmptyState()
74
- : unsafe(html `
75
- <ol class="er-press-queue__list">
76
- ${unsafe(items
77
- .map((item) => renderItem(item, defaultSite, now).__raw)
78
- .join('\n'))}
79
- </ol>`);
80
- return unsafe(html `
81
- <aside class="er-press-queue${items.length === 0 ? ' er-press-queue--empty' : ''}"
82
- aria-label="Awaiting your eyes">
83
- <header class="er-press-queue__head">
84
- <p class="er-press-queue__kicker">Press queue</p>
85
- <h2 class="er-press-queue__title">Awaiting your <em>eyes</em></h2>
86
- <p class="er-press-queue__count">№ ${items.length}</p>
87
- </header>
88
- ${body}
89
- </aside>`);
90
- }
91
- //# sourceMappingURL=press-queue.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"press-queue.js","sourceRoot":"","sources":["../../../src/pages/dashboard/press-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,eAAe,GAA0B;IAC7C,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG;IACZ,SAAS,EAAE,GAAG;IACd,QAAQ,EAAE,GAAG;IACb,KAAK,EAAE,GAAG;IACV,SAAS,EAAE,GAAG;IACd,OAAO,EAAE,GAAG;IACZ,SAAS,EAAE,GAAG;CACf,CAAC;AAOF;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,OAAyB,EAAE,GAAS;IAC/D,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,WAAW,KAAK,WAAW;YAAE,SAAS;QAChD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CACjB,IAAkB,EAClB,WAAmB,EACnB,GAAS;IAET,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACvB,KAAK,WAAW,CAAC;IACjB,MAAM,UAAU,GAAG,+BAA+B,KAAK,CAAC,IAAI,EAAE,CAAC;IAC/D,OAAO,MAAM,CAAC,IAAI,CAAA;mDAC+B,KAAK,CAAC,YAAY;8CACvB,UAAU;oEACY,eAAe,CAAC,KAAK,CAAC,YAAY,CAAC;;+CAExD,KAAK,CAAC,IAAI;;kDAEP,KAAK,CAAC,YAAY;;mDAEjB,kBAAkB,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC;;;;UAIjF,CAAC,CAAC;AACZ,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,MAAM,CAAC,IAAI,CAAA;;;;;WAKT,CAAC,CAAC;AACb,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,OAAyB,EACzB,WAAmB,EACnB,GAAS;IAET,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,IAAI,GACR,KAAK,CAAC,MAAM,KAAK,CAAC;QAChB,CAAC,CAAC,gBAAgB,EAAE;QACpB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAA;;cAEL,MAAM,CACN,KAAK;aACF,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC;aACvD,IAAI,CAAC,IAAI,CAAC,CACd;gBACG,CAAC,CAAC;IAChB,OAAO,MAAM,CAAC,IAAI,CAAA;kCACc,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE;;;;;6CAKvC,KAAK,CAAC,MAAM;;QAEjD,IAAI;aACC,CAAC,CAAC;AACf,CAAC"}
@@ -1,112 +0,0 @@
1
- /**
2
- * Press-queue sidebar — the dashboard's right column.
3
- *
4
- * "Press-check" gravity: at the press, the operator wants to know what
5
- * needs their eyes RIGHT NOW, separately from the at-a-glance pipeline
6
- * view on the left. This panel surfaces every entry in active review
7
- * (`reviewState === 'in-review'`), longest-waiting first, with a soft
8
- * empty state when the press is quiet.
9
- *
10
- * Closes the long-empty right column the dashboard's `.er-layout` grid
11
- * has been declaring since the surface shipped (#158 child concern).
12
- */
13
-
14
- import { html, unsafe, type RawHtml } from '../html.ts';
15
- import type { Entry, Stage } from '@deskwork/core/schema/entry';
16
- import { formatRelativeTime } from '@deskwork/core/scrapbook';
17
-
18
- const STAGE_ORNAMENTS: Record<Stage, string> = {
19
- Ideas: '◇',
20
- Planned: '§',
21
- Outlining: '⊹',
22
- Drafting: '✎',
23
- Final: '※',
24
- Published: '✓',
25
- Blocked: '⊘',
26
- Cancelled: '✗',
27
- };
28
-
29
- interface AwaitingItem {
30
- readonly entry: Entry;
31
- readonly waitedMs: number;
32
- }
33
-
34
- /**
35
- * Filter the dashboard's entries to those currently in review and
36
- * sort longest-waiting first. The "longest waiting" axis is `updatedAt`
37
- * — every iterate / review-state-change writes to it, so the entry
38
- * whose updatedAt is oldest is the one the operator has been ignoring
39
- * longest.
40
- */
41
- function selectAwaitingItems(entries: readonly Entry[], now: Date): AwaitingItem[] {
42
- const items: AwaitingItem[] = [];
43
- for (const entry of entries) {
44
- if (entry.reviewState !== 'in-review') continue;
45
- const updatedAt = new Date(entry.updatedAt).getTime();
46
- items.push({ entry, waitedMs: now.getTime() - updatedAt });
47
- }
48
- items.sort((a, b) => b.waitedMs - a.waitedMs);
49
- return items;
50
- }
51
-
52
- function renderItem(
53
- item: AwaitingItem,
54
- defaultSite: string,
55
- now: Date,
56
- ): RawHtml {
57
- const { entry } = item;
58
- void defaultSite;
59
- const reviewLink = `/dev/editorial-review/entry/${entry.uuid}`;
60
- return unsafe(html`
61
- <li class="er-press-queue__item" data-stage="${entry.currentStage}">
62
- <a class="er-press-queue__link" href="${reviewLink}">
63
- <span class="er-press-queue__ornament" aria-hidden="true">${STAGE_ORNAMENTS[entry.currentStage]}</span>
64
- <span class="er-press-queue__body">
65
- <span class="er-press-queue__slug">${entry.slug}</span>
66
- <span class="er-press-queue__meta">
67
- <span class="er-press-queue__stage">${entry.currentStage}</span>
68
- <span class="er-press-queue__sep" aria-hidden="true">·</span>
69
- <span class="er-press-queue__waited">${formatRelativeTime(entry.updatedAt, now)}</span>
70
- </span>
71
- </span>
72
- </a>
73
- </li>`);
74
- }
75
-
76
- function renderEmptyState(): RawHtml {
77
- return unsafe(html`
78
- <div class="er-press-queue__empty">
79
- <span class="er-press-queue__empty-mark" aria-hidden="true">※</span>
80
- <p class="er-press-queue__empty-line">The press is quiet.</p>
81
- <p class="er-press-queue__empty-hint">Nothing in review.</p>
82
- </div>`);
83
- }
84
-
85
- export function renderPressQueue(
86
- entries: readonly Entry[],
87
- defaultSite: string,
88
- now: Date,
89
- ): RawHtml {
90
- const items = selectAwaitingItems(entries, now);
91
- const body =
92
- items.length === 0
93
- ? renderEmptyState()
94
- : unsafe(html`
95
- <ol class="er-press-queue__list">
96
- ${unsafe(
97
- items
98
- .map((item) => renderItem(item, defaultSite, now).__raw)
99
- .join('\n'),
100
- )}
101
- </ol>`);
102
- return unsafe(html`
103
- <aside class="er-press-queue${items.length === 0 ? ' er-press-queue--empty' : ''}"
104
- aria-label="Awaiting your eyes">
105
- <header class="er-press-queue__head">
106
- <p class="er-press-queue__kicker">Press queue</p>
107
- <h2 class="er-press-queue__title">Awaiting your <em>eyes</em></h2>
108
- <p class="er-press-queue__count">№ ${items.length}</p>
109
- </header>
110
- ${body}
111
- </aside>`);
112
- }