@joewinke/jatui 0.36.3 → 0.38.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/artifact-blocks/AttachmentChip.svelte +66 -0
- package/dist/artifact-blocks/AttachmentChip.svelte.d.ts +7 -0
- package/dist/artifact-blocks/BlockComments.svelte +309 -0
- package/dist/artifact-blocks/BlockComments.svelte.d.ts +33 -0
- package/dist/artifact-blocks/BlockRenderer.svelte +674 -0
- package/dist/artifact-blocks/BlockRenderer.svelte.d.ts +55 -0
- package/dist/artifact-blocks/BlockVerdict.svelte +151 -0
- package/dist/artifact-blocks/BlockVerdict.svelte.d.ts +13 -0
- package/dist/artifact-blocks/BlocksArtifactView.svelte +1616 -0
- package/dist/artifact-blocks/BlocksArtifactView.svelte.d.ts +113 -0
- package/dist/artifact-blocks/CONTRACT.md +225 -0
- package/dist/artifact-blocks/CommentPill.svelte +49 -0
- package/dist/artifact-blocks/CommentPill.svelte.d.ts +16 -0
- package/dist/artifact-blocks/FoldedRounds.svelte +95 -0
- package/dist/artifact-blocks/FoldedRounds.svelte.d.ts +9 -0
- package/dist/artifact-blocks/Glyph.svelte +54 -0
- package/dist/artifact-blocks/Glyph.svelte.d.ts +10 -0
- package/dist/artifact-blocks/HistoryScrubber.svelte +500 -0
- package/dist/artifact-blocks/HistoryScrubber.svelte.d.ts +15 -0
- package/dist/artifact-blocks/Markdown.svelte +186 -0
- package/dist/artifact-blocks/Markdown.svelte.d.ts +30 -0
- package/dist/artifact-blocks/NoteComposer.svelte +31 -0
- package/dist/artifact-blocks/NoteComposer.svelte.d.ts +8 -0
- package/dist/artifact-blocks/PlainComposer.svelte +200 -0
- package/dist/artifact-blocks/PlainComposer.svelte.d.ts +15 -0
- package/dist/artifact-blocks/SectionTools.svelte +102 -0
- package/dist/artifact-blocks/SectionTools.svelte.d.ts +19 -0
- package/dist/artifact-blocks/adapter.d.ts +13 -0
- package/dist/artifact-blocks/adapter.js +31 -0
- package/dist/artifact-blocks/autoSend.d.ts +49 -0
- package/dist/artifact-blocks/autoSend.js +103 -0
- package/dist/artifact-blocks/blocks/actions/ActionsBlock.svelte +557 -0
- package/dist/artifact-blocks/blocks/actions/ActionsBlock.svelte.d.ts +48 -0
- package/dist/artifact-blocks/blocks/actions/block.d.ts +8 -0
- package/dist/artifact-blocks/blocks/actions/block.js +74 -0
- package/dist/artifact-blocks/blocks/actions/requests.d.ts +62 -0
- package/dist/artifact-blocks/blocks/actions/requests.js +26 -0
- package/dist/artifact-blocks/blocks/actions/schema.d.ts +168 -0
- package/dist/artifact-blocks/blocks/actions/schema.js +253 -0
- package/dist/artifact-blocks/blocks/callout/CalloutBlock.svelte +779 -0
- package/dist/artifact-blocks/blocks/callout/CalloutBlock.svelte.d.ts +40 -0
- package/dist/artifact-blocks/blocks/callout/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/callout/block.js +39 -0
- package/dist/artifact-blocks/blocks/callout/schema.d.ts +72 -0
- package/dist/artifact-blocks/blocks/callout/schema.js +115 -0
- package/dist/artifact-blocks/blocks/chart/ChartBlock.svelte +875 -0
- package/dist/artifact-blocks/blocks/chart/ChartBlock.svelte.d.ts +59 -0
- package/dist/artifact-blocks/blocks/chart/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/chart/block.js +70 -0
- package/dist/artifact-blocks/blocks/chart/schema.d.ts +171 -0
- package/dist/artifact-blocks/blocks/chart/schema.js +498 -0
- package/dist/artifact-blocks/blocks/chart/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/chart/thumb.js +201 -0
- package/dist/artifact-blocks/blocks/checklist/ChecklistBlock.svelte +1048 -0
- package/dist/artifact-blocks/blocks/checklist/ChecklistBlock.svelte.d.ts +16 -0
- package/dist/artifact-blocks/blocks/checklist/Icon.svelte +105 -0
- package/dist/artifact-blocks/blocks/checklist/Icon.svelte.d.ts +17 -0
- package/dist/artifact-blocks/blocks/checklist/block.d.ts +10 -0
- package/dist/artifact-blocks/blocks/checklist/block.js +63 -0
- package/dist/artifact-blocks/blocks/checklist/itemReview.d.ts +16 -0
- package/dist/artifact-blocks/blocks/checklist/itemReview.js +63 -0
- package/dist/artifact-blocks/blocks/checklist/labels.d.ts +62 -0
- package/dist/artifact-blocks/blocks/checklist/labels.js +96 -0
- package/dist/artifact-blocks/blocks/checklist/retest.d.ts +43 -0
- package/dist/artifact-blocks/blocks/checklist/retest.js +68 -0
- package/dist/artifact-blocks/blocks/checklist/schema.d.ts +84 -0
- package/dist/artifact-blocks/blocks/checklist/schema.js +91 -0
- package/dist/artifact-blocks/blocks/code/CodeBlock.svelte +128 -0
- package/dist/artifact-blocks/blocks/code/CodeBlock.svelte.d.ts +12 -0
- package/dist/artifact-blocks/blocks/code/block.d.ts +8 -0
- package/dist/artifact-blocks/blocks/code/block.js +31 -0
- package/dist/artifact-blocks/blocks/code/highlight.d.ts +34 -0
- package/dist/artifact-blocks/blocks/code/highlight.js +280 -0
- package/dist/artifact-blocks/blocks/code/schema.d.ts +32 -0
- package/dist/artifact-blocks/blocks/code/schema.js +39 -0
- package/dist/artifact-blocks/blocks/collage/CollageBlock.svelte +290 -0
- package/dist/artifact-blocks/blocks/collage/CollageBlock.svelte.d.ts +29 -0
- package/dist/artifact-blocks/blocks/collage/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/collage/block.js +29 -0
- package/dist/artifact-blocks/blocks/collage/schema.d.ts +52 -0
- package/dist/artifact-blocks/blocks/collage/schema.js +86 -0
- package/dist/artifact-blocks/blocks/compare/CompareBlock.svelte +484 -0
- package/dist/artifact-blocks/blocks/compare/CompareBlock.svelte.d.ts +25 -0
- package/dist/artifact-blocks/blocks/compare/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/compare/block.js +32 -0
- package/dist/artifact-blocks/blocks/compare/schema.d.ts +74 -0
- package/dist/artifact-blocks/blocks/compare/schema.js +148 -0
- package/dist/artifact-blocks/blocks/diagram/DiagramBlock.svelte +392 -0
- package/dist/artifact-blocks/blocks/diagram/DiagramBlock.svelte.d.ts +30 -0
- package/dist/artifact-blocks/blocks/diagram/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/diagram/block.js +50 -0
- package/dist/artifact-blocks/blocks/diagram/constants.d.ts +48 -0
- package/dist/artifact-blocks/blocks/diagram/constants.js +53 -0
- package/dist/artifact-blocks/blocks/diagram/schema.d.ts +161 -0
- package/dist/artifact-blocks/blocks/diagram/schema.js +621 -0
- package/dist/artifact-blocks/blocks/diagram/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/diagram/thumb.js +157 -0
- package/dist/artifact-blocks/blocks/diagram/types.d.ts +74 -0
- package/dist/artifact-blocks/blocks/diagram/types.js +1 -0
- package/dist/artifact-blocks/blocks/diff/DiffBlock.svelte +81 -0
- package/dist/artifact-blocks/blocks/diff/DiffBlock.svelte.d.ts +10 -0
- package/dist/artifact-blocks/blocks/diff/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/diff/block.js +36 -0
- package/dist/artifact-blocks/blocks/diff/schema.d.ts +18 -0
- package/dist/artifact-blocks/blocks/diff/schema.js +35 -0
- package/dist/artifact-blocks/blocks/diff-review/DiffReviewBlock.svelte +1055 -0
- package/dist/artifact-blocks/blocks/diff-review/DiffReviewBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/diff-review/block.d.ts +15 -0
- package/dist/artifact-blocks/blocks/diff-review/block.js +64 -0
- package/dist/artifact-blocks/blocks/diff-review/decisions.d.ts +57 -0
- package/dist/artifact-blocks/blocks/diff-review/decisions.js +80 -0
- package/dist/artifact-blocks/blocks/diff-review/schema.d.ts +13 -0
- package/dist/artifact-blocks/blocks/diff-review/schema.js +84 -0
- package/dist/artifact-blocks/blocks/diff-review/types.d.ts +35 -0
- package/dist/artifact-blocks/blocks/diff-review/types.js +1 -0
- package/dist/artifact-blocks/blocks/explainer/ExplainerBlock.svelte +145 -0
- package/dist/artifact-blocks/blocks/explainer/ExplainerBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/explainer/block.d.ts +8 -0
- package/dist/artifact-blocks/blocks/explainer/block.js +21 -0
- package/dist/artifact-blocks/blocks/explainer/schema.d.ts +26 -0
- package/dist/artifact-blocks/blocks/explainer/schema.js +69 -0
- package/dist/artifact-blocks/blocks/group-content.d.ts +10 -0
- package/dist/artifact-blocks/blocks/group-content.js +16 -0
- package/dist/artifact-blocks/blocks/group-data.d.ts +10 -0
- package/dist/artifact-blocks/blocks/group-data.js +7 -0
- package/dist/artifact-blocks/blocks/group-review.d.ts +10 -0
- package/dist/artifact-blocks/blocks/group-review.js +12 -0
- package/dist/artifact-blocks/blocks/group-visual.d.ts +17 -0
- package/dist/artifact-blocks/blocks/group-visual.js +14 -0
- package/dist/artifact-blocks/blocks/map/MapBlock.svelte +413 -0
- package/dist/artifact-blocks/blocks/map/MapBlock.svelte.d.ts +53 -0
- package/dist/artifact-blocks/blocks/map/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/map/block.js +62 -0
- package/dist/artifact-blocks/blocks/map/schema.d.ts +123 -0
- package/dist/artifact-blocks/blocks/map/schema.js +113 -0
- package/dist/artifact-blocks/blocks/map/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/map/thumb.js +69 -0
- package/dist/artifact-blocks/blocks/markdown/MarkdownBlock.svelte +33 -0
- package/dist/artifact-blocks/blocks/markdown/MarkdownBlock.svelte.d.ts +15 -0
- package/dist/artifact-blocks/blocks/markdown/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/markdown/block.js +28 -0
- package/dist/artifact-blocks/blocks/markdown/render.d.ts +17 -0
- package/dist/artifact-blocks/blocks/markdown/render.js +115 -0
- package/dist/artifact-blocks/blocks/markdown/schema.d.ts +10 -0
- package/dist/artifact-blocks/blocks/markdown/schema.js +23 -0
- package/dist/artifact-blocks/blocks/media-picker/MediaPickerBlock.svelte +2112 -0
- package/dist/artifact-blocks/blocks/media-picker/MediaPickerBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/media-picker/block.d.ts +24 -0
- package/dist/artifact-blocks/blocks/media-picker/block.js +137 -0
- package/dist/artifact-blocks/blocks/media-picker/choices.d.ts +28 -0
- package/dist/artifact-blocks/blocks/media-picker/choices.js +35 -0
- package/dist/artifact-blocks/blocks/media-picker/decisions.d.ts +51 -0
- package/dist/artifact-blocks/blocks/media-picker/decisions.js +75 -0
- package/dist/artifact-blocks/blocks/media-picker/schema.d.ts +7 -0
- package/dist/artifact-blocks/blocks/media-picker/schema.js +199 -0
- package/dist/artifact-blocks/blocks/media-picker/types.d.ts +92 -0
- package/dist/artifact-blocks/blocks/media-picker/types.js +1 -0
- package/dist/artifact-blocks/blocks/media-picker/versions.d.ts +51 -0
- package/dist/artifact-blocks/blocks/media-picker/versions.js +118 -0
- package/dist/artifact-blocks/blocks/mockup/MockupBlock.svelte +213 -0
- package/dist/artifact-blocks/blocks/mockup/MockupBlock.svelte.d.ts +5 -0
- package/dist/artifact-blocks/blocks/mockup/block.d.ts +26 -0
- package/dist/artifact-blocks/blocks/mockup/block.js +52 -0
- package/dist/artifact-blocks/blocks/mockup/doc.d.ts +24 -0
- package/dist/artifact-blocks/blocks/mockup/doc.js +44 -0
- package/dist/artifact-blocks/blocks/mockup/sandbox.d.ts +21 -0
- package/dist/artifact-blocks/blocks/mockup/sandbox.js +27 -0
- package/dist/artifact-blocks/blocks/mockup/schema.d.ts +7 -0
- package/dist/artifact-blocks/blocks/mockup/schema.js +90 -0
- package/dist/artifact-blocks/blocks/mockup/types.d.ts +36 -0
- package/dist/artifact-blocks/blocks/mockup/types.js +17 -0
- package/dist/artifact-blocks/blocks/program/ProgramBlock.svelte +359 -0
- package/dist/artifact-blocks/blocks/program/ProgramBlock.svelte.d.ts +32 -0
- package/dist/artifact-blocks/blocks/program/block.d.ts +35 -0
- package/dist/artifact-blocks/blocks/program/block.js +68 -0
- package/dist/artifact-blocks/blocks/program/schema.d.ts +132 -0
- package/dist/artifact-blocks/blocks/program/schema.js +268 -0
- package/dist/artifact-blocks/blocks/stats/StatsBlock.svelte +315 -0
- package/dist/artifact-blocks/blocks/stats/StatsBlock.svelte.d.ts +24 -0
- package/dist/artifact-blocks/blocks/stats/block.d.ts +7 -0
- package/dist/artifact-blocks/blocks/stats/block.js +49 -0
- package/dist/artifact-blocks/blocks/stats/schema.d.ts +82 -0
- package/dist/artifact-blocks/blocks/stats/schema.js +43 -0
- package/dist/artifact-blocks/blocks/stats/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/stats/thumb.js +102 -0
- package/dist/artifact-blocks/blocks/table/TableBlock.svelte +490 -0
- package/dist/artifact-blocks/blocks/table/TableBlock.svelte.d.ts +28 -0
- package/dist/artifact-blocks/blocks/table/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/table/block.js +100 -0
- package/dist/artifact-blocks/blocks/table/schema.d.ts +143 -0
- package/dist/artifact-blocks/blocks/table/schema.js +278 -0
- package/dist/artifact-blocks/blocks/timeline/TimelineBlock.svelte +347 -0
- package/dist/artifact-blocks/blocks/timeline/TimelineBlock.svelte.d.ts +42 -0
- package/dist/artifact-blocks/blocks/timeline/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/timeline/block.js +96 -0
- package/dist/artifact-blocks/blocks/timeline/constants.d.ts +26 -0
- package/dist/artifact-blocks/blocks/timeline/constants.js +27 -0
- package/dist/artifact-blocks/blocks/timeline/schema.d.ts +102 -0
- package/dist/artifact-blocks/blocks/timeline/schema.js +405 -0
- package/dist/artifact-blocks/blocks/timeline/thumb.d.ts +2 -0
- package/dist/artifact-blocks/blocks/timeline/thumb.js +117 -0
- package/dist/artifact-blocks/blocks/timeline/types.d.ts +66 -0
- package/dist/artifact-blocks/blocks/timeline/types.js +1 -0
- package/dist/artifact-blocks/blocks/transcript/TranscriptBlock.svelte +169 -0
- package/dist/artifact-blocks/blocks/transcript/TranscriptBlock.svelte.d.ts +26 -0
- package/dist/artifact-blocks/blocks/transcript/block.d.ts +9 -0
- package/dist/artifact-blocks/blocks/transcript/block.js +86 -0
- package/dist/artifact-blocks/blocks/transcript/schema.d.ts +114 -0
- package/dist/artifact-blocks/blocks/transcript/schema.js +126 -0
- package/dist/artifact-blocks/builtins.d.ts +40 -0
- package/dist/artifact-blocks/builtins.js +22 -0
- package/dist/artifact-blocks/contractBlocks.d.ts +92 -0
- package/dist/artifact-blocks/contractBlocks.js +279 -0
- package/dist/artifact-blocks/history.d.ts +140 -0
- package/dist/artifact-blocks/history.js +363 -0
- package/dist/artifact-blocks/index.d.ts +40 -0
- package/dist/artifact-blocks/index.js +46 -0
- package/dist/artifact-blocks/listen/context.d.ts +30 -0
- package/dist/artifact-blocks/listen/context.js +30 -0
- package/dist/artifact-blocks/liveData.d.ts +78 -0
- package/dist/artifact-blocks/liveData.js +137 -0
- package/dist/artifact-blocks/liveDataPoller.d.ts +41 -0
- package/dist/artifact-blocks/liveDataPoller.js +140 -0
- package/dist/artifact-blocks/openNav.d.ts +46 -0
- package/dist/artifact-blocks/openNav.js +106 -0
- package/dist/artifact-blocks/pageReviewKeys.d.ts +17 -0
- package/dist/artifact-blocks/pageReviewKeys.js +115 -0
- package/dist/artifact-blocks/params.d.ts +98 -0
- package/dist/artifact-blocks/params.js +159 -0
- package/dist/artifact-blocks/registry.d.ts +27 -0
- package/dist/artifact-blocks/registry.js +83 -0
- package/dist/artifact-blocks/review/BlockIcon.svelte +99 -0
- package/dist/artifact-blocks/review/BlockIcon.svelte.d.ts +17 -0
- package/dist/artifact-blocks/review/BulkRejectForm.svelte +94 -0
- package/dist/artifact-blocks/review/BulkRejectForm.svelte.d.ts +11 -0
- package/dist/artifact-blocks/review/BulkUndoBar.svelte +40 -0
- package/dist/artifact-blocks/review/BulkUndoBar.svelte.d.ts +9 -0
- package/dist/artifact-blocks/review/ItemNote.svelte +193 -0
- package/dist/artifact-blocks/review/ItemNote.svelte.d.ts +33 -0
- package/dist/artifact-blocks/review/NoteToggle.svelte +52 -0
- package/dist/artifact-blocks/review/NoteToggle.svelte.d.ts +12 -0
- package/dist/artifact-blocks/review/TeamChip.svelte +71 -0
- package/dist/artifact-blocks/review/TeamChip.svelte.d.ts +8 -0
- package/dist/artifact-blocks/review/attachments.d.ts +10 -0
- package/dist/artifact-blocks/review/attachments.js +37 -0
- package/dist/artifact-blocks/review/bulk.d.ts +52 -0
- package/dist/artifact-blocks/review/bulk.js +61 -0
- package/dist/artifact-blocks/review/itemReview.d.ts +33 -0
- package/dist/artifact-blocks/review/itemReview.js +112 -0
- package/dist/artifact-blocks/review/roundLines.d.ts +14 -0
- package/dist/artifact-blocks/review/roundLines.js +20 -0
- package/dist/artifact-blocks/review/rounds.d.ts +86 -0
- package/dist/artifact-blocks/review/rounds.js +302 -0
- package/dist/artifact-blocks/review/saver.d.ts +23 -0
- package/dist/artifact-blocks/review/saver.js +48 -0
- package/dist/artifact-blocks/review/team.d.ts +31 -0
- package/dist/artifact-blocks/review/team.js +42 -0
- package/dist/artifact-blocks/review/visualOrder.d.ts +29 -0
- package/dist/artifact-blocks/review/visualOrder.js +66 -0
- package/dist/artifact-blocks/review.d.ts +180 -0
- package/dist/artifact-blocks/review.js +716 -0
- package/dist/artifact-blocks/thumb-kit.d.ts +80 -0
- package/dist/artifact-blocks/thumb-kit.js +149 -0
- package/dist/artifact-blocks/types.d.ts +513 -0
- package/dist/artifact-blocks/types.js +1 -0
- package/dist/components/Button.svelte +8 -0
- package/dist/components/TextInput.svelte +39 -6
- package/dist/components/TextInput.svelte.d.ts +15 -7
- package/dist/components/basic/Checkbox.svelte +52 -14
- package/dist/components/basic/Checkbox.svelte.d.ts +11 -1
- package/package.json +11 -2
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { BlocksSpec, FoldedRound, HostAdapter, SentAnswer } from "./types.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
artifactId: string;
|
|
4
|
+
version: number;
|
|
5
|
+
title: string;
|
|
6
|
+
summary: string | null;
|
|
7
|
+
byline: string;
|
|
8
|
+
spec: BlocksSpec | null;
|
|
9
|
+
/** The host's services (types.ts HostAdapter). {} = read-only. */
|
|
10
|
+
adapter?: HostAdapter;
|
|
11
|
+
/** The server-rendered live-data blob ({} until a data publish). */
|
|
12
|
+
data?: Record<string, unknown>;
|
|
13
|
+
/** ISO string or null — when the data last changed. */
|
|
14
|
+
dataUpdatedAt?: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Write <title>, description and robots into <svelte:head>. Default
|
|
17
|
+
* true (a page of its own); false when the view is embedded in a host
|
|
18
|
+
* page that owns its head.
|
|
19
|
+
*/
|
|
20
|
+
head?: boolean;
|
|
21
|
+
/** Robots meta for the head (a share surface adds noarchive). */
|
|
22
|
+
robotsContent?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Inline chrome on the title line (mos-3q1o3): the host's Details
|
|
25
|
+
* control renders right after the page title. Omitted on the share
|
|
26
|
+
* surface.
|
|
27
|
+
*/
|
|
28
|
+
titleActions?: import("svelte").Snippet;
|
|
29
|
+
/**
|
|
30
|
+
* The linked task's chip (mos-t9wr6), leading the byline row. Omitted on
|
|
31
|
+
* the share surface — a share link never shows the task.
|
|
32
|
+
*/
|
|
33
|
+
taskLine?: import("svelte").Snippet;
|
|
34
|
+
/**
|
|
35
|
+
* The host's Listen player (mos-3q1o3, mos-8fvt9): a pill at the right
|
|
36
|
+
* end of the meta line; opened, its bar takes a full-width row.
|
|
37
|
+
*/
|
|
38
|
+
player?: import("svelte").Snippet;
|
|
39
|
+
/**
|
|
40
|
+
* Controls for the frame this page sits in (mos-8fvt9): inside the desk
|
|
41
|
+
* drawer, "Open in new tab" + Close join the right end of the top row
|
|
42
|
+
* instead of a drawer bar of their own. Omitted everywhere else.
|
|
43
|
+
*/
|
|
44
|
+
frameActions?: import("svelte").Snippet;
|
|
45
|
+
/**
|
|
46
|
+
* Where this page's answers really go (mos-guqgs): /a/<slug>. When the
|
|
47
|
+
* surface has NO save plumbing but the spec carries answer-taking
|
|
48
|
+
* content, a read-only notice renders with this link — the "Open to
|
|
49
|
+
* answer" affordance. Null hides the link.
|
|
50
|
+
*/
|
|
51
|
+
answerUrl?: string | null;
|
|
52
|
+
/**
|
|
53
|
+
* The host's own wording for the read-only notice. `kind` is
|
|
54
|
+
* "read-only" (no save plumbing — a share link) or "unsent" (picks save
|
|
55
|
+
* but no review leg sends them). Default: jatui's neutral copy.
|
|
56
|
+
*/
|
|
57
|
+
readOnlyNotice?: import("svelte").Snippet<[
|
|
58
|
+
{
|
|
59
|
+
kind: "read-only" | "unsent";
|
|
60
|
+
answerUrl: string | null;
|
|
61
|
+
}
|
|
62
|
+
]>;
|
|
63
|
+
/**
|
|
64
|
+
* This page's folded earlier rounds: each with its items and every
|
|
65
|
+
* viewer's verdicts/notes, locked. Empty when the page superseded
|
|
66
|
+
* nothing (or the host's read failed).
|
|
67
|
+
*/
|
|
68
|
+
foldedRounds?: FoldedRound[];
|
|
69
|
+
/** Start the folded rounds expanded (a host redirected an old slug here). */
|
|
70
|
+
foldedRoundsOpen?: boolean;
|
|
71
|
+
/** Per-block state plumbing (omitted on the read-only share surface). */
|
|
72
|
+
savedBlocks?: Record<string, unknown> | null;
|
|
73
|
+
onSaveBlock?: (payload: {
|
|
74
|
+
kind: "blocks";
|
|
75
|
+
blocks: Record<string, unknown>;
|
|
76
|
+
}) => Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Comments + the review moment (mos-kib2f). Omitted on the read-only
|
|
79
|
+
* share surface: no session → no drawer, no Done-reviewing button.
|
|
80
|
+
*/
|
|
81
|
+
comments?: {
|
|
82
|
+
enabled: boolean;
|
|
83
|
+
counts: Record<string, number>;
|
|
84
|
+
/** This viewer already recorded review_completed for this version. */
|
|
85
|
+
reviewed: boolean;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* The jat task this page serves (mos-wywa3). When set, decision cards
|
|
89
|
+
* and reviewable blocks (takesBlockVerdict) collect answers and the
|
|
90
|
+
* "Send answers" section at the foot of the page sends them as ONE
|
|
91
|
+
* answer to the task. Null → the plain "Done reviewing" moment.
|
|
92
|
+
*/
|
|
93
|
+
taskId?: string | null;
|
|
94
|
+
/** Who the answer reaches (the publishing agent), for the send label. */
|
|
95
|
+
answerTo?: string | null;
|
|
96
|
+
/**
|
|
97
|
+
* The server-seeded done state (mos-7j6r5): THIS viewer's last Send on
|
|
98
|
+
* THIS version, read by the page load from the review_completed event.
|
|
99
|
+
* Null when they never sent — a first visit. This is what makes a
|
|
100
|
+
* reload remember: without it the page offered "Finish review" again
|
|
101
|
+
* after every refresh, reading as still open when the task was done.
|
|
102
|
+
*/
|
|
103
|
+
reviewAnswer?: SentAnswer | null;
|
|
104
|
+
/**
|
|
105
|
+
* The linked task is closed/done (jat state, read server-side). With
|
|
106
|
+
* every item decided, the page shows the completed state — "Decided ·
|
|
107
|
+
* task closed" — even for a viewer who did not send.
|
|
108
|
+
*/
|
|
109
|
+
taskClosed?: boolean;
|
|
110
|
+
}
|
|
111
|
+
declare const BlocksArtifactView: import("svelte").Component<Props, {}, "">;
|
|
112
|
+
type BlocksArtifactView = ReturnType<typeof BlocksArtifactView>;
|
|
113
|
+
export default BlocksArtifactView;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Artifact blocks — contract (`jatui/artifact-blocks`)
|
|
2
|
+
|
|
3
|
+
Blocks artifacts are **data, not code**. `{ kind: "blocks", spec: BlocksSpec }`
|
|
4
|
+
is stored by the host; jatui renders each block with its Svelte component.
|
|
5
|
+
Origin: MOS epic mos-ab\* (moved into jatui by jatui-vsuzi so MOS and the jat
|
|
6
|
+
IDE render ONE thing). Types: `types.ts`. Catalog + validation: `registry.ts`.
|
|
7
|
+
|
|
8
|
+
## Adding a block (block workers)
|
|
9
|
+
|
|
10
|
+
- **A block task touches ONE shared file: its group barrel.** The blocks are
|
|
11
|
+
partitioned by task so the four block tasks never collide:
|
|
12
|
+
|
|
13
|
+
| Barrel | Task | Types |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `blocks/group-data.ts` | jatui-d4lyd | chart, stats, table, timeline |
|
|
16
|
+
| `blocks/group-content.ts` | jatui-zy9n5 | checklist, code, diff, transcript, program, compare |
|
|
17
|
+
| `blocks/group-visual.ts` | jatui-399p2 | diagram, collage, map, explainer, mockup |
|
|
18
|
+
| `blocks/group-review.ts` | jatui-n5z1x | callout, actions, diff-review, media-picker |
|
|
19
|
+
|
|
20
|
+
Create `blocks/<type>/` (`block.ts` default-exporting an
|
|
21
|
+
`ArtifactBlockDef`, `<Type>Block.svelte` with props `{ params, ctx }`,
|
|
22
|
+
`schema.ts`), then in YOUR barrel import the def, append it to `BLOCKS`
|
|
23
|
+
and drop the type from that barrel's `PENDING`. Never edit `builtins.ts`
|
|
24
|
+
(it concatenates the four barrels), `registry.ts`, another group's barrel
|
|
25
|
+
or a core file — ask the core owner instead. jatui cannot glob folders at
|
|
26
|
+
runtime the way a Vite app can, hence the barrels.
|
|
27
|
+
- Tests (yours, in your own files): the schema accepts `example` and rejects
|
|
28
|
+
bad params (`tests/unit/artifact-blocks/<type>.test.ts`, node vitest —
|
|
29
|
+
`npm run test:advisors`), and the component renders from the BUILT
|
|
30
|
+
package (`tests/built/artifact-blocks-<type>.test.ts`, Chromium —
|
|
31
|
+
`npm run package && npm run test:dist`).
|
|
32
|
+
- Showcase: nothing to edit. `/showcase/artifact-blocks/<group>` renders
|
|
33
|
+
every def in your barrel from its own `example`, light + dark — so make
|
|
34
|
+
`example` a realistic, complete demo.
|
|
35
|
+
- Imports stay inside jatui: relative paths to `../../types.js`,
|
|
36
|
+
`../../params.js`, `../../Markdown.svelte`, `../../NoteComposer.svelte`,
|
|
37
|
+
`../../SectionTools.svelte`, jatui components by relative path. **Never**
|
|
38
|
+
a host module. Anything a host must provide comes from `ctx.services` or
|
|
39
|
+
the adapter (below).
|
|
40
|
+
- Params are untrusted agent input: every string is rendered as text (never
|
|
41
|
+
`{@html}`) except through the shared markdown renderer
|
|
42
|
+
(`blocks/markdown/render.ts`, or the `<Markdown>` component that wraps it
|
|
43
|
+
with the shared prose styles). Resource URLs (img/video/frame src):
|
|
44
|
+
`https://` or root-relative only — `urlSchema` from `./params.ts`.
|
|
45
|
+
Navigation links (`<a href>`) may also be `http://` — `linkUrlSchema`
|
|
46
|
+
(a jat control plane serves task links over plain http on the tailnet).
|
|
47
|
+
- The component receives the schema-PARSED params (defaults applied, unknown
|
|
48
|
+
keys stripped), never the raw published input: a publish stores the spec
|
|
49
|
+
verbatim — history is truth — so anything the schema fills or inherits
|
|
50
|
+
must reach the component through the parse.
|
|
51
|
+
- Theming token-only (DaisyUI semantic classes / `--color-*` vars, jatui
|
|
52
|
+
radius tokens), light + dark + phone (390px) verified, reduced motion
|
|
53
|
+
respected. DaisyUI classes are internal skin; never a block prop.
|
|
54
|
+
- Interactive blocks read `ctx.state` and call `ctx.saveState()`; they must
|
|
55
|
+
render correctly when `saveState` is undefined (read-only / share link).
|
|
56
|
+
- A save failure is NEVER silent and never a block's problem: the renderer
|
|
57
|
+
wraps the save path so any failure (sync throw or rejected save) shows a
|
|
58
|
+
visible "Not saved — Retry" strip on the failing block and clears on a
|
|
59
|
+
successful retry. Build state to survive a failed save: keep the
|
|
60
|
+
optimistic local copy; the next save retries.
|
|
61
|
+
- Pass state up through `$state.snapshot()` (or plain spreads of
|
|
62
|
+
primitives) — never `structuredClone` a `$state` proxy (DataCloneError).
|
|
63
|
+
- Notes inside a block use `<NoteComposer {artifactId} …>` (the host's
|
|
64
|
+
composer, or jatui's text composer). Attachments are `NoteAttachment`
|
|
65
|
+
descriptors the host stored; render them with `AttachmentChip` or the
|
|
66
|
+
host's `adapter.attachmentChip`.
|
|
67
|
+
- Item-review blocks (checklist, media-picker, diff-review) declare
|
|
68
|
+
`itemReview` on their def: `vocabulary`, `name`, `items(params, state)`,
|
|
69
|
+
optional `itemLabel` / `itemThumb`. The census, the still-open walk, the
|
|
70
|
+
Send and the progress bar read items ONLY through it (`review.ts`). The
|
|
71
|
+
hook gets AUTHORED params (untrusted JSON) and must not throw. It must
|
|
72
|
+
reproduce MOS `feedbackReview.ts reviewItemsOf` exactly (see "Item-review
|
|
73
|
+
rules" below) — the counts a viewer sees and the answer a host sends both
|
|
74
|
+
come from it.
|
|
75
|
+
- Work-product blocks that take the block-level verdict strip by default
|
|
76
|
+
set `reviewableByDefault: true` (mockup, compare, collage and diff are
|
|
77
|
+
also known by name in `review.ts`). A spec overrides either way with
|
|
78
|
+
`params.reviewable: true|false`.
|
|
79
|
+
- `description` is written FOR AN AGENT: when to use the block, what each
|
|
80
|
+
param means, limits, one-line tip.
|
|
81
|
+
- Size limits: keep params under ~256KB per block; media by URL, never
|
|
82
|
+
base64 blobs.
|
|
83
|
+
- A block that renders `BlockRenderer` itself (program) imports it lazily or
|
|
84
|
+
at component level — `registry.ts` seeds itself from `builtins.ts` at
|
|
85
|
+
module init, so a module-level cycle back into the registry would read
|
|
86
|
+
the builtins list before it exists.
|
|
87
|
+
|
|
88
|
+
## Item-review rules (what `itemReview.items` must return)
|
|
89
|
+
|
|
90
|
+
Ported from MOS `modules/artifacts/feedbackReview.ts` (`reviewItemsOf`,
|
|
91
|
+
`itemLabelOf`, `mediaThumbOf`, `itemRoundOf`) — the block tasks own the code,
|
|
92
|
+
these are the rules. Each item is a `ReviewItem` `{ id, verdict, raw,
|
|
93
|
+
explicit, retest, note?, attachments? }`, in the block's own order.
|
|
94
|
+
|
|
95
|
+
- **Buckets.** A block's raw word maps to a bucket: approve / pass /
|
|
96
|
+
accept → `approved`; redo / modify / fail / blocked → `needs-work`;
|
|
97
|
+
reject → `rejected`. `raw` keeps the block's own word (it labels the
|
|
98
|
+
progress line and rides the answer); `verdict` is the bucket or null.
|
|
99
|
+
- **Notes.** `note` = the saved entry's trimmed note, capped at 2000 chars;
|
|
100
|
+
`attachments` = the saved entry's descriptors as-is. Both are dropped when
|
|
101
|
+
the verdict is stale (below).
|
|
102
|
+
- **checklist** — items are `params.rows[]` (each with an `id`); state is
|
|
103
|
+
`{ rows: { [rowId]: { status, note?, attachments? } } }`.
|
|
104
|
+
- The viewer's saved `status` (one of pass / fail / blocked / untested)
|
|
105
|
+
wins; with none saved, the row's AUTHORED seed applies (`seedStatus`:
|
|
106
|
+
the row's own `status` when it is a viewer status — pass / fail /
|
|
107
|
+
blocked / untested — else untested).
|
|
108
|
+
- `teamMode: true` and a row the team marked `status: "ready"` awaits the
|
|
109
|
+
viewer (`rowAwaitsViewer`) when the viewer has no saved status, saved
|
|
110
|
+
`untested`, or saved a verdict that is stale for the row's round (its
|
|
111
|
+
`retestSince`, compared by the checklist rounds helper) →
|
|
112
|
+
`verdict: null, raw: null, retest: true`.
|
|
113
|
+
- `untested` → `raw: null` (undecided). `explicit` = the viewer saved a
|
|
114
|
+
status (a seed is never the viewer's answer).
|
|
115
|
+
- **media-picker / diff-review** — items are `params.items[]`; state is
|
|
116
|
+
`{ [itemId]: { verdict, note?, attachments? } }` (verdict lower-cased).
|
|
117
|
+
- `informational: true` items are context, not units: SKIP them entirely
|
|
118
|
+
(they never count and never block a Send).
|
|
119
|
+
- Rounds: an item's round is its team `readySince` when
|
|
120
|
+
`team: { status: "ready", readySince }`, else (media-picker only) the
|
|
121
|
+
version under review — `currentVersion`, else the first variant's
|
|
122
|
+
`version`; null = no rounds. A saved verdict from an EARLIER round is
|
|
123
|
+
stale (`mediaRounds` / `diffRounds.isStale`): `verdict: null`, no note.
|
|
124
|
+
- `retest` = undecided AND (team-ready OR stale). `explicit` = a
|
|
125
|
+
current-round verdict exists.
|
|
126
|
+
- **Labels and thumbnails** (`itemLabel`, `itemThumb`): the row's / item's
|
|
127
|
+
`title`, else its id. media-picker thumb = the first `image` variant of
|
|
128
|
+
the round under review, else any image variant, else that round's video
|
|
129
|
+
`poster`; none → undefined.
|
|
130
|
+
|
|
131
|
+
## The renderer
|
|
132
|
+
|
|
133
|
+
- `BlockRenderer` renders a spec IN the host page (no iframe). Unknown type
|
|
134
|
+
and invalid params render a visible error card, never a throw and never a
|
|
135
|
+
silent skip; a type still being ported says so (`PENDING_BLOCK_TYPES`).
|
|
136
|
+
- Every block renders inside a per-block error boundary that is ACTIVE ONLY
|
|
137
|
+
AT SSR: a component that throws while server-rendering degrades to a
|
|
138
|
+
quiet notice; one bad block never fails the page. On the client the
|
|
139
|
+
boundary is transparent (Svelte cannot tell a render error from an effect
|
|
140
|
+
error, and a harmless effect hiccup must never blank a block) — so blocks
|
|
141
|
+
GUARD effect-side browser-API calls. The boundary is the last line of
|
|
142
|
+
defense, not a permission.
|
|
143
|
+
- **Groups** (PARAMS-SPEC §5): a block whose authored params carry
|
|
144
|
+
`group: { key: [a-z0-9-]{1,32}, label ≤60, quiet? }` sits under a header the
|
|
145
|
+
renderer draws between cards when the key changes — sticky label + card
|
|
146
|
+
count, anchored `#group-<key>` (first run of a key), collapsible; a
|
|
147
|
+
`quiet` group starts collapsed. Collapsing HIDES the cards (they keep their
|
|
148
|
+
state); the open-item walk, a Finish card and a `#block-<id>` link expand
|
|
149
|
+
the group first (`BlockRenderer.revealBlock`). Collapse is keyed by group
|
|
150
|
+
key. Set `--artifact-sticky-top` to clear a host's sticky header.
|
|
151
|
+
- Decision cards (`callout` variant `decision`) arrive from the provider
|
|
152
|
+
contract's `decision` block through `normalizeContractBlocks`
|
|
153
|
+
(`contractBlocks.ts`). The NEEDS YOU fields — `title`, `meta[]`,
|
|
154
|
+
`sections[]`, `primaryAction`, `group` — pass through validated with the
|
|
155
|
+
limits exported there (`decisionMetaSchema` …); a malformed one is DROPPED
|
|
156
|
+
and returned in `warnings`, never a refused publish. None of them is
|
|
157
|
+
answerable: links navigate, they never post a verdict.
|
|
158
|
+
|
|
159
|
+
## The host adapter
|
|
160
|
+
|
|
161
|
+
ONE typed object (`HostAdapter`, `types.ts`) carries everything that used to
|
|
162
|
+
be a MOS import. Pass it to `BlocksArtifactView` (`adapter={…}`) or to a bare
|
|
163
|
+
`BlockRenderer`; components below read it from the Svelte context
|
|
164
|
+
(`adapter.ts`). **Every key is optional, and a missing key degrades to
|
|
165
|
+
read-only, loudly** — the control disappears or the read-only notice shows;
|
|
166
|
+
nothing looks live and silently drops input.
|
|
167
|
+
|
|
168
|
+
| Key | What jatui calls | Absent → |
|
|
169
|
+
|---|---|---|
|
|
170
|
+
| `composer` | `Component<NoteComposerProps>` for verdict notes, comments, the Finish note, block notes (MOS: `ReviewComposer`) | jatui `PlainComposer` (text; files when `upload` is set) |
|
|
171
|
+
| `upload(artifactId)` | `ComposerUpload` — store bytes FIRST, return the `NoteAttachment` descriptor | text-only notes |
|
|
172
|
+
| `attachmentChip` | `Component<{ clip }>` | jatui `AttachmentChip` (labelled link) |
|
|
173
|
+
| `comments` | `load / post / setResolved` per block thread | no comment pills, no drawer |
|
|
174
|
+
| `review.send` | Finish review: ONE answer `{ version, taskId, blockTasks, verdicts, text?, attachments? }` → `{ answered, sentTo?, delivery? }`. `version` is the version this tab answered (a stale tab is detectable); `blockTasks` maps P11-linked blocks to `{ taskId, decisionId }` | no Finish review |
|
|
175
|
+
| `review.markReviewed` | "Done reviewing" `{ version, taskId }`; throw a human-readable Error on failure (shown beside the control) | no Done-reviewing control, no auto-send |
|
|
176
|
+
| `review.deliveryStatus` | poll a queued Send's delivery stamp | every Send reads as delivered once `send` resolves |
|
|
177
|
+
| `review.draftNote(blocks)` | a host-kept draft (`{ note, label }`) that pre-fills the Finish note (MOS: the desk's `desk:note`) | no prefill |
|
|
178
|
+
| `history` | `timeline()` + `at(instant)` for the scrubber | no History control |
|
|
179
|
+
| `liveData` | `fetch()` → `{ data, dataUpdatedAt }`, every `intervalMs` (30s) while visible; throw `{ status: 429 }` when rate limited (keeps the data, says "refresh pending") | the page shows the data it was rendered with and never claims "live" |
|
|
180
|
+
| `listen` | `Snippet<[{ group, label, anchor }]>` per prose block (jatui `ListenControl` fits) | no Listen |
|
|
181
|
+
| `crumb` | header crumb snippet | empty crumb row |
|
|
182
|
+
| `nextActions` | `Snippet<[{ compact, autofocus, nextKey }]>` in the done states (MOS: `DeskNextActions`) | nothing |
|
|
183
|
+
| `titleMenu` | `{ header?, items: ContextMenuItem[] }` on the title's right-click | no menu |
|
|
184
|
+
| `services` | block services: `loadGoogleMaps`, `explorer3d`, `sandboxAttr`, `teamLookup`, … (`ctx.services`) | each block's own quiet fallback |
|
|
185
|
+
|
|
186
|
+
View props that are not adapter keys stay props: `onSaveBlock` + `savedBlocks`
|
|
187
|
+
(per-block state plumbing; omit → blocks get no `saveState`), `comments`
|
|
188
|
+
(`{ enabled, counts, reviewed }`), `taskId`, `answerTo`, `reviewAnswer`
|
|
189
|
+
(the seeded done state), `taskClosed`, `foldedRounds`, `data` /
|
|
190
|
+
`dataUpdatedAt`, `answerUrl`, and the snippets `titleActions`, `taskLine`,
|
|
191
|
+
`player`, `frameActions`, `readOnlyNotice`. `head={false}` when the host owns
|
|
192
|
+
`<svelte:head>`.
|
|
193
|
+
|
|
194
|
+
**The answer must go somewhere, or the page says so.** A page that carries
|
|
195
|
+
answerable content (decision cards, item-review blocks, verdict-taking
|
|
196
|
+
blocks, actions) shows a notice instead of controls that look live:
|
|
197
|
+
|
|
198
|
+
- **read-only** — no `onSaveBlock` (a share link): "Answers aren't saved on
|
|
199
|
+
this view", with `answerUrl` as "Open to answer";
|
|
200
|
+
- **unsent** — `onSaveBlock` is set, but no review leg can carry the picks
|
|
201
|
+
(no `review.send` for a linked task, no `review.markReviewed` + comments
|
|
202
|
+
for Done reviewing): the picks save for the viewer and the notice says
|
|
203
|
+
nobody is notified.
|
|
204
|
+
|
|
205
|
+
`readOnlyNotice` (`{ kind, answerUrl }`) replaces the wording; it never
|
|
206
|
+
removes the notice.
|
|
207
|
+
|
|
208
|
+
## Host-side (never in jatui)
|
|
209
|
+
|
|
210
|
+
A host that serves blocks pages must provide, server-side:
|
|
211
|
+
|
|
212
|
+
- **Storage**: the spec per version, per-viewer block state (`savedBlocks`,
|
|
213
|
+
including the reserved `review:<blockId>` keys), comments, note assets,
|
|
214
|
+
live data and its history trail.
|
|
215
|
+
- **Publish validation**: `normalizeContractBlocks(spec)` then
|
|
216
|
+
`validateBlocksSpec(spec)`; refuse on errors, surface `warnings`.
|
|
217
|
+
- **The review answer**: validating an untrusted review body against the
|
|
218
|
+
current version, composing the answer comment, recording it, and routing
|
|
219
|
+
it to the page OWNER (MOS: `feedbackReview.ts`, `owner-routing.ts`,
|
|
220
|
+
`alerts.server.ts`). The pure census (`review.ts`) is shared, so a desk
|
|
221
|
+
Send and a page Send count identically.
|
|
222
|
+
- **Owner routing**: `BlockInstance.owner` (and checklist row owners) is read
|
|
223
|
+
server-side only; the client never names an owner.
|
|
224
|
+
- **Auth**: who may comment, save, send; read-only surfaces simply omit the
|
|
225
|
+
adapter keys and `onSaveBlock`.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The per-block comment trigger (origin mos-kib2f): an icon + unresolved
|
|
4
|
+
* count, or a quiet "comment" when there are none. One component for both
|
|
5
|
+
* placements: BlockComments' own row above a block, and a block's heading
|
|
6
|
+
* row via SectionTools — so the two never drift.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
/** The block's label, completing "Comments on <label>". */
|
|
11
|
+
label: string
|
|
12
|
+
unresolved: number
|
|
13
|
+
open: boolean
|
|
14
|
+
onclick: () => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let { label, unresolved, open, onclick }: Props = $props()
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<button
|
|
21
|
+
type="button"
|
|
22
|
+
class="text-base-content/50 hover:border-primary hover:text-primary border-base-content/20 inline-flex shrink-0 items-center gap-1.5 rounded-field border px-2.5 py-1 text-xs transition-colors motion-reduce:transition-none"
|
|
23
|
+
aria-expanded={open}
|
|
24
|
+
aria-label="Comments on {label}{unresolved > 0
|
|
25
|
+
? ` (${unresolved} unresolved)`
|
|
26
|
+
: ''}"
|
|
27
|
+
{onclick}
|
|
28
|
+
data-comment-pill
|
|
29
|
+
>
|
|
30
|
+
<!-- Speech bubble (lucide message-circle path), inline: jatui carries no
|
|
31
|
+
icon-library dependency. -->
|
|
32
|
+
<svg
|
|
33
|
+
width="13"
|
|
34
|
+
height="13"
|
|
35
|
+
viewBox="0 0 24 24"
|
|
36
|
+
fill="none"
|
|
37
|
+
stroke="currentColor"
|
|
38
|
+
stroke-width="2"
|
|
39
|
+
stroke-linecap="round"
|
|
40
|
+
stroke-linejoin="round"
|
|
41
|
+
aria-hidden="true"
|
|
42
|
+
><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z" /></svg
|
|
43
|
+
>
|
|
44
|
+
{#if unresolved > 0}
|
|
45
|
+
<span class="tabular-nums">{unresolved}</span>
|
|
46
|
+
{:else}
|
|
47
|
+
<span class="text-base-content/40">comment</span>
|
|
48
|
+
{/if}
|
|
49
|
+
</button>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-block comment trigger (origin mos-kib2f): an icon + unresolved
|
|
3
|
+
* count, or a quiet "comment" when there are none. One component for both
|
|
4
|
+
* placements: BlockComments' own row above a block, and a block's heading
|
|
5
|
+
* row via SectionTools — so the two never drift.
|
|
6
|
+
*/
|
|
7
|
+
interface Props {
|
|
8
|
+
/** The block's label, completing "Comments on <label>". */
|
|
9
|
+
label: string;
|
|
10
|
+
unresolved: number;
|
|
11
|
+
open: boolean;
|
|
12
|
+
onclick: () => void;
|
|
13
|
+
}
|
|
14
|
+
declare const CommentPill: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type CommentPill = ReturnType<typeof CommentPill>;
|
|
16
|
+
export default CommentPill;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* FoldedRounds (origin mos-guqgs) — the "▸ N earlier rounds" section on a
|
|
4
|
+
* page that superseded older rounds (--supersedes). Each folded round
|
|
5
|
+
* renders its items and EVERY viewer's verdicts/notes as locked, read-only
|
|
6
|
+
* lines (jatui RoundHistory — the lock icon is the point: a prior decision
|
|
7
|
+
* is history, not an editable control), newest round first. A host that
|
|
8
|
+
* redirects an old slug here (MOS: ?rounds=open) passes `initiallyOpen`,
|
|
9
|
+
* so following a stale link lands with the history already showing.
|
|
10
|
+
*/
|
|
11
|
+
import RoundHistory from "../components/review/RoundHistory.svelte"
|
|
12
|
+
import type { ReviewVerdictDef } from "../components/review/reviewSummary"
|
|
13
|
+
import type { FoldedRound } from "./types.js"
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
rounds?: FoldedRound[]
|
|
17
|
+
/** Start expanded (the host read its own "open the rounds" signal). */
|
|
18
|
+
initiallyOpen?: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let { rounds = [], initiallyOpen = false }: Props = $props()
|
|
22
|
+
|
|
23
|
+
// svelte-ignore state_referenced_locally
|
|
24
|
+
let open = $state(initiallyOpen)
|
|
25
|
+
|
|
26
|
+
const VERDICTS: ReviewVerdictDef[] = [
|
|
27
|
+
{ id: "approve", label: "Approved", tone: "success" },
|
|
28
|
+
{ id: "redo", label: "Needs work", tone: "warning" },
|
|
29
|
+
{ id: "reject", label: "Rejected", tone: "error" },
|
|
30
|
+
{ id: "modify", label: "Modify", tone: "warning" },
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
function roundDate(at: string): string {
|
|
34
|
+
const t = Date.parse(at)
|
|
35
|
+
return Number.isFinite(t) ? new Date(t).toLocaleDateString() : ""
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
{#if rounds.length > 0}
|
|
40
|
+
<section
|
|
41
|
+
class="border-base-content/10 bg-base-200/40 rounded-box mb-4 border p-4"
|
|
42
|
+
aria-label="Earlier rounds folded into this page"
|
|
43
|
+
>
|
|
44
|
+
<button
|
|
45
|
+
type="button"
|
|
46
|
+
class="text-base-content/70 hover:text-base-content flex items-center gap-1.5 text-sm font-medium"
|
|
47
|
+
aria-expanded={open}
|
|
48
|
+
onclick={() => (open = !open)}
|
|
49
|
+
>
|
|
50
|
+
<span
|
|
51
|
+
class="inline-block transition-transform {open ? 'rotate-90' : ''}"
|
|
52
|
+
aria-hidden="true">▸</span
|
|
53
|
+
>
|
|
54
|
+
{rounds.length}
|
|
55
|
+
{rounds.length === 1 ? "earlier round" : "earlier rounds"} folded into this
|
|
56
|
+
page
|
|
57
|
+
</button>
|
|
58
|
+
|
|
59
|
+
{#if open}
|
|
60
|
+
<div class="mt-3 flex flex-col gap-4">
|
|
61
|
+
{#each rounds as round (round.slug)}
|
|
62
|
+
<article class="border-base-content/10 rounded-box border p-3">
|
|
63
|
+
<header class="flex flex-wrap items-baseline gap-x-2 text-sm">
|
|
64
|
+
<span class="font-medium">{round.title}</span>
|
|
65
|
+
<span class="text-base-content/50 text-xs">
|
|
66
|
+
v{round.version} · {round.publishedBy} ·
|
|
67
|
+
{roundDate(round.publishedAt)}
|
|
68
|
+
</span>
|
|
69
|
+
{#if round.reason}
|
|
70
|
+
<span class="text-base-content/40 text-xs"
|
|
71
|
+
>({round.reason})</span
|
|
72
|
+
>
|
|
73
|
+
{/if}
|
|
74
|
+
</header>
|
|
75
|
+
{#if round.entries.length > 0}
|
|
76
|
+
<div class="mt-2">
|
|
77
|
+
<RoundHistory
|
|
78
|
+
rounds={round.entries}
|
|
79
|
+
verdicts={VERDICTS}
|
|
80
|
+
open={true}
|
|
81
|
+
toggleLabel={(n) =>
|
|
82
|
+
`${n} locked ${n === 1 ? "decision" : "decisions"}`}
|
|
83
|
+
/>
|
|
84
|
+
</div>
|
|
85
|
+
{:else}
|
|
86
|
+
<p class="text-base-content/50 mt-2 text-xs">
|
|
87
|
+
No verdicts were cast on this round.
|
|
88
|
+
</p>
|
|
89
|
+
{/if}
|
|
90
|
+
</article>
|
|
91
|
+
{/each}
|
|
92
|
+
</div>
|
|
93
|
+
{/if}
|
|
94
|
+
</section>
|
|
95
|
+
{/if}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FoldedRound } from "./types.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
rounds?: FoldedRound[];
|
|
4
|
+
/** Start expanded (the host read its own "open the rounds" signal). */
|
|
5
|
+
initiallyOpen?: boolean;
|
|
6
|
+
}
|
|
7
|
+
declare const FoldedRounds: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type FoldedRounds = ReturnType<typeof FoldedRounds>;
|
|
9
|
+
export default FoldedRounds;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/** The glyphs the artifact view draws (lucide paths, ISC), inline so jatui
|
|
3
|
+
* carries no icon-library dependency. */
|
|
4
|
+
export type GlyphName =
|
|
5
|
+
| "chevron-up"
|
|
6
|
+
| "chevron-down"
|
|
7
|
+
| "list-checks"
|
|
8
|
+
| "images"
|
|
9
|
+
| "file-diff"
|
|
10
|
+
| "circle-help"
|
|
11
|
+
| "badge-check"
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<script lang="ts">
|
|
15
|
+
let { name, size = 16 }: { name: GlyphName; size?: number } = $props()
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<svg
|
|
19
|
+
width={size}
|
|
20
|
+
height={size}
|
|
21
|
+
viewBox="0 0 24 24"
|
|
22
|
+
fill="none"
|
|
23
|
+
stroke="currentColor"
|
|
24
|
+
stroke-width="2"
|
|
25
|
+
stroke-linecap="round"
|
|
26
|
+
stroke-linejoin="round"
|
|
27
|
+
aria-hidden="true"
|
|
28
|
+
>
|
|
29
|
+
{#if name === "chevron-up"}
|
|
30
|
+
<path d="m18 15-6-6-6 6" />
|
|
31
|
+
{:else if name === "chevron-down"}
|
|
32
|
+
<path d="m6 9 6 6 6-6" />
|
|
33
|
+
{:else if name === "list-checks"}
|
|
34
|
+
<path d="m3 17 2 2 4-4" /><path d="m3 7 2 2 4-4" /><path d="M13 6h8" /><path
|
|
35
|
+
d="M13 12h8"
|
|
36
|
+
/><path d="M13 18h8" />
|
|
37
|
+
{:else if name === "images"}
|
|
38
|
+
<path d="M18 22H4a2 2 0 0 1-2-2V6" /><path
|
|
39
|
+
d="m22 13-1.296-1.296a2.41 2.41 0 0 0-3.408 0L11 18"
|
|
40
|
+
/><circle cx="12" cy="8" r="2" /><rect width="16" height="16" x="6" y="2" rx="2" />
|
|
41
|
+
{:else if name === "file-diff"}
|
|
42
|
+
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" /><path
|
|
43
|
+
d="M9 10h6"
|
|
44
|
+
/><path d="M12 13V7" /><path d="M9 17h6" />
|
|
45
|
+
{:else if name === "circle-help"}
|
|
46
|
+
<circle cx="12" cy="12" r="10" /><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" /><path
|
|
47
|
+
d="M12 17h.01"
|
|
48
|
+
/>
|
|
49
|
+
{:else}
|
|
50
|
+
<path
|
|
51
|
+
d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z"
|
|
52
|
+
/><path d="m9 12 2 2 4-4" />
|
|
53
|
+
{/if}
|
|
54
|
+
</svg>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The glyphs the artifact view draws (lucide paths, ISC), inline so jatui
|
|
2
|
+
* carries no icon-library dependency. */
|
|
3
|
+
export type GlyphName = "chevron-up" | "chevron-down" | "list-checks" | "images" | "file-diff" | "circle-help" | "badge-check";
|
|
4
|
+
type $$ComponentProps = {
|
|
5
|
+
name: GlyphName;
|
|
6
|
+
size?: number;
|
|
7
|
+
};
|
|
8
|
+
declare const Glyph: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type Glyph = ReturnType<typeof Glyph>;
|
|
10
|
+
export default Glyph;
|