plan/03-publishing.md
03 · Publishing: tray + Changes page (Wave 2)
TL;DR: local staging stays; "Save to draft" puts edits into one shared Policy Config draft (D4). The Changes page becomes: the shared draft (v13 · N pending changes, author per line, BlastRadius of the whole draft, Publish with a note), Policy Config versions (v13 live, rollback with a note, propagation bar), the log, and the config as syntax-coloured JSON with Download and Import.
Owns: app/pages/pages/phase4/mock/changes.vue, app/components/governance/mock/PublishTray.vue, app/layouts/governance-mock.vue, new app/components/governance/mock/ConfigJson.vue. Uses 00's publishing API and configJson/importConfig/fleetSummary, 01's BlastRadius.
Today
- Tray
PublishTray.vue: "Locally Staged Edits · N" (l.23), numbered list, "Preview changes in dashboard" (l.38–41), "Submit as draft…" title + note (l.42–54), "Discard all", footer "Live v13 · 97 of 100 endpoints · 2 open drafts · Changes →" (l.64–69). changes.vue: drafts table with approval toggle (l.8–73), versions table with lineage + propagation bar + roll back (l.76–125), log (l.128–138). No JSON.
Steps
- Tray. Title stays "Locally Staged Edits · N" (Mark's 10-21 polish holds). Each line shows its reason when present; a loosening line without reason can't exist (00 refuses it). Replace "Submit as draft…" with "Save to draft" (no title; one click; optional note per batch is fine). Keep "Preview changes in dashboard" (now
?preview=draft+ local edits). Footer: "Live Policy Config v13 · 97 of 100 endpoints · 6 pending changes · Changes →"; endpoints count links to the Endpoints page (06's URL). - Changes: Pending. Header "Policy Config v13 · 6 pending changes". Itemized list: change · reason · author · when (who changed what and when, I).
<BlastRadius variant="full" :impact="previewDraft(draft.changes)">above the list (L: "use this component to visually, simply, clearly explain what the changes do"). Validation summary (00 errors, e.g. exception on a removed team) blocks Publish with the affected item named (I). Publish… → note (required) → "Publish v14". Discard draft. Changes markedredundantafter a rollback show struck with "already live". - Changes: Versions. Row label "Policy Config v13" + LIVE pill; drop branch lineage words that only made sense for multi-draft (keep "rolled away from"). Propagation bar per the note (
../sources/logseq-propagation.png): green bar "97 of 100 endpoints · 3 still on earlier versions" on live, grey on others. "Roll back here…" with required note. Per row: View JSON / Download (policy-config-v13.json). - ConfigJson.vue. A read-only code view of
configJson(v)with syntax colouring done in the component (tokenise keys / strings / numbers / booleans with a small regex; no new dependency), line numbers, copy, download. Anchor#json; opens for the live version by default, a version picker for others and "draft". - Import (
#import): paste or file →importConfig()→ errors listed, or "Staged N edits — review them in the tray". States: empty, invalid JSON, validation errors, success. - Remove the approval toggle, Approve / Promote / Reconcile, the "viewing as" approval logic;
?as=still decides the author of new edits. - Layout: only if the tray mount needs a prop change.
Done when
Flow: stage two edits on S3 → Save to draft → Changes shows 8 pending with authors + BlastRadius → Publish with note → v14 live, bar resets → Roll back to v13 with note → draft changes re-based. JSON view + download + import (valid, invalid). Screenshots shots/03-*.png.
Look for (review)
Nowhere says "draft D-n", "promote", "approve"; version strings are integers; JSON is the whole org config, not a policy.