@sanity/workflow-studio-plugin 0.5.0 → 0.20.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 +120 -0
- package/README.md +36 -62
- package/dist/_chunks-cjs/index.cjs +471 -248
- package/dist/_chunks-cjs/workflows-tool-root.cjs +47 -36
- package/dist/_chunks-es/index.js +475 -248
- package/dist/_chunks-es/workflows-tool-root.js +49 -38
- package/dist/index.cjs +0 -6
- package/dist/index.d.cts +16 -74
- package/dist/index.d.ts +16 -74
- package/dist/index.js +2 -2
- package/package.json +14 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var jsxRuntime = require("react/jsx-runtime"), Timeline = require("@sanity/icons/Timeline"), ui = require("@sanity/ui"), react = require("react"), structure = require("sanity/structure"), workflowEngine = require("@sanity/workflow-engine"), Checkmark = require("@sanity/icons/Checkmark"), Close = require("@sanity/icons/Close"), formatDistanceToNow = require("date-fns/formatDistanceToNow"), csm = require("@sanity/client/csm"), workflowStudio = require("@sanity/workflow-studio"), sanity = require("sanity"), Calendar = require("@sanity/icons/Calendar"), workflowComponents = require("@sanity/workflow-components"), User = require("@sanity/icons/User"), Search = require("@sanity/icons/Search"), ChevronRight = require("@sanity/icons/ChevronRight"), Edit = require("@sanity/icons/Edit"), content = require("@sanity/util/content"), InfoOutline = require("@sanity/icons/InfoOutline"), Document = require("@sanity/icons/Document"), WarningOutline = require("@sanity/icons/WarningOutline"), router = require("sanity/router"), types = require("@sanity/types"), Launch = require("@sanity/icons/Launch"), Empty$1 = require("@sanity/icons/Empty"), ErrorFilled = require("@sanity/icons/ErrorFilled"), RemoveCircle = require("@sanity/icons/RemoveCircle"), Add = require("@sanity/icons/Add"), Bolt = require("@sanity/icons/Bolt"), ChevronDown = require("@sanity/icons/ChevronDown"), CheckmarkCircle = require("@sanity/icons/CheckmarkCircle"), Ulist = require("@sanity/icons/Ulist"), pluralize = require("pluralize-esm"), EllipsisHorizontal = require("@sanity/icons/EllipsisHorizontal"), ArrowUp = require("@sanity/icons/ArrowUp"), workflowReact = require("@sanity/workflow-react"), Transfer = require("@sanity/icons/Transfer");
|
|
4
4
|
|
|
5
5
|
function _interopDefaultCompat(e) {
|
|
6
6
|
return e && typeof e == "object" && "default" in e ? e : {
|
|
@@ -23,20 +23,58 @@ function gdrLocality(id, contentResource) {
|
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
function
|
|
27
|
-
|
|
26
|
+
function assertUniqueWorkflowMappings(mappings) {
|
|
27
|
+
const keys = /* @__PURE__ */ new Set;
|
|
28
|
+
for (const mapping of mappings) {
|
|
29
|
+
const key = mappingKey(mapping);
|
|
30
|
+
if (keys.has(key)) throw new Error(`Duplicate workflow mapping for ${key}`);
|
|
31
|
+
keys.add(key);
|
|
32
|
+
}
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
function
|
|
31
|
-
|
|
35
|
+
function discoverWorkflowMappings(args) {
|
|
36
|
+
assertUniqueWorkflowMappings(args.overrides ?? []);
|
|
37
|
+
const discovered = workflowEngine.latestDeployedDefinitions(args.definitions).flatMap(definition => {
|
|
38
|
+
if (!workflowEngine.isStartableDefinition(definition)) return [];
|
|
39
|
+
const subject = (definition.fields ?? []).find(workflowEngine.isSubjectEntry);
|
|
40
|
+
if (subject === void 0 || !workflowEngine.isInputSourced(subject)) return [];
|
|
41
|
+
const source = {
|
|
42
|
+
fields: [ ...definition.fields ?? [] ]
|
|
43
|
+
};
|
|
44
|
+
return [ ...args.schemaContentTypes ].filter(docType => workflowEngine.acceptsDocumentType(source, docType)).map(docType => ({
|
|
45
|
+
docType: docType,
|
|
46
|
+
definition: definition.name,
|
|
47
|
+
label: definition.title ?? definition.name
|
|
48
|
+
}));
|
|
49
|
+
}), byKey = new Map(discovered.map(mapping => [ mappingKey(mapping), mapping ]));
|
|
50
|
+
for (const override of args.overrides ?? []) {
|
|
51
|
+
const key = mappingKey(override);
|
|
52
|
+
byKey.set(key, override);
|
|
53
|
+
}
|
|
54
|
+
return [ ...byKey.values() ];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function mappingAutoStartMap(mappings) {
|
|
58
|
+
const byType = /* @__PURE__ */ Object.create(null);
|
|
59
|
+
for (const mapping of mappings) {
|
|
60
|
+
if (!mapping.autoStart) continue;
|
|
61
|
+
const definitions = byType[mapping.docType] ?? [];
|
|
62
|
+
byType[mapping.docType] = [ ...definitions, mapping.definition ];
|
|
63
|
+
}
|
|
64
|
+
return byType;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function mappingsForDocType(mappings, docType) {
|
|
68
|
+
return mappings.filter(m => m.docType === docType);
|
|
32
69
|
}
|
|
33
70
|
|
|
34
71
|
function mappingKey(mapping) {
|
|
35
72
|
return `${mapping.docType}::${mapping.definition}`;
|
|
36
73
|
}
|
|
37
74
|
|
|
38
|
-
function
|
|
39
|
-
|
|
75
|
+
function documentSubjectEntry(definition) {
|
|
76
|
+
const fields = definition.fields ?? [];
|
|
77
|
+
return fields.find(workflowEngine.isSubjectEntry) ?? fields.find(entry => entry.type === "doc.ref" && entry.name === "subject");
|
|
40
78
|
}
|
|
41
79
|
|
|
42
80
|
function mappingStartBlocks(args) {
|
|
@@ -357,7 +395,7 @@ function stateByActivity(instance) {
|
|
|
357
395
|
}
|
|
358
396
|
|
|
359
397
|
function evaluationFreshness(args) {
|
|
360
|
-
return args.evaluation ? args.committed.lastChangedAt > args.evaluation.instance.lastChangedAt ? "stale" : "current" : "pending";
|
|
398
|
+
return args.evaluation ? Date.parse(args.committed.lastChangedAt) > Date.parse(args.evaluation.instance.lastChangedAt) ? "stale" : "current" : "pending";
|
|
361
399
|
}
|
|
362
400
|
|
|
363
401
|
function isEvaluationCurrent(args) {
|
|
@@ -404,12 +442,27 @@ function useWorkflowContext() {
|
|
|
404
442
|
}
|
|
405
443
|
|
|
406
444
|
function useWorkflowsForDocument(rawId) {
|
|
407
|
-
|
|
445
|
+
return useDocumentWorkflowEntries(rawId, !0);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function useCommittedWorkflowsForDocument(rawId) {
|
|
449
|
+
return useDocumentWorkflowEntries(rawId, !1);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function useDocumentWorkflowEntries(rawId, evaluate) {
|
|
453
|
+
const {register: register, unregister: unregister, requestEvaluation: requestEvaluation, releaseEvaluation: releaseEvaluation, entries: entries} = useWorkflowContext(), docId = rawId ? csm.getPublishedId(rawId) : void 0;
|
|
408
454
|
react.useEffect(() => {
|
|
409
455
|
if (docId) return register(docId), () => unregister(docId);
|
|
410
456
|
}, [ docId, register, unregister ]);
|
|
411
|
-
const list = react.useSyncExternalStore(entries.subscribe, react.useCallback(() => docId ? entries.getDocument(docId) : EMPTY_ENTRIES, [ entries, docId ]));
|
|
412
|
-
return {
|
|
457
|
+
const list = react.useSyncExternalStore(entries.subscribe, react.useCallback(() => docId ? entries.getDocument(docId) : EMPTY_ENTRIES, [ entries, docId ])), evaluationKey = evaluate ? list.map(entry => entry.instance._id).join("\0") : "";
|
|
458
|
+
return react.useEffect(() => {
|
|
459
|
+
if (!evaluate) return;
|
|
460
|
+
const ids = evaluationKey === "" ? [] : evaluationKey.split("\0");
|
|
461
|
+
for (const id of ids) requestEvaluation(id);
|
|
462
|
+
return () => {
|
|
463
|
+
for (const id of ids) releaseEvaluation(id);
|
|
464
|
+
};
|
|
465
|
+
}, [ evaluate, evaluationKey, requestEvaluation, releaseEvaluation ]), {
|
|
413
466
|
docId: docId,
|
|
414
467
|
entries: list
|
|
415
468
|
};
|
|
@@ -420,11 +473,13 @@ function useHeldWorkflowEntry(instanceId) {
|
|
|
420
473
|
return react.useSyncExternalStore(entries.subscribe, react.useCallback(() => instanceId ? entries.getInstance(instanceId) : void 0, [ entries, instanceId ]));
|
|
421
474
|
}
|
|
422
475
|
|
|
423
|
-
function useWorkflowInstanceEntry(instanceId) {
|
|
424
|
-
const {requestInstance: requestInstance, releaseInstance: releaseInstance} = useWorkflowContext();
|
|
476
|
+
function useWorkflowInstanceEntry(instanceId, options = {}) {
|
|
477
|
+
const {requestInstance: requestInstance, releaseInstance: releaseInstance, requestEvaluation: requestEvaluation, releaseEvaluation: releaseEvaluation} = useWorkflowContext(), evaluate = options.evaluate ?? !0;
|
|
425
478
|
return react.useEffect(() => {
|
|
426
479
|
if (instanceId) return requestInstance(instanceId), () => releaseInstance(instanceId);
|
|
427
|
-
}, [ instanceId, requestInstance, releaseInstance ]),
|
|
480
|
+
}, [ instanceId, requestInstance, releaseInstance ]), react.useEffect(() => {
|
|
481
|
+
if (!(!instanceId || !evaluate)) return requestEvaluation(instanceId), () => releaseEvaluation(instanceId);
|
|
482
|
+
}, [ instanceId, evaluate, requestEvaluation, releaseEvaluation ]), useHeldWorkflowEntry(instanceId);
|
|
428
483
|
}
|
|
429
484
|
|
|
430
485
|
const isTodoDone = item => item.status === "done", toggledTodoStatus = item => isTodoDone(item) ? "open" : "done";
|
|
@@ -697,13 +752,29 @@ function concludesHere(actionEval, activityName) {
|
|
|
697
752
|
return changesOwnStatus(actionEval.action, activityName) || actionEval.firing?.exitsStage === !0;
|
|
698
753
|
}
|
|
699
754
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
tone: "
|
|
755
|
+
const SEMANTIC_FACE = {
|
|
756
|
+
"decision.accept": {
|
|
757
|
+
tone: "positive",
|
|
758
|
+
icon: Checkmark.CheckmarkIcon
|
|
759
|
+
},
|
|
760
|
+
"decision.decline": {
|
|
761
|
+
tone: "caution",
|
|
762
|
+
icon: Close.CloseIcon
|
|
763
|
+
}
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
function actionButtonFace(args) {
|
|
767
|
+
const mode = concludesHere(args.actionEval, args.activityName) ? "default" : "ghost";
|
|
768
|
+
if (actionAdvanceStatus(args.actionEval.action, args.activityName) === "failed") return {
|
|
769
|
+
mode: mode,
|
|
770
|
+
tone: "critical",
|
|
771
|
+
icon: void 0
|
|
772
|
+
};
|
|
773
|
+
const [semantic] = args.actionEval.semantics ?? [], face = semantic === void 0 ? void 0 : SEMANTIC_FACE[semantic];
|
|
774
|
+
return {
|
|
775
|
+
mode: mode,
|
|
776
|
+
tone: face?.tone ?? "default",
|
|
777
|
+
icon: face?.icon
|
|
707
778
|
};
|
|
708
779
|
}
|
|
709
780
|
|
|
@@ -958,10 +1029,19 @@ function personActor(user) {
|
|
|
958
1029
|
};
|
|
959
1030
|
}
|
|
960
1031
|
|
|
1032
|
+
const memberIndexes = /* @__PURE__ */ new WeakMap;
|
|
1033
|
+
|
|
1034
|
+
function memberIndex(members) {
|
|
1035
|
+
const cached = memberIndexes.get(members);
|
|
1036
|
+
if (cached) return cached;
|
|
1037
|
+
const created = new Map(members.map(member => [ member.id, member ]));
|
|
1038
|
+
return memberIndexes.set(members, created), created;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
961
1041
|
const selfUserFor = (id, me) => me != null && me.id === id ? me : void 0;
|
|
962
1042
|
|
|
963
1043
|
function userDisplayFor(args) {
|
|
964
|
-
const member = args.members.
|
|
1044
|
+
const member = memberIndex(args.members).get(args.id), self = selfUserFor(args.id, args.me);
|
|
965
1045
|
return {
|
|
966
1046
|
id: args.id,
|
|
967
1047
|
name: member?.displayName ?? self?.name ?? args.id,
|
|
@@ -971,19 +1051,20 @@ function userDisplayFor(args) {
|
|
|
971
1051
|
|
|
972
1052
|
function useUserDisplays(ids) {
|
|
973
1053
|
const {members: members} = useProjectMembers(), me = sanity.useCurrentUser();
|
|
974
|
-
return ids.map(id => userDisplayFor({
|
|
1054
|
+
return react.useMemo(() => ids.map(id => userDisplayFor({
|
|
975
1055
|
id: id,
|
|
976
1056
|
members: members,
|
|
977
1057
|
me: me
|
|
978
|
-
}));
|
|
1058
|
+
})), [ ids, me, members ]);
|
|
979
1059
|
}
|
|
980
1060
|
|
|
981
1061
|
function useUserDisplay(id) {
|
|
982
|
-
const
|
|
983
|
-
return
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1062
|
+
const {members: members} = useProjectMembers(), me = sanity.useCurrentUser();
|
|
1063
|
+
return react.useMemo(() => userDisplayFor({
|
|
1064
|
+
id: id,
|
|
1065
|
+
members: members,
|
|
1066
|
+
me: me
|
|
1067
|
+
}), [ id, me, members ]);
|
|
987
1068
|
}
|
|
988
1069
|
|
|
989
1070
|
function useAssignmentIdentity() {
|
|
@@ -994,8 +1075,12 @@ function useAssignmentIdentity() {
|
|
|
994
1075
|
};
|
|
995
1076
|
}
|
|
996
1077
|
|
|
1078
|
+
const projectMembersByUsers = /* @__PURE__ */ new WeakMap;
|
|
1079
|
+
|
|
997
1080
|
function projectMembersFrom(users) {
|
|
998
|
-
|
|
1081
|
+
const cached = projectMembersByUsers.get(users);
|
|
1082
|
+
if (cached) return cached;
|
|
1083
|
+
const members = users.map(({membership: membership, profile: profile}) => ({
|
|
999
1084
|
id: membership.id,
|
|
1000
1085
|
displayName: profile?.displayName ?? membership.id,
|
|
1001
1086
|
...profile?.email ? {
|
|
@@ -1006,6 +1091,7 @@ function projectMembersFrom(users) {
|
|
|
1006
1091
|
} : {},
|
|
1007
1092
|
roles: (membership.roles ?? []).map(role => role.name)
|
|
1008
1093
|
}));
|
|
1094
|
+
return projectMembersByUsers.set(users, members), members;
|
|
1009
1095
|
}
|
|
1010
1096
|
|
|
1011
1097
|
function useProjectMembers() {
|
|
@@ -1447,7 +1533,7 @@ function DocPicker({value: value, onChange: onChange, types: types2, readOnly: r
|
|
|
1447
1533
|
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
1448
1534
|
flex: 1,
|
|
1449
1535
|
children: /* @__PURE__ */ jsxRuntime.jsx(PreviewOrId, {
|
|
1450
|
-
id: workflowEngine.
|
|
1536
|
+
id: workflowEngine.toBareId(value.id),
|
|
1451
1537
|
type: value.type
|
|
1452
1538
|
})
|
|
1453
1539
|
})
|
|
@@ -1543,7 +1629,7 @@ function DocRefsInput({value: value, onChange: onChange, types: types2}) {
|
|
|
1543
1629
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
1544
1630
|
flex: 1,
|
|
1545
1631
|
children: /* @__PURE__ */ jsxRuntime.jsx(PreviewOrId, {
|
|
1546
|
-
id: workflowEngine.
|
|
1632
|
+
id: workflowEngine.toBareId(ref.id),
|
|
1547
1633
|
type: ref.type
|
|
1548
1634
|
})
|
|
1549
1635
|
}),
|
|
@@ -1697,6 +1783,15 @@ function useFireAction(args) {
|
|
|
1697
1783
|
};
|
|
1698
1784
|
}
|
|
1699
1785
|
|
|
1786
|
+
const ACTION_ICON_GAP = 2;
|
|
1787
|
+
|
|
1788
|
+
function actionIconProps(icon) {
|
|
1789
|
+
return icon ? {
|
|
1790
|
+
gap: ACTION_ICON_GAP,
|
|
1791
|
+
icon: icon
|
|
1792
|
+
} : {};
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1700
1795
|
function stopRowMouseDown(e) {
|
|
1701
1796
|
e.preventDefault(), e.stopPropagation();
|
|
1702
1797
|
}
|
|
@@ -1724,7 +1819,7 @@ function RowClickShield({active: active, children: children}) {
|
|
|
1724
1819
|
});
|
|
1725
1820
|
}
|
|
1726
1821
|
|
|
1727
|
-
function FireButton({instanceId: instanceId, activity: activity, action: action, label: label, mode: mode = "default", chrome: chrome, tone: tone = "default"}) {
|
|
1822
|
+
function FireButton({instanceId: instanceId, activity: activity, action: action, label: label, mode: mode = "default", chrome: chrome, tone: tone = "default", icon: icon}) {
|
|
1728
1823
|
const {fire: fire, pending: pending} = useFireAction({
|
|
1729
1824
|
instanceId: instanceId,
|
|
1730
1825
|
activity: activity,
|
|
@@ -1736,6 +1831,7 @@ function FireButton({instanceId: instanceId, activity: activity, action: action,
|
|
|
1736
1831
|
/* @__PURE__ */
|
|
1737
1832
|
return jsxRuntime.jsx(ui.Button, {
|
|
1738
1833
|
fontSize: 1,
|
|
1834
|
+
...actionIconProps(icon),
|
|
1739
1835
|
loading: pending,
|
|
1740
1836
|
mode: chrome?.mode ?? mode,
|
|
1741
1837
|
onClick: handleClick,
|
|
@@ -1753,6 +1849,7 @@ function ActivityActionRow({actionEval: actionEval, instanceId: instanceId, acti
|
|
|
1753
1849
|
const rowKind = actionRowKind(actionEval);
|
|
1754
1850
|
return rowKind.kind === "disabled" ? /* @__PURE__ */ jsxRuntime.jsx(DisabledActionButton, {
|
|
1755
1851
|
actionEval: actionEval,
|
|
1852
|
+
activity: activity,
|
|
1756
1853
|
chrome: chrome
|
|
1757
1854
|
}) : rowKind.kind === "plain" ? /* @__PURE__ */ jsxRuntime.jsx(PlainActionButton, {
|
|
1758
1855
|
actionEval: actionEval,
|
|
@@ -1767,13 +1864,18 @@ function ActivityActionRow({actionEval: actionEval, instanceId: instanceId, acti
|
|
|
1767
1864
|
});
|
|
1768
1865
|
}
|
|
1769
1866
|
|
|
1770
|
-
function DisabledActionButton({actionEval: actionEval, chrome: chrome}) {
|
|
1771
|
-
const label = actionTriggerLabel(actionEval),
|
|
1867
|
+
function DisabledActionButton({actionEval: actionEval, activity: activity, chrome: chrome}) {
|
|
1868
|
+
const label = actionTriggerLabel(actionEval), {tone: tone, icon: icon} = actionButtonFace({
|
|
1869
|
+
actionEval: actionEval,
|
|
1870
|
+
activityName: activity
|
|
1871
|
+
}), button = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
1772
1872
|
fontSize: 1,
|
|
1873
|
+
...actionIconProps(icon),
|
|
1773
1874
|
mode: chrome?.mode ?? "ghost",
|
|
1774
1875
|
onClick: e => e.stopPropagation(),
|
|
1775
1876
|
padding: 2,
|
|
1776
1877
|
text: label,
|
|
1878
|
+
tone: tone,
|
|
1777
1879
|
...spanTriggerProps(chrome),
|
|
1778
1880
|
disabled: !0
|
|
1779
1881
|
});
|
|
@@ -1784,11 +1886,12 @@ function DisabledActionButton({actionEval: actionEval, chrome: chrome}) {
|
|
|
1784
1886
|
}
|
|
1785
1887
|
|
|
1786
1888
|
function PlainActionButton({actionEval: actionEval, instanceId: instanceId, activity: activity, chrome: chrome}) {
|
|
1787
|
-
const {action: action} = actionEval, label = actionLabel(action), btn =
|
|
1889
|
+
const {action: action} = actionEval, label = actionLabel(action), btn = actionButtonFace({
|
|
1788
1890
|
actionEval: actionEval,
|
|
1789
1891
|
activityName: activity
|
|
1790
1892
|
}), button = /* @__PURE__ */ jsxRuntime.jsx(FireButton, {
|
|
1791
1893
|
action: action.name,
|
|
1894
|
+
icon: btn.icon,
|
|
1792
1895
|
instanceId: instanceId,
|
|
1793
1896
|
label: label,
|
|
1794
1897
|
mode: btn.mode,
|
|
@@ -1863,7 +1966,7 @@ function ParamsActionDialog({actionEval: actionEval, instanceId: instanceId, act
|
|
|
1863
1966
|
}
|
|
1864
1967
|
|
|
1865
1968
|
function ParamsActionButton({actionEval: actionEval, instanceId: instanceId, activity: activity, chrome: chrome}) {
|
|
1866
|
-
const [open, setOpen] = react.useState(!1), btn =
|
|
1969
|
+
const [open, setOpen] = react.useState(!1), btn = actionButtonFace({
|
|
1867
1970
|
actionEval: actionEval,
|
|
1868
1971
|
activityName: activity
|
|
1869
1972
|
});
|
|
@@ -1872,6 +1975,7 @@ function ParamsActionButton({actionEval: actionEval, instanceId: instanceId, act
|
|
|
1872
1975
|
children: [
|
|
1873
1976
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
1874
1977
|
fontSize: 1,
|
|
1978
|
+
...actionIconProps(btn.icon),
|
|
1875
1979
|
mode: chrome?.mode ?? btn.mode,
|
|
1876
1980
|
onClick: e => {
|
|
1877
1981
|
chrome?.inButtonCard === !0 && e.stopPropagation(), setOpen(!0);
|
|
@@ -2697,7 +2801,7 @@ function ReadOnlyDocRefs({entry: entry}) {
|
|
|
2697
2801
|
padding: 2,
|
|
2698
2802
|
radius: 2,
|
|
2699
2803
|
children: /* @__PURE__ */ jsxRuntime.jsx(PreviewOrId, {
|
|
2700
|
-
id: workflowEngine.
|
|
2804
|
+
id: workflowEngine.toBareId(ref.id),
|
|
2701
2805
|
type: ref.type
|
|
2702
2806
|
})
|
|
2703
2807
|
}, ref.id))
|
|
@@ -4061,7 +4165,12 @@ const ACTIONS_MENU_TRIGGER = {
|
|
|
4061
4165
|
};
|
|
4062
4166
|
|
|
4063
4167
|
function ActionMenuItem({actionEval: actionEval, instanceId: instanceId, activity: activity, onCollectParams: onCollectParams}) {
|
|
4064
|
-
const rowKind = actionRowKind(actionEval), label = actionTriggerLabel(actionEval), {
|
|
4168
|
+
const rowKind = actionRowKind(actionEval), label = actionTriggerLabel(actionEval), {tone: tone, icon: icon} = actionButtonFace({
|
|
4169
|
+
actionEval: actionEval,
|
|
4170
|
+
activityName: activity
|
|
4171
|
+
}), iconProp = icon ? {
|
|
4172
|
+
icon: icon
|
|
4173
|
+
} : {}, {fire: fire, pending: pending} = useFireAction({
|
|
4065
4174
|
instanceId: instanceId,
|
|
4066
4175
|
activity: activity,
|
|
4067
4176
|
action: actionEval.action.name,
|
|
@@ -4069,17 +4178,23 @@ function ActionMenuItem({actionEval: actionEval, instanceId: instanceId, activit
|
|
|
4069
4178
|
});
|
|
4070
4179
|
return rowKind.kind === "disabled" ? /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
|
|
4071
4180
|
disabled: !0,
|
|
4072
|
-
|
|
4181
|
+
...iconProp,
|
|
4182
|
+
text: label,
|
|
4183
|
+
tone: tone
|
|
4073
4184
|
}) : rowKind.kind === "plain" ? /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
|
|
4074
4185
|
disabled: pending,
|
|
4186
|
+
...iconProp,
|
|
4075
4187
|
onClick: () => {
|
|
4076
4188
|
fire();
|
|
4077
4189
|
},
|
|
4078
|
-
text: label
|
|
4190
|
+
text: label,
|
|
4191
|
+
tone: tone
|
|
4079
4192
|
}) : /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
|
|
4080
4193
|
disabled: pending,
|
|
4194
|
+
...iconProp,
|
|
4081
4195
|
onClick: onCollectParams,
|
|
4082
|
-
text: label
|
|
4196
|
+
text: label,
|
|
4197
|
+
tone: tone
|
|
4083
4198
|
});
|
|
4084
4199
|
}
|
|
4085
4200
|
|
|
@@ -4192,6 +4307,7 @@ function FittedActions({actions: actions, activity: activity, instanceId: instan
|
|
|
4192
4307
|
children: [
|
|
4193
4308
|
/* @__PURE__ */ jsxRuntime.jsx(MeasureRow, {
|
|
4194
4309
|
actions: actions,
|
|
4310
|
+
activity: activity,
|
|
4195
4311
|
onElement: setMeasureEl
|
|
4196
4312
|
}),
|
|
4197
4313
|
/* @__PURE__ */ jsxRuntime.jsxs(FooterRow, {
|
|
@@ -4211,7 +4327,7 @@ function FittedActions({actions: actions, activity: activity, instanceId: instan
|
|
|
4211
4327
|
});
|
|
4212
4328
|
}
|
|
4213
4329
|
|
|
4214
|
-
function MeasureRow({actions: actions, onElement: onElement}) {
|
|
4330
|
+
function MeasureRow({actions: actions, activity: activity, onElement: onElement}) {
|
|
4215
4331
|
/* @__PURE__ */
|
|
4216
4332
|
return jsxRuntime.jsx("div", {
|
|
4217
4333
|
"aria-hidden": !0,
|
|
@@ -4225,12 +4341,20 @@ function MeasureRow({actions: actions, onElement: onElement}) {
|
|
|
4225
4341
|
display: "inline-flex",
|
|
4226
4342
|
whiteSpace: "nowrap"
|
|
4227
4343
|
},
|
|
4228
|
-
children: [ actions.map(a =>
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4344
|
+
children: [ actions.map(a => {
|
|
4345
|
+
const {icon: icon} = actionButtonFace({
|
|
4346
|
+
actionEval: a,
|
|
4347
|
+
activityName: activity
|
|
4348
|
+
});
|
|
4349
|
+
/* @__PURE__ */
|
|
4350
|
+
return jsxRuntime.jsx(ui.Button, {
|
|
4351
|
+
as: "span",
|
|
4352
|
+
fontSize: 1,
|
|
4353
|
+
...actionIconProps(icon),
|
|
4354
|
+
padding: 2,
|
|
4355
|
+
text: actionTriggerLabel(a)
|
|
4356
|
+
}, a.action.name);
|
|
4357
|
+
}),
|
|
4234
4358
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
4235
4359
|
...ACTIONS_MENU_TRIGGER,
|
|
4236
4360
|
as: "span",
|
|
@@ -4512,7 +4636,26 @@ function CountedLabel({count: count, label: label}) {
|
|
|
4512
4636
|
});
|
|
4513
4637
|
}
|
|
4514
4638
|
|
|
4515
|
-
function
|
|
4639
|
+
function SpinnerSlot({busy: busy, size: size}) {
|
|
4640
|
+
/* @__PURE__ */
|
|
4641
|
+
return jsxRuntime.jsx(ui.Flex, {
|
|
4642
|
+
align: "center",
|
|
4643
|
+
flex: "none",
|
|
4644
|
+
justify: "center",
|
|
4645
|
+
style: {
|
|
4646
|
+
width: 19,
|
|
4647
|
+
height: 19
|
|
4648
|
+
},
|
|
4649
|
+
children: busy ? /* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, {
|
|
4650
|
+
muted: !0,
|
|
4651
|
+
...size !== void 0 ? {
|
|
4652
|
+
size: size
|
|
4653
|
+
} : {}
|
|
4654
|
+
}) : null
|
|
4655
|
+
});
|
|
4656
|
+
}
|
|
4657
|
+
|
|
4658
|
+
function GroupHeading({busy: busy, count: count, title: title, end: end}) {
|
|
4516
4659
|
/* @__PURE__ */
|
|
4517
4660
|
return jsxRuntime.jsxs(ui.Flex, {
|
|
4518
4661
|
align: "center",
|
|
@@ -4527,6 +4670,9 @@ function GroupHeading({count: count, title: title, end: end}) {
|
|
|
4527
4670
|
weight: "semibold",
|
|
4528
4671
|
children: title
|
|
4529
4672
|
})
|
|
4673
|
+
}), busy === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(SpinnerSlot, {
|
|
4674
|
+
busy: busy,
|
|
4675
|
+
size: 1
|
|
4530
4676
|
}), end === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
4531
4677
|
children: [
|
|
4532
4678
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
@@ -4649,6 +4795,18 @@ function TabSwitch({ariaControls: ariaControls, idPrefix: idPrefix, options: opt
|
|
|
4649
4795
|
});
|
|
4650
4796
|
}
|
|
4651
4797
|
|
|
4798
|
+
function useDelayedFlag(active, delayMs) {
|
|
4799
|
+
const [held, setHeld] = react.useState(!1);
|
|
4800
|
+
return react.useEffect(() => {
|
|
4801
|
+
if (!active) {
|
|
4802
|
+
setHeld(!1);
|
|
4803
|
+
return;
|
|
4804
|
+
}
|
|
4805
|
+
const timer = setTimeout(() => setHeld(!0), delayMs);
|
|
4806
|
+
return () => clearTimeout(timer);
|
|
4807
|
+
}, [ active, delayMs ]), held && active;
|
|
4808
|
+
}
|
|
4809
|
+
|
|
4652
4810
|
function instanceTitle(instance, definition) {
|
|
4653
4811
|
return definition?.title ?? instance.definition;
|
|
4654
4812
|
}
|
|
@@ -5487,9 +5645,16 @@ function instanceNotice(entry) {
|
|
|
5487
5645
|
size: 1,
|
|
5488
5646
|
children: "This workflow didn’t finish starting — use Start workflow to continue it"
|
|
5489
5647
|
})
|
|
5490
|
-
}) : pending ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5491
|
-
|
|
5492
|
-
|
|
5648
|
+
}) : pending ? /* @__PURE__ */ jsxRuntime.jsx(WorkRow, {
|
|
5649
|
+
lead: /* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, {
|
|
5650
|
+
muted: !0,
|
|
5651
|
+
size: 1
|
|
5652
|
+
}),
|
|
5653
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
5654
|
+
muted: !0,
|
|
5655
|
+
size: 1,
|
|
5656
|
+
children: "Loading…"
|
|
5657
|
+
})
|
|
5493
5658
|
}) : null;
|
|
5494
5659
|
}
|
|
5495
5660
|
|
|
@@ -6553,20 +6718,7 @@ function InstanceDebugMenu({entry: entry}) {
|
|
|
6553
6718
|
}
|
|
6554
6719
|
|
|
6555
6720
|
function InstanceAccordion({entry: entry, children: children, defaultOpen: defaultOpen}) {
|
|
6556
|
-
const definition = useDefinition(entry), {instance: instance
|
|
6557
|
-
align: "center",
|
|
6558
|
-
gap: 2,
|
|
6559
|
-
style: badgeTrim,
|
|
6560
|
-
children: [
|
|
6561
|
-
/* @__PURE__ */ jsxRuntime.jsx(AbortedBadge, {
|
|
6562
|
-
instance: instance
|
|
6563
|
-
}), settled ? null : /* @__PURE__ */ jsxRuntime.jsx(OlderDefinitionBadge, {
|
|
6564
|
-
instance: instance
|
|
6565
|
-
}), !ready && entry.invalid === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, {
|
|
6566
|
-
muted: !0,
|
|
6567
|
-
size: 1
|
|
6568
|
-
}) : null ]
|
|
6569
|
-
});
|
|
6721
|
+
const definition = useDefinition(entry), {instance: instance} = entry, settled = !isLiveEntry(entry), title = instanceTitle(instance, definition), badgeTrim = useBadgeCapTrim();
|
|
6570
6722
|
/* @__PURE__ */
|
|
6571
6723
|
return jsxRuntime.jsx(CollapsibleBand, {
|
|
6572
6724
|
defaultOpen: defaultOpen ?? !settled,
|
|
@@ -6589,7 +6741,18 @@ function InstanceAccordion({entry: entry, children: children, defaultOpen: defau
|
|
|
6589
6741
|
textOverflow: "ellipsis",
|
|
6590
6742
|
weight: "medium",
|
|
6591
6743
|
children: title
|
|
6592
|
-
}),
|
|
6744
|
+
}),
|
|
6745
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
|
|
6746
|
+
align: "center",
|
|
6747
|
+
gap: 2,
|
|
6748
|
+
style: badgeTrim,
|
|
6749
|
+
children: [
|
|
6750
|
+
/* @__PURE__ */ jsxRuntime.jsx(AbortedBadge, {
|
|
6751
|
+
instance: instance
|
|
6752
|
+
}), settled ? null : /* @__PURE__ */ jsxRuntime.jsx(OlderDefinitionBadge, {
|
|
6753
|
+
instance: instance
|
|
6754
|
+
}) ]
|
|
6755
|
+
}) ]
|
|
6593
6756
|
}),
|
|
6594
6757
|
/* @__PURE__ */ jsxRuntime.jsx(TrailingHairline, {}),
|
|
6595
6758
|
/* @__PURE__ */ jsxRuntime.jsx(InstanceDebugMenu, {
|
|
@@ -6607,7 +6770,7 @@ function InstanceAccordion({entry: entry, children: children, defaultOpen: defau
|
|
|
6607
6770
|
}
|
|
6608
6771
|
|
|
6609
6772
|
function PartOfBand({instance: instance}) {
|
|
6610
|
-
const parentRef = instance.ancestors.at(-1), parentId = parentRef ? workflowEngine.
|
|
6773
|
+
const parentRef = instance.ancestors.at(-1), parentId = parentRef ? workflowEngine.toBareId(parentRef.id) : null, parentEntry = useWorkflowInstanceEntry(parentId), parentDefinition = useDefinition(parentEntry);
|
|
6611
6774
|
if (!parentId) return null;
|
|
6612
6775
|
const title = parentEntry ? instanceTitle(parentEntry.instance, parentDefinition) : parentId;
|
|
6613
6776
|
/* @__PURE__ */
|
|
@@ -7164,11 +7327,9 @@ const VIEW_TAB_CODEC = workflowsTabCodec([ "overview", "for-me" ]), WorkflowsVie
|
|
|
7164
7327
|
};
|
|
7165
7328
|
|
|
7166
7329
|
function DiscoverySpinner() {
|
|
7167
|
-
const
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
return () => clearTimeout(timer);
|
|
7171
|
-
}, []), /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
7330
|
+
const visible = useDelayedFlag(!0, 1e3);
|
|
7331
|
+
/* @__PURE__ */
|
|
7332
|
+
return jsxRuntime.jsx(ui.Flex, {
|
|
7172
7333
|
align: "center",
|
|
7173
7334
|
height: "fill",
|
|
7174
7335
|
justify: "center",
|
|
@@ -7178,7 +7339,7 @@ function DiscoverySpinner() {
|
|
|
7178
7339
|
});
|
|
7179
7340
|
}
|
|
7180
7341
|
|
|
7181
|
-
const GROUP_GAP = 1;
|
|
7342
|
+
const BOOT_CUE_DELAY_MS = 400, GROUP_GAP = 1;
|
|
7182
7343
|
|
|
7183
7344
|
function useWorkflowsTab() {
|
|
7184
7345
|
const {params: params, setParams: setParams} = structure.usePaneRouter();
|
|
@@ -7203,7 +7364,7 @@ function useOpenActivity(entries) {
|
|
|
7203
7364
|
}
|
|
7204
7365
|
|
|
7205
7366
|
function WorkflowsPanel({entries: entries, documentId: documentId, docTypeMappings: docTypeMappings, initialValue: initialValue}) {
|
|
7206
|
-
const identity = useAssignmentIdentity(), panelId = react.useId(), {params: params} = structure.usePaneRouter(), {view: view, setView: setView} = useWorkflowsTab(), {openActivity: openActivity, setOpenActivity: setOpenActivity, dialogEntry: dialogEntry} = useOpenActivity(entries), active = entries.filter(isLiveEntry), finished = entries.filter(e => !isLiveEntry(e)), forMe = forMeWorkOf(active, identity), [landing] = react.useState(() => focusedLanding(params?.[WORKFLOWS_FOCUS_PARAM], entries.map(e => e.instance._id))), assignedWorkUnknown = active.some(e => e.invalid !== void 0), sectionFor = e => /* @__PURE__ */ jsxRuntime.jsx(WorkflowInstanceSection, {
|
|
7367
|
+
const identity = useAssignmentIdentity(), panelId = react.useId(), {params: params} = structure.usePaneRouter(), {view: view, setView: setView} = useWorkflowsTab(), {openActivity: openActivity, setOpenActivity: setOpenActivity, dialogEntry: dialogEntry} = useOpenActivity(entries), active = entries.filter(isLiveEntry), finished = entries.filter(e => !isLiveEntry(e)), forMe = forMeWorkOf(active, identity), [landing] = react.useState(() => focusedLanding(params?.[WORKFLOWS_FOCUS_PARAM], entries.map(e => e.instance._id))), assignedWorkUnknown = active.some(e => e.invalid !== void 0), booting = useDelayedFlag(active.some(e => !e.ready && e.invalid === void 0), BOOT_CUE_DELAY_MS), sectionFor = e => /* @__PURE__ */ jsxRuntime.jsx(WorkflowInstanceSection, {
|
|
7207
7368
|
defaultOpen: landingDefaultOpen(landing, e.instance._id),
|
|
7208
7369
|
entry: e,
|
|
7209
7370
|
onOpenActivity: activityName => setOpenActivity({
|
|
@@ -7224,6 +7385,7 @@ function WorkflowsPanel({entries: entries, documentId: documentId, docTypeMappin
|
|
|
7224
7385
|
padding: 3,
|
|
7225
7386
|
children: [
|
|
7226
7387
|
/* @__PURE__ */ jsxRuntime.jsx(GroupHeading, {
|
|
7388
|
+
busy: booting,
|
|
7227
7389
|
count: active.length,
|
|
7228
7390
|
end:
|
|
7229
7391
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
@@ -7359,10 +7521,8 @@ function workflowsView(S) {
|
|
|
7359
7521
|
return S.view.component(WorkflowsView).id(WORKFLOWS_VIEW_ID).title("Workflows");
|
|
7360
7522
|
}
|
|
7361
7523
|
|
|
7362
|
-
function workflowDefaultDocumentNode(
|
|
7363
|
-
return (S,
|
|
7364
|
-
if (mappingForDocType(options.mappings, ctx.schemaType)) return S.document().views([ S.view.form(), workflowsView(S) ]);
|
|
7365
|
-
};
|
|
7524
|
+
function workflowDefaultDocumentNode() {
|
|
7525
|
+
return S => S.document().views([ S.view.form(), workflowsView(S) ]);
|
|
7366
7526
|
}
|
|
7367
7527
|
|
|
7368
7528
|
function lockTitleFor(args) {
|
|
@@ -7375,26 +7535,12 @@ function lockTitleFor(args) {
|
|
|
7375
7535
|
return workflows.length === 1 ? `The ${workflowList} workflow is holding this document.` : `The ${workflowList} workflows are holding this document.`;
|
|
7376
7536
|
}
|
|
7377
7537
|
|
|
7378
|
-
const EMPTY = {
|
|
7379
|
-
byType: /* @__PURE__ */ new Map,
|
|
7380
|
-
definitions: /* @__PURE__ */ new Map,
|
|
7381
|
-
warnings: []
|
|
7382
|
-
};
|
|
7383
|
-
|
|
7384
7538
|
function resolveAutoStart(args) {
|
|
7385
|
-
const {autoStart: autoStart,
|
|
7386
|
-
|
|
7387
|
-
const evaluated = evaluateMap(autoStart, context);
|
|
7388
|
-
if ("warning" in evaluated) return {
|
|
7389
|
-
byType: /* @__PURE__ */ new Map,
|
|
7390
|
-
definitions: /* @__PURE__ */ new Map,
|
|
7391
|
-
warnings: [ evaluated.warning ]
|
|
7392
|
-
};
|
|
7393
|
-
const map = evaluated.map, latestByName = new Map(workflowEngine.latestDeployedDefinitions(definitions).map(d => [ d.name, d ])), byType = /* @__PURE__ */ new Map, resolvedDefinitions = /* @__PURE__ */ new Map, warnings = [];
|
|
7394
|
-
for (const [docType, spec] of Object.entries(map)) {
|
|
7539
|
+
const {autoStart: autoStart, knownDocTypes: knownDocTypes, definitions: definitions} = args, latestByName = new Map(workflowEngine.latestDeployedDefinitions(definitions).map(d => [ d.name, d ])), byType = /* @__PURE__ */ new Map, resolvedDefinitions = /* @__PURE__ */ new Map, warnings = [];
|
|
7540
|
+
for (const [docType, names] of Object.entries(autoStart)) {
|
|
7395
7541
|
const entry = resolveEntry({
|
|
7396
7542
|
docType: docType,
|
|
7397
|
-
|
|
7543
|
+
names: names,
|
|
7398
7544
|
knownDocTypes: knownDocTypes,
|
|
7399
7545
|
latestByName: latestByName
|
|
7400
7546
|
});
|
|
@@ -7410,35 +7556,15 @@ function resolveAutoStart(args) {
|
|
|
7410
7556
|
};
|
|
7411
7557
|
}
|
|
7412
7558
|
|
|
7413
|
-
function evaluateMap(autoStart, context) {
|
|
7414
|
-
let map;
|
|
7415
|
-
try {
|
|
7416
|
-
map = typeof autoStart == "function" ? autoStart(context) : autoStart;
|
|
7417
|
-
} catch (err) {
|
|
7418
|
-
return {
|
|
7419
|
-
warning: `autoStart: config function threw — ignoring it (${describeError(err)}).`
|
|
7420
|
-
};
|
|
7421
|
-
}
|
|
7422
|
-
return typeof map != "object" || map === null ? {
|
|
7423
|
-
warning: "autoStart: config did not resolve to an object — ignoring it."
|
|
7424
|
-
} : {
|
|
7425
|
-
map: map
|
|
7426
|
-
};
|
|
7427
|
-
}
|
|
7428
|
-
|
|
7429
|
-
function specNames(spec) {
|
|
7430
|
-
return typeof spec == "string" ? [ spec ] : Array.isArray(spec) ? spec : [];
|
|
7431
|
-
}
|
|
7432
|
-
|
|
7433
7559
|
function resolveEntry(args) {
|
|
7434
|
-
const {docType: docType,
|
|
7560
|
+
const {docType: docType, names: names, knownDocTypes: knownDocTypes, latestByName: latestByName} = args;
|
|
7435
7561
|
if (!knownDocTypes.has(docType)) return {
|
|
7436
7562
|
valid: [],
|
|
7437
7563
|
definitions: [],
|
|
7438
7564
|
warnings: [ `autoStart: no schema type "${docType}" — entry skipped.` ]
|
|
7439
7565
|
};
|
|
7440
7566
|
const valid = [], definitions = [], warnings = [];
|
|
7441
|
-
for (const name of
|
|
7567
|
+
for (const name of names) {
|
|
7442
7568
|
const definition = latestByName.get(name), issue = workflowIssue({
|
|
7443
7569
|
name: name,
|
|
7444
7570
|
docType: docType,
|
|
@@ -7464,11 +7590,9 @@ function workflowIssue(args) {
|
|
|
7464
7590
|
const {name: name, docType: docType, definition: definition} = args;
|
|
7465
7591
|
if (definition === void 0) return `autoStart: "${docType}" → workflow "${name}" is not deployed — skipped.`;
|
|
7466
7592
|
if (!workflowEngine.isStartableDefinition(definition)) return `autoStart: "${docType}" → workflow "${name}" is spawn-only, not startable — skipped.`;
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
const subject = (definition.fields ?? []).find(workflowEngine.isSubjectEntry);
|
|
7471
|
-
if (subject !== void 0 && !workflowEngine.isInputSourced(subject)) return `autoStart: "${docType}" → workflow "${name}" has a self-filling subject (not caller-provided), so the document can't be its subject — skipped.`;
|
|
7593
|
+
const subject = documentSubjectEntry(definition), acceptsType = subject?.types === void 0 || subject.types.includes(docType);
|
|
7594
|
+
if (subject === void 0 || !acceptsType) return `autoStart: "${docType}" → workflow "${name}" has no document subject accepting "${docType}" — skipped.`;
|
|
7595
|
+
if (!workflowEngine.isInputSourced(subject)) return `autoStart: "${docType}" → workflow "${name}" has a self-filling subject (not caller-provided), so the document can't be its subject — skipped.`;
|
|
7472
7596
|
}
|
|
7473
7597
|
|
|
7474
7598
|
function contentDocumentTypes(schema) {
|
|
@@ -7488,20 +7612,31 @@ const EMPTY_SNAPSHOT = {
|
|
|
7488
7612
|
};
|
|
7489
7613
|
|
|
7490
7614
|
function useDiscoveryState(args) {
|
|
7491
|
-
const {
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
react.
|
|
7495
|
-
watching || (setLatest(EMPTY_SNAPSHOT), setResolved(EMPTY_SNAPSHOT));
|
|
7496
|
-
}, [ watching ]);
|
|
7497
|
-
const filter = react.useMemo(() => ({
|
|
7498
|
-
documents: registered.map(id => workflowEngine.gdrFromResource(contentResource, id)),
|
|
7615
|
+
const {observed: observed, requested: requested, contentResource: contentResource} = args, documentWatching = observed.length > 0, requestedWatching = requested.length > 0, documents = useDiscoveryStream(documentWatching), explicit = useDiscoveryStream(requestedWatching), documentFilter = react.useMemo(() => documentWatching ? {
|
|
7616
|
+
documents: observed.map(id => workflowEngine.gdrFromResource(contentResource, id)),
|
|
7617
|
+
includeCompleted: !0
|
|
7618
|
+
} : void 0, [ documentWatching, observed, contentResource ]), requestedFilter = react.useMemo(() => requestedWatching ? {
|
|
7499
7619
|
ids: requested,
|
|
7500
7620
|
includeCompleted: !0
|
|
7501
|
-
}
|
|
7621
|
+
} : void 0, [ requestedWatching, requested ]), resolved = react.useMemo(() => mergeResolved(documents.resolved, explicit.resolved), [ documents.resolved, explicit.resolved ]);
|
|
7502
7622
|
return {
|
|
7503
|
-
|
|
7504
|
-
|
|
7623
|
+
documentFilter: documentFilter,
|
|
7624
|
+
requestedFilter: requestedFilter,
|
|
7625
|
+
loading: documents.loading || explicit.loading,
|
|
7626
|
+
invalid: documents.invalid ?? explicit.invalid,
|
|
7627
|
+
resolved: resolved,
|
|
7628
|
+
onDocumentSnapshot: documents.onSnapshot,
|
|
7629
|
+
onRequestedSnapshot: explicit.onSnapshot
|
|
7630
|
+
};
|
|
7631
|
+
}
|
|
7632
|
+
|
|
7633
|
+
function useDiscoveryStream(watching) {
|
|
7634
|
+
const [latest, setLatest] = react.useState(EMPTY_SNAPSHOT), [resolved, setResolved] = react.useState(EMPTY_SNAPSHOT), onSnapshot = react.useCallback(snapshot => {
|
|
7635
|
+
setLatest(snapshot), snapshot.instances !== void 0 && setResolved(snapshot);
|
|
7636
|
+
}, []);
|
|
7637
|
+
return react.useEffect(() => {
|
|
7638
|
+
watching || (setLatest(EMPTY_SNAPSHOT), setResolved(EMPTY_SNAPSHOT));
|
|
7639
|
+
}, [ watching ]), {
|
|
7505
7640
|
loading: watching && latest.instances === void 0 && latest.invalid === void 0,
|
|
7506
7641
|
invalid: watching ? latest.invalid : void 0,
|
|
7507
7642
|
resolved: resolved,
|
|
@@ -7509,18 +7644,62 @@ function useDiscoveryState(args) {
|
|
|
7509
7644
|
};
|
|
7510
7645
|
}
|
|
7511
7646
|
|
|
7512
|
-
function
|
|
7513
|
-
const
|
|
7514
|
-
for (const
|
|
7515
|
-
const
|
|
7516
|
-
|
|
7647
|
+
function mergeResolved(documents, explicit) {
|
|
7648
|
+
const rows = [ ...documents.instances ?? [], ...explicit.instances ?? [] ], freshest = /* @__PURE__ */ new Map;
|
|
7649
|
+
for (const instance of rows) {
|
|
7650
|
+
const current = freshest.get(instance._id);
|
|
7651
|
+
(current === void 0 || Date.parse(instance.lastChangedAt) > Date.parse(current.lastChangedAt)) && freshest.set(instance._id, instance);
|
|
7517
7652
|
}
|
|
7653
|
+
return {
|
|
7654
|
+
instances: documents.instances === void 0 && explicit.instances === void 0 ? void 0 : [ ...freshest.values() ],
|
|
7655
|
+
invalid: documents.invalid ?? explicit.invalid,
|
|
7656
|
+
registered: documents.registered
|
|
7657
|
+
};
|
|
7658
|
+
}
|
|
7659
|
+
|
|
7660
|
+
function createDiscoveryIndexer(deriveWatchSet = workflowEngine.subscriptionDocumentsForInstance) {
|
|
7661
|
+
const cached = /* @__PURE__ */ new Map;
|
|
7662
|
+
return {
|
|
7663
|
+
index(args) {
|
|
7664
|
+
const liveIds = new Set(args.instances.map(instance => instance._id));
|
|
7665
|
+
for (const id of cached.keys()) liveIds.has(id) || cached.delete(id);
|
|
7666
|
+
const watchedById = /* @__PURE__ */ new Map;
|
|
7667
|
+
for (const instance of args.instances) {
|
|
7668
|
+
let row = cached.get(instance._id);
|
|
7669
|
+
row?.source !== instance && (row = {
|
|
7670
|
+
source: instance,
|
|
7671
|
+
globalDocumentIds: [ ...new Set(deriveWatchSet(instance).documents.map(document => document.globalDocumentId)) ]
|
|
7672
|
+
}, cached.set(instance._id, row)), watchedById.set(instance._id, row.globalDocumentIds);
|
|
7673
|
+
}
|
|
7674
|
+
return buildDiscoveryIndex(args, watchedById);
|
|
7675
|
+
}
|
|
7676
|
+
};
|
|
7677
|
+
}
|
|
7678
|
+
|
|
7679
|
+
function buildDiscoveryIndex(args, watchedById) {
|
|
7680
|
+
const {instances: instances, registered: registered, contentResource: contentResource} = args, ordered = [ ...instances ].sort((a, b) => b.startedAt.localeCompare(a.startedAt)), index = /* @__PURE__ */ new Map, registeredByUri = new Map(registered.map(bareId => [ workflowEngine.gdrFromResource(contentResource, bareId), bareId ]));
|
|
7681
|
+
for (const instance of ordered) appendInstanceWatches({
|
|
7682
|
+
index: index,
|
|
7683
|
+
registeredByUri: registeredByUri,
|
|
7684
|
+
instanceId: instance._id,
|
|
7685
|
+
watched: watchedById.get(instance._id) ?? []
|
|
7686
|
+
});
|
|
7518
7687
|
return {
|
|
7519
7688
|
instances: new Map(ordered.map(inst => [ inst._id, inst ])),
|
|
7520
7689
|
index: index
|
|
7521
7690
|
};
|
|
7522
7691
|
}
|
|
7523
7692
|
|
|
7693
|
+
function appendInstanceWatches(args) {
|
|
7694
|
+
const {index: index, registeredByUri: registeredByUri, instanceId: instanceId, watched: watched} = args;
|
|
7695
|
+
for (const uri of watched) {
|
|
7696
|
+
const bareId = registeredByUri.get(uri);
|
|
7697
|
+
if (bareId === void 0) continue;
|
|
7698
|
+
const ids = index.get(bareId);
|
|
7699
|
+
ids === void 0 ? index.set(bareId, [ instanceId ]) : ids.push(instanceId);
|
|
7700
|
+
}
|
|
7701
|
+
}
|
|
7702
|
+
|
|
7524
7703
|
function sameInstance(a, b) {
|
|
7525
7704
|
return a === b || a._id === b._id && a._rev === b._rev;
|
|
7526
7705
|
}
|
|
@@ -7544,7 +7723,7 @@ function entryOf(inst, report) {
|
|
|
7544
7723
|
instance: report?.evaluation?.instance ?? inst,
|
|
7545
7724
|
committed: inst,
|
|
7546
7725
|
evaluation: report?.evaluation,
|
|
7547
|
-
ready: report?.ready ??
|
|
7726
|
+
ready: report?.ready ?? workflowEngine.terminalState(inst) !== "in-flight",
|
|
7548
7727
|
invalid: report?.invalid,
|
|
7549
7728
|
guards: report?.guards
|
|
7550
7729
|
};
|
|
@@ -7637,7 +7816,19 @@ function createEntriesStore() {
|
|
|
7637
7816
|
};
|
|
7638
7817
|
}
|
|
7639
7818
|
|
|
7640
|
-
|
|
7819
|
+
function sessionPlan(args) {
|
|
7820
|
+
const demandedIds = new Set(args.demanded), evaluated = [ ...args.discovered.values() ].filter(inst => demandedIds.has(inst._id));
|
|
7821
|
+
return {
|
|
7822
|
+
evaluated: evaluated,
|
|
7823
|
+
guardScope: evaluated.map(inst => inst._id).sort()
|
|
7824
|
+
};
|
|
7825
|
+
}
|
|
7826
|
+
|
|
7827
|
+
function useDefaultLayout(props) {
|
|
7828
|
+
return react.useMemo(() => props.renderDefault(props), [ props ]);
|
|
7829
|
+
}
|
|
7830
|
+
|
|
7831
|
+
const notReady = (..._args) => Promise.reject(new Error("workflow session not ready yet")), NO_REGISTERED_DOCUMENTS = [], DEMAND_RELEASE_GRACE_MS = 500;
|
|
7641
7832
|
|
|
7642
7833
|
function workspaceParts(config) {
|
|
7643
7834
|
if (!config.projectId || !config.dataset) throw new Error("workflow plugin requires a workspace with projectId and dataset");
|
|
@@ -7665,10 +7856,11 @@ class InstanceEvaluatorBoundary extends react.Component {
|
|
|
7665
7856
|
}
|
|
7666
7857
|
|
|
7667
7858
|
function InstanceEvaluator(props) {
|
|
7668
|
-
const {engine: engine, instanceId: instanceId, grantsFromPath: grantsFromPath, onReport: onReport} = props, {evaluation: evaluation, ready: ready, invalid: invalid, guards: guards, fireAction: fireAction, editField: editField, previewField: previewField, discardFieldPreview: discardFieldPreview} = workflowStudio.useWorkflowSession({
|
|
7859
|
+
const {engine: engine, instanceId: instanceId, grantsFromPath: grantsFromPath, guardScope: guardScope, onReport: onReport} = props, {evaluation: evaluation, ready: ready, invalid: invalid, guards: guards, fireAction: fireAction, editField: editField, previewField: previewField, discardFieldPreview: discardFieldPreview} = workflowStudio.useWorkflowSession({
|
|
7669
7860
|
engine: engine,
|
|
7670
7861
|
instanceId: instanceId,
|
|
7671
|
-
grantsFromPath: grantsFromPath
|
|
7862
|
+
grantsFromPath: grantsFromPath,
|
|
7863
|
+
guardScope: guardScope
|
|
7672
7864
|
});
|
|
7673
7865
|
return react.useEffect(() => {
|
|
7674
7866
|
onReport(instanceId, {
|
|
@@ -7712,9 +7904,9 @@ function engineOptionsFrom(config) {
|
|
|
7712
7904
|
}
|
|
7713
7905
|
|
|
7714
7906
|
function WorkflowProvider(props) {
|
|
7715
|
-
const {config: config} = props, studioClient = sanity.useClient({
|
|
7907
|
+
const {config: config} = props, defaultLayout = useDefaultLayout(props), studioClient = sanity.useClient({
|
|
7716
7908
|
apiVersion: WORKFLOW_API_VERSION
|
|
7717
|
-
}), schema = sanity.useSchema(), {
|
|
7909
|
+
}), schema = sanity.useSchema(), {projectId: projectId, dataset: contentDataset} = workspaceParts(studioClient.config()), workflowDataset = config.workflowDataset ?? contentDataset, binding = react.useMemo(() => ({
|
|
7718
7910
|
engineResource: {
|
|
7719
7911
|
type: "dataset",
|
|
7720
7912
|
id: `${projectId}.${workflowDataset}`
|
|
@@ -7732,7 +7924,15 @@ function WorkflowProvider(props) {
|
|
|
7732
7924
|
}), grantsFromPath = workflowEngine.aclPathForResource({
|
|
7733
7925
|
type: "dataset",
|
|
7734
7926
|
id: `${projectId}.${workflowDataset}`
|
|
7735
|
-
}), {ids: registered, acquire:
|
|
7927
|
+
}), {ids: registered, acquire: registerActive, release: unregisterActive} = workflowReact.useRefcountedIds(), {ids: observed, acquire: retainRegistration, release: releaseRegistration} = workflowReact.useRefcountedIds({
|
|
7928
|
+
releaseDelayMs: DEMAND_RELEASE_GRACE_MS
|
|
7929
|
+
}), register = react.useCallback(id => {
|
|
7930
|
+
registerActive(id), retainRegistration(id);
|
|
7931
|
+
}, [ registerActive, retainRegistration ]), unregister = react.useCallback(id => {
|
|
7932
|
+
unregisterActive(id), releaseRegistration(id);
|
|
7933
|
+
}, [ unregisterActive, releaseRegistration ]), {ids: requested, acquire: requestInstance, release: releaseInstance} = workflowReact.useRefcountedIds(), {ids: evaluationDemand, acquire: requestEvaluation, release: releaseEvaluation} = workflowReact.useRefcountedIds({
|
|
7934
|
+
releaseDelayMs: DEMAND_RELEASE_GRACE_MS
|
|
7935
|
+
}), [seeded, setSeeded] = react.useState(/* @__PURE__ */ new Map), seedInstance = react.useCallback(instance => {
|
|
7736
7936
|
setSeeded(prev => new Map(prev).set(instance._id, instance));
|
|
7737
7937
|
}, []), [startRequest2, setStartRequest] = react.useState(void 0), openStartDialog = react.useCallback(r => setStartRequest(r), []), closeStartDialog = react.useCallback(() => setStartRequest(void 0), []), [entriesStore] = react.useState(createEntriesStore);
|
|
7738
7938
|
react.useEffect(() => () => entriesStore.dispose(), [ entriesStore ]);
|
|
@@ -7783,15 +7983,18 @@ function WorkflowProvider(props) {
|
|
|
7783
7983
|
});
|
|
7784
7984
|
}, [ engine ]);
|
|
7785
7985
|
drainRef.current = drainEffectsFor;
|
|
7786
|
-
const {
|
|
7787
|
-
|
|
7986
|
+
const {documentFilter: documentFilter, requestedFilter: requestedFilter, loading: loading, invalid: discoveryInvalid, resolved: resolved, onDocumentSnapshot: onDocumentSnapshot, onRequestedSnapshot: onRequestedSnapshot} = useDiscoveryState({
|
|
7987
|
+
observed: observed,
|
|
7788
7988
|
requested: requested,
|
|
7789
7989
|
contentResource: binding.contentResource
|
|
7790
|
-
}), {instances: discovered, index: docIndex} = react.useMemo(() =>
|
|
7990
|
+
}), discoveryIndexer = react.useMemo(createDiscoveryIndexer, []), {instances: discovered, index: docIndex} = react.useMemo(() => discoveryIndexer.index({
|
|
7791
7991
|
instances: resolved.instances ?? [],
|
|
7792
7992
|
registered: resolved.registered,
|
|
7793
7993
|
contentResource: binding.contentResource
|
|
7794
|
-
}), [ resolved, binding.contentResource ]),
|
|
7994
|
+
}), [ discoveryIndexer, resolved, binding.contentResource ]), {evaluated: evaluated, guardScope: guardScope} = react.useMemo(() => sessionPlan({
|
|
7995
|
+
discovered: discovered,
|
|
7996
|
+
demanded: evaluationDemand
|
|
7997
|
+
}), [ discovered, evaluationDemand ]), resolvedDocs = react.useMemo(() => new Set(resolved.registered), [ resolved.registered ]);
|
|
7795
7998
|
react.useEffect(() => {
|
|
7796
7999
|
setSeeded(prev => {
|
|
7797
8000
|
const kept = [ ...prev ].filter(([id]) => !discovered.has(id));
|
|
@@ -7804,15 +8007,13 @@ function WorkflowProvider(props) {
|
|
|
7804
8007
|
docIndex: docIndex
|
|
7805
8008
|
});
|
|
7806
8009
|
}, [ entriesStore, seeded, discovered, docIndex ]);
|
|
7807
|
-
const isDocResolved = react.useCallback(docId => resolvedDocs.has(docId), [ resolvedDocs ]), schemaContentTypes = react.useMemo(() => new Set(contentDocumentTypes(schema)), [ schema ]), {issues: issues, starts: starts, fields: fields, latestVersions: latestVersions, autoStartByType: autoStartByType, autoStartDefinitions: autoStartDefinitions} = useDeployedDefinitions({
|
|
8010
|
+
const isDocResolved = react.useCallback(docId => resolvedDocs.has(docId), [ resolvedDocs ]), schemaContentTypes = react.useMemo(() => new Set(contentDocumentTypes(schema)), [ schema ]), {mappings: mappings, issues: issues, starts: starts, fields: fields, latestVersions: latestVersions, autoStartByType: autoStartByType, autoStartDefinitions: autoStartDefinitions} = useDeployedDefinitions({
|
|
7808
8011
|
engine: engine,
|
|
7809
|
-
|
|
8012
|
+
overrides: config.mappings,
|
|
7810
8013
|
contentResource: binding.contentResource,
|
|
7811
8014
|
schemaContentTypes: schemaContentTypes,
|
|
7812
8015
|
startRequest: startRequest2,
|
|
7813
|
-
|
|
7814
|
-
schema: schema,
|
|
7815
|
-
workspaceName: workspaceName
|
|
8016
|
+
schema: schema
|
|
7816
8017
|
}), value = react.useMemo(() => ({
|
|
7817
8018
|
register: register,
|
|
7818
8019
|
unregister: unregister,
|
|
@@ -7820,6 +8021,8 @@ function WorkflowProvider(props) {
|
|
|
7820
8021
|
entries: entriesStore,
|
|
7821
8022
|
requestInstance: requestInstance,
|
|
7822
8023
|
releaseInstance: releaseInstance,
|
|
8024
|
+
requestEvaluation: requestEvaluation,
|
|
8025
|
+
releaseEvaluation: releaseEvaluation,
|
|
7823
8026
|
seedInstance: seedInstance,
|
|
7824
8027
|
openStartDialog: openStartDialog,
|
|
7825
8028
|
closeStartDialog: closeStartDialog,
|
|
@@ -7834,7 +8037,7 @@ function WorkflowProvider(props) {
|
|
|
7834
8037
|
completeEffectFor: completeEffectFor,
|
|
7835
8038
|
engine: engine,
|
|
7836
8039
|
binding: binding,
|
|
7837
|
-
mappings:
|
|
8040
|
+
mappings: mappings,
|
|
7838
8041
|
mappingIssues: issues,
|
|
7839
8042
|
mappingStarts: starts,
|
|
7840
8043
|
mappingFields: fields,
|
|
@@ -7842,24 +8045,30 @@ function WorkflowProvider(props) {
|
|
|
7842
8045
|
effectHandlers: engine.effectHandlers,
|
|
7843
8046
|
autoStartByType: autoStartByType,
|
|
7844
8047
|
autoStartDefinitions: autoStartDefinitions
|
|
7845
|
-
}), [ register, unregister, isDocResolved, entriesStore, requestInstance, releaseInstance, seedInstance, openStartDialog, closeStartDialog, startRequest2, loading, discoveryInvalid, fireActionFor, editFieldFor, previewFieldFor, discardFieldPreviewFor, drainEffectsFor, completeEffectFor, engine, binding,
|
|
8048
|
+
}), [ register, unregister, isDocResolved, entriesStore, requestInstance, releaseInstance, requestEvaluation, releaseEvaluation, seedInstance, openStartDialog, closeStartDialog, startRequest2, loading, discoveryInvalid, fireActionFor, editFieldFor, previewFieldFor, discardFieldPreviewFor, drainEffectsFor, completeEffectFor, engine, binding, mappings, issues, starts, fields, latestVersions, autoStartByType, autoStartDefinitions ]);
|
|
7846
8049
|
/* @__PURE__ */
|
|
7847
8050
|
return jsxRuntime.jsxs(WorkflowContext.Provider, {
|
|
7848
8051
|
value: value,
|
|
7849
|
-
children: [
|
|
8052
|
+
children: [ documentFilter ? /* @__PURE__ */ jsxRuntime.jsx(DiscoverySubscription, {
|
|
7850
8053
|
engine: engine,
|
|
7851
|
-
filter:
|
|
7852
|
-
onSnapshot:
|
|
8054
|
+
filter: documentFilter,
|
|
8055
|
+
onSnapshot: onDocumentSnapshot,
|
|
7853
8056
|
registered: registered
|
|
7854
|
-
}) : null,
|
|
8057
|
+
}) : null, requestedFilter ? /* @__PURE__ */ jsxRuntime.jsx(DiscoverySubscription, {
|
|
8058
|
+
engine: engine,
|
|
8059
|
+
filter: requestedFilter,
|
|
8060
|
+
onSnapshot: onRequestedSnapshot,
|
|
8061
|
+
registered: NO_REGISTERED_DOCUMENTS
|
|
8062
|
+
}) : null, evaluated.map(inst => /* @__PURE__ */ jsxRuntime.jsx(InstanceEvaluatorBoundary, {
|
|
7855
8063
|
instanceId: inst._id,
|
|
7856
8064
|
children: /* @__PURE__ */ jsxRuntime.jsx(InstanceEvaluator, {
|
|
7857
8065
|
engine: engine,
|
|
7858
8066
|
grantsFromPath: grantsFromPath,
|
|
8067
|
+
guardScope: guardScope,
|
|
7859
8068
|
instanceId: inst._id,
|
|
7860
8069
|
onReport: onReport
|
|
7861
8070
|
})
|
|
7862
|
-
}, inst._id)),
|
|
8071
|
+
}, inst._id)), defaultLayout, props.overlay ]
|
|
7863
8072
|
});
|
|
7864
8073
|
}
|
|
7865
8074
|
|
|
@@ -7869,14 +8078,25 @@ function sameEntries(a, b) {
|
|
|
7869
8078
|
return !0;
|
|
7870
8079
|
}
|
|
7871
8080
|
|
|
8081
|
+
function sameMappings(a, b) {
|
|
8082
|
+
return a.length === b.length && a.every((mapping, index) => {
|
|
8083
|
+
const other = b[index];
|
|
8084
|
+
return other !== void 0 && mappingKey(mapping) === mappingKey(other) && mapping.label === other.label && mapping.autoStart === other.autoStart && mapping.initialStateBuilder === other.initialStateBuilder && mapping.contextBuilder === other.contextBuilder && mapping.perspectiveField === other.perspectiveField;
|
|
8085
|
+
});
|
|
8086
|
+
}
|
|
8087
|
+
|
|
7872
8088
|
function useDeployedDefinitions(args) {
|
|
7873
|
-
const {engine: engine,
|
|
8089
|
+
const {engine: engine, overrides: overrides, contentResource: contentResource, schemaContentTypes: schemaContentTypes, startRequest: startRequest2, schema: schema} = args, [mappings, setMappings] = react.useState([]), [issues, setIssues] = react.useState(/* @__PURE__ */ new Map), [starts, setStarts] = react.useState(/* @__PURE__ */ new Map), [fields, setFields] = react.useState(/* @__PURE__ */ new Map), [latestVersions, setLatestVersions] = react.useState(/* @__PURE__ */ new Map), [autoStartByType, setAutoStartByType] = react.useState(
|
|
7874
8090
|
/* @__PURE__ */ new Map), [autoStartDefinitions, setAutoStartDefinitions] = react.useState(/* @__PURE__ */ new Map), logged = react.useRef(/* @__PURE__ */ new Set);
|
|
7875
8091
|
return react.useEffect(() => {
|
|
7876
8092
|
let cancelled = !1;
|
|
7877
8093
|
return (async () => {
|
|
7878
|
-
const definitions = await readDeployedDefinitions(engine),
|
|
7879
|
-
|
|
8094
|
+
const definitions = await readDeployedDefinitions(engine), effectiveMappings = discoverWorkflowMappings({
|
|
8095
|
+
definitions: definitions,
|
|
8096
|
+
schemaContentTypes: schemaContentTypes,
|
|
8097
|
+
overrides: overrides
|
|
8098
|
+
}), found = mappingIssues({
|
|
8099
|
+
mappings: effectiveMappings,
|
|
7880
8100
|
definitions: definitions,
|
|
7881
8101
|
contentResource: contentResource,
|
|
7882
8102
|
schemaContentTypes: schemaContentTypes
|
|
@@ -7886,32 +8106,30 @@ function useDeployedDefinitions(args) {
|
|
|
7886
8106
|
logged.current.has(signature) || (logged.current.add(signature), console.error(`[workflow-studio-plugin] ${message}`));
|
|
7887
8107
|
}
|
|
7888
8108
|
const resolvedAutoStart = resolveAutoStart({
|
|
7889
|
-
autoStart:
|
|
7890
|
-
context: {
|
|
7891
|
-
workspaceName: workspaceName,
|
|
7892
|
-
schema: schema
|
|
7893
|
-
},
|
|
8109
|
+
autoStart: mappingAutoStartMap(effectiveMappings),
|
|
7894
8110
|
knownDocTypes: new Set(schema.getTypeNames()),
|
|
7895
8111
|
definitions: definitions
|
|
7896
8112
|
});
|
|
7897
8113
|
if (logOnce(resolvedAutoStart.warnings, logged.current), cancelled) return;
|
|
8114
|
+
setMappings(prev => sameMappings(prev, effectiveMappings) ? prev : effectiveMappings),
|
|
7898
8115
|
setIssues(prev => sameEntries(prev, found) ? prev : found), setStarts(mappingStartBlocks({
|
|
7899
|
-
mappings:
|
|
8116
|
+
mappings: effectiveMappings,
|
|
7900
8117
|
definitions: definitions
|
|
7901
8118
|
})), setFields(mappingDeclaredFields({
|
|
7902
|
-
mappings:
|
|
8119
|
+
mappings: effectiveMappings,
|
|
7903
8120
|
definitions: definitions
|
|
7904
8121
|
}));
|
|
7905
8122
|
const versions = new Map(workflowEngine.latestDeployedDefinitions(definitions).map(d => [ d.name, d.version ]));
|
|
7906
8123
|
setLatestVersions(prev => sameEntries(prev, versions) ? prev : versions), setAutoStartByType(resolvedAutoStart.byType),
|
|
7907
8124
|
setAutoStartDefinitions(resolvedAutoStart.definitions);
|
|
7908
8125
|
})().catch(err => {
|
|
7909
|
-
console.error("[workflow-studio-plugin] mapping
|
|
8126
|
+
console.error("[workflow-studio-plugin] mapping discovery failed — keeping the last resolved workflow state:", err);
|
|
7910
8127
|
}), () => {
|
|
7911
8128
|
cancelled = !0;
|
|
7912
8129
|
};
|
|
7913
|
-
}, [ engine,
|
|
8130
|
+
}, [ engine, overrides, contentResource, schemaContentTypes, startRequest2, schema ]),
|
|
7914
8131
|
{
|
|
8132
|
+
mappings: mappings,
|
|
7915
8133
|
issues: issues,
|
|
7916
8134
|
starts: starts,
|
|
7917
8135
|
fields: fields,
|
|
@@ -8697,7 +8915,7 @@ function isFreshDocument(value) {
|
|
|
8697
8915
|
}
|
|
8698
8916
|
|
|
8699
8917
|
function subjectEntry(definition) {
|
|
8700
|
-
return (definition
|
|
8918
|
+
return documentSubjectEntry(definition);
|
|
8701
8919
|
}
|
|
8702
8920
|
|
|
8703
8921
|
function autoStartInputs(args) {
|
|
@@ -8724,11 +8942,11 @@ function pendingWorkflows(workflows, live) {
|
|
|
8724
8942
|
}
|
|
8725
8943
|
|
|
8726
8944
|
function extraRequiredInputs(definition) {
|
|
8727
|
-
const fields = definition.fields ?? [],
|
|
8945
|
+
const fields = definition.fields ?? [], subjectName = subjectEntry(definition)?.name, requiredNames = new Set(workflowEngine.missingRequiredInputs({
|
|
8728
8946
|
entryDefs: fields,
|
|
8729
8947
|
initialFields: []
|
|
8730
8948
|
}).map(input => input.name));
|
|
8731
|
-
return fields.filter(entry => requiredNames.has(entry.name) &&
|
|
8949
|
+
return fields.filter(entry => requiredNames.has(entry.name) && entry.name !== subjectName);
|
|
8732
8950
|
}
|
|
8733
8951
|
|
|
8734
8952
|
function buildAutoStartRequests(args) {
|
|
@@ -8776,7 +8994,7 @@ function AutoStartDriver(props) {
|
|
|
8776
8994
|
const pending = react.useMemo(() => pendingWorkflows(workflows, new Set(entries.map(entry => entry.instance.definition))), [ workflows, entries ]), inputs = react.useMemo(() => autoStartInputs({
|
|
8777
8995
|
workflows: pending,
|
|
8778
8996
|
definitions: autoStartDefinitions
|
|
8779
|
-
}), [ pending, autoStartDefinitions ]), pendingRef = react.useRef(pending);
|
|
8997
|
+
}), [ pending, autoStartDefinitions ]), definitionsResolved = workflows.every(name => autoStartDefinitions.has(name)), pendingRef = react.useRef(pending);
|
|
8780
8998
|
pendingRef.current = pending;
|
|
8781
8999
|
const instanceIds = react.useRef(/* @__PURE__ */ new Map), instanceIdFor = react.useCallback(workflow => {
|
|
8782
9000
|
const held = instanceIds.current.get(workflow);
|
|
@@ -8820,7 +9038,7 @@ function AutoStartDriver(props) {
|
|
|
8820
9038
|
}, [ autoStartDefinitions, docId, docType, binding, engine, observer, seedInstance, instanceIdFor, selectedReleaseId ]), retry = react.useCallback(() => {
|
|
8821
9039
|
firedRef.current = !1, setFired(!1), setSettled(!1), setFailure(void 0);
|
|
8822
9040
|
}, []), action = autoStartAction({
|
|
8823
|
-
resolved: isDocResolved(docId),
|
|
9041
|
+
resolved: definitionsResolved && isDocResolved(docId),
|
|
8824
9042
|
pendingCount: pending.length,
|
|
8825
9043
|
needsInput: inputs.length > 0,
|
|
8826
9044
|
fired: fired,
|
|
@@ -9242,6 +9460,61 @@ function TaskCountSpinner({entry: entry}) {
|
|
|
9242
9460
|
});
|
|
9243
9461
|
}
|
|
9244
9462
|
|
|
9463
|
+
function stagePillState(instance) {
|
|
9464
|
+
const definition = definitionSnapshotOf(instance), stage = definition?.stages.find(candidate => candidate.name === instance.currentStage), state = workflowEngine.terminalState(instance);
|
|
9465
|
+
return {
|
|
9466
|
+
title: stageTitle(definition, instance.currentStage),
|
|
9467
|
+
terminal: stage !== void 0 && workflowEngine.isTerminalStage(stage) || state !== "in-flight",
|
|
9468
|
+
state: state,
|
|
9469
|
+
stageKnown: stage !== void 0
|
|
9470
|
+
};
|
|
9471
|
+
}
|
|
9472
|
+
|
|
9473
|
+
function WorkflowStagePreview(props) {
|
|
9474
|
+
const {mappings: mappings} = useWorkflowContext(), mapped = props.schemaType !== void 0 && mappingsForDocType(mappings, props.schemaType.name).length > 0, {entries: entries} = useCommittedWorkflowsForDocument(mapped ? props._id ?? null : null), lead = entries.find(isLiveEntry) ?? entries[0], extraLive = entries.filter(e => e !== lead && isLiveEntry(e)).length;
|
|
9475
|
+
return props.renderDefault({
|
|
9476
|
+
...props,
|
|
9477
|
+
status: lead ? /* @__PURE__ */ jsxRuntime.jsx(StagePill, {
|
|
9478
|
+
entry: lead,
|
|
9479
|
+
extraLive: extraLive
|
|
9480
|
+
}) : props.status
|
|
9481
|
+
});
|
|
9482
|
+
}
|
|
9483
|
+
|
|
9484
|
+
function StagePill({entry: entry, extraLive: extraLive}) {
|
|
9485
|
+
/* @__PURE__ */
|
|
9486
|
+
return jsxRuntime.jsxs(ui.Flex, {
|
|
9487
|
+
align: "center",
|
|
9488
|
+
gap: 2,
|
|
9489
|
+
children: [
|
|
9490
|
+
/* @__PURE__ */ jsxRuntime.jsx(LeadBadge, {
|
|
9491
|
+
entry: entry
|
|
9492
|
+
}), extraLive > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, {
|
|
9493
|
+
fontSize: 1,
|
|
9494
|
+
mode: "outline",
|
|
9495
|
+
tone: "default",
|
|
9496
|
+
children: [ "+", extraLive ]
|
|
9497
|
+
}) : null ]
|
|
9498
|
+
});
|
|
9499
|
+
}
|
|
9500
|
+
|
|
9501
|
+
function LeadBadge({entry: entry}) {
|
|
9502
|
+
const {instance: instance} = entry;
|
|
9503
|
+
if (workflowEngine.isUnprimed(instance)) /* @__PURE__ */ return jsxRuntime.jsx(StartIncompleteBadge, {});
|
|
9504
|
+
const pill = stagePillState(instance);
|
|
9505
|
+
/* @__PURE__ */
|
|
9506
|
+
return jsxRuntime.jsxs(ui.Badge, {
|
|
9507
|
+
fontSize: 1,
|
|
9508
|
+
mode: pill.terminal ? "default" : "outline",
|
|
9509
|
+
tone: pillTone(pill),
|
|
9510
|
+
children: [ pill.title, pill.state === "completed" ? " ✓" : "" ]
|
|
9511
|
+
});
|
|
9512
|
+
}
|
|
9513
|
+
|
|
9514
|
+
function pillTone(args) {
|
|
9515
|
+
return args.state === "aborted" ? "critical" : args.terminal ? "positive" : args.stageKnown ? "primary" : "default";
|
|
9516
|
+
}
|
|
9517
|
+
|
|
9245
9518
|
function StartWorkflowDialogHost() {
|
|
9246
9519
|
const {startRequest: startRequest2, closeStartDialog: closeStartDialog} = useWorkflowContext();
|
|
9247
9520
|
return startRequest2 ? /* @__PURE__ */ jsxRuntime.jsx(StartWorkflowDialog, {
|
|
@@ -9316,7 +9589,8 @@ function withWorkflowLock(Action, guardAction) {
|
|
|
9316
9589
|
Locked;
|
|
9317
9590
|
}
|
|
9318
9591
|
|
|
9319
|
-
const workflowStudioPlugin = sanity.definePlugin(config => (
|
|
9592
|
+
const workflowStudioPlugin = sanity.definePlugin(config => (assertUniqueWorkflowMappings(config.mappings ?? []),
|
|
9593
|
+
{
|
|
9320
9594
|
name: "workflow-studio-plugin",
|
|
9321
9595
|
tools: prev => [ ...prev, workflowsTool ],
|
|
9322
9596
|
studio: {
|
|
@@ -9330,84 +9604,37 @@ const workflowStudioPlugin = sanity.definePlugin(config => ({
|
|
|
9330
9604
|
},
|
|
9331
9605
|
form: {
|
|
9332
9606
|
components: {
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
mappings: docTypeMappings
|
|
9338
|
-
}) : props.renderDefault(props);
|
|
9339
|
-
/* @__PURE__ */
|
|
9340
|
-
return jsxRuntime.jsx(AutoStartGate, {
|
|
9341
|
-
...props,
|
|
9342
|
-
fallback: fallback
|
|
9343
|
-
});
|
|
9344
|
-
}
|
|
9345
|
-
return props.renderDefault(props);
|
|
9346
|
-
}
|
|
9607
|
+
preview: WorkflowStagePreview,
|
|
9608
|
+
input: props => props.id === "root" && sanity.isObjectInputProps(props) ? /* @__PURE__ */ jsxRuntime.jsx(WorkflowRootInput, {
|
|
9609
|
+
...props
|
|
9610
|
+
}) : props.renderDefault(props)
|
|
9347
9611
|
}
|
|
9348
9612
|
},
|
|
9349
9613
|
document: {
|
|
9350
9614
|
badges: (prev, ctx) => {
|
|
9351
|
-
if (!
|
|
9615
|
+
if (!ctx.documentId) return prev;
|
|
9352
9616
|
const docId = ctx.documentId;
|
|
9353
9617
|
return [ makeActiveWorkflowsBadge(docId), makePerspectiveBadge(docId), ...prev ];
|
|
9354
9618
|
},
|
|
9355
|
-
actions:
|
|
9619
|
+
actions: prev => prev.map(Action => {
|
|
9356
9620
|
const guardAction = Action.action ? LOCKABLE_ACTIONS.get(Action.action) : void 0;
|
|
9357
9621
|
return guardAction ? withWorkflowLock(Action, guardAction) : Action;
|
|
9358
|
-
})
|
|
9622
|
+
})
|
|
9359
9623
|
}
|
|
9360
9624
|
}));
|
|
9361
9625
|
|
|
9362
|
-
function
|
|
9363
|
-
const {
|
|
9364
|
-
return props.renderDefault({
|
|
9626
|
+
function WorkflowRootInput(props) {
|
|
9627
|
+
const {mappings: mappings} = useWorkflowContext(), docTypeMappings = mappingsForDocType(mappings, props.schemaType.name), fallback = docTypeMappings.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(WorkflowFormStrip, {
|
|
9365
9628
|
...props,
|
|
9366
|
-
|
|
9367
|
-
|
|
9368
|
-
extraLive: extraLive
|
|
9369
|
-
}) : props.status
|
|
9370
|
-
});
|
|
9371
|
-
}
|
|
9372
|
-
|
|
9373
|
-
function StagePill({entry: entry, extraLive: extraLive}) {
|
|
9374
|
-
/* @__PURE__ */
|
|
9375
|
-
return jsxRuntime.jsxs(ui.Flex, {
|
|
9376
|
-
align: "center",
|
|
9377
|
-
gap: 2,
|
|
9378
|
-
children: [
|
|
9379
|
-
/* @__PURE__ */ jsxRuntime.jsx(LeadBadge, {
|
|
9380
|
-
entry: entry
|
|
9381
|
-
}), extraLive > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, {
|
|
9382
|
-
fontSize: 1,
|
|
9383
|
-
mode: "outline",
|
|
9384
|
-
tone: "default",
|
|
9385
|
-
children: [ "+", extraLive ]
|
|
9386
|
-
}) : null ]
|
|
9387
|
-
});
|
|
9388
|
-
}
|
|
9389
|
-
|
|
9390
|
-
function LeadBadge({entry: entry}) {
|
|
9391
|
-
const {instance: instance, evaluation: evaluation} = entry;
|
|
9392
|
-
if (workflowEngine.isUnprimed(instance)) /* @__PURE__ */ return jsxRuntime.jsx(StartIncompleteBadge, {});
|
|
9393
|
-
const stage = evaluation?.currentStage?.stage, title = stage?.title ?? stageTitle(definitionSnapshotOf(instance), instance.currentStage), state = workflowEngine.terminalState(instance), isTerminal = (stage ? workflowEngine.isTerminalStage(stage) : !1) || state !== "in-flight";
|
|
9629
|
+
mappings: docTypeMappings
|
|
9630
|
+
}) : props.renderDefault(props);
|
|
9394
9631
|
/* @__PURE__ */
|
|
9395
|
-
return jsxRuntime.
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
tone: pillTone({
|
|
9399
|
-
state: state,
|
|
9400
|
-
isTerminal: isTerminal,
|
|
9401
|
-
stageKnown: stage !== void 0
|
|
9402
|
-
}),
|
|
9403
|
-
children: [ title, state === "completed" ? " ✓" : "" ]
|
|
9632
|
+
return jsxRuntime.jsx(AutoStartGate, {
|
|
9633
|
+
...props,
|
|
9634
|
+
fallback: fallback
|
|
9404
9635
|
});
|
|
9405
9636
|
}
|
|
9406
9637
|
|
|
9407
|
-
function pillTone(args) {
|
|
9408
|
-
return args.state === "aborted" ? "critical" : args.isTerminal ? "positive" : args.stageKnown ? "primary" : "default";
|
|
9409
|
-
}
|
|
9410
|
-
|
|
9411
9638
|
exports.AbortedBadge = AbortedBadge;
|
|
9412
9639
|
|
|
9413
9640
|
exports.ActivitiesList = ActivitiesList;
|
|
@@ -9436,6 +9663,8 @@ exports.LinkChip = LinkChip;
|
|
|
9436
9663
|
|
|
9437
9664
|
exports.LoadingRow = LoadingRow;
|
|
9438
9665
|
|
|
9666
|
+
exports.SpinnerSlot = SpinnerSlot;
|
|
9667
|
+
|
|
9439
9668
|
exports.StageChip = StageChip;
|
|
9440
9669
|
|
|
9441
9670
|
exports.StageFace = StageFace;
|
|
@@ -9450,8 +9679,6 @@ exports.TrailingHairline = TrailingHairline;
|
|
|
9450
9679
|
|
|
9451
9680
|
exports.UnreadableDocsNote = UnreadableDocsNote;
|
|
9452
9681
|
|
|
9453
|
-
exports.WorkflowStagePreview = WorkflowStagePreview;
|
|
9454
|
-
|
|
9455
9682
|
exports.activityRowProps = activityRowProps;
|
|
9456
9683
|
|
|
9457
9684
|
exports.assigneeUserIdsOf = assigneeUserIdsOf;
|
|
@@ -9488,8 +9715,6 @@ exports.isEvaluationStale = isEvaluationStale;
|
|
|
9488
9715
|
|
|
9489
9716
|
exports.isOpenActivityStatus = isOpenActivityStatus;
|
|
9490
9717
|
|
|
9491
|
-
exports.mappingForDocType = mappingForDocType;
|
|
9492
|
-
|
|
9493
9718
|
exports.openActivityGone = openActivityGone;
|
|
9494
9719
|
|
|
9495
9720
|
exports.parseDateFieldValue = parseDateFieldValue;
|
|
@@ -9528,8 +9753,6 @@ exports.useWorkflowInstanceEntry = useWorkflowInstanceEntry;
|
|
|
9528
9753
|
|
|
9529
9754
|
exports.workflowDefaultDocumentNode = workflowDefaultDocumentNode;
|
|
9530
9755
|
|
|
9531
|
-
exports.workflowDocTypes = workflowDocTypes;
|
|
9532
|
-
|
|
9533
9756
|
exports.workflowStudioPlugin = workflowStudioPlugin;
|
|
9534
9757
|
|
|
9535
9758
|
exports.workflowsTabCodec = workflowsTabCodec;
|