@sanity/workflow-studio-plugin 0.26.0 → 0.28.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,246 @@
1
1
  # @sanity/workflow-studio-plugin
2
2
 
3
+ ## 0.28.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b9947cb: Both "For me" surfaces — the document Workflows view's tab and the Workflows
8
+ tool's segment — now account for work that reached the reader through a role
9
+ rather than by name. When any listed row is assigned to a role the reader
10
+ holds, a line above the list reads "Including tasks assigned to your role". A
11
+ list whose rows only name the reader shows nothing, and neither does the tool's
12
+ "All documents" tab, which never claimed its rows were the reader's. In the tool
13
+ the line tracks the filtered list, so filtering every role-matched row away
14
+ takes it with it.
15
+
16
+ What counts as assigned is unchanged — role-matched work already appeared in
17
+ "For me" and still does, and the tab's task count is unaffected. Only the
18
+ explanation is new.
19
+
20
+ **No upgrade action required.** The notice derives from the same assignment
21
+ matching the list already used, so no definition, configuration, or role setup
22
+ changes.
23
+
24
+ **Docs impact:** Update the Studio plugin guide where it describes the "For me"
25
+ tab and the Workflows tool's For me segment, to note that role assignment
26
+ surfaces work to every holder of the role and that both surfaces say so when it
27
+ happens.
28
+
29
+ - 6584554: **BREAKING:** assignment surfaces now read the project's role catalog, so a role
30
+ with no current holders is assignable and carries its project title.
31
+
32
+ Previously the only role vocabulary was the roles loaded members happened to
33
+ hold. A role the project defines but nobody has yet could not be offered at all,
34
+ and a role named by a stored value rendered as its bare machine name because no
35
+ membership record carried a title for it. Both are fixed by reading
36
+ `GET /projects/{projectId}/roles`. That read is gated on
37
+ `sanity-project-roles: read`, which the default user-facing project roles carry
38
+ down to viewer, so it is not expected to need an administrator.
39
+
40
+ The catalog also becomes the bound on what a picker offers, which subtracts as
41
+ well as adds: a role a member holds that the catalog does not list stops being
42
+ offerable, though it still labels correctly wherever it is already assigned. On
43
+ a complete catalog nothing is lost, since every held role is in it.
44
+
45
+ Three API changes, all in `@sanity/workflow-components`:
46
+ - `ProjectMembersState` gains a required `roles` field, the project's assignable
47
+ roles. Anything constructing this state by hand must supply it; `roles: []`
48
+ preserves the previous behaviour, since resolution falls back to the roles
49
+ members hold. `MemberPicker` does not take it — it lists members only, and its
50
+ props were narrowed to the three fields it reads.
51
+ - `memberRoleFor` and `roleLabelFor` take a `RoleVocabulary` (`{members, roles}`)
52
+ in place of a bare member array. The state either adapter returns satisfies it,
53
+ so a caller holding one can pass it straight through.
54
+ - `AssigneeBadge` and `AssigneeBadges` take `vocabulary` in place of `members`,
55
+ for the same reason.
56
+
57
+ Not migrating leaves a type error at each call site rather than a silent
58
+ behaviour change.
59
+
60
+ Hosts using `@sanity/workflow-studio` or `@sanity/workflow-sdk` get the catalog
61
+ without changes: both adapters fetch it beside the member list, each behind a
62
+ per-client, per-project cache, so it costs one extra request per project per page
63
+ load however many surfaces read it. A failed roles read is deliberately
64
+ non-fatal — it degrades to the previous member-derived behaviour rather than
65
+ taking down the member list, and therefore every assignment control, with it. It
66
+ is reported once on the console with its cause, because nothing downstream can
67
+ tell an unreadable catalog from a project that defines no assignable roles. That
68
+ empty result is cached too, so a project whose catalog cannot be read stays on
69
+ the member-derived behaviour until the page reloads.
70
+
71
+ **Docs impact:** Update the assignment concepts and any Studio plugin guidance
72
+ that describes which roles can be assigned, to say the catalog is the source,
73
+ that a role with no holders is offered, and that a held role missing from the
74
+ catalog is not. The `@sanity/workflow-components` README covers the new
75
+ `RoleVocabulary` shape and the picker's behaviour.
76
+
77
+ ### Patch Changes
78
+
79
+ - f4405b4: The Workflows tool reports a failed read as a failure, in one critical-toned
80
+ banner, on every surface that derives counts or lists from it: the Workflows
81
+ tab, a workflow's definition panel, the task tabs, a workflow's board, and the
82
+ New workflow picker. A failed read is distinguishable from a project with
83
+ nothing running — it produces no zero counts, no "no tasks" empty state and no
84
+ empty board, and where a count cannot be stated the definition panel shows an
85
+ em-dash. The banner tells an editor plainly that something didn't load and that
86
+ trying later may work; the technical cause is logged to the browser console for
87
+ whoever maintains the Studio.
88
+
89
+ **No upgrade action required.** This is display-only — no API, configuration,
90
+ or stored data changes, and a successful read renders exactly as before.
91
+
92
+ **Docs impact:** None. Only the failed-read path changes; a successful read
93
+ renders identically, so nothing the Workflows tool guide describes about
94
+ active-instance counts, task lists, or the board is affected.
95
+
96
+ - a044ba5: Report a Studio start whose auto-advance lost a write race as the finished run
97
+ it is. Starting a workflow from the Studio while another runtime (a deployed
98
+ Function, a script) drives the same instance could hand the editor a warning
99
+ toast — "'…' started but didn't finish", with a raw `unexpected revision ID`
100
+ mutation error under it — for a run that had in fact completed: the Studio's own
101
+ auto-advance simply lost the write race to whoever committed the equivalent move
102
+ first. That toast was indistinguishable from a genuinely stuck workflow. The
103
+ Studio now confirms the completed start instead of warning about it.
104
+
105
+ Narrow by design: only a lost revision race whose run is already complete is
106
+ reclassified. A conflict that left the run in flight, and any other reason an
107
+ auto-advance failed, still surface as before.
108
+
109
+ `@sanity/workflow-engine` exports `isRevisionConflict`, the predicate that tells
110
+ a lost optimistic-locking race from a real error, so integrations can classify
111
+ one without matching on message text. It answers on the error alone, so narrow
112
+ to a single rev-guarded write before asking — a bare 409 also covers a create-id
113
+ collision.
114
+
115
+ **No upgrade action required.** Engine behaviour is unchanged and the new export
116
+ is additive.
117
+
118
+ **Docs impact:** `isRevisionConflict` is new public engine surface, added to the
119
+ errors section of `docs/reference.md` alongside the concurrency errors it
120
+ classifies; mirror that entry wherever published reference material lists the
121
+ engine's error helpers.
122
+
123
+ - Updated dependencies [1e4a5da]
124
+ - Updated dependencies [6584554]
125
+ - Updated dependencies [6584554]
126
+ - Updated dependencies [5050b06]
127
+ - Updated dependencies [a044ba5]
128
+ - Updated dependencies [6584554]
129
+ - @sanity/workflow-engine@0.28.0
130
+ - @sanity/workflow-components@0.28.0
131
+ - @sanity/workflow-studio@0.28.0
132
+ - @sanity/workflow-diagram@0.28.0
133
+ - @sanity/workflow-react@0.28.0
134
+
135
+ ## 0.27.0
136
+
137
+ ### Minor Changes
138
+
139
+ - b7ebbee: The Workflows document view now presents each workflow instance as its own
140
+ card rather than a row in a shared accordion band. The card's header carries
141
+ the run's title over the stage it sits at, with its status badges ("Aborted",
142
+ "Older version") on the trailing edge, so a collapsed run still says where it
143
+ stands. Clicking anywhere on the header toggles the card — the previous
144
+ double-click-the-band gesture and its discrete chevron button are gone. An
145
+ open card tints its header to separate it from the body below.
146
+
147
+ Each card carries a run's own history and actions behind an overflow menu on
148
+ its header. "Workflow history" opens the activity feed in a dialog, and
149
+ "Abort workflow…" sits under a divider, reusing the existing confirm dialog
150
+ and its required reason. Because both are now local to the card, the "View
151
+ workflow details" link that jumped to the Workflows tool is gone; the tool's
152
+ run detail keeps its own address and is still reachable from the Tasks tab
153
+ and from any link carrying the workflow intent.
154
+
155
+ Field pills lead with the field's title. A pill holding a value reads
156
+ "Title: value" with the title as a muted label; an empty pill shows the title
157
+ alone and no longer prefixes it with "Set". A pill's hover hint carries only
158
+ the author's description, since the chip now states the title itself, and a
159
+ read-only pill no longer repeats the run's own state back — "This workflow is
160
+ already complete" and "This workflow was aborted" describe the instance, which
161
+ the card already shows, while every verdict specific to the field still
162
+ appears. A to-do list holding nothing now says so with the shared empty card
163
+ rather than rendering blank, carrying the add affordance when the run can
164
+ still take items.
165
+
166
+ The stage diagram inside a card no longer sits on a filled band; its dividing
167
+ rule alone separates it from the stage's work. This also applies to the run
168
+ detail in the Workflows tool, which renders the same body.
169
+
170
+ **No upgrade action required.** This is presentation only: no plugin
171
+ configuration, workflow definition, telemetry event, or stored instance shape
172
+ changes.
173
+
174
+ **Docs impact:** Refresh any screenshot or walkthrough of the document
175
+ editor's Workflows tab — instances are cards, expanding one is a single click
176
+ on its header rather than a double click on a band, and a run's history and
177
+ abort are reached from the card's overflow menu rather than by navigating to
178
+ the Workflows tool. Update any guidance that tells readers to open the tool's
179
+ run detail for history or to stop a workflow.
180
+
181
+ - 780cf93: **BREAKING:** `ProjectMember.roles` is now `readonly {name: string; title?: string}[]` instead of `readonly string[]`, and `AssigneeStack`'s `roles` prop takes the same records rather than name strings. This affects integrations that build or read `ProjectMember` rows directly, or render `AssigneeStack` themselves. Read `role.name` wherever a role name was read before, and pass role records rather than name strings into `projectMemberRow` and `AssigneeStack`. Until migrated, TypeScript fails at those sites. Integrations using `useProjectMembers` from `@sanity/workflow-sdk` or the Studio plugin's own equivalent get the new shape without changes, because the adapters own the projection.
182
+
183
+ A role now reads as its project title rather than its machine name — `Administrator`, not `administrator` — wherever one is shown: picker role rows, assignee badges, the instance-snapshot pills, and the hover hint naming a collapsed assignee cluster. A square role avatar takes its letters from the title too, so `Blueprints Deployer` reads as `BD` where `blueprints-deployer` could only ever give one letter; its colour still derives from the machine name, so retitling a project role keeps the role's colour. A role whose membership record carries no title — or a title that is only whitespace, which counts as none — and a role named by an assignee that no current member holds, both still read as the machine name. `roleLabel`, `roleLabelFor`, and `memberRoleFor` are exported for callers rendering their own role labels.
184
+
185
+ Both people-pickers now say who a person is, so choosing one no longer requires knowing the org chart. Search matches role names and titles as well as display name and email, so typing a role narrows the list to its holders. Members are also listed by display name rather than in the order the host supplied them, which was the sequence people joined the project — expect the list order to change, and on a large project to become usable. And hovering a row previews the account behind the name — a larger avatar badged with the person's identity provider, their email, and the roles they hold. Marks exist for Google, GitHub, and `saml-`-prefixed deployments; any other provider badges nothing rather than showing an empty circle. That is what tells two members sharing a display name apart, which no role label could. Rows share one tooltip delay group, so the wait to open is paid once and moving along the list swaps the preview rather than waiting again at each row.
186
+
187
+ `MemberAvatar` takes an optional `loginProvider` to badge the provider mark onto its corner. `ProjectMember` gains optional `loginProvider` and `isCurrentUser`; both are populated by the adapters, so integrations using `useProjectMembers` get them without changes.
188
+
189
+ Neither picker ranks or groups its member rows by the roles those members hold, and neither claims who is eligible for an activity. (The roles-and-members picker still lists selectable roles above the members, as it did before.) An activity has no role gate; only an action does, and a manually fired action's `roles` is folded into its `filter` at desugar, so the accepted set is not readable from a deployed definition. A picker has nothing to derive eligibility from, and a ranked list would assert something no engine or Content Lake check backs.
190
+
191
+ Stored values are unchanged. An assignee still persists the machine role name, and titles are display only.
192
+
193
+ **Docs impact:** Update the `@sanity/workflow-components` member-selection reference for the `ProjectMember.roles` and `AssigneeStack` `roles` shapes and the `roleLabel` / `roleLabelFor` / `memberRoleFor` exports (done in this package's README). Any concept or guide page showing a role in Studio UI should show titles rather than machine names, and the assignment guide should state that a picker never restricts or ranks who may be assigned. Add the `ProjectMember.roles` migration to the release notes.
194
+
195
+ - 7788422: Every assignee field in the Studio plugin opens the same roles-and-members
196
+ picker, and a role can be assigned or cleared from any of them: the activity
197
+ row's assign control, a to-do item's assignee control, the start dialog's
198
+ assignees input, the instance-snapshot field pills and the editable field panel.
199
+ Actor fields — a claim, an action's `actor` param, provenance — keep the
200
+ members-only picker, because they name a concrete person and cannot hold a role.
201
+
202
+ A row shows one cluster holding both kinds: people as round avatars and each
203
+ assigned role as a square one, initialled and colored from the role's own name.
204
+ Roles ride on top, so a cluster past three items collapses to roles rather than
205
+ to faces, and a leading counter stands for the rest. The names live in the
206
+ cluster's hover hint, which lists roles and members under separate headings.
207
+
208
+ An activity row derives its assignment from the activity's `assignees` entry
209
+ alone. That kind is what the engine treats as the assignment — it reads that
210
+ kind for `$assigned` and caps a scope at one, the way `dueDate` is the deadline
211
+ and a plain `date` is not. Any other assignee-valued field on the activity, such
212
+ as a declared `primaryReviewer` of the singular `assignee` kind, is an ordinary
213
+ field and keeps its own picker in the snapshot pills and the activity dialog.
214
+
215
+ **No upgrade action required.** No stored shape changes: `{type: 'role', role}`
216
+ was already a valid assignee everywhere the engine accepts one. Two display
217
+ notes for anyone comparing before and after. An activity that carries an
218
+ assignee-valued field beside its `assignees` field shows fewer people on the row
219
+ than it used to, because only the `assignees` entry now feeds it — that other
220
+ field is unchanged and still editable in the snapshot and the dialog. And the
221
+ Workflows tool's assignee filter names people only, so a role-assigned task is
222
+ not selected by filtering on a member who holds that role.
223
+
224
+ **Docs impact:** Update the Studio plugin guide where it describes assigning
225
+ activities and to-do items, so it states that assignment accepts a role as well
226
+ as a person from every assignee control, and that a role shows as a square
227
+ avatar whose name appears on hover. Refresh screenshots of the activity row.
228
+ Note in the assignment concept material that a row's assignment is the
229
+ `assignees` entry, and that other assignee-valued fields are ordinary fields.
230
+ The assignee-filter behavior above is worth a sentence wherever the Workflows
231
+ tool's filters are documented.
232
+
233
+ ### Patch Changes
234
+
235
+ - Updated dependencies [780cf93]
236
+ - Updated dependencies [7788422]
237
+ - Updated dependencies [b7c8bed]
238
+ - @sanity/workflow-components@0.27.0
239
+ - @sanity/workflow-engine@0.27.0
240
+ - @sanity/workflow-studio@0.27.0
241
+ - @sanity/workflow-react@0.27.0
242
+ - @sanity/workflow-diagram@0.27.0
243
+
3
244
  ## 0.26.0
4
245
 
5
246
  ### Patch Changes