@sanity/workflow-studio-plugin 0.32.0 → 0.33.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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- var jsxRuntime = require("react/jsx-runtime"), Timeline = require("@sanity/icons/Timeline"), ui = require("@sanity/ui"), workflowReact = require("@sanity/workflow-react"), react = require("react"), structure = require("sanity/structure"), workflowEngine = require("@sanity/workflow-engine"), Checkmark = require("@sanity/icons/Checkmark"), Close = require("@sanity/icons/Close"), formatDistanceToNow = require("date-fns/formatDistanceToNow"), workflowComponents = require("@sanity/workflow-components"), csm = require("@sanity/client/csm"), telemetry = require("@sanity/telemetry"), workflowStudio = require("@sanity/workflow-studio"), sanity = require("sanity"), Calendar = require("@sanity/icons/Calendar"), User = require("@sanity/icons/User"), Search = require("@sanity/icons/Search"), Edit = require("@sanity/icons/Edit"), content = require("@sanity/util/content"), InfoOutline = require("@sanity/icons/InfoOutline"), Document = require("@sanity/icons/Document"), WarningOutline = require("@sanity/icons/WarningOutline"), router = require("sanity/router"), types = require("@sanity/types"), Launch = require("@sanity/icons/Launch"), ErrorOutline = require("@sanity/icons/ErrorOutline"), Empty$1 = require("@sanity/icons/Empty"), ErrorFilled = require("@sanity/icons/ErrorFilled"), RemoveCircle = require("@sanity/icons/RemoveCircle"), AddUser = require("@sanity/icons/AddUser"), Add = require("@sanity/icons/Add"), Ulist = require("@sanity/icons/Ulist"), CheckmarkCircle = require("@sanity/icons/CheckmarkCircle"), Bolt = require("@sanity/icons/Bolt"), ChevronDown = require("@sanity/icons/ChevronDown"), pluralize = require("pluralize-esm"), ChevronRight = require("@sanity/icons/ChevronRight"), styledComponents = require("styled-components"), EllipsisHorizontal = require("@sanity/icons/EllipsisHorizontal"), Clock = require("@sanity/icons/Clock"), Cog = require("@sanity/icons/Cog"), ArrowUp = require("@sanity/icons/ArrowUp"), rxjs = require("rxjs"), operators = require("rxjs/operators"), Transfer = require("@sanity/icons/Transfer");
3
+ var jsxRuntime = require("react/jsx-runtime"), Timeline = require("@sanity/icons/Timeline"), ui = require("@sanity/ui"), workflowReact = require("@sanity/workflow-react"), react = require("react"), structure = require("sanity/structure"), workflowEngine = require("@sanity/workflow-engine"), Checkmark = require("@sanity/icons/Checkmark"), Close = require("@sanity/icons/Close"), workflowComponents = require("@sanity/workflow-components"), formatDistanceToNow = require("date-fns/formatDistanceToNow"), csm = require("@sanity/client/csm"), telemetry = require("@sanity/telemetry"), workflowStudio = require("@sanity/workflow-studio"), sanity = require("sanity"), Calendar = require("@sanity/icons/Calendar"), User = require("@sanity/icons/User"), Search = require("@sanity/icons/Search"), Edit = require("@sanity/icons/Edit"), content = require("@sanity/util/content"), InfoOutline = require("@sanity/icons/InfoOutline"), Document = require("@sanity/icons/Document"), WarningOutline = require("@sanity/icons/WarningOutline"), router = require("sanity/router"), types = require("@sanity/types"), observer = require("@sanity/workflow-react/observer"), Launch = require("@sanity/icons/Launch"), ErrorOutline = require("@sanity/icons/ErrorOutline"), AddUser = require("@sanity/icons/AddUser"), Add = require("@sanity/icons/Add"), Ulist = require("@sanity/icons/Ulist"), CheckmarkCircle = require("@sanity/icons/CheckmarkCircle"), Bolt = require("@sanity/icons/Bolt"), ChevronDown = require("@sanity/icons/ChevronDown"), pluralize = require("pluralize-esm"), ChevronRight = require("@sanity/icons/ChevronRight"), styledComponents = require("styled-components"), EllipsisHorizontal = require("@sanity/icons/EllipsisHorizontal"), Clock = require("@sanity/icons/Clock"), Cog = require("@sanity/icons/Cog"), ArrowUp = require("@sanity/icons/ArrowUp"), rxjs = require("rxjs"), operators = require("rxjs/operators"), Transfer = require("@sanity/icons/Transfer"), Users = require("@sanity/icons/Users"), reactVirtual = require("@tanstack/react-virtual");
4
4
 
5
5
  function _interopDefaultCompat(e) {
6
6
  return e && typeof e == "object" && "default" in e ? e : {
@@ -384,17 +384,6 @@ function formatDateTime(value) {
384
384
  return Number.isNaN(d.getTime()) ? "—" : d.toLocaleString();
385
385
  }
386
386
 
387
- function formatShortDateTime(value) {
388
- const d = new Date(value);
389
- return Number.isNaN(d.getTime()) ? "—" : d.toLocaleString(void 0, {
390
- day: "numeric",
391
- month: "short",
392
- year: "numeric",
393
- hour: "2-digit",
394
- minute: "2-digit"
395
- });
396
- }
397
-
398
387
  function formatTimeAgo(value) {
399
388
  const d = new Date(value);
400
389
  return Number.isNaN(d.getTime()) ? "" : formatDistanceToNow.formatDistanceToNow(d, {
@@ -402,32 +391,13 @@ function formatTimeAgo(value) {
402
391
  });
403
392
  }
404
393
 
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) {
411
- return shortSpanOf(new Date(value), now);
412
- }
413
-
414
- function shortSpanOf(from, now) {
415
- if (from === void 0 || Number.isNaN(from.getTime())) return "—";
416
- const seconds = Math.floor((now.getTime() - from.getTime()) / 1e3);
417
- if (seconds < 60) return "now";
418
- const minutes = Math.floor(seconds / 60);
419
- if (minutes < 60) return `${minutes}m`;
420
- const hours = Math.floor(minutes / 60);
421
- return hours < 24 ? `${hours}h` : `${Math.floor(hours / 24)}d`;
422
- }
423
-
424
394
  function stampFace(verb, at) {
425
395
  const ago = formatTimeAgo(at);
426
396
  return ago === "" ? {
427
- lead: `${verb} ${formatShortDateTime(at)}`
397
+ lead: `${verb} ${workflowComponents._formatShortDateTime(at)}`
428
398
  } : {
429
399
  lead: `${verb} ${ago}`,
430
- detail: formatShortDateTime(at)
400
+ detail: workflowComponents._formatShortDateTime(at)
431
401
  };
432
402
  }
433
403
 
@@ -442,7 +412,7 @@ function formatDate(value) {
442
412
  }
443
413
 
444
414
  function formatDueMoment(value) {
445
- return storedDateKind(value) === "date" ? formatDate(value) : formatShortDateTime(value);
415
+ return storedDateKind(value) === "date" ? formatDate(value) : workflowComponents._formatShortDateTime(value);
446
416
  }
447
417
 
448
418
  function dueMomentSentence(value, now) {
@@ -1576,105 +1546,6 @@ function buildParams(decls, values) {
1576
1546
  };
1577
1547
  }
1578
1548
 
1579
- const LOADING_CUE_DELAY_MS = 400;
1580
-
1581
- function useDelayedFlag(active, delayMs) {
1582
- const [held, setHeld] = react.useState(!1);
1583
- return react.useEffect(() => {
1584
- if (!active) {
1585
- setHeld(!1);
1586
- return;
1587
- }
1588
- const timer = setTimeout(() => setHeld(!0), delayMs);
1589
- return () => clearTimeout(timer);
1590
- }, [ active, delayMs ]), held && active;
1591
- }
1592
-
1593
- const NEVER_MS = 2 ** 31 - 1, OPEN_DELAY_MS = 300;
1594
-
1595
- function HoverHint(props) {
1596
- return props.anchor !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(AnchoredHint, {
1597
- ...props
1598
- }) : /* @__PURE__ */ jsxRuntime.jsx(WrappingHint, {
1599
- ...props
1600
- });
1601
- }
1602
-
1603
- function AnchoredHint(props) {
1604
- const {disabled: disabled = !1} = props, open = useDelayedFlag(props.open === !0 && !disabled, OPEN_DELAY_MS);
1605
- /* @__PURE__ */
1606
- return jsxRuntime.jsx(ui.Popover, {
1607
- animate: !0,
1608
- content: /* @__PURE__ */ jsxRuntime.jsx(HintBody, {
1609
- ...props
1610
- }),
1611
- open: open,
1612
- padding: hintPadding(props),
1613
- placement: props.placement ?? "top",
1614
- portal: !0,
1615
- radius: 3,
1616
- referenceElement: props.anchor
1617
- });
1618
- }
1619
-
1620
- function hintPadding(props) {
1621
- return props.content !== void 0 && props.flush ? 0 : 2;
1622
- }
1623
-
1624
- function WrappingHint(props) {
1625
- const {children: children, disabled: disabled = !1} = props;
1626
- /* @__PURE__ */
1627
- return jsxRuntime.jsx(ui.Tooltip, {
1628
- animate: !0,
1629
- content: disabled ? null : /* @__PURE__ */ jsxRuntime.jsx(HintBody, {
1630
- ...props
1631
- }),
1632
- delay: {
1633
- close: 0,
1634
- open: disabled ? NEVER_MS : OPEN_DELAY_MS
1635
- },
1636
- padding: hintPadding(props),
1637
- placement: props.placement ?? "top",
1638
- portal: !0,
1639
- radius: 3,
1640
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
1641
- "data-testid": props["data-testid"],
1642
- style: {
1643
- display: props.fill ? "flex" : "inline-flex",
1644
- maxWidth: "100%",
1645
- ...props.fill ? {
1646
- width: "100%"
1647
- } : {}
1648
- },
1649
- children: children
1650
- })
1651
- });
1652
- }
1653
-
1654
- function HintBody(props) {
1655
- /* @__PURE__ */
1656
- return jsxRuntime.jsx(ui.Box, {
1657
- style: {
1658
- maxWidth: props.content !== void 0 && props.wide ? 400 : 280
1659
- },
1660
- children: props.content !== void 0 ? props.content : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
1661
- gap: 3,
1662
- children: [
1663
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
1664
- size: 1,
1665
- ...props.textWeight === void 0 ? {} : {
1666
- weight: props.textWeight
1667
- },
1668
- children: props.text
1669
- }), props.description === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
1670
- muted: !0,
1671
- size: 1,
1672
- children: props.description
1673
- }) ]
1674
- })
1675
- });
1676
- }
1677
-
1678
1549
  function textInputFacet(kind) {
1679
1550
  return kind === "number" || kind === "progress" ? {
1680
1551
  type: "number"
@@ -2083,7 +1954,7 @@ function DocRefsInput({value: value, onChange: onChange, types: types2}) {
2083
1954
  type: ref.type
2084
1955
  })
2085
1956
  }),
2086
- /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
1957
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
2087
1958
  text: "Remove",
2088
1959
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
2089
1960
  "aria-label": "Remove",
@@ -2417,7 +2288,7 @@ function DisabledActionButton({actionEval: actionEval, activity: activity, chrom
2417
2288
  ...spanTriggerProps(chrome),
2418
2289
  disabled: !0
2419
2290
  });
2420
- return actionEval.disabledReason ? /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
2291
+ return actionEval.disabledReason ? /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
2421
2292
  text: describeDisabledReason(actionEval.disabledReason),
2422
2293
  children: button
2423
2294
  }) : button;
@@ -2439,7 +2310,7 @@ function PlainActionButton({actionEval: actionEval, instanceId: instanceId, acti
2439
2310
  surface: surface,
2440
2311
  tone: btn.tone
2441
2312
  });
2442
- return action.description ? /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
2313
+ return action.description ? /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
2443
2314
  text: action.description,
2444
2315
  children: button
2445
2316
  }) : button;
@@ -2619,10 +2490,10 @@ function InfoHint({content: content2, label: label}) {
2619
2490
  size: 0,
2620
2491
  children: /* @__PURE__ */ jsxRuntime.jsx(InfoOutline.InfoOutlineIcon, {})
2621
2492
  });
2622
- return typeof content2 == "string" ? /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
2493
+ return typeof content2 == "string" ? /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
2623
2494
  text: content2,
2624
2495
  children: icon
2625
- }) : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
2496
+ }) : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
2626
2497
  content: content2,
2627
2498
  children: icon
2628
2499
  });
@@ -2722,6 +2593,8 @@ function FieldInput$1({kind: kind, value: value, onChange: onChange, onEnter: on
2722
2593
  }
2723
2594
  }
2724
2595
 
2596
+ const LOADING_CUE_DELAY_MS = 400;
2597
+
2725
2598
  function isCompact(layout) {
2726
2599
  return layout === "inline" || layout === "row";
2727
2600
  }
@@ -2833,7 +2706,7 @@ function useChipTrim() {
2833
2706
 
2834
2707
  function LinkChip({hint: hint, children: children, as: as = "a", fill: fill = !1, ...anchorProps}) {
2835
2708
  /* @__PURE__ */
2836
- return jsxRuntime.jsx(HoverHint, {
2709
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
2837
2710
  fill: fill,
2838
2711
  text: hint,
2839
2712
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
@@ -2859,6 +2732,8 @@ function LinkChip({hint: hint, children: children, as: as = "a", fill: fill = !1
2859
2732
  });
2860
2733
  }
2861
2734
 
2735
+ const UNREADABLE_DOCUMENT = /* @__PURE__ */ Symbol("unreadable document");
2736
+
2862
2737
  function docLinkState(input) {
2863
2738
  const {bareId: bareId, resource: resource} = input;
2864
2739
  if (bareId === void 0 || resource === void 0) return {
@@ -2901,6 +2776,23 @@ function openableSchemaType(schema, typeName) {
2901
2776
  if (!(entry === void 0 || !types.isDocumentSchemaType(entry) || entry.name === "document")) return entry;
2902
2777
  }
2903
2778
 
2779
+ function snapshotOf(store, ids) {
2780
+ let snapshot = /* @__PURE__ */ new Map;
2781
+ return () => {
2782
+ const next = new Map(ids.map(id => [ id, store.read(id) ]));
2783
+ return (next.size !== snapshot.size || ids.some(id => next.get(id) !== snapshot.get(id))) && (snapshot = next),
2784
+ snapshot;
2785
+ };
2786
+ }
2787
+
2788
+ function useActualDocTypes(ids) {
2789
+ const {actualTypes: actualTypes} = useWorkflowContext(), uniqueIds2 = [ ...new Set(ids) ].sort(), trackedIds = observer.useKeyed([ JSON.stringify(uniqueIds2) ], () => uniqueIds2);
2790
+ return react.useEffect(() => {
2791
+ const releases = trackedIds.map(id => actualTypes.track(id));
2792
+ return () => releases.forEach(release => release());
2793
+ }, [ actualTypes, trackedIds ]), react.useSyncExternalStore(actualTypes.subscribe, react.useMemo(() => snapshotOf(actualTypes, trackedIds), [ actualTypes, trackedIds ]));
2794
+ }
2795
+
2904
2796
  function useLocalDocRef(gdr) {
2905
2797
  const {binding: binding} = useWorkflowContext(), schema = sanity.useSchema(), schemaType = gdr === void 0 ? void 0 : schema.get(gdr.type);
2906
2798
  return {
@@ -2911,10 +2803,8 @@ function useLocalDocRef(gdr) {
2911
2803
  }
2912
2804
 
2913
2805
  function useActualDocType(bareId) {
2914
- const {actualTypes: actualTypes} = useWorkflowContext();
2915
- return react.useEffect(() => {
2916
- if (bareId !== null) return actualTypes.track(bareId);
2917
- }, [ actualTypes, bareId ]), react.useSyncExternalStore(actualTypes.subscribe, react.useCallback(() => bareId === null ? void 0 : actualTypes.read(bareId), [ actualTypes, bareId ]));
2806
+ const ids = react.useMemo(() => bareId === null ? [] : [ bareId ], [ bareId ]);
2807
+ return useActualDocTypes(ids).get(bareId ?? "");
2918
2808
  }
2919
2809
 
2920
2810
  function useDocLink(gdr) {
@@ -3071,7 +2961,7 @@ function CompactDocRef({face: face, fill: fill, link: link, onClick: onClick}) {
3071
2961
  const PENDING_FACE_MAX_WAIT_MS = 4e3;
3072
2962
 
3073
2963
  function PendingDocFace({bareId: bareId, layout: layout}) {
3074
- const expired = useDelayedFlag(!0, PENDING_FACE_MAX_WAIT_MS), compact = isCompact(layout);
2964
+ const expired = workflowComponents._useDelayedFlag(!0, PENDING_FACE_MAX_WAIT_MS), compact = isCompact(layout);
3075
2965
  if (expired) {
3076
2966
  const id = /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
3077
2967
  muted: !0,
@@ -3610,7 +3500,7 @@ function EditableFieldControl({instanceId: instanceId, field: field, surface: su
3610
3500
 
3611
3501
  function EditableValueButton({children: children, hint: hint, hintDisabled: hintDisabled = !1, onClick: onClick}) {
3612
3502
  /* @__PURE__ */
3613
- return jsxRuntime.jsx(HoverHint, {
3503
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
3614
3504
  disabled: hintDisabled,
3615
3505
  text: hint,
3616
3506
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
@@ -3894,7 +3784,7 @@ function FieldEditRow({field: field, onSave: onSave, onCancel: onCancel, saving:
3894
3784
  }
3895
3785
  })
3896
3786
  }),
3897
- /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
3787
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
3898
3788
  text: "Save",
3899
3789
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
3900
3790
  "aria-label": "Save",
@@ -3906,7 +3796,7 @@ function FieldEditRow({field: field, onSave: onSave, onCancel: onCancel, saving:
3906
3796
  padding: 2
3907
3797
  })
3908
3798
  }),
3909
- /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
3799
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
3910
3800
  text: "Cancel",
3911
3801
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
3912
3802
  "aria-label": "Cancel",
@@ -4114,7 +4004,7 @@ const ACTION_LABEL = {
4114
4004
  "set-stage": "Move the workflow on to its next stage yourself."
4115
4005
  };
4116
4006
 
4117
- function detailOf(cause) {
4007
+ function detailOf(cause, missingSummary) {
4118
4008
  switch (cause.kind) {
4119
4009
  case "failed-effect":
4120
4010
  return `The step “${effectLabel(cause.effect)}” failed`;
@@ -4126,12 +4016,15 @@ function detailOf(cause) {
4126
4016
  return "This task failed";
4127
4017
 
4128
4018
  default:
4129
- return summaryOf(cause);
4019
+ return summaryOf(cause, missingSummary);
4130
4020
  }
4131
4021
  }
4132
4022
 
4133
- function summaryOf(cause) {
4023
+ function summaryOf(cause, missingSummary) {
4134
4024
  switch (cause.kind) {
4025
+ case "document-missing":
4026
+ return missingSummary;
4027
+
4135
4028
  case "failed-effect":
4136
4029
  return "An automated step failed";
4137
4030
 
@@ -4149,6 +4042,10 @@ function summaryOf(cause) {
4149
4042
  }
4150
4043
  }
4151
4044
 
4045
+ function withMissingDocuments(title, missingSummary) {
4046
+ return missingSummary ? `${title}. ${missingSummary}` : title;
4047
+ }
4048
+
4152
4049
  function activityDeclaringEffect(args) {
4153
4050
  return workflowEngine.findStageNode(args)?.activities?.find(activity => (activity.actions ?? []).some(action => (action.effects ?? []).some(effect => effect.name === args.effectName)))?.name;
4154
4051
  }
@@ -4182,15 +4079,15 @@ function diagnosisOf(args) {
4182
4079
  function instanceFault(args) {
4183
4080
  const diagnosis = diagnosisOf(args);
4184
4081
  if (diagnosis === void 0 || diagnosis.state !== "stuck") return;
4185
- const verbs = workflowEngine.remediationsFor(diagnosis).map(remediation2 => remediation2.verb);
4082
+ const verbs = workflowEngine.remediationsFor(diagnosis).map(remediation2 => remediation2.verb), additional = workflowEngine._additionalMissingDocuments(diagnosis, args.evaluation?.missingDocuments), missingSummary = workflowEngine._missingDocumentsSummary(diagnosis.cause.kind === "document-missing" ? diagnosis.cause.documents : additional), additionalSummary = additional.length > 0 ? missingSummary : "";
4186
4083
  return {
4187
4084
  activity: faultingActivity({
4188
4085
  cause: diagnosis.cause,
4189
4086
  definition: args.definition,
4190
4087
  stageName: args.instance.currentStage
4191
4088
  }),
4192
- detail: detailOf(diagnosis.cause),
4193
- summary: summaryOf(diagnosis.cause),
4089
+ detail: withMissingDocuments(detailOf(diagnosis.cause, missingSummary), additionalSummary),
4090
+ summary: withMissingDocuments(summaryOf(diagnosis.cause, missingSummary), additionalSummary),
4194
4091
  remedies: verbs.flatMap(verb => REMEDY_TEXT[verb] ?? []),
4195
4092
  actions: verbs.flatMap(verb => isRunnable(verb) ? [ {
4196
4093
  verb: verb,
@@ -4235,7 +4132,7 @@ function AbortedBadge({instance: instance}) {
4235
4132
 
4236
4133
  function OlderDefinitionBadge({instance: instance}) {
4237
4134
  const {latestDefinitionVersions: latestDefinitionVersions} = useWorkflowContext(), latest = latestDefinitionVersions.get(instance.definition);
4238
- return latest === void 0 || latest <= instance.pinnedVersion ? null : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
4135
+ return latest === void 0 || latest <= instance.pinnedVersion ? null : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
4239
4136
  description: "Running workflows keep the version they started on",
4240
4137
  text: `Started on v${instance.pinnedVersion}, latest is now v${latest}`,
4241
4138
  textWeight: "medium",
@@ -4390,7 +4287,7 @@ function RowAssignees({assignees: assignees, hint: hint}) {
4390
4287
  if (ids.length === 0 && roles.length === 0) return null;
4391
4288
  const bothKinds = roles.length > 0 && displays.length > 0;
4392
4289
  /* @__PURE__ */
4393
- return jsxRuntime.jsx(HoverHint, {
4290
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
4394
4291
  content: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
4395
4292
  gap: 3,
4396
4293
  children: [ roles.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(HintSection, {
@@ -4459,61 +4356,8 @@ function OverlineHeading({children: children}) {
4459
4356
  });
4460
4357
  }
4461
4358
 
4462
- function CheckmarkCircleFilledIcon(props) {
4463
- /* @__PURE__ */
4464
- return jsxRuntime.jsx("svg", {
4465
- "data-sanity-icon": "checkmark-circle-filled",
4466
- fill: "none",
4467
- height: "1em",
4468
- viewBox: "0 0 25 25",
4469
- width: "1em",
4470
- xmlns: "http://www.w3.org/2000/svg",
4471
- ...props,
4472
- children: /* @__PURE__ */ jsxRuntime.jsx("path", {
4473
- clipRule: "evenodd",
4474
- d: "M4 12.5C4 7.80558 7.80558 4 12.5 4C17.1944 4 21 7.80558 21 12.5C21 17.1944 17.1944 21 12.5 21C7.80558 21 4 17.1944 4 12.5ZM9.9358 11.7192L11.7414 13.6271L15.5642 9.5876L16.4358 10.4124L12.1772 14.9124C11.9406 15.1624 11.5422 15.1624 11.3056 14.9124L9.0642 12.544L9.9358 11.7192Z",
4475
- fill: "currentColor",
4476
- fillRule: "evenodd"
4477
- })
4478
- });
4479
- }
4480
-
4481
- const STATUS_ICON = /* @__PURE__ */ new Map([ [ "active", {
4482
- icon: Empty$1.EmptyIcon,
4483
- muted: !1
4484
- } ], [ "done", {
4485
- icon: CheckmarkCircleFilledIcon,
4486
- muted: !1
4487
- } ], [ "failed", {
4488
- icon: ErrorFilled.ErrorFilledIcon,
4489
- muted: !1
4490
- } ], [ "skipped", {
4491
- icon: RemoveCircle.RemoveCircleIcon,
4492
- muted: !0
4493
- } ] ]);
4494
-
4495
- function ActivityStatusIcon({status: status}) {
4496
- const {icon: Icon, muted: muted} = STATUS_ICON.get(status) ?? {
4497
- icon: Empty$1.EmptyIcon,
4498
- muted: !0
4499
- };
4500
- return status === "failed" ? /* @__PURE__ */ jsxRuntime.jsx(sanity.TextWithTone, {
4501
- size: 1,
4502
- tone: "critical",
4503
- children: /* @__PURE__ */ jsxRuntime.jsx(Icon, {
4504
- style: {
4505
- color: "inherit"
4506
- }
4507
- })
4508
- }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
4509
- muted: muted,
4510
- size: 1,
4511
- children: /* @__PURE__ */ jsxRuntime.jsx(Icon, {})
4512
- });
4513
- }
4514
-
4515
4359
  function SpinnerSlot({busy: busy, reserve: reserve = !0}) {
4516
- const size = useTextIconSize(), trim = useCapTrimFor(size), spinning = useDelayedFlag(busy, LOADING_CUE_DELAY_MS);
4360
+ const size = useTextIconSize(), trim = useCapTrimFor(size), spinning = workflowComponents._useDelayedFlag(busy, LOADING_CUE_DELAY_MS);
4517
4361
  return !spinning && !reserve ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
4518
4362
  align: "center",
4519
4363
  flex: "none",
@@ -4532,7 +4376,7 @@ function SpinnerSlot({busy: busy, reserve: reserve = !0}) {
4532
4376
  }
4533
4377
 
4534
4378
  function LoadingRow({label: label, padding: padding}) {
4535
- const announced = useDelayedFlag(!0, LOADING_CUE_DELAY_MS);
4379
+ const announced = workflowComponents._useDelayedFlag(!0, LOADING_CUE_DELAY_MS);
4536
4380
  /* @__PURE__ */
4537
4381
  return jsxRuntime.jsxs(ui.Flex, {
4538
4382
  align: "center",
@@ -4656,7 +4500,7 @@ function AssignActivityControl({instanceId: instanceId, state: state, surface: s
4656
4500
  }),
4657
4501
  onClick: handleClick,
4658
4502
  onMouseDown: stopRowMouseDown
4659
- }) : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
4503
+ }) : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
4660
4504
  disabled: open,
4661
4505
  text: "Assign",
4662
4506
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
@@ -4796,7 +4640,7 @@ function DueDate({dueDate: dueDate, hintDisabled: hintDisabled, overdue: overdue
4796
4640
  return face === void 0 ? text :
4797
4641
  /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
4798
4642
  align: "center",
4799
- children: /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
4643
+ children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
4800
4644
  ...face,
4801
4645
  disabled: hintDisabled === !0,
4802
4646
  children: text
@@ -4879,7 +4723,7 @@ function DueDateControl({item: item, editable: editable, onPatch: onPatch}) {
4879
4723
  padding: 2,
4880
4724
  tone: overdue ? "caution" : "default",
4881
4725
  children: display
4882
- }) : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
4726
+ }) : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
4883
4727
  disabled: open,
4884
4728
  text: "Set due date",
4885
4729
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
@@ -4916,7 +4760,7 @@ function AssigneeControl({item: item, editable: editable, eligibleRoles: eligibl
4916
4760
  "aria-label": "Reassign",
4917
4761
  avatar: chip,
4918
4762
  onClick: () => setOpen(v => !v)
4919
- }) : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
4763
+ }) : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
4920
4764
  disabled: open,
4921
4765
  text: "Assign",
4922
4766
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
@@ -4978,7 +4822,7 @@ function AddItemControl({onAdd: onAdd, button: button, busy: busy}) {
4978
4822
 
4979
4823
  function RemoveItemButton({onClick: onClick}) {
4980
4824
  /* @__PURE__ */
4981
- return jsxRuntime.jsx(HoverHint, {
4825
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
4982
4826
  text: "Remove item",
4983
4827
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
4984
4828
  "aria-label": "Remove item",
@@ -5082,7 +4926,7 @@ function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle,
5082
4926
  }),
5083
4927
  lead:
5084
4928
  /* @__PURE__ */ jsxRuntime.jsx(CheckboxSlot, {
5085
- children: hint === void 0 ? checkbox : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
4929
+ children: hint === void 0 ? checkbox : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
5086
4930
  text: hint,
5087
4931
  children: checkbox
5088
4932
  })
@@ -5294,7 +5138,7 @@ function hintContent(hint) {
5294
5138
 
5295
5139
  function AutomationActionRow({actionEval: actionEval, definition: definition}) {
5296
5140
  /* @__PURE__ */
5297
- return jsxRuntime.jsx(HoverHint, {
5141
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
5298
5142
  content: hintContent(automationHint({
5299
5143
  actionEval: actionEval,
5300
5144
  definition: definition
@@ -5669,7 +5513,7 @@ function TaskStatusRow({detail: detail, holding: holding}) {
5669
5513
  align: "center",
5670
5514
  gap: 2,
5671
5515
  children: [
5672
- /* @__PURE__ */ jsxRuntime.jsx(ActivityStatusIcon, {
5516
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.ActivityStatusIcon, {
5673
5517
  status: status
5674
5518
  }),
5675
5519
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
@@ -5811,7 +5655,7 @@ function MetaBlock({document: document, ...props}) {
5811
5655
  align: "center",
5812
5656
  gap: 2,
5813
5657
  children: [
5814
- /* @__PURE__ */ jsxRuntime.jsx(ActivityStatusIcon, {
5658
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.ActivityStatusIcon, {
5815
5659
  status: status
5816
5660
  }),
5817
5661
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
@@ -6068,7 +5912,7 @@ function MetricText({children: children, tone: tone}) {
6068
5912
 
6069
5913
  function MetricPair({face: face, ...lockup}) {
6070
5914
  /* @__PURE__ */
6071
- return jsxRuntime.jsx(HoverHint, {
5915
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
6072
5916
  ...face,
6073
5917
  children: /* @__PURE__ */ jsxRuntime.jsx(MetricLockup, {
6074
5918
  ...lockup
@@ -6103,7 +5947,7 @@ function MetricLockup({Icon: Icon, empty: empty, label: label, tone: tone, value
6103
5947
 
6104
5948
  function AlertGlyph({Icon: Icon, hint: hint, label: label, tone: tone}) {
6105
5949
  /* @__PURE__ */
6106
- return jsxRuntime.jsx(HoverHint, {
5950
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
6107
5951
  text: hint,
6108
5952
  children: /* @__PURE__ */ jsxRuntime.jsx(sanity.TextWithTone, {
6109
5953
  size: 1,
@@ -6118,10 +5962,14 @@ function AlertGlyph({Icon: Icon, hint: hint, label: label, tone: tone}) {
6118
5962
  });
6119
5963
  }
6120
5964
 
5965
+ function useAlertChipSize() {
5966
+ return useTextIconSize() + useSpaceToken(1) * 2;
5967
+ }
5968
+
6121
5969
  function AlertChip({Icon: Icon, hint: hint, label: label, tone: tone}) {
6122
- const glyph = useTextIconSize(), disc = glyph + useSpaceToken(1) * 2;
5970
+ const glyph = useTextIconSize(), disc = useAlertChipSize();
6123
5971
  /* @__PURE__ */
6124
- return jsxRuntime.jsx(HoverHint, {
5972
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
6125
5973
  text: hint,
6126
5974
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
6127
5975
  radius: "full",
@@ -6221,7 +6069,7 @@ function ActivityDateControl({instanceId: instanceId, state: state, surface: sur
6221
6069
  onMouseDown: stopRowMouseDown,
6222
6070
  padding: 2,
6223
6071
  children: dueDate()
6224
- }) : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
6072
+ }) : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
6225
6073
  disabled: open,
6226
6074
  text: "Set date",
6227
6075
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
@@ -6246,9 +6094,9 @@ function settledDim(settled) {
6246
6094
 
6247
6095
  function ActivityStatusLead({status: status}) {
6248
6096
  /* @__PURE__ */
6249
- return jsxRuntime.jsx(HoverHint, {
6097
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
6250
6098
  text: ACTIVITY_STATUS_LABEL[status],
6251
- children: /* @__PURE__ */ jsxRuntime.jsx(ActivityStatusIcon, {
6099
+ children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.ActivityStatusIcon, {
6252
6100
  status: status
6253
6101
  })
6254
6102
  });
@@ -6297,7 +6145,7 @@ function RowTerminalActions({actions: actions, activity: activity, instanceId: i
6297
6145
  function TitleTag({hint: hint, tone: tone, children: children}) {
6298
6146
  const badgeTrim = useBadgeCapTrim();
6299
6147
  /* @__PURE__ */
6300
- return jsxRuntime.jsx(HoverHint, {
6148
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
6301
6149
  text: hint,
6302
6150
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, {
6303
6151
  fontSize: 1,
@@ -6563,7 +6411,7 @@ function deriveFieldPills(args) {
6563
6411
  function UserAvatar({id: id}) {
6564
6412
  const {name: name, imageUrl: imageUrl} = useUserDisplay(id);
6565
6413
  /* @__PURE__ */
6566
- return jsxRuntime.jsx(HoverHint, {
6414
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
6567
6415
  text: name,
6568
6416
  children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.MemberAvatar, {
6569
6417
  imageUrl: imageUrl,
@@ -6574,7 +6422,7 @@ function UserAvatar({id: id}) {
6574
6422
 
6575
6423
  function UserAvatarGroup({ids: ids, hint: hint}) {
6576
6424
  const displays = useUserDisplays(ids);
6577
- return displays.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
6425
+ return displays.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
6578
6426
  text: disambiguatedNames(displays).join(", "),
6579
6427
  ...hint === void 0 ? {} : {
6580
6428
  description: hint
@@ -6794,7 +6642,7 @@ function usePillChrome(face) {
6794
6642
  function PillHint({pill: pill, disabled: disabled = !1, children: children}) {
6795
6643
  const {description: description} = pill;
6796
6644
  /* @__PURE__ */
6797
- return jsxRuntime.jsx(HoverHint, {
6645
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
6798
6646
  disabled: disabled || description === void 0,
6799
6647
  text: description ?? "",
6800
6648
  children: children
@@ -7366,17 +7214,6 @@ function conditionLines(description) {
7366
7214
  });
7367
7215
  }
7368
7216
 
7369
- function StartIncompleteBadge({style: style}) {
7370
- /* @__PURE__ */
7371
- return jsxRuntime.jsx(ui.Badge, {
7372
- fontSize: 1,
7373
- mode: "outline",
7374
- style: style,
7375
- tone: "caution",
7376
- children: "Start incomplete"
7377
- });
7378
- }
7379
-
7380
7217
  function normalizeAbortReason(raw) {
7381
7218
  const trimmed = raw.trim();
7382
7219
  return trimmed === "" ? void 0 : trimmed;
@@ -7588,24 +7425,6 @@ function historyLine(h, titles) {
7588
7425
  return historyLiner[h._type](h, titles);
7589
7426
  }
7590
7427
 
7591
- function AgoStamp({at: at, now: now}) {
7592
- /* @__PURE__ */
7593
- return jsxRuntime.jsx(ui.Flex, {
7594
- align: "center",
7595
- children: /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
7596
- text: formatShortDateTime(at),
7597
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
7598
- muted: !0,
7599
- size: 1,
7600
- style: {
7601
- whiteSpace: "nowrap"
7602
- },
7603
- children: formatShortAgo(at, now)
7604
- })
7605
- })
7606
- });
7607
- }
7608
-
7609
7428
  function CodeChip({value: value}) {
7610
7429
  /* @__PURE__ */
7611
7430
  return jsxRuntime.jsx("code", {
@@ -7628,7 +7447,7 @@ function HintedMenuButton({hint: hint, ...menuButtonProps}) {
7628
7447
  return hint === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, {
7629
7448
  ...menuButtonProps,
7630
7449
  popover: popover
7631
- }) : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
7450
+ }) : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
7632
7451
  disabled: open,
7633
7452
  text: hint,
7634
7453
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, {
@@ -7831,7 +7650,7 @@ function FeedStamp({at: at, now: now}) {
7831
7650
  size: 1,
7832
7651
  children: "·"
7833
7652
  }),
7834
- /* @__PURE__ */ jsxRuntime.jsx(AgoStamp, {
7653
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.AgoStamp, {
7835
7654
  at: at,
7836
7655
  now: now
7837
7656
  }) ]
@@ -7895,7 +7714,7 @@ function ActorNameSpan({id: id}) {
7895
7714
  function FeedGlyph({hint: hint, icon: icon}) {
7896
7715
  const size = useAvatarSize();
7897
7716
  /* @__PURE__ */
7898
- return jsxRuntime.jsx(HoverHint, {
7717
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
7899
7718
  text: hint,
7900
7719
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
7901
7720
  align: "center",
@@ -8102,7 +7921,7 @@ function HeaderTitleLine({entry: entry}) {
8102
7921
  textOverflow: "ellipsis",
8103
7922
  weight: "medium",
8104
7923
  children: instanceTitle(entry.instance, definition)
8105
- }), face === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(StartIncompleteBadge, {
7924
+ }), face === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.StartIncompleteBadge, {
8106
7925
  style: badgeTrim
8107
7926
  }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
8108
7927
  children: [
@@ -8206,7 +8025,7 @@ function StageFace({completed: completed = !1, detail: detail, title: title}) {
8206
8025
  /* @__PURE__ */ jsxRuntime.jsx(sanity.TextWithTone, {
8207
8026
  size: 1,
8208
8027
  tone: tone,
8209
- children: completed ? /* @__PURE__ */ jsxRuntime.jsx(CheckmarkCircleFilledIcon, {
8028
+ children: completed ? /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._CheckmarkCircleFilledIcon, {
8210
8029
  style: {
8211
8030
  color: "inherit"
8212
8031
  }
@@ -8298,7 +8117,7 @@ function SpineNodeView({definition: definition, node: node, transitions: transit
8298
8117
  if (node.state === "current") {
8299
8118
  const detail = roundDetail(node.round);
8300
8119
  /* @__PURE__ */
8301
- return jsxRuntime.jsx(HoverHint, {
8120
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
8302
8121
  content: card,
8303
8122
  "data-testid": `spine-node-${node.name}`,
8304
8123
  flush: !0,
@@ -8314,7 +8133,7 @@ function SpineNodeView({definition: definition, node: node, transitions: transit
8314
8133
  }
8315
8134
  const Icon = NODE_ICON[node.state];
8316
8135
  /* @__PURE__ */
8317
- return jsxRuntime.jsx(HoverHint, {
8136
+ return jsxRuntime.jsx(workflowComponents._HoverHint, {
8318
8137
  content: card,
8319
8138
  "data-testid": `spine-node-${node.name}`,
8320
8139
  flush: !0,
@@ -8462,10 +8281,21 @@ function WorkflowInstanceSection({defaultOpen: defaultOpen, entry: entry, onOpen
8462
8281
  return jsxRuntime.jsx(InstanceCard, {
8463
8282
  defaultOpen: defaultOpen,
8464
8283
  entry: entry,
8465
- children: /* @__PURE__ */ jsxRuntime.jsx(InstanceSnapshotBody, {
8466
- entry: entry,
8467
- onOpenActivity: onOpenActivity,
8468
- surface: "document-view"
8284
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
8285
+ gap: 3,
8286
+ children: [
8287
+ /* @__PURE__ */ jsxRuntime.jsx(InstanceFaultNote, {
8288
+ entry: entry,
8289
+ scope: {
8290
+ kind: "run",
8291
+ onOpenActivity: onOpenActivity
8292
+ }
8293
+ }),
8294
+ /* @__PURE__ */ jsxRuntime.jsx(InstanceSnapshotBody, {
8295
+ entry: entry,
8296
+ onOpenActivity: onOpenActivity,
8297
+ surface: "document-view"
8298
+ }) ]
8469
8299
  })
8470
8300
  });
8471
8301
  }
@@ -9242,7 +9072,7 @@ function showRowOnError(key, mapping) {
9242
9072
  }
9243
9073
 
9244
9074
  function useStartWorkflow(args) {
9245
- const {mapping: mapping, docId: docId, initialValue: initialValue, source: source} = args, toast = useWorkflowToast(), schema = sanity.useSchema(), {engine: engine, openStartDialog: openStartDialog, mappingIssues: mappingIssues2, mappingStarts: mappingStarts} = useWorkflowContext(), observer = workflowStudio.useStudioObserver({
9075
+ const {mapping: mapping, docId: docId, initialValue: initialValue, source: source} = args, toast = useWorkflowToast(), schema = sanity.useSchema(), {engine: engine, openStartDialog: openStartDialog, mappingIssues: mappingIssues2, mappingStarts: mappingStarts} = useWorkflowContext(), observer2 = workflowStudio.useStudioObserver({
9246
9076
  engine: engine
9247
9077
  }), [starting, setStarting] = react.useState(!1), {selectedReleaseId: selectedReleaseId} = sanity.usePerspective(), releaseActive = sanity.useIsReleaseActive(), startBlock = mappingStarts.get(mappingKey(mapping)), hidden = workflowEngine.startKindOf({
9248
9078
  start: startBlock
@@ -9284,7 +9114,7 @@ function useStartWorkflow(args) {
9284
9114
  docId: docId,
9285
9115
  initialValue: initialValue,
9286
9116
  selectedReleaseId: selectedReleaseId,
9287
- ensureDocumentExists: observer.ensureDocumentExists,
9117
+ ensureDocumentExists: observer2.ensureDocumentExists,
9288
9118
  onPersistFailure: err => toast.push({
9289
9119
  id: TOAST_ID.documentSave,
9290
9120
  status: "error",
@@ -9329,7 +9159,7 @@ function StartWorkflowButton({mapping: mapping, docId: docId, initialValue: init
9329
9159
  },
9330
9160
  tone: tone
9331
9161
  }), hint = tooltip ?? (iconOnly ? startLabel : void 0);
9332
- return hint ? /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
9162
+ return hint ? /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
9333
9163
  text: hint,
9334
9164
  children: button
9335
9165
  }) : button;
@@ -9406,7 +9236,7 @@ function StartWorkflowMenuItem({mapping: mapping, docId: docId, initialValue: in
9406
9236
  },
9407
9237
  text: `Start ${mapping.label}`
9408
9238
  });
9409
- return tooltip ? /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
9239
+ return tooltip ? /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
9410
9240
  text: tooltip,
9411
9241
  children: item
9412
9242
  }) : item;
@@ -9494,7 +9324,7 @@ const VIEW_TAB_CODEC = workflowsTabCodec([ "overview", "for-me" ]), WorkflowsVie
9494
9324
  };
9495
9325
 
9496
9326
  function DiscoverySpinner() {
9497
- const visible = useDelayedFlag(!0, 1e3);
9327
+ const visible = workflowComponents._useDelayedFlag(!0, 1e3);
9498
9328
  /* @__PURE__ */
9499
9329
  return jsxRuntime.jsx(ui.Flex, {
9500
9330
  align: "center",
@@ -9864,20 +9694,30 @@ function createSubscribers() {
9864
9694
  }
9865
9695
 
9866
9696
  function actualType$(previews, bareId) {
9867
- return previews.unstable_observeDocumentPairAvailability(bareId).pipe(operators.switchMap(({draft: draft, published: published}) => draft.available ? previews.observeDocumentTypeFromId(csm.getDraftId(bareId)) : published.available ? previews.observeDocumentTypeFromId(bareId) : draft.reason === "PERMISSION_DENIED" || published.reason === "PERMISSION_DENIED" ? rxjs.of(void 0) : previews.unstable_observeVersionDocumentIds(bareId).pipe(operators.switchMap(([firstVersionId]) => firstVersionId === void 0 ? rxjs.of(null) : previews.observeDocumentTypeFromId(firstVersionId)))), operators.distinctUntilChanged());
9697
+ return previews.unstable_observeDocumentPairAvailability(bareId).pipe(operators.switchMap(pair => representationType$(previews, {
9698
+ bareId: bareId,
9699
+ ...pair
9700
+ }).pipe(operators.startWith(void 0))), operators.distinctUntilChanged());
9701
+ }
9702
+
9703
+ function representationType$(previews, {bareId: bareId, draft: draft, published: published}) {
9704
+ return draft.available ? previews.observeDocumentTypeFromId(csm.getDraftId(bareId)) : published.available ? previews.observeDocumentTypeFromId(bareId) : draft.reason === "PERMISSION_DENIED" || published.reason === "PERMISSION_DENIED" ? rxjs.of(UNREADABLE_DOCUMENT) : previews.unstable_observeVersionDocumentIds(bareId).pipe(operators.switchMap(([firstVersionId]) => firstVersionId === void 0 ? rxjs.of(null) : previews.observeDocumentTypeFromId(firstVersionId).pipe(operators.startWith(void 0))));
9868
9705
  }
9869
9706
 
9870
9707
  const REBUILD_DELAY_MS = 5e3;
9871
9708
 
9872
9709
  function createActualTypeProbeStore(previews) {
9873
- const verdicts = /* @__PURE__ */ new Map, live = /* @__PURE__ */ new Map, subscribers = createSubscribers(), start = (bareId, entry) => actualType$(previews, bareId).subscribe({
9874
- next: value => {
9875
- verdicts.has(bareId) && verdicts.get(bareId) === value || (verdicts.set(bareId, value),
9876
- subscribers.notify());
9877
- },
9710
+ const verdicts = /* @__PURE__ */ new Map, live = /* @__PURE__ */ new Map, subscribers = createSubscribers(), publish = (bareId, value) => {
9711
+ const changed = verdicts.get(bareId) !== value;
9712
+ verdicts.set(bareId, value), changed && subscribers.notify();
9713
+ }, forgetUnavailable = bareId => {
9714
+ const verdict = verdicts.get(bareId);
9715
+ (verdict === null || verdict === UNREADABLE_DOCUMENT) && publish(bareId, void 0);
9716
+ }, start = (bareId, entry) => actualType$(previews, bareId).subscribe({
9717
+ next: value => publish(bareId, value),
9878
9718
  error: err => {
9879
9719
  console.error(`[workflow-studio-plugin] actual-type probe for "${bareId}" failed:`, err),
9880
- entry.subscription = void 0, entry.rebuildTimer = setTimeout(() => {
9720
+ forgetUnavailable(bareId), entry.subscription = void 0, entry.rebuildTimer = setTimeout(() => {
9881
9721
  entry.rebuildTimer = void 0, !(live.get(bareId) !== entry || entry.count === 0) && (entry.subscription = start(bareId, entry));
9882
9722
  }, REBUILD_DELAY_MS);
9883
9723
  }
@@ -9905,7 +9745,8 @@ function createActualTypeProbeStore(previews) {
9905
9745
  let released = !1;
9906
9746
  return () => {
9907
9747
  released || (released = !0, entry.count -= 1, !(entry.count > 0) && (entry.subscription?.unsubscribe(),
9908
- entry.rebuildTimer !== void 0 && clearTimeout(entry.rebuildTimer), live.get(bareId) === entry && live.delete(bareId)));
9748
+ entry.rebuildTimer !== void 0 && clearTimeout(entry.rebuildTimer), live.get(bareId) === entry && live.delete(bareId),
9749
+ forgetUnavailable(bareId)));
9909
9750
  };
9910
9751
  }
9911
9752
  };
@@ -10536,7 +10377,7 @@ function AssigneesInput({value: value, onChange: onChange, eligibleRoles: eligib
10536
10377
  /* @__PURE__ */ jsxRuntime.jsx(AssigneeBadge, {
10537
10378
  assignee: assignee
10538
10379
  }),
10539
- /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
10380
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
10540
10381
  text: "Remove",
10541
10382
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
10542
10383
  "aria-label": "Remove",
@@ -10731,7 +10572,7 @@ function useLatestDefinition(definitionName) {
10731
10572
  }
10732
10573
 
10733
10574
  function useCreateDoc(args) {
10734
- const {releaseId: releaseId, onCreated: onCreated} = args, {engine: engine, binding: binding} = useWorkflowContext(), observer = workflowStudio.useStudioObserver({
10575
+ const {releaseId: releaseId, onCreated: onCreated} = args, {engine: engine, binding: binding} = useWorkflowContext(), observer2 = workflowStudio.useStudioObserver({
10735
10576
  engine: engine
10736
10577
  }), schema = sanity.useSchema(), templates = sanity.useTemplates(), resolverContext = sanity.useInitialValueResolverContext(), toast = useWorkflowToast(), [creating, setCreating] = react.useState(!1);
10737
10578
  return {
@@ -10742,7 +10583,7 @@ function useCreateDoc(args) {
10742
10583
  const documentId = crypto.randomUUID(), template = templates.find(t => t.id === type), initialValue = template !== void 0 ? await sanity.resolveInitialValue(schema, template, {}, resolverContext, {
10743
10584
  useCache: !0
10744
10585
  }) : void 0;
10745
- await observer.ensureDocumentExists({
10586
+ await observer2.ensureDocumentExists({
10746
10587
  documentId: documentId,
10747
10588
  type: type,
10748
10589
  ...releaseId !== void 0 ? {
@@ -11385,7 +11226,7 @@ function AutoStartGate(props) {
11385
11226
  }
11386
11227
 
11387
11228
  function AutoStartDriver(props) {
11388
- const {rawDocId: rawDocId, docType: docType, workflows: workflows, value: value, fallback: fallback} = props, {isDocResolved: isDocResolved, autoStartDefinitions: autoStartDefinitions, engine: engine, binding: binding, seedInstance: seedInstance} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry(), observer = workflowStudio.useStudioObserver({
11229
+ const {rawDocId: rawDocId, docType: docType, workflows: workflows, value: value, fallback: fallback} = props, {isDocResolved: isDocResolved, autoStartDefinitions: autoStartDefinitions, engine: engine, binding: binding, seedInstance: seedInstance} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry(), observer2 = workflowStudio.useStudioObserver({
11389
11230
  engine: engine
11390
11231
  }), {selectedReleaseId: selectedReleaseId} = sanity.usePerspective(), {entries: entries} = useWorkflowsForDocument(rawDocId), docId = csm.getPublishedId(rawDocId), valueRef = react.useRef(value);
11391
11232
  valueRef.current = value;
@@ -11407,7 +11248,7 @@ function AutoStartDriver(props) {
11407
11248
  if (!firedRef.current) {
11408
11249
  firedRef.current = !0, setFired(!0);
11409
11250
  try {
11410
- await observer.ensureDocumentExists({
11251
+ await observer2.ensureDocumentExists({
11411
11252
  documentId: docId,
11412
11253
  type: docType,
11413
11254
  initialValue: valueRef.current,
@@ -11442,7 +11283,7 @@ function AutoStartDriver(props) {
11442
11283
  setSettled(!0);
11443
11284
  }
11444
11285
  }
11445
- }, [ autoStartDefinitions, docId, docType, binding, engine, observer, seedInstance, instanceIdFor, selectedReleaseId, telemetry2 ]), retry = react.useCallback(() => {
11286
+ }, [ autoStartDefinitions, docId, docType, binding, engine, observer2, seedInstance, instanceIdFor, selectedReleaseId, telemetry2 ]), retry = react.useCallback(() => {
11446
11287
  firedRef.current = !1, setFired(!1), setSettled(!1), setFailure(void 0);
11447
11288
  }, []), action = autoStartAction({
11448
11289
  resolved: definitionsResolved && isDocResolved(docId),
@@ -11620,7 +11461,7 @@ function ActivityGlance({activityEval: activityEval}) {
11620
11461
  align: "center",
11621
11462
  gap: 2,
11622
11463
  children: [
11623
- /* @__PURE__ */ jsxRuntime.jsx(ActivityStatusIcon, {
11464
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.ActivityStatusIcon, {
11624
11465
  status: status
11625
11466
  }),
11626
11467
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
@@ -11775,7 +11616,7 @@ function StripLine({aside: aside, children: children, hint: hint, onOpen: onOpen
11775
11616
  return jsxRuntime.jsxs(ui.Flex, {
11776
11617
  align: "center",
11777
11618
  children: [
11778
- /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
11619
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
11779
11620
  ...hint,
11780
11621
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
11781
11622
  as: "button",
@@ -11809,7 +11650,7 @@ function InstanceLine({entry: entry, onOpen: onOpen}) {
11809
11650
  weight: "medium",
11810
11651
  children: instanceTitle(entry.instance, definition)
11811
11652
  })
11812
- }), unprimed ? /* @__PURE__ */ jsxRuntime.jsx(StartIncompleteBadge, {
11653
+ }), unprimed ? /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.StartIncompleteBadge, {
11813
11654
  style: badgeTrim
11814
11655
  }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
11815
11656
  children: [
@@ -12050,74 +11891,1657 @@ function WorkflowRootInput(props) {
12050
11891
  });
12051
11892
  }
12052
11893
 
12053
- exports.AbortWorkflowDialog = AbortWorkflowDialog;
12054
-
12055
- exports.ActivityDetailBody = ActivityDetailBody;
11894
+ function openActivitiesOf(instance) {
11895
+ return (workflowEngine.findOpenStageEntry(instance)?.activities ?? []).filter(activity => isOpenActivityStatus(activity.status));
11896
+ }
12056
11897
 
12057
- exports.ActivityDetailDialog = ActivityDetailDialog;
11898
+ function overdueTasks(instance, now) {
11899
+ return openActivitiesOf(instance).filter(activity => passedDuesOf(activity, now).length > 0);
11900
+ }
12058
11901
 
12059
- exports.ActivityLog = ActivityLog;
11902
+ function earliestDue(activity) {
11903
+ return earliestOf(dueDatesOf(activity.fields ?? []));
11904
+ }
12060
11905
 
12061
- exports.AgoStamp = AgoStamp;
11906
+ function passedDueOf(activity, now) {
11907
+ const passed = passedDuesOf(activity, now);
11908
+ return earliestOf(passed) ?? passed[0];
11909
+ }
12062
11910
 
12063
- exports.AlertChip = AlertChip;
11911
+ function passedDuesOf(activity, now) {
11912
+ return dueDatesOf(activity.fields ?? []).filter(due => isDueDatePast(due, now));
11913
+ }
12064
11914
 
12065
- exports.AlertGlyph = AlertGlyph;
11915
+ function earliestOf(values) {
11916
+ let earliest;
11917
+ for (const value of values) {
11918
+ const time = parseStoredDateValue(value)?.getTime();
11919
+ time !== void 0 && (earliest === void 0 || time < earliest.time) && (earliest = {
11920
+ time: time,
11921
+ value: value
11922
+ });
11923
+ }
11924
+ return earliest?.value;
11925
+ }
12066
11926
 
12067
- exports.Breadcrumb = Breadcrumb;
11927
+ const AUTONOMY_BY_DEFINITION = /* @__PURE__ */ new WeakMap;
12068
11928
 
12069
- exports.CodeChip = CodeChip;
11929
+ function cachedAutonomy(definition) {
11930
+ const hit = AUTONOMY_BY_DEFINITION.get(definition);
11931
+ if (hit !== void 0) return hit;
11932
+ const derived = workflowEngine.deriveWorkflowAutonomy(definition);
11933
+ return AUTONOMY_BY_DEFINITION.set(definition, derived), derived;
11934
+ }
12070
11935
 
12071
- exports.CountedLabel = CountedLabel;
11936
+ function isAutomatedActivity(args) {
11937
+ const stage = args.autonomy?.stages.find(entry => entry.stage === args.stageName);
11938
+ return isHandsOff({
11939
+ classification: workflowEngine.deriveExecutorClassification(args.activity),
11940
+ completesWithoutCaller: stage?.activities[args.activity.name]?.completesWithoutCaller
11941
+ });
11942
+ }
12072
11943
 
12073
- exports.DismissablePopover = DismissablePopover;
11944
+ function taskOf(args) {
11945
+ const {entry: entry, now: now, openedAt: openedAt, roleAliases: roleAliases, title: title} = args;
11946
+ return {
11947
+ name: entry.name,
11948
+ title: title,
11949
+ assignees: assigneesOf(entry.fields ?? []),
11950
+ roleAliases: roleAliases,
11951
+ openedAt: openedAt,
11952
+ due: earliestDue(entry),
11953
+ overdueSince: passedDueOf(entry, now),
11954
+ status: entry.status
11955
+ };
11956
+ }
12074
11957
 
12075
- exports.DocPreviewLink = DocPreviewLink;
11958
+ function humanTask(args) {
11959
+ const {activity: activity, autonomy: autonomy, entry: entry, now: now, openedAt: openedAt, roleAliases: roleAliases, stageName: stageName} = args;
11960
+ return entry === void 0 ? [] : isAutomatedActivity({
11961
+ activity: activity,
11962
+ autonomy: autonomy,
11963
+ stageName: stageName
11964
+ }) ? [] : [ taskOf({
11965
+ entry: entry,
11966
+ now: now,
11967
+ openedAt: openedAt,
11968
+ roleAliases: roleAliases,
11969
+ title: activityLabel(activity)
11970
+ }) ];
11971
+ }
12076
11972
 
12077
- exports.DocRefFace = DocRefFace;
11973
+ function undeclaredTasks(args) {
11974
+ const {definition: definition, now: now, open: open, openedAt: openedAt, roleAliases: roleAliases, seen: seen, stageName: stageName} = args;
11975
+ return open.filter(entry => !seen.has(entry.name)).map(entry => taskOf({
11976
+ entry: entry,
11977
+ now: now,
11978
+ openedAt: openedAt,
11979
+ roleAliases: roleAliases,
11980
+ title: findActivity({
11981
+ activityName: entry.name,
11982
+ definition: definition,
11983
+ stageName: stageName
11984
+ }).title
11985
+ }));
11986
+ }
12078
11987
 
12079
- exports.EmptyState = EmptyState;
11988
+ function definitionForPinned(definition, pinnedVersion) {
11989
+ if (!(definition === void 0 || definition.version !== pinnedVersion)) return definition;
11990
+ }
12080
11991
 
12081
- exports.FOR_ME_SECTION_COPY = FOR_ME_SECTION_COPY;
11992
+ function stageTasksOf(args) {
11993
+ const {definition: definition, instance: instance, now: now} = args, stageEntry = workflowEngine.findOpenStageEntry(instance);
11994
+ if (stageEntry === void 0) return [];
11995
+ const listed = listedStageActivities(stageEntry);
11996
+ if (listed.length === 0) return [];
11997
+ const openedAt = stageEntry.enteredAt, pinnedDefinition = definitionForPinned(definition, instance.pinnedVersion), autonomy = pinnedDefinition === void 0 ? void 0 : cachedAutonomy(pinnedDefinition), roleAliases = pinnedDefinition?.roleAliases, stageName = instance.currentStage, openByName = new Map(listed.map(entry => [ entry.name, entry ])), declared = workflowEngine.findStageNode({
11998
+ definition: definition,
11999
+ stageName: stageName
12000
+ })?.activities ?? [];
12001
+ return [ ...declared.flatMap(activity => humanTask({
12002
+ activity: activity,
12003
+ autonomy: autonomy,
12004
+ entry: openByName.get(activity.name),
12005
+ now: now,
12006
+ openedAt: openedAt,
12007
+ roleAliases: roleAliases,
12008
+ stageName: stageName
12009
+ })), ...undeclaredTasks({
12010
+ definition: definition,
12011
+ now: now,
12012
+ open: listed,
12013
+ openedAt: openedAt,
12014
+ roleAliases: roleAliases,
12015
+ seen: new Set(declared.map(activity => activity.name)),
12016
+ stageName: stageName
12017
+ }) ];
12018
+ }
12082
12019
 
12083
- exports.ForMeEmptyState = ForMeEmptyState;
12020
+ function listedStageActivities(stage) {
12021
+ return stage.activities.filter(entry => isOpenActivityStatus(entry.status) || entry.status === "failed");
12022
+ }
12084
12023
 
12085
- exports.ForMeSectionHeading = ForMeSectionHeading;
12024
+ function groupWidthOf(task, metrics) {
12025
+ const mark = taskAssignmentMarkOf(task.assignees), faces = mark.kind === "held" ? mark.members.length : 1;
12026
+ return metrics.face + (faces - 1) * (metrics.face - metrics.overlap);
12027
+ }
12086
12028
 
12087
- exports.HoverHint = HoverHint;
12029
+ function rowWidthOf(tasks, metrics) {
12030
+ return tasks.reduce((total, task) => total + groupWidthOf(task, metrics), 0) + Math.max(0, tasks.length - 1) * metrics.gap;
12031
+ }
12088
12032
 
12089
- exports.InstanceFaultNote = InstanceFaultNote;
12033
+ function countWithin(args) {
12034
+ const {budget: budget, metrics: metrics, tasks: tasks} = args;
12035
+ let used = 0, count = 0;
12036
+ for (const task of tasks) {
12037
+ const next = used + (count === 0 ? 0 : metrics.gap) + groupWidthOf(task, metrics);
12038
+ if (next > budget) break;
12039
+ used = next, count += 1;
12040
+ }
12041
+ return Math.max(1, count);
12042
+ }
12090
12043
 
12091
- exports.InstanceSnapshotBody = InstanceSnapshotBody;
12044
+ function visibleStageTasks(args) {
12045
+ const {metrics: metrics, room: room, tasks: tasks} = args;
12046
+ if (rowWidthOf(tasks, metrics) <= room) return {
12047
+ overflow: 0,
12048
+ visible: tasks
12049
+ };
12050
+ const shown = countWithin({
12051
+ budget: room - metrics.gap - metrics.counter,
12052
+ metrics: metrics,
12053
+ tasks: tasks
12054
+ });
12055
+ return {
12056
+ overflow: tasks.length - shown,
12057
+ visible: tasks.slice(0, shown)
12058
+ };
12059
+ }
12092
12060
 
12093
- exports.InvalidDocNotice = InvalidDocNotice;
12061
+ function taskAssignmentMarkOf(assignees) {
12062
+ const members = assignees.filter(assignee => assignee.type === "user");
12063
+ if (members.length > 0) return {
12064
+ kind: "held",
12065
+ members: members
12066
+ };
12067
+ const roles = assignees.flatMap(assignee => assignee.type === "role" ? [ assignee.role ] : []);
12068
+ return roles.length > 0 ? {
12069
+ kind: "routed",
12070
+ roles: roles
12071
+ } : {
12072
+ kind: "unassigned"
12073
+ };
12074
+ }
12094
12075
 
12095
- exports.LoadingRow = LoadingRow;
12076
+ const LATE_FACE = {
12077
+ Icon: Calendar.CalendarIcon,
12078
+ tone: "caution"
12079
+ };
12096
12080
 
12097
- exports.LogEventOnMount = LogEventOnMount;
12081
+ function LateSpan({now: now, since: since}) {
12082
+ /* @__PURE__ */
12083
+ return jsxRuntime.jsx(MetricLockup, {
12084
+ Icon: LATE_FACE.Icon,
12085
+ tone: LATE_FACE.tone,
12086
+ value: workflowComponents._shortSpanOf(parseStoredDateValue(since), now)
12087
+ });
12088
+ }
12098
12089
 
12099
- exports.MetaRow = MetaRow;
12090
+ const HOLDER_OVERLAP = 7, HOLDER_RING = 1.5, GROUP_GAP_TOKEN = 3, OVERDUE_DOT_RATIO = .4;
12100
12091
 
12101
- exports.MetricLockup = MetricLockup;
12092
+ function overdueDotOf(face) {
12093
+ const size = Math.round(face * OVERDUE_DOT_RATIO);
12094
+ return {
12095
+ overhang: Math.round(size / 4),
12096
+ size: size
12097
+ };
12098
+ }
12102
12099
 
12103
- exports.MetricPair = MetricPair;
12100
+ function useDisplayById(ids) {
12101
+ const displays = useUserDisplays(uniqueIds(ids)), labels = disambiguatedNames(displays);
12102
+ return new Map(displays.map((display, index) => [ display.id, {
12103
+ ...display,
12104
+ label: labels[index] ?? display.name
12105
+ } ]));
12106
+ }
12104
12107
 
12105
- exports.NoteBanner = NoteBanner;
12108
+ function holderKey(assignee, index) {
12109
+ return `${assignee.id}-${index}`;
12110
+ }
12106
12111
 
12107
- exports.OverlineHeading = OverlineHeading;
12112
+ function stageTasksFace(args) {
12113
+ return {
12114
+ content: /* @__PURE__ */ jsxRuntime.jsx(StageTasksCard, {
12115
+ now: args.now,
12116
+ tasks: args.tasks
12117
+ }),
12118
+ flush: !0,
12119
+ wide: !0
12120
+ };
12121
+ }
12108
12122
 
12109
- exports.RUN_SEARCH_PARAM = RUN_SEARCH_PARAM;
12123
+ function StageTaskGroups({now: now, room: room, tasks: tasks}) {
12124
+ const gap = useSpaceToken(GROUP_GAP_TOKEN), face = useAvatarSize(), {overhang: overhang} = overdueDotOf(face), {overflow: overflow, visible: visible} = visibleStageTasks({
12125
+ metrics: {
12126
+ counter: face,
12127
+ face: face,
12128
+ gap: gap,
12129
+ overlap: HOLDER_OVERLAP
12130
+ },
12131
+ room: room === void 0 ? face * 3 + gap * 2 : room - overhang,
12132
+ tasks: tasks
12133
+ });
12134
+ return tasks.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
12135
+ ...stageTasksFace({
12136
+ now: now,
12137
+ tasks: tasks
12138
+ }),
12139
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
12140
+ align: "center",
12141
+ "aria-label": "Tasks",
12142
+ style: {
12143
+ columnGap: gap,
12144
+ paddingRight: overhang
12145
+ },
12146
+ children: [ visible.map(task => /* @__PURE__ */ jsxRuntime.jsx(TaskGroupFace, {
12147
+ task: task
12148
+ }, task.name)), overflow === 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, {
12149
+ muted: !0,
12150
+ size: 1,
12151
+ children: [ "+", overflow ]
12152
+ }) ]
12153
+ })
12154
+ });
12155
+ }
12110
12156
 
12111
- exports.RowAssignees = RowAssignees;
12157
+ function TaskGroupFace({task: task}) {
12158
+ /* @__PURE__ */
12159
+ return jsxRuntime.jsxs(ui.Box, {
12160
+ style: {
12161
+ flexShrink: 0,
12162
+ position: "relative"
12163
+ },
12164
+ children: [
12165
+ /* @__PURE__ */ jsxRuntime.jsx(AssignmentFace, {
12166
+ assignees: task.assignees
12167
+ }), task.overdueSince === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(OverdueDot, {}) ]
12168
+ });
12169
+ }
12170
+
12171
+ function AssignmentFace({assignees: assignees}) {
12172
+ const mark = taskAssignmentMarkOf(assignees);
12173
+ return mark.kind === "unassigned" ? /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {}) : mark.kind === "routed" ? /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {
12174
+ routed: !0
12175
+ }) : /* @__PURE__ */ jsxRuntime.jsx(OverlappedHolders, {
12176
+ assignees: mark.members
12177
+ });
12178
+ }
12179
+
12180
+ function OverdueDot() {
12181
+ const {color: color} = ui.useTheme_v2(), {overhang: overhang, size: size} = overdueDotOf(useAvatarSize());
12182
+ /* @__PURE__ */
12183
+ return jsxRuntime.jsx(ui.Box, {
12184
+ "aria-label": "Overdue",
12185
+ role: "img",
12186
+ style: {
12187
+ backgroundColor: color.button.default.caution.enabled.bg,
12188
+ borderRadius: "50%",
12189
+ boxShadow: `0 0 0 ${HOLDER_RING}px ${color.bg}`,
12190
+ height: size,
12191
+ position: "absolute",
12192
+ right: -overhang,
12193
+ top: -overhang,
12194
+ width: size
12195
+ }
12196
+ });
12197
+ }
12198
+
12199
+ function HolderFace({assignee: assignee, displayById: displayById}) {
12200
+ const display = displayById.get(assignee.id);
12201
+ /* @__PURE__ */
12202
+ return jsxRuntime.jsx(workflowComponents.MemberAvatar, {
12203
+ imageUrl: display?.imageUrl,
12204
+ name: display?.name ?? assignee.id,
12205
+ size: 0
12206
+ });
12207
+ }
12208
+
12209
+ function OverlappedHolders({assignees: assignees}) {
12210
+ const {color: color} = ui.useTheme_v2(), displayById = useDisplayById(userIdsOf(assignees)), ring = `0 0 0 ${HOLDER_RING}px ${color.bg}`;
12211
+ /* @__PURE__ */
12212
+ return jsxRuntime.jsx(ui.Flex, {
12213
+ align: "center",
12214
+ style: {
12215
+ flexShrink: 0,
12216
+ isolation: "isolate"
12217
+ },
12218
+ children: assignees.map((assignee, index) => /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
12219
+ style: {
12220
+ borderRadius: "50%",
12221
+ boxShadow: ring,
12222
+ flexShrink: 0,
12223
+ marginLeft: index === 0 ? 0 : -HOLDER_OVERLAP,
12224
+ position: "relative",
12225
+ zIndex: index
12226
+ },
12227
+ children: /* @__PURE__ */ jsxRuntime.jsx(HolderFace, {
12228
+ assignee: assignee,
12229
+ displayById: displayById
12230
+ })
12231
+ }, holderKey(assignee, index)))
12232
+ });
12233
+ }
12234
+
12235
+ function PersonToken({routed: routed = !1}) {
12236
+ const size = useAvatarSize(), {color: color} = ui.useTheme_v2();
12237
+ /* @__PURE__ */
12238
+ return jsxRuntime.jsxs(ui.Box, {
12239
+ "aria-label": routed ? "Routed, no person assigned" : "Unassigned",
12240
+ role: "img",
12241
+ style: {
12242
+ flexShrink: 0,
12243
+ height: size,
12244
+ position: "relative",
12245
+ width: size
12246
+ },
12247
+ children: [
12248
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
12249
+ align: "center",
12250
+ justify: "center",
12251
+ style: {
12252
+ border: `1px dashed ${color.border}`,
12253
+ borderRadius: "50%",
12254
+ boxSizing: "border-box",
12255
+ height: size,
12256
+ width: size
12257
+ },
12258
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12259
+ size: 0,
12260
+ children: /* @__PURE__ */ jsxRuntime.jsx(User.UserIcon, {
12261
+ style: {
12262
+ color: color.input.default.enabled.placeholder
12263
+ }
12264
+ })
12265
+ })
12266
+ }), routed ? /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
12267
+ radius: 1,
12268
+ tone: "primary",
12269
+ style: {
12270
+ bottom: -3,
12271
+ position: "absolute",
12272
+ right: -3
12273
+ },
12274
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
12275
+ align: "center",
12276
+ justify: "center",
12277
+ style: {
12278
+ height: 13,
12279
+ width: 13
12280
+ },
12281
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12282
+ size: 0,
12283
+ children: /* @__PURE__ */ jsxRuntime.jsx(Users.UsersIcon, {})
12284
+ })
12285
+ })
12286
+ }) : null ]
12287
+ });
12288
+ }
12289
+
12290
+ function StageTasksCard({now: now, tasks: tasks}) {
12291
+ const displayById = useDisplayById(tasks.flatMap(task => userIdsOf(task.assignees)));
12292
+ /* @__PURE__ */
12293
+ return jsxRuntime.jsxs(ui.Stack, {
12294
+ gap: 4,
12295
+ padding: 3,
12296
+ children: [
12297
+ /* @__PURE__ */ jsxRuntime.jsx(OverlineHeading, {
12298
+ children: "Tasks in this stage"
12299
+ }),
12300
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
12301
+ gap: 4,
12302
+ children: tasks.map(task => /* @__PURE__ */ jsxRuntime.jsx(TaskCardRow, {
12303
+ displayById: displayById,
12304
+ now: now,
12305
+ task: task
12306
+ }, task.name))
12307
+ }) ]
12308
+ });
12309
+ }
12310
+
12311
+ function TaskCardRow({displayById: displayById, now: now, task: task}) {
12312
+ const mark = taskAssignmentMarkOf(task.assignees);
12313
+ /* @__PURE__ */
12314
+ return jsxRuntime.jsxs(ui.Stack, {
12315
+ gap: 3,
12316
+ children: [
12317
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
12318
+ gap: 2,
12319
+ children: [
12320
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
12321
+ align: "center",
12322
+ gap: 3,
12323
+ children: [
12324
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12325
+ size: 1,
12326
+ children: task.title
12327
+ }), task.overdueSince === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(LateSpan, {
12328
+ now: now,
12329
+ since: task.overdueSince
12330
+ }) ]
12331
+ }), task.due === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12332
+ muted: !0,
12333
+ size: 1,
12334
+ children: dueMomentSentence(task.due, now)
12335
+ }) ]
12336
+ }),
12337
+ /* @__PURE__ */ jsxRuntime.jsx(AssignmentLine, {
12338
+ displayById: displayById,
12339
+ mark: mark,
12340
+ now: now,
12341
+ openedAt: task.openedAt,
12342
+ roleAliases: task.roleAliases
12343
+ }) ]
12344
+ });
12345
+ }
12346
+
12347
+ function AssignmentLine({displayById: displayById, mark: mark, now: now, openedAt: openedAt, roleAliases: roleAliases}) {
12348
+ return mark.kind === "unassigned" ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
12349
+ align: "center",
12350
+ gap: 2,
12351
+ children: [
12352
+ /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {}),
12353
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12354
+ muted: !0,
12355
+ size: 1,
12356
+ children: "Unassigned"
12357
+ }) ]
12358
+ }) : mark.kind === "routed" ? /* @__PURE__ */ jsxRuntime.jsx(RoutedAssignmentLine, {
12359
+ mark: mark,
12360
+ now: now,
12361
+ openedAt: openedAt,
12362
+ roleAliases: roleAliases
12363
+ }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
12364
+ gap: 2,
12365
+ children: mark.members.map((assignee, index) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
12366
+ align: "center",
12367
+ gap: 2,
12368
+ children: [
12369
+ /* @__PURE__ */ jsxRuntime.jsx(HolderFace, {
12370
+ assignee: assignee,
12371
+ displayById: displayById
12372
+ }),
12373
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12374
+ size: 1,
12375
+ children: displayById.get(assignee.id)?.label ?? assignee.id
12376
+ }) ]
12377
+ }, holderKey(assignee, index)))
12378
+ });
12379
+ }
12380
+
12381
+ function RoutedAssignmentLine({mark: mark, now: now, openedAt: openedAt, roleAliases: roleAliases}) {
12382
+ const vocabulary = useProjectMembers(), count = workflowComponents.roleMemberCount({
12383
+ members: vocabulary.members,
12384
+ requiredRoles: mark.roles,
12385
+ roleAliases: roleAliases
12386
+ }), names = mark.roles.map(role => workflowComponents.roleLabel(workflowComponents.memberRoleFor(vocabulary, role)));
12387
+ /* @__PURE__ */
12388
+ return jsxRuntime.jsxs(ui.Flex, {
12389
+ align: "center",
12390
+ gap: 2,
12391
+ children: [
12392
+ /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {
12393
+ routed: !0
12394
+ }),
12395
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
12396
+ gap: 1,
12397
+ children: [
12398
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12399
+ size: 1,
12400
+ children: names.join(", ")
12401
+ }),
12402
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, {
12403
+ muted: !0,
12404
+ size: 1,
12405
+ children: [ workflowComponents.memberCountLabel(count), " · Open ", workflowComponents._formatShortAgo(openedAt, now) ]
12406
+ }) ]
12407
+ }) ]
12408
+ });
12409
+ }
12410
+
12411
+ function useTableWidth(element) {
12412
+ const [width, setWidth] = react.useState(void 0);
12413
+ return react.useLayoutEffect(() => {
12414
+ if (element === null) {
12415
+ setWidth(void 0);
12416
+ return;
12417
+ }
12418
+ const measure = () => setWidth(element.getBoundingClientRect().width || void 0);
12419
+ measure();
12420
+ const observer2 = new ResizeObserver(measure);
12421
+ return observer2.observe(element), () => observer2.disconnect();
12422
+ }, [ element ]), width;
12423
+ }
12424
+
12425
+ function useTableStyles() {
12426
+ const {color: color} = ui.useTheme_v2(), headTop = useSpaceToken(3), cellX = useSpaceToken(2);
12427
+ return react.useMemo(() => ({
12428
+ cell: {
12429
+ borderBottom: `1px solid ${color.border}`,
12430
+ boxSizing: "border-box",
12431
+ padding: `0 ${cellX}px`,
12432
+ verticalAlign: "middle",
12433
+ whiteSpace: "nowrap"
12434
+ },
12435
+ head: {
12436
+ background: color.bg,
12437
+ borderBottom: `1px solid ${color.border}`,
12438
+ boxSizing: "border-box",
12439
+ padding: `${headTop}px 0 6px`,
12440
+ position: "sticky",
12441
+ textAlign: "left",
12442
+ top: 0,
12443
+ zIndex: 1
12444
+ }
12445
+ }), [ cellX, color, headTop ]);
12446
+ }
12447
+
12448
+ function scrollParentOf(el) {
12449
+ for (let node = el.parentElement; node !== null; node = node.parentElement) {
12450
+ const overflowY = getComputedStyle(node).overflowY;
12451
+ if (overflowY === "auto" || overflowY === "scroll") return node;
12452
+ }
12453
+ }
12454
+
12455
+ function useRowWindow(args) {
12456
+ const {element: element, keyAt: keyAt, rowCount: rowCount} = args, [scroller, setScroller] = react.useState(null);
12457
+ react.useLayoutEffect(() => {
12458
+ setScroller(element === null ? null : scrollParentOf(element) ?? null);
12459
+ }, [ element ]);
12460
+ const [margin, setMargin] = react.useState(0);
12461
+ react.useLayoutEffect(() => {
12462
+ element === null || scroller === null || setMargin(element.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop);
12463
+ }, [ element, rowCount, scroller ]);
12464
+ const virtualizer = reactVirtual.useVirtualizer({
12465
+ count: rowCount,
12466
+ estimateSize: () => 44,
12467
+ getItemKey: keyAt,
12468
+ getScrollElement: () => scroller,
12469
+ overscan: 10,
12470
+ scrollMargin: margin
12471
+ }), items = virtualizer.getVirtualItems(), first = items[0], last = items[items.length - 1];
12472
+ return {
12473
+ items: items,
12474
+ measureRow: virtualizer.measureElement,
12475
+ padBottom: last === void 0 ? 0 : virtualizer.getTotalSize() - (last.end - margin),
12476
+ padTop: first === void 0 ? 0 : first.start - margin
12477
+ };
12478
+ }
12479
+
12480
+ function SpacerRow({height: height}) {
12481
+ return height <= 0 ? null : /* @__PURE__ */ jsxRuntime.jsx("tr", {
12482
+ "aria-hidden": !0,
12483
+ style: {
12484
+ height: height
12485
+ },
12486
+ children: /* @__PURE__ */ jsxRuntime.jsx("td", {
12487
+ colSpan: 99,
12488
+ style: {
12489
+ border: 0,
12490
+ padding: 0
12491
+ }
12492
+ })
12493
+ });
12494
+ }
12495
+
12496
+ const TABLE_TIME_WIDTH = 112, TABLE_WORKFLOW_WIDTH = {
12497
+ cap: 260,
12498
+ fraction: .18
12499
+ }, TABLE_STAGE_WIDTH = {
12500
+ cap: 260,
12501
+ fraction: .16
12502
+ };
12503
+
12504
+ function SortableHeaderCells({children: children, columns: columns, onSort: onSort, sort: sort, styles: styles, tableWidth: tableWidth, widthOf: widthOf}) {
12505
+ /* @__PURE__ */
12506
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
12507
+ children: [ columns.map(column => {
12508
+ const width = widthOf(column, tableWidth);
12509
+ /* @__PURE__ */
12510
+ return jsxRuntime.jsx("th", {
12511
+ style: {
12512
+ ...styles.head,
12513
+ ...width === void 0 ? {} : {
12514
+ width: width
12515
+ }
12516
+ },
12517
+ children: /* @__PURE__ */ jsxRuntime.jsx(SortHeaderButton, {
12518
+ active: sort.key === column.key,
12519
+ dir: sort.dir,
12520
+ label: column.label,
12521
+ onSort: () => onSort(column.key)
12522
+ })
12523
+ }, column.key);
12524
+ }), children ]
12525
+ });
12526
+ }
12527
+
12528
+ function VirtualTable({keyAt: keyAt, renderHeader: renderHeader, renderRow: renderRow, rowCount: rowCount}) {
12529
+ const styles = useTableStyles(), [element, setElement] = react.useState(null), tableWidth = useTableWidth(element), window = useRowWindow({
12530
+ element: element,
12531
+ keyAt: keyAt,
12532
+ rowCount: rowCount
12533
+ });
12534
+ /* @__PURE__ */
12535
+ return jsxRuntime.jsx("div", {
12536
+ ref: setElement,
12537
+ style: {
12538
+ overflowX: "clip",
12539
+ ...tableWidth === void 0 ? {
12540
+ visibility: "hidden"
12541
+ } : {}
12542
+ },
12543
+ children: /* @__PURE__ */ jsxRuntime.jsxs("table", {
12544
+ style: {
12545
+ borderCollapse: "separate",
12546
+ borderSpacing: 0,
12547
+ tableLayout: "fixed",
12548
+ width: "100%"
12549
+ },
12550
+ children: [
12551
+ /* @__PURE__ */ jsxRuntime.jsx("thead", {
12552
+ children: /* @__PURE__ */ jsxRuntime.jsx("tr", {
12553
+ children: renderHeader({
12554
+ styles: styles,
12555
+ tableWidth: tableWidth
12556
+ })
12557
+ })
12558
+ }),
12559
+ /* @__PURE__ */ jsxRuntime.jsxs("tbody", {
12560
+ children: [
12561
+ /* @__PURE__ */ jsxRuntime.jsx(SpacerRow, {
12562
+ height: window.padTop
12563
+ }), window.items.map(item => renderRow({
12564
+ index: item.index,
12565
+ key: item.key,
12566
+ measureRow: window.measureRow,
12567
+ tableWidth: tableWidth
12568
+ })),
12569
+ /* @__PURE__ */ jsxRuntime.jsx(SpacerRow, {
12570
+ height: window.padBottom
12571
+ }) ]
12572
+ }) ]
12573
+ })
12574
+ });
12575
+ }
12576
+
12577
+ function SortHeaderButton({active: active, dir: dir, label: label, onSort: onSort}) {
12578
+ /* @__PURE__ */
12579
+ return jsxRuntime.jsx(ui.Button, {
12580
+ fontSize: 1,
12581
+ mode: "bleed",
12582
+ onClick: onSort,
12583
+ padding: 2,
12584
+ text: `${label}${active ? dir === "asc" ? " ↑" : " ↓" : ""}`
12585
+ });
12586
+ }
12587
+
12588
+ function TableRowCard({children: children, dataIndex: dataIndex, onClick: onClick, onKeyDown: onKeyDown, rowRef: rowRef, selected: selected, selectedRef: selectedRef}) {
12589
+ const setRow = react.useCallback(element => {
12590
+ rowRef?.(element), selected === !0 && selectedRef?.(element);
12591
+ }, [ rowRef, selected, selectedRef ]);
12592
+ /* @__PURE__ */
12593
+ return jsxRuntime.jsx(ui.Card, {
12594
+ as: "tr",
12595
+ "data-as": "a",
12596
+ onClick: event => {
12597
+ event.currentTarget.focus(), onClick();
12598
+ },
12599
+ onKeyDown: selected === !0 ? onKeyDown : void 0,
12600
+ style: {
12601
+ cursor: "pointer",
12602
+ display: "table-row"
12603
+ },
12604
+ ...dataIndex === void 0 ? {} : {
12605
+ "data-index": dataIndex
12606
+ },
12607
+ ...rowRef === void 0 && selectedRef === void 0 ? {} : {
12608
+ ref: setRow
12609
+ },
12610
+ ...selected === void 0 ? {} : {
12611
+ "aria-selected": selected,
12612
+ pressed: selected,
12613
+ tabIndex: selected ? 0 : -1
12614
+ },
12615
+ children: children
12616
+ });
12617
+ }
12618
+
12619
+ function resolveColumnWidth(width, tableWidth) {
12620
+ return typeof width != "object" ? width : tableWidth === void 0 ? `${width.fraction * 100}%` : Math.min(width.cap, Math.round(tableWidth * width.fraction));
12621
+ }
12622
+
12623
+ function fillColumnWidth(args) {
12624
+ const {columns: columns, tableWidth: tableWidth, trailingWidth: trailingWidth} = args;
12625
+ if (tableWidth === void 0) return;
12626
+ const fixed = columns.reduce((sum, column) => {
12627
+ const width = resolveColumnWidth(column.width, tableWidth);
12628
+ return typeof width == "number" ? sum + width : sum;
12629
+ }, trailingWidth);
12630
+ return Math.max(160, Math.floor(tableWidth - fixed));
12631
+ }
12632
+
12633
+ function TableSubjectCell({document: document}) {
12634
+ return document === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12635
+ muted: !0,
12636
+ size: 1,
12637
+ textOverflow: "ellipsis",
12638
+ children: "No document"
12639
+ }) : /* @__PURE__ */ jsxRuntime.jsx(DocRefFace, {
12640
+ gdr: document
12641
+ });
12642
+ }
12643
+
12644
+ function overdueAttentionHint(documents) {
12645
+ const task = documents === 1 ? "an overdue task" : "overdue tasks";
12646
+ return `${pluralize__default.default("document", documents, !0)} ${documents === 1 ? "has" : "have"} ${task}`;
12647
+ }
12648
+
12649
+ function blockedAttentionHint(documents) {
12650
+ return `${pluralize__default.default("document", documents, !0)} ${documents === 1 ? "is" : "are"} blocked`;
12651
+ }
12652
+
12653
+ function overdueMark(detail, now) {
12654
+ const spans = overdueSpans(detail.dues, now), longest = spans.length === detail.dues.length ? spans[0]?.span : void 0;
12655
+ return {
12656
+ hint: overdueHint({
12657
+ detail: detail,
12658
+ longest: longest
12659
+ }),
12660
+ value: sharedSpan(spans, detail.dues.length) ?? "overdue"
12661
+ };
12662
+ }
12663
+
12664
+ function overdueHint(args) {
12665
+ const {detail: detail, longest: longest} = args;
12666
+ if (detail.dues.length === 1 && detail.task !== void 0) return `“${detail.task}” — ${longest === void 0 ? "overdue" : `${longest} overdue`}`;
12667
+ const tasks = pluralize__default.default("task", detail.dues.length, !0);
12668
+ return longest === void 0 ? `${tasks} overdue` : `${tasks} overdue — the longest by ${longest}`;
12669
+ }
12670
+
12671
+ function sharedSpan(spans, late) {
12672
+ if (spans.length === late) return new Set(spans.map(entry => entry.span)).size === 1 ? spans[0]?.span : void 0;
12673
+ }
12674
+
12675
+ function overdueSpans(dues, now) {
12676
+ return dues.flatMap(due => {
12677
+ const from = parseStoredDateValue(due);
12678
+ return from === void 0 ? [] : [ {
12679
+ elapsed: now.getTime() - from.getTime(),
12680
+ span: workflowComponents._shortSpanOf(from, now)
12681
+ } ];
12682
+ }).sort((a, b) => b.elapsed - a.elapsed);
12683
+ }
12684
+
12685
+ function overdueMarkOpensPanel(tasks) {
12686
+ return tasks.some(task => task.overdueSince !== void 0);
12687
+ }
12688
+
12689
+ function blockedMarkHint(detail) {
12690
+ return detail.kind === "blocked-many" ? `${pluralize__default.default("task", detail.count, !0)} were sent back` : detail.kind === "blocked-effect" ? `Automation “${detail.effect}” ${detail.failed ? "failed" : "didn’t finish"}` : detail.task === void 0 ? "A task was sent back" : `“${detail.task}” was sent back`;
12691
+ }
12692
+
12693
+ const ATTENTION_FACES = {
12694
+ blocked: {
12695
+ Icon: ErrorOutline.ErrorOutlineIcon,
12696
+ tone: "critical"
12697
+ },
12698
+ overdue: LATE_FACE
12699
+ };
12700
+
12701
+ function AttentionMark({detail: detail, now: now, tasks: tasks}) {
12702
+ if (detail.kind === "overdue") {
12703
+ const {hint: hint2, value: value} = overdueMark(detail, now);
12704
+ /* @__PURE__ */
12705
+ return jsxRuntime.jsx(MetricPair, {
12706
+ Icon: ATTENTION_FACES.overdue.Icon,
12707
+ face: overdueMarkOpensPanel(tasks) ? stageTasksFace({
12708
+ now: now,
12709
+ tasks: tasks
12710
+ }) : {
12711
+ text: hint2
12712
+ },
12713
+ label: hint2,
12714
+ tone: ATTENTION_FACES.overdue.tone,
12715
+ value: value
12716
+ });
12717
+ }
12718
+ const hint = blockedMarkHint(detail);
12719
+ /* @__PURE__ */
12720
+ return jsxRuntime.jsx(AlertChip, {
12721
+ Icon: ATTENTION_FACES.blocked.Icon,
12722
+ hint: hint,
12723
+ label: hint,
12724
+ tone: ATTENTION_FACES.blocked.tone
12725
+ });
12726
+ }
12727
+
12728
+ function documentRefsOf(instance) {
12729
+ const seen = /* @__PURE__ */ new Map;
12730
+ for (const ref of workflowEngine.entryDocRefs(instance.fields)) seen.has(ref.id) || seen.set(ref.id, ref);
12731
+ return [ ...seen.values() ];
12732
+ }
12733
+
12734
+ function rootInstanceOf(instance, byId) {
12735
+ const rootRef = instance.ancestors[0];
12736
+ return rootRef ? byId.get(workflowEngine.toBareId(rootRef.id)) ?? instance : instance;
12737
+ }
12738
+
12739
+ function runsScopeOf(row) {
12740
+ return row.endedAt === void 0 ? "open" : "closed";
12741
+ }
12742
+
12743
+ function rowHasTaskHeldBy(row, who) {
12744
+ return row.tasks.some(task => workflowComponents.assignmentMatch(task.assignees, who) !== void 0);
12745
+ }
12746
+
12747
+ function runCountsByWorkflow(rows) {
12748
+ return countBy(rows, row => [ row.workflowName ]);
12749
+ }
12750
+
12751
+ function runCountsByAssignee(rows) {
12752
+ return countBy(rows, row => new Set(userIdsOf(row.assignees)));
12753
+ }
12754
+
12755
+ function runCountsByRole(rows) {
12756
+ return countBy(rows, row => new Set(row.assignees.flatMap(assignee => assignee.type === "role" ? [ assignee.role ] : [])));
12757
+ }
12758
+
12759
+ function runAttentionCounts(rows) {
12760
+ let blocked = 0, overdue = 0;
12761
+ for (const row of rows) row.attention === "blocked" && (blocked += 1), row.attention === "overdue" && (overdue += 1);
12762
+ return {
12763
+ blocked: blocked,
12764
+ overdue: overdue
12765
+ };
12766
+ }
12767
+
12768
+ function unassignedRunCount(rows) {
12769
+ return rows.filter(row => row.assignmentStateCounts.unrouted > 0).length;
12770
+ }
12771
+
12772
+ function runCountsByStage(rows) {
12773
+ return countBy(rows, row => [ row.stage ]);
12774
+ }
12775
+
12776
+ function runCountsByRelease(rows) {
12777
+ return countBy(rows, row => new Set(row.releases));
12778
+ }
12779
+
12780
+ function noReleaseRunCount(rows) {
12781
+ return rows.filter(row => row.releases.length === 0).length;
12782
+ }
12783
+
12784
+ function releasesOfPerspective(perspective) {
12785
+ return Array.isArray(perspective) ? perspective.filter(name => name !== "drafts") : [];
12786
+ }
12787
+
12788
+ function runRowsOf(args) {
12789
+ const byId = new Map(args.previews.map(preview => [ preview._id, preview ]));
12790
+ return args.previews.map(preview => runRowOf({
12791
+ byId: byId,
12792
+ definitions: args.definitions,
12793
+ now: args.now,
12794
+ preview: preview
12795
+ }));
12796
+ }
12797
+
12798
+ function runRowOf(args) {
12799
+ const {byId: byId, definitions: definitions, now: now, preview: preview} = args, definition = definitions.get(preview.definition), settled = workflowEngine.terminalState(preview) !== "in-flight", held = settled ? NO_ASSIGNEES : openAssignees(preview), attentionDetail = settled ? void 0 : blockedRunDetail({
12800
+ definition: definition,
12801
+ preview: preview
12802
+ }) ?? overdueRunDetail({
12803
+ definition: definition,
12804
+ now: now,
12805
+ preview: preview
12806
+ });
12807
+ return {
12808
+ id: preview._id,
12809
+ document: documentRefsOf(rootInstanceOf(preview, byId))[0],
12810
+ workflowName: preview.definition,
12811
+ workflowTitle: definition?.title ?? preview.definition,
12812
+ stage: preview.currentStage,
12813
+ stageTitle: stageTitle(definition, preview.currentStage),
12814
+ releases: releasesOfPerspective(preview.perspective),
12815
+ startedAt: preview.startedAt,
12816
+ endedAt: settled ? preview.completedAt ?? preview.abortedAt : void 0,
12817
+ outcome: outcomeOf(preview, definition),
12818
+ attention: attentionKindOf(attentionDetail),
12819
+ attentionDetail: attentionDetail,
12820
+ assignees: held.assignees,
12821
+ assignments: held.assignments,
12822
+ assignmentStateCounts: held.counts,
12823
+ tasks: settled ? [] : stageTasksOf({
12824
+ definition: definition,
12825
+ instance: preview,
12826
+ now: now
12827
+ })
12828
+ };
12829
+ }
12830
+
12831
+ function attentionKindOf(detail) {
12832
+ if (detail !== void 0) return detail.kind === "overdue" ? "overdue" : "blocked";
12833
+ }
12834
+
12835
+ function blockedArmOf(detail) {
12836
+ if (!(detail === void 0 || detail.kind === "overdue")) return detail;
12837
+ }
12838
+
12839
+ function overdueArmOf(detail) {
12840
+ return detail?.kind === "overdue" ? detail : void 0;
12841
+ }
12842
+
12843
+ function outcomeOf(preview, definition) {
12844
+ const state = workflowEngine.terminalState(preview);
12845
+ if (state !== "in-flight") return state === "aborted" ? "Aborted" : stageTitle(definition, preview.currentStage);
12846
+ }
12847
+
12848
+ function blockedRunDetail(args) {
12849
+ const {definition: definition, preview: preview} = args, {stage: stage, titleOf: titleOf2} = activityTitleResolver(preview, definition), failed = (stage?.activities ?? []).filter(activity => activity.status === "failed");
12850
+ if (failed.length > 1) return {
12851
+ count: failed.length,
12852
+ kind: "blocked-many"
12853
+ };
12854
+ const only = failed[0];
12855
+ if (only !== void 0) return {
12856
+ kind: "blocked",
12857
+ task: titleOf2(only.name)
12858
+ };
12859
+ const stuck = stuckEffectOf({
12860
+ definition: definition,
12861
+ preview: preview,
12862
+ stage: stage
12863
+ });
12864
+ return stuck === void 0 ? void 0 : {
12865
+ effect: stuck.effect.title ?? stuck.effect.name,
12866
+ failed: stuck.failed,
12867
+ kind: "blocked-effect"
12868
+ };
12869
+ }
12870
+
12871
+ function stuckEffectOf(args) {
12872
+ const reported = failedDeclaredEffect(args);
12873
+ if (reported !== void 0) return {
12874
+ effect: reported,
12875
+ failed: !0
12876
+ };
12877
+ const claimed = args.preview.claimedEffects[0];
12878
+ return claimed === void 0 ? void 0 : {
12879
+ effect: claimed,
12880
+ failed: !1
12881
+ };
12882
+ }
12883
+
12884
+ function failedDeclaredEffect(args) {
12885
+ const {definition: definition, preview: preview, stage: stage} = args;
12886
+ if (definition === void 0 || definition.version !== preview.pinnedVersion || stage === void 0) return;
12887
+ const stageNode = workflowEngine.findStageNode({
12888
+ definition: definition,
12889
+ stageName: stage.name
12890
+ }), unresolved = new Set(stage.activities.filter(activity => activity.status !== "done" && activity.status !== "skipped").map(activity => activity.name)), declared = new Set((stageNode?.activities ?? []).filter(activity => unresolved.has(activity.name)).flatMap(activity => (activity.actions ?? []).flatMap(action => (action.effects ?? []).map(e => e.name))));
12891
+ return [ ...preview.failedEffects ].reverse().find(effect => declared.has(effect.name));
12892
+ }
12893
+
12894
+ function overdueRunDetail(args) {
12895
+ const {definition: definition, now: now, preview: preview} = args, late = overdueTasks(preview, now);
12896
+ if (late.length === 0) return;
12897
+ const {titleOf: titleOf2} = activityTitleResolver(preview, definition), only = late.length === 1 ? late[0] : void 0;
12898
+ return {
12899
+ dues: late.flatMap(activity => {
12900
+ const due = passedDueOf(activity, now);
12901
+ return due === void 0 ? [] : [ due ];
12902
+ }),
12903
+ kind: "overdue",
12904
+ task: only === void 0 ? void 0 : titleOf2(only.name)
12905
+ };
12906
+ }
12907
+
12908
+ function activityTitleResolver(preview, definition) {
12909
+ const stage = workflowEngine.findOpenStageEntry(preview);
12910
+ return {
12911
+ stage: stage,
12912
+ titleOf: activityName => findActivity({
12913
+ activityName: activityName,
12914
+ definition: definition,
12915
+ stageName: stage?.name ?? ""
12916
+ }).title
12917
+ };
12918
+ }
12919
+
12920
+ const NO_ASSIGNEES = {
12921
+ assignees: [],
12922
+ assignments: [],
12923
+ counts: {
12924
+ unrouted: 0,
12925
+ routed: 0,
12926
+ held: 0
12927
+ }
12928
+ };
12929
+
12930
+ function openAssignees(instance) {
12931
+ const users = /* @__PURE__ */ new Map, roles = /* @__PURE__ */ new Map, assignments = workflowEngine.openActivityAssignments(instance), counts = {
12932
+ unrouted: 0,
12933
+ routed: 0,
12934
+ held: 0
12935
+ };
12936
+ for (const members of assignments) counts[workflowEngine.assignmentState(members)] += 1,
12937
+ recordAssignees(workflowEngine.activeAssignmentMembers(members), {
12938
+ users: users,
12939
+ roles: roles
12940
+ });
12941
+ return {
12942
+ assignees: [ ...users.values(), ...roles.values() ],
12943
+ assignments: assignments,
12944
+ counts: counts
12945
+ };
12946
+ }
12947
+
12948
+ function recordAssignees(assignees, maps) {
12949
+ for (const assignee of assignees) (assignee.type === "user" ? maps.users : maps.roles).set(assignee.type === "user" ? assignee.id : assignee.role, assignee);
12950
+ }
12951
+
12952
+ function tasksWidthOf(tableWidth) {
12953
+ return tableWidth === void 0 ? 176 : tableWidth >= 1040 ? 224 : 176;
12954
+ }
12955
+
12956
+ function taskRoomOf(args) {
12957
+ const cell = tasksWidthOf(args.tableWidth) - args.inset * 2;
12958
+ return args.overdue ? cell - 76 - args.gap : cell;
12959
+ }
12960
+
12961
+ const OPEN_COLUMNS = [ {
12962
+ key: "document",
12963
+ label: "Workflow subject"
12964
+ }, {
12965
+ key: "workflow",
12966
+ label: "Workflow",
12967
+ width: TABLE_WORKFLOW_WIDTH
12968
+ }, {
12969
+ key: "stage",
12970
+ label: "Stage",
12971
+ width: TABLE_STAGE_WIDTH
12972
+ }, {
12973
+ key: "started",
12974
+ label: "Started",
12975
+ width: TABLE_TIME_WIDTH
12976
+ } ], CLOSED_COLUMNS = [ {
12977
+ key: "document",
12978
+ label: "Workflow subject"
12979
+ }, {
12980
+ key: "workflow",
12981
+ label: "Workflow",
12982
+ width: TABLE_WORKFLOW_WIDTH
12983
+ }, {
12984
+ key: "outcome",
12985
+ label: "Outcome",
12986
+ width: TABLE_STAGE_WIDTH
12987
+ }, {
12988
+ key: "started",
12989
+ label: "Started",
12990
+ width: TABLE_TIME_WIDTH
12991
+ }, {
12992
+ key: "ended",
12993
+ label: "Closed",
12994
+ width: TABLE_TIME_WIDTH
12995
+ } ];
12996
+
12997
+ function runsTableColumnsOf(args) {
12998
+ const columns = args.scope === "closed" ? CLOSED_COLUMNS : OPEN_COLUMNS;
12999
+ return args.scopedToWorkflow ? columns.filter(column => column.key !== "workflow") : columns;
13000
+ }
13001
+
13002
+ function runsDocumentWidthOf(args) {
13003
+ const trailing = args.scope === "open" ? tasksWidthOf(args.tableWidth) : 0;
13004
+ return fillColumnWidth({
13005
+ columns: args.columns,
13006
+ tableWidth: args.tableWidth,
13007
+ trailingWidth: trailing
13008
+ });
13009
+ }
13010
+
13011
+ const TASKS_CELL_GAP_TOKEN = 3;
13012
+
13013
+ function RunsTable({now: now, onNavigateKey: onNavigateKey, onSelectRun: onSelectRun, onSort: onSort, rows: rows, scope: scope, scopedToWorkflow: scopedToWorkflow, selectedId: selectedId, selectedRef: selectedRef, sort: sort}) {
13014
+ const columns = runsTableColumnsOf({
13015
+ scope: scope,
13016
+ scopedToWorkflow: scopedToWorkflow
13017
+ }), cellInset = useSpaceToken(2), markGap = useSpaceToken(TASKS_CELL_GAP_TOKEN);
13018
+ /* @__PURE__ */
13019
+ return jsxRuntime.jsx(VirtualTable, {
13020
+ renderHeader: args => /* @__PURE__ */ jsxRuntime.jsx(RunsHeader, {
13021
+ columns: columns,
13022
+ onSort: onSort,
13023
+ scope: scope,
13024
+ sort: sort,
13025
+ styles: args.styles,
13026
+ tableWidth: args.tableWidth
13027
+ }),
13028
+ keyAt: index => rows[index]?.id ?? String(index),
13029
+ renderRow: ({index: index, key: key, measureRow: measureRow, tableWidth: tableWidth}) => {
13030
+ const row = rows[index];
13031
+ if (row === void 0) return null;
13032
+ const overdue = overdueArmOf(row.attentionDetail);
13033
+ /* @__PURE__ */
13034
+ return jsxRuntime.jsx(RunTableRow, {
13035
+ dataIndex: index,
13036
+ measureRow: measureRow,
13037
+ now: now,
13038
+ onNavigateKey: onNavigateKey,
13039
+ onSelectRun: onSelectRun,
13040
+ row: row,
13041
+ scope: scope,
13042
+ scopedToWorkflow: scopedToWorkflow,
13043
+ selected: row.id === selectedId,
13044
+ selectedRef: selectedRef,
13045
+ overdue: overdue,
13046
+ taskRoom: taskRoomOf({
13047
+ gap: markGap,
13048
+ inset: cellInset,
13049
+ overdue: overdue !== void 0,
13050
+ tableWidth: tableWidth
13051
+ })
13052
+ }, key);
13053
+ },
13054
+ rowCount: rows.length
13055
+ });
13056
+ }
13057
+
13058
+ function RunsHeader({columns: columns, onSort: onSort, scope: scope, sort: sort, styles: styles, tableWidth: tableWidth}) {
13059
+ /* @__PURE__ */
13060
+ return jsxRuntime.jsx(SortableHeaderCells, {
13061
+ columns: columns,
13062
+ onSort: onSort,
13063
+ sort: sort,
13064
+ styles: styles,
13065
+ tableWidth: tableWidth,
13066
+ widthOf: (column, width) => column.key === "document" ? runsDocumentWidthOf({
13067
+ columns: columns,
13068
+ scope: scope,
13069
+ tableWidth: width
13070
+ }) : resolveColumnWidth(column.width, width),
13071
+ children: scope === "open" ? /* @__PURE__ */ jsxRuntime.jsx("th", {
13072
+ style: {
13073
+ ...styles.head,
13074
+ width: tasksWidthOf(tableWidth)
13075
+ },
13076
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
13077
+ padding: 2,
13078
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13079
+ muted: !0,
13080
+ size: 1,
13081
+ children: "Tasks"
13082
+ })
13083
+ })
13084
+ }) : null
13085
+ });
13086
+ }
13087
+
13088
+ const RunTableRow = react.memo(function({dataIndex: dataIndex, measureRow: measureRow, now: now, onNavigateKey: onNavigateKey, onSelectRun: onSelectRun, overdue: overdue, row: row, scope: scope, scopedToWorkflow: scopedToWorkflow, selected: selected, selectedRef: selectedRef, taskRoom: taskRoom}) {
13089
+ const styles = useTableStyles(), documentInset = useSpaceToken(1);
13090
+ /* @__PURE__ */
13091
+ return jsxRuntime.jsxs(TableRowCard, {
13092
+ dataIndex: dataIndex,
13093
+ onClick: () => onSelectRun(row),
13094
+ onKeyDown: onNavigateKey,
13095
+ rowRef: measureRow,
13096
+ selected: selected,
13097
+ selectedRef: selectedRef,
13098
+ children: [
13099
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13100
+ style: {
13101
+ ...styles.cell,
13102
+ paddingLeft: documentInset
13103
+ },
13104
+ children: /* @__PURE__ */ jsxRuntime.jsx(TableSubjectCell, {
13105
+ document: row.document
13106
+ })
13107
+ }), scopedToWorkflow ? null : /* @__PURE__ */ jsxRuntime.jsx("td", {
13108
+ style: styles.cell,
13109
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13110
+ muted: !0,
13111
+ size: 1,
13112
+ textOverflow: "ellipsis",
13113
+ children: row.workflowTitle
13114
+ })
13115
+ }), scope === "closed" ? /* @__PURE__ */ jsxRuntime.jsx(ClosedCells, {
13116
+ now: now,
13117
+ row: row
13118
+ }) : /* @__PURE__ */ jsxRuntime.jsx(OpenCells, {
13119
+ now: now,
13120
+ overdue: overdue,
13121
+ row: row,
13122
+ taskRoom: taskRoom
13123
+ }) ]
13124
+ });
13125
+ });
13126
+
13127
+ function OpenCells({now: now, overdue: overdue, row: row, taskRoom: taskRoom}) {
13128
+ const styles = useTableStyles(), blocked = blockedArmOf(row.attentionDetail);
13129
+ /* @__PURE__ */
13130
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
13131
+ children: [
13132
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13133
+ style: styles.cell,
13134
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
13135
+ align: "center",
13136
+ gap: 2,
13137
+ children: [
13138
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13139
+ size: 1,
13140
+ textOverflow: "ellipsis",
13141
+ children: row.stageTitle
13142
+ }), blocked === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(AttentionMark, {
13143
+ detail: blocked,
13144
+ now: now,
13145
+ tasks: row.tasks
13146
+ }) ]
13147
+ })
13148
+ }),
13149
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13150
+ style: styles.cell,
13151
+ children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.AgoStamp, {
13152
+ at: row.startedAt,
13153
+ now: now
13154
+ })
13155
+ }),
13156
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13157
+ style: {
13158
+ ...styles.cell,
13159
+ overflow: "hidden"
13160
+ },
13161
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
13162
+ align: "center",
13163
+ gap: TASKS_CELL_GAP_TOKEN,
13164
+ children: [
13165
+ /* @__PURE__ */ jsxRuntime.jsx(StageTaskGroups, {
13166
+ now: now,
13167
+ room: taskRoom,
13168
+ tasks: row.tasks
13169
+ }), overdue === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(AttentionMark, {
13170
+ detail: overdue,
13171
+ now: now,
13172
+ tasks: row.tasks
13173
+ }) ]
13174
+ })
13175
+ }) ]
13176
+ });
13177
+ }
13178
+
13179
+ function ClosedCells({now: now, row: row}) {
13180
+ const styles = useTableStyles();
13181
+ /* @__PURE__ */
13182
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
13183
+ children: [
13184
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13185
+ style: styles.cell,
13186
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13187
+ size: 1,
13188
+ textOverflow: "ellipsis",
13189
+ children: row.outcome
13190
+ })
13191
+ }),
13192
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13193
+ style: styles.cell,
13194
+ children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.AgoStamp, {
13195
+ at: row.startedAt,
13196
+ now: now
13197
+ })
13198
+ }),
13199
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13200
+ style: styles.cell,
13201
+ children: row.endedAt === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.AgoStamp, {
13202
+ at: row.endedAt,
13203
+ now: now
13204
+ })
13205
+ }) ]
13206
+ });
13207
+ }
13208
+
13209
+ function DueStamp({due: due, now: now}) {
13210
+ /* @__PURE__ */
13211
+ return jsxRuntime.jsx(ui.Flex, {
13212
+ align: "center",
13213
+ children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
13214
+ text: dueMomentSentence(due, now),
13215
+ children: isDueDatePast(due, now) ? /* @__PURE__ */ jsxRuntime.jsx(LateSpan, {
13216
+ now: now,
13217
+ since: due
13218
+ }) :
13219
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13220
+ muted: !0,
13221
+ size: 1,
13222
+ style: {
13223
+ whiteSpace: "nowrap"
13224
+ },
13225
+ children: formatDate(due)
13226
+ })
13227
+ })
13228
+ });
13229
+ }
13230
+
13231
+ const TASK_WIDTH = {
13232
+ cap: 280,
13233
+ fraction: .22
13234
+ }, FOR_ME_ATTENTION_WIDTH = 48, FOR_ME_ASSIGNEE_WIDTH = 96, FOR_ME_COLUMNS = [ {
13235
+ key: "document",
13236
+ label: "Workflow subject"
13237
+ }, {
13238
+ key: "task",
13239
+ label: "Task",
13240
+ width: TASK_WIDTH
13241
+ }, {
13242
+ key: "opened",
13243
+ label: "Opened",
13244
+ width: TABLE_TIME_WIDTH
13245
+ }, {
13246
+ key: "workflow",
13247
+ label: "Workflow",
13248
+ width: TABLE_WORKFLOW_WIDTH
13249
+ }, {
13250
+ key: "due",
13251
+ label: "Due",
13252
+ width: TABLE_TIME_WIDTH
13253
+ } ];
13254
+
13255
+ function forMeDocumentWidthOf(tableWidth) {
13256
+ return fillColumnWidth({
13257
+ columns: FOR_ME_COLUMNS,
13258
+ tableWidth: tableWidth,
13259
+ trailingWidth: FOR_ME_ASSIGNEE_WIDTH + FOR_ME_ATTENTION_WIDTH
13260
+ });
13261
+ }
13262
+
13263
+ function ForMeTable({now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, onSort: onSort, rows: rows, selectedId: selectedId, selectedRef: selectedRef, sort: sort}) {
13264
+ /* @__PURE__ */
13265
+ return jsxRuntime.jsx(VirtualTable, {
13266
+ renderHeader: args => /* @__PURE__ */ jsxRuntime.jsxs(SortableHeaderCells, {
13267
+ columns: FOR_ME_COLUMNS,
13268
+ onSort: onSort,
13269
+ sort: sort,
13270
+ styles: args.styles,
13271
+ tableWidth: args.tableWidth,
13272
+ widthOf: (column, tableWidth) => column.key === "document" ? forMeDocumentWidthOf(tableWidth) : resolveColumnWidth(column.width, tableWidth),
13273
+ children: [
13274
+ /* @__PURE__ */ jsxRuntime.jsx("th", {
13275
+ style: {
13276
+ ...args.styles.head,
13277
+ width: FOR_ME_ASSIGNEE_WIDTH
13278
+ },
13279
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
13280
+ padding: 2,
13281
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13282
+ muted: !0,
13283
+ size: 1,
13284
+ children: "Assignee"
13285
+ })
13286
+ })
13287
+ }),
13288
+ /* @__PURE__ */ jsxRuntime.jsx("th", {
13289
+ "aria-label": "Attention",
13290
+ style: {
13291
+ ...args.styles.head,
13292
+ width: FOR_ME_ATTENTION_WIDTH
13293
+ }
13294
+ }) ]
13295
+ }),
13296
+ keyAt: index => rows[index]?.id ?? String(index),
13297
+ renderRow: ({index: index, key: key, measureRow: measureRow}) => {
13298
+ const row = rows[index];
13299
+ return row === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ForMeTableRow, {
13300
+ dataIndex: index,
13301
+ measureRow: measureRow,
13302
+ now: now,
13303
+ onNavigateKey: onNavigateKey,
13304
+ onSelect: onSelect,
13305
+ row: row,
13306
+ selected: row.id === selectedId,
13307
+ selectedRef: selectedRef
13308
+ }, key);
13309
+ },
13310
+ rowCount: rows.length
13311
+ });
13312
+ }
13313
+
13314
+ const ForMeTableRow = react.memo(function({dataIndex: dataIndex, measureRow: measureRow, now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, row: row, selected: selected, selectedRef: selectedRef}) {
13315
+ const styles = useTableStyles(), documentInset = useSpaceToken(1);
13316
+ /* @__PURE__ */
13317
+ return jsxRuntime.jsxs(TableRowCard, {
13318
+ dataIndex: dataIndex,
13319
+ onClick: () => onSelect(row),
13320
+ onKeyDown: onNavigateKey,
13321
+ rowRef: measureRow,
13322
+ selected: selected,
13323
+ selectedRef: selectedRef,
13324
+ children: [
13325
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13326
+ style: {
13327
+ ...styles.cell,
13328
+ paddingLeft: documentInset
13329
+ },
13330
+ children: /* @__PURE__ */ jsxRuntime.jsx(TableSubjectCell, {
13331
+ document: row.document
13332
+ })
13333
+ }),
13334
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13335
+ style: styles.cell,
13336
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13337
+ size: 1,
13338
+ textOverflow: "ellipsis",
13339
+ children: row.title
13340
+ })
13341
+ }),
13342
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13343
+ style: styles.cell,
13344
+ children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.AgoStamp, {
13345
+ at: row.openedAt,
13346
+ now: now
13347
+ })
13348
+ }),
13349
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13350
+ style: styles.cell,
13351
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13352
+ muted: !0,
13353
+ size: 1,
13354
+ textOverflow: "ellipsis",
13355
+ children: row.workflowTitle
13356
+ })
13357
+ }),
13358
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13359
+ style: styles.cell,
13360
+ children: row.due === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(DueStamp, {
13361
+ due: row.due,
13362
+ now: now
13363
+ })
13364
+ }),
13365
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13366
+ style: {
13367
+ ...styles.cell,
13368
+ overflow: "hidden"
13369
+ },
13370
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
13371
+ align: "center",
13372
+ children: /* @__PURE__ */ jsxRuntime.jsx(RowAssignees, {
13373
+ assignees: row.assignees
13374
+ })
13375
+ })
13376
+ }),
13377
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13378
+ style: styles.cell,
13379
+ children: /* @__PURE__ */ jsxRuntime.jsx(ForMeAttentionCell, {
13380
+ now: now,
13381
+ row: row
13382
+ })
13383
+ }) ]
13384
+ });
13385
+ });
13386
+
13387
+ function ForMeAttentionCell({now: now, row: row}) {
13388
+ const blocked = blockedArmOf(row.attentionDetail);
13389
+ return blocked === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
13390
+ align: "center",
13391
+ children: /* @__PURE__ */ jsxRuntime.jsx(AttentionMark, {
13392
+ detail: blocked,
13393
+ now: now,
13394
+ tasks: []
13395
+ })
13396
+ });
13397
+ }
13398
+
13399
+ function forMeRowId(instanceId, activityName) {
13400
+ return `${instanceId}\t${activityName}`;
13401
+ }
13402
+
13403
+ function forMeTaskRowsOf(args) {
13404
+ const {rows: rows, who: who} = args;
13405
+ return rows.flatMap(row => row.tasks.flatMap(task => {
13406
+ const assignment = assignmentHolding(task.assignees, who);
13407
+ if (assignment === "other") return [];
13408
+ const attentionDetail = taskAttentionDetail({
13409
+ row: row,
13410
+ task: task
13411
+ });
13412
+ return [ {
13413
+ id: forMeRowId(row.id, task.name),
13414
+ instanceId: row.id,
13415
+ activityName: task.name,
13416
+ title: task.title,
13417
+ document: row.document,
13418
+ workflowTitle: row.workflowTitle,
13419
+ releases: row.releases,
13420
+ openedAt: task.openedAt,
13421
+ due: task.due,
13422
+ attention: attentionKindOf(attentionDetail),
13423
+ attentionDetail: attentionDetail,
13424
+ assignees: task.assignees,
13425
+ assignment: assignment
13426
+ } ];
13427
+ }));
13428
+ }
13429
+
13430
+ function forMeSummaryOf(rows) {
13431
+ const documents = new Set(rows.flatMap(row => row.document === void 0 ? [] : [ row.document.id ])), releases = new Set(rows.flatMap(row => row.releases));
13432
+ return {
13433
+ lead: rows.length === 0 ? "No tasks" : pluralize__default.default("task", rows.length, !0),
13434
+ subjects: `on ${pluralize__default.default("document", documents.size, !0)}, and ${pluralize__default.default("release", releases.size, !0)}`
13435
+ };
13436
+ }
13437
+
13438
+ function forMeSectionsOf(rows) {
13439
+ return {
13440
+ assignedToUser: rows.filter(row => row.assignment === "you"),
13441
+ assignedToRoles: rows.filter(row => row.assignment === "role")
13442
+ };
13443
+ }
13444
+
13445
+ function resolveForMeAddress(args) {
13446
+ const {rows: rows, run: run, task: task} = args;
13447
+ if (run === void 0) return;
13448
+ if (task !== void 0) return rows.some(row => row.instanceId === run && row.activityName === task) ? {
13449
+ run: run,
13450
+ task: task
13451
+ } : void 0;
13452
+ const first = rows.find(row => row.instanceId === run);
13453
+ return first === void 0 ? void 0 : {
13454
+ run: first.instanceId,
13455
+ task: first.activityName
13456
+ };
13457
+ }
13458
+
13459
+ function taskAttentionDetail(args) {
13460
+ const {row: row, task: task} = args;
13461
+ if (task.status === "failed") return {
13462
+ kind: "blocked",
13463
+ task: task.title
13464
+ };
13465
+ if (row.attention === "blocked") return row.attentionDetail;
13466
+ if (task.overdueSince !== void 0) return {
13467
+ dues: [ task.overdueSince ],
13468
+ kind: "overdue",
13469
+ task: task.title
13470
+ };
13471
+ }
13472
+
13473
+ exports.ATTENTION_FACES = ATTENTION_FACES;
13474
+
13475
+ exports.AbortWorkflowDialog = AbortWorkflowDialog;
13476
+
13477
+ exports.ActivityDetailBody = ActivityDetailBody;
13478
+
13479
+ exports.ActivityDetailDialog = ActivityDetailDialog;
13480
+
13481
+ exports.ActivityLog = ActivityLog;
13482
+
13483
+ exports.AlertGlyph = AlertGlyph;
13484
+
13485
+ exports.AttentionMark = AttentionMark;
13486
+
13487
+ exports.Breadcrumb = Breadcrumb;
13488
+
13489
+ exports.CodeChip = CodeChip;
13490
+
13491
+ exports.CountedLabel = CountedLabel;
13492
+
13493
+ exports.DismissablePopover = DismissablePopover;
13494
+
13495
+ exports.DocPreviewLink = DocPreviewLink;
13496
+
13497
+ exports.DocRefFace = DocRefFace;
13498
+
13499
+ exports.EmptyState = EmptyState;
13500
+
13501
+ exports.FOR_ME_SECTION_COPY = FOR_ME_SECTION_COPY;
13502
+
13503
+ exports.ForMeEmptyState = ForMeEmptyState;
13504
+
13505
+ exports.ForMeSectionHeading = ForMeSectionHeading;
13506
+
13507
+ exports.ForMeTable = ForMeTable;
13508
+
13509
+ exports.InstanceFaultNote = InstanceFaultNote;
13510
+
13511
+ exports.InstanceSnapshotBody = InstanceSnapshotBody;
13512
+
13513
+ exports.InvalidDocNotice = InvalidDocNotice;
13514
+
13515
+ exports.LoadingRow = LoadingRow;
13516
+
13517
+ exports.LogEventOnMount = LogEventOnMount;
13518
+
13519
+ exports.MetaRow = MetaRow;
13520
+
13521
+ exports.MetricPair = MetricPair;
13522
+
13523
+ exports.NoteBanner = NoteBanner;
13524
+
13525
+ exports.RUN_SEARCH_PARAM = RUN_SEARCH_PARAM;
13526
+
13527
+ exports.RunsTable = RunsTable;
12112
13528
 
12113
13529
  exports.SectionHeading = SectionHeading;
12114
13530
 
13531
+ exports.SortHeaderButton = SortHeaderButton;
13532
+
12115
13533
  exports.SpinnerSlot = SpinnerSlot;
12116
13534
 
13535
+ exports.StageTaskGroups = StageTaskGroups;
13536
+
12117
13537
  exports.TOOL_TABS = TOOL_TABS;
12118
13538
 
12119
13539
  exports.TabSwitch = TabSwitch;
12120
13540
 
13541
+ exports.TableRowCard = TableRowCard;
13542
+
13543
+ exports.UNREADABLE_DOCUMENT = UNREADABLE_DOCUMENT;
13544
+
12121
13545
  exports.UnreadableDocsNote = UnreadableDocsNote;
12122
13546
 
12123
13547
  exports.WORKFLOW_API_VERSION = WORKFLOW_API_VERSION;
@@ -12132,11 +13556,9 @@ exports.WorkflowTitleSeedDrifted = WorkflowTitleSeedDrifted;
12132
13556
 
12133
13557
  exports.WorkflowToolOpened = WorkflowToolOpened;
12134
13558
 
12135
- exports.activityLabel = activityLabel;
12136
-
12137
- exports.assigneesOf = assigneesOf;
13559
+ exports.blockedAttentionHint = blockedAttentionHint;
12138
13560
 
12139
- exports.assignmentHolding = assignmentHolding;
13561
+ exports.blockedRunDetail = blockedRunDetail;
12140
13562
 
12141
13563
  exports.countBy = countBy;
12142
13564
 
@@ -12148,19 +13570,15 @@ exports.deriveActivityDetail = deriveActivityDetail;
12148
13570
 
12149
13571
  exports.describeError = describeError;
12150
13572
 
12151
- exports.disambiguatedNames = disambiguatedNames;
13573
+ exports.documentRefsOf = documentRefsOf;
12152
13574
 
12153
- exports.dueDatesOf = dueDatesOf;
13575
+ exports.forMeRowId = forMeRowId;
12154
13576
 
12155
- exports.dueMomentSentence = dueMomentSentence;
13577
+ exports.forMeSectionsOf = forMeSectionsOf;
12156
13578
 
12157
- exports.findActivity = findActivity;
13579
+ exports.forMeSummaryOf = forMeSummaryOf;
12158
13580
 
12159
- exports.formatDate = formatDate;
12160
-
12161
- exports.formatShortAgo = formatShortAgo;
12162
-
12163
- exports.formatShortDateTime = formatShortDateTime;
13581
+ exports.forMeTaskRowsOf = forMeTaskRowsOf;
12164
13582
 
12165
13583
  exports.formatTimeAgo = formatTimeAgo;
12166
13584
 
@@ -12172,31 +13590,51 @@ exports.instanceBreadcrumb = instanceBreadcrumb;
12172
13590
 
12173
13591
  exports.instanceTitle = instanceTitle;
12174
13592
 
12175
- exports.isDueDatePast = isDueDatePast;
12176
-
12177
13593
  exports.isEvaluationStale = isEvaluationStale;
12178
13594
 
12179
- exports.isHandsOff = isHandsOff;
12180
-
12181
13595
  exports.isLiveEntry = isLiveEntry;
12182
13596
 
12183
- exports.isOpenActivityStatus = isOpenActivityStatus;
12184
-
12185
13597
  exports.landingState = landingState;
12186
13598
 
12187
13599
  exports.mappingIssueDetail = mappingIssueDetail;
12188
13600
 
12189
13601
  exports.namesNoDeployedDefinition = namesNoDeployedDefinition;
12190
13602
 
13603
+ exports.noReleaseRunCount = noReleaseRunCount;
13604
+
12191
13605
  exports.openActivityGone = openActivityGone;
12192
13606
 
12193
13607
  exports.openableSchemaType = openableSchemaType;
12194
13608
 
12195
- exports.parseStoredDateValue = parseStoredDateValue;
13609
+ exports.overdueAttentionHint = overdueAttentionHint;
13610
+
13611
+ exports.overdueRunDetail = overdueRunDetail;
12196
13612
 
12197
13613
  exports.readDeployedDefinitions = readDeployedDefinitions;
12198
13614
 
12199
- exports.shortSpanOf = shortSpanOf;
13615
+ exports.resolveForMeAddress = resolveForMeAddress;
13616
+
13617
+ exports.rowHasTaskHeldBy = rowHasTaskHeldBy;
13618
+
13619
+ exports.runAttentionCounts = runAttentionCounts;
13620
+
13621
+ exports.runCountsByAssignee = runCountsByAssignee;
13622
+
13623
+ exports.runCountsByRelease = runCountsByRelease;
13624
+
13625
+ exports.runCountsByRole = runCountsByRole;
13626
+
13627
+ exports.runCountsByStage = runCountsByStage;
13628
+
13629
+ exports.runCountsByWorkflow = runCountsByWorkflow;
13630
+
13631
+ exports.runRowsOf = runRowsOf;
13632
+
13633
+ exports.runsScopeOf = runsScopeOf;
13634
+
13635
+ exports.scrollParentOf = scrollParentOf;
13636
+
13637
+ exports.stageTasksOf = stageTasksOf;
12200
13638
 
12201
13639
  exports.stageTitle = stageTitle;
12202
13640
 
@@ -12206,7 +13644,9 @@ exports.toolRoute = toolRoute;
12206
13644
 
12207
13645
  exports.toolTabState = toolTabState;
12208
13646
 
12209
- exports.uniqueIds = uniqueIds;
13647
+ exports.unassignedRunCount = unassignedRunCount;
13648
+
13649
+ exports.useAlertChipSize = useAlertChipSize;
12210
13650
 
12211
13651
  exports.useAssignmentIdentity = useAssignmentIdentity;
12212
13652
 
@@ -12232,6 +13672,8 @@ exports.useReleaseTitles = useReleaseTitles;
12232
13672
 
12233
13673
  exports.useSpaceToken = useSpaceToken;
12234
13674
 
13675
+ exports.useTableStyles = useTableStyles;
13676
+
12235
13677
  exports.useTextIconSize = useTextIconSize;
12236
13678
 
12237
13679
  exports.useUserDisplays = useUserDisplays;