@deskwork/studio 0.21.0 → 0.22.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/adjacent-section.d.ts +38 -0
- package/dist/pages/dashboard/adjacent-section.d.ts.map +1 -0
- package/dist/pages/dashboard/adjacent-section.js +61 -0
- package/dist/pages/dashboard/adjacent-section.js.map +1 -0
- package/dist/pages/dashboard/adjacent-section.ts +71 -0
- package/dist/pages/dashboard/data.d.ts +35 -4
- package/dist/pages/dashboard/data.d.ts.map +1 -1
- package/dist/pages/dashboard/data.js +69 -5
- package/dist/pages/dashboard/data.js.map +1 -1
- package/dist/pages/dashboard/data.ts +84 -5
- package/dist/pages/dashboard/press-queue.d.ts +16 -0
- package/dist/pages/dashboard/press-queue.d.ts.map +1 -0
- package/dist/pages/dashboard/press-queue.js +91 -0
- package/dist/pages/dashboard/press-queue.js.map +1 -0
- package/dist/pages/dashboard/press-queue.ts +112 -0
- package/dist/pages/dashboard/section.d.ts.map +1 -1
- package/dist/pages/dashboard/section.js +7 -0
- package/dist/pages/dashboard/section.js.map +1 -1
- package/dist/pages/dashboard/section.ts +7 -0
- package/dist/pages/dashboard/shortform-section.d.ts +86 -0
- package/dist/pages/dashboard/shortform-section.d.ts.map +1 -0
- package/dist/pages/dashboard/shortform-section.js +189 -0
- package/dist/pages/dashboard/shortform-section.js.map +1 -0
- package/dist/pages/dashboard/shortform-section.ts +228 -0
- package/dist/pages/dashboard.d.ts.map +1 -1
- package/dist/pages/dashboard.js +34 -1
- package/dist/pages/dashboard.js.map +1 -1
- package/dist/pages/dashboard.ts +40 -1
- package/dist/pages/entry-review/index.d.ts.map +1 -1
- package/dist/pages/entry-review/index.js +24 -2
- package/dist/pages/entry-review/index.js.map +1 -1
- package/dist/pages/entry-review/mobile-sheet.d.ts +65 -0
- package/dist/pages/entry-review/mobile-sheet.d.ts.map +1 -0
- package/dist/pages/entry-review/mobile-sheet.js +170 -0
- package/dist/pages/entry-review/mobile-sheet.js.map +1 -0
- package/dist/pages/masthead-menu.d.ts +38 -0
- package/dist/pages/masthead-menu.d.ts.map +1 -0
- package/dist/pages/masthead-menu.js +126 -0
- package/dist/pages/masthead-menu.js.map +1 -0
- package/dist/pages/masthead-menu.ts +128 -0
- package/dist/pages/masthead.d.ts +85 -0
- package/dist/pages/masthead.d.ts.map +1 -0
- package/dist/pages/masthead.js +99 -0
- package/dist/pages/masthead.js.map +1 -0
- package/dist/pages/masthead.ts +155 -0
- package/dist/pages/mobile-bar.d.ts +72 -0
- package/dist/pages/mobile-bar.d.ts.map +1 -0
- package/dist/pages/mobile-bar.js +88 -0
- package/dist/pages/mobile-bar.js.map +1 -0
- package/dist/pages/mobile-bar.ts +129 -0
- package/dist/pages/shortform-review-mobile-sheet.d.ts +76 -0
- package/dist/pages/shortform-review-mobile-sheet.d.ts.map +1 -0
- package/dist/pages/shortform-review-mobile-sheet.js +159 -0
- package/dist/pages/shortform-review-mobile-sheet.js.map +1 -0
- package/dist/pages/shortform-review-mobile-sheet.ts +185 -0
- package/dist/pages/shortform-review.d.ts +18 -0
- package/dist/pages/shortform-review.d.ts.map +1 -1
- package/dist/pages/shortform-review.js +62 -111
- package/dist/pages/shortform-review.js.map +1 -1
- package/dist/pages/shortform-review.ts +68 -140
- package/dist/pages/shortform.d.ts.map +1 -1
- package/dist/pages/shortform.js +0 -1
- package/dist/pages/shortform.js.map +1 -1
- package/dist/pages/shortform.ts +0 -1
- package/dist/server.js +41 -1
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,112 @@
|
|
|
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
|
+
}
|
|
@@ -1 +1 @@
|
|
|
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,CAgDnF;
|
|
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,CAgDnF;AAsCD;;;;;;;;;;;;;;;;;;;;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,CAuBvD"}
|
|
@@ -113,9 +113,15 @@ function renderStageTile(stage, count) {
|
|
|
113
113
|
const isEmpty = count === 0;
|
|
114
114
|
const classes = isEmpty ? 'er-stage-tile is-empty' : 'er-stage-tile';
|
|
115
115
|
const disabledAttr = isEmpty ? ' disabled' : '';
|
|
116
|
+
// v7 architecture (Step 2.2.9): `data-stage-section-group="longform"`
|
|
117
|
+
// partitions single-expand state so the longform pipeline and the
|
|
118
|
+
// shortform-by-platform section operate independently. The client
|
|
119
|
+
// controller in `dashboard/stage-tiles.ts` reads this attribute to
|
|
120
|
+
// collapse only siblings in the same group when a tile is opened.
|
|
116
121
|
return unsafe(html `
|
|
117
122
|
<button class="${classes}" type="button"
|
|
118
123
|
data-stage-tile="${stage}"
|
|
124
|
+
data-stage-section-group="longform"
|
|
119
125
|
aria-expanded="false"
|
|
120
126
|
aria-controls="stage-${stage.toLowerCase()}"${unsafe(disabledAttr)}>
|
|
121
127
|
<span class="er-stage-tile-glyph" aria-hidden="true">${STAGE_ORNAMENTS[stage]}</span>
|
|
@@ -194,6 +200,7 @@ export function renderDistributionPlaceholder() {
|
|
|
194
200
|
<div class="er-stage-block" data-stage-block="Distribution">
|
|
195
201
|
<button class="er-stage-tile is-empty" type="button"
|
|
196
202
|
data-stage-tile="Distribution"
|
|
203
|
+
data-stage-section-group="longform"
|
|
197
204
|
aria-expanded="false"
|
|
198
205
|
aria-controls="stage-distribution" disabled>
|
|
199
206
|
<span class="er-stage-tile-glyph" aria-hidden="true">⌘</span>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section.js","sourceRoot":"","sources":["../../../src/pages/dashboard/section.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"section.js","sourceRoot":"","sources":["../../../src/pages/dashboard/section.ts"],"names":[],"mappings":"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"}
|
|
@@ -121,9 +121,15 @@ function renderStageTile(stage: Stage, count: number): RawHtml {
|
|
|
121
121
|
const isEmpty = count === 0;
|
|
122
122
|
const classes = isEmpty ? 'er-stage-tile is-empty' : 'er-stage-tile';
|
|
123
123
|
const disabledAttr = isEmpty ? ' disabled' : '';
|
|
124
|
+
// v7 architecture (Step 2.2.9): `data-stage-section-group="longform"`
|
|
125
|
+
// partitions single-expand state so the longform pipeline and the
|
|
126
|
+
// shortform-by-platform section operate independently. The client
|
|
127
|
+
// controller in `dashboard/stage-tiles.ts` reads this attribute to
|
|
128
|
+
// collapse only siblings in the same group when a tile is opened.
|
|
124
129
|
return unsafe(html`
|
|
125
130
|
<button class="${classes}" type="button"
|
|
126
131
|
data-stage-tile="${stage}"
|
|
132
|
+
data-stage-section-group="longform"
|
|
127
133
|
aria-expanded="false"
|
|
128
134
|
aria-controls="stage-${stage.toLowerCase()}"${unsafe(disabledAttr)}>
|
|
129
135
|
<span class="er-stage-tile-glyph" aria-hidden="true">${STAGE_ORNAMENTS[stage]}</span>
|
|
@@ -211,6 +217,7 @@ export function renderDistributionPlaceholder(): RawHtml {
|
|
|
211
217
|
<div class="er-stage-block" data-stage-block="Distribution">
|
|
212
218
|
<button class="er-stage-tile is-empty" type="button"
|
|
213
219
|
data-stage-tile="Distribution"
|
|
220
|
+
data-stage-section-group="longform"
|
|
214
221
|
aria-expanded="false"
|
|
215
222
|
aria-controls="stage-distribution" disabled>
|
|
216
223
|
<span class="er-stage-tile-glyph" aria-hidden="true">⌘</span>
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shortform-by-platform section renderer (Step 2.2.9 — studio-mobile-first).
|
|
3
|
+
*
|
|
4
|
+
* Per DESIGN-STANDARDS.md § Desk information architecture, the Desk's
|
|
5
|
+
* second section absorbs the legacy `/dev/editorial-review-shortform`
|
|
6
|
+
* page as four platform tiles (LinkedIn / Reddit / YouTube / Instagram),
|
|
7
|
+
* each collapsible to reveal that platform's open workflows. Tiles share
|
|
8
|
+
* the longform-pipeline tile shape (data-stage-tile + aria-expanded +
|
|
9
|
+
* data-stage-section attrs) so the existing `dashboard/stage-tiles.ts`
|
|
10
|
+
* client controller can drive both. `data-stage-section-group="shortform"`
|
|
11
|
+
* partitions single-expand state so longform and shortform open
|
|
12
|
+
* independently.
|
|
13
|
+
*
|
|
14
|
+
* Per DESKWORK-STATE-MACHINE.md Commandment III, rows do NOT render
|
|
15
|
+
* `.er-stamp` / `er-stamp-<state>` chrome. The pre-v7 shortform page
|
|
16
|
+
* rendered review-state stamps inline; this section does not.
|
|
17
|
+
*
|
|
18
|
+
* Per THESIS Consequence 2, rows are navigation-only. The trailing `⋮`
|
|
19
|
+
* placeholder anchor links to `/dev/editorial-review/<workflow.id>`;
|
|
20
|
+
* Step 2.2.10 lands the v0.20-style row popover with stage-aware verbs
|
|
21
|
+
* once the shortform verb-routing pieces (issues G.1-G.6) land. This
|
|
22
|
+
* commit does NOT smuggle verb-routing in early. Tracked in
|
|
23
|
+
* https://github.com/audiocontrol-org/deskwork/issues/263.
|
|
24
|
+
*
|
|
25
|
+
* TRANSITIONAL SHAPE: this row's `er-row-shell` markup is a strict
|
|
26
|
+
* subset of the longform row shell defined in
|
|
27
|
+
* `dashboard/section.ts:renderRow`. Longform shells carry three
|
|
28
|
+
* children (`er-row-drawer`, `er-row-fg`, `er-row-menu`); this shell
|
|
29
|
+
* carries only the `er-row-fg`. Step 2.2.10's popover wire-up is
|
|
30
|
+
* purely additive on the existing shape — it inserts the missing
|
|
31
|
+
* `er-row-menu` (and possibly `er-row-drawer` if a swipe gesture is
|
|
32
|
+
* scoped in). Keep the two row paths' attribute conventions aligned
|
|
33
|
+
* (data-row-shell, data-platform, data-site, data-slug already match)
|
|
34
|
+
* so the unification stays straightforward.
|
|
35
|
+
*/
|
|
36
|
+
import { type RawHtml } from '../html.ts';
|
|
37
|
+
import type { DraftWorkflowItem } from '@deskwork/core/review/types';
|
|
38
|
+
import type { Platform } from '@deskwork/core/types';
|
|
39
|
+
/**
|
|
40
|
+
* Render the shortform section head — `<div class="er-desk-section-head
|
|
41
|
+
* er-desk-section-head--shortform">` matching the mockup's
|
|
42
|
+
* `.desk-section-head.shortform` shape. Glyph + label + caption count.
|
|
43
|
+
*/
|
|
44
|
+
export declare function renderShortformSectionHead(totalCount: number): RawHtml;
|
|
45
|
+
/**
|
|
46
|
+
* Render one platform tile. Shares its tile shape + a11y attrs with the
|
|
47
|
+
* longform stage tile so the stage-tiles.ts client controller drives
|
|
48
|
+
* both. Empty platforms get `disabled` + `.is-empty` so the operator
|
|
49
|
+
* sees the platform exists but cannot drill into nothing.
|
|
50
|
+
*/
|
|
51
|
+
export declare function renderShortformPlatformTile(platform: Platform, count: number): RawHtml;
|
|
52
|
+
/**
|
|
53
|
+
* Render a single shortform workflow row. Mirrors the v0.20 row-affordance
|
|
54
|
+
* shape: shell + foreground (slug + title + channel) + meta column (ts +
|
|
55
|
+
* version) + trailing `⋮`. The `⋮` is a navigation placeholder anchor —
|
|
56
|
+
* Step 2.2.10 wires the stage-aware row popover.
|
|
57
|
+
*/
|
|
58
|
+
export declare function renderShortformRow(workflow: DraftWorkflowItem, now: Date): RawHtml;
|
|
59
|
+
/**
|
|
60
|
+
* Section data shape — the renderer reads counts + workflows per platform
|
|
61
|
+
* from the dashboard's loadDashboardData() output. Caller passes the
|
|
62
|
+
* ordered Map directly (insertion order = display order).
|
|
63
|
+
*/
|
|
64
|
+
export interface ShortformSectionData {
|
|
65
|
+
readonly shortformByPlatform: ReadonlyMap<Platform, readonly DraftWorkflowItem[]>;
|
|
66
|
+
readonly totalCount: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Compose the full shortform section: head + 4 platform tiles + per-
|
|
70
|
+
* platform row groups, in `DASHBOARD_PLATFORM_ORDER` order. All 4
|
|
71
|
+
* platforms render even when zero — empty tiles communicate platform
|
|
72
|
+
* existence (per § Empty-state rendering, "the absence of items is
|
|
73
|
+
* information about the pipeline shape").
|
|
74
|
+
*
|
|
75
|
+
* API shape note: this helper iterates platforms internally (single
|
|
76
|
+
* call → whole section), whereas the longform `renderStageSection` is
|
|
77
|
+
* called per-stage by `dashboard.ts` (caller iterates). The asymmetry
|
|
78
|
+
* is intentional: longform stages share a uniform shape across all
|
|
79
|
+
* eight stages, so the caller-iterates pattern keeps the loop visible
|
|
80
|
+
* in `dashboard.ts`. Shortform's four platforms share a section head
|
|
81
|
+
* and ordered iteration constraint that lives more cleanly inside the
|
|
82
|
+
* composer. If a future surface needs both shapes via a common
|
|
83
|
+
* abstraction, the unification belongs there, not here.
|
|
84
|
+
*/
|
|
85
|
+
export declare function renderShortformSection(data: ShortformSectionData, now: Date): RawHtml;
|
|
86
|
+
//# sourceMappingURL=shortform-section.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortform-section.d.ts","sourceRoot":"","sources":["../../../src/pages/dashboard/shortform-section.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAoBrD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAOtE;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAmBT;AAaD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,iBAAiB,EAC3B,GAAG,EAAE,IAAI,GACR,OAAO,CAqCT;AA6BD;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,mBAAmB,EAAE,WAAW,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC,CAAC;IAClF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,IAAI,GACR,OAAO,CAST"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shortform-by-platform section renderer (Step 2.2.9 — studio-mobile-first).
|
|
3
|
+
*
|
|
4
|
+
* Per DESIGN-STANDARDS.md § Desk information architecture, the Desk's
|
|
5
|
+
* second section absorbs the legacy `/dev/editorial-review-shortform`
|
|
6
|
+
* page as four platform tiles (LinkedIn / Reddit / YouTube / Instagram),
|
|
7
|
+
* each collapsible to reveal that platform's open workflows. Tiles share
|
|
8
|
+
* the longform-pipeline tile shape (data-stage-tile + aria-expanded +
|
|
9
|
+
* data-stage-section attrs) so the existing `dashboard/stage-tiles.ts`
|
|
10
|
+
* client controller can drive both. `data-stage-section-group="shortform"`
|
|
11
|
+
* partitions single-expand state so longform and shortform open
|
|
12
|
+
* independently.
|
|
13
|
+
*
|
|
14
|
+
* Per DESKWORK-STATE-MACHINE.md Commandment III, rows do NOT render
|
|
15
|
+
* `.er-stamp` / `er-stamp-<state>` chrome. The pre-v7 shortform page
|
|
16
|
+
* rendered review-state stamps inline; this section does not.
|
|
17
|
+
*
|
|
18
|
+
* Per THESIS Consequence 2, rows are navigation-only. The trailing `⋮`
|
|
19
|
+
* placeholder anchor links to `/dev/editorial-review/<workflow.id>`;
|
|
20
|
+
* Step 2.2.10 lands the v0.20-style row popover with stage-aware verbs
|
|
21
|
+
* once the shortform verb-routing pieces (issues G.1-G.6) land. This
|
|
22
|
+
* commit does NOT smuggle verb-routing in early. Tracked in
|
|
23
|
+
* https://github.com/audiocontrol-org/deskwork/issues/263.
|
|
24
|
+
*
|
|
25
|
+
* TRANSITIONAL SHAPE: this row's `er-row-shell` markup is a strict
|
|
26
|
+
* subset of the longform row shell defined in
|
|
27
|
+
* `dashboard/section.ts:renderRow`. Longform shells carry three
|
|
28
|
+
* children (`er-row-drawer`, `er-row-fg`, `er-row-menu`); this shell
|
|
29
|
+
* carries only the `er-row-fg`. Step 2.2.10's popover wire-up is
|
|
30
|
+
* purely additive on the existing shape — it inserts the missing
|
|
31
|
+
* `er-row-menu` (and possibly `er-row-drawer` if a swipe gesture is
|
|
32
|
+
* scoped in). Keep the two row paths' attribute conventions aligned
|
|
33
|
+
* (data-row-shell, data-platform, data-site, data-slug already match)
|
|
34
|
+
* so the unification stays straightforward.
|
|
35
|
+
*/
|
|
36
|
+
import { html, unsafe } from "../html.js";
|
|
37
|
+
import { DASHBOARD_PLATFORM_ORDER } from "./data.js";
|
|
38
|
+
const PLATFORM_CHROME = {
|
|
39
|
+
linkedin: { badge: 'in', name: 'LinkedIn', variant: 'linkedin' },
|
|
40
|
+
reddit: { badge: 'r/', name: 'Reddit', variant: 'reddit' },
|
|
41
|
+
youtube: { badge: '@', name: 'YouTube', variant: 'youtube' },
|
|
42
|
+
instagram: { badge: 'IG', name: 'Instagram', variant: 'instagram' },
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Render the shortform section head — `<div class="er-desk-section-head
|
|
46
|
+
* er-desk-section-head--shortform">` matching the mockup's
|
|
47
|
+
* `.desk-section-head.shortform` shape. Glyph + label + caption count.
|
|
48
|
+
*/
|
|
49
|
+
export function renderShortformSectionHead(totalCount) {
|
|
50
|
+
return unsafe(html `
|
|
51
|
+
<div class="er-desk-section-head er-desk-section-head--shortform">
|
|
52
|
+
<span class="er-desk-section-head-glyph" aria-hidden="true">⊟</span>
|
|
53
|
+
<span class="er-desk-section-head-label">Shortform · by platform</span>
|
|
54
|
+
<span class="er-desk-section-head-count">· ${totalCount} ${totalCount === 1 ? 'workflow' : 'workflows'}</span>
|
|
55
|
+
</div>`);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Render one platform tile. Shares its tile shape + a11y attrs with the
|
|
59
|
+
* longform stage tile so the stage-tiles.ts client controller drives
|
|
60
|
+
* both. Empty platforms get `disabled` + `.is-empty` so the operator
|
|
61
|
+
* sees the platform exists but cannot drill into nothing.
|
|
62
|
+
*/
|
|
63
|
+
export function renderShortformPlatformTile(platform, count) {
|
|
64
|
+
const chrome = PLATFORM_CHROME[platform];
|
|
65
|
+
const isEmpty = count === 0;
|
|
66
|
+
const classes = isEmpty
|
|
67
|
+
? 'er-stage-tile er-stage-tile--shortform is-empty'
|
|
68
|
+
: 'er-stage-tile er-stage-tile--shortform';
|
|
69
|
+
const disabledAttr = isEmpty ? ' disabled' : '';
|
|
70
|
+
const sectionId = `shortform-${platform}`;
|
|
71
|
+
return unsafe(html `
|
|
72
|
+
<button class="${classes}" type="button"
|
|
73
|
+
data-stage-tile="${sectionId}"
|
|
74
|
+
data-stage-section-group="shortform"
|
|
75
|
+
aria-expanded="false"
|
|
76
|
+
aria-controls="${sectionId}"${unsafe(disabledAttr)}>
|
|
77
|
+
<span class="er-platform-badge er-platform-badge--${chrome.variant}" aria-hidden="true">${chrome.badge}</span>
|
|
78
|
+
<span class="er-stage-tile-name">${chrome.name}</span>
|
|
79
|
+
<span class="er-stage-tile-count"><span class="num">${count}</span></span>
|
|
80
|
+
<span class="er-stage-tile-chev" aria-hidden="true">›</span>
|
|
81
|
+
</button>`);
|
|
82
|
+
}
|
|
83
|
+
function fmtRelTime(iso, now) {
|
|
84
|
+
const t = new Date(iso).getTime();
|
|
85
|
+
const s = Math.max(0, Math.floor((now.getTime() - t) / 1000));
|
|
86
|
+
if (s < 60)
|
|
87
|
+
return `${s}s ago`;
|
|
88
|
+
const m = Math.floor(s / 60);
|
|
89
|
+
if (m < 60)
|
|
90
|
+
return `${m}m ago`;
|
|
91
|
+
const h = Math.floor(m / 60);
|
|
92
|
+
if (h < 48)
|
|
93
|
+
return `${h}h ago`;
|
|
94
|
+
return `${Math.floor(h / 24)}d ago`;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Render a single shortform workflow row. Mirrors the v0.20 row-affordance
|
|
98
|
+
* shape: shell + foreground (slug + title + channel) + meta column (ts +
|
|
99
|
+
* version) + trailing `⋮`. The `⋮` is a navigation placeholder anchor —
|
|
100
|
+
* Step 2.2.10 wires the stage-aware row popover.
|
|
101
|
+
*/
|
|
102
|
+
export function renderShortformRow(workflow, now) {
|
|
103
|
+
// workflow.id is typed as `string` on DraftWorkflowItem; UUIDs are the
|
|
104
|
+
// current shape but the type system doesn't enforce that. Encode the
|
|
105
|
+
// path segment so a future non-UUID id (e.g. one containing `?`, `#`,
|
|
106
|
+
// space) doesn't silently produce a broken link.
|
|
107
|
+
const reviewLink = `/dev/editorial-review/${encodeURIComponent(workflow.id)}`;
|
|
108
|
+
const search = [workflow.slug, workflow.channel ?? '', workflow.platform ?? '']
|
|
109
|
+
.join(' ')
|
|
110
|
+
.toLowerCase();
|
|
111
|
+
const channelMarkup = workflow.channel
|
|
112
|
+
? unsafe(html `<span class="er-row-shell-channel">${workflow.channel}</span>`)
|
|
113
|
+
: unsafe('');
|
|
114
|
+
// The workflow `slug` is the post slug; we surface it as the row's
|
|
115
|
+
// primary handle (consistent with longform rows). The workflow `id` is
|
|
116
|
+
// the navigation key (uuid in the review-pipeline store).
|
|
117
|
+
return unsafe(html `
|
|
118
|
+
<div class="er-row-shell er-row-shell--shortform"
|
|
119
|
+
data-row-shell data-search="${search}"
|
|
120
|
+
data-workflow-id="${workflow.id}"
|
|
121
|
+
data-platform="${workflow.platform ?? ''}"
|
|
122
|
+
data-site="${workflow.site}"
|
|
123
|
+
data-slug="${workflow.slug}">
|
|
124
|
+
<div class="er-row-fg er-shortform-row-fg">
|
|
125
|
+
<div class="er-shortform-row-body">
|
|
126
|
+
<span class="er-row-shell-slug"><a href="${reviewLink}"
|
|
127
|
+
title="open the review surface">${workflow.slug}</a></span>
|
|
128
|
+
${channelMarkup}
|
|
129
|
+
</div>
|
|
130
|
+
<div class="er-shortform-row-meta">
|
|
131
|
+
<span class="er-shortform-row-ts">${fmtRelTime(workflow.updatedAt, now)}</span>
|
|
132
|
+
<span class="er-shortform-row-version">v${workflow.currentVersion}</span>
|
|
133
|
+
</div>
|
|
134
|
+
<a class="er-row-shell-link" href="${reviewLink}"
|
|
135
|
+
aria-label="Open shortform review for ${workflow.slug}"
|
|
136
|
+
title="open the review surface">⋮</a>
|
|
137
|
+
</div>
|
|
138
|
+
</div>`);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Render the platform's row group — the `<div class="er-row-group">`
|
|
142
|
+
* container holding all rows for that platform. The container carries
|
|
143
|
+
* the `data-stage-section` attr the stage-tiles.ts controller targets
|
|
144
|
+
* to apply `data-collapsed`.
|
|
145
|
+
*/
|
|
146
|
+
function renderPlatformRowGroup(platform, workflows, now) {
|
|
147
|
+
const sectionId = `shortform-${platform}`;
|
|
148
|
+
if (workflows.length === 0) {
|
|
149
|
+
// Empty platform — still emit the row-group container so the
|
|
150
|
+
// controller's `[data-stage-section="<id>"]` selector resolves. The
|
|
151
|
+
// tile is `disabled` so it cannot expand anyway; the empty container
|
|
152
|
+
// is structurally inert.
|
|
153
|
+
return unsafe(html `
|
|
154
|
+
<div class="er-row-group" id="${sectionId}" data-stage-section="${sectionId}"></div>`);
|
|
155
|
+
}
|
|
156
|
+
const rows = workflows.map((w) => renderShortformRow(w, now).__raw).join('');
|
|
157
|
+
return unsafe(html `
|
|
158
|
+
<div class="er-row-group" id="${sectionId}" data-stage-section="${sectionId}">
|
|
159
|
+
${unsafe(rows)}
|
|
160
|
+
</div>`);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Compose the full shortform section: head + 4 platform tiles + per-
|
|
164
|
+
* platform row groups, in `DASHBOARD_PLATFORM_ORDER` order. All 4
|
|
165
|
+
* platforms render even when zero — empty tiles communicate platform
|
|
166
|
+
* existence (per § Empty-state rendering, "the absence of items is
|
|
167
|
+
* information about the pipeline shape").
|
|
168
|
+
*
|
|
169
|
+
* API shape note: this helper iterates platforms internally (single
|
|
170
|
+
* call → whole section), whereas the longform `renderStageSection` is
|
|
171
|
+
* called per-stage by `dashboard.ts` (caller iterates). The asymmetry
|
|
172
|
+
* is intentional: longform stages share a uniform shape across all
|
|
173
|
+
* eight stages, so the caller-iterates pattern keeps the loop visible
|
|
174
|
+
* in `dashboard.ts`. Shortform's four platforms share a section head
|
|
175
|
+
* and ordered iteration constraint that lives more cleanly inside the
|
|
176
|
+
* composer. If a future surface needs both shapes via a common
|
|
177
|
+
* abstraction, the unification belongs there, not here.
|
|
178
|
+
*/
|
|
179
|
+
export function renderShortformSection(data, now) {
|
|
180
|
+
const sectionHead = renderShortformSectionHead(data.totalCount);
|
|
181
|
+
const tilesAndGroups = DASHBOARD_PLATFORM_ORDER.map((platform) => {
|
|
182
|
+
const workflows = data.shortformByPlatform.get(platform) ?? [];
|
|
183
|
+
const tile = renderShortformPlatformTile(platform, workflows.length);
|
|
184
|
+
const group = renderPlatformRowGroup(platform, workflows, now);
|
|
185
|
+
return `${tile.__raw}${group.__raw}`;
|
|
186
|
+
}).join('');
|
|
187
|
+
return unsafe(html `${sectionHead}${unsafe(tilesAndGroups)}`);
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=shortform-section.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortform-section.js","sourceRoot":"","sources":["../../../src/pages/dashboard/shortform-section.ts"],"names":[],"mappings":"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"}
|