@revenexx/studio-integrations 0.5.1 → 0.7.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 +428 -0
- package/README.md +48 -4
- package/dist/module.d.mts +17 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +10 -2
- package/dist/runtime/components/Integrations/CredentialCreateDialog.vue +43 -41
- package/dist/runtime/components/Integrations/CredentialDetailDialog.vue +123 -50
- package/dist/runtime/components/Integrations/CredentialRevenexxSource.vue +108 -71
- package/dist/runtime/components/Integrations/CredentialTypePicker.vue +12 -15
- package/dist/runtime/components/Integrations/DeadLettersPanel.vue +18 -17
- package/dist/runtime/components/Integrations/EventTypeCombobox.d.vue.ts +1 -0
- package/dist/runtime/components/Integrations/EventTypeCombobox.vue +7 -4
- package/dist/runtime/components/Integrations/EventTypeCombobox.vue.d.ts +1 -0
- package/dist/runtime/components/Integrations/ExpressionInput.d.vue.ts +4 -0
- package/dist/runtime/components/Integrations/ExpressionInput.vue +67 -37
- package/dist/runtime/components/Integrations/ExpressionInput.vue.d.ts +4 -0
- package/dist/runtime/components/Integrations/GroupFrameView.vue +30 -20
- package/dist/runtime/components/Integrations/Layout.vue +48 -4
- package/dist/runtime/components/Integrations/NodeConfigDynamicField.vue +23 -23
- package/dist/runtime/components/Integrations/NodeConfigDynamicSchema.vue +11 -13
- package/dist/runtime/components/Integrations/NodeConfigField.d.vue.ts +2 -0
- package/dist/runtime/components/Integrations/NodeConfigField.vue +187 -93
- package/dist/runtime/components/Integrations/NodeConfigField.vue.d.ts +2 -0
- package/dist/runtime/components/Integrations/NodeInspector.d.vue.ts +6 -0
- package/dist/runtime/components/Integrations/NodeInspector.vue +1157 -376
- package/dist/runtime/components/Integrations/NodeInspector.vue.d.ts +6 -0
- package/dist/runtime/components/Integrations/NodeLogo.d.vue.ts +12 -0
- package/dist/runtime/components/Integrations/NodeLogo.vue +2 -30
- package/dist/runtime/components/Integrations/NodeLogo.vue.d.ts +12 -0
- package/dist/runtime/components/Integrations/NodeMark.d.vue.ts +15 -0
- package/dist/runtime/components/Integrations/NodeMark.vue +79 -0
- package/dist/runtime/components/Integrations/NodeMark.vue.d.ts +15 -0
- package/dist/runtime/components/Integrations/NodeOutputSchema.d.vue.ts +21 -0
- package/dist/runtime/components/Integrations/NodeOutputSchema.vue +43 -0
- package/dist/runtime/components/Integrations/NodeOutputSchema.vue.d.ts +21 -0
- package/dist/runtime/components/Integrations/NodePalette.vue +122 -55
- package/dist/runtime/components/Integrations/QueryBuilder.vue +46 -38
- package/dist/runtime/components/Integrations/RunActionsMenu.vue +38 -12
- package/dist/runtime/components/Integrations/RunDetailPanel.vue +114 -62
- package/dist/runtime/components/Integrations/RunPayloadInput.vue +27 -13
- package/dist/runtime/components/Integrations/RunResponseModal.vue +11 -10
- package/dist/runtime/components/Integrations/RunsTable.d.vue.ts +0 -1
- package/dist/runtime/components/Integrations/RunsTable.vue +38 -16
- package/dist/runtime/components/Integrations/RunsTable.vue.d.ts +0 -1
- package/dist/runtime/components/Integrations/SftpAccountImportDialog.vue +8 -7
- package/dist/runtime/components/Integrations/Sidebar.vue +14 -10
- package/dist/runtime/components/Integrations/StickyNoteView.d.vue.ts +14 -4
- package/dist/runtime/components/Integrations/StickyNoteView.vue +38 -23
- package/dist/runtime/components/Integrations/StickyNoteView.vue.d.ts +14 -4
- package/dist/runtime/components/Integrations/TemplateCard.d.vue.ts +18 -0
- package/dist/runtime/components/Integrations/TemplateCard.vue +119 -0
- package/dist/runtime/components/Integrations/TemplateCard.vue.d.ts +18 -0
- package/dist/runtime/components/Integrations/TemplateFlowPreview.d.vue.ts +2 -2
- package/dist/runtime/components/Integrations/TemplateFlowPreview.vue +16 -18
- package/dist/runtime/components/Integrations/TemplateFlowPreview.vue.d.ts +2 -2
- package/dist/runtime/components/Integrations/WorkflowContextMenu.vue +34 -33
- package/dist/runtime/components/Integrations/WorkflowCreateDialog.vue +52 -67
- package/dist/runtime/components/Integrations/WorkflowDuplicateDialog.vue +8 -7
- package/dist/runtime/components/Integrations/WorkflowEdgeView.d.vue.ts +18 -4
- package/dist/runtime/components/Integrations/WorkflowEdgeView.vue +29 -11
- package/dist/runtime/components/Integrations/WorkflowEdgeView.vue.d.ts +18 -4
- package/dist/runtime/components/Integrations/WorkflowEditor.d.vue.ts +20 -1
- package/dist/runtime/components/Integrations/WorkflowEditor.vue +240 -116
- package/dist/runtime/components/Integrations/WorkflowEditor.vue.d.ts +20 -1
- package/dist/runtime/components/Integrations/WorkflowHistoryPanel.vue +28 -43
- package/dist/runtime/components/Integrations/WorkflowIconPicker.d.vue.ts +19 -1
- package/dist/runtime/components/Integrations/WorkflowIconPicker.vue +17 -7
- package/dist/runtime/components/Integrations/WorkflowIconPicker.vue.d.ts +19 -1
- package/dist/runtime/components/Integrations/WorkflowNodeView.d.vue.ts +4 -0
- package/dist/runtime/components/Integrations/WorkflowNodeView.vue +198 -56
- package/dist/runtime/components/Integrations/WorkflowNodeView.vue.d.ts +4 -0
- package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.vue +56 -59
- package/dist/runtime/components/Integrations/WorkflowSettingsDialog.vue +28 -21
- package/dist/runtime/components/Integrations/WorkflowTagsInput.d.vue.ts +1 -0
- package/dist/runtime/components/Integrations/WorkflowTagsInput.vue +15 -9
- package/dist/runtime/components/Integrations/WorkflowTagsInput.vue.d.ts +1 -0
- package/dist/runtime/components/Integrations/WorkflowTriggerView.vue +15 -10
- package/dist/runtime/components/Integrations/WorkflowVariablesDialog.vue +50 -36
- package/dist/runtime/components/Integrations/WorkflowsTable.vue +126 -48
- package/dist/runtime/composables/integrationsApi.js +4 -2
- package/dist/runtime/composables/useCredentialTypes.js +8 -6
- package/dist/runtime/composables/useIntegrationsAudit.js +4 -3
- package/dist/runtime/composables/useIntegrationsCredentials.js +10 -8
- package/dist/runtime/composables/useIntegrationsDeadLetters.js +7 -6
- package/dist/runtime/composables/useIntegrationsFocus.d.ts +12 -0
- package/dist/runtime/composables/useIntegrationsLocale.d.ts +26 -0
- package/dist/runtime/composables/useIntegrationsLocale.js +8 -0
- package/dist/runtime/composables/useIntegrationsNodes.js +7 -5
- package/dist/runtime/composables/useIntegrationsRealtime.d.ts +149 -0
- package/dist/runtime/composables/useIntegrationsRealtime.js +80 -0
- package/dist/runtime/composables/useIntegrationsRevisions.js +9 -7
- package/dist/runtime/composables/useIntegrationsRuns.d.ts +1 -1
- package/dist/runtime/composables/useIntegrationsRuns.js +14 -7
- package/dist/runtime/composables/useIntegrationsSchedules.d.ts +4 -0
- package/dist/runtime/composables/useIntegrationsSchedules.js +10 -3
- package/dist/runtime/composables/useIntegrationsSecrets.js +14 -9
- package/dist/runtime/composables/useIntegrationsT.d.ts +35 -0
- package/dist/runtime/composables/useIntegrationsT.js +9 -0
- package/dist/runtime/composables/useIntegrationsTemplates.d.ts +3 -3
- package/dist/runtime/composables/useIntegrationsTemplates.js +28 -16
- package/dist/runtime/composables/useIntegrationsTriggers.js +10 -8
- package/dist/runtime/composables/useIntegrationsWorkflows.js +13 -7
- package/dist/runtime/composables/useLoadGate.d.ts +17 -0
- package/dist/runtime/composables/useLoadGate.js +8 -0
- package/dist/runtime/composables/useNodeConfigResolve.js +2 -1
- package/dist/runtime/data/branchReorder.d.ts +37 -0
- package/dist/runtime/data/branchReorder.js +71 -0
- package/dist/runtime/data/handleId.d.ts +23 -0
- package/dist/runtime/data/handleId.js +6 -0
- package/dist/runtime/data/integrationNodeCatalog.d.ts +41 -0
- package/dist/runtime/data/integrationNodeCatalog.js +14 -0
- package/dist/runtime/data/integrationTemplates.d.ts +48 -0
- package/dist/runtime/data/integrationTemplates.js +21 -0
- package/dist/runtime/data/integrationWorkflowSamples.js +1 -1
- package/dist/runtime/data/nodeIcons.d.ts +2 -0
- package/dist/runtime/data/nodeIcons.js +73 -0
- package/dist/runtime/data/nodeInputData.d.ts +16 -4
- package/dist/runtime/data/nodeInputData.js +4 -0
- package/dist/runtime/data/payloadForm.d.ts +9 -2
- package/dist/runtime/data/payloadForm.js +29 -4
- package/dist/runtime/data/portTone.d.ts +17 -0
- package/dist/runtime/data/portTone.js +7 -0
- package/dist/runtime/data/webhookAuth.d.ts +18 -0
- package/dist/runtime/data/webhookAuth.js +19 -0
- package/dist/runtime/data/workflowIconCatalog.js +4 -6
- package/dist/runtime/i18n/messages/de.json +1207 -0
- package/dist/runtime/i18n/messages/en.json +1207 -0
- package/dist/runtime/i18n/translate.d.ts +83 -0
- package/dist/runtime/i18n/translate.js +41 -0
- package/dist/runtime/pages/integrations/audit.vue +140 -37
- package/dist/runtime/pages/integrations/credentials/oauth-complete.vue +9 -6
- package/dist/runtime/pages/integrations/credentials.vue +180 -64
- package/dist/runtime/pages/integrations/index.vue +91 -92
- package/dist/runtime/pages/integrations/runs.vue +33 -21
- package/dist/runtime/pages/integrations/schedules.vue +88 -23
- package/dist/runtime/pages/integrations/secrets.vue +57 -35
- package/dist/runtime/pages/integrations/templates/[slug].vue +119 -88
- package/dist/runtime/pages/integrations/templates/index.vue +82 -103
- package/dist/runtime/pages/integrations/workflows/[id].vue +344 -91
- package/dist/runtime/pages/integrations/workflows/index.vue +23 -5
- package/dist/runtime/plugins/locale.d.ts +10 -0
- package/dist/runtime/plugins/locale.js +6 -0
- package/dist/runtime/plugins/realtime.client.d.ts +32 -0
- package/dist/runtime/plugins/realtime.client.js +4 -0
- package/dist/runtime/types/integrations.d.ts +65 -6
- package/dist/runtime/utils/apiError.d.ts +47 -0
- package/dist/runtime/utils/apiError.js +32 -0
- package/dist/runtime/utils/cockpitSources.d.ts +153 -0
- package/dist/runtime/utils/cockpitSources.js +14 -0
- package/dist/runtime/utils/credentialState.d.ts +24 -1
- package/dist/runtime/utils/credentialState.js +26 -11
- package/dist/runtime/utils/loadGate.d.ts +61 -0
- package/dist/runtime/utils/loadGate.js +22 -0
- package/dist/runtime/utils/localize.d.ts +46 -4
- package/dist/runtime/utils/localize.js +34 -7
- package/dist/runtime/utils/notify.d.ts +59 -0
- package/dist/runtime/utils/notify.js +21 -0
- package/dist/runtime/utils/pollBudget.d.ts +72 -0
- package/dist/runtime/utils/pollBudget.js +17 -0
- package/dist/runtime/utils/revenexxCredentialSource.d.ts +26 -0
- package/dist/runtime/utils/revenexxCredentialSource.js +8 -0
- package/dist/runtime/utils/schedule.d.ts +116 -0
- package/dist/runtime/utils/schedule.js +219 -0
- package/dist/runtime/utils/statusStyle.d.ts +26 -2
- package/dist/runtime/utils/statusStyle.js +9 -1
- package/dist/runtime/utils/validationFindings.d.ts +101 -0
- package/dist/runtime/utils/validationFindings.js +54 -0
- package/dist/runtime/utils/whenIdle.d.ts +42 -0
- package/dist/runtime/utils/whenIdle.js +12 -0
- package/dist/types.d.mts +2 -6
- package/package.json +10 -3
|
@@ -8,8 +8,27 @@ type __VLS_Props = {
|
|
|
8
8
|
runBusy?: boolean;
|
|
9
9
|
/** The run is queued behind a bundle build — busy, but worth saying why. */
|
|
10
10
|
runWaiting?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* One of the page's own lightboxes is open above the editor (settings,
|
|
13
|
+
* duplicate, run payload, the sync response, the deactivation prompt). The
|
|
14
|
+
* canvas stands its keyboard shortcuts down while one is up — see
|
|
15
|
+
* `canvasHasKeyboard` below. A new page-level dialog belongs in here too.
|
|
16
|
+
*/
|
|
17
|
+
overlayOpen?: boolean;
|
|
11
18
|
};
|
|
12
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Show a node the user was sent to from outside the canvas — the validation
|
|
21
|
+
* banner's per-node line (PO-209). Centres the card and opens its settings,
|
|
22
|
+
* which is where the fields at fault are.
|
|
23
|
+
*
|
|
24
|
+
* A node inside a collapsed group has no card on the canvas: centring would pan
|
|
25
|
+
* to empty space, so it only opens the settings. The reverse can't happen — an
|
|
26
|
+
* id that is on the canvas is in the blob by construction.
|
|
27
|
+
*/
|
|
28
|
+
declare function revealNode(id: string): void;
|
|
29
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {
|
|
30
|
+
revealNode: typeof revealNode;
|
|
31
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
13
32
|
change: (blob: WorkflowBlob) => any;
|
|
14
33
|
run: () => any;
|
|
15
34
|
toggleActive: () => any;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { computed, markRaw, nextTick, onMounted, provide, ref, watch } from "vue";
|
|
3
3
|
import {
|
|
4
4
|
MarkerType,
|
|
5
|
-
PanOnScrollMode,
|
|
6
5
|
VueFlow,
|
|
7
6
|
useVueFlow
|
|
8
7
|
} from "@vue-flow/core";
|
|
@@ -25,6 +24,7 @@ const props = defineProps({
|
|
|
25
24
|
});
|
|
26
25
|
const emit = defineEmits(["restored"]);
|
|
27
26
|
const revisionsApi = useIntegrationsRevisions();
|
|
27
|
+
const t = useIntegrationsT();
|
|
28
28
|
const entries = ref([]);
|
|
29
29
|
const page = ref(1);
|
|
30
30
|
const lastPage = ref(1);
|
|
@@ -65,24 +65,9 @@ function onResolvedOutputs(nodeId, outputs) {
|
|
|
65
65
|
const previewNodes = ref([]);
|
|
66
66
|
const previewEdges = ref([]);
|
|
67
67
|
const preview = useVueFlow("workflow-history-preview");
|
|
68
|
-
provide("workflow-node-actions",
|
|
69
|
-
}, remove: () => {
|
|
70
|
-
} });
|
|
68
|
+
provide("workflow-node-actions", null);
|
|
71
69
|
function edgeColorByKind(kind) {
|
|
72
|
-
|
|
73
|
-
case "success":
|
|
74
|
-
return "#10b981";
|
|
75
|
-
case "error":
|
|
76
|
-
return "#f43f5e";
|
|
77
|
-
case "branch-true":
|
|
78
|
-
return "#10b981";
|
|
79
|
-
case "branch-false":
|
|
80
|
-
return "#f59e0b";
|
|
81
|
-
case "branch":
|
|
82
|
-
return "#8b5cf6";
|
|
83
|
-
default:
|
|
84
|
-
return "#94a3b8";
|
|
85
|
-
}
|
|
70
|
+
return kind === "error" ? "#cbd5e1" : "#94a3b8";
|
|
86
71
|
}
|
|
87
72
|
const GROUP_PAD = 24;
|
|
88
73
|
const GROUP_LABEL_ROOM = 26;
|
|
@@ -126,7 +111,7 @@ function buildPreview(blob) {
|
|
|
126
111
|
const nodePos = (id) => {
|
|
127
112
|
const wn = blob.nodes.find((n) => n.id === id);
|
|
128
113
|
if (wn) return { x: wn.position?.x ?? 0, y: wn.position?.y ?? 0 };
|
|
129
|
-
const ti = blob.triggers.findIndex((
|
|
114
|
+
const ti = blob.triggers.findIndex((t2) => t2.id === id);
|
|
130
115
|
if (ti >= 0) return triggerPos(id, ti);
|
|
131
116
|
return { x: 0, y: 0 };
|
|
132
117
|
};
|
|
@@ -140,6 +125,7 @@ function buildPreview(blob) {
|
|
|
140
125
|
if (output === "true") return "branch-true";
|
|
141
126
|
if (output === "false") return "branch-false";
|
|
142
127
|
if (output === "error") return "error";
|
|
128
|
+
if (output === "done") return "success";
|
|
143
129
|
const outs = [...manifest.outputs ?? [], ...dynamicOutputs.value[sourceNodeId] ?? []];
|
|
144
130
|
const portDef = outs.find((o) => o.name === output);
|
|
145
131
|
if (portDef) {
|
|
@@ -164,16 +150,16 @@ function buildPreview(blob) {
|
|
|
164
150
|
position: { x: s.position.x, y: s.position.y },
|
|
165
151
|
zIndex: -100 + i,
|
|
166
152
|
draggable: false,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
153
|
+
// No callbacks: that absence is what makes the note read-only — it then
|
|
154
|
+
// draws no toolbar, no resize handle and does not open for typing (PO-284).
|
|
155
|
+
data: { sticky: s }
|
|
170
156
|
})),
|
|
171
|
-
...blob.triggers.map((
|
|
172
|
-
id:
|
|
157
|
+
...blob.triggers.map((t2, i) => ({
|
|
158
|
+
id: t2.id,
|
|
173
159
|
type: "trigger",
|
|
174
|
-
position: triggerPos(
|
|
160
|
+
position: triggerPos(t2.id, i),
|
|
175
161
|
draggable: false,
|
|
176
|
-
data:
|
|
162
|
+
data: t2
|
|
177
163
|
})),
|
|
178
164
|
...blob.nodes.map((n) => ({
|
|
179
165
|
id: n.id,
|
|
@@ -187,7 +173,7 @@ function buildPreview(blob) {
|
|
|
187
173
|
const kind = edgeKind(e.from.nodeId, e.from.output);
|
|
188
174
|
const wn = blob.nodes.find((n) => n.id === e.from.nodeId);
|
|
189
175
|
const manifest = wn ? findManifest(wn.nodeSlug, wn.nodeVersion) : null;
|
|
190
|
-
const isBranchPort = (manifest?.outputs ?? []).some((o) => o.sourceFromConfig) || ["true", "false"
|
|
176
|
+
const isBranchPort = (manifest?.outputs ?? []).some((o) => o.sourceFromConfig) || ["true", "false"].includes(e.from.output);
|
|
191
177
|
const srcSide = pickSourceSide(e.from.nodeId, e.to.nodeId);
|
|
192
178
|
return {
|
|
193
179
|
id: e.id,
|
|
@@ -233,23 +219,23 @@ async function select(revision) {
|
|
|
233
219
|
buildPreview(detail.blob);
|
|
234
220
|
}
|
|
235
221
|
} catch (e) {
|
|
236
|
-
toast.error(e?.message ?? "
|
|
222
|
+
toast.error(e?.message ?? t("integration.history.toast.loadRevisionFailed"));
|
|
237
223
|
} finally {
|
|
238
224
|
detailLoading.value = false;
|
|
239
225
|
}
|
|
240
226
|
}
|
|
241
227
|
async function restoreRevision(rev) {
|
|
242
|
-
if (!confirm(
|
|
228
|
+
if (!confirm(t("integration.history.confirm.restore", { revision: rev.revision }))) return;
|
|
243
229
|
restoring.value = rev.revision;
|
|
244
230
|
try {
|
|
245
231
|
await revisionsApi.restore(props.workflow.id, rev.revision);
|
|
246
|
-
toast.success(
|
|
232
|
+
toast.success(t("integration.history.toast.restored", { revision: rev.revision }));
|
|
247
233
|
detailCache.clear();
|
|
248
234
|
emit("restored");
|
|
249
235
|
await loadList(true);
|
|
250
236
|
void select(null);
|
|
251
237
|
} catch (e) {
|
|
252
|
-
toast.error(e?.message ?? "
|
|
238
|
+
toast.error(e?.message ?? t("integration.history.toast.restoreFailed"));
|
|
253
239
|
} finally {
|
|
254
240
|
restoring.value = null;
|
|
255
241
|
}
|
|
@@ -274,7 +260,7 @@ const nodeTypes = {
|
|
|
274
260
|
const edgeTypes = {
|
|
275
261
|
flow: markRaw(WorkflowEdgeView)
|
|
276
262
|
};
|
|
277
|
-
const previewTitle = computed(() => selected.value === null ?
|
|
263
|
+
const previewTitle = computed(() => selected.value === null ? t("integration.history.preview.title.current", { revision: props.workflow.revision }) : t("integration.history.preview.title.revision", { revision: selected.value }));
|
|
278
264
|
onMounted(() => {
|
|
279
265
|
void loadList(true);
|
|
280
266
|
void select(null);
|
|
@@ -296,7 +282,6 @@ onMounted(() => {
|
|
|
296
282
|
:nodes-connectable="false"
|
|
297
283
|
:elements-selectable="false"
|
|
298
284
|
:edges-updatable="false"
|
|
299
|
-
:pan-on-scroll-mode="PanOnScrollMode.Free"
|
|
300
285
|
:delete-key-code="null"
|
|
301
286
|
:min-zoom="0.25"
|
|
302
287
|
:max-zoom="2"
|
|
@@ -327,9 +312,9 @@ onMounted(() => {
|
|
|
327
312
|
<!-- Revision list -->
|
|
328
313
|
<aside class="flex w-80 shrink-0 flex-col border-l border-black/[0.06] bg-white">
|
|
329
314
|
<div class="border-b border-black/[0.06] px-3 py-2">
|
|
330
|
-
<div class="text-sm font-semibold">
|
|
315
|
+
<div class="text-sm font-semibold">{{ t("integration.history.heading.title") }}</div>
|
|
331
316
|
<p class="text-sm text-muted-foreground">
|
|
332
|
-
|
|
317
|
+
{{ t("integration.history.heading.description") }}
|
|
333
318
|
</p>
|
|
334
319
|
</div>
|
|
335
320
|
|
|
@@ -343,17 +328,17 @@ onMounted(() => {
|
|
|
343
328
|
>
|
|
344
329
|
<div class="flex items-center justify-between gap-2">
|
|
345
330
|
<span class="text-sm font-medium tabular-nums">{{ formatDateTime(workflow.updated_at) }}</span>
|
|
346
|
-
<Badge variant="outline" class="text-xs font-medium uppercase border-emerald-500/30 text-emerald-700">
|
|
331
|
+
<Badge variant="outline" class="text-xs font-medium uppercase border-emerald-500/30 text-emerald-700">{{ t("integration.history.badge.current") }}</Badge>
|
|
347
332
|
<Badge
|
|
348
333
|
variant="outline"
|
|
349
334
|
class="text-xs font-medium uppercase"
|
|
350
335
|
:class="workflow.active ? 'border-emerald-500/30 bg-emerald-500/10 text-emerald-700' : 'border-black/[0.08] text-muted-foreground'"
|
|
351
|
-
:title="workflow.active ? '
|
|
336
|
+
:title="workflow.active ? t('integration.history.badge.activeHint') : t('integration.history.badge.pausedHint')"
|
|
352
337
|
>
|
|
353
|
-
{{ workflow.active ? "
|
|
338
|
+
{{ workflow.active ? t("integration.history.badge.active") : t("integration.history.badge.paused") }}
|
|
354
339
|
</Badge>
|
|
355
340
|
</div>
|
|
356
|
-
<div class="mt-0.5 text-sm text-muted-foreground">
|
|
341
|
+
<div class="mt-0.5 text-sm text-muted-foreground">{{ t("integration.history.list.revisionLabel", { revision: workflow.revision }) }}</div>
|
|
357
342
|
</button>
|
|
358
343
|
|
|
359
344
|
<!-- Archived revisions -->
|
|
@@ -367,7 +352,7 @@ onMounted(() => {
|
|
|
367
352
|
<div class="flex items-center justify-between gap-2">
|
|
368
353
|
<span class="text-sm font-medium tabular-nums">{{ formatDateTime(rev.archived_at) }}</span>
|
|
369
354
|
</div>
|
|
370
|
-
<div class="mt-0.5 text-sm text-muted-foreground">
|
|
355
|
+
<div class="mt-0.5 text-sm text-muted-foreground">{{ t("integration.history.list.revisionLabel", { revision: rev.revision }) }}</div>
|
|
371
356
|
</button>
|
|
372
357
|
<div class="absolute right-2 top-1/2 -translate-y-1/2 opacity-0 transition group-hover:opacity-100">
|
|
373
358
|
<Button
|
|
@@ -378,13 +363,13 @@ onMounted(() => {
|
|
|
378
363
|
@click.stop="restoreRevision(rev)"
|
|
379
364
|
>
|
|
380
365
|
<Loader2 v-if="restoring === rev.revision" :size="11" class="mr-1 animate-spin" />
|
|
381
|
-
|
|
366
|
+
{{ t("integration.history.action.restore") }}
|
|
382
367
|
</Button>
|
|
383
368
|
</div>
|
|
384
369
|
</div>
|
|
385
370
|
|
|
386
371
|
<p v-if="!entries.length && !listLoading" class="px-2 py-6 text-center text-sm text-muted-foreground">
|
|
387
|
-
|
|
372
|
+
{{ t("integration.history.state.empty") }}
|
|
388
373
|
</p>
|
|
389
374
|
<p v-if="revisionsApi.error.value" class="px-2 py-2 text-sm text-rose-600">
|
|
390
375
|
{{ revisionsApi.error.value }}
|
|
@@ -409,7 +394,7 @@ onMounted(() => {
|
|
|
409
394
|
class="w-full text-sm"
|
|
410
395
|
@click="loadMore"
|
|
411
396
|
>
|
|
412
|
-
|
|
397
|
+
{{ t("integration.history.action.loadMore") }}
|
|
413
398
|
</Button>
|
|
414
399
|
</div>
|
|
415
400
|
</aside>
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import type { WorkflowIcon } from '../../types/integrations.js';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* The caller names the picker by pointing at its own `<Label>`'s id — not with
|
|
4
|
+
* `<Label for>`, and not with an `id` of ours on the trigger.
|
|
5
|
+
*
|
|
6
|
+
* An `id` on the trigger would be a quiet regression: `PopoverTrigger` puts
|
|
7
|
+
* reka-ui's generated `triggerId` there, `PopoverContentImpl` points the opened
|
|
8
|
+
* dialog's `aria-labelledby` at exactly that id, and reka's `Slot` merges with
|
|
9
|
+
* the *child's* props winning — so ours would replace it and leave the popover
|
|
10
|
+
* naming an element that no longer exists.
|
|
11
|
+
*
|
|
12
|
+
* `aria-labelledby` also lists the id of the span holding the current choice, so
|
|
13
|
+
* the name stays "Icon Business Central" rather than dropping the value the way
|
|
14
|
+
* a plain label would. Attribute fallthrough is no help here either: the root
|
|
15
|
+
* this component renders is the popover, not the button.
|
|
16
|
+
*/
|
|
17
|
+
type __VLS_Props = {
|
|
18
|
+
triggerLabelledby?: string;
|
|
19
|
+
};
|
|
20
|
+
type __VLS_PublicProps = __VLS_Props & {
|
|
3
21
|
modelValue?: WorkflowIcon | null;
|
|
4
22
|
};
|
|
5
23
|
declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, ref } from "vue";
|
|
2
|
+
import { computed, ref, useId } from "vue";
|
|
3
3
|
import { AltArrowDown as ChevronDown } from "#solar-icons";
|
|
4
4
|
import { Popover, PopoverContent, PopoverTrigger } from "@revenexx/studio";
|
|
5
5
|
import { WORKFLOW_SOLAR_ICONS, imageIdFromSrc, nodeLogoOptions } from "../../data/workflowIconCatalog";
|
|
6
6
|
import WorkflowIconView from "./WorkflowIconView.vue";
|
|
7
7
|
const model = defineModel({ type: [Object, null], ...{ default: null } });
|
|
8
|
+
const props = defineProps({
|
|
9
|
+
triggerLabelledby: { type: String, required: false }
|
|
10
|
+
});
|
|
11
|
+
const t = useIntegrationsT();
|
|
12
|
+
const valueId = useId();
|
|
13
|
+
const triggerLabelledby = computed(
|
|
14
|
+
() => props.triggerLabelledby ? `${props.triggerLabelledby} ${valueId}` : void 0
|
|
15
|
+
);
|
|
8
16
|
const open = ref(false);
|
|
9
17
|
const logos = computed(() => nodeLogoOptions());
|
|
10
18
|
function pick(icon) {
|
|
@@ -19,10 +27,10 @@ function isImage(id) {
|
|
|
19
27
|
return (imageIdFromSrc(model.value.src) ?? model.value.src) === id;
|
|
20
28
|
}
|
|
21
29
|
const selectedLabel = computed(() => {
|
|
22
|
-
if (!model.value) return "
|
|
23
|
-
if (model.value.kind === "solar") return model.value.name ?? "
|
|
30
|
+
if (!model.value) return t("integration.workflows.iconPicker.label.default");
|
|
31
|
+
if (model.value.kind === "solar") return model.value.name ?? t("integration.workflows.iconPicker.label.iconFallback");
|
|
24
32
|
const id = imageIdFromSrc(model.value.src) ?? model.value.src;
|
|
25
|
-
return logos.value.find((l) => l.id === id)?.label ?? "
|
|
33
|
+
return logos.value.find((l) => l.id === id)?.label ?? t("integration.workflows.iconPicker.label.imageFallback");
|
|
26
34
|
});
|
|
27
35
|
</script>
|
|
28
36
|
|
|
@@ -30,13 +38,14 @@ const selectedLabel = computed(() => {
|
|
|
30
38
|
<Popover v-model:open="open">
|
|
31
39
|
<PopoverTrigger as-child>
|
|
32
40
|
<button
|
|
41
|
+
:aria-labelledby="triggerLabelledby"
|
|
33
42
|
type="button"
|
|
34
43
|
class="flex h-9 w-full items-center gap-2 rounded-md border border-black/[0.08] bg-white px-2.5 text-left text-sm transition hover:border-black/20"
|
|
35
44
|
>
|
|
36
45
|
<span class="flex size-6 shrink-0 items-center justify-center rounded-md bg-slate-100 text-slate-500">
|
|
37
46
|
<WorkflowIconView :icon="model" :size="14" />
|
|
38
47
|
</span>
|
|
39
|
-
<span class="min-w-0 flex-1 truncate" :class="model ? '' : 'text-muted-foreground'">
|
|
48
|
+
<span :id="valueId" class="min-w-0 flex-1 truncate" :class="model ? '' : 'text-muted-foreground'">
|
|
40
49
|
{{ selectedLabel }}
|
|
41
50
|
</span>
|
|
42
51
|
<ChevronDown :size="14" class="shrink-0 text-muted-foreground" />
|
|
@@ -49,7 +58,8 @@ const selectedLabel = computed(() => {
|
|
|
49
58
|
type="button"
|
|
50
59
|
class="flex size-8 items-center justify-center rounded-md border text-sm text-muted-foreground transition hover:bg-muted/50"
|
|
51
60
|
:class="!model ? 'border-emerald-500/40 bg-emerald-500/10' : 'border-transparent'"
|
|
52
|
-
title="
|
|
61
|
+
:title="t('integration.workflows.iconPicker.action.none')"
|
|
62
|
+
:aria-label="t('integration.workflows.iconPicker.action.none')"
|
|
53
63
|
@click="pick(null)"
|
|
54
64
|
>
|
|
55
65
|
—
|
|
@@ -68,7 +78,7 @@ const selectedLabel = computed(() => {
|
|
|
68
78
|
</div>
|
|
69
79
|
|
|
70
80
|
<template v-if="logos.length">
|
|
71
|
-
<div class="text-mono text-muted-foreground">
|
|
81
|
+
<div class="text-mono text-muted-foreground">{{ t("integration.workflows.iconPicker.section.integrations") }}</div>
|
|
72
82
|
<div class="flex flex-wrap gap-1">
|
|
73
83
|
<button
|
|
74
84
|
v-for="l in logos"
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import type { WorkflowIcon } from '../../types/integrations.js';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* The caller names the picker by pointing at its own `<Label>`'s id — not with
|
|
4
|
+
* `<Label for>`, and not with an `id` of ours on the trigger.
|
|
5
|
+
*
|
|
6
|
+
* An `id` on the trigger would be a quiet regression: `PopoverTrigger` puts
|
|
7
|
+
* reka-ui's generated `triggerId` there, `PopoverContentImpl` points the opened
|
|
8
|
+
* dialog's `aria-labelledby` at exactly that id, and reka's `Slot` merges with
|
|
9
|
+
* the *child's* props winning — so ours would replace it and leave the popover
|
|
10
|
+
* naming an element that no longer exists.
|
|
11
|
+
*
|
|
12
|
+
* `aria-labelledby` also lists the id of the span holding the current choice, so
|
|
13
|
+
* the name stays "Icon Business Central" rather than dropping the value the way
|
|
14
|
+
* a plain label would. Attribute fallthrough is no help here either: the root
|
|
15
|
+
* this component renders is the popover, not the button.
|
|
16
|
+
*/
|
|
17
|
+
type __VLS_Props = {
|
|
18
|
+
triggerLabelledby?: string;
|
|
19
|
+
};
|
|
20
|
+
type __VLS_PublicProps = __VLS_Props & {
|
|
3
21
|
modelValue?: WorkflowIcon | null;
|
|
4
22
|
};
|
|
5
23
|
declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
@@ -5,6 +5,10 @@ interface NodeData extends WorkflowNode {
|
|
|
5
5
|
* editor without persisting to the blob. When present and non-empty, these
|
|
6
6
|
* drive the rendered handles instead of the static manifest computation. */
|
|
7
7
|
__resolvedOutputs?: NodeManifestOutput[];
|
|
8
|
+
/** Config keys the backend reported as incomplete at the last save (PO-209),
|
|
9
|
+
* injected by the editor the same non-persisting way. Read-only canvases
|
|
10
|
+
* (run replay, history preview) never pass them, so nothing is marked there. */
|
|
11
|
+
__invalidFields?: string[];
|
|
8
12
|
}
|
|
9
13
|
type __VLS_Props = {
|
|
10
14
|
id: string;
|