@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
package/dist/_chunks-es/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
|
2
2
|
|
|
3
3
|
import { TimelineIcon } from "@sanity/icons/Timeline";
|
|
4
4
|
|
|
5
|
-
import { Tooltip, Box, Stack, Text, useClickOutsideEvent,
|
|
5
|
+
import { Popover, Tooltip, Box, Stack, Text, useClickOutsideEvent, Flex, TextInput, Button, Select, Checkbox, Autocomplete, Card, TextArea, useToast, Dialog, Switch, TextSkeleton, Code, useTheme_v2, Spinner, Badge, MenuButton, Menu, MenuItem, useElementSize, TabList, Tab, TabPanel } from "@sanity/ui";
|
|
6
6
|
|
|
7
7
|
import { editFieldTarget, useWorkflowTelemetry, useRefcountedIds } from "@sanity/workflow-react";
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ import { createContext, useContext, useEffect, useSyncExternalStore, useCallback
|
|
|
10
10
|
|
|
11
11
|
import { usePaneRouter } from "sanity/structure";
|
|
12
12
|
|
|
13
|
-
import { tryParseGdr, resourceFromParsed, latestDeployedDefinitions, isStartableDefinition, isSubjectEntry, isInputSourced, acceptsDocumentType,
|
|
13
|
+
import { WORKFLOW_INSTANCE_TYPE, WORKFLOW_DEFINITION_TYPE, GUARD_DOC_TYPE, tryParseGdr, resourceFromParsed, latestDeployedDefinitions, isStartableDefinition, isSubjectEntry, isInputSourced, acceptsDocumentType, initialFieldIssues, gdrRef, releaseRef, refKindAcceptsTypes, rejectedRefTypes, ActionDisabledError, MutationGuardDeniedError, EditFieldDeniedError, errorMessage, terminalState, findOpenStageEntry, actionRendering, isTodoListEntry, isTodoListItem, isTerminalActivityStatus, describeCondition, sentenceCase, checklistLines, findCurrentActivityEntry, ENGINE_API_VERSION, scalarValidationIssues, classifyPrincipalId, toBareId, isSingleDocRefEntry, isGdr, resolveFieldEntry, isSingleDocRefKind, isNotesEntry, parseDefinitionSnapshot, isUnprimed, isTerminalStage, DEFAULT_TRANSITION_WHEN, instancesQuery, assertReadableModel, projectStartSliceRow, StartNotSettledError, StartNotAllowedError, humanize, unboundRequirementReads, explainStartRequirement, singleSubjectRequirementRefused, evaluateStartFilter, startKindOf, hasSingleSubjectRequirement, readsRootDocument, latestDefinitionsGroq, gdrFromResource, subscriptionDocumentsForInstance, aclPathForResource, definitionLookupGroq, instanceDocId, missingRequiredInputs, documentActionDenials } from "@sanity/workflow-engine";
|
|
14
14
|
|
|
15
15
|
import { CheckmarkIcon } from "@sanity/icons/Checkmark";
|
|
16
16
|
|
|
@@ -26,7 +26,7 @@ import { defineEvent } from "@sanity/telemetry";
|
|
|
26
26
|
|
|
27
27
|
import { useStudioProjectUsers, useStudioObserver, useWorkflowEngine, useWorkflowInstances, useWorkflowSession } from "@sanity/workflow-studio";
|
|
28
28
|
|
|
29
|
-
import { useCurrentUser,
|
|
29
|
+
import { useCurrentUser, Preview, SanityDefaultPreview, useValuePreview, useClient, useSchema, useWorkspace, TextWithTone, usePerspective, useIsReleaseActive, useDocumentPreviewStore, useActiveReleases, useTemplates, useInitialValueResolverContext, resolveInitialValue, definePlugin, isObjectInputProps } from "sanity";
|
|
30
30
|
|
|
31
31
|
import { CalendarIcon } from "@sanity/icons/Calendar";
|
|
32
32
|
|
|
@@ -78,6 +78,18 @@ import { switchMap, distinctUntilChanged } from "rxjs/operators";
|
|
|
78
78
|
|
|
79
79
|
import { TransferIcon } from "@sanity/icons/Transfer";
|
|
80
80
|
|
|
81
|
+
const WORKFLOW_SYSTEM_TYPES = [ WORKFLOW_INSTANCE_TYPE, WORKFLOW_DEFINITION_TYPE, GUARD_DOC_TYPE ];
|
|
82
|
+
|
|
83
|
+
function contentDocumentTypes(schema) {
|
|
84
|
+
return schema.getTypeNames().filter(name => schema.get(name)?.type?.name === "document" && !WORKFLOW_SYSTEM_TYPES.includes(name));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const SYSTEM_TYPE_PREFIX = "sanity.";
|
|
88
|
+
|
|
89
|
+
function isSystemDocumentType(name) {
|
|
90
|
+
return name.startsWith(SYSTEM_TYPE_PREFIX) || WORKFLOW_SYSTEM_TYPES.includes(name);
|
|
91
|
+
}
|
|
92
|
+
|
|
81
93
|
function isLocalContentResource(resource, contentResource) {
|
|
82
94
|
return resource?.type === "dataset" && resource.id === contentResource.id;
|
|
83
95
|
}
|
|
@@ -102,14 +114,14 @@ function assertUniqueWorkflowMappings(mappings) {
|
|
|
102
114
|
|
|
103
115
|
function discoverWorkflowMappings(args) {
|
|
104
116
|
assertUniqueWorkflowMappings(args.overrides ?? []);
|
|
105
|
-
const discovered = latestDeployedDefinitions(args.definitions).flatMap(definition => {
|
|
117
|
+
const bindable = [ ...args.schemaContentTypes ].filter(name => !isSystemDocumentType(name)), discovered = latestDeployedDefinitions(args.definitions).flatMap(definition => {
|
|
106
118
|
if (!isStartableDefinition(definition)) return [];
|
|
107
119
|
const subject = (definition.fields ?? []).find(isSubjectEntry);
|
|
108
120
|
if (subject === void 0 || !isInputSourced(subject)) return [];
|
|
109
121
|
const source = {
|
|
110
122
|
fields: [ ...definition.fields ?? [] ]
|
|
111
123
|
};
|
|
112
|
-
return
|
|
124
|
+
return bindable.filter(docType => acceptsDocumentType(source, docType)).map(docType => ({
|
|
113
125
|
docType: docType,
|
|
114
126
|
definition: definition.name,
|
|
115
127
|
label: definition.title ?? definition.name
|
|
@@ -240,14 +252,11 @@ function rowProblems(args) {
|
|
|
240
252
|
mapping: args.mapping,
|
|
241
253
|
contentResource: args.contentResource,
|
|
242
254
|
declared: declared
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
initialFields: seeded
|
|
246
|
-
}), consumptionProblems = initialFieldIssues({
|
|
255
|
+
});
|
|
256
|
+
return [ ...initialFieldIssues({
|
|
247
257
|
workflowFields: declared,
|
|
248
258
|
initialFields: seeded
|
|
249
|
-
}).flatMap(issue => seedConsumptionProblem(issue) ?? [])
|
|
250
|
-
return [ ...missing.map(m => `its start would not provide the required entry "${m.name}" (${m.type})`), ...consumptionProblems, ...seeded.flatMap(seed => seedReferenceProblems({
|
|
259
|
+
}).flatMap(issue => seedConsumptionProblem(issue) ?? []), ...seeded.flatMap(seed => seedReferenceProblems({
|
|
251
260
|
seed: seed,
|
|
252
261
|
declared: declared
|
|
253
262
|
})), ...seeded.flatMap(seed => seededSchemaProblems({
|
|
@@ -257,12 +266,24 @@ function rowProblems(args) {
|
|
|
257
266
|
})) ];
|
|
258
267
|
}
|
|
259
268
|
|
|
269
|
+
const NOT_DEPLOYED = "the definition is not deployed — deploy it or fix the mapping row";
|
|
270
|
+
|
|
271
|
+
function namesNoDeployedDefinition(issue) {
|
|
272
|
+
return issue.version === void 0;
|
|
273
|
+
}
|
|
274
|
+
|
|
260
275
|
function mappingIssues(args) {
|
|
261
276
|
const latestByName = new Map(latestDeployedDefinitions(args.definitions).map(d => [ d.name, d ])), issues = /* @__PURE__ */ new Map;
|
|
262
277
|
for (const mapping of args.mappings) {
|
|
263
|
-
const
|
|
278
|
+
const identity = {
|
|
279
|
+
docType: mapping.docType,
|
|
280
|
+
definition: mapping.definition
|
|
281
|
+
}, definition = latestByName.get(mapping.definition);
|
|
264
282
|
if (definition === void 0) {
|
|
265
|
-
issues.set(mappingKey(mapping),
|
|
283
|
+
issues.set(mappingKey(mapping), {
|
|
284
|
+
...identity,
|
|
285
|
+
problems: [ NOT_DEPLOYED ]
|
|
286
|
+
});
|
|
266
287
|
continue;
|
|
267
288
|
}
|
|
268
289
|
const problems = rowProblems({
|
|
@@ -271,11 +292,31 @@ function mappingIssues(args) {
|
|
|
271
292
|
contentResource: args.contentResource,
|
|
272
293
|
schemaContentTypes: args.schemaContentTypes
|
|
273
294
|
});
|
|
274
|
-
problems.length > 0 && issues.set(mappingKey(mapping),
|
|
295
|
+
problems.length > 0 && issues.set(mappingKey(mapping), {
|
|
296
|
+
...identity,
|
|
297
|
+
version: definition.version,
|
|
298
|
+
problems: problems
|
|
299
|
+
});
|
|
275
300
|
}
|
|
276
301
|
return issues;
|
|
277
302
|
}
|
|
278
303
|
|
|
304
|
+
function sameMappingIssue(left, right) {
|
|
305
|
+
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]);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function mappingIssueDetail(issue) {
|
|
309
|
+
return issue.problems.join("; ");
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function versionSuffix(issue) {
|
|
313
|
+
return issue.version === void 0 ? "" : ` (v${issue.version})`;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function mappingIssueLogLines(issues) {
|
|
317
|
+
return [ ...issues.values() ].map(issue => `The "${issue.docType}" → "${issue.definition}" mapping row${versionSuffix(issue)} is disabled: ${mappingIssueDetail(issue)}.`);
|
|
318
|
+
}
|
|
319
|
+
|
|
279
320
|
const WORKFLOWS_VIEW_ID = "workflows", WORKFLOWS_TAB_PARAM = "workflowsTab";
|
|
280
321
|
|
|
281
322
|
function withoutWorkflowsTab(params) {
|
|
@@ -318,10 +359,16 @@ function landingDefaultOpen(landing, instanceId) {
|
|
|
318
359
|
if (!(landing === void 0 || !landing.instanceIds.includes(instanceId))) return instanceId === landing.focusedId;
|
|
319
360
|
}
|
|
320
361
|
|
|
321
|
-
const WORKFLOWS_TOOL_NAME = "workflows"
|
|
362
|
+
const WORKFLOWS_TOOL_NAME = "workflows";
|
|
363
|
+
|
|
364
|
+
function workflowsToolAvailable(tools) {
|
|
365
|
+
return tools.some(tool => tool.name === WORKFLOWS_TOOL_NAME);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const WORKFLOW_INTENT = "workflow";
|
|
322
369
|
|
|
323
|
-
function
|
|
324
|
-
return args.
|
|
370
|
+
function pathSegmentName(args) {
|
|
371
|
+
return args.names.find(name => name === args.segment);
|
|
325
372
|
}
|
|
326
373
|
|
|
327
374
|
function handlesWorkflowIntent(intent, params) {
|
|
@@ -335,11 +382,23 @@ function workflowIntentState(intent, params) {
|
|
|
335
382
|
} : null;
|
|
336
383
|
}
|
|
337
384
|
|
|
338
|
-
const pad2 = n => String(n).padStart(2, "0");
|
|
385
|
+
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);
|
|
386
|
+
|
|
387
|
+
function isDateFieldKind(kind) {
|
|
388
|
+
return DATE_FIELD_KIND_SET.has(kind);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function isDueDateFieldKind(kind) {
|
|
392
|
+
return DUE_DATE_FIELD_KIND_SET.has(kind);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function hasTimeOfDay(kind) {
|
|
396
|
+
return kind === "datetime" || kind === "dueDatetime";
|
|
397
|
+
}
|
|
339
398
|
|
|
340
399
|
function parseDateFieldValue(value, kind) {
|
|
341
400
|
if (typeof value != "string" || value === "") return;
|
|
342
|
-
const parsed2 = kind
|
|
401
|
+
const parsed2 = hasTimeOfDay(kind) ? new Date(value) : parseLocalDate(value);
|
|
343
402
|
return Number.isNaN(parsed2.getTime()) ? void 0 : parsed2;
|
|
344
403
|
}
|
|
345
404
|
|
|
@@ -355,16 +414,24 @@ function parseStoredDateValue(value) {
|
|
|
355
414
|
}
|
|
356
415
|
|
|
357
416
|
function serializeDateFieldValue(date, kind) {
|
|
358
|
-
return kind
|
|
417
|
+
return hasTimeOfDay(kind) ? date.toISOString() : `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
class EffectsIncompleteError extends Error {
|
|
421
|
+
reason;
|
|
422
|
+
constructor(reason, options) {
|
|
423
|
+
super(`The change was committed, but running its effects failed: ${reason}`, options),
|
|
424
|
+
this.name = "EffectsIncompleteError", this.reason = reason;
|
|
425
|
+
}
|
|
359
426
|
}
|
|
360
427
|
|
|
361
428
|
const editDisabledSentence = {
|
|
362
429
|
"edit-window-closed": () => "Can only be edited while its activity is active",
|
|
363
|
-
"editor-not-permitted": () => "You don
|
|
430
|
+
"editor-not-permitted": () => "You don’t have permission to edit this",
|
|
364
431
|
"instance-aborted": () => "This workflow was aborted",
|
|
365
432
|
"instance-completed": () => "This workflow is already complete",
|
|
366
433
|
"mutation-guard-denied": () => "An earlier step is holding this document",
|
|
367
|
-
"not-editable": () => "This isn
|
|
434
|
+
"not-editable": () => "This isn’t editable here"
|
|
368
435
|
};
|
|
369
436
|
|
|
370
437
|
function describeEditDisabledReason(reason) {
|
|
@@ -437,24 +504,43 @@ const activityNotActiveSentence = {
|
|
|
437
504
|
}, disabledSentence = {
|
|
438
505
|
"activity-not-active": r => activityNotActiveSentence[r.status],
|
|
439
506
|
"cascade-fired": () => "This happens automatically — the workflow runs it when its condition is met.",
|
|
440
|
-
"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
|
|
507
|
+
"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.",
|
|
441
508
|
"instance-aborted": () => "This workflow was aborted.",
|
|
442
509
|
"instance-completed": () => "This workflow is already complete.",
|
|
443
510
|
"mutation-guard-denied": () => "An earlier step is holding this document.",
|
|
444
|
-
"requirements-unmet": () => "This step isn
|
|
511
|
+
"requirements-unmet": () => "This step isn’t ready yet — a required condition hasn’t been met.",
|
|
445
512
|
"stage-terminal": () => "This stage is finished.",
|
|
446
|
-
"subject-permission-denied": () => "You don
|
|
513
|
+
"subject-permission-denied": () => "You don’t have permission to change the document this step works on."
|
|
447
514
|
};
|
|
448
515
|
|
|
449
516
|
function describeDisabledReason(reason) {
|
|
450
517
|
return disabledSentence[reason.kind](reason);
|
|
451
518
|
}
|
|
452
519
|
|
|
520
|
+
function readRejection(err) {
|
|
521
|
+
return err instanceof ActionDisabledError ? {
|
|
522
|
+
kind: "refusal",
|
|
523
|
+
message: describeDisabledReason(err.reason)
|
|
524
|
+
} : err instanceof MutationGuardDeniedError ? {
|
|
525
|
+
kind: "refusal",
|
|
526
|
+
message: describeDisabledReason({
|
|
527
|
+
kind: "mutation-guard-denied",
|
|
528
|
+
denied: err.denied
|
|
529
|
+
})
|
|
530
|
+
} : err instanceof EditFieldDeniedError ? {
|
|
531
|
+
kind: "refusal",
|
|
532
|
+
message: describeEditDisabledReason(err.reason)
|
|
533
|
+
} : err instanceof EffectsIncompleteError ? {
|
|
534
|
+
kind: "committed-incomplete",
|
|
535
|
+
message: err.reason
|
|
536
|
+
} : {
|
|
537
|
+
kind: "failure",
|
|
538
|
+
message: errorMessage(err)
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
|
|
453
542
|
function describeError(err) {
|
|
454
|
-
return
|
|
455
|
-
kind: "mutation-guard-denied",
|
|
456
|
-
denied: err.denied
|
|
457
|
-
}) : errorMessage(err);
|
|
543
|
+
return readRejection(err).message;
|
|
458
544
|
}
|
|
459
545
|
|
|
460
546
|
function hrefIfHttp(value) {
|
|
@@ -510,6 +596,28 @@ function isTodoOverdue(item, today = /* @__PURE__ */ new Date) {
|
|
|
510
596
|
return !item.dueDate || isTodoDone(item) ? !1 : item.dueDate < serializeDateFieldValue(today, "date");
|
|
511
597
|
}
|
|
512
598
|
|
|
599
|
+
function todoEditKind(patch) {
|
|
600
|
+
return "assignee" in patch ? "assignee" : "due-date";
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
function assertNamesOneRow(items, key) {
|
|
604
|
+
const matches = items.filter(row => row._key === key).length;
|
|
605
|
+
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.`);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
function todoItemsPatched(args) {
|
|
609
|
+
const {items: items, key: key, patch: patch} = args;
|
|
610
|
+
return assertNamesOneRow(items, key), items.map(row => row._key === key ? {
|
|
611
|
+
...row,
|
|
612
|
+
...patch
|
|
613
|
+
} : row);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
function todoItemsWithout(args) {
|
|
617
|
+
const {items: items, key: key} = args;
|
|
618
|
+
return assertNamesOneRow(items, key), items.filter(row => row._key !== key);
|
|
619
|
+
}
|
|
620
|
+
|
|
513
621
|
function tickOpsOf(action) {
|
|
514
622
|
return (action.ops ?? []).flatMap(o => o.type === "field.updateWhere" ? [ o ] : []);
|
|
515
623
|
}
|
|
@@ -950,11 +1058,23 @@ function rowAssignControlState(args) {
|
|
|
950
1058
|
|
|
951
1059
|
function rowDateControlState(args) {
|
|
952
1060
|
return rowControlState({
|
|
953
|
-
kinds:
|
|
1061
|
+
kinds: DUE_DATE_FIELD_KINDS,
|
|
954
1062
|
...args
|
|
955
1063
|
});
|
|
956
1064
|
}
|
|
957
1065
|
|
|
1066
|
+
function dateValuesOf(state, matches) {
|
|
1067
|
+
return state.filter(entry => matches(entry._type)).map(entry => entry.value).filter(value => typeof value == "string" && value !== "");
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
function datesOf(state) {
|
|
1071
|
+
return dateValuesOf(state, isDateFieldKind);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
function dueDatesOf(state) {
|
|
1075
|
+
return dateValuesOf(state, isDueDateFieldKind);
|
|
1076
|
+
}
|
|
1077
|
+
|
|
958
1078
|
function committedRowFace(row) {
|
|
959
1079
|
return {
|
|
960
1080
|
activityName: row.activityName,
|
|
@@ -966,7 +1086,11 @@ function committedRowFace(row) {
|
|
|
966
1086
|
}
|
|
967
1087
|
|
|
968
1088
|
function activityRowProps(args) {
|
|
969
|
-
const {activityEval: activityEval, activityState: activityState, editableFields: editableFields} = args, state = activityState.get(activityEval.activity.name) ?? []
|
|
1089
|
+
const {activityEval: activityEval, activityState: activityState, editableFields: editableFields} = args, state = activityState.get(activityEval.activity.name) ?? [], controlArgs = {
|
|
1090
|
+
activity: activityEval.activity,
|
|
1091
|
+
status: activityEval.status,
|
|
1092
|
+
editableFields: editableFields
|
|
1093
|
+
};
|
|
970
1094
|
return {
|
|
971
1095
|
face: {
|
|
972
1096
|
activityName: activityEval.activity.name,
|
|
@@ -975,12 +1099,10 @@ function activityRowProps(args) {
|
|
|
975
1099
|
automated: showsAutomatedPill(activityEval),
|
|
976
1100
|
blocked: showsBlockedTag(activityEval)
|
|
977
1101
|
},
|
|
978
|
-
assignState: rowAssignControlState(
|
|
979
|
-
activity: activityEval.activity,
|
|
980
|
-
status: activityEval.status,
|
|
981
|
-
editableFields: editableFields
|
|
982
|
-
}),
|
|
1102
|
+
assignState: rowAssignControlState(controlArgs),
|
|
983
1103
|
assigneeIds: assigneeUserIdsOf(state),
|
|
1104
|
+
dateState: rowDateControlState(controlArgs),
|
|
1105
|
+
dueDates: dueDatesOf(state),
|
|
984
1106
|
terminalActions: rowTerminalActions({
|
|
985
1107
|
activityEval: activityEval,
|
|
986
1108
|
state: state,
|
|
@@ -990,12 +1112,12 @@ function activityRowProps(args) {
|
|
|
990
1112
|
}
|
|
991
1113
|
|
|
992
1114
|
function dateControlKind(state) {
|
|
993
|
-
if (state.kind === "editable" && (state.field.type
|
|
1115
|
+
if (state.kind === "editable" && isDueDateFieldKind(state.field.type)) return state.field.type;
|
|
994
1116
|
}
|
|
995
1117
|
|
|
996
1118
|
function dateControlValue(args) {
|
|
997
|
-
const {state: state,
|
|
998
|
-
return state.kind === "editable" ? typeof state.field.value == "string" && state.field.value !== "" ? state.field.value : void 0 :
|
|
1119
|
+
const {state: state, dueDates: dueDates} = args;
|
|
1120
|
+
return state.kind === "editable" ? typeof state.field.value == "string" && state.field.value !== "" ? state.field.value : void 0 : dueDates.find(value => parseStoredDateValue(value) !== void 0);
|
|
999
1121
|
}
|
|
1000
1122
|
|
|
1001
1123
|
function activityStateOf(instance, activityName) {
|
|
@@ -1020,7 +1142,7 @@ function deriveActivityDetail(args) {
|
|
|
1020
1142
|
};
|
|
1021
1143
|
}
|
|
1022
1144
|
|
|
1023
|
-
const WORKFLOW_API_VERSION = ENGINE_API_VERSION,
|
|
1145
|
+
const WORKFLOW_API_VERSION = ENGINE_API_VERSION, EMPTY_ENTRIES = [], WorkflowContext = createContext(null);
|
|
1024
1146
|
|
|
1025
1147
|
function useWorkflowContext() {
|
|
1026
1148
|
const value = useContext(WorkflowContext);
|
|
@@ -1062,7 +1184,7 @@ function useWorkflowInstanceEntry(instanceId, options = {}) {
|
|
|
1062
1184
|
|
|
1063
1185
|
const WorkflowToolOpened = defineEvent({
|
|
1064
1186
|
name: "Editorial Workflows Studio Plugin Tool Opened",
|
|
1065
|
-
version:
|
|
1187
|
+
version: 2,
|
|
1066
1188
|
description: "The Workflows tool was opened or its tab was switched"
|
|
1067
1189
|
}), WorkflowDocumentViewOpened = defineEvent({
|
|
1068
1190
|
name: "Editorial Workflows Studio Plugin Document View Opened",
|
|
@@ -1072,10 +1194,27 @@ const WorkflowToolOpened = defineEvent({
|
|
|
1072
1194
|
name: "Editorial Workflows Studio Plugin Instance Detail Viewed",
|
|
1073
1195
|
version: 1,
|
|
1074
1196
|
description: "The Workflows tool's per-instance detail view was opened"
|
|
1197
|
+
});
|
|
1198
|
+
|
|
1199
|
+
function definitionFingerprint(definition) {
|
|
1200
|
+
const hash = definition?.contentHash;
|
|
1201
|
+
return hash === void 0 ? {} : {
|
|
1202
|
+
definitionContentHash: hash
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
const WorkflowDefinitionDetailViewed = defineEvent({
|
|
1207
|
+
name: "Editorial Workflows Studio Plugin Definition Detail Viewed",
|
|
1208
|
+
version: 1,
|
|
1209
|
+
description: "A workflow's definition page was opened in the Workflows tool"
|
|
1075
1210
|
}), WorkflowFormStripClicked = defineEvent({
|
|
1076
1211
|
name: "Editorial Workflows Studio Plugin Form Strip Clicked",
|
|
1077
1212
|
version: 1,
|
|
1078
1213
|
description: "The form strip's instance line was clicked, opening the document view"
|
|
1214
|
+
}), WorkflowDocumentLinkClicked = defineEvent({
|
|
1215
|
+
name: "Editorial Workflows Studio Plugin Document Link Clicked",
|
|
1216
|
+
version: 2,
|
|
1217
|
+
description: "A document link was clicked, opening the referenced document's editor"
|
|
1079
1218
|
}), WorkflowStartDialogOpened = defineEvent({
|
|
1080
1219
|
name: "Editorial Workflows Studio Plugin Start Dialog Opened",
|
|
1081
1220
|
version: 1,
|
|
@@ -1090,8 +1229,12 @@ const WorkflowToolOpened = defineEvent({
|
|
|
1090
1229
|
description: "A fresh document's auto-start ran — one start request per configured workflow"
|
|
1091
1230
|
}), WorkflowActionControlUsed = defineEvent({
|
|
1092
1231
|
name: "Editorial Workflows Studio Plugin Action Control Used",
|
|
1093
|
-
version:
|
|
1232
|
+
version: 2,
|
|
1094
1233
|
description: "An action-firing control was used, attributed to its UI surface"
|
|
1234
|
+
}), WorkflowFieldControlUsed = defineEvent({
|
|
1235
|
+
name: "Editorial Workflows Studio Plugin Field Control Used",
|
|
1236
|
+
version: 1,
|
|
1237
|
+
description: "A field-editing control committed an edit, attributed to its UI surface"
|
|
1095
1238
|
}), WorkflowActivityDialogOpened = defineEvent({
|
|
1096
1239
|
name: "Editorial Workflows Studio Plugin Activity Dialog Opened",
|
|
1097
1240
|
version: 1,
|
|
@@ -1100,10 +1243,30 @@ const WorkflowToolOpened = defineEvent({
|
|
|
1100
1243
|
name: "Editorial Workflows Studio Plugin Task Filters Applied",
|
|
1101
1244
|
version: 1,
|
|
1102
1245
|
description: "The tool's task-filter menu closed with a changed selection"
|
|
1246
|
+
}), WorkflowBoardWorkflowSelected = defineEvent({
|
|
1247
|
+
name: "Editorial Workflows Studio Plugin Board Workflow Selected",
|
|
1248
|
+
version: 2,
|
|
1249
|
+
description: "The workflow documents page settled on the workflow it's showing"
|
|
1250
|
+
}), WorkflowTitleSeedDrifted = defineEvent({
|
|
1251
|
+
name: "Editorial Workflows Studio Plugin Title Seed Drifted",
|
|
1252
|
+
version: 1,
|
|
1253
|
+
description: "A cold-start seeded preview title diverged from the live preview pipeline"
|
|
1103
1254
|
}), WorkflowTodoToggled = defineEvent({
|
|
1104
1255
|
name: "Editorial Workflows Studio Plugin Todo Toggled",
|
|
1105
1256
|
version: 1,
|
|
1106
1257
|
description: "A todo checkbox was toggled, attributed to its UI surface and write seam"
|
|
1258
|
+
}), WorkflowTodoEdited = defineEvent({
|
|
1259
|
+
name: "Editorial Workflows Studio Plugin Todo Edited",
|
|
1260
|
+
version: 1,
|
|
1261
|
+
description: "A non-toggle todo-list write, attributed to its UI surface and gesture"
|
|
1262
|
+
}), WorkflowAbortDialogOpened = defineEvent({
|
|
1263
|
+
name: "Editorial Workflows Studio Plugin Abort Dialog Opened",
|
|
1264
|
+
version: 1,
|
|
1265
|
+
description: "The abort-workflow confirm was opened"
|
|
1266
|
+
}), WorkflowAbortDialogSubmitted = defineEvent({
|
|
1267
|
+
name: "Editorial Workflows Studio Plugin Abort Dialog Submitted",
|
|
1268
|
+
version: 1,
|
|
1269
|
+
description: "The abort-workflow confirm was submitted, carrying the attempt's outcome"
|
|
1107
1270
|
});
|
|
1108
1271
|
|
|
1109
1272
|
function useLogEventOnMount(event, data) {
|
|
@@ -1193,20 +1356,32 @@ function useUserDisplay(id) {
|
|
|
1193
1356
|
};
|
|
1194
1357
|
}
|
|
1195
1358
|
|
|
1196
|
-
const
|
|
1359
|
+
const warnedSelfUnavailable = /* @__PURE__ */ new Set;
|
|
1360
|
+
|
|
1361
|
+
function warnSelfUnavailableOnce(key, message) {
|
|
1362
|
+
warnedSelfUnavailable.has(key) || (warnedSelfUnavailable.add(key), console.warn(message));
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
function bridgedSelfId(users, meId) {
|
|
1366
|
+
const classified = classifyPrincipalId(meId);
|
|
1367
|
+
return users.find(user => user.membership.id === meId)?.profile?.sanityUserId ?? classified.globalId ?? (classified.namespace === "project" ? void 0 : meId);
|
|
1368
|
+
}
|
|
1197
1369
|
|
|
1198
1370
|
function useBridgedSelf() {
|
|
1199
|
-
const me = useCurrentUser(), {users: users, loading: loading} = useStudioProjectUsers();
|
|
1200
|
-
if (!me
|
|
1201
|
-
const
|
|
1202
|
-
if (id
|
|
1203
|
-
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.`));
|
|
1204
|
-
return;
|
|
1205
|
-
}
|
|
1206
|
-
return {
|
|
1371
|
+
const me = useCurrentUser(), {users: users, loading: loading, error: error} = useStudioProjectUsers();
|
|
1372
|
+
if (!me) return;
|
|
1373
|
+
const id = bridgedSelfId(users, me.id);
|
|
1374
|
+
if (id !== void 0) return {
|
|
1207
1375
|
id: id,
|
|
1208
1376
|
roles: me.roles ?? []
|
|
1209
1377
|
};
|
|
1378
|
+
if (!loading) {
|
|
1379
|
+
if (error !== void 0) {
|
|
1380
|
+
warnSelfUnavailableOnce(`load:${me.id}`, `workflow: the project member directory failed to load ("${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.`);
|
|
1381
|
+
return;
|
|
1382
|
+
}
|
|
1383
|
+
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.`);
|
|
1384
|
+
}
|
|
1210
1385
|
}
|
|
1211
1386
|
|
|
1212
1387
|
function useSelfActor() {
|
|
@@ -1326,9 +1501,50 @@ function buildParams(decls, values) {
|
|
|
1326
1501
|
};
|
|
1327
1502
|
}
|
|
1328
1503
|
|
|
1329
|
-
|
|
1504
|
+
function useDelayedFlag(active, delayMs) {
|
|
1505
|
+
const [held, setHeld] = useState(!1);
|
|
1506
|
+
return useEffect(() => {
|
|
1507
|
+
if (!active) {
|
|
1508
|
+
setHeld(!1);
|
|
1509
|
+
return;
|
|
1510
|
+
}
|
|
1511
|
+
const timer = setTimeout(() => setHeld(!0), delayMs);
|
|
1512
|
+
return () => clearTimeout(timer);
|
|
1513
|
+
}, [ active, delayMs ]), held && active;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
const NEVER_MS = 2 ** 31 - 1, OPEN_DELAY_MS = 300;
|
|
1330
1517
|
|
|
1331
1518
|
function HoverHint(props) {
|
|
1519
|
+
return props.anchor !== void 0 ? /* @__PURE__ */ jsx(AnchoredHint, {
|
|
1520
|
+
...props
|
|
1521
|
+
}) : /* @__PURE__ */ jsx(WrappingHint, {
|
|
1522
|
+
...props
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
function AnchoredHint(props) {
|
|
1527
|
+
const {disabled: disabled = !1} = props, open = useDelayedFlag(props.open === !0 && !disabled, OPEN_DELAY_MS);
|
|
1528
|
+
/* @__PURE__ */
|
|
1529
|
+
return jsx(Popover, {
|
|
1530
|
+
animate: !0,
|
|
1531
|
+
content: /* @__PURE__ */ jsx(HintBody, {
|
|
1532
|
+
...props
|
|
1533
|
+
}),
|
|
1534
|
+
open: open,
|
|
1535
|
+
padding: hintPadding(props),
|
|
1536
|
+
placement: props.placement ?? "top",
|
|
1537
|
+
portal: !0,
|
|
1538
|
+
radius: 3,
|
|
1539
|
+
referenceElement: props.anchor
|
|
1540
|
+
});
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
function hintPadding(props) {
|
|
1544
|
+
return props.content !== void 0 && props.flush ? 0 : 2;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
function WrappingHint(props) {
|
|
1332
1548
|
const {children: children, disabled: disabled = !1} = props;
|
|
1333
1549
|
/* @__PURE__ */
|
|
1334
1550
|
return jsx(Tooltip, {
|
|
@@ -1338,17 +1554,20 @@ function HoverHint(props) {
|
|
|
1338
1554
|
}),
|
|
1339
1555
|
delay: {
|
|
1340
1556
|
close: 0,
|
|
1341
|
-
open: disabled ? NEVER_MS :
|
|
1557
|
+
open: disabled ? NEVER_MS : OPEN_DELAY_MS
|
|
1342
1558
|
},
|
|
1343
|
-
padding: props
|
|
1344
|
-
placement: "top",
|
|
1559
|
+
padding: hintPadding(props),
|
|
1560
|
+
placement: props.placement ?? "top",
|
|
1345
1561
|
portal: !0,
|
|
1346
1562
|
radius: 3,
|
|
1347
1563
|
children: /* @__PURE__ */ jsx(Box, {
|
|
1348
1564
|
"data-testid": props["data-testid"],
|
|
1349
1565
|
style: {
|
|
1350
|
-
display: "inline-flex",
|
|
1351
|
-
maxWidth: "100%"
|
|
1566
|
+
display: props.fill ? "flex" : "inline-flex",
|
|
1567
|
+
maxWidth: "100%",
|
|
1568
|
+
...props.fill ? {
|
|
1569
|
+
width: "100%"
|
|
1570
|
+
} : {}
|
|
1352
1571
|
},
|
|
1353
1572
|
children: children
|
|
1354
1573
|
})
|
|
@@ -1436,7 +1655,7 @@ function DismissablePopover({children: children, content: content, onDismiss: on
|
|
|
1436
1655
|
function DateFieldInput({kind: kind, value: value, onChange: onChange, readOnly: readOnly = !1}) {
|
|
1437
1656
|
const [open, setOpen] = useState(!1), parsed2 = parseDateFieldValue(value, kind), close = () => setOpen(!1), toggle = () => {
|
|
1438
1657
|
readOnly || setOpen(v => !v);
|
|
1439
|
-
};
|
|
1658
|
+
}, pickHint = hasTimeOfDay(kind) ? "Pick a date and time…" : "Pick a date…";
|
|
1440
1659
|
/* @__PURE__ */
|
|
1441
1660
|
return jsx(DismissablePopover, {
|
|
1442
1661
|
content: /* @__PURE__ */ jsx(ClearableDatePicker, {
|
|
@@ -1447,7 +1666,7 @@ function DateFieldInput({kind: kind, value: value, onChange: onChange, readOnly:
|
|
|
1447
1666
|
onPick: next => {
|
|
1448
1667
|
close(), onChange(serializeDateFieldValue(next, kind));
|
|
1449
1668
|
},
|
|
1450
|
-
selectTime: kind
|
|
1669
|
+
selectTime: hasTimeOfDay(kind),
|
|
1451
1670
|
value: parsed2
|
|
1452
1671
|
}),
|
|
1453
1672
|
onDismiss: close,
|
|
@@ -1460,7 +1679,7 @@ function DateFieldInput({kind: kind, value: value, onChange: onChange, readOnly:
|
|
|
1460
1679
|
children: /* @__PURE__ */ jsx(TextInput, {
|
|
1461
1680
|
fontSize: 1,
|
|
1462
1681
|
onClick: toggle,
|
|
1463
|
-
placeholder: readOnly ? "" :
|
|
1682
|
+
placeholder: readOnly ? "" : pickHint,
|
|
1464
1683
|
readOnly: !0,
|
|
1465
1684
|
value: parsed2 ? formatDate(String(value)) : ""
|
|
1466
1685
|
})
|
|
@@ -1504,7 +1723,7 @@ function ChoiceSelect({options: options, value: value, onChange: onChange, readO
|
|
|
1504
1723
|
});
|
|
1505
1724
|
}
|
|
1506
1725
|
|
|
1507
|
-
const SCALAR_INPUT_KINDS = [ "string", "text", "url", "number", "progress",
|
|
1726
|
+
const SCALAR_INPUT_KINDS = [ "string", "text", "url", "number", "progress", ...DATE_FIELD_KINDS, "dateTime", "boolean" ], SCALAR_INPUT_KIND_SET = new Set(SCALAR_INPUT_KINDS);
|
|
1508
1727
|
|
|
1509
1728
|
function isScalarInputKind(kind) {
|
|
1510
1729
|
return SCALAR_INPUT_KIND_SET.has(kind);
|
|
@@ -1522,8 +1741,8 @@ function ScalarInput({kind: kind, value: value, onChange: onChange, options: opt
|
|
|
1522
1741
|
}) : kind === "boolean" ? /* @__PURE__ */ jsx(Checkbox, {
|
|
1523
1742
|
checked: value === !0,
|
|
1524
1743
|
onChange: e => onChange(e.currentTarget.checked)
|
|
1525
|
-
}) : kind
|
|
1526
|
-
kind: kind === "
|
|
1744
|
+
}) : isDateFieldKind(kind) || kind === "dateTime" ? /* @__PURE__ */ jsx(DateFieldInput, {
|
|
1745
|
+
kind: kind === "dateTime" ? "datetime" : kind,
|
|
1527
1746
|
onChange: next => onChange(next ?? ""),
|
|
1528
1747
|
value: value
|
|
1529
1748
|
}) : /* @__PURE__ */ jsx(TextInput, {
|
|
@@ -1629,11 +1848,16 @@ function useStubValuePreview(id, schemaType) {
|
|
|
1629
1848
|
};
|
|
1630
1849
|
}
|
|
1631
1850
|
|
|
1851
|
+
function PreviewPlaceholder() {
|
|
1852
|
+
/* @__PURE__ */
|
|
1853
|
+
return jsx(SanityDefaultPreview, {
|
|
1854
|
+
isPlaceholder: !0
|
|
1855
|
+
});
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1632
1858
|
function StubPreview({id: id, schemaType: schemaType}) {
|
|
1633
1859
|
const {value: value, preview: preview} = useStubValuePreview(id, schemaType);
|
|
1634
|
-
return preview.isLoading ? /* @__PURE__ */ jsx(
|
|
1635
|
-
isPlaceholder: !0
|
|
1636
|
-
}) : /* @__PURE__ */ jsx(Preview, {
|
|
1860
|
+
return preview.isLoading ? /* @__PURE__ */ jsx(PreviewPlaceholder, {}) : /* @__PURE__ */ jsx(Preview, {
|
|
1637
1861
|
layout: "default",
|
|
1638
1862
|
schemaType: schemaType,
|
|
1639
1863
|
skipVisibilityCheck: !0,
|
|
@@ -1866,14 +2090,87 @@ function ParamsForm({decls: decls, values: values, onChange: onChange}) {
|
|
|
1866
2090
|
});
|
|
1867
2091
|
}
|
|
1868
2092
|
|
|
1869
|
-
|
|
2093
|
+
const TOAST_ID = {
|
|
2094
|
+
abort: "workflow-abort",
|
|
2095
|
+
detailsCopy: "workflow-details-copy",
|
|
2096
|
+
documentCreate: "workflow-document-create",
|
|
2097
|
+
documentSave: "workflow-document-save",
|
|
2098
|
+
effectResolve: "workflow-effect-resolve",
|
|
2099
|
+
effectsDrain: "workflow-effects-drain",
|
|
2100
|
+
effectsIncomplete: "workflow-effects-incomplete",
|
|
2101
|
+
orphanSettle: "workflow-orphan-settle",
|
|
2102
|
+
start: "workflow-start"
|
|
2103
|
+
};
|
|
2104
|
+
|
|
2105
|
+
function instanceToastId(gesture, instanceId) {
|
|
2106
|
+
return `workflow-${gesture}:${instanceId}`;
|
|
2107
|
+
}
|
|
2108
|
+
|
|
2109
|
+
function actionFireToastId(args) {
|
|
2110
|
+
return `workflow-action-fire:${args.instanceId}:${args.activity}:${args.action}`;
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
const REASON_TOAST_DURATION = 2e4, DISMISS_SENTINEL_DURATION = .01;
|
|
2114
|
+
|
|
2115
|
+
function carriesReason(params) {
|
|
2116
|
+
return params.description !== void 0 && params.status !== "info";
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
function withConvention(params) {
|
|
2120
|
+
return {
|
|
2121
|
+
...params,
|
|
2122
|
+
closable: !0,
|
|
2123
|
+
...carriesReason(params) ? {
|
|
2124
|
+
duration: REASON_TOAST_DURATION
|
|
2125
|
+
} : {}
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
function useWorkflowToast() {
|
|
1870
2130
|
const toast = useToast();
|
|
1871
2131
|
return useMemo(() => ({
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
2132
|
+
push: params => {
|
|
2133
|
+
toast.push(withConvention(params));
|
|
2134
|
+
},
|
|
2135
|
+
dismiss: id => {
|
|
2136
|
+
toast.push({
|
|
2137
|
+
id: id,
|
|
2138
|
+
duration: DISMISS_SENTINEL_DURATION
|
|
2139
|
+
});
|
|
2140
|
+
}
|
|
2141
|
+
}), [ toast ]);
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
const COMMITTED_INCOMPLETE_TITLE = "Saved, but its follow-up didn’t run";
|
|
2145
|
+
|
|
2146
|
+
function rejectionToast(reading, titles) {
|
|
2147
|
+
return reading.kind === "committed-incomplete" ? {
|
|
2148
|
+
id: TOAST_ID.effectsIncomplete,
|
|
2149
|
+
status: "warning",
|
|
2150
|
+
title: COMMITTED_INCOMPLETE_TITLE,
|
|
2151
|
+
description: reading.message
|
|
2152
|
+
} : reading.kind === "refusal" ? {
|
|
2153
|
+
id: titles.id,
|
|
2154
|
+
status: "warning",
|
|
2155
|
+
title: titles.refused,
|
|
2156
|
+
description: reading.message
|
|
2157
|
+
} : {
|
|
2158
|
+
id: titles.id,
|
|
2159
|
+
status: "error",
|
|
2160
|
+
title: titles.failed,
|
|
2161
|
+
description: reading.message
|
|
2162
|
+
};
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
function useRejectionReport() {
|
|
2166
|
+
const toast = useWorkflowToast();
|
|
2167
|
+
return useMemo(() => ({
|
|
2168
|
+
rejected: args => {
|
|
2169
|
+
const reading = readRejection(args.err);
|
|
2170
|
+
reading.kind !== "refusal" && console.error(`[workflow-studio-plugin] ${args.context} rejected:`, args.err),
|
|
2171
|
+
toast.push(rejectionToast(reading, args));
|
|
2172
|
+
},
|
|
2173
|
+
dismiss: toast.dismiss
|
|
1877
2174
|
}), [ toast ]);
|
|
1878
2175
|
}
|
|
1879
2176
|
|
|
@@ -1896,10 +2193,21 @@ function useActionClusterPending() {
|
|
|
1896
2193
|
}
|
|
1897
2194
|
|
|
1898
2195
|
function useFireAction(args) {
|
|
1899
|
-
const {instanceId: instanceId, activity: activity, action: action, label: label, surface: surface, viaMenu: viaMenu} = args, {fireActionFor: fireActionFor} = useWorkflowContext(), telemetry = useWorkflowTelemetry(),
|
|
2196
|
+
const {instanceId: instanceId, activity: activity, action: action, label: label, surface: surface, placement: placement, viaMenu: viaMenu} = args, {fireActionFor: fireActionFor} = useWorkflowContext(), telemetry = useWorkflowTelemetry(), report = useRejectionReport(), cluster = useActionClusterLock(), [localPending, setLocalPending] = useState(!1), pending = localPending || cluster?.pending === !0, toastId = actionFireToastId({
|
|
2197
|
+
instanceId: instanceId,
|
|
2198
|
+
activity: activity,
|
|
2199
|
+
action: action
|
|
2200
|
+
});
|
|
1900
2201
|
return {
|
|
1901
2202
|
fire: useCallback(async params => {
|
|
1902
2203
|
if (pending) return !1;
|
|
2204
|
+
const log = success => telemetry.log(WorkflowActionControlUsed, {
|
|
2205
|
+
instanceId: instanceId,
|
|
2206
|
+
surface: surface,
|
|
2207
|
+
placement: placement,
|
|
2208
|
+
viaMenu: viaMenu,
|
|
2209
|
+
success: success
|
|
2210
|
+
});
|
|
1903
2211
|
setLocalPending(!0), cluster?.onFireChange(!0);
|
|
1904
2212
|
try {
|
|
1905
2213
|
return await fireActionFor(instanceId, {
|
|
@@ -1908,31 +2216,19 @@ function useFireAction(args) {
|
|
|
1908
2216
|
...params && Object.keys(params).length > 0 ? {
|
|
1909
2217
|
params: params
|
|
1910
2218
|
} : {}
|
|
1911
|
-
}),
|
|
1912
|
-
status: "success",
|
|
1913
|
-
title: `${label} done`
|
|
1914
|
-
}), telemetry.log(WorkflowActionControlUsed, {
|
|
1915
|
-
instanceId: instanceId,
|
|
1916
|
-
surface: surface,
|
|
1917
|
-
viaMenu: viaMenu,
|
|
1918
|
-
success: !0
|
|
1919
|
-
}), !0;
|
|
2219
|
+
}), report.dismiss(toastId), log(!0), !0;
|
|
1920
2220
|
} catch (err) {
|
|
1921
|
-
return
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
surface: surface,
|
|
1929
|
-
viaMenu: viaMenu,
|
|
1930
|
-
success: !1
|
|
1931
|
-
}), !1;
|
|
2221
|
+
return report.rejected({
|
|
2222
|
+
err: err,
|
|
2223
|
+
context: `firing "${action}" on "${activity}"`,
|
|
2224
|
+
id: toastId,
|
|
2225
|
+
refused: `“${label}” isn’t available right now`,
|
|
2226
|
+
failed: `Failed to complete “${label}”`
|
|
2227
|
+
}), log(!1), !1;
|
|
1932
2228
|
} finally {
|
|
1933
2229
|
setLocalPending(!1), cluster?.onFireChange(!1);
|
|
1934
2230
|
}
|
|
1935
|
-
}, [ fireActionFor, instanceId, activity, action, label, pending,
|
|
2231
|
+
}, [ fireActionFor, instanceId, activity, action, label, pending, report, toastId, cluster, telemetry, surface, placement, viaMenu ]),
|
|
1936
2232
|
pending: pending
|
|
1937
2233
|
};
|
|
1938
2234
|
}
|
|
@@ -1973,13 +2269,14 @@ function RowClickShield({active: active, children: children}) {
|
|
|
1973
2269
|
});
|
|
1974
2270
|
}
|
|
1975
2271
|
|
|
1976
|
-
function FireButton({instanceId: instanceId, activity: activity, action: action, label: label, surface: surface, mode: mode = "default", chrome: chrome, tone: tone = "default", icon: icon}) {
|
|
2272
|
+
function FireButton({instanceId: instanceId, activity: activity, action: action, label: label, surface: surface, placement: placement, mode: mode = "default", chrome: chrome, tone: tone = "default", icon: icon}) {
|
|
1977
2273
|
const {fire: fire, pending: pending} = useFireAction({
|
|
1978
2274
|
instanceId: instanceId,
|
|
1979
2275
|
activity: activity,
|
|
1980
2276
|
action: action,
|
|
1981
2277
|
label: label,
|
|
1982
2278
|
surface: surface,
|
|
2279
|
+
placement: placement,
|
|
1983
2280
|
viaMenu: !1
|
|
1984
2281
|
}), handleClick = e => {
|
|
1985
2282
|
chrome?.inButtonCard === !0 && e.stopPropagation(), !pending && fire();
|
|
@@ -2001,7 +2298,7 @@ function FireButton({instanceId: instanceId, activity: activity, action: action,
|
|
|
2001
2298
|
});
|
|
2002
2299
|
}
|
|
2003
2300
|
|
|
2004
|
-
function ActivityActionRow({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, chrome: chrome}) {
|
|
2301
|
+
function ActivityActionRow({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, placement: placement, chrome: chrome}) {
|
|
2005
2302
|
const rowKind = actionRowKind(actionEval);
|
|
2006
2303
|
return rowKind.kind === "disabled" ? /* @__PURE__ */ jsx(DisabledActionButton, {
|
|
2007
2304
|
actionEval: actionEval,
|
|
@@ -2012,12 +2309,14 @@ function ActivityActionRow({actionEval: actionEval, instanceId: instanceId, acti
|
|
|
2012
2309
|
instanceId: instanceId,
|
|
2013
2310
|
activity: activity,
|
|
2014
2311
|
chrome: chrome,
|
|
2312
|
+
placement: placement,
|
|
2015
2313
|
surface: surface
|
|
2016
2314
|
}) : /* @__PURE__ */ jsx(ParamsActionButton, {
|
|
2017
2315
|
actionEval: actionEval,
|
|
2018
2316
|
instanceId: instanceId,
|
|
2019
2317
|
activity: activity,
|
|
2020
2318
|
chrome: chrome,
|
|
2319
|
+
placement: placement,
|
|
2021
2320
|
surface: surface
|
|
2022
2321
|
});
|
|
2023
2322
|
}
|
|
@@ -2043,7 +2342,7 @@ function DisabledActionButton({actionEval: actionEval, activity: activity, chrom
|
|
|
2043
2342
|
}) : button;
|
|
2044
2343
|
}
|
|
2045
2344
|
|
|
2046
|
-
function PlainActionButton({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, chrome: chrome}) {
|
|
2345
|
+
function PlainActionButton({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, placement: placement, chrome: chrome}) {
|
|
2047
2346
|
const {action: action} = actionEval, label = actionLabel(action), btn = actionButtonFace({
|
|
2048
2347
|
actionEval: actionEval,
|
|
2049
2348
|
activityName: activity
|
|
@@ -2055,6 +2354,7 @@ function PlainActionButton({actionEval: actionEval, instanceId: instanceId, acti
|
|
|
2055
2354
|
mode: btn.mode,
|
|
2056
2355
|
activity: activity,
|
|
2057
2356
|
chrome: chrome,
|
|
2357
|
+
placement: placement,
|
|
2058
2358
|
surface: surface,
|
|
2059
2359
|
tone: btn.tone
|
|
2060
2360
|
});
|
|
@@ -2064,13 +2364,14 @@ function PlainActionButton({actionEval: actionEval, instanceId: instanceId, acti
|
|
|
2064
2364
|
}) : button;
|
|
2065
2365
|
}
|
|
2066
2366
|
|
|
2067
|
-
function ParamsActionDialog({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, viaMenu: viaMenu, onClose: onClose}) {
|
|
2367
|
+
function ParamsActionDialog({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, placement: placement, viaMenu: viaMenu, onClose: onClose}) {
|
|
2068
2368
|
const {action: action} = actionEval, label = actionLabel(action), decls = action.params ?? [], [values, setValues] = useState({}), {fire: fire, pending: pending} = useFireAction({
|
|
2069
2369
|
instanceId: instanceId,
|
|
2070
2370
|
activity: activity,
|
|
2071
2371
|
action: action.name,
|
|
2072
2372
|
label: label,
|
|
2073
2373
|
surface: surface,
|
|
2374
|
+
placement: placement,
|
|
2074
2375
|
viaMenu: viaMenu
|
|
2075
2376
|
}), built = buildParams(decls, values), confirm = async () => {
|
|
2076
2377
|
await fire(built.params) && onClose();
|
|
@@ -2126,7 +2427,7 @@ function ParamsActionDialog({actionEval: actionEval, instanceId: instanceId, act
|
|
|
2126
2427
|
});
|
|
2127
2428
|
}
|
|
2128
2429
|
|
|
2129
|
-
function ParamsActionButton({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, chrome: chrome}) {
|
|
2430
|
+
function ParamsActionButton({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, placement: placement, chrome: chrome}) {
|
|
2130
2431
|
const [open, setOpen] = useState(!1), btn = actionButtonFace({
|
|
2131
2432
|
actionEval: actionEval,
|
|
2132
2433
|
activityName: activity
|
|
@@ -2152,6 +2453,7 @@ function ParamsActionButton({actionEval: actionEval, instanceId: instanceId, act
|
|
|
2152
2453
|
activity: activity,
|
|
2153
2454
|
instanceId: instanceId,
|
|
2154
2455
|
onClose: () => setOpen(!1),
|
|
2456
|
+
placement: placement,
|
|
2155
2457
|
surface: surface,
|
|
2156
2458
|
viaMenu: !1
|
|
2157
2459
|
})
|
|
@@ -2325,7 +2627,9 @@ function FieldInput$1({kind: kind, value: value, onChange: onChange, onEnter: on
|
|
|
2325
2627
|
});
|
|
2326
2628
|
|
|
2327
2629
|
case "date":
|
|
2630
|
+
case "dueDate":
|
|
2328
2631
|
case "datetime":
|
|
2632
|
+
case "dueDatetime":
|
|
2329
2633
|
/* @__PURE__ */
|
|
2330
2634
|
return jsx(DateFieldInput, {
|
|
2331
2635
|
kind: kind,
|
|
@@ -2371,22 +2675,64 @@ function FieldInput$1({kind: kind, value: value, onChange: onChange, onEnter: on
|
|
|
2371
2675
|
}
|
|
2372
2676
|
}
|
|
2373
2677
|
|
|
2374
|
-
function
|
|
2678
|
+
function isCompact(layout) {
|
|
2679
|
+
return layout === "inline" || layout === "row";
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
function docFaceChrome(args) {
|
|
2683
|
+
const {layout: layout, state: state} = args, compact = isCompact(layout);
|
|
2684
|
+
switch (state.kind) {
|
|
2685
|
+
case "linked":
|
|
2686
|
+
return {
|
|
2687
|
+
bareId: state.bareId,
|
|
2688
|
+
selfInset: !compact
|
|
2689
|
+
};
|
|
2690
|
+
|
|
2691
|
+
case "foreign":
|
|
2692
|
+
return {};
|
|
2693
|
+
|
|
2694
|
+
case "missing":
|
|
2695
|
+
return {
|
|
2696
|
+
tone: "caution"
|
|
2697
|
+
};
|
|
2698
|
+
|
|
2699
|
+
case "unopenable":
|
|
2700
|
+
return {};
|
|
2701
|
+
|
|
2702
|
+
case "pending":
|
|
2703
|
+
return compact ? {} : {
|
|
2704
|
+
selfInset: !0
|
|
2705
|
+
};
|
|
2706
|
+
|
|
2707
|
+
case "unresolvable":
|
|
2708
|
+
return {};
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2712
|
+
function chipPadding(fill) {
|
|
2713
|
+
return fill ? 3 : 2;
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
function LinkChip({hint: hint, children: children, as: as = "a", fill: fill = !1, ...anchorProps}) {
|
|
2375
2717
|
/* @__PURE__ */
|
|
2376
2718
|
return jsx(HoverHint, {
|
|
2719
|
+
fill: fill,
|
|
2377
2720
|
text: hint,
|
|
2378
2721
|
children: /* @__PURE__ */ jsx(Card, {
|
|
2379
2722
|
__unstable_focusRing: !0,
|
|
2380
2723
|
as: as,
|
|
2381
2724
|
"data-as": "a",
|
|
2382
|
-
padding:
|
|
2725
|
+
padding: chipPadding(fill),
|
|
2383
2726
|
radius: 3,
|
|
2384
2727
|
style: {
|
|
2385
2728
|
alignItems: "center",
|
|
2386
2729
|
color: "inherit",
|
|
2387
2730
|
display: "flex",
|
|
2388
2731
|
minWidth: 0,
|
|
2389
|
-
textDecoration: "none"
|
|
2732
|
+
textDecoration: "none",
|
|
2733
|
+
...fill ? {
|
|
2734
|
+
width: "100%"
|
|
2735
|
+
} : {}
|
|
2390
2736
|
},
|
|
2391
2737
|
tone: "inherit",
|
|
2392
2738
|
...anchorProps,
|
|
@@ -2505,7 +2851,7 @@ function DocRefFace({gdr: gdr}) {
|
|
|
2505
2851
|
});
|
|
2506
2852
|
}
|
|
2507
2853
|
|
|
2508
|
-
function
|
|
2854
|
+
function foreignNotice(bareId, resource) {
|
|
2509
2855
|
const location = resource.type === "dataset" ? `another dataset (${resource.id})` : `${resource.type} (${resource.id})`;
|
|
2510
2856
|
/* @__PURE__ */
|
|
2511
2857
|
return jsxs(Text, {
|
|
@@ -2515,44 +2861,22 @@ function ForeignRefNotice({bareId: bareId, resource: resource}) {
|
|
|
2515
2861
|
});
|
|
2516
2862
|
}
|
|
2517
2863
|
|
|
2518
|
-
function
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
children: "Document unavailable"
|
|
2535
|
-
}) ]
|
|
2536
|
-
})
|
|
2537
|
-
}) : /* @__PURE__ */ jsx(Card, {
|
|
2538
|
-
border: !0,
|
|
2539
|
-
padding: 2,
|
|
2540
|
-
radius: 3,
|
|
2541
|
-
tone: "caution",
|
|
2542
|
-
children: /* @__PURE__ */ jsxs(Flex, {
|
|
2543
|
-
align: "center",
|
|
2544
|
-
gap: 2,
|
|
2545
|
-
children: [
|
|
2546
|
-
/* @__PURE__ */ jsx(Text, {
|
|
2547
|
-
size: 1,
|
|
2548
|
-
children: /* @__PURE__ */ jsx(WarningOutlineIcon, {})
|
|
2549
|
-
}),
|
|
2550
|
-
/* @__PURE__ */ jsxs(Text, {
|
|
2551
|
-
muted: !0,
|
|
2552
|
-
size: 1,
|
|
2553
|
-
children: [ "Document unavailable — ", bareId ]
|
|
2554
|
-
}) ]
|
|
2555
|
-
})
|
|
2864
|
+
function missingNotice(bareId, layout) {
|
|
2865
|
+
/* @__PURE__ */
|
|
2866
|
+
return jsxs(Flex, {
|
|
2867
|
+
align: "center",
|
|
2868
|
+
gap: 2,
|
|
2869
|
+
children: [
|
|
2870
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2871
|
+
muted: !0,
|
|
2872
|
+
size: 1,
|
|
2873
|
+
children: /* @__PURE__ */ jsx(WarningOutlineIcon, {})
|
|
2874
|
+
}),
|
|
2875
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2876
|
+
muted: !0,
|
|
2877
|
+
size: 1,
|
|
2878
|
+
children: isCompact(layout) ? "Document unavailable" : `Document unavailable — ${bareId}`
|
|
2879
|
+
}) ]
|
|
2556
2880
|
});
|
|
2557
2881
|
}
|
|
2558
2882
|
|
|
@@ -2569,6 +2893,18 @@ function renderTypeIcon(icon) {
|
|
|
2569
2893
|
return typeof icon == "function" ? createElement(icon) : isValidElement(icon) ? icon : /* @__PURE__ */ jsx(DocumentIcon, {});
|
|
2570
2894
|
}
|
|
2571
2895
|
|
|
2896
|
+
function TitleSkeleton() {
|
|
2897
|
+
/* @__PURE__ */
|
|
2898
|
+
return jsx(TextSkeleton, {
|
|
2899
|
+
animated: !0,
|
|
2900
|
+
radius: 1,
|
|
2901
|
+
size: 1,
|
|
2902
|
+
style: {
|
|
2903
|
+
width: 96
|
|
2904
|
+
}
|
|
2905
|
+
});
|
|
2906
|
+
}
|
|
2907
|
+
|
|
2572
2908
|
function InlineChipFace({bareId: bareId, schemaType: schemaType}) {
|
|
2573
2909
|
const {preview: preview} = useStubValuePreview(bareId, schemaType);
|
|
2574
2910
|
/* @__PURE__ */
|
|
@@ -2579,14 +2915,7 @@ function InlineChipFace({bareId: bareId, schemaType: schemaType}) {
|
|
|
2579
2915
|
/* @__PURE__ */ jsx(Text, {
|
|
2580
2916
|
size: 1,
|
|
2581
2917
|
children: renderTypeIcon(schemaType.icon)
|
|
2582
|
-
}), preview.isLoading ? /* @__PURE__ */ jsx(
|
|
2583
|
-
animated: !0,
|
|
2584
|
-
radius: 1,
|
|
2585
|
-
size: 1,
|
|
2586
|
-
style: {
|
|
2587
|
-
width: 96
|
|
2588
|
-
}
|
|
2589
|
-
}) : /* @__PURE__ */ jsx(Text, {
|
|
2918
|
+
}), preview.isLoading ? /* @__PURE__ */ jsx(TitleSkeleton, {}) : /* @__PURE__ */ jsx(Text, {
|
|
2590
2919
|
size: 1,
|
|
2591
2920
|
textOverflow: "ellipsis",
|
|
2592
2921
|
weight: "medium",
|
|
@@ -2597,8 +2926,59 @@ function InlineChipFace({bareId: bareId, schemaType: schemaType}) {
|
|
|
2597
2926
|
});
|
|
2598
2927
|
}
|
|
2599
2928
|
|
|
2600
|
-
|
|
2601
|
-
|
|
2929
|
+
const NOTICE_PADDING = 2;
|
|
2930
|
+
|
|
2931
|
+
function CompactDocRef({face: face, fill: fill, link: link, onClick: onClick}) {
|
|
2932
|
+
return link === void 0 ? /* @__PURE__ */ jsx(Box, {
|
|
2933
|
+
padding: chipPadding(fill),
|
|
2934
|
+
style: fill ? {
|
|
2935
|
+
width: "100%"
|
|
2936
|
+
} : {},
|
|
2937
|
+
children: face.content
|
|
2938
|
+
}) : /* @__PURE__ */ jsx(LinkChip, {
|
|
2939
|
+
as: link,
|
|
2940
|
+
fill: fill,
|
|
2941
|
+
hint: "Open document",
|
|
2942
|
+
onClick: onClick,
|
|
2943
|
+
children: face.content
|
|
2944
|
+
});
|
|
2945
|
+
}
|
|
2946
|
+
|
|
2947
|
+
const PENDING_FACE_MAX_WAIT_MS = 4e3;
|
|
2948
|
+
|
|
2949
|
+
function PendingDocFace({bareId: bareId, layout: layout}) {
|
|
2950
|
+
const expired = useDelayedFlag(!0, PENDING_FACE_MAX_WAIT_MS), compact = isCompact(layout);
|
|
2951
|
+
if (expired) {
|
|
2952
|
+
const id = /* @__PURE__ */ jsx(Text, {
|
|
2953
|
+
muted: !0,
|
|
2954
|
+
size: 1,
|
|
2955
|
+
children: bareId
|
|
2956
|
+
});
|
|
2957
|
+
return compact ? id : /* @__PURE__ */ jsx(Box, {
|
|
2958
|
+
padding: NOTICE_PADDING,
|
|
2959
|
+
children: id
|
|
2960
|
+
});
|
|
2961
|
+
}
|
|
2962
|
+
return compact ?
|
|
2963
|
+
/* @__PURE__ */ jsxs(Flex, {
|
|
2964
|
+
align: "center",
|
|
2965
|
+
gap: 2,
|
|
2966
|
+
children: [
|
|
2967
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2968
|
+
muted: !0,
|
|
2969
|
+
size: 1,
|
|
2970
|
+
children: /* @__PURE__ */ jsx(DocumentIcon, {})
|
|
2971
|
+
}),
|
|
2972
|
+
/* @__PURE__ */ jsx(TitleSkeleton, {}) ]
|
|
2973
|
+
}) : /* @__PURE__ */ jsx(PreviewPlaceholder, {});
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2976
|
+
function DocRefShell({face: face, layout: layout, source: source}) {
|
|
2977
|
+
const telemetry = useWorkflowTelemetry(), {bareId: bareId} = face, handleClick = e => {
|
|
2978
|
+
e.stopPropagation(), telemetry.log(WorkflowDocumentLinkClicked, {
|
|
2979
|
+
source: source
|
|
2980
|
+
});
|
|
2981
|
+
}, EditIntentLink = useMemo(() => bareId === void 0 ? void 0 : function(linkProps) {
|
|
2602
2982
|
/* @__PURE__ */
|
|
2603
2983
|
return jsx(IntentLink, {
|
|
2604
2984
|
...linkProps,
|
|
@@ -2608,58 +2988,52 @@ function LinkedDocPreview({bareId: bareId, layout: layout, schemaType: schemaTyp
|
|
|
2608
2988
|
}
|
|
2609
2989
|
});
|
|
2610
2990
|
}, [ bareId ]);
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2991
|
+
if (isCompact(layout)) /* @__PURE__ */
|
|
2992
|
+
return jsx(CompactDocRef, {
|
|
2993
|
+
face: face,
|
|
2994
|
+
fill: layout === "row",
|
|
2995
|
+
link: EditIntentLink,
|
|
2996
|
+
onClick: handleClick
|
|
2997
|
+
});
|
|
2998
|
+
const padding = face.selfInset === !0 ? 0 : NOTICE_PADDING;
|
|
2999
|
+
/* @__PURE__ */
|
|
3000
|
+
return jsx(Card, {
|
|
2620
3001
|
__unstable_focusRing: !0,
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
"data-as": "a",
|
|
2624
|
-
onClick: e => e.stopPropagation(),
|
|
2625
|
-
padding: 1,
|
|
3002
|
+
border: layout === "default",
|
|
3003
|
+
padding: padding,
|
|
2626
3004
|
radius: 3,
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
3005
|
+
tone: face.tone ?? (layout === "bare" ? "inherit" : "default"),
|
|
3006
|
+
...EditIntentLink === void 0 ? {} : {
|
|
3007
|
+
as: EditIntentLink,
|
|
3008
|
+
"data-as": "a",
|
|
3009
|
+
onClick: handleClick,
|
|
3010
|
+
style: {
|
|
3011
|
+
color: "inherit",
|
|
3012
|
+
textDecoration: "none",
|
|
3013
|
+
display: "block"
|
|
3014
|
+
}
|
|
2631
3015
|
},
|
|
2632
|
-
children:
|
|
2633
|
-
id: bareId,
|
|
2634
|
-
schemaType: schemaType
|
|
2635
|
-
})
|
|
3016
|
+
children: face.content
|
|
2636
3017
|
});
|
|
2637
3018
|
}
|
|
2638
3019
|
|
|
2639
|
-
function
|
|
2640
|
-
const state =
|
|
3020
|
+
function faceContent(args) {
|
|
3021
|
+
const {gdr: gdr, layout: layout, state: state} = args, compact = isCompact(layout);
|
|
2641
3022
|
switch (state.kind) {
|
|
2642
3023
|
case "linked":
|
|
2643
|
-
/* @__PURE__ */
|
|
2644
|
-
return jsx(LinkedDocPreview, {
|
|
3024
|
+
return compact ? /* @__PURE__ */ jsx(InlineChipFace, {
|
|
2645
3025
|
bareId: state.bareId,
|
|
2646
|
-
|
|
3026
|
+
schemaType: state.schemaType
|
|
3027
|
+
}) : /* @__PURE__ */ jsx(StubPreview, {
|
|
3028
|
+
id: state.bareId,
|
|
2647
3029
|
schemaType: state.schemaType
|
|
2648
3030
|
});
|
|
2649
3031
|
|
|
2650
3032
|
case "foreign":
|
|
2651
|
-
|
|
2652
|
-
return jsx(ForeignRefNotice, {
|
|
2653
|
-
bareId: state.bareId,
|
|
2654
|
-
resource: state.resource
|
|
2655
|
-
});
|
|
3033
|
+
return foreignNotice(state.bareId, state.resource);
|
|
2656
3034
|
|
|
2657
3035
|
case "missing":
|
|
2658
|
-
|
|
2659
|
-
return jsx(MissingDocNotice, {
|
|
2660
|
-
bareId: state.bareId,
|
|
2661
|
-
layout: layout
|
|
2662
|
-
});
|
|
3036
|
+
return missingNotice(state.bareId, layout);
|
|
2663
3037
|
|
|
2664
3038
|
case "unopenable":
|
|
2665
3039
|
/* @__PURE__ */
|
|
@@ -2670,10 +3044,9 @@ function DocPreviewLink({gdr: gdr, layout: layout = "default"}) {
|
|
|
2670
3044
|
|
|
2671
3045
|
case "pending":
|
|
2672
3046
|
/* @__PURE__ */
|
|
2673
|
-
return jsx(
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
children: state.bareId
|
|
3047
|
+
return jsx(PendingDocFace, {
|
|
3048
|
+
bareId: state.bareId,
|
|
3049
|
+
layout: layout
|
|
2677
3050
|
});
|
|
2678
3051
|
|
|
2679
3052
|
case "unresolvable":
|
|
@@ -2686,6 +3059,27 @@ function DocPreviewLink({gdr: gdr, layout: layout = "default"}) {
|
|
|
2686
3059
|
}
|
|
2687
3060
|
}
|
|
2688
3061
|
|
|
3062
|
+
function docFace(args) {
|
|
3063
|
+
return {
|
|
3064
|
+
...docFaceChrome(args),
|
|
3065
|
+
content: faceContent(args)
|
|
3066
|
+
};
|
|
3067
|
+
}
|
|
3068
|
+
|
|
3069
|
+
function DocPreviewLink({gdr: gdr, layout: layout = "default", source: source}) {
|
|
3070
|
+
const state = useDocLink(gdr);
|
|
3071
|
+
/* @__PURE__ */
|
|
3072
|
+
return jsx(DocRefShell, {
|
|
3073
|
+
face: docFace({
|
|
3074
|
+
gdr: gdr,
|
|
3075
|
+
layout: layout,
|
|
3076
|
+
state: state
|
|
3077
|
+
}),
|
|
3078
|
+
layout: layout,
|
|
3079
|
+
source: source
|
|
3080
|
+
});
|
|
3081
|
+
}
|
|
3082
|
+
|
|
2689
3083
|
function ReleaseLink({releaseName: releaseName, label: label}) {
|
|
2690
3084
|
const {basePath: basePath} = useWorkspace(), href = `${basePath === "/" ? "" : basePath}/releases/${releaseName}`;
|
|
2691
3085
|
/* @__PURE__ */
|
|
@@ -2744,7 +3138,8 @@ function renderTextValue(field) {
|
|
|
2744
3138
|
|
|
2745
3139
|
function renderSingleDocRef(field) {
|
|
2746
3140
|
return field.value ? /* @__PURE__ */ jsx(DocPreviewLink, {
|
|
2747
|
-
gdr: field.value
|
|
3141
|
+
gdr: field.value,
|
|
3142
|
+
source: "field-value"
|
|
2748
3143
|
}) : /* @__PURE__ */ jsx(Empty, {});
|
|
2749
3144
|
}
|
|
2750
3145
|
|
|
@@ -2766,12 +3161,15 @@ const fieldValueRenderer = {
|
|
|
2766
3161
|
children: formatBoolean(field.value)
|
|
2767
3162
|
}),
|
|
2768
3163
|
date: renderTextValue,
|
|
3164
|
+
dueDate: renderTextValue,
|
|
2769
3165
|
datetime: renderTextValue,
|
|
3166
|
+
dueDatetime: renderTextValue,
|
|
2770
3167
|
"doc.ref": renderSingleDocRef,
|
|
2771
3168
|
"doc.refs": field => field.value.length > 0 ? /* @__PURE__ */ jsx(Stack, {
|
|
2772
3169
|
gap: 2,
|
|
2773
3170
|
children: field.value.map(ref => /* @__PURE__ */ jsx(DocPreviewLink, {
|
|
2774
|
-
gdr: ref
|
|
3171
|
+
gdr: ref,
|
|
3172
|
+
source: "field-value"
|
|
2775
3173
|
}, ref.id))
|
|
2776
3174
|
}) : /* @__PURE__ */ jsx(Empty, {}),
|
|
2777
3175
|
number: renderTextValue,
|
|
@@ -2993,6 +3391,27 @@ function ReadOnlyField({entry: entry}) {
|
|
|
2993
3391
|
});
|
|
2994
3392
|
}
|
|
2995
3393
|
|
|
3394
|
+
function useEditField(surface) {
|
|
3395
|
+
const {editFieldFor: editFieldFor} = useWorkflowContext(), telemetry = useWorkflowTelemetry();
|
|
3396
|
+
return useCallback(async ({instanceId: instanceId, field: field, ...change}) => {
|
|
3397
|
+
const log = success => telemetry.log(WorkflowFieldControlUsed, {
|
|
3398
|
+
instanceId: instanceId,
|
|
3399
|
+
surface: surface,
|
|
3400
|
+
fieldKind: field.type,
|
|
3401
|
+
success: success
|
|
3402
|
+
});
|
|
3403
|
+
try {
|
|
3404
|
+
await editFieldFor(instanceId, {
|
|
3405
|
+
...change,
|
|
3406
|
+
target: editFieldTarget(field)
|
|
3407
|
+
});
|
|
3408
|
+
} catch (err) {
|
|
3409
|
+
throw log(!1), err;
|
|
3410
|
+
}
|
|
3411
|
+
log(!0);
|
|
3412
|
+
}, [ editFieldFor, surface, telemetry ]);
|
|
3413
|
+
}
|
|
3414
|
+
|
|
2996
3415
|
function sameValue(a, b) {
|
|
2997
3416
|
return (a ?? void 0) === (b ?? void 0);
|
|
2998
3417
|
}
|
|
@@ -3029,11 +3448,12 @@ function useFieldDraft(args) {
|
|
|
3029
3448
|
};
|
|
3030
3449
|
}
|
|
3031
3450
|
|
|
3032
|
-
function EditableFieldControl({instanceId: instanceId, field: field}) {
|
|
3033
|
-
const {
|
|
3451
|
+
function EditableFieldControl({instanceId: instanceId, field: field, surface: surface}) {
|
|
3452
|
+
const {previewFieldFor: previewFieldFor, discardFieldPreviewFor: discardFieldPreviewFor} = useWorkflowContext(), editField = useEditField(surface), selfActor = useSelfActor(), held = useHeldWorkflowEntry(instanceId), entry = held ? resolveFieldEntry(held.instance, field) : void 0, evaluation = held?.evaluation, target = editFieldTarget(field), consequence = fieldConsequence(evaluation, field.name), advanceTo = advanceTargetTitle(evaluation, field.name);
|
|
3034
3453
|
/* @__PURE__ */
|
|
3035
3454
|
return jsx(EditableField, {
|
|
3036
3455
|
field: field,
|
|
3456
|
+
instanceId: instanceId,
|
|
3037
3457
|
...entry === void 0 ? {} : {
|
|
3038
3458
|
entry: entry
|
|
3039
3459
|
},
|
|
@@ -3046,30 +3466,33 @@ function EditableFieldControl({instanceId: instanceId, field: field}) {
|
|
|
3046
3466
|
...advanceTo === void 0 ? {} : {
|
|
3047
3467
|
advanceTo: advanceTo
|
|
3048
3468
|
},
|
|
3049
|
-
onSave: value =>
|
|
3050
|
-
|
|
3469
|
+
onSave: value => editField({
|
|
3470
|
+
instanceId: instanceId,
|
|
3471
|
+
field: field,
|
|
3051
3472
|
mode: "set",
|
|
3052
3473
|
value: value
|
|
3053
|
-
})
|
|
3474
|
+
}),
|
|
3054
3475
|
onPreview: value => previewFieldFor(instanceId, {
|
|
3055
3476
|
target: target,
|
|
3056
3477
|
mode: "set",
|
|
3057
3478
|
value: value
|
|
3058
3479
|
}),
|
|
3059
3480
|
onDiscardPreview: () => discardFieldPreviewFor(instanceId, target),
|
|
3060
|
-
onUnset: () =>
|
|
3061
|
-
|
|
3481
|
+
onUnset: () => editField({
|
|
3482
|
+
instanceId: instanceId,
|
|
3483
|
+
field: field,
|
|
3062
3484
|
mode: "unset"
|
|
3063
|
-
})
|
|
3064
|
-
onAppend: body =>
|
|
3065
|
-
|
|
3485
|
+
}),
|
|
3486
|
+
onAppend: body => editField({
|
|
3487
|
+
instanceId: instanceId,
|
|
3488
|
+
field: field,
|
|
3066
3489
|
mode: "append",
|
|
3067
3490
|
value: noteRow({
|
|
3068
3491
|
body: body,
|
|
3069
3492
|
actor: selfActor,
|
|
3070
3493
|
at: /* @__PURE__ */ (new Date).toISOString()
|
|
3071
3494
|
})
|
|
3072
|
-
})
|
|
3495
|
+
})
|
|
3073
3496
|
});
|
|
3074
3497
|
}
|
|
3075
3498
|
|
|
@@ -3097,28 +3520,34 @@ function EditableValueButton({children: children, hint: hint, hintDisabled: hint
|
|
|
3097
3520
|
});
|
|
3098
3521
|
}
|
|
3099
3522
|
|
|
3100
|
-
function
|
|
3101
|
-
const
|
|
3102
|
-
return
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3523
|
+
function useFieldSaveReport(instanceId) {
|
|
3524
|
+
const report = useRejectionReport();
|
|
3525
|
+
return useMemo(() => {
|
|
3526
|
+
const id = instanceToastId("field-save", instanceId);
|
|
3527
|
+
return {
|
|
3528
|
+
rejected: err => report.rejected({
|
|
3529
|
+
err: err,
|
|
3530
|
+
context: "field save",
|
|
3531
|
+
id: id,
|
|
3532
|
+
refused: "This field can’t be edited right now",
|
|
3533
|
+
failed: "Failed to save the field"
|
|
3534
|
+
}),
|
|
3535
|
+
dismiss: () => report.dismiss(id)
|
|
3536
|
+
};
|
|
3537
|
+
}, [ report, instanceId ]);
|
|
3109
3538
|
}
|
|
3110
3539
|
|
|
3111
|
-
function useSaveField(args
|
|
3112
|
-
const
|
|
3540
|
+
function useSaveField(args) {
|
|
3541
|
+
const report = useFieldSaveReport(args.instanceId), [saving, setSaving] = useState(!1);
|
|
3113
3542
|
return {
|
|
3114
3543
|
saving: saving,
|
|
3115
3544
|
save: async commit => {
|
|
3116
3545
|
if (!saving) {
|
|
3117
3546
|
setSaving(!0);
|
|
3118
3547
|
try {
|
|
3119
|
-
await commit(), args.onSaved?.();
|
|
3548
|
+
await commit(), report.dismiss(), args.onSaved?.();
|
|
3120
3549
|
} catch (err) {
|
|
3121
|
-
|
|
3550
|
+
report.rejected(err);
|
|
3122
3551
|
} finally {
|
|
3123
3552
|
setSaving(!1);
|
|
3124
3553
|
}
|
|
@@ -3128,7 +3557,9 @@ function useSaveField(args = {}) {
|
|
|
3128
3557
|
}
|
|
3129
3558
|
|
|
3130
3559
|
function useActorPick(args) {
|
|
3131
|
-
const {current: current, onSave: onSave, onUnset: onUnset} = args, {saving: saving, save: save} = useSaveField(
|
|
3560
|
+
const {current: current, onSave: onSave, onUnset: onUnset} = args, {saving: saving, save: save} = useSaveField({
|
|
3561
|
+
instanceId: args.instanceId
|
|
3562
|
+
});
|
|
3132
3563
|
return {
|
|
3133
3564
|
saving: saving,
|
|
3134
3565
|
pick: member => {
|
|
@@ -3137,9 +3568,10 @@ function useActorPick(args) {
|
|
|
3137
3568
|
};
|
|
3138
3569
|
}
|
|
3139
3570
|
|
|
3140
|
-
function ActorField({field: field, onSave: onSave, onUnset: onUnset}) {
|
|
3571
|
+
function ActorField({field: field, instanceId: instanceId, onSave: onSave, onUnset: onUnset}) {
|
|
3141
3572
|
const [open, setOpen] = useState(!1), cur = isActorShape(field.value) ? field.value : null, {pick: pick} = useActorPick({
|
|
3142
3573
|
current: cur,
|
|
3574
|
+
instanceId: instanceId,
|
|
3143
3575
|
onSave: onSave,
|
|
3144
3576
|
onUnset: onUnset
|
|
3145
3577
|
}), pickAndClose = member => {
|
|
@@ -3174,7 +3606,9 @@ function ActorField({field: field, onSave: onSave, onUnset: onUnset}) {
|
|
|
3174
3606
|
}
|
|
3175
3607
|
|
|
3176
3608
|
function useAssigneePick(args) {
|
|
3177
|
-
const {current: current, onSave: onSave, onUnset: onUnset} = args, {saving: saving, save: save} = useSaveField(
|
|
3609
|
+
const {current: current, onSave: onSave, onUnset: onUnset} = args, {saving: saving, save: save} = useSaveField({
|
|
3610
|
+
instanceId: args.instanceId
|
|
3611
|
+
});
|
|
3178
3612
|
return {
|
|
3179
3613
|
saving: saving,
|
|
3180
3614
|
pick: assignee => {
|
|
@@ -3189,9 +3623,10 @@ function useAssigneePick(args) {
|
|
|
3189
3623
|
};
|
|
3190
3624
|
}
|
|
3191
3625
|
|
|
3192
|
-
function AssigneeField({field: field, onSave: onSave, onUnset: onUnset}) {
|
|
3626
|
+
function AssigneeField({field: field, instanceId: instanceId, onSave: onSave, onUnset: onUnset}) {
|
|
3193
3627
|
const [open, setOpen] = useState(!1), cur = isAssigneeShape(field.value) ? field.value : null, {pick: pick} = useAssigneePick({
|
|
3194
3628
|
current: cur,
|
|
3629
|
+
instanceId: instanceId,
|
|
3195
3630
|
onSave: onSave,
|
|
3196
3631
|
onUnset: onUnset
|
|
3197
3632
|
}), pickAndClose = assignee => {
|
|
@@ -3231,8 +3666,10 @@ function arrayRowsOf(value) {
|
|
|
3231
3666
|
return Array.isArray(value) ? value.filter(row => typeof row == "object" && row !== null) : [];
|
|
3232
3667
|
}
|
|
3233
3668
|
|
|
3234
|
-
function NotesField({field: field, onAppend: onAppend}) {
|
|
3235
|
-
const [body, setBody] = useState(""), {saving: saving, save: save} = useSaveField(
|
|
3669
|
+
function NotesField({field: field, instanceId: instanceId, onAppend: onAppend}) {
|
|
3670
|
+
const [body, setBody] = useState(""), {saving: saving, save: save} = useSaveField({
|
|
3671
|
+
instanceId: instanceId
|
|
3672
|
+
}), rows = arrayRowsOf(field.value), trimmed = body.trim(), add = () => {
|
|
3236
3673
|
saving || trimmed === "" || (setBody(""), save(async () => {
|
|
3237
3674
|
try {
|
|
3238
3675
|
await onAppend(trimmed);
|
|
@@ -3273,11 +3710,13 @@ function NotesField({field: field, onAppend: onAppend}) {
|
|
|
3273
3710
|
});
|
|
3274
3711
|
}
|
|
3275
3712
|
|
|
3276
|
-
function DateField({field: field, onSave: onSave, onUnset: onUnset}) {
|
|
3277
|
-
const {save: save} = useSaveField(
|
|
3713
|
+
function DateField({field: field, kind: kind, instanceId: instanceId, onSave: onSave, onUnset: onUnset}) {
|
|
3714
|
+
const {save: save} = useSaveField({
|
|
3715
|
+
instanceId: instanceId
|
|
3716
|
+
});
|
|
3278
3717
|
/* @__PURE__ */
|
|
3279
3718
|
return jsx(DateFieldInput, {
|
|
3280
|
-
kind:
|
|
3719
|
+
kind: kind,
|
|
3281
3720
|
onChange: next => {
|
|
3282
3721
|
save(() => next === null && onUnset !== void 0 ? onUnset() : onSave(next));
|
|
3283
3722
|
},
|
|
@@ -3285,8 +3724,10 @@ function DateField({field: field, onSave: onSave, onUnset: onUnset}) {
|
|
|
3285
3724
|
});
|
|
3286
3725
|
}
|
|
3287
3726
|
|
|
3288
|
-
function DocRefField({field: field, entry: entry, onSave: onSave, onUnset: onUnset}) {
|
|
3289
|
-
const {save: save} = useSaveField(
|
|
3727
|
+
function DocRefField({field: field, entry: entry, instanceId: instanceId, onSave: onSave, onUnset: onUnset}) {
|
|
3728
|
+
const {save: save} = useSaveField({
|
|
3729
|
+
instanceId: instanceId
|
|
3730
|
+
}), value = isGdr(field.value) ? field.value : null, types = entry !== void 0 && isSingleDocRefEntry(entry) ? entry.types : void 0;
|
|
3290
3731
|
return field.editable ? /* @__PURE__ */ jsx(DocPicker, {
|
|
3291
3732
|
onChange: ref => {
|
|
3292
3733
|
save(() => ref === null && onUnset !== void 0 ? onUnset() : onSave(ref));
|
|
@@ -3301,8 +3742,10 @@ function DocRefField({field: field, entry: entry, onSave: onSave, onUnset: onUns
|
|
|
3301
3742
|
});
|
|
3302
3743
|
}
|
|
3303
3744
|
|
|
3304
|
-
function BooleanSwitchField({field: field, onSave: onSave}) {
|
|
3305
|
-
const {save: save} = useSaveField(
|
|
3745
|
+
function BooleanSwitchField({field: field, instanceId: instanceId, onSave: onSave}) {
|
|
3746
|
+
const {save: save} = useSaveField({
|
|
3747
|
+
instanceId: instanceId
|
|
3748
|
+
}), committed = field.value === !0;
|
|
3306
3749
|
/* @__PURE__ */
|
|
3307
3750
|
return jsx(Flex, {
|
|
3308
3751
|
align: "center",
|
|
@@ -3315,8 +3758,10 @@ function BooleanSwitchField({field: field, onSave: onSave}) {
|
|
|
3315
3758
|
});
|
|
3316
3759
|
}
|
|
3317
3760
|
|
|
3318
|
-
function ChoiceField({field: field, options: options, onSave: onSave, onUnset: onUnset}) {
|
|
3319
|
-
const {save: save} = useSaveField(
|
|
3761
|
+
function ChoiceField({field: field, instanceId: instanceId, options: options, onSave: onSave, onUnset: onUnset}) {
|
|
3762
|
+
const {save: save} = useSaveField({
|
|
3763
|
+
instanceId: instanceId
|
|
3764
|
+
});
|
|
3320
3765
|
/* @__PURE__ */
|
|
3321
3766
|
return jsx(ChoiceSelect, {
|
|
3322
3767
|
onChange: value => {
|
|
@@ -3390,8 +3835,8 @@ function FieldEditRow({field: field, onSave: onSave, onCancel: onCancel, saving:
|
|
|
3390
3835
|
});
|
|
3391
3836
|
}
|
|
3392
3837
|
|
|
3393
|
-
function GenericField({field: field, onSave: onSave, onPreview: onPreview, onDiscardPreview: onDiscardPreview}) {
|
|
3394
|
-
const
|
|
3838
|
+
function GenericField({field: field, onSave: onSave, instanceId: instanceId, onPreview: onPreview, onDiscardPreview: onDiscardPreview}) {
|
|
3839
|
+
const report = useFieldSaveReport(instanceId), canSave = value => scalarValidationIssue({
|
|
3395
3840
|
kind: field.type,
|
|
3396
3841
|
label: field.title ?? field.name,
|
|
3397
3842
|
validation: field.validation,
|
|
@@ -3402,7 +3847,7 @@ function GenericField({field: field, onSave: onSave, onPreview: onPreview, onDis
|
|
|
3402
3847
|
onPreview: onPreview,
|
|
3403
3848
|
onDiscardPreview: onDiscardPreview,
|
|
3404
3849
|
canSave: canSave,
|
|
3405
|
-
onSaveFailure:
|
|
3850
|
+
onSaveFailure: report.rejected
|
|
3406
3851
|
}), validationIssue = scalarValidationIssue({
|
|
3407
3852
|
kind: field.type,
|
|
3408
3853
|
label: field.title ?? field.name,
|
|
@@ -3448,9 +3893,10 @@ function AdvanceHint({stageTitle: stageTitle2}) {
|
|
|
3448
3893
|
});
|
|
3449
3894
|
}
|
|
3450
3895
|
|
|
3451
|
-
function arrayArm({field: field, entry: entry, onAppend: onAppend}) {
|
|
3896
|
+
function arrayArm({field: field, entry: entry, instanceId: instanceId, onAppend: onAppend}) {
|
|
3452
3897
|
return field.editable && onAppend !== void 0 && entry !== void 0 && isNotesEntry(entry) ? /* @__PURE__ */ jsx(NotesField, {
|
|
3453
3898
|
field: field,
|
|
3899
|
+
instanceId: instanceId,
|
|
3454
3900
|
onAppend: onAppend
|
|
3455
3901
|
}) : /* @__PURE__ */ jsx(ArrayValueRows, {
|
|
3456
3902
|
rows: arrayRowsOf(field.value)
|
|
@@ -3458,7 +3904,7 @@ function arrayArm({field: field, entry: entry, onAppend: onAppend}) {
|
|
|
3458
3904
|
}
|
|
3459
3905
|
|
|
3460
3906
|
function fieldArm({arm: arm, entry: entry, onUnset: onUnset, onAppend: onAppend, onPreview: onPreview, onDiscardPreview: onDiscardPreview}) {
|
|
3461
|
-
const {field: field} = arm;
|
|
3907
|
+
const {field: field, instanceId: instanceId} = arm;
|
|
3462
3908
|
return field.type === "actor" ? /* @__PURE__ */ jsx(ActorField, {
|
|
3463
3909
|
...arm,
|
|
3464
3910
|
onUnset: onUnset
|
|
@@ -3471,11 +3917,13 @@ function fieldArm({arm: arm, entry: entry, onUnset: onUnset, onAppend: onAppend,
|
|
|
3471
3917
|
}) : field.type === "array" ? arrayArm({
|
|
3472
3918
|
field: field,
|
|
3473
3919
|
entry: entry,
|
|
3920
|
+
instanceId: instanceId,
|
|
3474
3921
|
onAppend: onAppend
|
|
3475
3922
|
}) : field.type === "boolean" && field.editable ? /* @__PURE__ */ jsx(BooleanSwitchField, {
|
|
3476
3923
|
...arm
|
|
3477
|
-
}) : (field.type
|
|
3924
|
+
}) : isDateFieldKind(field.type) && field.editable ? /* @__PURE__ */ jsx(DateField, {
|
|
3478
3925
|
...arm,
|
|
3926
|
+
kind: field.type,
|
|
3479
3927
|
onUnset: onUnset
|
|
3480
3928
|
}) : isSingleDocRefKind(field.type) ? /* @__PURE__ */ jsx(DocRefField, {
|
|
3481
3929
|
...arm,
|
|
@@ -3488,9 +3936,10 @@ function fieldArm({arm: arm, entry: entry, onUnset: onUnset, onAppend: onAppend,
|
|
|
3488
3936
|
});
|
|
3489
3937
|
}
|
|
3490
3938
|
|
|
3491
|
-
function EditableField({field: field, entry: entry, description: description, onSave: onSave, onUnset: onUnset, onAppend: onAppend, onPreview: onPreview, onDiscardPreview: onDiscardPreview, consequence: consequence, advanceTo: advanceTo}) {
|
|
3939
|
+
function EditableField({field: field, entry: entry, description: description, instanceId: instanceId, onSave: onSave, onUnset: onUnset, onAppend: onAppend, onPreview: onPreview, onDiscardPreview: onDiscardPreview, consequence: consequence, advanceTo: advanceTo}) {
|
|
3492
3940
|
const label = field.title ?? field.name, arm = {
|
|
3493
3941
|
field: field,
|
|
3942
|
+
instanceId: instanceId,
|
|
3494
3943
|
onSave: onSave
|
|
3495
3944
|
}, content = entry?.options === void 0 ? fieldArm({
|
|
3496
3945
|
arm: arm,
|
|
@@ -3522,11 +3971,15 @@ function EditableField({field: field, entry: entry, description: description, on
|
|
|
3522
3971
|
});
|
|
3523
3972
|
}
|
|
3524
3973
|
|
|
3525
|
-
function MetaRow({
|
|
3974
|
+
function MetaRow({children: children, fillHeight: fillHeight, label: label}) {
|
|
3526
3975
|
/* @__PURE__ */
|
|
3527
3976
|
return jsxs(Flex, {
|
|
3528
|
-
align: "flex-start",
|
|
3529
3977
|
gap: 4,
|
|
3978
|
+
...fillHeight ? {
|
|
3979
|
+
flex: 1
|
|
3980
|
+
} : {
|
|
3981
|
+
align: "flex-start"
|
|
3982
|
+
},
|
|
3530
3983
|
children: [
|
|
3531
3984
|
/* @__PURE__ */ jsx(Box, {
|
|
3532
3985
|
style: {
|
|
@@ -3599,27 +4052,6 @@ function ActivityStatusIcon({status: status}) {
|
|
|
3599
4052
|
});
|
|
3600
4053
|
}
|
|
3601
4054
|
|
|
3602
|
-
function LoadingRow({label: label, padding: padding}) {
|
|
3603
|
-
/* @__PURE__ */
|
|
3604
|
-
return jsxs(Flex, {
|
|
3605
|
-
align: "center",
|
|
3606
|
-
gap: 2,
|
|
3607
|
-
...padding === void 0 ? {} : {
|
|
3608
|
-
padding: padding
|
|
3609
|
-
},
|
|
3610
|
-
children: [
|
|
3611
|
-
/* @__PURE__ */ jsx(Spinner, {
|
|
3612
|
-
muted: !0,
|
|
3613
|
-
size: 1
|
|
3614
|
-
}),
|
|
3615
|
-
/* @__PURE__ */ jsx(Text, {
|
|
3616
|
-
muted: !0,
|
|
3617
|
-
size: 1,
|
|
3618
|
-
children: label
|
|
3619
|
-
}) ]
|
|
3620
|
-
});
|
|
3621
|
-
}
|
|
3622
|
-
|
|
3623
4055
|
function useSpaceToken(index) {
|
|
3624
4056
|
const value = useTheme_v2().space[index];
|
|
3625
4057
|
if (value === void 0) throw new Error(`theme is missing space token ${index}`);
|
|
@@ -3666,6 +4098,46 @@ function useBadgeCapTrim() {
|
|
|
3666
4098
|
};
|
|
3667
4099
|
}
|
|
3668
4100
|
|
|
4101
|
+
function SpinnerSlot({busy: busy}) {
|
|
4102
|
+
const size = useTextIconSize(), trim = useCapTrimFor(size);
|
|
4103
|
+
/* @__PURE__ */
|
|
4104
|
+
return jsx(Flex, {
|
|
4105
|
+
align: "center",
|
|
4106
|
+
flex: "none",
|
|
4107
|
+
justify: "center",
|
|
4108
|
+
style: {
|
|
4109
|
+
height: size,
|
|
4110
|
+
marginBottom: trim,
|
|
4111
|
+
marginTop: trim,
|
|
4112
|
+
width: size
|
|
4113
|
+
},
|
|
4114
|
+
children: busy ? /* @__PURE__ */ jsx(Spinner, {
|
|
4115
|
+
muted: !0,
|
|
4116
|
+
size: 1
|
|
4117
|
+
}) : null
|
|
4118
|
+
});
|
|
4119
|
+
}
|
|
4120
|
+
|
|
4121
|
+
function LoadingRow({label: label, padding: padding}) {
|
|
4122
|
+
/* @__PURE__ */
|
|
4123
|
+
return jsxs(Flex, {
|
|
4124
|
+
align: "center",
|
|
4125
|
+
gap: 2,
|
|
4126
|
+
...padding === void 0 ? {} : {
|
|
4127
|
+
padding: padding
|
|
4128
|
+
},
|
|
4129
|
+
children: [
|
|
4130
|
+
/* @__PURE__ */ jsx(SpinnerSlot, {
|
|
4131
|
+
busy: !0
|
|
4132
|
+
}),
|
|
4133
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4134
|
+
muted: !0,
|
|
4135
|
+
size: 1,
|
|
4136
|
+
children: label
|
|
4137
|
+
}) ]
|
|
4138
|
+
});
|
|
4139
|
+
}
|
|
4140
|
+
|
|
3669
4141
|
function AvatarDisplay({avatar: avatar, "aria-label": ariaLabel}) {
|
|
3670
4142
|
const trim = useAvatarCapTrim();
|
|
3671
4143
|
/* @__PURE__ */
|
|
@@ -3746,8 +4218,8 @@ function UserAvatarGroup({ids: ids, hint: hint}) {
|
|
|
3746
4218
|
});
|
|
3747
4219
|
}
|
|
3748
4220
|
|
|
3749
|
-
function AssignActivityControl({instanceId: instanceId, state: state, assigneeIds: assigneeIds = []}) {
|
|
3750
|
-
const
|
|
4221
|
+
function AssignActivityControl({instanceId: instanceId, state: state, surface: surface, assigneeIds: assigneeIds = []}) {
|
|
4222
|
+
const editField = useEditField(surface), report = useRejectionReport(), [open, setOpen] = useState(!1), [busy, setBusy] = useState(!1);
|
|
3751
4223
|
if (state.kind === "none") return assigneeIds.length === 0 ? null : /* @__PURE__ */ jsx(AvatarDisplay, {
|
|
3752
4224
|
"aria-label": "Assignees",
|
|
3753
4225
|
avatar: /* @__PURE__ */ jsx(UserAvatarGroup, {
|
|
@@ -3768,23 +4240,27 @@ function AssignActivityControl({instanceId: instanceId, state: state, assigneeId
|
|
|
3768
4240
|
if (!(busy || field === void 0)) {
|
|
3769
4241
|
setBusy(!0);
|
|
3770
4242
|
try {
|
|
3771
|
-
selectedIds.has(memberId) ? await
|
|
3772
|
-
|
|
4243
|
+
selectedIds.has(memberId) ? await editField({
|
|
4244
|
+
instanceId: instanceId,
|
|
4245
|
+
field: field,
|
|
3773
4246
|
mode: "set",
|
|
3774
4247
|
value: members.filter(m => !(m.type === "user" && m.id === memberId))
|
|
3775
|
-
}) : await
|
|
3776
|
-
|
|
4248
|
+
}) : await editField({
|
|
4249
|
+
instanceId: instanceId,
|
|
4250
|
+
field: field,
|
|
3777
4251
|
mode: "append",
|
|
3778
4252
|
value: {
|
|
3779
4253
|
type: "user",
|
|
3780
4254
|
id: memberId
|
|
3781
4255
|
}
|
|
3782
|
-
});
|
|
4256
|
+
}), report.dismiss(instanceToastId("assign", instanceId));
|
|
3783
4257
|
} catch (err) {
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
4258
|
+
report.rejected({
|
|
4259
|
+
err: err,
|
|
4260
|
+
context: "assignment",
|
|
4261
|
+
id: instanceToastId("assign", instanceId),
|
|
4262
|
+
refused: "Assignees can’t be changed right now",
|
|
4263
|
+
failed: "Failed to update assignees"
|
|
3788
4264
|
});
|
|
3789
4265
|
} finally {
|
|
3790
4266
|
setBusy(!1);
|
|
@@ -3851,6 +4327,11 @@ function appendTargetFor(targets, filter) {
|
|
|
3851
4327
|
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];
|
|
3852
4328
|
}
|
|
3853
4329
|
|
|
4330
|
+
function canRemoveRow(args) {
|
|
4331
|
+
const {editTarget: editTarget, appendTarget: appendTarget} = args;
|
|
4332
|
+
return editTarget === void 0 || appendTarget === void 0 ? !1 : editTarget.scope === appendTarget.scope && editTarget.field === appendTarget.field && editTarget.activity === appendTarget.activity;
|
|
4333
|
+
}
|
|
4334
|
+
|
|
3854
4335
|
function looksLikeDefinition(value) {
|
|
3855
4336
|
return typeof value == "object" && value !== null && Array.isArray(value.stages);
|
|
3856
4337
|
}
|
|
@@ -4092,6 +4573,21 @@ function AddItemControl({onAdd: onAdd, button: button, busy: busy}) {
|
|
|
4092
4573
|
});
|
|
4093
4574
|
}
|
|
4094
4575
|
|
|
4576
|
+
function RemoveItemButton({onClick: onClick}) {
|
|
4577
|
+
/* @__PURE__ */
|
|
4578
|
+
return jsx(HoverHint, {
|
|
4579
|
+
text: "Remove item",
|
|
4580
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
4581
|
+
"aria-label": "Remove item",
|
|
4582
|
+
fontSize: 1,
|
|
4583
|
+
icon: CloseIcon,
|
|
4584
|
+
mode: "bleed",
|
|
4585
|
+
onClick: onClick,
|
|
4586
|
+
padding: 2
|
|
4587
|
+
})
|
|
4588
|
+
});
|
|
4589
|
+
}
|
|
4590
|
+
|
|
4095
4591
|
function BreadcrumbTail({segments: segments, style: style}) {
|
|
4096
4592
|
/* @__PURE__ */
|
|
4097
4593
|
return jsx(Text, {
|
|
@@ -4158,7 +4654,7 @@ function WorkRow({lead: lead, children: children, end: end, onOpen: onOpen}) {
|
|
|
4158
4654
|
});
|
|
4159
4655
|
}
|
|
4160
4656
|
|
|
4161
|
-
function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle, onPatch: onPatch}) {
|
|
4657
|
+
function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle, onPatch: onPatch, onRemove: onRemove}) {
|
|
4162
4658
|
const {canClick: canClick, hint: hint} = rowInteractivity(row), editable = row.editTarget !== void 0, checkbox = /* @__PURE__ */ jsx(TodoCheckbox, {
|
|
4163
4659
|
canClick: canClick,
|
|
4164
4660
|
checked: isTodoDone(row.item),
|
|
@@ -4177,6 +4673,8 @@ function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle,
|
|
|
4177
4673
|
editable: editable,
|
|
4178
4674
|
item: row.item,
|
|
4179
4675
|
onPatch: onPatch
|
|
4676
|
+
}), onRemove === void 0 ? null : /* @__PURE__ */ jsx(RemoveItemButton, {
|
|
4677
|
+
onClick: onRemove
|
|
4180
4678
|
}) ]
|
|
4181
4679
|
}),
|
|
4182
4680
|
lead:
|
|
@@ -4203,37 +4701,41 @@ function TodoItemRowView({breadcrumb: breadcrumb, row: row, onToggle: onToggle,
|
|
|
4203
4701
|
}
|
|
4204
4702
|
|
|
4205
4703
|
function TodoItemsList({breadcrumb: breadcrumb, entry: entry, filter: filter, surface: surface}) {
|
|
4206
|
-
const {instance: instance} = entry, definition = useDefinition(entry), {editFieldFor: editFieldFor, fireActionFor: fireActionFor} = useWorkflowContext(), telemetry = useWorkflowTelemetry(),
|
|
4704
|
+
const {instance: instance} = entry, definition = useDefinition(entry), {editFieldFor: editFieldFor, fireActionFor: fireActionFor} = useWorkflowContext(), telemetry = useWorkflowTelemetry(), report = useRejectionReport(), [busy, setBusy] = useState(!1), derivation = deriveTodoItems(entry), rows = derivation.rows.filter(row => rowMatches(row, filter)), appendTarget = appendTargetFor(derivation.appendTargets, filter), run = async op => {
|
|
4207
4705
|
if (busy) return !1;
|
|
4208
4706
|
setBusy(!0);
|
|
4209
4707
|
try {
|
|
4210
|
-
return await op(),
|
|
4708
|
+
return await op(), report.dismiss(instanceToastId("todo-write", instance._id)),
|
|
4709
|
+
!0;
|
|
4211
4710
|
} catch (err) {
|
|
4212
|
-
return
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4711
|
+
return report.rejected({
|
|
4712
|
+
err: err,
|
|
4713
|
+
context: "to-do write",
|
|
4714
|
+
id: instanceToastId("todo-write", instance._id),
|
|
4715
|
+
refused: "To-dos can’t be changed right now",
|
|
4716
|
+
failed: "Failed to update to-dos"
|
|
4216
4717
|
}), !1;
|
|
4217
4718
|
} finally {
|
|
4218
4719
|
setBusy(!1);
|
|
4219
4720
|
}
|
|
4220
|
-
},
|
|
4221
|
-
if (!row.editTarget) return Promise.resolve();
|
|
4222
|
-
const target = row.editTarget
|
|
4223
|
-
...it,
|
|
4224
|
-
...patch
|
|
4225
|
-
} : it);
|
|
4721
|
+
}, writeItems = (row, nextItems) => {
|
|
4722
|
+
if (!row.editTarget) return Promise.resolve(!1);
|
|
4723
|
+
const target = row.editTarget;
|
|
4226
4724
|
return run(() => editFieldFor(instance._id, {
|
|
4227
4725
|
target: target,
|
|
4228
4726
|
mode: "set",
|
|
4229
|
-
value:
|
|
4727
|
+
value: nextItems()
|
|
4230
4728
|
}));
|
|
4231
|
-
},
|
|
4729
|
+
}, patchItem = (row, patch) => writeItems(row, () => todoItemsPatched({
|
|
4730
|
+
items: row.items,
|
|
4731
|
+
key: row.item._key,
|
|
4732
|
+
patch: patch
|
|
4733
|
+
})), toggleRow = async row => {
|
|
4232
4734
|
if (busy) return;
|
|
4233
4735
|
if (row.editTarget) {
|
|
4234
4736
|
const done = !isTodoDone(row.item), success = await patchItem(row, {
|
|
4235
4737
|
status: toggledTodoStatus(row.item)
|
|
4236
|
-
})
|
|
4738
|
+
});
|
|
4237
4739
|
telemetry.log(WorkflowTodoToggled, {
|
|
4238
4740
|
instanceId: instance._id,
|
|
4239
4741
|
surface: surface,
|
|
@@ -4257,14 +4759,44 @@ function TodoItemsList({breadcrumb: breadcrumb, entry: entry, filter: filter, su
|
|
|
4257
4759
|
success: success
|
|
4258
4760
|
});
|
|
4259
4761
|
}
|
|
4260
|
-
}, addItem = label =>
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4762
|
+
}, addItem = async label => {
|
|
4763
|
+
if (busy || !appendTarget) return !1;
|
|
4764
|
+
const success = await run(() => editFieldFor(instance._id, {
|
|
4765
|
+
target: appendTarget,
|
|
4766
|
+
mode: "append",
|
|
4767
|
+
value: {
|
|
4768
|
+
label: label,
|
|
4769
|
+
status: "open"
|
|
4770
|
+
}
|
|
4771
|
+
}));
|
|
4772
|
+
return telemetry.log(WorkflowTodoEdited, {
|
|
4773
|
+
instanceId: instance._id,
|
|
4774
|
+
surface: surface,
|
|
4775
|
+
kind: "add",
|
|
4776
|
+
success: success
|
|
4777
|
+
}), success;
|
|
4778
|
+
}, editRow = async (row, patch) => {
|
|
4779
|
+
if (busy || row.editTarget === void 0) return;
|
|
4780
|
+
const success = await patchItem(row, patch);
|
|
4781
|
+
telemetry.log(WorkflowTodoEdited, {
|
|
4782
|
+
instanceId: instance._id,
|
|
4783
|
+
surface: surface,
|
|
4784
|
+
kind: todoEditKind(patch),
|
|
4785
|
+
success: success
|
|
4786
|
+
});
|
|
4787
|
+
}, removeRow = async row => {
|
|
4788
|
+
if (busy || row.editTarget === void 0) return;
|
|
4789
|
+
const success = await writeItems(row, () => todoItemsWithout({
|
|
4790
|
+
items: row.items,
|
|
4791
|
+
key: row.item._key
|
|
4792
|
+
}));
|
|
4793
|
+
telemetry.log(WorkflowTodoEdited, {
|
|
4794
|
+
instanceId: instance._id,
|
|
4795
|
+
surface: surface,
|
|
4796
|
+
kind: "remove",
|
|
4797
|
+
success: success
|
|
4798
|
+
});
|
|
4799
|
+
};
|
|
4268
4800
|
if (rows.length === 0 && !appendTarget) return null;
|
|
4269
4801
|
const rowKey = row => `${row.scope}:${row.activityName ?? ""}:${row.fieldName}:${row.item._key}`, rowBreadcrumb = row => {
|
|
4270
4802
|
if (breadcrumb === void 0 || row.activityName === void 0) return breadcrumb;
|
|
@@ -4284,8 +4816,16 @@ function TodoItemsList({breadcrumb: breadcrumb, entry: entry, filter: filter, su
|
|
|
4284
4816
|
children: rows.map(row => /* @__PURE__ */ jsx(TodoItemRowView, {
|
|
4285
4817
|
breadcrumb: rowBreadcrumb(row),
|
|
4286
4818
|
onPatch: patch => {
|
|
4287
|
-
|
|
4819
|
+
editRow(row, patch);
|
|
4288
4820
|
},
|
|
4821
|
+
...canRemoveRow({
|
|
4822
|
+
editTarget: row.editTarget,
|
|
4823
|
+
appendTarget: appendTarget
|
|
4824
|
+
}) ? {
|
|
4825
|
+
onRemove: () => {
|
|
4826
|
+
removeRow(row);
|
|
4827
|
+
}
|
|
4828
|
+
} : {},
|
|
4289
4829
|
onToggle: () => {
|
|
4290
4830
|
toggleRow(row);
|
|
4291
4831
|
},
|
|
@@ -4373,7 +4913,7 @@ const ACTIONS_MENU_TRIGGER = {
|
|
|
4373
4913
|
padding: 2
|
|
4374
4914
|
};
|
|
4375
4915
|
|
|
4376
|
-
function ActionMenuItem({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, onCollectParams: onCollectParams}) {
|
|
4916
|
+
function ActionMenuItem({actionEval: actionEval, instanceId: instanceId, activity: activity, surface: surface, placement: placement, onCollectParams: onCollectParams}) {
|
|
4377
4917
|
const rowKind = actionRowKind(actionEval), label = actionTriggerLabel(actionEval), {tone: tone, icon: icon} = actionButtonFace({
|
|
4378
4918
|
actionEval: actionEval,
|
|
4379
4919
|
activityName: activity
|
|
@@ -4385,6 +4925,7 @@ function ActionMenuItem({actionEval: actionEval, instanceId: instanceId, activit
|
|
|
4385
4925
|
action: actionEval.action.name,
|
|
4386
4926
|
label: label,
|
|
4387
4927
|
surface: surface,
|
|
4928
|
+
placement: placement,
|
|
4388
4929
|
viaMenu: !0
|
|
4389
4930
|
});
|
|
4390
4931
|
return rowKind.kind === "disabled" ? /* @__PURE__ */ jsx(MenuItem, {
|
|
@@ -4421,7 +4962,7 @@ function rowShield(menuButton) {
|
|
|
4421
4962
|
});
|
|
4422
4963
|
}
|
|
4423
4964
|
|
|
4424
|
-
function ActionsMenuButton({actions: actions, instanceId: instanceId, activity: activity, label: label, surface: surface, mode: mode = "ghost", inButtonCard: inButtonCard = !1}) {
|
|
4965
|
+
function ActionsMenuButton({actions: actions, instanceId: instanceId, activity: activity, label: label, surface: surface, placement: placement, mode: mode = "ghost", inButtonCard: inButtonCard = !1}) {
|
|
4425
4966
|
const [paramsAction, setParamsAction] = useState(void 0), clusterPending = useActionClusterPending(), menuId = useId(), menuButton = /* @__PURE__ */ jsx(MenuButton, {
|
|
4426
4967
|
button: /* @__PURE__ */ jsx(Button, {
|
|
4427
4968
|
...ACTIONS_MENU_TRIGGER,
|
|
@@ -4441,6 +4982,7 @@ function ActionsMenuButton({actions: actions, instanceId: instanceId, activity:
|
|
|
4441
4982
|
activity: activity,
|
|
4442
4983
|
instanceId: instanceId,
|
|
4443
4984
|
onCollectParams: () => setParamsAction(a),
|
|
4985
|
+
placement: placement,
|
|
4444
4986
|
surface: surface
|
|
4445
4987
|
}, a.action.name))
|
|
4446
4988
|
}),
|
|
@@ -4458,6 +5000,7 @@ function ActionsMenuButton({actions: actions, instanceId: instanceId, activity:
|
|
|
4458
5000
|
activity: activity,
|
|
4459
5001
|
instanceId: instanceId,
|
|
4460
5002
|
onClose: () => setParamsAction(void 0),
|
|
5003
|
+
placement: placement,
|
|
4461
5004
|
surface: surface,
|
|
4462
5005
|
viaMenu: !0
|
|
4463
5006
|
})
|
|
@@ -4476,7 +5019,8 @@ function TerminalFooter({actions: actions, activity: activity, instanceId: insta
|
|
|
4476
5019
|
actionEval: only,
|
|
4477
5020
|
activity: activity,
|
|
4478
5021
|
instanceId: instanceId,
|
|
4479
|
-
|
|
5022
|
+
placement: "terminal-footer",
|
|
5023
|
+
surface: "activity-dialog"
|
|
4480
5024
|
})
|
|
4481
5025
|
}) : /* @__PURE__ */ jsx(FittedActions, {
|
|
4482
5026
|
actions: actions,
|
|
@@ -4531,14 +5075,16 @@ function FittedActions({actions: actions, activity: activity, instanceId: instan
|
|
|
4531
5075
|
actionEval: a,
|
|
4532
5076
|
activity: activity,
|
|
4533
5077
|
instanceId: instanceId,
|
|
4534
|
-
|
|
5078
|
+
placement: "terminal-footer",
|
|
5079
|
+
surface: "activity-dialog"
|
|
4535
5080
|
}, a.action.name)), overflow.length > 0 ? /* @__PURE__ */ jsx(ActionsMenuButton, {
|
|
4536
5081
|
actions: overflow,
|
|
4537
5082
|
activity: activity,
|
|
4538
5083
|
instanceId: instanceId,
|
|
4539
5084
|
label: MORE_ACTIONS_LABEL,
|
|
4540
5085
|
mode: "default",
|
|
4541
|
-
|
|
5086
|
+
placement: "terminal-footer",
|
|
5087
|
+
surface: "activity-dialog"
|
|
4542
5088
|
}) : null ]
|
|
4543
5089
|
}) ]
|
|
4544
5090
|
});
|
|
@@ -4673,7 +5219,8 @@ function MetaBlock({detail: detail, definition: definition, document: document,
|
|
|
4673
5219
|
children: /* @__PURE__ */ jsx(Flex, {
|
|
4674
5220
|
children: /* @__PURE__ */ jsx(DocPreviewLink, {
|
|
4675
5221
|
gdr: document,
|
|
4676
|
-
layout: "inline"
|
|
5222
|
+
layout: "inline",
|
|
5223
|
+
source: "dialog-subject"
|
|
4677
5224
|
})
|
|
4678
5225
|
})
|
|
4679
5226
|
}) : null,
|
|
@@ -4697,7 +5244,8 @@ function TopActions({detail: detail, definition: definition, instanceId: instanc
|
|
|
4697
5244
|
actionEval: a,
|
|
4698
5245
|
activity: activityName,
|
|
4699
5246
|
instanceId: instanceId,
|
|
4700
|
-
|
|
5247
|
+
placement: "dialog-strip",
|
|
5248
|
+
surface: "activity-dialog"
|
|
4701
5249
|
}, a.action.name)), p.manualTarget ? /* @__PURE__ */ jsx(Button, {
|
|
4702
5250
|
as: "a",
|
|
4703
5251
|
fontSize: 1,
|
|
@@ -4755,7 +5303,8 @@ function FieldRow({field: field, detail: detail, entry: entry, activityName: act
|
|
|
4755
5303
|
state: {
|
|
4756
5304
|
kind: "editable",
|
|
4757
5305
|
field: assignField
|
|
4758
|
-
}
|
|
5306
|
+
},
|
|
5307
|
+
surface: "activity-dialog"
|
|
4759
5308
|
}) : null ]
|
|
4760
5309
|
}) ]
|
|
4761
5310
|
});
|
|
@@ -4763,7 +5312,8 @@ function FieldRow({field: field, detail: detail, entry: entry, activityName: act
|
|
|
4763
5312
|
const editable = detail.editableByName.get(field.name);
|
|
4764
5313
|
return editable ? /* @__PURE__ */ jsx(EditableFieldControl, {
|
|
4765
5314
|
field: editable,
|
|
4766
|
-
instanceId: instanceId
|
|
5315
|
+
instanceId: instanceId,
|
|
5316
|
+
surface: "activity-dialog"
|
|
4767
5317
|
}) : /* @__PURE__ */ jsxs(Stack, {
|
|
4768
5318
|
gap: 2,
|
|
4769
5319
|
children: [ head,
|
|
@@ -4837,42 +5387,22 @@ function ForMeEmptyState() {
|
|
|
4837
5387
|
description: "No activities or to-dos are assigned to you",
|
|
4838
5388
|
icon: /* @__PURE__ */ jsx(CheckmarkCircleIcon, {}),
|
|
4839
5389
|
title: "Nothing to do!"
|
|
4840
|
-
});
|
|
4841
|
-
}
|
|
4842
|
-
|
|
4843
|
-
function CountedLabel({count: count, label: label}) {
|
|
4844
|
-
return count === void 0 || count === 0 ? /* @__PURE__ */ jsx(Fragment, {
|
|
4845
|
-
children: label
|
|
4846
|
-
}) : /* @__PURE__ */ jsxs(Flex, {
|
|
4847
|
-
align: "center",
|
|
4848
|
-
gap: 2,
|
|
4849
|
-
children: [ label,
|
|
4850
|
-
/* @__PURE__ */ jsx(Text, {
|
|
4851
|
-
muted: !0,
|
|
4852
|
-
size: 1,
|
|
4853
|
-
weight: "regular",
|
|
4854
|
-
children: count
|
|
4855
|
-
}) ]
|
|
4856
|
-
});
|
|
4857
|
-
}
|
|
4858
|
-
|
|
4859
|
-
function SpinnerSlot({busy: busy}) {
|
|
4860
|
-
const size = useTextIconSize(), trim = useCapTrimFor(size);
|
|
4861
|
-
/* @__PURE__ */
|
|
4862
|
-
return jsx(Flex, {
|
|
4863
|
-
align: "center",
|
|
4864
|
-
flex: "none",
|
|
4865
|
-
justify: "center",
|
|
4866
|
-
style: {
|
|
4867
|
-
height: size,
|
|
4868
|
-
marginBottom: trim,
|
|
4869
|
-
marginTop: trim,
|
|
4870
|
-
width: size
|
|
4871
|
-
},
|
|
4872
|
-
children: busy ? /* @__PURE__ */ jsx(Spinner, {
|
|
5390
|
+
});
|
|
5391
|
+
}
|
|
5392
|
+
|
|
5393
|
+
function CountedLabel({count: count, label: label}) {
|
|
5394
|
+
return count === void 0 || count === 0 ? /* @__PURE__ */ jsx(Fragment, {
|
|
5395
|
+
children: label
|
|
5396
|
+
}) : /* @__PURE__ */ jsxs(Flex, {
|
|
5397
|
+
align: "center",
|
|
5398
|
+
gap: 2,
|
|
5399
|
+
children: [ label,
|
|
5400
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4873
5401
|
muted: !0,
|
|
4874
|
-
size: 1
|
|
4875
|
-
|
|
5402
|
+
size: 1,
|
|
5403
|
+
weight: "regular",
|
|
5404
|
+
children: count
|
|
5405
|
+
}) ]
|
|
4876
5406
|
});
|
|
4877
5407
|
}
|
|
4878
5408
|
|
|
@@ -4902,6 +5432,92 @@ function GroupHeading({busy: busy, count: count, title: title, end: end}) {
|
|
|
4902
5432
|
});
|
|
4903
5433
|
}
|
|
4904
5434
|
|
|
5435
|
+
function ActivityDateControl({instanceId: instanceId, state: state, surface: surface, dueDates: dueDates}) {
|
|
5436
|
+
const editField = useEditField(surface), {save: save} = useSaveField({
|
|
5437
|
+
instanceId: instanceId
|
|
5438
|
+
}), [open, setOpen] = useState(!1), raw = dateControlValue({
|
|
5439
|
+
state: state,
|
|
5440
|
+
dueDates: dueDates
|
|
5441
|
+
}), display = raw === void 0 ? null : /* @__PURE__ */ jsx(Text, {
|
|
5442
|
+
muted: !0,
|
|
5443
|
+
size: 1,
|
|
5444
|
+
children: formatDate(raw)
|
|
5445
|
+
});
|
|
5446
|
+
if (state.kind === "none") return display;
|
|
5447
|
+
if (state.kind === "closed") return display === null ? null : /* @__PURE__ */ jsx(HoverHint, {
|
|
5448
|
+
text: state.reason,
|
|
5449
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
5450
|
+
"aria-label": "Date",
|
|
5451
|
+
as: "span",
|
|
5452
|
+
fontSize: 1,
|
|
5453
|
+
mode: "bleed",
|
|
5454
|
+
onClick: stopRowClick,
|
|
5455
|
+
onMouseDown: stopRowMouseDown,
|
|
5456
|
+
padding: 2,
|
|
5457
|
+
children: display
|
|
5458
|
+
})
|
|
5459
|
+
});
|
|
5460
|
+
const kind = dateControlKind(state), commit = (mode, value) => {
|
|
5461
|
+
state.kind === "editable" && save(() => editField({
|
|
5462
|
+
instanceId: instanceId,
|
|
5463
|
+
field: state.field,
|
|
5464
|
+
...mode === "set" ? {
|
|
5465
|
+
mode: mode,
|
|
5466
|
+
value: value
|
|
5467
|
+
} : {
|
|
5468
|
+
mode: mode
|
|
5469
|
+
}
|
|
5470
|
+
}));
|
|
5471
|
+
}, handleClick = e => {
|
|
5472
|
+
e.stopPropagation(), setOpen(v => !v);
|
|
5473
|
+
};
|
|
5474
|
+
/* @__PURE__ */
|
|
5475
|
+
return jsx(DismissablePopover, {
|
|
5476
|
+
content: /* @__PURE__ */ jsx(Box, {
|
|
5477
|
+
onClick: stopRowClick,
|
|
5478
|
+
children: state.kind === "loading" || kind === void 0 ? /* @__PURE__ */ jsx(LoadingRow, {
|
|
5479
|
+
label: "Loading…",
|
|
5480
|
+
padding: 3
|
|
5481
|
+
}) : /* @__PURE__ */ jsx(ClearableDatePicker, {
|
|
5482
|
+
clearLabel: "Clear date",
|
|
5483
|
+
onClear: () => {
|
|
5484
|
+
setOpen(!1), commit("unset");
|
|
5485
|
+
},
|
|
5486
|
+
onPick: next => {
|
|
5487
|
+
hasTimeOfDay(kind) || setOpen(!1), commit("set", serializeDateFieldValue(next, kind));
|
|
5488
|
+
},
|
|
5489
|
+
selectTime: hasTimeOfDay(kind),
|
|
5490
|
+
value: parseDateFieldValue(state.field.value, kind)
|
|
5491
|
+
})
|
|
5492
|
+
}),
|
|
5493
|
+
onDismiss: () => setOpen(!1),
|
|
5494
|
+
open: open,
|
|
5495
|
+
children: display ? /* @__PURE__ */ jsx(Button, {
|
|
5496
|
+
"aria-label": "Change date",
|
|
5497
|
+
as: "span",
|
|
5498
|
+
fontSize: 1,
|
|
5499
|
+
mode: "bleed",
|
|
5500
|
+
onClick: handleClick,
|
|
5501
|
+
onMouseDown: stopRowMouseDown,
|
|
5502
|
+
padding: 2,
|
|
5503
|
+
children: display
|
|
5504
|
+
}) : /* @__PURE__ */ jsx(HoverHint, {
|
|
5505
|
+
disabled: open,
|
|
5506
|
+
text: "Set date",
|
|
5507
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
5508
|
+
"aria-label": "Set date",
|
|
5509
|
+
as: "span",
|
|
5510
|
+
fontSize: 1,
|
|
5511
|
+
icon: CalendarIcon,
|
|
5512
|
+
mode: "bleed",
|
|
5513
|
+
onClick: handleClick,
|
|
5514
|
+
onMouseDown: stopRowMouseDown,
|
|
5515
|
+
padding: 2
|
|
5516
|
+
})
|
|
5517
|
+
})
|
|
5518
|
+
});
|
|
5519
|
+
}
|
|
5520
|
+
|
|
4905
5521
|
function settledDim(settled) {
|
|
4906
5522
|
return settled ? {
|
|
4907
5523
|
opacity: .66
|
|
@@ -4932,7 +5548,7 @@ function ActivityRowTitle({dimmed: dimmed, children: children}) {
|
|
|
4932
5548
|
});
|
|
4933
5549
|
}
|
|
4934
5550
|
|
|
4935
|
-
function RowTerminalActions({actions: actions, activity: activity, instanceId: instanceId}) {
|
|
5551
|
+
function RowTerminalActions({actions: actions, activity: activity, instanceId: instanceId, surface: surface}) {
|
|
4936
5552
|
const lock = useActionClusterState(), [only, ...rest] = actions;
|
|
4937
5553
|
return only ? /* @__PURE__ */ jsx(ActionClusterProvider, {
|
|
4938
5554
|
value: lock,
|
|
@@ -4944,14 +5560,16 @@ function RowTerminalActions({actions: actions, activity: activity, instanceId: i
|
|
|
4944
5560
|
inButtonCard: !0
|
|
4945
5561
|
},
|
|
4946
5562
|
instanceId: instanceId,
|
|
4947
|
-
|
|
5563
|
+
placement: "inline-row",
|
|
5564
|
+
surface: surface
|
|
4948
5565
|
}) : /* @__PURE__ */ jsx(ActionsMenuButton, {
|
|
4949
5566
|
actions: actions,
|
|
4950
5567
|
activity: activity,
|
|
4951
5568
|
inButtonCard: !0,
|
|
4952
5569
|
instanceId: instanceId,
|
|
4953
5570
|
label: "Select action",
|
|
4954
|
-
|
|
5571
|
+
placement: "inline-row",
|
|
5572
|
+
surface: surface
|
|
4955
5573
|
})
|
|
4956
5574
|
}) : null;
|
|
4957
5575
|
}
|
|
@@ -4972,7 +5590,7 @@ function TitleTag({hint: hint, tone: tone, children: children}) {
|
|
|
4972
5590
|
});
|
|
4973
5591
|
}
|
|
4974
5592
|
|
|
4975
|
-
function ActivityRow({face: face, breadcrumb: breadcrumb, assigneeIds: assigneeIds, assignState: assignState,
|
|
5593
|
+
function ActivityRow({face: face, breadcrumb: breadcrumb, assigneeIds: assigneeIds, assignState: assignState, dateState: dateState, dueDates: dueDates, instanceId: instanceId, onOpen: onOpen, surface: surface, terminalActions: terminalActions = []}) {
|
|
4976
5594
|
const settled = isTerminalActivityStatus(face.status), dimmed = settledDim(settled);
|
|
4977
5595
|
/* @__PURE__ */
|
|
4978
5596
|
return jsxs(WorkRow, {
|
|
@@ -4980,12 +5598,20 @@ function ActivityRow({face: face, breadcrumb: breadcrumb, assigneeIds: assigneeI
|
|
|
4980
5598
|
children: [ settled || terminalActions.length === 0 ? null : /* @__PURE__ */ jsx(RowTerminalActions, {
|
|
4981
5599
|
actions: terminalActions,
|
|
4982
5600
|
activity: face.activityName,
|
|
4983
|
-
instanceId: instanceId
|
|
4984
|
-
|
|
5601
|
+
instanceId: instanceId,
|
|
5602
|
+
surface: surface
|
|
5603
|
+
}),
|
|
5604
|
+
/* @__PURE__ */ jsx(ActivityDateControl, {
|
|
5605
|
+
dueDates: dueDates,
|
|
5606
|
+
instanceId: instanceId,
|
|
5607
|
+
state: dateState,
|
|
5608
|
+
surface: surface
|
|
5609
|
+
}),
|
|
4985
5610
|
/* @__PURE__ */ jsx(AssignActivityControl, {
|
|
4986
5611
|
assigneeIds: assigneeIds,
|
|
4987
5612
|
instanceId: instanceId,
|
|
4988
|
-
state: assignState
|
|
5613
|
+
state: assignState,
|
|
5614
|
+
surface: surface
|
|
4989
5615
|
}) ]
|
|
4990
5616
|
}),
|
|
4991
5617
|
lead: /* @__PURE__ */ jsx(ActivityStatusLead, {
|
|
@@ -5010,7 +5636,7 @@ function ActivityRow({face: face, breadcrumb: breadcrumb, assigneeIds: assigneeI
|
|
|
5010
5636
|
});
|
|
5011
5637
|
}
|
|
5012
5638
|
|
|
5013
|
-
function ActivitiesList({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
5639
|
+
function ActivitiesList({entry: entry, onOpenActivity: onOpenActivity, surface: surface}) {
|
|
5014
5640
|
const activities = (entry.evaluation?.currentStage.activities ?? []).filter(t => !t.scopedOut), activityState = stateByActivity(entry.instance);
|
|
5015
5641
|
return activities.length === 0 ?
|
|
5016
5642
|
/* @__PURE__ */ jsx(Box, {
|
|
@@ -5030,7 +5656,8 @@ function ActivitiesList({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
|
5030
5656
|
editableFields: entry.evaluation?.editableFields
|
|
5031
5657
|
}),
|
|
5032
5658
|
instanceId: entry.instance._id,
|
|
5033
|
-
onOpen: () => onOpenActivity(t.activity.name)
|
|
5659
|
+
onOpen: () => onOpenActivity(t.activity.name),
|
|
5660
|
+
surface: surface
|
|
5034
5661
|
}, t.activity.name))
|
|
5035
5662
|
});
|
|
5036
5663
|
}
|
|
@@ -5094,7 +5721,9 @@ const EDITOR_BY_KIND = {
|
|
|
5094
5721
|
assignees: "assignees",
|
|
5095
5722
|
boolean: "scalar",
|
|
5096
5723
|
date: "scalar",
|
|
5724
|
+
dueDate: "scalar",
|
|
5097
5725
|
datetime: "scalar",
|
|
5726
|
+
dueDatetime: "scalar",
|
|
5098
5727
|
number: "scalar",
|
|
5099
5728
|
progress: "scalar",
|
|
5100
5729
|
string: "scalar",
|
|
@@ -5104,7 +5733,9 @@ const EDITOR_BY_KIND = {
|
|
|
5104
5733
|
array: e => e.value.length > 0 ? pluralize("item", e.value.length, !0) : void 0,
|
|
5105
5734
|
boolean: e => e.value === null ? void 0 : formatBoolean(e.value),
|
|
5106
5735
|
date: e => e.value === null ? void 0 : formatDate(e.value),
|
|
5736
|
+
dueDate: e => e.value === null ? void 0 : formatDate(e.value),
|
|
5107
5737
|
datetime: e => e.value === null ? void 0 : formatDateTime(e.value),
|
|
5738
|
+
dueDatetime: e => e.value === null ? void 0 : formatDateTime(e.value),
|
|
5108
5739
|
"doc.refs": e => e.value.length > 0 ? pluralize("document", e.value.length, !0) : void 0,
|
|
5109
5740
|
object: e => e.value === null ? void 0 : "Set",
|
|
5110
5741
|
"release.ref": e => e.value === null ? void 0 : e.value.releaseName
|
|
@@ -5228,7 +5859,7 @@ function TodoFieldDialog({entry: entry, scope: scope, field: field, title: title
|
|
|
5228
5859
|
|
|
5229
5860
|
const MAX_VISIBLE_PILLS = 4;
|
|
5230
5861
|
|
|
5231
|
-
function FieldPills({entry: entry, scope: scope, definition: definition}) {
|
|
5862
|
+
function FieldPills({entry: entry, scope: scope, definition: definition, surface: surface}) {
|
|
5232
5863
|
const [expanded, setExpanded] = useState(!1), pills = deriveFieldPills({
|
|
5233
5864
|
scope: scope,
|
|
5234
5865
|
definition: definition,
|
|
@@ -5246,7 +5877,8 @@ function FieldPills({entry: entry, scope: scope, definition: definition}) {
|
|
|
5246
5877
|
children: [ visible.map(pill => /* @__PURE__ */ jsx(FieldPill, {
|
|
5247
5878
|
entry: entry,
|
|
5248
5879
|
pill: pill,
|
|
5249
|
-
scope: scope
|
|
5880
|
+
scope: scope,
|
|
5881
|
+
surface: surface
|
|
5250
5882
|
}, pill.name)), overflow > 0 ?
|
|
5251
5883
|
/* @__PURE__ */ jsx(Button, {
|
|
5252
5884
|
mode: "bleed",
|
|
@@ -5280,7 +5912,9 @@ function isEmptyFace(face) {
|
|
|
5280
5912
|
|
|
5281
5913
|
const KIND_ICON = {
|
|
5282
5914
|
date: CalendarIcon,
|
|
5915
|
+
dueDate: CalendarIcon,
|
|
5283
5916
|
datetime: CalendarIcon,
|
|
5917
|
+
dueDatetime: CalendarIcon,
|
|
5284
5918
|
"doc.ref": DocumentIcon,
|
|
5285
5919
|
"doc.refs": DocumentIcon,
|
|
5286
5920
|
subject: DocumentIcon
|
|
@@ -5432,18 +6066,20 @@ function PillButton({children: children, pill: pill, hintDisabled: hintDisabled
|
|
|
5432
6066
|
});
|
|
5433
6067
|
}
|
|
5434
6068
|
|
|
5435
|
-
function useFieldCommit({entry: entry, editability: editability}) {
|
|
5436
|
-
const
|
|
6069
|
+
function useFieldCommit({entry: entry, editability: editability, surface: surface}) {
|
|
6070
|
+
const editField = useEditField(surface), instanceId = entry.instance._id;
|
|
5437
6071
|
return {
|
|
5438
|
-
set: value =>
|
|
5439
|
-
|
|
6072
|
+
set: value => editField({
|
|
6073
|
+
instanceId: instanceId,
|
|
6074
|
+
field: editability,
|
|
5440
6075
|
mode: "set",
|
|
5441
6076
|
value: value
|
|
5442
|
-
})
|
|
5443
|
-
unset: () =>
|
|
5444
|
-
|
|
6077
|
+
}),
|
|
6078
|
+
unset: () => editField({
|
|
6079
|
+
instanceId: instanceId,
|
|
6080
|
+
field: editability,
|
|
5445
6081
|
mode: "unset"
|
|
5446
|
-
})
|
|
6082
|
+
})
|
|
5447
6083
|
};
|
|
5448
6084
|
}
|
|
5449
6085
|
|
|
@@ -5513,11 +6149,28 @@ function ReadOnlyPill({pill: pill}) {
|
|
|
5513
6149
|
});
|
|
5514
6150
|
}
|
|
5515
6151
|
|
|
5516
|
-
function
|
|
5517
|
-
const
|
|
6152
|
+
function usePillWrite(args) {
|
|
6153
|
+
const {entry: entry, editability: editability, surface: surface, onSaved: onSaved} = args, commit = useFieldCommit({
|
|
6154
|
+
entry: entry,
|
|
6155
|
+
editability: editability,
|
|
6156
|
+
surface: surface
|
|
6157
|
+
}), saver = useSaveField({
|
|
6158
|
+
instanceId: entry.instance._id,
|
|
6159
|
+
...onSaved === void 0 ? {} : {
|
|
6160
|
+
onSaved: onSaved
|
|
6161
|
+
}
|
|
6162
|
+
});
|
|
6163
|
+
return {
|
|
6164
|
+
...commit,
|
|
6165
|
+
...saver
|
|
6166
|
+
};
|
|
6167
|
+
}
|
|
6168
|
+
|
|
6169
|
+
function ScalarPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
6170
|
+
const [open, setOpen] = useState(!1), {set: set, saving: saving, save: save} = usePillWrite({
|
|
5518
6171
|
entry: entry,
|
|
5519
|
-
editability: editability
|
|
5520
|
-
|
|
6172
|
+
editability: editability,
|
|
6173
|
+
surface: surface,
|
|
5521
6174
|
onSaved: () => setOpen(!1)
|
|
5522
6175
|
});
|
|
5523
6176
|
/* @__PURE__ */
|
|
@@ -5543,18 +6196,21 @@ function ScalarPill({entry: entry, pill: pill, editability: editability}) {
|
|
|
5543
6196
|
});
|
|
5544
6197
|
}
|
|
5545
6198
|
|
|
5546
|
-
function DatePill({entry: entry, pill: pill, editability: editability, kind: kind}) {
|
|
6199
|
+
function DatePill({entry: entry, pill: pill, editability: editability, surface: surface, kind: kind}) {
|
|
5547
6200
|
const [open, setOpen] = useState(!1), {set: set} = useFieldCommit({
|
|
5548
6201
|
entry: entry,
|
|
5549
|
-
editability: editability
|
|
5550
|
-
|
|
6202
|
+
editability: editability,
|
|
6203
|
+
surface: surface
|
|
6204
|
+
}), {save: save} = useSaveField({
|
|
6205
|
+
instanceId: entry.instance._id
|
|
6206
|
+
});
|
|
5551
6207
|
/* @__PURE__ */
|
|
5552
6208
|
return jsx(PillPopover, {
|
|
5553
6209
|
content: /* @__PURE__ */ jsx(DatePicker, {
|
|
5554
6210
|
onSelect: next => {
|
|
5555
|
-
kind
|
|
6211
|
+
hasTimeOfDay(kind) || setOpen(!1), save(() => set(serializeDateFieldValue(next, kind)));
|
|
5556
6212
|
},
|
|
5557
|
-
selectTime: kind
|
|
6213
|
+
selectTime: hasTimeOfDay(kind),
|
|
5558
6214
|
value: parseDateFieldValue(pill.entry?.value, kind)
|
|
5559
6215
|
}),
|
|
5560
6216
|
onDismiss: () => setOpen(!1),
|
|
@@ -5564,11 +6220,12 @@ function DatePill({entry: entry, pill: pill, editability: editability, kind: kin
|
|
|
5564
6220
|
});
|
|
5565
6221
|
}
|
|
5566
6222
|
|
|
5567
|
-
function BooleanPill({entry: entry, pill: pill, editability: editability}) {
|
|
5568
|
-
const {set: set} =
|
|
6223
|
+
function BooleanPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
6224
|
+
const {set: set, save: save} = usePillWrite({
|
|
5569
6225
|
entry: entry,
|
|
5570
|
-
editability: editability
|
|
5571
|
-
|
|
6226
|
+
editability: editability,
|
|
6227
|
+
surface: surface
|
|
6228
|
+
}), chrome = usePillChrome(), current = pill.entry?._type === "boolean" ? pill.entry.value : null, menuId = useId();
|
|
5572
6229
|
/* @__PURE__ */
|
|
5573
6230
|
return jsx(PillHint, {
|
|
5574
6231
|
pill: pill,
|
|
@@ -5612,12 +6269,14 @@ function BooleanPill({entry: entry, pill: pill, editability: editability}) {
|
|
|
5612
6269
|
});
|
|
5613
6270
|
}
|
|
5614
6271
|
|
|
5615
|
-
function ActorPill({entry: entry, pill: pill, editability: editability}) {
|
|
6272
|
+
function ActorPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
5616
6273
|
const [open, setOpen] = useState(!1), {set: set, unset: unset} = useFieldCommit({
|
|
5617
6274
|
entry: entry,
|
|
5618
|
-
editability: editability
|
|
6275
|
+
editability: editability,
|
|
6276
|
+
surface: surface
|
|
5619
6277
|
}), current = isActorShape(pill.entry?.value) ? pill.entry.value : null, {pick: pick} = useActorPick({
|
|
5620
6278
|
current: current,
|
|
6279
|
+
instanceId: entry.instance._id,
|
|
5621
6280
|
onSave: set,
|
|
5622
6281
|
onUnset: unset
|
|
5623
6282
|
});
|
|
@@ -5637,12 +6296,14 @@ function ActorPill({entry: entry, pill: pill, editability: editability}) {
|
|
|
5637
6296
|
});
|
|
5638
6297
|
}
|
|
5639
6298
|
|
|
5640
|
-
function AssigneePill({entry: entry, pill: pill, editability: editability}) {
|
|
6299
|
+
function AssigneePill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
5641
6300
|
const [open, setOpen] = useState(!1), {set: set, unset: unset} = useFieldCommit({
|
|
5642
6301
|
entry: entry,
|
|
5643
|
-
editability: editability
|
|
6302
|
+
editability: editability,
|
|
6303
|
+
surface: surface
|
|
5644
6304
|
}), current = pill.entry?._type === "assignee" ? pill.entry.value : null, {pick: pick} = useAssigneePick({
|
|
5645
6305
|
current: current,
|
|
6306
|
+
instanceId: entry.instance._id,
|
|
5646
6307
|
onSave: set,
|
|
5647
6308
|
onUnset: unset
|
|
5648
6309
|
});
|
|
@@ -5662,11 +6323,12 @@ function AssigneePill({entry: entry, pill: pill, editability: editability}) {
|
|
|
5662
6323
|
});
|
|
5663
6324
|
}
|
|
5664
6325
|
|
|
5665
|
-
function AssigneesPill({entry: entry, pill: pill, editability: editability}) {
|
|
5666
|
-
const [open, setOpen] = useState(!1), {set: set} =
|
|
6326
|
+
function AssigneesPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
6327
|
+
const [open, setOpen] = useState(!1), {set: set, saving: saving, save: save} = usePillWrite({
|
|
5667
6328
|
entry: entry,
|
|
5668
|
-
editability: editability
|
|
5669
|
-
|
|
6329
|
+
editability: editability,
|
|
6330
|
+
surface: surface
|
|
6331
|
+
}), current = pill.face.kind === "assignees" ? pill.face.assignees : [];
|
|
5670
6332
|
/* @__PURE__ */
|
|
5671
6333
|
return jsx(PillPopover, {
|
|
5672
6334
|
content: /* @__PURE__ */ jsx(AssigneePicker, {
|
|
@@ -5709,46 +6371,53 @@ function TodoPill({entry: entry, pill: pill, scope: scope}) {
|
|
|
5709
6371
|
});
|
|
5710
6372
|
}
|
|
5711
6373
|
|
|
5712
|
-
function ScalarEditorPill({entry: entry, pill: pill, editability: editability}) {
|
|
6374
|
+
function ScalarEditorPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
5713
6375
|
return editability.type === "boolean" ? /* @__PURE__ */ jsx(BooleanPill, {
|
|
5714
6376
|
editability: editability,
|
|
5715
6377
|
entry: entry,
|
|
5716
|
-
pill: pill
|
|
5717
|
-
|
|
6378
|
+
pill: pill,
|
|
6379
|
+
surface: surface
|
|
6380
|
+
}) : isDateFieldKind(editability.type) ? /* @__PURE__ */ jsx(DatePill, {
|
|
5718
6381
|
editability: editability,
|
|
5719
6382
|
entry: entry,
|
|
5720
6383
|
kind: editability.type,
|
|
5721
|
-
pill: pill
|
|
6384
|
+
pill: pill,
|
|
6385
|
+
surface: surface
|
|
5722
6386
|
}) : /* @__PURE__ */ jsx(ScalarPill, {
|
|
5723
6387
|
editability: editability,
|
|
5724
6388
|
entry: entry,
|
|
5725
|
-
pill: pill
|
|
6389
|
+
pill: pill,
|
|
6390
|
+
surface: surface
|
|
5726
6391
|
});
|
|
5727
6392
|
}
|
|
5728
6393
|
|
|
5729
|
-
function EditorPill({entry: entry, pill: pill, editability: editability}) {
|
|
6394
|
+
function EditorPill({entry: entry, pill: pill, editability: editability, surface: surface}) {
|
|
5730
6395
|
return pill.editor === "scalar" ? /* @__PURE__ */ jsx(ScalarEditorPill, {
|
|
5731
6396
|
editability: editability,
|
|
5732
6397
|
entry: entry,
|
|
5733
|
-
pill: pill
|
|
6398
|
+
pill: pill,
|
|
6399
|
+
surface: surface
|
|
5734
6400
|
}) : pill.editor === "actor" ? /* @__PURE__ */ jsx(ActorPill, {
|
|
5735
6401
|
editability: editability,
|
|
5736
6402
|
entry: entry,
|
|
5737
|
-
pill: pill
|
|
6403
|
+
pill: pill,
|
|
6404
|
+
surface: surface
|
|
5738
6405
|
}) : pill.editor === "assignee" ? /* @__PURE__ */ jsx(AssigneePill, {
|
|
5739
6406
|
editability: editability,
|
|
5740
6407
|
entry: entry,
|
|
5741
|
-
pill: pill
|
|
6408
|
+
pill: pill,
|
|
6409
|
+
surface: surface
|
|
5742
6410
|
}) : pill.editor === "assignees" ? /* @__PURE__ */ jsx(AssigneesPill, {
|
|
5743
6411
|
editability: editability,
|
|
5744
6412
|
entry: entry,
|
|
5745
|
-
pill: pill
|
|
6413
|
+
pill: pill,
|
|
6414
|
+
surface: surface
|
|
5746
6415
|
}) : /* @__PURE__ */ jsx(ReadOnlyPill, {
|
|
5747
6416
|
pill: pill
|
|
5748
6417
|
});
|
|
5749
6418
|
}
|
|
5750
6419
|
|
|
5751
|
-
function FieldPill({entry: entry, pill: pill, scope: scope}) {
|
|
6420
|
+
function FieldPill({entry: entry, pill: pill, scope: scope, surface: surface}) {
|
|
5752
6421
|
if (pill.editor === "todoList" && pill.entry !== void 0) /* @__PURE__ */
|
|
5753
6422
|
return jsx(TodoPill, {
|
|
5754
6423
|
entry: entry,
|
|
@@ -5761,7 +6430,8 @@ function FieldPill({entry: entry, pill: pill, scope: scope}) {
|
|
|
5761
6430
|
}) : /* @__PURE__ */ jsx(EditorPill, {
|
|
5762
6431
|
editability: editability,
|
|
5763
6432
|
entry: entry,
|
|
5764
|
-
pill: pill
|
|
6433
|
+
pill: pill,
|
|
6434
|
+
surface: surface
|
|
5765
6435
|
});
|
|
5766
6436
|
}
|
|
5767
6437
|
|
|
@@ -5892,7 +6562,7 @@ function InstanceToolLink({entry: entry}) {
|
|
|
5892
6562
|
}
|
|
5893
6563
|
});
|
|
5894
6564
|
}, [ instanceId ]);
|
|
5895
|
-
return tools
|
|
6565
|
+
return workflowsToolAvailable(tools) ? /* @__PURE__ */ jsx(Flex, {
|
|
5896
6566
|
children: /* @__PURE__ */ jsx(Button, {
|
|
5897
6567
|
as: WorkflowIntentLink,
|
|
5898
6568
|
fontSize: 1,
|
|
@@ -6095,6 +6765,7 @@ function StageGlyph(props) {
|
|
|
6095
6765
|
}
|
|
6096
6766
|
|
|
6097
6767
|
function StageFace({completed: completed = !1, detail: detail, title: title}) {
|
|
6768
|
+
const tone = completed ? "default" : "primary";
|
|
6098
6769
|
/* @__PURE__ */
|
|
6099
6770
|
return jsxs(Flex, {
|
|
6100
6771
|
align: "center",
|
|
@@ -6103,8 +6774,8 @@ function StageFace({completed: completed = !1, detail: detail, title: title}) {
|
|
|
6103
6774
|
children: [
|
|
6104
6775
|
/* @__PURE__ */ jsx(TextWithTone, {
|
|
6105
6776
|
size: 1,
|
|
6106
|
-
tone:
|
|
6107
|
-
children: completed ? /* @__PURE__ */ jsx(
|
|
6777
|
+
tone: tone,
|
|
6778
|
+
children: completed ? /* @__PURE__ */ jsx(CheckmarkCircleFilledIcon, {
|
|
6108
6779
|
style: {
|
|
6109
6780
|
color: "inherit"
|
|
6110
6781
|
}
|
|
@@ -6116,7 +6787,7 @@ function StageFace({completed: completed = !1, detail: detail, title: title}) {
|
|
|
6116
6787
|
}),
|
|
6117
6788
|
/* @__PURE__ */ jsx(TextWithTone, {
|
|
6118
6789
|
size: 1,
|
|
6119
|
-
tone:
|
|
6790
|
+
tone: tone,
|
|
6120
6791
|
weight: "medium",
|
|
6121
6792
|
children: title
|
|
6122
6793
|
}), detail === void 0 ? null : /* @__PURE__ */ jsx(Text, {
|
|
@@ -6134,10 +6805,10 @@ function StageChip({completed: completed = !1, detail: detail, interactive: inte
|
|
|
6134
6805
|
padding: 3,
|
|
6135
6806
|
radius: 4,
|
|
6136
6807
|
style: {
|
|
6137
|
-
boxShadow: `inset 0 0 0 1px ${color.focusRing}`,
|
|
6808
|
+
boxShadow: `inset 0 0 0 1px ${completed ? color.badge.default.fg : color.focusRing}`,
|
|
6138
6809
|
cursor: interactive ? "help" : "default"
|
|
6139
6810
|
},
|
|
6140
|
-
tone: "primary",
|
|
6811
|
+
tone: completed ? "default" : "primary",
|
|
6141
6812
|
...interactive ? {
|
|
6142
6813
|
tabIndex: 0
|
|
6143
6814
|
} : {},
|
|
@@ -6365,7 +7036,8 @@ function WorkflowInstanceSection({defaultOpen: defaultOpen, entry: entry, onOpen
|
|
|
6365
7036
|
children: [
|
|
6366
7037
|
/* @__PURE__ */ jsx(InstanceSnapshotBody, {
|
|
6367
7038
|
entry: entry,
|
|
6368
|
-
onOpenActivity: onOpenActivity
|
|
7039
|
+
onOpenActivity: onOpenActivity,
|
|
7040
|
+
surface: "document-view"
|
|
6369
7041
|
}),
|
|
6370
7042
|
/* @__PURE__ */ jsx(InstanceToolLink, {
|
|
6371
7043
|
entry: entry
|
|
@@ -6374,7 +7046,7 @@ function WorkflowInstanceSection({defaultOpen: defaultOpen, entry: entry, onOpen
|
|
|
6374
7046
|
});
|
|
6375
7047
|
}
|
|
6376
7048
|
|
|
6377
|
-
function InstanceSnapshotBody({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
7049
|
+
function InstanceSnapshotBody({entry: entry, onOpenActivity: onOpenActivity, surface: surface}) {
|
|
6378
7050
|
const definition = useDefinition(entry), {instance: instance} = entry;
|
|
6379
7051
|
/* @__PURE__ */
|
|
6380
7052
|
return jsxs(Stack, {
|
|
@@ -6385,7 +7057,8 @@ function InstanceSnapshotBody({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
|
6385
7057
|
/* @__PURE__ */ jsx(FieldPills, {
|
|
6386
7058
|
definition: definition,
|
|
6387
7059
|
entry: entry,
|
|
6388
|
-
scope: "workflow"
|
|
7060
|
+
scope: "workflow",
|
|
7061
|
+
surface: surface
|
|
6389
7062
|
}),
|
|
6390
7063
|
/* @__PURE__ */ jsxs(Card, {
|
|
6391
7064
|
border: !0,
|
|
@@ -6410,14 +7083,15 @@ function InstanceSnapshotBody({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
|
6410
7083
|
padding: 2,
|
|
6411
7084
|
children: /* @__PURE__ */ jsx(StageSection, {
|
|
6412
7085
|
entry: entry,
|
|
6413
|
-
onOpenActivity: onOpenActivity
|
|
7086
|
+
onOpenActivity: onOpenActivity,
|
|
7087
|
+
surface: surface
|
|
6414
7088
|
})
|
|
6415
7089
|
}) ]
|
|
6416
7090
|
}) ]
|
|
6417
7091
|
});
|
|
6418
7092
|
}
|
|
6419
7093
|
|
|
6420
|
-
function StageSection({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
7094
|
+
function StageSection({entry: entry, onOpenActivity: onOpenActivity, surface: surface}) {
|
|
6421
7095
|
const definition = useDefinition(entry), notice = instanceNotice(entry);
|
|
6422
7096
|
return notice !== null ? notice : /* @__PURE__ */ jsx(StaleLock, {
|
|
6423
7097
|
stale: isEvaluationStale(entry),
|
|
@@ -6427,11 +7101,13 @@ function StageSection({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
|
6427
7101
|
/* @__PURE__ */ jsx(FieldPills, {
|
|
6428
7102
|
definition: definition,
|
|
6429
7103
|
entry: entry,
|
|
6430
|
-
scope: "stage"
|
|
7104
|
+
scope: "stage",
|
|
7105
|
+
surface: surface
|
|
6431
7106
|
}),
|
|
6432
7107
|
/* @__PURE__ */ jsx(ActivitiesList, {
|
|
6433
7108
|
entry: entry,
|
|
6434
|
-
onOpenActivity: onOpenActivity
|
|
7109
|
+
onOpenActivity: onOpenActivity,
|
|
7110
|
+
surface: surface
|
|
6435
7111
|
}) ]
|
|
6436
7112
|
})
|
|
6437
7113
|
});
|
|
@@ -6440,8 +7116,9 @@ function StageSection({entry: entry, onOpenActivity: onOpenActivity}) {
|
|
|
6440
7116
|
function CautionNote({action: action, label: label}) {
|
|
6441
7117
|
/* @__PURE__ */
|
|
6442
7118
|
return jsxs(Card, {
|
|
6443
|
-
padding: 2,
|
|
6444
7119
|
paddingLeft: 3,
|
|
7120
|
+
paddingRight: 2,
|
|
7121
|
+
paddingY: 3,
|
|
6445
7122
|
radius: 3,
|
|
6446
7123
|
style: {
|
|
6447
7124
|
alignItems: "center",
|
|
@@ -6469,18 +7146,20 @@ function CautionNote({action: action, label: label}) {
|
|
|
6469
7146
|
}
|
|
6470
7147
|
|
|
6471
7148
|
function CopyDetailsButton({unreadable: unreadable}) {
|
|
6472
|
-
const toast =
|
|
7149
|
+
const toast = useWorkflowToast();
|
|
6473
7150
|
/* @__PURE__ */
|
|
6474
7151
|
return jsx(Button, {
|
|
6475
7152
|
fontSize: 1,
|
|
6476
7153
|
mode: "ghost",
|
|
6477
7154
|
onClick: () => {
|
|
6478
7155
|
navigator.clipboard.writeText(unreadableDocsReport(unreadable)).then(() => toast.push({
|
|
6479
|
-
|
|
6480
|
-
|
|
7156
|
+
id: TOAST_ID.detailsCopy,
|
|
7157
|
+
status: "info",
|
|
7158
|
+
title: "Details copied to clipboard"
|
|
6481
7159
|
}), () => toast.push({
|
|
7160
|
+
id: TOAST_ID.detailsCopy,
|
|
6482
7161
|
status: "error",
|
|
6483
|
-
title: "
|
|
7162
|
+
title: "Failed to copy the details"
|
|
6484
7163
|
}));
|
|
6485
7164
|
},
|
|
6486
7165
|
padding: 2,
|
|
@@ -6506,7 +7185,7 @@ const HEADLINES = {
|
|
|
6506
7185
|
};
|
|
6507
7186
|
|
|
6508
7187
|
function remediation(invalid) {
|
|
6509
|
-
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
|
|
7188
|
+
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.`;
|
|
6510
7189
|
}
|
|
6511
7190
|
|
|
6512
7191
|
function InvalidDocNotice({invalid: invalid}) {
|
|
@@ -6557,18 +7236,6 @@ function TabSwitch({ariaControls: ariaControls, idPrefix: idPrefix, options: opt
|
|
|
6557
7236
|
});
|
|
6558
7237
|
}
|
|
6559
7238
|
|
|
6560
|
-
function useDelayedFlag(active, delayMs) {
|
|
6561
|
-
const [held, setHeld] = useState(!1);
|
|
6562
|
-
return useEffect(() => {
|
|
6563
|
-
if (!active) {
|
|
6564
|
-
setHeld(!1);
|
|
6565
|
-
return;
|
|
6566
|
-
}
|
|
6567
|
-
const timer = setTimeout(() => setHeld(!0), delayMs);
|
|
6568
|
-
return () => clearTimeout(timer);
|
|
6569
|
-
}, [ active, delayMs ]), held && active;
|
|
6570
|
-
}
|
|
6571
|
-
|
|
6572
7239
|
function openActivityGone(args) {
|
|
6573
7240
|
const {entry: entry, target: target} = args;
|
|
6574
7241
|
if (entry === void 0 || entry.instance.currentStage !== target.stage) return !0;
|
|
@@ -6633,18 +7300,16 @@ function coveredFieldNames(ctx) {
|
|
|
6633
7300
|
return release && names.add(release.name), names;
|
|
6634
7301
|
}
|
|
6635
7302
|
|
|
6636
|
-
const OPTIONAL_INIT_KINDS = /* @__PURE__ */ new Set([ "array", "assignees", "doc.refs" ]);
|
|
6637
|
-
|
|
6638
7303
|
function inputInitFields(args) {
|
|
6639
7304
|
return (args.definition?.fields ?? []).filter(entry => entry.initialValue?.type === "input" && !args.covered.has(entry.name));
|
|
6640
7305
|
}
|
|
6641
7306
|
|
|
6642
|
-
function
|
|
6643
|
-
return
|
|
7307
|
+
function isRequiredEntry(entry) {
|
|
7308
|
+
return entry.required === !0;
|
|
6644
7309
|
}
|
|
6645
7310
|
|
|
6646
7311
|
function missingInitFields(initFields, values) {
|
|
6647
|
-
return initFields.filter(entry =>
|
|
7312
|
+
return initFields.filter(entry => isRequiredEntry(entry) && !isFieldFilled(entry, values[entry.name] ?? null));
|
|
6648
7313
|
}
|
|
6649
7314
|
|
|
6650
7315
|
function numericFilled(value) {
|
|
@@ -6701,7 +7366,9 @@ const asInitial = candidate => candidate, scalarInitialValue = (entry, value) =>
|
|
|
6701
7366
|
value: value === !0
|
|
6702
7367
|
}),
|
|
6703
7368
|
date: scalarInitialValue,
|
|
7369
|
+
dueDate: scalarInitialValue,
|
|
6704
7370
|
datetime: scalarInitialValue,
|
|
7371
|
+
dueDatetime: scalarInitialValue,
|
|
6705
7372
|
"doc.ref": singleRefInitialValue,
|
|
6706
7373
|
"doc.refs": (entry, value) => asInitial({
|
|
6707
7374
|
type: entry.type,
|
|
@@ -6852,15 +7519,36 @@ function classifyStartError(err) {
|
|
|
6852
7519
|
};
|
|
6853
7520
|
}
|
|
6854
7521
|
|
|
7522
|
+
function startOutcomeToast(outcome, label) {
|
|
7523
|
+
return outcome.kind === "started-not-settled" ? {
|
|
7524
|
+
id: TOAST_ID.start,
|
|
7525
|
+
status: "warning",
|
|
7526
|
+
title: `“${label}” started but didn’t finish`,
|
|
7527
|
+
description: outcome.description
|
|
7528
|
+
} : outcome.kind === "not-allowed" ? {
|
|
7529
|
+
id: TOAST_ID.start,
|
|
7530
|
+
status: "warning",
|
|
7531
|
+
title: `“${label}” can’t be started right now`,
|
|
7532
|
+
description: outcome.description
|
|
7533
|
+
} : {
|
|
7534
|
+
id: TOAST_ID.start,
|
|
7535
|
+
status: "error",
|
|
7536
|
+
title: `Failed to start “${label}”`,
|
|
7537
|
+
description: outcome.description
|
|
7538
|
+
};
|
|
7539
|
+
}
|
|
7540
|
+
|
|
6855
7541
|
function boundReleaseId(mapping, selectedReleaseId) {
|
|
6856
7542
|
return mapping?.perspectiveField !== void 0 && selectedReleaseId !== void 0 ? selectedReleaseId : void 0;
|
|
6857
7543
|
}
|
|
6858
7544
|
|
|
7545
|
+
const MAPPING_BROKEN_HINT = docTypeLabel => `Unavailable — this workflow isn’t set up correctly for ${docTypeLabel} documents`;
|
|
7546
|
+
|
|
6859
7547
|
function startGate(args) {
|
|
6860
7548
|
const {mapping: mapping, mappingIssue: mappingIssue, selectedReleaseId: selectedReleaseId, releaseActive: releaseActive} = args;
|
|
6861
7549
|
if (mappingIssue !== void 0) return {
|
|
6862
7550
|
blocked: !0,
|
|
6863
|
-
tooltip:
|
|
7551
|
+
tooltip: MAPPING_BROKEN_HINT(args.docTypeLabel)
|
|
6864
7552
|
};
|
|
6865
7553
|
if (mapping.perspectiveField?.required === !0 && selectedReleaseId === void 0) return {
|
|
6866
7554
|
blocked: !0,
|
|
@@ -6872,7 +7560,7 @@ function startGate(args) {
|
|
|
6872
7560
|
};
|
|
6873
7561
|
if (args.startFilterFailed === !0) return {
|
|
6874
7562
|
blocked: !0,
|
|
6875
|
-
tooltip: `${mapping.label} can
|
|
7563
|
+
tooltip: `${mapping.label} can’t start for this document right now — the workflow’s start condition isn’t met`
|
|
6876
7564
|
};
|
|
6877
7565
|
if (args.unmetRequirement !== void 0) {
|
|
6878
7566
|
const requirement = args.unmetRequirement;
|
|
@@ -7134,7 +7822,7 @@ function showRowOnError(key, mapping) {
|
|
|
7134
7822
|
}
|
|
7135
7823
|
|
|
7136
7824
|
function useStartWorkflow(args) {
|
|
7137
|
-
const {mapping: mapping, docId: docId, initialValue: initialValue, source: source} = args, toast =
|
|
7825
|
+
const {mapping: mapping, docId: docId, initialValue: initialValue, source: source} = args, toast = useWorkflowToast(), schema = useSchema(), {engine: engine, openStartDialog: openStartDialog, mappingIssues: mappingIssues2, mappingStarts: mappingStarts} = useWorkflowContext(), observer = useStudioObserver({
|
|
7138
7826
|
engine: engine
|
|
7139
7827
|
}), [starting, setStarting] = useState(!1), {selectedReleaseId: selectedReleaseId} = usePerspective(), releaseActive = useIsReleaseActive(), startBlock = mappingStarts.get(mappingKey(mapping)), hidden = startKindOf({
|
|
7140
7828
|
start: startBlock
|
|
@@ -7154,6 +7842,7 @@ function useStartWorkflow(args) {
|
|
|
7154
7842
|
}), {blocked: blocked, tooltip: tooltip} = startGate({
|
|
7155
7843
|
mapping: mapping,
|
|
7156
7844
|
mappingIssue: mappingIssues2.get(mappingKey(mapping)),
|
|
7845
|
+
docTypeLabel: schema.get(mapping.docType)?.title ?? mapping.docType,
|
|
7157
7846
|
selectedReleaseId: selectedReleaseId,
|
|
7158
7847
|
releaseActive: releaseActive,
|
|
7159
7848
|
startFilterFailed: filterFailed,
|
|
@@ -7177,8 +7866,9 @@ function useStartWorkflow(args) {
|
|
|
7177
7866
|
selectedReleaseId: selectedReleaseId,
|
|
7178
7867
|
ensureDocumentExists: observer.ensureDocumentExists,
|
|
7179
7868
|
onPersistFailure: err => toast.push({
|
|
7869
|
+
id: TOAST_ID.documentSave,
|
|
7180
7870
|
status: "error",
|
|
7181
|
-
title: "
|
|
7871
|
+
title: "Failed to save the document",
|
|
7182
7872
|
description: describeError(err)
|
|
7183
7873
|
}),
|
|
7184
7874
|
openStartDialog: request => openStartDialog({
|
|
@@ -7319,7 +8009,8 @@ function ForMeList({entry: entry, work: work, identity: identity, onOpenActivity
|
|
|
7319
8009
|
}),
|
|
7320
8010
|
breadcrumb: breadcrumb,
|
|
7321
8011
|
instanceId: instance._id,
|
|
7322
|
-
onOpen: () => onOpenActivity(activityEval.activity.name)
|
|
8012
|
+
onOpen: () => onOpenActivity(activityEval.activity.name),
|
|
8013
|
+
surface: "document-view"
|
|
7323
8014
|
}, activityEval.activity.name)), itemCount > 0 ? /* @__PURE__ */ jsx(TodoItemsList, {
|
|
7324
8015
|
breadcrumb: breadcrumb,
|
|
7325
8016
|
entry: entry,
|
|
@@ -7495,7 +8186,7 @@ function WorkflowsPanel({entries: entries, documentId: documentId, docTypeMappin
|
|
|
7495
8186
|
children: /* @__PURE__ */ jsx(Flex, {
|
|
7496
8187
|
direction: "column",
|
|
7497
8188
|
flex: 1,
|
|
7498
|
-
children: view === "overview" ? /* @__PURE__ */ jsx(
|
|
8189
|
+
children: view === "overview" ? /* @__PURE__ */ jsx(OverviewSections, {
|
|
7499
8190
|
active: active,
|
|
7500
8191
|
empty: /* @__PURE__ */ jsx(OverviewEmptyState, {
|
|
7501
8192
|
docId: documentId,
|
|
@@ -7519,7 +8210,7 @@ function WorkflowsPanel({entries: entries, documentId: documentId, docTypeMappin
|
|
|
7519
8210
|
});
|
|
7520
8211
|
}
|
|
7521
8212
|
|
|
7522
|
-
function
|
|
8213
|
+
function OverviewSections({active: active, empty: empty, finished: finished, sectionFor: sectionFor}) {
|
|
7523
8214
|
/* @__PURE__ */
|
|
7524
8215
|
return jsxs(Stack, {
|
|
7525
8216
|
gap: 5,
|
|
@@ -7667,6 +8358,23 @@ function workflowIssue(args) {
|
|
|
7667
8358
|
if (!isInputSourced(subject)) return `autoStart: "${docType}" → workflow "${name}" has a self-filling subject (not caller-provided), so the document can't be its subject — skipped.`;
|
|
7668
8359
|
}
|
|
7669
8360
|
|
|
8361
|
+
function createSubscribers() {
|
|
8362
|
+
const listeners = /* @__PURE__ */ new Set;
|
|
8363
|
+
return {
|
|
8364
|
+
subscribe(listener) {
|
|
8365
|
+
return listeners.add(listener), () => {
|
|
8366
|
+
listeners.delete(listener);
|
|
8367
|
+
};
|
|
8368
|
+
},
|
|
8369
|
+
notify() {
|
|
8370
|
+
for (const listener of [ ...listeners ]) listener();
|
|
8371
|
+
},
|
|
8372
|
+
clear() {
|
|
8373
|
+
listeners.clear();
|
|
8374
|
+
}
|
|
8375
|
+
};
|
|
8376
|
+
}
|
|
8377
|
+
|
|
7670
8378
|
function actualType$(previews, bareId) {
|
|
7671
8379
|
return previews.unstable_observeDocumentPairAvailability(bareId).pipe(switchMap(({draft: draft, published: published}) => draft.available ? previews.observeDocumentTypeFromId(getDraftId(bareId)) : published.available ? previews.observeDocumentTypeFromId(bareId) : draft.reason === "PERMISSION_DENIED" || published.reason === "PERMISSION_DENIED" ? of(void 0) : previews.unstable_observeVersionDocumentIds(bareId).pipe(switchMap(([firstVersionId]) => firstVersionId === void 0 ? of(null) : previews.observeDocumentTypeFromId(firstVersionId)))), distinctUntilChanged());
|
|
7672
8380
|
}
|
|
@@ -7674,12 +8382,10 @@ function actualType$(previews, bareId) {
|
|
|
7674
8382
|
const REBUILD_DELAY_MS = 5e3;
|
|
7675
8383
|
|
|
7676
8384
|
function createActualTypeProbeStore(previews) {
|
|
7677
|
-
const verdicts = /* @__PURE__ */ new Map, live = /* @__PURE__ */ new Map,
|
|
7678
|
-
for (const listener of [ ...listeners ]) listener();
|
|
7679
|
-
}, start = (bareId, entry) => actualType$(previews, bareId).subscribe({
|
|
8385
|
+
const verdicts = /* @__PURE__ */ new Map, live = /* @__PURE__ */ new Map, subscribers = createSubscribers(), start = (bareId, entry) => actualType$(previews, bareId).subscribe({
|
|
7680
8386
|
next: value => {
|
|
7681
8387
|
verdicts.has(bareId) && verdicts.get(bareId) === value || (verdicts.set(bareId, value),
|
|
7682
|
-
notify());
|
|
8388
|
+
subscribers.notify());
|
|
7683
8389
|
},
|
|
7684
8390
|
error: err => {
|
|
7685
8391
|
console.error(`[workflow-studio-plugin] actual-type probe for "${bareId}" failed:`, err),
|
|
@@ -7689,12 +8395,14 @@ function createActualTypeProbeStore(previews) {
|
|
|
7689
8395
|
}
|
|
7690
8396
|
});
|
|
7691
8397
|
return {
|
|
7692
|
-
subscribe
|
|
7693
|
-
return listeners.add(listener), () => {
|
|
7694
|
-
listeners.delete(listener);
|
|
7695
|
-
};
|
|
7696
|
-
},
|
|
8398
|
+
subscribe: subscribers.subscribe,
|
|
7697
8399
|
read: bareId => verdicts.get(bareId),
|
|
8400
|
+
seed(types) {
|
|
8401
|
+
let changed = !1;
|
|
8402
|
+
for (const [bareId, actualType] of types) verdicts.has(bareId) || (verdicts.set(bareId, actualType),
|
|
8403
|
+
changed = !0);
|
|
8404
|
+
changed && subscribers.notify();
|
|
8405
|
+
},
|
|
7698
8406
|
track(bareId) {
|
|
7699
8407
|
let entry = live.get(bareId);
|
|
7700
8408
|
if (entry === void 0) {
|
|
@@ -7715,10 +8423,6 @@ function createActualTypeProbeStore(previews) {
|
|
|
7715
8423
|
};
|
|
7716
8424
|
}
|
|
7717
8425
|
|
|
7718
|
-
function contentDocumentTypes(schema) {
|
|
7719
|
-
return schema.getTypeNames().filter(name => schema.get(name)?.type?.name === "document" && !WORKFLOW_SYSTEM_TYPES.includes(name));
|
|
7720
|
-
}
|
|
7721
|
-
|
|
7722
8426
|
async function readDeployedDefinitions(engine) {
|
|
7723
8427
|
return (await engine.query({
|
|
7724
8428
|
groq: latestDefinitionsGroq()
|
|
@@ -7893,7 +8597,7 @@ const REPORT_FLUSH_MS = 50, EMPTY_COMMITTED = {
|
|
|
7893
8597
|
|
|
7894
8598
|
function createEntriesStore() {
|
|
7895
8599
|
let committed = EMPTY_COMMITTED, reports = /* @__PURE__ */ new Map, byInstance = /* @__PURE__ */ new Map, byDocument = /* @__PURE__ */ new Map;
|
|
7896
|
-
const
|
|
8600
|
+
const subscribers = createSubscribers();
|
|
7897
8601
|
let flushTimer;
|
|
7898
8602
|
const recompute = () => {
|
|
7899
8603
|
flushTimer !== void 0 && (clearTimeout(flushTimer), flushTimer = void 0);
|
|
@@ -7906,10 +8610,8 @@ function createEntriesStore() {
|
|
|
7906
8610
|
byInstance: nextByInstance,
|
|
7907
8611
|
previous: byDocument
|
|
7908
8612
|
});
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
for (const listener of [ ...listeners ]) listener();
|
|
7912
|
-
}
|
|
8613
|
+
nextByInstance === byInstance && nextByDocument === byDocument || (byInstance = nextByInstance,
|
|
8614
|
+
byDocument = nextByDocument, subscribers.notify());
|
|
7913
8615
|
};
|
|
7914
8616
|
return {
|
|
7915
8617
|
setCommitted(inputs) {
|
|
@@ -7925,13 +8627,9 @@ function createEntriesStore() {
|
|
|
7925
8627
|
getReport: instanceId => reports.get(instanceId),
|
|
7926
8628
|
getInstance: instanceId => byInstance.get(instanceId),
|
|
7927
8629
|
getDocument: docId => byDocument.get(docId) ?? EMPTY_ENTRIES,
|
|
7928
|
-
subscribe
|
|
7929
|
-
return listeners.add(listener), () => {
|
|
7930
|
-
listeners.delete(listener);
|
|
7931
|
-
};
|
|
7932
|
-
},
|
|
8630
|
+
subscribe: subscribers.subscribe,
|
|
7933
8631
|
dispose() {
|
|
7934
|
-
flushTimer !== void 0 && clearTimeout(flushTimer), flushTimer = void 0,
|
|
8632
|
+
flushTimer !== void 0 && clearTimeout(flushTimer), flushTimer = void 0, subscribers.clear();
|
|
7935
8633
|
}
|
|
7936
8634
|
};
|
|
7937
8635
|
}
|
|
@@ -8061,7 +8759,7 @@ function WorkflowProvider(props) {
|
|
|
8061
8759
|
try {
|
|
8062
8760
|
await (drainRef.current?.(instanceId));
|
|
8063
8761
|
} catch (err) {
|
|
8064
|
-
throw new
|
|
8762
|
+
throw new EffectsIncompleteError(describeError(err), {
|
|
8065
8763
|
cause: err
|
|
8066
8764
|
});
|
|
8067
8765
|
}
|
|
@@ -8192,12 +8890,19 @@ function WorkflowProvider(props) {
|
|
|
8192
8890
|
});
|
|
8193
8891
|
}
|
|
8194
8892
|
|
|
8195
|
-
function
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8893
|
+
function entriesSameBy(equal) {
|
|
8894
|
+
return (a, b) => {
|
|
8895
|
+
if (a.size !== b.size) return !1;
|
|
8896
|
+
for (const [key, value] of b) {
|
|
8897
|
+
const previous = a.get(key);
|
|
8898
|
+
if (previous === void 0 || !equal(previous, value)) return !1;
|
|
8899
|
+
}
|
|
8900
|
+
return !0;
|
|
8901
|
+
};
|
|
8199
8902
|
}
|
|
8200
8903
|
|
|
8904
|
+
const sameIssues = entriesSameBy(sameMappingIssue), sameVersions = entriesSameBy(Object.is);
|
|
8905
|
+
|
|
8201
8906
|
function sameMappings(a, b) {
|
|
8202
8907
|
return a.length === b.length && a.every((mapping, index) => {
|
|
8203
8908
|
const other = b[index];
|
|
@@ -8221,10 +8926,7 @@ function useDeployedDefinitions(args) {
|
|
|
8221
8926
|
contentResource: contentResource,
|
|
8222
8927
|
schemaContentTypes: schemaContentTypes
|
|
8223
8928
|
});
|
|
8224
|
-
|
|
8225
|
-
const signature = `${rowKey}|${message}`;
|
|
8226
|
-
logged.current.has(signature) || (logged.current.add(signature), console.error(`[workflow-studio-plugin] ${message}`));
|
|
8227
|
-
}
|
|
8929
|
+
logOnce(mappingIssueLogLines(found), logged.current);
|
|
8228
8930
|
const resolvedAutoStart = resolveAutoStart({
|
|
8229
8931
|
autoStart: mappingAutoStartMap(effectiveMappings),
|
|
8230
8932
|
knownDocTypes: new Set(schema.getTypeNames()),
|
|
@@ -8232,7 +8934,7 @@ function useDeployedDefinitions(args) {
|
|
|
8232
8934
|
});
|
|
8233
8935
|
if (logOnce(resolvedAutoStart.warnings, logged.current), cancelled) return;
|
|
8234
8936
|
setMappings(prev => sameMappings(prev, effectiveMappings) ? prev : effectiveMappings),
|
|
8235
|
-
setIssues(prev =>
|
|
8937
|
+
setIssues(prev => sameIssues(prev, found) ? prev : found), setStarts(mappingStartBlocks({
|
|
8236
8938
|
mappings: effectiveMappings,
|
|
8237
8939
|
definitions: definitions
|
|
8238
8940
|
})), setFields(mappingDeclaredFields({
|
|
@@ -8240,7 +8942,7 @@ function useDeployedDefinitions(args) {
|
|
|
8240
8942
|
definitions: definitions
|
|
8241
8943
|
}));
|
|
8242
8944
|
const versions = new Map(latestDeployedDefinitions(definitions).map(d => [ d.name, d.version ]));
|
|
8243
|
-
setLatestVersions(prev =>
|
|
8945
|
+
setLatestVersions(prev => sameVersions(prev, versions) ? prev : versions), setAutoStartByType(resolvedAutoStart.byType),
|
|
8244
8946
|
setAutoStartDefinitions(resolvedAutoStart.definitions);
|
|
8245
8947
|
})().catch(err => {
|
|
8246
8948
|
console.error("[workflow-studio-plugin] mapping discovery failed — keeping the last resolved workflow state:", err);
|
|
@@ -8384,16 +9086,8 @@ function ChecklistInput({value: value, onChange: onChange}) {
|
|
|
8384
9086
|
value: it.label
|
|
8385
9087
|
})
|
|
8386
9088
|
}),
|
|
8387
|
-
/* @__PURE__ */ jsx(
|
|
8388
|
-
|
|
8389
|
-
children: /* @__PURE__ */ jsx(Button, {
|
|
8390
|
-
"aria-label": "Remove item",
|
|
8391
|
-
fontSize: 1,
|
|
8392
|
-
icon: CloseIcon,
|
|
8393
|
-
mode: "bleed",
|
|
8394
|
-
onClick: () => remove(i),
|
|
8395
|
-
padding: 2
|
|
8396
|
-
})
|
|
9089
|
+
/* @__PURE__ */ jsx(RemoveItemButton, {
|
|
9090
|
+
onClick: () => remove(i)
|
|
8397
9091
|
}) ]
|
|
8398
9092
|
}, it._key)),
|
|
8399
9093
|
/* @__PURE__ */ jsx(Flex, {
|
|
@@ -8497,7 +9191,7 @@ function useLatestDefinition(definitionName) {
|
|
|
8497
9191
|
function useCreateDoc(args) {
|
|
8498
9192
|
const {releaseId: releaseId, onCreated: onCreated} = args, {engine: engine, binding: binding} = useWorkflowContext(), observer = useStudioObserver({
|
|
8499
9193
|
engine: engine
|
|
8500
|
-
}), schema = useSchema(), templates = useTemplates(), resolverContext = useInitialValueResolverContext(), toast =
|
|
9194
|
+
}), schema = useSchema(), templates = useTemplates(), resolverContext = useInitialValueResolverContext(), toast = useWorkflowToast(), [creating, setCreating] = useState(!1);
|
|
8501
9195
|
return {
|
|
8502
9196
|
creating: creating,
|
|
8503
9197
|
createDoc: async type => {
|
|
@@ -8522,8 +9216,9 @@ function useCreateDoc(args) {
|
|
|
8522
9216
|
}));
|
|
8523
9217
|
} catch (err) {
|
|
8524
9218
|
toast.push({
|
|
9219
|
+
id: TOAST_ID.documentCreate,
|
|
8525
9220
|
status: "error",
|
|
8526
|
-
title: "
|
|
9221
|
+
title: "Failed to create the document",
|
|
8527
9222
|
description: describeError(err)
|
|
8528
9223
|
});
|
|
8529
9224
|
} finally {
|
|
@@ -8735,7 +9430,7 @@ function InitFieldRow({entry: entry, docType: docType, releaseId: releaseId, val
|
|
|
8735
9430
|
/* @__PURE__ */ jsx(Text, {
|
|
8736
9431
|
size: 1,
|
|
8737
9432
|
weight: "medium",
|
|
8738
|
-
children:
|
|
9433
|
+
children: isRequiredEntry(entry) ? `${label} (Required)` : label
|
|
8739
9434
|
}), entry.description ? /* @__PURE__ */ jsx(Text, {
|
|
8740
9435
|
muted: !0,
|
|
8741
9436
|
size: 1,
|
|
@@ -8840,31 +9535,12 @@ function ResumeNote({onStartNew: onStartNew}) {
|
|
|
8840
9535
|
|
|
8841
9536
|
function handleStartError(args) {
|
|
8842
9537
|
const {label: label, toast: toast, seedInstance: seedInstance, onClose: onClose} = args, outcome = classifyStartError(args.err);
|
|
8843
|
-
|
|
8844
|
-
|
|
8845
|
-
status: "warning",
|
|
8846
|
-
title: `${label} started, but didn’t finish auto-advancing`,
|
|
8847
|
-
description: outcome.description
|
|
8848
|
-
}), outcome.instance !== void 0 && seedInstance(outcome.instance), onClose();
|
|
8849
|
-
return;
|
|
8850
|
-
}
|
|
8851
|
-
if (outcome.kind === "not-allowed") {
|
|
8852
|
-
toast.push({
|
|
8853
|
-
status: "warning",
|
|
8854
|
-
title: `${label} can't be started right now`,
|
|
8855
|
-
description: outcome.description
|
|
8856
|
-
});
|
|
8857
|
-
return;
|
|
8858
|
-
}
|
|
8859
|
-
toast.push({
|
|
8860
|
-
status: "error",
|
|
8861
|
-
title: `Failed to start ${label}`,
|
|
8862
|
-
description: outcome.description
|
|
8863
|
-
});
|
|
9538
|
+
toast.push(startOutcomeToast(outcome, label)), outcome.kind === "started-not-settled" && (outcome.instance !== void 0 && seedInstance(outcome.instance),
|
|
9539
|
+
onClose());
|
|
8864
9540
|
}
|
|
8865
9541
|
|
|
8866
9542
|
function StartWorkflowForm({request: request, onClose: onClose}) {
|
|
8867
|
-
const {definition: definitionName, label: label, mapping: mapping, subjectDocId: subjectDocId} = request, {engine: engine, binding: binding, seedInstance: seedInstance} = useWorkflowContext(), telemetry = useWorkflowTelemetry(), toast =
|
|
9543
|
+
const {definition: definitionName, label: label, mapping: mapping, subjectDocId: subjectDocId} = request, {engine: engine, binding: binding, seedInstance: seedInstance} = useWorkflowContext(), telemetry = useWorkflowTelemetry(), toast = useWorkflowToast(), {def: definition, error: definitionError} = useLatestDefinition(definitionName), {selectedReleaseId: selectedReleaseId} = usePerspective(), releaseId = boundReleaseId(mapping, selectedReleaseId), [values, setValues] = useState({}), [attempt, setAttempt] = useState(void 0), starting = attempt !== void 0, [heldInstanceId, setHeldInstanceId] = useState(void 0), [startNew, setStartNew] = useState(!1), {entries: entries} = useWorkflowsForDocument(subjectDocId), resumeEntry = presentedResumeEntry({
|
|
8868
9544
|
entries: entries,
|
|
8869
9545
|
definitionName: definitionName,
|
|
8870
9546
|
heldInstanceId: heldInstanceId,
|
|
@@ -8904,8 +9580,9 @@ function StartWorkflowForm({request: request, onClose: onClose}) {
|
|
|
8904
9580
|
values: values
|
|
8905
9581
|
}));
|
|
8906
9582
|
toast.push({
|
|
8907
|
-
|
|
8908
|
-
|
|
9583
|
+
id: TOAST_ID.start,
|
|
9584
|
+
status: "info",
|
|
9585
|
+
title: `“${definition?.title ?? label}” started`,
|
|
8909
9586
|
description: `Stage: ${stageTitle(definition ?? void 0, result.instance.currentStage)}`
|
|
8910
9587
|
}), seedInstance(result.instance), onClose();
|
|
8911
9588
|
} catch (err) {
|
|
@@ -9407,6 +10084,22 @@ function finishedLinesOf(entries) {
|
|
|
9407
10084
|
return [ ...latestByType.values() ].sort((a, b) => b.at - a.at).map(({entry: entry}) => entry);
|
|
9408
10085
|
}
|
|
9409
10086
|
|
|
10087
|
+
function openStageTaskCount(evaluation) {
|
|
10088
|
+
if (evaluation !== void 0) return evaluation.currentStage.activities.filter(activity => isOpenActivityStatus(activity.status)).length;
|
|
10089
|
+
}
|
|
10090
|
+
|
|
10091
|
+
const OPEN_VIEW = "Open the Workflows view";
|
|
10092
|
+
|
|
10093
|
+
function unassignedLineHint(args) {
|
|
10094
|
+
return !args.identityKnown || args.openTaskCount === void 0 ? {
|
|
10095
|
+
text: OPEN_VIEW
|
|
10096
|
+
} : args.openTaskCount === 0 ? {
|
|
10097
|
+
text: "No open tasks in this stage"
|
|
10098
|
+
} : {
|
|
10099
|
+
text: `${pluralize("open task", args.openTaskCount, !0)}, none assigned to you`
|
|
10100
|
+
};
|
|
10101
|
+
}
|
|
10102
|
+
|
|
9410
10103
|
function WorkflowFormStrip(props) {
|
|
9411
10104
|
const {mappings: mappings} = props, {isDocResolved: isDocResolved, discoveryInvalid: discoveryInvalid} = useWorkflowContext(), {docId: docId, entries: entries} = useWorkflowsForDocument(props.value?._id ?? null), {params: params, setParams: setParams} = usePaneRouter(), telemetry = useWorkflowTelemetry(), openWorkflowsView = focusId => {
|
|
9412
10105
|
telemetry.log(WorkflowFormStripClicked), setParams(focusedViewParams(params, focusId));
|
|
@@ -9451,18 +10144,17 @@ function StripLines({active: active, docId: docId, finished: finished, initialVa
|
|
|
9451
10144
|
});
|
|
9452
10145
|
}
|
|
9453
10146
|
|
|
9454
|
-
function lineHint(
|
|
10147
|
+
function lineHint(entry, identity) {
|
|
10148
|
+
const forMe = forMeWorkOf([ entry ], identity);
|
|
9455
10149
|
return forMe.work.some(({shown: shown}) => hasOpenAssignedWork(shown)) ? {
|
|
9456
10150
|
content: /* @__PURE__ */ jsx(AssignedTasksHint, {
|
|
9457
10151
|
work: forMe.work
|
|
9458
10152
|
}),
|
|
9459
10153
|
wide: !0
|
|
9460
|
-
} :
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
}
|
|
9464
|
-
text: "Open the Workflows view"
|
|
9465
|
-
};
|
|
10154
|
+
} : unassignedLineHint({
|
|
10155
|
+
identityKnown: identity !== void 0,
|
|
10156
|
+
openTaskCount: openStageTaskCount(entry.evaluation)
|
|
10157
|
+
});
|
|
9466
10158
|
}
|
|
9467
10159
|
|
|
9468
10160
|
function StripLine({aside: aside, children: children, hint: hint, onOpen: onOpen}) {
|
|
@@ -9495,7 +10187,7 @@ function InstanceLine({entry: entry, onOpen: onOpen}) {
|
|
|
9495
10187
|
aside: unprimed ? void 0 : /* @__PURE__ */ jsx(TaskCountSpinner, {
|
|
9496
10188
|
entry: entry
|
|
9497
10189
|
}),
|
|
9498
|
-
hint: lineHint(
|
|
10190
|
+
hint: lineHint(entry, identity),
|
|
9499
10191
|
onOpen: onOpen,
|
|
9500
10192
|
children: [
|
|
9501
10193
|
/* @__PURE__ */ jsx(Flex, {
|
|
@@ -9600,6 +10292,103 @@ function StartWorkflowDialogHost() {
|
|
|
9600
10292
|
}, `${startRequest2.definition}:${startRequest2.subjectDocId ?? ""}`) : null;
|
|
9601
10293
|
}
|
|
9602
10294
|
|
|
10295
|
+
const TOOL_TAB_LABELS = {
|
|
10296
|
+
overview: "Workflows",
|
|
10297
|
+
"all-documents": "All documents",
|
|
10298
|
+
"for-me": "For me"
|
|
10299
|
+
}, TOOL_TAB_VALUES = Object.keys(TOOL_TAB_LABELS), TOOL_TABS = TOOL_TAB_VALUES.map(value => ({
|
|
10300
|
+
value: value,
|
|
10301
|
+
label: TOOL_TAB_LABELS[value]
|
|
10302
|
+
})), LANDING_TAB = "overview", TASKS_TAB = "all-documents", WORKFLOW_PAGE_LABELS = {
|
|
10303
|
+
workflow: "Documents",
|
|
10304
|
+
definition: "Definition"
|
|
10305
|
+
}, 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 => ({
|
|
10306
|
+
value: value,
|
|
10307
|
+
label: WORKFLOW_PAGE_LABELS[value]
|
|
10308
|
+
})), toolRouter = route.create("/", [ route.create("/instance/:instanceId"), route.create(`/${LANDING_TAB}/:workflowName`, [ route.create("/:workflowPage") ]), route.create("/:workflowsTab") ]);
|
|
10309
|
+
|
|
10310
|
+
function toolTabState(tab) {
|
|
10311
|
+
return {
|
|
10312
|
+
workflowsTab: tab
|
|
10313
|
+
};
|
|
10314
|
+
}
|
|
10315
|
+
|
|
10316
|
+
function landingState() {
|
|
10317
|
+
return toolTabState(LANDING_TAB);
|
|
10318
|
+
}
|
|
10319
|
+
|
|
10320
|
+
function workflowState(workflowName) {
|
|
10321
|
+
return {
|
|
10322
|
+
workflowName: workflowName
|
|
10323
|
+
};
|
|
10324
|
+
}
|
|
10325
|
+
|
|
10326
|
+
function instanceState(instanceId) {
|
|
10327
|
+
return {
|
|
10328
|
+
instanceId: instanceId
|
|
10329
|
+
};
|
|
10330
|
+
}
|
|
10331
|
+
|
|
10332
|
+
function tabSelectionNavigates(current, tab) {
|
|
10333
|
+
return !(current.kind === "home" && tab === current.tab);
|
|
10334
|
+
}
|
|
10335
|
+
|
|
10336
|
+
function toolTabLabel(tab) {
|
|
10337
|
+
return TOOL_TAB_LABELS[tab];
|
|
10338
|
+
}
|
|
10339
|
+
|
|
10340
|
+
function backToTabLabel(tab) {
|
|
10341
|
+
return `Back to ${toolTabLabel(tab)}`;
|
|
10342
|
+
}
|
|
10343
|
+
|
|
10344
|
+
function workflowPageState(page, workflowName) {
|
|
10345
|
+
return page === DEFAULT_WORKFLOW_PAGE ? workflowState(workflowName) : {
|
|
10346
|
+
...workflowState(workflowName),
|
|
10347
|
+
workflowPage: page
|
|
10348
|
+
};
|
|
10349
|
+
}
|
|
10350
|
+
|
|
10351
|
+
function toolRoute(state) {
|
|
10352
|
+
const {instanceId: instanceId, workflowName: workflowName} = state;
|
|
10353
|
+
if (typeof instanceId == "string") return {
|
|
10354
|
+
kind: "instance",
|
|
10355
|
+
instanceId: instanceId,
|
|
10356
|
+
tab: TASKS_TAB
|
|
10357
|
+
};
|
|
10358
|
+
if (typeof workflowName == "string") return workflowRoute(workflowName, state.workflowPage);
|
|
10359
|
+
const tab = pathSegmentName({
|
|
10360
|
+
segment: state.workflowsTab,
|
|
10361
|
+
names: TOOL_TAB_VALUES
|
|
10362
|
+
});
|
|
10363
|
+
return tab === void 0 ? {
|
|
10364
|
+
kind: "unnamed",
|
|
10365
|
+
tab: LANDING_TAB
|
|
10366
|
+
} : {
|
|
10367
|
+
kind: "home",
|
|
10368
|
+
tab: tab
|
|
10369
|
+
};
|
|
10370
|
+
}
|
|
10371
|
+
|
|
10372
|
+
function workflowRoute(workflowName, pageSegment) {
|
|
10373
|
+
if (pageSegment === void 0) return {
|
|
10374
|
+
kind: "workflow",
|
|
10375
|
+
workflowName: workflowName,
|
|
10376
|
+
tab: LANDING_TAB
|
|
10377
|
+
};
|
|
10378
|
+
const page = pathSegmentName({
|
|
10379
|
+
segment: pageSegment,
|
|
10380
|
+
names: WORKFLOW_PAGES
|
|
10381
|
+
});
|
|
10382
|
+
return page === void 0 ? {
|
|
10383
|
+
kind: "unnamed",
|
|
10384
|
+
tab: LANDING_TAB
|
|
10385
|
+
} : {
|
|
10386
|
+
kind: page,
|
|
10387
|
+
workflowName: workflowName,
|
|
10388
|
+
tab: LANDING_TAB
|
|
10389
|
+
};
|
|
10390
|
+
}
|
|
10391
|
+
|
|
9603
10392
|
const WorkflowsToolRoot = lazy(() => import("./workflows-tool-root.js"));
|
|
9604
10393
|
|
|
9605
10394
|
function LazyWorkflowsTool() {
|
|
@@ -9615,7 +10404,7 @@ const workflowsTool = {
|
|
|
9615
10404
|
title: "Workflows",
|
|
9616
10405
|
icon: TransferIcon,
|
|
9617
10406
|
component: LazyWorkflowsTool,
|
|
9618
|
-
router:
|
|
10407
|
+
router: toolRouter,
|
|
9619
10408
|
canHandleIntent: (intent, params) => handlesWorkflowIntent(intent, params),
|
|
9620
10409
|
getIntentState: (intent, params) => workflowIntentState(intent, params)
|
|
9621
10410
|
}, LOCKABLE_ACTIONS = /* @__PURE__ */ new Map([ [ "delete", "delete" ], [ "publish", "publish" ], [ "unpublish", "unpublish" ] ]);
|
|
@@ -9709,4 +10498,4 @@ function WorkflowRootInput(props) {
|
|
|
9709
10498
|
});
|
|
9710
10499
|
}
|
|
9711
10500
|
|
|
9712
|
-
export { ActivityDetailDialog, ActivityRow, BreadcrumbTail, CautionNote, CollapsibleBand, DismissablePopover, DocPreviewLink, DocRefFace, ForMeEmptyState, HintedMenuButton, HoverHint, InstanceSnapshotBody, InvalidDocNotice, LinkChip, LoadingRow, MetaRow, SpinnerSlot, StageFace, StaleLock, TabSwitch, TrailingHairline, UnreadableDocsNote, UserAvatar, WORKFLOW_API_VERSION, WorkflowInstanceDetailViewed, WorkflowTaskFiltersApplied, WorkflowToolOpened, activityRowProps, assigneeUserIdsOf, committedRowFace,
|
|
10501
|
+
export { ActivityDetailDialog, ActivityRow, BreadcrumbTail, CautionNote, CollapsibleBand, CountedLabel, DismissablePopover, DocPreviewLink, DocRefFace, EmptyState, ForMeEmptyState, Hairline, HintedMenuButton, HoverHint, InstanceSnapshotBody, InvalidDocNotice, LinkChip, LoadingRow, LogEventOnMount, MetaRow, SpinnerSlot, StageFace, StaleLock, TOAST_ID, TOOL_TABS, TabSwitch, TrailingHairline, UnreadableDocsNote, UserAvatar, WORKFLOW_API_VERSION, WORKFLOW_PAGE_TABS, WorkflowAbortDialogOpened, WorkflowAbortDialogSubmitted, WorkflowBoardWorkflowSelected, WorkflowDefinitionDetailViewed, WorkflowInstanceDetailViewed, WorkflowTaskFiltersApplied, WorkflowTitleSeedDrifted, WorkflowToolOpened, activityRowProps, assigneeUserIdsOf, backToTabLabel, committedRowFace, createSubscribers, datesOf, definitionFingerprint, definitionSnapshotOf, describeError, dueDatesOf, findActivity, findActivityNode, formatDate, formatDateTime, formatShortAgo, formatShortDateTime, formatTimeAgo, gdrLocality, instanceBreadcrumb, instanceState, instanceTitle, isActivityAssignedTo, isEvaluationStale, isLiveEntry, isOpenActivityStatus, landingState, mappingIssueDetail, namesNoDeployedDefinition, openActivityGone, openableSchemaType, parseStoredDateValue, readDeployedDefinitions, rowAssignControlState, rowDateControlState, stageTitle, stateByActivity, tabSelectionNavigates, toolRoute, toolTabState, useAssignmentIdentity, useAvatarSize, useBadgeCapTrim, useContainerToken, useDefinition, useDelayedFlag, useLogEventOnMount, useProjectMembers, useSpaceToken, useUserDisplay, useUserDisplays, useWorkflowContext, useWorkflowInstanceEntry, useWorkflowToast, workflowDefaultDocumentNode, workflowPageState, workflowState, workflowStudioPlugin, workflowsView };
|