@sanity/workflow-studio-plugin 0.29.0 → 0.30.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.
@@ -291,7 +291,7 @@ function landingDefaultOpen(landing, instanceId) {
291
291
  if (!(landing === void 0 || !landing.instanceIds.includes(instanceId))) return instanceId === landing.focusedId;
292
292
  }
293
293
 
294
- const WORKFLOWS_TOOL_NAME = "workflows", WORKFLOW_INTENT = "workflow";
294
+ const WORKFLOWS_TOOL_NAME = "workflows", WORKFLOW_INTENT = "workflow", RUN_SEARCH_PARAM = "run";
295
295
 
296
296
  function pathSegmentName(args) {
297
297
  return args.names.find(name => name === args.segment);
@@ -303,9 +303,10 @@ function handlesWorkflowIntent(intent, params) {
303
303
 
304
304
  function workflowIntentState(intent, params) {
305
305
  const instanceId = params.instanceId;
306
- return intent === WORKFLOW_INTENT && typeof instanceId == "string" ? {
307
- instanceId: instanceId
308
- } : null;
306
+ return intent !== WORKFLOW_INTENT || typeof instanceId != "string" ? null : {
307
+ workflowsTab: "overview",
308
+ _searchParams: [ [ RUN_SEARCH_PARAM, instanceId ] ]
309
+ };
309
310
  }
310
311
 
311
312
  const pad2 = n => String(n).padStart(2, "0"), DUE_DATE_FIELD_KINDS = [ "dueDate", "dueDatetime" ], DATE_FIELD_KINDS = [ "date", "datetime", ...DUE_DATE_FIELD_KINDS ], DATE_FIELD_KIND_SET = new Set(DATE_FIELD_KINDS), DUE_DATE_FIELD_KIND_SET = new Set(DUE_DATE_FIELD_KINDS);
@@ -402,14 +403,19 @@ function formatTimeAgo(value) {
402
403
  }
403
404
 
404
405
  function formatShortAgo(value, now) {
406
+ const span = formatShortSpan(value, now);
407
+ return span === "—" ? "—" : span === "now" ? "just now" : `${span} ago`;
408
+ }
409
+
410
+ function formatShortSpan(value, now) {
405
411
  const d = new Date(value);
406
412
  if (Number.isNaN(d.getTime())) return "—";
407
413
  const seconds = Math.floor((now.getTime() - d.getTime()) / 1e3);
408
- if (seconds < 60) return "just now";
414
+ if (seconds < 60) return "now";
409
415
  const minutes = Math.floor(seconds / 60);
410
- if (minutes < 60) return `${minutes}m ago`;
416
+ if (minutes < 60) return `${minutes}m`;
411
417
  const hours = Math.floor(minutes / 60);
412
- return hours < 24 ? `${hours}h ago` : `${Math.floor(hours / 24)}d ago`;
418
+ return hours < 24 ? `${hours}h` : `${Math.floor(hours / 24)}d`;
413
419
  }
414
420
 
415
421
  function stampFace(verb, at) {
@@ -633,7 +639,7 @@ function todoFieldEditability(args) {
633
639
  }
634
640
 
635
641
  function itemRow(args) {
636
- const {item: item, items: items, field: field, source: source, ticks: ticks, editability: editability} = args, tick = ticks.get(tickKey(field.name, item._key));
642
+ const {item: item, items: items, field: field, source: source, ticks: ticks, editability: editability} = args, tick = ticks.get(tickKey(field.name, item._key)), eligibleAssigneeRoles = field.of.find(column => column.name === "assignee" && column.type === "assignee")?.roles;
637
643
  return {
638
644
  item: item,
639
645
  items: items,
@@ -648,6 +654,9 @@ function itemRow(args) {
648
654
  ...editability.editDisabledReason ? {
649
655
  editDisabledReason: editability.editDisabledReason
650
656
  } : {},
657
+ ...eligibleAssigneeRoles === void 0 ? {} : {
658
+ eligibleAssigneeRoles: eligibleAssigneeRoles
659
+ },
651
660
  ...tick ? {
652
661
  tick: tick
653
662
  } : {}
@@ -1047,24 +1056,10 @@ function dateValuesOf(state, matches) {
1047
1056
  return state.filter(entry => matches(entry._type)).map(entry => entry.value).filter(value => typeof value == "string" && value !== "");
1048
1057
  }
1049
1058
 
1050
- function datesOf(state) {
1051
- return dateValuesOf(state, isDateFieldKind);
1052
- }
1053
-
1054
1059
  function dueDatesOf(state) {
1055
1060
  return dateValuesOf(state, isDueDateFieldKind);
1056
1061
  }
1057
1062
 
1058
- function committedRowFace(row) {
1059
- return {
1060
- activityName: row.activityName,
1061
- title: row.title,
1062
- status: row.status,
1063
- automated: !1,
1064
- blocked: !1
1065
- };
1066
- }
1067
-
1068
1063
  function activityRowProps(args) {
1069
1064
  const {activityEval: activityEval, activityState: activityState, editableFields: editableFields} = args, state = activityState.get(activityEval.activity.name) ?? [], controlArgs = {
1070
1065
  activity: activityEval.activity,
@@ -1163,15 +1158,15 @@ function useWorkflowInstanceEntry(instanceId, options = {}) {
1163
1158
  }
1164
1159
 
1165
1160
  const WorkflowToolOpened = telemetry.defineEvent({
1166
- name: "Editorial Workflows Studio Plugin Tool Opened",
1167
- version: 2,
1161
+ name: "Workflows Studio Plugin Tool Opened",
1162
+ version: 3,
1168
1163
  description: "The Workflows tool was opened or its tab was switched"
1169
1164
  }), WorkflowDocumentViewOpened = telemetry.defineEvent({
1170
- name: "Editorial Workflows Studio Plugin Document View Opened",
1165
+ name: "Workflows Studio Plugin Document View Opened",
1171
1166
  version: 1,
1172
1167
  description: "The Workflows document view was opened or its tab was switched"
1173
1168
  }), WorkflowInstanceDetailViewed = telemetry.defineEvent({
1174
- name: "Editorial Workflows Studio Plugin Instance Detail Viewed",
1169
+ name: "Workflows Studio Plugin Instance Detail Viewed",
1175
1170
  version: 1,
1176
1171
  description: "The Workflows tool's per-instance detail view was opened"
1177
1172
  });
@@ -1184,67 +1179,63 @@ function definitionFingerprint(definition) {
1184
1179
  }
1185
1180
 
1186
1181
  const WorkflowDefinitionDetailViewed = telemetry.defineEvent({
1187
- name: "Editorial Workflows Studio Plugin Definition Detail Viewed",
1182
+ name: "Workflows Studio Plugin Definition Detail Viewed",
1188
1183
  version: 1,
1189
1184
  description: "A workflow's definition page was opened in the Workflows tool"
1190
1185
  }), WorkflowFormStripClicked = telemetry.defineEvent({
1191
- name: "Editorial Workflows Studio Plugin Form Strip Clicked",
1186
+ name: "Workflows Studio Plugin Form Strip Clicked",
1192
1187
  version: 1,
1193
1188
  description: "The form strip's instance line was clicked, opening the document view"
1194
1189
  }), WorkflowDocumentLinkClicked = telemetry.defineEvent({
1195
- name: "Editorial Workflows Studio Plugin Document Link Clicked",
1196
- version: 2,
1190
+ name: "Workflows Studio Plugin Document Link Clicked",
1191
+ version: 3,
1197
1192
  description: "A document link was clicked, opening the referenced document's editor"
1198
1193
  }), WorkflowStartDialogOpened = telemetry.defineEvent({
1199
- name: "Editorial Workflows Studio Plugin Start Dialog Opened",
1194
+ name: "Workflows Studio Plugin Start Dialog Opened",
1200
1195
  version: 1,
1201
1196
  description: "The start-workflow dialog was opened"
1202
1197
  }), WorkflowStartDialogSubmitted = telemetry.defineEvent({
1203
- name: "Editorial Workflows Studio Plugin Start Dialog Submitted",
1198
+ name: "Workflows Studio Plugin Start Dialog Submitted",
1204
1199
  version: 1,
1205
1200
  description: "The start-workflow dialog's confirm was pressed"
1206
1201
  }), WorkflowAutoStartRan = telemetry.defineEvent({
1207
- name: "Editorial Workflows Studio Plugin Auto Start Ran",
1202
+ name: "Workflows Studio Plugin Auto Start Ran",
1208
1203
  version: 1,
1209
1204
  description: "A fresh document's auto-start ran — one start request per configured workflow"
1210
1205
  }), WorkflowActionControlUsed = telemetry.defineEvent({
1211
- name: "Editorial Workflows Studio Plugin Action Control Used",
1212
- version: 2,
1206
+ name: "Workflows Studio Plugin Action Control Used",
1207
+ version: 3,
1213
1208
  description: "An action-firing control was used, attributed to its UI surface"
1214
1209
  }), WorkflowFieldControlUsed = telemetry.defineEvent({
1215
- name: "Editorial Workflows Studio Plugin Field Control Used",
1216
- version: 1,
1210
+ name: "Workflows Studio Plugin Field Control Used",
1211
+ version: 2,
1217
1212
  description: "A field-editing control committed an edit, attributed to its UI surface"
1218
1213
  }), WorkflowActivityDialogOpened = telemetry.defineEvent({
1219
- name: "Editorial Workflows Studio Plugin Activity Dialog Opened",
1220
- version: 1,
1214
+ name: "Workflows Studio Plugin Activity Dialog Opened",
1215
+ version: 2,
1221
1216
  description: "The activity detail dialog was opened"
1222
- }), WorkflowTaskFiltersApplied = telemetry.defineEvent({
1223
- name: "Editorial Workflows Studio Plugin Task Filters Applied",
1224
- version: 1,
1225
- description: "The tool's task-filter menu closed with a changed selection"
1226
1217
  }), WorkflowBoardWorkflowSelected = telemetry.defineEvent({
1227
- name: "Editorial Workflows Studio Plugin Board Workflow Selected",
1228
- version: 2,
1229
- description: "The workflow documents page settled on the workflow it's showing"
1218
+ name: "Workflows Studio Plugin Board Workflow Selected",
1219
+ version: 3,
1220
+ description: "The Overview's board display settled on the workflow it's showing"
1230
1221
  }), WorkflowTitleSeedDrifted = telemetry.defineEvent({
1231
- name: "Editorial Workflows Studio Plugin Title Seed Drifted",
1222
+ name: "Workflows Studio Plugin Title Seed Drifted",
1232
1223
  version: 1,
1233
1224
  description: "A cold-start seeded preview title diverged from the live preview pipeline"
1234
1225
  }), WorkflowTodoToggled = telemetry.defineEvent({
1235
- name: "Editorial Workflows Studio Plugin Todo Toggled",
1226
+ name: "Workflows Studio Plugin Todo Toggled",
1236
1227
  version: 1,
1237
1228
  description: "A todo checkbox was toggled, attributed to its UI surface and write seam"
1238
1229
  }), WorkflowTodoEdited = telemetry.defineEvent({
1239
- name: "Editorial Workflows Studio Plugin Todo Edited",
1230
+ name: "Workflows Studio Plugin Todo Edited",
1240
1231
  version: 1,
1241
1232
  description: "A non-toggle todo-list write, attributed to its UI surface and gesture"
1242
1233
  }), WorkflowAbortDialogOpened = telemetry.defineEvent({
1243
- name: "Editorial Workflows Studio Plugin Abort Dialog Opened",
1234
+ name: "Workflows Studio Plugin Abort Dialog Opened",
1244
1235
  version: 1,
1245
1236
  description: "The abort-workflow confirm was opened"
1246
1237
  }), WorkflowAbortDialogSubmitted = telemetry.defineEvent({
1247
- name: "Editorial Workflows Studio Plugin Abort Dialog Submitted",
1238
+ name: "Workflows Studio Plugin Abort Dialog Submitted",
1248
1239
  version: 1,
1249
1240
  description: "The abort-workflow confirm was submitted, carrying the attempt's outcome"
1250
1241
  });
@@ -1280,6 +1271,12 @@ function scalarValidationIssue(args) {
1280
1271
  return issues === void 0 ? void 0 : `${args.label}: ${issues.join("; ")}`;
1281
1272
  }
1282
1273
 
1274
+ function countBy(rows, keysOf) {
1275
+ const counts = /* @__PURE__ */ new Map;
1276
+ for (const row of rows) for (const key of keysOf(row)) counts.set(key, (counts.get(key) ?? 0) + 1);
1277
+ return counts;
1278
+ }
1279
+
1283
1280
  function personActor(user) {
1284
1281
  const roles = user.roles.map(role => typeof role == "string" ? role : role.name);
1285
1282
  return {
@@ -1311,10 +1308,16 @@ function userDisplayFor(args) {
1311
1308
  return {
1312
1309
  id: args.id,
1313
1310
  name: member?.displayName ?? self?.name ?? args.id,
1314
- imageUrl: member?.imageUrl ?? self?.profileImage ?? void 0
1311
+ imageUrl: member?.imageUrl ?? self?.profileImage ?? void 0,
1312
+ loginProvider: member?.loginProvider
1315
1313
  };
1316
1314
  }
1317
1315
 
1316
+ function disambiguatedNames(displays) {
1317
+ const counts = countBy(displays, display => [ display.name ]);
1318
+ return displays.map(display => (counts.get(display.name) ?? 0) < 2 || display.loginProvider === void 0 ? display.name : `${display.name} (${workflowComponents.providerTitle(display.loginProvider) ?? display.loginProvider})`);
1319
+ }
1320
+
1318
1321
  function useUserDisplays(ids) {
1319
1322
  const {members: members} = useProjectMembers(), {users: users} = workflowStudio.useStudioProjectUsers(), meRaw = sanity.useCurrentUser(), me = react.useMemo(() => meRaw === null ? null : {
1320
1323
  ...meRaw,
@@ -1397,6 +1400,10 @@ function identityOf(state) {
1397
1400
  return state.kind === "resolved" ? state.identity : void 0;
1398
1401
  }
1399
1402
 
1403
+ function useCurrentUserId() {
1404
+ return identityOf(useAssignmentIdentity())?.userId;
1405
+ }
1406
+
1400
1407
  const projectMembersByUsers = /* @__PURE__ */ new WeakMap;
1401
1408
 
1402
1409
  function projectMembersFrom(users) {
@@ -1787,23 +1794,27 @@ function MemberPicker({selectedIds: selectedIds, onSelect: onSelect, unassignRow
1787
1794
  });
1788
1795
  }
1789
1796
 
1790
- function AssigneePicker({value: value, onChange: onChange}) {
1797
+ function AssigneePicker({value: value, onChange: onChange, eligibleRoles: eligibleRoles, roleAliases: roleAliases}) {
1791
1798
  const state = useProjectMembers();
1792
1799
  /* @__PURE__ */
1793
1800
  return jsxRuntime.jsx(workflowComponents.AssigneePicker, {
1794
1801
  ...state,
1802
+ eligibleRoles: eligibleRoles,
1795
1803
  onChange: onChange,
1804
+ roleAliases: roleAliases,
1796
1805
  value: value
1797
1806
  });
1798
1807
  }
1799
1808
 
1800
- function SingleAssigneePicker({current: current, onPick: onPick}) {
1809
+ function SingleAssigneePicker({current: current, onPick: onPick, eligibleRoles: eligibleRoles, roleAliases: roleAliases}) {
1801
1810
  /* @__PURE__ */
1802
1811
  return jsxRuntime.jsx(AssigneePicker, {
1812
+ eligibleRoles: eligibleRoles,
1803
1813
  onChange: next => {
1804
1814
  const picked = singleAssigneePick(current, next);
1805
1815
  picked !== void 0 && onPick(picked);
1806
1816
  },
1817
+ roleAliases: roleAliases,
1807
1818
  value: current ? [ current ] : []
1808
1819
  });
1809
1820
  }
@@ -2116,7 +2127,6 @@ const TOAST_ID = {
2116
2127
  effectResolve: "workflow-effect-resolve",
2117
2128
  effectsDrain: "workflow-effects-drain",
2118
2129
  effectsIncomplete: "workflow-effects-incomplete",
2119
- orphanSettle: "workflow-orphan-settle",
2120
2130
  start: "workflow-start"
2121
2131
  };
2122
2132
 
@@ -2976,8 +2986,7 @@ function PendingDocFace({bareId: bareId, layout: layout}) {
2976
2986
  children: id
2977
2987
  });
2978
2988
  }
2979
- return compact ?
2980
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
2989
+ return compact ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
2981
2990
  align: "center",
2982
2991
  gap: 2,
2983
2992
  children: [
@@ -3651,9 +3660,11 @@ function AssigneeField({field: field, instanceId: instanceId, onSave: onSave, on
3651
3660
  children: /* @__PURE__ */ jsxRuntime.jsx(DismissablePopover, {
3652
3661
  content: /* @__PURE__ */ jsxRuntime.jsx(SingleAssigneePicker, {
3653
3662
  current: cur,
3663
+ eligibleRoles: field.roles,
3654
3664
  onPick: picked => {
3655
3665
  setOpen(!1), pick(picked);
3656
- }
3666
+ },
3667
+ roleAliases: field.roleAliases
3657
3668
  }),
3658
3669
  onDismiss: () => setOpen(!1),
3659
3670
  open: open,
@@ -4332,6 +4343,12 @@ function useSpaceToken(index) {
4332
4343
  return value;
4333
4344
  }
4334
4345
 
4346
+ function useRadiusToken(index) {
4347
+ const value = ui.useTheme_v2().radius[index];
4348
+ if (value === void 0) throw new Error(`theme is missing radius token ${index}`);
4349
+ return value;
4350
+ }
4351
+
4335
4352
  function useContainerToken(index) {
4336
4353
  const value = ui.useTheme_v2().container[index];
4337
4354
  if (value === void 0) throw new Error(`theme is missing container token ${index}`);
@@ -4372,10 +4389,9 @@ function useBadgeCapTrim() {
4372
4389
  };
4373
4390
  }
4374
4391
 
4375
- function SpinnerSlot({busy: busy}) {
4392
+ function SpinnerSlot({busy: busy, reserve: reserve = !0}) {
4376
4393
  const size = useTextIconSize(), trim = useCapTrimFor(size), spinning = useDelayedFlag(busy, LOADING_CUE_DELAY_MS);
4377
- /* @__PURE__ */
4378
- return jsxRuntime.jsx(ui.Flex, {
4394
+ return !spinning && !reserve ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
4379
4395
  align: "center",
4380
4396
  flex: "none",
4381
4397
  justify: "center",
@@ -4469,8 +4485,7 @@ function RowAssignees({assignees: assignees, hint: hint}) {
4469
4485
  const bothKinds = roles.length > 0 && displays.length > 0;
4470
4486
  /* @__PURE__ */
4471
4487
  return jsxRuntime.jsx(HoverHint, {
4472
- content:
4473
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
4488
+ content: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
4474
4489
  gap: 3,
4475
4490
  children: [ roles.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(HintSection, {
4476
4491
  names: roles.map(workflowComponents.roleLabel),
@@ -4478,7 +4493,7 @@ function RowAssignees({assignees: assignees, hint: hint}) {
4478
4493
  label: "Roles"
4479
4494
  } : {}
4480
4495
  }) : null, displays.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(HintSection, {
4481
- names: displays.map(display => display.name),
4496
+ names: disambiguatedNames(displays),
4482
4497
  ...bothKinds ? {
4483
4498
  label: "Members"
4484
4499
  } : {}
@@ -4557,8 +4572,7 @@ function AssignActivityControl({instanceId: instanceId, state: state, surface: s
4557
4572
  }
4558
4573
  }, handleClick = e => {
4559
4574
  e.stopPropagation(), setOpen(v => !v);
4560
- }, button = assignees.length > 0 ?
4561
- /* @__PURE__ */ jsxRuntime.jsx(AvatarButton, {
4575
+ }, button = assignees.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(AvatarButton, {
4562
4576
  "aria-label": "Assignees",
4563
4577
  as: "span",
4564
4578
  avatar: /* @__PURE__ */ jsxRuntime.jsx(RowAssignees, {
@@ -4588,9 +4602,11 @@ function AssignActivityControl({instanceId: instanceId, state: state, surface: s
4588
4602
  label: "Loading…",
4589
4603
  padding: 3
4590
4604
  }) : /* @__PURE__ */ jsxRuntime.jsx(AssigneePicker, {
4605
+ eligibleRoles: state.field.roles,
4591
4606
  onChange: next => {
4592
4607
  change(next);
4593
4608
  },
4609
+ roleAliases: state.field.roleAliases,
4594
4610
  value: current
4595
4611
  })
4596
4612
  }),
@@ -4692,8 +4708,7 @@ function DueDate({dueDate: dueDate, hintDisabled: hintDisabled, overdue: overdue
4692
4708
  const face = hintFace({
4693
4709
  overdue: overdue,
4694
4710
  reason: reason
4695
- }), text = overdue ?
4696
- /* @__PURE__ */ jsxRuntime.jsx(sanity.TextWithTone, {
4711
+ }), text = overdue ? /* @__PURE__ */ jsxRuntime.jsx(sanity.TextWithTone, {
4697
4712
  size: 1,
4698
4713
  tone: "caution",
4699
4714
  children: formatDate(dueDate)
@@ -4804,7 +4819,7 @@ function DueDateControl({item: item, editable: editable, onPatch: onPatch}) {
4804
4819
  }) : display;
4805
4820
  }
4806
4821
 
4807
- function AssigneeControl({item: item, editable: editable, onPatch: onPatch}) {
4822
+ function AssigneeControl({item: item, editable: editable, eligibleRoles: eligibleRoles, onPatch: onPatch, roleAliases: roleAliases}) {
4808
4823
  const [open, setOpen] = react.useState(!1), current = item.assignee ?? null, chip = current ? /* @__PURE__ */ jsxRuntime.jsx(RowAssignees, {
4809
4824
  assignees: [ current ]
4810
4825
  }) : null;
@@ -4812,11 +4827,13 @@ function AssigneeControl({item: item, editable: editable, onPatch: onPatch}) {
4812
4827
  content:
4813
4828
  /* @__PURE__ */ jsxRuntime.jsx(SingleAssigneePicker, {
4814
4829
  current: current,
4830
+ eligibleRoles: eligibleRoles,
4815
4831
  onPick: picked => {
4816
4832
  setOpen(!1), onPatch({
4817
4833
  assignee: picked
4818
4834
  });
4819
- }
4835
+ },
4836
+ roleAliases: roleAliases
4820
4837
  }),
4821
4838
  onDismiss: () => setOpen(!1),
4822
4839
  open: open,
@@ -4918,8 +4935,7 @@ function BreadcrumbTail({segments: segments, style: style}) {
4918
4935
  }
4919
4936
 
4920
4937
  function WorkRow({lead: lead, children: children, end: end, onOpen: onOpen}) {
4921
- const frame =
4922
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
4938
+ const frame = /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
4923
4939
  align: "center",
4924
4940
  children: [
4925
4941
  /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
@@ -4953,8 +4969,7 @@ function WorkRow({lead: lead, children: children, end: end, onOpen: onOpen}) {
4953
4969
  padding: 1,
4954
4970
  radius: 3,
4955
4971
  children: frame
4956
- }) :
4957
- /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
4972
+ }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
4958
4973
  as: "button",
4959
4974
  onClick: onOpen,
4960
4975
  padding: 1,
@@ -4966,7 +4981,7 @@ function WorkRow({lead: lead, children: children, end: end, onOpen: onOpen}) {
4966
4981
  });
4967
4982
  }
4968
4983
 
4969
- function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle, onPatch: onPatch, onRemove: onRemove}) {
4984
+ function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle, onPatch: onPatch, onRemove: onRemove, roleAliases: roleAliases}) {
4970
4985
  const {canClick: canClick, hint: hint} = rowInteractivity(row), editable = row.editTarget !== void 0, checkbox = /* @__PURE__ */ jsxRuntime.jsx(TodoCheckbox, {
4971
4986
  canClick: canClick,
4972
4987
  checked: isTodoDone(row.item),
@@ -4983,8 +4998,10 @@ function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle,
4983
4998
  }),
4984
4999
  /* @__PURE__ */ jsxRuntime.jsx(AssigneeControl, {
4985
5000
  editable: editable,
5001
+ eligibleRoles: row.eligibleAssigneeRoles,
4986
5002
  item: row.item,
4987
- onPatch: onPatch
5003
+ onPatch: onPatch,
5004
+ roleAliases: roleAliases
4988
5005
  }), onRemove === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(RemoveItemButton, {
4989
5006
  onClick: onRemove
4990
5007
  }) ]
@@ -5161,6 +5178,7 @@ function TodoItemsList({breadcrumb: breadcrumb, entry: entry, filter: filter, sh
5161
5178
  onToggle: () => {
5162
5179
  toggleRow(row);
5163
5180
  },
5181
+ roleAliases: definition?.roleAliases,
5164
5182
  row: row
5165
5183
  }, rowKey(row)))
5166
5184
  }), addControl === null ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
@@ -5758,7 +5776,7 @@ function MetricPair({Icon: Icon, empty: empty, face: face, tone: tone, value: va
5758
5776
  });
5759
5777
  }
5760
5778
 
5761
- function AlertGlyph({Icon: Icon, hint: hint, tone: tone}) {
5779
+ function AlertGlyph({Icon: Icon, hint: hint, label: label, tone: tone}) {
5762
5780
  /* @__PURE__ */
5763
5781
  return jsxRuntime.jsx(HoverHint, {
5764
5782
  text: hint,
@@ -5766,6 +5784,10 @@ function AlertGlyph({Icon: Icon, hint: hint, tone: tone}) {
5766
5784
  size: 1,
5767
5785
  tone: tone,
5768
5786
  children: /* @__PURE__ */ jsxRuntime.jsx(Icon, {
5787
+ ...label === void 0 ? {} : {
5788
+ "aria-label": label,
5789
+ role: "img"
5790
+ },
5769
5791
  style: {
5770
5792
  color: "inherit"
5771
5793
  }
@@ -5939,8 +5961,7 @@ function ActivityRow({face: face, breadcrumb: breadcrumb, assignees: assignees,
5939
5961
  const settled = workflowEngine.isTerminalActivityStatus(face.status), dimmed = settledDim(settled);
5940
5962
  /* @__PURE__ */
5941
5963
  return jsxRuntime.jsxs(WorkRow, {
5942
- end:
5943
- /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
5964
+ end: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
5944
5965
  children: [
5945
5966
  /* @__PURE__ */ jsxRuntime.jsx(ActivityDateControl, {
5946
5967
  dueDates: dueDates,
@@ -5988,8 +6009,7 @@ function ActivityRow({face: face, breadcrumb: breadcrumb, assignees: assignees,
5988
6009
 
5989
6010
  function ActivitiesList({entry: entry, onOpenActivity: onOpenActivity, surface: surface}) {
5990
6011
  const activities = (entry.evaluation?.currentStage.activities ?? []).filter(t => !t.scopedOut), activityState = stateByActivity(entry.instance), fault = useInstanceFault(entry);
5991
- return activities.length === 0 ?
5992
- /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
6012
+ return activities.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
5993
6013
  paddingX: 1,
5994
6014
  paddingY: 3,
5995
6015
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
@@ -6017,8 +6037,7 @@ function ActivitiesList({entry: entry, onOpenActivity: onOpenActivity, surface:
6017
6037
 
6018
6038
  function instanceNotice(entry) {
6019
6039
  const {instance: instance, committed: committed, evaluation: evaluation} = entry, state = workflowEngine.terminalState(instance);
6020
- if (state !== "in-flight")
6021
- /* @__PURE__ */
6040
+ if (state !== "in-flight") /* @__PURE__ */
6022
6041
  return jsxRuntime.jsx(ui.Box, {
6023
6042
  paddingX: 1,
6024
6043
  paddingY: 2,
@@ -6206,7 +6225,7 @@ function UserAvatar({id: id}) {
6206
6225
  function UserAvatarGroup({ids: ids, hint: hint}) {
6207
6226
  const displays = useUserDisplays(ids);
6208
6227
  return displays.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
6209
- text: displays.map(d => d.name).join(", "),
6228
+ text: disambiguatedNames(displays).join(", "),
6210
6229
  ...hint === void 0 ? {} : {
6211
6230
  description: hint
6212
6231
  },
@@ -6265,8 +6284,7 @@ function FieldPills({entry: entry, scope: scope, definition: definition, surface
6265
6284
  pill: pill,
6266
6285
  scope: scope,
6267
6286
  surface: surface
6268
- }, pill.name)), overflow > 0 ?
6269
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
6287
+ }, pill.name)), overflow > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
6270
6288
  mode: "bleed",
6271
6289
  onClick: () => setExpanded(v => !v),
6272
6290
  padding: 2,
@@ -6705,9 +6723,11 @@ function AssigneePill({entry: entry, pill: pill, editability: editability, surfa
6705
6723
  return jsxRuntime.jsx(PillPopover, {
6706
6724
  content: /* @__PURE__ */ jsxRuntime.jsx(SingleAssigneePicker, {
6707
6725
  current: current,
6726
+ eligibleRoles: editability.roles,
6708
6727
  onPick: picked => {
6709
6728
  setOpen(!1), pick(picked);
6710
- }
6729
+ },
6730
+ roleAliases: editability.roleAliases
6711
6731
  }),
6712
6732
  onDismiss: () => setOpen(!1),
6713
6733
  onToggle: () => setOpen(v => !v),
@@ -6721,13 +6741,15 @@ function AssigneesPill({entry: entry, pill: pill, editability: editability, surf
6721
6741
  entry: entry,
6722
6742
  editability: editability,
6723
6743
  surface: surface
6724
- }), current = pill.face.kind === "assignees" ? pill.face.assignees : [];
6744
+ }), current = pill.face.kind === "assignees" ? pill.face.assignees : [], change = next => {
6745
+ saving || save(() => set(next));
6746
+ };
6725
6747
  /* @__PURE__ */
6726
6748
  return jsxRuntime.jsx(PillPopover, {
6727
6749
  content: /* @__PURE__ */ jsxRuntime.jsx(AssigneePicker, {
6728
- onChange: next => {
6729
- saving || save(() => set(next));
6730
- },
6750
+ eligibleRoles: editability.roles,
6751
+ onChange: change,
6752
+ roleAliases: editability.roleAliases,
6731
6753
  value: current
6732
6754
  }),
6733
6755
  onDismiss: () => setOpen(!1),
@@ -7313,6 +7335,24 @@ function historyLine(h, titles) {
7313
7335
  return historyLiner[h._type](h, titles);
7314
7336
  }
7315
7337
 
7338
+ function AgoStamp({at: at, now: now}) {
7339
+ /* @__PURE__ */
7340
+ return jsxRuntime.jsx(ui.Flex, {
7341
+ align: "center",
7342
+ children: /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
7343
+ text: formatShortDateTime(at),
7344
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
7345
+ muted: !0,
7346
+ size: 1,
7347
+ style: {
7348
+ whiteSpace: "nowrap"
7349
+ },
7350
+ children: formatShortAgo(at, now)
7351
+ })
7352
+ })
7353
+ });
7354
+ }
7355
+
7316
7356
  function CodeChip({value: value}) {
7317
7357
  /* @__PURE__ */
7318
7358
  return jsxRuntime.jsx("code", {
@@ -7538,16 +7578,9 @@ function FeedStamp({at: at, now: now}) {
7538
7578
  size: 1,
7539
7579
  children: "·"
7540
7580
  }),
7541
- /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
7542
- text: formatDateTime(at),
7543
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
7544
- muted: !0,
7545
- size: 1,
7546
- style: {
7547
- whiteSpace: "nowrap"
7548
- },
7549
- children: formatShortAgo(at, now)
7550
- })
7581
+ /* @__PURE__ */ jsxRuntime.jsx(AgoStamp, {
7582
+ at: at,
7583
+ now: now
7551
7584
  }) ]
7552
7585
  });
7553
7586
  }
@@ -7656,8 +7689,7 @@ function InstanceCardMenu({entry: entry, title: title}) {
7656
7689
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
7657
7690
  children: [
7658
7691
  /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, {
7659
- button:
7660
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
7692
+ button: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
7661
7693
  "aria-label": `More options for ${title}`,
7662
7694
  fontSize: 1,
7663
7695
  icon: EllipsisHorizontal.EllipsisHorizontalIcon,
@@ -7978,8 +8010,7 @@ function StageOverviewCard({overview: overview}) {
7978
8010
  size: 1,
7979
8011
  weight: "medium",
7980
8012
  children: overview.title
7981
- }), overview.description === void 0 ? null :
7982
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
8013
+ }), overview.description === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
7983
8014
  muted: !0,
7984
8015
  size: 1,
7985
8016
  style: {
@@ -8023,8 +8054,7 @@ function AdvanceCard({advance: advance}) {
8023
8054
  /* @__PURE__ */ jsxRuntime.jsx(InlineEmphasis, {
8024
8055
  children: advance.toTitle
8025
8056
  }), ADVANCE_TAILS[advance.kind] ]
8026
- }), advance.kind !== "conditions" ? null : advance.lines.map((line, index) =>
8027
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
8057
+ }), advance.kind !== "conditions" ? null : advance.lines.map((line, index) => /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
8028
8058
  muted: !0,
8029
8059
  size: 1,
8030
8060
  style: {
@@ -9078,8 +9108,7 @@ const VIEW_TAB_CODEC = workflowsTabCodec([ "overview", "for-me" ]), WorkflowsVie
9078
9108
  children: /* @__PURE__ */ jsxRuntime.jsx(InvalidDocNotice, {
9079
9109
  invalid: discoveryInvalid
9080
9110
  })
9081
- }) : resolved ?
9082
- /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
9111
+ }) : resolved ? /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
9083
9112
  direction: "column",
9084
9113
  height: "fill",
9085
9114
  padding: 4,
@@ -9381,7 +9410,10 @@ function resolveEntry(args) {
9381
9410
  }
9382
9411
  valid.push(name), definition && definitions.push({
9383
9412
  name: name,
9384
- fields: definition.fields
9413
+ fields: definition.fields,
9414
+ ...definition.roleAliases === void 0 ? {} : {
9415
+ roleAliases: definition.roleAliases
9416
+ }
9385
9417
  });
9386
9418
  }
9387
9419
  return {
@@ -9899,6 +9931,7 @@ function WorkflowProvider(props) {
9899
9931
  engine: engine,
9900
9932
  binding: binding,
9901
9933
  mappings: mappings,
9934
+ previewHydration: config.previewHydration,
9902
9935
  mappingIssues: issues,
9903
9936
  mappingStarts: starts,
9904
9937
  mappingFields: fields,
@@ -9906,7 +9939,7 @@ function WorkflowProvider(props) {
9906
9939
  effectHandlers: engine.effectHandlers,
9907
9940
  autoStartByType: autoStartByType,
9908
9941
  autoStartDefinitions: autoStartDefinitions
9909
- }), [ register, unregister, isDocResolved, entriesStore, actualTypes, requestInstance, releaseInstance, requestEvaluation, releaseEvaluation, seedInstance, openStartDialog, closeStartDialog, startRequest2, loading, discoveryInvalid, fireActionFor, editFieldFor, previewFieldFor, discardFieldPreviewFor, drainEffectsFor, completeEffectFor, engine, binding, mappings, issues, starts, fields, latestVersions, autoStartByType, autoStartDefinitions ]);
9942
+ }), [ register, unregister, isDocResolved, entriesStore, actualTypes, requestInstance, releaseInstance, requestEvaluation, releaseEvaluation, seedInstance, openStartDialog, closeStartDialog, startRequest2, loading, discoveryInvalid, fireActionFor, editFieldFor, previewFieldFor, discardFieldPreviewFor, drainEffectsFor, completeEffectFor, engine, binding, mappings, config.previewHydration, issues, starts, fields, latestVersions, autoStartByType, autoStartDefinitions ]);
9910
9943
  /* @__PURE__ */
9911
9944
  return jsxRuntime.jsxs(WorkflowContext.Provider, {
9912
9945
  value: value,
@@ -10008,7 +10041,7 @@ function logOnce(messages, logged) {
10008
10041
  for (const message of messages) logged.has(message) || (logged.add(message), console.warn(`[workflow-studio-plugin] ${message}`));
10009
10042
  }
10010
10043
 
10011
- function AssigneesInput({value: value, onChange: onChange}) {
10044
+ function AssigneesInput({value: value, onChange: onChange, eligibleRoles: eligibleRoles, roleAliases: roleAliases}) {
10012
10045
  const [open, setOpen] = react.useState(!1), remove = index => onChange(value.filter((_, i) => i !== index));
10013
10046
  /* @__PURE__ */
10014
10047
  return jsxRuntime.jsxs(ui.Stack, {
@@ -10042,7 +10075,9 @@ function AssigneesInput({value: value, onChange: onChange}) {
10042
10075
  wrap: "wrap",
10043
10076
  children: /* @__PURE__ */ jsxRuntime.jsx(DismissablePopover, {
10044
10077
  content: /* @__PURE__ */ jsxRuntime.jsx(AssigneePicker, {
10078
+ eligibleRoles: eligibleRoles,
10045
10079
  onChange: next => onChange([ ...next ]),
10080
+ roleAliases: roleAliases,
10046
10081
  value: value
10047
10082
  }),
10048
10083
  onDismiss: () => setOpen(!1),
@@ -10111,11 +10146,29 @@ function ChecklistInput({value: value, onChange: onChange}) {
10111
10146
  });
10112
10147
  }
10113
10148
 
10114
- function ReleasePicker({value: value, onChange: onChange}) {
10115
- const {binding: binding} = useWorkflowContext(), {data: data, loading: loading, error: error} = sanity.useActiveReleases(), releases = react.useMemo(() => data.filter(release => release.state === "active").map(release => ({
10149
+ function titleOf(release) {
10150
+ return release.metadata.title ?? release.name;
10151
+ }
10152
+
10153
+ function useReleaseTitles() {
10154
+ const {data: data} = sanity.useActiveReleases();
10155
+ return react.useMemo(() => new Map(data.map(release => [ release.name, titleOf(release) ])), [ data ]);
10156
+ }
10157
+
10158
+ function useActiveReleaseOptions() {
10159
+ const {data: data, loading: loading, error: error} = sanity.useActiveReleases(), releases = react.useMemo(() => data.filter(release => release.state === "active").map(release => ({
10116
10160
  name: release.name,
10117
- title: release.metadata.title ?? release.name
10118
- })).toSorted((a, b) => a.title.localeCompare(b.title)), [ data ]), labelOf = react.useMemo(() => {
10161
+ title: titleOf(release)
10162
+ })).toSorted((a, b) => a.title.localeCompare(b.title)), [ data ]);
10163
+ return {
10164
+ error: error,
10165
+ loading: loading,
10166
+ releases: releases
10167
+ };
10168
+ }
10169
+
10170
+ function ReleasePicker({value: value, onChange: onChange}) {
10171
+ const {binding: binding} = useWorkflowContext(), {error: error, loading: loading, releases: releases} = useActiveReleaseOptions(), labelOf = react.useMemo(() => {
10119
10172
  const m = new Map(releases.map(r => [ r.name, r.title ]));
10120
10173
  return name => m.get(name) ?? name;
10121
10174
  }, [ releases ]);
@@ -10383,8 +10436,10 @@ const docRefInput = ({entry: entry, docType: docType, releaseId: releaseId, valu
10383
10436
  onChange: onChange,
10384
10437
  value: value ?? []
10385
10438
  }),
10386
- assignees: ({value: value, onChange: onChange}) => /* @__PURE__ */ jsxRuntime.jsx(AssigneesInput, {
10439
+ assignees: ({entry: entry, roleAliases: roleAliases, value: value, onChange: onChange}) => /* @__PURE__ */ jsxRuntime.jsx(AssigneesInput, {
10440
+ eligibleRoles: entry.roles,
10387
10441
  onChange: onChange,
10442
+ roleAliases: roleAliases,
10388
10443
  value: value ?? []
10389
10444
  }),
10390
10445
  array: ({entry: entry, value: value, onChange: onChange}) => {
@@ -10426,7 +10481,7 @@ function FieldInput(props) {
10426
10481
  });
10427
10482
  }
10428
10483
 
10429
- function InitFieldRow({entry: entry, docType: docType, releaseId: releaseId, value: value, onChange: onChange}) {
10484
+ function InitFieldRow({entry: entry, docType: docType, releaseId: releaseId, roleAliases: roleAliases, value: value, onChange: onChange}) {
10430
10485
  const label = entry.title ?? entry.name;
10431
10486
  /* @__PURE__ */
10432
10487
  return jsxRuntime.jsxs(ui.Stack, {
@@ -10450,6 +10505,7 @@ function InitFieldRow({entry: entry, docType: docType, releaseId: releaseId, val
10450
10505
  entry: entry,
10451
10506
  onChange: onChange,
10452
10507
  releaseId: releaseId,
10508
+ roleAliases: roleAliases,
10453
10509
  value: value
10454
10510
  }) ]
10455
10511
  });
@@ -10499,7 +10555,7 @@ function StartFooter({canStart: canStart, starting: starting, startLabel: startL
10499
10555
  });
10500
10556
  }
10501
10557
 
10502
- function StartInputList({initFields: initFields, mapping: mapping, releaseId: releaseId, values: values, onChange: onChange}) {
10558
+ function StartInputList({initFields: initFields, mapping: mapping, releaseId: releaseId, roleAliases: roleAliases, values: values, onChange: onChange}) {
10503
10559
  return initFields.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
10504
10560
  muted: !0,
10505
10561
  size: 1,
@@ -10510,6 +10566,7 @@ function StartInputList({initFields: initFields, mapping: mapping, releaseId: re
10510
10566
  entry: entry,
10511
10567
  onChange: v => onChange(entry.name, v),
10512
10568
  releaseId: releaseId,
10569
+ roleAliases: roleAliases,
10513
10570
  value: values[entry.name] ?? null
10514
10571
  }, entry.name))
10515
10572
  });
@@ -10640,6 +10697,7 @@ function StartWorkflowForm({request: request, onClose: onClose}) {
10640
10697
  mapping: mapping,
10641
10698
  onChange: setValue,
10642
10699
  releaseId: releaseId,
10700
+ roleAliases: definition.roleAliases,
10643
10701
  values: values
10644
10702
  }),
10645
10703
  /* @__PURE__ */ jsxRuntime.jsx(StartFooter, {
@@ -10694,11 +10752,12 @@ function AutoStartInputDialog(props) {
10694
10752
  }),
10695
10753
  /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
10696
10754
  gap: 4,
10697
- children: inputs.map(({entry: entry}) => /* @__PURE__ */ jsxRuntime.jsx(InitFieldRow, {
10755
+ children: inputs.map(({entry: entry, roleAliases: roleAliases}) => /* @__PURE__ */ jsxRuntime.jsx(InitFieldRow, {
10698
10756
  docType: docType,
10699
10757
  entry: entry,
10700
10758
  onChange: value => setValue(entry.name, value),
10701
10759
  releaseId: void 0,
10760
+ roleAliases: roleAliases,
10702
10761
  value: values[entry.name] ?? null
10703
10762
  }, entry.name))
10704
10763
  }),
@@ -10727,23 +10786,65 @@ function subjectEntry(definition) {
10727
10786
  return documentSubjectEntry(definition);
10728
10787
  }
10729
10788
 
10730
- function autoStartInputs(args) {
10789
+ function autoStartInputPlan(args) {
10731
10790
  const byName = /* @__PURE__ */ new Map;
10732
10791
  for (const name of args.workflows) {
10733
10792
  const definition = args.definitions.get(name);
10734
10793
  if (definition !== void 0) for (const entry of extraRequiredInputs(definition)) {
10735
- const existing = byName.get(entry.name);
10736
- existing === void 0 ? byName.set(entry.name, {
10794
+ const conflict = mergeAutoStartInput(byName, {
10737
10795
  entry: entry,
10738
- workflows: [ name ]
10739
- }) : existing.workflows.push(name);
10796
+ workflow: name,
10797
+ roleAliases: definition.roleAliases
10798
+ });
10799
+ if (conflict !== void 0) return {
10800
+ inputs: [],
10801
+ conflict: conflict
10802
+ };
10740
10803
  }
10741
10804
  }
10742
- return [ ...byName.values() ];
10805
+ return {
10806
+ inputs: [ ...byName.values() ]
10807
+ };
10808
+ }
10809
+
10810
+ function mergeAutoStartInput(byName, args) {
10811
+ const existing = byName.get(args.entry.name);
10812
+ if (existing === void 0) {
10813
+ byName.set(args.entry.name, {
10814
+ entry: args.entry,
10815
+ workflows: [ args.workflow ],
10816
+ ...args.roleAliases === void 0 ? {} : {
10817
+ roleAliases: args.roleAliases
10818
+ }
10819
+ });
10820
+ return;
10821
+ }
10822
+ if (!sameRoleSet(existing.entry.roles, args.entry.roles)) return `Auto-start input "${args.entry.name}" is shared by workflows "${existing.workflows.join('", "')}" and "${args.workflow}" with different role constraints`;
10823
+ existing.workflows.push(args.workflow), sameRoleAliases(existing.roleAliases, args.roleAliases) || delete existing.roleAliases;
10824
+ }
10825
+
10826
+ function sameRoleSet(left, right) {
10827
+ return roleSetKey(left) === roleSetKey(right);
10828
+ }
10829
+
10830
+ function roleSetKey(roles) {
10831
+ return roles === void 0 ? void 0 : JSON.stringify(sortedUnique(roles));
10832
+ }
10833
+
10834
+ function sameRoleAliases(left, right) {
10835
+ return roleAliasesKey(left) === roleAliasesKey(right);
10836
+ }
10837
+
10838
+ function roleAliasesKey(aliases) {
10839
+ if (aliases !== void 0) return JSON.stringify(Object.entries(aliases).map(([role, fulfillers]) => [ role, sortedUnique(fulfillers) ]).toSorted(([left], [right]) => left.localeCompare(right)));
10840
+ }
10841
+
10842
+ function sortedUnique(values) {
10843
+ return [ ...new Set(values) ].toSorted();
10743
10844
  }
10744
10845
 
10745
10846
  function autoStartAction(args) {
10746
- return args.fired ? args.settled ? "reveal" : "starting" : args.pendingCount === 0 ? "reveal" : args.resolved ? args.needsInput ? "collect" : "silent-start" : "wait";
10847
+ return args.fired ? args.settled ? "reveal" : "starting" : args.blocked || args.pendingCount === 0 ? "reveal" : args.resolved ? args.needsInput ? "collect" : "silent-start" : "wait";
10747
10848
  }
10748
10849
 
10749
10850
  function pendingWorkflows(workflows, live) {
@@ -10800,10 +10901,14 @@ function AutoStartDriver(props) {
10800
10901
  engine: engine
10801
10902
  }), {selectedReleaseId: selectedReleaseId} = sanity.usePerspective(), {entries: entries} = useWorkflowsForDocument(rawDocId), docId = csm.getPublishedId(rawDocId), valueRef = react.useRef(value);
10802
10903
  valueRef.current = value;
10803
- const pending = react.useMemo(() => pendingWorkflows(workflows, new Set(entries.map(entry => entry.instance.definition))), [ workflows, entries ]), inputs = react.useMemo(() => autoStartInputs({
10904
+ const pending = react.useMemo(() => pendingWorkflows(workflows, new Set(entries.map(entry => entry.instance.definition))), [ workflows, entries ]), inputPlan = react.useMemo(() => autoStartInputPlan({
10804
10905
  workflows: pending,
10805
10906
  definitions: autoStartDefinitions
10806
- }), [ pending, autoStartDefinitions ]), definitionsResolved = workflows.every(name => autoStartDefinitions.has(name)), pendingRef = react.useRef(pending);
10907
+ }), [ pending, autoStartDefinitions ]), inputs = inputPlan.inputs;
10908
+ react.useEffect(() => {
10909
+ inputPlan.conflict !== void 0 && console.warn(`[Workflows] Auto-start skipped. ${inputPlan.conflict}`);
10910
+ }, [ inputPlan.conflict ]);
10911
+ const definitionsResolved = workflows.every(name => autoStartDefinitions.has(name)), pendingRef = react.useRef(pending);
10807
10912
  pendingRef.current = pending;
10808
10913
  const instanceIds = react.useRef(/* @__PURE__ */ new Map), instanceIdFor = react.useCallback(workflow => {
10809
10914
  const held = instanceIds.current.get(workflow);
@@ -10855,6 +10960,7 @@ function AutoStartDriver(props) {
10855
10960
  resolved: definitionsResolved && isDocResolved(docId),
10856
10961
  pendingCount: pending.length,
10857
10962
  needsInput: inputs.length > 0,
10963
+ blocked: inputPlan.conflict !== void 0,
10858
10964
  fired: fired,
10859
10965
  settled: settled
10860
10966
  });
@@ -11300,19 +11406,13 @@ function StartWorkflowDialogHost() {
11300
11406
  }
11301
11407
 
11302
11408
  const TOOL_TAB_LABELS = {
11303
- overview: "Workflows",
11304
- "all-documents": "All documents",
11305
- "for-me": "For me"
11409
+ overview: "Overview",
11410
+ "for-me": "For me",
11411
+ definitions: "Definitions"
11306
11412
  }, TOOL_TAB_VALUES = Object.keys(TOOL_TAB_LABELS), TOOL_TABS = TOOL_TAB_VALUES.map(value => ({
11307
11413
  value: value,
11308
11414
  label: TOOL_TAB_LABELS[value]
11309
- })), LANDING_TAB = "overview", TASKS_TAB = "all-documents", WORKFLOW_PAGE_LABELS = {
11310
- workflow: "Documents",
11311
- definition: "Definition"
11312
- }, WORKFLOW_PAGE_VALUES = Object.keys(WORKFLOW_PAGE_LABELS), DEFAULT_WORKFLOW_PAGE = "workflow", WORKFLOW_PAGES = WORKFLOW_PAGE_VALUES.filter(page => page !== DEFAULT_WORKFLOW_PAGE), WORKFLOW_PAGE_TABS = WORKFLOW_PAGE_VALUES.map(value => ({
11313
- value: value,
11314
- label: WORKFLOW_PAGE_LABELS[value]
11315
- })), toolRouter = router.route.create("/", [ router.route.create("/instance/:instanceId"), router.route.create(`/${LANDING_TAB}/:workflowName`, [ router.route.create("/:workflowPage") ]), router.route.create("/:workflowsTab") ]);
11415
+ })), LANDING_TAB = "overview", DEFINITIONS_TAB = "definitions", toolRouter = router.route.create("/", [ router.route.create(`/${DEFINITIONS_TAB}/:workflowName`), router.route.create("/:workflowsTab") ]);
11316
11416
 
11317
11417
  function toolTabState(tab) {
11318
11418
  return {
@@ -11330,39 +11430,17 @@ function workflowState(workflowName) {
11330
11430
  };
11331
11431
  }
11332
11432
 
11333
- function instanceState(instanceId) {
11334
- return {
11335
- instanceId: instanceId
11336
- };
11337
- }
11338
-
11339
11433
  function tabSelectionNavigates(current, tab) {
11340
11434
  return !(current.kind === "home" && tab === current.tab);
11341
11435
  }
11342
11436
 
11343
- function toolTabLabel(tab) {
11344
- return TOOL_TAB_LABELS[tab];
11345
- }
11346
-
11347
- function backToTabLabel(tab) {
11348
- return `Back to ${toolTabLabel(tab)}`;
11349
- }
11350
-
11351
- function workflowPageState(page, workflowName) {
11352
- return page === DEFAULT_WORKFLOW_PAGE ? workflowState(workflowName) : {
11353
- ...workflowState(workflowName),
11354
- workflowPage: page
11355
- };
11356
- }
11357
-
11358
11437
  function toolRoute(state) {
11359
- const {instanceId: instanceId, workflowName: workflowName} = state;
11360
- if (typeof instanceId == "string") return {
11361
- kind: "instance",
11362
- instanceId: instanceId,
11363
- tab: TASKS_TAB
11438
+ const {workflowName: workflowName} = state;
11439
+ if (typeof workflowName == "string") return {
11440
+ kind: "definition",
11441
+ workflowName: workflowName,
11442
+ tab: DEFINITIONS_TAB
11364
11443
  };
11365
- if (typeof workflowName == "string") return workflowRoute(workflowName, state.workflowPage);
11366
11444
  const tab = pathSegmentName({
11367
11445
  segment: state.workflowsTab,
11368
11446
  names: TOOL_TAB_VALUES
@@ -11376,24 +11454,11 @@ function toolRoute(state) {
11376
11454
  };
11377
11455
  }
11378
11456
 
11379
- function workflowRoute(workflowName, pageSegment) {
11380
- if (pageSegment === void 0) return {
11381
- kind: "workflow",
11382
- workflowName: workflowName,
11383
- tab: LANDING_TAB
11384
- };
11385
- const page = pathSegmentName({
11386
- segment: pageSegment,
11387
- names: WORKFLOW_PAGES
11388
- });
11389
- return page === void 0 ? {
11390
- kind: "unnamed",
11391
- tab: LANDING_TAB
11392
- } : {
11393
- kind: page,
11394
- workflowName: workflowName,
11395
- tab: LANDING_TAB
11457
+ function definitionsRouteOf(route2) {
11458
+ if (route2.kind === "definition") return {
11459
+ workflowName: route2.workflowName
11396
11460
  };
11461
+ if (route2.kind === "home" && route2.tab === "definitions") return {};
11397
11462
  }
11398
11463
 
11399
11464
  const WorkflowsToolRoot = react.lazy(() => Promise.resolve().then(function() {
@@ -11513,12 +11578,10 @@ exports.ActivityDetailDialog = ActivityDetailDialog;
11513
11578
 
11514
11579
  exports.ActivityLog = ActivityLog;
11515
11580
 
11516
- exports.ActivityRow = ActivityRow;
11581
+ exports.AgoStamp = AgoStamp;
11517
11582
 
11518
11583
  exports.AlertGlyph = AlertGlyph;
11519
11584
 
11520
- exports.BreadcrumbTail = BreadcrumbTail;
11521
-
11522
11585
  exports.CodeChip = CodeChip;
11523
11586
 
11524
11587
  exports.CountedHeading = CountedHeading;
@@ -11531,22 +11594,14 @@ exports.DocRefFace = DocRefFace;
11531
11594
 
11532
11595
  exports.EmptyState = EmptyState;
11533
11596
 
11534
- exports.ForMeEmptyState = ForMeEmptyState;
11535
-
11536
- exports.Hairline = Hairline;
11537
-
11538
11597
  exports.HoverHint = HoverHint;
11539
11598
 
11540
- exports.InlineEmphasis = InlineEmphasis;
11541
-
11542
11599
  exports.InstanceFaultNote = InstanceFaultNote;
11543
11600
 
11544
11601
  exports.InstanceSnapshotBody = InstanceSnapshotBody;
11545
11602
 
11546
11603
  exports.InvalidDocNotice = InvalidDocNotice;
11547
11604
 
11548
- exports.LinkChip = LinkChip;
11549
-
11550
11605
  exports.LoadingRow = LoadingRow;
11551
11606
 
11552
11607
  exports.LogEventOnMount = LogEventOnMount;
@@ -11557,15 +11612,13 @@ exports.MetricPair = MetricPair;
11557
11612
 
11558
11613
  exports.NoteBanner = NoteBanner;
11559
11614
 
11560
- exports.RoleAssignedNotice = RoleAssignedNotice;
11561
-
11562
- exports.SpinnerSlot = SpinnerSlot;
11615
+ exports.RUN_SEARCH_PARAM = RUN_SEARCH_PARAM;
11563
11616
 
11564
- exports.StageFace = StageFace;
11617
+ exports.RoleAssignedNotice = RoleAssignedNotice;
11565
11618
 
11566
- exports.StaleLock = StaleLock;
11619
+ exports.RowAssignees = RowAssignees;
11567
11620
 
11568
- exports.TOAST_ID = TOAST_ID;
11621
+ exports.SpinnerSlot = SpinnerSlot;
11569
11622
 
11570
11623
  exports.TOOL_TABS = TOOL_TABS;
11571
11624
 
@@ -11575,35 +11628,23 @@ exports.UnreadableDocsNote = UnreadableDocsNote;
11575
11628
 
11576
11629
  exports.WORKFLOW_API_VERSION = WORKFLOW_API_VERSION;
11577
11630
 
11578
- exports.WORKFLOW_PAGE_TABS = WORKFLOW_PAGE_TABS;
11579
-
11580
11631
  exports.WorkflowBoardWorkflowSelected = WorkflowBoardWorkflowSelected;
11581
11632
 
11582
11633
  exports.WorkflowDefinitionDetailViewed = WorkflowDefinitionDetailViewed;
11583
11634
 
11584
11635
  exports.WorkflowInstanceDetailViewed = WorkflowInstanceDetailViewed;
11585
11636
 
11586
- exports.WorkflowTaskFiltersApplied = WorkflowTaskFiltersApplied;
11587
-
11588
11637
  exports.WorkflowTitleSeedDrifted = WorkflowTitleSeedDrifted;
11589
11638
 
11590
11639
  exports.WorkflowToolOpened = WorkflowToolOpened;
11591
11640
 
11592
- exports.activityRowProps = activityRowProps;
11593
-
11594
11641
  exports.assigneesOf = assigneesOf;
11595
11642
 
11596
- exports.backToTabLabel = backToTabLabel;
11597
-
11598
- exports.committedRowFace = committedRowFace;
11599
-
11600
- exports.createSubscribers = createSubscribers;
11601
-
11602
- exports.datesOf = datesOf;
11643
+ exports.countBy = countBy;
11603
11644
 
11604
11645
  exports.definitionFingerprint = definitionFingerprint;
11605
11646
 
11606
- exports.definitionSnapshotOf = definitionSnapshotOf;
11647
+ exports.definitionsRouteOf = definitionsRouteOf;
11607
11648
 
11608
11649
  exports.describeError = describeError;
11609
11650
 
@@ -11611,10 +11652,6 @@ exports.dueDatesOf = dueDatesOf;
11611
11652
 
11612
11653
  exports.findActivity = findActivity;
11613
11654
 
11614
- exports.formatDate = formatDate;
11615
-
11616
- exports.formatShortAgo = formatShortAgo;
11617
-
11618
11655
  exports.formatShortDateTime = formatShortDateTime;
11619
11656
 
11620
11657
  exports.formatTimeAgo = formatTimeAgo;
@@ -11625,12 +11662,8 @@ exports.identityOf = identityOf;
11625
11662
 
11626
11663
  exports.instanceBreadcrumb = instanceBreadcrumb;
11627
11664
 
11628
- exports.instanceState = instanceState;
11629
-
11630
11665
  exports.instanceTitle = instanceTitle;
11631
11666
 
11632
- exports.isActivityAssignedTo = isActivityAssignedTo;
11633
-
11634
11667
  exports.isDueDatePast = isDueDatePast;
11635
11668
 
11636
11669
  exports.isEvaluationStale = isEvaluationStale;
@@ -11639,8 +11672,6 @@ exports.isLiveEntry = isLiveEntry;
11639
11672
 
11640
11673
  exports.isOpenActivityStatus = isOpenActivityStatus;
11641
11674
 
11642
- exports.isRoleAssignedTo = isRoleAssignedTo;
11643
-
11644
11675
  exports.landingState = landingState;
11645
11676
 
11646
11677
  exports.mappingIssueDetail = mappingIssueDetail;
@@ -11655,14 +11686,8 @@ exports.parseStoredDateValue = parseStoredDateValue;
11655
11686
 
11656
11687
  exports.readDeployedDefinitions = readDeployedDefinitions;
11657
11688
 
11658
- exports.rowAssignControlState = rowAssignControlState;
11659
-
11660
- exports.rowDateControlState = rowDateControlState;
11661
-
11662
11689
  exports.stageTitle = stageTitle;
11663
11690
 
11664
- exports.stateByActivity = stateByActivity;
11665
-
11666
11691
  exports.tabSelectionNavigates = tabSelectionNavigates;
11667
11692
 
11668
11693
  exports.toolRoute = toolRoute;
@@ -11671,8 +11696,14 @@ exports.toolTabState = toolTabState;
11671
11696
 
11672
11697
  exports.useAssignmentIdentity = useAssignmentIdentity;
11673
11698
 
11699
+ exports.useAvatarSize = useAvatarSize;
11700
+
11701
+ exports.useCapTrimFor = useCapTrimFor;
11702
+
11674
11703
  exports.useContainerToken = useContainerToken;
11675
11704
 
11705
+ exports.useCurrentUserId = useCurrentUserId;
11706
+
11676
11707
  exports.useDefinition = useDefinition;
11677
11708
 
11678
11709
  exports.useLogEventOnMount = useLogEventOnMount;
@@ -11681,20 +11712,22 @@ exports.useMinuteClock = useMinuteClock;
11681
11712
 
11682
11713
  exports.useProjectMembers = useProjectMembers;
11683
11714
 
11715
+ exports.useRadiusToken = useRadiusToken;
11716
+
11717
+ exports.useReleaseTitles = useReleaseTitles;
11718
+
11684
11719
  exports.useSpaceToken = useSpaceToken;
11685
11720
 
11721
+ exports.useTextIconSize = useTextIconSize;
11722
+
11686
11723
  exports.useUserDisplays = useUserDisplays;
11687
11724
 
11688
11725
  exports.useWorkflowContext = useWorkflowContext;
11689
11726
 
11690
11727
  exports.useWorkflowInstanceEntry = useWorkflowInstanceEntry;
11691
11728
 
11692
- exports.useWorkflowToast = useWorkflowToast;
11693
-
11694
11729
  exports.workflowDefaultDocumentNode = workflowDefaultDocumentNode;
11695
11730
 
11696
- exports.workflowPageState = workflowPageState;
11697
-
11698
11731
  exports.workflowState = workflowState;
11699
11732
 
11700
11733
  exports.workflowStudioPlugin = workflowStudioPlugin;