@sanity/workflow-studio-plugin 0.32.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,23 +2,23 @@ import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
2
 
3
3
  import { TimelineIcon } from "@sanity/icons/Timeline";
4
4
 
5
- import { Popover, Tooltip, Box, Stack, Text, useClickOutsideEvent, Flex, TextInput, Button, Select, Checkbox, Autocomplete, Card, TextArea, useToast, Dialog, Switch, useTheme_v2, TextSkeleton, Code, Badge, Spinner, MenuButton, Menu, MenuItem, useElementSize, MenuDivider, TabList, Tab, TabPanel } from "@sanity/ui";
5
+ import { useClickOutsideEvent, Popover, Box, Flex, TextInput, Button, Select, Checkbox, Text, Stack, Autocomplete, Card, TextArea, useToast, Dialog, Switch, useTheme_v2, TextSkeleton, Code, Badge, Spinner, MenuButton, Menu, MenuItem, useElementSize, MenuDivider, TabList, Tab, TabPanel } from "@sanity/ui";
6
6
 
7
7
  import { editFieldTarget, useWorkflowTelemetry, useRefcountedIds } from "@sanity/workflow-react";
8
8
 
9
- import { createContext, useContext, useEffect, useSyncExternalStore, useCallback, Fragment as Fragment$1, useRef, useMemo, useState, createElement, isValidElement, useId, useLayoutEffect, Component, useEffectEvent, lazy, Suspense } from "react";
9
+ import { createContext, useContext, useEffect, useSyncExternalStore, useCallback, Fragment as Fragment$1, useRef, useMemo, useState, createElement, isValidElement, useId, useLayoutEffect, Component, useEffectEvent, lazy, Suspense, memo } from "react";
10
10
 
11
11
  import { usePaneRouter } from "sanity/structure";
12
12
 
13
- import { WORKFLOW_INSTANCE_TYPE, WORKFLOW_DEFINITION_TYPE, GUARD_DOC_TYPE, tryParseGdr, resourceFromParsed, latestDeployedDefinitions, isStartableDefinition, isSubjectEntry, isInputSourced, acceptsDocumentType, initialFieldIssues, gdrRef, releaseRef, refKindAcceptsTypes, rejectedRefTypes, ActionDisabledError, MutationGuardDeniedError, EditFieldDeniedError, errorMessage, actionRendering, terminalState, findOpenStageEntry, isTodoListEntry, isTodoListItem, isTerminalActivityStatus, assignmentMembers, describeCondition, sentenceCase, checklistLines, findCurrentActivityEntry, ENGINE_API_VERSION, userLoginProvider, classifyPrincipalId, scalarValidationIssues, toBareId, findStageNode, findActivityNode, isSingleDocRefEntry, isGdr, resolveFieldEntry, isSingleDocRefKind, isNotesEntry, remediationsFor, diagnoseInstance, diagnoseInputFromEvaluation, documentStuckCause, parseDefinitionSnapshot, isUnprimed, isTerminalStage, DEFAULT_TRANSITION_WHEN, instancesQuery, assertReadableModel, projectStartSliceRow, StartNotSettledError, StartNotAllowedError, isRevisionConflict, humanize, unboundRequirementReads, explainStartRequirement, singleSubjectRequirementRefused, evaluateStartFilter, startKindOf, hasSingleSubjectRequirement, readsRootDocument, latestDefinitionsGroq, gdrFromResource, subscriptionDocumentsForInstance, aclPathForResource, documentActionDenials, definitionLookupGroq, instanceDocId, missingRequiredInputs, clientGuardDereference } from "@sanity/workflow-engine";
13
+ import { WORKFLOW_INSTANCE_TYPE, WORKFLOW_DEFINITION_TYPE, GUARD_DOC_TYPE, tryParseGdr, resourceFromParsed, latestDeployedDefinitions, isStartableDefinition, isSubjectEntry, isInputSourced, acceptsDocumentType, initialFieldIssues, gdrRef, releaseRef, refKindAcceptsTypes, rejectedRefTypes, ActionDisabledError, MutationGuardDeniedError, EditFieldDeniedError, errorMessage, actionRendering, terminalState, findOpenStageEntry, isTodoListEntry, isTodoListItem, isTerminalActivityStatus, assignmentMembers, describeCondition, sentenceCase, checklistLines, findCurrentActivityEntry, ENGINE_API_VERSION, userLoginProvider, classifyPrincipalId, scalarValidationIssues, toBareId, findStageNode, findActivityNode, isSingleDocRefEntry, isGdr, resolveFieldEntry, isSingleDocRefKind, isNotesEntry, remediationsFor, _additionalMissingDocuments, _missingDocumentsSummary, diagnoseInstance, diagnoseInputFromEvaluation, documentStuckCause, parseDefinitionSnapshot, isUnprimed, isTerminalStage, DEFAULT_TRANSITION_WHEN, instancesQuery, assertReadableModel, projectStartSliceRow, StartNotSettledError, StartNotAllowedError, isRevisionConflict, humanize, unboundRequirementReads, explainStartRequirement, singleSubjectRequirementRefused, evaluateStartFilter, startKindOf, hasSingleSubjectRequirement, readsRootDocument, latestDefinitionsGroq, gdrFromResource, subscriptionDocumentsForInstance, aclPathForResource, documentActionDenials, definitionLookupGroq, instanceDocId, missingRequiredInputs, clientGuardDereference, deriveWorkflowAutonomy, deriveExecutorClassification, entryDocRefs, openActivityAssignments, assignmentState, activeAssignmentMembers } from "@sanity/workflow-engine";
14
14
 
15
15
  import { CheckmarkIcon } from "@sanity/icons/Checkmark";
16
16
 
17
17
  import { CloseIcon } from "@sanity/icons/Close";
18
18
 
19
- import { formatDistanceToNow } from "date-fns/formatDistanceToNow";
19
+ import { _formatShortDateTime, assignmentMatch, sameAssignee, projectMemberRow, providerTitle, ClearableDatePicker, AssigneePicker as AssigneePicker$1, MemberPicker as MemberPicker$1, MemberAvatar, _HoverHint, AssigneeBadges as AssigneeBadges$1, AssigneeBadge as AssigneeBadge$1, _useDelayedFlag, ProgressBar, memberRoleFor, AssigneeStack, roleLabel, ActivityStatusIcon, clampProgress, MemberAvatarGroup, progressCaption, DatePicker, roleLabelFor, roleListLabel, AgoStamp, StartIncompleteBadge, _CheckmarkCircleFilledIcon, _shortSpanOf, roleMemberCount, memberCountLabel, _formatShortAgo } from "@sanity/workflow-components";
20
20
 
21
- import { assignmentMatch, sameAssignee, projectMemberRow, providerTitle, ClearableDatePicker, AssigneePicker as AssigneePicker$1, MemberPicker as MemberPicker$1, MemberAvatar, AssigneeBadges as AssigneeBadges$1, AssigneeBadge as AssigneeBadge$1, ProgressBar, memberRoleFor, AssigneeStack, roleLabel, clampProgress, MemberAvatarGroup, progressCaption, DatePicker, roleLabelFor, roleListLabel } from "@sanity/workflow-components";
21
+ import { formatDistanceToNow } from "date-fns/formatDistanceToNow";
22
22
 
23
23
  import { getPublishedId, getDraftId } from "@sanity/client/csm";
24
24
 
@@ -48,16 +48,12 @@ import { IntentLink, route } from "sanity/router";
48
48
 
49
49
  import { isDocumentSchemaType } from "@sanity/types";
50
50
 
51
+ import { useKeyed } from "@sanity/workflow-react/observer";
52
+
51
53
  import { LaunchIcon } from "@sanity/icons/Launch";
52
54
 
53
55
  import { ErrorOutlineIcon } from "@sanity/icons/ErrorOutline";
54
56
 
55
- import { EmptyIcon } from "@sanity/icons/Empty";
56
-
57
- import { ErrorFilledIcon } from "@sanity/icons/ErrorFilled";
58
-
59
- import { RemoveCircleIcon } from "@sanity/icons/RemoveCircle";
60
-
61
57
  import { AddUserIcon } from "@sanity/icons/AddUser";
62
58
 
63
59
  import { AddIcon } from "@sanity/icons/Add";
@@ -86,10 +82,14 @@ import { ArrowUpIcon } from "@sanity/icons/ArrowUp";
86
82
 
87
83
  import { of } from "rxjs";
88
84
 
89
- import { switchMap, distinctUntilChanged } from "rxjs/operators";
85
+ import { switchMap, startWith, distinctUntilChanged } from "rxjs/operators";
90
86
 
91
87
  import { TransferIcon } from "@sanity/icons/Transfer";
92
88
 
89
+ import { UsersIcon } from "@sanity/icons/Users";
90
+
91
+ import { useVirtualizer } from "@tanstack/react-virtual";
92
+
93
93
  const WORKFLOW_SYSTEM_TYPES = [ WORKFLOW_INSTANCE_TYPE, WORKFLOW_DEFINITION_TYPE, GUARD_DOC_TYPE ];
94
94
 
95
95
  function contentDocumentTypes(schema) {
@@ -464,17 +464,6 @@ function formatDateTime(value) {
464
464
  return Number.isNaN(d.getTime()) ? "—" : d.toLocaleString();
465
465
  }
466
466
 
467
- function formatShortDateTime(value) {
468
- const d = new Date(value);
469
- return Number.isNaN(d.getTime()) ? "—" : d.toLocaleString(void 0, {
470
- day: "numeric",
471
- month: "short",
472
- year: "numeric",
473
- hour: "2-digit",
474
- minute: "2-digit"
475
- });
476
- }
477
-
478
467
  function formatTimeAgo(value) {
479
468
  const d = new Date(value);
480
469
  return Number.isNaN(d.getTime()) ? "" : formatDistanceToNow(d, {
@@ -482,32 +471,13 @@ function formatTimeAgo(value) {
482
471
  });
483
472
  }
484
473
 
485
- function formatShortAgo(value, now) {
486
- const span = formatShortSpan(value, now);
487
- return span === "—" ? "—" : span === "now" ? "just now" : `${span} ago`;
488
- }
489
-
490
- function formatShortSpan(value, now) {
491
- return shortSpanOf(new Date(value), now);
492
- }
493
-
494
- function shortSpanOf(from, now) {
495
- if (from === void 0 || Number.isNaN(from.getTime())) return "—";
496
- const seconds = Math.floor((now.getTime() - from.getTime()) / 1e3);
497
- if (seconds < 60) return "now";
498
- const minutes = Math.floor(seconds / 60);
499
- if (minutes < 60) return `${minutes}m`;
500
- const hours = Math.floor(minutes / 60);
501
- return hours < 24 ? `${hours}h` : `${Math.floor(hours / 24)}d`;
502
- }
503
-
504
474
  function stampFace(verb, at) {
505
475
  const ago = formatTimeAgo(at);
506
476
  return ago === "" ? {
507
- lead: `${verb} ${formatShortDateTime(at)}`
477
+ lead: `${verb} ${_formatShortDateTime(at)}`
508
478
  } : {
509
479
  lead: `${verb} ${ago}`,
510
- detail: formatShortDateTime(at)
480
+ detail: _formatShortDateTime(at)
511
481
  };
512
482
  }
513
483
 
@@ -522,7 +492,7 @@ function formatDate(value) {
522
492
  }
523
493
 
524
494
  function formatDueMoment(value) {
525
- return storedDateKind(value) === "date" ? formatDate(value) : formatShortDateTime(value);
495
+ return storedDateKind(value) === "date" ? formatDate(value) : _formatShortDateTime(value);
526
496
  }
527
497
 
528
498
  function dueMomentSentence(value, now) {
@@ -1656,105 +1626,6 @@ function buildParams(decls, values) {
1656
1626
  };
1657
1627
  }
1658
1628
 
1659
- const LOADING_CUE_DELAY_MS = 400;
1660
-
1661
- function useDelayedFlag(active, delayMs) {
1662
- const [held, setHeld] = useState(!1);
1663
- return useEffect(() => {
1664
- if (!active) {
1665
- setHeld(!1);
1666
- return;
1667
- }
1668
- const timer = setTimeout(() => setHeld(!0), delayMs);
1669
- return () => clearTimeout(timer);
1670
- }, [ active, delayMs ]), held && active;
1671
- }
1672
-
1673
- const NEVER_MS = 2 ** 31 - 1, OPEN_DELAY_MS = 300;
1674
-
1675
- function HoverHint(props) {
1676
- return props.anchor !== void 0 ? /* @__PURE__ */ jsx(AnchoredHint, {
1677
- ...props
1678
- }) : /* @__PURE__ */ jsx(WrappingHint, {
1679
- ...props
1680
- });
1681
- }
1682
-
1683
- function AnchoredHint(props) {
1684
- const {disabled: disabled = !1} = props, open = useDelayedFlag(props.open === !0 && !disabled, OPEN_DELAY_MS);
1685
- /* @__PURE__ */
1686
- return jsx(Popover, {
1687
- animate: !0,
1688
- content: /* @__PURE__ */ jsx(HintBody, {
1689
- ...props
1690
- }),
1691
- open: open,
1692
- padding: hintPadding(props),
1693
- placement: props.placement ?? "top",
1694
- portal: !0,
1695
- radius: 3,
1696
- referenceElement: props.anchor
1697
- });
1698
- }
1699
-
1700
- function hintPadding(props) {
1701
- return props.content !== void 0 && props.flush ? 0 : 2;
1702
- }
1703
-
1704
- function WrappingHint(props) {
1705
- const {children: children, disabled: disabled = !1} = props;
1706
- /* @__PURE__ */
1707
- return jsx(Tooltip, {
1708
- animate: !0,
1709
- content: disabled ? null : /* @__PURE__ */ jsx(HintBody, {
1710
- ...props
1711
- }),
1712
- delay: {
1713
- close: 0,
1714
- open: disabled ? NEVER_MS : OPEN_DELAY_MS
1715
- },
1716
- padding: hintPadding(props),
1717
- placement: props.placement ?? "top",
1718
- portal: !0,
1719
- radius: 3,
1720
- children: /* @__PURE__ */ jsx(Box, {
1721
- "data-testid": props["data-testid"],
1722
- style: {
1723
- display: props.fill ? "flex" : "inline-flex",
1724
- maxWidth: "100%",
1725
- ...props.fill ? {
1726
- width: "100%"
1727
- } : {}
1728
- },
1729
- children: children
1730
- })
1731
- });
1732
- }
1733
-
1734
- function HintBody(props) {
1735
- /* @__PURE__ */
1736
- return jsx(Box, {
1737
- style: {
1738
- maxWidth: props.content !== void 0 && props.wide ? 400 : 280
1739
- },
1740
- children: props.content !== void 0 ? props.content : /* @__PURE__ */ jsxs(Stack, {
1741
- gap: 3,
1742
- children: [
1743
- /* @__PURE__ */ jsx(Text, {
1744
- size: 1,
1745
- ...props.textWeight === void 0 ? {} : {
1746
- weight: props.textWeight
1747
- },
1748
- children: props.text
1749
- }), props.description === void 0 ? null : /* @__PURE__ */ jsx(Text, {
1750
- muted: !0,
1751
- size: 1,
1752
- children: props.description
1753
- }) ]
1754
- })
1755
- });
1756
- }
1757
-
1758
1629
  function textInputFacet(kind) {
1759
1630
  return kind === "number" || kind === "progress" ? {
1760
1631
  type: "number"
@@ -2163,7 +2034,7 @@ function DocRefsInput({value: value, onChange: onChange, types: types}) {
2163
2034
  type: ref.type
2164
2035
  })
2165
2036
  }),
2166
- /* @__PURE__ */ jsx(HoverHint, {
2037
+ /* @__PURE__ */ jsx(_HoverHint, {
2167
2038
  text: "Remove",
2168
2039
  children: /* @__PURE__ */ jsx(Button, {
2169
2040
  "aria-label": "Remove",
@@ -2497,7 +2368,7 @@ function DisabledActionButton({actionEval: actionEval, activity: activity, chrom
2497
2368
  ...spanTriggerProps(chrome),
2498
2369
  disabled: !0
2499
2370
  });
2500
- return actionEval.disabledReason ? /* @__PURE__ */ jsx(HoverHint, {
2371
+ return actionEval.disabledReason ? /* @__PURE__ */ jsx(_HoverHint, {
2501
2372
  text: describeDisabledReason(actionEval.disabledReason),
2502
2373
  children: button
2503
2374
  }) : button;
@@ -2519,7 +2390,7 @@ function PlainActionButton({actionEval: actionEval, instanceId: instanceId, acti
2519
2390
  surface: surface,
2520
2391
  tone: btn.tone
2521
2392
  });
2522
- return action.description ? /* @__PURE__ */ jsx(HoverHint, {
2393
+ return action.description ? /* @__PURE__ */ jsx(_HoverHint, {
2523
2394
  text: action.description,
2524
2395
  children: button
2525
2396
  }) : button;
@@ -2699,10 +2570,10 @@ function InfoHint({content: content, label: label}) {
2699
2570
  size: 0,
2700
2571
  children: /* @__PURE__ */ jsx(InfoOutlineIcon, {})
2701
2572
  });
2702
- return typeof content == "string" ? /* @__PURE__ */ jsx(HoverHint, {
2573
+ return typeof content == "string" ? /* @__PURE__ */ jsx(_HoverHint, {
2703
2574
  text: content,
2704
2575
  children: icon
2705
- }) : /* @__PURE__ */ jsx(HoverHint, {
2576
+ }) : /* @__PURE__ */ jsx(_HoverHint, {
2706
2577
  content: content,
2707
2578
  children: icon
2708
2579
  });
@@ -2802,6 +2673,8 @@ function FieldInput$1({kind: kind, value: value, onChange: onChange, onEnter: on
2802
2673
  }
2803
2674
  }
2804
2675
 
2676
+ const LOADING_CUE_DELAY_MS = 400;
2677
+
2805
2678
  function isCompact(layout) {
2806
2679
  return layout === "inline" || layout === "row";
2807
2680
  }
@@ -2913,7 +2786,7 @@ function useChipTrim() {
2913
2786
 
2914
2787
  function LinkChip({hint: hint, children: children, as: as = "a", fill: fill = !1, ...anchorProps}) {
2915
2788
  /* @__PURE__ */
2916
- return jsx(HoverHint, {
2789
+ return jsx(_HoverHint, {
2917
2790
  fill: fill,
2918
2791
  text: hint,
2919
2792
  children: /* @__PURE__ */ jsx(Card, {
@@ -2939,6 +2812,8 @@ function LinkChip({hint: hint, children: children, as: as = "a", fill: fill = !1
2939
2812
  });
2940
2813
  }
2941
2814
 
2815
+ const UNREADABLE_DOCUMENT = /* @__PURE__ */ Symbol("unreadable document");
2816
+
2942
2817
  function docLinkState(input) {
2943
2818
  const {bareId: bareId, resource: resource} = input;
2944
2819
  if (bareId === void 0 || resource === void 0) return {
@@ -2981,6 +2856,23 @@ function openableSchemaType(schema, typeName) {
2981
2856
  if (!(entry === void 0 || !isDocumentSchemaType(entry) || entry.name === "document")) return entry;
2982
2857
  }
2983
2858
 
2859
+ function snapshotOf(store, ids) {
2860
+ let snapshot = /* @__PURE__ */ new Map;
2861
+ return () => {
2862
+ const next = new Map(ids.map(id => [ id, store.read(id) ]));
2863
+ return (next.size !== snapshot.size || ids.some(id => next.get(id) !== snapshot.get(id))) && (snapshot = next),
2864
+ snapshot;
2865
+ };
2866
+ }
2867
+
2868
+ function useActualDocTypes(ids) {
2869
+ const {actualTypes: actualTypes} = useWorkflowContext(), uniqueIds2 = [ ...new Set(ids) ].sort(), trackedIds = useKeyed([ JSON.stringify(uniqueIds2) ], () => uniqueIds2);
2870
+ return useEffect(() => {
2871
+ const releases = trackedIds.map(id => actualTypes.track(id));
2872
+ return () => releases.forEach(release => release());
2873
+ }, [ actualTypes, trackedIds ]), useSyncExternalStore(actualTypes.subscribe, useMemo(() => snapshotOf(actualTypes, trackedIds), [ actualTypes, trackedIds ]));
2874
+ }
2875
+
2984
2876
  function useLocalDocRef(gdr) {
2985
2877
  const {binding: binding} = useWorkflowContext(), schema = useSchema(), schemaType = gdr === void 0 ? void 0 : schema.get(gdr.type);
2986
2878
  return {
@@ -2991,10 +2883,8 @@ function useLocalDocRef(gdr) {
2991
2883
  }
2992
2884
 
2993
2885
  function useActualDocType(bareId) {
2994
- const {actualTypes: actualTypes} = useWorkflowContext();
2995
- return useEffect(() => {
2996
- if (bareId !== null) return actualTypes.track(bareId);
2997
- }, [ actualTypes, bareId ]), useSyncExternalStore(actualTypes.subscribe, useCallback(() => bareId === null ? void 0 : actualTypes.read(bareId), [ actualTypes, bareId ]));
2886
+ const ids = useMemo(() => bareId === null ? [] : [ bareId ], [ bareId ]);
2887
+ return useActualDocTypes(ids).get(bareId ?? "");
2998
2888
  }
2999
2889
 
3000
2890
  function useDocLink(gdr) {
@@ -3151,7 +3041,7 @@ function CompactDocRef({face: face, fill: fill, link: link, onClick: onClick}) {
3151
3041
  const PENDING_FACE_MAX_WAIT_MS = 4e3;
3152
3042
 
3153
3043
  function PendingDocFace({bareId: bareId, layout: layout}) {
3154
- const expired = useDelayedFlag(!0, PENDING_FACE_MAX_WAIT_MS), compact = isCompact(layout);
3044
+ const expired = _useDelayedFlag(!0, PENDING_FACE_MAX_WAIT_MS), compact = isCompact(layout);
3155
3045
  if (expired) {
3156
3046
  const id = /* @__PURE__ */ jsx(Text, {
3157
3047
  muted: !0,
@@ -3690,7 +3580,7 @@ function EditableFieldControl({instanceId: instanceId, field: field, surface: su
3690
3580
 
3691
3581
  function EditableValueButton({children: children, hint: hint, hintDisabled: hintDisabled = !1, onClick: onClick}) {
3692
3582
  /* @__PURE__ */
3693
- return jsx(HoverHint, {
3583
+ return jsx(_HoverHint, {
3694
3584
  disabled: hintDisabled,
3695
3585
  text: hint,
3696
3586
  children: /* @__PURE__ */ jsx(Button, {
@@ -3974,7 +3864,7 @@ function FieldEditRow({field: field, onSave: onSave, onCancel: onCancel, saving:
3974
3864
  }
3975
3865
  })
3976
3866
  }),
3977
- /* @__PURE__ */ jsx(HoverHint, {
3867
+ /* @__PURE__ */ jsx(_HoverHint, {
3978
3868
  text: "Save",
3979
3869
  children: /* @__PURE__ */ jsx(Button, {
3980
3870
  "aria-label": "Save",
@@ -3986,7 +3876,7 @@ function FieldEditRow({field: field, onSave: onSave, onCancel: onCancel, saving:
3986
3876
  padding: 2
3987
3877
  })
3988
3878
  }),
3989
- /* @__PURE__ */ jsx(HoverHint, {
3879
+ /* @__PURE__ */ jsx(_HoverHint, {
3990
3880
  text: "Cancel",
3991
3881
  children: /* @__PURE__ */ jsx(Button, {
3992
3882
  "aria-label": "Cancel",
@@ -4194,7 +4084,7 @@ const ACTION_LABEL = {
4194
4084
  "set-stage": "Move the workflow on to its next stage yourself."
4195
4085
  };
4196
4086
 
4197
- function detailOf(cause) {
4087
+ function detailOf(cause, missingSummary) {
4198
4088
  switch (cause.kind) {
4199
4089
  case "failed-effect":
4200
4090
  return `The step “${effectLabel(cause.effect)}” failed`;
@@ -4206,12 +4096,15 @@ function detailOf(cause) {
4206
4096
  return "This task failed";
4207
4097
 
4208
4098
  default:
4209
- return summaryOf(cause);
4099
+ return summaryOf(cause, missingSummary);
4210
4100
  }
4211
4101
  }
4212
4102
 
4213
- function summaryOf(cause) {
4103
+ function summaryOf(cause, missingSummary) {
4214
4104
  switch (cause.kind) {
4105
+ case "document-missing":
4106
+ return missingSummary;
4107
+
4215
4108
  case "failed-effect":
4216
4109
  return "An automated step failed";
4217
4110
 
@@ -4229,6 +4122,10 @@ function summaryOf(cause) {
4229
4122
  }
4230
4123
  }
4231
4124
 
4125
+ function withMissingDocuments(title, missingSummary) {
4126
+ return missingSummary ? `${title}. ${missingSummary}` : title;
4127
+ }
4128
+
4232
4129
  function activityDeclaringEffect(args) {
4233
4130
  return findStageNode(args)?.activities?.find(activity => (activity.actions ?? []).some(action => (action.effects ?? []).some(effect => effect.name === args.effectName)))?.name;
4234
4131
  }
@@ -4262,15 +4159,15 @@ function diagnosisOf(args) {
4262
4159
  function instanceFault(args) {
4263
4160
  const diagnosis = diagnosisOf(args);
4264
4161
  if (diagnosis === void 0 || diagnosis.state !== "stuck") return;
4265
- const verbs = remediationsFor(diagnosis).map(remediation2 => remediation2.verb);
4162
+ const verbs = remediationsFor(diagnosis).map(remediation2 => remediation2.verb), additional = _additionalMissingDocuments(diagnosis, args.evaluation?.missingDocuments), missingSummary = _missingDocumentsSummary(diagnosis.cause.kind === "document-missing" ? diagnosis.cause.documents : additional), additionalSummary = additional.length > 0 ? missingSummary : "";
4266
4163
  return {
4267
4164
  activity: faultingActivity({
4268
4165
  cause: diagnosis.cause,
4269
4166
  definition: args.definition,
4270
4167
  stageName: args.instance.currentStage
4271
4168
  }),
4272
- detail: detailOf(diagnosis.cause),
4273
- summary: summaryOf(diagnosis.cause),
4169
+ detail: withMissingDocuments(detailOf(diagnosis.cause, missingSummary), additionalSummary),
4170
+ summary: withMissingDocuments(summaryOf(diagnosis.cause, missingSummary), additionalSummary),
4274
4171
  remedies: verbs.flatMap(verb => REMEDY_TEXT[verb] ?? []),
4275
4172
  actions: verbs.flatMap(verb => isRunnable(verb) ? [ {
4276
4173
  verb: verb,
@@ -4315,7 +4212,7 @@ function AbortedBadge({instance: instance}) {
4315
4212
 
4316
4213
  function OlderDefinitionBadge({instance: instance}) {
4317
4214
  const {latestDefinitionVersions: latestDefinitionVersions} = useWorkflowContext(), latest = latestDefinitionVersions.get(instance.definition);
4318
- return latest === void 0 || latest <= instance.pinnedVersion ? null : /* @__PURE__ */ jsx(HoverHint, {
4215
+ return latest === void 0 || latest <= instance.pinnedVersion ? null : /* @__PURE__ */ jsx(_HoverHint, {
4319
4216
  description: "Running workflows keep the version they started on",
4320
4217
  text: `Started on v${instance.pinnedVersion}, latest is now v${latest}`,
4321
4218
  textWeight: "medium",
@@ -4470,7 +4367,7 @@ function RowAssignees({assignees: assignees, hint: hint}) {
4470
4367
  if (ids.length === 0 && roles.length === 0) return null;
4471
4368
  const bothKinds = roles.length > 0 && displays.length > 0;
4472
4369
  /* @__PURE__ */
4473
- return jsx(HoverHint, {
4370
+ return jsx(_HoverHint, {
4474
4371
  content: /* @__PURE__ */ jsxs(Stack, {
4475
4372
  gap: 3,
4476
4373
  children: [ roles.length > 0 ? /* @__PURE__ */ jsx(HintSection, {
@@ -4539,61 +4436,8 @@ function OverlineHeading({children: children}) {
4539
4436
  });
4540
4437
  }
4541
4438
 
4542
- function CheckmarkCircleFilledIcon(props) {
4543
- /* @__PURE__ */
4544
- return jsx("svg", {
4545
- "data-sanity-icon": "checkmark-circle-filled",
4546
- fill: "none",
4547
- height: "1em",
4548
- viewBox: "0 0 25 25",
4549
- width: "1em",
4550
- xmlns: "http://www.w3.org/2000/svg",
4551
- ...props,
4552
- children: /* @__PURE__ */ jsx("path", {
4553
- clipRule: "evenodd",
4554
- 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",
4555
- fill: "currentColor",
4556
- fillRule: "evenodd"
4557
- })
4558
- });
4559
- }
4560
-
4561
- const STATUS_ICON = /* @__PURE__ */ new Map([ [ "active", {
4562
- icon: EmptyIcon,
4563
- muted: !1
4564
- } ], [ "done", {
4565
- icon: CheckmarkCircleFilledIcon,
4566
- muted: !1
4567
- } ], [ "failed", {
4568
- icon: ErrorFilledIcon,
4569
- muted: !1
4570
- } ], [ "skipped", {
4571
- icon: RemoveCircleIcon,
4572
- muted: !0
4573
- } ] ]);
4574
-
4575
- function ActivityStatusIcon({status: status}) {
4576
- const {icon: Icon, muted: muted} = STATUS_ICON.get(status) ?? {
4577
- icon: EmptyIcon,
4578
- muted: !0
4579
- };
4580
- return status === "failed" ? /* @__PURE__ */ jsx(TextWithTone, {
4581
- size: 1,
4582
- tone: "critical",
4583
- children: /* @__PURE__ */ jsx(Icon, {
4584
- style: {
4585
- color: "inherit"
4586
- }
4587
- })
4588
- }) : /* @__PURE__ */ jsx(Text, {
4589
- muted: muted,
4590
- size: 1,
4591
- children: /* @__PURE__ */ jsx(Icon, {})
4592
- });
4593
- }
4594
-
4595
4439
  function SpinnerSlot({busy: busy, reserve: reserve = !0}) {
4596
- const size = useTextIconSize(), trim = useCapTrimFor(size), spinning = useDelayedFlag(busy, LOADING_CUE_DELAY_MS);
4440
+ const size = useTextIconSize(), trim = useCapTrimFor(size), spinning = _useDelayedFlag(busy, LOADING_CUE_DELAY_MS);
4597
4441
  return !spinning && !reserve ? null : /* @__PURE__ */ jsx(Flex, {
4598
4442
  align: "center",
4599
4443
  flex: "none",
@@ -4612,7 +4456,7 @@ function SpinnerSlot({busy: busy, reserve: reserve = !0}) {
4612
4456
  }
4613
4457
 
4614
4458
  function LoadingRow({label: label, padding: padding}) {
4615
- const announced = useDelayedFlag(!0, LOADING_CUE_DELAY_MS);
4459
+ const announced = _useDelayedFlag(!0, LOADING_CUE_DELAY_MS);
4616
4460
  /* @__PURE__ */
4617
4461
  return jsxs(Flex, {
4618
4462
  align: "center",
@@ -4736,7 +4580,7 @@ function AssignActivityControl({instanceId: instanceId, state: state, surface: s
4736
4580
  }),
4737
4581
  onClick: handleClick,
4738
4582
  onMouseDown: stopRowMouseDown
4739
- }) : /* @__PURE__ */ jsx(HoverHint, {
4583
+ }) : /* @__PURE__ */ jsx(_HoverHint, {
4740
4584
  disabled: open,
4741
4585
  text: "Assign",
4742
4586
  children: /* @__PURE__ */ jsx(Button, {
@@ -4876,7 +4720,7 @@ function DueDate({dueDate: dueDate, hintDisabled: hintDisabled, overdue: overdue
4876
4720
  return face === void 0 ? text :
4877
4721
  /* @__PURE__ */ jsx(Flex, {
4878
4722
  align: "center",
4879
- children: /* @__PURE__ */ jsx(HoverHint, {
4723
+ children: /* @__PURE__ */ jsx(_HoverHint, {
4880
4724
  ...face,
4881
4725
  disabled: hintDisabled === !0,
4882
4726
  children: text
@@ -4959,7 +4803,7 @@ function DueDateControl({item: item, editable: editable, onPatch: onPatch}) {
4959
4803
  padding: 2,
4960
4804
  tone: overdue ? "caution" : "default",
4961
4805
  children: display
4962
- }) : /* @__PURE__ */ jsx(HoverHint, {
4806
+ }) : /* @__PURE__ */ jsx(_HoverHint, {
4963
4807
  disabled: open,
4964
4808
  text: "Set due date",
4965
4809
  children: /* @__PURE__ */ jsx(Button, {
@@ -4996,7 +4840,7 @@ function AssigneeControl({item: item, editable: editable, eligibleRoles: eligibl
4996
4840
  "aria-label": "Reassign",
4997
4841
  avatar: chip,
4998
4842
  onClick: () => setOpen(v => !v)
4999
- }) : /* @__PURE__ */ jsx(HoverHint, {
4843
+ }) : /* @__PURE__ */ jsx(_HoverHint, {
5000
4844
  disabled: open,
5001
4845
  text: "Assign",
5002
4846
  children: /* @__PURE__ */ jsx(Button, {
@@ -5058,7 +4902,7 @@ function AddItemControl({onAdd: onAdd, button: button, busy: busy}) {
5058
4902
 
5059
4903
  function RemoveItemButton({onClick: onClick}) {
5060
4904
  /* @__PURE__ */
5061
- return jsx(HoverHint, {
4905
+ return jsx(_HoverHint, {
5062
4906
  text: "Remove item",
5063
4907
  children: /* @__PURE__ */ jsx(Button, {
5064
4908
  "aria-label": "Remove item",
@@ -5162,7 +5006,7 @@ function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle,
5162
5006
  }),
5163
5007
  lead:
5164
5008
  /* @__PURE__ */ jsx(CheckboxSlot, {
5165
- children: hint === void 0 ? checkbox : /* @__PURE__ */ jsx(HoverHint, {
5009
+ children: hint === void 0 ? checkbox : /* @__PURE__ */ jsx(_HoverHint, {
5166
5010
  text: hint,
5167
5011
  children: checkbox
5168
5012
  })
@@ -5374,7 +5218,7 @@ function hintContent(hint) {
5374
5218
 
5375
5219
  function AutomationActionRow({actionEval: actionEval, definition: definition}) {
5376
5220
  /* @__PURE__ */
5377
- return jsx(HoverHint, {
5221
+ return jsx(_HoverHint, {
5378
5222
  content: hintContent(automationHint({
5379
5223
  actionEval: actionEval,
5380
5224
  definition: definition
@@ -6148,7 +5992,7 @@ function MetricText({children: children, tone: tone}) {
6148
5992
 
6149
5993
  function MetricPair({face: face, ...lockup}) {
6150
5994
  /* @__PURE__ */
6151
- return jsx(HoverHint, {
5995
+ return jsx(_HoverHint, {
6152
5996
  ...face,
6153
5997
  children: /* @__PURE__ */ jsx(MetricLockup, {
6154
5998
  ...lockup
@@ -6183,7 +6027,7 @@ function MetricLockup({Icon: Icon, empty: empty, label: label, tone: tone, value
6183
6027
 
6184
6028
  function AlertGlyph({Icon: Icon, hint: hint, label: label, tone: tone}) {
6185
6029
  /* @__PURE__ */
6186
- return jsx(HoverHint, {
6030
+ return jsx(_HoverHint, {
6187
6031
  text: hint,
6188
6032
  children: /* @__PURE__ */ jsx(TextWithTone, {
6189
6033
  size: 1,
@@ -6198,10 +6042,14 @@ function AlertGlyph({Icon: Icon, hint: hint, label: label, tone: tone}) {
6198
6042
  });
6199
6043
  }
6200
6044
 
6045
+ function useAlertChipSize() {
6046
+ return useTextIconSize() + useSpaceToken(1) * 2;
6047
+ }
6048
+
6201
6049
  function AlertChip({Icon: Icon, hint: hint, label: label, tone: tone}) {
6202
- const glyph = useTextIconSize(), disc = glyph + useSpaceToken(1) * 2;
6050
+ const glyph = useTextIconSize(), disc = useAlertChipSize();
6203
6051
  /* @__PURE__ */
6204
- return jsx(HoverHint, {
6052
+ return jsx(_HoverHint, {
6205
6053
  text: hint,
6206
6054
  children: /* @__PURE__ */ jsx(Card, {
6207
6055
  radius: "full",
@@ -6301,7 +6149,7 @@ function ActivityDateControl({instanceId: instanceId, state: state, surface: sur
6301
6149
  onMouseDown: stopRowMouseDown,
6302
6150
  padding: 2,
6303
6151
  children: dueDate()
6304
- }) : /* @__PURE__ */ jsx(HoverHint, {
6152
+ }) : /* @__PURE__ */ jsx(_HoverHint, {
6305
6153
  disabled: open,
6306
6154
  text: "Set date",
6307
6155
  children: /* @__PURE__ */ jsx(Button, {
@@ -6326,7 +6174,7 @@ function settledDim(settled) {
6326
6174
 
6327
6175
  function ActivityStatusLead({status: status}) {
6328
6176
  /* @__PURE__ */
6329
- return jsx(HoverHint, {
6177
+ return jsx(_HoverHint, {
6330
6178
  text: ACTIVITY_STATUS_LABEL[status],
6331
6179
  children: /* @__PURE__ */ jsx(ActivityStatusIcon, {
6332
6180
  status: status
@@ -6377,7 +6225,7 @@ function RowTerminalActions({actions: actions, activity: activity, instanceId: i
6377
6225
  function TitleTag({hint: hint, tone: tone, children: children}) {
6378
6226
  const badgeTrim = useBadgeCapTrim();
6379
6227
  /* @__PURE__ */
6380
- return jsx(HoverHint, {
6228
+ return jsx(_HoverHint, {
6381
6229
  text: hint,
6382
6230
  children: /* @__PURE__ */ jsx(Badge, {
6383
6231
  fontSize: 1,
@@ -6643,7 +6491,7 @@ function deriveFieldPills(args) {
6643
6491
  function UserAvatar({id: id}) {
6644
6492
  const {name: name, imageUrl: imageUrl} = useUserDisplay(id);
6645
6493
  /* @__PURE__ */
6646
- return jsx(HoverHint, {
6494
+ return jsx(_HoverHint, {
6647
6495
  text: name,
6648
6496
  children: /* @__PURE__ */ jsx(MemberAvatar, {
6649
6497
  imageUrl: imageUrl,
@@ -6654,7 +6502,7 @@ function UserAvatar({id: id}) {
6654
6502
 
6655
6503
  function UserAvatarGroup({ids: ids, hint: hint}) {
6656
6504
  const displays = useUserDisplays(ids);
6657
- return displays.length === 0 ? null : /* @__PURE__ */ jsx(HoverHint, {
6505
+ return displays.length === 0 ? null : /* @__PURE__ */ jsx(_HoverHint, {
6658
6506
  text: disambiguatedNames(displays).join(", "),
6659
6507
  ...hint === void 0 ? {} : {
6660
6508
  description: hint
@@ -6874,7 +6722,7 @@ function usePillChrome(face) {
6874
6722
  function PillHint({pill: pill, disabled: disabled = !1, children: children}) {
6875
6723
  const {description: description} = pill;
6876
6724
  /* @__PURE__ */
6877
- return jsx(HoverHint, {
6725
+ return jsx(_HoverHint, {
6878
6726
  disabled: disabled || description === void 0,
6879
6727
  text: description ?? "",
6880
6728
  children: children
@@ -7446,17 +7294,6 @@ function conditionLines(description) {
7446
7294
  });
7447
7295
  }
7448
7296
 
7449
- function StartIncompleteBadge({style: style}) {
7450
- /* @__PURE__ */
7451
- return jsx(Badge, {
7452
- fontSize: 1,
7453
- mode: "outline",
7454
- style: style,
7455
- tone: "caution",
7456
- children: "Start incomplete"
7457
- });
7458
- }
7459
-
7460
7297
  function normalizeAbortReason(raw) {
7461
7298
  const trimmed = raw.trim();
7462
7299
  return trimmed === "" ? void 0 : trimmed;
@@ -7668,24 +7505,6 @@ function historyLine(h, titles) {
7668
7505
  return historyLiner[h._type](h, titles);
7669
7506
  }
7670
7507
 
7671
- function AgoStamp({at: at, now: now}) {
7672
- /* @__PURE__ */
7673
- return jsx(Flex, {
7674
- align: "center",
7675
- children: /* @__PURE__ */ jsx(HoverHint, {
7676
- text: formatShortDateTime(at),
7677
- children: /* @__PURE__ */ jsx(Text, {
7678
- muted: !0,
7679
- size: 1,
7680
- style: {
7681
- whiteSpace: "nowrap"
7682
- },
7683
- children: formatShortAgo(at, now)
7684
- })
7685
- })
7686
- });
7687
- }
7688
-
7689
7508
  function CodeChip({value: value}) {
7690
7509
  /* @__PURE__ */
7691
7510
  return jsx("code", {
@@ -7708,7 +7527,7 @@ function HintedMenuButton({hint: hint, ...menuButtonProps}) {
7708
7527
  return hint === void 0 ? /* @__PURE__ */ jsx(MenuButton, {
7709
7528
  ...menuButtonProps,
7710
7529
  popover: popover
7711
- }) : /* @__PURE__ */ jsx(HoverHint, {
7530
+ }) : /* @__PURE__ */ jsx(_HoverHint, {
7712
7531
  disabled: open,
7713
7532
  text: hint,
7714
7533
  children: /* @__PURE__ */ jsx(MenuButton, {
@@ -7975,7 +7794,7 @@ function ActorNameSpan({id: id}) {
7975
7794
  function FeedGlyph({hint: hint, icon: icon}) {
7976
7795
  const size = useAvatarSize();
7977
7796
  /* @__PURE__ */
7978
- return jsx(HoverHint, {
7797
+ return jsx(_HoverHint, {
7979
7798
  text: hint,
7980
7799
  children: /* @__PURE__ */ jsx(Flex, {
7981
7800
  align: "center",
@@ -8286,7 +8105,7 @@ function StageFace({completed: completed = !1, detail: detail, title: title}) {
8286
8105
  /* @__PURE__ */ jsx(TextWithTone, {
8287
8106
  size: 1,
8288
8107
  tone: tone,
8289
- children: completed ? /* @__PURE__ */ jsx(CheckmarkCircleFilledIcon, {
8108
+ children: completed ? /* @__PURE__ */ jsx(_CheckmarkCircleFilledIcon, {
8290
8109
  style: {
8291
8110
  color: "inherit"
8292
8111
  }
@@ -8378,7 +8197,7 @@ function SpineNodeView({definition: definition, node: node, transitions: transit
8378
8197
  if (node.state === "current") {
8379
8198
  const detail = roundDetail(node.round);
8380
8199
  /* @__PURE__ */
8381
- return jsx(HoverHint, {
8200
+ return jsx(_HoverHint, {
8382
8201
  content: card,
8383
8202
  "data-testid": `spine-node-${node.name}`,
8384
8203
  flush: !0,
@@ -8394,7 +8213,7 @@ function SpineNodeView({definition: definition, node: node, transitions: transit
8394
8213
  }
8395
8214
  const Icon = NODE_ICON[node.state];
8396
8215
  /* @__PURE__ */
8397
- return jsx(HoverHint, {
8216
+ return jsx(_HoverHint, {
8398
8217
  content: card,
8399
8218
  "data-testid": `spine-node-${node.name}`,
8400
8219
  flush: !0,
@@ -8542,10 +8361,21 @@ function WorkflowInstanceSection({defaultOpen: defaultOpen, entry: entry, onOpen
8542
8361
  return jsx(InstanceCard, {
8543
8362
  defaultOpen: defaultOpen,
8544
8363
  entry: entry,
8545
- children: /* @__PURE__ */ jsx(InstanceSnapshotBody, {
8546
- entry: entry,
8547
- onOpenActivity: onOpenActivity,
8548
- surface: "document-view"
8364
+ children: /* @__PURE__ */ jsxs(Stack, {
8365
+ gap: 3,
8366
+ children: [
8367
+ /* @__PURE__ */ jsx(InstanceFaultNote, {
8368
+ entry: entry,
8369
+ scope: {
8370
+ kind: "run",
8371
+ onOpenActivity: onOpenActivity
8372
+ }
8373
+ }),
8374
+ /* @__PURE__ */ jsx(InstanceSnapshotBody, {
8375
+ entry: entry,
8376
+ onOpenActivity: onOpenActivity,
8377
+ surface: "document-view"
8378
+ }) ]
8549
8379
  })
8550
8380
  });
8551
8381
  }
@@ -9409,7 +9239,7 @@ function StartWorkflowButton({mapping: mapping, docId: docId, initialValue: init
9409
9239
  },
9410
9240
  tone: tone
9411
9241
  }), hint = tooltip ?? (iconOnly ? startLabel : void 0);
9412
- return hint ? /* @__PURE__ */ jsx(HoverHint, {
9242
+ return hint ? /* @__PURE__ */ jsx(_HoverHint, {
9413
9243
  text: hint,
9414
9244
  children: button
9415
9245
  }) : button;
@@ -9486,7 +9316,7 @@ function StartWorkflowMenuItem({mapping: mapping, docId: docId, initialValue: in
9486
9316
  },
9487
9317
  text: `Start ${mapping.label}`
9488
9318
  });
9489
- return tooltip ? /* @__PURE__ */ jsx(HoverHint, {
9319
+ return tooltip ? /* @__PURE__ */ jsx(_HoverHint, {
9490
9320
  text: tooltip,
9491
9321
  children: item
9492
9322
  }) : item;
@@ -9574,7 +9404,7 @@ const VIEW_TAB_CODEC = workflowsTabCodec([ "overview", "for-me" ]), WorkflowsVie
9574
9404
  };
9575
9405
 
9576
9406
  function DiscoverySpinner() {
9577
- const visible = useDelayedFlag(!0, 1e3);
9407
+ const visible = _useDelayedFlag(!0, 1e3);
9578
9408
  /* @__PURE__ */
9579
9409
  return jsx(Flex, {
9580
9410
  align: "center",
@@ -9944,20 +9774,30 @@ function createSubscribers() {
9944
9774
  }
9945
9775
 
9946
9776
  function actualType$(previews, bareId) {
9947
- return previews.unstable_observeDocumentPairAvailability(bareId).pipe(switchMap(({draft: draft, published: published}) => draft.available ? previews.observeDocumentTypeFromId(getDraftId(bareId)) : published.available ? previews.observeDocumentTypeFromId(bareId) : draft.reason === "PERMISSION_DENIED" || published.reason === "PERMISSION_DENIED" ? of(void 0) : previews.unstable_observeVersionDocumentIds(bareId).pipe(switchMap(([firstVersionId]) => firstVersionId === void 0 ? of(null) : previews.observeDocumentTypeFromId(firstVersionId)))), distinctUntilChanged());
9777
+ return previews.unstable_observeDocumentPairAvailability(bareId).pipe(switchMap(pair => representationType$(previews, {
9778
+ bareId: bareId,
9779
+ ...pair
9780
+ }).pipe(startWith(void 0))), distinctUntilChanged());
9781
+ }
9782
+
9783
+ function representationType$(previews, {bareId: bareId, draft: draft, published: published}) {
9784
+ return draft.available ? previews.observeDocumentTypeFromId(getDraftId(bareId)) : published.available ? previews.observeDocumentTypeFromId(bareId) : draft.reason === "PERMISSION_DENIED" || published.reason === "PERMISSION_DENIED" ? of(UNREADABLE_DOCUMENT) : previews.unstable_observeVersionDocumentIds(bareId).pipe(switchMap(([firstVersionId]) => firstVersionId === void 0 ? of(null) : previews.observeDocumentTypeFromId(firstVersionId).pipe(startWith(void 0))));
9948
9785
  }
9949
9786
 
9950
9787
  const REBUILD_DELAY_MS = 5e3;
9951
9788
 
9952
9789
  function createActualTypeProbeStore(previews) {
9953
- const verdicts = /* @__PURE__ */ new Map, live = /* @__PURE__ */ new Map, subscribers = createSubscribers(), start = (bareId, entry) => actualType$(previews, bareId).subscribe({
9954
- next: value => {
9955
- verdicts.has(bareId) && verdicts.get(bareId) === value || (verdicts.set(bareId, value),
9956
- subscribers.notify());
9957
- },
9790
+ const verdicts = /* @__PURE__ */ new Map, live = /* @__PURE__ */ new Map, subscribers = createSubscribers(), publish = (bareId, value) => {
9791
+ const changed = verdicts.get(bareId) !== value;
9792
+ verdicts.set(bareId, value), changed && subscribers.notify();
9793
+ }, forgetUnavailable = bareId => {
9794
+ const verdict = verdicts.get(bareId);
9795
+ (verdict === null || verdict === UNREADABLE_DOCUMENT) && publish(bareId, void 0);
9796
+ }, start = (bareId, entry) => actualType$(previews, bareId).subscribe({
9797
+ next: value => publish(bareId, value),
9958
9798
  error: err => {
9959
9799
  console.error(`[workflow-studio-plugin] actual-type probe for "${bareId}" failed:`, err),
9960
- entry.subscription = void 0, entry.rebuildTimer = setTimeout(() => {
9800
+ forgetUnavailable(bareId), entry.subscription = void 0, entry.rebuildTimer = setTimeout(() => {
9961
9801
  entry.rebuildTimer = void 0, !(live.get(bareId) !== entry || entry.count === 0) && (entry.subscription = start(bareId, entry));
9962
9802
  }, REBUILD_DELAY_MS);
9963
9803
  }
@@ -9985,7 +9825,8 @@ function createActualTypeProbeStore(previews) {
9985
9825
  let released = !1;
9986
9826
  return () => {
9987
9827
  released || (released = !0, entry.count -= 1, !(entry.count > 0) && (entry.subscription?.unsubscribe(),
9988
- entry.rebuildTimer !== void 0 && clearTimeout(entry.rebuildTimer), live.get(bareId) === entry && live.delete(bareId)));
9828
+ entry.rebuildTimer !== void 0 && clearTimeout(entry.rebuildTimer), live.get(bareId) === entry && live.delete(bareId),
9829
+ forgetUnavailable(bareId)));
9989
9830
  };
9990
9831
  }
9991
9832
  };
@@ -10615,7 +10456,7 @@ function AssigneesInput({value: value, onChange: onChange, eligibleRoles: eligib
10615
10456
  /* @__PURE__ */ jsx(AssigneeBadge, {
10616
10457
  assignee: assignee
10617
10458
  }),
10618
- /* @__PURE__ */ jsx(HoverHint, {
10459
+ /* @__PURE__ */ jsx(_HoverHint, {
10619
10460
  text: "Remove",
10620
10461
  children: /* @__PURE__ */ jsx(Button, {
10621
10462
  "aria-label": "Remove",
@@ -11854,7 +11695,7 @@ function StripLine({aside: aside, children: children, hint: hint, onOpen: onOpen
11854
11695
  return jsxs(Flex, {
11855
11696
  align: "center",
11856
11697
  children: [
11857
- /* @__PURE__ */ jsx(HoverHint, {
11698
+ /* @__PURE__ */ jsx(_HoverHint, {
11858
11699
  ...hint,
11859
11700
  children: /* @__PURE__ */ jsx(Card, {
11860
11701
  as: "button",
@@ -12127,4 +11968,1582 @@ function WorkflowRootInput(props) {
12127
11968
  });
12128
11969
  }
12129
11970
 
12130
- export { AbortWorkflowDialog, ActivityDetailBody, ActivityDetailDialog, ActivityLog, AgoStamp, AlertChip, AlertGlyph, Breadcrumb, CodeChip, CountedLabel, DismissablePopover, DocPreviewLink, DocRefFace, EmptyState, FOR_ME_SECTION_COPY, ForMeEmptyState, ForMeSectionHeading, HoverHint, InstanceFaultNote, InstanceSnapshotBody, InvalidDocNotice, LoadingRow, LogEventOnMount, MetaRow, MetricLockup, MetricPair, NoteBanner, OverlineHeading, RUN_SEARCH_PARAM, RowAssignees, SectionHeading, SpinnerSlot, TOOL_TABS, TabSwitch, UnreadableDocsNote, WORKFLOW_API_VERSION, WorkflowBoardWorkflowSelected, WorkflowDefinitionDetailViewed, WorkflowInstanceDetailViewed, WorkflowTitleSeedDrifted, WorkflowToolOpened, activityLabel, assigneesOf, assignmentHolding, countBy, definitionFingerprint, definitionsRouteOf, deriveActivityDetail, describeError, disambiguatedNames, dueDatesOf, dueMomentSentence, findActivity, formatDate, formatShortAgo, formatShortDateTime, formatTimeAgo, gdrLocality, identityOf, instanceBreadcrumb, instanceTitle, isDueDatePast, isEvaluationStale, isHandsOff, isLiveEntry, isOpenActivityStatus, landingState, mappingIssueDetail, namesNoDeployedDefinition, openActivityGone, openableSchemaType, parseStoredDateValue, readDeployedDefinitions, shortSpanOf, stageTitle, tabSelectionNavigates, toolRoute, toolTabState, uniqueIds, useAssignmentIdentity, useAvatarSize, useCapTrimFor, useContainerToken, useCurrentUserId, useDefinition, useLogEventOnMount, useMinuteClock, useProjectMembers, useRadiusToken, useReleaseTitles, useSpaceToken, useTextIconSize, useUserDisplays, useWorkflowContext, useWorkflowInstanceEntry, userIdsOf, workflowDefaultDocumentNode, workflowState, workflowStudioPlugin, workflowsView };
11971
+ function openActivitiesOf(instance) {
11972
+ return (findOpenStageEntry(instance)?.activities ?? []).filter(activity => isOpenActivityStatus(activity.status));
11973
+ }
11974
+
11975
+ function overdueTasks(instance, now) {
11976
+ return openActivitiesOf(instance).filter(activity => passedDuesOf(activity, now).length > 0);
11977
+ }
11978
+
11979
+ function earliestDue(activity) {
11980
+ return earliestOf(dueDatesOf(activity.fields ?? []));
11981
+ }
11982
+
11983
+ function passedDueOf(activity, now) {
11984
+ const passed = passedDuesOf(activity, now);
11985
+ return earliestOf(passed) ?? passed[0];
11986
+ }
11987
+
11988
+ function passedDuesOf(activity, now) {
11989
+ return dueDatesOf(activity.fields ?? []).filter(due => isDueDatePast(due, now));
11990
+ }
11991
+
11992
+ function earliestOf(values) {
11993
+ let earliest;
11994
+ for (const value of values) {
11995
+ const time = parseStoredDateValue(value)?.getTime();
11996
+ time !== void 0 && (earliest === void 0 || time < earliest.time) && (earliest = {
11997
+ time: time,
11998
+ value: value
11999
+ });
12000
+ }
12001
+ return earliest?.value;
12002
+ }
12003
+
12004
+ const AUTONOMY_BY_DEFINITION = /* @__PURE__ */ new WeakMap;
12005
+
12006
+ function cachedAutonomy(definition) {
12007
+ const hit = AUTONOMY_BY_DEFINITION.get(definition);
12008
+ if (hit !== void 0) return hit;
12009
+ const derived = deriveWorkflowAutonomy(definition);
12010
+ return AUTONOMY_BY_DEFINITION.set(definition, derived), derived;
12011
+ }
12012
+
12013
+ function isAutomatedActivity(args) {
12014
+ const stage = args.autonomy?.stages.find(entry => entry.stage === args.stageName);
12015
+ return isHandsOff({
12016
+ classification: deriveExecutorClassification(args.activity),
12017
+ completesWithoutCaller: stage?.activities[args.activity.name]?.completesWithoutCaller
12018
+ });
12019
+ }
12020
+
12021
+ function taskOf(args) {
12022
+ const {entry: entry, now: now, openedAt: openedAt, roleAliases: roleAliases, title: title} = args;
12023
+ return {
12024
+ name: entry.name,
12025
+ title: title,
12026
+ assignees: assigneesOf(entry.fields ?? []),
12027
+ roleAliases: roleAliases,
12028
+ openedAt: openedAt,
12029
+ due: earliestDue(entry),
12030
+ overdueSince: passedDueOf(entry, now),
12031
+ status: entry.status
12032
+ };
12033
+ }
12034
+
12035
+ function humanTask(args) {
12036
+ const {activity: activity, autonomy: autonomy, entry: entry, now: now, openedAt: openedAt, roleAliases: roleAliases, stageName: stageName} = args;
12037
+ return entry === void 0 ? [] : isAutomatedActivity({
12038
+ activity: activity,
12039
+ autonomy: autonomy,
12040
+ stageName: stageName
12041
+ }) ? [] : [ taskOf({
12042
+ entry: entry,
12043
+ now: now,
12044
+ openedAt: openedAt,
12045
+ roleAliases: roleAliases,
12046
+ title: activityLabel(activity)
12047
+ }) ];
12048
+ }
12049
+
12050
+ function undeclaredTasks(args) {
12051
+ const {definition: definition, now: now, open: open, openedAt: openedAt, roleAliases: roleAliases, seen: seen, stageName: stageName} = args;
12052
+ return open.filter(entry => !seen.has(entry.name)).map(entry => taskOf({
12053
+ entry: entry,
12054
+ now: now,
12055
+ openedAt: openedAt,
12056
+ roleAliases: roleAliases,
12057
+ title: findActivity({
12058
+ activityName: entry.name,
12059
+ definition: definition,
12060
+ stageName: stageName
12061
+ }).title
12062
+ }));
12063
+ }
12064
+
12065
+ function definitionForPinned(definition, pinnedVersion) {
12066
+ if (!(definition === void 0 || definition.version !== pinnedVersion)) return definition;
12067
+ }
12068
+
12069
+ function stageTasksOf(args) {
12070
+ const {definition: definition, instance: instance, now: now} = args, stageEntry = findOpenStageEntry(instance);
12071
+ if (stageEntry === void 0) return [];
12072
+ const listed = listedStageActivities(stageEntry);
12073
+ if (listed.length === 0) return [];
12074
+ 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 = findStageNode({
12075
+ definition: definition,
12076
+ stageName: stageName
12077
+ })?.activities ?? [];
12078
+ return [ ...declared.flatMap(activity => humanTask({
12079
+ activity: activity,
12080
+ autonomy: autonomy,
12081
+ entry: openByName.get(activity.name),
12082
+ now: now,
12083
+ openedAt: openedAt,
12084
+ roleAliases: roleAliases,
12085
+ stageName: stageName
12086
+ })), ...undeclaredTasks({
12087
+ definition: definition,
12088
+ now: now,
12089
+ open: listed,
12090
+ openedAt: openedAt,
12091
+ roleAliases: roleAliases,
12092
+ seen: new Set(declared.map(activity => activity.name)),
12093
+ stageName: stageName
12094
+ }) ];
12095
+ }
12096
+
12097
+ function listedStageActivities(stage) {
12098
+ return stage.activities.filter(entry => isOpenActivityStatus(entry.status) || entry.status === "failed");
12099
+ }
12100
+
12101
+ function groupWidthOf(task, metrics) {
12102
+ const mark = taskAssignmentMarkOf(task.assignees), faces = mark.kind === "held" ? mark.members.length : 1;
12103
+ return metrics.face + (faces - 1) * (metrics.face - metrics.overlap);
12104
+ }
12105
+
12106
+ function rowWidthOf(tasks, metrics) {
12107
+ return tasks.reduce((total, task) => total + groupWidthOf(task, metrics), 0) + Math.max(0, tasks.length - 1) * metrics.gap;
12108
+ }
12109
+
12110
+ function countWithin(args) {
12111
+ const {budget: budget, metrics: metrics, tasks: tasks} = args;
12112
+ let used = 0, count = 0;
12113
+ for (const task of tasks) {
12114
+ const next = used + (count === 0 ? 0 : metrics.gap) + groupWidthOf(task, metrics);
12115
+ if (next > budget) break;
12116
+ used = next, count += 1;
12117
+ }
12118
+ return Math.max(1, count);
12119
+ }
12120
+
12121
+ function visibleStageTasks(args) {
12122
+ const {metrics: metrics, room: room, tasks: tasks} = args;
12123
+ if (rowWidthOf(tasks, metrics) <= room) return {
12124
+ overflow: 0,
12125
+ visible: tasks
12126
+ };
12127
+ const shown = countWithin({
12128
+ budget: room - metrics.gap - metrics.counter,
12129
+ metrics: metrics,
12130
+ tasks: tasks
12131
+ });
12132
+ return {
12133
+ overflow: tasks.length - shown,
12134
+ visible: tasks.slice(0, shown)
12135
+ };
12136
+ }
12137
+
12138
+ function taskAssignmentMarkOf(assignees) {
12139
+ const members = assignees.filter(assignee => assignee.type === "user");
12140
+ if (members.length > 0) return {
12141
+ kind: "held",
12142
+ members: members
12143
+ };
12144
+ const roles = assignees.flatMap(assignee => assignee.type === "role" ? [ assignee.role ] : []);
12145
+ return roles.length > 0 ? {
12146
+ kind: "routed",
12147
+ roles: roles
12148
+ } : {
12149
+ kind: "unassigned"
12150
+ };
12151
+ }
12152
+
12153
+ const LATE_FACE = {
12154
+ Icon: CalendarIcon,
12155
+ tone: "caution"
12156
+ };
12157
+
12158
+ function LateSpan({now: now, since: since}) {
12159
+ /* @__PURE__ */
12160
+ return jsx(MetricLockup, {
12161
+ Icon: LATE_FACE.Icon,
12162
+ tone: LATE_FACE.tone,
12163
+ value: _shortSpanOf(parseStoredDateValue(since), now)
12164
+ });
12165
+ }
12166
+
12167
+ const HOLDER_OVERLAP = 7, HOLDER_RING = 1.5, GROUP_GAP_TOKEN = 3, OVERDUE_DOT_RATIO = .4;
12168
+
12169
+ function overdueDotOf(face) {
12170
+ const size = Math.round(face * OVERDUE_DOT_RATIO);
12171
+ return {
12172
+ overhang: Math.round(size / 4),
12173
+ size: size
12174
+ };
12175
+ }
12176
+
12177
+ function useDisplayById(ids) {
12178
+ const displays = useUserDisplays(uniqueIds(ids)), labels = disambiguatedNames(displays);
12179
+ return new Map(displays.map((display, index) => [ display.id, {
12180
+ ...display,
12181
+ label: labels[index] ?? display.name
12182
+ } ]));
12183
+ }
12184
+
12185
+ function holderKey(assignee, index) {
12186
+ return `${assignee.id}-${index}`;
12187
+ }
12188
+
12189
+ function stageTasksFace(args) {
12190
+ return {
12191
+ content: /* @__PURE__ */ jsx(StageTasksCard, {
12192
+ now: args.now,
12193
+ tasks: args.tasks
12194
+ }),
12195
+ flush: !0,
12196
+ wide: !0
12197
+ };
12198
+ }
12199
+
12200
+ function StageTaskGroups({now: now, room: room, tasks: tasks}) {
12201
+ const gap = useSpaceToken(GROUP_GAP_TOKEN), face = useAvatarSize(), {overhang: overhang} = overdueDotOf(face), {overflow: overflow, visible: visible} = visibleStageTasks({
12202
+ metrics: {
12203
+ counter: face,
12204
+ face: face,
12205
+ gap: gap,
12206
+ overlap: HOLDER_OVERLAP
12207
+ },
12208
+ room: room === void 0 ? face * 3 + gap * 2 : room - overhang,
12209
+ tasks: tasks
12210
+ });
12211
+ return tasks.length === 0 ? null : /* @__PURE__ */ jsx(_HoverHint, {
12212
+ ...stageTasksFace({
12213
+ now: now,
12214
+ tasks: tasks
12215
+ }),
12216
+ children: /* @__PURE__ */ jsxs(Flex, {
12217
+ align: "center",
12218
+ "aria-label": "Tasks",
12219
+ style: {
12220
+ columnGap: gap,
12221
+ paddingRight: overhang
12222
+ },
12223
+ children: [ visible.map(task => /* @__PURE__ */ jsx(TaskGroupFace, {
12224
+ task: task
12225
+ }, task.name)), overflow === 0 ? null : /* @__PURE__ */ jsxs(Text, {
12226
+ muted: !0,
12227
+ size: 1,
12228
+ children: [ "+", overflow ]
12229
+ }) ]
12230
+ })
12231
+ });
12232
+ }
12233
+
12234
+ function TaskGroupFace({task: task}) {
12235
+ /* @__PURE__ */
12236
+ return jsxs(Box, {
12237
+ style: {
12238
+ flexShrink: 0,
12239
+ position: "relative"
12240
+ },
12241
+ children: [
12242
+ /* @__PURE__ */ jsx(AssignmentFace, {
12243
+ assignees: task.assignees
12244
+ }), task.overdueSince === void 0 ? null : /* @__PURE__ */ jsx(OverdueDot, {}) ]
12245
+ });
12246
+ }
12247
+
12248
+ function AssignmentFace({assignees: assignees}) {
12249
+ const mark = taskAssignmentMarkOf(assignees);
12250
+ return mark.kind === "unassigned" ? /* @__PURE__ */ jsx(PersonToken, {}) : mark.kind === "routed" ? /* @__PURE__ */ jsx(PersonToken, {
12251
+ routed: !0
12252
+ }) : /* @__PURE__ */ jsx(OverlappedHolders, {
12253
+ assignees: mark.members
12254
+ });
12255
+ }
12256
+
12257
+ function OverdueDot() {
12258
+ const {color: color} = useTheme_v2(), {overhang: overhang, size: size} = overdueDotOf(useAvatarSize());
12259
+ /* @__PURE__ */
12260
+ return jsx(Box, {
12261
+ "aria-label": "Overdue",
12262
+ role: "img",
12263
+ style: {
12264
+ backgroundColor: color.button.default.caution.enabled.bg,
12265
+ borderRadius: "50%",
12266
+ boxShadow: `0 0 0 ${HOLDER_RING}px ${color.bg}`,
12267
+ height: size,
12268
+ position: "absolute",
12269
+ right: -overhang,
12270
+ top: -overhang,
12271
+ width: size
12272
+ }
12273
+ });
12274
+ }
12275
+
12276
+ function HolderFace({assignee: assignee, displayById: displayById}) {
12277
+ const display = displayById.get(assignee.id);
12278
+ /* @__PURE__ */
12279
+ return jsx(MemberAvatar, {
12280
+ imageUrl: display?.imageUrl,
12281
+ name: display?.name ?? assignee.id,
12282
+ size: 0
12283
+ });
12284
+ }
12285
+
12286
+ function OverlappedHolders({assignees: assignees}) {
12287
+ const {color: color} = useTheme_v2(), displayById = useDisplayById(userIdsOf(assignees)), ring = `0 0 0 ${HOLDER_RING}px ${color.bg}`;
12288
+ /* @__PURE__ */
12289
+ return jsx(Flex, {
12290
+ align: "center",
12291
+ style: {
12292
+ flexShrink: 0,
12293
+ isolation: "isolate"
12294
+ },
12295
+ children: assignees.map((assignee, index) => /* @__PURE__ */ jsx(Box, {
12296
+ style: {
12297
+ borderRadius: "50%",
12298
+ boxShadow: ring,
12299
+ flexShrink: 0,
12300
+ marginLeft: index === 0 ? 0 : -HOLDER_OVERLAP,
12301
+ position: "relative",
12302
+ zIndex: index
12303
+ },
12304
+ children: /* @__PURE__ */ jsx(HolderFace, {
12305
+ assignee: assignee,
12306
+ displayById: displayById
12307
+ })
12308
+ }, holderKey(assignee, index)))
12309
+ });
12310
+ }
12311
+
12312
+ function PersonToken({routed: routed = !1}) {
12313
+ const size = useAvatarSize(), {color: color} = useTheme_v2();
12314
+ /* @__PURE__ */
12315
+ return jsxs(Box, {
12316
+ "aria-label": routed ? "Routed, no person assigned" : "Unassigned",
12317
+ role: "img",
12318
+ style: {
12319
+ flexShrink: 0,
12320
+ height: size,
12321
+ position: "relative",
12322
+ width: size
12323
+ },
12324
+ children: [
12325
+ /* @__PURE__ */ jsx(Flex, {
12326
+ align: "center",
12327
+ justify: "center",
12328
+ style: {
12329
+ border: `1px dashed ${color.border}`,
12330
+ borderRadius: "50%",
12331
+ boxSizing: "border-box",
12332
+ height: size,
12333
+ width: size
12334
+ },
12335
+ children: /* @__PURE__ */ jsx(Text, {
12336
+ size: 0,
12337
+ children: /* @__PURE__ */ jsx(UserIcon, {
12338
+ style: {
12339
+ color: color.input.default.enabled.placeholder
12340
+ }
12341
+ })
12342
+ })
12343
+ }), routed ? /* @__PURE__ */ jsx(Card, {
12344
+ radius: 1,
12345
+ tone: "primary",
12346
+ style: {
12347
+ bottom: -3,
12348
+ position: "absolute",
12349
+ right: -3
12350
+ },
12351
+ children: /* @__PURE__ */ jsx(Flex, {
12352
+ align: "center",
12353
+ justify: "center",
12354
+ style: {
12355
+ height: 13,
12356
+ width: 13
12357
+ },
12358
+ children: /* @__PURE__ */ jsx(Text, {
12359
+ size: 0,
12360
+ children: /* @__PURE__ */ jsx(UsersIcon, {})
12361
+ })
12362
+ })
12363
+ }) : null ]
12364
+ });
12365
+ }
12366
+
12367
+ function StageTasksCard({now: now, tasks: tasks}) {
12368
+ const displayById = useDisplayById(tasks.flatMap(task => userIdsOf(task.assignees)));
12369
+ /* @__PURE__ */
12370
+ return jsxs(Stack, {
12371
+ gap: 4,
12372
+ padding: 3,
12373
+ children: [
12374
+ /* @__PURE__ */ jsx(OverlineHeading, {
12375
+ children: "Tasks in this stage"
12376
+ }),
12377
+ /* @__PURE__ */ jsx(Stack, {
12378
+ gap: 4,
12379
+ children: tasks.map(task => /* @__PURE__ */ jsx(TaskCardRow, {
12380
+ displayById: displayById,
12381
+ now: now,
12382
+ task: task
12383
+ }, task.name))
12384
+ }) ]
12385
+ });
12386
+ }
12387
+
12388
+ function TaskCardRow({displayById: displayById, now: now, task: task}) {
12389
+ const mark = taskAssignmentMarkOf(task.assignees);
12390
+ /* @__PURE__ */
12391
+ return jsxs(Stack, {
12392
+ gap: 3,
12393
+ children: [
12394
+ /* @__PURE__ */ jsxs(Stack, {
12395
+ gap: 2,
12396
+ children: [
12397
+ /* @__PURE__ */ jsxs(Flex, {
12398
+ align: "center",
12399
+ gap: 3,
12400
+ children: [
12401
+ /* @__PURE__ */ jsx(Text, {
12402
+ size: 1,
12403
+ children: task.title
12404
+ }), task.overdueSince === void 0 ? null : /* @__PURE__ */ jsx(LateSpan, {
12405
+ now: now,
12406
+ since: task.overdueSince
12407
+ }) ]
12408
+ }), task.due === void 0 ? null : /* @__PURE__ */ jsx(Text, {
12409
+ muted: !0,
12410
+ size: 1,
12411
+ children: dueMomentSentence(task.due, now)
12412
+ }) ]
12413
+ }),
12414
+ /* @__PURE__ */ jsx(AssignmentLine, {
12415
+ displayById: displayById,
12416
+ mark: mark,
12417
+ now: now,
12418
+ openedAt: task.openedAt,
12419
+ roleAliases: task.roleAliases
12420
+ }) ]
12421
+ });
12422
+ }
12423
+
12424
+ function AssignmentLine({displayById: displayById, mark: mark, now: now, openedAt: openedAt, roleAliases: roleAliases}) {
12425
+ return mark.kind === "unassigned" ? /* @__PURE__ */ jsxs(Flex, {
12426
+ align: "center",
12427
+ gap: 2,
12428
+ children: [
12429
+ /* @__PURE__ */ jsx(PersonToken, {}),
12430
+ /* @__PURE__ */ jsx(Text, {
12431
+ muted: !0,
12432
+ size: 1,
12433
+ children: "Unassigned"
12434
+ }) ]
12435
+ }) : mark.kind === "routed" ? /* @__PURE__ */ jsx(RoutedAssignmentLine, {
12436
+ mark: mark,
12437
+ now: now,
12438
+ openedAt: openedAt,
12439
+ roleAliases: roleAliases
12440
+ }) : /* @__PURE__ */ jsx(Stack, {
12441
+ gap: 2,
12442
+ children: mark.members.map((assignee, index) => /* @__PURE__ */ jsxs(Flex, {
12443
+ align: "center",
12444
+ gap: 2,
12445
+ children: [
12446
+ /* @__PURE__ */ jsx(HolderFace, {
12447
+ assignee: assignee,
12448
+ displayById: displayById
12449
+ }),
12450
+ /* @__PURE__ */ jsx(Text, {
12451
+ size: 1,
12452
+ children: displayById.get(assignee.id)?.label ?? assignee.id
12453
+ }) ]
12454
+ }, holderKey(assignee, index)))
12455
+ });
12456
+ }
12457
+
12458
+ function RoutedAssignmentLine({mark: mark, now: now, openedAt: openedAt, roleAliases: roleAliases}) {
12459
+ const vocabulary = useProjectMembers(), count = roleMemberCount({
12460
+ members: vocabulary.members,
12461
+ requiredRoles: mark.roles,
12462
+ roleAliases: roleAliases
12463
+ }), names = mark.roles.map(role => roleLabel(memberRoleFor(vocabulary, role)));
12464
+ /* @__PURE__ */
12465
+ return jsxs(Flex, {
12466
+ align: "center",
12467
+ gap: 2,
12468
+ children: [
12469
+ /* @__PURE__ */ jsx(PersonToken, {
12470
+ routed: !0
12471
+ }),
12472
+ /* @__PURE__ */ jsxs(Stack, {
12473
+ gap: 1,
12474
+ children: [
12475
+ /* @__PURE__ */ jsx(Text, {
12476
+ size: 1,
12477
+ children: names.join(", ")
12478
+ }),
12479
+ /* @__PURE__ */ jsxs(Text, {
12480
+ muted: !0,
12481
+ size: 1,
12482
+ children: [ memberCountLabel(count), " · Open ", _formatShortAgo(openedAt, now) ]
12483
+ }) ]
12484
+ }) ]
12485
+ });
12486
+ }
12487
+
12488
+ function useTableWidth(element) {
12489
+ const [width, setWidth] = useState(void 0);
12490
+ return useLayoutEffect(() => {
12491
+ if (element === null) {
12492
+ setWidth(void 0);
12493
+ return;
12494
+ }
12495
+ const measure = () => setWidth(element.getBoundingClientRect().width || void 0);
12496
+ measure();
12497
+ const observer = new ResizeObserver(measure);
12498
+ return observer.observe(element), () => observer.disconnect();
12499
+ }, [ element ]), width;
12500
+ }
12501
+
12502
+ function useTableStyles() {
12503
+ const {color: color} = useTheme_v2(), headTop = useSpaceToken(3), cellX = useSpaceToken(2);
12504
+ return useMemo(() => ({
12505
+ cell: {
12506
+ borderBottom: `1px solid ${color.border}`,
12507
+ boxSizing: "border-box",
12508
+ padding: `0 ${cellX}px`,
12509
+ verticalAlign: "middle",
12510
+ whiteSpace: "nowrap"
12511
+ },
12512
+ head: {
12513
+ background: color.bg,
12514
+ borderBottom: `1px solid ${color.border}`,
12515
+ boxSizing: "border-box",
12516
+ padding: `${headTop}px 0 6px`,
12517
+ position: "sticky",
12518
+ textAlign: "left",
12519
+ top: 0,
12520
+ zIndex: 1
12521
+ }
12522
+ }), [ cellX, color, headTop ]);
12523
+ }
12524
+
12525
+ function scrollParentOf(el) {
12526
+ for (let node = el.parentElement; node !== null; node = node.parentElement) {
12527
+ const overflowY = getComputedStyle(node).overflowY;
12528
+ if (overflowY === "auto" || overflowY === "scroll") return node;
12529
+ }
12530
+ }
12531
+
12532
+ function useRowWindow(args) {
12533
+ const {element: element, keyAt: keyAt, rowCount: rowCount} = args, [scroller, setScroller] = useState(null);
12534
+ useLayoutEffect(() => {
12535
+ setScroller(element === null ? null : scrollParentOf(element) ?? null);
12536
+ }, [ element ]);
12537
+ const [margin, setMargin] = useState(0);
12538
+ useLayoutEffect(() => {
12539
+ element === null || scroller === null || setMargin(element.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop);
12540
+ }, [ element, rowCount, scroller ]);
12541
+ const virtualizer = useVirtualizer({
12542
+ count: rowCount,
12543
+ estimateSize: () => 44,
12544
+ getItemKey: keyAt,
12545
+ getScrollElement: () => scroller,
12546
+ overscan: 10,
12547
+ scrollMargin: margin
12548
+ }), items = virtualizer.getVirtualItems(), first = items[0], last = items[items.length - 1];
12549
+ return {
12550
+ items: items,
12551
+ measureRow: virtualizer.measureElement,
12552
+ padBottom: last === void 0 ? 0 : virtualizer.getTotalSize() - (last.end - margin),
12553
+ padTop: first === void 0 ? 0 : first.start - margin
12554
+ };
12555
+ }
12556
+
12557
+ function SpacerRow({height: height}) {
12558
+ return height <= 0 ? null : /* @__PURE__ */ jsx("tr", {
12559
+ "aria-hidden": !0,
12560
+ style: {
12561
+ height: height
12562
+ },
12563
+ children: /* @__PURE__ */ jsx("td", {
12564
+ colSpan: 99,
12565
+ style: {
12566
+ border: 0,
12567
+ padding: 0
12568
+ }
12569
+ })
12570
+ });
12571
+ }
12572
+
12573
+ const TABLE_TIME_WIDTH = 112, TABLE_WORKFLOW_WIDTH = {
12574
+ cap: 260,
12575
+ fraction: .18
12576
+ }, TABLE_STAGE_WIDTH = {
12577
+ cap: 260,
12578
+ fraction: .16
12579
+ };
12580
+
12581
+ function SortableHeaderCells({children: children, columns: columns, onSort: onSort, sort: sort, styles: styles, tableWidth: tableWidth, widthOf: widthOf}) {
12582
+ /* @__PURE__ */
12583
+ return jsxs(Fragment, {
12584
+ children: [ columns.map(column => {
12585
+ const width = widthOf(column, tableWidth);
12586
+ /* @__PURE__ */
12587
+ return jsx("th", {
12588
+ style: {
12589
+ ...styles.head,
12590
+ ...width === void 0 ? {} : {
12591
+ width: width
12592
+ }
12593
+ },
12594
+ children: /* @__PURE__ */ jsx(SortHeaderButton, {
12595
+ active: sort.key === column.key,
12596
+ dir: sort.dir,
12597
+ label: column.label,
12598
+ onSort: () => onSort(column.key)
12599
+ })
12600
+ }, column.key);
12601
+ }), children ]
12602
+ });
12603
+ }
12604
+
12605
+ function VirtualTable({keyAt: keyAt, renderHeader: renderHeader, renderRow: renderRow, rowCount: rowCount}) {
12606
+ const styles = useTableStyles(), [element, setElement] = useState(null), tableWidth = useTableWidth(element), window = useRowWindow({
12607
+ element: element,
12608
+ keyAt: keyAt,
12609
+ rowCount: rowCount
12610
+ });
12611
+ /* @__PURE__ */
12612
+ return jsx("div", {
12613
+ ref: setElement,
12614
+ style: {
12615
+ overflowX: "clip",
12616
+ ...tableWidth === void 0 ? {
12617
+ visibility: "hidden"
12618
+ } : {}
12619
+ },
12620
+ children: /* @__PURE__ */ jsxs("table", {
12621
+ style: {
12622
+ borderCollapse: "separate",
12623
+ borderSpacing: 0,
12624
+ tableLayout: "fixed",
12625
+ width: "100%"
12626
+ },
12627
+ children: [
12628
+ /* @__PURE__ */ jsx("thead", {
12629
+ children: /* @__PURE__ */ jsx("tr", {
12630
+ children: renderHeader({
12631
+ styles: styles,
12632
+ tableWidth: tableWidth
12633
+ })
12634
+ })
12635
+ }),
12636
+ /* @__PURE__ */ jsxs("tbody", {
12637
+ children: [
12638
+ /* @__PURE__ */ jsx(SpacerRow, {
12639
+ height: window.padTop
12640
+ }), window.items.map(item => renderRow({
12641
+ index: item.index,
12642
+ key: item.key,
12643
+ measureRow: window.measureRow,
12644
+ tableWidth: tableWidth
12645
+ })),
12646
+ /* @__PURE__ */ jsx(SpacerRow, {
12647
+ height: window.padBottom
12648
+ }) ]
12649
+ }) ]
12650
+ })
12651
+ });
12652
+ }
12653
+
12654
+ function SortHeaderButton({active: active, dir: dir, label: label, onSort: onSort}) {
12655
+ /* @__PURE__ */
12656
+ return jsx(Button, {
12657
+ fontSize: 1,
12658
+ mode: "bleed",
12659
+ onClick: onSort,
12660
+ padding: 2,
12661
+ text: `${label}${active ? dir === "asc" ? " ↑" : " ↓" : ""}`
12662
+ });
12663
+ }
12664
+
12665
+ function TableRowCard({children: children, dataIndex: dataIndex, onClick: onClick, onKeyDown: onKeyDown, rowRef: rowRef, selected: selected, selectedRef: selectedRef}) {
12666
+ const setRow = useCallback(element => {
12667
+ rowRef?.(element), selected === !0 && selectedRef?.(element);
12668
+ }, [ rowRef, selected, selectedRef ]);
12669
+ /* @__PURE__ */
12670
+ return jsx(Card, {
12671
+ as: "tr",
12672
+ "data-as": "a",
12673
+ onClick: event => {
12674
+ event.currentTarget.focus(), onClick();
12675
+ },
12676
+ onKeyDown: selected === !0 ? onKeyDown : void 0,
12677
+ style: {
12678
+ cursor: "pointer",
12679
+ display: "table-row"
12680
+ },
12681
+ ...dataIndex === void 0 ? {} : {
12682
+ "data-index": dataIndex
12683
+ },
12684
+ ...rowRef === void 0 && selectedRef === void 0 ? {} : {
12685
+ ref: setRow
12686
+ },
12687
+ ...selected === void 0 ? {} : {
12688
+ "aria-selected": selected,
12689
+ pressed: selected,
12690
+ tabIndex: selected ? 0 : -1
12691
+ },
12692
+ children: children
12693
+ });
12694
+ }
12695
+
12696
+ function resolveColumnWidth(width, tableWidth) {
12697
+ return typeof width != "object" ? width : tableWidth === void 0 ? `${width.fraction * 100}%` : Math.min(width.cap, Math.round(tableWidth * width.fraction));
12698
+ }
12699
+
12700
+ function fillColumnWidth(args) {
12701
+ const {columns: columns, tableWidth: tableWidth, trailingWidth: trailingWidth} = args;
12702
+ if (tableWidth === void 0) return;
12703
+ const fixed = columns.reduce((sum, column) => {
12704
+ const width = resolveColumnWidth(column.width, tableWidth);
12705
+ return typeof width == "number" ? sum + width : sum;
12706
+ }, trailingWidth);
12707
+ return Math.max(160, Math.floor(tableWidth - fixed));
12708
+ }
12709
+
12710
+ function TableSubjectCell({document: document}) {
12711
+ return document === void 0 ? /* @__PURE__ */ jsx(Text, {
12712
+ muted: !0,
12713
+ size: 1,
12714
+ textOverflow: "ellipsis",
12715
+ children: "No document"
12716
+ }) : /* @__PURE__ */ jsx(DocRefFace, {
12717
+ gdr: document
12718
+ });
12719
+ }
12720
+
12721
+ function overdueAttentionHint(documents) {
12722
+ const task = documents === 1 ? "an overdue task" : "overdue tasks";
12723
+ return `${pluralize("document", documents, !0)} ${documents === 1 ? "has" : "have"} ${task}`;
12724
+ }
12725
+
12726
+ function blockedAttentionHint(documents) {
12727
+ return `${pluralize("document", documents, !0)} ${documents === 1 ? "is" : "are"} blocked`;
12728
+ }
12729
+
12730
+ function overdueMark(detail, now) {
12731
+ const spans = overdueSpans(detail.dues, now), longest = spans.length === detail.dues.length ? spans[0]?.span : void 0;
12732
+ return {
12733
+ hint: overdueHint({
12734
+ detail: detail,
12735
+ longest: longest
12736
+ }),
12737
+ value: sharedSpan(spans, detail.dues.length) ?? "overdue"
12738
+ };
12739
+ }
12740
+
12741
+ function overdueHint(args) {
12742
+ const {detail: detail, longest: longest} = args;
12743
+ if (detail.dues.length === 1 && detail.task !== void 0) return `“${detail.task}” — ${longest === void 0 ? "overdue" : `${longest} overdue`}`;
12744
+ const tasks = pluralize("task", detail.dues.length, !0);
12745
+ return longest === void 0 ? `${tasks} overdue` : `${tasks} overdue — the longest by ${longest}`;
12746
+ }
12747
+
12748
+ function sharedSpan(spans, late) {
12749
+ if (spans.length === late) return new Set(spans.map(entry => entry.span)).size === 1 ? spans[0]?.span : void 0;
12750
+ }
12751
+
12752
+ function overdueSpans(dues, now) {
12753
+ return dues.flatMap(due => {
12754
+ const from = parseStoredDateValue(due);
12755
+ return from === void 0 ? [] : [ {
12756
+ elapsed: now.getTime() - from.getTime(),
12757
+ span: _shortSpanOf(from, now)
12758
+ } ];
12759
+ }).sort((a, b) => b.elapsed - a.elapsed);
12760
+ }
12761
+
12762
+ function overdueMarkOpensPanel(tasks) {
12763
+ return tasks.some(task => task.overdueSince !== void 0);
12764
+ }
12765
+
12766
+ function blockedMarkHint(detail) {
12767
+ return detail.kind === "blocked-many" ? `${pluralize("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`;
12768
+ }
12769
+
12770
+ const ATTENTION_FACES = {
12771
+ blocked: {
12772
+ Icon: ErrorOutlineIcon,
12773
+ tone: "critical"
12774
+ },
12775
+ overdue: LATE_FACE
12776
+ };
12777
+
12778
+ function AttentionMark({detail: detail, now: now, tasks: tasks}) {
12779
+ if (detail.kind === "overdue") {
12780
+ const {hint: hint2, value: value} = overdueMark(detail, now);
12781
+ /* @__PURE__ */
12782
+ return jsx(MetricPair, {
12783
+ Icon: ATTENTION_FACES.overdue.Icon,
12784
+ face: overdueMarkOpensPanel(tasks) ? stageTasksFace({
12785
+ now: now,
12786
+ tasks: tasks
12787
+ }) : {
12788
+ text: hint2
12789
+ },
12790
+ label: hint2,
12791
+ tone: ATTENTION_FACES.overdue.tone,
12792
+ value: value
12793
+ });
12794
+ }
12795
+ const hint = blockedMarkHint(detail);
12796
+ /* @__PURE__ */
12797
+ return jsx(AlertChip, {
12798
+ Icon: ATTENTION_FACES.blocked.Icon,
12799
+ hint: hint,
12800
+ label: hint,
12801
+ tone: ATTENTION_FACES.blocked.tone
12802
+ });
12803
+ }
12804
+
12805
+ function documentRefsOf(instance) {
12806
+ const seen = /* @__PURE__ */ new Map;
12807
+ for (const ref of entryDocRefs(instance.fields)) seen.has(ref.id) || seen.set(ref.id, ref);
12808
+ return [ ...seen.values() ];
12809
+ }
12810
+
12811
+ function rootInstanceOf(instance, byId) {
12812
+ const rootRef = instance.ancestors[0];
12813
+ return rootRef ? byId.get(toBareId(rootRef.id)) ?? instance : instance;
12814
+ }
12815
+
12816
+ function runsScopeOf(row) {
12817
+ return row.endedAt === void 0 ? "open" : "closed";
12818
+ }
12819
+
12820
+ function rowHasTaskHeldBy(row, who) {
12821
+ return row.tasks.some(task => assignmentMatch(task.assignees, who) !== void 0);
12822
+ }
12823
+
12824
+ function runCountsByWorkflow(rows) {
12825
+ return countBy(rows, row => [ row.workflowName ]);
12826
+ }
12827
+
12828
+ function runCountsByAssignee(rows) {
12829
+ return countBy(rows, row => new Set(userIdsOf(row.assignees)));
12830
+ }
12831
+
12832
+ function runCountsByRole(rows) {
12833
+ return countBy(rows, row => new Set(row.assignees.flatMap(assignee => assignee.type === "role" ? [ assignee.role ] : [])));
12834
+ }
12835
+
12836
+ function runAttentionCounts(rows) {
12837
+ let blocked = 0, overdue = 0;
12838
+ for (const row of rows) row.attention === "blocked" && (blocked += 1), row.attention === "overdue" && (overdue += 1);
12839
+ return {
12840
+ blocked: blocked,
12841
+ overdue: overdue
12842
+ };
12843
+ }
12844
+
12845
+ function unassignedRunCount(rows) {
12846
+ return rows.filter(row => row.assignmentStateCounts.unrouted > 0).length;
12847
+ }
12848
+
12849
+ function runCountsByStage(rows) {
12850
+ return countBy(rows, row => [ row.stage ]);
12851
+ }
12852
+
12853
+ function runCountsByRelease(rows) {
12854
+ return countBy(rows, row => new Set(row.releases));
12855
+ }
12856
+
12857
+ function noReleaseRunCount(rows) {
12858
+ return rows.filter(row => row.releases.length === 0).length;
12859
+ }
12860
+
12861
+ function releasesOfPerspective(perspective) {
12862
+ return Array.isArray(perspective) ? perspective.filter(name => name !== "drafts") : [];
12863
+ }
12864
+
12865
+ function runRowsOf(args) {
12866
+ const byId = new Map(args.previews.map(preview => [ preview._id, preview ]));
12867
+ return args.previews.map(preview => runRowOf({
12868
+ byId: byId,
12869
+ definitions: args.definitions,
12870
+ now: args.now,
12871
+ preview: preview
12872
+ }));
12873
+ }
12874
+
12875
+ function runRowOf(args) {
12876
+ const {byId: byId, definitions: definitions, now: now, preview: preview} = args, definition = definitions.get(preview.definition), settled = terminalState(preview) !== "in-flight", held = settled ? NO_ASSIGNEES : openAssignees(preview), attentionDetail = settled ? void 0 : blockedRunDetail({
12877
+ definition: definition,
12878
+ preview: preview
12879
+ }) ?? overdueRunDetail({
12880
+ definition: definition,
12881
+ now: now,
12882
+ preview: preview
12883
+ });
12884
+ return {
12885
+ id: preview._id,
12886
+ document: documentRefsOf(rootInstanceOf(preview, byId))[0],
12887
+ workflowName: preview.definition,
12888
+ workflowTitle: definition?.title ?? preview.definition,
12889
+ stage: preview.currentStage,
12890
+ stageTitle: stageTitle(definition, preview.currentStage),
12891
+ releases: releasesOfPerspective(preview.perspective),
12892
+ startedAt: preview.startedAt,
12893
+ endedAt: settled ? preview.completedAt ?? preview.abortedAt : void 0,
12894
+ outcome: outcomeOf(preview, definition),
12895
+ attention: attentionKindOf(attentionDetail),
12896
+ attentionDetail: attentionDetail,
12897
+ assignees: held.assignees,
12898
+ assignments: held.assignments,
12899
+ assignmentStateCounts: held.counts,
12900
+ tasks: settled ? [] : stageTasksOf({
12901
+ definition: definition,
12902
+ instance: preview,
12903
+ now: now
12904
+ })
12905
+ };
12906
+ }
12907
+
12908
+ function attentionKindOf(detail) {
12909
+ if (detail !== void 0) return detail.kind === "overdue" ? "overdue" : "blocked";
12910
+ }
12911
+
12912
+ function blockedArmOf(detail) {
12913
+ if (!(detail === void 0 || detail.kind === "overdue")) return detail;
12914
+ }
12915
+
12916
+ function overdueArmOf(detail) {
12917
+ return detail?.kind === "overdue" ? detail : void 0;
12918
+ }
12919
+
12920
+ function outcomeOf(preview, definition) {
12921
+ const state = terminalState(preview);
12922
+ if (state !== "in-flight") return state === "aborted" ? "Aborted" : stageTitle(definition, preview.currentStage);
12923
+ }
12924
+
12925
+ function blockedRunDetail(args) {
12926
+ const {definition: definition, preview: preview} = args, {stage: stage, titleOf: titleOf2} = activityTitleResolver(preview, definition), failed = (stage?.activities ?? []).filter(activity => activity.status === "failed");
12927
+ if (failed.length > 1) return {
12928
+ count: failed.length,
12929
+ kind: "blocked-many"
12930
+ };
12931
+ const only = failed[0];
12932
+ if (only !== void 0) return {
12933
+ kind: "blocked",
12934
+ task: titleOf2(only.name)
12935
+ };
12936
+ const stuck = stuckEffectOf({
12937
+ definition: definition,
12938
+ preview: preview,
12939
+ stage: stage
12940
+ });
12941
+ return stuck === void 0 ? void 0 : {
12942
+ effect: stuck.effect.title ?? stuck.effect.name,
12943
+ failed: stuck.failed,
12944
+ kind: "blocked-effect"
12945
+ };
12946
+ }
12947
+
12948
+ function stuckEffectOf(args) {
12949
+ const reported = failedDeclaredEffect(args);
12950
+ if (reported !== void 0) return {
12951
+ effect: reported,
12952
+ failed: !0
12953
+ };
12954
+ const claimed = args.preview.claimedEffects[0];
12955
+ return claimed === void 0 ? void 0 : {
12956
+ effect: claimed,
12957
+ failed: !1
12958
+ };
12959
+ }
12960
+
12961
+ function failedDeclaredEffect(args) {
12962
+ const {definition: definition, preview: preview, stage: stage} = args;
12963
+ if (definition === void 0 || definition.version !== preview.pinnedVersion || stage === void 0) return;
12964
+ const stageNode = findStageNode({
12965
+ definition: definition,
12966
+ stageName: stage.name
12967
+ }), 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))));
12968
+ return [ ...preview.failedEffects ].reverse().find(effect => declared.has(effect.name));
12969
+ }
12970
+
12971
+ function overdueRunDetail(args) {
12972
+ const {definition: definition, now: now, preview: preview} = args, late = overdueTasks(preview, now);
12973
+ if (late.length === 0) return;
12974
+ const {titleOf: titleOf2} = activityTitleResolver(preview, definition), only = late.length === 1 ? late[0] : void 0;
12975
+ return {
12976
+ dues: late.flatMap(activity => {
12977
+ const due = passedDueOf(activity, now);
12978
+ return due === void 0 ? [] : [ due ];
12979
+ }),
12980
+ kind: "overdue",
12981
+ task: only === void 0 ? void 0 : titleOf2(only.name)
12982
+ };
12983
+ }
12984
+
12985
+ function activityTitleResolver(preview, definition) {
12986
+ const stage = findOpenStageEntry(preview);
12987
+ return {
12988
+ stage: stage,
12989
+ titleOf: activityName => findActivity({
12990
+ activityName: activityName,
12991
+ definition: definition,
12992
+ stageName: stage?.name ?? ""
12993
+ }).title
12994
+ };
12995
+ }
12996
+
12997
+ const NO_ASSIGNEES = {
12998
+ assignees: [],
12999
+ assignments: [],
13000
+ counts: {
13001
+ unrouted: 0,
13002
+ routed: 0,
13003
+ held: 0
13004
+ }
13005
+ };
13006
+
13007
+ function openAssignees(instance) {
13008
+ const users = /* @__PURE__ */ new Map, roles = /* @__PURE__ */ new Map, assignments = openActivityAssignments(instance), counts = {
13009
+ unrouted: 0,
13010
+ routed: 0,
13011
+ held: 0
13012
+ };
13013
+ for (const members of assignments) counts[assignmentState(members)] += 1, recordAssignees(activeAssignmentMembers(members), {
13014
+ users: users,
13015
+ roles: roles
13016
+ });
13017
+ return {
13018
+ assignees: [ ...users.values(), ...roles.values() ],
13019
+ assignments: assignments,
13020
+ counts: counts
13021
+ };
13022
+ }
13023
+
13024
+ function recordAssignees(assignees, maps) {
13025
+ for (const assignee of assignees) (assignee.type === "user" ? maps.users : maps.roles).set(assignee.type === "user" ? assignee.id : assignee.role, assignee);
13026
+ }
13027
+
13028
+ function tasksWidthOf(tableWidth) {
13029
+ return tableWidth === void 0 ? 176 : tableWidth >= 1040 ? 224 : 176;
13030
+ }
13031
+
13032
+ function taskRoomOf(args) {
13033
+ const cell = tasksWidthOf(args.tableWidth) - args.inset * 2;
13034
+ return args.overdue ? cell - 76 - args.gap : cell;
13035
+ }
13036
+
13037
+ const OPEN_COLUMNS = [ {
13038
+ key: "document",
13039
+ label: "Workflow subject"
13040
+ }, {
13041
+ key: "workflow",
13042
+ label: "Workflow",
13043
+ width: TABLE_WORKFLOW_WIDTH
13044
+ }, {
13045
+ key: "stage",
13046
+ label: "Stage",
13047
+ width: TABLE_STAGE_WIDTH
13048
+ }, {
13049
+ key: "started",
13050
+ label: "Started",
13051
+ width: TABLE_TIME_WIDTH
13052
+ } ], CLOSED_COLUMNS = [ {
13053
+ key: "document",
13054
+ label: "Workflow subject"
13055
+ }, {
13056
+ key: "workflow",
13057
+ label: "Workflow",
13058
+ width: TABLE_WORKFLOW_WIDTH
13059
+ }, {
13060
+ key: "outcome",
13061
+ label: "Outcome",
13062
+ width: TABLE_STAGE_WIDTH
13063
+ }, {
13064
+ key: "started",
13065
+ label: "Started",
13066
+ width: TABLE_TIME_WIDTH
13067
+ }, {
13068
+ key: "ended",
13069
+ label: "Closed",
13070
+ width: TABLE_TIME_WIDTH
13071
+ } ];
13072
+
13073
+ function runsTableColumnsOf(args) {
13074
+ const columns = args.scope === "closed" ? CLOSED_COLUMNS : OPEN_COLUMNS;
13075
+ return args.scopedToWorkflow ? columns.filter(column => column.key !== "workflow") : columns;
13076
+ }
13077
+
13078
+ function runsDocumentWidthOf(args) {
13079
+ const trailing = args.scope === "open" ? tasksWidthOf(args.tableWidth) : 0;
13080
+ return fillColumnWidth({
13081
+ columns: args.columns,
13082
+ tableWidth: args.tableWidth,
13083
+ trailingWidth: trailing
13084
+ });
13085
+ }
13086
+
13087
+ const TASKS_CELL_GAP_TOKEN = 3;
13088
+
13089
+ function RunsTable({now: now, onNavigateKey: onNavigateKey, onSelectRun: onSelectRun, onSort: onSort, rows: rows, scope: scope, scopedToWorkflow: scopedToWorkflow, selectedId: selectedId, selectedRef: selectedRef, sort: sort}) {
13090
+ const columns = runsTableColumnsOf({
13091
+ scope: scope,
13092
+ scopedToWorkflow: scopedToWorkflow
13093
+ }), cellInset = useSpaceToken(2), markGap = useSpaceToken(TASKS_CELL_GAP_TOKEN);
13094
+ /* @__PURE__ */
13095
+ return jsx(VirtualTable, {
13096
+ renderHeader: args => /* @__PURE__ */ jsx(RunsHeader, {
13097
+ columns: columns,
13098
+ onSort: onSort,
13099
+ scope: scope,
13100
+ sort: sort,
13101
+ styles: args.styles,
13102
+ tableWidth: args.tableWidth
13103
+ }),
13104
+ keyAt: index => rows[index]?.id ?? String(index),
13105
+ renderRow: ({index: index, key: key, measureRow: measureRow, tableWidth: tableWidth}) => {
13106
+ const row = rows[index];
13107
+ if (row === void 0) return null;
13108
+ const overdue = overdueArmOf(row.attentionDetail);
13109
+ /* @__PURE__ */
13110
+ return jsx(RunTableRow, {
13111
+ dataIndex: index,
13112
+ measureRow: measureRow,
13113
+ now: now,
13114
+ onNavigateKey: onNavigateKey,
13115
+ onSelectRun: onSelectRun,
13116
+ row: row,
13117
+ scope: scope,
13118
+ scopedToWorkflow: scopedToWorkflow,
13119
+ selected: row.id === selectedId,
13120
+ selectedRef: selectedRef,
13121
+ overdue: overdue,
13122
+ taskRoom: taskRoomOf({
13123
+ gap: markGap,
13124
+ inset: cellInset,
13125
+ overdue: overdue !== void 0,
13126
+ tableWidth: tableWidth
13127
+ })
13128
+ }, key);
13129
+ },
13130
+ rowCount: rows.length
13131
+ });
13132
+ }
13133
+
13134
+ function RunsHeader({columns: columns, onSort: onSort, scope: scope, sort: sort, styles: styles, tableWidth: tableWidth}) {
13135
+ /* @__PURE__ */
13136
+ return jsx(SortableHeaderCells, {
13137
+ columns: columns,
13138
+ onSort: onSort,
13139
+ sort: sort,
13140
+ styles: styles,
13141
+ tableWidth: tableWidth,
13142
+ widthOf: (column, width) => column.key === "document" ? runsDocumentWidthOf({
13143
+ columns: columns,
13144
+ scope: scope,
13145
+ tableWidth: width
13146
+ }) : resolveColumnWidth(column.width, width),
13147
+ children: scope === "open" ? /* @__PURE__ */ jsx("th", {
13148
+ style: {
13149
+ ...styles.head,
13150
+ width: tasksWidthOf(tableWidth)
13151
+ },
13152
+ children: /* @__PURE__ */ jsx(Box, {
13153
+ padding: 2,
13154
+ children: /* @__PURE__ */ jsx(Text, {
13155
+ muted: !0,
13156
+ size: 1,
13157
+ children: "Tasks"
13158
+ })
13159
+ })
13160
+ }) : null
13161
+ });
13162
+ }
13163
+
13164
+ const RunTableRow = 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}) {
13165
+ const styles = useTableStyles(), documentInset = useSpaceToken(1);
13166
+ /* @__PURE__ */
13167
+ return jsxs(TableRowCard, {
13168
+ dataIndex: dataIndex,
13169
+ onClick: () => onSelectRun(row),
13170
+ onKeyDown: onNavigateKey,
13171
+ rowRef: measureRow,
13172
+ selected: selected,
13173
+ selectedRef: selectedRef,
13174
+ children: [
13175
+ /* @__PURE__ */ jsx("td", {
13176
+ style: {
13177
+ ...styles.cell,
13178
+ paddingLeft: documentInset
13179
+ },
13180
+ children: /* @__PURE__ */ jsx(TableSubjectCell, {
13181
+ document: row.document
13182
+ })
13183
+ }), scopedToWorkflow ? null : /* @__PURE__ */ jsx("td", {
13184
+ style: styles.cell,
13185
+ children: /* @__PURE__ */ jsx(Text, {
13186
+ muted: !0,
13187
+ size: 1,
13188
+ textOverflow: "ellipsis",
13189
+ children: row.workflowTitle
13190
+ })
13191
+ }), scope === "closed" ? /* @__PURE__ */ jsx(ClosedCells, {
13192
+ now: now,
13193
+ row: row
13194
+ }) : /* @__PURE__ */ jsx(OpenCells, {
13195
+ now: now,
13196
+ overdue: overdue,
13197
+ row: row,
13198
+ taskRoom: taskRoom
13199
+ }) ]
13200
+ });
13201
+ });
13202
+
13203
+ function OpenCells({now: now, overdue: overdue, row: row, taskRoom: taskRoom}) {
13204
+ const styles = useTableStyles(), blocked = blockedArmOf(row.attentionDetail);
13205
+ /* @__PURE__ */
13206
+ return jsxs(Fragment, {
13207
+ children: [
13208
+ /* @__PURE__ */ jsx("td", {
13209
+ style: styles.cell,
13210
+ children: /* @__PURE__ */ jsxs(Flex, {
13211
+ align: "center",
13212
+ gap: 2,
13213
+ children: [
13214
+ /* @__PURE__ */ jsx(Text, {
13215
+ size: 1,
13216
+ textOverflow: "ellipsis",
13217
+ children: row.stageTitle
13218
+ }), blocked === void 0 ? null : /* @__PURE__ */ jsx(AttentionMark, {
13219
+ detail: blocked,
13220
+ now: now,
13221
+ tasks: row.tasks
13222
+ }) ]
13223
+ })
13224
+ }),
13225
+ /* @__PURE__ */ jsx("td", {
13226
+ style: styles.cell,
13227
+ children: /* @__PURE__ */ jsx(AgoStamp, {
13228
+ at: row.startedAt,
13229
+ now: now
13230
+ })
13231
+ }),
13232
+ /* @__PURE__ */ jsx("td", {
13233
+ style: {
13234
+ ...styles.cell,
13235
+ overflow: "hidden"
13236
+ },
13237
+ children: /* @__PURE__ */ jsxs(Flex, {
13238
+ align: "center",
13239
+ gap: TASKS_CELL_GAP_TOKEN,
13240
+ children: [
13241
+ /* @__PURE__ */ jsx(StageTaskGroups, {
13242
+ now: now,
13243
+ room: taskRoom,
13244
+ tasks: row.tasks
13245
+ }), overdue === void 0 ? null : /* @__PURE__ */ jsx(AttentionMark, {
13246
+ detail: overdue,
13247
+ now: now,
13248
+ tasks: row.tasks
13249
+ }) ]
13250
+ })
13251
+ }) ]
13252
+ });
13253
+ }
13254
+
13255
+ function ClosedCells({now: now, row: row}) {
13256
+ const styles = useTableStyles();
13257
+ /* @__PURE__ */
13258
+ return jsxs(Fragment, {
13259
+ children: [
13260
+ /* @__PURE__ */ jsx("td", {
13261
+ style: styles.cell,
13262
+ children: /* @__PURE__ */ jsx(Text, {
13263
+ size: 1,
13264
+ textOverflow: "ellipsis",
13265
+ children: row.outcome
13266
+ })
13267
+ }),
13268
+ /* @__PURE__ */ jsx("td", {
13269
+ style: styles.cell,
13270
+ children: /* @__PURE__ */ jsx(AgoStamp, {
13271
+ at: row.startedAt,
13272
+ now: now
13273
+ })
13274
+ }),
13275
+ /* @__PURE__ */ jsx("td", {
13276
+ style: styles.cell,
13277
+ children: row.endedAt === void 0 ? null : /* @__PURE__ */ jsx(AgoStamp, {
13278
+ at: row.endedAt,
13279
+ now: now
13280
+ })
13281
+ }) ]
13282
+ });
13283
+ }
13284
+
13285
+ function DueStamp({due: due, now: now}) {
13286
+ /* @__PURE__ */
13287
+ return jsx(Flex, {
13288
+ align: "center",
13289
+ children: /* @__PURE__ */ jsx(_HoverHint, {
13290
+ text: dueMomentSentence(due, now),
13291
+ children: isDueDatePast(due, now) ? /* @__PURE__ */ jsx(LateSpan, {
13292
+ now: now,
13293
+ since: due
13294
+ }) :
13295
+ /* @__PURE__ */ jsx(Text, {
13296
+ muted: !0,
13297
+ size: 1,
13298
+ style: {
13299
+ whiteSpace: "nowrap"
13300
+ },
13301
+ children: formatDate(due)
13302
+ })
13303
+ })
13304
+ });
13305
+ }
13306
+
13307
+ const TASK_WIDTH = {
13308
+ cap: 280,
13309
+ fraction: .22
13310
+ }, FOR_ME_ATTENTION_WIDTH = 48, FOR_ME_ASSIGNEE_WIDTH = 96, FOR_ME_COLUMNS = [ {
13311
+ key: "document",
13312
+ label: "Workflow subject"
13313
+ }, {
13314
+ key: "task",
13315
+ label: "Task",
13316
+ width: TASK_WIDTH
13317
+ }, {
13318
+ key: "opened",
13319
+ label: "Opened",
13320
+ width: TABLE_TIME_WIDTH
13321
+ }, {
13322
+ key: "workflow",
13323
+ label: "Workflow",
13324
+ width: TABLE_WORKFLOW_WIDTH
13325
+ }, {
13326
+ key: "due",
13327
+ label: "Due",
13328
+ width: TABLE_TIME_WIDTH
13329
+ } ];
13330
+
13331
+ function forMeDocumentWidthOf(tableWidth) {
13332
+ return fillColumnWidth({
13333
+ columns: FOR_ME_COLUMNS,
13334
+ tableWidth: tableWidth,
13335
+ trailingWidth: FOR_ME_ASSIGNEE_WIDTH + FOR_ME_ATTENTION_WIDTH
13336
+ });
13337
+ }
13338
+
13339
+ function ForMeTable({now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, onSort: onSort, rows: rows, selectedId: selectedId, selectedRef: selectedRef, sort: sort}) {
13340
+ /* @__PURE__ */
13341
+ return jsx(VirtualTable, {
13342
+ renderHeader: args => /* @__PURE__ */ jsxs(SortableHeaderCells, {
13343
+ columns: FOR_ME_COLUMNS,
13344
+ onSort: onSort,
13345
+ sort: sort,
13346
+ styles: args.styles,
13347
+ tableWidth: args.tableWidth,
13348
+ widthOf: (column, tableWidth) => column.key === "document" ? forMeDocumentWidthOf(tableWidth) : resolveColumnWidth(column.width, tableWidth),
13349
+ children: [
13350
+ /* @__PURE__ */ jsx("th", {
13351
+ style: {
13352
+ ...args.styles.head,
13353
+ width: FOR_ME_ASSIGNEE_WIDTH
13354
+ },
13355
+ children: /* @__PURE__ */ jsx(Box, {
13356
+ padding: 2,
13357
+ children: /* @__PURE__ */ jsx(Text, {
13358
+ muted: !0,
13359
+ size: 1,
13360
+ children: "Assignee"
13361
+ })
13362
+ })
13363
+ }),
13364
+ /* @__PURE__ */ jsx("th", {
13365
+ "aria-label": "Attention",
13366
+ style: {
13367
+ ...args.styles.head,
13368
+ width: FOR_ME_ATTENTION_WIDTH
13369
+ }
13370
+ }) ]
13371
+ }),
13372
+ keyAt: index => rows[index]?.id ?? String(index),
13373
+ renderRow: ({index: index, key: key, measureRow: measureRow}) => {
13374
+ const row = rows[index];
13375
+ return row === void 0 ? null : /* @__PURE__ */ jsx(ForMeTableRow, {
13376
+ dataIndex: index,
13377
+ measureRow: measureRow,
13378
+ now: now,
13379
+ onNavigateKey: onNavigateKey,
13380
+ onSelect: onSelect,
13381
+ row: row,
13382
+ selected: row.id === selectedId,
13383
+ selectedRef: selectedRef
13384
+ }, key);
13385
+ },
13386
+ rowCount: rows.length
13387
+ });
13388
+ }
13389
+
13390
+ const ForMeTableRow = memo(function({dataIndex: dataIndex, measureRow: measureRow, now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, row: row, selected: selected, selectedRef: selectedRef}) {
13391
+ const styles = useTableStyles(), documentInset = useSpaceToken(1);
13392
+ /* @__PURE__ */
13393
+ return jsxs(TableRowCard, {
13394
+ dataIndex: dataIndex,
13395
+ onClick: () => onSelect(row),
13396
+ onKeyDown: onNavigateKey,
13397
+ rowRef: measureRow,
13398
+ selected: selected,
13399
+ selectedRef: selectedRef,
13400
+ children: [
13401
+ /* @__PURE__ */ jsx("td", {
13402
+ style: {
13403
+ ...styles.cell,
13404
+ paddingLeft: documentInset
13405
+ },
13406
+ children: /* @__PURE__ */ jsx(TableSubjectCell, {
13407
+ document: row.document
13408
+ })
13409
+ }),
13410
+ /* @__PURE__ */ jsx("td", {
13411
+ style: styles.cell,
13412
+ children: /* @__PURE__ */ jsx(Text, {
13413
+ size: 1,
13414
+ textOverflow: "ellipsis",
13415
+ children: row.title
13416
+ })
13417
+ }),
13418
+ /* @__PURE__ */ jsx("td", {
13419
+ style: styles.cell,
13420
+ children: /* @__PURE__ */ jsx(AgoStamp, {
13421
+ at: row.openedAt,
13422
+ now: now
13423
+ })
13424
+ }),
13425
+ /* @__PURE__ */ jsx("td", {
13426
+ style: styles.cell,
13427
+ children: /* @__PURE__ */ jsx(Text, {
13428
+ muted: !0,
13429
+ size: 1,
13430
+ textOverflow: "ellipsis",
13431
+ children: row.workflowTitle
13432
+ })
13433
+ }),
13434
+ /* @__PURE__ */ jsx("td", {
13435
+ style: styles.cell,
13436
+ children: row.due === void 0 ? null : /* @__PURE__ */ jsx(DueStamp, {
13437
+ due: row.due,
13438
+ now: now
13439
+ })
13440
+ }),
13441
+ /* @__PURE__ */ jsx("td", {
13442
+ style: {
13443
+ ...styles.cell,
13444
+ overflow: "hidden"
13445
+ },
13446
+ children: /* @__PURE__ */ jsx(Flex, {
13447
+ align: "center",
13448
+ children: /* @__PURE__ */ jsx(RowAssignees, {
13449
+ assignees: row.assignees
13450
+ })
13451
+ })
13452
+ }),
13453
+ /* @__PURE__ */ jsx("td", {
13454
+ style: styles.cell,
13455
+ children: /* @__PURE__ */ jsx(ForMeAttentionCell, {
13456
+ now: now,
13457
+ row: row
13458
+ })
13459
+ }) ]
13460
+ });
13461
+ });
13462
+
13463
+ function ForMeAttentionCell({now: now, row: row}) {
13464
+ const blocked = blockedArmOf(row.attentionDetail);
13465
+ return blocked === void 0 ? null : /* @__PURE__ */ jsx(Flex, {
13466
+ align: "center",
13467
+ children: /* @__PURE__ */ jsx(AttentionMark, {
13468
+ detail: blocked,
13469
+ now: now,
13470
+ tasks: []
13471
+ })
13472
+ });
13473
+ }
13474
+
13475
+ function forMeRowId(instanceId, activityName) {
13476
+ return `${instanceId}\t${activityName}`;
13477
+ }
13478
+
13479
+ function forMeTaskRowsOf(args) {
13480
+ const {rows: rows, who: who} = args;
13481
+ return rows.flatMap(row => row.tasks.flatMap(task => {
13482
+ const assignment = assignmentHolding(task.assignees, who);
13483
+ if (assignment === "other") return [];
13484
+ const attentionDetail = taskAttentionDetail({
13485
+ row: row,
13486
+ task: task
13487
+ });
13488
+ return [ {
13489
+ id: forMeRowId(row.id, task.name),
13490
+ instanceId: row.id,
13491
+ activityName: task.name,
13492
+ title: task.title,
13493
+ document: row.document,
13494
+ workflowTitle: row.workflowTitle,
13495
+ releases: row.releases,
13496
+ openedAt: task.openedAt,
13497
+ due: task.due,
13498
+ attention: attentionKindOf(attentionDetail),
13499
+ attentionDetail: attentionDetail,
13500
+ assignees: task.assignees,
13501
+ assignment: assignment
13502
+ } ];
13503
+ }));
13504
+ }
13505
+
13506
+ function forMeSummaryOf(rows) {
13507
+ const documents = new Set(rows.flatMap(row => row.document === void 0 ? [] : [ row.document.id ])), releases = new Set(rows.flatMap(row => row.releases));
13508
+ return {
13509
+ lead: rows.length === 0 ? "No tasks" : pluralize("task", rows.length, !0),
13510
+ subjects: `on ${pluralize("document", documents.size, !0)}, and ${pluralize("release", releases.size, !0)}`
13511
+ };
13512
+ }
13513
+
13514
+ function forMeSectionsOf(rows) {
13515
+ return {
13516
+ assignedToUser: rows.filter(row => row.assignment === "you"),
13517
+ assignedToRoles: rows.filter(row => row.assignment === "role")
13518
+ };
13519
+ }
13520
+
13521
+ function resolveForMeAddress(args) {
13522
+ const {rows: rows, run: run, task: task} = args;
13523
+ if (run === void 0) return;
13524
+ if (task !== void 0) return rows.some(row => row.instanceId === run && row.activityName === task) ? {
13525
+ run: run,
13526
+ task: task
13527
+ } : void 0;
13528
+ const first = rows.find(row => row.instanceId === run);
13529
+ return first === void 0 ? void 0 : {
13530
+ run: first.instanceId,
13531
+ task: first.activityName
13532
+ };
13533
+ }
13534
+
13535
+ function taskAttentionDetail(args) {
13536
+ const {row: row, task: task} = args;
13537
+ if (task.status === "failed") return {
13538
+ kind: "blocked",
13539
+ task: task.title
13540
+ };
13541
+ if (row.attention === "blocked") return row.attentionDetail;
13542
+ if (task.overdueSince !== void 0) return {
13543
+ dues: [ task.overdueSince ],
13544
+ kind: "overdue",
13545
+ task: task.title
13546
+ };
13547
+ }
13548
+
13549
+ export { ATTENTION_FACES, AbortWorkflowDialog, ActivityDetailBody, ActivityDetailDialog, ActivityLog, AlertGlyph, AttentionMark, Breadcrumb, CodeChip, CountedLabel, DismissablePopover, DocPreviewLink, DocRefFace, EmptyState, FOR_ME_SECTION_COPY, ForMeEmptyState, ForMeSectionHeading, ForMeTable, InstanceFaultNote, InstanceSnapshotBody, InvalidDocNotice, LoadingRow, LogEventOnMount, MetaRow, MetricPair, NoteBanner, RUN_SEARCH_PARAM, RunsTable, SectionHeading, SortHeaderButton, SpinnerSlot, StageTaskGroups, TOOL_TABS, TabSwitch, TableRowCard, UNREADABLE_DOCUMENT, UnreadableDocsNote, WORKFLOW_API_VERSION, WorkflowBoardWorkflowSelected, WorkflowDefinitionDetailViewed, WorkflowInstanceDetailViewed, WorkflowTitleSeedDrifted, WorkflowToolOpened, blockedAttentionHint, blockedRunDetail, countBy, definitionFingerprint, definitionsRouteOf, deriveActivityDetail, describeError, documentRefsOf, forMeRowId, forMeSectionsOf, forMeSummaryOf, forMeTaskRowsOf, formatTimeAgo, gdrLocality, identityOf, instanceBreadcrumb, instanceTitle, isEvaluationStale, isLiveEntry, landingState, mappingIssueDetail, namesNoDeployedDefinition, noReleaseRunCount, openActivityGone, openableSchemaType, overdueAttentionHint, overdueRunDetail, readDeployedDefinitions, resolveForMeAddress, rowHasTaskHeldBy, runAttentionCounts, runCountsByAssignee, runCountsByRelease, runCountsByRole, runCountsByStage, runCountsByWorkflow, runRowsOf, runsScopeOf, scrollParentOf, stageTasksOf, stageTitle, tabSelectionNavigates, toolRoute, toolTabState, unassignedRunCount, useAlertChipSize, useAssignmentIdentity, useAvatarSize, useCapTrimFor, useContainerToken, useCurrentUserId, useDefinition, useLogEventOnMount, useMinuteClock, useProjectMembers, useRadiusToken, useReleaseTitles, useSpaceToken, useTableStyles, useTextIconSize, useUserDisplays, useWorkflowContext, useWorkflowInstanceEntry, userIdsOf, workflowDefaultDocumentNode, workflowState, workflowStudioPlugin, workflowsView };