@sanity/workflow-studio-plugin 0.1.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,111 @@
1
1
  # @sanity/workflow-studio-plugin
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 50269b7: Every activity-row chip explains itself on hover: "Awaiting decision" ("More than one action can settle this activity — someone needs to decide"), "Blocked" ("None of its actions can be fired right now — open the activity to see why"), and "Failed" ("This activity settled as failed"), matching the "Automated" pill's hover. The hint copy is keyed on the chip vocabulary, so a new chip fails typecheck until it carries one.
8
+ - 000297c: Redesigned activity detail dialog, and one date/reference editing model across the plugin.
9
+ - The activity dialog is now a form-like surface: a sticky meta block (description, status, and the non-terminal action strip) above a separator, then every declared field in declaration order — assignees included — each with its label, declared description, and editor (or read-only face). The meta block stays in reach while the fields scroll. All edits stay real-time (text commits on blur/Enter, single-gesture widgets commit on change).
10
+ - Actions split into two buckets. Actions that leave the activity's status alone (field writes, effects, cross-activity nudges) render as a quiet strip in the meta block; actions that write the activity's own status live in the footer beside a Cancel button — the first as the solid primary (critical tone for a failed-settling back-out), the rest behind the split button's chevron menu segment.
11
+ - Terminal actions also fire straight from the activity list rows (Overview and For me): each open row carries a quiet ghost cluster — one outline around the primary and the chevron menu segment — so routine advances don't require opening the dialog. Settled rows stay control-free.
12
+ - Uniform action model: every rendered action is a button. Actions with params — a single actor or document pick included — open a confirm dialog from an ellipsis-suffixed button; the assignment and fire-on-pick row treatments are gone (one extra confirm click for those flows).
13
+ - Cascade-fired actions render in the top action row as caution-toned automation rows; clicking opens an explainer that puts the trigger into plain language with live outcome marks. The off-system manual link rides the same row with the same caution tone.
14
+ - Fields whose change can advance the workflow or fire an activity's automation carry an info affordance beside their label explaining the consequence; the lightning-bolt hot-field badge is gone.
15
+ - `doc.ref` fields are now editable inline through the document picker, scoped to the field's declared accepted types.
16
+ - Every date/datetime editing surface (dialog fields, field-pill popovers, action params, the start form) uses the shared DatePicker input — no native browser date inputs remain.
17
+ - Every field in the dialog renders through its input face: read-only fields keep the same chrome inert (read-only text inputs, a disabled switch, a disabled date picker, reference previews without their Change affordance, an inert search face for empty references) with no "Read-only" caption, and empty values render as empty inputs, never an em-dash.
18
+ - The activity status label reads "Active" (was "Open"), matching the engine's status vocabulary.
19
+ - Quieter surfaces: the dialog's "Pending on you" callout is gone, and a done or skipped activity shows no status chip in the activities list (its status icon carries it) — the chip column is reserved for Failed, Blocked, and Awaiting decision.
20
+ - The stage spine tells the truth about send-backs: a visited stage that lies AHEAD of the current one again no longer wears the completed checkmark or a "Completed at" tooltip — it reads as a plain upcoming pill whose hover card says "Last exited …" and counts its activities like upcoming work.
21
+
22
+ - 000297c: Activity rows drop the "Skipped" chip — the status icon already carries that state — and hovering any row's status icon now shows the status name in a tooltip.
23
+ - 000297c: The singular `assignee` kind is now editable everywhere it renders. The Overview's field pills and the activity dialog's inline fields both open the same roles-and-members picker as the plural `assignees` editor, in single-select form: a pick replaces the value and closes the picker, and picking the current holder clears the field. Previously the kind had no editing surface at all — an editable assignee rendered as a read-only pill, and the dialog fell back to a free-text input over the stringified value.
24
+ - 50269b7: Activity list rows (Overview and For me) mark truly hands-off activities with an "Automated" pill, so editors scanning a stage can tell which rows need a person and which the system resolves on its own. The pill keys on two engine facets agreeing: every action is cascade-fired (executor classification `autonomous`) AND the causal autonomy analysis is certain the activity completes without a caller — a mechanically autonomous activity whose triggers read caller-written state is progressed by the person doing that work, and shows no pill. Undecidable verdicts render nothing (quiet over wrong), and settled rows show no pill. Hovering the pill explains it: "Completes on its own — no user action is needed".
25
+ - 50269b7: The activity dialog's cascade-fired automation rows are inert with an explanatory hover, replacing the click-to-open explainer dialog. The button is permanently disabled and default-toned (nothing needs attention — the engine has it); hovering shows a "Fired by the system" lead, the action's declared description when it has one, then the trigger's reason — one plain-language sentence for a single-atom trigger, the marked checklist lines for a compound one, the raw GROQ while the definition is still resolving. Constant triggers phrase as the rule they follow ("Runs automatically each time the stage is entered") rather than the checklist's bare "always"/"never". The rows also tighten the gap between the bolt icon and the action label by one spacing step.
26
+ - 000297c: Counts shed their parenthesized suffixes for a muted count after the label: the Workflows view's "For me" tab and the pill rows' "Show more" toggle.
27
+ - d0c62ea: The plugin renders the reactive layer's `invalid` state instead of an eternal spinner: an unreadable engine-owned document (a `model-ahead` doc needing a newer `@sanity/workflow-engine`, or a corrupt one) surfaces a remediation notice in the form strip and the Workflows view — both for a live session's instance and for a wholesale-invalid discovery read, which now also stops reading as "loading" while keeping already-resolved entries rendered.
28
+ - 000297c: Instance headers (the Overview's sections and For me's, which share the same accordion) mark an instance whose pinned definition version has been superseded by a newer deploy: an "Older definition" chip with a hover hint naming the pinned and latest versions. Advisory only — an instance keeps the definition it started on, so the chip explains why a fresh deploy isn't reflected rather than offering an action. The comparison reads the same deployed-definitions query mapping validation already runs (provider mount and every start-dialog open), so it can lag a deploy made since.
29
+ - 5a1a9fe: The plugin's direct `engine.query` reads adopt the data-model gate. The two definition reads (mapping validation, the start dialog's definition lookup) surface a newer-model definition through their existing error paths ("upgrade `@sanity/workflow-engine`") instead of rendering it unchecked; the start-filter pre-flight's instance-slice read gates each row too, with a gate failure riding its declared fail-open posture (log and keep the start control shown — the verdict is a visibility hint, not a gate).
30
+ - c3eed2e: Add the dedicated Workflows tool — a Studio navbar tab with a Tasks view (My tasks / All tasks segments over every open activity, grouped by document with sub-workflow folding), a dashboard of the newest workflow instances (capped, settled runs folded behind a toggle), and a deep-linkable per-instance detail view rendering the stage diagram (`@sanity/workflow-diagram`) plus the same activities/action-items lists and activity detail dialog as the Workflows document view. Both tabs mount a five-category filter panel (document, status, assignee, workflow, date — the date arm bounds ANY date/datetime a task carries; dates are plain facts, the model has no deadline property): tag inputs with pills inside the field, options in overlays anchored under each field, multi-value within a category, and active filters mirrored as dismissible chips. "New workflow" starts any deployed startable definition through a searchable picker feeding the existing start dialog; the tool claims a `workflow` intent, and the instance header's overflow menu links into it.
31
+
32
+ Display faces no longer flip through wrong values while data resolves: the document-list stage pill reads its title from the instance's embedded definition snapshot (instead of flashing the raw stage name until the live evaluation lands), document previews hold a placeholder skeleton instead of painting "Untitled" first, and filter pill/chip labels hold a neutral pending face until preview titles and member names resolve.
33
+
34
+ - 1321ba5: The start control pre-flights both start predicates: `start.filter` (visibility — evaluated browse-time-pure, no `$fields`) and the new `start.allowed` (permission — `$fields` bound from the seeded subject and selected release; the row disables with a reason only on a definitive refusal, and only when every entry the predicate reads is bindable up front). The start dialog surfaces a `StartNotAllowedError` from `startInstance` as its own warning toast instead of a generic failure.
35
+ - 000297c: The plugin speaks the engine's todo-list vocabulary end to end: the todo failure toast reads "Updating to-dos failed" and the add-item placeholder reads "New to-do" — both previously said "action item(s)".
36
+ - e3a7ba2: The start dialog now holds a per-attempt instance id — start's idempotency key — so a retry after a failed start resumes the same instance instead of minting a duplicate; editing inputs after a failure deliberately starts a new one. An unfinished start already on the subject is adopted when the dialog opens: the input form is replaced by a "continue that attempt" note (its inputs were pinned at create) with an explicit "start a new workflow instead" opt-out. A start whose first auto-advance fails (`StartNotSettledError`) reports "started, but didn't finish auto-advancing" and closes — the run exists, so a failure toast would contradict the live list. Unfinished starts (created, never primed) are named where they render: a "Start incomplete" badge in the form strip and on document-list preview rows, and a Workflows-view notice instead of a normal run at its initial stage. The start control's advisory `start.filter`/`start.allowed` pre-flights stand down when an unfinished start exists on the subject — the flow resumes it, and a dedupe-style `allowed` would otherwise refuse because of the very husk the start needs to finish.
37
+ - 092a0d4: `WorkflowPluginConfig` takes `resourceClients` — a cross-resource read-routing resolver passed through to the Studio engine. A served resource is also part of the declared surface for refs written into field state, so this is how a Studio deployment admits media-library/canvas refs written through the plugin.
38
+ - 000297c: The Workflows view's Overview / For me tab now rides the pane's URL params, so a reload or bookmark restores the selected tab. The param is written only for For me — Overview URLs stay unchanged — and an unrecognized value falls back to Overview.
39
+
40
+ ### Patch Changes
41
+
42
+ - 50269b7: The activity detail dialog drops its empty body panel for activities with no declared fields: the meta block's bottom separator and the padded field area render only when there are fields (or a blocked notice) to show below them.
43
+ - 000297c: The spine's stage-overview hint drops the extra inner padding that made it visibly fatter than every other tooltip. All hints now render through one seam that pins the tooltip chrome (padding, radius, width cap, open delay), and a lint rule keeps raw Tooltip imports out of the plugin so the chrome can't drift per surface.
44
+ - Updated dependencies [f9389e5]
45
+ - Updated dependencies [f9389e5]
46
+ - Updated dependencies [d0c62ea]
47
+ - Updated dependencies [c3eed2e]
48
+ - Updated dependencies [df4bd80]
49
+ - Updated dependencies [b43de49]
50
+ - Updated dependencies [092a0d4]
51
+ - Updated dependencies [5a1a9fe]
52
+ - Updated dependencies [5a1a9fe]
53
+ - Updated dependencies [5a1a9fe]
54
+ - Updated dependencies [e3a7ba2]
55
+ - Updated dependencies [30fed9e]
56
+ - Updated dependencies [c3eed2e]
57
+ - Updated dependencies [1321ba5]
58
+ - Updated dependencies [e683875]
59
+ - Updated dependencies [a8ace4d]
60
+ - @sanity/workflow-diagram@0.3.0
61
+ - @sanity/workflow-engine@0.17.0
62
+ - @sanity/workflow-studio@0.8.0
63
+ - @sanity/workflow-react@0.12.0
64
+
65
+ ## 0.2.0
66
+
67
+ ### Minor Changes
68
+
69
+ - 11e2d6f: Activity rows' status chips gain a settled vocabulary: Done / Skipped / Failed activities now carry their outcome as a chip, and the decision attention state renames from "Decision needed" to "Awaiting decision" (Blocked is unchanged). Pending rows stay chip-less — the dashed status icon and muted title already read as not-yet-open.
70
+ - 11e2d6f: Date and datetime field pills now open a Studio-style calendar picker directly (month dropdown, year stepper, day grid — plus a time row with "Set to current time" on datetime fields) instead of the free-text edit row. A day pick commits immediately; date-only pickers close on pick, while datetime pickers stay open so the time row remains reachable. The action-item due-date control opens the same calendar in place of its native date input, keeping its clear affordance as a footer row.
71
+ - 11e2d6f: The form strip's start affordance now scales with the document type's mapping rows, like the Overview header's "+" already did: one row keeps the direct "Start workflow" button, several open a bottom/left-anchored menu (falling back to top/left) with one start per workflow. The mandatory-workflow gate offers the same choice, and its prompt names the workflow only when exactly one is mapped. `WorkflowFormStrip` and `MandatoryWorkflowGate` now take `mappings` (every row for the doc type) instead of a single `mapping`; `StartWorkflowControl` grew the button's appearance props (`label`, `iconOnly`, `mode`, `tone`) so each surface styles both of its faces at once.
72
+ - 11e2d6f: Redesign the Workflows document view's Overview. Every instance renders as a collapsible accordion section — in-flight runs under "Active Workflows", settled runs under a "Finished Workflows" heading, collapsed by default with the Completed/Aborted chip on the header. Each section carries workflow- and stage-scope field pills (popover editing for scalars, the actor picker, and the combined roles+members assignees picker; a True/False menu for booleans; a modal dialog for todo lists; a pill without an editor opens a read-only popover with the committed value and, when known, the reason it can't be edited). Document-reference pill faces show the resolved preview title, or italic "Untitled" when none resolves; role assignees render on the pill as plain text rather than a badge, so every pill keeps the same height. Sections also carry the stage spine, a next-stage hint card (rendered only for single-transition stages), and the activity rows. The action-items section leaves the Overview: todo items live on the For me tab — now aggregated across every instance with one shared empty state — and in the per-field todo dialog. Completed todos stay listed on For me with a struck-through label instead of vanishing on check; only open work counts toward the tab's number and the form strip's assigned-tasks metric, and the empty state waits until no assigned rows (open or done) remain. The header's start affordance becomes a menu when several workflow definitions map to the document type, and mapping validation verdicts are keyed per mapping row (docType + definition), so two rows sharing a docType keep distinct verdicts. The debug surfaces leave the tab strip: the State (debug) tab is removed, and the activity log moves behind each section's overflow menu as an "Event log (debug)" dialog.
73
+ - e5f5b77: **BREAKING:** follow the engine's actions-only payload model across every plugin surface.
74
+ - A cascade-fired (`when`) action is never a button: it leaves the action rows, the detail-dialog footer, and the checklist tick wiring, and surfaces only as "happens automatically" narration in the activity detail dialog.
75
+ - Filter-existence semantics: an action whose filter failed renders ABSENT — not disabled. The Blocked chip and the blocked-reason panel consider only rendered actions, so an activity whose only actions the engine fires reads as waiting, never blocked.
76
+ - A filter-scoped-out activity does not exist for the visit: it leaves the activities list (the history feed keeps the audit trail); an activity an action resolved `skipped` was real work and stays visible. The `pending` activation lifecycle is gone — activities are active from stage entry (its `EmptyIcon` status glyph leaves the status-icon map with it).
77
+ - The history feed follows the new entries: no activation rows, and a cascade-fired action reads "by the workflow" instead of an actor.
78
+ - `WorkflowMapping.effectsContextBuilder` renamed `contextBuilder` — it seeds `startInstance`'s renamed `context` bag (the `$context` variable).
79
+
80
+ - 11e2d6f: The Overview's stage block is now one bordered card: the spine band sits above a hairline divider, the current stage's work below it. Spine nodes render as bordered pills joined by hairline connectors sized on the theme's space scale, and the definition-missing notice takes the band slot inside the same card. The current-stage chip — on the spine and the form strip — now wears the theme's vibrant primary-button blues: a focus-ring outline with the ghost-primary fg/bg pair. Rows that mix badges into capsized text (the stage heading's round chip, the start dialog's release row) derive the same height whether or not the badge renders. Every spine pill now responds to hover/focus with a stage overview card — title, authored description, where the current stage advances (single-transition stages), the completion moment on past stages, and the activity count on current/upcoming ones. The pills hover like buttons (help cursor) but are not buttons: they drive nothing on click and show no pressed face.
81
+ - 6a46db1: Follow the engine's `start` block (`start.kind` classification + the read-side `start.filter` visibility predicate):
82
+ - workflow-mcp: `list_workflow_definitions` entries carry `startKind` (`'interactive' | 'autonomous'` — a classification, never a restriction).
83
+ - workflow-studio-plugin: start controls adopt the start model — `start.kind: 'autonomous'` mappings render no start affordance (automation owns their genesis), and a `start.filter` that DEFINITIVELY evaluates false on what's known before the dialog opens hides/disables the row with the start-condition reason. The pre-flight is purely additive: it never blocks a start the engine would accept, so every uncertain case (still loading, a dialog-collected `$fields` read, an eval error) shows the row. A failed start surfaces through the dialog's normal error toast.
84
+ - workflow-examples: `expense-approval` demonstrates a `start.filter` — one open approval per expense, as a picker-visibility filter (the Start list won't offer a second; not a gate).
85
+
86
+ - 11e2d6f: The form strip simplifies to one line. A single active instance renders its definition title as plain text beside the current stage in the primary chip — the same `StageChip` face the Overview spine's current node now wears (the chip carries the stage glyph instead of a dot). Several active instances collapse to "N active workflows" with no stages, and the assigned-task count aggregates across the listed runs (held at Loading…/Updating… until every instance's evaluation is trustworthy). Finished runs no longer appear on the strip — the "Show N finished" reveal is gone; the Workflows view owns history. Clicking the line opens the Workflows view without targeting an instance, and the unused `workflowInstance` pane param is removed.
87
+
88
+ ### Patch Changes
89
+
90
+ - 9dc592d: Four document-surface correctness fixes:
91
+ - **Self-registering document hooks.** `useWorkflowsForDocument` now registers the document with discovery on mount and releases it on unmount (refcounted), so reading a document's workflows is what keeps discovery live for it. The footer badges and the publish/delete action lock previously read discovery without registering — on a host-added custom document view, switching away from the form strip dropped the document and the lock silently disengaged while the guard still denied the write. Every surface that reads a document's workflows now inherits registration.
92
+ - **Existence probe sees release versions.** The doc-ref preview's "Document unavailable" probe now matches published, draft, and any release version (`versions.<release>.<id>`) under the raw perspective — a subject persisted only as a release version no longer renders as missing.
93
+ - **The `doc.ref` picker honours the entry's `types` facet.** The start dialog's reference picker and its "Create new" affordance scope to the entry's declared accepted types, falling back to the mapped document type only when the entry declares none — facet-declared entries are pickable and "Create new" mints an accepted type. Several accepted types get a create menu over just those types.
94
+ - **No empty footer for checkbox-only activities.** The activity detail dialog's footer no longer renders an empty band when an activity's only actions are ticks (they render as their item's checkbox, never a footer button).
95
+
96
+ - Updated dependencies [11e2d6f]
97
+ - Updated dependencies [7510fd5]
98
+ - Updated dependencies [01e8042]
99
+ - Updated dependencies [79c54db]
100
+ - Updated dependencies [9dc592d]
101
+ - Updated dependencies [6a46db1]
102
+ - Updated dependencies [35b9b85]
103
+ - Updated dependencies [e5f5b77]
104
+ - Updated dependencies [01e8042]
105
+ - @sanity/workflow-engine@0.16.0
106
+ - @sanity/workflow-react@0.11.0
107
+ - @sanity/workflow-studio@0.7.1
108
+
3
109
  ## 0.1.0
4
110
 
5
111
  ### Minor Changes
package/README.md CHANGED
@@ -9,8 +9,10 @@ stages like _Drafting → Review → Approved_, and the actions that move work
9
9
  between them — deploy it to your dataset, and this plugin gives editors the
10
10
  UI: a **workflow strip** above the editor form of mapped documents (the
11
11
  current stage, your task count, and a **Start workflow** button), and a
12
- **Workflows tab** next to the editor with the stage's activities and action
13
- items, where they fire actions and read the history.
12
+ **Workflows tab** next to the editor with the stage's activities and to-dos,
13
+ where they fire actions and read the history, and a **Workflows tool** in the
14
+ Studio navbar — a tasks view, a dashboard of the newest workflow instances,
15
+ and a deep-linkable per-workflow detail view.
14
16
 
15
17
  Four ideas cover everything in this guide:
16
18
 
@@ -64,12 +66,11 @@ export const articleReview = defineWorkflow({
64
66
  {
65
67
  name: 'write',
66
68
  title: 'Write the article',
67
- activation: 'auto',
68
69
  // `status: 'done'` = firing this action completes the activity.
69
70
  actions: [{name: 'submit', title: 'Submit for review', status: 'done'}],
70
71
  },
71
72
  ],
72
- // No filter = the stage advances once all its activities are done.
73
+ // No `when` = the stage advances once all its activities are done.
73
74
  transitions: [{name: 'to-review', title: 'Send to review', to: 'review'}],
74
75
  },
75
76
  {
@@ -79,7 +80,6 @@ export const articleReview = defineWorkflow({
79
80
  {
80
81
  name: 'review',
81
82
  title: 'Review the article',
82
- activation: 'auto',
83
83
  actions: [{name: 'approve', title: 'Approve', status: 'done'}],
84
84
  },
85
85
  ],
@@ -205,10 +205,10 @@ Everything above works with editors driving. Two things need a caller when
205
205
  no editor is looking, and both are small
206
206
  [Sanity Functions](https://www.sanity.io/docs/functions):
207
207
 
208
- - **heartbeat** — definitions can wait on time (`completeWhen` conditions
209
- over `$now`, e.g. an embargo date). Time passing emits no event, so a
210
- schedule must periodically `tick` in-flight instances. Ticking an instance
211
- with nothing due is a no-op.
208
+ - **heartbeat** — definitions can wait on time (`when` triggers over `$now`,
209
+ e.g. an embargo date). Time passing emits no event, so a schedule must
210
+ periodically `tick` in-flight instances. Ticking an instance with nothing
211
+ due is a no-op.
212
212
  - **drain-effects** — definitions can queue **effects** (named side-effects
213
213
  like "publish the subject"). This function runs your handlers for them
214
214
  whenever an instance has pending effects. Effects it has no handler for