@sanity/workflow-studio-plugin 0.23.0 → 0.25.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 +181 -0
- package/README.md +14 -5
- package/dist/_chunks-cjs/index.cjs +1361 -528
- package/dist/_chunks-cjs/workflows-tool-root.cjs +3759 -2193
- package/dist/_chunks-es/index.js +1309 -520
- package/dist/_chunks-es/workflows-tool-root.js +3768 -2196
- package/package.json +13 -12
|
@@ -10,6 +10,18 @@ function _interopDefaultCompat(e) {
|
|
|
10
10
|
|
|
11
11
|
var pluralize__default = /* @__PURE__ */ _interopDefaultCompat(pluralize);
|
|
12
12
|
|
|
13
|
+
const WORKFLOW_SYSTEM_TYPES = [ workflowEngine.WORKFLOW_INSTANCE_TYPE, workflowEngine.WORKFLOW_DEFINITION_TYPE, workflowEngine.GUARD_DOC_TYPE ];
|
|
14
|
+
|
|
15
|
+
function contentDocumentTypes(schema) {
|
|
16
|
+
return schema.getTypeNames().filter(name => schema.get(name)?.type?.name === "document" && !WORKFLOW_SYSTEM_TYPES.includes(name));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const SYSTEM_TYPE_PREFIX = "sanity.";
|
|
20
|
+
|
|
21
|
+
function isSystemDocumentType(name) {
|
|
22
|
+
return name.startsWith(SYSTEM_TYPE_PREFIX) || WORKFLOW_SYSTEM_TYPES.includes(name);
|
|
23
|
+
}
|
|
24
|
+
|
|
13
25
|
function isLocalContentResource(resource, contentResource) {
|
|
14
26
|
return resource?.type === "dataset" && resource.id === contentResource.id;
|
|
15
27
|
}
|
|
@@ -34,14 +46,14 @@ function assertUniqueWorkflowMappings(mappings) {
|
|
|
34
46
|
|
|
35
47
|
function discoverWorkflowMappings(args) {
|
|
36
48
|
assertUniqueWorkflowMappings(args.overrides ?? []);
|
|
37
|
-
const discovered = workflowEngine.latestDeployedDefinitions(args.definitions).flatMap(definition => {
|
|
49
|
+
const bindable = [ ...args.schemaContentTypes ].filter(name => !isSystemDocumentType(name)), discovered = workflowEngine.latestDeployedDefinitions(args.definitions).flatMap(definition => {
|
|
38
50
|
if (!workflowEngine.isStartableDefinition(definition)) return [];
|
|
39
51
|
const subject = (definition.fields ?? []).find(workflowEngine.isSubjectEntry);
|
|
40
52
|
if (subject === void 0 || !workflowEngine.isInputSourced(subject)) return [];
|
|
41
53
|
const source = {
|
|
42
54
|
fields: [ ...definition.fields ?? [] ]
|
|
43
55
|
};
|
|
44
|
-
return
|
|
56
|
+
return bindable.filter(docType => workflowEngine.acceptsDocumentType(source, docType)).map(docType => ({
|
|
45
57
|
docType: docType,
|
|
46
58
|
definition: definition.name,
|
|
47
59
|
label: definition.title ?? definition.name
|
|
@@ -172,14 +184,11 @@ function rowProblems(args) {
|
|
|
172
184
|
mapping: args.mapping,
|
|
173
185
|
contentResource: args.contentResource,
|
|
174
186
|
declared: declared
|
|
175
|
-
})
|
|
176
|
-
|
|
177
|
-
initialFields: seeded
|
|
178
|
-
}), consumptionProblems = workflowEngine.initialFieldIssues({
|
|
187
|
+
});
|
|
188
|
+
return [ ...workflowEngine.initialFieldIssues({
|
|
179
189
|
workflowFields: declared,
|
|
180
190
|
initialFields: seeded
|
|
181
|
-
}).flatMap(issue => seedConsumptionProblem(issue) ?? [])
|
|
182
|
-
return [ ...missing.map(m => `its start would not provide the required entry "${m.name}" (${m.type})`), ...consumptionProblems, ...seeded.flatMap(seed => seedReferenceProblems({
|
|
191
|
+
}).flatMap(issue => seedConsumptionProblem(issue) ?? []), ...seeded.flatMap(seed => seedReferenceProblems({
|
|
183
192
|
seed: seed,
|
|
184
193
|
declared: declared
|
|
185
194
|
})), ...seeded.flatMap(seed => seededSchemaProblems({
|
|
@@ -189,12 +198,24 @@ function rowProblems(args) {
|
|
|
189
198
|
})) ];
|
|
190
199
|
}
|
|
191
200
|
|
|
201
|
+
const NOT_DEPLOYED = "the definition is not deployed — deploy it or fix the mapping row";
|
|
202
|
+
|
|
203
|
+
function namesNoDeployedDefinition(issue) {
|
|
204
|
+
return issue.version === void 0;
|
|
205
|
+
}
|
|
206
|
+
|
|
192
207
|
function mappingIssues(args) {
|
|
193
208
|
const latestByName = new Map(workflowEngine.latestDeployedDefinitions(args.definitions).map(d => [ d.name, d ])), issues = /* @__PURE__ */ new Map;
|
|
194
209
|
for (const mapping of args.mappings) {
|
|
195
|
-
const
|
|
210
|
+
const identity = {
|
|
211
|
+
docType: mapping.docType,
|
|
212
|
+
definition: mapping.definition
|
|
213
|
+
}, definition = latestByName.get(mapping.definition);
|
|
196
214
|
if (definition === void 0) {
|
|
197
|
-
issues.set(mappingKey(mapping),
|
|
215
|
+
issues.set(mappingKey(mapping), {
|
|
216
|
+
...identity,
|
|
217
|
+
problems: [ NOT_DEPLOYED ]
|
|
218
|
+
});
|
|
198
219
|
continue;
|
|
199
220
|
}
|
|
200
221
|
const problems = rowProblems({
|
|
@@ -203,11 +224,31 @@ function mappingIssues(args) {
|
|
|
203
224
|
contentResource: args.contentResource,
|
|
204
225
|
schemaContentTypes: args.schemaContentTypes
|
|
205
226
|
});
|
|
206
|
-
problems.length > 0 && issues.set(mappingKey(mapping),
|
|
227
|
+
problems.length > 0 && issues.set(mappingKey(mapping), {
|
|
228
|
+
...identity,
|
|
229
|
+
version: definition.version,
|
|
230
|
+
problems: problems
|
|
231
|
+
});
|
|
207
232
|
}
|
|
208
233
|
return issues;
|
|
209
234
|
}
|
|
210
235
|
|
|
236
|
+
function sameMappingIssue(left, right) {
|
|
237
|
+
return left.docType === right.docType && left.definition === right.definition && left.version === right.version && left.problems.length === right.problems.length && left.problems.every((problem, index) => problem === right.problems[index]);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function mappingIssueDetail(issue) {
|
|
241
|
+
return issue.problems.join("; ");
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function versionSuffix(issue) {
|
|
245
|
+
return issue.version === void 0 ? "" : ` (v${issue.version})`;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function mappingIssueLogLines(issues) {
|
|
249
|
+
return [ ...issues.values() ].map(issue => `The "${issue.docType}" → "${issue.definition}" mapping row${versionSuffix(issue)} is disabled: ${mappingIssueDetail(issue)}.`);
|
|
250
|
+
}
|
|
251
|
+
|
|
211
252
|
const WORKFLOWS_VIEW_ID = "workflows", WORKFLOWS_TAB_PARAM = "workflowsTab";
|
|
212
253
|
|
|
213
254
|
function withoutWorkflowsTab(params) {
|
|
@@ -250,10 +291,16 @@ function landingDefaultOpen(landing, instanceId) {
|
|
|
250
291
|
if (!(landing === void 0 || !landing.instanceIds.includes(instanceId))) return instanceId === landing.focusedId;
|
|
251
292
|
}
|
|
252
293
|
|
|
253
|
-
const WORKFLOWS_TOOL_NAME = "workflows"
|
|
294
|
+
const WORKFLOWS_TOOL_NAME = "workflows";
|
|
295
|
+
|
|
296
|
+
function workflowsToolAvailable(tools) {
|
|
297
|
+
return tools.some(tool => tool.name === WORKFLOWS_TOOL_NAME);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const WORKFLOW_INTENT = "workflow";
|
|
254
301
|
|
|
255
|
-
function
|
|
256
|
-
return args.
|
|
302
|
+
function pathSegmentName(args) {
|
|
303
|
+
return args.names.find(name => name === args.segment);
|
|
257
304
|
}
|
|
258
305
|
|
|
259
306
|
function handlesWorkflowIntent(intent, params) {
|
|
@@ -267,11 +314,23 @@ function workflowIntentState(intent, params) {
|
|
|
267
314
|
} : null;
|
|
268
315
|
}
|
|
269
316
|
|
|
270
|
-
const pad2 = n => String(n).padStart(2, "0");
|
|
317
|
+
const pad2 = n => String(n).padStart(2, "0"), DUE_DATE_FIELD_KINDS = [ "dueDate", "dueDatetime" ], DATE_FIELD_KINDS = [ "date", "datetime", ...DUE_DATE_FIELD_KINDS ], DATE_FIELD_KIND_SET = new Set(DATE_FIELD_KINDS), DUE_DATE_FIELD_KIND_SET = new Set(DUE_DATE_FIELD_KINDS);
|
|
318
|
+
|
|
319
|
+
function isDateFieldKind(kind) {
|
|
320
|
+
return DATE_FIELD_KIND_SET.has(kind);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function isDueDateFieldKind(kind) {
|
|
324
|
+
return DUE_DATE_FIELD_KIND_SET.has(kind);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function hasTimeOfDay(kind) {
|
|
328
|
+
return kind === "datetime" || kind === "dueDatetime";
|
|
329
|
+
}
|
|
271
330
|
|
|
272
331
|
function parseDateFieldValue(value, kind) {
|
|
273
332
|
if (typeof value != "string" || value === "") return;
|
|
274
|
-
const parsed2 = kind
|
|
333
|
+
const parsed2 = hasTimeOfDay(kind) ? new Date(value) : parseLocalDate(value);
|
|
275
334
|
return Number.isNaN(parsed2.getTime()) ? void 0 : parsed2;
|
|
276
335
|
}
|
|
277
336
|
|
|
@@ -287,16 +346,24 @@ function parseStoredDateValue(value) {
|
|
|
287
346
|
}
|
|
288
347
|
|
|
289
348
|
function serializeDateFieldValue(date, kind) {
|
|
290
|
-
return kind
|
|
349
|
+
return hasTimeOfDay(kind) ? date.toISOString() : `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
class EffectsIncompleteError extends Error {
|
|
353
|
+
reason;
|
|
354
|
+
constructor(reason, options) {
|
|
355
|
+
super(`The change was committed, but running its effects failed: ${reason}`, options),
|
|
356
|
+
this.name = "EffectsIncompleteError", this.reason = reason;
|
|
357
|
+
}
|
|
291
358
|
}
|
|
292
359
|
|
|
293
360
|
const editDisabledSentence = {
|
|
294
361
|
"edit-window-closed": () => "Can only be edited while its activity is active",
|
|
295
|
-
"editor-not-permitted": () => "You don
|
|
362
|
+
"editor-not-permitted": () => "You don’t have permission to edit this",
|
|
296
363
|
"instance-aborted": () => "This workflow was aborted",
|
|
297
364
|
"instance-completed": () => "This workflow is already complete",
|
|
298
365
|
"mutation-guard-denied": () => "An earlier step is holding this document",
|
|
299
|
-
"not-editable": () => "This isn
|
|
366
|
+
"not-editable": () => "This isn’t editable here"
|
|
300
367
|
};
|
|
301
368
|
|
|
302
369
|
function describeEditDisabledReason(reason) {
|
|
@@ -369,24 +436,43 @@ const activityNotActiveSentence = {
|
|
|
369
436
|
}, disabledSentence = {
|
|
370
437
|
"activity-not-active": r => activityNotActiveSentence[r.status],
|
|
371
438
|
"cascade-fired": () => "This happens automatically — the workflow runs it when its condition is met.",
|
|
372
|
-
"filter-failed": () => "Not available to you yet — you may not have the required role, it may be assigned to someone else, or a needed value isn
|
|
439
|
+
"filter-failed": () => "Not available to you yet — you may not have the required role, it may be assigned to someone else, or a needed value isn’t set.",
|
|
373
440
|
"instance-aborted": () => "This workflow was aborted.",
|
|
374
441
|
"instance-completed": () => "This workflow is already complete.",
|
|
375
442
|
"mutation-guard-denied": () => "An earlier step is holding this document.",
|
|
376
|
-
"requirements-unmet": () => "This step isn
|
|
443
|
+
"requirements-unmet": () => "This step isn’t ready yet — a required condition hasn’t been met.",
|
|
377
444
|
"stage-terminal": () => "This stage is finished.",
|
|
378
|
-
"subject-permission-denied": () => "You don
|
|
445
|
+
"subject-permission-denied": () => "You don’t have permission to change the document this step works on."
|
|
379
446
|
};
|
|
380
447
|
|
|
381
448
|
function describeDisabledReason(reason) {
|
|
382
449
|
return disabledSentence[reason.kind](reason);
|
|
383
450
|
}
|
|
384
451
|
|
|
452
|
+
function readRejection(err) {
|
|
453
|
+
return err instanceof workflowEngine.ActionDisabledError ? {
|
|
454
|
+
kind: "refusal",
|
|
455
|
+
message: describeDisabledReason(err.reason)
|
|
456
|
+
} : err instanceof workflowEngine.MutationGuardDeniedError ? {
|
|
457
|
+
kind: "refusal",
|
|
458
|
+
message: describeDisabledReason({
|
|
459
|
+
kind: "mutation-guard-denied",
|
|
460
|
+
denied: err.denied
|
|
461
|
+
})
|
|
462
|
+
} : err instanceof workflowEngine.EditFieldDeniedError ? {
|
|
463
|
+
kind: "refusal",
|
|
464
|
+
message: describeEditDisabledReason(err.reason)
|
|
465
|
+
} : err instanceof EffectsIncompleteError ? {
|
|
466
|
+
kind: "committed-incomplete",
|
|
467
|
+
message: err.reason
|
|
468
|
+
} : {
|
|
469
|
+
kind: "failure",
|
|
470
|
+
message: workflowEngine.errorMessage(err)
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
|
|
385
474
|
function describeError(err) {
|
|
386
|
-
return
|
|
387
|
-
kind: "mutation-guard-denied",
|
|
388
|
-
denied: err.denied
|
|
389
|
-
}) : workflowEngine.errorMessage(err);
|
|
475
|
+
return readRejection(err).message;
|
|
390
476
|
}
|
|
391
477
|
|
|
392
478
|
function hrefIfHttp(value) {
|
|
@@ -442,6 +528,28 @@ function isTodoOverdue(item, today = /* @__PURE__ */ new Date) {
|
|
|
442
528
|
return !item.dueDate || isTodoDone(item) ? !1 : item.dueDate < serializeDateFieldValue(today, "date");
|
|
443
529
|
}
|
|
444
530
|
|
|
531
|
+
function todoEditKind(patch) {
|
|
532
|
+
return "assignee" in patch ? "assignee" : "due-date";
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
function assertNamesOneRow(items, key) {
|
|
536
|
+
const matches = items.filter(row => row._key === key).length;
|
|
537
|
+
if (matches !== 1) throw new Error(matches === 0 ? "This to-do is no longer in the stored list. Reload and try again." : `${matches} to-dos in this list share one id, so they cannot be told apart. The stored list has to be repaired before it can be edited.`);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
function todoItemsPatched(args) {
|
|
541
|
+
const {items: items, key: key, patch: patch} = args;
|
|
542
|
+
return assertNamesOneRow(items, key), items.map(row => row._key === key ? {
|
|
543
|
+
...row,
|
|
544
|
+
...patch
|
|
545
|
+
} : row);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function todoItemsWithout(args) {
|
|
549
|
+
const {items: items, key: key} = args;
|
|
550
|
+
return assertNamesOneRow(items, key), items.filter(row => row._key !== key);
|
|
551
|
+
}
|
|
552
|
+
|
|
445
553
|
function tickOpsOf(action) {
|
|
446
554
|
return (action.ops ?? []).flatMap(o => o.type === "field.updateWhere" ? [ o ] : []);
|
|
447
555
|
}
|
|
@@ -882,11 +990,23 @@ function rowAssignControlState(args) {
|
|
|
882
990
|
|
|
883
991
|
function rowDateControlState(args) {
|
|
884
992
|
return rowControlState({
|
|
885
|
-
kinds:
|
|
993
|
+
kinds: DUE_DATE_FIELD_KINDS,
|
|
886
994
|
...args
|
|
887
995
|
});
|
|
888
996
|
}
|
|
889
997
|
|
|
998
|
+
function dateValuesOf(state, matches) {
|
|
999
|
+
return state.filter(entry => matches(entry._type)).map(entry => entry.value).filter(value => typeof value == "string" && value !== "");
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
function datesOf(state) {
|
|
1003
|
+
return dateValuesOf(state, isDateFieldKind);
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
function dueDatesOf(state) {
|
|
1007
|
+
return dateValuesOf(state, isDueDateFieldKind);
|
|
1008
|
+
}
|
|
1009
|
+
|
|
890
1010
|
function committedRowFace(row) {
|
|
891
1011
|
return {
|
|
892
1012
|
activityName: row.activityName,
|
|
@@ -898,7 +1018,11 @@ function committedRowFace(row) {
|
|
|
898
1018
|
}
|
|
899
1019
|
|
|
900
1020
|
function activityRowProps(args) {
|
|
901
|
-
const {activityEval: activityEval, activityState: activityState, editableFields: editableFields} = args, state = activityState.get(activityEval.activity.name) ?? []
|
|
1021
|
+
const {activityEval: activityEval, activityState: activityState, editableFields: editableFields} = args, state = activityState.get(activityEval.activity.name) ?? [], controlArgs = {
|
|
1022
|
+
activity: activityEval.activity,
|
|
1023
|
+
status: activityEval.status,
|
|
1024
|
+
editableFields: editableFields
|
|
1025
|
+
};
|
|
902
1026
|
return {
|
|
903
1027
|
face: {
|
|
904
1028
|
activityName: activityEval.activity.name,
|
|
@@ -907,12 +1031,10 @@ function activityRowProps(args) {
|
|
|
907
1031
|
automated: showsAutomatedPill(activityEval),
|
|
908
1032
|
blocked: showsBlockedTag(activityEval)
|
|
909
1033
|
},
|
|
910
|
-
assignState: rowAssignControlState(
|
|
911
|
-
activity: activityEval.activity,
|
|
912
|
-
status: activityEval.status,
|
|
913
|
-
editableFields: editableFields
|
|
914
|
-
}),
|
|
1034
|
+
assignState: rowAssignControlState(controlArgs),
|
|
915
1035
|
assigneeIds: assigneeUserIdsOf(state),
|
|
1036
|
+
dateState: rowDateControlState(controlArgs),
|
|
1037
|
+
dueDates: dueDatesOf(state),
|
|
916
1038
|
terminalActions: rowTerminalActions({
|
|
917
1039
|
activityEval: activityEval,
|
|
918
1040
|
state: state,
|
|
@@ -922,12 +1044,12 @@ function activityRowProps(args) {
|
|
|
922
1044
|
}
|
|
923
1045
|
|
|
924
1046
|
function dateControlKind(state) {
|
|
925
|
-
if (state.kind === "editable" && (state.field.type
|
|
1047
|
+
if (state.kind === "editable" && isDueDateFieldKind(state.field.type)) return state.field.type;
|
|
926
1048
|
}
|
|
927
1049
|
|
|
928
1050
|
function dateControlValue(args) {
|
|
929
|
-
const {state: state,
|
|
930
|
-
return state.kind === "editable" ? typeof state.field.value == "string" && state.field.value !== "" ? state.field.value : void 0 :
|
|
1051
|
+
const {state: state, dueDates: dueDates} = args;
|
|
1052
|
+
return state.kind === "editable" ? typeof state.field.value == "string" && state.field.value !== "" ? state.field.value : void 0 : dueDates.find(value => parseStoredDateValue(value) !== void 0);
|
|
931
1053
|
}
|
|
932
1054
|
|
|
933
1055
|
function activityStateOf(instance, activityName) {
|
|
@@ -952,7 +1074,7 @@ function deriveActivityDetail(args) {
|
|
|
952
1074
|
};
|
|
953
1075
|
}
|
|
954
1076
|
|
|
955
|
-
const WORKFLOW_API_VERSION = workflowEngine.ENGINE_API_VERSION,
|
|
1077
|
+
const WORKFLOW_API_VERSION = workflowEngine.ENGINE_API_VERSION, EMPTY_ENTRIES = [], WorkflowContext = react.createContext(null);
|
|
956
1078
|
|
|
957
1079
|
function useWorkflowContext() {
|
|
958
1080
|
const value = react.useContext(WorkflowContext);
|
|
@@ -994,7 +1116,7 @@ function useWorkflowInstanceEntry(instanceId, options = {}) {
|
|
|
994
1116
|
|
|
995
1117
|
const WorkflowToolOpened = telemetry.defineEvent({
|
|
996
1118
|
name: "Editorial Workflows Studio Plugin Tool Opened",
|
|
997
|
-
version:
|
|
1119
|
+
version: 2,
|
|
998
1120
|
description: "The Workflows tool was opened or its tab was switched"
|
|
999
1121
|
}), WorkflowDocumentViewOpened = telemetry.defineEvent({
|
|
1000
1122
|
name: "Editorial Workflows Studio Plugin Document View Opened",
|
|
@@ -1004,10 +1126,27 @@ const WorkflowToolOpened = telemetry.defineEvent({
|
|
|
1004
1126
|
name: "Editorial Workflows Studio Plugin Instance Detail Viewed",
|
|
1005
1127
|
version: 1,
|
|
1006
1128
|
description: "The Workflows tool's per-instance detail view was opened"
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
function definitionFingerprint(definition) {
|
|
1132
|
+
const hash = definition?.contentHash;
|
|
1133
|
+
return hash === void 0 ? {} : {
|
|
1134
|
+
definitionContentHash: hash
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
const WorkflowDefinitionDetailViewed = telemetry.defineEvent({
|
|
1139
|
+
name: "Editorial Workflows Studio Plugin Definition Detail Viewed",
|
|
1140
|
+
version: 1,
|
|
1141
|
+
description: "A workflow's definition page was opened in the Workflows tool"
|
|
1007
1142
|
}), WorkflowFormStripClicked = telemetry.defineEvent({
|
|
1008
1143
|
name: "Editorial Workflows Studio Plugin Form Strip Clicked",
|
|
1009
1144
|
version: 1,
|
|
1010
1145
|
description: "The form strip's instance line was clicked, opening the document view"
|
|
1146
|
+
}), WorkflowDocumentLinkClicked = telemetry.defineEvent({
|
|
1147
|
+
name: "Editorial Workflows Studio Plugin Document Link Clicked",
|
|
1148
|
+
version: 2,
|
|
1149
|
+
description: "A document link was clicked, opening the referenced document's editor"
|
|
1011
1150
|
}), WorkflowStartDialogOpened = telemetry.defineEvent({
|
|
1012
1151
|
name: "Editorial Workflows Studio Plugin Start Dialog Opened",
|
|
1013
1152
|
version: 1,
|
|
@@ -1022,8 +1161,12 @@ const WorkflowToolOpened = telemetry.defineEvent({
|
|
|
1022
1161
|
description: "A fresh document's auto-start ran — one start request per configured workflow"
|
|
1023
1162
|
}), WorkflowActionControlUsed = telemetry.defineEvent({
|
|
1024
1163
|
name: "Editorial Workflows Studio Plugin Action Control Used",
|
|
1025
|
-
version:
|
|
1164
|
+
version: 2,
|
|
1026
1165
|
description: "An action-firing control was used, attributed to its UI surface"
|
|
1166
|
+
}), WorkflowFieldControlUsed = telemetry.defineEvent({
|
|
1167
|
+
name: "Editorial Workflows Studio Plugin Field Control Used",
|
|
1168
|
+
version: 1,
|
|
1169
|
+
description: "A field-editing control committed an edit, attributed to its UI surface"
|
|
1027
1170
|
}), WorkflowActivityDialogOpened = telemetry.defineEvent({
|
|
1028
1171
|
name: "Editorial Workflows Studio Plugin Activity Dialog Opened",
|
|
1029
1172
|
version: 1,
|
|
@@ -1032,10 +1175,30 @@ const WorkflowToolOpened = telemetry.defineEvent({
|
|
|
1032
1175
|
name: "Editorial Workflows Studio Plugin Task Filters Applied",
|
|
1033
1176
|
version: 1,
|
|
1034
1177
|
description: "The tool's task-filter menu closed with a changed selection"
|
|
1178
|
+
}), WorkflowBoardWorkflowSelected = telemetry.defineEvent({
|
|
1179
|
+
name: "Editorial Workflows Studio Plugin Board Workflow Selected",
|
|
1180
|
+
version: 2,
|
|
1181
|
+
description: "The workflow documents page settled on the workflow it's showing"
|
|
1182
|
+
}), WorkflowTitleSeedDrifted = telemetry.defineEvent({
|
|
1183
|
+
name: "Editorial Workflows Studio Plugin Title Seed Drifted",
|
|
1184
|
+
version: 1,
|
|
1185
|
+
description: "A cold-start seeded preview title diverged from the live preview pipeline"
|
|
1035
1186
|
}), WorkflowTodoToggled = telemetry.defineEvent({
|
|
1036
1187
|
name: "Editorial Workflows Studio Plugin Todo Toggled",
|
|
1037
1188
|
version: 1,
|
|
1038
1189
|
description: "A todo checkbox was toggled, attributed to its UI surface and write seam"
|
|
1190
|
+
}), WorkflowTodoEdited = telemetry.defineEvent({
|
|
1191
|
+
name: "Editorial Workflows Studio Plugin Todo Edited",
|
|
1192
|
+
version: 1,
|
|
1193
|
+
description: "A non-toggle todo-list write, attributed to its UI surface and gesture"
|
|
1194
|
+
}), WorkflowAbortDialogOpened = telemetry.defineEvent({
|
|
1195
|
+
name: "Editorial Workflows Studio Plugin Abort Dialog Opened",
|
|
1196
|
+
version: 1,
|
|
1197
|
+
description: "The abort-workflow confirm was opened"
|
|
1198
|
+
}), WorkflowAbortDialogSubmitted = telemetry.defineEvent({
|
|
1199
|
+
name: "Editorial Workflows Studio Plugin Abort Dialog Submitted",
|
|
1200
|
+
version: 1,
|
|
1201
|
+
description: "The abort-workflow confirm was submitted, carrying the attempt's outcome"
|
|
1039
1202
|
});
|
|
1040
1203
|
|
|
1041
1204
|
function useLogEventOnMount(event, data) {
|
|
@@ -1125,20 +1288,32 @@ function useUserDisplay(id) {
|
|
|
1125
1288
|
};
|
|
1126
1289
|
}
|
|
1127
1290
|
|
|
1128
|
-
const
|
|
1291
|
+
const warnedSelfUnavailable = /* @__PURE__ */ new Set;
|
|
1292
|
+
|
|
1293
|
+
function warnSelfUnavailableOnce(key, message) {
|
|
1294
|
+
warnedSelfUnavailable.has(key) || (warnedSelfUnavailable.add(key), console.warn(message));
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
function bridgedSelfId(users, meId) {
|
|
1298
|
+
const classified = workflowEngine.classifyPrincipalId(meId);
|
|
1299
|
+
return users.find(user => user.membership.id === meId)?.profile?.sanityUserId ?? classified.globalId ?? (classified.namespace === "project" ? void 0 : meId);
|
|
1300
|
+
}
|
|
1129
1301
|
|
|
1130
1302
|
function useBridgedSelf() {
|
|
1131
|
-
const me = sanity.useCurrentUser(), {users: users, loading: loading} = workflowStudio.useStudioProjectUsers();
|
|
1132
|
-
if (!me
|
|
1133
|
-
const
|
|
1134
|
-
if (id
|
|
1135
|
-
warnedNotMember.has(me.id) || (warnedNotMember.add(me.id), console.warn(`workflow: the project member directory cannot resolve the logged-in user ("${me.id}") to an account-global identity — the engine stores account-global user ids only, so workflow assignment and authoring controls stay disabled. Typically this user is not a member of this project.`));
|
|
1136
|
-
return;
|
|
1137
|
-
}
|
|
1138
|
-
return {
|
|
1303
|
+
const me = sanity.useCurrentUser(), {users: users, loading: loading, error: error} = workflowStudio.useStudioProjectUsers();
|
|
1304
|
+
if (!me) return;
|
|
1305
|
+
const id = bridgedSelfId(users, me.id);
|
|
1306
|
+
if (id !== void 0) return {
|
|
1139
1307
|
id: id,
|
|
1140
1308
|
roles: me.roles ?? []
|
|
1141
1309
|
};
|
|
1310
|
+
if (!loading) {
|
|
1311
|
+
if (error !== void 0) {
|
|
1312
|
+
warnSelfUnavailableOnce(`load:${me.id}`, `workflow: the project member directory failed to load ("${workflowEngine.errorMessage(error)}") — the logged-in user ("${me.id}") is project-scoped, and only that directory maps it to the account-global identity the engine stores, so workflow assignment and authoring controls stay disabled. A mounted view does not retry on its own; the next consumer to ask reloads the directory once its backoff has passed.`);
|
|
1313
|
+
return;
|
|
1314
|
+
}
|
|
1315
|
+
warnSelfUnavailableOnce(`unresolved:${me.id}`, `workflow: the project member directory cannot resolve the logged-in user ("${me.id}") to an account-global identity — the engine stores account-global user ids only, so workflow assignment and authoring controls stay disabled. Typically this user is not a member of this project.`);
|
|
1316
|
+
}
|
|
1142
1317
|
}
|
|
1143
1318
|
|
|
1144
1319
|
function useSelfActor() {
|
|
@@ -1258,9 +1433,50 @@ function buildParams(decls, values) {
|
|
|
1258
1433
|
};
|
|
1259
1434
|
}
|
|
1260
1435
|
|
|
1261
|
-
|
|
1436
|
+
function useDelayedFlag(active, delayMs) {
|
|
1437
|
+
const [held, setHeld] = react.useState(!1);
|
|
1438
|
+
return react.useEffect(() => {
|
|
1439
|
+
if (!active) {
|
|
1440
|
+
setHeld(!1);
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
const timer = setTimeout(() => setHeld(!0), delayMs);
|
|
1444
|
+
return () => clearTimeout(timer);
|
|
1445
|
+
}, [ active, delayMs ]), held && active;
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
const NEVER_MS = 2 ** 31 - 1, OPEN_DELAY_MS = 300;
|
|
1262
1449
|
|
|
1263
1450
|
function HoverHint(props) {
|
|
1451
|
+
return props.anchor !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(AnchoredHint, {
|
|
1452
|
+
...props
|
|
1453
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(WrappingHint, {
|
|
1454
|
+
...props
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
function AnchoredHint(props) {
|
|
1459
|
+
const {disabled: disabled = !1} = props, open = useDelayedFlag(props.open === !0 && !disabled, OPEN_DELAY_MS);
|
|
1460
|
+
/* @__PURE__ */
|
|
1461
|
+
return jsxRuntime.jsx(ui.Popover, {
|
|
1462
|
+
animate: !0,
|
|
1463
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(HintBody, {
|
|
1464
|
+
...props
|
|
1465
|
+
}),
|
|
1466
|
+
open: open,
|
|
1467
|
+
padding: hintPadding(props),
|
|
1468
|
+
placement: props.placement ?? "top",
|
|
1469
|
+
portal: !0,
|
|
1470
|
+
radius: 3,
|
|
1471
|
+
referenceElement: props.anchor
|
|
1472
|
+
});
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
function hintPadding(props) {
|
|
1476
|
+
return props.content !== void 0 && props.flush ? 0 : 2;
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
function WrappingHint(props) {
|
|
1264
1480
|
const {children: children, disabled: disabled = !1} = props;
|
|
1265
1481
|
/* @__PURE__ */
|
|
1266
1482
|
return jsxRuntime.jsx(ui.Tooltip, {
|
|
@@ -1270,17 +1486,20 @@ function HoverHint(props) {
|
|
|
1270
1486
|
}),
|
|
1271
1487
|
delay: {
|
|
1272
1488
|
close: 0,
|
|
1273
|
-
open: disabled ? NEVER_MS :
|
|
1489
|
+
open: disabled ? NEVER_MS : OPEN_DELAY_MS
|
|
1274
1490
|
},
|
|
1275
|
-
padding: props
|
|
1276
|
-
placement: "top",
|
|
1491
|
+
padding: hintPadding(props),
|
|
1492
|
+
placement: props.placement ?? "top",
|
|
1277
1493
|
portal: !0,
|
|
1278
1494
|
radius: 3,
|
|
1279
1495
|
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
1280
1496
|
"data-testid": props["data-testid"],
|
|
1281
1497
|
style: {
|
|
1282
|
-
display: "inline-flex",
|
|
1283
|
-
maxWidth: "100%"
|
|
1498
|
+
display: props.fill ? "flex" : "inline-flex",
|
|
1499
|
+
maxWidth: "100%",
|
|
1500
|
+
...props.fill ? {
|
|
1501
|
+
width: "100%"
|
|
1502
|
+
} : {}
|
|
1284
1503
|
},
|
|
1285
1504
|
children: children
|
|
1286
1505
|
})
|
|
@@ -1368,7 +1587,7 @@ function DismissablePopover({children: children, content: content2, onDismiss: o
|
|
|
1368
1587
|
function DateFieldInput({kind: kind, value: value, onChange: onChange, readOnly: readOnly = !1}) {
|
|
1369
1588
|
const [open, setOpen] = react.useState(!1), parsed2 = parseDateFieldValue(value, kind), close = () => setOpen(!1), toggle = () => {
|
|
1370
1589
|
readOnly || setOpen(v => !v);
|
|
1371
|
-
};
|
|
1590
|
+
}, pickHint = hasTimeOfDay(kind) ? "Pick a date and time…" : "Pick a date…";
|
|
1372
1591
|
/* @__PURE__ */
|
|
1373
1592
|
return jsxRuntime.jsx(DismissablePopover, {
|
|
1374
1593
|
content: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.ClearableDatePicker, {
|
|
@@ -1379,7 +1598,7 @@ function DateFieldInput({kind: kind, value: value, onChange: onChange, readOnly:
|
|
|
1379
1598
|
onPick: next => {
|
|
1380
1599
|
close(), onChange(serializeDateFieldValue(next, kind));
|
|
1381
1600
|
},
|
|
1382
|
-
selectTime: kind
|
|
1601
|
+
selectTime: hasTimeOfDay(kind),
|
|
1383
1602
|
value: parsed2
|
|
1384
1603
|
}),
|
|
1385
1604
|
onDismiss: close,
|
|
@@ -1392,7 +1611,7 @@ function DateFieldInput({kind: kind, value: value, onChange: onChange, readOnly:
|
|
|
1392
1611
|
children: /* @__PURE__ */ jsxRuntime.jsx(ui.TextInput, {
|
|
1393
1612
|
fontSize: 1,
|
|
1394
1613
|
onClick: toggle,
|
|
1395
|
-
placeholder: readOnly ? "" :
|
|
1614
|
+
placeholder: readOnly ? "" : pickHint,
|
|
1396
1615
|
readOnly: !0,
|
|
1397
1616
|
value: parsed2 ? formatDate(String(value)) : ""
|
|
1398
1617
|
})
|
|
@@ -1436,7 +1655,7 @@ function ChoiceSelect({options: options, value: value, onChange: onChange, readO
|
|
|
1436
1655
|
});
|
|
1437
1656
|
}
|
|
1438
1657
|
|
|
1439
|
-
const SCALAR_INPUT_KINDS = [ "string", "text", "url", "number", "progress",
|
|
1658
|
+
const SCALAR_INPUT_KINDS = [ "string", "text", "url", "number", "progress", ...DATE_FIELD_KINDS, "dateTime", "boolean" ], SCALAR_INPUT_KIND_SET = new Set(SCALAR_INPUT_KINDS);
|
|
1440
1659
|
|
|
1441
1660
|
function isScalarInputKind(kind) {
|
|
1442
1661
|
return SCALAR_INPUT_KIND_SET.has(kind);
|
|
@@ -1454,8 +1673,8 @@ function ScalarInput({kind: kind, value: value, onChange: onChange, options: opt
|
|
|
1454
1673
|
}) : kind === "boolean" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Checkbox, {
|
|
1455
1674
|
checked: value === !0,
|
|
1456
1675
|
onChange: e => onChange(e.currentTarget.checked)
|
|
1457
|
-
}) : kind
|
|
1458
|
-
kind: kind === "
|
|
1676
|
+
}) : isDateFieldKind(kind) || kind === "dateTime" ? /* @__PURE__ */ jsxRuntime.jsx(DateFieldInput, {
|
|
1677
|
+
kind: kind === "dateTime" ? "datetime" : kind,
|
|
1459
1678
|
onChange: next => onChange(next ?? ""),
|
|
1460
1679
|
value: value
|
|
1461
1680
|
}) : /* @__PURE__ */ jsxRuntime.jsx(ui.TextInput, {
|
|
@@ -1561,11 +1780,16 @@ function useStubValuePreview(id, schemaType) {
|
|
|
1561
1780
|
};
|
|
1562
1781
|
}
|
|
1563
1782
|
|
|
1783
|
+
function PreviewPlaceholder() {
|
|
1784
|
+
/* @__PURE__ */
|
|
1785
|
+
return jsxRuntime.jsx(sanity.SanityDefaultPreview, {
|
|
1786
|
+
isPlaceholder: !0
|
|
1787
|
+
});
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1564
1790
|
function StubPreview({id: id, schemaType: schemaType}) {
|
|
1565
1791
|
const {value: value, preview: preview} = useStubValuePreview(id, schemaType);
|
|
1566
|
-
return preview.isLoading ? /* @__PURE__ */ jsxRuntime.jsx(sanity.
|
|
1567
|
-
isPlaceholder: !0
|
|
1568
|
-
}) : /* @__PURE__ */ jsxRuntime.jsx(sanity.Preview, {
|
|
1792
|
+
return preview.isLoading ? /* @__PURE__ */ jsxRuntime.jsx(PreviewPlaceholder, {}) : /* @__PURE__ */ jsxRuntime.jsx(sanity.Preview, {
|
|
1569
1793
|
layout: "default",
|
|
1570
1794
|
schemaType: schemaType,
|
|
1571
1795
|
skipVisibilityCheck: !0,
|
|
@@ -1798,14 +2022,87 @@ function ParamsForm({decls: decls, values: values, onChange: onChange}) {
|
|
|
1798
2022
|
});
|
|
1799
2023
|
}
|
|
1800
2024
|
|
|
1801
|
-
|
|
2025
|
+
const TOAST_ID = {
|
|
2026
|
+
abort: "workflow-abort",
|
|
2027
|
+
detailsCopy: "workflow-details-copy",
|
|
2028
|
+
documentCreate: "workflow-document-create",
|
|
2029
|
+
documentSave: "workflow-document-save",
|
|
2030
|
+
effectResolve: "workflow-effect-resolve",
|
|
2031
|
+
effectsDrain: "workflow-effects-drain",
|
|
2032
|
+
effectsIncomplete: "workflow-effects-incomplete",
|
|
2033
|
+
orphanSettle: "workflow-orphan-settle",
|
|
2034
|
+
start: "workflow-start"
|
|
2035
|
+
};
|
|
2036
|
+
|
|
2037
|
+
function instanceToastId(gesture, instanceId) {
|
|
2038
|
+
return `workflow-${gesture}:${instanceId}`;
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
function actionFireToastId(args) {
|
|
2042
|
+
return `workflow-action-fire:${args.instanceId}:${args.activity}:${args.action}`;
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
const REASON_TOAST_DURATION = 2e4, DISMISS_SENTINEL_DURATION = .01;
|
|
2046
|
+
|
|
2047
|
+
function carriesReason(params) {
|
|
2048
|
+
return params.description !== void 0 && params.status !== "info";
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
function withConvention(params) {
|
|
2052
|
+
return {
|
|
2053
|
+
...params,
|
|
2054
|
+
closable: !0,
|
|
2055
|
+
...carriesReason(params) ? {
|
|
2056
|
+
duration: REASON_TOAST_DURATION
|
|
2057
|
+
} : {}
|
|
2058
|
+
};
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
function useWorkflowToast() {
|
|
1802
2062
|
const toast = ui.useToast();
|
|
1803
2063
|
return react.useMemo(() => ({
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
2064
|
+
push: params => {
|
|
2065
|
+
toast.push(withConvention(params));
|
|
2066
|
+
},
|
|
2067
|
+
dismiss: id => {
|
|
2068
|
+
toast.push({
|
|
2069
|
+
id: id,
|
|
2070
|
+
duration: DISMISS_SENTINEL_DURATION
|
|
2071
|
+
});
|
|
2072
|
+
}
|
|
2073
|
+
}), [ toast ]);
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
const COMMITTED_INCOMPLETE_TITLE = "Saved, but its follow-up didn’t run";
|
|
2077
|
+
|
|
2078
|
+
function rejectionToast(reading, titles) {
|
|
2079
|
+
return reading.kind === "committed-incomplete" ? {
|
|
2080
|
+
id: TOAST_ID.effectsIncomplete,
|
|
2081
|
+
status: "warning",
|
|
2082
|
+
title: COMMITTED_INCOMPLETE_TITLE,
|
|
2083
|
+
description: reading.message
|
|
2084
|
+
} : reading.kind === "refusal" ? {
|
|
2085
|
+
id: titles.id,
|
|
2086
|
+
status: "warning",
|
|
2087
|
+
title: titles.refused,
|
|
2088
|
+
description: reading.message
|
|
2089
|
+
} : {
|
|
2090
|
+
id: titles.id,
|
|
2091
|
+
status: "error",
|
|
2092
|
+
title: titles.failed,
|
|
2093
|
+
description: reading.message
|
|
2094
|
+
};
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
function useRejectionReport() {
|
|
2098
|
+
const toast = useWorkflowToast();
|
|
2099
|
+
return react.useMemo(() => ({
|
|
2100
|
+
rejected: args => {
|
|
2101
|
+
const reading = readRejection(args.err);
|
|
2102
|
+
reading.kind !== "refusal" && console.error(`[workflow-studio-plugin] ${args.context} rejected:`, args.err),
|
|
2103
|
+
toast.push(rejectionToast(reading, args));
|
|
2104
|
+
},
|
|
2105
|
+
dismiss: toast.dismiss
|
|
1809
2106
|
}), [ toast ]);
|
|
1810
2107
|
}
|
|
1811
2108
|
|
|
@@ -1828,10 +2125,21 @@ function useActionClusterPending() {
|
|
|
1828
2125
|
}
|
|
1829
2126
|
|
|
1830
2127
|
function useFireAction(args) {
|
|
1831
|
-
const {instanceId: instanceId, activity: activity, action: action, label: label, surface: surface, viaMenu: viaMenu} = args, {fireActionFor: fireActionFor} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry(),
|
|
2128
|
+
const {instanceId: instanceId, activity: activity, action: action, label: label, surface: surface, placement: placement, viaMenu: viaMenu} = args, {fireActionFor: fireActionFor} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry(), report = useRejectionReport(), cluster = useActionClusterLock(), [localPending, setLocalPending] = react.useState(!1), pending = localPending || cluster?.pending === !0, toastId = actionFireToastId({
|
|
2129
|
+
instanceId: instanceId,
|
|
2130
|
+
activity: activity,
|
|
2131
|
+
action: action
|
|
2132
|
+
});
|
|
1832
2133
|
return {
|
|
1833
2134
|
fire: react.useCallback(async params => {
|
|
1834
2135
|
if (pending) return !1;
|
|
2136
|
+
const log = success => telemetry2.log(WorkflowActionControlUsed, {
|
|
2137
|
+
instanceId: instanceId,
|
|
2138
|
+
surface: surface,
|
|
2139
|
+
placement: placement,
|
|
2140
|
+
viaMenu: viaMenu,
|
|
2141
|
+
success: success
|
|
2142
|
+
});
|
|
1835
2143
|
setLocalPending(!0), cluster?.onFireChange(!0);
|
|
1836
2144
|
try {
|
|
1837
2145
|
return await fireActionFor(instanceId, {
|
|
@@ -1840,31 +2148,19 @@ function useFireAction(args) {
|
|
|
1840
2148
|
...params && Object.keys(params).length > 0 ? {
|
|
1841
2149
|
params: params
|
|
1842
2150
|
} : {}
|
|
1843
|
-
}),
|
|
1844
|
-
status: "success",
|
|
1845
|
-
title: `${label} done`
|
|
1846
|
-
}), telemetry2.log(WorkflowActionControlUsed, {
|
|
1847
|
-
instanceId: instanceId,
|
|
1848
|
-
surface: surface,
|
|
1849
|
-
viaMenu: viaMenu,
|
|
1850
|
-
success: !0
|
|
1851
|
-
}), !0;
|
|
2151
|
+
}), report.dismiss(toastId), log(!0), !0;
|
|
1852
2152
|
} catch (err) {
|
|
1853
|
-
return
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
surface: surface,
|
|
1861
|
-
viaMenu: viaMenu,
|
|
1862
|
-
success: !1
|
|
1863
|
-
}), !1;
|
|
2153
|
+
return report.rejected({
|
|
2154
|
+
err: err,
|
|
2155
|
+
context: `firing "${action}" on "${activity}"`,
|
|
2156
|
+
id: toastId,
|
|
2157
|
+
refused: `“${label}” isn’t available right now`,
|
|
2158
|
+
failed: `Failed to complete “${label}”`
|
|
2159
|
+
}), log(!1), !1;
|
|
1864
2160
|
} finally {
|
|
1865
2161
|
setLocalPending(!1), cluster?.onFireChange(!1);
|
|
1866
2162
|
}
|
|
1867
|
-
}, [ fireActionFor, instanceId, activity, action, label, pending,
|
|
2163
|
+
}, [ fireActionFor, instanceId, activity, action, label, pending, report, toastId, cluster, telemetry2, surface, placement, viaMenu ]),
|
|
1868
2164
|
pending: pending
|
|
1869
2165
|
};
|
|
1870
2166
|
}
|
|
@@ -1905,13 +2201,14 @@ function RowClickShield({active: active, children: children}) {
|
|
|
1905
2201
|
});
|
|
1906
2202
|
}
|
|
1907
2203
|
|
|
1908
|
-
function FireButton({instanceId: instanceId, activity: activity, action: action, label: label, surface: surface, mode: mode = "default", chrome: chrome, tone: tone = "default", icon: icon}) {
|
|
2204
|
+
function FireButton({instanceId: instanceId, activity: activity, action: action, label: label, surface: surface, placement: placement, mode: mode = "default", chrome: chrome, tone: tone = "default", icon: icon}) {
|
|
1909
2205
|
const {fire: fire, pending: pending} = useFireAction({
|
|
1910
2206
|
instanceId: instanceId,
|
|
1911
2207
|
activity: activity,
|
|
1912
2208
|
action: action,
|
|
1913
2209
|
label: label,
|
|
1914
2210
|
surface: surface,
|
|
2211
|
+
placement: placement,
|
|
1915
2212
|
viaMenu: !1
|
|
1916
2213
|
}), handleClick = e => {
|
|
1917
2214
|
chrome?.inButtonCard === !0 && e.stopPropagation(), !pending && fire();
|
|
@@ -1933,7 +2230,7 @@ function FireButton({instanceId: instanceId, activity: activity, action: action,
|
|
|
1933
2230
|
});
|
|
1934
2231
|
}
|
|
1935
2232
|
|
|
1936
|
-
function ActivityActionRow({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, chrome: chrome}) {
|
|
2233
|
+
function ActivityActionRow({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, placement: placement, chrome: chrome}) {
|
|
1937
2234
|
const rowKind = actionRowKind(actionEval);
|
|
1938
2235
|
return rowKind.kind === "disabled" ? /* @__PURE__ */ jsxRuntime.jsx(DisabledActionButton, {
|
|
1939
2236
|
actionEval: actionEval,
|
|
@@ -1944,12 +2241,14 @@ function ActivityActionRow({actionEval: actionEval, instanceId: instanceId, acti
|
|
|
1944
2241
|
instanceId: instanceId,
|
|
1945
2242
|
activity: activity,
|
|
1946
2243
|
chrome: chrome,
|
|
2244
|
+
placement: placement,
|
|
1947
2245
|
surface: surface
|
|
1948
2246
|
}) : /* @__PURE__ */ jsxRuntime.jsx(ParamsActionButton, {
|
|
1949
2247
|
actionEval: actionEval,
|
|
1950
2248
|
instanceId: instanceId,
|
|
1951
2249
|
activity: activity,
|
|
1952
2250
|
chrome: chrome,
|
|
2251
|
+
placement: placement,
|
|
1953
2252
|
surface: surface
|
|
1954
2253
|
});
|
|
1955
2254
|
}
|
|
@@ -1975,7 +2274,7 @@ function DisabledActionButton({actionEval: actionEval, activity: activity, chrom
|
|
|
1975
2274
|
}) : button;
|
|
1976
2275
|
}
|
|
1977
2276
|
|
|
1978
|
-
function PlainActionButton({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, chrome: chrome}) {
|
|
2277
|
+
function PlainActionButton({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, placement: placement, chrome: chrome}) {
|
|
1979
2278
|
const {action: action} = actionEval, label = actionLabel(action), btn = actionButtonFace({
|
|
1980
2279
|
actionEval: actionEval,
|
|
1981
2280
|
activityName: activity
|
|
@@ -1987,6 +2286,7 @@ function PlainActionButton({actionEval: actionEval, instanceId: instanceId, acti
|
|
|
1987
2286
|
mode: btn.mode,
|
|
1988
2287
|
activity: activity,
|
|
1989
2288
|
chrome: chrome,
|
|
2289
|
+
placement: placement,
|
|
1990
2290
|
surface: surface,
|
|
1991
2291
|
tone: btn.tone
|
|
1992
2292
|
});
|
|
@@ -1996,13 +2296,14 @@ function PlainActionButton({actionEval: actionEval, instanceId: instanceId, acti
|
|
|
1996
2296
|
}) : button;
|
|
1997
2297
|
}
|
|
1998
2298
|
|
|
1999
|
-
function ParamsActionDialog({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, viaMenu: viaMenu, onClose: onClose}) {
|
|
2299
|
+
function ParamsActionDialog({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, placement: placement, viaMenu: viaMenu, onClose: onClose}) {
|
|
2000
2300
|
const {action: action} = actionEval, label = actionLabel(action), decls = action.params ?? [], [values, setValues] = react.useState({}), {fire: fire, pending: pending} = useFireAction({
|
|
2001
2301
|
instanceId: instanceId,
|
|
2002
2302
|
activity: activity,
|
|
2003
2303
|
action: action.name,
|
|
2004
2304
|
label: label,
|
|
2005
2305
|
surface: surface,
|
|
2306
|
+
placement: placement,
|
|
2006
2307
|
viaMenu: viaMenu
|
|
2007
2308
|
}), built = buildParams(decls, values), confirm = async () => {
|
|
2008
2309
|
await fire(built.params) && onClose();
|
|
@@ -2058,7 +2359,7 @@ function ParamsActionDialog({actionEval: actionEval, instanceId: instanceId, act
|
|
|
2058
2359
|
});
|
|
2059
2360
|
}
|
|
2060
2361
|
|
|
2061
|
-
function ParamsActionButton({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, chrome: chrome}) {
|
|
2362
|
+
function ParamsActionButton({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, placement: placement, chrome: chrome}) {
|
|
2062
2363
|
const [open, setOpen] = react.useState(!1), btn = actionButtonFace({
|
|
2063
2364
|
actionEval: actionEval,
|
|
2064
2365
|
activityName: activity
|
|
@@ -2084,6 +2385,7 @@ function ParamsActionButton({actionEval: actionEval, instanceId: instanceId, act
|
|
|
2084
2385
|
activity: activity,
|
|
2085
2386
|
instanceId: instanceId,
|
|
2086
2387
|
onClose: () => setOpen(!1),
|
|
2388
|
+
placement: placement,
|
|
2087
2389
|
surface: surface,
|
|
2088
2390
|
viaMenu: !1
|
|
2089
2391
|
})
|
|
@@ -2257,7 +2559,9 @@ function FieldInput$1({kind: kind, value: value, onChange: onChange, onEnter: on
|
|
|
2257
2559
|
});
|
|
2258
2560
|
|
|
2259
2561
|
case "date":
|
|
2562
|
+
case "dueDate":
|
|
2260
2563
|
case "datetime":
|
|
2564
|
+
case "dueDatetime":
|
|
2261
2565
|
/* @__PURE__ */
|
|
2262
2566
|
return jsxRuntime.jsx(DateFieldInput, {
|
|
2263
2567
|
kind: kind,
|
|
@@ -2303,22 +2607,64 @@ function FieldInput$1({kind: kind, value: value, onChange: onChange, onEnter: on
|
|
|
2303
2607
|
}
|
|
2304
2608
|
}
|
|
2305
2609
|
|
|
2306
|
-
function
|
|
2610
|
+
function isCompact(layout) {
|
|
2611
|
+
return layout === "inline" || layout === "row";
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2614
|
+
function docFaceChrome(args) {
|
|
2615
|
+
const {layout: layout, state: state} = args, compact = isCompact(layout);
|
|
2616
|
+
switch (state.kind) {
|
|
2617
|
+
case "linked":
|
|
2618
|
+
return {
|
|
2619
|
+
bareId: state.bareId,
|
|
2620
|
+
selfInset: !compact
|
|
2621
|
+
};
|
|
2622
|
+
|
|
2623
|
+
case "foreign":
|
|
2624
|
+
return {};
|
|
2625
|
+
|
|
2626
|
+
case "missing":
|
|
2627
|
+
return {
|
|
2628
|
+
tone: "caution"
|
|
2629
|
+
};
|
|
2630
|
+
|
|
2631
|
+
case "unopenable":
|
|
2632
|
+
return {};
|
|
2633
|
+
|
|
2634
|
+
case "pending":
|
|
2635
|
+
return compact ? {} : {
|
|
2636
|
+
selfInset: !0
|
|
2637
|
+
};
|
|
2638
|
+
|
|
2639
|
+
case "unresolvable":
|
|
2640
|
+
return {};
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
function chipPadding(fill) {
|
|
2645
|
+
return fill ? 3 : 2;
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2648
|
+
function LinkChip({hint: hint, children: children, as: as = "a", fill: fill = !1, ...anchorProps}) {
|
|
2307
2649
|
/* @__PURE__ */
|
|
2308
2650
|
return jsxRuntime.jsx(HoverHint, {
|
|
2651
|
+
fill: fill,
|
|
2309
2652
|
text: hint,
|
|
2310
2653
|
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
|
|
2311
2654
|
__unstable_focusRing: !0,
|
|
2312
2655
|
as: as,
|
|
2313
2656
|
"data-as": "a",
|
|
2314
|
-
padding:
|
|
2657
|
+
padding: chipPadding(fill),
|
|
2315
2658
|
radius: 3,
|
|
2316
2659
|
style: {
|
|
2317
2660
|
alignItems: "center",
|
|
2318
2661
|
color: "inherit",
|
|
2319
2662
|
display: "flex",
|
|
2320
2663
|
minWidth: 0,
|
|
2321
|
-
textDecoration: "none"
|
|
2664
|
+
textDecoration: "none",
|
|
2665
|
+
...fill ? {
|
|
2666
|
+
width: "100%"
|
|
2667
|
+
} : {}
|
|
2322
2668
|
},
|
|
2323
2669
|
tone: "inherit",
|
|
2324
2670
|
...anchorProps,
|
|
@@ -2437,7 +2783,7 @@ function DocRefFace({gdr: gdr}) {
|
|
|
2437
2783
|
});
|
|
2438
2784
|
}
|
|
2439
2785
|
|
|
2440
|
-
function
|
|
2786
|
+
function foreignNotice(bareId, resource) {
|
|
2441
2787
|
const location = resource.type === "dataset" ? `another dataset (${resource.id})` : `${resource.type} (${resource.id})`;
|
|
2442
2788
|
/* @__PURE__ */
|
|
2443
2789
|
return jsxRuntime.jsxs(ui.Text, {
|
|
@@ -2447,44 +2793,22 @@ function ForeignRefNotice({bareId: bareId, resource: resource}) {
|
|
|
2447
2793
|
});
|
|
2448
2794
|
}
|
|
2449
2795
|
|
|
2450
|
-
function
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
children: "Document unavailable"
|
|
2467
|
-
}) ]
|
|
2468
|
-
})
|
|
2469
|
-
}) : /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
|
|
2470
|
-
border: !0,
|
|
2471
|
-
padding: 2,
|
|
2472
|
-
radius: 3,
|
|
2473
|
-
tone: "caution",
|
|
2474
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
|
|
2475
|
-
align: "center",
|
|
2476
|
-
gap: 2,
|
|
2477
|
-
children: [
|
|
2478
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
2479
|
-
size: 1,
|
|
2480
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(WarningOutline.WarningOutlineIcon, {})
|
|
2481
|
-
}),
|
|
2482
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, {
|
|
2483
|
-
muted: !0,
|
|
2484
|
-
size: 1,
|
|
2485
|
-
children: [ "Document unavailable — ", bareId ]
|
|
2486
|
-
}) ]
|
|
2487
|
-
})
|
|
2796
|
+
function missingNotice(bareId, layout) {
|
|
2797
|
+
/* @__PURE__ */
|
|
2798
|
+
return jsxRuntime.jsxs(ui.Flex, {
|
|
2799
|
+
align: "center",
|
|
2800
|
+
gap: 2,
|
|
2801
|
+
children: [
|
|
2802
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
2803
|
+
muted: !0,
|
|
2804
|
+
size: 1,
|
|
2805
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(WarningOutline.WarningOutlineIcon, {})
|
|
2806
|
+
}),
|
|
2807
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
2808
|
+
muted: !0,
|
|
2809
|
+
size: 1,
|
|
2810
|
+
children: isCompact(layout) ? "Document unavailable" : `Document unavailable — ${bareId}`
|
|
2811
|
+
}) ]
|
|
2488
2812
|
});
|
|
2489
2813
|
}
|
|
2490
2814
|
|
|
@@ -2501,6 +2825,18 @@ function renderTypeIcon(icon) {
|
|
|
2501
2825
|
return typeof icon == "function" ? react.createElement(icon) : react.isValidElement(icon) ? icon : /* @__PURE__ */ jsxRuntime.jsx(Document.DocumentIcon, {});
|
|
2502
2826
|
}
|
|
2503
2827
|
|
|
2828
|
+
function TitleSkeleton() {
|
|
2829
|
+
/* @__PURE__ */
|
|
2830
|
+
return jsxRuntime.jsx(ui.TextSkeleton, {
|
|
2831
|
+
animated: !0,
|
|
2832
|
+
radius: 1,
|
|
2833
|
+
size: 1,
|
|
2834
|
+
style: {
|
|
2835
|
+
width: 96
|
|
2836
|
+
}
|
|
2837
|
+
});
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2504
2840
|
function InlineChipFace({bareId: bareId, schemaType: schemaType}) {
|
|
2505
2841
|
const {preview: preview} = useStubValuePreview(bareId, schemaType);
|
|
2506
2842
|
/* @__PURE__ */
|
|
@@ -2511,14 +2847,7 @@ function InlineChipFace({bareId: bareId, schemaType: schemaType}) {
|
|
|
2511
2847
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
2512
2848
|
size: 1,
|
|
2513
2849
|
children: renderTypeIcon(schemaType.icon)
|
|
2514
|
-
}), preview.isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ui.
|
|
2515
|
-
animated: !0,
|
|
2516
|
-
radius: 1,
|
|
2517
|
-
size: 1,
|
|
2518
|
-
style: {
|
|
2519
|
-
width: 96
|
|
2520
|
-
}
|
|
2521
|
-
}) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
2850
|
+
}), preview.isLoading ? /* @__PURE__ */ jsxRuntime.jsx(TitleSkeleton, {}) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
2522
2851
|
size: 1,
|
|
2523
2852
|
textOverflow: "ellipsis",
|
|
2524
2853
|
weight: "medium",
|
|
@@ -2529,69 +2858,114 @@ function InlineChipFace({bareId: bareId, schemaType: schemaType}) {
|
|
|
2529
2858
|
});
|
|
2530
2859
|
}
|
|
2531
2860
|
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2861
|
+
const NOTICE_PADDING = 2;
|
|
2862
|
+
|
|
2863
|
+
function CompactDocRef({face: face, fill: fill, link: link, onClick: onClick}) {
|
|
2864
|
+
return link === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
2865
|
+
padding: chipPadding(fill),
|
|
2866
|
+
style: fill ? {
|
|
2867
|
+
width: "100%"
|
|
2868
|
+
} : {},
|
|
2869
|
+
children: face.content
|
|
2870
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(LinkChip, {
|
|
2871
|
+
as: link,
|
|
2872
|
+
fill: fill,
|
|
2873
|
+
hint: "Open document",
|
|
2874
|
+
onClick: onClick,
|
|
2875
|
+
children: face.content
|
|
2876
|
+
});
|
|
2877
|
+
}
|
|
2878
|
+
|
|
2879
|
+
const PENDING_FACE_MAX_WAIT_MS = 4e3;
|
|
2880
|
+
|
|
2881
|
+
function PendingDocFace({bareId: bareId, layout: layout}) {
|
|
2882
|
+
const expired = useDelayedFlag(!0, PENDING_FACE_MAX_WAIT_MS), compact = isCompact(layout);
|
|
2883
|
+
if (expired) {
|
|
2884
|
+
const id = /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
2885
|
+
muted: !0,
|
|
2886
|
+
size: 1,
|
|
2887
|
+
children: bareId
|
|
2888
|
+
});
|
|
2889
|
+
return compact ? id : /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
2890
|
+
padding: NOTICE_PADDING,
|
|
2891
|
+
children: id
|
|
2892
|
+
});
|
|
2893
|
+
}
|
|
2894
|
+
return compact ?
|
|
2895
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
|
|
2896
|
+
align: "center",
|
|
2897
|
+
gap: 2,
|
|
2898
|
+
children: [
|
|
2899
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
2900
|
+
muted: !0,
|
|
2901
|
+
size: 1,
|
|
2902
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Document.DocumentIcon, {})
|
|
2903
|
+
}),
|
|
2904
|
+
/* @__PURE__ */ jsxRuntime.jsx(TitleSkeleton, {}) ]
|
|
2905
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(PreviewPlaceholder, {});
|
|
2906
|
+
}
|
|
2907
|
+
|
|
2908
|
+
function DocRefShell({face: face, layout: layout, source: source}) {
|
|
2909
|
+
const telemetry2 = workflowReact.useWorkflowTelemetry(), {bareId: bareId} = face, handleClick = e => {
|
|
2910
|
+
e.stopPropagation(), telemetry2.log(WorkflowDocumentLinkClicked, {
|
|
2911
|
+
source: source
|
|
2912
|
+
});
|
|
2913
|
+
}, EditIntentLink = react.useMemo(() => bareId === void 0 ? void 0 : function(linkProps) {
|
|
2914
|
+
/* @__PURE__ */
|
|
2915
|
+
return jsxRuntime.jsx(router.IntentLink, {
|
|
2916
|
+
...linkProps,
|
|
2917
|
+
intent: "edit",
|
|
2918
|
+
params: {
|
|
2539
2919
|
id: bareId
|
|
2540
2920
|
}
|
|
2541
2921
|
});
|
|
2542
2922
|
}, [ bareId ]);
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2923
|
+
if (isCompact(layout)) /* @__PURE__ */
|
|
2924
|
+
return jsxRuntime.jsx(CompactDocRef, {
|
|
2925
|
+
face: face,
|
|
2926
|
+
fill: layout === "row",
|
|
2927
|
+
link: EditIntentLink,
|
|
2928
|
+
onClick: handleClick
|
|
2929
|
+
});
|
|
2930
|
+
const padding = face.selfInset === !0 ? 0 : NOTICE_PADDING;
|
|
2931
|
+
/* @__PURE__ */
|
|
2932
|
+
return jsxRuntime.jsx(ui.Card, {
|
|
2552
2933
|
__unstable_focusRing: !0,
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
"data-as": "a",
|
|
2556
|
-
onClick: e => e.stopPropagation(),
|
|
2557
|
-
padding: 1,
|
|
2934
|
+
border: layout === "default",
|
|
2935
|
+
padding: padding,
|
|
2558
2936
|
radius: 3,
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2937
|
+
tone: face.tone ?? (layout === "bare" ? "inherit" : "default"),
|
|
2938
|
+
...EditIntentLink === void 0 ? {} : {
|
|
2939
|
+
as: EditIntentLink,
|
|
2940
|
+
"data-as": "a",
|
|
2941
|
+
onClick: handleClick,
|
|
2942
|
+
style: {
|
|
2943
|
+
color: "inherit",
|
|
2944
|
+
textDecoration: "none",
|
|
2945
|
+
display: "block"
|
|
2946
|
+
}
|
|
2563
2947
|
},
|
|
2564
|
-
children:
|
|
2565
|
-
id: bareId,
|
|
2566
|
-
schemaType: schemaType
|
|
2567
|
-
})
|
|
2948
|
+
children: face.content
|
|
2568
2949
|
});
|
|
2569
2950
|
}
|
|
2570
2951
|
|
|
2571
|
-
function
|
|
2572
|
-
const state =
|
|
2952
|
+
function faceContent(args) {
|
|
2953
|
+
const {gdr: gdr, layout: layout, state: state} = args, compact = isCompact(layout);
|
|
2573
2954
|
switch (state.kind) {
|
|
2574
2955
|
case "linked":
|
|
2575
|
-
/* @__PURE__ */
|
|
2576
|
-
return jsxRuntime.jsx(LinkedDocPreview, {
|
|
2956
|
+
return compact ? /* @__PURE__ */ jsxRuntime.jsx(InlineChipFace, {
|
|
2577
2957
|
bareId: state.bareId,
|
|
2578
|
-
|
|
2958
|
+
schemaType: state.schemaType
|
|
2959
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(StubPreview, {
|
|
2960
|
+
id: state.bareId,
|
|
2579
2961
|
schemaType: state.schemaType
|
|
2580
2962
|
});
|
|
2581
2963
|
|
|
2582
2964
|
case "foreign":
|
|
2583
|
-
|
|
2584
|
-
return jsxRuntime.jsx(ForeignRefNotice, {
|
|
2585
|
-
bareId: state.bareId,
|
|
2586
|
-
resource: state.resource
|
|
2587
|
-
});
|
|
2965
|
+
return foreignNotice(state.bareId, state.resource);
|
|
2588
2966
|
|
|
2589
2967
|
case "missing":
|
|
2590
|
-
|
|
2591
|
-
return jsxRuntime.jsx(MissingDocNotice, {
|
|
2592
|
-
bareId: state.bareId,
|
|
2593
|
-
layout: layout
|
|
2594
|
-
});
|
|
2968
|
+
return missingNotice(state.bareId, layout);
|
|
2595
2969
|
|
|
2596
2970
|
case "unopenable":
|
|
2597
2971
|
/* @__PURE__ */
|
|
@@ -2602,10 +2976,9 @@ function DocPreviewLink({gdr: gdr, layout: layout = "default"}) {
|
|
|
2602
2976
|
|
|
2603
2977
|
case "pending":
|
|
2604
2978
|
/* @__PURE__ */
|
|
2605
|
-
return jsxRuntime.jsx(
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
children: state.bareId
|
|
2979
|
+
return jsxRuntime.jsx(PendingDocFace, {
|
|
2980
|
+
bareId: state.bareId,
|
|
2981
|
+
layout: layout
|
|
2609
2982
|
});
|
|
2610
2983
|
|
|
2611
2984
|
case "unresolvable":
|
|
@@ -2618,6 +2991,27 @@ function DocPreviewLink({gdr: gdr, layout: layout = "default"}) {
|
|
|
2618
2991
|
}
|
|
2619
2992
|
}
|
|
2620
2993
|
|
|
2994
|
+
function docFace(args) {
|
|
2995
|
+
return {
|
|
2996
|
+
...docFaceChrome(args),
|
|
2997
|
+
content: faceContent(args)
|
|
2998
|
+
};
|
|
2999
|
+
}
|
|
3000
|
+
|
|
3001
|
+
function DocPreviewLink({gdr: gdr, layout: layout = "default", source: source}) {
|
|
3002
|
+
const state = useDocLink(gdr);
|
|
3003
|
+
/* @__PURE__ */
|
|
3004
|
+
return jsxRuntime.jsx(DocRefShell, {
|
|
3005
|
+
face: docFace({
|
|
3006
|
+
gdr: gdr,
|
|
3007
|
+
layout: layout,
|
|
3008
|
+
state: state
|
|
3009
|
+
}),
|
|
3010
|
+
layout: layout,
|
|
3011
|
+
source: source
|
|
3012
|
+
});
|
|
3013
|
+
}
|
|
3014
|
+
|
|
2621
3015
|
function ReleaseLink({releaseName: releaseName, label: label}) {
|
|
2622
3016
|
const {basePath: basePath} = sanity.useWorkspace(), href = `${basePath === "/" ? "" : basePath}/releases/${releaseName}`;
|
|
2623
3017
|
/* @__PURE__ */
|
|
@@ -2676,7 +3070,8 @@ function renderTextValue(field) {
|
|
|
2676
3070
|
|
|
2677
3071
|
function renderSingleDocRef(field) {
|
|
2678
3072
|
return field.value ? /* @__PURE__ */ jsxRuntime.jsx(DocPreviewLink, {
|
|
2679
|
-
gdr: field.value
|
|
3073
|
+
gdr: field.value,
|
|
3074
|
+
source: "field-value"
|
|
2680
3075
|
}) : /* @__PURE__ */ jsxRuntime.jsx(Empty, {});
|
|
2681
3076
|
}
|
|
2682
3077
|
|
|
@@ -2698,12 +3093,15 @@ const fieldValueRenderer = {
|
|
|
2698
3093
|
children: formatBoolean(field.value)
|
|
2699
3094
|
}),
|
|
2700
3095
|
date: renderTextValue,
|
|
3096
|
+
dueDate: renderTextValue,
|
|
2701
3097
|
datetime: renderTextValue,
|
|
3098
|
+
dueDatetime: renderTextValue,
|
|
2702
3099
|
"doc.ref": renderSingleDocRef,
|
|
2703
3100
|
"doc.refs": field => field.value.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
|
|
2704
3101
|
gap: 2,
|
|
2705
3102
|
children: field.value.map(ref => /* @__PURE__ */ jsxRuntime.jsx(DocPreviewLink, {
|
|
2706
|
-
gdr: ref
|
|
3103
|
+
gdr: ref,
|
|
3104
|
+
source: "field-value"
|
|
2707
3105
|
}, ref.id))
|
|
2708
3106
|
}) : /* @__PURE__ */ jsxRuntime.jsx(Empty, {}),
|
|
2709
3107
|
number: renderTextValue,
|
|
@@ -2925,6 +3323,27 @@ function ReadOnlyField({entry: entry}) {
|
|
|
2925
3323
|
});
|
|
2926
3324
|
}
|
|
2927
3325
|
|
|
3326
|
+
function useEditField(surface) {
|
|
3327
|
+
const {editFieldFor: editFieldFor} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry();
|
|
3328
|
+
return react.useCallback(async ({instanceId: instanceId, field: field, ...change}) => {
|
|
3329
|
+
const log = success => telemetry2.log(WorkflowFieldControlUsed, {
|
|
3330
|
+
instanceId: instanceId,
|
|
3331
|
+
surface: surface,
|
|
3332
|
+
fieldKind: field.type,
|
|
3333
|
+
success: success
|
|
3334
|
+
});
|
|
3335
|
+
try {
|
|
3336
|
+
await editFieldFor(instanceId, {
|
|
3337
|
+
...change,
|
|
3338
|
+
target: workflowReact.editFieldTarget(field)
|
|
3339
|
+
});
|
|
3340
|
+
} catch (err) {
|
|
3341
|
+
throw log(!1), err;
|
|
3342
|
+
}
|
|
3343
|
+
log(!0);
|
|
3344
|
+
}, [ editFieldFor, surface, telemetry2 ]);
|
|
3345
|
+
}
|
|
3346
|
+
|
|
2928
3347
|
function sameValue(a, b) {
|
|
2929
3348
|
return (a ?? void 0) === (b ?? void 0);
|
|
2930
3349
|
}
|
|
@@ -2961,11 +3380,12 @@ function useFieldDraft(args) {
|
|
|
2961
3380
|
};
|
|
2962
3381
|
}
|
|
2963
3382
|
|
|
2964
|
-
function EditableFieldControl({instanceId: instanceId, field: field}) {
|
|
2965
|
-
const {
|
|
3383
|
+
function EditableFieldControl({instanceId: instanceId, field: field, surface: surface}) {
|
|
3384
|
+
const {previewFieldFor: previewFieldFor, discardFieldPreviewFor: discardFieldPreviewFor} = useWorkflowContext(), editField = useEditField(surface), selfActor = useSelfActor(), held = useHeldWorkflowEntry(instanceId), entry = held ? workflowEngine.resolveFieldEntry(held.instance, field) : void 0, evaluation = held?.evaluation, target = workflowReact.editFieldTarget(field), consequence = fieldConsequence(evaluation, field.name), advanceTo = advanceTargetTitle(evaluation, field.name);
|
|
2966
3385
|
/* @__PURE__ */
|
|
2967
3386
|
return jsxRuntime.jsx(EditableField, {
|
|
2968
3387
|
field: field,
|
|
3388
|
+
instanceId: instanceId,
|
|
2969
3389
|
...entry === void 0 ? {} : {
|
|
2970
3390
|
entry: entry
|
|
2971
3391
|
},
|
|
@@ -2978,30 +3398,33 @@ function EditableFieldControl({instanceId: instanceId, field: field}) {
|
|
|
2978
3398
|
...advanceTo === void 0 ? {} : {
|
|
2979
3399
|
advanceTo: advanceTo
|
|
2980
3400
|
},
|
|
2981
|
-
onSave: value =>
|
|
2982
|
-
|
|
3401
|
+
onSave: value => editField({
|
|
3402
|
+
instanceId: instanceId,
|
|
3403
|
+
field: field,
|
|
2983
3404
|
mode: "set",
|
|
2984
3405
|
value: value
|
|
2985
|
-
})
|
|
3406
|
+
}),
|
|
2986
3407
|
onPreview: value => previewFieldFor(instanceId, {
|
|
2987
3408
|
target: target,
|
|
2988
3409
|
mode: "set",
|
|
2989
3410
|
value: value
|
|
2990
3411
|
}),
|
|
2991
3412
|
onDiscardPreview: () => discardFieldPreviewFor(instanceId, target),
|
|
2992
|
-
onUnset: () =>
|
|
2993
|
-
|
|
3413
|
+
onUnset: () => editField({
|
|
3414
|
+
instanceId: instanceId,
|
|
3415
|
+
field: field,
|
|
2994
3416
|
mode: "unset"
|
|
2995
|
-
})
|
|
2996
|
-
onAppend: body =>
|
|
2997
|
-
|
|
3417
|
+
}),
|
|
3418
|
+
onAppend: body => editField({
|
|
3419
|
+
instanceId: instanceId,
|
|
3420
|
+
field: field,
|
|
2998
3421
|
mode: "append",
|
|
2999
3422
|
value: noteRow({
|
|
3000
3423
|
body: body,
|
|
3001
3424
|
actor: selfActor,
|
|
3002
3425
|
at: /* @__PURE__ */ (new Date).toISOString()
|
|
3003
3426
|
})
|
|
3004
|
-
})
|
|
3427
|
+
})
|
|
3005
3428
|
});
|
|
3006
3429
|
}
|
|
3007
3430
|
|
|
@@ -3029,28 +3452,34 @@ function EditableValueButton({children: children, hint: hint, hintDisabled: hint
|
|
|
3029
3452
|
});
|
|
3030
3453
|
}
|
|
3031
3454
|
|
|
3032
|
-
function
|
|
3033
|
-
const
|
|
3034
|
-
return
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3455
|
+
function useFieldSaveReport(instanceId) {
|
|
3456
|
+
const report = useRejectionReport();
|
|
3457
|
+
return react.useMemo(() => {
|
|
3458
|
+
const id = instanceToastId("field-save", instanceId);
|
|
3459
|
+
return {
|
|
3460
|
+
rejected: err => report.rejected({
|
|
3461
|
+
err: err,
|
|
3462
|
+
context: "field save",
|
|
3463
|
+
id: id,
|
|
3464
|
+
refused: "This field can’t be edited right now",
|
|
3465
|
+
failed: "Failed to save the field"
|
|
3466
|
+
}),
|
|
3467
|
+
dismiss: () => report.dismiss(id)
|
|
3468
|
+
};
|
|
3469
|
+
}, [ report, instanceId ]);
|
|
3041
3470
|
}
|
|
3042
3471
|
|
|
3043
|
-
function useSaveField(args
|
|
3044
|
-
const
|
|
3472
|
+
function useSaveField(args) {
|
|
3473
|
+
const report = useFieldSaveReport(args.instanceId), [saving, setSaving] = react.useState(!1);
|
|
3045
3474
|
return {
|
|
3046
3475
|
saving: saving,
|
|
3047
3476
|
save: async commit => {
|
|
3048
3477
|
if (!saving) {
|
|
3049
3478
|
setSaving(!0);
|
|
3050
3479
|
try {
|
|
3051
|
-
await commit(), args.onSaved?.();
|
|
3480
|
+
await commit(), report.dismiss(), args.onSaved?.();
|
|
3052
3481
|
} catch (err) {
|
|
3053
|
-
|
|
3482
|
+
report.rejected(err);
|
|
3054
3483
|
} finally {
|
|
3055
3484
|
setSaving(!1);
|
|
3056
3485
|
}
|
|
@@ -3060,7 +3489,9 @@ function useSaveField(args = {}) {
|
|
|
3060
3489
|
}
|
|
3061
3490
|
|
|
3062
3491
|
function useActorPick(args) {
|
|
3063
|
-
const {current: current, onSave: onSave, onUnset: onUnset} = args, {saving: saving, save: save} = useSaveField(
|
|
3492
|
+
const {current: current, onSave: onSave, onUnset: onUnset} = args, {saving: saving, save: save} = useSaveField({
|
|
3493
|
+
instanceId: args.instanceId
|
|
3494
|
+
});
|
|
3064
3495
|
return {
|
|
3065
3496
|
saving: saving,
|
|
3066
3497
|
pick: member => {
|
|
@@ -3069,9 +3500,10 @@ function useActorPick(args) {
|
|
|
3069
3500
|
};
|
|
3070
3501
|
}
|
|
3071
3502
|
|
|
3072
|
-
function ActorField({field: field, onSave: onSave, onUnset: onUnset}) {
|
|
3503
|
+
function ActorField({field: field, instanceId: instanceId, onSave: onSave, onUnset: onUnset}) {
|
|
3073
3504
|
const [open, setOpen] = react.useState(!1), cur = isActorShape(field.value) ? field.value : null, {pick: pick} = useActorPick({
|
|
3074
3505
|
current: cur,
|
|
3506
|
+
instanceId: instanceId,
|
|
3075
3507
|
onSave: onSave,
|
|
3076
3508
|
onUnset: onUnset
|
|
3077
3509
|
}), pickAndClose = member => {
|
|
@@ -3106,7 +3538,9 @@ function ActorField({field: field, onSave: onSave, onUnset: onUnset}) {
|
|
|
3106
3538
|
}
|
|
3107
3539
|
|
|
3108
3540
|
function useAssigneePick(args) {
|
|
3109
|
-
const {current: current, onSave: onSave, onUnset: onUnset} = args, {saving: saving, save: save} = useSaveField(
|
|
3541
|
+
const {current: current, onSave: onSave, onUnset: onUnset} = args, {saving: saving, save: save} = useSaveField({
|
|
3542
|
+
instanceId: args.instanceId
|
|
3543
|
+
});
|
|
3110
3544
|
return {
|
|
3111
3545
|
saving: saving,
|
|
3112
3546
|
pick: assignee => {
|
|
@@ -3121,9 +3555,10 @@ function useAssigneePick(args) {
|
|
|
3121
3555
|
};
|
|
3122
3556
|
}
|
|
3123
3557
|
|
|
3124
|
-
function AssigneeField({field: field, onSave: onSave, onUnset: onUnset}) {
|
|
3558
|
+
function AssigneeField({field: field, instanceId: instanceId, onSave: onSave, onUnset: onUnset}) {
|
|
3125
3559
|
const [open, setOpen] = react.useState(!1), cur = isAssigneeShape(field.value) ? field.value : null, {pick: pick} = useAssigneePick({
|
|
3126
3560
|
current: cur,
|
|
3561
|
+
instanceId: instanceId,
|
|
3127
3562
|
onSave: onSave,
|
|
3128
3563
|
onUnset: onUnset
|
|
3129
3564
|
}), pickAndClose = assignee => {
|
|
@@ -3163,8 +3598,10 @@ function arrayRowsOf(value) {
|
|
|
3163
3598
|
return Array.isArray(value) ? value.filter(row => typeof row == "object" && row !== null) : [];
|
|
3164
3599
|
}
|
|
3165
3600
|
|
|
3166
|
-
function NotesField({field: field, onAppend: onAppend}) {
|
|
3167
|
-
const [body, setBody] = react.useState(""), {saving: saving, save: save} = useSaveField(
|
|
3601
|
+
function NotesField({field: field, instanceId: instanceId, onAppend: onAppend}) {
|
|
3602
|
+
const [body, setBody] = react.useState(""), {saving: saving, save: save} = useSaveField({
|
|
3603
|
+
instanceId: instanceId
|
|
3604
|
+
}), rows = arrayRowsOf(field.value), trimmed = body.trim(), add = () => {
|
|
3168
3605
|
saving || trimmed === "" || (setBody(""), save(async () => {
|
|
3169
3606
|
try {
|
|
3170
3607
|
await onAppend(trimmed);
|
|
@@ -3205,11 +3642,13 @@ function NotesField({field: field, onAppend: onAppend}) {
|
|
|
3205
3642
|
});
|
|
3206
3643
|
}
|
|
3207
3644
|
|
|
3208
|
-
function DateField({field: field, onSave: onSave, onUnset: onUnset}) {
|
|
3209
|
-
const {save: save} = useSaveField(
|
|
3645
|
+
function DateField({field: field, kind: kind, instanceId: instanceId, onSave: onSave, onUnset: onUnset}) {
|
|
3646
|
+
const {save: save} = useSaveField({
|
|
3647
|
+
instanceId: instanceId
|
|
3648
|
+
});
|
|
3210
3649
|
/* @__PURE__ */
|
|
3211
3650
|
return jsxRuntime.jsx(DateFieldInput, {
|
|
3212
|
-
kind:
|
|
3651
|
+
kind: kind,
|
|
3213
3652
|
onChange: next => {
|
|
3214
3653
|
save(() => next === null && onUnset !== void 0 ? onUnset() : onSave(next));
|
|
3215
3654
|
},
|
|
@@ -3217,8 +3656,10 @@ function DateField({field: field, onSave: onSave, onUnset: onUnset}) {
|
|
|
3217
3656
|
});
|
|
3218
3657
|
}
|
|
3219
3658
|
|
|
3220
|
-
function DocRefField({field: field, entry: entry, onSave: onSave, onUnset: onUnset}) {
|
|
3221
|
-
const {save: save} = useSaveField(
|
|
3659
|
+
function DocRefField({field: field, entry: entry, instanceId: instanceId, onSave: onSave, onUnset: onUnset}) {
|
|
3660
|
+
const {save: save} = useSaveField({
|
|
3661
|
+
instanceId: instanceId
|
|
3662
|
+
}), value = workflowEngine.isGdr(field.value) ? field.value : null, types2 = entry !== void 0 && workflowEngine.isSingleDocRefEntry(entry) ? entry.types : void 0;
|
|
3222
3663
|
return field.editable ? /* @__PURE__ */ jsxRuntime.jsx(DocPicker, {
|
|
3223
3664
|
onChange: ref => {
|
|
3224
3665
|
save(() => ref === null && onUnset !== void 0 ? onUnset() : onSave(ref));
|
|
@@ -3233,8 +3674,10 @@ function DocRefField({field: field, entry: entry, onSave: onSave, onUnset: onUns
|
|
|
3233
3674
|
});
|
|
3234
3675
|
}
|
|
3235
3676
|
|
|
3236
|
-
function BooleanSwitchField({field: field, onSave: onSave}) {
|
|
3237
|
-
const {save: save} = useSaveField(
|
|
3677
|
+
function BooleanSwitchField({field: field, instanceId: instanceId, onSave: onSave}) {
|
|
3678
|
+
const {save: save} = useSaveField({
|
|
3679
|
+
instanceId: instanceId
|
|
3680
|
+
}), committed = field.value === !0;
|
|
3238
3681
|
/* @__PURE__ */
|
|
3239
3682
|
return jsxRuntime.jsx(ui.Flex, {
|
|
3240
3683
|
align: "center",
|
|
@@ -3247,8 +3690,10 @@ function BooleanSwitchField({field: field, onSave: onSave}) {
|
|
|
3247
3690
|
});
|
|
3248
3691
|
}
|
|
3249
3692
|
|
|
3250
|
-
function ChoiceField({field: field, options: options, onSave: onSave, onUnset: onUnset}) {
|
|
3251
|
-
const {save: save} = useSaveField(
|
|
3693
|
+
function ChoiceField({field: field, instanceId: instanceId, options: options, onSave: onSave, onUnset: onUnset}) {
|
|
3694
|
+
const {save: save} = useSaveField({
|
|
3695
|
+
instanceId: instanceId
|
|
3696
|
+
});
|
|
3252
3697
|
/* @__PURE__ */
|
|
3253
3698
|
return jsxRuntime.jsx(ChoiceSelect, {
|
|
3254
3699
|
onChange: value => {
|
|
@@ -3322,8 +3767,8 @@ function FieldEditRow({field: field, onSave: onSave, onCancel: onCancel, saving:
|
|
|
3322
3767
|
});
|
|
3323
3768
|
}
|
|
3324
3769
|
|
|
3325
|
-
function GenericField({field: field, onSave: onSave, onPreview: onPreview, onDiscardPreview: onDiscardPreview}) {
|
|
3326
|
-
const
|
|
3770
|
+
function GenericField({field: field, onSave: onSave, instanceId: instanceId, onPreview: onPreview, onDiscardPreview: onDiscardPreview}) {
|
|
3771
|
+
const report = useFieldSaveReport(instanceId), canSave = value => scalarValidationIssue({
|
|
3327
3772
|
kind: field.type,
|
|
3328
3773
|
label: field.title ?? field.name,
|
|
3329
3774
|
validation: field.validation,
|
|
@@ -3334,7 +3779,7 @@ function GenericField({field: field, onSave: onSave, onPreview: onPreview, onDis
|
|
|
3334
3779
|
onPreview: onPreview,
|
|
3335
3780
|
onDiscardPreview: onDiscardPreview,
|
|
3336
3781
|
canSave: canSave,
|
|
3337
|
-
onSaveFailure:
|
|
3782
|
+
onSaveFailure: report.rejected
|
|
3338
3783
|
}), validationIssue = scalarValidationIssue({
|
|
3339
3784
|
kind: field.type,
|
|
3340
3785
|
label: field.title ?? field.name,
|
|
@@ -3380,9 +3825,10 @@ function AdvanceHint({stageTitle: stageTitle2}) {
|
|
|
3380
3825
|
});
|
|
3381
3826
|
}
|
|
3382
3827
|
|
|
3383
|
-
function arrayArm({field: field, entry: entry, onAppend: onAppend}) {
|
|
3828
|
+
function arrayArm({field: field, entry: entry, instanceId: instanceId, onAppend: onAppend}) {
|
|
3384
3829
|
return field.editable && onAppend !== void 0 && entry !== void 0 && workflowEngine.isNotesEntry(entry) ? /* @__PURE__ */ jsxRuntime.jsx(NotesField, {
|
|
3385
3830
|
field: field,
|
|
3831
|
+
instanceId: instanceId,
|
|
3386
3832
|
onAppend: onAppend
|
|
3387
3833
|
}) : /* @__PURE__ */ jsxRuntime.jsx(ArrayValueRows, {
|
|
3388
3834
|
rows: arrayRowsOf(field.value)
|
|
@@ -3390,7 +3836,7 @@ function arrayArm({field: field, entry: entry, onAppend: onAppend}) {
|
|
|
3390
3836
|
}
|
|
3391
3837
|
|
|
3392
3838
|
function fieldArm({arm: arm, entry: entry, onUnset: onUnset, onAppend: onAppend, onPreview: onPreview, onDiscardPreview: onDiscardPreview}) {
|
|
3393
|
-
const {field: field} = arm;
|
|
3839
|
+
const {field: field, instanceId: instanceId} = arm;
|
|
3394
3840
|
return field.type === "actor" ? /* @__PURE__ */ jsxRuntime.jsx(ActorField, {
|
|
3395
3841
|
...arm,
|
|
3396
3842
|
onUnset: onUnset
|
|
@@ -3403,11 +3849,13 @@ function fieldArm({arm: arm, entry: entry, onUnset: onUnset, onAppend: onAppend,
|
|
|
3403
3849
|
}) : field.type === "array" ? arrayArm({
|
|
3404
3850
|
field: field,
|
|
3405
3851
|
entry: entry,
|
|
3852
|
+
instanceId: instanceId,
|
|
3406
3853
|
onAppend: onAppend
|
|
3407
3854
|
}) : field.type === "boolean" && field.editable ? /* @__PURE__ */ jsxRuntime.jsx(BooleanSwitchField, {
|
|
3408
3855
|
...arm
|
|
3409
|
-
}) : (field.type
|
|
3856
|
+
}) : isDateFieldKind(field.type) && field.editable ? /* @__PURE__ */ jsxRuntime.jsx(DateField, {
|
|
3410
3857
|
...arm,
|
|
3858
|
+
kind: field.type,
|
|
3411
3859
|
onUnset: onUnset
|
|
3412
3860
|
}) : workflowEngine.isSingleDocRefKind(field.type) ? /* @__PURE__ */ jsxRuntime.jsx(DocRefField, {
|
|
3413
3861
|
...arm,
|
|
@@ -3420,9 +3868,10 @@ function fieldArm({arm: arm, entry: entry, onUnset: onUnset, onAppend: onAppend,
|
|
|
3420
3868
|
});
|
|
3421
3869
|
}
|
|
3422
3870
|
|
|
3423
|
-
function EditableField({field: field, entry: entry, description: description, onSave: onSave, onUnset: onUnset, onAppend: onAppend, onPreview: onPreview, onDiscardPreview: onDiscardPreview, consequence: consequence, advanceTo: advanceTo}) {
|
|
3871
|
+
function EditableField({field: field, entry: entry, description: description, instanceId: instanceId, onSave: onSave, onUnset: onUnset, onAppend: onAppend, onPreview: onPreview, onDiscardPreview: onDiscardPreview, consequence: consequence, advanceTo: advanceTo}) {
|
|
3424
3872
|
const label = field.title ?? field.name, arm = {
|
|
3425
3873
|
field: field,
|
|
3874
|
+
instanceId: instanceId,
|
|
3426
3875
|
onSave: onSave
|
|
3427
3876
|
}, content2 = entry?.options === void 0 ? fieldArm({
|
|
3428
3877
|
arm: arm,
|
|
@@ -3454,11 +3903,15 @@ function EditableField({field: field, entry: entry, description: description, on
|
|
|
3454
3903
|
});
|
|
3455
3904
|
}
|
|
3456
3905
|
|
|
3457
|
-
function MetaRow({
|
|
3906
|
+
function MetaRow({children: children, fillHeight: fillHeight, label: label}) {
|
|
3458
3907
|
/* @__PURE__ */
|
|
3459
3908
|
return jsxRuntime.jsxs(ui.Flex, {
|
|
3460
|
-
align: "flex-start",
|
|
3461
3909
|
gap: 4,
|
|
3910
|
+
...fillHeight ? {
|
|
3911
|
+
flex: 1
|
|
3912
|
+
} : {
|
|
3913
|
+
align: "flex-start"
|
|
3914
|
+
},
|
|
3462
3915
|
children: [
|
|
3463
3916
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
3464
3917
|
style: {
|
|
@@ -3531,27 +3984,6 @@ function ActivityStatusIcon({status: status}) {
|
|
|
3531
3984
|
});
|
|
3532
3985
|
}
|
|
3533
3986
|
|
|
3534
|
-
function LoadingRow({label: label, padding: padding}) {
|
|
3535
|
-
/* @__PURE__ */
|
|
3536
|
-
return jsxRuntime.jsxs(ui.Flex, {
|
|
3537
|
-
align: "center",
|
|
3538
|
-
gap: 2,
|
|
3539
|
-
...padding === void 0 ? {} : {
|
|
3540
|
-
padding: padding
|
|
3541
|
-
},
|
|
3542
|
-
children: [
|
|
3543
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, {
|
|
3544
|
-
muted: !0,
|
|
3545
|
-
size: 1
|
|
3546
|
-
}),
|
|
3547
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
3548
|
-
muted: !0,
|
|
3549
|
-
size: 1,
|
|
3550
|
-
children: label
|
|
3551
|
-
}) ]
|
|
3552
|
-
});
|
|
3553
|
-
}
|
|
3554
|
-
|
|
3555
3987
|
function useSpaceToken(index) {
|
|
3556
3988
|
const value = ui.useTheme_v2().space[index];
|
|
3557
3989
|
if (value === void 0) throw new Error(`theme is missing space token ${index}`);
|
|
@@ -3598,6 +4030,46 @@ function useBadgeCapTrim() {
|
|
|
3598
4030
|
};
|
|
3599
4031
|
}
|
|
3600
4032
|
|
|
4033
|
+
function SpinnerSlot({busy: busy}) {
|
|
4034
|
+
const size = useTextIconSize(), trim = useCapTrimFor(size);
|
|
4035
|
+
/* @__PURE__ */
|
|
4036
|
+
return jsxRuntime.jsx(ui.Flex, {
|
|
4037
|
+
align: "center",
|
|
4038
|
+
flex: "none",
|
|
4039
|
+
justify: "center",
|
|
4040
|
+
style: {
|
|
4041
|
+
height: size,
|
|
4042
|
+
marginBottom: trim,
|
|
4043
|
+
marginTop: trim,
|
|
4044
|
+
width: size
|
|
4045
|
+
},
|
|
4046
|
+
children: busy ? /* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, {
|
|
4047
|
+
muted: !0,
|
|
4048
|
+
size: 1
|
|
4049
|
+
}) : null
|
|
4050
|
+
});
|
|
4051
|
+
}
|
|
4052
|
+
|
|
4053
|
+
function LoadingRow({label: label, padding: padding}) {
|
|
4054
|
+
/* @__PURE__ */
|
|
4055
|
+
return jsxRuntime.jsxs(ui.Flex, {
|
|
4056
|
+
align: "center",
|
|
4057
|
+
gap: 2,
|
|
4058
|
+
...padding === void 0 ? {} : {
|
|
4059
|
+
padding: padding
|
|
4060
|
+
},
|
|
4061
|
+
children: [
|
|
4062
|
+
/* @__PURE__ */ jsxRuntime.jsx(SpinnerSlot, {
|
|
4063
|
+
busy: !0
|
|
4064
|
+
}),
|
|
4065
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
4066
|
+
muted: !0,
|
|
4067
|
+
size: 1,
|
|
4068
|
+
children: label
|
|
4069
|
+
}) ]
|
|
4070
|
+
});
|
|
4071
|
+
}
|
|
4072
|
+
|
|
3601
4073
|
function AvatarDisplay({avatar: avatar, "aria-label": ariaLabel}) {
|
|
3602
4074
|
const trim = useAvatarCapTrim();
|
|
3603
4075
|
/* @__PURE__ */
|
|
@@ -3678,8 +4150,8 @@ function UserAvatarGroup({ids: ids, hint: hint}) {
|
|
|
3678
4150
|
});
|
|
3679
4151
|
}
|
|
3680
4152
|
|
|
3681
|
-
function AssignActivityControl({instanceId: instanceId, state: state, assigneeIds: assigneeIds = []}) {
|
|
3682
|
-
const
|
|
4153
|
+
function AssignActivityControl({instanceId: instanceId, state: state, surface: surface, assigneeIds: assigneeIds = []}) {
|
|
4154
|
+
const editField = useEditField(surface), report = useRejectionReport(), [open, setOpen] = react.useState(!1), [busy, setBusy] = react.useState(!1);
|
|
3683
4155
|
if (state.kind === "none") return assigneeIds.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(AvatarDisplay, {
|
|
3684
4156
|
"aria-label": "Assignees",
|
|
3685
4157
|
avatar: /* @__PURE__ */ jsxRuntime.jsx(UserAvatarGroup, {
|
|
@@ -3700,23 +4172,27 @@ function AssignActivityControl({instanceId: instanceId, state: state, assigneeId
|
|
|
3700
4172
|
if (!(busy || field === void 0)) {
|
|
3701
4173
|
setBusy(!0);
|
|
3702
4174
|
try {
|
|
3703
|
-
selectedIds.has(memberId) ? await
|
|
3704
|
-
|
|
4175
|
+
selectedIds.has(memberId) ? await editField({
|
|
4176
|
+
instanceId: instanceId,
|
|
4177
|
+
field: field,
|
|
3705
4178
|
mode: "set",
|
|
3706
4179
|
value: members.filter(m => !(m.type === "user" && m.id === memberId))
|
|
3707
|
-
}) : await
|
|
3708
|
-
|
|
4180
|
+
}) : await editField({
|
|
4181
|
+
instanceId: instanceId,
|
|
4182
|
+
field: field,
|
|
3709
4183
|
mode: "append",
|
|
3710
4184
|
value: {
|
|
3711
4185
|
type: "user",
|
|
3712
4186
|
id: memberId
|
|
3713
4187
|
}
|
|
3714
|
-
});
|
|
4188
|
+
}), report.dismiss(instanceToastId("assign", instanceId));
|
|
3715
4189
|
} catch (err) {
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
4190
|
+
report.rejected({
|
|
4191
|
+
err: err,
|
|
4192
|
+
context: "assignment",
|
|
4193
|
+
id: instanceToastId("assign", instanceId),
|
|
4194
|
+
refused: "Assignees can’t be changed right now",
|
|
4195
|
+
failed: "Failed to update assignees"
|
|
3720
4196
|
});
|
|
3721
4197
|
} finally {
|
|
3722
4198
|
setBusy(!1);
|
|
@@ -3783,6 +4259,11 @@ function appendTargetFor(targets, filter) {
|
|
|
3783
4259
|
if (filter?.kind !== "mine") return filter?.kind === "activity" ? targets.find(t => t.activity === filter.activity) : filter?.kind === "field" ? targets.find(t => t.scope === filter.scope && t.field === filter.field && (filter.scope !== "activity" || t.activity === filter.activity)) : targets[0];
|
|
3784
4260
|
}
|
|
3785
4261
|
|
|
4262
|
+
function canRemoveRow(args) {
|
|
4263
|
+
const {editTarget: editTarget, appendTarget: appendTarget} = args;
|
|
4264
|
+
return editTarget === void 0 || appendTarget === void 0 ? !1 : editTarget.scope === appendTarget.scope && editTarget.field === appendTarget.field && editTarget.activity === appendTarget.activity;
|
|
4265
|
+
}
|
|
4266
|
+
|
|
3786
4267
|
function looksLikeDefinition(value) {
|
|
3787
4268
|
return typeof value == "object" && value !== null && Array.isArray(value.stages);
|
|
3788
4269
|
}
|
|
@@ -4024,6 +4505,21 @@ function AddItemControl({onAdd: onAdd, button: button, busy: busy}) {
|
|
|
4024
4505
|
});
|
|
4025
4506
|
}
|
|
4026
4507
|
|
|
4508
|
+
function RemoveItemButton({onClick: onClick}) {
|
|
4509
|
+
/* @__PURE__ */
|
|
4510
|
+
return jsxRuntime.jsx(HoverHint, {
|
|
4511
|
+
text: "Remove item",
|
|
4512
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
4513
|
+
"aria-label": "Remove item",
|
|
4514
|
+
fontSize: 1,
|
|
4515
|
+
icon: Close.CloseIcon,
|
|
4516
|
+
mode: "bleed",
|
|
4517
|
+
onClick: onClick,
|
|
4518
|
+
padding: 2
|
|
4519
|
+
})
|
|
4520
|
+
});
|
|
4521
|
+
}
|
|
4522
|
+
|
|
4027
4523
|
function BreadcrumbTail({segments: segments, style: style}) {
|
|
4028
4524
|
/* @__PURE__ */
|
|
4029
4525
|
return jsxRuntime.jsx(ui.Text, {
|
|
@@ -4090,7 +4586,7 @@ function WorkRow({lead: lead, children: children, end: end, onOpen: onOpen}) {
|
|
|
4090
4586
|
});
|
|
4091
4587
|
}
|
|
4092
4588
|
|
|
4093
|
-
function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle, onPatch: onPatch}) {
|
|
4589
|
+
function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle, onPatch: onPatch, onRemove: onRemove}) {
|
|
4094
4590
|
const {canClick: canClick, hint: hint} = rowInteractivity(row), editable = row.editTarget !== void 0, checkbox = /* @__PURE__ */ jsxRuntime.jsx(TodoCheckbox, {
|
|
4095
4591
|
canClick: canClick,
|
|
4096
4592
|
checked: isTodoDone(row.item),
|
|
@@ -4109,6 +4605,8 @@ function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle,
|
|
|
4109
4605
|
editable: editable,
|
|
4110
4606
|
item: row.item,
|
|
4111
4607
|
onPatch: onPatch
|
|
4608
|
+
}), onRemove === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(RemoveItemButton, {
|
|
4609
|
+
onClick: onRemove
|
|
4112
4610
|
}) ]
|
|
4113
4611
|
}),
|
|
4114
4612
|
lead:
|
|
@@ -4135,37 +4633,41 @@ function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle,
|
|
|
4135
4633
|
}
|
|
4136
4634
|
|
|
4137
4635
|
function TodoItemsList({breadcrumb: breadcrumb, entry: entry, filter: filter, surface: surface}) {
|
|
4138
|
-
const {instance: instance} = entry, definition = useDefinition(entry), {editFieldFor: editFieldFor, fireActionFor: fireActionFor} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry(),
|
|
4636
|
+
const {instance: instance} = entry, definition = useDefinition(entry), {editFieldFor: editFieldFor, fireActionFor: fireActionFor} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry(), report = useRejectionReport(), [busy, setBusy] = react.useState(!1), derivation = deriveTodoItems(entry), rows = derivation.rows.filter(row => rowMatches(row, filter)), appendTarget = appendTargetFor(derivation.appendTargets, filter), run = async op => {
|
|
4139
4637
|
if (busy) return !1;
|
|
4140
4638
|
setBusy(!0);
|
|
4141
4639
|
try {
|
|
4142
|
-
return await op(),
|
|
4640
|
+
return await op(), report.dismiss(instanceToastId("todo-write", instance._id)),
|
|
4641
|
+
!0;
|
|
4143
4642
|
} catch (err) {
|
|
4144
|
-
return
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4643
|
+
return report.rejected({
|
|
4644
|
+
err: err,
|
|
4645
|
+
context: "to-do write",
|
|
4646
|
+
id: instanceToastId("todo-write", instance._id),
|
|
4647
|
+
refused: "To-dos can’t be changed right now",
|
|
4648
|
+
failed: "Failed to update to-dos"
|
|
4148
4649
|
}), !1;
|
|
4149
4650
|
} finally {
|
|
4150
4651
|
setBusy(!1);
|
|
4151
4652
|
}
|
|
4152
|
-
},
|
|
4153
|
-
if (!row.editTarget) return Promise.resolve();
|
|
4154
|
-
const target = row.editTarget
|
|
4155
|
-
...it,
|
|
4156
|
-
...patch
|
|
4157
|
-
} : it);
|
|
4653
|
+
}, writeItems = (row, nextItems) => {
|
|
4654
|
+
if (!row.editTarget) return Promise.resolve(!1);
|
|
4655
|
+
const target = row.editTarget;
|
|
4158
4656
|
return run(() => editFieldFor(instance._id, {
|
|
4159
4657
|
target: target,
|
|
4160
4658
|
mode: "set",
|
|
4161
|
-
value:
|
|
4659
|
+
value: nextItems()
|
|
4162
4660
|
}));
|
|
4163
|
-
},
|
|
4661
|
+
}, patchItem = (row, patch) => writeItems(row, () => todoItemsPatched({
|
|
4662
|
+
items: row.items,
|
|
4663
|
+
key: row.item._key,
|
|
4664
|
+
patch: patch
|
|
4665
|
+
})), toggleRow = async row => {
|
|
4164
4666
|
if (busy) return;
|
|
4165
4667
|
if (row.editTarget) {
|
|
4166
4668
|
const done = !isTodoDone(row.item), success = await patchItem(row, {
|
|
4167
4669
|
status: toggledTodoStatus(row.item)
|
|
4168
|
-
})
|
|
4670
|
+
});
|
|
4169
4671
|
telemetry2.log(WorkflowTodoToggled, {
|
|
4170
4672
|
instanceId: instance._id,
|
|
4171
4673
|
surface: surface,
|
|
@@ -4189,14 +4691,44 @@ function TodoItemsList({breadcrumb: breadcrumb, entry: entry, filter: filter, su
|
|
|
4189
4691
|
success: success
|
|
4190
4692
|
});
|
|
4191
4693
|
}
|
|
4192
|
-
}, addItem = label =>
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4694
|
+
}, addItem = async label => {
|
|
4695
|
+
if (busy || !appendTarget) return !1;
|
|
4696
|
+
const success = await run(() => editFieldFor(instance._id, {
|
|
4697
|
+
target: appendTarget,
|
|
4698
|
+
mode: "append",
|
|
4699
|
+
value: {
|
|
4700
|
+
label: label,
|
|
4701
|
+
status: "open"
|
|
4702
|
+
}
|
|
4703
|
+
}));
|
|
4704
|
+
return telemetry2.log(WorkflowTodoEdited, {
|
|
4705
|
+
instanceId: instance._id,
|
|
4706
|
+
surface: surface,
|
|
4707
|
+
kind: "add",
|
|
4708
|
+
success: success
|
|
4709
|
+
}), success;
|
|
4710
|
+
}, editRow = async (row, patch) => {
|
|
4711
|
+
if (busy || row.editTarget === void 0) return;
|
|
4712
|
+
const success = await patchItem(row, patch);
|
|
4713
|
+
telemetry2.log(WorkflowTodoEdited, {
|
|
4714
|
+
instanceId: instance._id,
|
|
4715
|
+
surface: surface,
|
|
4716
|
+
kind: todoEditKind(patch),
|
|
4717
|
+
success: success
|
|
4718
|
+
});
|
|
4719
|
+
}, removeRow = async row => {
|
|
4720
|
+
if (busy || row.editTarget === void 0) return;
|
|
4721
|
+
const success = await writeItems(row, () => todoItemsWithout({
|
|
4722
|
+
items: row.items,
|
|
4723
|
+
key: row.item._key
|
|
4724
|
+
}));
|
|
4725
|
+
telemetry2.log(WorkflowTodoEdited, {
|
|
4726
|
+
instanceId: instance._id,
|
|
4727
|
+
surface: surface,
|
|
4728
|
+
kind: "remove",
|
|
4729
|
+
success: success
|
|
4730
|
+
});
|
|
4731
|
+
};
|
|
4200
4732
|
if (rows.length === 0 && !appendTarget) return null;
|
|
4201
4733
|
const rowKey = row => `${row.scope}:${row.activityName ?? ""}:${row.fieldName}:${row.item._key}`, rowBreadcrumb = row => {
|
|
4202
4734
|
if (breadcrumb === void 0 || row.activityName === void 0) return breadcrumb;
|
|
@@ -4216,8 +4748,16 @@ function TodoItemsList({breadcrumb: breadcrumb, entry: entry, filter: filter, su
|
|
|
4216
4748
|
children: rows.map(row => /* @__PURE__ */ jsxRuntime.jsx(TodoItemRowView, {
|
|
4217
4749
|
breadcrumb: rowBreadcrumb(row),
|
|
4218
4750
|
onPatch: patch => {
|
|
4219
|
-
|
|
4751
|
+
editRow(row, patch);
|
|
4220
4752
|
},
|
|
4753
|
+
...canRemoveRow({
|
|
4754
|
+
editTarget: row.editTarget,
|
|
4755
|
+
appendTarget: appendTarget
|
|
4756
|
+
}) ? {
|
|
4757
|
+
onRemove: () => {
|
|
4758
|
+
removeRow(row);
|
|
4759
|
+
}
|
|
4760
|
+
} : {},
|
|
4221
4761
|
onToggle: () => {
|
|
4222
4762
|
toggleRow(row);
|
|
4223
4763
|
},
|
|
@@ -4305,7 +4845,7 @@ const ACTIONS_MENU_TRIGGER = {
|
|
|
4305
4845
|
padding: 2
|
|
4306
4846
|
};
|
|
4307
4847
|
|
|
4308
|
-
function ActionMenuItem({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, onCollectParams: onCollectParams}) {
|
|
4848
|
+
function ActionMenuItem({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, placement: placement, onCollectParams: onCollectParams}) {
|
|
4309
4849
|
const rowKind = actionRowKind(actionEval), label = actionTriggerLabel(actionEval), {tone: tone, icon: icon} = actionButtonFace({
|
|
4310
4850
|
actionEval: actionEval,
|
|
4311
4851
|
activityName: activity
|
|
@@ -4317,6 +4857,7 @@ function ActionMenuItem({actionEval: actionEval, instanceId: instanceId, activit
|
|
|
4317
4857
|
action: actionEval.action.name,
|
|
4318
4858
|
label: label,
|
|
4319
4859
|
surface: surface,
|
|
4860
|
+
placement: placement,
|
|
4320
4861
|
viaMenu: !0
|
|
4321
4862
|
});
|
|
4322
4863
|
return rowKind.kind === "disabled" ? /* @__PURE__ */ jsxRuntime.jsx(ui.MenuItem, {
|
|
@@ -4353,7 +4894,7 @@ function rowShield(menuButton) {
|
|
|
4353
4894
|
});
|
|
4354
4895
|
}
|
|
4355
4896
|
|
|
4356
|
-
function ActionsMenuButton({actions: actions, instanceId: instanceId, activity: activity, label: label, surface: surface, mode: mode = "ghost", inButtonCard: inButtonCard = !1}) {
|
|
4897
|
+
function ActionsMenuButton({actions: actions, instanceId: instanceId, activity: activity, label: label, surface: surface, placement: placement, mode: mode = "ghost", inButtonCard: inButtonCard = !1}) {
|
|
4357
4898
|
const [paramsAction, setParamsAction] = react.useState(void 0), clusterPending = useActionClusterPending(), menuId = react.useId(), menuButton = /* @__PURE__ */ jsxRuntime.jsx(ui.MenuButton, {
|
|
4358
4899
|
button: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
4359
4900
|
...ACTIONS_MENU_TRIGGER,
|
|
@@ -4373,6 +4914,7 @@ function ActionsMenuButton({actions: actions, instanceId: instanceId, activity:
|
|
|
4373
4914
|
activity: activity,
|
|
4374
4915
|
instanceId: instanceId,
|
|
4375
4916
|
onCollectParams: () => setParamsAction(a),
|
|
4917
|
+
placement: placement,
|
|
4376
4918
|
surface: surface
|
|
4377
4919
|
}, a.action.name))
|
|
4378
4920
|
}),
|
|
@@ -4390,6 +4932,7 @@ function ActionsMenuButton({actions: actions, instanceId: instanceId, activity:
|
|
|
4390
4932
|
activity: activity,
|
|
4391
4933
|
instanceId: instanceId,
|
|
4392
4934
|
onClose: () => setParamsAction(void 0),
|
|
4935
|
+
placement: placement,
|
|
4393
4936
|
surface: surface,
|
|
4394
4937
|
viaMenu: !0
|
|
4395
4938
|
})
|
|
@@ -4408,7 +4951,8 @@ function TerminalFooter({actions: actions, activity: activity, instanceId: insta
|
|
|
4408
4951
|
actionEval: only,
|
|
4409
4952
|
activity: activity,
|
|
4410
4953
|
instanceId: instanceId,
|
|
4411
|
-
|
|
4954
|
+
placement: "terminal-footer",
|
|
4955
|
+
surface: "activity-dialog"
|
|
4412
4956
|
})
|
|
4413
4957
|
}) : /* @__PURE__ */ jsxRuntime.jsx(FittedActions, {
|
|
4414
4958
|
actions: actions,
|
|
@@ -4463,14 +5007,16 @@ function FittedActions({actions: actions, activity: activity, instanceId: instan
|
|
|
4463
5007
|
actionEval: a,
|
|
4464
5008
|
activity: activity,
|
|
4465
5009
|
instanceId: instanceId,
|
|
4466
|
-
|
|
5010
|
+
placement: "terminal-footer",
|
|
5011
|
+
surface: "activity-dialog"
|
|
4467
5012
|
}, a.action.name)), overflow.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ActionsMenuButton, {
|
|
4468
5013
|
actions: overflow,
|
|
4469
5014
|
activity: activity,
|
|
4470
5015
|
instanceId: instanceId,
|
|
4471
5016
|
label: MORE_ACTIONS_LABEL,
|
|
4472
5017
|
mode: "default",
|
|
4473
|
-
|
|
5018
|
+
placement: "terminal-footer",
|
|
5019
|
+
surface: "activity-dialog"
|
|
4474
5020
|
}) : null ]
|
|
4475
5021
|
}) ]
|
|
4476
5022
|
});
|
|
@@ -4605,7 +5151,8 @@ function MetaBlock({detail: detail, definition: definition, document: document,
|
|
|
4605
5151
|
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
4606
5152
|
children: /* @__PURE__ */ jsxRuntime.jsx(DocPreviewLink, {
|
|
4607
5153
|
gdr: document,
|
|
4608
|
-
layout: "inline"
|
|
5154
|
+
layout: "inline",
|
|
5155
|
+
source: "dialog-subject"
|
|
4609
5156
|
})
|
|
4610
5157
|
})
|
|
4611
5158
|
}) : null,
|
|
@@ -4629,7 +5176,8 @@ function TopActions({detail: detail, definition: definition, instanceId: instanc
|
|
|
4629
5176
|
actionEval: a,
|
|
4630
5177
|
activity: activityName,
|
|
4631
5178
|
instanceId: instanceId,
|
|
4632
|
-
|
|
5179
|
+
placement: "dialog-strip",
|
|
5180
|
+
surface: "activity-dialog"
|
|
4633
5181
|
}, a.action.name)), p.manualTarget ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
4634
5182
|
as: "a",
|
|
4635
5183
|
fontSize: 1,
|
|
@@ -4687,7 +5235,8 @@ function FieldRow({field: field, detail: detail, entry: entry, activityName: act
|
|
|
4687
5235
|
state: {
|
|
4688
5236
|
kind: "editable",
|
|
4689
5237
|
field: assignField
|
|
4690
|
-
}
|
|
5238
|
+
},
|
|
5239
|
+
surface: "activity-dialog"
|
|
4691
5240
|
}) : null ]
|
|
4692
5241
|
}) ]
|
|
4693
5242
|
});
|
|
@@ -4695,7 +5244,8 @@ function FieldRow({field: field, detail: detail, entry: entry, activityName: act
|
|
|
4695
5244
|
const editable = detail.editableByName.get(field.name);
|
|
4696
5245
|
return editable ? /* @__PURE__ */ jsxRuntime.jsx(EditableFieldControl, {
|
|
4697
5246
|
field: editable,
|
|
4698
|
-
instanceId: instanceId
|
|
5247
|
+
instanceId: instanceId,
|
|
5248
|
+
surface: "activity-dialog"
|
|
4699
5249
|
}) : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
|
|
4700
5250
|
gap: 2,
|
|
4701
5251
|
children: [ head,
|
|
@@ -4788,26 +5338,6 @@ function CountedLabel({count: count, label: label}) {
|
|
|
4788
5338
|
});
|
|
4789
5339
|
}
|
|
4790
5340
|
|
|
4791
|
-
function SpinnerSlot({busy: busy}) {
|
|
4792
|
-
const size = useTextIconSize(), trim = useCapTrimFor(size);
|
|
4793
|
-
/* @__PURE__ */
|
|
4794
|
-
return jsxRuntime.jsx(ui.Flex, {
|
|
4795
|
-
align: "center",
|
|
4796
|
-
flex: "none",
|
|
4797
|
-
justify: "center",
|
|
4798
|
-
style: {
|
|
4799
|
-
height: size,
|
|
4800
|
-
marginBottom: trim,
|
|
4801
|
-
marginTop: trim,
|
|
4802
|
-
width: size
|
|
4803
|
-
},
|
|
4804
|
-
children: busy ? /* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, {
|
|
4805
|
-
muted: !0,
|
|
4806
|
-
size: 1
|
|
4807
|
-
}) : null
|
|
4808
|
-
});
|
|
4809
|
-
}
|
|
4810
|
-
|
|
4811
5341
|
function GroupHeading({busy: busy, count: count, title: title, end: end}) {
|
|
4812
5342
|
/* @__PURE__ */
|
|
4813
5343
|
return jsxRuntime.jsxs(ui.Flex, {
|
|
@@ -4823,14 +5353,100 @@ function GroupHeading({busy: busy, count: count, title: title, end: end}) {
|
|
|
4823
5353
|
weight: "semibold",
|
|
4824
5354
|
children: title
|
|
4825
5355
|
})
|
|
4826
|
-
}), busy === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(SpinnerSlot, {
|
|
4827
|
-
busy: busy
|
|
4828
|
-
}), end === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
4829
|
-
children: [
|
|
4830
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
4831
|
-
flex: 1
|
|
4832
|
-
}), end ]
|
|
4833
|
-
}) ]
|
|
5356
|
+
}), busy === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(SpinnerSlot, {
|
|
5357
|
+
busy: busy
|
|
5358
|
+
}), end === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
5359
|
+
children: [
|
|
5360
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
5361
|
+
flex: 1
|
|
5362
|
+
}), end ]
|
|
5363
|
+
}) ]
|
|
5364
|
+
});
|
|
5365
|
+
}
|
|
5366
|
+
|
|
5367
|
+
function ActivityDateControl({instanceId: instanceId, state: state, surface: surface, dueDates: dueDates}) {
|
|
5368
|
+
const editField = useEditField(surface), {save: save} = useSaveField({
|
|
5369
|
+
instanceId: instanceId
|
|
5370
|
+
}), [open, setOpen] = react.useState(!1), raw = dateControlValue({
|
|
5371
|
+
state: state,
|
|
5372
|
+
dueDates: dueDates
|
|
5373
|
+
}), display = raw === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
5374
|
+
muted: !0,
|
|
5375
|
+
size: 1,
|
|
5376
|
+
children: formatDate(raw)
|
|
5377
|
+
});
|
|
5378
|
+
if (state.kind === "none") return display;
|
|
5379
|
+
if (state.kind === "closed") return display === null ? null : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
|
|
5380
|
+
text: state.reason,
|
|
5381
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
5382
|
+
"aria-label": "Date",
|
|
5383
|
+
as: "span",
|
|
5384
|
+
fontSize: 1,
|
|
5385
|
+
mode: "bleed",
|
|
5386
|
+
onClick: stopRowClick,
|
|
5387
|
+
onMouseDown: stopRowMouseDown,
|
|
5388
|
+
padding: 2,
|
|
5389
|
+
children: display
|
|
5390
|
+
})
|
|
5391
|
+
});
|
|
5392
|
+
const kind = dateControlKind(state), commit = (mode, value) => {
|
|
5393
|
+
state.kind === "editable" && save(() => editField({
|
|
5394
|
+
instanceId: instanceId,
|
|
5395
|
+
field: state.field,
|
|
5396
|
+
...mode === "set" ? {
|
|
5397
|
+
mode: mode,
|
|
5398
|
+
value: value
|
|
5399
|
+
} : {
|
|
5400
|
+
mode: mode
|
|
5401
|
+
}
|
|
5402
|
+
}));
|
|
5403
|
+
}, handleClick = e => {
|
|
5404
|
+
e.stopPropagation(), setOpen(v => !v);
|
|
5405
|
+
};
|
|
5406
|
+
/* @__PURE__ */
|
|
5407
|
+
return jsxRuntime.jsx(DismissablePopover, {
|
|
5408
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
5409
|
+
onClick: stopRowClick,
|
|
5410
|
+
children: state.kind === "loading" || kind === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(LoadingRow, {
|
|
5411
|
+
label: "Loading…",
|
|
5412
|
+
padding: 3
|
|
5413
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.ClearableDatePicker, {
|
|
5414
|
+
clearLabel: "Clear date",
|
|
5415
|
+
onClear: () => {
|
|
5416
|
+
setOpen(!1), commit("unset");
|
|
5417
|
+
},
|
|
5418
|
+
onPick: next => {
|
|
5419
|
+
hasTimeOfDay(kind) || setOpen(!1), commit("set", serializeDateFieldValue(next, kind));
|
|
5420
|
+
},
|
|
5421
|
+
selectTime: hasTimeOfDay(kind),
|
|
5422
|
+
value: parseDateFieldValue(state.field.value, kind)
|
|
5423
|
+
})
|
|
5424
|
+
}),
|
|
5425
|
+
onDismiss: () => setOpen(!1),
|
|
5426
|
+
open: open,
|
|
5427
|
+
children: display ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
5428
|
+
"aria-label": "Change date",
|
|
5429
|
+
as: "span",
|
|
5430
|
+
fontSize: 1,
|
|
5431
|
+
mode: "bleed",
|
|
5432
|
+
onClick: handleClick,
|
|
5433
|
+
onMouseDown: stopRowMouseDown,
|
|
5434
|
+
padding: 2,
|
|
5435
|
+
children: display
|
|
5436
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(HoverHint, {
|
|
5437
|
+
disabled: open,
|
|
5438
|
+
text: "Set date",
|
|
5439
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
5440
|
+
"aria-label": "Set date",
|
|
5441
|
+
as: "span",
|
|
5442
|
+
fontSize: 1,
|
|
5443
|
+
icon: Calendar.CalendarIcon,
|
|
5444
|
+
mode: "bleed",
|
|
5445
|
+
onClick: handleClick,
|
|
5446
|
+
onMouseDown: stopRowMouseDown,
|
|
5447
|
+
padding: 2
|
|
5448
|
+
})
|
|
5449
|
+
})
|
|
4834
5450
|
});
|
|
4835
5451
|
}
|
|
4836
5452
|
|
|
@@ -4864,7 +5480,7 @@ function ActivityRowTitle({dimmed: dimmed, children: children}) {
|
|
|
4864
5480
|
});
|
|
4865
5481
|
}
|
|
4866
5482
|
|
|
4867
|
-
function RowTerminalActions({actions: actions, activity: activity, instanceId: instanceId}) {
|
|
5483
|
+
function RowTerminalActions({actions: actions, activity: activity, instanceId: instanceId, surface: surface}) {
|
|
4868
5484
|
const lock = useActionClusterState(), [only, ...rest] = actions;
|
|
4869
5485
|
return only ? /* @__PURE__ */ jsxRuntime.jsx(ActionClusterProvider, {
|
|
4870
5486
|
value: lock,
|
|
@@ -4876,14 +5492,16 @@ function RowTerminalActions({actions: actions, activity: activity, instanceId: i
|
|
|
4876
5492
|
inButtonCard: !0
|
|
4877
5493
|
},
|
|
4878
5494
|
instanceId: instanceId,
|
|
4879
|
-
|
|
5495
|
+
placement: "inline-row",
|
|
5496
|
+
surface: surface
|
|
4880
5497
|
}) : /* @__PURE__ */ jsxRuntime.jsx(ActionsMenuButton, {
|
|
4881
5498
|
actions: actions,
|
|
4882
5499
|
activity: activity,
|
|
4883
5500
|
inButtonCard: !0,
|
|
4884
5501
|
instanceId: instanceId,
|
|
4885
5502
|
label: "Select action",
|
|
4886
|
-
|
|
5503
|
+
placement: "inline-row",
|
|
5504
|
+
surface: surface
|
|
4887
5505
|
})
|
|
4888
5506
|
}) : null;
|
|
4889
5507
|
}
|
|
@@ -4904,7 +5522,7 @@ function TitleTag({hint: hint, tone: tone, children: children}) {
|
|
|
4904
5522
|
});
|
|
4905
5523
|
}
|
|
4906
5524
|
|
|
4907
|
-
function ActivityRow({face: face, breadcrumb: breadcrumb, assigneeIds: assigneeIds, assignState: assignState,
|
|
5525
|
+
function ActivityRow({face: face, breadcrumb: breadcrumb, assigneeIds: assigneeIds, assignState: assignState, dateState: dateState, dueDates: dueDates, instanceId: instanceId, onOpen: onOpen, surface: surface, terminalActions: terminalActions = []}) {
|
|
4908
5526
|
const settled = workflowEngine.isTerminalActivityStatus(face.status), dimmed = settledDim(settled);
|
|
4909
5527
|
/* @__PURE__ */
|
|
4910
5528
|
return jsxRuntime.jsxs(WorkRow, {
|
|
@@ -4912,12 +5530,20 @@ function ActivityRow({face: face, breadcrumb: breadcrumb, assigneeIds: assigneeI
|
|
|
4912
5530
|
children: [ settled || terminalActions.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(RowTerminalActions, {
|
|
4913
5531
|
actions: terminalActions,
|
|
4914
5532
|
activity: face.activityName,
|
|
4915
|
-
instanceId: instanceId
|
|
4916
|
-
|
|
5533
|
+
instanceId: instanceId,
|
|
5534
|
+
surface: surface
|
|
5535
|
+
}),
|
|
5536
|
+
/* @__PURE__ */ jsxRuntime.jsx(ActivityDateControl, {
|
|
5537
|
+
dueDates: dueDates,
|
|
5538
|
+
instanceId: instanceId,
|
|
5539
|
+
state: dateState,
|
|
5540
|
+
surface: surface
|
|
5541
|
+
}),
|
|
4917
5542
|
/* @__PURE__ */ jsxRuntime.jsx(AssignActivityControl, {
|
|
4918
5543
|
assigneeIds: assigneeIds,
|
|
4919
5544
|
instanceId: instanceId,
|
|
4920
|
-
state: assignState
|
|
5545
|
+
state: assignState,
|
|
5546
|
+
surface: surface
|
|
4921
5547
|
}) ]
|
|
4922
5548
|
}),
|
|
4923
5549
|
lead: /* @__PURE__ */ jsxRuntime.jsx(ActivityStatusLead, {
|
|
@@ -4942,7 +5568,7 @@ function ActivityRow({face: face, breadcrumb: breadcrumb, assigneeIds: assigneeI
|
|
|
4942
5568
|
});
|
|
4943
5569
|
}
|
|
4944
5570
|
|
|
4945
|
-
function ActivitiesList({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
5571
|
+
function ActivitiesList({entry: entry, onOpenActivity: onOpenActivity, surface: surface}) {
|
|
4946
5572
|
const activities = (entry.evaluation?.currentStage.activities ?? []).filter(t => !t.scopedOut), activityState = stateByActivity(entry.instance);
|
|
4947
5573
|
return activities.length === 0 ?
|
|
4948
5574
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
|
|
@@ -4962,7 +5588,8 @@ function ActivitiesList({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
|
4962
5588
|
editableFields: entry.evaluation?.editableFields
|
|
4963
5589
|
}),
|
|
4964
5590
|
instanceId: entry.instance._id,
|
|
4965
|
-
onOpen: () => onOpenActivity(t.activity.name)
|
|
5591
|
+
onOpen: () => onOpenActivity(t.activity.name),
|
|
5592
|
+
surface: surface
|
|
4966
5593
|
}, t.activity.name))
|
|
4967
5594
|
});
|
|
4968
5595
|
}
|
|
@@ -5026,7 +5653,9 @@ const EDITOR_BY_KIND = {
|
|
|
5026
5653
|
assignees: "assignees",
|
|
5027
5654
|
boolean: "scalar",
|
|
5028
5655
|
date: "scalar",
|
|
5656
|
+
dueDate: "scalar",
|
|
5029
5657
|
datetime: "scalar",
|
|
5658
|
+
dueDatetime: "scalar",
|
|
5030
5659
|
number: "scalar",
|
|
5031
5660
|
progress: "scalar",
|
|
5032
5661
|
string: "scalar",
|
|
@@ -5036,7 +5665,9 @@ const EDITOR_BY_KIND = {
|
|
|
5036
5665
|
array: e => e.value.length > 0 ? pluralize__default.default("item", e.value.length, !0) : void 0,
|
|
5037
5666
|
boolean: e => e.value === null ? void 0 : formatBoolean(e.value),
|
|
5038
5667
|
date: e => e.value === null ? void 0 : formatDate(e.value),
|
|
5668
|
+
dueDate: e => e.value === null ? void 0 : formatDate(e.value),
|
|
5039
5669
|
datetime: e => e.value === null ? void 0 : formatDateTime(e.value),
|
|
5670
|
+
dueDatetime: e => e.value === null ? void 0 : formatDateTime(e.value),
|
|
5040
5671
|
"doc.refs": e => e.value.length > 0 ? pluralize__default.default("document", e.value.length, !0) : void 0,
|
|
5041
5672
|
object: e => e.value === null ? void 0 : "Set",
|
|
5042
5673
|
"release.ref": e => e.value === null ? void 0 : e.value.releaseName
|
|
@@ -5160,7 +5791,7 @@ function TodoFieldDialog({entry: entry, scope: scope, field: field, title: title
|
|
|
5160
5791
|
|
|
5161
5792
|
const MAX_VISIBLE_PILLS = 4;
|
|
5162
5793
|
|
|
5163
|
-
function FieldPills({entry: entry, scope: scope, definition: definition}) {
|
|
5794
|
+
function FieldPills({entry: entry, scope: scope, definition: definition, surface: surface}) {
|
|
5164
5795
|
const [expanded, setExpanded] = react.useState(!1), pills = deriveFieldPills({
|
|
5165
5796
|
scope: scope,
|
|
5166
5797
|
definition: definition,
|
|
@@ -5178,7 +5809,8 @@ function FieldPills({entry: entry, scope: scope, definition: definition}) {
|
|
|
5178
5809
|
children: [ visible.map(pill => /* @__PURE__ */ jsxRuntime.jsx(FieldPill, {
|
|
5179
5810
|
entry: entry,
|
|
5180
5811
|
pill: pill,
|
|
5181
|
-
scope: scope
|
|
5812
|
+
scope: scope,
|
|
5813
|
+
surface: surface
|
|
5182
5814
|
}, pill.name)), overflow > 0 ?
|
|
5183
5815
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
5184
5816
|
mode: "bleed",
|
|
@@ -5212,7 +5844,9 @@ function isEmptyFace(face) {
|
|
|
5212
5844
|
|
|
5213
5845
|
const KIND_ICON = {
|
|
5214
5846
|
date: Calendar.CalendarIcon,
|
|
5847
|
+
dueDate: Calendar.CalendarIcon,
|
|
5215
5848
|
datetime: Calendar.CalendarIcon,
|
|
5849
|
+
dueDatetime: Calendar.CalendarIcon,
|
|
5216
5850
|
"doc.ref": Document.DocumentIcon,
|
|
5217
5851
|
"doc.refs": Document.DocumentIcon,
|
|
5218
5852
|
subject: Document.DocumentIcon
|
|
@@ -5364,18 +5998,20 @@ function PillButton({children: children, pill: pill, hintDisabled: hintDisabled
|
|
|
5364
5998
|
});
|
|
5365
5999
|
}
|
|
5366
6000
|
|
|
5367
|
-
function useFieldCommit({entry: entry, editability: editability}) {
|
|
5368
|
-
const
|
|
6001
|
+
function useFieldCommit({entry: entry, editability: editability, surface: surface}) {
|
|
6002
|
+
const editField = useEditField(surface), instanceId = entry.instance._id;
|
|
5369
6003
|
return {
|
|
5370
|
-
set: value =>
|
|
5371
|
-
|
|
6004
|
+
set: value => editField({
|
|
6005
|
+
instanceId: instanceId,
|
|
6006
|
+
field: editability,
|
|
5372
6007
|
mode: "set",
|
|
5373
6008
|
value: value
|
|
5374
|
-
})
|
|
5375
|
-
unset: () =>
|
|
5376
|
-
|
|
6009
|
+
}),
|
|
6010
|
+
unset: () => editField({
|
|
6011
|
+
instanceId: instanceId,
|
|
6012
|
+
field: editability,
|
|
5377
6013
|
mode: "unset"
|
|
5378
|
-
})
|
|
6014
|
+
})
|
|
5379
6015
|
};
|
|
5380
6016
|
}
|
|
5381
6017
|
|
|
@@ -5445,11 +6081,28 @@ function ReadOnlyPill({pill: pill}) {
|
|
|
5445
6081
|
});
|
|
5446
6082
|
}
|
|
5447
6083
|
|
|
5448
|
-
function
|
|
5449
|
-
const
|
|
6084
|
+
function usePillWrite(args) {
|
|
6085
|
+
const {entry: entry, editability: editability, surface: surface, onSaved: onSaved} = args, commit = useFieldCommit({
|
|
6086
|
+
entry: entry,
|
|
6087
|
+
editability: editability,
|
|
6088
|
+
surface: surface
|
|
6089
|
+
}), saver = useSaveField({
|
|
6090
|
+
instanceId: entry.instance._id,
|
|
6091
|
+
...onSaved === void 0 ? {} : {
|
|
6092
|
+
onSaved: onSaved
|
|
6093
|
+
}
|
|
6094
|
+
});
|
|
6095
|
+
return {
|
|
6096
|
+
...commit,
|
|
6097
|
+
...saver
|
|
6098
|
+
};
|
|
6099
|
+
}
|
|
6100
|
+
|
|
6101
|
+
function ScalarPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
6102
|
+
const [open, setOpen] = react.useState(!1), {set: set, saving: saving, save: save} = usePillWrite({
|
|
5450
6103
|
entry: entry,
|
|
5451
|
-
editability: editability
|
|
5452
|
-
|
|
6104
|
+
editability: editability,
|
|
6105
|
+
surface: surface,
|
|
5453
6106
|
onSaved: () => setOpen(!1)
|
|
5454
6107
|
});
|
|
5455
6108
|
/* @__PURE__ */
|
|
@@ -5475,18 +6128,21 @@ function ScalarPill({entry: entry, pill: pill, editability: editability}) {
|
|
|
5475
6128
|
});
|
|
5476
6129
|
}
|
|
5477
6130
|
|
|
5478
|
-
function DatePill({entry: entry, pill: pill, editability: editability, kind: kind}) {
|
|
6131
|
+
function DatePill({entry: entry, pill: pill, editability: editability, surface: surface, kind: kind}) {
|
|
5479
6132
|
const [open, setOpen] = react.useState(!1), {set: set} = useFieldCommit({
|
|
5480
6133
|
entry: entry,
|
|
5481
|
-
editability: editability
|
|
5482
|
-
|
|
6134
|
+
editability: editability,
|
|
6135
|
+
surface: surface
|
|
6136
|
+
}), {save: save} = useSaveField({
|
|
6137
|
+
instanceId: entry.instance._id
|
|
6138
|
+
});
|
|
5483
6139
|
/* @__PURE__ */
|
|
5484
6140
|
return jsxRuntime.jsx(PillPopover, {
|
|
5485
6141
|
content: /* @__PURE__ */ jsxRuntime.jsx(workflowComponents.DatePicker, {
|
|
5486
6142
|
onSelect: next => {
|
|
5487
|
-
kind
|
|
6143
|
+
hasTimeOfDay(kind) || setOpen(!1), save(() => set(serializeDateFieldValue(next, kind)));
|
|
5488
6144
|
},
|
|
5489
|
-
selectTime: kind
|
|
6145
|
+
selectTime: hasTimeOfDay(kind),
|
|
5490
6146
|
value: parseDateFieldValue(pill.entry?.value, kind)
|
|
5491
6147
|
}),
|
|
5492
6148
|
onDismiss: () => setOpen(!1),
|
|
@@ -5496,11 +6152,12 @@ function DatePill({entry: entry, pill: pill, editability: editability, kind: kin
|
|
|
5496
6152
|
});
|
|
5497
6153
|
}
|
|
5498
6154
|
|
|
5499
|
-
function BooleanPill({entry: entry, pill: pill, editability: editability}) {
|
|
5500
|
-
const {set: set} =
|
|
6155
|
+
function BooleanPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
6156
|
+
const {set: set, save: save} = usePillWrite({
|
|
5501
6157
|
entry: entry,
|
|
5502
|
-
editability: editability
|
|
5503
|
-
|
|
6158
|
+
editability: editability,
|
|
6159
|
+
surface: surface
|
|
6160
|
+
}), chrome = usePillChrome(), current = pill.entry?._type === "boolean" ? pill.entry.value : null, menuId = react.useId();
|
|
5504
6161
|
/* @__PURE__ */
|
|
5505
6162
|
return jsxRuntime.jsx(PillHint, {
|
|
5506
6163
|
pill: pill,
|
|
@@ -5544,12 +6201,14 @@ function BooleanPill({entry: entry, pill: pill, editability: editability}) {
|
|
|
5544
6201
|
});
|
|
5545
6202
|
}
|
|
5546
6203
|
|
|
5547
|
-
function ActorPill({entry: entry, pill: pill, editability: editability}) {
|
|
6204
|
+
function ActorPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
5548
6205
|
const [open, setOpen] = react.useState(!1), {set: set, unset: unset} = useFieldCommit({
|
|
5549
6206
|
entry: entry,
|
|
5550
|
-
editability: editability
|
|
6207
|
+
editability: editability,
|
|
6208
|
+
surface: surface
|
|
5551
6209
|
}), current = isActorShape(pill.entry?.value) ? pill.entry.value : null, {pick: pick} = useActorPick({
|
|
5552
6210
|
current: current,
|
|
6211
|
+
instanceId: entry.instance._id,
|
|
5553
6212
|
onSave: set,
|
|
5554
6213
|
onUnset: unset
|
|
5555
6214
|
});
|
|
@@ -5569,12 +6228,14 @@ function ActorPill({entry: entry, pill: pill, editability: editability}) {
|
|
|
5569
6228
|
});
|
|
5570
6229
|
}
|
|
5571
6230
|
|
|
5572
|
-
function AssigneePill({entry: entry, pill: pill, editability: editability}) {
|
|
6231
|
+
function AssigneePill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
5573
6232
|
const [open, setOpen] = react.useState(!1), {set: set, unset: unset} = useFieldCommit({
|
|
5574
6233
|
entry: entry,
|
|
5575
|
-
editability: editability
|
|
6234
|
+
editability: editability,
|
|
6235
|
+
surface: surface
|
|
5576
6236
|
}), current = pill.entry?._type === "assignee" ? pill.entry.value : null, {pick: pick} = useAssigneePick({
|
|
5577
6237
|
current: current,
|
|
6238
|
+
instanceId: entry.instance._id,
|
|
5578
6239
|
onSave: set,
|
|
5579
6240
|
onUnset: unset
|
|
5580
6241
|
});
|
|
@@ -5594,11 +6255,12 @@ function AssigneePill({entry: entry, pill: pill, editability: editability}) {
|
|
|
5594
6255
|
});
|
|
5595
6256
|
}
|
|
5596
6257
|
|
|
5597
|
-
function AssigneesPill({entry: entry, pill: pill, editability: editability}) {
|
|
5598
|
-
const [open, setOpen] = react.useState(!1), {set: set} =
|
|
6258
|
+
function AssigneesPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
6259
|
+
const [open, setOpen] = react.useState(!1), {set: set, saving: saving, save: save} = usePillWrite({
|
|
5599
6260
|
entry: entry,
|
|
5600
|
-
editability: editability
|
|
5601
|
-
|
|
6261
|
+
editability: editability,
|
|
6262
|
+
surface: surface
|
|
6263
|
+
}), current = pill.face.kind === "assignees" ? pill.face.assignees : [];
|
|
5602
6264
|
/* @__PURE__ */
|
|
5603
6265
|
return jsxRuntime.jsx(PillPopover, {
|
|
5604
6266
|
content: /* @__PURE__ */ jsxRuntime.jsx(AssigneePicker, {
|
|
@@ -5641,46 +6303,53 @@ function TodoPill({entry: entry, pill: pill, scope: scope}) {
|
|
|
5641
6303
|
});
|
|
5642
6304
|
}
|
|
5643
6305
|
|
|
5644
|
-
function ScalarEditorPill({entry: entry, pill: pill, editability: editability}) {
|
|
6306
|
+
function ScalarEditorPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
5645
6307
|
return editability.type === "boolean" ? /* @__PURE__ */ jsxRuntime.jsx(BooleanPill, {
|
|
5646
6308
|
editability: editability,
|
|
5647
6309
|
entry: entry,
|
|
5648
|
-
pill: pill
|
|
5649
|
-
|
|
6310
|
+
pill: pill,
|
|
6311
|
+
surface: surface
|
|
6312
|
+
}) : isDateFieldKind(editability.type) ? /* @__PURE__ */ jsxRuntime.jsx(DatePill, {
|
|
5650
6313
|
editability: editability,
|
|
5651
6314
|
entry: entry,
|
|
5652
6315
|
kind: editability.type,
|
|
5653
|
-
pill: pill
|
|
6316
|
+
pill: pill,
|
|
6317
|
+
surface: surface
|
|
5654
6318
|
}) : /* @__PURE__ */ jsxRuntime.jsx(ScalarPill, {
|
|
5655
6319
|
editability: editability,
|
|
5656
6320
|
entry: entry,
|
|
5657
|
-
pill: pill
|
|
6321
|
+
pill: pill,
|
|
6322
|
+
surface: surface
|
|
5658
6323
|
});
|
|
5659
6324
|
}
|
|
5660
6325
|
|
|
5661
|
-
function EditorPill({entry: entry, pill: pill, editability: editability}) {
|
|
6326
|
+
function EditorPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
5662
6327
|
return pill.editor === "scalar" ? /* @__PURE__ */ jsxRuntime.jsx(ScalarEditorPill, {
|
|
5663
6328
|
editability: editability,
|
|
5664
6329
|
entry: entry,
|
|
5665
|
-
pill: pill
|
|
6330
|
+
pill: pill,
|
|
6331
|
+
surface: surface
|
|
5666
6332
|
}) : pill.editor === "actor" ? /* @__PURE__ */ jsxRuntime.jsx(ActorPill, {
|
|
5667
6333
|
editability: editability,
|
|
5668
6334
|
entry: entry,
|
|
5669
|
-
pill: pill
|
|
6335
|
+
pill: pill,
|
|
6336
|
+
surface: surface
|
|
5670
6337
|
}) : pill.editor === "assignee" ? /* @__PURE__ */ jsxRuntime.jsx(AssigneePill, {
|
|
5671
6338
|
editability: editability,
|
|
5672
6339
|
entry: entry,
|
|
5673
|
-
pill: pill
|
|
6340
|
+
pill: pill,
|
|
6341
|
+
surface: surface
|
|
5674
6342
|
}) : pill.editor === "assignees" ? /* @__PURE__ */ jsxRuntime.jsx(AssigneesPill, {
|
|
5675
6343
|
editability: editability,
|
|
5676
6344
|
entry: entry,
|
|
5677
|
-
pill: pill
|
|
6345
|
+
pill: pill,
|
|
6346
|
+
surface: surface
|
|
5678
6347
|
}) : /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyPill, {
|
|
5679
6348
|
pill: pill
|
|
5680
6349
|
});
|
|
5681
6350
|
}
|
|
5682
6351
|
|
|
5683
|
-
function FieldPill({entry: entry, pill: pill, scope: scope}) {
|
|
6352
|
+
function FieldPill({entry: entry, pill: pill, scope: scope, surface: surface}) {
|
|
5684
6353
|
if (pill.editor === "todoList" && pill.entry !== void 0) /* @__PURE__ */
|
|
5685
6354
|
return jsxRuntime.jsx(TodoPill, {
|
|
5686
6355
|
entry: entry,
|
|
@@ -5693,7 +6362,8 @@ function FieldPill({entry: entry, pill: pill, scope: scope}) {
|
|
|
5693
6362
|
}) : /* @__PURE__ */ jsxRuntime.jsx(EditorPill, {
|
|
5694
6363
|
editability: editability,
|
|
5695
6364
|
entry: entry,
|
|
5696
|
-
pill: pill
|
|
6365
|
+
pill: pill,
|
|
6366
|
+
surface: surface
|
|
5697
6367
|
});
|
|
5698
6368
|
}
|
|
5699
6369
|
|
|
@@ -5824,7 +6494,7 @@ function InstanceToolLink({entry: entry}) {
|
|
|
5824
6494
|
}
|
|
5825
6495
|
});
|
|
5826
6496
|
}, [ instanceId ]);
|
|
5827
|
-
return tools
|
|
6497
|
+
return workflowsToolAvailable(tools) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
5828
6498
|
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
5829
6499
|
as: WorkflowIntentLink,
|
|
5830
6500
|
fontSize: 1,
|
|
@@ -6027,6 +6697,7 @@ function StageGlyph(props) {
|
|
|
6027
6697
|
}
|
|
6028
6698
|
|
|
6029
6699
|
function StageFace({completed: completed = !1, detail: detail, title: title}) {
|
|
6700
|
+
const tone = completed ? "default" : "primary";
|
|
6030
6701
|
/* @__PURE__ */
|
|
6031
6702
|
return jsxRuntime.jsxs(ui.Flex, {
|
|
6032
6703
|
align: "center",
|
|
@@ -6035,8 +6706,8 @@ function StageFace({completed: completed = !1, detail: detail, title: title}) {
|
|
|
6035
6706
|
children: [
|
|
6036
6707
|
/* @__PURE__ */ jsxRuntime.jsx(sanity.TextWithTone, {
|
|
6037
6708
|
size: 1,
|
|
6038
|
-
tone:
|
|
6039
|
-
children: completed ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6709
|
+
tone: tone,
|
|
6710
|
+
children: completed ? /* @__PURE__ */ jsxRuntime.jsx(CheckmarkCircleFilledIcon, {
|
|
6040
6711
|
style: {
|
|
6041
6712
|
color: "inherit"
|
|
6042
6713
|
}
|
|
@@ -6048,7 +6719,7 @@ function StageFace({completed: completed = !1, detail: detail, title: title}) {
|
|
|
6048
6719
|
}),
|
|
6049
6720
|
/* @__PURE__ */ jsxRuntime.jsx(sanity.TextWithTone, {
|
|
6050
6721
|
size: 1,
|
|
6051
|
-
tone:
|
|
6722
|
+
tone: tone,
|
|
6052
6723
|
weight: "medium",
|
|
6053
6724
|
children: title
|
|
6054
6725
|
}), detail === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
@@ -6066,10 +6737,10 @@ function StageChip({completed: completed = !1, detail: detail, interactive: inte
|
|
|
6066
6737
|
padding: 3,
|
|
6067
6738
|
radius: 4,
|
|
6068
6739
|
style: {
|
|
6069
|
-
boxShadow: `inset 0 0 0 1px ${color.focusRing}`,
|
|
6740
|
+
boxShadow: `inset 0 0 0 1px ${completed ? color.badge.default.fg : color.focusRing}`,
|
|
6070
6741
|
cursor: interactive ? "help" : "default"
|
|
6071
6742
|
},
|
|
6072
|
-
tone: "primary",
|
|
6743
|
+
tone: completed ? "default" : "primary",
|
|
6073
6744
|
...interactive ? {
|
|
6074
6745
|
tabIndex: 0
|
|
6075
6746
|
} : {},
|
|
@@ -6297,7 +6968,8 @@ function WorkflowInstanceSection({defaultOpen: defaultOpen, entry: entry, onOpen
|
|
|
6297
6968
|
children: [
|
|
6298
6969
|
/* @__PURE__ */ jsxRuntime.jsx(InstanceSnapshotBody, {
|
|
6299
6970
|
entry: entry,
|
|
6300
|
-
onOpenActivity: onOpenActivity
|
|
6971
|
+
onOpenActivity: onOpenActivity,
|
|
6972
|
+
surface: "document-view"
|
|
6301
6973
|
}),
|
|
6302
6974
|
/* @__PURE__ */ jsxRuntime.jsx(InstanceToolLink, {
|
|
6303
6975
|
entry: entry
|
|
@@ -6306,7 +6978,7 @@ function WorkflowInstanceSection({defaultOpen: defaultOpen, entry: entry, onOpen
|
|
|
6306
6978
|
});
|
|
6307
6979
|
}
|
|
6308
6980
|
|
|
6309
|
-
function InstanceSnapshotBody({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
6981
|
+
function InstanceSnapshotBody({entry: entry, onOpenActivity: onOpenActivity, surface: surface}) {
|
|
6310
6982
|
const definition = useDefinition(entry), {instance: instance} = entry;
|
|
6311
6983
|
/* @__PURE__ */
|
|
6312
6984
|
return jsxRuntime.jsxs(ui.Stack, {
|
|
@@ -6317,7 +6989,8 @@ function InstanceSnapshotBody({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
|
6317
6989
|
/* @__PURE__ */ jsxRuntime.jsx(FieldPills, {
|
|
6318
6990
|
definition: definition,
|
|
6319
6991
|
entry: entry,
|
|
6320
|
-
scope: "workflow"
|
|
6992
|
+
scope: "workflow",
|
|
6993
|
+
surface: surface
|
|
6321
6994
|
}),
|
|
6322
6995
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Card, {
|
|
6323
6996
|
border: !0,
|
|
@@ -6342,14 +7015,15 @@ function InstanceSnapshotBody({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
|
6342
7015
|
padding: 2,
|
|
6343
7016
|
children: /* @__PURE__ */ jsxRuntime.jsx(StageSection, {
|
|
6344
7017
|
entry: entry,
|
|
6345
|
-
onOpenActivity: onOpenActivity
|
|
7018
|
+
onOpenActivity: onOpenActivity,
|
|
7019
|
+
surface: surface
|
|
6346
7020
|
})
|
|
6347
7021
|
}) ]
|
|
6348
7022
|
}) ]
|
|
6349
7023
|
});
|
|
6350
7024
|
}
|
|
6351
7025
|
|
|
6352
|
-
function StageSection({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
7026
|
+
function StageSection({entry: entry, onOpenActivity: onOpenActivity, surface: surface}) {
|
|
6353
7027
|
const definition = useDefinition(entry), notice = instanceNotice(entry);
|
|
6354
7028
|
return notice !== null ? notice : /* @__PURE__ */ jsxRuntime.jsx(StaleLock, {
|
|
6355
7029
|
stale: isEvaluationStale(entry),
|
|
@@ -6359,11 +7033,13 @@ function StageSection({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
|
6359
7033
|
/* @__PURE__ */ jsxRuntime.jsx(FieldPills, {
|
|
6360
7034
|
definition: definition,
|
|
6361
7035
|
entry: entry,
|
|
6362
|
-
scope: "stage"
|
|
7036
|
+
scope: "stage",
|
|
7037
|
+
surface: surface
|
|
6363
7038
|
}),
|
|
6364
7039
|
/* @__PURE__ */ jsxRuntime.jsx(ActivitiesList, {
|
|
6365
7040
|
entry: entry,
|
|
6366
|
-
onOpenActivity: onOpenActivity
|
|
7041
|
+
onOpenActivity: onOpenActivity,
|
|
7042
|
+
surface: surface
|
|
6367
7043
|
}) ]
|
|
6368
7044
|
})
|
|
6369
7045
|
});
|
|
@@ -6372,8 +7048,9 @@ function StageSection({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
|
6372
7048
|
function CautionNote({action: action, label: label}) {
|
|
6373
7049
|
/* @__PURE__ */
|
|
6374
7050
|
return jsxRuntime.jsxs(ui.Card, {
|
|
6375
|
-
padding: 2,
|
|
6376
7051
|
paddingLeft: 3,
|
|
7052
|
+
paddingRight: 2,
|
|
7053
|
+
paddingY: 3,
|
|
6377
7054
|
radius: 3,
|
|
6378
7055
|
style: {
|
|
6379
7056
|
alignItems: "center",
|
|
@@ -6401,18 +7078,20 @@ function CautionNote({action: action, label: label}) {
|
|
|
6401
7078
|
}
|
|
6402
7079
|
|
|
6403
7080
|
function CopyDetailsButton({unreadable: unreadable}) {
|
|
6404
|
-
const toast =
|
|
7081
|
+
const toast = useWorkflowToast();
|
|
6405
7082
|
/* @__PURE__ */
|
|
6406
7083
|
return jsxRuntime.jsx(ui.Button, {
|
|
6407
7084
|
fontSize: 1,
|
|
6408
7085
|
mode: "ghost",
|
|
6409
7086
|
onClick: () => {
|
|
6410
7087
|
navigator.clipboard.writeText(unreadableDocsReport(unreadable)).then(() => toast.push({
|
|
6411
|
-
|
|
6412
|
-
|
|
7088
|
+
id: TOAST_ID.detailsCopy,
|
|
7089
|
+
status: "info",
|
|
7090
|
+
title: "Details copied to clipboard"
|
|
6413
7091
|
}), () => toast.push({
|
|
7092
|
+
id: TOAST_ID.detailsCopy,
|
|
6414
7093
|
status: "error",
|
|
6415
|
-
title: "
|
|
7094
|
+
title: "Failed to copy the details"
|
|
6416
7095
|
}));
|
|
6417
7096
|
},
|
|
6418
7097
|
padding: 2,
|
|
@@ -6438,7 +7117,7 @@ const HEADLINES = {
|
|
|
6438
7117
|
};
|
|
6439
7118
|
|
|
6440
7119
|
function remediation(invalid) {
|
|
6441
|
-
return invalid.reason === "model-ahead" ? `"${invalid.documentId}" was created by a newer version of the workflow engine than this Studio can read. It needs a plugin update that supports the newer data model — share the details with your Studio maintainers.` : `This version of the Studio can
|
|
7120
|
+
return invalid.reason === "model-ahead" ? `"${invalid.documentId}" was created by a newer version of the workflow engine than this Studio can read. It needs a plugin update that supports the newer data model — share the details with your Studio maintainers.` : `This version of the Studio can’t read "${invalid.documentId}" — it was likely created by a newer or different version of the workflow tooling. Share the details with your Studio maintainers.`;
|
|
6442
7121
|
}
|
|
6443
7122
|
|
|
6444
7123
|
function InvalidDocNotice({invalid: invalid}) {
|
|
@@ -6489,18 +7168,6 @@ function TabSwitch({ariaControls: ariaControls, idPrefix: idPrefix, options: opt
|
|
|
6489
7168
|
});
|
|
6490
7169
|
}
|
|
6491
7170
|
|
|
6492
|
-
function useDelayedFlag(active, delayMs) {
|
|
6493
|
-
const [held, setHeld] = react.useState(!1);
|
|
6494
|
-
return react.useEffect(() => {
|
|
6495
|
-
if (!active) {
|
|
6496
|
-
setHeld(!1);
|
|
6497
|
-
return;
|
|
6498
|
-
}
|
|
6499
|
-
const timer = setTimeout(() => setHeld(!0), delayMs);
|
|
6500
|
-
return () => clearTimeout(timer);
|
|
6501
|
-
}, [ active, delayMs ]), held && active;
|
|
6502
|
-
}
|
|
6503
|
-
|
|
6504
7171
|
function openActivityGone(args) {
|
|
6505
7172
|
const {entry: entry, target: target} = args;
|
|
6506
7173
|
if (entry === void 0 || entry.instance.currentStage !== target.stage) return !0;
|
|
@@ -6565,18 +7232,16 @@ function coveredFieldNames(ctx) {
|
|
|
6565
7232
|
return release && names.add(release.name), names;
|
|
6566
7233
|
}
|
|
6567
7234
|
|
|
6568
|
-
const OPTIONAL_INIT_KINDS = /* @__PURE__ */ new Set([ "array", "assignees", "doc.refs" ]);
|
|
6569
|
-
|
|
6570
7235
|
function inputInitFields(args) {
|
|
6571
7236
|
return (args.definition?.fields ?? []).filter(entry => entry.initialValue?.type === "input" && !args.covered.has(entry.name));
|
|
6572
7237
|
}
|
|
6573
7238
|
|
|
6574
|
-
function
|
|
6575
|
-
return
|
|
7239
|
+
function isRequiredEntry(entry) {
|
|
7240
|
+
return entry.required === !0;
|
|
6576
7241
|
}
|
|
6577
7242
|
|
|
6578
7243
|
function missingInitFields(initFields, values) {
|
|
6579
|
-
return initFields.filter(entry =>
|
|
7244
|
+
return initFields.filter(entry => isRequiredEntry(entry) && !isFieldFilled(entry, values[entry.name] ?? null));
|
|
6580
7245
|
}
|
|
6581
7246
|
|
|
6582
7247
|
function numericFilled(value) {
|
|
@@ -6633,7 +7298,9 @@ const asInitial = candidate => candidate, scalarInitialValue = (entry, value) =>
|
|
|
6633
7298
|
value: value === !0
|
|
6634
7299
|
}),
|
|
6635
7300
|
date: scalarInitialValue,
|
|
7301
|
+
dueDate: scalarInitialValue,
|
|
6636
7302
|
datetime: scalarInitialValue,
|
|
7303
|
+
dueDatetime: scalarInitialValue,
|
|
6637
7304
|
"doc.ref": singleRefInitialValue,
|
|
6638
7305
|
"doc.refs": (entry, value) => asInitial({
|
|
6639
7306
|
type: entry.type,
|
|
@@ -6784,15 +7451,36 @@ function classifyStartError(err) {
|
|
|
6784
7451
|
};
|
|
6785
7452
|
}
|
|
6786
7453
|
|
|
7454
|
+
function startOutcomeToast(outcome, label) {
|
|
7455
|
+
return outcome.kind === "started-not-settled" ? {
|
|
7456
|
+
id: TOAST_ID.start,
|
|
7457
|
+
status: "warning",
|
|
7458
|
+
title: `“${label}” started but didn’t finish`,
|
|
7459
|
+
description: outcome.description
|
|
7460
|
+
} : outcome.kind === "not-allowed" ? {
|
|
7461
|
+
id: TOAST_ID.start,
|
|
7462
|
+
status: "warning",
|
|
7463
|
+
title: `“${label}” can’t be started right now`,
|
|
7464
|
+
description: outcome.description
|
|
7465
|
+
} : {
|
|
7466
|
+
id: TOAST_ID.start,
|
|
7467
|
+
status: "error",
|
|
7468
|
+
title: `Failed to start “${label}”`,
|
|
7469
|
+
description: outcome.description
|
|
7470
|
+
};
|
|
7471
|
+
}
|
|
7472
|
+
|
|
6787
7473
|
function boundReleaseId(mapping, selectedReleaseId) {
|
|
6788
7474
|
return mapping?.perspectiveField !== void 0 && selectedReleaseId !== void 0 ? selectedReleaseId : void 0;
|
|
6789
7475
|
}
|
|
6790
7476
|
|
|
7477
|
+
const MAPPING_BROKEN_HINT = docTypeLabel => `Unavailable — this workflow isn’t set up correctly for ${docTypeLabel} documents`;
|
|
7478
|
+
|
|
6791
7479
|
function startGate(args) {
|
|
6792
7480
|
const {mapping: mapping, mappingIssue: mappingIssue, selectedReleaseId: selectedReleaseId, releaseActive: releaseActive} = args;
|
|
6793
7481
|
if (mappingIssue !== void 0) return {
|
|
6794
7482
|
blocked: !0,
|
|
6795
|
-
tooltip:
|
|
7483
|
+
tooltip: MAPPING_BROKEN_HINT(args.docTypeLabel)
|
|
6796
7484
|
};
|
|
6797
7485
|
if (mapping.perspectiveField?.required === !0 && selectedReleaseId === void 0) return {
|
|
6798
7486
|
blocked: !0,
|
|
@@ -6804,7 +7492,7 @@ function startGate(args) {
|
|
|
6804
7492
|
};
|
|
6805
7493
|
if (args.startFilterFailed === !0) return {
|
|
6806
7494
|
blocked: !0,
|
|
6807
|
-
tooltip: `${mapping.label} can
|
|
7495
|
+
tooltip: `${mapping.label} can’t start for this document right now — the workflow’s start condition isn’t met`
|
|
6808
7496
|
};
|
|
6809
7497
|
if (args.unmetRequirement !== void 0) {
|
|
6810
7498
|
const requirement = args.unmetRequirement;
|
|
@@ -7066,7 +7754,7 @@ function showRowOnError(key, mapping) {
|
|
|
7066
7754
|
}
|
|
7067
7755
|
|
|
7068
7756
|
function useStartWorkflow(args) {
|
|
7069
|
-
const {mapping: mapping, docId: docId, initialValue: initialValue, source: source} = args, toast =
|
|
7757
|
+
const {mapping: mapping, docId: docId, initialValue: initialValue, source: source} = args, toast = useWorkflowToast(), schema = sanity.useSchema(), {engine: engine, openStartDialog: openStartDialog, mappingIssues: mappingIssues2, mappingStarts: mappingStarts} = useWorkflowContext(), observer = workflowStudio.useStudioObserver({
|
|
7070
7758
|
engine: engine
|
|
7071
7759
|
}), [starting, setStarting] = react.useState(!1), {selectedReleaseId: selectedReleaseId} = sanity.usePerspective(), releaseActive = sanity.useIsReleaseActive(), startBlock = mappingStarts.get(mappingKey(mapping)), hidden = workflowEngine.startKindOf({
|
|
7072
7760
|
start: startBlock
|
|
@@ -7086,6 +7774,7 @@ function useStartWorkflow(args) {
|
|
|
7086
7774
|
}), {blocked: blocked, tooltip: tooltip} = startGate({
|
|
7087
7775
|
mapping: mapping,
|
|
7088
7776
|
mappingIssue: mappingIssues2.get(mappingKey(mapping)),
|
|
7777
|
+
docTypeLabel: schema.get(mapping.docType)?.title ?? mapping.docType,
|
|
7089
7778
|
selectedReleaseId: selectedReleaseId,
|
|
7090
7779
|
releaseActive: releaseActive,
|
|
7091
7780
|
startFilterFailed: filterFailed,
|
|
@@ -7109,8 +7798,9 @@ function useStartWorkflow(args) {
|
|
|
7109
7798
|
selectedReleaseId: selectedReleaseId,
|
|
7110
7799
|
ensureDocumentExists: observer.ensureDocumentExists,
|
|
7111
7800
|
onPersistFailure: err => toast.push({
|
|
7801
|
+
id: TOAST_ID.documentSave,
|
|
7112
7802
|
status: "error",
|
|
7113
|
-
title: "
|
|
7803
|
+
title: "Failed to save the document",
|
|
7114
7804
|
description: describeError(err)
|
|
7115
7805
|
}),
|
|
7116
7806
|
openStartDialog: request => openStartDialog({
|
|
@@ -7251,7 +7941,8 @@ function ForMeList({entry: entry, work: work, identity: identity, onOpenActivity
|
|
|
7251
7941
|
}),
|
|
7252
7942
|
breadcrumb: breadcrumb,
|
|
7253
7943
|
instanceId: instance._id,
|
|
7254
|
-
onOpen: () => onOpenActivity(activityEval.activity.name)
|
|
7944
|
+
onOpen: () => onOpenActivity(activityEval.activity.name),
|
|
7945
|
+
surface: "document-view"
|
|
7255
7946
|
}, activityEval.activity.name)), itemCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx(TodoItemsList, {
|
|
7256
7947
|
breadcrumb: breadcrumb,
|
|
7257
7948
|
entry: entry,
|
|
@@ -7427,7 +8118,7 @@ function WorkflowsPanel({entries: entries, documentId: documentId, docTypeMappin
|
|
|
7427
8118
|
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
7428
8119
|
direction: "column",
|
|
7429
8120
|
flex: 1,
|
|
7430
|
-
children: view === "overview" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
8121
|
+
children: view === "overview" ? /* @__PURE__ */ jsxRuntime.jsx(OverviewSections, {
|
|
7431
8122
|
active: active,
|
|
7432
8123
|
empty: /* @__PURE__ */ jsxRuntime.jsx(OverviewEmptyState, {
|
|
7433
8124
|
docId: documentId,
|
|
@@ -7451,7 +8142,7 @@ function WorkflowsPanel({entries: entries, documentId: documentId, docTypeMappin
|
|
|
7451
8142
|
});
|
|
7452
8143
|
}
|
|
7453
8144
|
|
|
7454
|
-
function
|
|
8145
|
+
function OverviewSections({active: active, empty: empty, finished: finished, sectionFor: sectionFor}) {
|
|
7455
8146
|
/* @__PURE__ */
|
|
7456
8147
|
return jsxRuntime.jsxs(ui.Stack, {
|
|
7457
8148
|
gap: 5,
|
|
@@ -7599,6 +8290,23 @@ function workflowIssue(args) {
|
|
|
7599
8290
|
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.`;
|
|
7600
8291
|
}
|
|
7601
8292
|
|
|
8293
|
+
function createSubscribers() {
|
|
8294
|
+
const listeners = /* @__PURE__ */ new Set;
|
|
8295
|
+
return {
|
|
8296
|
+
subscribe(listener) {
|
|
8297
|
+
return listeners.add(listener), () => {
|
|
8298
|
+
listeners.delete(listener);
|
|
8299
|
+
};
|
|
8300
|
+
},
|
|
8301
|
+
notify() {
|
|
8302
|
+
for (const listener of [ ...listeners ]) listener();
|
|
8303
|
+
},
|
|
8304
|
+
clear() {
|
|
8305
|
+
listeners.clear();
|
|
8306
|
+
}
|
|
8307
|
+
};
|
|
8308
|
+
}
|
|
8309
|
+
|
|
7602
8310
|
function actualType$(previews, bareId) {
|
|
7603
8311
|
return previews.unstable_observeDocumentPairAvailability(bareId).pipe(operators.switchMap(({draft: draft, published: published}) => draft.available ? previews.observeDocumentTypeFromId(csm.getDraftId(bareId)) : published.available ? previews.observeDocumentTypeFromId(bareId) : draft.reason === "PERMISSION_DENIED" || published.reason === "PERMISSION_DENIED" ? rxjs.of(void 0) : previews.unstable_observeVersionDocumentIds(bareId).pipe(operators.switchMap(([firstVersionId]) => firstVersionId === void 0 ? rxjs.of(null) : previews.observeDocumentTypeFromId(firstVersionId)))), operators.distinctUntilChanged());
|
|
7604
8312
|
}
|
|
@@ -7606,12 +8314,10 @@ function actualType$(previews, bareId) {
|
|
|
7606
8314
|
const REBUILD_DELAY_MS = 5e3;
|
|
7607
8315
|
|
|
7608
8316
|
function createActualTypeProbeStore(previews) {
|
|
7609
|
-
const verdicts = /* @__PURE__ */ new Map, live = /* @__PURE__ */ new Map,
|
|
7610
|
-
for (const listener of [ ...listeners ]) listener();
|
|
7611
|
-
}, start = (bareId, entry) => actualType$(previews, bareId).subscribe({
|
|
8317
|
+
const verdicts = /* @__PURE__ */ new Map, live = /* @__PURE__ */ new Map, subscribers = createSubscribers(), start = (bareId, entry) => actualType$(previews, bareId).subscribe({
|
|
7612
8318
|
next: value => {
|
|
7613
8319
|
verdicts.has(bareId) && verdicts.get(bareId) === value || (verdicts.set(bareId, value),
|
|
7614
|
-
notify());
|
|
8320
|
+
subscribers.notify());
|
|
7615
8321
|
},
|
|
7616
8322
|
error: err => {
|
|
7617
8323
|
console.error(`[workflow-studio-plugin] actual-type probe for "${bareId}" failed:`, err),
|
|
@@ -7621,12 +8327,14 @@ function createActualTypeProbeStore(previews) {
|
|
|
7621
8327
|
}
|
|
7622
8328
|
});
|
|
7623
8329
|
return {
|
|
7624
|
-
subscribe
|
|
7625
|
-
return listeners.add(listener), () => {
|
|
7626
|
-
listeners.delete(listener);
|
|
7627
|
-
};
|
|
7628
|
-
},
|
|
8330
|
+
subscribe: subscribers.subscribe,
|
|
7629
8331
|
read: bareId => verdicts.get(bareId),
|
|
8332
|
+
seed(types2) {
|
|
8333
|
+
let changed = !1;
|
|
8334
|
+
for (const [bareId, actualType] of types2) verdicts.has(bareId) || (verdicts.set(bareId, actualType),
|
|
8335
|
+
changed = !0);
|
|
8336
|
+
changed && subscribers.notify();
|
|
8337
|
+
},
|
|
7630
8338
|
track(bareId) {
|
|
7631
8339
|
let entry = live.get(bareId);
|
|
7632
8340
|
if (entry === void 0) {
|
|
@@ -7647,10 +8355,6 @@ function createActualTypeProbeStore(previews) {
|
|
|
7647
8355
|
};
|
|
7648
8356
|
}
|
|
7649
8357
|
|
|
7650
|
-
function contentDocumentTypes(schema) {
|
|
7651
|
-
return schema.getTypeNames().filter(name => schema.get(name)?.type?.name === "document" && !WORKFLOW_SYSTEM_TYPES.includes(name));
|
|
7652
|
-
}
|
|
7653
|
-
|
|
7654
8358
|
async function readDeployedDefinitions(engine) {
|
|
7655
8359
|
return (await engine.query({
|
|
7656
8360
|
groq: workflowEngine.latestDefinitionsGroq()
|
|
@@ -7825,7 +8529,7 @@ const REPORT_FLUSH_MS = 50, EMPTY_COMMITTED = {
|
|
|
7825
8529
|
|
|
7826
8530
|
function createEntriesStore() {
|
|
7827
8531
|
let committed = EMPTY_COMMITTED, reports = /* @__PURE__ */ new Map, byInstance = /* @__PURE__ */ new Map, byDocument = /* @__PURE__ */ new Map;
|
|
7828
|
-
const
|
|
8532
|
+
const subscribers = createSubscribers();
|
|
7829
8533
|
let flushTimer;
|
|
7830
8534
|
const recompute = () => {
|
|
7831
8535
|
flushTimer !== void 0 && (clearTimeout(flushTimer), flushTimer = void 0);
|
|
@@ -7838,10 +8542,8 @@ function createEntriesStore() {
|
|
|
7838
8542
|
byInstance: nextByInstance,
|
|
7839
8543
|
previous: byDocument
|
|
7840
8544
|
});
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
for (const listener of [ ...listeners ]) listener();
|
|
7844
|
-
}
|
|
8545
|
+
nextByInstance === byInstance && nextByDocument === byDocument || (byInstance = nextByInstance,
|
|
8546
|
+
byDocument = nextByDocument, subscribers.notify());
|
|
7845
8547
|
};
|
|
7846
8548
|
return {
|
|
7847
8549
|
setCommitted(inputs) {
|
|
@@ -7857,13 +8559,9 @@ function createEntriesStore() {
|
|
|
7857
8559
|
getReport: instanceId => reports.get(instanceId),
|
|
7858
8560
|
getInstance: instanceId => byInstance.get(instanceId),
|
|
7859
8561
|
getDocument: docId => byDocument.get(docId) ?? EMPTY_ENTRIES,
|
|
7860
|
-
subscribe
|
|
7861
|
-
return listeners.add(listener), () => {
|
|
7862
|
-
listeners.delete(listener);
|
|
7863
|
-
};
|
|
7864
|
-
},
|
|
8562
|
+
subscribe: subscribers.subscribe,
|
|
7865
8563
|
dispose() {
|
|
7866
|
-
flushTimer !== void 0 && clearTimeout(flushTimer), flushTimer = void 0,
|
|
8564
|
+
flushTimer !== void 0 && clearTimeout(flushTimer), flushTimer = void 0, subscribers.clear();
|
|
7867
8565
|
}
|
|
7868
8566
|
};
|
|
7869
8567
|
}
|
|
@@ -7994,7 +8692,7 @@ function WorkflowProvider(props) {
|
|
|
7994
8692
|
try {
|
|
7995
8693
|
await (drainRef.current?.(instanceId));
|
|
7996
8694
|
} catch (err) {
|
|
7997
|
-
throw new
|
|
8695
|
+
throw new EffectsIncompleteError(describeError(err), {
|
|
7998
8696
|
cause: err
|
|
7999
8697
|
});
|
|
8000
8698
|
}
|
|
@@ -8125,12 +8823,19 @@ function WorkflowProvider(props) {
|
|
|
8125
8823
|
});
|
|
8126
8824
|
}
|
|
8127
8825
|
|
|
8128
|
-
function
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8826
|
+
function entriesSameBy(equal) {
|
|
8827
|
+
return (a, b) => {
|
|
8828
|
+
if (a.size !== b.size) return !1;
|
|
8829
|
+
for (const [key, value] of b) {
|
|
8830
|
+
const previous = a.get(key);
|
|
8831
|
+
if (previous === void 0 || !equal(previous, value)) return !1;
|
|
8832
|
+
}
|
|
8833
|
+
return !0;
|
|
8834
|
+
};
|
|
8132
8835
|
}
|
|
8133
8836
|
|
|
8837
|
+
const sameIssues = entriesSameBy(sameMappingIssue), sameVersions = entriesSameBy(Object.is);
|
|
8838
|
+
|
|
8134
8839
|
function sameMappings(a, b) {
|
|
8135
8840
|
return a.length === b.length && a.every((mapping, index) => {
|
|
8136
8841
|
const other = b[index];
|
|
@@ -8154,10 +8859,7 @@ function useDeployedDefinitions(args) {
|
|
|
8154
8859
|
contentResource: contentResource,
|
|
8155
8860
|
schemaContentTypes: schemaContentTypes
|
|
8156
8861
|
});
|
|
8157
|
-
|
|
8158
|
-
const signature = `${rowKey}|${message}`;
|
|
8159
|
-
logged.current.has(signature) || (logged.current.add(signature), console.error(`[workflow-studio-plugin] ${message}`));
|
|
8160
|
-
}
|
|
8862
|
+
logOnce(mappingIssueLogLines(found), logged.current);
|
|
8161
8863
|
const resolvedAutoStart = resolveAutoStart({
|
|
8162
8864
|
autoStart: mappingAutoStartMap(effectiveMappings),
|
|
8163
8865
|
knownDocTypes: new Set(schema.getTypeNames()),
|
|
@@ -8165,7 +8867,7 @@ function useDeployedDefinitions(args) {
|
|
|
8165
8867
|
});
|
|
8166
8868
|
if (logOnce(resolvedAutoStart.warnings, logged.current), cancelled) return;
|
|
8167
8869
|
setMappings(prev => sameMappings(prev, effectiveMappings) ? prev : effectiveMappings),
|
|
8168
|
-
setIssues(prev =>
|
|
8870
|
+
setIssues(prev => sameIssues(prev, found) ? prev : found), setStarts(mappingStartBlocks({
|
|
8169
8871
|
mappings: effectiveMappings,
|
|
8170
8872
|
definitions: definitions
|
|
8171
8873
|
})), setFields(mappingDeclaredFields({
|
|
@@ -8173,7 +8875,7 @@ function useDeployedDefinitions(args) {
|
|
|
8173
8875
|
definitions: definitions
|
|
8174
8876
|
}));
|
|
8175
8877
|
const versions = new Map(workflowEngine.latestDeployedDefinitions(definitions).map(d => [ d.name, d.version ]));
|
|
8176
|
-
setLatestVersions(prev =>
|
|
8878
|
+
setLatestVersions(prev => sameVersions(prev, versions) ? prev : versions), setAutoStartByType(resolvedAutoStart.byType),
|
|
8177
8879
|
setAutoStartDefinitions(resolvedAutoStart.definitions);
|
|
8178
8880
|
})().catch(err => {
|
|
8179
8881
|
console.error("[workflow-studio-plugin] mapping discovery failed — keeping the last resolved workflow state:", err);
|
|
@@ -8317,16 +9019,8 @@ function ChecklistInput({value: value, onChange: onChange}) {
|
|
|
8317
9019
|
value: it.label
|
|
8318
9020
|
})
|
|
8319
9021
|
}),
|
|
8320
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8321
|
-
|
|
8322
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
|
|
8323
|
-
"aria-label": "Remove item",
|
|
8324
|
-
fontSize: 1,
|
|
8325
|
-
icon: Close.CloseIcon,
|
|
8326
|
-
mode: "bleed",
|
|
8327
|
-
onClick: () => remove(i),
|
|
8328
|
-
padding: 2
|
|
8329
|
-
})
|
|
9022
|
+
/* @__PURE__ */ jsxRuntime.jsx(RemoveItemButton, {
|
|
9023
|
+
onClick: () => remove(i)
|
|
8330
9024
|
}) ]
|
|
8331
9025
|
}, it._key)),
|
|
8332
9026
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
@@ -8430,7 +9124,7 @@ function useLatestDefinition(definitionName) {
|
|
|
8430
9124
|
function useCreateDoc(args) {
|
|
8431
9125
|
const {releaseId: releaseId, onCreated: onCreated} = args, {engine: engine, binding: binding} = useWorkflowContext(), observer = workflowStudio.useStudioObserver({
|
|
8432
9126
|
engine: engine
|
|
8433
|
-
}), schema = sanity.useSchema(), templates = sanity.useTemplates(), resolverContext = sanity.useInitialValueResolverContext(), toast =
|
|
9127
|
+
}), schema = sanity.useSchema(), templates = sanity.useTemplates(), resolverContext = sanity.useInitialValueResolverContext(), toast = useWorkflowToast(), [creating, setCreating] = react.useState(!1);
|
|
8434
9128
|
return {
|
|
8435
9129
|
creating: creating,
|
|
8436
9130
|
createDoc: async type => {
|
|
@@ -8455,8 +9149,9 @@ function useCreateDoc(args) {
|
|
|
8455
9149
|
}));
|
|
8456
9150
|
} catch (err) {
|
|
8457
9151
|
toast.push({
|
|
9152
|
+
id: TOAST_ID.documentCreate,
|
|
8458
9153
|
status: "error",
|
|
8459
|
-
title: "
|
|
9154
|
+
title: "Failed to create the document",
|
|
8460
9155
|
description: describeError(err)
|
|
8461
9156
|
});
|
|
8462
9157
|
} finally {
|
|
@@ -8668,7 +9363,7 @@ function InitFieldRow({entry: entry, docType: docType, releaseId: releaseId, val
|
|
|
8668
9363
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
8669
9364
|
size: 1,
|
|
8670
9365
|
weight: "medium",
|
|
8671
|
-
children:
|
|
9366
|
+
children: isRequiredEntry(entry) ? `${label} (Required)` : label
|
|
8672
9367
|
}), entry.description ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
|
|
8673
9368
|
muted: !0,
|
|
8674
9369
|
size: 1,
|
|
@@ -8773,31 +9468,12 @@ function ResumeNote({onStartNew: onStartNew}) {
|
|
|
8773
9468
|
|
|
8774
9469
|
function handleStartError(args) {
|
|
8775
9470
|
const {label: label, toast: toast, seedInstance: seedInstance, onClose: onClose} = args, outcome = classifyStartError(args.err);
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
status: "warning",
|
|
8779
|
-
title: `${label} started, but didn’t finish auto-advancing`,
|
|
8780
|
-
description: outcome.description
|
|
8781
|
-
}), outcome.instance !== void 0 && seedInstance(outcome.instance), onClose();
|
|
8782
|
-
return;
|
|
8783
|
-
}
|
|
8784
|
-
if (outcome.kind === "not-allowed") {
|
|
8785
|
-
toast.push({
|
|
8786
|
-
status: "warning",
|
|
8787
|
-
title: `${label} can't be started right now`,
|
|
8788
|
-
description: outcome.description
|
|
8789
|
-
});
|
|
8790
|
-
return;
|
|
8791
|
-
}
|
|
8792
|
-
toast.push({
|
|
8793
|
-
status: "error",
|
|
8794
|
-
title: `Failed to start ${label}`,
|
|
8795
|
-
description: outcome.description
|
|
8796
|
-
});
|
|
9471
|
+
toast.push(startOutcomeToast(outcome, label)), outcome.kind === "started-not-settled" && (outcome.instance !== void 0 && seedInstance(outcome.instance),
|
|
9472
|
+
onClose());
|
|
8797
9473
|
}
|
|
8798
9474
|
|
|
8799
9475
|
function StartWorkflowForm({request: request, onClose: onClose}) {
|
|
8800
|
-
const {definition: definitionName, label: label, mapping: mapping, subjectDocId: subjectDocId} = request, {engine: engine, binding: binding, seedInstance: seedInstance} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry(), toast =
|
|
9476
|
+
const {definition: definitionName, label: label, mapping: mapping, subjectDocId: subjectDocId} = request, {engine: engine, binding: binding, seedInstance: seedInstance} = useWorkflowContext(), telemetry2 = workflowReact.useWorkflowTelemetry(), toast = useWorkflowToast(), {def: definition, error: definitionError} = useLatestDefinition(definitionName), {selectedReleaseId: selectedReleaseId} = sanity.usePerspective(), releaseId = boundReleaseId(mapping, selectedReleaseId), [values, setValues] = react.useState({}), [attempt, setAttempt] = react.useState(void 0), starting = attempt !== void 0, [heldInstanceId, setHeldInstanceId] = react.useState(void 0), [startNew, setStartNew] = react.useState(!1), {entries: entries} = useWorkflowsForDocument(subjectDocId), resumeEntry = presentedResumeEntry({
|
|
8801
9477
|
entries: entries,
|
|
8802
9478
|
definitionName: definitionName,
|
|
8803
9479
|
heldInstanceId: heldInstanceId,
|
|
@@ -8837,8 +9513,9 @@ function StartWorkflowForm({request: request, onClose: onClose}) {
|
|
|
8837
9513
|
values: values
|
|
8838
9514
|
}));
|
|
8839
9515
|
toast.push({
|
|
8840
|
-
|
|
8841
|
-
|
|
9516
|
+
id: TOAST_ID.start,
|
|
9517
|
+
status: "info",
|
|
9518
|
+
title: `“${definition?.title ?? label}” started`,
|
|
8842
9519
|
description: `Stage: ${stageTitle(definition ?? void 0, result.instance.currentStage)}`
|
|
8843
9520
|
}), seedInstance(result.instance), onClose();
|
|
8844
9521
|
} catch (err) {
|
|
@@ -9340,6 +10017,22 @@ function finishedLinesOf(entries) {
|
|
|
9340
10017
|
return [ ...latestByType.values() ].sort((a, b) => b.at - a.at).map(({entry: entry}) => entry);
|
|
9341
10018
|
}
|
|
9342
10019
|
|
|
10020
|
+
function openStageTaskCount(evaluation) {
|
|
10021
|
+
if (evaluation !== void 0) return evaluation.currentStage.activities.filter(activity => isOpenActivityStatus(activity.status)).length;
|
|
10022
|
+
}
|
|
10023
|
+
|
|
10024
|
+
const OPEN_VIEW = "Open the Workflows view";
|
|
10025
|
+
|
|
10026
|
+
function unassignedLineHint(args) {
|
|
10027
|
+
return !args.identityKnown || args.openTaskCount === void 0 ? {
|
|
10028
|
+
text: OPEN_VIEW
|
|
10029
|
+
} : args.openTaskCount === 0 ? {
|
|
10030
|
+
text: "No open tasks in this stage"
|
|
10031
|
+
} : {
|
|
10032
|
+
text: `${pluralize__default.default("open task", args.openTaskCount, !0)}, none assigned to you`
|
|
10033
|
+
};
|
|
10034
|
+
}
|
|
10035
|
+
|
|
9343
10036
|
function WorkflowFormStrip(props) {
|
|
9344
10037
|
const {mappings: mappings} = props, {isDocResolved: isDocResolved, discoveryInvalid: discoveryInvalid} = useWorkflowContext(), {docId: docId, entries: entries} = useWorkflowsForDocument(props.value?._id ?? null), {params: params, setParams: setParams} = structure.usePaneRouter(), telemetry2 = workflowReact.useWorkflowTelemetry(), openWorkflowsView = focusId => {
|
|
9345
10038
|
telemetry2.log(WorkflowFormStripClicked), setParams(focusedViewParams(params, focusId));
|
|
@@ -9384,18 +10077,17 @@ function StripLines({active: active, docId: docId, finished: finished, initialVa
|
|
|
9384
10077
|
});
|
|
9385
10078
|
}
|
|
9386
10079
|
|
|
9387
|
-
function lineHint(
|
|
10080
|
+
function lineHint(entry, identity) {
|
|
10081
|
+
const forMe = forMeWorkOf([ entry ], identity);
|
|
9388
10082
|
return forMe.work.some(({shown: shown}) => hasOpenAssignedWork(shown)) ? {
|
|
9389
10083
|
content: /* @__PURE__ */ jsxRuntime.jsx(AssignedTasksHint, {
|
|
9390
10084
|
work: forMe.work
|
|
9391
10085
|
}),
|
|
9392
10086
|
wide: !0
|
|
9393
|
-
} :
|
|
9394
|
-
|
|
9395
|
-
|
|
9396
|
-
}
|
|
9397
|
-
text: "Open the Workflows view"
|
|
9398
|
-
};
|
|
10087
|
+
} : unassignedLineHint({
|
|
10088
|
+
identityKnown: identity !== void 0,
|
|
10089
|
+
openTaskCount: openStageTaskCount(entry.evaluation)
|
|
10090
|
+
});
|
|
9399
10091
|
}
|
|
9400
10092
|
|
|
9401
10093
|
function StripLine({aside: aside, children: children, hint: hint, onOpen: onOpen}) {
|
|
@@ -9428,7 +10120,7 @@ function InstanceLine({entry: entry, onOpen: onOpen}) {
|
|
|
9428
10120
|
aside: unprimed ? void 0 : /* @__PURE__ */ jsxRuntime.jsx(TaskCountSpinner, {
|
|
9429
10121
|
entry: entry
|
|
9430
10122
|
}),
|
|
9431
|
-
hint: lineHint(
|
|
10123
|
+
hint: lineHint(entry, identity),
|
|
9432
10124
|
onOpen: onOpen,
|
|
9433
10125
|
children: [
|
|
9434
10126
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Flex, {
|
|
@@ -9533,6 +10225,103 @@ function StartWorkflowDialogHost() {
|
|
|
9533
10225
|
}, `${startRequest2.definition}:${startRequest2.subjectDocId ?? ""}`) : null;
|
|
9534
10226
|
}
|
|
9535
10227
|
|
|
10228
|
+
const TOOL_TAB_LABELS = {
|
|
10229
|
+
overview: "Workflows",
|
|
10230
|
+
"all-documents": "All documents",
|
|
10231
|
+
"for-me": "For me"
|
|
10232
|
+
}, TOOL_TAB_VALUES = Object.keys(TOOL_TAB_LABELS), TOOL_TABS = TOOL_TAB_VALUES.map(value => ({
|
|
10233
|
+
value: value,
|
|
10234
|
+
label: TOOL_TAB_LABELS[value]
|
|
10235
|
+
})), LANDING_TAB = "overview", TASKS_TAB = "all-documents", WORKFLOW_PAGE_LABELS = {
|
|
10236
|
+
workflow: "Documents",
|
|
10237
|
+
definition: "Definition"
|
|
10238
|
+
}, WORKFLOW_PAGE_VALUES = Object.keys(WORKFLOW_PAGE_LABELS), DEFAULT_WORKFLOW_PAGE = "workflow", WORKFLOW_PAGES = WORKFLOW_PAGE_VALUES.filter(page => page !== DEFAULT_WORKFLOW_PAGE), WORKFLOW_PAGE_TABS = WORKFLOW_PAGE_VALUES.map(value => ({
|
|
10239
|
+
value: value,
|
|
10240
|
+
label: WORKFLOW_PAGE_LABELS[value]
|
|
10241
|
+
})), toolRouter = router.route.create("/", [ router.route.create("/instance/:instanceId"), router.route.create(`/${LANDING_TAB}/:workflowName`, [ router.route.create("/:workflowPage") ]), router.route.create("/:workflowsTab") ]);
|
|
10242
|
+
|
|
10243
|
+
function toolTabState(tab) {
|
|
10244
|
+
return {
|
|
10245
|
+
workflowsTab: tab
|
|
10246
|
+
};
|
|
10247
|
+
}
|
|
10248
|
+
|
|
10249
|
+
function landingState() {
|
|
10250
|
+
return toolTabState(LANDING_TAB);
|
|
10251
|
+
}
|
|
10252
|
+
|
|
10253
|
+
function workflowState(workflowName) {
|
|
10254
|
+
return {
|
|
10255
|
+
workflowName: workflowName
|
|
10256
|
+
};
|
|
10257
|
+
}
|
|
10258
|
+
|
|
10259
|
+
function instanceState(instanceId) {
|
|
10260
|
+
return {
|
|
10261
|
+
instanceId: instanceId
|
|
10262
|
+
};
|
|
10263
|
+
}
|
|
10264
|
+
|
|
10265
|
+
function tabSelectionNavigates(current, tab) {
|
|
10266
|
+
return !(current.kind === "home" && tab === current.tab);
|
|
10267
|
+
}
|
|
10268
|
+
|
|
10269
|
+
function toolTabLabel(tab) {
|
|
10270
|
+
return TOOL_TAB_LABELS[tab];
|
|
10271
|
+
}
|
|
10272
|
+
|
|
10273
|
+
function backToTabLabel(tab) {
|
|
10274
|
+
return `Back to ${toolTabLabel(tab)}`;
|
|
10275
|
+
}
|
|
10276
|
+
|
|
10277
|
+
function workflowPageState(page, workflowName) {
|
|
10278
|
+
return page === DEFAULT_WORKFLOW_PAGE ? workflowState(workflowName) : {
|
|
10279
|
+
...workflowState(workflowName),
|
|
10280
|
+
workflowPage: page
|
|
10281
|
+
};
|
|
10282
|
+
}
|
|
10283
|
+
|
|
10284
|
+
function toolRoute(state) {
|
|
10285
|
+
const {instanceId: instanceId, workflowName: workflowName} = state;
|
|
10286
|
+
if (typeof instanceId == "string") return {
|
|
10287
|
+
kind: "instance",
|
|
10288
|
+
instanceId: instanceId,
|
|
10289
|
+
tab: TASKS_TAB
|
|
10290
|
+
};
|
|
10291
|
+
if (typeof workflowName == "string") return workflowRoute(workflowName, state.workflowPage);
|
|
10292
|
+
const tab = pathSegmentName({
|
|
10293
|
+
segment: state.workflowsTab,
|
|
10294
|
+
names: TOOL_TAB_VALUES
|
|
10295
|
+
});
|
|
10296
|
+
return tab === void 0 ? {
|
|
10297
|
+
kind: "unnamed",
|
|
10298
|
+
tab: LANDING_TAB
|
|
10299
|
+
} : {
|
|
10300
|
+
kind: "home",
|
|
10301
|
+
tab: tab
|
|
10302
|
+
};
|
|
10303
|
+
}
|
|
10304
|
+
|
|
10305
|
+
function workflowRoute(workflowName, pageSegment) {
|
|
10306
|
+
if (pageSegment === void 0) return {
|
|
10307
|
+
kind: "workflow",
|
|
10308
|
+
workflowName: workflowName,
|
|
10309
|
+
tab: LANDING_TAB
|
|
10310
|
+
};
|
|
10311
|
+
const page = pathSegmentName({
|
|
10312
|
+
segment: pageSegment,
|
|
10313
|
+
names: WORKFLOW_PAGES
|
|
10314
|
+
});
|
|
10315
|
+
return page === void 0 ? {
|
|
10316
|
+
kind: "unnamed",
|
|
10317
|
+
tab: LANDING_TAB
|
|
10318
|
+
} : {
|
|
10319
|
+
kind: page,
|
|
10320
|
+
workflowName: workflowName,
|
|
10321
|
+
tab: LANDING_TAB
|
|
10322
|
+
};
|
|
10323
|
+
}
|
|
10324
|
+
|
|
9536
10325
|
const WorkflowsToolRoot = react.lazy(() => Promise.resolve().then(function() {
|
|
9537
10326
|
return require("./workflows-tool-root.cjs");
|
|
9538
10327
|
}));
|
|
@@ -9550,7 +10339,7 @@ const workflowsTool = {
|
|
|
9550
10339
|
title: "Workflows",
|
|
9551
10340
|
icon: Transfer.TransferIcon,
|
|
9552
10341
|
component: LazyWorkflowsTool,
|
|
9553
|
-
router:
|
|
10342
|
+
router: toolRouter,
|
|
9554
10343
|
canHandleIntent: (intent, params) => handlesWorkflowIntent(intent, params),
|
|
9555
10344
|
getIntentState: (intent, params) => workflowIntentState(intent, params)
|
|
9556
10345
|
}, LOCKABLE_ACTIONS = /* @__PURE__ */ new Map([ [ "delete", "delete" ], [ "publish", "publish" ], [ "unpublish", "unpublish" ] ]);
|
|
@@ -9654,14 +10443,20 @@ exports.CautionNote = CautionNote;
|
|
|
9654
10443
|
|
|
9655
10444
|
exports.CollapsibleBand = CollapsibleBand;
|
|
9656
10445
|
|
|
10446
|
+
exports.CountedLabel = CountedLabel;
|
|
10447
|
+
|
|
9657
10448
|
exports.DismissablePopover = DismissablePopover;
|
|
9658
10449
|
|
|
9659
10450
|
exports.DocPreviewLink = DocPreviewLink;
|
|
9660
10451
|
|
|
9661
10452
|
exports.DocRefFace = DocRefFace;
|
|
9662
10453
|
|
|
10454
|
+
exports.EmptyState = EmptyState;
|
|
10455
|
+
|
|
9663
10456
|
exports.ForMeEmptyState = ForMeEmptyState;
|
|
9664
10457
|
|
|
10458
|
+
exports.Hairline = Hairline;
|
|
10459
|
+
|
|
9665
10460
|
exports.HintedMenuButton = HintedMenuButton;
|
|
9666
10461
|
|
|
9667
10462
|
exports.HoverHint = HoverHint;
|
|
@@ -9674,6 +10469,8 @@ exports.LinkChip = LinkChip;
|
|
|
9674
10469
|
|
|
9675
10470
|
exports.LoadingRow = LoadingRow;
|
|
9676
10471
|
|
|
10472
|
+
exports.LogEventOnMount = LogEventOnMount;
|
|
10473
|
+
|
|
9677
10474
|
exports.MetaRow = MetaRow;
|
|
9678
10475
|
|
|
9679
10476
|
exports.SpinnerSlot = SpinnerSlot;
|
|
@@ -9682,6 +10479,10 @@ exports.StageFace = StageFace;
|
|
|
9682
10479
|
|
|
9683
10480
|
exports.StaleLock = StaleLock;
|
|
9684
10481
|
|
|
10482
|
+
exports.TOAST_ID = TOAST_ID;
|
|
10483
|
+
|
|
10484
|
+
exports.TOOL_TABS = TOOL_TABS;
|
|
10485
|
+
|
|
9685
10486
|
exports.TabSwitch = TabSwitch;
|
|
9686
10487
|
|
|
9687
10488
|
exports.TrailingHairline = TrailingHairline;
|
|
@@ -9692,26 +10493,44 @@ exports.UserAvatar = UserAvatar;
|
|
|
9692
10493
|
|
|
9693
10494
|
exports.WORKFLOW_API_VERSION = WORKFLOW_API_VERSION;
|
|
9694
10495
|
|
|
10496
|
+
exports.WORKFLOW_PAGE_TABS = WORKFLOW_PAGE_TABS;
|
|
10497
|
+
|
|
10498
|
+
exports.WorkflowAbortDialogOpened = WorkflowAbortDialogOpened;
|
|
10499
|
+
|
|
10500
|
+
exports.WorkflowAbortDialogSubmitted = WorkflowAbortDialogSubmitted;
|
|
10501
|
+
|
|
10502
|
+
exports.WorkflowBoardWorkflowSelected = WorkflowBoardWorkflowSelected;
|
|
10503
|
+
|
|
10504
|
+
exports.WorkflowDefinitionDetailViewed = WorkflowDefinitionDetailViewed;
|
|
10505
|
+
|
|
9695
10506
|
exports.WorkflowInstanceDetailViewed = WorkflowInstanceDetailViewed;
|
|
9696
10507
|
|
|
9697
10508
|
exports.WorkflowTaskFiltersApplied = WorkflowTaskFiltersApplied;
|
|
9698
10509
|
|
|
10510
|
+
exports.WorkflowTitleSeedDrifted = WorkflowTitleSeedDrifted;
|
|
10511
|
+
|
|
9699
10512
|
exports.WorkflowToolOpened = WorkflowToolOpened;
|
|
9700
10513
|
|
|
9701
10514
|
exports.activityRowProps = activityRowProps;
|
|
9702
10515
|
|
|
9703
10516
|
exports.assigneeUserIdsOf = assigneeUserIdsOf;
|
|
9704
10517
|
|
|
10518
|
+
exports.backToTabLabel = backToTabLabel;
|
|
10519
|
+
|
|
9705
10520
|
exports.committedRowFace = committedRowFace;
|
|
9706
10521
|
|
|
9707
|
-
exports.
|
|
10522
|
+
exports.createSubscribers = createSubscribers;
|
|
10523
|
+
|
|
10524
|
+
exports.datesOf = datesOf;
|
|
9708
10525
|
|
|
9709
|
-
exports.
|
|
10526
|
+
exports.definitionFingerprint = definitionFingerprint;
|
|
9710
10527
|
|
|
9711
10528
|
exports.definitionSnapshotOf = definitionSnapshotOf;
|
|
9712
10529
|
|
|
9713
10530
|
exports.describeError = describeError;
|
|
9714
10531
|
|
|
10532
|
+
exports.dueDatesOf = dueDatesOf;
|
|
10533
|
+
|
|
9715
10534
|
exports.findActivity = findActivity;
|
|
9716
10535
|
|
|
9717
10536
|
exports.findActivityNode = findActivityNode;
|
|
@@ -9722,43 +10541,53 @@ exports.formatDateTime = formatDateTime;
|
|
|
9722
10541
|
|
|
9723
10542
|
exports.formatShortAgo = formatShortAgo;
|
|
9724
10543
|
|
|
10544
|
+
exports.formatShortDateTime = formatShortDateTime;
|
|
10545
|
+
|
|
10546
|
+
exports.formatTimeAgo = formatTimeAgo;
|
|
10547
|
+
|
|
9725
10548
|
exports.gdrLocality = gdrLocality;
|
|
9726
10549
|
|
|
9727
10550
|
exports.instanceBreadcrumb = instanceBreadcrumb;
|
|
9728
10551
|
|
|
10552
|
+
exports.instanceState = instanceState;
|
|
10553
|
+
|
|
9729
10554
|
exports.instanceTitle = instanceTitle;
|
|
9730
10555
|
|
|
9731
10556
|
exports.isActivityAssignedTo = isActivityAssignedTo;
|
|
9732
10557
|
|
|
9733
10558
|
exports.isEvaluationStale = isEvaluationStale;
|
|
9734
10559
|
|
|
10560
|
+
exports.isLiveEntry = isLiveEntry;
|
|
10561
|
+
|
|
9735
10562
|
exports.isOpenActivityStatus = isOpenActivityStatus;
|
|
9736
10563
|
|
|
10564
|
+
exports.landingState = landingState;
|
|
10565
|
+
|
|
10566
|
+
exports.mappingIssueDetail = mappingIssueDetail;
|
|
10567
|
+
|
|
10568
|
+
exports.namesNoDeployedDefinition = namesNoDeployedDefinition;
|
|
10569
|
+
|
|
9737
10570
|
exports.openActivityGone = openActivityGone;
|
|
9738
10571
|
|
|
9739
10572
|
exports.openableSchemaType = openableSchemaType;
|
|
9740
10573
|
|
|
9741
|
-
exports.parseDateFieldValue = parseDateFieldValue;
|
|
9742
|
-
|
|
9743
10574
|
exports.parseStoredDateValue = parseStoredDateValue;
|
|
9744
10575
|
|
|
9745
|
-
exports.pathSegmentTab = pathSegmentTab;
|
|
9746
|
-
|
|
9747
10576
|
exports.readDeployedDefinitions = readDeployedDefinitions;
|
|
9748
10577
|
|
|
9749
10578
|
exports.rowAssignControlState = rowAssignControlState;
|
|
9750
10579
|
|
|
9751
10580
|
exports.rowDateControlState = rowDateControlState;
|
|
9752
10581
|
|
|
9753
|
-
exports.serializeDateFieldValue = serializeDateFieldValue;
|
|
9754
|
-
|
|
9755
10582
|
exports.stageTitle = stageTitle;
|
|
9756
10583
|
|
|
9757
10584
|
exports.stateByActivity = stateByActivity;
|
|
9758
10585
|
|
|
9759
|
-
exports.
|
|
10586
|
+
exports.tabSelectionNavigates = tabSelectionNavigates;
|
|
10587
|
+
|
|
10588
|
+
exports.toolRoute = toolRoute;
|
|
9760
10589
|
|
|
9761
|
-
exports.
|
|
10590
|
+
exports.toolTabState = toolTabState;
|
|
9762
10591
|
|
|
9763
10592
|
exports.useAssignmentIdentity = useAssignmentIdentity;
|
|
9764
10593
|
|
|
@@ -9766,18 +10595,16 @@ exports.useAvatarSize = useAvatarSize;
|
|
|
9766
10595
|
|
|
9767
10596
|
exports.useBadgeCapTrim = useBadgeCapTrim;
|
|
9768
10597
|
|
|
9769
|
-
exports.useClosableToast = useClosableToast;
|
|
9770
|
-
|
|
9771
10598
|
exports.useContainerToken = useContainerToken;
|
|
9772
10599
|
|
|
9773
10600
|
exports.useDefinition = useDefinition;
|
|
9774
10601
|
|
|
10602
|
+
exports.useDelayedFlag = useDelayedFlag;
|
|
10603
|
+
|
|
9775
10604
|
exports.useLogEventOnMount = useLogEventOnMount;
|
|
9776
10605
|
|
|
9777
10606
|
exports.useProjectMembers = useProjectMembers;
|
|
9778
10607
|
|
|
9779
|
-
exports.useSaveField = useSaveField;
|
|
9780
|
-
|
|
9781
10608
|
exports.useSpaceToken = useSpaceToken;
|
|
9782
10609
|
|
|
9783
10610
|
exports.useUserDisplay = useUserDisplay;
|
|
@@ -9788,8 +10615,14 @@ exports.useWorkflowContext = useWorkflowContext;
|
|
|
9788
10615
|
|
|
9789
10616
|
exports.useWorkflowInstanceEntry = useWorkflowInstanceEntry;
|
|
9790
10617
|
|
|
10618
|
+
exports.useWorkflowToast = useWorkflowToast;
|
|
10619
|
+
|
|
9791
10620
|
exports.workflowDefaultDocumentNode = workflowDefaultDocumentNode;
|
|
9792
10621
|
|
|
10622
|
+
exports.workflowPageState = workflowPageState;
|
|
10623
|
+
|
|
10624
|
+
exports.workflowState = workflowState;
|
|
10625
|
+
|
|
9793
10626
|
exports.workflowStudioPlugin = workflowStudioPlugin;
|
|
9794
10627
|
|
|
9795
10628
|
exports.workflowsView = workflowsView;
|