@sanity/workflow-studio-plugin 0.3.0 → 0.4.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 +119 -0
- package/README.md +63 -7
- package/dist/_chunks-cjs/index.cjs +4043 -3603
- package/dist/_chunks-cjs/workflows-tool-root.cjs +41 -42
- package/dist/_chunks-es/index.js +3775 -3361
- package/dist/_chunks-es/workflows-tool-root.js +43 -42
- package/dist/index.d.cts +40 -15
- package/dist/index.d.ts +40 -15
- package/package.json +11 -8
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
|
|
3
|
-
import { Box, Text, Flex, Button, Badge, Stack, Card, useTheme_v2, Spinner, TextInput, Dialog,
|
|
3
|
+
import { Box, Text, Flex, Button, Badge, Stack, Card, useTheme_v2, Spinner, TextInput, Dialog, Menu, MenuItem, TabList, Tab, Container } from "@sanity/ui";
|
|
4
4
|
|
|
5
5
|
import { useMemo, useState, useEffect, useRef } from "react";
|
|
6
6
|
|
|
7
7
|
import { useRouter } from "sanity/router";
|
|
8
8
|
|
|
9
|
-
import { DocPreviewLink, findActivity, definitionSnapshotOf, instanceTitle, stateByActivity, isActivityAssignedTo, assigneeUserIdsOf, isOpenActivityStatus, stageTitle, formatDate, parseStoredDateValue, useWorkflowContext,
|
|
9
|
+
import { DocPreviewLink, findActivity, definitionSnapshotOf, instanceTitle, stateByActivity, isActivityAssignedTo, assigneeUserIdsOf, isOpenActivityStatus, stageTitle, formatDate, parseStoredDateValue, useWorkflowContext, gdrLocality, useUserDisplays, useProjectMembers, DismissablePopover, HoverHint, DocRefFace, useAssignmentIdentity, LoadingRow, AbortedBadge, instanceNotice, StaleLock, ActivitiesList, TodoItemsList, isEvaluationStale, useWorkflowInstanceEntry, InvalidDocNotice, useDefinition, openActivityGone, GroupHeading, ActivityDetailDialog, instanceBreadcrumb, StageChip, readDeployedDefinitions, describeError, StageGlyph, useDocLink, HintedMenuButton, ActivityStatusIcon, UserAvatarGroup } from "./index.js";
|
|
10
10
|
|
|
11
11
|
import { ChevronDownIcon } from "@sanity/icons/ChevronDown";
|
|
12
12
|
|
|
13
13
|
import { ChevronRightIcon } from "@sanity/icons/ChevronRight";
|
|
14
14
|
|
|
15
|
-
import { entryDocRefs, extractDocumentId, findOpenStageEntry, terminalState,
|
|
15
|
+
import { entryDocRefs, extractDocumentId, findOpenStageEntry, terminalState, latestDeployedDefinitions, isStartableDefinition } from "@sanity/workflow-engine";
|
|
16
16
|
|
|
17
17
|
import { CheckmarkIcon } from "@sanity/icons/Checkmark";
|
|
18
18
|
|
|
@@ -20,6 +20,8 @@ import { CloseIcon } from "@sanity/icons/Close";
|
|
|
20
20
|
|
|
21
21
|
import { FilterIcon } from "@sanity/icons/Filter";
|
|
22
22
|
|
|
23
|
+
import { MemberAvatar, DatePicker } from "@sanity/workflow-components";
|
|
24
|
+
|
|
23
25
|
import { endOfDay } from "date-fns/endOfDay";
|
|
24
26
|
|
|
25
27
|
import { useDocumentPreviewStore, useSchema } from "sanity";
|
|
@@ -384,7 +386,7 @@ function useDocPreviewTitles(documents) {
|
|
|
384
386
|
titles: new Map(titles),
|
|
385
387
|
resolved: new Set(resolved)
|
|
386
388
|
}), subscriptions = documents.flatMap(doc => {
|
|
387
|
-
const parsedRef
|
|
389
|
+
const {parsed: parsedRef, local: local} = gdrLocality(doc.id, binding.contentResource), schemaType = schema.get(doc.type);
|
|
388
390
|
return !parsedRef || !local || !schemaType ? (resolved.add(doc.id), []) : [ previewStore.observeForPreview({
|
|
389
391
|
_type: "reference",
|
|
390
392
|
_ref: parsedRef.documentId
|
|
@@ -418,14 +420,18 @@ function TaskFilterMenu({filters: filters, options: options, onChange: onChange}
|
|
|
418
420
|
onDismiss: () => setOpen(!1),
|
|
419
421
|
open: open,
|
|
420
422
|
overflow: "visible",
|
|
421
|
-
children: /* @__PURE__ */ jsx(
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
423
|
+
children: /* @__PURE__ */ jsx(HoverHint, {
|
|
424
|
+
disabled: open,
|
|
425
|
+
text: "Filter",
|
|
426
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
427
|
+
"aria-label": "Filter",
|
|
428
|
+
fontSize: 1,
|
|
429
|
+
icon: FilterIcon,
|
|
430
|
+
mode: "bleed",
|
|
431
|
+
onClick: () => setOpen(v => !v),
|
|
432
|
+
padding: 2,
|
|
433
|
+
selected: active || open
|
|
434
|
+
})
|
|
429
435
|
})
|
|
430
436
|
});
|
|
431
437
|
}
|
|
@@ -555,7 +561,7 @@ function FilterField({label: label, placeholder: placeholder, pills: pills, onCl
|
|
|
555
561
|
});
|
|
556
562
|
}
|
|
557
563
|
|
|
558
|
-
function TagField({label: label, placeholder: placeholder, rows: rows, activeKeys: activeKeys, onToggle: onToggle, pillLabel: pillLabel, open: open, onOpen: onOpen, emptyNote: emptyNote = "Nothing matches
|
|
564
|
+
function TagField({label: label, placeholder: placeholder, rows: rows, activeKeys: activeKeys, onToggle: onToggle, pillLabel: pillLabel, open: open, onOpen: onOpen, emptyNote: emptyNote = "Nothing matches"}) {
|
|
559
565
|
const [query, setQuery] = useState(""), q = query.trim().toLowerCase(), hits = q ? rows.filter(row => row.text.toLowerCase().includes(q)) : rows, shown = shownHits(hits, HITS_CAP);
|
|
560
566
|
/* @__PURE__ */
|
|
561
567
|
return jsx(FilterField, {
|
|
@@ -772,7 +778,7 @@ function DocumentField({documents: documents, activeIds: activeIds, onToggle: on
|
|
|
772
778
|
/* @__PURE__ */
|
|
773
779
|
return jsx(TagField, {
|
|
774
780
|
activeKeys: activeIds,
|
|
775
|
-
emptyNote: "No documents match
|
|
781
|
+
emptyNote: "No documents match",
|
|
776
782
|
label: "Document",
|
|
777
783
|
onOpen: onOpen,
|
|
778
784
|
onToggle: onToggle,
|
|
@@ -929,7 +935,7 @@ function WorkflowsDashboard({instances: instances, onOpenInstance: onOpenInstanc
|
|
|
929
935
|
return loading ? /* @__PURE__ */ jsx(LoadingRow, {
|
|
930
936
|
label: "Loading workflows…"
|
|
931
937
|
}) : inFlight.length === 0 && settled.length === 0 ? /* @__PURE__ */ jsx(MutedNote, {
|
|
932
|
-
text: "No workflows yet — start one with “New workflow
|
|
938
|
+
text: "No workflows yet — start one with “New workflow”"
|
|
933
939
|
}) : /* @__PURE__ */ jsxs(Stack, {
|
|
934
940
|
gap: 2,
|
|
935
941
|
children: [
|
|
@@ -949,7 +955,7 @@ function WorkflowsDashboard({instances: instances, onOpenInstance: onOpenInstanc
|
|
|
949
955
|
options: options
|
|
950
956
|
}) ]
|
|
951
957
|
}), visibleInFlight.length === 0 ? /* @__PURE__ */ jsx(MutedNote, {
|
|
952
|
-
text: "No running workflows match
|
|
958
|
+
text: "No running workflows match"
|
|
953
959
|
}) : /* @__PURE__ */ jsx(InstanceRows, {
|
|
954
960
|
instances: visibleInFlight,
|
|
955
961
|
onOpenInstance: onOpenInstance
|
|
@@ -1031,11 +1037,7 @@ function InstanceRow({instance: instance, onOpen: onOpen}) {
|
|
|
1031
1037
|
/* @__PURE__ */ jsx(Flex, {
|
|
1032
1038
|
flex: 1
|
|
1033
1039
|
}),
|
|
1034
|
-
/* @__PURE__ */ jsx(
|
|
1035
|
-
definition: definition,
|
|
1036
|
-
instance: instance
|
|
1037
|
-
}),
|
|
1038
|
-
/* @__PURE__ */ jsx(PendingWorkBadge, {
|
|
1040
|
+
/* @__PURE__ */ jsx(AbortedBadge, {
|
|
1039
1041
|
instance: instance
|
|
1040
1042
|
}) ]
|
|
1041
1043
|
})
|
|
@@ -1190,13 +1192,16 @@ function DetailHeader({entry: entry, definition: definition, onBack: onBack}) {
|
|
|
1190
1192
|
gap: 3,
|
|
1191
1193
|
wrap: "wrap",
|
|
1192
1194
|
children: [
|
|
1193
|
-
/* @__PURE__ */ jsx(
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1195
|
+
/* @__PURE__ */ jsx(HoverHint, {
|
|
1196
|
+
text: "Back to workflows",
|
|
1197
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
1198
|
+
"aria-label": "Back to workflows",
|
|
1199
|
+
fontSize: 1,
|
|
1200
|
+
icon: ArrowLeftIcon,
|
|
1201
|
+
mode: "bleed",
|
|
1202
|
+
onClick: onBack,
|
|
1203
|
+
padding: 2
|
|
1204
|
+
})
|
|
1200
1205
|
}),
|
|
1201
1206
|
/* @__PURE__ */ jsxs(Stack, {
|
|
1202
1207
|
gap: 2,
|
|
@@ -1213,11 +1218,7 @@ function DetailHeader({entry: entry, definition: definition, onBack: onBack}) {
|
|
|
1213
1218
|
}) ]
|
|
1214
1219
|
}), terminalState(instance) === "in-flight" ? /* @__PURE__ */ jsx(StageChip, {
|
|
1215
1220
|
title: stageTitle(definition, instance.currentStage)
|
|
1216
|
-
}) : /* @__PURE__ */ jsx(
|
|
1217
|
-
definition: definition,
|
|
1218
|
-
instance: instance
|
|
1219
|
-
}),
|
|
1220
|
-
/* @__PURE__ */ jsx(PendingWorkBadge, {
|
|
1221
|
+
}) : /* @__PURE__ */ jsx(AbortedBadge, {
|
|
1221
1222
|
instance: instance
|
|
1222
1223
|
}),
|
|
1223
1224
|
/* @__PURE__ */ jsx(SpinnerSlot, {
|
|
@@ -1268,7 +1269,7 @@ function StageDiagramSection({entry: entry, definition: definition}) {
|
|
|
1268
1269
|
children: /* @__PURE__ */ jsx(Text, {
|
|
1269
1270
|
muted: !0,
|
|
1270
1271
|
size: 1,
|
|
1271
|
-
children: "Couldn’t load this workflow’s
|
|
1272
|
+
children: "Couldn’t load this workflow’s full details — the stage diagram is unavailable, and technical names show instead of titles."
|
|
1272
1273
|
})
|
|
1273
1274
|
});
|
|
1274
1275
|
}
|
|
@@ -1347,9 +1348,9 @@ function DefinitionPickerPanel({onPick: onPick}) {
|
|
|
1347
1348
|
}) : null, !definitions && !error ? /* @__PURE__ */ jsx(LoadingRow, {
|
|
1348
1349
|
label: "Loading workflows…"
|
|
1349
1350
|
}) : null, definitions && definitions.length === 0 ? /* @__PURE__ */ jsx(MutedNote, {
|
|
1350
|
-
text: "No startable workflows are deployed
|
|
1351
|
+
text: "No startable workflows are deployed"
|
|
1351
1352
|
}) : null, definitions && definitions.length > 0 && visible.length === 0 ? /* @__PURE__ */ jsx(MutedNote, {
|
|
1352
|
-
text: "No workflows match
|
|
1353
|
+
text: "No workflows match"
|
|
1353
1354
|
}) : null,
|
|
1354
1355
|
/* @__PURE__ */ jsx(Stack, {
|
|
1355
1356
|
gap: 1,
|
|
@@ -1427,7 +1428,7 @@ function ToolActivityDialog({target: target, onClose: onClose}) {
|
|
|
1427
1428
|
|
|
1428
1429
|
function TaskGroupList({groups: groups, onOpenTask: onOpenTask, onOpenWorkflow: onOpenWorkflow}) {
|
|
1429
1430
|
return groups.withDocuments.length === 0 && groups.withoutDocuments.length === 0 ? /* @__PURE__ */ jsx(MutedNote, {
|
|
1430
|
-
text: "No tasks match — adjust the filters, or start a workflow
|
|
1431
|
+
text: "No tasks match — adjust the filters, or start a workflow"
|
|
1431
1432
|
}) : /* @__PURE__ */ jsxs(Stack, {
|
|
1432
1433
|
gap: 2,
|
|
1433
1434
|
children: [ groups.withDocuments.map(group => /* @__PURE__ */ jsx(DocumentTaskGroup, {
|
|
@@ -1554,9 +1555,9 @@ function DocumentTaskGroup({group: group, onOpenTask: onOpenTask, onOpenWorkflow
|
|
|
1554
1555
|
}
|
|
1555
1556
|
|
|
1556
1557
|
function GroupMenu({group: group, document: document, onOpenWorkflow: onOpenWorkflow}) {
|
|
1557
|
-
const router = useRouter();
|
|
1558
|
+
const router = useRouter(), state = useDocLink(document);
|
|
1558
1559
|
/* @__PURE__ */
|
|
1559
|
-
return jsx(
|
|
1560
|
+
return jsx(HintedMenuButton, {
|
|
1560
1561
|
button: /* @__PURE__ */ jsx(Button, {
|
|
1561
1562
|
"aria-label": "Group actions",
|
|
1562
1563
|
fontSize: 1,
|
|
@@ -1564,16 +1565,16 @@ function GroupMenu({group: group, document: document, onOpenWorkflow: onOpenWork
|
|
|
1564
1565
|
mode: "bleed",
|
|
1565
1566
|
padding: 2
|
|
1566
1567
|
}),
|
|
1568
|
+
hint: "Group actions",
|
|
1567
1569
|
id: `task-group-menu-${group.key}`,
|
|
1568
1570
|
menu: /* @__PURE__ */ jsxs(Menu, {
|
|
1569
1571
|
children: [
|
|
1570
1572
|
/* @__PURE__ */ jsx(MenuItem, {
|
|
1571
1573
|
onClick: () => onOpenWorkflow(group.instanceId),
|
|
1572
1574
|
text: "View workflow"
|
|
1573
|
-
}),
|
|
1575
|
+
}), state.kind === "linked" ? /* @__PURE__ */ jsx(MenuItem, {
|
|
1574
1576
|
onClick: () => router.navigateIntent("edit", {
|
|
1575
|
-
id:
|
|
1576
|
-
type: document.type
|
|
1577
|
+
id: state.bareId
|
|
1577
1578
|
}),
|
|
1578
1579
|
text: "Open document"
|
|
1579
1580
|
}) : null ]
|
package/dist/index.d.cts
CHANGED
|
@@ -6,10 +6,39 @@ import { JSX } from "react";
|
|
|
6
6
|
import { Plugin as Plugin_2 } from "sanity";
|
|
7
7
|
import { PreviewProps } from "sanity";
|
|
8
8
|
import { ResourceClientResolver } from "@sanity/workflow-engine";
|
|
9
|
+
import type { SanityClient } from "sanity";
|
|
10
|
+
import type { Schema } from "sanity";
|
|
9
11
|
import { StartContext } from "@sanity/workflow-engine";
|
|
10
12
|
import type { StructureBuilder } from "sanity/structure";
|
|
11
13
|
import type { ViewBuilder } from "sanity/structure";
|
|
12
14
|
|
|
15
|
+
/**
|
|
16
|
+
* The auto-start map, or a function computing it from the workspace at
|
|
17
|
+
* runtime (so it can vary by workspace name or schema). Resolved and
|
|
18
|
+
* validated in the plugin layout; see {@link resolveAutoStart}.
|
|
19
|
+
*/
|
|
20
|
+
declare type AutoStart =
|
|
21
|
+
| AutoStartMap
|
|
22
|
+
| ((context: AutoStartContext) => AutoStartMap);
|
|
23
|
+
|
|
24
|
+
/** What the plugin layout hands the function form of {@link AutoStart}. */
|
|
25
|
+
declare interface AutoStartContext {
|
|
26
|
+
/** The Studio workspace name. */
|
|
27
|
+
readonly workspaceName: string;
|
|
28
|
+
/** The workspace schema — to derive or gate on document types. */
|
|
29
|
+
readonly schema: Schema;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Document `_type` → the deployed workflow definition name(s) to auto-start on
|
|
34
|
+
* a fresh document of that type. Several names ⇒ all start together: one
|
|
35
|
+
* dialog collects the union of their required inputs, and the fresh document
|
|
36
|
+
* is the shared subject of each. Naming a workflow here does not require a
|
|
37
|
+
* {@link WorkflowMapping} entry — the required inputs come from the deployed
|
|
38
|
+
* definition itself.
|
|
39
|
+
*/
|
|
40
|
+
declare type AutoStartMap = Record<string, string | readonly string[]>;
|
|
41
|
+
|
|
13
42
|
/** The first mapping row for a document type — the tie-break wherever a
|
|
14
43
|
* surface binds to exactly one row. */
|
|
15
44
|
export declare function mappingForDocType(
|
|
@@ -44,22 +73,8 @@ export declare function workflowDocTypes(
|
|
|
44
73
|
export declare interface WorkflowMapping {
|
|
45
74
|
/** Studio schema type. */
|
|
46
75
|
readonly docType: string;
|
|
47
|
-
/**
|
|
48
|
-
* The document type must have a workflow: the editor form is gated until
|
|
49
|
-
* an instance references the document. Doctype-level: the flag on ANY
|
|
50
|
-
* mapping row for a docType gates the form, and starting any mapped
|
|
51
|
-
* workflow satisfies the gate. Advisory, UI-only enforcement — any raw
|
|
52
|
-
* API client can still write; the Content Lake is the only enforcement
|
|
53
|
-
* point.
|
|
54
|
-
*/
|
|
55
|
-
readonly mandatory?: boolean;
|
|
56
76
|
/** The definition `name` the engine deployed under. */
|
|
57
77
|
readonly definition: string;
|
|
58
|
-
/** Logical role of the doc — sets the GDR `type` discriminator in the
|
|
59
|
-
* builders. Subject lives on a field `doc.ref` entry, not an envelope. */
|
|
60
|
-
readonly subjectKind: "document" | "release";
|
|
61
|
-
/** Schema type stamped into the `doc.ref` field entry's `value.type`. */
|
|
62
|
-
readonly subjectGdrType: string;
|
|
63
78
|
/** Human-readable label for menus and dialogs. */
|
|
64
79
|
readonly label: string;
|
|
65
80
|
/** Optional initial workflow field entries to seed on Start. */
|
|
@@ -104,7 +119,7 @@ export declare interface WorkflowPluginConfig {
|
|
|
104
119
|
* each committed action; anything unregistered stays pending for another
|
|
105
120
|
* runtime to claim.
|
|
106
121
|
*/
|
|
107
|
-
readonly effectHandlers?: Record<string, EffectHandler
|
|
122
|
+
readonly effectHandlers?: Record<string, EffectHandler<SanityClient>>;
|
|
108
123
|
/**
|
|
109
124
|
* Routing override for cross-resource reads, replacing the Studio's
|
|
110
125
|
* default per-dataset routing — see `useWorkflowEngine`. A served resource
|
|
@@ -114,6 +129,16 @@ export declare interface WorkflowPluginConfig {
|
|
|
114
129
|
* stable (module scope or memoized).
|
|
115
130
|
*/
|
|
116
131
|
readonly resourceClients?: ResourceClientResolver;
|
|
132
|
+
/**
|
|
133
|
+
* Auto-start workflows when a FRESH document of a configured type is created
|
|
134
|
+
* in this Studio — the plugin takes over the form until they've started
|
|
135
|
+
* (collecting any inputs the workflows need beyond the subject), so the
|
|
136
|
+
* document is born with its workflow. A starting *convenience*, not
|
|
137
|
+
* enforcement: a raw client or any non-Studio surface bypasses it entirely,
|
|
138
|
+
* and pre-existing documents are never touched. Studio-only. See
|
|
139
|
+
* {@link AutoStart}.
|
|
140
|
+
*/
|
|
141
|
+
readonly autoStart?: AutoStart;
|
|
117
142
|
}
|
|
118
143
|
|
|
119
144
|
declare interface WorkflowPreviewProps extends PreviewProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -6,10 +6,39 @@ import { JSX } from "react";
|
|
|
6
6
|
import { Plugin as Plugin_2 } from "sanity";
|
|
7
7
|
import { PreviewProps } from "sanity";
|
|
8
8
|
import { ResourceClientResolver } from "@sanity/workflow-engine";
|
|
9
|
+
import type { SanityClient } from "sanity";
|
|
10
|
+
import type { Schema } from "sanity";
|
|
9
11
|
import { StartContext } from "@sanity/workflow-engine";
|
|
10
12
|
import type { StructureBuilder } from "sanity/structure";
|
|
11
13
|
import type { ViewBuilder } from "sanity/structure";
|
|
12
14
|
|
|
15
|
+
/**
|
|
16
|
+
* The auto-start map, or a function computing it from the workspace at
|
|
17
|
+
* runtime (so it can vary by workspace name or schema). Resolved and
|
|
18
|
+
* validated in the plugin layout; see {@link resolveAutoStart}.
|
|
19
|
+
*/
|
|
20
|
+
declare type AutoStart =
|
|
21
|
+
| AutoStartMap
|
|
22
|
+
| ((context: AutoStartContext) => AutoStartMap);
|
|
23
|
+
|
|
24
|
+
/** What the plugin layout hands the function form of {@link AutoStart}. */
|
|
25
|
+
declare interface AutoStartContext {
|
|
26
|
+
/** The Studio workspace name. */
|
|
27
|
+
readonly workspaceName: string;
|
|
28
|
+
/** The workspace schema — to derive or gate on document types. */
|
|
29
|
+
readonly schema: Schema;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Document `_type` → the deployed workflow definition name(s) to auto-start on
|
|
34
|
+
* a fresh document of that type. Several names ⇒ all start together: one
|
|
35
|
+
* dialog collects the union of their required inputs, and the fresh document
|
|
36
|
+
* is the shared subject of each. Naming a workflow here does not require a
|
|
37
|
+
* {@link WorkflowMapping} entry — the required inputs come from the deployed
|
|
38
|
+
* definition itself.
|
|
39
|
+
*/
|
|
40
|
+
declare type AutoStartMap = Record<string, string | readonly string[]>;
|
|
41
|
+
|
|
13
42
|
/** The first mapping row for a document type — the tie-break wherever a
|
|
14
43
|
* surface binds to exactly one row. */
|
|
15
44
|
export declare function mappingForDocType(
|
|
@@ -44,22 +73,8 @@ export declare function workflowDocTypes(
|
|
|
44
73
|
export declare interface WorkflowMapping {
|
|
45
74
|
/** Studio schema type. */
|
|
46
75
|
readonly docType: string;
|
|
47
|
-
/**
|
|
48
|
-
* The document type must have a workflow: the editor form is gated until
|
|
49
|
-
* an instance references the document. Doctype-level: the flag on ANY
|
|
50
|
-
* mapping row for a docType gates the form, and starting any mapped
|
|
51
|
-
* workflow satisfies the gate. Advisory, UI-only enforcement — any raw
|
|
52
|
-
* API client can still write; the Content Lake is the only enforcement
|
|
53
|
-
* point.
|
|
54
|
-
*/
|
|
55
|
-
readonly mandatory?: boolean;
|
|
56
76
|
/** The definition `name` the engine deployed under. */
|
|
57
77
|
readonly definition: string;
|
|
58
|
-
/** Logical role of the doc — sets the GDR `type` discriminator in the
|
|
59
|
-
* builders. Subject lives on a field `doc.ref` entry, not an envelope. */
|
|
60
|
-
readonly subjectKind: "document" | "release";
|
|
61
|
-
/** Schema type stamped into the `doc.ref` field entry's `value.type`. */
|
|
62
|
-
readonly subjectGdrType: string;
|
|
63
78
|
/** Human-readable label for menus and dialogs. */
|
|
64
79
|
readonly label: string;
|
|
65
80
|
/** Optional initial workflow field entries to seed on Start. */
|
|
@@ -104,7 +119,7 @@ export declare interface WorkflowPluginConfig {
|
|
|
104
119
|
* each committed action; anything unregistered stays pending for another
|
|
105
120
|
* runtime to claim.
|
|
106
121
|
*/
|
|
107
|
-
readonly effectHandlers?: Record<string, EffectHandler
|
|
122
|
+
readonly effectHandlers?: Record<string, EffectHandler<SanityClient>>;
|
|
108
123
|
/**
|
|
109
124
|
* Routing override for cross-resource reads, replacing the Studio's
|
|
110
125
|
* default per-dataset routing — see `useWorkflowEngine`. A served resource
|
|
@@ -114,6 +129,16 @@ export declare interface WorkflowPluginConfig {
|
|
|
114
129
|
* stable (module scope or memoized).
|
|
115
130
|
*/
|
|
116
131
|
readonly resourceClients?: ResourceClientResolver;
|
|
132
|
+
/**
|
|
133
|
+
* Auto-start workflows when a FRESH document of a configured type is created
|
|
134
|
+
* in this Studio — the plugin takes over the form until they've started
|
|
135
|
+
* (collecting any inputs the workflows need beyond the subject), so the
|
|
136
|
+
* document is born with its workflow. A starting *convenience*, not
|
|
137
|
+
* enforcement: a raw client or any non-Studio surface bypasses it entirely,
|
|
138
|
+
* and pre-existing documents are never touched. Studio-only. See
|
|
139
|
+
* {@link AutoStart}.
|
|
140
|
+
*/
|
|
141
|
+
readonly autoStart?: AutoStart;
|
|
117
142
|
}
|
|
118
143
|
|
|
119
144
|
declare interface WorkflowPreviewProps extends PreviewProps {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/workflow-studio-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Sanity Studio plugin for @sanity/workflow-engine: the form strip, a Workflows document view, stage badges, and the document-action lock.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -44,32 +44,35 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@sanity/client": "^7.23.0",
|
|
46
46
|
"@sanity/icons": "^4.1.0",
|
|
47
|
+
"@sanity/types": "^6",
|
|
47
48
|
"@sanity/ui": "^3.3.0",
|
|
48
49
|
"@sanity/util": "^6.3.0",
|
|
49
50
|
"date-fns": "^4.4.0",
|
|
50
51
|
"pluralize-esm": "^9.0.5",
|
|
51
|
-
"@sanity/workflow-diagram": "0.
|
|
52
|
-
"@sanity/workflow-engine": "0.
|
|
53
|
-
"@sanity/workflow-react": "0.
|
|
54
|
-
"@sanity/workflow-
|
|
52
|
+
"@sanity/workflow-diagram": "0.4.0",
|
|
53
|
+
"@sanity/workflow-engine": "0.18.0",
|
|
54
|
+
"@sanity/workflow-react": "0.13.0",
|
|
55
|
+
"@sanity/workflow-components": "0.1.0",
|
|
56
|
+
"@sanity/workflow-studio": "0.9.0"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
59
|
"@sanity/pkg-utils": "^10.5.3",
|
|
60
|
+
"@sanity/schema": "^6",
|
|
58
61
|
"@sanity/sdk": "^2.12.0",
|
|
59
62
|
"@testing-library/react": "^16.3.2",
|
|
60
63
|
"@types/react": "^19.2.17",
|
|
61
64
|
"jsdom": "^29.1.1",
|
|
62
65
|
"react": "^19.2.7",
|
|
63
66
|
"react-dom": "^19.2.7",
|
|
64
|
-
"sanity": "^
|
|
67
|
+
"sanity": "^6",
|
|
65
68
|
"styled-components": "^6.4.2",
|
|
66
69
|
"vitest": "^4.1.8",
|
|
67
|
-
"@sanity/workflow-engine-test": "0.
|
|
70
|
+
"@sanity/workflow-engine-test": "0.13.0"
|
|
68
71
|
},
|
|
69
72
|
"peerDependencies": {
|
|
70
73
|
"@sanity/sdk": "^2.12.0",
|
|
71
74
|
"react": "^19.2.7",
|
|
72
|
-
"sanity": "^
|
|
75
|
+
"sanity": "^6",
|
|
73
76
|
"styled-components": "^6.4.2"
|
|
74
77
|
},
|
|
75
78
|
"engines": {
|