@sanity/workflow-studio-plugin 0.32.0 → 0.34.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"), popover = require("@sanity/ui/popover"), User = require("@sanity/icons/User"), Search = require("@sanity/icons/Search"), autocomplete = require("@sanity/ui/autocomplete"), toast = require("@sanity/ui/toast"), Edit = require("@sanity/icons/Edit"), content = require("@sanity/util/content"), InfoOutline = require("@sanity/icons/InfoOutline"), code = require("@sanity/ui/code"), 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"), menu = require("@sanity/ui/menu"), 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"
@@ -1700,7 +1571,7 @@ function DismissablePopover({children: children, content: content2, onDismiss: o
1700
1571
  const triggerRef = react.useRef(null), [popoverElement, setPopoverElement] = react.useState(null);
1701
1572
  return ui.useClickOutsideEvent(() => {
1702
1573
  open && onDismiss();
1703
- }, () => [ triggerRef.current, popoverElement ]), /* @__PURE__ */ jsxRuntime.jsx(ui.Popover, {
1574
+ }, () => [ triggerRef.current, popoverElement ]), /* @__PURE__ */ jsxRuntime.jsx(popover.Popover, {
1704
1575
  content: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
1705
1576
  onKeyDown: event => {
1706
1577
  event.key === "Escape" && onDismiss();
@@ -1995,7 +1866,7 @@ function DocPicker({value: value, onChange: onChange, types: types2, readOnly: r
1995
1866
  }) : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
1996
1867
  gap: 2,
1997
1868
  children: [
1998
- /* @__PURE__ */ jsxRuntime.jsx(ui.Autocomplete, {
1869
+ /* @__PURE__ */ jsxRuntime.jsx(autocomplete.Autocomplete, {
1999
1870
  filterOption: () => !0,
2000
1871
  fontSize: 1,
2001
1872
  icon: Search.SearchIcon,
@@ -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",
@@ -2208,18 +2079,18 @@ function withConvention(params) {
2208
2079
  }
2209
2080
 
2210
2081
  function useWorkflowToast() {
2211
- const toast = ui.useToast();
2082
+ const toast$1 = toast.useToast();
2212
2083
  return react.useMemo(() => ({
2213
2084
  push: params => {
2214
- toast.push(withConvention(params));
2085
+ toast$1.push(withConvention(params));
2215
2086
  },
2216
2087
  dismiss: id => {
2217
- toast.push({
2088
+ toast$1.push({
2218
2089
  id: id,
2219
2090
  duration: DISMISS_SENTINEL_DURATION
2220
2091
  });
2221
2092
  }
2222
- }), [ toast ]);
2093
+ }), [ toast$1 ]);
2223
2094
  }
2224
2095
 
2225
2096
  const COMMITTED_INCOMPLETE_TITLE = "Saved, but its follow-up didn’t run";
@@ -2244,15 +2115,15 @@ function rejectionToast(reading, titles) {
2244
2115
  }
2245
2116
 
2246
2117
  function useRejectionReport() {
2247
- const toast = useWorkflowToast();
2118
+ const toast2 = useWorkflowToast();
2248
2119
  return react.useMemo(() => ({
2249
2120
  rejected: args => {
2250
2121
  const reading = readRejection(args.err);
2251
2122
  reading.kind !== "refusal" && console.error(`[workflow-studio-plugin] ${args.context} rejected:`, args.err),
2252
- toast.push(rejectionToast(reading, args));
2123
+ toast2.push(rejectionToast(reading, args));
2253
2124
  },
2254
- dismiss: toast.dismiss
2255
- }), [ toast ]);
2125
+ dismiss: toast2.dismiss
2126
+ }), [ toast2 ]);
2256
2127
  }
2257
2128
 
2258
2129
  const ActionClusterContext = react.createContext(void 0), ActionClusterProvider = ActionClusterContext.Provider;
@@ -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,
@@ -3291,7 +3181,7 @@ const fieldValueRenderer = {
3291
3181
  label: field.title ?? field.name,
3292
3182
  value: field.value
3293
3183
  }),
3294
- object: field => field.value === null ? /* @__PURE__ */ jsxRuntime.jsx(Empty, {}) : /* @__PURE__ */ jsxRuntime.jsx(ui.Code, {
3184
+ object: field => field.value === null ? /* @__PURE__ */ jsxRuntime.jsx(Empty, {}) : /* @__PURE__ */ jsxRuntime.jsx(code.Code, {
3295
3185
  size: 1,
3296
3186
  style: {
3297
3187
  overflowWrap: "anywhere",
@@ -3377,7 +3267,7 @@ function ArrayRow({row: row}) {
3377
3267
  /* @__PURE__ */ jsxRuntime.jsx(NoteMeta, {
3378
3268
  row: row
3379
3269
  }) ]
3380
- }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Code, {
3270
+ }) : /* @__PURE__ */ jsxRuntime.jsx(code.Code, {
3381
3271
  size: 1,
3382
3272
  style: {
3383
3273
  overflowWrap: "anywhere",
@@ -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",
@@ -4073,19 +3963,19 @@ function Hairline({weight: weight, style: style}) {
4073
3963
  }
4074
3964
 
4075
3965
  function useDrainEffects(instanceId) {
4076
- const {drainEffectsFor: drainEffectsFor} = useWorkflowContext(), toast = useWorkflowToast(), [busy, setBusy] = react.useState(!1);
3966
+ const {drainEffectsFor: drainEffectsFor} = useWorkflowContext(), toast2 = useWorkflowToast(), [busy, setBusy] = react.useState(!1);
4077
3967
  return {
4078
3968
  busy: busy,
4079
3969
  run: async () => {
4080
3970
  setBusy(!0);
4081
3971
  try {
4082
- await drainEffectsFor(instanceId), toast.push({
3972
+ await drainEffectsFor(instanceId), toast2.push({
4083
3973
  id: TOAST_ID.effectsDrain,
4084
3974
  status: "info",
4085
3975
  title: "Ran the registered handlers"
4086
3976
  });
4087
3977
  } catch (err) {
4088
- toast.push({
3978
+ toast2.push({
4089
3979
  id: TOAST_ID.effectsDrain,
4090
3980
  status: "error",
4091
3981
  title: "Failed to run pending effects",
@@ -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
@@ -5314,8 +5158,8 @@ function AutomationActionRow({actionEval: actionEval, definition: definition}) {
5314
5158
  function inlineActionCount(args) {
5315
5159
  const {available: available, actionWidths: actionWidths, menuWidth: menuWidth, gap: gap} = args, max = Math.min(3, actionWidths.length);
5316
5160
  for (let count = max; count > 0; count--) {
5317
- const buttons = actionWidths.slice(0, count).reduce((sum, w) => sum + w, 0) + gap * (count - 1), menu = count === actionWidths.length ? 0 : menuWidth + gap;
5318
- if (buttons + menu <= available) return count;
5161
+ const buttons = actionWidths.slice(0, count).reduce((sum, w) => sum + w, 0) + gap * (count - 1), menu2 = count === actionWidths.length ? 0 : menuWidth + gap;
5162
+ if (buttons + menu2 <= available) return count;
5319
5163
  }
5320
5164
  return 0;
5321
5165
  }
@@ -5342,12 +5186,12 @@ function ActionMenuItem({actionEval: actionEval, instanceId: instanceId, activit
5342
5186
  placement: placement,
5343
5187
  viaMenu: !0
5344
5188
  });
5345
- return rowKind.kind === "disabled" ? /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
5189
+ return rowKind.kind === "disabled" ? /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
5346
5190
  disabled: !0,
5347
5191
  ...iconProp,
5348
5192
  text: label,
5349
5193
  tone: tone
5350
- }) : rowKind.kind === "plain" ? /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
5194
+ }) : rowKind.kind === "plain" ? /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
5351
5195
  disabled: pending,
5352
5196
  ...iconProp,
5353
5197
  onClick: () => {
@@ -5355,7 +5199,7 @@ function ActionMenuItem({actionEval: actionEval, instanceId: instanceId, activit
5355
5199
  },
5356
5200
  text: label,
5357
5201
  tone: tone
5358
- }) : /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
5202
+ }) : /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
5359
5203
  disabled: pending,
5360
5204
  ...iconProp,
5361
5205
  onClick: onCollectParams,
@@ -5377,7 +5221,7 @@ function rowShield(menuButton) {
5377
5221
  }
5378
5222
 
5379
5223
  function ActionsMenuButton({actions: actions, instanceId: instanceId, activity: activity, label: label, surface: surface, placement: placement, mode: mode = "ghost", inButtonCard: inButtonCard = !1}) {
5380
- const [paramsAction, setParamsAction] = react.useState(void 0), clusterPending = useActionClusterPending(), menuId = react.useId(), menuButton = /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, {
5224
+ const [paramsAction, setParamsAction] = react.useState(void 0), clusterPending = useActionClusterPending(), menuId = react.useId(), menuButton = /* @__PURE__ */ jsxRuntime.jsx(menu.MenuButton, {
5381
5225
  button: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
5382
5226
  ...ACTIONS_MENU_TRIGGER,
5383
5227
  mode: mode,
@@ -5390,7 +5234,7 @@ function ActionsMenuButton({actions: actions, instanceId: instanceId, activity:
5390
5234
  } : {}
5391
5235
  }),
5392
5236
  id: `workflow-actions-menu-${menuId}`,
5393
- menu: /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, {
5237
+ menu: /* @__PURE__ */ jsxRuntime.jsx(menu.Menu, {
5394
5238
  children: actions.map(a => /* @__PURE__ */ jsxRuntime.jsx(ActionMenuItem, {
5395
5239
  actionEval: a,
5396
5240
  activity: activity,
@@ -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
@@ -6992,7 +6840,7 @@ function BooleanPill({entry: entry, pill: pill, editability: editability, surfac
6992
6840
  /* @__PURE__ */
6993
6841
  return jsxRuntime.jsx(PillHint, {
6994
6842
  pill: pill,
6995
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, {
6843
+ children: /* @__PURE__ */ jsxRuntime.jsx(menu.MenuButton, {
6996
6844
  button: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
6997
6845
  ...chrome,
6998
6846
  children: /* @__PURE__ */ jsxRuntime.jsx(PillFaceContent, {
@@ -7002,9 +6850,9 @@ function BooleanPill({entry: entry, pill: pill, editability: editability, surfac
7002
6850
  })
7003
6851
  }),
7004
6852
  id: `boolean-pill-${menuId}`,
7005
- menu: /* @__PURE__ */ jsxRuntime.jsxs(ui.Menu, {
6853
+ menu: /* @__PURE__ */ jsxRuntime.jsxs(menu.Menu, {
7006
6854
  children: [
7007
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
6855
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
7008
6856
  ...current === !0 ? {
7009
6857
  iconRight: Checkmark.CheckmarkIcon
7010
6858
  } : {},
@@ -7013,7 +6861,7 @@ function BooleanPill({entry: entry, pill: pill, editability: editability, surfac
7013
6861
  },
7014
6862
  text: formatBoolean(!0)
7015
6863
  }),
7016
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
6864
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
7017
6865
  ...current === !1 ? {
7018
6866
  iconRight: Checkmark.CheckmarkIcon
7019
6867
  } : {},
@@ -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;
@@ -7419,7 +7256,7 @@ function abortUnconfirmedToast(args) {
7419
7256
  }
7420
7257
 
7421
7258
  function AbortWorkflowDialog({entry: entry, onClose: onClose}) {
7422
- const {engine: engine} = useWorkflowContext(), definition = useDefinition(entry), toast = useWorkflowToast(), telemetry2 = workflowReact.useWorkflowTelemetry(), [typedReason, setTypedReason] = react.useState(""), [pending, setPending] = react.useState(!1), {instance: instance} = entry, title = instanceTitle(instance, definition), reason = normalizeAbortReason(typedReason), reasonInputId = `abort-workflow-reason-${instance._id}`;
7259
+ const {engine: engine} = useWorkflowContext(), definition = useDefinition(entry), toast2 = useWorkflowToast(), telemetry2 = workflowReact.useWorkflowTelemetry(), [typedReason, setTypedReason] = react.useState(""), [pending, setPending] = react.useState(!1), {instance: instance} = entry, title = instanceTitle(instance, definition), reason = normalizeAbortReason(typedReason), reasonInputId = `abort-workflow-reason-${instance._id}`;
7423
7260
  useLogEventOnMount(WorkflowAbortDialogOpened, {
7424
7261
  instanceId: instance._id
7425
7262
  });
@@ -7438,9 +7275,9 @@ function AbortWorkflowDialog({entry: entry, onClose: onClose}) {
7438
7275
  title: title,
7439
7276
  changed: changed
7440
7277
  });
7441
- toast.push(report.toast), log(report.outcome), onClose();
7278
+ toast2.push(report.toast), log(report.outcome), onClose();
7442
7279
  } catch (err) {
7443
- toast.push(abortUnconfirmedToast({
7280
+ toast2.push(abortUnconfirmedToast({
7444
7281
  title: title,
7445
7282
  err: err
7446
7283
  })), log("unconfirmed"), setPending(!1);
@@ -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", {
@@ -7617,7 +7436,7 @@ function CodeChip({value: value}) {
7617
7436
  }
7618
7437
 
7619
7438
  function HintedMenuButton({hint: hint, ...menuButtonProps}) {
7620
- const [open, setOpen] = react.useState(!1), popover = {
7439
+ const [open, setOpen] = react.useState(!1), popover2 = {
7621
7440
  tone: "default",
7622
7441
  ...menuButtonProps.popover?.placement === void 0 ? {
7623
7442
  placement: "bottom-end",
@@ -7625,17 +7444,17 @@ function HintedMenuButton({hint: hint, ...menuButtonProps}) {
7625
7444
  } : {},
7626
7445
  ...menuButtonProps.popover
7627
7446
  };
7628
- return hint === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, {
7447
+ return hint === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(menu.MenuButton, {
7629
7448
  ...menuButtonProps,
7630
- popover: popover
7631
- }) : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
7449
+ popover: popover2
7450
+ }) : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
7632
7451
  disabled: open,
7633
7452
  text: hint,
7634
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, {
7453
+ children: /* @__PURE__ */ jsxRuntime.jsx(menu.MenuButton, {
7635
7454
  ...menuButtonProps,
7636
7455
  onClose: () => setOpen(!1),
7637
7456
  onOpen: () => setOpen(!0),
7638
- popover: popover
7457
+ popover: popover2
7639
7458
  })
7640
7459
  });
7641
7460
  }
@@ -7670,7 +7489,7 @@ function historyWindow(args) {
7670
7489
  }
7671
7490
 
7672
7491
  function PendingEffectRows({instance: instance, now: now}) {
7673
- const {completeEffectFor: completeEffectFor, effectHandlers: effectHandlers} = useWorkflowContext(), toast = useWorkflowToast(), drain = useDrainEffects(instance._id), [resolving, setResolving] = react.useState(!1), pending = instance.pendingEffects ?? [];
7492
+ const {completeEffectFor: completeEffectFor, effectHandlers: effectHandlers} = useWorkflowContext(), toast2 = useWorkflowToast(), drain = useDrainEffects(instance._id), [resolving, setResolving] = react.useState(!1), pending = instance.pendingEffects ?? [];
7674
7493
  if (pending.length === 0) return null;
7675
7494
  const resolve = async (effectKey, status) => {
7676
7495
  setResolving(!0);
@@ -7679,13 +7498,13 @@ function PendingEffectRows({instance: instance, now: now}) {
7679
7498
  effectKey: effectKey,
7680
7499
  status: status,
7681
7500
  detail: "Resolved in Studio"
7682
- }), toast.push({
7501
+ }), toast2.push({
7683
7502
  id: TOAST_ID.effectResolve,
7684
7503
  status: "info",
7685
7504
  title: `Effect marked as ${status}`
7686
7505
  });
7687
7506
  } catch (err) {
7688
- toast.push({
7507
+ toast2.push({
7689
7508
  id: TOAST_ID.effectResolve,
7690
7509
  status: "error",
7691
7510
  title: "Failed to resolve the effect",
@@ -7764,16 +7583,16 @@ function PendingEffectRow({busy: busy, effect: effect, instanceId: instanceId, n
7764
7583
  }),
7765
7584
  hint: "Resolve",
7766
7585
  id: `pending-effect-menu-${instanceId}-${effect._key}`,
7767
- menu: /* @__PURE__ */ jsxRuntime.jsxs(ui.Menu, {
7768
- children: [ registered ? /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
7586
+ menu: /* @__PURE__ */ jsxRuntime.jsxs(menu.Menu, {
7587
+ children: [ registered ? /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
7769
7588
  onClick: onRunHandlers,
7770
7589
  text: "Run registered handlers"
7771
7590
  }) : null,
7772
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
7591
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
7773
7592
  onClick: () => onResolve("done"),
7774
7593
  text: "Mark done"
7775
7594
  }),
7776
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
7595
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
7777
7596
  onClick: () => onResolve("failed"),
7778
7597
  text: "Mark failed",
7779
7598
  tone: "critical"
@@ -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",
@@ -7941,7 +7760,7 @@ function InstanceCardMenu({entry: entry, title: title}) {
7941
7760
  /* @__PURE__ */
7942
7761
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
7943
7762
  children: [
7944
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, {
7763
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuButton, {
7945
7764
  button: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
7946
7765
  "aria-label": `More options for ${title}`,
7947
7766
  fontSize: 1,
@@ -7950,15 +7769,15 @@ function InstanceCardMenu({entry: entry, title: title}) {
7950
7769
  padding: 2
7951
7770
  }),
7952
7771
  id: `workflow-instance-menu-${menuId}`,
7953
- menu: /* @__PURE__ */ jsxRuntime.jsxs(ui.Menu, {
7772
+ menu: /* @__PURE__ */ jsxRuntime.jsxs(menu.Menu, {
7954
7773
  children: [
7955
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
7774
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
7956
7775
  onClick: () => setDialog("history"),
7957
7776
  text: "Workflow history"
7958
7777
  }), isLiveEntry(entry) ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
7959
7778
  children: [
7960
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuDivider, {}),
7961
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
7779
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuDivider, {}),
7780
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
7962
7781
  onClick: () => setDialog("abort"),
7963
7782
  text: "Cancel workflow…",
7964
7783
  tone: "critical"
@@ -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
  }
@@ -8575,17 +8405,17 @@ function NoteBanner({action: action, label: label, tone: tone = "caution"}) {
8575
8405
  }
8576
8406
 
8577
8407
  function CopyDetailsButton({unreadable: unreadable}) {
8578
- const toast = useWorkflowToast();
8408
+ const toast2 = useWorkflowToast();
8579
8409
  /* @__PURE__ */
8580
8410
  return jsxRuntime.jsx(ui.Button, {
8581
8411
  fontSize: 1,
8582
8412
  mode: "ghost",
8583
8413
  onClick: () => {
8584
- navigator.clipboard.writeText(unreadableDocsReport(unreadable)).then(() => toast.push({
8414
+ navigator.clipboard.writeText(unreadableDocsReport(unreadable)).then(() => toast2.push({
8585
8415
  id: TOAST_ID.detailsCopy,
8586
8416
  status: "info",
8587
8417
  title: "Details copied to clipboard"
8588
- }), () => toast.push({
8418
+ }), () => toast2.push({
8589
8419
  id: TOAST_ID.detailsCopy,
8590
8420
  status: "error",
8591
8421
  title: "Failed to copy the details"
@@ -8625,7 +8455,7 @@ function InvalidDocNotice({invalid: invalid}) {
8625
8455
  radius: 2,
8626
8456
  tone: "caution",
8627
8457
  children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
8628
- space: 3,
8458
+ gap: 3,
8629
8459
  children: [
8630
8460
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
8631
8461
  size: 1,
@@ -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, toast2 = 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,8 +9114,8 @@ function useStartWorkflow(args) {
9284
9114
  docId: docId,
9285
9115
  initialValue: initialValue,
9286
9116
  selectedReleaseId: selectedReleaseId,
9287
- ensureDocumentExists: observer.ensureDocumentExists,
9288
- onPersistFailure: err => toast.push({
9117
+ ensureDocumentExists: observer2.ensureDocumentExists,
9118
+ onPersistFailure: err => toast2.push({
9289
9119
  id: TOAST_ID.documentSave,
9290
9120
  status: "error",
9291
9121
  title: "Failed to save the document",
@@ -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;
@@ -9377,7 +9207,7 @@ function StartWorkflowControl({mappings: mappings, docId: docId, initialValue: i
9377
9207
  hint: menuLabel
9378
9208
  } : {},
9379
9209
  id: `start-workflow-menu-${menuId}`,
9380
- menu: /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, {
9210
+ menu: /* @__PURE__ */ jsxRuntime.jsx(menu.Menu, {
9381
9211
  children: startable.map(mapping => /* @__PURE__ */ jsxRuntime.jsx(StartWorkflowMenuItem, {
9382
9212
  docId: docId,
9383
9213
  initialValue: initialValue,
@@ -9399,14 +9229,14 @@ function StartWorkflowMenuItem({mapping: mapping, docId: docId, initialValue: in
9399
9229
  docId: docId,
9400
9230
  initialValue: initialValue,
9401
9231
  source: source
9402
- }), item = /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
9232
+ }), item = /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
9403
9233
  disabled: blocked || starting || !docId,
9404
9234
  onClick: () => {
9405
9235
  start();
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",
@@ -10672,7 +10513,7 @@ function ReleasePicker({value: value, onChange: onChange}) {
10672
10513
  releaseName: value.releaseName
10673
10514
  })
10674
10515
  })
10675
- }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Autocomplete, {
10516
+ }) : /* @__PURE__ */ jsxRuntime.jsx(autocomplete.Autocomplete, {
10676
10517
  filterOption: (query, option) => labelOf(option.value).toLowerCase().includes(query.toLowerCase()),
10677
10518
  fontSize: 1,
10678
10519
  icon: Search.SearchIcon,
@@ -10731,9 +10572,9 @@ 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
- }), schema = sanity.useSchema(), templates = sanity.useTemplates(), resolverContext = sanity.useInitialValueResolverContext(), toast = useWorkflowToast(), [creating, setCreating] = react.useState(!1);
10577
+ }), schema = sanity.useSchema(), templates = sanity.useTemplates(), resolverContext = sanity.useInitialValueResolverContext(), toast2 = useWorkflowToast(), [creating, setCreating] = react.useState(!1);
10737
10578
  return {
10738
10579
  creating: creating,
10739
10580
  createDoc: async type => {
@@ -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 ? {
@@ -10757,7 +10598,7 @@ function useCreateDoc(args) {
10757
10598
  type: type
10758
10599
  }));
10759
10600
  } catch (err) {
10760
- toast.push({
10601
+ toast2.push({
10761
10602
  id: TOAST_ID.documentCreate,
10762
10603
  status: "error",
10763
10604
  title: "Failed to create the document",
@@ -10805,7 +10646,7 @@ function CreateDocMenu({entryName: entryName, options: options, releaseId: relea
10805
10646
  onCreated: onCreated
10806
10647
  });
10807
10648
  return options.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
10808
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, {
10649
+ children: /* @__PURE__ */ jsxRuntime.jsx(menu.MenuButton, {
10809
10650
  button: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
10810
10651
  disabled: creating,
10811
10652
  fontSize: 1,
@@ -10815,8 +10656,8 @@ function CreateDocMenu({entryName: entryName, options: options, releaseId: relea
10815
10656
  text: creating ? "Creating…" : "Create new document…"
10816
10657
  }),
10817
10658
  id: `create-doc-${entryName}`,
10818
- menu: /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, {
10819
- children: options.map(type => /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
10659
+ menu: /* @__PURE__ */ jsxRuntime.jsx(menu.Menu, {
10660
+ children: options.map(type => /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
10820
10661
  onClick: () => {
10821
10662
  createDoc(type);
10822
10663
  },
@@ -11011,7 +10852,6 @@ function SelectedReleaseRow({mapping: mapping, selectedReleaseId: selectedReleas
11011
10852
  children: "Release:"
11012
10853
  }),
11013
10854
  /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, {
11014
- mode: "outline",
11015
10855
  style: badgeTrim,
11016
10856
  tone: "primary",
11017
10857
  children: selectedReleaseId
@@ -11087,13 +10927,13 @@ function ResumeNote({onStartNew: onStartNew}) {
11087
10927
  }
11088
10928
 
11089
10929
  function handleStartError(args) {
11090
- const {label: label, toast: toast, seedInstance: seedInstance, onClose: onClose} = args, outcome = classifyStartError(args.err);
11091
- toast.push(startOutcomeToast(outcome, label)), startProducedRun(outcome) && (outcome.instance !== void 0 && seedInstance(outcome.instance),
10930
+ const {label: label, toast: toast2, seedInstance: seedInstance, onClose: onClose} = args, outcome = classifyStartError(args.err);
10931
+ toast2.push(startOutcomeToast(outcome, label)), startProducedRun(outcome) && (outcome.instance !== void 0 && seedInstance(outcome.instance),
11092
10932
  onClose());
11093
10933
  }
11094
10934
 
11095
10935
  function StartWorkflowForm({request: request, onClose: onClose}) {
11096
- const {definition: definitionName, label: label, mapping: mapping, subjectDocId: subjectDocId} = request, {engine: engine, binding: binding, seedInstance: seedInstance} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry(), toast = useWorkflowToast(), {def: definition, error: definitionError} = useLatestDefinition(definitionName), {selectedReleaseId: selectedReleaseId} = sanity.usePerspective(), releaseId = boundReleaseId(mapping, selectedReleaseId), [values, setValues] = react.useState({}), [attempt, setAttempt] = react.useState(void 0), starting = attempt !== void 0, [heldInstanceId, setHeldInstanceId] = react.useState(void 0), [startNew, setStartNew] = react.useState(!1), {entries: entries} = useWorkflowsForDocument(subjectDocId), resumeEntry = presentedResumeEntry({
10936
+ const {definition: definitionName, label: label, mapping: mapping, subjectDocId: subjectDocId} = request, {engine: engine, binding: binding, seedInstance: seedInstance} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry(), toast2 = useWorkflowToast(), {def: definition, error: definitionError} = useLatestDefinition(definitionName), {selectedReleaseId: selectedReleaseId} = sanity.usePerspective(), releaseId = boundReleaseId(mapping, selectedReleaseId), [values, setValues] = react.useState({}), [attempt, setAttempt] = react.useState(void 0), starting = attempt !== void 0, [heldInstanceId, setHeldInstanceId] = react.useState(void 0), [startNew, setStartNew] = react.useState(!1), {entries: entries} = useWorkflowsForDocument(subjectDocId), resumeEntry = presentedResumeEntry({
11097
10937
  entries: entries,
11098
10938
  definitionName: definitionName,
11099
10939
  heldInstanceId: heldInstanceId,
@@ -11132,7 +10972,7 @@ function StartWorkflowForm({request: request, onClose: onClose}) {
11132
10972
  initFields: initFields,
11133
10973
  values: values
11134
10974
  }));
11135
- toast.push({
10975
+ toast2.push({
11136
10976
  id: TOAST_ID.start,
11137
10977
  status: "info",
11138
10978
  title: `“${definition?.title ?? label}” started`,
@@ -11142,7 +10982,7 @@ function StartWorkflowForm({request: request, onClose: onClose}) {
11142
10982
  handleStartError({
11143
10983
  err: err,
11144
10984
  label: definition?.title ?? label,
11145
- toast: toast,
10985
+ toast: toast2,
11146
10986
  seedInstance: seedInstance,
11147
10987
  onClose: onClose
11148
10988
  });
@@ -11385,7 +11225,7 @@ function AutoStartGate(props) {
11385
11225
  }
11386
11226
 
11387
11227
  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({
11228
+ 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
11229
  engine: engine
11390
11230
  }), {selectedReleaseId: selectedReleaseId} = sanity.usePerspective(), {entries: entries} = useWorkflowsForDocument(rawDocId), docId = csm.getPublishedId(rawDocId), valueRef = react.useRef(value);
11391
11231
  valueRef.current = value;
@@ -11407,7 +11247,7 @@ function AutoStartDriver(props) {
11407
11247
  if (!firedRef.current) {
11408
11248
  firedRef.current = !0, setFired(!0);
11409
11249
  try {
11410
- await observer.ensureDocumentExists({
11250
+ await observer2.ensureDocumentExists({
11411
11251
  documentId: docId,
11412
11252
  type: docType,
11413
11253
  initialValue: valueRef.current,
@@ -11442,7 +11282,7 @@ function AutoStartDriver(props) {
11442
11282
  setSettled(!0);
11443
11283
  }
11444
11284
  }
11445
- }, [ autoStartDefinitions, docId, docType, binding, engine, observer, seedInstance, instanceIdFor, selectedReleaseId, telemetry2 ]), retry = react.useCallback(() => {
11285
+ }, [ autoStartDefinitions, docId, docType, binding, engine, observer2, seedInstance, instanceIdFor, selectedReleaseId, telemetry2 ]), retry = react.useCallback(() => {
11446
11286
  firedRef.current = !1, setFired(!1), setSettled(!1), setFailure(void 0);
11447
11287
  }, []), action = autoStartAction({
11448
11288
  resolved: definitionsResolved && isDocResolved(docId),
@@ -11620,7 +11460,7 @@ function ActivityGlance({activityEval: activityEval}) {
11620
11460
  align: "center",
11621
11461
  gap: 2,
11622
11462
  children: [
11623
- /* @__PURE__ */ jsxRuntime.jsx(ActivityStatusIcon, {
11463
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.ActivityStatusIcon, {
11624
11464
  status: status
11625
11465
  }),
11626
11466
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
@@ -11775,7 +11615,7 @@ function StripLine({aside: aside, children: children, hint: hint, onOpen: onOpen
11775
11615
  return jsxRuntime.jsxs(ui.Flex, {
11776
11616
  align: "center",
11777
11617
  children: [
11778
- /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
11618
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
11779
11619
  ...hint,
11780
11620
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
11781
11621
  as: "button",
@@ -11809,7 +11649,7 @@ function InstanceLine({entry: entry, onOpen: onOpen}) {
11809
11649
  weight: "medium",
11810
11650
  children: instanceTitle(entry.instance, definition)
11811
11651
  })
11812
- }), unprimed ? /* @__PURE__ */ jsxRuntime.jsx(StartIncompleteBadge, {
11652
+ }), unprimed ? /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.StartIncompleteBadge, {
11813
11653
  style: badgeTrim
11814
11654
  }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
11815
11655
  children: [
@@ -12050,74 +11890,1657 @@ function WorkflowRootInput(props) {
12050
11890
  });
12051
11891
  }
12052
11892
 
12053
- exports.AbortWorkflowDialog = AbortWorkflowDialog;
11893
+ function openActivitiesOf(instance) {
11894
+ return (workflowEngine.findOpenStageEntry(instance)?.activities ?? []).filter(activity => isOpenActivityStatus(activity.status));
11895
+ }
12054
11896
 
12055
- exports.ActivityDetailBody = ActivityDetailBody;
11897
+ function overdueTasks(instance, now) {
11898
+ return openActivitiesOf(instance).filter(activity => passedDuesOf(activity, now).length > 0);
11899
+ }
12056
11900
 
12057
- exports.ActivityDetailDialog = ActivityDetailDialog;
11901
+ function earliestDue(activity) {
11902
+ return earliestOf(dueDatesOf(activity.fields ?? []));
11903
+ }
12058
11904
 
12059
- exports.ActivityLog = ActivityLog;
11905
+ function passedDueOf(activity, now) {
11906
+ const passed = passedDuesOf(activity, now);
11907
+ return earliestOf(passed) ?? passed[0];
11908
+ }
12060
11909
 
12061
- exports.AgoStamp = AgoStamp;
11910
+ function passedDuesOf(activity, now) {
11911
+ return dueDatesOf(activity.fields ?? []).filter(due => isDueDatePast(due, now));
11912
+ }
12062
11913
 
12063
- exports.AlertChip = AlertChip;
11914
+ function earliestOf(values) {
11915
+ let earliest;
11916
+ for (const value of values) {
11917
+ const time = parseStoredDateValue(value)?.getTime();
11918
+ time !== void 0 && (earliest === void 0 || time < earliest.time) && (earliest = {
11919
+ time: time,
11920
+ value: value
11921
+ });
11922
+ }
11923
+ return earliest?.value;
11924
+ }
12064
11925
 
12065
- exports.AlertGlyph = AlertGlyph;
11926
+ const AUTONOMY_BY_DEFINITION = /* @__PURE__ */ new WeakMap;
12066
11927
 
12067
- exports.Breadcrumb = Breadcrumb;
11928
+ function cachedAutonomy(definition) {
11929
+ const hit = AUTONOMY_BY_DEFINITION.get(definition);
11930
+ if (hit !== void 0) return hit;
11931
+ const derived = workflowEngine.deriveWorkflowAutonomy(definition);
11932
+ return AUTONOMY_BY_DEFINITION.set(definition, derived), derived;
11933
+ }
12068
11934
 
12069
- exports.CodeChip = CodeChip;
11935
+ function isAutomatedActivity(args) {
11936
+ const stage = args.autonomy?.stages.find(entry => entry.stage === args.stageName);
11937
+ return isHandsOff({
11938
+ classification: workflowEngine.deriveExecutorClassification(args.activity),
11939
+ completesWithoutCaller: stage?.activities[args.activity.name]?.completesWithoutCaller
11940
+ });
11941
+ }
12070
11942
 
12071
- exports.CountedLabel = CountedLabel;
11943
+ function taskOf(args) {
11944
+ const {entry: entry, now: now, openedAt: openedAt, roleAliases: roleAliases, title: title} = args;
11945
+ return {
11946
+ name: entry.name,
11947
+ title: title,
11948
+ assignees: assigneesOf(entry.fields ?? []),
11949
+ roleAliases: roleAliases,
11950
+ openedAt: openedAt,
11951
+ due: earliestDue(entry),
11952
+ overdueSince: passedDueOf(entry, now),
11953
+ status: entry.status
11954
+ };
11955
+ }
12072
11956
 
12073
- exports.DismissablePopover = DismissablePopover;
11957
+ function humanTask(args) {
11958
+ const {activity: activity, autonomy: autonomy, entry: entry, now: now, openedAt: openedAt, roleAliases: roleAliases, stageName: stageName} = args;
11959
+ return entry === void 0 ? [] : isAutomatedActivity({
11960
+ activity: activity,
11961
+ autonomy: autonomy,
11962
+ stageName: stageName
11963
+ }) ? [] : [ taskOf({
11964
+ entry: entry,
11965
+ now: now,
11966
+ openedAt: openedAt,
11967
+ roleAliases: roleAliases,
11968
+ title: activityLabel(activity)
11969
+ }) ];
11970
+ }
12074
11971
 
12075
- exports.DocPreviewLink = DocPreviewLink;
11972
+ function undeclaredTasks(args) {
11973
+ const {definition: definition, now: now, open: open, openedAt: openedAt, roleAliases: roleAliases, seen: seen, stageName: stageName} = args;
11974
+ return open.filter(entry => !seen.has(entry.name)).map(entry => taskOf({
11975
+ entry: entry,
11976
+ now: now,
11977
+ openedAt: openedAt,
11978
+ roleAliases: roleAliases,
11979
+ title: findActivity({
11980
+ activityName: entry.name,
11981
+ definition: definition,
11982
+ stageName: stageName
11983
+ }).title
11984
+ }));
11985
+ }
12076
11986
 
12077
- exports.DocRefFace = DocRefFace;
11987
+ function definitionForPinned(definition, pinnedVersion) {
11988
+ if (!(definition === void 0 || definition.version !== pinnedVersion)) return definition;
11989
+ }
12078
11990
 
12079
- exports.EmptyState = EmptyState;
11991
+ function stageTasksOf(args) {
11992
+ const {definition: definition, instance: instance, now: now} = args, stageEntry = workflowEngine.findOpenStageEntry(instance);
11993
+ if (stageEntry === void 0) return [];
11994
+ const listed = listedStageActivities(stageEntry);
11995
+ if (listed.length === 0) return [];
11996
+ 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({
11997
+ definition: definition,
11998
+ stageName: stageName
11999
+ })?.activities ?? [];
12000
+ return [ ...declared.flatMap(activity => humanTask({
12001
+ activity: activity,
12002
+ autonomy: autonomy,
12003
+ entry: openByName.get(activity.name),
12004
+ now: now,
12005
+ openedAt: openedAt,
12006
+ roleAliases: roleAliases,
12007
+ stageName: stageName
12008
+ })), ...undeclaredTasks({
12009
+ definition: definition,
12010
+ now: now,
12011
+ open: listed,
12012
+ openedAt: openedAt,
12013
+ roleAliases: roleAliases,
12014
+ seen: new Set(declared.map(activity => activity.name)),
12015
+ stageName: stageName
12016
+ }) ];
12017
+ }
12080
12018
 
12081
- exports.FOR_ME_SECTION_COPY = FOR_ME_SECTION_COPY;
12019
+ function listedStageActivities(stage) {
12020
+ return stage.activities.filter(entry => isOpenActivityStatus(entry.status) || entry.status === "failed");
12021
+ }
12082
12022
 
12083
- exports.ForMeEmptyState = ForMeEmptyState;
12023
+ function groupWidthOf(task, metrics) {
12024
+ const mark = taskAssignmentMarkOf(task.assignees), faces = mark.kind === "held" ? mark.members.length : 1;
12025
+ return metrics.face + (faces - 1) * (metrics.face - metrics.overlap);
12026
+ }
12084
12027
 
12085
- exports.ForMeSectionHeading = ForMeSectionHeading;
12028
+ function rowWidthOf(tasks, metrics) {
12029
+ return tasks.reduce((total, task) => total + groupWidthOf(task, metrics), 0) + Math.max(0, tasks.length - 1) * metrics.gap;
12030
+ }
12086
12031
 
12087
- exports.HoverHint = HoverHint;
12032
+ function countWithin(args) {
12033
+ const {budget: budget, metrics: metrics, tasks: tasks} = args;
12034
+ let used = 0, count = 0;
12035
+ for (const task of tasks) {
12036
+ const next = used + (count === 0 ? 0 : metrics.gap) + groupWidthOf(task, metrics);
12037
+ if (next > budget) break;
12038
+ used = next, count += 1;
12039
+ }
12040
+ return Math.max(1, count);
12041
+ }
12088
12042
 
12089
- exports.InstanceFaultNote = InstanceFaultNote;
12043
+ function visibleStageTasks(args) {
12044
+ const {metrics: metrics, room: room, tasks: tasks} = args;
12045
+ if (rowWidthOf(tasks, metrics) <= room) return {
12046
+ overflow: 0,
12047
+ visible: tasks
12048
+ };
12049
+ const shown = countWithin({
12050
+ budget: room - metrics.gap - metrics.counter,
12051
+ metrics: metrics,
12052
+ tasks: tasks
12053
+ });
12054
+ return {
12055
+ overflow: tasks.length - shown,
12056
+ visible: tasks.slice(0, shown)
12057
+ };
12058
+ }
12090
12059
 
12091
- exports.InstanceSnapshotBody = InstanceSnapshotBody;
12060
+ function taskAssignmentMarkOf(assignees) {
12061
+ const members = assignees.filter(assignee => assignee.type === "user");
12062
+ if (members.length > 0) return {
12063
+ kind: "held",
12064
+ members: members
12065
+ };
12066
+ const roles = assignees.flatMap(assignee => assignee.type === "role" ? [ assignee.role ] : []);
12067
+ return roles.length > 0 ? {
12068
+ kind: "routed",
12069
+ roles: roles
12070
+ } : {
12071
+ kind: "unassigned"
12072
+ };
12073
+ }
12092
12074
 
12093
- exports.InvalidDocNotice = InvalidDocNotice;
12075
+ const LATE_FACE = {
12076
+ Icon: Calendar.CalendarIcon,
12077
+ tone: "caution"
12078
+ };
12094
12079
 
12095
- exports.LoadingRow = LoadingRow;
12080
+ function LateSpan({now: now, since: since}) {
12081
+ /* @__PURE__ */
12082
+ return jsxRuntime.jsx(MetricLockup, {
12083
+ Icon: LATE_FACE.Icon,
12084
+ tone: LATE_FACE.tone,
12085
+ value: workflowComponents._shortSpanOf(parseStoredDateValue(since), now)
12086
+ });
12087
+ }
12096
12088
 
12097
- exports.LogEventOnMount = LogEventOnMount;
12089
+ const HOLDER_OVERLAP = 7, HOLDER_RING = 1.5, GROUP_GAP_TOKEN = 3, OVERDUE_DOT_RATIO = .4;
12098
12090
 
12099
- exports.MetaRow = MetaRow;
12091
+ function overdueDotOf(face) {
12092
+ const size = Math.round(face * OVERDUE_DOT_RATIO);
12093
+ return {
12094
+ overhang: Math.round(size / 4),
12095
+ size: size
12096
+ };
12097
+ }
12100
12098
 
12101
- exports.MetricLockup = MetricLockup;
12099
+ function useDisplayById(ids) {
12100
+ const displays = useUserDisplays(uniqueIds(ids)), labels = disambiguatedNames(displays);
12101
+ return new Map(displays.map((display, index) => [ display.id, {
12102
+ ...display,
12103
+ label: labels[index] ?? display.name
12104
+ } ]));
12105
+ }
12102
12106
 
12103
- exports.MetricPair = MetricPair;
12107
+ function holderKey(assignee, index) {
12108
+ return `${assignee.id}-${index}`;
12109
+ }
12104
12110
 
12105
- exports.NoteBanner = NoteBanner;
12111
+ function stageTasksFace(args) {
12112
+ return {
12113
+ content: /* @__PURE__ */ jsxRuntime.jsx(StageTasksCard, {
12114
+ now: args.now,
12115
+ tasks: args.tasks
12116
+ }),
12117
+ flush: !0,
12118
+ wide: !0
12119
+ };
12120
+ }
12106
12121
 
12107
- exports.OverlineHeading = OverlineHeading;
12122
+ function StageTaskGroups({now: now, room: room, tasks: tasks}) {
12123
+ const gap = useSpaceToken(GROUP_GAP_TOKEN), face = useAvatarSize(), {overhang: overhang} = overdueDotOf(face), {overflow: overflow, visible: visible} = visibleStageTasks({
12124
+ metrics: {
12125
+ counter: face,
12126
+ face: face,
12127
+ gap: gap,
12128
+ overlap: HOLDER_OVERLAP
12129
+ },
12130
+ room: room === void 0 ? face * 3 + gap * 2 : room - overhang,
12131
+ tasks: tasks
12132
+ });
12133
+ return tasks.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
12134
+ ...stageTasksFace({
12135
+ now: now,
12136
+ tasks: tasks
12137
+ }),
12138
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
12139
+ align: "center",
12140
+ "aria-label": "Tasks",
12141
+ style: {
12142
+ columnGap: gap,
12143
+ paddingRight: overhang
12144
+ },
12145
+ children: [ visible.map(task => /* @__PURE__ */ jsxRuntime.jsx(TaskGroupFace, {
12146
+ task: task
12147
+ }, task.name)), overflow === 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, {
12148
+ muted: !0,
12149
+ size: 1,
12150
+ children: [ "+", overflow ]
12151
+ }) ]
12152
+ })
12153
+ });
12154
+ }
12108
12155
 
12109
- exports.RUN_SEARCH_PARAM = RUN_SEARCH_PARAM;
12156
+ function TaskGroupFace({task: task}) {
12157
+ /* @__PURE__ */
12158
+ return jsxRuntime.jsxs(ui.Box, {
12159
+ style: {
12160
+ flexShrink: 0,
12161
+ position: "relative"
12162
+ },
12163
+ children: [
12164
+ /* @__PURE__ */ jsxRuntime.jsx(AssignmentFace, {
12165
+ assignees: task.assignees
12166
+ }), task.overdueSince === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(OverdueDot, {}) ]
12167
+ });
12168
+ }
12110
12169
 
12111
- exports.RowAssignees = RowAssignees;
12170
+ function AssignmentFace({assignees: assignees}) {
12171
+ const mark = taskAssignmentMarkOf(assignees);
12172
+ return mark.kind === "unassigned" ? /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {}) : mark.kind === "routed" ? /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {
12173
+ routed: !0
12174
+ }) : /* @__PURE__ */ jsxRuntime.jsx(OverlappedHolders, {
12175
+ assignees: mark.members
12176
+ });
12177
+ }
12178
+
12179
+ function OverdueDot() {
12180
+ const {color: color} = ui.useTheme_v2(), {overhang: overhang, size: size} = overdueDotOf(useAvatarSize());
12181
+ /* @__PURE__ */
12182
+ return jsxRuntime.jsx(ui.Box, {
12183
+ "aria-label": "Overdue",
12184
+ role: "img",
12185
+ style: {
12186
+ backgroundColor: color.button.default.caution.enabled.bg,
12187
+ borderRadius: "50%",
12188
+ boxShadow: `0 0 0 ${HOLDER_RING}px ${color.bg}`,
12189
+ height: size,
12190
+ position: "absolute",
12191
+ right: -overhang,
12192
+ top: -overhang,
12193
+ width: size
12194
+ }
12195
+ });
12196
+ }
12197
+
12198
+ function HolderFace({assignee: assignee, displayById: displayById}) {
12199
+ const display = displayById.get(assignee.id);
12200
+ /* @__PURE__ */
12201
+ return jsxRuntime.jsx(workflowComponents.MemberAvatar, {
12202
+ imageUrl: display?.imageUrl,
12203
+ name: display?.name ?? assignee.id,
12204
+ size: 0
12205
+ });
12206
+ }
12207
+
12208
+ function OverlappedHolders({assignees: assignees}) {
12209
+ const {color: color} = ui.useTheme_v2(), displayById = useDisplayById(userIdsOf(assignees)), ring = `0 0 0 ${HOLDER_RING}px ${color.bg}`;
12210
+ /* @__PURE__ */
12211
+ return jsxRuntime.jsx(ui.Flex, {
12212
+ align: "center",
12213
+ style: {
12214
+ flexShrink: 0,
12215
+ isolation: "isolate"
12216
+ },
12217
+ children: assignees.map((assignee, index) => /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
12218
+ style: {
12219
+ borderRadius: "50%",
12220
+ boxShadow: ring,
12221
+ flexShrink: 0,
12222
+ marginLeft: index === 0 ? 0 : -HOLDER_OVERLAP,
12223
+ position: "relative",
12224
+ zIndex: index
12225
+ },
12226
+ children: /* @__PURE__ */ jsxRuntime.jsx(HolderFace, {
12227
+ assignee: assignee,
12228
+ displayById: displayById
12229
+ })
12230
+ }, holderKey(assignee, index)))
12231
+ });
12232
+ }
12233
+
12234
+ function PersonToken({routed: routed = !1}) {
12235
+ const size = useAvatarSize(), {color: color} = ui.useTheme_v2();
12236
+ /* @__PURE__ */
12237
+ return jsxRuntime.jsxs(ui.Box, {
12238
+ "aria-label": routed ? "Routed, no person assigned" : "Unassigned",
12239
+ role: "img",
12240
+ style: {
12241
+ flexShrink: 0,
12242
+ height: size,
12243
+ position: "relative",
12244
+ width: size
12245
+ },
12246
+ children: [
12247
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
12248
+ align: "center",
12249
+ justify: "center",
12250
+ style: {
12251
+ border: `1px dashed ${color.border}`,
12252
+ borderRadius: "50%",
12253
+ boxSizing: "border-box",
12254
+ height: size,
12255
+ width: size
12256
+ },
12257
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12258
+ size: 0,
12259
+ children: /* @__PURE__ */ jsxRuntime.jsx(User.UserIcon, {
12260
+ style: {
12261
+ color: color.input.default.enabled.placeholder
12262
+ }
12263
+ })
12264
+ })
12265
+ }), routed ? /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
12266
+ radius: 1,
12267
+ tone: "primary",
12268
+ style: {
12269
+ bottom: -3,
12270
+ position: "absolute",
12271
+ right: -3
12272
+ },
12273
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
12274
+ align: "center",
12275
+ justify: "center",
12276
+ style: {
12277
+ height: 13,
12278
+ width: 13
12279
+ },
12280
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12281
+ size: 0,
12282
+ children: /* @__PURE__ */ jsxRuntime.jsx(Users.UsersIcon, {})
12283
+ })
12284
+ })
12285
+ }) : null ]
12286
+ });
12287
+ }
12288
+
12289
+ function StageTasksCard({now: now, tasks: tasks}) {
12290
+ const displayById = useDisplayById(tasks.flatMap(task => userIdsOf(task.assignees)));
12291
+ /* @__PURE__ */
12292
+ return jsxRuntime.jsxs(ui.Stack, {
12293
+ gap: 4,
12294
+ padding: 3,
12295
+ children: [
12296
+ /* @__PURE__ */ jsxRuntime.jsx(OverlineHeading, {
12297
+ children: "Tasks in this stage"
12298
+ }),
12299
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
12300
+ gap: 4,
12301
+ children: tasks.map(task => /* @__PURE__ */ jsxRuntime.jsx(TaskCardRow, {
12302
+ displayById: displayById,
12303
+ now: now,
12304
+ task: task
12305
+ }, task.name))
12306
+ }) ]
12307
+ });
12308
+ }
12309
+
12310
+ function TaskCardRow({displayById: displayById, now: now, task: task}) {
12311
+ const mark = taskAssignmentMarkOf(task.assignees);
12312
+ /* @__PURE__ */
12313
+ return jsxRuntime.jsxs(ui.Stack, {
12314
+ gap: 3,
12315
+ children: [
12316
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
12317
+ gap: 2,
12318
+ children: [
12319
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
12320
+ align: "center",
12321
+ gap: 3,
12322
+ children: [
12323
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12324
+ size: 1,
12325
+ children: task.title
12326
+ }), task.overdueSince === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(LateSpan, {
12327
+ now: now,
12328
+ since: task.overdueSince
12329
+ }) ]
12330
+ }), task.due === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12331
+ muted: !0,
12332
+ size: 1,
12333
+ children: dueMomentSentence(task.due, now)
12334
+ }) ]
12335
+ }),
12336
+ /* @__PURE__ */ jsxRuntime.jsx(AssignmentLine, {
12337
+ displayById: displayById,
12338
+ mark: mark,
12339
+ now: now,
12340
+ openedAt: task.openedAt,
12341
+ roleAliases: task.roleAliases
12342
+ }) ]
12343
+ });
12344
+ }
12345
+
12346
+ function AssignmentLine({displayById: displayById, mark: mark, now: now, openedAt: openedAt, roleAliases: roleAliases}) {
12347
+ return mark.kind === "unassigned" ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
12348
+ align: "center",
12349
+ gap: 2,
12350
+ children: [
12351
+ /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {}),
12352
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12353
+ muted: !0,
12354
+ size: 1,
12355
+ children: "Unassigned"
12356
+ }) ]
12357
+ }) : mark.kind === "routed" ? /* @__PURE__ */ jsxRuntime.jsx(RoutedAssignmentLine, {
12358
+ mark: mark,
12359
+ now: now,
12360
+ openedAt: openedAt,
12361
+ roleAliases: roleAliases
12362
+ }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
12363
+ gap: 2,
12364
+ children: mark.members.map((assignee, index) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
12365
+ align: "center",
12366
+ gap: 2,
12367
+ children: [
12368
+ /* @__PURE__ */ jsxRuntime.jsx(HolderFace, {
12369
+ assignee: assignee,
12370
+ displayById: displayById
12371
+ }),
12372
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12373
+ size: 1,
12374
+ children: displayById.get(assignee.id)?.label ?? assignee.id
12375
+ }) ]
12376
+ }, holderKey(assignee, index)))
12377
+ });
12378
+ }
12379
+
12380
+ function RoutedAssignmentLine({mark: mark, now: now, openedAt: openedAt, roleAliases: roleAliases}) {
12381
+ const vocabulary = useProjectMembers(), count = workflowComponents.roleMemberCount({
12382
+ members: vocabulary.members,
12383
+ requiredRoles: mark.roles,
12384
+ roleAliases: roleAliases
12385
+ }), names = mark.roles.map(role => workflowComponents.roleLabel(workflowComponents.memberRoleFor(vocabulary, role)));
12386
+ /* @__PURE__ */
12387
+ return jsxRuntime.jsxs(ui.Flex, {
12388
+ align: "center",
12389
+ gap: 2,
12390
+ children: [
12391
+ /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {
12392
+ routed: !0
12393
+ }),
12394
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
12395
+ gap: 1,
12396
+ children: [
12397
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12398
+ size: 1,
12399
+ children: names.join(", ")
12400
+ }),
12401
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, {
12402
+ muted: !0,
12403
+ size: 1,
12404
+ children: [ workflowComponents.memberCountLabel(count), " · Open ", workflowComponents._formatShortAgo(openedAt, now) ]
12405
+ }) ]
12406
+ }) ]
12407
+ });
12408
+ }
12409
+
12410
+ function useTableWidth(element) {
12411
+ const [width, setWidth] = react.useState(void 0);
12412
+ return react.useLayoutEffect(() => {
12413
+ if (element === null) {
12414
+ setWidth(void 0);
12415
+ return;
12416
+ }
12417
+ const measure = () => setWidth(element.getBoundingClientRect().width || void 0);
12418
+ measure();
12419
+ const observer2 = new ResizeObserver(measure);
12420
+ return observer2.observe(element), () => observer2.disconnect();
12421
+ }, [ element ]), width;
12422
+ }
12423
+
12424
+ function useTableStyles() {
12425
+ const {color: color} = ui.useTheme_v2(), headTop = useSpaceToken(3), cellX = useSpaceToken(2);
12426
+ return react.useMemo(() => ({
12427
+ cell: {
12428
+ borderBottom: `1px solid ${color.border}`,
12429
+ boxSizing: "border-box",
12430
+ padding: `0 ${cellX}px`,
12431
+ verticalAlign: "middle",
12432
+ whiteSpace: "nowrap"
12433
+ },
12434
+ head: {
12435
+ background: color.bg,
12436
+ borderBottom: `1px solid ${color.border}`,
12437
+ boxSizing: "border-box",
12438
+ padding: `${headTop}px 0 6px`,
12439
+ position: "sticky",
12440
+ textAlign: "left",
12441
+ top: 0,
12442
+ zIndex: 1
12443
+ }
12444
+ }), [ cellX, color, headTop ]);
12445
+ }
12446
+
12447
+ function scrollParentOf(el) {
12448
+ for (let node = el.parentElement; node !== null; node = node.parentElement) {
12449
+ const overflowY = getComputedStyle(node).overflowY;
12450
+ if (overflowY === "auto" || overflowY === "scroll") return node;
12451
+ }
12452
+ }
12453
+
12454
+ function useRowWindow(args) {
12455
+ const {element: element, keyAt: keyAt, rowCount: rowCount} = args, [scroller, setScroller] = react.useState(null);
12456
+ react.useLayoutEffect(() => {
12457
+ setScroller(element === null ? null : scrollParentOf(element) ?? null);
12458
+ }, [ element ]);
12459
+ const [margin, setMargin] = react.useState(0);
12460
+ react.useLayoutEffect(() => {
12461
+ element === null || scroller === null || setMargin(element.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop);
12462
+ }, [ element, rowCount, scroller ]);
12463
+ const virtualizer = reactVirtual.useVirtualizer({
12464
+ count: rowCount,
12465
+ estimateSize: () => 44,
12466
+ getItemKey: keyAt,
12467
+ getScrollElement: () => scroller,
12468
+ overscan: 10,
12469
+ scrollMargin: margin
12470
+ }), items = virtualizer.getVirtualItems(), first = items[0], last = items[items.length - 1];
12471
+ return {
12472
+ items: items,
12473
+ measureRow: virtualizer.measureElement,
12474
+ padBottom: last === void 0 ? 0 : virtualizer.getTotalSize() - (last.end - margin),
12475
+ padTop: first === void 0 ? 0 : first.start - margin
12476
+ };
12477
+ }
12478
+
12479
+ function SpacerRow({height: height}) {
12480
+ return height <= 0 ? null : /* @__PURE__ */ jsxRuntime.jsx("tr", {
12481
+ "aria-hidden": !0,
12482
+ style: {
12483
+ height: height
12484
+ },
12485
+ children: /* @__PURE__ */ jsxRuntime.jsx("td", {
12486
+ colSpan: 99,
12487
+ style: {
12488
+ border: 0,
12489
+ padding: 0
12490
+ }
12491
+ })
12492
+ });
12493
+ }
12494
+
12495
+ const TABLE_TIME_WIDTH = 112, TABLE_WORKFLOW_WIDTH = {
12496
+ cap: 260,
12497
+ fraction: .18
12498
+ }, TABLE_STAGE_WIDTH = {
12499
+ cap: 260,
12500
+ fraction: .16
12501
+ };
12502
+
12503
+ function SortableHeaderCells({children: children, columns: columns, onSort: onSort, sort: sort, styles: styles, tableWidth: tableWidth, widthOf: widthOf}) {
12504
+ /* @__PURE__ */
12505
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
12506
+ children: [ columns.map(column => {
12507
+ const width = widthOf(column, tableWidth);
12508
+ /* @__PURE__ */
12509
+ return jsxRuntime.jsx("th", {
12510
+ style: {
12511
+ ...styles.head,
12512
+ ...width === void 0 ? {} : {
12513
+ width: width
12514
+ }
12515
+ },
12516
+ children: /* @__PURE__ */ jsxRuntime.jsx(SortHeaderButton, {
12517
+ active: sort.key === column.key,
12518
+ dir: sort.dir,
12519
+ label: column.label,
12520
+ onSort: () => onSort(column.key)
12521
+ })
12522
+ }, column.key);
12523
+ }), children ]
12524
+ });
12525
+ }
12526
+
12527
+ function VirtualTable({keyAt: keyAt, renderHeader: renderHeader, renderRow: renderRow, rowCount: rowCount}) {
12528
+ const styles = useTableStyles(), [element, setElement] = react.useState(null), tableWidth = useTableWidth(element), window = useRowWindow({
12529
+ element: element,
12530
+ keyAt: keyAt,
12531
+ rowCount: rowCount
12532
+ });
12533
+ /* @__PURE__ */
12534
+ return jsxRuntime.jsx("div", {
12535
+ ref: setElement,
12536
+ style: {
12537
+ overflowX: "clip",
12538
+ ...tableWidth === void 0 ? {
12539
+ visibility: "hidden"
12540
+ } : {}
12541
+ },
12542
+ children: /* @__PURE__ */ jsxRuntime.jsxs("table", {
12543
+ style: {
12544
+ borderCollapse: "separate",
12545
+ borderSpacing: 0,
12546
+ tableLayout: "fixed",
12547
+ width: "100%"
12548
+ },
12549
+ children: [
12550
+ /* @__PURE__ */ jsxRuntime.jsx("thead", {
12551
+ children: /* @__PURE__ */ jsxRuntime.jsx("tr", {
12552
+ children: renderHeader({
12553
+ styles: styles,
12554
+ tableWidth: tableWidth
12555
+ })
12556
+ })
12557
+ }),
12558
+ /* @__PURE__ */ jsxRuntime.jsxs("tbody", {
12559
+ children: [
12560
+ /* @__PURE__ */ jsxRuntime.jsx(SpacerRow, {
12561
+ height: window.padTop
12562
+ }), window.items.map(item => renderRow({
12563
+ index: item.index,
12564
+ key: item.key,
12565
+ measureRow: window.measureRow,
12566
+ tableWidth: tableWidth
12567
+ })),
12568
+ /* @__PURE__ */ jsxRuntime.jsx(SpacerRow, {
12569
+ height: window.padBottom
12570
+ }) ]
12571
+ }) ]
12572
+ })
12573
+ });
12574
+ }
12575
+
12576
+ function SortHeaderButton({active: active, dir: dir, label: label, onSort: onSort}) {
12577
+ /* @__PURE__ */
12578
+ return jsxRuntime.jsx(ui.Button, {
12579
+ fontSize: 1,
12580
+ mode: "bleed",
12581
+ onClick: onSort,
12582
+ padding: 2,
12583
+ text: `${label}${active ? dir === "asc" ? " ↑" : " ↓" : ""}`
12584
+ });
12585
+ }
12586
+
12587
+ function TableRowCard({children: children, dataIndex: dataIndex, onClick: onClick, onKeyDown: onKeyDown, rowRef: rowRef, selected: selected, selectedRef: selectedRef}) {
12588
+ const setRow = react.useCallback(element => {
12589
+ rowRef?.(element), selected === !0 && selectedRef?.(element);
12590
+ }, [ rowRef, selected, selectedRef ]);
12591
+ /* @__PURE__ */
12592
+ return jsxRuntime.jsx(ui.Card, {
12593
+ as: "tr",
12594
+ "data-as": "a",
12595
+ onClick: event => {
12596
+ event.currentTarget.focus(), onClick();
12597
+ },
12598
+ onKeyDown: selected === !0 ? onKeyDown : void 0,
12599
+ style: {
12600
+ cursor: "pointer",
12601
+ display: "table-row"
12602
+ },
12603
+ ...dataIndex === void 0 ? {} : {
12604
+ "data-index": dataIndex
12605
+ },
12606
+ ...rowRef === void 0 && selectedRef === void 0 ? {} : {
12607
+ ref: setRow
12608
+ },
12609
+ ...selected === void 0 ? {} : {
12610
+ "aria-selected": selected,
12611
+ pressed: selected,
12612
+ tabIndex: selected ? 0 : -1
12613
+ },
12614
+ children: children
12615
+ });
12616
+ }
12617
+
12618
+ function resolveColumnWidth(width, tableWidth) {
12619
+ return typeof width != "object" ? width : tableWidth === void 0 ? `${width.fraction * 100}%` : Math.min(width.cap, Math.round(tableWidth * width.fraction));
12620
+ }
12621
+
12622
+ function fillColumnWidth(args) {
12623
+ const {columns: columns, tableWidth: tableWidth, trailingWidth: trailingWidth} = args;
12624
+ if (tableWidth === void 0) return;
12625
+ const fixed = columns.reduce((sum, column) => {
12626
+ const width = resolveColumnWidth(column.width, tableWidth);
12627
+ return typeof width == "number" ? sum + width : sum;
12628
+ }, trailingWidth);
12629
+ return Math.max(160, Math.floor(tableWidth - fixed));
12630
+ }
12631
+
12632
+ function TableSubjectCell({document: document}) {
12633
+ return document === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
12634
+ muted: !0,
12635
+ size: 1,
12636
+ textOverflow: "ellipsis",
12637
+ children: "No document"
12638
+ }) : /* @__PURE__ */ jsxRuntime.jsx(DocRefFace, {
12639
+ gdr: document
12640
+ });
12641
+ }
12642
+
12643
+ function overdueAttentionHint(documents) {
12644
+ const task = documents === 1 ? "an overdue task" : "overdue tasks";
12645
+ return `${pluralize__default.default("document", documents, !0)} ${documents === 1 ? "has" : "have"} ${task}`;
12646
+ }
12647
+
12648
+ function blockedAttentionHint(documents) {
12649
+ return `${pluralize__default.default("document", documents, !0)} ${documents === 1 ? "is" : "are"} blocked`;
12650
+ }
12651
+
12652
+ function overdueMark(detail, now) {
12653
+ const spans = overdueSpans(detail.dues, now), longest = spans.length === detail.dues.length ? spans[0]?.span : void 0;
12654
+ return {
12655
+ hint: overdueHint({
12656
+ detail: detail,
12657
+ longest: longest
12658
+ }),
12659
+ value: sharedSpan(spans, detail.dues.length) ?? "overdue"
12660
+ };
12661
+ }
12662
+
12663
+ function overdueHint(args) {
12664
+ const {detail: detail, longest: longest} = args;
12665
+ if (detail.dues.length === 1 && detail.task !== void 0) return `“${detail.task}” — ${longest === void 0 ? "overdue" : `${longest} overdue`}`;
12666
+ const tasks = pluralize__default.default("task", detail.dues.length, !0);
12667
+ return longest === void 0 ? `${tasks} overdue` : `${tasks} overdue — the longest by ${longest}`;
12668
+ }
12669
+
12670
+ function sharedSpan(spans, late) {
12671
+ if (spans.length === late) return new Set(spans.map(entry => entry.span)).size === 1 ? spans[0]?.span : void 0;
12672
+ }
12673
+
12674
+ function overdueSpans(dues, now) {
12675
+ return dues.flatMap(due => {
12676
+ const from = parseStoredDateValue(due);
12677
+ return from === void 0 ? [] : [ {
12678
+ elapsed: now.getTime() - from.getTime(),
12679
+ span: workflowComponents._shortSpanOf(from, now)
12680
+ } ];
12681
+ }).sort((a, b) => b.elapsed - a.elapsed);
12682
+ }
12683
+
12684
+ function overdueMarkOpensPanel(tasks) {
12685
+ return tasks.some(task => task.overdueSince !== void 0);
12686
+ }
12687
+
12688
+ function blockedMarkHint(detail) {
12689
+ 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`;
12690
+ }
12691
+
12692
+ const ATTENTION_FACES = {
12693
+ blocked: {
12694
+ Icon: ErrorOutline.ErrorOutlineIcon,
12695
+ tone: "critical"
12696
+ },
12697
+ overdue: LATE_FACE
12698
+ };
12699
+
12700
+ function AttentionMark({detail: detail, now: now, tasks: tasks}) {
12701
+ if (detail.kind === "overdue") {
12702
+ const {hint: hint2, value: value} = overdueMark(detail, now);
12703
+ /* @__PURE__ */
12704
+ return jsxRuntime.jsx(MetricPair, {
12705
+ Icon: ATTENTION_FACES.overdue.Icon,
12706
+ face: overdueMarkOpensPanel(tasks) ? stageTasksFace({
12707
+ now: now,
12708
+ tasks: tasks
12709
+ }) : {
12710
+ text: hint2
12711
+ },
12712
+ label: hint2,
12713
+ tone: ATTENTION_FACES.overdue.tone,
12714
+ value: value
12715
+ });
12716
+ }
12717
+ const hint = blockedMarkHint(detail);
12718
+ /* @__PURE__ */
12719
+ return jsxRuntime.jsx(AlertChip, {
12720
+ Icon: ATTENTION_FACES.blocked.Icon,
12721
+ hint: hint,
12722
+ label: hint,
12723
+ tone: ATTENTION_FACES.blocked.tone
12724
+ });
12725
+ }
12726
+
12727
+ function documentRefsOf(instance) {
12728
+ const seen = /* @__PURE__ */ new Map;
12729
+ for (const ref of workflowEngine.entryDocRefs(instance.fields)) seen.has(ref.id) || seen.set(ref.id, ref);
12730
+ return [ ...seen.values() ];
12731
+ }
12732
+
12733
+ function rootInstanceOf(instance, byId) {
12734
+ const rootRef = instance.ancestors[0];
12735
+ return rootRef ? byId.get(workflowEngine.toBareId(rootRef.id)) ?? instance : instance;
12736
+ }
12737
+
12738
+ function runsScopeOf(row) {
12739
+ return row.endedAt === void 0 ? "open" : "closed";
12740
+ }
12741
+
12742
+ function rowHasTaskHeldBy(row, who) {
12743
+ return row.tasks.some(task => workflowComponents.assignmentMatch(task.assignees, who) !== void 0);
12744
+ }
12745
+
12746
+ function runCountsByWorkflow(rows) {
12747
+ return countBy(rows, row => [ row.workflowName ]);
12748
+ }
12749
+
12750
+ function runCountsByAssignee(rows) {
12751
+ return countBy(rows, row => new Set(userIdsOf(row.assignees)));
12752
+ }
12753
+
12754
+ function runCountsByRole(rows) {
12755
+ return countBy(rows, row => new Set(row.assignees.flatMap(assignee => assignee.type === "role" ? [ assignee.role ] : [])));
12756
+ }
12757
+
12758
+ function runAttentionCounts(rows) {
12759
+ let blocked = 0, overdue = 0;
12760
+ for (const row of rows) row.attention === "blocked" && (blocked += 1), row.attention === "overdue" && (overdue += 1);
12761
+ return {
12762
+ blocked: blocked,
12763
+ overdue: overdue
12764
+ };
12765
+ }
12766
+
12767
+ function unassignedRunCount(rows) {
12768
+ return rows.filter(row => row.assignmentStateCounts.unrouted > 0).length;
12769
+ }
12770
+
12771
+ function runCountsByStage(rows) {
12772
+ return countBy(rows, row => [ row.stage ]);
12773
+ }
12774
+
12775
+ function runCountsByRelease(rows) {
12776
+ return countBy(rows, row => new Set(row.releases));
12777
+ }
12778
+
12779
+ function noReleaseRunCount(rows) {
12780
+ return rows.filter(row => row.releases.length === 0).length;
12781
+ }
12782
+
12783
+ function releasesOfPerspective(perspective) {
12784
+ return Array.isArray(perspective) ? perspective.filter(name => name !== "drafts") : [];
12785
+ }
12786
+
12787
+ function runRowsOf(args) {
12788
+ const byId = new Map(args.previews.map(preview => [ preview._id, preview ]));
12789
+ return args.previews.map(preview => runRowOf({
12790
+ byId: byId,
12791
+ definitions: args.definitions,
12792
+ now: args.now,
12793
+ preview: preview
12794
+ }));
12795
+ }
12796
+
12797
+ function runRowOf(args) {
12798
+ 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({
12799
+ definition: definition,
12800
+ preview: preview
12801
+ }) ?? overdueRunDetail({
12802
+ definition: definition,
12803
+ now: now,
12804
+ preview: preview
12805
+ });
12806
+ return {
12807
+ id: preview._id,
12808
+ document: documentRefsOf(rootInstanceOf(preview, byId))[0],
12809
+ workflowName: preview.definition,
12810
+ workflowTitle: definition?.title ?? preview.definition,
12811
+ stage: preview.currentStage,
12812
+ stageTitle: stageTitle(definition, preview.currentStage),
12813
+ releases: releasesOfPerspective(preview.perspective),
12814
+ startedAt: preview.startedAt,
12815
+ endedAt: settled ? preview.completedAt ?? preview.abortedAt : void 0,
12816
+ outcome: outcomeOf(preview, definition),
12817
+ attention: attentionKindOf(attentionDetail),
12818
+ attentionDetail: attentionDetail,
12819
+ assignees: held.assignees,
12820
+ assignments: held.assignments,
12821
+ assignmentStateCounts: held.counts,
12822
+ tasks: settled ? [] : stageTasksOf({
12823
+ definition: definition,
12824
+ instance: preview,
12825
+ now: now
12826
+ })
12827
+ };
12828
+ }
12829
+
12830
+ function attentionKindOf(detail) {
12831
+ if (detail !== void 0) return detail.kind === "overdue" ? "overdue" : "blocked";
12832
+ }
12833
+
12834
+ function blockedArmOf(detail) {
12835
+ if (!(detail === void 0 || detail.kind === "overdue")) return detail;
12836
+ }
12837
+
12838
+ function overdueArmOf(detail) {
12839
+ return detail?.kind === "overdue" ? detail : void 0;
12840
+ }
12841
+
12842
+ function outcomeOf(preview, definition) {
12843
+ const state = workflowEngine.terminalState(preview);
12844
+ if (state !== "in-flight") return state === "aborted" ? "Aborted" : stageTitle(definition, preview.currentStage);
12845
+ }
12846
+
12847
+ function blockedRunDetail(args) {
12848
+ const {definition: definition, preview: preview} = args, {stage: stage, titleOf: titleOf2} = activityTitleResolver(preview, definition), failed = (stage?.activities ?? []).filter(activity => activity.status === "failed");
12849
+ if (failed.length > 1) return {
12850
+ count: failed.length,
12851
+ kind: "blocked-many"
12852
+ };
12853
+ const only = failed[0];
12854
+ if (only !== void 0) return {
12855
+ kind: "blocked",
12856
+ task: titleOf2(only.name)
12857
+ };
12858
+ const stuck = stuckEffectOf({
12859
+ definition: definition,
12860
+ preview: preview,
12861
+ stage: stage
12862
+ });
12863
+ return stuck === void 0 ? void 0 : {
12864
+ effect: stuck.effect.title ?? stuck.effect.name,
12865
+ failed: stuck.failed,
12866
+ kind: "blocked-effect"
12867
+ };
12868
+ }
12869
+
12870
+ function stuckEffectOf(args) {
12871
+ const reported = failedDeclaredEffect(args);
12872
+ if (reported !== void 0) return {
12873
+ effect: reported,
12874
+ failed: !0
12875
+ };
12876
+ const claimed = args.preview.claimedEffects[0];
12877
+ return claimed === void 0 ? void 0 : {
12878
+ effect: claimed,
12879
+ failed: !1
12880
+ };
12881
+ }
12882
+
12883
+ function failedDeclaredEffect(args) {
12884
+ const {definition: definition, preview: preview, stage: stage} = args;
12885
+ if (definition === void 0 || definition.version !== preview.pinnedVersion || stage === void 0) return;
12886
+ const stageNode = workflowEngine.findStageNode({
12887
+ definition: definition,
12888
+ stageName: stage.name
12889
+ }), 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))));
12890
+ return [ ...preview.failedEffects ].reverse().find(effect => declared.has(effect.name));
12891
+ }
12892
+
12893
+ function overdueRunDetail(args) {
12894
+ const {definition: definition, now: now, preview: preview} = args, late = overdueTasks(preview, now);
12895
+ if (late.length === 0) return;
12896
+ const {titleOf: titleOf2} = activityTitleResolver(preview, definition), only = late.length === 1 ? late[0] : void 0;
12897
+ return {
12898
+ dues: late.flatMap(activity => {
12899
+ const due = passedDueOf(activity, now);
12900
+ return due === void 0 ? [] : [ due ];
12901
+ }),
12902
+ kind: "overdue",
12903
+ task: only === void 0 ? void 0 : titleOf2(only.name)
12904
+ };
12905
+ }
12906
+
12907
+ function activityTitleResolver(preview, definition) {
12908
+ const stage = workflowEngine.findOpenStageEntry(preview);
12909
+ return {
12910
+ stage: stage,
12911
+ titleOf: activityName => findActivity({
12912
+ activityName: activityName,
12913
+ definition: definition,
12914
+ stageName: stage?.name ?? ""
12915
+ }).title
12916
+ };
12917
+ }
12918
+
12919
+ const NO_ASSIGNEES = {
12920
+ assignees: [],
12921
+ assignments: [],
12922
+ counts: {
12923
+ unrouted: 0,
12924
+ routed: 0,
12925
+ held: 0
12926
+ }
12927
+ };
12928
+
12929
+ function openAssignees(instance) {
12930
+ const users = /* @__PURE__ */ new Map, roles = /* @__PURE__ */ new Map, assignments = workflowEngine.openActivityAssignments(instance), counts = {
12931
+ unrouted: 0,
12932
+ routed: 0,
12933
+ held: 0
12934
+ };
12935
+ for (const members of assignments) counts[workflowEngine.assignmentState(members)] += 1,
12936
+ recordAssignees(workflowEngine.activeAssignmentMembers(members), {
12937
+ users: users,
12938
+ roles: roles
12939
+ });
12940
+ return {
12941
+ assignees: [ ...users.values(), ...roles.values() ],
12942
+ assignments: assignments,
12943
+ counts: counts
12944
+ };
12945
+ }
12946
+
12947
+ function recordAssignees(assignees, maps) {
12948
+ for (const assignee of assignees) (assignee.type === "user" ? maps.users : maps.roles).set(assignee.type === "user" ? assignee.id : assignee.role, assignee);
12949
+ }
12950
+
12951
+ function tasksWidthOf(tableWidth) {
12952
+ return tableWidth === void 0 ? 176 : tableWidth >= 1040 ? 224 : 176;
12953
+ }
12954
+
12955
+ function taskRoomOf(args) {
12956
+ const cell = tasksWidthOf(args.tableWidth) - args.inset * 2;
12957
+ return args.overdue ? cell - 76 - args.gap : cell;
12958
+ }
12959
+
12960
+ const OPEN_COLUMNS = [ {
12961
+ key: "document",
12962
+ label: "Workflow subject"
12963
+ }, {
12964
+ key: "workflow",
12965
+ label: "Workflow",
12966
+ width: TABLE_WORKFLOW_WIDTH
12967
+ }, {
12968
+ key: "stage",
12969
+ label: "Stage",
12970
+ width: TABLE_STAGE_WIDTH
12971
+ }, {
12972
+ key: "started",
12973
+ label: "Started",
12974
+ width: TABLE_TIME_WIDTH
12975
+ } ], CLOSED_COLUMNS = [ {
12976
+ key: "document",
12977
+ label: "Workflow subject"
12978
+ }, {
12979
+ key: "workflow",
12980
+ label: "Workflow",
12981
+ width: TABLE_WORKFLOW_WIDTH
12982
+ }, {
12983
+ key: "outcome",
12984
+ label: "Outcome",
12985
+ width: TABLE_STAGE_WIDTH
12986
+ }, {
12987
+ key: "started",
12988
+ label: "Started",
12989
+ width: TABLE_TIME_WIDTH
12990
+ }, {
12991
+ key: "ended",
12992
+ label: "Closed",
12993
+ width: TABLE_TIME_WIDTH
12994
+ } ];
12995
+
12996
+ function runsTableColumnsOf(args) {
12997
+ const columns = args.scope === "closed" ? CLOSED_COLUMNS : OPEN_COLUMNS;
12998
+ return args.scopedToWorkflow ? columns.filter(column => column.key !== "workflow") : columns;
12999
+ }
13000
+
13001
+ function runsDocumentWidthOf(args) {
13002
+ const trailing = args.scope === "open" ? tasksWidthOf(args.tableWidth) : 0;
13003
+ return fillColumnWidth({
13004
+ columns: args.columns,
13005
+ tableWidth: args.tableWidth,
13006
+ trailingWidth: trailing
13007
+ });
13008
+ }
13009
+
13010
+ const TASKS_CELL_GAP_TOKEN = 3;
13011
+
13012
+ function RunsTable({now: now, onNavigateKey: onNavigateKey, onSelectRun: onSelectRun, onSort: onSort, rows: rows, scope: scope, scopedToWorkflow: scopedToWorkflow, selectedId: selectedId, selectedRef: selectedRef, sort: sort}) {
13013
+ const columns = runsTableColumnsOf({
13014
+ scope: scope,
13015
+ scopedToWorkflow: scopedToWorkflow
13016
+ }), cellInset = useSpaceToken(2), markGap = useSpaceToken(TASKS_CELL_GAP_TOKEN);
13017
+ /* @__PURE__ */
13018
+ return jsxRuntime.jsx(VirtualTable, {
13019
+ renderHeader: args => /* @__PURE__ */ jsxRuntime.jsx(RunsHeader, {
13020
+ columns: columns,
13021
+ onSort: onSort,
13022
+ scope: scope,
13023
+ sort: sort,
13024
+ styles: args.styles,
13025
+ tableWidth: args.tableWidth
13026
+ }),
13027
+ keyAt: index => rows[index]?.id ?? String(index),
13028
+ renderRow: ({index: index, key: key, measureRow: measureRow, tableWidth: tableWidth}) => {
13029
+ const row = rows[index];
13030
+ if (row === void 0) return null;
13031
+ const overdue = overdueArmOf(row.attentionDetail);
13032
+ /* @__PURE__ */
13033
+ return jsxRuntime.jsx(RunTableRow, {
13034
+ dataIndex: index,
13035
+ measureRow: measureRow,
13036
+ now: now,
13037
+ onNavigateKey: onNavigateKey,
13038
+ onSelectRun: onSelectRun,
13039
+ row: row,
13040
+ scope: scope,
13041
+ scopedToWorkflow: scopedToWorkflow,
13042
+ selected: row.id === selectedId,
13043
+ selectedRef: selectedRef,
13044
+ overdue: overdue,
13045
+ taskRoom: taskRoomOf({
13046
+ gap: markGap,
13047
+ inset: cellInset,
13048
+ overdue: overdue !== void 0,
13049
+ tableWidth: tableWidth
13050
+ })
13051
+ }, key);
13052
+ },
13053
+ rowCount: rows.length
13054
+ });
13055
+ }
13056
+
13057
+ function RunsHeader({columns: columns, onSort: onSort, scope: scope, sort: sort, styles: styles, tableWidth: tableWidth}) {
13058
+ /* @__PURE__ */
13059
+ return jsxRuntime.jsx(SortableHeaderCells, {
13060
+ columns: columns,
13061
+ onSort: onSort,
13062
+ sort: sort,
13063
+ styles: styles,
13064
+ tableWidth: tableWidth,
13065
+ widthOf: (column, width) => column.key === "document" ? runsDocumentWidthOf({
13066
+ columns: columns,
13067
+ scope: scope,
13068
+ tableWidth: width
13069
+ }) : resolveColumnWidth(column.width, width),
13070
+ children: scope === "open" ? /* @__PURE__ */ jsxRuntime.jsx("th", {
13071
+ style: {
13072
+ ...styles.head,
13073
+ width: tasksWidthOf(tableWidth)
13074
+ },
13075
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
13076
+ padding: 2,
13077
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13078
+ muted: !0,
13079
+ size: 1,
13080
+ children: "Tasks"
13081
+ })
13082
+ })
13083
+ }) : null
13084
+ });
13085
+ }
13086
+
13087
+ 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}) {
13088
+ const styles = useTableStyles(), documentInset = useSpaceToken(1);
13089
+ /* @__PURE__ */
13090
+ return jsxRuntime.jsxs(TableRowCard, {
13091
+ dataIndex: dataIndex,
13092
+ onClick: () => onSelectRun(row),
13093
+ onKeyDown: onNavigateKey,
13094
+ rowRef: measureRow,
13095
+ selected: selected,
13096
+ selectedRef: selectedRef,
13097
+ children: [
13098
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13099
+ style: {
13100
+ ...styles.cell,
13101
+ paddingLeft: documentInset
13102
+ },
13103
+ children: /* @__PURE__ */ jsxRuntime.jsx(TableSubjectCell, {
13104
+ document: row.document
13105
+ })
13106
+ }), scopedToWorkflow ? null : /* @__PURE__ */ jsxRuntime.jsx("td", {
13107
+ style: styles.cell,
13108
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13109
+ muted: !0,
13110
+ size: 1,
13111
+ textOverflow: "ellipsis",
13112
+ children: row.workflowTitle
13113
+ })
13114
+ }), scope === "closed" ? /* @__PURE__ */ jsxRuntime.jsx(ClosedCells, {
13115
+ now: now,
13116
+ row: row
13117
+ }) : /* @__PURE__ */ jsxRuntime.jsx(OpenCells, {
13118
+ now: now,
13119
+ overdue: overdue,
13120
+ row: row,
13121
+ taskRoom: taskRoom
13122
+ }) ]
13123
+ });
13124
+ });
13125
+
13126
+ function OpenCells({now: now, overdue: overdue, row: row, taskRoom: taskRoom}) {
13127
+ const styles = useTableStyles(), blocked = blockedArmOf(row.attentionDetail);
13128
+ /* @__PURE__ */
13129
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
13130
+ children: [
13131
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13132
+ style: styles.cell,
13133
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
13134
+ align: "center",
13135
+ gap: 2,
13136
+ children: [
13137
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13138
+ size: 1,
13139
+ textOverflow: "ellipsis",
13140
+ children: row.stageTitle
13141
+ }), blocked === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(AttentionMark, {
13142
+ detail: blocked,
13143
+ now: now,
13144
+ tasks: row.tasks
13145
+ }) ]
13146
+ })
13147
+ }),
13148
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13149
+ style: styles.cell,
13150
+ children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.AgoStamp, {
13151
+ at: row.startedAt,
13152
+ now: now
13153
+ })
13154
+ }),
13155
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13156
+ style: {
13157
+ ...styles.cell,
13158
+ overflow: "hidden"
13159
+ },
13160
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
13161
+ align: "center",
13162
+ gap: TASKS_CELL_GAP_TOKEN,
13163
+ children: [
13164
+ /* @__PURE__ */ jsxRuntime.jsx(StageTaskGroups, {
13165
+ now: now,
13166
+ room: taskRoom,
13167
+ tasks: row.tasks
13168
+ }), overdue === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(AttentionMark, {
13169
+ detail: overdue,
13170
+ now: now,
13171
+ tasks: row.tasks
13172
+ }) ]
13173
+ })
13174
+ }) ]
13175
+ });
13176
+ }
13177
+
13178
+ function ClosedCells({now: now, row: row}) {
13179
+ const styles = useTableStyles();
13180
+ /* @__PURE__ */
13181
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
13182
+ children: [
13183
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13184
+ style: styles.cell,
13185
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13186
+ size: 1,
13187
+ textOverflow: "ellipsis",
13188
+ children: row.outcome
13189
+ })
13190
+ }),
13191
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13192
+ style: styles.cell,
13193
+ children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.AgoStamp, {
13194
+ at: row.startedAt,
13195
+ now: now
13196
+ })
13197
+ }),
13198
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13199
+ style: styles.cell,
13200
+ children: row.endedAt === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.AgoStamp, {
13201
+ at: row.endedAt,
13202
+ now: now
13203
+ })
13204
+ }) ]
13205
+ });
13206
+ }
13207
+
13208
+ function DueStamp({due: due, now: now}) {
13209
+ /* @__PURE__ */
13210
+ return jsxRuntime.jsx(ui.Flex, {
13211
+ align: "center",
13212
+ children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
13213
+ text: dueMomentSentence(due, now),
13214
+ children: isDueDatePast(due, now) ? /* @__PURE__ */ jsxRuntime.jsx(LateSpan, {
13215
+ now: now,
13216
+ since: due
13217
+ }) :
13218
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13219
+ muted: !0,
13220
+ size: 1,
13221
+ style: {
13222
+ whiteSpace: "nowrap"
13223
+ },
13224
+ children: formatDate(due)
13225
+ })
13226
+ })
13227
+ });
13228
+ }
13229
+
13230
+ const TASK_WIDTH = {
13231
+ cap: 280,
13232
+ fraction: .22
13233
+ }, FOR_ME_ATTENTION_WIDTH = 48, FOR_ME_ASSIGNEE_WIDTH = 96, FOR_ME_COLUMNS = [ {
13234
+ key: "document",
13235
+ label: "Workflow subject"
13236
+ }, {
13237
+ key: "task",
13238
+ label: "Task",
13239
+ width: TASK_WIDTH
13240
+ }, {
13241
+ key: "opened",
13242
+ label: "Opened",
13243
+ width: TABLE_TIME_WIDTH
13244
+ }, {
13245
+ key: "workflow",
13246
+ label: "Workflow",
13247
+ width: TABLE_WORKFLOW_WIDTH
13248
+ }, {
13249
+ key: "due",
13250
+ label: "Due",
13251
+ width: TABLE_TIME_WIDTH
13252
+ } ];
13253
+
13254
+ function forMeDocumentWidthOf(tableWidth) {
13255
+ return fillColumnWidth({
13256
+ columns: FOR_ME_COLUMNS,
13257
+ tableWidth: tableWidth,
13258
+ trailingWidth: FOR_ME_ASSIGNEE_WIDTH + FOR_ME_ATTENTION_WIDTH
13259
+ });
13260
+ }
13261
+
13262
+ function ForMeTable({now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, onSort: onSort, rows: rows, selectedId: selectedId, selectedRef: selectedRef, sort: sort}) {
13263
+ /* @__PURE__ */
13264
+ return jsxRuntime.jsx(VirtualTable, {
13265
+ renderHeader: args => /* @__PURE__ */ jsxRuntime.jsxs(SortableHeaderCells, {
13266
+ columns: FOR_ME_COLUMNS,
13267
+ onSort: onSort,
13268
+ sort: sort,
13269
+ styles: args.styles,
13270
+ tableWidth: args.tableWidth,
13271
+ widthOf: (column, tableWidth) => column.key === "document" ? forMeDocumentWidthOf(tableWidth) : resolveColumnWidth(column.width, tableWidth),
13272
+ children: [
13273
+ /* @__PURE__ */ jsxRuntime.jsx("th", {
13274
+ style: {
13275
+ ...args.styles.head,
13276
+ width: FOR_ME_ASSIGNEE_WIDTH
13277
+ },
13278
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
13279
+ padding: 2,
13280
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13281
+ muted: !0,
13282
+ size: 1,
13283
+ children: "Assignee"
13284
+ })
13285
+ })
13286
+ }),
13287
+ /* @__PURE__ */ jsxRuntime.jsx("th", {
13288
+ "aria-label": "Attention",
13289
+ style: {
13290
+ ...args.styles.head,
13291
+ width: FOR_ME_ATTENTION_WIDTH
13292
+ }
13293
+ }) ]
13294
+ }),
13295
+ keyAt: index => rows[index]?.id ?? String(index),
13296
+ renderRow: ({index: index, key: key, measureRow: measureRow}) => {
13297
+ const row = rows[index];
13298
+ return row === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ForMeTableRow, {
13299
+ dataIndex: index,
13300
+ measureRow: measureRow,
13301
+ now: now,
13302
+ onNavigateKey: onNavigateKey,
13303
+ onSelect: onSelect,
13304
+ row: row,
13305
+ selected: row.id === selectedId,
13306
+ selectedRef: selectedRef
13307
+ }, key);
13308
+ },
13309
+ rowCount: rows.length
13310
+ });
13311
+ }
13312
+
13313
+ const ForMeTableRow = react.memo(function({dataIndex: dataIndex, measureRow: measureRow, now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, row: row, selected: selected, selectedRef: selectedRef}) {
13314
+ const styles = useTableStyles(), documentInset = useSpaceToken(1);
13315
+ /* @__PURE__ */
13316
+ return jsxRuntime.jsxs(TableRowCard, {
13317
+ dataIndex: dataIndex,
13318
+ onClick: () => onSelect(row),
13319
+ onKeyDown: onNavigateKey,
13320
+ rowRef: measureRow,
13321
+ selected: selected,
13322
+ selectedRef: selectedRef,
13323
+ children: [
13324
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13325
+ style: {
13326
+ ...styles.cell,
13327
+ paddingLeft: documentInset
13328
+ },
13329
+ children: /* @__PURE__ */ jsxRuntime.jsx(TableSubjectCell, {
13330
+ document: row.document
13331
+ })
13332
+ }),
13333
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13334
+ style: styles.cell,
13335
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13336
+ size: 1,
13337
+ textOverflow: "ellipsis",
13338
+ children: row.title
13339
+ })
13340
+ }),
13341
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13342
+ style: styles.cell,
13343
+ children: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.AgoStamp, {
13344
+ at: row.openedAt,
13345
+ now: now
13346
+ })
13347
+ }),
13348
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13349
+ style: styles.cell,
13350
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
13351
+ muted: !0,
13352
+ size: 1,
13353
+ textOverflow: "ellipsis",
13354
+ children: row.workflowTitle
13355
+ })
13356
+ }),
13357
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13358
+ style: styles.cell,
13359
+ children: row.due === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(DueStamp, {
13360
+ due: row.due,
13361
+ now: now
13362
+ })
13363
+ }),
13364
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13365
+ style: {
13366
+ ...styles.cell,
13367
+ overflow: "hidden"
13368
+ },
13369
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
13370
+ align: "center",
13371
+ children: /* @__PURE__ */ jsxRuntime.jsx(RowAssignees, {
13372
+ assignees: row.assignees
13373
+ })
13374
+ })
13375
+ }),
13376
+ /* @__PURE__ */ jsxRuntime.jsx("td", {
13377
+ style: styles.cell,
13378
+ children: /* @__PURE__ */ jsxRuntime.jsx(ForMeAttentionCell, {
13379
+ now: now,
13380
+ row: row
13381
+ })
13382
+ }) ]
13383
+ });
13384
+ });
13385
+
13386
+ function ForMeAttentionCell({now: now, row: row}) {
13387
+ const blocked = blockedArmOf(row.attentionDetail);
13388
+ return blocked === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
13389
+ align: "center",
13390
+ children: /* @__PURE__ */ jsxRuntime.jsx(AttentionMark, {
13391
+ detail: blocked,
13392
+ now: now,
13393
+ tasks: []
13394
+ })
13395
+ });
13396
+ }
13397
+
13398
+ function forMeRowId(instanceId, activityName) {
13399
+ return `${instanceId}\t${activityName}`;
13400
+ }
13401
+
13402
+ function forMeTaskRowsOf(args) {
13403
+ const {rows: rows, who: who} = args;
13404
+ return rows.flatMap(row => row.tasks.flatMap(task => {
13405
+ const assignment = assignmentHolding(task.assignees, who);
13406
+ if (assignment === "other") return [];
13407
+ const attentionDetail = taskAttentionDetail({
13408
+ row: row,
13409
+ task: task
13410
+ });
13411
+ return [ {
13412
+ id: forMeRowId(row.id, task.name),
13413
+ instanceId: row.id,
13414
+ activityName: task.name,
13415
+ title: task.title,
13416
+ document: row.document,
13417
+ workflowTitle: row.workflowTitle,
13418
+ releases: row.releases,
13419
+ openedAt: task.openedAt,
13420
+ due: task.due,
13421
+ attention: attentionKindOf(attentionDetail),
13422
+ attentionDetail: attentionDetail,
13423
+ assignees: task.assignees,
13424
+ assignment: assignment
13425
+ } ];
13426
+ }));
13427
+ }
13428
+
13429
+ function forMeSummaryOf(rows) {
13430
+ const documents = new Set(rows.flatMap(row => row.document === void 0 ? [] : [ row.document.id ])), releases = new Set(rows.flatMap(row => row.releases));
13431
+ return {
13432
+ lead: rows.length === 0 ? "No tasks" : pluralize__default.default("task", rows.length, !0),
13433
+ subjects: `on ${pluralize__default.default("document", documents.size, !0)}, and ${pluralize__default.default("release", releases.size, !0)}`
13434
+ };
13435
+ }
13436
+
13437
+ function forMeSectionsOf(rows) {
13438
+ return {
13439
+ assignedToUser: rows.filter(row => row.assignment === "you"),
13440
+ assignedToRoles: rows.filter(row => row.assignment === "role")
13441
+ };
13442
+ }
13443
+
13444
+ function resolveForMeAddress(args) {
13445
+ const {rows: rows, run: run, task: task} = args;
13446
+ if (run === void 0) return;
13447
+ if (task !== void 0) return rows.some(row => row.instanceId === run && row.activityName === task) ? {
13448
+ run: run,
13449
+ task: task
13450
+ } : void 0;
13451
+ const first = rows.find(row => row.instanceId === run);
13452
+ return first === void 0 ? void 0 : {
13453
+ run: first.instanceId,
13454
+ task: first.activityName
13455
+ };
13456
+ }
13457
+
13458
+ function taskAttentionDetail(args) {
13459
+ const {row: row, task: task} = args;
13460
+ if (task.status === "failed") return {
13461
+ kind: "blocked",
13462
+ task: task.title
13463
+ };
13464
+ if (row.attention === "blocked") return row.attentionDetail;
13465
+ if (task.overdueSince !== void 0) return {
13466
+ dues: [ task.overdueSince ],
13467
+ kind: "overdue",
13468
+ task: task.title
13469
+ };
13470
+ }
13471
+
13472
+ exports.ATTENTION_FACES = ATTENTION_FACES;
13473
+
13474
+ exports.AbortWorkflowDialog = AbortWorkflowDialog;
13475
+
13476
+ exports.ActivityDetailBody = ActivityDetailBody;
13477
+
13478
+ exports.ActivityDetailDialog = ActivityDetailDialog;
13479
+
13480
+ exports.ActivityLog = ActivityLog;
13481
+
13482
+ exports.AlertGlyph = AlertGlyph;
13483
+
13484
+ exports.AttentionMark = AttentionMark;
13485
+
13486
+ exports.Breadcrumb = Breadcrumb;
13487
+
13488
+ exports.CodeChip = CodeChip;
13489
+
13490
+ exports.CountedLabel = CountedLabel;
13491
+
13492
+ exports.DismissablePopover = DismissablePopover;
13493
+
13494
+ exports.DocPreviewLink = DocPreviewLink;
13495
+
13496
+ exports.DocRefFace = DocRefFace;
13497
+
13498
+ exports.EmptyState = EmptyState;
13499
+
13500
+ exports.FOR_ME_SECTION_COPY = FOR_ME_SECTION_COPY;
13501
+
13502
+ exports.ForMeEmptyState = ForMeEmptyState;
13503
+
13504
+ exports.ForMeSectionHeading = ForMeSectionHeading;
13505
+
13506
+ exports.ForMeTable = ForMeTable;
13507
+
13508
+ exports.InstanceFaultNote = InstanceFaultNote;
13509
+
13510
+ exports.InstanceSnapshotBody = InstanceSnapshotBody;
13511
+
13512
+ exports.InvalidDocNotice = InvalidDocNotice;
13513
+
13514
+ exports.LoadingRow = LoadingRow;
13515
+
13516
+ exports.LogEventOnMount = LogEventOnMount;
13517
+
13518
+ exports.MetaRow = MetaRow;
13519
+
13520
+ exports.MetricPair = MetricPair;
13521
+
13522
+ exports.NoteBanner = NoteBanner;
13523
+
13524
+ exports.RUN_SEARCH_PARAM = RUN_SEARCH_PARAM;
13525
+
13526
+ exports.RunsTable = RunsTable;
12112
13527
 
12113
13528
  exports.SectionHeading = SectionHeading;
12114
13529
 
13530
+ exports.SortHeaderButton = SortHeaderButton;
13531
+
12115
13532
  exports.SpinnerSlot = SpinnerSlot;
12116
13533
 
13534
+ exports.StageTaskGroups = StageTaskGroups;
13535
+
12117
13536
  exports.TOOL_TABS = TOOL_TABS;
12118
13537
 
12119
13538
  exports.TabSwitch = TabSwitch;
12120
13539
 
13540
+ exports.TableRowCard = TableRowCard;
13541
+
13542
+ exports.UNREADABLE_DOCUMENT = UNREADABLE_DOCUMENT;
13543
+
12121
13544
  exports.UnreadableDocsNote = UnreadableDocsNote;
12122
13545
 
12123
13546
  exports.WORKFLOW_API_VERSION = WORKFLOW_API_VERSION;
@@ -12132,11 +13555,9 @@ exports.WorkflowTitleSeedDrifted = WorkflowTitleSeedDrifted;
12132
13555
 
12133
13556
  exports.WorkflowToolOpened = WorkflowToolOpened;
12134
13557
 
12135
- exports.activityLabel = activityLabel;
12136
-
12137
- exports.assigneesOf = assigneesOf;
13558
+ exports.blockedAttentionHint = blockedAttentionHint;
12138
13559
 
12139
- exports.assignmentHolding = assignmentHolding;
13560
+ exports.blockedRunDetail = blockedRunDetail;
12140
13561
 
12141
13562
  exports.countBy = countBy;
12142
13563
 
@@ -12148,19 +13569,15 @@ exports.deriveActivityDetail = deriveActivityDetail;
12148
13569
 
12149
13570
  exports.describeError = describeError;
12150
13571
 
12151
- exports.disambiguatedNames = disambiguatedNames;
13572
+ exports.documentRefsOf = documentRefsOf;
12152
13573
 
12153
- exports.dueDatesOf = dueDatesOf;
13574
+ exports.forMeRowId = forMeRowId;
12154
13575
 
12155
- exports.dueMomentSentence = dueMomentSentence;
13576
+ exports.forMeSectionsOf = forMeSectionsOf;
12156
13577
 
12157
- exports.findActivity = findActivity;
13578
+ exports.forMeSummaryOf = forMeSummaryOf;
12158
13579
 
12159
- exports.formatDate = formatDate;
12160
-
12161
- exports.formatShortAgo = formatShortAgo;
12162
-
12163
- exports.formatShortDateTime = formatShortDateTime;
13580
+ exports.forMeTaskRowsOf = forMeTaskRowsOf;
12164
13581
 
12165
13582
  exports.formatTimeAgo = formatTimeAgo;
12166
13583
 
@@ -12172,31 +13589,51 @@ exports.instanceBreadcrumb = instanceBreadcrumb;
12172
13589
 
12173
13590
  exports.instanceTitle = instanceTitle;
12174
13591
 
12175
- exports.isDueDatePast = isDueDatePast;
12176
-
12177
13592
  exports.isEvaluationStale = isEvaluationStale;
12178
13593
 
12179
- exports.isHandsOff = isHandsOff;
12180
-
12181
13594
  exports.isLiveEntry = isLiveEntry;
12182
13595
 
12183
- exports.isOpenActivityStatus = isOpenActivityStatus;
12184
-
12185
13596
  exports.landingState = landingState;
12186
13597
 
12187
13598
  exports.mappingIssueDetail = mappingIssueDetail;
12188
13599
 
12189
13600
  exports.namesNoDeployedDefinition = namesNoDeployedDefinition;
12190
13601
 
13602
+ exports.noReleaseRunCount = noReleaseRunCount;
13603
+
12191
13604
  exports.openActivityGone = openActivityGone;
12192
13605
 
12193
13606
  exports.openableSchemaType = openableSchemaType;
12194
13607
 
12195
- exports.parseStoredDateValue = parseStoredDateValue;
13608
+ exports.overdueAttentionHint = overdueAttentionHint;
13609
+
13610
+ exports.overdueRunDetail = overdueRunDetail;
12196
13611
 
12197
13612
  exports.readDeployedDefinitions = readDeployedDefinitions;
12198
13613
 
12199
- exports.shortSpanOf = shortSpanOf;
13614
+ exports.resolveForMeAddress = resolveForMeAddress;
13615
+
13616
+ exports.rowHasTaskHeldBy = rowHasTaskHeldBy;
13617
+
13618
+ exports.runAttentionCounts = runAttentionCounts;
13619
+
13620
+ exports.runCountsByAssignee = runCountsByAssignee;
13621
+
13622
+ exports.runCountsByRelease = runCountsByRelease;
13623
+
13624
+ exports.runCountsByRole = runCountsByRole;
13625
+
13626
+ exports.runCountsByStage = runCountsByStage;
13627
+
13628
+ exports.runCountsByWorkflow = runCountsByWorkflow;
13629
+
13630
+ exports.runRowsOf = runRowsOf;
13631
+
13632
+ exports.runsScopeOf = runsScopeOf;
13633
+
13634
+ exports.scrollParentOf = scrollParentOf;
13635
+
13636
+ exports.stageTasksOf = stageTasksOf;
12200
13637
 
12201
13638
  exports.stageTitle = stageTitle;
12202
13639
 
@@ -12206,7 +13643,9 @@ exports.toolRoute = toolRoute;
12206
13643
 
12207
13644
  exports.toolTabState = toolTabState;
12208
13645
 
12209
- exports.uniqueIds = uniqueIds;
13646
+ exports.unassignedRunCount = unassignedRunCount;
13647
+
13648
+ exports.useAlertChipSize = useAlertChipSize;
12210
13649
 
12211
13650
  exports.useAssignmentIdentity = useAssignmentIdentity;
12212
13651
 
@@ -12232,6 +13671,8 @@ exports.useReleaseTitles = useReleaseTitles;
12232
13671
 
12233
13672
  exports.useSpaceToken = useSpaceToken;
12234
13673
 
13674
+ exports.useTableStyles = useTableStyles;
13675
+
12235
13676
  exports.useTextIconSize = useTextIconSize;
12236
13677
 
12237
13678
  exports.useUserDisplays = useUserDisplays;