@revenexx/studio-integrations 0.7.0 → 1.1.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 +633 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +2 -1
- package/dist/runtime/components/Integrations/CredentialCreateDialog.vue +4 -1
- package/dist/runtime/components/Integrations/CredentialDetailDialog.vue +8 -2
- package/dist/runtime/components/Integrations/DeadLettersPanel.vue +2 -6
- package/dist/runtime/components/Integrations/ExpressionInput.vue +5 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicField.d.vue.ts +3 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicField.vue +16 -3
- package/dist/runtime/components/Integrations/NodeConfigDynamicField.vue.d.ts +3 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicSchema.vue +1 -0
- package/dist/runtime/components/Integrations/NodeConfigField.d.vue.ts +3 -0
- package/dist/runtime/components/Integrations/NodeConfigField.vue +2 -0
- package/dist/runtime/components/Integrations/NodeConfigField.vue.d.ts +3 -0
- package/dist/runtime/components/Integrations/NodeInspector.d.vue.ts +2 -2
- package/dist/runtime/components/Integrations/NodeInspector.vue +135 -10
- package/dist/runtime/components/Integrations/NodeInspector.vue.d.ts +2 -2
- package/dist/runtime/components/Integrations/NodeOutputSchema.d.vue.ts +2 -1
- package/dist/runtime/components/Integrations/NodeOutputSchema.vue +34 -8
- package/dist/runtime/components/Integrations/NodeOutputSchema.vue.d.ts +2 -1
- package/dist/runtime/components/Integrations/NodePalette.vue +12 -8
- package/dist/runtime/components/Integrations/RunDetailPanel.vue +9 -6
- package/dist/runtime/components/Integrations/RunsTable.vue +2 -2
- package/dist/runtime/components/Integrations/StickyNoteView.vue +45 -11
- package/dist/runtime/components/Integrations/SurfaceCard.d.vue.ts +50 -0
- package/dist/runtime/components/Integrations/SurfaceCard.vue +55 -0
- package/dist/runtime/components/Integrations/SurfaceCard.vue.d.ts +50 -0
- package/dist/runtime/components/Integrations/TemplateCard.vue +3 -3
- package/dist/runtime/components/Integrations/TemplateFlowPreview.vue +12 -3
- package/dist/runtime/components/Integrations/WorkflowCreateDialog.vue +5 -4
- package/dist/runtime/components/Integrations/WorkflowEditor.d.vue.ts +16 -0
- package/dist/runtime/components/Integrations/WorkflowEditor.vue +79 -12
- package/dist/runtime/components/Integrations/WorkflowEditor.vue.d.ts +16 -0
- package/dist/runtime/components/Integrations/WorkflowHistoryPanel.d.vue.ts +6 -0
- package/dist/runtime/components/Integrations/WorkflowHistoryPanel.vue +13 -3
- package/dist/runtime/components/Integrations/WorkflowHistoryPanel.vue.d.ts +6 -0
- package/dist/runtime/components/Integrations/WorkflowNodeView.d.vue.ts +13 -0
- package/dist/runtime/components/Integrations/WorkflowNodeView.vue +95 -29
- package/dist/runtime/components/Integrations/WorkflowNodeView.vue.d.ts +13 -0
- package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.vue +11 -10
- package/dist/runtime/components/Integrations/WorkflowSettingsDialog.d.vue.ts +16 -17
- package/dist/runtime/components/Integrations/WorkflowSettingsDialog.vue +37 -26
- package/dist/runtime/components/Integrations/WorkflowSettingsDialog.vue.d.ts +16 -17
- package/dist/runtime/components/Integrations/WorkflowTriggerView.vue +4 -5
- package/dist/runtime/components/Integrations/WorkflowVariablesDialog.vue +53 -14
- package/dist/runtime/components/Integrations/WorkflowsTable.vue +9 -4
- package/dist/runtime/composables/useIntegrationsCredentials.d.ts +11 -0
- package/dist/runtime/composables/useIntegrationsCredentials.js +2 -2
- package/dist/runtime/composables/useIntegrationsDeadLetters.d.ts +9 -2
- package/dist/runtime/composables/useIntegrationsDeadLetters.js +27 -18
- package/dist/runtime/composables/useIntegrationsNodes.js +11 -1
- package/dist/runtime/composables/useIntegrationsRuns.d.ts +30 -1
- package/dist/runtime/composables/useIntegrationsRuns.js +70 -29
- package/dist/runtime/composables/useIntegrationsSchedules.d.ts +7 -14
- package/dist/runtime/composables/useIntegrationsSchedules.js +80 -35
- package/dist/runtime/composables/useIntegrationsTriggers.d.ts +30 -3
- package/dist/runtime/composables/useIntegrationsTriggers.js +18 -7
- package/dist/runtime/composables/useIntegrationsWorkflows.d.ts +10 -1
- package/dist/runtime/composables/useIntegrationsWorkflows.js +25 -4
- package/dist/runtime/composables/useNodeConfigResolve.js +2 -1
- package/dist/runtime/data/integrationNodeCatalog.d.ts +22 -1
- package/dist/runtime/data/integrationNodeCatalog.js +8 -4
- package/dist/runtime/data/loopBody.d.ts +129 -0
- package/dist/runtime/data/loopBody.js +76 -0
- package/dist/runtime/data/nodeInputData.d.ts +58 -1
- package/dist/runtime/data/nodeInputData.js +30 -5
- package/dist/runtime/data/triggerGlyphs.d.ts +47 -0
- package/dist/runtime/data/triggerGlyphs.js +11 -0
- package/dist/runtime/i18n/messages/de.json +62 -33
- package/dist/runtime/i18n/messages/en.json +32 -3
- package/dist/runtime/pages/integrations/credentials.vue +4 -1
- package/dist/runtime/pages/integrations/index.vue +32 -34
- package/dist/runtime/pages/integrations/runs.vue +22 -10
- package/dist/runtime/pages/integrations/schedules.vue +64 -7
- package/dist/runtime/pages/integrations/templates/[slug].vue +13 -5
- package/dist/runtime/pages/integrations/workflows/[id].vue +193 -104
- package/dist/runtime/types/integrations.d.ts +64 -1
- package/dist/runtime/utils/cockpitSources.d.ts +22 -3
- package/dist/runtime/utils/credentialState.d.ts +6 -1
- package/dist/runtime/utils/credentialState.js +1 -1
- package/dist/runtime/utils/localize.d.ts +34 -0
- package/dist/runtime/utils/localize.js +22 -7
- package/dist/runtime/utils/pollBudget.d.ts +1 -1
- package/dist/runtime/utils/servedPaths.d.ts +22 -0
- package/dist/runtime/utils/servedPaths.js +3 -0
- package/dist/runtime/utils/statusStyle.d.ts +52 -0
- package/dist/runtime/utils/statusStyle.js +26 -0
- package/package.json +1 -1
|
@@ -11,6 +11,40 @@
|
|
|
11
11
|
export declare function setStudioLocale(locale: string | null | undefined): void;
|
|
12
12
|
/** The language the studio is currently rendering in. Reactive when read in an effect. */
|
|
13
13
|
export declare function studioLocale(): string;
|
|
14
|
+
/**
|
|
15
|
+
* The key a read answers from — which is the key a *deletion* has to remove, since
|
|
16
|
+
* what the user is clearing is the text in front of them.
|
|
17
|
+
*
|
|
18
|
+
* All four steps, in the order `resolveLocalized` reads them: the exact tag, the same
|
|
19
|
+
* language in another region, English, and the map's own first entry. `''` when the
|
|
20
|
+
* map holds no string at all.
|
|
21
|
+
*/
|
|
22
|
+
export declare function languageKeyRead(map: unknown, locale?: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* The key an edit is written to.
|
|
25
|
+
*
|
|
26
|
+
* The first two steps of {@link languageKeyRead} and deliberately not its last two:
|
|
27
|
+
* falling back to English or to the first entry answers "what can I show you", and
|
|
28
|
+
* writing there would put the author's text into a language they are not reading —
|
|
29
|
+
* the silent loss this exists to prevent (PO-259). A language the map does not hold
|
|
30
|
+
* yet is written under its base subtag, never the tag the host set, so that reading
|
|
31
|
+
* it back finds it: a `de-CH` studio reading a `de` text through the region step
|
|
32
|
+
* would otherwise write a new `de-CH` key and leave every plain-`de` reader on the
|
|
33
|
+
* old wording.
|
|
34
|
+
*
|
|
35
|
+
* **That guarantee is about the keys this function invents.** The first two steps
|
|
36
|
+
* return a key the map already holds, verbatim — so a map carrying `DE-ch` is written
|
|
37
|
+
* back into `DE-ch`, which the API's `^[a-z]{2,3}(-[A-Z]{2})?$` rejects. Not a case
|
|
38
|
+
* that can arise: such a map could not have been saved in the first place, and the
|
|
39
|
+
* only writer of these keys is this function. Returning an existing key as it stands
|
|
40
|
+
* is what makes the write land where the read came from, which is worth more here than
|
|
41
|
+
* normalising a shape nothing can produce — but it is why the sentence above says
|
|
42
|
+
* *invents* rather than *writes*.
|
|
43
|
+
*
|
|
44
|
+
* Deleting is the other question and has the other answer — see
|
|
45
|
+
* {@link languageKeyRead}.
|
|
46
|
+
*/
|
|
47
|
+
export declare function languageKeyToWrite(map: unknown, locale?: string): string;
|
|
14
48
|
/**
|
|
15
49
|
* Resolve a multilingual value from the Integrations API. The API returns
|
|
16
50
|
* names and descriptions either as a plain string or as an already-parsed
|
|
@@ -7,24 +7,39 @@ export function setStudioLocale(locale) {
|
|
|
7
7
|
export function studioLocale() {
|
|
8
8
|
return uiLocale.value;
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
const
|
|
10
|
+
function baseLanguage(locale) {
|
|
11
|
+
const base = locale.toLowerCase().split(/[-_]/)[0] ?? "";
|
|
12
|
+
return /^[a-z]{2,3}$/.test(base) ? base : "en";
|
|
13
|
+
}
|
|
14
|
+
export function languageKeyRead(map, locale = studioLocale()) {
|
|
15
|
+
const obj = map && typeof map === "object" ? map : {};
|
|
16
|
+
const keys = Object.keys(obj);
|
|
12
17
|
if (!keys.length) return "";
|
|
13
18
|
const wanted = locale.toLowerCase();
|
|
14
|
-
const base =
|
|
19
|
+
const base = baseLanguage(locale);
|
|
15
20
|
const candidates = [
|
|
16
21
|
keys.find((k) => k.toLowerCase() === wanted),
|
|
17
|
-
keys.find((k) => k
|
|
18
|
-
keys.find((k) => k
|
|
22
|
+
keys.find((k) => baseLanguage(k) === base),
|
|
23
|
+
keys.find((k) => baseLanguage(k) === "en"),
|
|
19
24
|
keys[0]
|
|
20
25
|
];
|
|
21
26
|
for (const key of candidates) {
|
|
22
27
|
if (key === void 0) continue;
|
|
23
|
-
|
|
24
|
-
if (typeof picked === "string") return picked;
|
|
28
|
+
if (typeof obj[key] === "string") return key;
|
|
25
29
|
}
|
|
26
30
|
return "";
|
|
27
31
|
}
|
|
32
|
+
export function languageKeyToWrite(map, locale = studioLocale()) {
|
|
33
|
+
const keys = map && typeof map === "object" ? Object.keys(map) : [];
|
|
34
|
+
const wanted = locale.toLowerCase();
|
|
35
|
+
const base = baseLanguage(locale);
|
|
36
|
+
return keys.find((k) => k.toLowerCase() === wanted) ?? keys.find((k) => baseLanguage(k) === base) ?? base;
|
|
37
|
+
}
|
|
38
|
+
function pickLanguage(map, locale) {
|
|
39
|
+
const key = languageKeyRead(map, locale);
|
|
40
|
+
const picked = key ? map[key] : void 0;
|
|
41
|
+
return typeof picked === "string" ? picked : "";
|
|
42
|
+
}
|
|
28
43
|
export function resolveLocalized(value, locale = uiLocale.value) {
|
|
29
44
|
if (value === null || value === void 0) return "";
|
|
30
45
|
if (typeof value === "object" && !Array.isArray(value)) {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* COUNTING TICKS, NOT READING A CLOCK, and that is deliberate twice over. The tick
|
|
18
18
|
* is the only thing that has actually happened — a wall-clock reading would make
|
|
19
19
|
* this disagree with a `setInterval` the browser throttled in a background tab. And
|
|
20
|
-
* `specs/runs.md` AC-
|
|
20
|
+
* `specs/runs.md` AC-8's test installs Playwright's fake clock and fast-forwards
|
|
21
21
|
* it; a `Date.now()` in here would read the fake time, which is the kind of
|
|
22
22
|
* coupling that makes a test pass for the wrong reason.
|
|
23
23
|
*
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `/integrations/…` paths a host actually serves, out of the route records its
|
|
3
|
+
* router hands back.
|
|
4
|
+
*
|
|
5
|
+
* The dashboard's four shortcuts into Import & Export, the SFTP server, the event
|
|
6
|
+
* stream and inbound webhooks point at pages this module does not have — they are
|
|
7
|
+
* the host's (PO-223, [`docs/host-surfaces.md`](../../../docs/host-surfaces.md)) —
|
|
8
|
+
* so each card is offered as a way in only where the host has the path.
|
|
9
|
+
*
|
|
10
|
+
* It lives here rather than in the page for the same reason `scanRoutes` lives in
|
|
11
|
+
* `src/pageRoutes.ts`: the trailing-slash strip and the decision to compare exactly
|
|
12
|
+
* are what the doc names as the *misinforming* failure mode, and prose does not
|
|
13
|
+
* fail. `servedPaths.test.ts` pins the three cases that matter.
|
|
14
|
+
*
|
|
15
|
+
* **Exact strings, deliberately.** A parametrised page registers
|
|
16
|
+
* `/integrations/:surface`, and a route-prefixing i18n strategy registers
|
|
17
|
+
* `/en/integrations/io`; neither is one of the four literals, so a host built that
|
|
18
|
+
* way is told its own surfaces live elsewhere. That is the documented limit of the
|
|
19
|
+
* question — narrower than resolving through the matcher, which a host with a
|
|
20
|
+
* catch-all page answers "yes" to everywhere.
|
|
21
|
+
*/
|
|
22
|
+
export declare function servedPaths(routePaths: string[]): Set<string>;
|
|
@@ -42,4 +42,56 @@ export declare const RUN_STATUS_WORDS: readonly ["running", "succeeded", "failed
|
|
|
42
42
|
* never disagree about which status they mean.
|
|
43
43
|
*/
|
|
44
44
|
export declare function normalisedRunStatus(status: string | null | undefined): string;
|
|
45
|
+
/**
|
|
46
|
+
* The classes a run's status badge is drawn with — the colour half of
|
|
47
|
+
* {@link runStatusLabel}, and it reads the same word.
|
|
48
|
+
*
|
|
49
|
+
* `statusClass` on its own is handed whatever the platform wrote, and the map it
|
|
50
|
+
* looks in knows the studio's vocabulary rather than Temporal's: `terminated` and
|
|
51
|
+
* `timed_out` are in no branch of it, so a run the operator terminated was drawn
|
|
52
|
+
* neutral — the colour a *cancelled* run wears — while its badge said "failed".
|
|
53
|
+
* Two runs reading the same, in two colours, because the word went through
|
|
54
|
+
* {@link normalisedRunStatus} and the colour did not.
|
|
55
|
+
*
|
|
56
|
+
* So this normalises first. Every surface drawing a run's state calls it rather
|
|
57
|
+
* than `statusClass`, which stays what it is: one map from a status *word* to a
|
|
58
|
+
* tone, for the many vocabularies across the cockpit that already speak it.
|
|
59
|
+
*/
|
|
60
|
+
export declare function runStatusClass(status: string | null | undefined): string;
|
|
45
61
|
export declare function runStatusLabel(status: string | null | undefined): string;
|
|
62
|
+
/**
|
|
63
|
+
* A missed run's state, as a word written for the operator.
|
|
64
|
+
*
|
|
65
|
+
* The counterpart to {@link runStatusLabel} for the entry a trigger firing leaves
|
|
66
|
+
* when its workflow could not run. A state the catalogue does not know is named as
|
|
67
|
+
* unknown and carries the platform's own value inside that frame, so an operator
|
|
68
|
+
* can still quote what arrived without the studio claiming the word as one of its
|
|
69
|
+
* own. Nothing in, nothing out — the same answer `runStatusLabel` gives, for a
|
|
70
|
+
* column that is never actually empty.
|
|
71
|
+
*
|
|
72
|
+
* **The match is exact, unlike `runStatusLabel`'s**, and that is the point rather
|
|
73
|
+
* than an omission. Everything else that reads this field compares it strictly —
|
|
74
|
+
* whether an entry offers replay and discard, and whether it counts towards the
|
|
75
|
+
* firings still waiting — so a value differing by case or a stray space is one the
|
|
76
|
+
* studio does not act on. Saying "waiting" for it would promise an action that is
|
|
77
|
+
* not offered; saying it is unknown is what the rest of the studio already
|
|
78
|
+
* believes.
|
|
79
|
+
*
|
|
80
|
+
* The frame carries the value with its surrounding whitespace off and nothing else
|
|
81
|
+
* touched. Not verbatim, twice over, and neither is worth chasing: the badge is
|
|
82
|
+
* HTML, which collapses whitespace, and it draws its text uppercased — so an
|
|
83
|
+
* operator reads the letters that arrived rather than the casing, exactly as they
|
|
84
|
+
* do for the three states the studio does have words for.
|
|
85
|
+
*/
|
|
86
|
+
export declare function deadLetterStatusLabel(status: string | null | undefined): string;
|
|
87
|
+
/**
|
|
88
|
+
* The classes a missed run's state badge is drawn with, on every surface that lists
|
|
89
|
+
* one.
|
|
90
|
+
*
|
|
91
|
+
* The colour half of {@link deadLetterStatusLabel}, reading the same map by the same
|
|
92
|
+
* exact match, so the two cannot disagree about which states the studio knows: a
|
|
93
|
+
* state named as unknown is drawn as unknown. Tones come from the shared palette,
|
|
94
|
+
* so this is one more vocabulary mapped into the studio's colours rather than a
|
|
95
|
+
* second set of colours.
|
|
96
|
+
*/
|
|
97
|
+
export declare function deadLetterStatusClass(status: string | null | undefined): string;
|
|
@@ -89,13 +89,39 @@ export function normalisedRunStatus(status) {
|
|
|
89
89
|
case "terminated":
|
|
90
90
|
case "timed_out":
|
|
91
91
|
return "failed";
|
|
92
|
+
// Temporal spells a cancellation the American way and the studio does not, so
|
|
93
|
+
// without this the *word* half of the promise fails on the surfaces that read
|
|
94
|
+
// the platform's answer directly: the row said `cancelled`, the record
|
|
95
|
+
// `canceled`, and in German the record said it in English.
|
|
96
|
+
case "canceled":
|
|
97
|
+
return "cancelled";
|
|
92
98
|
default:
|
|
93
99
|
return s;
|
|
94
100
|
}
|
|
95
101
|
}
|
|
102
|
+
export function runStatusClass(status) {
|
|
103
|
+
return statusClass(normalisedRunStatus(status));
|
|
104
|
+
}
|
|
96
105
|
export function runStatusLabel(status) {
|
|
97
106
|
const normalized = normalisedRunStatus(status);
|
|
98
107
|
if (!normalized) return "";
|
|
99
108
|
if (!RUN_STATUS_WORD_SET.has(normalized)) return normalized;
|
|
100
109
|
return useIntegrationsT()(`integration.runs.status.${normalized}`);
|
|
101
110
|
}
|
|
111
|
+
const MISSED_RUN_STATUS_TONE = /* @__PURE__ */ new Map([
|
|
112
|
+
["pending", "warning"],
|
|
113
|
+
["replayed", "success"],
|
|
114
|
+
["discarded", "neutral"]
|
|
115
|
+
]);
|
|
116
|
+
export function deadLetterStatusLabel(status) {
|
|
117
|
+
if (!status) return "";
|
|
118
|
+
const raw = String(status);
|
|
119
|
+
if (!MISSED_RUN_STATUS_TONE.has(raw)) {
|
|
120
|
+
return useIntegrationsT()("integration.deadLetters.status.unknown", { status: raw.trim() || raw });
|
|
121
|
+
}
|
|
122
|
+
return useIntegrationsT()(`integration.deadLetters.status.${raw}`);
|
|
123
|
+
}
|
|
124
|
+
export function deadLetterStatusClass(status) {
|
|
125
|
+
const tone = status ? MISSED_RUN_STATUS_TONE.get(String(status)) : void 0;
|
|
126
|
+
return toneClass(tone ?? "neutral");
|
|
127
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revenexx/studio-integrations",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Integration Studio (core: workflows, node editor, runs, schedules, credentials, secrets, audit) as a standalone, publishable Nuxt module.",
|
|
6
6
|
"repository": {
|