@sanity/workflow-studio-plugin 0.32.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- var jsxRuntime = require("react/jsx-runtime"), ChevronDown = require("@sanity/icons/ChevronDown"), ChevronRight = require("@sanity/icons/ChevronRight"), EllipsisHorizontal = require("@sanity/icons/EllipsisHorizontal"), Launch = require("@sanity/icons/Launch"), ui = require("@sanity/ui"), workflowReact = require("@sanity/workflow-react"), react = require("react"), router = require("sanity/router"), index = require("./index.cjs"), Transfer = require("@sanity/icons/Transfer"), WarningOutline = require("@sanity/icons/WarningOutline"), sanity = require("sanity"), workflowComponents = require("@sanity/workflow-components"), workflowEngine = require("@sanity/workflow-engine"), reactVirtual = require("@tanstack/react-virtual"), workflowStudio = require("@sanity/workflow-studio"), pluralize = require("pluralize-esm"), ChevronLeft = require("@sanity/icons/ChevronLeft"), Close = require("@sanity/icons/Close"), Expand = require("@sanity/icons/Expand"), react$1 = require("motion/react"), Calendar = require("@sanity/icons/Calendar"), ErrorOutline = require("@sanity/icons/ErrorOutline"), User = require("@sanity/icons/User"), Users = require("@sanity/icons/Users"), reactDom = require("react-dom"), styledComponents = require("styled-components"), types = require("@sanity/types"), Add = require("@sanity/icons/Add"), Checkmark = require("@sanity/icons/Checkmark"), Search = require("@sanity/icons/Search"), workflowDiagram = require("@sanity/workflow-diagram");
3
+ var jsxRuntime = require("react/jsx-runtime"), ChevronDown = require("@sanity/icons/ChevronDown"), ChevronRight = require("@sanity/icons/ChevronRight"), EllipsisHorizontal = require("@sanity/icons/EllipsisHorizontal"), Launch = require("@sanity/icons/Launch"), ui = require("@sanity/ui"), menu = require("@sanity/ui/menu"), workflowReact = require("@sanity/workflow-react"), react = require("react"), router = require("sanity/router"), index = require("./index.cjs"), Transfer = require("@sanity/icons/Transfer"), WarningOutline = require("@sanity/icons/WarningOutline"), workflowComponents = require("@sanity/workflow-components"), sanity = require("sanity"), workflowEngine = require("@sanity/workflow-engine"), workflowStudio = require("@sanity/workflow-studio"), pluralize = require("pluralize-esm"), ChevronLeft = require("@sanity/icons/ChevronLeft"), Close = require("@sanity/icons/Close"), Expand = require("@sanity/icons/Expand"), react$1 = require("motion/react"), reactVirtual = require("@tanstack/react-virtual"), reactDom = require("react-dom"), styledComponents = require("styled-components"), types = require("@sanity/types"), User = require("@sanity/icons/User"), popover = require("@sanity/ui/popover"), Add = require("@sanity/icons/Add"), Checkmark = require("@sanity/icons/Checkmark"), Search = require("@sanity/icons/Search"), workflowDiagram = require("@sanity/workflow-diagram");
4
4
 
5
5
  function _interopDefaultCompat(e) {
6
6
  return e && typeof e == "object" && "default" in e ? e : {
@@ -22,401 +22,6 @@ function MutedNote({text: text}) {
22
22
  });
23
23
  }
24
24
 
25
- function documentRefsOf(instance) {
26
- const seen = /* @__PURE__ */ new Map;
27
- for (const ref of workflowEngine.entryDocRefs(instance.fields)) seen.has(ref.id) || seen.set(ref.id, ref);
28
- return [ ...seen.values() ];
29
- }
30
-
31
- function rootInstanceOf(instance, byId) {
32
- const rootRef = instance.ancestors[0];
33
- return rootRef ? byId.get(workflowEngine.toBareId(rootRef.id)) ?? instance : instance;
34
- }
35
-
36
- function openActivitiesOf(instance) {
37
- return (workflowEngine.findOpenStageEntry(instance)?.activities ?? []).filter(activity => index.isOpenActivityStatus(activity.status));
38
- }
39
-
40
- function overdueTasks(instance, now) {
41
- return openActivitiesOf(instance).filter(activity => index.dueDatesOf(activity.fields ?? []).some(due => index.isDueDatePast(due, now)));
42
- }
43
-
44
- function earliestDue(activity) {
45
- return earliestOf(index.dueDatesOf(activity.fields ?? []));
46
- }
47
-
48
- function earliestPastDue(activity, now) {
49
- return earliestPastDueAcross([ activity ], now);
50
- }
51
-
52
- function earliestPastDueAcross(activities, now) {
53
- return earliestOf(activities.flatMap(activity => index.dueDatesOf(activity.fields ?? []).filter(due => index.isDueDatePast(due, now))));
54
- }
55
-
56
- function earliestOf(values) {
57
- let earliest;
58
- for (const value of values) {
59
- const time = index.parseStoredDateValue(value)?.getTime();
60
- time !== void 0 && (earliest === void 0 || time < earliest.time) && (earliest = {
61
- time: time,
62
- value: value
63
- });
64
- }
65
- return earliest?.value;
66
- }
67
-
68
- const AUTONOMY_BY_DEFINITION = /* @__PURE__ */ new WeakMap;
69
-
70
- function cachedAutonomy(definition) {
71
- const hit = AUTONOMY_BY_DEFINITION.get(definition);
72
- if (hit !== void 0) return hit;
73
- const derived = workflowEngine.deriveWorkflowAutonomy(definition);
74
- return AUTONOMY_BY_DEFINITION.set(definition, derived), derived;
75
- }
76
-
77
- function isAutomatedActivity(args) {
78
- const stage = args.autonomy?.stages.find(entry => entry.stage === args.stageName);
79
- return index.isHandsOff({
80
- classification: workflowEngine.deriveExecutorClassification(args.activity),
81
- completesWithoutCaller: stage?.activities[args.activity.name]?.completesWithoutCaller
82
- });
83
- }
84
-
85
- function taskOf(args) {
86
- const {entry: entry, now: now, openedAt: openedAt, roleAliases: roleAliases, title: title} = args;
87
- return {
88
- name: entry.name,
89
- title: title,
90
- assignees: index.assigneesOf(entry.fields ?? []),
91
- roleAliases: roleAliases,
92
- openedAt: openedAt,
93
- due: earliestDue(entry),
94
- overdueSince: earliestPastDue(entry, now),
95
- status: entry.status
96
- };
97
- }
98
-
99
- function humanTask(args) {
100
- const {activity: activity, autonomy: autonomy, entry: entry, now: now, openedAt: openedAt, roleAliases: roleAliases, stageName: stageName} = args;
101
- return entry === void 0 ? [] : isAutomatedActivity({
102
- activity: activity,
103
- autonomy: autonomy,
104
- stageName: stageName
105
- }) ? [] : [ taskOf({
106
- entry: entry,
107
- now: now,
108
- openedAt: openedAt,
109
- roleAliases: roleAliases,
110
- title: index.activityLabel(activity)
111
- }) ];
112
- }
113
-
114
- function undeclaredTasks(args) {
115
- const {definition: definition, now: now, open: open, openedAt: openedAt, roleAliases: roleAliases, seen: seen, stageName: stageName} = args;
116
- return open.filter(entry => !seen.has(entry.name)).map(entry => taskOf({
117
- entry: entry,
118
- now: now,
119
- openedAt: openedAt,
120
- roleAliases: roleAliases,
121
- title: index.findActivity({
122
- activityName: entry.name,
123
- definition: definition,
124
- stageName: stageName
125
- }).title
126
- }));
127
- }
128
-
129
- function definitionForPinned(definition, pinnedVersion) {
130
- if (!(definition === void 0 || definition.version !== pinnedVersion)) return definition;
131
- }
132
-
133
- function stageTasksOf(args) {
134
- const {definition: definition, instance: instance, now: now} = args, stageEntry = workflowEngine.findOpenStageEntry(instance);
135
- if (stageEntry === void 0) return [];
136
- const listed = listedStageActivities(stageEntry);
137
- if (listed.length === 0) return [];
138
- const openedAt = stageEntry.enteredAt, pinnedDefinition = definitionForPinned(definition, instance.pinnedVersion), autonomy = pinnedDefinition === void 0 ? void 0 : cachedAutonomy(pinnedDefinition), roleAliases = pinnedDefinition?.roleAliases, stageName = instance.currentStage, openByName = new Map(listed.map(entry => [ entry.name, entry ])), declared = workflowEngine.findStageNode({
139
- definition: definition,
140
- stageName: stageName
141
- })?.activities ?? [];
142
- return [ ...declared.flatMap(activity => humanTask({
143
- activity: activity,
144
- autonomy: autonomy,
145
- entry: openByName.get(activity.name),
146
- now: now,
147
- openedAt: openedAt,
148
- roleAliases: roleAliases,
149
- stageName: stageName
150
- })), ...undeclaredTasks({
151
- definition: definition,
152
- now: now,
153
- open: listed,
154
- openedAt: openedAt,
155
- roleAliases: roleAliases,
156
- seen: new Set(declared.map(activity => activity.name)),
157
- stageName: stageName
158
- }) ];
159
- }
160
-
161
- function listedStageActivities(stage) {
162
- return stage.activities.filter(entry => index.isOpenActivityStatus(entry.status) || entry.status === "failed");
163
- }
164
-
165
- function groupWidthOf(task, metrics) {
166
- const mark = taskAssignmentMarkOf(task.assignees), faces = mark.kind === "held" ? mark.members.length : 1;
167
- return metrics.face + (faces - 1) * (metrics.face - metrics.overlap);
168
- }
169
-
170
- function rowWidthOf(tasks, metrics) {
171
- return tasks.reduce((total, task) => total + groupWidthOf(task, metrics), 0) + Math.max(0, tasks.length - 1) * metrics.gap;
172
- }
173
-
174
- function countWithin(args) {
175
- const {budget: budget, metrics: metrics, tasks: tasks} = args;
176
- let used = 0, count = 0;
177
- for (const task of tasks) {
178
- const next = used + (count === 0 ? 0 : metrics.gap) + groupWidthOf(task, metrics);
179
- if (next > budget) break;
180
- used = next, count += 1;
181
- }
182
- return Math.max(1, count);
183
- }
184
-
185
- function visibleStageTasks(args) {
186
- const {metrics: metrics, room: room, tasks: tasks} = args;
187
- if (rowWidthOf(tasks, metrics) <= room) return {
188
- overflow: 0,
189
- visible: tasks
190
- };
191
- const shown = countWithin({
192
- budget: room - metrics.gap - metrics.counter,
193
- metrics: metrics,
194
- tasks: tasks
195
- });
196
- return {
197
- overflow: tasks.length - shown,
198
- visible: tasks.slice(0, shown)
199
- };
200
- }
201
-
202
- function taskAssignmentMarkOf(assignees) {
203
- const members = assignees.filter(assignee => assignee.type === "user");
204
- if (members.length > 0) return {
205
- kind: "held",
206
- members: members
207
- };
208
- const roles = assignees.flatMap(assignee => assignee.type === "role" ? [ assignee.role ] : []);
209
- return roles.length > 0 ? {
210
- kind: "routed",
211
- roles: roles
212
- } : {
213
- kind: "unassigned"
214
- };
215
- }
216
-
217
- function runsScopeOf(row) {
218
- return row.endedAt === void 0 ? "open" : "closed";
219
- }
220
-
221
- function rowHasTaskHeldBy(row, who) {
222
- return row.tasks.some(task => workflowComponents.assignmentMatch(task.assignees, who) !== void 0);
223
- }
224
-
225
- function runCountsByWorkflow(rows) {
226
- return index.countBy(rows, row => [ row.workflowName ]);
227
- }
228
-
229
- function runCountsByAssignee(rows) {
230
- return index.countBy(rows, row => new Set(index.userIdsOf(row.assignees)));
231
- }
232
-
233
- function runCountsByRole(rows) {
234
- return index.countBy(rows, row => new Set(row.assignees.flatMap(assignee => assignee.type === "role" ? [ assignee.role ] : [])));
235
- }
236
-
237
- function runAttentionCounts(rows) {
238
- let blocked = 0, overdue = 0;
239
- for (const row of rows) row.attention === "blocked" && (blocked += 1), row.attention === "overdue" && (overdue += 1);
240
- return {
241
- blocked: blocked,
242
- overdue: overdue
243
- };
244
- }
245
-
246
- function unassignedRunCount(rows) {
247
- return rows.filter(row => row.assignmentStateCounts.unrouted > 0).length;
248
- }
249
-
250
- function runCountsByStage(rows) {
251
- return index.countBy(rows, row => [ row.stage ]);
252
- }
253
-
254
- function runCountsByRelease(rows) {
255
- return index.countBy(rows, row => new Set(row.releases));
256
- }
257
-
258
- function noReleaseRunCount(rows) {
259
- return rows.filter(row => row.releases.length === 0).length;
260
- }
261
-
262
- function releasesOfPerspective(perspective) {
263
- return Array.isArray(perspective) ? perspective.filter(name => name !== "drafts") : [];
264
- }
265
-
266
- function runRowsOf(args) {
267
- const byId = new Map(args.previews.map(preview => [ preview._id, preview ]));
268
- return args.previews.map(preview => runRowOf({
269
- byId: byId,
270
- definitions: args.definitions,
271
- now: args.now,
272
- preview: preview
273
- }));
274
- }
275
-
276
- function runRowOf(args) {
277
- const {byId: byId, definitions: definitions, now: now, preview: preview} = args, definition = definitions.get(preview.definition), settled = workflowEngine.terminalState(preview) !== "in-flight", held = settled ? NO_ASSIGNEES : openAssignees(preview), attentionDetail = settled ? void 0 : blockedRunDetail({
278
- definition: definition,
279
- preview: preview
280
- }) ?? overdueRunDetail({
281
- definition: definition,
282
- now: now,
283
- preview: preview
284
- });
285
- return {
286
- id: preview._id,
287
- document: documentRefsOf(rootInstanceOf(preview, byId))[0],
288
- workflowName: preview.definition,
289
- workflowTitle: definition?.title ?? preview.definition,
290
- stage: preview.currentStage,
291
- stageTitle: index.stageTitle(definition, preview.currentStage),
292
- releases: releasesOfPerspective(preview.perspective),
293
- startedAt: preview.startedAt,
294
- endedAt: settled ? preview.completedAt ?? preview.abortedAt : void 0,
295
- outcome: outcomeOf(preview, definition),
296
- attention: attentionKindOf(attentionDetail),
297
- attentionDetail: attentionDetail,
298
- assignees: held.assignees,
299
- assignments: held.assignments,
300
- assignmentStateCounts: held.counts,
301
- tasks: settled ? [] : stageTasksOf({
302
- definition: definition,
303
- instance: preview,
304
- now: now
305
- })
306
- };
307
- }
308
-
309
- function attentionKindOf(detail) {
310
- if (detail !== void 0) return detail.kind === "overdue" ? "overdue" : "blocked";
311
- }
312
-
313
- function outcomeOf(preview, definition) {
314
- const state = workflowEngine.terminalState(preview);
315
- if (state !== "in-flight") return state === "aborted" ? "Aborted" : index.stageTitle(definition, preview.currentStage);
316
- }
317
-
318
- function blockedRunDetail(args) {
319
- const {definition: definition, preview: preview} = args, {stage: stage, titleOf: titleOf} = activityTitleResolver(preview, definition), failed = (stage?.activities ?? []).filter(activity => activity.status === "failed");
320
- if (failed.length > 1) return {
321
- count: failed.length,
322
- kind: "blocked-many"
323
- };
324
- const only = failed[0];
325
- if (only !== void 0) return {
326
- kind: "blocked",
327
- task: titleOf(only.name)
328
- };
329
- const stuck = stuckEffectOf({
330
- definition: definition,
331
- preview: preview,
332
- stage: stage
333
- });
334
- return stuck === void 0 ? void 0 : {
335
- effect: stuck.effect.title ?? stuck.effect.name,
336
- failed: stuck.failed,
337
- kind: "blocked-effect"
338
- };
339
- }
340
-
341
- function stuckEffectOf(args) {
342
- const reported = failedDeclaredEffect(args);
343
- if (reported !== void 0) return {
344
- effect: reported,
345
- failed: !0
346
- };
347
- const claimed = args.preview.claimedEffects[0];
348
- return claimed === void 0 ? void 0 : {
349
- effect: claimed,
350
- failed: !1
351
- };
352
- }
353
-
354
- function failedDeclaredEffect(args) {
355
- const {definition: definition, preview: preview, stage: stage} = args;
356
- if (definition === void 0 || definition.version !== preview.pinnedVersion || stage === void 0) return;
357
- const stageNode = workflowEngine.findStageNode({
358
- definition: definition,
359
- stageName: stage.name
360
- }), 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))));
361
- return [ ...preview.failedEffects ].reverse().find(effect => declared.has(effect.name));
362
- }
363
-
364
- function overdueRunDetail(args) {
365
- const {definition: definition, now: now, preview: preview} = args, late = overdueTasks(preview, now);
366
- if (late.length === 0) return;
367
- const {titleOf: titleOf} = activityTitleResolver(preview, definition), only = late.length === 1 ? late[0] : void 0;
368
- return {
369
- count: late.length,
370
- due: earliestPastDueAcross(late, now),
371
- kind: "overdue",
372
- task: only === void 0 ? void 0 : titleOf(only.name)
373
- };
374
- }
375
-
376
- function activityTitleResolver(preview, definition) {
377
- const stage = workflowEngine.findOpenStageEntry(preview);
378
- return {
379
- stage: stage,
380
- titleOf: activityName => index.findActivity({
381
- activityName: activityName,
382
- definition: definition,
383
- stageName: stage?.name ?? ""
384
- }).title
385
- };
386
- }
387
-
388
- const NO_ASSIGNEES = {
389
- assignees: [],
390
- assignments: [],
391
- counts: {
392
- unrouted: 0,
393
- routed: 0,
394
- held: 0
395
- }
396
- };
397
-
398
- function openAssignees(instance) {
399
- const users = /* @__PURE__ */ new Map, roles = /* @__PURE__ */ new Map, assignments = workflowEngine.openActivityAssignments(instance), counts = {
400
- unrouted: 0,
401
- routed: 0,
402
- held: 0
403
- };
404
- for (const members of assignments) counts[workflowEngine.assignmentState(members)] += 1,
405
- recordAssignees(workflowEngine.activeAssignmentMembers(members), {
406
- users: users,
407
- roles: roles
408
- });
409
- return {
410
- assignees: [ ...users.values(), ...roles.values() ],
411
- assignments: assignments,
412
- counts: counts
413
- };
414
- }
415
-
416
- function recordAssignees(assignees, maps) {
417
- for (const assignee of assignees) (assignee.type === "user" ? maps.users : maps.roles).set(assignee.type === "user" ? assignee.id : assignee.role, assignee);
418
- }
419
-
420
25
  function clausePolarity(operator) {
421
26
  return operator === "isNot" || operator === "isNoneOf" ? "isNot" : "is";
422
27
  }
@@ -437,7 +42,7 @@ function applyRunFilters(rows, args) {
437
42
 
438
43
  function previewsMatchingRunFilters(args) {
439
44
  if (args.filters.clauses === void 0) return args.previews;
440
- const rows = runRowsOf({
45
+ const rows = index.runRowsOf({
441
46
  definitions: args.definitions,
442
47
  now: args.now,
443
48
  previews: args.previews
@@ -790,7 +395,7 @@ function deployedPhrase(definition) {
790
395
  const deployedAt = deployedAtOf(definition);
791
396
  if (deployedAt === void 0) return `v${definition.version}`;
792
397
  const ago = index.formatTimeAgo(deployedAt);
793
- return ago === "" ? index.formatShortDateTime(deployedAt) : `${index.formatShortDateTime(deployedAt)} (${ago})`;
398
+ return ago === "" ? workflowComponents._formatShortDateTime(deployedAt) : `${workflowComponents._formatShortDateTime(deployedAt)} (${ago})`;
794
399
  }
795
400
 
796
401
  const INSTANCES_READ_FAILED = "Couldn’t load workflow data. Try again later.", TOOL_PANEL_PADDING = 3, TOOL_HEADING_PADDING = 2, PANEL_STEP = 3;
@@ -808,207 +413,6 @@ function TabStatusRow({children: children}) {
808
413
  });
809
414
  }
810
415
 
811
- function useTableStyles() {
812
- const {color: color} = ui.useTheme_v2(), headTop = index.useSpaceToken(3), cellX = index.useSpaceToken(2);
813
- return react.useMemo(() => ({
814
- cell: {
815
- borderBottom: `1px solid ${color.border}`,
816
- boxSizing: "border-box",
817
- padding: `0 ${cellX}px`,
818
- verticalAlign: "middle",
819
- whiteSpace: "nowrap"
820
- },
821
- head: {
822
- background: color.bg,
823
- borderBottom: `1px solid ${color.border}`,
824
- boxSizing: "border-box",
825
- padding: `${headTop}px 0 6px`,
826
- position: "sticky",
827
- textAlign: "left",
828
- top: 0,
829
- zIndex: 1
830
- }
831
- }), [ cellX, color, headTop ]);
832
- }
833
-
834
- function scrollParentOf(el) {
835
- for (let node = el.parentElement; node !== null; node = node.parentElement) {
836
- const overflowY = getComputedStyle(node).overflowY;
837
- if (overflowY === "auto" || overflowY === "scroll") return node;
838
- }
839
- }
840
-
841
- function useRowWindow(args) {
842
- const {element: element, keyAt: keyAt, rowCount: rowCount} = args, [scroller, setScroller] = react.useState(null);
843
- react.useLayoutEffect(() => {
844
- setScroller(element === null ? null : scrollParentOf(element) ?? null);
845
- }, [ element ]);
846
- const [margin, setMargin] = react.useState(0);
847
- react.useLayoutEffect(() => {
848
- element === null || scroller === null || setMargin(element.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop);
849
- }, [ element, rowCount, scroller ]);
850
- const virtualizer = reactVirtual.useVirtualizer({
851
- count: rowCount,
852
- estimateSize: () => 44,
853
- getItemKey: keyAt,
854
- getScrollElement: () => scroller,
855
- overscan: 10,
856
- scrollMargin: margin
857
- }), items = virtualizer.getVirtualItems(), first = items[0], last = items[items.length - 1];
858
- return {
859
- items: items,
860
- measureRow: virtualizer.measureElement,
861
- padBottom: last === void 0 ? 0 : virtualizer.getTotalSize() - (last.end - margin),
862
- padTop: first === void 0 ? 0 : first.start - margin
863
- };
864
- }
865
-
866
- function SpacerRow({height: height}) {
867
- return height <= 0 ? null : /* @__PURE__ */ jsxRuntime.jsx("tr", {
868
- "aria-hidden": !0,
869
- style: {
870
- height: height
871
- },
872
- children: /* @__PURE__ */ jsxRuntime.jsx("td", {
873
- colSpan: 99,
874
- style: {
875
- border: 0,
876
- padding: 0
877
- }
878
- })
879
- });
880
- }
881
-
882
- const TABLE_TIME_WIDTH = 112, TABLE_WORKFLOW_WIDTH = {
883
- cap: 260,
884
- fraction: .18
885
- }, TABLE_STAGE_WIDTH = {
886
- cap: 260,
887
- fraction: .16
888
- };
889
-
890
- function SortableHeaderCells({children: children, columns: columns, onSort: onSort, sort: sort, styles: styles, tableWidth: tableWidth, widthOf: widthOf}) {
891
- /* @__PURE__ */
892
- return jsxRuntime.jsxs(jsxRuntime.Fragment, {
893
- children: [ columns.map(column => {
894
- const width = widthOf(column, tableWidth);
895
- /* @__PURE__ */
896
- return jsxRuntime.jsx("th", {
897
- style: {
898
- ...styles.head,
899
- ...width === void 0 ? {} : {
900
- width: width
901
- }
902
- },
903
- children: /* @__PURE__ */ jsxRuntime.jsx(SortHeaderButton, {
904
- active: sort.key === column.key,
905
- dir: sort.dir,
906
- label: column.label,
907
- onSort: () => onSort(column.key)
908
- })
909
- }, column.key);
910
- }), children ]
911
- });
912
- }
913
-
914
- function VirtualTable({keyAt: keyAt, renderHeader: renderHeader, renderRow: renderRow, rowCount: rowCount}) {
915
- const styles = useTableStyles(), [element, setElement] = react.useState(null), tableWidth = useTableWidth(element), window2 = useRowWindow({
916
- element: element,
917
- keyAt: keyAt,
918
- rowCount: rowCount
919
- });
920
- /* @__PURE__ */
921
- return jsxRuntime.jsx("div", {
922
- ref: setElement,
923
- style: {
924
- overflowX: "clip",
925
- ...tableWidth === void 0 ? {
926
- visibility: "hidden"
927
- } : {}
928
- },
929
- children: /* @__PURE__ */ jsxRuntime.jsxs("table", {
930
- style: {
931
- borderCollapse: "separate",
932
- borderSpacing: 0,
933
- tableLayout: "fixed",
934
- width: "100%"
935
- },
936
- children: [
937
- /* @__PURE__ */ jsxRuntime.jsx("thead", {
938
- children: /* @__PURE__ */ jsxRuntime.jsx("tr", {
939
- children: renderHeader({
940
- styles: styles,
941
- tableWidth: tableWidth
942
- })
943
- })
944
- }),
945
- /* @__PURE__ */ jsxRuntime.jsxs("tbody", {
946
- children: [
947
- /* @__PURE__ */ jsxRuntime.jsx(SpacerRow, {
948
- height: window2.padTop
949
- }), window2.items.map(item => renderRow({
950
- index: item.index,
951
- key: item.key,
952
- measureRow: window2.measureRow,
953
- tableWidth: tableWidth
954
- })),
955
- /* @__PURE__ */ jsxRuntime.jsx(SpacerRow, {
956
- height: window2.padBottom
957
- }) ]
958
- }) ]
959
- })
960
- });
961
- }
962
-
963
- function useTableWidth(element) {
964
- const observed = ui.useElementRect(element), [mounted, setMounted] = react.useState(void 0);
965
- return react.useLayoutEffect(() => {
966
- setMounted(element === null ? void 0 : element.getBoundingClientRect().width);
967
- }, [ element ]), observed?.width ?? mounted;
968
- }
969
-
970
- function SortHeaderButton({active: active, dir: dir, label: label, onSort: onSort}) {
971
- /* @__PURE__ */
972
- return jsxRuntime.jsx(ui.Button, {
973
- fontSize: 1,
974
- mode: "bleed",
975
- onClick: onSort,
976
- padding: 2,
977
- text: `${label}${active ? dir === "asc" ? " ↑" : " ↓" : ""}`
978
- });
979
- }
980
-
981
- function TableRowCard({children: children, dataIndex: dataIndex, onClick: onClick, onKeyDown: onKeyDown, rowRef: rowRef, selected: selected, selectedRef: selectedRef}) {
982
- const setRow = react.useCallback(element => {
983
- rowRef?.(element), selected === !0 && selectedRef?.(element);
984
- }, [ rowRef, selected, selectedRef ]);
985
- /* @__PURE__ */
986
- return jsxRuntime.jsx(ui.Card, {
987
- as: "tr",
988
- "data-as": "a",
989
- onClick: event => {
990
- event.currentTarget.focus(), onClick();
991
- },
992
- onKeyDown: selected === !0 ? onKeyDown : void 0,
993
- style: {
994
- cursor: "pointer",
995
- display: "table-row"
996
- },
997
- ...dataIndex === void 0 ? {} : {
998
- "data-index": dataIndex
999
- },
1000
- ...rowRef === void 0 && selectedRef === void 0 ? {} : {
1001
- ref: setRow
1002
- },
1003
- ...selected === void 0 ? {} : {
1004
- "aria-selected": selected,
1005
- pressed: selected,
1006
- tabIndex: selected ? 0 : -1
1007
- },
1008
- children: children
1009
- });
1010
- }
1011
-
1012
416
  const logged = /* @__PURE__ */ new WeakSet;
1013
417
 
1014
418
  function logReadFailure(what, error) {
@@ -1206,7 +610,7 @@ function UndeployedWorkflows({notices: notices}) {
1206
610
  });
1207
611
  }
1208
612
 
1209
- const COLUMNS$1 = [ {
613
+ const COLUMNS = [ {
1210
614
  key: "workflow",
1211
615
  label: "Workflow"
1212
616
  }, {
@@ -1225,14 +629,14 @@ const COLUMNS$1 = [ {
1225
629
 
1226
630
  function DefinitionsTable({countKnown: countKnown, now: now, onOpenWorkflow: onOpenWorkflow, rows: rows}) {
1227
631
  const head = {
1228
- ...useTableStyles().head,
632
+ ...index.useTableStyles().head,
1229
633
  padding: "14px 0 6px"
1230
634
  }, [sort, setSort] = react.useState(DEFAULT_DEFINITION_SORT), sorted = react.useMemo(() => sortDefinitionRows({
1231
635
  rows: rows,
1232
636
  sort: sort
1233
637
  }), [ rows, sort ]), [element, setElement] = react.useState(null);
1234
638
  return react.useEffect(() => {
1235
- element !== null && scrollParentOf(element)?.scrollTo({
639
+ element !== null && index.scrollParentOf(element)?.scrollTo({
1236
640
  top: 0
1237
641
  });
1238
642
  }, [ element, sort ]), /* @__PURE__ */ jsxRuntime.jsxs("table", {
@@ -1246,14 +650,14 @@ function DefinitionsTable({countKnown: countKnown, now: now, onOpenWorkflow: onO
1246
650
  children: [
1247
651
  /* @__PURE__ */ jsxRuntime.jsx("thead", {
1248
652
  children: /* @__PURE__ */ jsxRuntime.jsxs("tr", {
1249
- children: [ COLUMNS$1.map(column => /* @__PURE__ */ jsxRuntime.jsx("th", {
653
+ children: [ COLUMNS.map(column => /* @__PURE__ */ jsxRuntime.jsx("th", {
1250
654
  style: {
1251
655
  ...head,
1252
656
  ...column.width === void 0 ? {} : {
1253
657
  width: column.width
1254
658
  }
1255
659
  },
1256
- children: /* @__PURE__ */ jsxRuntime.jsx(SortHeaderButton, {
660
+ children: /* @__PURE__ */ jsxRuntime.jsx(index.SortHeaderButton, {
1257
661
  active: sort.key === column.key,
1258
662
  dir: sort.dir,
1259
663
  label: column.label,
@@ -1289,13 +693,13 @@ function DefinitionsTable({countKnown: countKnown, now: now, onOpenWorkflow: onO
1289
693
 
1290
694
  function DefinitionRow({countKnown: countKnown, now: now, onOpen: onOpen, row: row}) {
1291
695
  const cell = {
1292
- ...useTableStyles().cell,
696
+ ...index.useTableStyles().cell,
1293
697
  padding: "16px 8px",
1294
698
  verticalAlign: "top",
1295
699
  whiteSpace: "normal"
1296
700
  }, titleGap = index.useSpaceToken(5), alert = definitionAlert(row);
1297
701
  /* @__PURE__ */
1298
- return jsxRuntime.jsxs(TableRowCard, {
702
+ return jsxRuntime.jsxs(index.TableRowCard, {
1299
703
  onClick: onOpen,
1300
704
  children: [
1301
705
  /* @__PURE__ */ jsxRuntime.jsx("td", {
@@ -1304,7 +708,7 @@ function DefinitionRow({countKnown: countKnown, now: now, onOpen: onOpen, row: r
1304
708
  paddingRight: titleGap
1305
709
  },
1306
710
  children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
1307
- space: 3,
711
+ gap: 3,
1308
712
  children: [
1309
713
  /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
1310
714
  size: 1,
@@ -1319,7 +723,7 @@ function DefinitionRow({countKnown: countKnown, now: now, onOpen: onOpen, row: r
1319
723
  }),
1320
724
  /* @__PURE__ */ jsxRuntime.jsx("td", {
1321
725
  style: cell,
1322
- children: row.deployedAt === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.AgoStamp, {
726
+ children: row.deployedAt === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.AgoStamp, {
1323
727
  at: row.deployedAt,
1324
728
  now: now
1325
729
  })
@@ -1423,7 +827,7 @@ function useDocPreviewTitles(documents) {
1423
827
  }, evaluate = () => {
1424
828
  for (const {doc: doc, bareId: bareId} of localDocs) {
1425
829
  const probe = actualTypes.read(bareId);
1426
- if (probe === null) {
830
+ if (probe === null || probe === index.UNREADABLE_DOCUMENT) {
1427
831
  dropPreview(doc.id), resolved.add(doc.id);
1428
832
  continue;
1429
833
  }
@@ -1501,80 +905,12 @@ function outsiderIds(args) {
1501
905
  return [ ...new Set(candidates.filter(id => !memberIds.has(id))) ];
1502
906
  }
1503
907
 
1504
- function forMeRowId(instanceId, activityName) {
1505
- return `${instanceId}\t${activityName}`;
1506
- }
1507
-
1508
- function forMeTaskRowsOf(args) {
1509
- const {now: now, rows: rows, who: who} = args;
1510
- return rows.flatMap(row => row.tasks.flatMap(task => {
1511
- const assignment = index.assignmentHolding(task.assignees, who);
1512
- if (assignment === "other") return [];
1513
- const attentionDetail = taskAttentionDetail({
1514
- now: now,
1515
- row: row,
1516
- task: task
1517
- });
1518
- return [ {
1519
- id: forMeRowId(row.id, task.name),
1520
- instanceId: row.id,
1521
- activityName: task.name,
1522
- title: task.title,
1523
- document: row.document,
1524
- workflowTitle: row.workflowTitle,
1525
- releases: row.releases,
1526
- openedAt: task.openedAt,
1527
- due: task.due,
1528
- attention: attentionKindOf(attentionDetail),
1529
- attentionDetail: attentionDetail,
1530
- assignees: task.assignees,
1531
- assignment: assignment
1532
- } ];
1533
- }));
1534
- }
1535
-
1536
- function forMeSummaryOf(rows) {
1537
- const documents = new Set(rows.flatMap(row => row.document === void 0 ? [] : [ row.document.id ])), releases = new Set(rows.flatMap(row => row.releases));
1538
- return {
1539
- lead: rows.length === 0 ? "No tasks" : pluralize__default.default("task", rows.length, !0),
1540
- subjects: `on ${pluralize__default.default("document", documents.size, !0)}, and ${pluralize__default.default("release", releases.size, !0)}`
1541
- };
1542
- }
1543
-
1544
- function forMeSectionsOf(rows) {
1545
- return {
1546
- assignedToUser: rows.filter(row => row.assignment === "you"),
1547
- assignedToRoles: rows.filter(row => row.assignment === "role")
1548
- };
1549
- }
1550
-
1551
- function resolveForMeAddress(args) {
1552
- const {rows: rows, run: run, task: task} = args;
1553
- if (run === void 0) return;
1554
- if (task !== void 0) return rows.some(row => row.instanceId === run && row.activityName === task) ? {
1555
- run: run,
1556
- task: task
1557
- } : void 0;
1558
- const first = rows.find(row => row.instanceId === run);
1559
- return first === void 0 ? void 0 : {
1560
- run: first.instanceId,
1561
- task: first.activityName
1562
- };
908
+ function documentTitleKey(row, titles) {
909
+ return row.document === void 0 ? "" : titles.get(row.document.id) ?? "";
1563
910
  }
1564
911
 
1565
- function taskAttentionDetail(args) {
1566
- const {now: now, row: row, task: task} = args;
1567
- if (task.status === "failed") return {
1568
- kind: "blocked",
1569
- task: task.title
1570
- };
1571
- if (row.attention === "blocked") return row.attentionDetail;
1572
- if (task.due !== void 0 && index.isDueDatePast(task.due, now)) return {
1573
- count: 1,
1574
- due: task.due,
1575
- kind: "overdue",
1576
- task: task.title
1577
- };
912
+ function namedRowComparator(key, titles) {
913
+ return key === "document" ? (a, b) => documentTitleKey(a, titles).localeCompare(documentTitleKey(b, titles)) : (a, b) => a.workflowTitle.localeCompare(b.workflowTitle);
1578
914
  }
1579
915
 
1580
916
  function defaultForMeSort() {
@@ -1611,17 +947,11 @@ function forMeCompare(args) {
1611
947
  return (a, b) => dir * named(a, b);
1612
948
  }
1613
949
 
1614
- function documentTitleKey$1(row, titles) {
1615
- return row.document === void 0 ? "" : titles.get(row.document.id) ?? "";
1616
- }
1617
-
1618
950
  function namedCompare(key, titles) {
1619
951
  switch (key) {
1620
952
  case "document":
1621
- return (a, b) => documentTitleKey$1(a, titles).localeCompare(documentTitleKey$1(b, titles));
1622
-
1623
953
  case "workflow":
1624
- return (a, b) => a.workflowTitle.localeCompare(b.workflowTitle);
954
+ return namedRowComparator(key, titles);
1625
955
 
1626
956
  default:
1627
957
  return (a, b) => a.title.localeCompare(b.title);
@@ -1869,7 +1199,7 @@ function PanelResizeHandle({enabled: enabled, onClose: onClose, onCommit: onComm
1869
1199
  top: 0
1870
1200
  }
1871
1201
  }),
1872
- /* @__PURE__ */ jsxRuntime.jsx(index.HoverHint, {
1202
+ /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
1873
1203
  anchor: anchor,
1874
1204
  disabled: !enabled || dragging,
1875
1205
  open: pointed,
@@ -2351,7 +1681,7 @@ function ResolvedTaskBody({activityName: activityName, entry: entry}) {
2351
1681
  }) : /* @__PURE__ */ jsxRuntime.jsx(index.ActivityDetailBody, {
2352
1682
  activityName: activityName,
2353
1683
  definition: definition,
2354
- document: documentRefsOf(entry.instance)[0],
1684
+ document: index.documentRefsOf(entry.instance)[0],
2355
1685
  entry: entry,
2356
1686
  layout: "panel",
2357
1687
  source: "tool-for-me",
@@ -2379,567 +1709,96 @@ function ForMeDetailPanel({activityName: activityName, instanceId: instanceId, o
2379
1709
  });
2380
1710
  }
2381
1711
 
2382
- const LATE_FACE = {
2383
- Icon: Calendar.CalendarIcon,
2384
- tone: "caution"
2385
- };
2386
-
2387
- function LateSpan({now: now, since: since}) {
2388
- /* @__PURE__ */
2389
- return jsxRuntime.jsx(index.MetricLockup, {
2390
- Icon: LATE_FACE.Icon,
2391
- tone: LATE_FACE.tone,
2392
- value: index.shortSpanOf(index.parseStoredDateValue(since), now)
2393
- });
2394
- }
2395
-
2396
- function DueStamp({due: due, now: now}) {
2397
- /* @__PURE__ */
2398
- return jsxRuntime.jsx(ui.Flex, {
2399
- align: "center",
2400
- children: /* @__PURE__ */ jsxRuntime.jsx(index.HoverHint, {
2401
- text: index.dueMomentSentence(due, now),
2402
- children: index.isDueDatePast(due, now) ? /* @__PURE__ */ jsxRuntime.jsx(LateSpan, {
2403
- now: now,
2404
- since: due
2405
- }) :
2406
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2407
- muted: !0,
2408
- size: 1,
2409
- style: {
2410
- whiteSpace: "nowrap"
2411
- },
2412
- children: index.formatDate(due)
2413
- })
2414
- })
2415
- });
2416
- }
2417
-
2418
- function resolveColumnWidth(width, tableWidth) {
2419
- return typeof width != "object" ? width : tableWidth === void 0 ? `${width.fraction * 100}%` : Math.min(width.cap, Math.round(tableWidth * width.fraction));
2420
- }
2421
-
2422
- function fillColumnWidth(args) {
2423
- const {columns: columns, tableWidth: tableWidth, trailingWidth: trailingWidth} = args;
2424
- if (tableWidth === void 0) return;
2425
- const fixed = columns.reduce((sum, column) => {
2426
- const width = resolveColumnWidth(column.width, tableWidth);
2427
- return typeof width == "number" ? sum + width : sum;
2428
- }, trailingWidth);
2429
- return Math.max(160, Math.floor(tableWidth - fixed));
2430
- }
2431
-
2432
- const HOLDER_OVERLAP = 7, HOLDER_RING = 1.5, GROUP_GAP_TOKEN = 3;
2433
-
2434
- function useDisplayById(ids) {
2435
- const displays = index.useUserDisplays(index.uniqueIds(ids)), labels = index.disambiguatedNames(displays);
2436
- return new Map(displays.map((display, index2) => [ display.id, {
2437
- ...display,
2438
- label: labels[index2] ?? display.name
2439
- } ]));
2440
- }
2441
-
2442
- function holderKey(assignee, index2) {
2443
- return `${assignee.id}-${index2}`;
2444
- }
2445
-
2446
- function stageTasksFace(args) {
2447
- return {
2448
- content: /* @__PURE__ */ jsxRuntime.jsx(StageTasksCard, {
2449
- now: args.now,
2450
- tasks: args.tasks
2451
- }),
2452
- flush: !0,
2453
- wide: !0
2454
- };
2455
- }
2456
-
2457
- function StageTaskGroups({now: now, room: room, tasks: tasks}) {
2458
- const gap = index.useSpaceToken(GROUP_GAP_TOKEN), face = index.useAvatarSize(), {overflow: overflow, visible: visible} = visibleStageTasks({
2459
- metrics: {
2460
- counter: face,
2461
- face: face,
2462
- gap: gap,
2463
- overlap: HOLDER_OVERLAP
2464
- },
2465
- room: room ?? face * 3 + gap * 2,
2466
- tasks: tasks
2467
- });
2468
- return tasks.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.HoverHint, {
2469
- ...stageTasksFace({
2470
- now: now,
2471
- tasks: tasks
2472
- }),
2473
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
2474
- align: "center",
2475
- "aria-label": "Tasks",
2476
- style: {
2477
- columnGap: gap
2478
- },
2479
- children: [ visible.map(task => /* @__PURE__ */ jsxRuntime.jsx(TaskGroupFace, {
2480
- assignees: task.assignees
2481
- }, task.name)), overflow === 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, {
2482
- muted: !0,
2483
- size: 1,
2484
- children: [ "+", overflow ]
2485
- }) ]
2486
- })
2487
- });
2488
- }
2489
-
2490
- function TaskGroupFace({assignees: assignees}) {
2491
- const mark = taskAssignmentMarkOf(assignees);
2492
- return mark.kind === "unassigned" ? /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {}) : mark.kind === "routed" ? /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {
2493
- routed: !0
2494
- }) : /* @__PURE__ */ jsxRuntime.jsx(OverlappedHolders, {
2495
- assignees: mark.members
2496
- });
2497
- }
2498
-
2499
- function HolderFace({assignee: assignee, displayById: displayById}) {
2500
- const display = displayById.get(assignee.id);
2501
- /* @__PURE__ */
2502
- return jsxRuntime.jsx(workflowComponents.MemberAvatar, {
2503
- imageUrl: display?.imageUrl,
2504
- name: display?.name ?? assignee.id,
2505
- size: 0
2506
- });
2507
- }
2508
-
2509
- function OverlappedHolders({assignees: assignees}) {
2510
- const {color: color} = ui.useTheme_v2(), displayById = useDisplayById(index.userIdsOf(assignees)), ring = `0 0 0 ${HOLDER_RING}px ${color.bg}`;
2511
- /* @__PURE__ */
2512
- return jsxRuntime.jsx(ui.Flex, {
2513
- align: "center",
2514
- style: {
2515
- flexShrink: 0,
2516
- isolation: "isolate"
2517
- },
2518
- children: assignees.map((assignee, index2) => /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
2519
- style: {
2520
- borderRadius: "50%",
2521
- boxShadow: ring,
2522
- flexShrink: 0,
2523
- marginLeft: index2 === 0 ? 0 : -HOLDER_OVERLAP,
2524
- position: "relative",
2525
- zIndex: index2
2526
- },
2527
- children: /* @__PURE__ */ jsxRuntime.jsx(HolderFace, {
2528
- assignee: assignee,
2529
- displayById: displayById
2530
- })
2531
- }, holderKey(assignee, index2)))
2532
- });
2533
- }
2534
-
2535
- function PersonToken({routed: routed = !1}) {
2536
- const size = index.useAvatarSize(), {color: color} = ui.useTheme_v2();
2537
- /* @__PURE__ */
2538
- return jsxRuntime.jsxs(ui.Box, {
2539
- "aria-label": routed ? "Routed, no person assigned" : "Unassigned",
2540
- role: "img",
2541
- style: {
2542
- flexShrink: 0,
2543
- height: size,
2544
- position: "relative",
2545
- width: size
2546
- },
1712
+ function ForMeTables({loading: loading, now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, onSort: onSort, selectedId: selectedId, selectedRef: selectedRef, sort: sort, sections: sections}) {
1713
+ return loading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
2547
1714
  children: [
2548
- /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
2549
- align: "center",
2550
- justify: "center",
2551
- style: {
2552
- border: `1px dashed ${color.border}`,
2553
- borderRadius: "50%",
2554
- boxSizing: "border-box",
2555
- height: size,
2556
- width: size
2557
- },
2558
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2559
- size: 0,
2560
- children: /* @__PURE__ */ jsxRuntime.jsx(User.UserIcon, {
2561
- style: {
2562
- color: color.input.default.enabled.placeholder
2563
- }
2564
- })
2565
- })
2566
- }), routed ? /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
2567
- radius: 1,
2568
- tone: "primary",
2569
- style: {
2570
- bottom: -3,
2571
- position: "absolute",
2572
- right: -3
2573
- },
2574
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
2575
- align: "center",
2576
- justify: "center",
2577
- style: {
2578
- height: 13,
2579
- width: 13
2580
- },
2581
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2582
- size: 0,
2583
- children: /* @__PURE__ */ jsxRuntime.jsx(Users.UsersIcon, {})
2584
- })
1715
+ /* @__PURE__ */ jsxRuntime.jsx(index.LoadingRow, {
1716
+ label: "Loading…",
1717
+ padding: 2
1718
+ }), selectedId === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(LoadingTablePlaceholder, {
1719
+ children: /* @__PURE__ */ jsxRuntime.jsx(index.ForMeTable, {
1720
+ now: now,
1721
+ onNavigateKey: onNavigateKey,
1722
+ onSelect: onSelect,
1723
+ onSort: onSort,
1724
+ rows: [],
1725
+ selectedId: void 0,
1726
+ selectedRef: selectedRef,
1727
+ sort: sort
2585
1728
  })
2586
- }) : null ]
2587
- });
2588
- }
2589
-
2590
- function StageTasksCard({now: now, tasks: tasks}) {
2591
- const displayById = useDisplayById(tasks.flatMap(task => index.userIdsOf(task.assignees)));
2592
- /* @__PURE__ */
2593
- return jsxRuntime.jsxs(ui.Stack, {
2594
- gap: 4,
2595
- padding: 3,
1729
+ }) ]
1730
+ }) : sections.assignedToUser.length === 0 && sections.assignedToRoles.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(index.ForMeEmptyState, {}) : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
1731
+ gap: 6,
2596
1732
  children: [
2597
- /* @__PURE__ */ jsxRuntime.jsx(index.OverlineHeading, {
2598
- children: "Tasks in this stage"
1733
+ /* @__PURE__ */ jsxRuntime.jsx(ForMeSection, {
1734
+ description: /* @__PURE__ */ jsxRuntime.jsx(ForMeSectionCount, {
1735
+ rows: sections.assignedToUser
1736
+ }),
1737
+ now: now,
1738
+ onNavigateKey: onNavigateKey,
1739
+ onSelect: onSelect,
1740
+ onSort: onSort,
1741
+ rows: sections.assignedToUser,
1742
+ selectedId: selectedId,
1743
+ selectedRef: selectedRef,
1744
+ sort: sort,
1745
+ title: index.FOR_ME_SECTION_COPY.assignedTitle
2599
1746
  }),
2600
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
2601
- gap: 4,
2602
- children: tasks.map(task => /* @__PURE__ */ jsxRuntime.jsx(TaskCardRow, {
2603
- displayById: displayById,
2604
- now: now,
2605
- task: task
2606
- }, task.name))
1747
+ /* @__PURE__ */ jsxRuntime.jsx(ForMeSection, {
1748
+ description: index.FOR_ME_SECTION_COPY.roleDescription,
1749
+ now: now,
1750
+ onNavigateKey: onNavigateKey,
1751
+ onSelect: onSelect,
1752
+ onSort: onSort,
1753
+ rows: sections.assignedToRoles,
1754
+ selectedId: selectedId,
1755
+ selectedRef: selectedRef,
1756
+ sort: sort,
1757
+ title: index.FOR_ME_SECTION_COPY.roleTitle
2607
1758
  }) ]
2608
1759
  });
2609
1760
  }
2610
1761
 
2611
- function TaskCardRow({displayById: displayById, now: now, task: task}) {
2612
- const mark = taskAssignmentMarkOf(task.assignees);
2613
- /* @__PURE__ */
2614
- return jsxRuntime.jsxs(ui.Stack, {
1762
+ function ForMeSection({description: description, now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, onSort: onSort, rows: rows, selectedId: selectedId, selectedRef: selectedRef, sort: sort, title: title}) {
1763
+ return rows.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
2615
1764
  gap: 3,
2616
1765
  children: [
2617
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
2618
- gap: 2,
2619
- children: [
2620
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
2621
- align: "center",
2622
- gap: 3,
2623
- children: [
2624
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2625
- size: 1,
2626
- children: task.title
2627
- }), task.overdueSince === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(LateSpan, {
2628
- now: now,
2629
- since: task.overdueSince
2630
- }) ]
2631
- }), task.due === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2632
- muted: !0,
2633
- size: 1,
2634
- children: index.dueMomentSentence(task.due, now)
2635
- }) ]
1766
+ /* @__PURE__ */ jsxRuntime.jsx(index.ForMeSectionHeading, {
1767
+ description: description,
1768
+ title: title
2636
1769
  }),
2637
- /* @__PURE__ */ jsxRuntime.jsx(AssignmentLine, {
2638
- displayById: displayById,
2639
- mark: mark,
1770
+ /* @__PURE__ */ jsxRuntime.jsx(index.ForMeTable, {
2640
1771
  now: now,
2641
- openedAt: task.openedAt,
2642
- roleAliases: task.roleAliases
2643
- }) ]
2644
- });
2645
- }
2646
-
2647
- function AssignmentLine({displayById: displayById, mark: mark, now: now, openedAt: openedAt, roleAliases: roleAliases}) {
2648
- return mark.kind === "unassigned" ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
2649
- align: "center",
2650
- gap: 2,
2651
- children: [
2652
- /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {}),
2653
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2654
- muted: !0,
2655
- size: 1,
2656
- children: "Unassigned"
1772
+ onNavigateKey: onNavigateKey,
1773
+ onSelect: onSelect,
1774
+ onSort: onSort,
1775
+ rows: rows,
1776
+ selectedId: selectedId,
1777
+ selectedRef: selectedRef,
1778
+ sort: sort
2657
1779
  }) ]
2658
- }) : mark.kind === "routed" ? /* @__PURE__ */ jsxRuntime.jsx(RoutedAssignmentLine, {
2659
- mark: mark,
2660
- now: now,
2661
- openedAt: openedAt,
2662
- roleAliases: roleAliases
2663
- }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
2664
- gap: 2,
2665
- children: mark.members.map((assignee, index2) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
2666
- align: "center",
2667
- gap: 2,
2668
- children: [
2669
- /* @__PURE__ */ jsxRuntime.jsx(HolderFace, {
2670
- assignee: assignee,
2671
- displayById: displayById
2672
- }),
2673
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2674
- size: 1,
2675
- children: displayById.get(assignee.id)?.label ?? assignee.id
2676
- }) ]
2677
- }, holderKey(assignee, index2)))
2678
1780
  });
2679
1781
  }
2680
1782
 
2681
- function RoutedAssignmentLine({mark: mark, now: now, openedAt: openedAt, roleAliases: roleAliases}) {
2682
- const vocabulary = index.useProjectMembers(), count = workflowComponents.roleMemberCount({
2683
- members: vocabulary.members,
2684
- requiredRoles: mark.roles,
2685
- roleAliases: roleAliases
2686
- }), names = mark.roles.map(role => workflowComponents.roleLabel(workflowComponents.memberRoleFor(vocabulary, role)));
1783
+ function ForMeSectionCount({rows: rows}) {
1784
+ const summary = index.forMeSummaryOf(rows);
2687
1785
  /* @__PURE__ */
2688
1786
  return jsxRuntime.jsxs(ui.Flex, {
2689
1787
  align: "center",
2690
- gap: 2,
2691
- children: [
2692
- /* @__PURE__ */ jsxRuntime.jsx(PersonToken, {
2693
- routed: !0
2694
- }),
2695
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
2696
- gap: 1,
2697
- children: [
2698
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2699
- size: 1,
2700
- children: names.join(", ")
2701
- }),
2702
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, {
2703
- muted: !0,
2704
- size: 1,
2705
- children: [ workflowComponents.memberCountLabel(count), " · Open ", index.formatShortAgo(openedAt, now) ]
2706
- }) ]
2707
- }) ]
2708
- });
2709
- }
2710
-
2711
- function overdueAttentionHint(documents) {
2712
- const task = documents === 1 ? "an overdue task" : "overdue tasks";
2713
- return `${pluralize__default.default("document", documents, !0)} ${documents === 1 ? "has" : "have"} ${task}`;
2714
- }
2715
-
2716
- function blockedAttentionHint(documents) {
2717
- return `${pluralize__default.default("document", documents, !0)} ${documents === 1 ? "is" : "are"} blocked`;
2718
- }
2719
-
2720
- function overdueMark(detail, now) {
2721
- const span = overdueSpan(detail.due, now), tasks = pluralize__default.default("task", detail.count, !0);
2722
- return detail.count === 1 && detail.task !== void 0 ? {
2723
- hint: `“${detail.task}” — ${span === void 0 ? "overdue" : `${span} overdue`}`,
2724
- value: span ?? tasks
2725
- } : {
2726
- hint: span === void 0 ? `${tasks} overdue` : `${tasks} overdue — the longest by ${span}`,
2727
- value: tasks
2728
- };
2729
- }
2730
-
2731
- function overdueSpan(due, now) {
2732
- const from = index.parseStoredDateValue(due);
2733
- if (from !== void 0) return index.shortSpanOf(from, now);
2734
- }
2735
-
2736
- function overdueMarkOpensPanel(tasks) {
2737
- return tasks.some(task => task.overdueSince !== void 0);
2738
- }
2739
-
2740
- function blockedMarkHint(detail) {
2741
- return detail.kind === "blocked-many" ? `${pluralize__default.default("task", detail.count, !0)} were sent back` : detail.kind === "blocked-effect" ? `Automation “${detail.effect}” ${detail.failed ? "failed" : "didn’t finish"}` : detail.task === void 0 ? "A task was sent back" : `“${detail.task}” was sent back`;
2742
- }
2743
-
2744
- const ATTENTION_FACES = {
2745
- blocked: {
2746
- Icon: ErrorOutline.ErrorOutlineIcon,
2747
- tone: "critical"
2748
- },
2749
- overdue: LATE_FACE
2750
- };
2751
-
2752
- function AttentionMark({detail: detail, now: now, tasks: tasks}) {
2753
- if (detail.kind === "overdue") {
2754
- const {hint: hint2, value: value} = overdueMark(detail, now);
2755
- /* @__PURE__ */
2756
- return jsxRuntime.jsx(index.MetricPair, {
2757
- Icon: ATTENTION_FACES.overdue.Icon,
2758
- face: overdueMarkOpensPanel(tasks) ? stageTasksFace({
2759
- now: now,
2760
- tasks: tasks
2761
- }) : {
2762
- text: hint2
2763
- },
2764
- label: hint2,
2765
- tone: ATTENTION_FACES.overdue.tone,
2766
- value: value
2767
- });
2768
- }
2769
- const hint = blockedMarkHint(detail);
2770
- /* @__PURE__ */
2771
- return jsxRuntime.jsx(index.AlertChip, {
2772
- Icon: ATTENTION_FACES.blocked.Icon,
2773
- hint: hint,
2774
- label: hint,
2775
- tone: ATTENTION_FACES.blocked.tone
2776
- });
2777
- }
2778
-
2779
- const TASK_WIDTH = {
2780
- cap: 280,
2781
- fraction: .22
2782
- }, ATTENTION_WIDTH$1 = 48, ASSIGNEE_WIDTH = 96, COLUMNS = [ {
2783
- key: "document",
2784
- label: "Workflow subject"
2785
- }, {
2786
- key: "task",
2787
- label: "Task",
2788
- width: TASK_WIDTH
2789
- }, {
2790
- key: "opened",
2791
- label: "Opened",
2792
- width: TABLE_TIME_WIDTH
2793
- }, {
2794
- key: "workflow",
2795
- label: "Workflow",
2796
- width: TABLE_WORKFLOW_WIDTH
2797
- }, {
2798
- key: "due",
2799
- label: "Due",
2800
- width: TABLE_TIME_WIDTH
2801
- } ];
2802
-
2803
- function documentWidthOf$1(tableWidth) {
2804
- return fillColumnWidth({
2805
- columns: COLUMNS,
2806
- tableWidth: tableWidth,
2807
- trailingWidth: ASSIGNEE_WIDTH + ATTENTION_WIDTH$1
2808
- });
2809
- }
2810
-
2811
- function ForMeTable({now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, onSort: onSort, rows: rows, selectedId: selectedId, selectedRef: selectedRef, sort: sort}) {
2812
- /* @__PURE__ */
2813
- return jsxRuntime.jsx(VirtualTable, {
2814
- renderHeader: args => /* @__PURE__ */ jsxRuntime.jsxs(SortableHeaderCells, {
2815
- columns: COLUMNS,
2816
- onSort: onSort,
2817
- sort: sort,
2818
- styles: args.styles,
2819
- tableWidth: args.tableWidth,
2820
- widthOf: (column, tableWidth) => column.key === "document" ? documentWidthOf$1(tableWidth) : resolveColumnWidth(column.width, tableWidth),
2821
- children: [
2822
- /* @__PURE__ */ jsxRuntime.jsx("th", {
2823
- style: {
2824
- ...args.styles.head,
2825
- width: ASSIGNEE_WIDTH
2826
- },
2827
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
2828
- padding: 2,
2829
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2830
- muted: !0,
2831
- size: 1,
2832
- children: "Assignee"
2833
- })
2834
- })
2835
- }),
2836
- /* @__PURE__ */ jsxRuntime.jsx("th", {
2837
- "aria-label": "Attention",
2838
- style: {
2839
- ...args.styles.head,
2840
- width: ATTENTION_WIDTH$1
2841
- }
2842
- }) ]
2843
- }),
2844
- keyAt: index2 => rows[index2]?.id ?? String(index2),
2845
- renderRow: ({index: index2, key: key, measureRow: measureRow}) => {
2846
- const row = rows[index2];
2847
- return row === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ForMeTableRow, {
2848
- dataIndex: index2,
2849
- measureRow: measureRow,
2850
- now: now,
2851
- onNavigateKey: onNavigateKey,
2852
- onSelect: onSelect,
2853
- row: row,
2854
- selected: row.id === selectedId,
2855
- selectedRef: selectedRef
2856
- }, key);
2857
- },
2858
- rowCount: rows.length
2859
- });
2860
- }
2861
-
2862
- const ForMeTableRow = react.memo(function({dataIndex: dataIndex, measureRow: measureRow, now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, row: row, selected: selected, selectedRef: selectedRef}) {
2863
- const styles = useTableStyles(), documentInset = index.useSpaceToken(1);
2864
- /* @__PURE__ */
2865
- return jsxRuntime.jsxs(TableRowCard, {
2866
- dataIndex: dataIndex,
2867
- onClick: () => onSelect(row),
2868
- onKeyDown: onNavigateKey,
2869
- rowRef: measureRow,
2870
- selected: selected,
2871
- selectedRef: selectedRef,
1788
+ gap: 1,
2872
1789
  children: [
2873
- /* @__PURE__ */ jsxRuntime.jsx("td", {
2874
- style: {
2875
- ...styles.cell,
2876
- paddingLeft: documentInset
2877
- },
2878
- children: row.document === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2879
- muted: !0,
2880
- size: 1,
2881
- textOverflow: "ellipsis",
2882
- children: "No document"
2883
- }) : /* @__PURE__ */ jsxRuntime.jsx(index.DocRefFace, {
2884
- gdr: row.document
2885
- })
2886
- }),
2887
- /* @__PURE__ */ jsxRuntime.jsx("td", {
2888
- style: styles.cell,
2889
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2890
- size: 1,
2891
- textOverflow: "ellipsis",
2892
- children: row.title
2893
- })
2894
- }),
2895
- /* @__PURE__ */ jsxRuntime.jsx("td", {
2896
- style: styles.cell,
2897
- children: /* @__PURE__ */ jsxRuntime.jsx(index.AgoStamp, {
2898
- at: row.openedAt,
2899
- now: now
2900
- })
2901
- }),
2902
- /* @__PURE__ */ jsxRuntime.jsx("td", {
2903
- style: styles.cell,
2904
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
2905
- muted: !0,
2906
- size: 1,
2907
- textOverflow: "ellipsis",
2908
- children: row.workflowTitle
2909
- })
2910
- }),
2911
- /* @__PURE__ */ jsxRuntime.jsx("td", {
2912
- style: styles.cell,
2913
- children: row.due === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(DueStamp, {
2914
- due: row.due,
2915
- now: now
2916
- })
2917
- }),
2918
- /* @__PURE__ */ jsxRuntime.jsx("td", {
2919
- style: {
2920
- ...styles.cell,
2921
- overflow: "hidden"
2922
- },
2923
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
2924
- align: "center",
2925
- children: /* @__PURE__ */ jsxRuntime.jsx(index.RowAssignees, {
2926
- assignees: row.assignees
2927
- })
2928
- })
1790
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
1791
+ size: 1,
1792
+ weight: "semibold",
1793
+ children: summary.lead
2929
1794
  }),
2930
- /* @__PURE__ */ jsxRuntime.jsx("td", {
2931
- style: styles.cell,
2932
- children: row.attentionDetail === void 0 || row.attentionDetail.kind === "overdue" ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
2933
- align: "center",
2934
- children: /* @__PURE__ */ jsxRuntime.jsx(AttentionMark, {
2935
- detail: row.attentionDetail,
2936
- now: now,
2937
- tasks: []
2938
- })
2939
- })
1795
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
1796
+ muted: !0,
1797
+ size: 1,
1798
+ children: summary.subjects
2940
1799
  }) ]
2941
1800
  });
2942
- });
1801
+ }
2943
1802
 
2944
1803
  function AbortWorkflowSection({entry: entry}) {
2945
1804
  const [aborting, setAborting] = react.useState(!1);
@@ -3104,7 +1963,7 @@ function InstanceDetailBody({entry: entry}) {
3104
1963
  }
3105
1964
 
3106
1965
  function SubjectPreview({instance: instance}) {
3107
- const document2 = documentRefsOf(instance)[0];
1966
+ const document2 = index.documentRefsOf(instance)[0];
3108
1967
  return document2 === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
3109
1968
  gap: 4,
3110
1969
  children: [
@@ -3130,7 +1989,7 @@ function useViewportBoundHeight() {
3130
1989
  const [el, setEl] = react.useState(null);
3131
1990
  return react.useLayoutEffect(() => {
3132
1991
  if (el === null) return;
3133
- const scroller = scrollParentOf(el);
1992
+ const scroller = index.scrollParentOf(el);
3134
1993
  if (scroller === void 0) return;
3135
1994
  const apply = () => {
3136
1995
  const offset = el.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop, room = Math.floor(scroller.clientHeight - offset) - PANEL_BOTTOM_MARGIN;
@@ -3217,7 +2076,7 @@ function ForMeWorkArea({previews: previews, loading: loading, model: model, now:
3217
2076
  loading: loading,
3218
2077
  previews: previews,
3219
2078
  resetKey: `${sort.dir}:${sort.key}`,
3220
- children: /* @__PURE__ */ jsxRuntime.jsx(ForMeBody, {
2079
+ children: /* @__PURE__ */ jsxRuntime.jsx(ForMeTables, {
3221
2080
  loading: loading,
3222
2081
  now: now,
3223
2082
  onNavigateKey: keyboardNavigation.onKeyDown,
@@ -3242,97 +2101,6 @@ function ForMeWorkArea({previews: previews, loading: loading, model: model, now:
3242
2101
  });
3243
2102
  }
3244
2103
 
3245
- function ForMeBody({loading: loading, now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, onSort: onSort, selectedId: selectedId, selectedRef: selectedRef, sort: sort, sections: sections}) {
3246
- return loading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
3247
- children: [
3248
- /* @__PURE__ */ jsxRuntime.jsx(index.LoadingRow, {
3249
- label: "Loading…",
3250
- padding: 2
3251
- }), selectedId === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(LoadingTablePlaceholder, {
3252
- children: /* @__PURE__ */ jsxRuntime.jsx(ForMeTable, {
3253
- now: now,
3254
- onNavigateKey: onNavigateKey,
3255
- onSelect: onSelect,
3256
- onSort: onSort,
3257
- rows: [],
3258
- selectedId: void 0,
3259
- selectedRef: selectedRef,
3260
- sort: sort
3261
- })
3262
- }) ]
3263
- }) : sections.assignedToUser.length === 0 && sections.assignedToRoles.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(index.ForMeEmptyState, {}) : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
3264
- gap: 6,
3265
- children: [
3266
- /* @__PURE__ */ jsxRuntime.jsx(ForMeSection, {
3267
- description: /* @__PURE__ */ jsxRuntime.jsx(ForMeSectionCount, {
3268
- rows: sections.assignedToUser
3269
- }),
3270
- now: now,
3271
- onNavigateKey: onNavigateKey,
3272
- onSelect: onSelect,
3273
- onSort: onSort,
3274
- rows: sections.assignedToUser,
3275
- selectedId: selectedId,
3276
- selectedRef: selectedRef,
3277
- sort: sort,
3278
- title: index.FOR_ME_SECTION_COPY.assignedTitle
3279
- }),
3280
- /* @__PURE__ */ jsxRuntime.jsx(ForMeSection, {
3281
- description: index.FOR_ME_SECTION_COPY.roleDescription,
3282
- now: now,
3283
- onNavigateKey: onNavigateKey,
3284
- onSelect: onSelect,
3285
- onSort: onSort,
3286
- rows: sections.assignedToRoles,
3287
- selectedId: selectedId,
3288
- selectedRef: selectedRef,
3289
- sort: sort,
3290
- title: index.FOR_ME_SECTION_COPY.roleTitle
3291
- }) ]
3292
- });
3293
- }
3294
-
3295
- function ForMeSection({description: description, now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, onSort: onSort, rows: rows, selectedId: selectedId, selectedRef: selectedRef, sort: sort, title: title}) {
3296
- return rows.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
3297
- gap: 3,
3298
- children: [
3299
- /* @__PURE__ */ jsxRuntime.jsx(index.ForMeSectionHeading, {
3300
- description: description,
3301
- title: title
3302
- }),
3303
- /* @__PURE__ */ jsxRuntime.jsx(ForMeTable, {
3304
- now: now,
3305
- onNavigateKey: onNavigateKey,
3306
- onSelect: onSelect,
3307
- onSort: onSort,
3308
- rows: rows,
3309
- selectedId: selectedId,
3310
- selectedRef: selectedRef,
3311
- sort: sort
3312
- }) ]
3313
- });
3314
- }
3315
-
3316
- function ForMeSectionCount({rows: rows}) {
3317
- const summary = forMeSummaryOf(rows);
3318
- /* @__PURE__ */
3319
- return jsxRuntime.jsxs(ui.Flex, {
3320
- align: "center",
3321
- gap: 1,
3322
- children: [
3323
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
3324
- size: 1,
3325
- weight: "semibold",
3326
- children: summary.lead
3327
- }),
3328
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
3329
- muted: !0,
3330
- size: 1,
3331
- children: summary.subjects
3332
- }) ]
3333
- });
3334
- }
3335
-
3336
2104
  function defaultRunSort(scope) {
3337
2105
  return scope === "closed" ? {
3338
2106
  key: "ended",
@@ -3358,17 +2126,11 @@ function sortRunRows(args) {
3358
2126
  return [ ...rows ].sort((a, b) => dir * primary(a, b) || tiebreak(a, b));
3359
2127
  }
3360
2128
 
3361
- function documentTitleKey(row, titles) {
3362
- return row.document === void 0 ? "" : titles.get(row.document.id) ?? "";
3363
- }
3364
-
3365
2129
  function comparatorFor(key, titles) {
3366
2130
  switch (key) {
3367
2131
  case "document":
3368
- return (a, b) => documentTitleKey(a, titles).localeCompare(documentTitleKey(b, titles));
3369
-
3370
2132
  case "workflow":
3371
- return (a, b) => a.workflowTitle.localeCompare(b.workflowTitle);
2133
+ return namedRowComparator(key, titles);
3372
2134
 
3373
2135
  case "stage":
3374
2136
  return (a, b) => a.stageTitle.localeCompare(b.stageTitle);
@@ -3392,17 +2154,17 @@ function cardFacts(args) {
3392
2154
  return new Map(args.previews.map(preview => {
3393
2155
  const settled = workflowEngine.terminalState(preview) !== "in-flight";
3394
2156
  return [ preview._id, {
3395
- tasks: settled ? [] : stageTasksOf({
2157
+ tasks: settled ? [] : index.stageTasksOf({
3396
2158
  definition: args.definition,
3397
2159
  instance: preview,
3398
2160
  now: args.now
3399
2161
  }),
3400
- overdueDetail: overdueRunDetail({
2162
+ overdueDetail: index.overdueRunDetail({
3401
2163
  definition: args.definition,
3402
2164
  now: args.now,
3403
2165
  preview: preview
3404
2166
  }),
3405
- blocked: blockedRunDetail({
2167
+ blocked: settled ? void 0 : index.blockedRunDetail({
3406
2168
  definition: args.definition,
3407
2169
  preview: preview
3408
2170
  }),
@@ -3699,7 +2461,7 @@ function BoardNavigator({items: items, onActivate: onActivate, navigatorWindow:
3699
2461
  const BOARD_EMPTY_STAGE_NOTE = "No items";
3700
2462
 
3701
2463
  function faceOf(preview, definition) {
3702
- const document2 = documentRefsOf(preview)[0];
2464
+ const document2 = index.documentRefsOf(preview)[0];
3703
2465
  return document2 ? {
3704
2466
  kind: "document",
3705
2467
  document: document2
@@ -3761,9 +2523,9 @@ function boardDocuments(board) {
3761
2523
  const CARD_RADIUS = 3;
3762
2524
 
3763
2525
  function BoardCard({card: card, wiring: wiring}) {
3764
- const {facts: facts, now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, selectedInstanceId: selectedInstanceId, selectedRef: selectedRef} = wiring, {color: color} = ui.useTheme_v2(), faceInset = index.useSpaceToken(2), selected = card.instanceId === selectedInstanceId, held = facts.get(card.instanceId);
2526
+ const {facts: facts, now: now, onNavigateKey: onNavigateKey, onSelect: onSelect, selectedInstanceId: selectedInstanceId, selectedRef: selectedRef} = wiring, {color: color} = ui.useTheme_v2(), faceInset = index.useSpaceToken(2), markClearance = index.useAlertChipSize() + index.useSpaceToken(3), selected = card.instanceId === selectedInstanceId, held = facts.get(card.instanceId), blocked = held?.blocked;
3765
2527
  /* @__PURE__ */
3766
- return jsxRuntime.jsx(ui.Card, {
2528
+ return jsxRuntime.jsxs(ui.Card, {
3767
2529
  "aria-pressed": selected,
3768
2530
  as: "button",
3769
2531
  onClick: event => {
@@ -3777,18 +2539,32 @@ function BoardCard({card: card, wiring: wiring}) {
3777
2539
  border: `1px solid ${color.border}`,
3778
2540
  display: "flex",
3779
2541
  flexDirection: "column",
2542
+ position: "relative",
3780
2543
  textAlign: "left",
3781
2544
  width: "100%"
3782
2545
  },
3783
2546
  ...selected ? {
3784
2547
  ref: selectedRef
3785
2548
  } : {},
3786
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
2549
+ children: [ held === void 0 || blocked === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
2550
+ style: {
2551
+ position: "absolute",
2552
+ right: faceInset,
2553
+ top: faceInset
2554
+ },
2555
+ children: /* @__PURE__ */ jsxRuntime.jsx(index.AttentionMark, {
2556
+ detail: blocked,
2557
+ now: now,
2558
+ tasks: held.tasks
2559
+ })
2560
+ }),
2561
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
3787
2562
  gap: 2,
3788
2563
  children: [
3789
2564
  /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
3790
2565
  style: {
3791
2566
  minWidth: 0,
2567
+ paddingRight: blocked === void 0 ? void 0 : markClearance,
3792
2568
  ...card.face.kind === "document" ? {
3793
2569
  margin: `${-faceInset}px 0 ${-faceInset}px ${-faceInset}px`
3794
2570
  } : {}
@@ -3806,23 +2582,22 @@ function BoardCard({card: card, wiring: wiring}) {
3806
2582
  facts: held,
3807
2583
  now: now
3808
2584
  }) ]
3809
- })
2585
+ }) ]
3810
2586
  });
3811
2587
  }
3812
2588
 
3813
2589
  function CardMetrics({facts: facts, now: now}) {
3814
- const markOverhang = -index.useCapTrimFor(index.useTextIconSize()), bare = facts.tasks.length === 0 && facts.overdueDetail === void 0 && facts.blocked === void 0;
3815
- return facts.settled || bare ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
2590
+ const markOverhang = -index.useCapTrimFor(index.useTextIconSize());
2591
+ return facts.settled || facts.tasks.length === 0 && facts.overdueDetail === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
3816
2592
  padding: 1,
3817
2593
  children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
3818
2594
  align: "center",
3819
2595
  gap: 3,
3820
2596
  children: [
3821
- /* @__PURE__ */ jsxRuntime.jsx(StageTaskGroups, {
2597
+ /* @__PURE__ */ jsxRuntime.jsx(index.StageTaskGroups, {
3822
2598
  now: now,
3823
2599
  tasks: facts.tasks
3824
- }),
3825
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
2600
+ }), facts.overdueDetail === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
3826
2601
  align: "center",
3827
2602
  flex: 1,
3828
2603
  gap: 3,
@@ -3830,15 +2605,11 @@ function CardMetrics({facts: facts, now: now}) {
3830
2605
  style: {
3831
2606
  paddingRight: markOverhang
3832
2607
  },
3833
- children: [ facts.overdueDetail === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(AttentionMark, {
2608
+ children: /* @__PURE__ */ jsxRuntime.jsx(index.AttentionMark, {
3834
2609
  detail: facts.overdueDetail,
3835
2610
  now: now,
3836
2611
  tasks: facts.tasks
3837
- }), facts.blocked === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(AttentionMark, {
3838
- detail: facts.blocked,
3839
- now: now,
3840
- tasks: facts.tasks
3841
- }) ]
2612
+ })
3842
2613
  }) ]
3843
2614
  })
3844
2615
  });
@@ -3876,18 +2647,18 @@ function StageGroupHeading({facts: facts, group: group}) {
3876
2647
  flex: "none",
3877
2648
  gap: 3,
3878
2649
  children: [ totals.overdue === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.MetricPair, {
3879
- Icon: ATTENTION_FACES.overdue.Icon,
2650
+ Icon: index.ATTENTION_FACES.overdue.Icon,
3880
2651
  face: {
3881
- text: overdueAttentionHint(totals.overdue)
2652
+ text: index.overdueAttentionHint(totals.overdue)
3882
2653
  },
3883
- tone: ATTENTION_FACES.overdue.tone,
2654
+ tone: index.ATTENTION_FACES.overdue.tone,
3884
2655
  value: String(totals.overdue)
3885
2656
  }), totals.stuck === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.MetricPair, {
3886
- Icon: ATTENTION_FACES.blocked.Icon,
2657
+ Icon: index.ATTENTION_FACES.blocked.Icon,
3887
2658
  face: {
3888
- text: blockedAttentionHint(totals.stuck)
2659
+ text: index.blockedAttentionHint(totals.stuck)
3889
2660
  },
3890
- tone: ATTENTION_FACES.blocked.tone,
2661
+ tone: index.ATTENTION_FACES.blocked.tone,
3891
2662
  value: String(totals.stuck)
3892
2663
  }) ]
3893
2664
  }) ]
@@ -4561,7 +3332,7 @@ function Segment({active: active, joined: joined, mode: mode, onPick: onPick, op
4561
3332
  tone: tone
4562
3333
  }
4563
3334
  });
4564
- return option.tooltip === void 0 ? button : /* @__PURE__ */ jsxRuntime.jsx(index.HoverHint, {
3335
+ return option.tooltip === void 0 ? button : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents._HoverHint, {
4565
3336
  text: option.tooltip,
4566
3337
  children: button
4567
3338
  });
@@ -4829,7 +3600,7 @@ function RunsFilterMenu({definition: definition, onView: onView, scoped: scoped,
4829
3600
  value: value
4830
3601
  })), applied = facet => appliedFacetValues(view.filters, facet), myId = index.useCurrentUserId();
4831
3602
  /* @__PURE__ */
4832
- return jsxRuntime.jsx(ui.MenuButton, {
3603
+ return jsxRuntime.jsx(menu.MenuButton, {
4833
3604
  button: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
4834
3605
  fontSize: 1,
4835
3606
  gap: 2,
@@ -4839,9 +3610,9 @@ function RunsFilterMenu({definition: definition, onView: onView, scoped: scoped,
4839
3610
  text: "Add filter"
4840
3611
  }),
4841
3612
  id: "runs-filter-menu",
4842
- menu: /* @__PURE__ */ jsxRuntime.jsxs(ui.Menu, {
3613
+ menu: /* @__PURE__ */ jsxRuntime.jsxs(menu.Menu, {
4843
3614
  children: [
4844
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuGroup, {
3615
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuGroup, {
4845
3616
  fontSize: 1,
4846
3617
  popover: SUBMENU_POPOVER,
4847
3618
  text: "Assignee",
@@ -4856,14 +3627,14 @@ function RunsFilterMenu({definition: definition, onView: onView, scoped: scoped,
4856
3627
  myId: myId,
4857
3628
  pick: value => add("assignee", value),
4858
3629
  toggle: value => add("assignee", value),
4859
- unassignedCount: unassignedRunCount(scoped)
3630
+ unassignedCount: index.unassignedRunCount(scoped)
4860
3631
  })
4861
3632
  })
4862
- }), definition === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.MenuGroup, {
3633
+ }), definition === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(menu.MenuGroup, {
4863
3634
  fontSize: 1,
4864
3635
  popover: SUBMENU_POPOVER,
4865
3636
  text: "Stage",
4866
- children: options.stage.map(option => /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
3637
+ children: options.stage.map(option => /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
4867
3638
  fontSize: 1,
4868
3639
  onClick: () => add("stage", option.key),
4869
3640
  children: /* @__PURE__ */ jsxRuntime.jsx(CountedMenuRow, {
@@ -4874,11 +3645,11 @@ function RunsFilterMenu({definition: definition, onView: onView, scoped: scoped,
4874
3645
  })
4875
3646
  }, option.key))
4876
3647
  }),
4877
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuGroup, {
3648
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuGroup, {
4878
3649
  fontSize: 1,
4879
3650
  popover: SUBMENU_POPOVER,
4880
3651
  text: "Needs attention",
4881
- children: options.attention.map(option => /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
3652
+ children: options.attention.map(option => /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
4882
3653
  fontSize: 1,
4883
3654
  onClick: () => add("attention", option.key),
4884
3655
  children: /* @__PURE__ */ jsxRuntime.jsx(CountedMenuRow, {
@@ -4889,8 +3660,8 @@ function RunsFilterMenu({definition: definition, onView: onView, scoped: scoped,
4889
3660
  })
4890
3661
  }, option.key))
4891
3662
  }),
4892
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuDivider, {}),
4893
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuGroup, {
3663
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuDivider, {}),
3664
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuGroup, {
4894
3665
  fontSize: 1,
4895
3666
  popover: SUBMENU_POPOVER,
4896
3667
  text: "Release",
@@ -4900,7 +3671,7 @@ function RunsFilterMenu({definition: definition, onView: onView, scoped: scoped,
4900
3671
  sections: [ withActiveValues(options.release, applied("release")) ],
4901
3672
  specials: [ {
4902
3673
  active: applied("release").includes(NO_RELEASE_VALUE),
4903
- count: noReleaseRunCount(scoped),
3674
+ count: index.noReleaseRunCount(scoped),
4904
3675
  label: "No release",
4905
3676
  onPick: () => add("release", NO_RELEASE_VALUE),
4906
3677
  onToggle: () => add("release", NO_RELEASE_VALUE)
@@ -4917,7 +3688,7 @@ function RunsFilterMenu({definition: definition, onView: onView, scoped: scoped,
4917
3688
  }
4918
3689
 
4919
3690
  function useAssigneeDirectory({filters: filters, scoped: scoped}) {
4920
- const {members: members, roles: roles} = index.useProjectMembers(), userCounts = react.useMemo(() => runCountsByAssignee(scoped), [ scoped ]), roleCounts = react.useMemo(() => runCountsByRole(scoped), [ scoped ]), allRoles = react.useMemo(() => directoryRoles({
3691
+ const {members: members, roles: roles} = index.useProjectMembers(), userCounts = react.useMemo(() => index.runCountsByAssignee(scoped), [ scoped ]), roleCounts = react.useMemo(() => index.runCountsByRole(scoped), [ scoped ]), allRoles = react.useMemo(() => directoryRoles({
4921
3692
  held: roleCounts,
4922
3693
  members: members,
4923
3694
  roles: roles
@@ -4948,19 +3719,19 @@ function useValueOptions({definition: definition, filters: filters, scoped: scop
4948
3719
  filters: filters,
4949
3720
  scoped: scoped
4950
3721
  }), attention = react.useMemo(() => {
4951
- const counts = runAttentionCounts(scoped);
3722
+ const counts = index.runAttentionCounts(scoped);
4952
3723
  return ATTENTION_VALUES.map(value => ({
4953
3724
  count: value.key === "blocked" ? counts.blocked : counts.overdue,
4954
3725
  key: value.key,
4955
3726
  label: value.label
4956
3727
  }));
4957
- }, [ scoped ]), releaseTitles = index.useReleaseTitles(), release = react.useMemo(() => [ ...runCountsByRelease(scoped) ].map(([name, count]) => ({
3728
+ }, [ scoped ]), releaseTitles = index.useReleaseTitles(), release = react.useMemo(() => [ ...index.runCountsByRelease(scoped) ].map(([name, count]) => ({
4958
3729
  count: count,
4959
3730
  key: name,
4960
3731
  label: releaseTitles.get(name) ?? name
4961
3732
  })).sort(byResolvedTitle(option => option.label, option => option.key)), [ releaseTitles, scoped ]), stage = react.useMemo(() => {
4962
3733
  if (definition === void 0) return [];
4963
- const counts = runCountsByStage(scoped);
3734
+ const counts = index.runCountsByStage(scoped);
4964
3735
  return definition.stages.map(held => ({
4965
3736
  count: counts.get(held.name) ?? 0,
4966
3737
  key: held.name,
@@ -5000,7 +3771,7 @@ function QueryableValues({mediaOf: mediaOf, onPick: onPick, onToggle: onToggle,
5000
3771
  children: [ shownSpecials.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
5001
3772
  children: [ shownSpecials.map(row => /* @__PURE__ */ jsxRuntime.jsx(SpecialValueItem, {
5002
3773
  special: row
5003
- }, row.label)), trimmed === "" && hitSections.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.MenuDivider, {}) : null ]
3774
+ }, row.label)), trimmed === "" && hitSections.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(menu.MenuDivider, {}) : null ]
5004
3775
  }), hitSections.length === 0 && shownSpecials.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
5005
3776
  padding: 3,
5006
3777
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
@@ -5010,7 +3781,7 @@ function QueryableValues({mediaOf: mediaOf, onPick: onPick, onToggle: onToggle,
5010
3781
  })
5011
3782
  }) : null, grouped.map((rows, index2) =>
5012
3783
  /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, {
5013
- children: [ index2 > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.MenuDivider, {}) : null, rows.map(row => /* @__PURE__ */ jsxRuntime.jsx(ValueItem, {
3784
+ children: [ index2 > 0 ? /* @__PURE__ */ jsxRuntime.jsx(menu.MenuDivider, {}) : null, rows.map(row => /* @__PURE__ */ jsxRuntime.jsx(ValueItem, {
5014
3785
  media: mediaOf?.(row),
5015
3786
  onPick: () => onPick(row),
5016
3787
  onToggle: onToggle === void 0 ? void 0 : () => onToggle(row),
@@ -5033,7 +3804,7 @@ function mannerProps(args) {
5033
3804
 
5034
3805
  function SpecialValueItem({special: special}) {
5035
3806
  /* @__PURE__ */
5036
- return jsxRuntime.jsx(ui.MenuItem, {
3807
+ return jsxRuntime.jsx(menu.MenuItem, {
5037
3808
  fontSize: 1,
5038
3809
  onClick: special.onPick,
5039
3810
  children: /* @__PURE__ */ jsxRuntime.jsx(CountedMenuRow, {
@@ -5052,7 +3823,7 @@ function SpecialValueItem({special: special}) {
5052
3823
 
5053
3824
  function ValueItem({media: media, onPick: onPick, onToggle: onToggle, row: row}) {
5054
3825
  /* @__PURE__ */
5055
- return jsxRuntime.jsx(ui.MenuItem, {
3826
+ return jsxRuntime.jsx(menu.MenuItem, {
5056
3827
  fontSize: 1,
5057
3828
  onClick: onPick,
5058
3829
  children: /* @__PURE__ */ jsxRuntime.jsx(CountedMenuRow, {
@@ -5127,7 +3898,7 @@ function RunsFilterChips({definition: definition, onView: onView, scoped: scoped
5127
3898
 
5128
3899
  function OperatorButton({facet: facet, index: index2, label: label, onPick: onPick, picked: picked}) {
5129
3900
  /* @__PURE__ */
5130
- return jsxRuntime.jsx(ui.MenuButton, {
3901
+ return jsxRuntime.jsx(menu.MenuButton, {
5131
3902
  button: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
5132
3903
  fontSize: 1,
5133
3904
  mode: "bleed",
@@ -5136,8 +3907,8 @@ function OperatorButton({facet: facet, index: index2, label: label, onPick: onPi
5136
3907
  text: label
5137
3908
  }),
5138
3909
  id: `runs-chip-operator-${index2}`,
5139
- menu: /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, {
5140
- children: polarityOptionsOf(facet).map(option => /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
3910
+ menu: /* @__PURE__ */ jsxRuntime.jsx(menu.Menu, {
3911
+ children: polarityOptionsOf(facet).map(option => /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
5141
3912
  fontSize: 1,
5142
3913
  onClick: () => onPick(option.key),
5143
3914
  pressed: picked === option.key,
@@ -5198,7 +3969,7 @@ function ValuesButton({apply: apply, chip: chip, displayById: displayById, optio
5198
3969
  myId: myId,
5199
3970
  pick: value => pick(value, close),
5200
3971
  toggle: toggle,
5201
- unassignedCount: unassignedRunCount(scoped)
3972
+ unassignedCount: index.unassignedRunCount(scoped)
5202
3973
  })
5203
3974
  })
5204
3975
  });
@@ -5212,7 +3983,7 @@ function ValuesButton({apply: apply, chip: chip, displayById: displayById, optio
5212
3983
  sections: [ withActiveValues(options.release, chip.clause.values) ],
5213
3984
  specials: [ {
5214
3985
  active: chip.clause.values.includes(NO_RELEASE_VALUE),
5215
- count: noReleaseRunCount(scoped),
3986
+ count: index.noReleaseRunCount(scoped),
5216
3987
  label: "No release",
5217
3988
  onPick: () => pick(NO_RELEASE_VALUE, close),
5218
3989
  onToggle: () => toggle(NO_RELEASE_VALUE)
@@ -5223,7 +3994,7 @@ function ValuesButton({apply: apply, chip: chip, displayById: displayById, optio
5223
3994
  /* @__PURE__ */
5224
3995
  return jsxRuntime.jsx(ValuePopoverButton, {
5225
3996
  label: label,
5226
- children: close => listed.map(option => /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
3997
+ children: close => listed.map(option => /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
5227
3998
  fontSize: 1,
5228
3999
  onClick: () => pick(option.key, close),
5229
4000
  children: /* @__PURE__ */ jsxRuntime.jsx(CountedMenuRow, {
@@ -5239,8 +4010,8 @@ function ValuesButton({apply: apply, chip: chip, displayById: displayById, optio
5239
4010
  function ValuePopoverButton({children: children, faces: faces, label: label}) {
5240
4011
  const [open, setOpen] = react.useState(!1), buttonRef = react.useRef(null), close = () => setOpen(!1);
5241
4012
  /* @__PURE__ */
5242
- return jsxRuntime.jsx(ui.Popover, {
5243
- content: /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, {
4013
+ return jsxRuntime.jsx(popover.Popover, {
4014
+ content: /* @__PURE__ */ jsxRuntime.jsx(menu.Menu, {
5244
4015
  onClickOutside: event => {
5245
4016
  event.target instanceof Node && buttonRef.current?.contains(event.target) || close();
5246
4017
  },
@@ -5505,7 +4276,7 @@ function ScopeSelect({onView: onView, view: view}) {
5505
4276
  filters: view.filters
5506
4277
  });
5507
4278
  /* @__PURE__ */
5508
- return jsxRuntime.jsx(ui.MenuButton, {
4279
+ return jsxRuntime.jsx(menu.MenuButton, {
5509
4280
  button: /* @__PURE__ */ jsxRuntime.jsx(SurfaceButton, {
5510
4281
  $surface: color.bg,
5511
4282
  fontSize: 1,
@@ -5515,15 +4286,15 @@ function ScopeSelect({onView: onView, view: view}) {
5515
4286
  text: view.scope === "closed" ? "Closed runs" : "Open runs"
5516
4287
  }),
5517
4288
  id: "runs-scope-filter",
5518
- menu: /* @__PURE__ */ jsxRuntime.jsxs(ui.Menu, {
4289
+ menu: /* @__PURE__ */ jsxRuntime.jsxs(menu.Menu, {
5519
4290
  children: [
5520
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
4291
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
5521
4292
  fontSize: 1,
5522
4293
  onClick: () => pick("open"),
5523
4294
  pressed: view.scope === "open",
5524
4295
  text: "Open runs"
5525
4296
  }),
5526
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
4297
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
5527
4298
  fontSize: 1,
5528
4299
  onClick: () => pick("closed"),
5529
4300
  pressed: view.scope === "closed",
@@ -5542,7 +4313,7 @@ function ScopeSelect({onView: onView, view: view}) {
5542
4313
  function WorkflowSelect({counts: counts, definitions: definitions, onView: onView, totalCount: totalCount, view: view}) {
5543
4314
  const options = [ ...definitions ].sort(byTitleThenName), selected = options.find(definition => definition.name === view.filters.workflow), pick = name => onView(workflowScopedView(view, name));
5544
4315
  /* @__PURE__ */
5545
- return jsxRuntime.jsx(ui.MenuButton, {
4316
+ return jsxRuntime.jsx(menu.MenuButton, {
5546
4317
  button:
5547
4318
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
5548
4319
  disabled: options.length === 0,
@@ -5566,7 +4337,7 @@ function WorkflowSelect({counts: counts, definitions: definitions, onView: onVie
5566
4337
  })
5567
4338
  }),
5568
4339
  id: "runs-workflow-filter",
5569
- menu: /* @__PURE__ */ jsxRuntime.jsxs(ui.Menu, {
4340
+ menu: /* @__PURE__ */ jsxRuntime.jsxs(menu.Menu, {
5570
4341
  children: [
5571
4342
  /* @__PURE__ */ jsxRuntime.jsx(QueryableValues, {
5572
4343
  onPick: row => pick(row.key),
@@ -5584,7 +4355,7 @@ function WorkflowSelect({counts: counts, definitions: definitions, onView: onVie
5584
4355
  } ]
5585
4356
  }), options.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
5586
4357
  children: [
5587
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuDivider, {}),
4358
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuDivider, {}),
5588
4359
  /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
5589
4360
  padding: 2,
5590
4361
  children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
@@ -5713,16 +4484,16 @@ function useScopeForRun(args) {
5713
4484
  return react.useMemo(() => {
5714
4485
  if (forMe || !ready || view.run === void 0) return view;
5715
4486
  const held = rows.find(row => row.id === view.run);
5716
- return held === void 0 || runsScopeOf(held) === view.scope ? view : {
4487
+ return held === void 0 || index.runsScopeOf(held) === view.scope ? view : {
5717
4488
  ...view,
5718
- scope: runsScopeOf(held)
4489
+ scope: index.runsScopeOf(held)
5719
4490
  };
5720
4491
  }, [ forMe, ready, rows, view ]);
5721
4492
  }
5722
4493
 
5723
4494
  function useCutRows(args) {
5724
4495
  const {currentUserId: currentUserId, currentUserRoles: currentUserRoles, forMe: forMe, identity: identity, scoped: scoped, view: view} = args;
5725
- return react.useMemo(() => forMe ? identity === void 0 ? [] : scoped.filter(row => rowHasTaskHeldBy(row, identity)) : applyRunFilters(scoped, {
4496
+ return react.useMemo(() => forMe ? identity === void 0 ? [] : scoped.filter(row => index.rowHasTaskHeldBy(row, identity)) : applyRunFilters(scoped, {
5726
4497
  currentUserId: currentUserId,
5727
4498
  currentUserRoles: currentUserRoles,
5728
4499
  filters: view.filters
@@ -5769,273 +4540,7 @@ function useRunPanelModel(args) {
5769
4540
  }
5770
4541
 
5771
4542
  function walkIdOf(view) {
5772
- if (view.run !== void 0) return view.task === void 0 ? view.run : forMeRowId(view.run, view.task);
5773
- }
5774
-
5775
- const OPEN_COLUMNS = [ {
5776
- key: "document",
5777
- label: "Workflow subject"
5778
- }, {
5779
- key: "workflow",
5780
- label: "Workflow",
5781
- width: TABLE_WORKFLOW_WIDTH
5782
- }, {
5783
- key: "stage",
5784
- label: "Stage",
5785
- width: TABLE_STAGE_WIDTH
5786
- }, {
5787
- key: "started",
5788
- label: "Started",
5789
- width: TABLE_TIME_WIDTH
5790
- } ], CLOSED_COLUMNS = [ {
5791
- key: "document",
5792
- label: "Workflow subject"
5793
- }, {
5794
- key: "workflow",
5795
- label: "Workflow",
5796
- width: TABLE_WORKFLOW_WIDTH
5797
- }, {
5798
- key: "outcome",
5799
- label: "Outcome",
5800
- width: TABLE_STAGE_WIDTH
5801
- }, {
5802
- key: "started",
5803
- label: "Started",
5804
- width: TABLE_TIME_WIDTH
5805
- }, {
5806
- key: "ended",
5807
- label: "Closed",
5808
- width: TABLE_TIME_WIDTH
5809
- } ], TASKS_WIDTH = 120, TASKS_WIDTH_ROOMY = 168, ROOMY_TABLE_WIDTH = 1040;
5810
-
5811
- function tasksWidthOf(tableWidth) {
5812
- return tableWidth === void 0 ? TASKS_WIDTH : tableWidth >= ROOMY_TABLE_WIDTH ? TASKS_WIDTH_ROOMY : TASKS_WIDTH;
5813
- }
5814
-
5815
- function taskRoomOf(args) {
5816
- return tasksWidthOf(args.tableWidth) - args.inset * 2;
5817
- }
5818
-
5819
- const ATTENTION_WIDTH = 96;
5820
-
5821
- function documentWidthOf(args) {
5822
- const {columns: columns, scope: scope, tableWidth: tableWidth} = args, trailing = scope === "open" ? tasksWidthOf(tableWidth) + ATTENTION_WIDTH : 0;
5823
- return fillColumnWidth({
5824
- columns: columns,
5825
- tableWidth: tableWidth,
5826
- trailingWidth: trailing
5827
- });
5828
- }
5829
-
5830
- function RunsTable({now: now, onNavigateKey: onNavigateKey, onSelectRun: onSelectRun, onSort: onSort, rows: rows, scope: scope, scopedToWorkflow: scopedToWorkflow, selectedId: selectedId, selectedRef: selectedRef, sort: sort}) {
5831
- const columns = (scope === "closed" ? CLOSED_COLUMNS : OPEN_COLUMNS).filter(column => !(scopedToWorkflow && column.key === "workflow")), cellInset = index.useSpaceToken(2);
5832
- /* @__PURE__ */
5833
- return jsxRuntime.jsx(VirtualTable, {
5834
- renderHeader: args => /* @__PURE__ */ jsxRuntime.jsx(RunsHeader, {
5835
- columns: columns,
5836
- onSort: onSort,
5837
- scope: scope,
5838
- sort: sort,
5839
- styles: args.styles,
5840
- tableWidth: args.tableWidth
5841
- }),
5842
- keyAt: index2 => rows[index2]?.id ?? String(index2),
5843
- renderRow: ({index: index2, key: key, measureRow: measureRow, tableWidth: tableWidth}) => {
5844
- const row = rows[index2];
5845
- return row === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(RunTableRow, {
5846
- dataIndex: index2,
5847
- measureRow: measureRow,
5848
- now: now,
5849
- onNavigateKey: onNavigateKey,
5850
- onSelectRun: onSelectRun,
5851
- row: row,
5852
- scope: scope,
5853
- scopedToWorkflow: scopedToWorkflow,
5854
- selected: row.id === selectedId,
5855
- selectedRef: selectedRef,
5856
- taskRoom: taskRoomOf({
5857
- inset: cellInset,
5858
- tableWidth: tableWidth
5859
- })
5860
- }, key);
5861
- },
5862
- rowCount: rows.length
5863
- });
5864
- }
5865
-
5866
- function RunsHeader({columns: columns, onSort: onSort, scope: scope, sort: sort, styles: styles, tableWidth: tableWidth}) {
5867
- /* @__PURE__ */
5868
- return jsxRuntime.jsx(SortableHeaderCells, {
5869
- columns: columns,
5870
- onSort: onSort,
5871
- sort: sort,
5872
- styles: styles,
5873
- tableWidth: tableWidth,
5874
- widthOf: (column, width) => column.key === "document" ? documentWidthOf({
5875
- columns: columns,
5876
- scope: scope,
5877
- tableWidth: width
5878
- }) : resolveColumnWidth(column.width, width),
5879
- children: scope === "open" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
5880
- children: [
5881
- /* @__PURE__ */ jsxRuntime.jsx("th", {
5882
- style: {
5883
- ...styles.head,
5884
- width: tasksWidthOf(tableWidth)
5885
- },
5886
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
5887
- padding: 2,
5888
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
5889
- muted: !0,
5890
- size: 1,
5891
- children: "Tasks"
5892
- })
5893
- })
5894
- }),
5895
- /* @__PURE__ */ jsxRuntime.jsx("th", {
5896
- "aria-label": "Attention",
5897
- style: {
5898
- ...styles.head,
5899
- width: ATTENTION_WIDTH
5900
- }
5901
- }) ]
5902
- }) : null
5903
- });
5904
- }
5905
-
5906
- const RunTableRow = react.memo(function({dataIndex: dataIndex, measureRow: measureRow, now: now, onNavigateKey: onNavigateKey, onSelectRun: onSelectRun, row: row, scope: scope, scopedToWorkflow: scopedToWorkflow, selected: selected, selectedRef: selectedRef, taskRoom: taskRoom}) {
5907
- const styles = useTableStyles(), documentInset = index.useSpaceToken(1);
5908
- /* @__PURE__ */
5909
- return jsxRuntime.jsxs(TableRowCard, {
5910
- dataIndex: dataIndex,
5911
- onClick: () => onSelectRun(row),
5912
- onKeyDown: onNavigateKey,
5913
- rowRef: measureRow,
5914
- selected: selected,
5915
- selectedRef: selectedRef,
5916
- children: [
5917
- /* @__PURE__ */ jsxRuntime.jsx("td", {
5918
- style: {
5919
- ...styles.cell,
5920
- paddingLeft: documentInset
5921
- },
5922
- children: /* @__PURE__ */ jsxRuntime.jsx(DocumentCell, {
5923
- row: row
5924
- })
5925
- }), scopedToWorkflow ? null : /* @__PURE__ */ jsxRuntime.jsx("td", {
5926
- style: styles.cell,
5927
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
5928
- muted: !0,
5929
- size: 1,
5930
- textOverflow: "ellipsis",
5931
- children: row.workflowTitle
5932
- })
5933
- }), scope === "closed" ? /* @__PURE__ */ jsxRuntime.jsx(ClosedCells, {
5934
- now: now,
5935
- row: row
5936
- }) : /* @__PURE__ */ jsxRuntime.jsx(OpenCells, {
5937
- now: now,
5938
- row: row,
5939
- taskRoom: taskRoom
5940
- }) ]
5941
- });
5942
- });
5943
-
5944
- function DocumentCell({row: row}) {
5945
- return row.document === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
5946
- muted: !0,
5947
- size: 1,
5948
- textOverflow: "ellipsis",
5949
- children: "No document"
5950
- }) : /* @__PURE__ */ jsxRuntime.jsx(index.DocRefFace, {
5951
- gdr: row.document
5952
- });
5953
- }
5954
-
5955
- function OpenCells({now: now, row: row, taskRoom: taskRoom}) {
5956
- const styles = useTableStyles();
5957
- /* @__PURE__ */
5958
- return jsxRuntime.jsxs(jsxRuntime.Fragment, {
5959
- children: [
5960
- /* @__PURE__ */ jsxRuntime.jsx("td", {
5961
- style: styles.cell,
5962
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
5963
- size: 1,
5964
- textOverflow: "ellipsis",
5965
- children: row.stageTitle
5966
- })
5967
- }),
5968
- /* @__PURE__ */ jsxRuntime.jsx("td", {
5969
- style: styles.cell,
5970
- children: /* @__PURE__ */ jsxRuntime.jsx(index.AgoStamp, {
5971
- at: row.startedAt,
5972
- now: now
5973
- })
5974
- }),
5975
- /* @__PURE__ */ jsxRuntime.jsx("td", {
5976
- style: {
5977
- ...styles.cell,
5978
- overflow: "hidden"
5979
- },
5980
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
5981
- align: "center",
5982
- children: /* @__PURE__ */ jsxRuntime.jsx(StageTaskGroups, {
5983
- now: now,
5984
- room: taskRoom,
5985
- tasks: row.tasks
5986
- })
5987
- })
5988
- }),
5989
- /* @__PURE__ */ jsxRuntime.jsx("td", {
5990
- style: styles.cell,
5991
- children: /* @__PURE__ */ jsxRuntime.jsx(AttentionCell, {
5992
- now: now,
5993
- row: row
5994
- })
5995
- }) ]
5996
- });
5997
- }
5998
-
5999
- function ClosedCells({now: now, row: row}) {
6000
- const styles = useTableStyles();
6001
- /* @__PURE__ */
6002
- return jsxRuntime.jsxs(jsxRuntime.Fragment, {
6003
- children: [
6004
- /* @__PURE__ */ jsxRuntime.jsx("td", {
6005
- style: styles.cell,
6006
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
6007
- size: 1,
6008
- textOverflow: "ellipsis",
6009
- children: row.outcome
6010
- })
6011
- }),
6012
- /* @__PURE__ */ jsxRuntime.jsx("td", {
6013
- style: styles.cell,
6014
- children: /* @__PURE__ */ jsxRuntime.jsx(index.AgoStamp, {
6015
- at: row.startedAt,
6016
- now: now
6017
- })
6018
- }),
6019
- /* @__PURE__ */ jsxRuntime.jsx("td", {
6020
- style: styles.cell,
6021
- children: row.endedAt === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.AgoStamp, {
6022
- at: row.endedAt,
6023
- now: now
6024
- })
6025
- }) ]
6026
- });
6027
- }
6028
-
6029
- function AttentionCell({now: now, row: row}) {
6030
- return row.attentionDetail === void 0 ? null :
6031
- /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
6032
- align: "center",
6033
- children: /* @__PURE__ */ jsxRuntime.jsx(AttentionMark, {
6034
- detail: row.attentionDetail,
6035
- now: now,
6036
- tasks: row.tasks
6037
- })
6038
- });
4543
+ if (view.run !== void 0) return view.task === void 0 ? view.run : index.forMeRowId(view.run, view.task);
6039
4544
  }
6040
4545
 
6041
4546
  function RunsWorkArea({boardMode: boardMode, boardState: boardState, previews: previews, loading: loading, model: model, navigatorSlot: navigatorSlot, now: now, onSort: onSort, scopedCount: scopedCount, sort: sort, sorted: sorted, view: view}) {
@@ -6112,7 +4617,7 @@ function useWorkColumnStyle(args) {
6112
4617
 
6113
4618
  function RunsBody({loading: loading, now: now, onNavigateKey: onNavigateKey, onSelectRun: onSelectRun, onSort: onSort, scopedCount: scopedCount, selectedId: selectedId, selectedRef: selectedRef, sort: sort, sorted: sorted, view: view}) {
6114
4619
  return loading ? selectedId === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(LoadingTablePlaceholder, {
6115
- children: /* @__PURE__ */ jsxRuntime.jsx(RunsTable, {
4620
+ children: /* @__PURE__ */ jsxRuntime.jsx(index.RunsTable, {
6116
4621
  now: now,
6117
4622
  onNavigateKey: onNavigateKey,
6118
4623
  onSelectRun: onSelectRun,
@@ -6132,7 +4637,7 @@ function RunsBody({loading: loading, now: now, onNavigateKey: onNavigateKey, onS
6132
4637
  description: "Adjust the filters",
6133
4638
  icon: /* @__PURE__ */ jsxRuntime.jsx(Search.SearchIcon, {}),
6134
4639
  title: "No runs match"
6135
- }) : /* @__PURE__ */ jsxRuntime.jsx(RunsTable, {
4640
+ }) : /* @__PURE__ */ jsxRuntime.jsx(index.RunsTable, {
6136
4641
  now: now,
6137
4642
  onNavigateKey: onNavigateKey,
6138
4643
  onSelectRun: onSelectRun,
@@ -6203,7 +4708,7 @@ const RunsTab = react.memo(function({addressed: addressed, filterSlot: filterSlo
6203
4708
  next: next,
6204
4709
  picked: picked
6205
4710
  }) && setPicked(void 0), onNavigate(next);
6206
- }, now = index.useMinuteClock(), definitions = resources.definitions, definitionsByName = react.useMemo(() => new Map((definitions ?? []).map(definition => [ definition.name, definition ])), [ definitions ]), rows = react.useMemo(() => runRowsOf({
4711
+ }, now = index.useMinuteClock(), definitions = resources.definitions, definitionsByName = react.useMemo(() => new Map((definitions ?? []).map(definition => [ definition.name, definition ])), [ definitions ]), rows = react.useMemo(() => index.runRowsOf({
6207
4712
  previews: previews.previews,
6208
4713
  definitions: definitionsByName,
6209
4714
  now: now
@@ -6242,7 +4747,7 @@ const RunsTab = react.memo(function({addressed: addressed, filterSlot: filterSlo
6242
4747
  loading: previews.loading,
6243
4748
  now: now,
6244
4749
  previews: previews.previews
6245
- }), scoped = react.useMemo(() => rows.filter(row => runsScopeOf(row) === view.scope), [ rows, view.scope ]), workflowCounts = react.useMemo(() => runCountsByWorkflow(scoped), [ scoped ]), workflowScoped = react.useMemo(() => applyRunFilters(scoped, {
4750
+ }), scoped = react.useMemo(() => rows.filter(row => index.runsScopeOf(row) === view.scope), [ rows, view.scope ]), workflowCounts = react.useMemo(() => index.runCountsByWorkflow(scoped), [ scoped ]), workflowScoped = react.useMemo(() => applyRunFilters(scoped, {
6246
4751
  filters: withWorkflow(NO_RUN_FILTERS, view.filters.workflow)
6247
4752
  }), [ scoped, view.filters.workflow ]), currentUserId = currentUserIdentity?.userId, currentUserRoles = currentUserIdentity?.roles, filtered = useCutRows({
6248
4753
  currentUserId: currentUserId,
@@ -6251,15 +4756,14 @@ const RunsTab = react.memo(function({addressed: addressed, filterSlot: filterSlo
6251
4756
  identity: forMeIdentity,
6252
4757
  scoped: scoped,
6253
4758
  view: view
6254
- }), taskRows = react.useMemo(() => forMeIdentity === void 0 ? [] : forMeTaskRowsOf({
6255
- now: now,
4759
+ }), taskRows = react.useMemo(() => forMeIdentity === void 0 ? [] : index.forMeTaskRowsOf({
6256
4760
  rows: filtered,
6257
4761
  who: forMeIdentity
6258
- }), [ filtered, forMeIdentity, now ]), shownAttention = react.useMemo(() => runAttentionCounts(filtered), [ filtered ]), documents = react.useMemo(() => filtered.flatMap(row => row.document === void 0 ? [] : [ row.document ]), [ filtered ]), titles = useDocPreviewTitles(documents), sortedTasks = react.useMemo(() => sortForMeRows({
4762
+ }), [ filtered, forMeIdentity ]), shownAttention = react.useMemo(() => index.runAttentionCounts(filtered), [ filtered ]), documents = react.useMemo(() => filtered.flatMap(row => row.document === void 0 ? [] : [ row.document ]), [ filtered ]), titles = useDocPreviewTitles(documents), sortedTasks = react.useMemo(() => sortForMeRows({
6259
4763
  rows: taskRows,
6260
4764
  sort: forMeSort,
6261
4765
  titles: titles.titles
6262
- }), [ forMeSort, taskRows, titles ]), taskSections = react.useMemo(() => forMeSectionsOf(sortedTasks), [ sortedTasks ]), orderedTasks = react.useMemo(() => [ ...taskSections.assignedToUser, ...taskSections.assignedToRoles ], [ taskSections ]), sorted = react.useMemo(() => sortRunRows({
4766
+ }), [ forMeSort, taskRows, titles ]), taskSections = react.useMemo(() => index.forMeSectionsOf(sortedTasks), [ sortedTasks ]), orderedTasks = react.useMemo(() => [ ...taskSections.assignedToUser, ...taskSections.assignedToRoles ], [ taskSections ]), sorted = react.useMemo(() => sortRunRows({
6263
4767
  rows: filtered,
6264
4768
  sort: sort,
6265
4769
  titles: titles.titles
@@ -6269,7 +4773,7 @@ const RunsTab = react.memo(function({addressed: addressed, filterSlot: filterSlo
6269
4773
  ready: titlesReady
6270
4774
  }), panelView = react.useMemo(() => {
6271
4775
  if (!isForMe) return view;
6272
- const resolved = resolveForMeAddress({
4776
+ const resolved = index.resolveForMeAddress({
6273
4777
  rows: orderedTasks,
6274
4778
  run: view.run,
6275
4779
  task: view.task
@@ -7057,7 +5561,7 @@ function WorkflowsToolRoot() {
7057
5561
 
7058
5562
  function ToolOverflowMenu({onOpenDefinitions: onOpenDefinitions}) {
7059
5563
  /* @__PURE__ */
7060
- return jsxRuntime.jsx(ui.MenuButton, {
5564
+ return jsxRuntime.jsx(menu.MenuButton, {
7061
5565
  button: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
7062
5566
  "aria-label": "More",
7063
5567
  fontSize: 1,
@@ -7066,15 +5570,15 @@ function ToolOverflowMenu({onOpenDefinitions: onOpenDefinitions}) {
7066
5570
  padding: 2
7067
5571
  }),
7068
5572
  id: "workflows-tool-overflow",
7069
- menu: /* @__PURE__ */ jsxRuntime.jsxs(ui.Menu, {
5573
+ menu: /* @__PURE__ */ jsxRuntime.jsxs(menu.Menu, {
7070
5574
  children: [
7071
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
5575
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
7072
5576
  fontSize: 1,
7073
5577
  onClick: onOpenDefinitions,
7074
5578
  text: "Definitions"
7075
5579
  }),
7076
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuDivider, {}),
7077
- /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
5580
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuDivider, {}),
5581
+ /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
7078
5582
  as: "a",
7079
5583
  fontSize: 1,
7080
5584
  href: WORKFLOWS_DOCS_URL,
@@ -7140,7 +5644,7 @@ function DefinitionsCrumbs({onOpenDefinitions: onOpenDefinitions, onOpenWorkflow
7140
5644
  function WorkflowCrumbPicker({name: name, onOpenWorkflow: onOpenWorkflow}) {
7141
5645
  const {definitions: definitions} = useDeployedDefinitions(), options = workflowOptions(definitions ?? []), title = options.find(option => option.name === name)?.title ?? name;
7142
5646
  /* @__PURE__ */
7143
- return jsxRuntime.jsx(ui.MenuButton, {
5647
+ return jsxRuntime.jsx(menu.MenuButton, {
7144
5648
  button:
7145
5649
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
7146
5650
  disabled: options.length === 0,
@@ -7164,8 +5668,8 @@ function WorkflowCrumbPicker({name: name, onOpenWorkflow: onOpenWorkflow}) {
7164
5668
  })
7165
5669
  }),
7166
5670
  id: "workflows-crumb-picker",
7167
- menu: /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, {
7168
- children: options.map(option => /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
5671
+ menu: /* @__PURE__ */ jsxRuntime.jsx(menu.Menu, {
5672
+ children: options.map(option => /* @__PURE__ */ jsxRuntime.jsx(menu.MenuItem, {
7169
5673
  fontSize: 1,
7170
5674
  onClick: () => onOpenWorkflow(option.name),
7171
5675
  pressed: option.name === name,