@sanity/workflow-studio-plugin 0.27.0 → 0.29.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.
- package/CHANGELOG.md +427 -0
- package/dist/_chunks-cjs/index.cjs +650 -221
- package/dist/_chunks-cjs/workflows-tool-root.cjs +820 -312
- package/dist/_chunks-es/index.js +630 -213
- package/dist/_chunks-es/workflows-tool-root.js +834 -316
- package/package.json +12 -12
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var jsxRuntime = require("react/jsx-runtime"), ui = require("@sanity/ui"), workflowReact = require("@sanity/workflow-react"), react = require("react"), router = require("sanity/router"), index = require("./index.cjs"), workflowEngine = require("@sanity/workflow-engine"), ArrowLeft = require("@sanity/icons/ArrowLeft"),
|
|
3
|
+
var jsxRuntime = require("react/jsx-runtime"), ui = require("@sanity/ui"), workflowReact = require("@sanity/workflow-react"), react = require("react"), router = require("sanity/router"), index = require("./index.cjs"), workflowEngine = require("@sanity/workflow-engine"), ArrowLeft = require("@sanity/icons/ArrowLeft"), Calendar = require("@sanity/icons/Calendar"), Clock = require("@sanity/icons/Clock"), Document = require("@sanity/icons/Document"), ErrorOutline = require("@sanity/icons/ErrorOutline"), Transfer = require("@sanity/icons/Transfer"), sanity = require("sanity"), workflowStudio = require("@sanity/workflow-studio"), pluralize = require("pluralize-esm"), Add = require("@sanity/icons/Add"), Search = require("@sanity/icons/Search"), Checkmark = require("@sanity/icons/Checkmark"), Close = require("@sanity/icons/Close"), Filter = require("@sanity/icons/Filter"), workflowComponents = require("@sanity/workflow-components"), endOfDay = require("date-fns/endOfDay"), reactDom = require("react-dom"), ChevronDown = require("@sanity/icons/ChevronDown"), ChevronRight = require("@sanity/icons/ChevronRight"), types = require("@sanity/types"), Empty = require("@sanity/icons/Empty"), WarningOutline = require("@sanity/icons/WarningOutline"), workflowDiagram = require("@sanity/workflow-diagram"), react$1 = require("motion/react");
|
|
4
4
|
|
|
5
5
|
function _interopDefaultCompat(e) {
|
|
6
6
|
return e && typeof e == "object" && "default" in e ? e : {
|
|
@@ -49,11 +49,22 @@ function documentRefsOf(instance) {
|
|
|
49
49
|
return [ ...seen.values() ];
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
function rootInstanceOf(instance, byId) {
|
|
53
|
+
const rootRef = instance.ancestors[0];
|
|
54
|
+
return rootRef ? byId.get(workflowEngine.toBareId(rootRef.id)) ?? instance : instance;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const TOOL_PANEL_PADDING = 3, TOOL_HEADING_PADDING = 2, PANEL_STEP = 3;
|
|
58
|
+
|
|
52
59
|
function TabStatusRow({children: children}) {
|
|
60
|
+
const firstLineOffset = index.useSpaceToken(PANEL_STEP) + index.useSpaceToken(TOOL_HEADING_PADDING);
|
|
53
61
|
/* @__PURE__ */
|
|
54
62
|
return jsxRuntime.jsx(ui.Box, {
|
|
55
|
-
|
|
56
|
-
|
|
63
|
+
paddingBottom: PANEL_STEP,
|
|
64
|
+
paddingLeft: TOOL_HEADING_PADDING,
|
|
65
|
+
style: {
|
|
66
|
+
paddingTop: firstLineOffset
|
|
67
|
+
},
|
|
57
68
|
children: children
|
|
58
69
|
});
|
|
59
70
|
}
|
|
@@ -304,14 +315,24 @@ function InstanceDetailBody({entry: entry, framed: framed, subject: subject}) {
|
|
|
304
315
|
},
|
|
305
316
|
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
|
|
306
317
|
gap: 5,
|
|
307
|
-
children: [
|
|
318
|
+
children: [
|
|
319
|
+
/* @__PURE__ */ jsxRuntime.jsx(index.InstanceFaultNote, {
|
|
320
|
+
entry: entry,
|
|
321
|
+
scope: {
|
|
322
|
+
kind: "run",
|
|
323
|
+
onOpenActivity: activityName => setOpenActivity({
|
|
324
|
+
stage: instance.currentStage,
|
|
325
|
+
activityName: activityName
|
|
326
|
+
})
|
|
327
|
+
}
|
|
328
|
+
}), subject === "preview" ? /* @__PURE__ */ jsxRuntime.jsx(SubjectPreview, {
|
|
308
329
|
instance: instance
|
|
309
330
|
}) : null,
|
|
310
331
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
|
|
311
332
|
gap: 4,
|
|
312
333
|
children: [
|
|
313
334
|
/* @__PURE__ */ jsxRuntime.jsx(SectionHeading, {
|
|
314
|
-
children: "Stages
|
|
335
|
+
children: "Stages"
|
|
315
336
|
}),
|
|
316
337
|
/* @__PURE__ */ jsxRuntime.jsx(index.InstanceSnapshotBody, {
|
|
317
338
|
entry: entry,
|
|
@@ -393,12 +414,140 @@ function byResolvedTitle(titleOf, keyOf) {
|
|
|
393
414
|
};
|
|
394
415
|
}
|
|
395
416
|
|
|
417
|
+
function openActivitiesOf(instance) {
|
|
418
|
+
return (workflowEngine.findOpenStageEntry(instance)?.activities ?? []).filter(activity => index.isOpenActivityStatus(activity.status));
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function overdueTaskCount(instance, now) {
|
|
422
|
+
return openActivitiesOf(instance).filter(activity => index.dueDatesOf(activity.fields ?? []).some(due => index.isDueDatePast(due, now))).length;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
const NO_SIGNALS = {
|
|
426
|
+
activeCount: 0,
|
|
427
|
+
assignedToMe: 0,
|
|
428
|
+
documentCount: 0,
|
|
429
|
+
documentlessCount: 0,
|
|
430
|
+
initialStageDocumentCount: 0,
|
|
431
|
+
lastTransition: void 0,
|
|
432
|
+
overdueDocumentCount: 0,
|
|
433
|
+
overdueDocumentlessCount: 0,
|
|
434
|
+
stuckCount: 0
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
function noDefinitionSignals() {
|
|
438
|
+
return NO_SIGNALS;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function holdsWorkFor(instance, who) {
|
|
442
|
+
return openActivitiesOf(instance).some(activity => index.isActivityAssignedTo({
|
|
443
|
+
state: activity.fields ?? [],
|
|
444
|
+
who: who
|
|
445
|
+
}));
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function arrivalOf(instance, byId) {
|
|
449
|
+
const stage = workflowEngine.findOpenStageEntry(instance);
|
|
450
|
+
if (stage !== void 0) return {
|
|
451
|
+
at: stage.enteredAt,
|
|
452
|
+
document: documentRefOf(instance, byId),
|
|
453
|
+
stage: index.stageTitle(index.definitionSnapshotOf(instance), stage.name)
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function laterArrival(held, next) {
|
|
458
|
+
return next === void 0 ? held : held === void 0 || next.at > held.at ? next : held;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function documentRefOf(instance, byId) {
|
|
462
|
+
return documentRefsOf(rootInstanceOf(instance, byId))[0];
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
const NO_DRAFT = {
|
|
466
|
+
...NO_SIGNALS,
|
|
467
|
+
documents: /* @__PURE__ */ new Set,
|
|
468
|
+
initialStageDocuments: /* @__PURE__ */ new Set,
|
|
469
|
+
overdueDocuments: /* @__PURE__ */ new Set
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
function withDocument(held, document2) {
|
|
473
|
+
return document2 === void 0 ? held : new Set(held).add(document2);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function atInitialStage(instance) {
|
|
477
|
+
const snapshot = index.definitionSnapshotOf(instance);
|
|
478
|
+
return snapshot !== void 0 && instance.currentStage === snapshot.initialStage;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function fold(args) {
|
|
482
|
+
const {byId: byId, held: held, instance: instance, now: now, who: who} = args, stuck = workflowEngine.documentStuckCause({
|
|
483
|
+
instance: instance,
|
|
484
|
+
definition: index.definitionSnapshotOf(instance)
|
|
485
|
+
}), document2 = documentRefOf(instance, byId)?.id, overdue = overdueTaskCount(instance, now) > 0;
|
|
486
|
+
return {
|
|
487
|
+
activeCount: held.activeCount + 1,
|
|
488
|
+
assignedToMe: held.assignedToMe + (who !== void 0 && holdsWorkFor(instance, who) ? 1 : 0),
|
|
489
|
+
documentlessCount: held.documentlessCount + (document2 === void 0 ? 1 : 0),
|
|
490
|
+
documents: withDocument(held.documents, document2),
|
|
491
|
+
initialStageDocuments: atInitialStage(instance) ? withDocument(held.initialStageDocuments, document2) : held.initialStageDocuments,
|
|
492
|
+
lastTransition: laterArrival(held.lastTransition, arrivalOf(instance, byId)),
|
|
493
|
+
overdueDocumentlessCount: held.overdueDocumentlessCount + (overdue && document2 === void 0 ? 1 : 0),
|
|
494
|
+
overdueDocuments: overdue ? withDocument(held.overdueDocuments, document2) : held.overdueDocuments,
|
|
495
|
+
stuckCount: held.stuckCount + (stuck === void 0 ? 0 : 1)
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function settle(draft) {
|
|
500
|
+
const {documents: documents, initialStageDocuments: initialStageDocuments, overdueDocuments: overdueDocuments, ...rest} = draft;
|
|
501
|
+
return {
|
|
502
|
+
...rest,
|
|
503
|
+
documentCount: documents.size,
|
|
504
|
+
initialStageDocumentCount: initialStageDocuments.size,
|
|
505
|
+
overdueDocumentCount: overdueDocuments.size
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
function definitionSignals(args) {
|
|
510
|
+
const byId = new Map(args.instances.map(instance => [ instance._id, instance ])), drafts = /* @__PURE__ */ new Map;
|
|
511
|
+
for (const instance of args.instances) {
|
|
512
|
+
if (workflowEngine.terminalState(instance) !== "in-flight") continue;
|
|
513
|
+
const held = drafts.get(instance.definition) ?? NO_DRAFT;
|
|
514
|
+
drafts.set(instance.definition, fold({
|
|
515
|
+
byId: byId,
|
|
516
|
+
held: held,
|
|
517
|
+
instance: instance,
|
|
518
|
+
now: args.now,
|
|
519
|
+
who: args.identity
|
|
520
|
+
}));
|
|
521
|
+
}
|
|
522
|
+
return new Map([ ...drafts ].map(([name, draft]) => [ name, settle(draft) ]));
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function catalogBands(rows) {
|
|
526
|
+
const assigned = rows.filter(row => row.signals.assignedToMe > 0);
|
|
527
|
+
if (assigned.length === 0) return [ {
|
|
528
|
+
rows: rows,
|
|
529
|
+
title: void 0
|
|
530
|
+
} ];
|
|
531
|
+
const rest = rows.filter(row => row.signals.assignedToMe === 0);
|
|
532
|
+
return [ {
|
|
533
|
+
rows: assigned,
|
|
534
|
+
title: "Assigned to you"
|
|
535
|
+
}, {
|
|
536
|
+
rows: rest,
|
|
537
|
+
title: "Other workflows"
|
|
538
|
+
} ].filter(band => band.rows.length > 0);
|
|
539
|
+
}
|
|
540
|
+
|
|
396
541
|
function definitionCatalog(args) {
|
|
397
|
-
const rejected = [ ...args.issues.values() ]
|
|
542
|
+
const rejected = [ ...args.issues.values() ], signals = definitionSignals({
|
|
543
|
+
identity: args.identity,
|
|
544
|
+
instances: args.instances,
|
|
545
|
+
now: args.now
|
|
546
|
+
});
|
|
398
547
|
return args.definitions.map(definition => ({
|
|
399
548
|
name: definition.name,
|
|
400
549
|
title: definition.title ?? definition.name,
|
|
401
|
-
|
|
550
|
+
signals: signals.get(definition.name) ?? noDefinitionSignals(),
|
|
402
551
|
docTypes: [ ...new Set(args.mappings.filter(mapping => mapping.definition === definition.name).map(mapping => mapping.docType)) ],
|
|
403
552
|
brokenBindings: rejected.filter(issue => issue.definition === definition.name && issue.version === definition.version).map(issue => ({
|
|
404
553
|
docType: issue.docType,
|
|
@@ -436,28 +585,60 @@ function deployedPhrase(definition) {
|
|
|
436
585
|
return ago === "" ? index.formatShortDateTime(deployedAt) : `${index.formatShortDateTime(deployedAt)} (${ago})`;
|
|
437
586
|
}
|
|
438
587
|
|
|
439
|
-
const
|
|
588
|
+
const logged = /* @__PURE__ */ new WeakSet;
|
|
589
|
+
|
|
590
|
+
function logReadFailure(what, error) {
|
|
591
|
+
if (typeof error == "object" && error !== null) {
|
|
592
|
+
if (logged.has(error)) return;
|
|
593
|
+
logged.add(error);
|
|
594
|
+
}
|
|
595
|
+
console.error(`[workflow-studio-plugin] could not load ${what}:`, error);
|
|
596
|
+
}
|
|
440
597
|
|
|
441
|
-
function
|
|
442
|
-
|
|
598
|
+
function useReadFailureLog(what, error) {
|
|
599
|
+
react.useEffect(() => {
|
|
600
|
+
error !== void 0 && logReadFailure(what, error);
|
|
601
|
+
}, [ what, error ]);
|
|
443
602
|
}
|
|
444
603
|
|
|
445
|
-
const
|
|
604
|
+
const INSTANCE_CAP = 200, INSTANCES_READ_FAILED = "Couldn’t load workflow data. Try again later.";
|
|
605
|
+
|
|
606
|
+
function useCappedInstances(filter) {
|
|
607
|
+
const {engine: engine} = index.useWorkflowContext(), capped = react.useMemo(() => ({
|
|
608
|
+
...filter,
|
|
609
|
+
limit: INSTANCE_CAP
|
|
610
|
+
}), [ filter ]), {instances: instances, loading: loading, unreadable: unreadable, error: error} = workflowStudio.useWorkflowInstances({
|
|
611
|
+
engine: engine,
|
|
612
|
+
filter: capped
|
|
613
|
+
});
|
|
614
|
+
return useReadFailureLog("workflow data", error), react.useMemo(() => {
|
|
615
|
+
const rows = instances ?? [];
|
|
616
|
+
return {
|
|
617
|
+
rows: rows,
|
|
618
|
+
truncated: rows.length + unreadable.length === INSTANCE_CAP,
|
|
619
|
+
loading: loading,
|
|
620
|
+
unreadable: unreadable,
|
|
621
|
+
error: error === void 0 ? void 0 : workflowEngine.errorMessage(error)
|
|
622
|
+
};
|
|
623
|
+
}, [ instances, loading, unreadable, error ]);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
const CATALOG_READ_FAILED = "Couldn’t load the deployed workflows. Try again later.", lastRead$1 = /* @__PURE__ */ new WeakMap, issuedReads = /* @__PURE__ */ new WeakMap;
|
|
446
627
|
|
|
447
628
|
function useDeployedDefinitions() {
|
|
448
|
-
const {engine: engine} = index.useWorkflowContext(), [definitions, setDefinitions] = react.useState(() => lastRead.get(engine)?.rows), [error, setError] = react.useState(void 0);
|
|
629
|
+
const {engine: engine} = index.useWorkflowContext(), [definitions, setDefinitions] = react.useState(() => lastRead$1.get(engine)?.rows), [error, setError] = react.useState(void 0);
|
|
449
630
|
return react.useEffect(() => {
|
|
450
631
|
let cancelled = !1;
|
|
451
|
-
setDefinitions(lastRead.get(engine)?.rows), setError(void 0);
|
|
632
|
+
setDefinitions(lastRead$1.get(engine)?.rows), setError(void 0);
|
|
452
633
|
const seq = (issuedReads.get(engine) ?? 0) + 1;
|
|
453
634
|
return issuedReads.set(engine, seq), (async () => {
|
|
454
|
-
const rows = await index.readDeployedDefinitions(engine), latest = workflowEngine.latestDeployedDefinitions(rows), held = lastRead.get(engine);
|
|
455
|
-
(held === void 0 || seq > held.seq) && lastRead.set(engine, {
|
|
635
|
+
const rows = await index.readDeployedDefinitions(engine), latest = workflowEngine.latestDeployedDefinitions(rows), held = lastRead$1.get(engine);
|
|
636
|
+
(held === void 0 || seq > held.seq) && lastRead$1.set(engine, {
|
|
456
637
|
seq: seq,
|
|
457
638
|
rows: latest
|
|
458
639
|
}), cancelled || (setDefinitions(latest), setError(void 0));
|
|
459
640
|
})().catch(err => {
|
|
460
|
-
cancelled || setError(index.describeError(err));
|
|
641
|
+
logReadFailure("the deployed workflows", err), cancelled || setError(index.describeError(err));
|
|
461
642
|
}), () => {
|
|
462
643
|
cancelled = !0;
|
|
463
644
|
};
|
|
@@ -467,75 +648,197 @@ function useDeployedDefinitions() {
|
|
|
467
648
|
};
|
|
468
649
|
}
|
|
469
650
|
|
|
470
|
-
const
|
|
651
|
+
const NO_TITLES = {
|
|
652
|
+
titles: /* @__PURE__ */ new Map,
|
|
653
|
+
resolved: /* @__PURE__ */ new Set
|
|
654
|
+
};
|
|
471
655
|
|
|
472
|
-
function
|
|
473
|
-
const {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
656
|
+
function useDocPreviewTitles(documents) {
|
|
657
|
+
const previewStore = sanity.useDocumentPreviewStore(), schema = sanity.useSchema(), {perspectiveStack: perspectiveStack} = sanity.usePerspective(), {actualTypes: actualTypes, binding: binding} = index.useWorkflowContext(), [state, setState] = react.useState(NO_TITLES), key = documents.map(doc => doc.id).join("|");
|
|
658
|
+
return react.useEffect(() => {
|
|
659
|
+
const titles = /* @__PURE__ */ new Map, resolved = /* @__PURE__ */ new Set, previews = /* @__PURE__ */ new Map, publish = () => setState({
|
|
660
|
+
titles: new Map(titles),
|
|
661
|
+
resolved: new Set(resolved)
|
|
662
|
+
}), localDocs = documents.flatMap(doc => {
|
|
663
|
+
const {parsed: parsed, local: local} = index.gdrLocality(doc.id, binding.contentResource);
|
|
664
|
+
return !parsed || !local ? (resolved.add(doc.id), []) : [ {
|
|
665
|
+
doc: doc,
|
|
666
|
+
bareId: parsed.documentId
|
|
667
|
+
} ];
|
|
668
|
+
}), untracks = localDocs.map(({bareId: bareId}) => actualTypes.track(bareId)), dropPreview = docId => {
|
|
669
|
+
previews.get(docId)?.unsubscribe(), previews.delete(docId), titles.delete(docId);
|
|
670
|
+
}, observe = ({docId: docId, bareId: bareId, typeName: typeName}) => {
|
|
671
|
+
const schemaType = index.openableSchemaType(schema, typeName);
|
|
672
|
+
if (!schemaType) return !1;
|
|
673
|
+
if (previews.get(docId)?.typeName === typeName) return !0;
|
|
674
|
+
dropPreview(docId), resolved.delete(docId);
|
|
675
|
+
const subscription = previewStore.observeForPreview({
|
|
676
|
+
_id: bareId,
|
|
677
|
+
_type: schemaType.name
|
|
678
|
+
}, schemaType, {
|
|
679
|
+
perspective: perspectiveStack
|
|
680
|
+
}).subscribe({
|
|
681
|
+
next: event => {
|
|
682
|
+
resolved.add(docId);
|
|
683
|
+
const title = event.snapshot?.title;
|
|
684
|
+
typeof title == "string" ? titles.set(docId, title) : titles.delete(docId), publish();
|
|
685
|
+
},
|
|
686
|
+
error: err => {
|
|
687
|
+
console.error(`[workflow-studio-plugin] preview for "${docId}" failed:`, err), resolved.add(docId),
|
|
688
|
+
publish();
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
return previews.set(docId, {
|
|
692
|
+
typeName: typeName,
|
|
693
|
+
unsubscribe: () => subscription.unsubscribe()
|
|
694
|
+
}), !0;
|
|
695
|
+
}, evaluate = () => {
|
|
696
|
+
for (const {doc: doc, bareId: bareId} of localDocs) {
|
|
697
|
+
const probe = actualTypes.read(bareId);
|
|
698
|
+
if (probe === null) {
|
|
699
|
+
dropPreview(doc.id), resolved.add(doc.id);
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
!observe({
|
|
703
|
+
docId: doc.id,
|
|
704
|
+
bareId: bareId,
|
|
705
|
+
typeName: probe ?? doc.type
|
|
706
|
+
}) && typeof probe == "string" && (dropPreview(doc.id), resolved.add(doc.id));
|
|
707
|
+
}
|
|
708
|
+
publish();
|
|
709
|
+
}, unsubscribeProbes = actualTypes.subscribe(evaluate);
|
|
710
|
+
return evaluate(), () => {
|
|
711
|
+
unsubscribeProbes(), untracks.forEach(untrack => untrack()), previews.forEach(preview => preview.unsubscribe());
|
|
487
712
|
};
|
|
488
|
-
}, [
|
|
713
|
+
}, [ key, previewStore, schema, actualTypes, binding.contentResource.id, perspectiveStack.join("|") ]),
|
|
714
|
+
state;
|
|
489
715
|
}
|
|
490
716
|
|
|
491
717
|
const INSTANCE_CAP_COUNT_NOTE = `Counts from the latest ${INSTANCE_CAP} workflows — older ones aren’t counted.`, NEWEST_INSTANCES = {
|
|
492
718
|
includeCompleted: !0
|
|
493
|
-
};
|
|
719
|
+
}, lastRead = /* @__PURE__ */ new WeakMap;
|
|
494
720
|
|
|
495
721
|
function useToolInstances() {
|
|
496
|
-
const {rows: rows, truncated: truncated, loading: loading, unreadable: unreadable} = useCappedInstances(NEWEST_INSTANCES)
|
|
497
|
-
return react.useMemo(() => ({
|
|
722
|
+
const {engine: engine} = index.useWorkflowContext(), {rows: rows, truncated: truncated, loading: loading, unreadable: unreadable, error: error} = useCappedInstances(NEWEST_INSTANCES), fresh = react.useMemo(() => ({
|
|
498
723
|
inFlight: rows.filter(instance => workflowEngine.terminalState(instance) === "in-flight"),
|
|
499
724
|
settled: rows.filter(instance => workflowEngine.terminalState(instance) !== "in-flight"),
|
|
500
725
|
truncated: truncated,
|
|
501
726
|
loading: loading,
|
|
502
|
-
unreadable: unreadable
|
|
503
|
-
|
|
727
|
+
unreadable: unreadable,
|
|
728
|
+
error: error
|
|
729
|
+
}), [ rows, truncated, loading, unreadable, error ]);
|
|
730
|
+
return react.useEffect(() => {
|
|
731
|
+
!fresh.loading && fresh.error === void 0 && lastRead.set(engine, fresh);
|
|
732
|
+
}, [ engine, fresh ]), loading ? lastRead.get(engine) ?? fresh : fresh;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
function documentPhrase(count) {
|
|
736
|
+
return count === 0 ? "No documents" : pluralize__default.default("document", count, !0);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
function documentlessTail(count) {
|
|
740
|
+
return count === 0 ? "" : ` (${pluralize__default.default("instance", count, !0)})`;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
function documentlessNote(work) {
|
|
744
|
+
return work.documentCount > 0 ? "" : documentlessTail(work.documentlessCount);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
function documentFace(work, atStart) {
|
|
748
|
+
const lead = `${documentPhrase(work.documentCount)} with an active workflow${documentlessNote(work)}`;
|
|
749
|
+
return atStart === 0 ? {
|
|
750
|
+
lead: lead,
|
|
751
|
+
startLine: void 0
|
|
752
|
+
} : atStart === work.documentCount ? {
|
|
753
|
+
lead: `${lead}, yet to leave the starting stage`,
|
|
754
|
+
startLine: void 0
|
|
755
|
+
} : {
|
|
756
|
+
lead: lead,
|
|
757
|
+
startLine: `${atStart} still at the starting stage`
|
|
758
|
+
};
|
|
504
759
|
}
|
|
505
760
|
|
|
506
|
-
function
|
|
507
|
-
return
|
|
761
|
+
function overdueHint(work) {
|
|
762
|
+
return `${documentPhrase(work.documentCount)} with overdue tasks${documentlessTail(work.documentlessCount)}`;
|
|
508
763
|
}
|
|
509
764
|
|
|
510
|
-
const
|
|
765
|
+
const UNTITLED_DOCUMENT = "Untitled", TRANSITION_HINT_PENDING = "Loading…";
|
|
511
766
|
|
|
512
|
-
function
|
|
513
|
-
|
|
767
|
+
function transitionHeading(at) {
|
|
768
|
+
return `Last stage change at ${index.formatShortDateTime(at)}`;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
function transitionFace(args) {
|
|
772
|
+
return args.documentPending ? {
|
|
773
|
+
state: "pending"
|
|
774
|
+
} : {
|
|
775
|
+
state: "ready",
|
|
776
|
+
document: args.documentTitle,
|
|
777
|
+
heading: transitionHeading(args.at),
|
|
778
|
+
lead: args.documentTitle === void 0 ? "Changed to" : "changed to",
|
|
779
|
+
stage: args.stage
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
function catalogView(args) {
|
|
784
|
+
if (args.error !== void 0) return {
|
|
785
|
+
kind: "unreadable"
|
|
786
|
+
};
|
|
787
|
+
if (args.definitions === void 0 || args.instances.loading || args.identity.kind === "pending") return {
|
|
788
|
+
kind: "loading"
|
|
789
|
+
};
|
|
790
|
+
if (args.definitions.length === 0) return {
|
|
791
|
+
kind: "empty"
|
|
792
|
+
};
|
|
793
|
+
const rows = definitionCatalog({
|
|
794
|
+
definitions: args.definitions,
|
|
795
|
+
identity: index.identityOf(args.identity),
|
|
796
|
+
instances: [ ...args.instances.inFlight, ...args.instances.settled ],
|
|
797
|
+
issues: args.issues,
|
|
798
|
+
mappings: args.mappings,
|
|
799
|
+
now: args.now
|
|
800
|
+
});
|
|
801
|
+
return {
|
|
802
|
+
kind: "bands",
|
|
803
|
+
bands: catalogBands(rows)
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
function definitionAlert(row) {
|
|
808
|
+
if (row.signals.stuckCount !== 0) return {
|
|
809
|
+
hint: `${pluralize__default.default("run", row.signals.stuckCount, !0)} here can’t continue without help`
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
const CARD_MIN_WIDTH = 280, CARD_RADIUS$1 = 3, CARD_PADDING = 4, HINT_DOCUMENT_MAX_WIDTH = 200, BAND_GAP = 6, CARD_MIN_HEIGHT = 120;
|
|
814
|
+
|
|
815
|
+
function OverviewTab({identity: identity, onOpenWorkflow: onOpenWorkflow}) {
|
|
816
|
+
const {definitions: definitions, error: error} = useDeployedDefinitions(), {mappingIssues: mappingIssues, mappings: mappings} = index.useWorkflowContext(), schema = sanity.useSchema(), instances = useToolInstances(), now = index.useMinuteClock(), view = catalogView({
|
|
817
|
+
definitions: definitions,
|
|
818
|
+
error: error,
|
|
819
|
+
identity: identity,
|
|
820
|
+
instances: instances,
|
|
821
|
+
issues: mappingIssues,
|
|
822
|
+
mappings: mappings,
|
|
823
|
+
now: now
|
|
824
|
+
}), undeployed = /* @__PURE__ */ jsxRuntime.jsx(UndeployedWorkflows, {
|
|
514
825
|
notices: undeployedWorkflowNotices({
|
|
515
826
|
issues: mappingIssues,
|
|
516
827
|
titleOf: name => schema.get(name)?.title
|
|
517
828
|
})
|
|
518
829
|
});
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
size: 1,
|
|
524
|
-
children: catalogReadError(error)
|
|
525
|
-
})
|
|
526
|
-
});
|
|
527
|
-
if (definitions === void 0) /* @__PURE__ */
|
|
528
|
-
return jsxRuntime.jsx(TabStatusRow, {
|
|
830
|
+
return view.kind === "unreadable" ? /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
|
|
831
|
+
label: CATALOG_READ_FAILED,
|
|
832
|
+
tone: "critical"
|
|
833
|
+
}) : view.kind === "loading" ? /* @__PURE__ */ jsxRuntime.jsx(TabStatusRow, {
|
|
529
834
|
children: /* @__PURE__ */ jsxRuntime.jsx(index.LoadingRow, {
|
|
530
835
|
label: "Loading workflows…"
|
|
531
836
|
})
|
|
532
|
-
})
|
|
533
|
-
if (definitions.length === 0) /* @__PURE__ */
|
|
534
|
-
return jsxRuntime.jsxs(ui.Flex, {
|
|
837
|
+
}) : view.kind === "empty" ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
|
|
535
838
|
direction: "column",
|
|
536
839
|
flex: 1,
|
|
537
840
|
gap: 3,
|
|
538
|
-
paddingBottom:
|
|
841
|
+
paddingBottom: 3,
|
|
539
842
|
paddingTop: 3,
|
|
540
843
|
children: [ undeployed,
|
|
541
844
|
/* @__PURE__ */ jsxRuntime.jsx(index.EmptyState, {
|
|
@@ -543,67 +846,166 @@ function OverviewTab({onOpenWorkflow: onOpenWorkflow}) {
|
|
|
543
846
|
icon: /* @__PURE__ */ jsxRuntime.jsx(Transfer.TransferIcon, {}),
|
|
544
847
|
title: "No workflows deployed"
|
|
545
848
|
}) ]
|
|
546
|
-
})
|
|
547
|
-
const rows = definitionCatalog({
|
|
548
|
-
definitions: definitions,
|
|
549
|
-
mappings: mappings,
|
|
550
|
-
inFlight: instances.inFlight,
|
|
551
|
-
issues: mappingIssues
|
|
552
|
-
}), active = rows.reduce((sum, row) => sum + row.activeCount, 0);
|
|
553
|
-
/* @__PURE__ */
|
|
554
|
-
return jsxRuntime.jsxs(ui.Stack, {
|
|
849
|
+
}) : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
|
|
555
850
|
gap: 3,
|
|
556
851
|
paddingBottom: 4,
|
|
557
852
|
paddingTop: 3,
|
|
558
|
-
children: [ undeployed,
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
gap: 2,
|
|
562
|
-
padding: TOOL_HEADING_PADDING,
|
|
563
|
-
children: [
|
|
564
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
565
|
-
size: 1,
|
|
566
|
-
weight: "semibold",
|
|
567
|
-
children: pluralize__default.default("workflow", rows.length, !0)
|
|
568
|
-
}),
|
|
569
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
570
|
-
muted: !0,
|
|
571
|
-
size: 1,
|
|
572
|
-
children: instances.loading ? "counting active instances…" : activeSummary(active)
|
|
573
|
-
}) ]
|
|
853
|
+
children: [ undeployed, instances.error === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
|
|
854
|
+
label: INSTANCES_READ_FAILED,
|
|
855
|
+
tone: "critical"
|
|
574
856
|
}),
|
|
575
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.
|
|
576
|
-
gap:
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
857
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
|
|
858
|
+
gap: BAND_GAP,
|
|
859
|
+
children: view.bands.map(band => /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
|
|
860
|
+
gap: 3,
|
|
861
|
+
children: [ band.title === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
862
|
+
padding: TOOL_HEADING_PADDING,
|
|
863
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(index.CountedHeading, {
|
|
864
|
+
count: band.rows.length,
|
|
865
|
+
title: band.title
|
|
866
|
+
})
|
|
867
|
+
}),
|
|
868
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardGrid, {
|
|
869
|
+
countKnown: instances.error === void 0,
|
|
870
|
+
now: now,
|
|
871
|
+
onOpenWorkflow: onOpenWorkflow,
|
|
872
|
+
rows: band.rows
|
|
873
|
+
}) ]
|
|
874
|
+
}, band.title ?? UNBANDED_KEY))
|
|
586
875
|
}), instances.truncated ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
|
|
587
876
|
text: INSTANCE_CAP_COUNT_NOTE
|
|
588
877
|
}) : null ]
|
|
589
878
|
});
|
|
590
879
|
}
|
|
591
880
|
|
|
592
|
-
const
|
|
881
|
+
const UNBANDED_KEY = "all";
|
|
882
|
+
|
|
883
|
+
function CardGrid({countKnown: countKnown, now: now, onOpenWorkflow: onOpenWorkflow, rows: rows}) {
|
|
884
|
+
/* @__PURE__ */
|
|
885
|
+
return jsxRuntime.jsx(ui.Grid, {
|
|
886
|
+
gap: 3,
|
|
887
|
+
style: {
|
|
888
|
+
gridAutoRows: `minmax(${CARD_MIN_HEIGHT}px, auto)`,
|
|
889
|
+
gridTemplateColumns: `repeat(auto-fill, minmax(${CARD_MIN_WIDTH}px, 1fr))`
|
|
890
|
+
},
|
|
891
|
+
children: rows.map(row => /* @__PURE__ */ jsxRuntime.jsx(WorkflowCard, {
|
|
892
|
+
countKnown: countKnown,
|
|
893
|
+
now: now,
|
|
894
|
+
onOpen: () => onOpenWorkflow(row.name),
|
|
895
|
+
row: row
|
|
896
|
+
}, row.name))
|
|
897
|
+
});
|
|
898
|
+
}
|
|
593
899
|
|
|
594
900
|
function UndeployedWorkflows({notices: notices}) {
|
|
595
901
|
return notices.length === 0 ? null :
|
|
596
902
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
|
|
597
903
|
gap: 2,
|
|
598
904
|
paddingBottom: 1,
|
|
599
|
-
children: notices.map(notice => /* @__PURE__ */ jsxRuntime.jsx(index.
|
|
905
|
+
children: notices.map(notice => /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
|
|
600
906
|
label: notice
|
|
601
907
|
}, notice))
|
|
602
908
|
});
|
|
603
909
|
}
|
|
604
910
|
|
|
605
|
-
function
|
|
606
|
-
const
|
|
911
|
+
function LastTransitionHint({transition: transition}) {
|
|
912
|
+
const documents = react.useMemo(() => transition.document === void 0 ? [] : [ transition.document ], [ transition.document ]), {resolved: resolved, titles: titles} = useDocPreviewTitles(documents), id = transition.document?.id, face = transitionFace({
|
|
913
|
+
at: transition.at,
|
|
914
|
+
documentPending: id !== void 0 && !resolved.has(id),
|
|
915
|
+
documentTitle: id === void 0 ? void 0 : titles.get(id) ?? UNTITLED_DOCUMENT,
|
|
916
|
+
stage: transition.stage
|
|
917
|
+
});
|
|
918
|
+
return face.state === "pending" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
919
|
+
muted: !0,
|
|
920
|
+
size: 1,
|
|
921
|
+
children: TRANSITION_HINT_PENDING
|
|
922
|
+
}) :
|
|
923
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
|
|
924
|
+
gap: 3,
|
|
925
|
+
children: [
|
|
926
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
927
|
+
muted: !0,
|
|
928
|
+
size: 1,
|
|
929
|
+
children: face.heading
|
|
930
|
+
}),
|
|
931
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, {
|
|
932
|
+
size: 1,
|
|
933
|
+
textOverflow: "ellipsis",
|
|
934
|
+
children: [ face.document === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(HintDocument, {
|
|
935
|
+
children: face.document
|
|
936
|
+
}), face.document === void 0 ? "" : " ", face.lead, " ",
|
|
937
|
+
/* @__PURE__ */ jsxRuntime.jsx(index.InlineEmphasis, {
|
|
938
|
+
children: face.stage
|
|
939
|
+
}) ]
|
|
940
|
+
}) ]
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
function HintDocument({children: children}) {
|
|
945
|
+
/* @__PURE__ */
|
|
946
|
+
return jsxRuntime.jsx("span", {
|
|
947
|
+
style: {
|
|
948
|
+
display: "inline-block",
|
|
949
|
+
maxWidth: HINT_DOCUMENT_MAX_WIDTH,
|
|
950
|
+
overflow: "hidden",
|
|
951
|
+
textOverflow: "ellipsis",
|
|
952
|
+
verticalAlign: "bottom",
|
|
953
|
+
whiteSpace: "nowrap"
|
|
954
|
+
},
|
|
955
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(index.InlineEmphasis, {
|
|
956
|
+
children: children
|
|
957
|
+
})
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
function overdueWork(signals) {
|
|
962
|
+
return {
|
|
963
|
+
documentCount: signals.overdueDocumentCount,
|
|
964
|
+
documentlessCount: signals.overdueDocumentlessCount
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
function CardMetrics$1({now: now, signals: signals}) {
|
|
969
|
+
const overdue = overdueWork(signals), overdueTotal = overdue.documentCount + overdue.documentlessCount, documents = documentFace(signals, signals.initialStageDocumentCount);
|
|
970
|
+
/* @__PURE__ */
|
|
971
|
+
return jsxRuntime.jsxs(ui.Flex, {
|
|
972
|
+
align: "center",
|
|
973
|
+
gap: 3,
|
|
974
|
+
children: [
|
|
975
|
+
/* @__PURE__ */ jsxRuntime.jsx(index.MetricPair, {
|
|
976
|
+
Icon: Document.DocumentIcon,
|
|
977
|
+
empty: signals.documentCount === 0 && signals.documentlessCount === 0,
|
|
978
|
+
face: {
|
|
979
|
+
text: documents.lead,
|
|
980
|
+
...documents.startLine === void 0 ? {} : {
|
|
981
|
+
description: documents.startLine
|
|
982
|
+
}
|
|
983
|
+
},
|
|
984
|
+
value: String(signals.documentCount)
|
|
985
|
+
}), signals.lastTransition === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.MetricPair, {
|
|
986
|
+
Icon: Clock.ClockIcon,
|
|
987
|
+
face: {
|
|
988
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(LastTransitionHint, {
|
|
989
|
+
transition: signals.lastTransition
|
|
990
|
+
}),
|
|
991
|
+
wide: !0
|
|
992
|
+
},
|
|
993
|
+
value: index.formatShortAgo(signals.lastTransition.at, now)
|
|
994
|
+
}), overdueTotal === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.MetricPair, {
|
|
995
|
+
Icon: Calendar.CalendarIcon,
|
|
996
|
+
face: {
|
|
997
|
+
text: overdueHint(overdue)
|
|
998
|
+
},
|
|
999
|
+
tone: "caution",
|
|
1000
|
+
value: String(overdueTotal)
|
|
1001
|
+
}) ]
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
function WorkflowCard({countKnown: countKnown, now: now, onOpen: onOpen, row: row}) {
|
|
1006
|
+
const alert = definitionAlert(row);
|
|
1007
|
+
/* @__PURE__ */
|
|
1008
|
+
return jsxRuntime.jsxs(ui.Card, {
|
|
607
1009
|
as: "button",
|
|
608
1010
|
onClick: onOpen,
|
|
609
1011
|
padding: CARD_PADDING,
|
|
@@ -616,50 +1018,44 @@ function WorkflowCard({countPending: countPending, onOpen: onOpen, row: row}) {
|
|
|
616
1018
|
textAlign: "left",
|
|
617
1019
|
width: "100%"
|
|
618
1020
|
},
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
} : {},
|
|
622
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
|
|
1021
|
+
children: [
|
|
1022
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
|
|
623
1023
|
align: "flex-start",
|
|
624
|
-
gap:
|
|
625
|
-
|
|
626
|
-
size: 1,
|
|
627
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(WarningOutline.WarningOutlineIcon, {})
|
|
628
|
-
}) : null,
|
|
629
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
|
|
1024
|
+
gap: 2,
|
|
1025
|
+
style: {
|
|
630
1026
|
flex: 1,
|
|
631
|
-
|
|
1027
|
+
minWidth: 0
|
|
1028
|
+
},
|
|
1029
|
+
children: [
|
|
1030
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
1031
|
+
size: 1,
|
|
632
1032
|
style: {
|
|
1033
|
+
flex: 1,
|
|
633
1034
|
minWidth: 0
|
|
634
1035
|
},
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
muted: !0,
|
|
642
|
-
size: 1,
|
|
643
|
-
children: activeSummary(row.activeCount)
|
|
644
|
-
}) ]
|
|
1036
|
+
weight: "medium",
|
|
1037
|
+
children: row.title
|
|
1038
|
+
}), alert === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.AlertGlyph, {
|
|
1039
|
+
Icon: ErrorOutline.ErrorOutlineIcon,
|
|
1040
|
+
hint: alert.hint,
|
|
1041
|
+
tone: "critical"
|
|
645
1042
|
}) ]
|
|
646
|
-
})
|
|
1043
|
+
}), countKnown ? /* @__PURE__ */ jsxRuntime.jsx(CardMetrics$1, {
|
|
1044
|
+
now: now,
|
|
1045
|
+
signals: row.signals
|
|
1046
|
+
}) : null ]
|
|
647
1047
|
});
|
|
648
|
-
return flagged ? /* @__PURE__ */ jsxRuntime.jsx(index.HoverHint, {
|
|
649
|
-
fill: !0,
|
|
650
|
-
text: CARD_ISSUES_HINT,
|
|
651
|
-
children: card
|
|
652
|
-
}) : card;
|
|
653
1048
|
}
|
|
654
1049
|
|
|
655
1050
|
function useStartableDefinitions() {
|
|
656
|
-
const {definitions: definitions, error: error} = useDeployedDefinitions()
|
|
1051
|
+
const {definitions: definitions, error: error} = useDeployedDefinitions(), startable = react.useMemo(() => definitions?.filter(row => workflowEngine.isStartableDefinition(row)).map(row => ({
|
|
1052
|
+
name: row.name,
|
|
1053
|
+
title: row.title ?? row.name,
|
|
1054
|
+
description: row.description
|
|
1055
|
+
})), [ definitions ]);
|
|
657
1056
|
return {
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
title: row.title ?? row.name,
|
|
661
|
-
description: row.description
|
|
662
|
-
})), [ definitions ]),
|
|
1057
|
+
catalogEmpty: definitions?.length === 0,
|
|
1058
|
+
definitions: startable,
|
|
663
1059
|
error: error
|
|
664
1060
|
};
|
|
665
1061
|
}
|
|
@@ -691,16 +1087,45 @@ function NewWorkflowButton() {
|
|
|
691
1087
|
});
|
|
692
1088
|
}
|
|
693
1089
|
|
|
1090
|
+
const PANEL_WIDTH = 340;
|
|
1091
|
+
|
|
1092
|
+
function NothingToStart({catalogEmpty: catalogEmpty}) {
|
|
1093
|
+
/* @__PURE__ */
|
|
1094
|
+
return jsxRuntime.jsx(ui.Box, {
|
|
1095
|
+
padding: 4,
|
|
1096
|
+
style: {
|
|
1097
|
+
width: PANEL_WIDTH
|
|
1098
|
+
},
|
|
1099
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
|
|
1100
|
+
gap: 3,
|
|
1101
|
+
children: [
|
|
1102
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
1103
|
+
align: "center",
|
|
1104
|
+
size: 1,
|
|
1105
|
+
weight: "medium",
|
|
1106
|
+
children: catalogEmpty ? "No workflows deployed" : "Nothing to start by hand"
|
|
1107
|
+
}),
|
|
1108
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
1109
|
+
align: "center",
|
|
1110
|
+
muted: !0,
|
|
1111
|
+
size: 1,
|
|
1112
|
+
children: catalogEmpty ? "Deploy a workflow to this project to start one from here" : "Every deployed workflow here is started by a parent workflow, never by hand"
|
|
1113
|
+
}) ]
|
|
1114
|
+
})
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
|
|
694
1118
|
function DefinitionPickerPanel({onPick: onPick}) {
|
|
695
|
-
const {definitions: definitions, error: error} = useStartableDefinitions(), [query, setQuery] = react.useState(""), visible = react.useMemo(() => {
|
|
1119
|
+
const {catalogEmpty: catalogEmpty, definitions: definitions, error: error} = useStartableDefinitions(), [query, setQuery] = react.useState(""), visible = react.useMemo(() => {
|
|
696
1120
|
const q = query.trim().toLowerCase();
|
|
697
1121
|
return definitions ? q ? definitions.filter(d => `${d.title} ${d.name}`.toLowerCase().includes(q)) : definitions : [];
|
|
698
|
-
}, [ definitions, query ]);
|
|
699
|
-
/* @__PURE__ */
|
|
700
|
-
|
|
1122
|
+
}, [ definitions, query ]), settled = error === void 0 ? definitions : void 0;
|
|
1123
|
+
return settled?.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(NothingToStart, {
|
|
1124
|
+
catalogEmpty: catalogEmpty
|
|
1125
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
701
1126
|
padding: 2,
|
|
702
1127
|
style: {
|
|
703
|
-
width:
|
|
1128
|
+
width: PANEL_WIDTH
|
|
704
1129
|
},
|
|
705
1130
|
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
|
|
706
1131
|
gap: 2,
|
|
@@ -712,13 +1137,12 @@ function DefinitionPickerPanel({onPick: onPick}) {
|
|
|
712
1137
|
onChange: event => setQuery(event.currentTarget.value),
|
|
713
1138
|
placeholder: "Filter workflows…",
|
|
714
1139
|
value: query
|
|
715
|
-
}), error ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
716
|
-
|
|
1140
|
+
}), error ? /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
|
|
1141
|
+
label: CATALOG_READ_FAILED,
|
|
1142
|
+
tone: "critical"
|
|
717
1143
|
}) : null, !definitions && !error ? /* @__PURE__ */ jsxRuntime.jsx(index.LoadingRow, {
|
|
718
1144
|
label: "Loading workflows…"
|
|
719
|
-
}) : null,
|
|
720
|
-
text: "No startable workflows are deployed"
|
|
721
|
-
}) : null, definitions && definitions.length > 0 && visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
|
|
1145
|
+
}) : null, settled !== void 0 && settled.length > 0 && visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
|
|
722
1146
|
text: "No workflows match"
|
|
723
1147
|
}) : null,
|
|
724
1148
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
|
|
@@ -996,13 +1420,20 @@ function useBandOpen(bands, key) {
|
|
|
996
1420
|
};
|
|
997
1421
|
}
|
|
998
1422
|
|
|
999
|
-
const
|
|
1423
|
+
const REVEAL_STALL_MS = 2e3, REVEAL_COLD_MS = 15e3;
|
|
1000
1424
|
|
|
1001
1425
|
function useRevealGate(args) {
|
|
1002
|
-
const {loading: loading, ready: ready} = args, settled = !loading && ready,
|
|
1426
|
+
const {loading: loading, progress: progress, ready: ready} = args, settled = !loading && ready, [stalled, setStalled] = react.useState(!1);
|
|
1427
|
+
react.useEffect(() => {
|
|
1428
|
+
if (loading || ready) return;
|
|
1429
|
+
setStalled(!1);
|
|
1430
|
+
const budget = progress > 0 ? REVEAL_STALL_MS : REVEAL_COLD_MS, timer = setTimeout(() => setStalled(!0), budget);
|
|
1431
|
+
return () => clearTimeout(timer);
|
|
1432
|
+
}, [ loading, progress, ready ]);
|
|
1433
|
+
const [revealed, setRevealed] = react.useState(!1);
|
|
1003
1434
|
return react.useEffect(() => {
|
|
1004
|
-
!revealed && (settled ||
|
|
1005
|
-
}, [
|
|
1435
|
+
!revealed && (settled || stalled) && setRevealed(!0);
|
|
1436
|
+
}, [ revealed, settled, stalled ]), revealed || settled || stalled;
|
|
1006
1437
|
}
|
|
1007
1438
|
|
|
1008
1439
|
function spawnOrigins(instances) {
|
|
@@ -1015,16 +1446,11 @@ function spawnOrigins(instances) {
|
|
|
1015
1446
|
return origins;
|
|
1016
1447
|
}
|
|
1017
1448
|
|
|
1018
|
-
function rootOf(instance, byId) {
|
|
1019
|
-
const rootRef = instance.ancestors[0];
|
|
1020
|
-
return rootRef ? byId.get(workflowEngine.toBareId(rootRef.id)) ?? instance : instance;
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
1449
|
function taskRowsOf(args) {
|
|
1024
1450
|
const {instance: instance, identity: identity} = args, open = workflowEngine.findOpenStageEntry(instance);
|
|
1025
1451
|
if (!open) return [];
|
|
1026
1452
|
const definition = index.definitionSnapshotOf(instance), state = index.stateByActivity(instance), rows = (open.activities ?? []).map(activity => {
|
|
1027
|
-
const fields = state.get(activity.name) ?? [], declared =
|
|
1453
|
+
const fields = state.get(activity.name) ?? [], declared = workflowEngine.findActivityNode({
|
|
1028
1454
|
definition: definition,
|
|
1029
1455
|
stageName: open.name,
|
|
1030
1456
|
activityName: activity.name
|
|
@@ -1049,6 +1475,10 @@ function taskRowsOf(args) {
|
|
|
1049
1475
|
state: fields,
|
|
1050
1476
|
who: identity
|
|
1051
1477
|
}),
|
|
1478
|
+
roleMatched: identity !== void 0 && index.isRoleAssignedTo({
|
|
1479
|
+
state: fields,
|
|
1480
|
+
who: identity
|
|
1481
|
+
}),
|
|
1052
1482
|
assignControl: index.rowAssignControlState(controlArgs),
|
|
1053
1483
|
dateControl: index.rowDateControlState(controlArgs)
|
|
1054
1484
|
};
|
|
@@ -1075,7 +1505,7 @@ function deriveTaskGroups(args) {
|
|
|
1075
1505
|
activityName: origin.activityName
|
|
1076
1506
|
}).title : void 0,
|
|
1077
1507
|
rows: rows
|
|
1078
|
-
}, root =
|
|
1508
|
+
}, root = rootInstanceOf(instance, byId), documents = documentRefsOf(root), document2 = documents[0];
|
|
1079
1509
|
if (!document2) {
|
|
1080
1510
|
withoutDocuments.push(entry);
|
|
1081
1511
|
continue;
|
|
@@ -1131,6 +1561,11 @@ function onlyMyTasks(groups) {
|
|
|
1131
1561
|
});
|
|
1132
1562
|
}
|
|
1133
1563
|
|
|
1564
|
+
function hasRoleMatchedTasks(groups) {
|
|
1565
|
+
const bandHasOne = band => band.rows.some(row => row.roleMatched);
|
|
1566
|
+
return groups.withDocuments.some(group => group.instances.some(bandHasOne)) || groups.withoutDocuments.some(bandHasOne);
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1134
1569
|
function rowActivityEval(entry, row) {
|
|
1135
1570
|
const evaluation = entry?.evaluation;
|
|
1136
1571
|
if (!(evaluation === void 0 || evaluation.currentStage.stage.name !== row.stage)) return evaluation.currentStage.activities.find(a => a.activity.name === row.activityName);
|
|
@@ -1274,7 +1709,7 @@ function OrphanedWorkflowsNote({orphans: orphans}) {
|
|
|
1274
1709
|
/* @__PURE__ */
|
|
1275
1710
|
return jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
1276
1711
|
children: [
|
|
1277
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.
|
|
1712
|
+
/* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
|
|
1278
1713
|
action: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
1279
1714
|
fontSize: 1,
|
|
1280
1715
|
mode: "ghost",
|
|
@@ -1376,72 +1811,6 @@ function SettleOrphansDialog({workflows: workflows, onClose: onClose}) {
|
|
|
1376
1811
|
});
|
|
1377
1812
|
}
|
|
1378
1813
|
|
|
1379
|
-
const NO_TITLES = {
|
|
1380
|
-
titles: /* @__PURE__ */ new Map,
|
|
1381
|
-
resolved: /* @__PURE__ */ new Set
|
|
1382
|
-
};
|
|
1383
|
-
|
|
1384
|
-
function useDocPreviewTitles(documents) {
|
|
1385
|
-
const previewStore = sanity.useDocumentPreviewStore(), schema = sanity.useSchema(), {perspectiveStack: perspectiveStack} = sanity.usePerspective(), {actualTypes: actualTypes, binding: binding} = index.useWorkflowContext(), [state, setState] = react.useState(NO_TITLES), key = documents.map(doc => doc.id).join("|");
|
|
1386
|
-
return react.useEffect(() => {
|
|
1387
|
-
const titles = /* @__PURE__ */ new Map, resolved = /* @__PURE__ */ new Set, previews = /* @__PURE__ */ new Map, publish = () => setState({
|
|
1388
|
-
titles: new Map(titles),
|
|
1389
|
-
resolved: new Set(resolved)
|
|
1390
|
-
}), localDocs = documents.flatMap(doc => {
|
|
1391
|
-
const {parsed: parsed, local: local} = index.gdrLocality(doc.id, binding.contentResource);
|
|
1392
|
-
return !parsed || !local ? (resolved.add(doc.id), []) : [ {
|
|
1393
|
-
doc: doc,
|
|
1394
|
-
bareId: parsed.documentId
|
|
1395
|
-
} ];
|
|
1396
|
-
}), untracks = localDocs.map(({bareId: bareId}) => actualTypes.track(bareId)), dropPreview = docId => {
|
|
1397
|
-
previews.get(docId)?.unsubscribe(), previews.delete(docId), titles.delete(docId);
|
|
1398
|
-
}, observe = ({docId: docId, bareId: bareId, typeName: typeName}) => {
|
|
1399
|
-
const schemaType = index.openableSchemaType(schema, typeName);
|
|
1400
|
-
if (!schemaType) return !1;
|
|
1401
|
-
if (previews.get(docId)?.typeName === typeName) return !0;
|
|
1402
|
-
dropPreview(docId), resolved.delete(docId);
|
|
1403
|
-
const subscription = previewStore.observeForPreview({
|
|
1404
|
-
_id: bareId,
|
|
1405
|
-
_type: schemaType.name
|
|
1406
|
-
}, schemaType, {
|
|
1407
|
-
perspective: perspectiveStack
|
|
1408
|
-
}).subscribe({
|
|
1409
|
-
next: event => {
|
|
1410
|
-
resolved.add(docId);
|
|
1411
|
-
const title = event.snapshot?.title;
|
|
1412
|
-
typeof title == "string" ? titles.set(docId, title) : titles.delete(docId), publish();
|
|
1413
|
-
},
|
|
1414
|
-
error: err => {
|
|
1415
|
-
console.error(`[workflow-studio-plugin] preview for "${docId}" failed:`, err), resolved.add(docId),
|
|
1416
|
-
publish();
|
|
1417
|
-
}
|
|
1418
|
-
});
|
|
1419
|
-
return previews.set(docId, {
|
|
1420
|
-
typeName: typeName,
|
|
1421
|
-
unsubscribe: () => subscription.unsubscribe()
|
|
1422
|
-
}), !0;
|
|
1423
|
-
}, evaluate = () => {
|
|
1424
|
-
for (const {doc: doc, bareId: bareId} of localDocs) {
|
|
1425
|
-
const probe = actualTypes.read(bareId);
|
|
1426
|
-
if (probe === null) {
|
|
1427
|
-
dropPreview(doc.id), resolved.add(doc.id);
|
|
1428
|
-
continue;
|
|
1429
|
-
}
|
|
1430
|
-
!observe({
|
|
1431
|
-
docId: doc.id,
|
|
1432
|
-
bareId: bareId,
|
|
1433
|
-
typeName: probe ?? doc.type
|
|
1434
|
-
}) && typeof probe == "string" && (dropPreview(doc.id), resolved.add(doc.id));
|
|
1435
|
-
}
|
|
1436
|
-
publish();
|
|
1437
|
-
}, unsubscribeProbes = actualTypes.subscribe(evaluate);
|
|
1438
|
-
return evaluate(), () => {
|
|
1439
|
-
unsubscribeProbes(), untracks.forEach(untrack => untrack()), previews.forEach(preview => preview.unsubscribe());
|
|
1440
|
-
};
|
|
1441
|
-
}, [ key, previewStore, schema, actualTypes, binding.contentResource.id, perspectiveStack.join("|") ]),
|
|
1442
|
-
state;
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
1814
|
function taskFilterOptions(groups) {
|
|
1446
1815
|
const workflows = /* @__PURE__ */ new Map, documents = /* @__PURE__ */ new Map;
|
|
1447
1816
|
for (const group of groups.withDocuments) {
|
|
@@ -2610,7 +2979,7 @@ function useOrphanedWorkflows(groups) {
|
|
|
2610
2979
|
}), [ groups, contentResource, missing ]);
|
|
2611
2980
|
}
|
|
2612
2981
|
|
|
2613
|
-
function TasksTab({filterSlot: filterSlot, instances: instances, loading: loading, identity: identity, onOpenInstance: onOpenInstance, onOpenTask: onOpenTask, tab: tab, truncated: truncated, unreadable: unreadable}) {
|
|
2982
|
+
function TasksTab({error: error, filterSlot: filterSlot, instances: instances, loading: loading, identity: identity, onOpenInstance: onOpenInstance, onOpenTask: onOpenTask, tab: tab, truncated: truncated, unreadable: unreadable}) {
|
|
2614
2983
|
const mineOnly = tab === "for-me", {binding: binding} = index.useWorkflowContext(), bands = useBandOpenState({
|
|
2615
2984
|
segment: TASK_BAND_SEGMENTS[tab],
|
|
2616
2985
|
scope: binding.engineResource.id
|
|
@@ -2619,6 +2988,7 @@ function TasksTab({filterSlot: filterSlot, instances: instances, loading: loadin
|
|
|
2619
2988
|
identity: identity
|
|
2620
2989
|
}), [ instances, identity ]), orphans = useOrphanedWorkflows(groups), listed = react.useMemo(() => hideOrphanedGroups(groups, orphans.groupKeys), [ groups, orphans.groupKeys ]), options = react.useMemo(() => taskFilterOptions(listed), [ listed ]), titles = useGroupTitles(listed), revealed = useRevealGate({
|
|
2621
2990
|
loading: loading,
|
|
2991
|
+
progress: titles.resolved.size,
|
|
2622
2992
|
ready: titles.ready
|
|
2623
2993
|
}), visible = react.useMemo(() => {
|
|
2624
2994
|
const filtered = applyTaskFilters({
|
|
@@ -2628,6 +2998,10 @@ function TasksTab({filterSlot: filterSlot, instances: instances, loading: loadin
|
|
|
2628
2998
|
}), cut = mineOnly ? onlyMyTasks(filtered) : filtered;
|
|
2629
2999
|
return orderGroupsByPreviewTitle(cut, titles.titles);
|
|
2630
3000
|
}, [ listed, filters, mineOnly, titles ]);
|
|
3001
|
+
if (error !== void 0) /* @__PURE__ */ return jsxRuntime.jsx(index.NoteBanner, {
|
|
3002
|
+
label: INSTANCES_READ_FAILED,
|
|
3003
|
+
tone: "critical"
|
|
3004
|
+
});
|
|
2631
3005
|
if (loading || !revealed) /* @__PURE__ */
|
|
2632
3006
|
return jsxRuntime.jsx(TabStatusRow, {
|
|
2633
3007
|
children: /* @__PURE__ */ jsxRuntime.jsx(index.LoadingRow, {
|
|
@@ -2667,13 +3041,37 @@ function TasksTab({filterSlot: filterSlot, instances: instances, loading: loadin
|
|
|
2667
3041
|
}),
|
|
2668
3042
|
/* @__PURE__ */ jsxRuntime.jsx(OrphanedWorkflowsNote, {
|
|
2669
3043
|
orphans: orphans
|
|
2670
|
-
}), body, truncated ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
|
|
3044
|
+
}), mineOnly && hasRoleMatchedTasks(visible) ? /* @__PURE__ */ jsxRuntime.jsx(index.RoleAssignedNotice, {}) : null, body, truncated ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
|
|
2671
3045
|
text: `Tasks from the latest ${INSTANCE_CAP} workflows — older ones aren’t listed.`
|
|
2672
3046
|
}) : null ]
|
|
2673
3047
|
}) ]
|
|
2674
3048
|
});
|
|
2675
3049
|
}
|
|
2676
3050
|
|
|
3051
|
+
function cardFacts(args) {
|
|
3052
|
+
return new Map(args.instances.map(instance => [ instance._id, {
|
|
3053
|
+
pending: openActivitiesOf(instance).length,
|
|
3054
|
+
overdue: overdueTaskCount(instance, args.now),
|
|
3055
|
+
stuck: workflowEngine.documentStuckCause({
|
|
3056
|
+
instance: instance,
|
|
3057
|
+
definition: index.definitionSnapshotOf(instance)
|
|
3058
|
+
}) !== void 0,
|
|
3059
|
+
settled: workflowEngine.terminalState(instance) !== "in-flight"
|
|
3060
|
+
} ]));
|
|
3061
|
+
}
|
|
3062
|
+
|
|
3063
|
+
function laneTotals(cards, facts) {
|
|
3064
|
+
let overdue = 0, stuck = 0;
|
|
3065
|
+
for (const card of cards) {
|
|
3066
|
+
const held = facts.get(card.instanceId);
|
|
3067
|
+
held !== void 0 && (held.overdue > 0 && (overdue += 1), held.stuck && (stuck += 1));
|
|
3068
|
+
}
|
|
3069
|
+
return {
|
|
3070
|
+
overdue: overdue,
|
|
3071
|
+
stuck: stuck
|
|
3072
|
+
};
|
|
3073
|
+
}
|
|
3074
|
+
|
|
2677
3075
|
const BOARD_EMPTY_STAGE_NOTE = "No items";
|
|
2678
3076
|
|
|
2679
3077
|
function faceOf(instance) {
|
|
@@ -2732,6 +3130,24 @@ function boardDocuments(board) {
|
|
|
2732
3130
|
return board.groups.flatMap(group => group.cards.flatMap(card => card.face.kind === "document" ? [ card.face.document ] : []));
|
|
2733
3131
|
}
|
|
2734
3132
|
|
|
3133
|
+
function pendingHint(pending) {
|
|
3134
|
+
return pending === 0 ? "All tasks done" : `${pluralize__default.default("task", pending, !0)} still open`;
|
|
3135
|
+
}
|
|
3136
|
+
|
|
3137
|
+
function overdueTasksHint(overdue) {
|
|
3138
|
+
return `${pluralize__default.default("task", overdue, !0)} past ${overdue === 1 ? "its" : "their"} due date`;
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
const STUCK_RUN_HINT = "This run can’t continue without help";
|
|
3142
|
+
|
|
3143
|
+
function laneOverdueHint(overdue) {
|
|
3144
|
+
return `${overdue} of these ${overdue === 1 ? "has" : "have"} overdue tasks`;
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3147
|
+
function laneStuckHint(stuck) {
|
|
3148
|
+
return `${stuck} of these can’t continue without help`;
|
|
3149
|
+
}
|
|
3150
|
+
|
|
2735
3151
|
function CardTitleFace({title: title}) {
|
|
2736
3152
|
return title.kind === "title" ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
2737
3153
|
children: title.title
|
|
@@ -2758,23 +3174,10 @@ function cardTitle(args) {
|
|
|
2758
3174
|
};
|
|
2759
3175
|
}
|
|
2760
3176
|
|
|
2761
|
-
function ownOpenTasks(instance) {
|
|
2762
|
-
const open = workflowEngine.findOpenStageEntry(instance);
|
|
2763
|
-
return open ? (open.activities ?? []).filter(activity => index.isOpenActivityStatus(activity.status)).length : 0;
|
|
2764
|
-
}
|
|
2765
|
-
|
|
2766
|
-
function pendingTaskCounts(instances) {
|
|
2767
|
-
return new Map(instances.map(instance => [ instance._id, ownOpenTasks(instance) ]));
|
|
2768
|
-
}
|
|
2769
|
-
|
|
2770
|
-
function pendingTasksPhrase(pending) {
|
|
2771
|
-
if (pending !== void 0) return pending === 0 ? "All tasks done" : pluralize__default.default("pending task", pending, !0);
|
|
2772
|
-
}
|
|
2773
|
-
|
|
2774
3177
|
const CARD_RADIUS = 3;
|
|
2775
3178
|
|
|
2776
3179
|
function BoardCard({card: card, wiring: wiring}) {
|
|
2777
|
-
const {
|
|
3180
|
+
const {facts: facts, onSelect: onSelect, selectedInstanceId: selectedInstanceId, titles: titles} = wiring, {color: color} = ui.useTheme_v2(), selected = card.instanceId === selectedInstanceId, held = facts.get(card.instanceId);
|
|
2778
3181
|
/* @__PURE__ */
|
|
2779
3182
|
return jsxRuntime.jsx(ui.Card, {
|
|
2780
3183
|
"aria-pressed": selected,
|
|
@@ -2792,54 +3195,93 @@ function BoardCard({card: card, wiring: wiring}) {
|
|
|
2792
3195
|
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
|
|
2793
3196
|
gap: 3,
|
|
2794
3197
|
children: [
|
|
2795
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
children:
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
3198
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
|
|
3199
|
+
align: "flex-start",
|
|
3200
|
+
gap: 2,
|
|
3201
|
+
children: [
|
|
3202
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
3203
|
+
size: 1,
|
|
3204
|
+
style: {
|
|
3205
|
+
flex: 1,
|
|
3206
|
+
minWidth: 0
|
|
3207
|
+
},
|
|
3208
|
+
weight: "medium",
|
|
3209
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(CardTitleFace, {
|
|
3210
|
+
title: cardTitle({
|
|
3211
|
+
face: card.face,
|
|
3212
|
+
titles: titles
|
|
3213
|
+
})
|
|
2802
3214
|
})
|
|
2803
|
-
})
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
3215
|
+
}), held?.stuck === !0 ? /* @__PURE__ */ jsxRuntime.jsx(index.AlertGlyph, {
|
|
3216
|
+
Icon: ErrorOutline.ErrorOutlineIcon,
|
|
3217
|
+
hint: STUCK_RUN_HINT,
|
|
3218
|
+
tone: "critical"
|
|
3219
|
+
}) : null ]
|
|
3220
|
+
}), held === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(CardMetrics, {
|
|
3221
|
+
facts: held
|
|
2807
3222
|
}) ]
|
|
2808
3223
|
})
|
|
2809
3224
|
});
|
|
2810
3225
|
}
|
|
2811
3226
|
|
|
2812
|
-
function
|
|
2813
|
-
|
|
2814
|
-
return phrase === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
3227
|
+
function CardMetrics({facts: facts}) {
|
|
3228
|
+
return facts.settled ? null : /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
|
|
2815
3229
|
align: "center",
|
|
2816
|
-
|
|
2817
|
-
children:
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
3230
|
+
gap: 3,
|
|
3231
|
+
children: [
|
|
3232
|
+
/* @__PURE__ */ jsxRuntime.jsx(index.MetricPair, {
|
|
3233
|
+
Icon: Empty.EmptyIcon,
|
|
3234
|
+
empty: facts.pending === 0,
|
|
3235
|
+
face: {
|
|
3236
|
+
text: pendingHint(facts.pending)
|
|
3237
|
+
},
|
|
3238
|
+
value: String(facts.pending)
|
|
3239
|
+
}), facts.overdue === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.MetricPair, {
|
|
3240
|
+
Icon: Calendar.CalendarIcon,
|
|
3241
|
+
face: {
|
|
3242
|
+
text: overdueTasksHint(facts.overdue)
|
|
3243
|
+
},
|
|
3244
|
+
tone: "caution",
|
|
3245
|
+
value: String(facts.overdue)
|
|
3246
|
+
}) ]
|
|
2827
3247
|
});
|
|
2828
3248
|
}
|
|
2829
3249
|
|
|
2830
|
-
function StageGroupHeading({group: group}) {
|
|
3250
|
+
function StageGroupHeading({facts: facts, group: group}) {
|
|
3251
|
+
const totals = laneTotals(group.cards, facts);
|
|
2831
3252
|
/* @__PURE__ */
|
|
2832
3253
|
return jsxRuntime.jsxs(ui.Flex, {
|
|
2833
3254
|
align: "center",
|
|
2834
3255
|
gap: 2,
|
|
2835
3256
|
children: [
|
|
2836
|
-
/* @__PURE__ */ jsxRuntime.jsx(index.
|
|
3257
|
+
/* @__PURE__ */ jsxRuntime.jsx(index.CountedHeading, {
|
|
2837
3258
|
count: group.cards.length,
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
3259
|
+
title: group.title
|
|
3260
|
+
}), totals.overdue === 0 && totals.stuck === 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
3261
|
+
children: [
|
|
3262
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
3263
|
+
flex: 1
|
|
3264
|
+
}),
|
|
3265
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
|
|
3266
|
+
align: "center",
|
|
3267
|
+
flex: "none",
|
|
3268
|
+
gap: 3,
|
|
3269
|
+
children: [ totals.overdue === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.MetricPair, {
|
|
3270
|
+
Icon: Calendar.CalendarIcon,
|
|
3271
|
+
face: {
|
|
3272
|
+
text: laneOverdueHint(totals.overdue)
|
|
3273
|
+
},
|
|
3274
|
+
tone: "caution",
|
|
3275
|
+
value: String(totals.overdue)
|
|
3276
|
+
}), totals.stuck === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.MetricPair, {
|
|
3277
|
+
Icon: ErrorOutline.ErrorOutlineIcon,
|
|
3278
|
+
face: {
|
|
3279
|
+
text: laneStuckHint(totals.stuck)
|
|
3280
|
+
},
|
|
3281
|
+
tone: "critical",
|
|
3282
|
+
value: String(totals.stuck)
|
|
3283
|
+
}) ]
|
|
3284
|
+
}) ]
|
|
2843
3285
|
}), group.retired ?
|
|
2844
3286
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
2845
3287
|
muted: !0,
|
|
@@ -2888,6 +3330,7 @@ function StageColumn({group: group, leadingRule: leadingRule, trailingRule: trai
|
|
|
2888
3330
|
paddingTop: 4,
|
|
2889
3331
|
paddingX: LANE_PADDING,
|
|
2890
3332
|
children: /* @__PURE__ */ jsxRuntime.jsx(StageGroupHeading, {
|
|
3333
|
+
facts: wiring.facts,
|
|
2891
3334
|
group: group
|
|
2892
3335
|
})
|
|
2893
3336
|
}), group.cards.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
@@ -3028,7 +3471,7 @@ function useBoard(args) {
|
|
|
3028
3471
|
}), {titles: titles, ready: ready} = seeded, board = react.useMemo(() => derived ? orderBoardByPreviewTitle(derived, titles) : void 0, [ derived, titles ]);
|
|
3029
3472
|
return react.useMemo(() => ({
|
|
3030
3473
|
board: board,
|
|
3031
|
-
ready: ready,
|
|
3474
|
+
ready: board !== void 0 && ready,
|
|
3032
3475
|
titles: seeded
|
|
3033
3476
|
}), [ board, ready, seeded ]);
|
|
3034
3477
|
}
|
|
@@ -3045,6 +3488,16 @@ function useBoardInstances(definitionName) {
|
|
|
3045
3488
|
return useCappedInstances(filter);
|
|
3046
3489
|
}
|
|
3047
3490
|
|
|
3491
|
+
function activeCountFace(args) {
|
|
3492
|
+
return args.error !== void 0 || args.loading ? {
|
|
3493
|
+
count: void 0,
|
|
3494
|
+
note: void 0
|
|
3495
|
+
} : {
|
|
3496
|
+
count: args.count,
|
|
3497
|
+
note: args.truncated ? INSTANCE_CAP_COUNT_NOTE : void 0
|
|
3498
|
+
};
|
|
3499
|
+
}
|
|
3500
|
+
|
|
3048
3501
|
function DefinitionPanel({definition: definition}) {
|
|
3049
3502
|
/* @__PURE__ */
|
|
3050
3503
|
return jsxRuntime.jsx(ui.Box, {
|
|
@@ -3107,12 +3560,31 @@ function SetupIssues({bindings: bindings}) {
|
|
|
3107
3560
|
});
|
|
3108
3561
|
}
|
|
3109
3562
|
|
|
3563
|
+
function ActiveCount({face: face}) {
|
|
3564
|
+
/* @__PURE__ */
|
|
3565
|
+
return jsxRuntime.jsxs(ui.Stack, {
|
|
3566
|
+
gap: 2,
|
|
3567
|
+
children: [
|
|
3568
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
3569
|
+
muted: face.count === void 0,
|
|
3570
|
+
size: 1,
|
|
3571
|
+
children: face.count ?? "—"
|
|
3572
|
+
}), face.note === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
3573
|
+
muted: !0,
|
|
3574
|
+
size: 1,
|
|
3575
|
+
children: face.note
|
|
3576
|
+
}) ]
|
|
3577
|
+
});
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3110
3580
|
function DefinitionFacts({definition: definition}) {
|
|
3111
|
-
const {mappingIssues: mappingIssues, mappings: mappings} = index.useWorkflowContext(), schema = sanity.useSchema(), instances = useToolInstances(), snapshotWidth = index.useContainerToken(2), [row] = definitionCatalog({
|
|
3581
|
+
const {mappingIssues: mappingIssues, mappings: mappings} = index.useWorkflowContext(), schema = sanity.useSchema(), instances = useToolInstances(), now = index.useMinuteClock(), snapshotWidth = index.useContainerToken(2), [row] = definitionCatalog({
|
|
3112
3582
|
definitions: [ definition ],
|
|
3583
|
+
identity: void 0,
|
|
3113
3584
|
mappings: mappings,
|
|
3114
|
-
|
|
3115
|
-
issues: mappingIssues
|
|
3585
|
+
instances: [ ...instances.inFlight, ...instances.settled ],
|
|
3586
|
+
issues: mappingIssues,
|
|
3587
|
+
now: now
|
|
3116
3588
|
}), runsOn = docTypeLabels(row?.docTypes ?? [], name => schema.get(name)?.title).map(docType => docType.title);
|
|
3117
3589
|
/* @__PURE__ */
|
|
3118
3590
|
return jsxRuntime.jsxs(ui.Flex, {
|
|
@@ -3124,6 +3596,12 @@ function DefinitionFacts({definition: definition}) {
|
|
|
3124
3596
|
children: /* @__PURE__ */ jsxRuntime.jsx(SetupIssues, {
|
|
3125
3597
|
bindings: row.brokenBindings
|
|
3126
3598
|
})
|
|
3599
|
+
}), instances.error === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
3600
|
+
flex: "none",
|
|
3601
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
|
|
3602
|
+
label: INSTANCES_READ_FAILED,
|
|
3603
|
+
tone: "critical"
|
|
3604
|
+
})
|
|
3127
3605
|
}),
|
|
3128
3606
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
3129
3607
|
flex: "none",
|
|
@@ -3142,21 +3620,13 @@ function DefinitionFacts({definition: definition}) {
|
|
|
3142
3620
|
}),
|
|
3143
3621
|
/* @__PURE__ */ jsxRuntime.jsx(index.MetaRow, {
|
|
3144
3622
|
label: "Active instances",
|
|
3145
|
-
children:
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
3153
|
-
size: 1,
|
|
3154
|
-
children: row?.activeCount ?? 0
|
|
3155
|
-
}), instances.truncated ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
3156
|
-
muted: !0,
|
|
3157
|
-
size: 1,
|
|
3158
|
-
children: INSTANCE_CAP_COUNT_NOTE
|
|
3159
|
-
}) : null ]
|
|
3623
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ActiveCount, {
|
|
3624
|
+
face: activeCountFace({
|
|
3625
|
+
count: row?.signals.activeCount ?? 0,
|
|
3626
|
+
error: instances.error,
|
|
3627
|
+
loading: instances.loading,
|
|
3628
|
+
truncated: instances.truncated
|
|
3629
|
+
})
|
|
3160
3630
|
})
|
|
3161
3631
|
}),
|
|
3162
3632
|
/* @__PURE__ */ jsxRuntime.jsx(index.MetaRow, {
|
|
@@ -3220,7 +3690,7 @@ function pickerLabel(face) {
|
|
|
3220
3690
|
}
|
|
3221
3691
|
|
|
3222
3692
|
function WorkflowPicker({face: face, onSelect: onSelect, options: options}) {
|
|
3223
|
-
const empty = options.length === 0;
|
|
3693
|
+
const empty = options.length === 0, reclaimed = -index.useSpaceToken(TOOL_HEADING_PADDING);
|
|
3224
3694
|
/* @__PURE__ */
|
|
3225
3695
|
return jsxRuntime.jsx(ui.MenuButton, {
|
|
3226
3696
|
button: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
@@ -3230,6 +3700,9 @@ function WorkflowPicker({face: face, onSelect: onSelect, options: options}) {
|
|
|
3230
3700
|
iconRight: ChevronDown.ChevronDownIcon,
|
|
3231
3701
|
mode: "bleed",
|
|
3232
3702
|
padding: TOOL_HEADING_PADDING,
|
|
3703
|
+
style: {
|
|
3704
|
+
margin: reclaimed
|
|
3705
|
+
},
|
|
3233
3706
|
text: pickerLabel(face),
|
|
3234
3707
|
textWeight: "semibold"
|
|
3235
3708
|
}),
|
|
@@ -3260,6 +3733,7 @@ function WorkflowPageHeader({face: face, onSelectPage: onSelectPage, onSelectWor
|
|
|
3260
3733
|
children: [
|
|
3261
3734
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
3262
3735
|
align: "center",
|
|
3736
|
+
padding: TOOL_HEADING_PADDING,
|
|
3263
3737
|
children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowPicker, {
|
|
3264
3738
|
face: face,
|
|
3265
3739
|
onSelect: onSelectWorkflow,
|
|
@@ -3693,30 +4167,38 @@ function usePageSelection(page) {
|
|
|
3693
4167
|
}
|
|
3694
4168
|
|
|
3695
4169
|
function WorkflowPage({onOpenWorkflow: onOpenWorkflow, onSelectPage: onSelectPage, page: page, workflowName: workflowName}) {
|
|
3696
|
-
const {definitions: definitions, error:
|
|
4170
|
+
const {definitions: definitions, error: catalogError} = useDeployedDefinitions(), selection = resolveWorkflowSelection({
|
|
3697
4171
|
definitions: definitions,
|
|
3698
4172
|
routeName: workflowName
|
|
3699
4173
|
}), selected = resolvedDefinition(selection), view = workflowPageView({
|
|
3700
|
-
error:
|
|
4174
|
+
error: catalogError,
|
|
3701
4175
|
page: page,
|
|
3702
4176
|
selection: selection
|
|
3703
4177
|
}), instances = useBoardInstances(view.streamName), {board: board, ready: ready, titles: titles} = useBoard({
|
|
3704
4178
|
definition: selected,
|
|
3705
4179
|
instances: instances.rows
|
|
3706
|
-
}), {select: select, selectedInstanceId: selectedInstanceId} = usePageSelection(page), panel = usePanelPresence(panelSubject({
|
|
4180
|
+
}), {select: select, selectedInstanceId: selectedInstanceId} = usePageSelection(page), now = index.useMinuteClock(), panel = usePanelPresence(panelSubject({
|
|
3707
4181
|
board: board,
|
|
3708
4182
|
selectedInstanceId: selectedInstanceId
|
|
3709
4183
|
})), revealed = useRevealGate({
|
|
3710
4184
|
loading: instances.loading,
|
|
4185
|
+
progress: titles.resolved.size,
|
|
3711
4186
|
ready: ready
|
|
3712
|
-
})
|
|
4187
|
+
});
|
|
3713
4188
|
if (selection.kind === "loading") /* @__PURE__ */ return jsxRuntime.jsx(UnresolvedPage, {
|
|
3714
|
-
error:
|
|
3715
|
-
|
|
4189
|
+
error: catalogError
|
|
4190
|
+
});
|
|
4191
|
+
const catalogEmpty = (definitions ?? []).length === 0;
|
|
4192
|
+
if (selection.kind === "unknown" && catalogEmpty) /* @__PURE__ */
|
|
4193
|
+
return jsxRuntime.jsx(EmptyCatalogPage, {
|
|
4194
|
+
name: selection.name
|
|
3716
4195
|
});
|
|
3717
4196
|
const wiring = {
|
|
3718
4197
|
onSelect: select,
|
|
3719
|
-
|
|
4198
|
+
facts: cardFacts({
|
|
4199
|
+
instances: instances.rows,
|
|
4200
|
+
now: now
|
|
4201
|
+
}),
|
|
3720
4202
|
selectedInstanceId: selectedInstanceId,
|
|
3721
4203
|
titles: titles
|
|
3722
4204
|
};
|
|
@@ -3769,8 +4251,9 @@ function WorkflowPage({onOpenWorkflow: onOpenWorkflow, onSelectPage: onSelectPag
|
|
|
3769
4251
|
}),
|
|
3770
4252
|
/* @__PURE__ */ jsxRuntime.jsx(PageBody, {
|
|
3771
4253
|
board: board,
|
|
3772
|
-
catalogEmpty:
|
|
3773
|
-
|
|
4254
|
+
catalogEmpty: catalogEmpty,
|
|
4255
|
+
catalogError: catalogError,
|
|
4256
|
+
instancesError: instances.error,
|
|
3774
4257
|
loading: !revealed,
|
|
3775
4258
|
page: page,
|
|
3776
4259
|
selection: selection,
|
|
@@ -3798,45 +4281,66 @@ function WorkflowPage({onOpenWorkflow: onOpenWorkflow, onSelectPage: onSelectPag
|
|
|
3798
4281
|
});
|
|
3799
4282
|
}
|
|
3800
4283
|
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
function UnresolvedPage({error: error, waiting: waiting}) {
|
|
4284
|
+
function UnresolvedPage({error: error}) {
|
|
3804
4285
|
/* @__PURE__ */
|
|
3805
4286
|
return jsxRuntime.jsx(ui.Flex, {
|
|
3806
4287
|
direction: "column",
|
|
3807
4288
|
height: "fill",
|
|
3808
4289
|
overflow: "hidden",
|
|
3809
|
-
children: error === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(WaitingFace, {
|
|
3810
|
-
|
|
3811
|
-
}) : /* @__PURE__ */ jsxRuntime.jsx(CatalogErrorFace, {
|
|
3812
|
-
error: error
|
|
4290
|
+
children: error === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(WaitingFace, {}) : /* @__PURE__ */ jsxRuntime.jsx(ReadErrorFace, {
|
|
4291
|
+
text: CATALOG_READ_FAILED
|
|
3813
4292
|
})
|
|
3814
4293
|
});
|
|
3815
4294
|
}
|
|
3816
4295
|
|
|
3817
|
-
function WaitingFace(
|
|
4296
|
+
function WaitingFace() {
|
|
3818
4297
|
/* @__PURE__ */
|
|
3819
4298
|
return jsxRuntime.jsx(StatusBox, {
|
|
3820
|
-
children:
|
|
4299
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(TabStatusRow, {
|
|
3821
4300
|
children: /* @__PURE__ */ jsxRuntime.jsx(index.LoadingRow, {
|
|
3822
4301
|
label: "Loading workflow…"
|
|
3823
4302
|
})
|
|
3824
|
-
})
|
|
4303
|
+
})
|
|
4304
|
+
});
|
|
4305
|
+
}
|
|
4306
|
+
|
|
4307
|
+
function EmptyCatalogPage({name: name}) {
|
|
4308
|
+
const face = unknownWorkflowFace({
|
|
4309
|
+
catalogEmpty: !0,
|
|
4310
|
+
name: name
|
|
4311
|
+
});
|
|
4312
|
+
/* @__PURE__ */
|
|
4313
|
+
return jsxRuntime.jsx(ui.Flex, {
|
|
4314
|
+
direction: "column",
|
|
4315
|
+
height: "fill",
|
|
4316
|
+
overflow: "hidden",
|
|
4317
|
+
padding: LANE_PADDING,
|
|
4318
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(index.EmptyState, {
|
|
4319
|
+
description: face.description,
|
|
4320
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Search.SearchIcon, {}),
|
|
4321
|
+
title: face.title
|
|
4322
|
+
})
|
|
3825
4323
|
});
|
|
3826
4324
|
}
|
|
3827
4325
|
|
|
3828
|
-
|
|
4326
|
+
const BANNER_LANE_INSET = 2;
|
|
4327
|
+
|
|
4328
|
+
function ReadErrorFace({text: text}) {
|
|
3829
4329
|
/* @__PURE__ */
|
|
3830
4330
|
return jsxRuntime.jsx(StatusBox, {
|
|
3831
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3832
|
-
|
|
4331
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
4332
|
+
paddingTop: BANNER_LANE_INSET,
|
|
4333
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
|
|
4334
|
+
label: text,
|
|
4335
|
+
tone: "critical"
|
|
4336
|
+
})
|
|
3833
4337
|
})
|
|
3834
4338
|
});
|
|
3835
4339
|
}
|
|
3836
4340
|
|
|
3837
|
-
function PageBody({board: board, catalogEmpty: catalogEmpty,
|
|
3838
|
-
if (
|
|
3839
|
-
|
|
4341
|
+
function PageBody({board: board, catalogEmpty: catalogEmpty, catalogError: catalogError, instancesError: instancesError, loading: loading, page: page, selection: selection, wiring: wiring}) {
|
|
4342
|
+
if (catalogError !== void 0) /* @__PURE__ */ return jsxRuntime.jsx(ReadErrorFace, {
|
|
4343
|
+
text: CATALOG_READ_FAILED
|
|
3840
4344
|
});
|
|
3841
4345
|
if (selection.kind === "unknown") {
|
|
3842
4346
|
const face = unknownWorkflowFace({
|
|
@@ -3854,6 +4358,8 @@ function PageBody({board: board, catalogEmpty: catalogEmpty, error: error, loadi
|
|
|
3854
4358
|
}
|
|
3855
4359
|
return page === "definition" ? /* @__PURE__ */ jsxRuntime.jsx(DefinitionPanel, {
|
|
3856
4360
|
definition: selection.definition
|
|
4361
|
+
}) : instancesError !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ReadErrorFace, {
|
|
4362
|
+
text: INSTANCES_READ_FAILED
|
|
3857
4363
|
}) : loading || board === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(StatusBox, {
|
|
3858
4364
|
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
3859
4365
|
paddingTop: LANE_PADDING,
|
|
@@ -4018,10 +4524,12 @@ function WorkflowsHome({filterSlot: filterSlot, onOpenInstance: onOpenInstance,
|
|
|
4018
4524
|
|
|
4019
4525
|
function HomePanel({filterSlot: filterSlot, identity: identity, instances: instances, onOpenInstance: onOpenInstance, onOpenTask: onOpenTask, onOpenWorkflow: onOpenWorkflow, tab: tab}) {
|
|
4020
4526
|
return tab === "overview" ? /* @__PURE__ */ jsxRuntime.jsx(OverviewTab, {
|
|
4527
|
+
identity: identity,
|
|
4021
4528
|
onOpenWorkflow: onOpenWorkflow
|
|
4022
4529
|
}) : /* @__PURE__ */ jsxRuntime.jsx(TasksTab, {
|
|
4530
|
+
error: instances.error,
|
|
4023
4531
|
filterSlot: filterSlot,
|
|
4024
|
-
identity: identity,
|
|
4532
|
+
identity: index.identityOf(identity),
|
|
4025
4533
|
instances: [ ...instances.inFlight, ...instances.settled ],
|
|
4026
4534
|
loading: instances.loading,
|
|
4027
4535
|
onOpenInstance: onOpenInstance,
|