@calliopelabs/ui 0.6.1 → 0.11.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/README.md +253 -3
- package/dist/appearance/AppearancePicker.js +6 -4
- package/dist/appearance/AppearanceProvider.d.ts +10 -2
- package/dist/appearance/AppearanceProvider.js +6 -2
- package/dist/appearance/AppearanceScript.d.ts +15 -4
- package/dist/appearance/AppearanceScript.js +11 -5
- package/dist/appearance/appearance.js +1 -1
- package/dist/appearance/boot.d.ts +13 -2
- package/dist/appearance/boot.js +35 -5
- package/dist/appearance/product.d.ts +13 -0
- package/dist/appearance/product.js +2 -2
- package/dist/appearance/runtime-brand.d.ts +106 -0
- package/dist/appearance/runtime-brand.js +420 -0
- package/dist/css/appearance.js +147 -0
- package/dist/css/calliope.css +1221 -0
- package/dist/css/components.css +729 -0
- package/dist/css/tokens.css +491 -0
- package/dist/data/DefinitionList.d.ts +16 -0
- package/dist/data/DefinitionList.js +9 -0
- package/dist/data/Stat.d.ts +25 -0
- package/dist/data/Stat.js +19 -0
- package/dist/data/Tag.d.ts +21 -0
- package/dist/data/Tag.js +18 -0
- package/dist/data/types.d.ts +3 -2
- package/dist/data/use-local-table.d.ts +36 -0
- package/dist/data/use-local-table.js +127 -0
- package/dist/index.d.ts +42 -3
- package/dist/index.js +39 -1
- package/dist/nav/Nav.d.ts +2 -1
- package/dist/nav/Nav.js +34 -15
- package/dist/nav/model.d.ts +21 -0
- package/dist/page/PageHeader.d.ts +5 -3
- package/dist/page/PageHeader.js +5 -4
- package/dist/page/Panel.d.ts +19 -0
- package/dist/page/Panel.js +12 -0
- package/dist/primitives/Avatar.d.ts +37 -0
- package/dist/primitives/Avatar.js +43 -0
- package/dist/primitives/Field.d.ts +33 -0
- package/dist/primitives/Field.js +30 -0
- package/dist/primitives/Segmented.d.ts +30 -0
- package/dist/primitives/Segmented.js +20 -0
- package/dist/primitives/Select.d.ts +40 -0
- package/dist/primitives/Select.js +47 -0
- package/dist/primitives/Switch.d.ts +7 -0
- package/dist/primitives/Switch.js +8 -0
- package/dist/primitives/Textarea.d.ts +3 -0
- package/dist/primitives/Textarea.js +6 -0
- package/dist/provider/messages.d.ts +415 -2
- package/dist/provider/messages.js +633 -0
- package/dist/shell/BrandMark.d.ts +25 -3
- package/dist/shell/BrandMark.js +34 -4
- package/dist/shell/RailPanel.js +2 -2
- package/dist/shell/RailTree.js +2 -2
- package/dist/shell/Sidebar.d.ts +9 -2
- package/dist/shell/Sidebar.js +10 -4
- package/dist/shell/UserMenu.d.ts +3 -1
- package/dist/shell/UserMenu.js +3 -11
- package/dist/shell/rail-boot.d.ts +28 -0
- package/dist/shell/rail-boot.js +45 -0
- package/dist/shell/rail-state.d.ts +6 -1
- package/dist/shell/rail-state.js +18 -2
- package/dist/styles/preset.css +4 -0
- package/dist/styles/theme.css +36 -13
- package/dist/theme/css-layer.d.ts +19 -0
- package/dist/theme/css-layer.js +171 -0
- package/dist/theme/css.d.ts +1 -0
- package/dist/theme/css.js +45 -9
- package/dist/workflow/ArtifactCard.d.ts +47 -0
- package/dist/workflow/ArtifactCard.js +45 -0
- package/dist/workflow/DocumentReview.d.ts +74 -0
- package/dist/workflow/DocumentReview.js +54 -0
- package/dist/workflow/FormReview.d.ts +53 -0
- package/dist/workflow/FormReview.js +83 -0
- package/dist/workflow/GateBadge.d.ts +11 -0
- package/dist/workflow/GateBadge.js +14 -0
- package/dist/workflow/MediaReview.d.ts +63 -0
- package/dist/workflow/MediaReview.js +166 -0
- package/dist/workflow/ReviewPanel.d.ts +41 -0
- package/dist/workflow/ReviewPanel.js +59 -0
- package/dist/workflow/RunTimeline.d.ts +25 -0
- package/dist/workflow/RunTimeline.js +56 -0
- package/dist/workflow/WorkflowCard.d.ts +39 -0
- package/dist/workflow/WorkflowCard.js +56 -0
- package/dist/workflow/WorkflowGallery.d.ts +43 -0
- package/dist/workflow/WorkflowGallery.js +69 -0
- package/dist/workflow/canvas/WorkflowCanvas.d.ts +39 -0
- package/dist/workflow/canvas/WorkflowCanvas.js +648 -0
- package/dist/workflow/definition.d.ts +408 -0
- package/dist/workflow/definition.js +411 -0
- package/dist/workflow/editor/WorkflowDiff.d.ts +17 -0
- package/dist/workflow/editor/WorkflowDiff.js +25 -0
- package/dist/workflow/editor/WorkflowImportPreview.d.ts +19 -0
- package/dist/workflow/editor/WorkflowImportPreview.js +50 -0
- package/dist/workflow/editor/WorkflowInspector.d.ts +40 -0
- package/dist/workflow/editor/WorkflowInspector.js +349 -0
- package/dist/workflow/editor/WorkflowJsonView.d.ts +16 -0
- package/dist/workflow/editor/WorkflowJsonView.js +40 -0
- package/dist/workflow/editor/WorkflowPalette.d.ts +16 -0
- package/dist/workflow/editor/WorkflowPalette.js +36 -0
- package/dist/workflow/editor/WorkflowProblems.d.ts +20 -0
- package/dist/workflow/editor/WorkflowProblems.js +51 -0
- package/dist/workflow/editor/WorkflowWorkspace.d.ts +49 -0
- package/dist/workflow/editor/WorkflowWorkspace.js +154 -0
- package/dist/workflow/gallery.d.ts +21 -0
- package/dist/workflow/gallery.js +29 -0
- package/dist/workflow/layout.d.ts +49 -0
- package/dist/workflow/layout.js +162 -0
- package/dist/workflow/model.d.ts +50 -0
- package/dist/workflow/model.js +7 -0
- package/dist/workflow/palette.d.ts +34 -0
- package/dist/workflow/palette.js +70 -0
- package/dist/workflow/portable.d.ts +162 -0
- package/dist/workflow/portable.js +547 -0
- package/dist/workflow/problems.d.ts +38 -0
- package/dist/workflow/problems.js +409 -0
- package/dist/workflow/run.d.ts +94 -0
- package/dist/workflow/run.js +31 -0
- package/dist/workflow/workspace.d.ts +33 -0
- package/dist/workflow/workspace.js +17 -0
- package/package.json +6 -1
|
@@ -1,5 +1,148 @@
|
|
|
1
1
|
const lower = (label) => label.toLocaleLowerCase("en");
|
|
2
2
|
const count = (n) => n.toLocaleString("en");
|
|
3
|
+
/** "a", "a or b", "a, b or c". */
|
|
4
|
+
const either = (items) => items.length <= 1 ? items.join("") : `${items.slice(0, -1).join(", ")} or ${items.at(-1)}`;
|
|
5
|
+
const KIND_LABEL = {
|
|
6
|
+
step: "Step",
|
|
7
|
+
subflow: "Sub-flow",
|
|
8
|
+
gate: "Gate",
|
|
9
|
+
condition: "Condition",
|
|
10
|
+
goto: "Go to",
|
|
11
|
+
fanout: "Fan out",
|
|
12
|
+
join: "Join",
|
|
13
|
+
variants: "Variants",
|
|
14
|
+
evaluator: "Evaluator",
|
|
15
|
+
classifier: "Classifier",
|
|
16
|
+
check: "Yes or no",
|
|
17
|
+
};
|
|
18
|
+
const KIND_HINT = {
|
|
19
|
+
step: "One unit of work, from a module's preset or your own",
|
|
20
|
+
subflow: "Runs another flow of this workflow in its place",
|
|
21
|
+
gate: "Waits until people, a score, a policy or a time window say go",
|
|
22
|
+
condition: "If or switch on run facts; each case is its own exit",
|
|
23
|
+
goto: "Jumps back to a named node, at most a set number of times",
|
|
24
|
+
fanout: "Starts every branch leaving it",
|
|
25
|
+
join: "Waits for all, any or some of the branches arriving",
|
|
26
|
+
variants: "Runs one step several ways side by side and keeps a winner",
|
|
27
|
+
evaluator: "Scores its subject on a rubric and routes on pass or fail",
|
|
28
|
+
classifier: "Labels its subject and routes on the label",
|
|
29
|
+
check: "Asks a yes or no question and routes on the answer",
|
|
30
|
+
};
|
|
31
|
+
const EXIT_NAME = {
|
|
32
|
+
else: "else",
|
|
33
|
+
yes: "yes",
|
|
34
|
+
no: "no",
|
|
35
|
+
other: "other",
|
|
36
|
+
pass: "pass",
|
|
37
|
+
fail: "fail",
|
|
38
|
+
out: "next",
|
|
39
|
+
};
|
|
40
|
+
const exitName = (exit) => EXIT_NAME[exit] ?? exit;
|
|
41
|
+
function problemText({ code, values: v }) {
|
|
42
|
+
const n = `"${v.node}"`;
|
|
43
|
+
switch (code) {
|
|
44
|
+
case "no-main":
|
|
45
|
+
return `The main flow "${v.flow}" is missing.`;
|
|
46
|
+
case "flow-empty":
|
|
47
|
+
return `${v.flow} has no nodes yet.`;
|
|
48
|
+
case "duplicate-id":
|
|
49
|
+
return `The node id "${v.id}" is used twice.`;
|
|
50
|
+
case "unreachable":
|
|
51
|
+
return `${n} can never be reached.`;
|
|
52
|
+
case "dangling-edge":
|
|
53
|
+
return `A connection from ${v.from} to ${v.to} points at a node that is not here.`;
|
|
54
|
+
case "missing-exit":
|
|
55
|
+
return `"${v.from}" has no ${exitName(String(v.exit))} exit.`;
|
|
56
|
+
case "cycle":
|
|
57
|
+
return `${v.flow} goes round in a circle that never ends. Go back with a loop instead.`;
|
|
58
|
+
case "loop-no-until":
|
|
59
|
+
return `The loop from "${v.from}" back to "${v.to}" has no exit condition.`;
|
|
60
|
+
case "loop-no-max":
|
|
61
|
+
return `The loop from "${v.from}" back to "${v.to}" has no limit.`;
|
|
62
|
+
case "loop-not-back":
|
|
63
|
+
return `The loop from "${v.from}" does not go back to an earlier node.`;
|
|
64
|
+
case "exit-unwired":
|
|
65
|
+
return `The ${exitName(String(v.exit))} exit of ${n} goes nowhere; a run that takes it stops there.`;
|
|
66
|
+
case "input-unbound":
|
|
67
|
+
return `${n} needs ${v.input} (${v.type}), and nothing before it makes one.`;
|
|
68
|
+
case "data-port-missing":
|
|
69
|
+
return `A data connection from "${v.from}" to "${v.to}" names a port that is not there.`;
|
|
70
|
+
case "data-type":
|
|
71
|
+
return `${v.output} of "${v.from}" (${v.given}) does not fit ${v.input} of "${v.to}" (${v.wanted}).`;
|
|
72
|
+
case "data-order":
|
|
73
|
+
return `"${v.to}" takes ${v.output} from "${v.from}", which does not run before it.`;
|
|
74
|
+
case "unknown-preset":
|
|
75
|
+
return `${n} uses ${v.module}/${v.preset}, which this factory's modules do not offer.`;
|
|
76
|
+
case "unknown-model":
|
|
77
|
+
return `${n} names the model "${v.value}", which is not offered here.`;
|
|
78
|
+
case "unknown-harness":
|
|
79
|
+
return `${n} names the harness "${v.value}", which is not offered here.`;
|
|
80
|
+
case "unknown-effort":
|
|
81
|
+
return `${n} names the effort "${v.value}", which is not offered here.`;
|
|
82
|
+
case "subflow-none":
|
|
83
|
+
return `${n} names no flow to run.`;
|
|
84
|
+
case "subflow-missing":
|
|
85
|
+
return `${n} calls the flow "${v.flow}", which does not exist.`;
|
|
86
|
+
case "subflow-recursive":
|
|
87
|
+
return `${n} calls "${v.flow}", which calls back into this flow.`;
|
|
88
|
+
case "unknown-gate-kind":
|
|
89
|
+
return `${n} is a "${v.gate}" gate, which this factory does not know.`;
|
|
90
|
+
case "gate-no-approver":
|
|
91
|
+
return `${n} has no role or member to approve.`;
|
|
92
|
+
case "gate-quorum":
|
|
93
|
+
return `${n} needs ${v.quorum} approvals from ${v.members} named members.`;
|
|
94
|
+
case "gate-no-threshold":
|
|
95
|
+
return `${n} has no threshold.`;
|
|
96
|
+
case "gate-no-rule":
|
|
97
|
+
return `${n} has no rule.`;
|
|
98
|
+
case "gate-no-timeout-action":
|
|
99
|
+
return `${n} times out but does not say what happens then.`;
|
|
100
|
+
case "no-cases":
|
|
101
|
+
return `${n} has no cases.`;
|
|
102
|
+
case "unknown-fact":
|
|
103
|
+
return `${n} tests "${v.fact}", which this factory's runs do not report.`;
|
|
104
|
+
case "unknown-operator":
|
|
105
|
+
return `${n} compares with "${v.op}", which this factory does not know.`;
|
|
106
|
+
case "operator-mismatch":
|
|
107
|
+
return `${n} uses "${v.op}", which does not fit ${v.fact}.`;
|
|
108
|
+
case "value-missing":
|
|
109
|
+
return `${n} compares ${v.fact} with nothing.`;
|
|
110
|
+
case "value-type":
|
|
111
|
+
return `${n} compares ${v.fact} with a value of the wrong kind.`;
|
|
112
|
+
case "fact-node-missing":
|
|
113
|
+
return `${n} tests ${v.fact} but names no node it can come from.`;
|
|
114
|
+
case "goto-no-target":
|
|
115
|
+
return `${n} has no target.`;
|
|
116
|
+
case "goto-missing-target":
|
|
117
|
+
return `${n} jumps to "${v.target}", which is not in this flow.`;
|
|
118
|
+
case "goto-no-max":
|
|
119
|
+
return `${n} has no limit, so it could jump forever.`;
|
|
120
|
+
case "fanout-few":
|
|
121
|
+
return `${n} has fewer than two branches.`;
|
|
122
|
+
case "join-few":
|
|
123
|
+
return `${n} has fewer than two branches arriving.`;
|
|
124
|
+
case "join-no-n":
|
|
125
|
+
return `${n} waits for some branches but does not say how many.`;
|
|
126
|
+
case "variants-few":
|
|
127
|
+
return `${n} needs at least two variants.`;
|
|
128
|
+
case "variants-no-select":
|
|
129
|
+
return `${n} does not say how the winner is picked.`;
|
|
130
|
+
case "variants-no-evaluator":
|
|
131
|
+
return `${n} picks by evaluator score but names no evaluator.`;
|
|
132
|
+
case "rubric-short":
|
|
133
|
+
return `${n} needs a rubric of at least two levels.`;
|
|
134
|
+
case "no-threshold":
|
|
135
|
+
return `${n} routes on pass and fail but has no threshold.`;
|
|
136
|
+
case "no-question":
|
|
137
|
+
return `${n} asks no question.`;
|
|
138
|
+
case "options-few":
|
|
139
|
+
return `${n} needs at least two labels.`;
|
|
140
|
+
case "option-duplicate":
|
|
141
|
+
return `${n} has the label "${v.option}" twice.`;
|
|
142
|
+
case "not-runnable":
|
|
143
|
+
return `${n} cannot run here.`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
3
146
|
export const defaultMessages = {
|
|
4
147
|
shell: {
|
|
5
148
|
skipToContent: "Skip to content",
|
|
@@ -12,6 +155,8 @@ export const defaultMessages = {
|
|
|
12
155
|
expand: "Expand sidebar",
|
|
13
156
|
collapseTitle: "Collapse sidebar ([)",
|
|
14
157
|
expandTitle: "Expand sidebar ([)",
|
|
158
|
+
withBadge: (label, badge) => `${label}, ${badge}`,
|
|
159
|
+
areaWithBadges: (area) => `${area}, has updates`,
|
|
15
160
|
},
|
|
16
161
|
rail: {
|
|
17
162
|
show: (label) => `Show ${lower(label)}`,
|
|
@@ -65,6 +210,19 @@ export const defaultMessages = {
|
|
|
65
210
|
failed: "That did not work. Try again.",
|
|
66
211
|
reasonRequired: "A reason is required.",
|
|
67
212
|
},
|
|
213
|
+
data: {
|
|
214
|
+
noValue: "No data",
|
|
215
|
+
notSet: "Not set",
|
|
216
|
+
removeTag: (label) => `Remove ${label}`,
|
|
217
|
+
},
|
|
218
|
+
avatar: {
|
|
219
|
+
people: (names, more) => {
|
|
220
|
+
const all = more > 0 ? [...names, `${count(more)} more`] : [...names];
|
|
221
|
+
if (all.length <= 1)
|
|
222
|
+
return all.join("");
|
|
223
|
+
return `${all.slice(0, -1).join(", ")} and ${all[all.length - 1]}`;
|
|
224
|
+
},
|
|
225
|
+
},
|
|
68
226
|
user: {
|
|
69
227
|
accountMenu: (name, initials) => `${initials}, account menu for ${name}`,
|
|
70
228
|
signOut: "Sign out",
|
|
@@ -95,6 +253,481 @@ export const defaultMessages = {
|
|
|
95
253
|
customAccentOk: (ratio) => `${ratio}:1 against this ground.`,
|
|
96
254
|
customAccentFaint: (ratio, min, mode) => `${ratio}:1 against this ground; it needs ${min}:1. Try a ${mode === "dark" ? "lighter" : "darker"} colour.`,
|
|
97
255
|
},
|
|
256
|
+
workflow: {
|
|
257
|
+
status: (status) => (status === "draft" ? "Draft" : "Published"),
|
|
258
|
+
scope: (scope) => ({ private: "Private", project: "Project", organization: "Organization", shared: "Shared" })[scope],
|
|
259
|
+
module: (label, version) => (version ? `${label} ${version}` : label),
|
|
260
|
+
revision: (revision) => `Revision ${revision}`,
|
|
261
|
+
action: (action) => ({ edit: "Edit", start: "Start", export: "Export" })[action],
|
|
262
|
+
actionName: (label, name) => `${label} ${name}`,
|
|
263
|
+
availability: (status) => ({
|
|
264
|
+
available: "Available",
|
|
265
|
+
unsupported: "Unavailable",
|
|
266
|
+
"missing-capabilities": "Missing capabilities",
|
|
267
|
+
})[status],
|
|
268
|
+
unsupported: "This factory does not have this module, so the workflow cannot start here.",
|
|
269
|
+
missingCapabilities: (missing) => missing.length
|
|
270
|
+
? `Cannot start here: missing ${missing.join(", ")}.`
|
|
271
|
+
: "Cannot start here: a capability it needs is missing.",
|
|
272
|
+
denied: (actions) => `Your role cannot ${either(actions.map(lower))} this workflow.`,
|
|
273
|
+
preview: (name) => `Preview of ${name}`,
|
|
274
|
+
galleryTitle: "Workflows",
|
|
275
|
+
filters: "Find workflows",
|
|
276
|
+
search: "Search workflows",
|
|
277
|
+
moduleFilter: "Module",
|
|
278
|
+
anyModule: "All modules",
|
|
279
|
+
scopeFilter: "Scope",
|
|
280
|
+
anyScope: "Any scope",
|
|
281
|
+
statusFilter: "Status",
|
|
282
|
+
anyStatus: "Any status",
|
|
283
|
+
view: "View",
|
|
284
|
+
grid: "Grid",
|
|
285
|
+
list: "List",
|
|
286
|
+
count: (n) => (n === 1 ? "1 workflow" : `${count(n)} workflows`),
|
|
287
|
+
create: "New workflow",
|
|
288
|
+
import: "Import",
|
|
289
|
+
loadFailed: "Could not load workflows",
|
|
290
|
+
empty: "No workflows yet",
|
|
291
|
+
emptyDescription: "Save a workflow to reuse it here, or import one from another factory.",
|
|
292
|
+
noMatches: "No matches",
|
|
293
|
+
noMatchesDescription: "No workflows match the search and filters.",
|
|
294
|
+
clearFilters: "Clear filters",
|
|
295
|
+
},
|
|
296
|
+
editor: {
|
|
297
|
+
kind: (kind) => KIND_LABEL[kind],
|
|
298
|
+
kindHint: (kind) => KIND_HINT[kind],
|
|
299
|
+
exit: (exit) => exitName(exit),
|
|
300
|
+
selector: (selector) => ({
|
|
301
|
+
evaluator: "Highest evaluator score",
|
|
302
|
+
"first-passing": "First that passes",
|
|
303
|
+
"cheapest-passing": "Cheapest that passes",
|
|
304
|
+
person: "A person picks",
|
|
305
|
+
})[selector],
|
|
306
|
+
problemLevel: (level) => ({ blocking: "Blocking", warning: "Warning", "not-run": "Not run here" })[level],
|
|
307
|
+
problem: (p) => problemText(p),
|
|
308
|
+
connect: (reason, v) => ({
|
|
309
|
+
"missing-node": "Both ends must be nodes in this flow.",
|
|
310
|
+
self: "A node cannot connect to itself.",
|
|
311
|
+
"loop-target": "A loop goes into a node's loop input.",
|
|
312
|
+
"loop-not-back": `A loop goes back to a node before ${v.from}.`,
|
|
313
|
+
"loop-exists": `${v.from} already loops back to ${v.to}.`,
|
|
314
|
+
"next-target": "The run goes on into a node's input.",
|
|
315
|
+
"no-exit": `${v.from} has no ${exitName(v.exit ?? "")} exit.`,
|
|
316
|
+
"exit-taken": `The ${exitName(v.exit ?? "")} exit of ${v.from} already goes somewhere. Use a fan-out for branches.`,
|
|
317
|
+
exists: `${v.from} already goes to ${v.to}.`,
|
|
318
|
+
cycle: "That would make a cycle. Go back with a loop instead.",
|
|
319
|
+
"no-output": `${v.from} has no such output.`,
|
|
320
|
+
"no-input": `${v.to} has no such input.`,
|
|
321
|
+
"data-target": "An output goes into an input.",
|
|
322
|
+
"type-mismatch": `${v.output} (${v.given}) does not fit ${v.input} (${v.wanted}).`,
|
|
323
|
+
"data-order": `${v.to} does not run after ${v.from}, so it cannot take its ${v.output}.`,
|
|
324
|
+
"input-taken": `${v.input} of ${v.to} already has a source.`,
|
|
325
|
+
})[reason],
|
|
326
|
+
readError: (e) => e.code === "not-json"
|
|
327
|
+
? "This is not valid JSON."
|
|
328
|
+
: e.code === "not-a-package"
|
|
329
|
+
? "This is not a workflow package."
|
|
330
|
+
: e.code === "unsupported-version"
|
|
331
|
+
? `This was written in format version ${String(e.version)}, which this editor cannot read.`
|
|
332
|
+
: `This is not a workflow definition: ${e.path} is missing or wrong.`,
|
|
333
|
+
canvas: "Workflow canvas",
|
|
334
|
+
canvasTools: "Canvas tools",
|
|
335
|
+
add: "Add",
|
|
336
|
+
paletteGroup: (group) => ({ gates: "Gates", logic: "Logic", judges: "Judges", other: "Other" })[group],
|
|
337
|
+
customStep: "Custom step",
|
|
338
|
+
connectAction: "Connect",
|
|
339
|
+
connectTitle: (node) => `Connect ${node}`,
|
|
340
|
+
connectDescription: "Pick an exit, a loop or an output, then where it goes. Only connections that fit are offered.",
|
|
341
|
+
connectFrom: "From",
|
|
342
|
+
connectTo: "To",
|
|
343
|
+
connectNone: "Nothing in this flow can take a connection from here.",
|
|
344
|
+
cancel: "Cancel",
|
|
345
|
+
deleteSelection: "Delete",
|
|
346
|
+
arrange: "Arrange",
|
|
347
|
+
zoomIn: "Zoom in",
|
|
348
|
+
zoomOut: "Zoom out",
|
|
349
|
+
fit: "Fit to view",
|
|
350
|
+
nodeName: (kind, label, blocking, warnings, notRun) => [
|
|
351
|
+
`${kind}: ${label}`,
|
|
352
|
+
blocking
|
|
353
|
+
? blocking === 1
|
|
354
|
+
? "1 blocking problem"
|
|
355
|
+
: `${count(blocking)} blocking problems`
|
|
356
|
+
: "",
|
|
357
|
+
warnings ? (warnings === 1 ? "1 warning" : `${count(warnings)} warnings`) : "",
|
|
358
|
+
notRun ? "not run here" : "",
|
|
359
|
+
]
|
|
360
|
+
.filter(Boolean)
|
|
361
|
+
.join(", "),
|
|
362
|
+
edgeName: (kind, from, to, detail) => ({
|
|
363
|
+
next: `${from} to ${to}`,
|
|
364
|
+
loop: `Loop from ${from} back to ${to}`,
|
|
365
|
+
data: `Data from ${from} to ${to}`,
|
|
366
|
+
goto: `${from} jumps to ${to}`,
|
|
367
|
+
})[kind] + (detail ? `, ${detail}` : ""),
|
|
368
|
+
summary: (n, names) => {
|
|
369
|
+
switch (n.kind) {
|
|
370
|
+
case "step":
|
|
371
|
+
return names.preset ? `${names.module} · ${names.preset}` : "Custom step";
|
|
372
|
+
case "subflow":
|
|
373
|
+
return n.flow ? `Runs ${n.flow}${n.each ? `, once per ${n.each}` : ""}` : "Names no flow";
|
|
374
|
+
case "gate":
|
|
375
|
+
return names.gate ?? n.gate;
|
|
376
|
+
case "condition":
|
|
377
|
+
return n.cases.length === 1 ? "If, else" : `${count(n.cases.length)} cases, else`;
|
|
378
|
+
case "goto":
|
|
379
|
+
return names.target ? `To ${names.target}, at most ${n.max ?? "?"}` : "No target";
|
|
380
|
+
case "fanout":
|
|
381
|
+
return "Every branch";
|
|
382
|
+
case "join":
|
|
383
|
+
return n.wait === "n"
|
|
384
|
+
? `Waits for ${n.n ?? "?"}`
|
|
385
|
+
: n.wait === "all"
|
|
386
|
+
? "Waits for all"
|
|
387
|
+
: "Waits for any";
|
|
388
|
+
case "variants":
|
|
389
|
+
return `${count(n.variants.length)} variants`;
|
|
390
|
+
case "evaluator":
|
|
391
|
+
return n.routes && n.threshold !== undefined
|
|
392
|
+
? `Passes at ${Math.round(n.threshold * 100)}%`
|
|
393
|
+
: `${count(n.levels.length)} levels`;
|
|
394
|
+
case "classifier":
|
|
395
|
+
return n.options.length === 1 ? "1 label" : `${count(n.options.length)} labels`;
|
|
396
|
+
case "check":
|
|
397
|
+
return n.question || "No question";
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
notRun: "Not run here",
|
|
401
|
+
loopMax: (max) => (max ? `at most ${count(max)}` : "no limit"),
|
|
402
|
+
port: (label, type) => `${label} (${type})`,
|
|
403
|
+
loopHandle: "Loop back",
|
|
404
|
+
loopInHandle: "Loop in",
|
|
405
|
+
inHandle: "In",
|
|
406
|
+
regionName: (kind, head, n) => kind === "loop"
|
|
407
|
+
? `Loop from ${head}, ${count(n)} nodes`
|
|
408
|
+
: `Branches from ${head}, ${count(n)} nodes`,
|
|
409
|
+
fold: (name) => `Fold ${name}`,
|
|
410
|
+
unfold: (name) => `Unfold ${name}`,
|
|
411
|
+
showInPlace: (label) => `Show ${label} in place`,
|
|
412
|
+
hideInPlace: (label) => `Fold ${label}`,
|
|
413
|
+
readOnly: "Read only",
|
|
414
|
+
connected: (from, to) => `Connected ${from} to ${to}.`,
|
|
415
|
+
added: (label) => `Added ${label}.`,
|
|
416
|
+
deleted: (n) => (n === 1 ? "Deleted 1 item." : `Deleted ${count(n)} items.`),
|
|
417
|
+
selected: (name) => `Selected ${name}.`,
|
|
418
|
+
nodeHelp: "Press Enter or Space to select. Arrow keys move a selected node, Shift with an arrow moves it further. Delete removes it.",
|
|
419
|
+
edgeHelp: "Press Enter or Space to select. Delete removes it.",
|
|
420
|
+
movedLive: (direction, x, y) => `Moved ${direction}, to ${Math.round(x)}, ${Math.round(y)}.`,
|
|
421
|
+
palette: "Add to the flow",
|
|
422
|
+
paletteSearch: "Find a step, gate or block",
|
|
423
|
+
paletteEmpty: "Nothing matches.",
|
|
424
|
+
problems: "Problems",
|
|
425
|
+
noProblems: "Nothing blocks publishing",
|
|
426
|
+
problemCount: (level, n) => level === "blocking"
|
|
427
|
+
? n === 1
|
|
428
|
+
? "1 blocking"
|
|
429
|
+
: `${count(n)} blocking`
|
|
430
|
+
: level === "warning"
|
|
431
|
+
? n === 1
|
|
432
|
+
? "1 warning"
|
|
433
|
+
: `${count(n)} warnings`
|
|
434
|
+
: n === 1
|
|
435
|
+
? "1 node not run here"
|
|
436
|
+
: `${count(n)} nodes not run here`,
|
|
437
|
+
json: "Definition as JSON",
|
|
438
|
+
jsonHint: "Edits here apply as soon as the text reads as a definition.",
|
|
439
|
+
inspector: "Properties",
|
|
440
|
+
inspectorFor: (kind, label) => `${kind}: ${label}`,
|
|
441
|
+
inspectorEmpty: "Select a node or a connection to edit it.",
|
|
442
|
+
workflowDetails: "Workflow",
|
|
443
|
+
name: "Name",
|
|
444
|
+
description: "Description",
|
|
445
|
+
runInputs: "What a run starts with",
|
|
446
|
+
label: "Label",
|
|
447
|
+
nodeId: (id) => `Id: ${id}`,
|
|
448
|
+
note: "Note",
|
|
449
|
+
choose: "Choose",
|
|
450
|
+
hostDefault: "Default",
|
|
451
|
+
preset: "Preset",
|
|
452
|
+
noPreset: "No preset",
|
|
453
|
+
model: "Model",
|
|
454
|
+
harness: "Harness",
|
|
455
|
+
effort: "Effort",
|
|
456
|
+
inputs: "Inputs",
|
|
457
|
+
outputs: "Outputs",
|
|
458
|
+
optional: "optional",
|
|
459
|
+
addPort: "Add a port",
|
|
460
|
+
newPort: "New port",
|
|
461
|
+
portLabel: "Port name",
|
|
462
|
+
portType: "Type",
|
|
463
|
+
anyType: "Anything",
|
|
464
|
+
remove: (label) => `Remove ${label}`,
|
|
465
|
+
subflow: "Flow to run",
|
|
466
|
+
each: "Once per",
|
|
467
|
+
eachHint: "Runs the flow once for each item of this input. Leave it empty to run it once.",
|
|
468
|
+
gateKind: "Kind of gate",
|
|
469
|
+
approvers: "Approval",
|
|
470
|
+
roles: "Roles",
|
|
471
|
+
members: "Named members",
|
|
472
|
+
quorum: "Approvals needed",
|
|
473
|
+
quorumHint: "One when empty.",
|
|
474
|
+
timeoutHours: "Timeout in hours",
|
|
475
|
+
onTimeout: "When it times out",
|
|
476
|
+
onTimeoutOption: (option) => (option === "fail" ? "Fail the run" : "Escalate"),
|
|
477
|
+
threshold: "Pass at (%)",
|
|
478
|
+
rule: "Rule",
|
|
479
|
+
cases: "Cases",
|
|
480
|
+
caseLabel: "Case name",
|
|
481
|
+
addCase: "Add a case",
|
|
482
|
+
newCase: (n) => `Case ${count(n)}`,
|
|
483
|
+
when: (label) => `${label}: when`,
|
|
484
|
+
fact: "Run fact",
|
|
485
|
+
factNode: "Of node",
|
|
486
|
+
operator: "Comparison",
|
|
487
|
+
value: "Value",
|
|
488
|
+
boolean: (value) => (value ? "Yes" : "No"),
|
|
489
|
+
target: "Jump to",
|
|
490
|
+
limit: "At most (times)",
|
|
491
|
+
wait: "Waits for",
|
|
492
|
+
waitOption: (wait) => ({ all: "All branches", any: "Any branch", n: "Some branches" })[wait],
|
|
493
|
+
waitN: "How many",
|
|
494
|
+
winner: "Winner",
|
|
495
|
+
evaluator: "Evaluator that picks",
|
|
496
|
+
variants: "Variants",
|
|
497
|
+
addVariant: "Add a variant",
|
|
498
|
+
newVariant: (n) => `Variant ${count(n)}`,
|
|
499
|
+
variantLabel: "Variant name",
|
|
500
|
+
question: "Question",
|
|
501
|
+
levels: "Rubric",
|
|
502
|
+
levelsHint: "One level per line, lowest first.",
|
|
503
|
+
routes: "Route on pass and fail",
|
|
504
|
+
minConfidence: "Ask a person below (%)",
|
|
505
|
+
minConfidenceHint: "Below this confidence a person decides.",
|
|
506
|
+
options: "Labels",
|
|
507
|
+
addOption: "Add a label",
|
|
508
|
+
newOption: (n) => `Label ${count(n)}`,
|
|
509
|
+
optionLabel: "Label",
|
|
510
|
+
optionDescription: "What it means",
|
|
511
|
+
otherExit: "Other exit, for inputs no label fits",
|
|
512
|
+
yesAt: "Yes at (%)",
|
|
513
|
+
exitIs: (exit) => `Leaves by the ${exit} exit.`,
|
|
514
|
+
edgeLabel: "Label",
|
|
515
|
+
dataFlow: (output, input) => `Hands ${output} to ${input}.`,
|
|
516
|
+
until: "Until",
|
|
517
|
+
deleteNode: (label) => `Delete ${label}`,
|
|
518
|
+
deleteEdge: "Delete this connection",
|
|
519
|
+
},
|
|
520
|
+
workspace: {
|
|
521
|
+
loading: "Loading the workflow",
|
|
522
|
+
loadFailed: "Could not load the workflow",
|
|
523
|
+
actions: "Workflow actions",
|
|
524
|
+
panels: "Panels",
|
|
525
|
+
paletteRegion: "Building blocks",
|
|
526
|
+
problemsTab: (n) => (n ? `Problems (${count(n)})` : "Problems"),
|
|
527
|
+
jsonTab: "JSON",
|
|
528
|
+
flow: "Flow",
|
|
529
|
+
unsaved: "Unsaved changes",
|
|
530
|
+
saved: (label) => (label ? `Saved, revision ${label}` : "Saved"),
|
|
531
|
+
live: (label) => (label ? `Live, revision ${label}` : "Live"),
|
|
532
|
+
differsFromLive: (label) => label ? `Differs from live revision ${label}` : "Differs from live",
|
|
533
|
+
notPublished: "Not published",
|
|
534
|
+
conflict: "Conflict",
|
|
535
|
+
conflictDescription: (by, label) => `${by ? `${by} saved` : "Someone saved"} ${label ? `revision ${label}` : "a newer revision"} while you had unsaved changes. Compare them, use theirs, or keep yours and save over it.`,
|
|
536
|
+
compare: "Compare",
|
|
537
|
+
compareTitle: "Your changes against the saved revision",
|
|
538
|
+
compareDescription: "What saving your copy would change in the revision saved since you started.",
|
|
539
|
+
useTheirs: "Use theirs",
|
|
540
|
+
keepMine: "Keep mine",
|
|
541
|
+
save: "Save draft",
|
|
542
|
+
saving: "Saving",
|
|
543
|
+
savedNotice: "Draft saved.",
|
|
544
|
+
saveAs: "Save as",
|
|
545
|
+
saveAsTitle: "Save as a new workflow",
|
|
546
|
+
saveAsDescription: "A copy under its own name, to reuse. This workflow stays as it is.",
|
|
547
|
+
copyName: (name) => `${name} (copy)`,
|
|
548
|
+
savedAsNotice: (name) => `Saved as ${name}.`,
|
|
549
|
+
publish: "Publish",
|
|
550
|
+
publishing: "Publishing",
|
|
551
|
+
publishTitle: "Publish this draft?",
|
|
552
|
+
publishDescription: (label) => `It replaces what runs today${label ? `, revision ${label}` : ""}. New runs use it; runs in progress keep theirs.`,
|
|
553
|
+
firstPublish: "This is its first publish. New runs use it.",
|
|
554
|
+
draftAgainstLive: "Draft against live",
|
|
555
|
+
publishBlocked: (n) => n === 1
|
|
556
|
+
? "1 blocking problem must be fixed first."
|
|
557
|
+
: `${count(n)} blocking problems must be fixed first.`,
|
|
558
|
+
publishedNotice: "Published.",
|
|
559
|
+
failed: "That did not work. Try again.",
|
|
560
|
+
discard: "Discard changes",
|
|
561
|
+
discardTitle: "Discard your changes?",
|
|
562
|
+
discardDescription: "Your copy goes back to the revision you started from. Unsaved changes are lost.",
|
|
563
|
+
export: "Export",
|
|
564
|
+
import: "Import",
|
|
565
|
+
importTitle: "Import a workflow package",
|
|
566
|
+
importDescription: "What importing it would do here. Nothing changes until you import.",
|
|
567
|
+
importAction: "Import",
|
|
568
|
+
importing: "Importing",
|
|
569
|
+
importedNotice: "Imported.",
|
|
570
|
+
importAvailability: (status) => ({
|
|
571
|
+
available: "Runs here",
|
|
572
|
+
"missing-capabilities": "Missing capabilities here",
|
|
573
|
+
unsupported: "Cannot run here",
|
|
574
|
+
})[status],
|
|
575
|
+
modules: "Modules",
|
|
576
|
+
noModules: "It needs no module.",
|
|
577
|
+
moduleStatus: (status, installed) => ({
|
|
578
|
+
available: "Installed",
|
|
579
|
+
missing: "Not installed here",
|
|
580
|
+
version: `Installed at ${installed ?? "another version"}`,
|
|
581
|
+
unavailable: "Installed, not available",
|
|
582
|
+
})[status],
|
|
583
|
+
missingCapabilities: "Missing capabilities",
|
|
584
|
+
unknownVocabulary: "Not known here",
|
|
585
|
+
unknownGateKind: (id) => `Gate kind "${id}"`,
|
|
586
|
+
unknownFact: (id) => `Run fact "${id}"`,
|
|
587
|
+
unknownOperator: (id) => `Comparison "${id}"`,
|
|
588
|
+
disabledNodes: (n) => n === 1 ? "1 node would be disabled" : `${count(n)} nodes would be disabled`,
|
|
589
|
+
needsApprovers: "Gates that need approvers here",
|
|
590
|
+
importBlocking: (n) => n === 1 ? "1 blocking problem here." : `${count(n)} blocking problems here.`,
|
|
591
|
+
replaces: "Against the workflow it replaces",
|
|
592
|
+
diff: "Changes",
|
|
593
|
+
noChanges: "Nothing that runs changes.",
|
|
594
|
+
onlyMoved: (n) => n === 1
|
|
595
|
+
? "Only 1 node moved; nothing that runs changes."
|
|
596
|
+
: `Only ${count(n)} nodes moved; nothing that runs changes.`,
|
|
597
|
+
moved: (n) => (n === 1 ? "1 node moved." : `${count(n)} nodes moved.`),
|
|
598
|
+
change: (change, what) => `${what} ${change}`,
|
|
599
|
+
details: "Details",
|
|
600
|
+
detail: (key) => ({ name: "name", description: "description", module: "module", main: "main flow" })[key],
|
|
601
|
+
flows: "Flows",
|
|
602
|
+
nodes: "Nodes",
|
|
603
|
+
connections: "Connections",
|
|
604
|
+
},
|
|
605
|
+
run: {
|
|
606
|
+
timeline: "Run stages",
|
|
607
|
+
loadFailed: (label) => `Could not load ${lower(label)}`,
|
|
608
|
+
noStages: "No stages yet",
|
|
609
|
+
noStagesDescription: "Stages appear here as the run starts them.",
|
|
610
|
+
stageStatus: (status) => ({
|
|
611
|
+
pending: "pending",
|
|
612
|
+
running: "running",
|
|
613
|
+
waiting: "waiting",
|
|
614
|
+
blocked: "blocked",
|
|
615
|
+
passed: "passed",
|
|
616
|
+
failed: "failed",
|
|
617
|
+
skipped: "skipped",
|
|
618
|
+
cancelled: "cancelled",
|
|
619
|
+
})[status],
|
|
620
|
+
attempt: (attempt, max) => max ? `Attempt ${count(attempt)} of ${count(max)}` : `Attempt ${count(attempt)}`,
|
|
621
|
+
startedAt: (time) => `Started ${time}`,
|
|
622
|
+
duration: (duration) => duration,
|
|
623
|
+
inputsOutputs: (inputs, outputs) => `${inputs === 1 ? "1 input" : `${count(inputs)} inputs`}, ${outputs === 1 ? "1 output" : `${count(outputs)} outputs`}`,
|
|
624
|
+
inputs: "Inputs",
|
|
625
|
+
outputs: "Outputs",
|
|
626
|
+
none: "None",
|
|
627
|
+
gate: (label, status, approvals, required) => {
|
|
628
|
+
const word = {
|
|
629
|
+
waiting: "waiting",
|
|
630
|
+
approved: "approved",
|
|
631
|
+
rejected: "rejected",
|
|
632
|
+
expired: "expired",
|
|
633
|
+
skipped: "skipped",
|
|
634
|
+
}[status];
|
|
635
|
+
const quorum = required ? ` (${count(approvals ?? 0)} of ${count(required)})` : "";
|
|
636
|
+
return `${label}: ${word}${quorum}`;
|
|
637
|
+
},
|
|
638
|
+
artifacts: "Artifacts",
|
|
639
|
+
noArtifacts: "No artifacts yet",
|
|
640
|
+
noArtifactsDescription: "What the run produces appears here.",
|
|
641
|
+
artifactStatus: (status) => ({
|
|
642
|
+
draft: "draft",
|
|
643
|
+
"in-review": "in review",
|
|
644
|
+
approved: "approved",
|
|
645
|
+
rejected: "rejected",
|
|
646
|
+
superseded: "superseded",
|
|
647
|
+
})[status],
|
|
648
|
+
version: (version) => `Version ${version}`,
|
|
649
|
+
producedBy: (stage) => `From ${stage}`,
|
|
650
|
+
},
|
|
651
|
+
review: {
|
|
652
|
+
title: "Review",
|
|
653
|
+
titleFor: (subject) => `Review: ${subject}`,
|
|
654
|
+
verdict: (verdict) => ({
|
|
655
|
+
pending: "pending",
|
|
656
|
+
approved: "approved",
|
|
657
|
+
"changes-requested": "changes requested",
|
|
658
|
+
rejected: "rejected",
|
|
659
|
+
})[verdict],
|
|
660
|
+
decided: (verdict, by, at) => `${verdict === "approved" ? "Approved" : "Rejected"}${by ? ` by ${by}` : ""}${at ? `, ${at}` : ""}.`,
|
|
661
|
+
approve: "Approve",
|
|
662
|
+
reject: "Reject",
|
|
663
|
+
approveTitle: "Approve this?",
|
|
664
|
+
approveDescription: "Your approval is recorded on this review with your name.",
|
|
665
|
+
rejectTitle: "Reject this?",
|
|
666
|
+
rejectDescription: "Your rejection and its reason are recorded on this review with your name.",
|
|
667
|
+
reasonLabel: "Reason",
|
|
668
|
+
comments: (n) => (n === 1 ? "1 comment" : `${count(n)} comments`),
|
|
669
|
+
noComments: "No comments yet.",
|
|
670
|
+
addComment: "Add a comment",
|
|
671
|
+
post: "Comment",
|
|
672
|
+
commentOn: (anchor) => `Commenting on ${anchor}`,
|
|
673
|
+
clearAnchor: "Comment on the whole",
|
|
674
|
+
goToAnchor: (anchor) => `${anchor}, go to it`,
|
|
675
|
+
resolved: "resolved",
|
|
676
|
+
},
|
|
677
|
+
media: {
|
|
678
|
+
markers: "Comments on the timeline",
|
|
679
|
+
timeComment: (timecode, author) => `${timecode}, comment by ${author}`,
|
|
680
|
+
regionComment: (author, timecode) => timecode ? `Region at ${timecode}, comment by ${author}` : `Region, comment by ${author}`,
|
|
681
|
+
commentHere: "Comment here",
|
|
682
|
+
drawHint: "Drag on the image to comment on a region.",
|
|
683
|
+
count: (n) => (n === 1 ? "1 comment" : `${count(n)} comments`),
|
|
684
|
+
markRegion: "Mark a region",
|
|
685
|
+
regionBox: "Region to comment on",
|
|
686
|
+
regionHelp: "Arrow keys move the region, Shift and arrow keys resize it, Enter comments on it, Escape cancels.",
|
|
687
|
+
regionBounds: (left, top, width, height) => `${left}% from the left, ${top}% from the top, ${width}% wide, ${height}% high`,
|
|
688
|
+
confirmRegion: "Comment on region",
|
|
689
|
+
cancel: "Cancel",
|
|
690
|
+
},
|
|
691
|
+
document: {
|
|
692
|
+
changes: (n) => (n === 1 ? "1 change" : `${count(n)} changes`),
|
|
693
|
+
annotations: (n) => (n === 1 ? "1 annotation" : `${count(n)} annotations`),
|
|
694
|
+
pages: "Pages",
|
|
695
|
+
previousPage: "Previous page",
|
|
696
|
+
nextPage: "Next page",
|
|
697
|
+
pageOf: (page, total) => `Page ${count(page)} of ${count(total)}`,
|
|
698
|
+
anchor: (page, clause) => (clause ? `p. ${page}, ${clause}` : `p. ${page}`),
|
|
699
|
+
commentOnClause: (clause) => `${clause}, comment on this clause`,
|
|
700
|
+
commentOnBlock: (anchor) => `Comment on this paragraph, ${anchor}`,
|
|
701
|
+
inserted: (text) => `inserted: ${text}`,
|
|
702
|
+
deleted: (text) => `deleted: ${text}`,
|
|
703
|
+
annotationBy: (author, anchor) => `Annotation by ${author}, ${anchor}`,
|
|
704
|
+
empty: "This page has no text.",
|
|
705
|
+
signOff: "Sign-off",
|
|
706
|
+
signOffAction: "Sign off",
|
|
707
|
+
signOffStatus: (status) => ({ pending: "pending", signed: "signed", declined: "declined" })[status],
|
|
708
|
+
signOffTitle: (title) => `Sign off ${title}?`,
|
|
709
|
+
signOffDescription: (role) => role
|
|
710
|
+
? `You sign as ${role}. Your name and the time are recorded.`
|
|
711
|
+
: "Your name and the time are recorded.",
|
|
712
|
+
},
|
|
713
|
+
form: {
|
|
714
|
+
source: "Source",
|
|
715
|
+
sourcePage: "Source page",
|
|
716
|
+
page: (page) => `Page ${count(page)}`,
|
|
717
|
+
fields: "Extracted fields",
|
|
718
|
+
fieldOnSource: (label) => `${label}, on the source page`,
|
|
719
|
+
progress: (done, total, flagged) => `${count(done)} of ${count(total)} confirmed${flagged ? `, ${count(flagged)} flagged` : ""}`,
|
|
720
|
+
confidence: (confidence) => `${Math.round(confidence * 100)}% confident`,
|
|
721
|
+
status: (status) => (status === "accepted" ? "accepted" : "corrected"),
|
|
722
|
+
accept: "Accept",
|
|
723
|
+
correct: "Correct",
|
|
724
|
+
actionName: (label, field) => `${label} ${field}`,
|
|
725
|
+
correctLabel: (label) => `Corrected ${label}`,
|
|
726
|
+
extracted: (value) => `Extracted: ${value}`,
|
|
727
|
+
save: "Save",
|
|
728
|
+
cancel: "Cancel",
|
|
729
|
+
empty: "Nothing found",
|
|
730
|
+
},
|
|
98
731
|
};
|
|
99
732
|
export function mergeMessages(overrides) {
|
|
100
733
|
if (!overrides)
|