@revenexx/studio-integrations 0.6.0 → 1.0.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 +643 -0
- package/README.md +31 -0
- package/dist/module.d.mts +17 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +12 -3
- package/dist/runtime/components/Integrations/CredentialCreateDialog.vue +32 -28
- package/dist/runtime/components/Integrations/CredentialDetailDialog.vue +45 -38
- package/dist/runtime/components/Integrations/CredentialRevenexxSource.vue +58 -58
- package/dist/runtime/components/Integrations/CredentialTypePicker.vue +10 -9
- package/dist/runtime/components/Integrations/DeadLettersPanel.vue +18 -17
- package/dist/runtime/components/Integrations/EventTypeCombobox.vue +4 -3
- package/dist/runtime/components/Integrations/ExpressionInput.vue +21 -15
- package/dist/runtime/components/Integrations/GroupFrameView.vue +29 -19
- package/dist/runtime/components/Integrations/Layout.vue +28 -3
- package/dist/runtime/components/Integrations/NodeConfigDynamicField.d.vue.ts +3 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicField.vue +30 -16
- package/dist/runtime/components/Integrations/NodeConfigDynamicField.vue.d.ts +3 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicSchema.vue +10 -8
- package/dist/runtime/components/Integrations/NodeConfigField.d.vue.ts +3 -0
- package/dist/runtime/components/Integrations/NodeConfigField.vue +45 -42
- 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 +315 -221
- 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 +37 -10
- package/dist/runtime/components/Integrations/NodeOutputSchema.vue.d.ts +2 -1
- package/dist/runtime/components/Integrations/NodePalette.vue +40 -35
- package/dist/runtime/components/Integrations/QueryBuilder.vue +44 -43
- package/dist/runtime/components/Integrations/RunActionsMenu.vue +36 -12
- package/dist/runtime/components/Integrations/RunDetailPanel.vue +114 -62
- package/dist/runtime/components/Integrations/RunPayloadInput.vue +14 -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 +82 -34
- package/dist/runtime/components/Integrations/StickyNoteView.vue.d.ts +14 -4
- 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 +18 -8
- package/dist/runtime/components/Integrations/TemplateFlowPreview.vue +22 -12
- package/dist/runtime/components/Integrations/WorkflowContextMenu.vue +34 -33
- package/dist/runtime/components/Integrations/WorkflowCreateDialog.vue +41 -39
- package/dist/runtime/components/Integrations/WorkflowDuplicateDialog.vue +8 -7
- package/dist/runtime/components/Integrations/WorkflowEdgeView.vue +6 -4
- package/dist/runtime/components/Integrations/WorkflowEditor.d.vue.ts +16 -0
- package/dist/runtime/components/Integrations/WorkflowEditor.vue +131 -87
- 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 +27 -24
- package/dist/runtime/components/Integrations/WorkflowHistoryPanel.vue.d.ts +6 -0
- package/dist/runtime/components/Integrations/WorkflowIconPicker.vue +7 -6
- package/dist/runtime/components/Integrations/WorkflowNodeView.vue +76 -46
- package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.vue +55 -43
- package/dist/runtime/components/Integrations/WorkflowSettingsDialog.d.vue.ts +16 -17
- package/dist/runtime/components/Integrations/WorkflowSettingsDialog.vue +55 -43
- package/dist/runtime/components/Integrations/WorkflowSettingsDialog.vue.d.ts +16 -17
- package/dist/runtime/components/Integrations/WorkflowTagsInput.vue +9 -8
- package/dist/runtime/components/Integrations/WorkflowTriggerView.vue +15 -13
- package/dist/runtime/components/Integrations/WorkflowVariablesDialog.vue +79 -39
- package/dist/runtime/components/Integrations/WorkflowsTable.vue +83 -45
- package/dist/runtime/composables/integrationsApi.js +4 -2
- package/dist/runtime/composables/useCredentialTypes.js +4 -2
- package/dist/runtime/composables/useIntegrationsCredentials.d.ts +11 -0
- package/dist/runtime/composables/useIntegrationsCredentials.js +8 -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 +14 -2
- 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 +3 -1
- package/dist/runtime/composables/useIntegrationsSchedules.d.ts +3 -2
- package/dist/runtime/composables/useIntegrationsSecrets.js +4 -2
- 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 +16 -8
- package/dist/runtime/composables/useIntegrationsTriggers.d.ts +23 -3
- package/dist/runtime/composables/useIntegrationsTriggers.js +21 -8
- package/dist/runtime/composables/useIntegrationsWorkflows.d.ts +10 -1
- package/dist/runtime/composables/useIntegrationsWorkflows.js +30 -7
- package/dist/runtime/composables/useNodeConfigResolve.js +4 -2
- package/dist/runtime/data/integrationNodeCatalog.d.ts +63 -1
- package/dist/runtime/data/integrationNodeCatalog.js +22 -4
- package/dist/runtime/data/integrationTemplates.d.ts +9 -0
- package/dist/runtime/data/integrationTemplates.js +7 -1
- package/dist/runtime/data/nodeInputData.d.ts +58 -1
- package/dist/runtime/data/nodeInputData.js +30 -5
- package/dist/runtime/data/payloadForm.js +2 -1
- package/dist/runtime/data/triggerGlyphs.d.ts +47 -0
- package/dist/runtime/data/triggerGlyphs.js +11 -0
- package/dist/runtime/data/workflowIconCatalog.js +2 -1
- package/dist/runtime/i18n/messages/de.json +1224 -0
- package/dist/runtime/i18n/messages/en.json +1224 -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 +52 -34
- package/dist/runtime/pages/integrations/credentials/oauth-complete.vue +3 -2
- package/dist/runtime/pages/integrations/credentials.vue +73 -52
- package/dist/runtime/pages/integrations/index.vue +66 -73
- package/dist/runtime/pages/integrations/runs.vue +33 -21
- package/dist/runtime/pages/integrations/schedules.vue +49 -28
- package/dist/runtime/pages/integrations/secrets.vue +34 -34
- package/dist/runtime/pages/integrations/templates/[slug].vue +89 -72
- package/dist/runtime/pages/integrations/templates/index.vue +35 -27
- package/dist/runtime/pages/integrations/workflows/[id].vue +351 -197
- package/dist/runtime/pages/integrations/workflows/index.vue +10 -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 +25 -1
- package/dist/runtime/utils/cockpitSources.d.ts +22 -3
- package/dist/runtime/utils/credentialState.d.ts +30 -2
- package/dist/runtime/utils/credentialState.js +26 -11
- package/dist/runtime/utils/localize.d.ts +52 -5
- package/dist/runtime/utils/localize.js +47 -9
- package/dist/runtime/utils/pollBudget.d.ts +72 -0
- package/dist/runtime/utils/pollBudget.js +17 -0
- package/dist/runtime/utils/schedule.d.ts +0 -25
- package/dist/runtime/utils/schedule.js +37 -25
- package/dist/runtime/utils/servedPaths.d.ts +22 -0
- package/dist/runtime/utils/servedPaths.js +3 -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 +2 -2
- package/dist/runtime/utils/validationFindings.js +4 -3
- package/dist/types.d.mts +2 -6
- package/package.json +3 -2
|
@@ -4,11 +4,13 @@ import { Download as DownloadIcon, RefreshCircle as RefreshIcon } from "#solar-i
|
|
|
4
4
|
import { Badge, Button, Dialog, DialogContent, DialogHeader, DialogTitle } from "@revenexx/studio";
|
|
5
5
|
import { runStatusLabel, statusClass } from "../../utils/statusStyle";
|
|
6
6
|
import { IntegrationsApiError } from "../../utils/apiError";
|
|
7
|
+
import { createPollBudget, SAFETY_POLL_MS } from "../../utils/pollBudget";
|
|
7
8
|
const props = defineProps({
|
|
8
9
|
run: { type: Object, required: true },
|
|
9
10
|
view: { type: String, required: false, default: "details" }
|
|
10
11
|
});
|
|
11
12
|
const emit = defineEmits(["changed"]);
|
|
13
|
+
const t = useIntegrationsT();
|
|
12
14
|
const {
|
|
13
15
|
getRun,
|
|
14
16
|
getDetails,
|
|
@@ -23,6 +25,9 @@ const {
|
|
|
23
25
|
const DETAILS_POLL_MS = 3e3;
|
|
24
26
|
const HISTORY_POLL_MS = 1e4;
|
|
25
27
|
const HISTORY_PAGE_SIZE = 50;
|
|
28
|
+
const { delivering: realtimeDelivering, runTick, lastRunEvent } = useIntegrationsRealtime();
|
|
29
|
+
const summaryBudget = createPollBudget({ intervalMs: DETAILS_POLL_MS, liveIntervalMs: SAFETY_POLL_MS });
|
|
30
|
+
const historyBudget = createPollBudget({ intervalMs: HISTORY_POLL_MS, liveIntervalMs: SAFETY_POLL_MS });
|
|
26
31
|
const COCKPIT_TERMINAL = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled"]);
|
|
27
32
|
const API_TERMINAL = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "terminated", "timed_out"]);
|
|
28
33
|
const runData = ref(null);
|
|
@@ -127,9 +132,9 @@ function eventAttributes(ev) {
|
|
|
127
132
|
return pick(ev, ["attributes"]);
|
|
128
133
|
}
|
|
129
134
|
function eventColor(type) {
|
|
130
|
-
const
|
|
131
|
-
if (
|
|
132
|
-
if (
|
|
135
|
+
const t2 = type.toLowerCase();
|
|
136
|
+
if (t2.includes("failed") || t2.includes("terminated")) return "text-rose-600";
|
|
137
|
+
if (t2.includes("completed")) return "text-emerald-600";
|
|
133
138
|
return "text-foreground";
|
|
134
139
|
}
|
|
135
140
|
function statusOf(e) {
|
|
@@ -141,29 +146,29 @@ function genericMsg(e, fallback) {
|
|
|
141
146
|
}
|
|
142
147
|
function detailsErrMsg(e) {
|
|
143
148
|
const s = statusOf(e);
|
|
144
|
-
if (s === 410) return "
|
|
145
|
-
if (s === 503) return "
|
|
146
|
-
return genericMsg(e, "
|
|
149
|
+
if (s === 410) return t("integration.runs.detail.error.details.expired");
|
|
150
|
+
if (s === 503) return t("integration.runs.detail.error.details.unavailable");
|
|
151
|
+
return genericMsg(e, t("integration.runs.detail.error.details.generic"));
|
|
147
152
|
}
|
|
148
153
|
function historyErrMsg(e) {
|
|
149
154
|
const s = statusOf(e);
|
|
150
|
-
if (s === 410) return "
|
|
151
|
-
if (s === 422) return "
|
|
152
|
-
return genericMsg(e, "
|
|
155
|
+
if (s === 410) return t("integration.runs.detail.error.history.expired");
|
|
156
|
+
if (s === 422) return t("integration.runs.detail.error.history.cursorInvalid");
|
|
157
|
+
return genericMsg(e, t("integration.runs.detail.error.history.generic"));
|
|
153
158
|
}
|
|
154
159
|
function stackErrMsg(e) {
|
|
155
160
|
const s = statusOf(e);
|
|
156
|
-
if (s === 409) return "
|
|
157
|
-
if (s === 410) return "
|
|
158
|
-
if (s === 503) return "
|
|
159
|
-
return genericMsg(e, "
|
|
161
|
+
if (s === 409) return t("integration.runs.detail.error.stack.notRunning");
|
|
162
|
+
if (s === 410) return t("integration.runs.detail.error.stack.unknown");
|
|
163
|
+
if (s === 503) return t("integration.runs.detail.error.stack.unavailable");
|
|
164
|
+
return genericMsg(e, t("integration.runs.detail.error.stack.generic"));
|
|
160
165
|
}
|
|
161
166
|
function stepsErrMsg(e) {
|
|
162
167
|
const s = statusOf(e);
|
|
163
|
-
if (s === 409) return "
|
|
164
|
-
if (s === 410) return "
|
|
165
|
-
if (s === 503) return "
|
|
166
|
-
return genericMsg(e, "
|
|
168
|
+
if (s === 409) return t("integration.runs.detail.notHandedOff");
|
|
169
|
+
if (s === 410) return t("integration.runs.detail.error.steps.expired");
|
|
170
|
+
if (s === 503) return t("integration.runs.detail.error.details.unavailable");
|
|
171
|
+
return genericMsg(e, t("integration.runs.detail.error.steps.generic"));
|
|
167
172
|
}
|
|
168
173
|
function fmtMs(ms) {
|
|
169
174
|
if (ms == null) return "\u2014";
|
|
@@ -174,7 +179,7 @@ function fmtMs(ms) {
|
|
|
174
179
|
function activityName(a) {
|
|
175
180
|
const at = a ? a.activity_type ?? a.activityType : void 0;
|
|
176
181
|
if (typeof at === "string") return at;
|
|
177
|
-
return pickStr(at, ["name"]) ?? "
|
|
182
|
+
return pickStr(at, ["name"]) ?? t("integration.runs.detail.timeline.label.activity");
|
|
178
183
|
}
|
|
179
184
|
const timeline = computed(() => {
|
|
180
185
|
const evs = timelineEvents.value;
|
|
@@ -189,7 +194,7 @@ const timeline = computed(() => {
|
|
|
189
194
|
const ts = timeOf(ev);
|
|
190
195
|
if (!Number.isFinite(ts)) continue;
|
|
191
196
|
if (type === "workflow_execution_started") {
|
|
192
|
-
wf = { label: "
|
|
197
|
+
wf = { label: t("integration.runs.detail.timeline.label.workflow"), kind: "workflow", sched: ts, start: ts, end: null, ok: true, events: [ev] };
|
|
193
198
|
} else if (type.startsWith("workflow_execution_")) {
|
|
194
199
|
if (wf) {
|
|
195
200
|
wf.end = ts;
|
|
@@ -199,7 +204,7 @@ const timeline = computed(() => {
|
|
|
199
204
|
} else if (type === "activity_task_scheduled") {
|
|
200
205
|
cycles.set(eventId(ev), { label: activityName(attrsOf(ev)), kind: "activity", sched: ts, start: null, end: null, ok: true, events: [ev] });
|
|
201
206
|
} else if (type === "workflow_task_scheduled") {
|
|
202
|
-
cycles.set(eventId(ev), { label: "
|
|
207
|
+
cycles.set(eventId(ev), { label: t("integration.runs.detail.timeline.label.workflowTask"), kind: "wf-task", sched: ts, start: null, end: null, ok: true, events: [ev] });
|
|
203
208
|
} else if (type === "activity_task_started" || type === "workflow_task_started") {
|
|
204
209
|
const c = cycles.get(refOf(ev, ["scheduled_event_id", "scheduledEventId"]));
|
|
205
210
|
if (c) {
|
|
@@ -214,7 +219,7 @@ const timeline = computed(() => {
|
|
|
214
219
|
c.events.push(ev);
|
|
215
220
|
}
|
|
216
221
|
} else if (type === "timer_started") {
|
|
217
|
-
cycles.set(eventId(ev), { label: "
|
|
222
|
+
cycles.set(eventId(ev), { label: t("integration.runs.detail.timeline.label.timer"), kind: "timer", sched: ts, start: ts, end: null, ok: true, events: [ev] });
|
|
218
223
|
} else if (type === "timer_fired" || type === "timer_canceled") {
|
|
219
224
|
const c = cycles.get(refOf(ev, ["started_event_id", "startedEventId"]));
|
|
220
225
|
if (c) {
|
|
@@ -266,8 +271,8 @@ function timelineBarClass(row) {
|
|
|
266
271
|
}
|
|
267
272
|
const timelineDetail = ref(null);
|
|
268
273
|
function timelineRowStatus(row) {
|
|
269
|
-
if (row.durationMs == null) return "running";
|
|
270
|
-
return row.ok ? "succeeded" : "failed";
|
|
274
|
+
if (row.durationMs == null) return t("integration.runs.status.running");
|
|
275
|
+
return t(row.ok ? "integration.runs.status.succeeded" : "integration.runs.status.failed");
|
|
271
276
|
}
|
|
272
277
|
function fmtClock(ms) {
|
|
273
278
|
try {
|
|
@@ -277,6 +282,7 @@ function fmtClock(ms) {
|
|
|
277
282
|
}
|
|
278
283
|
}
|
|
279
284
|
async function loadSummary() {
|
|
285
|
+
summaryBudget.spend();
|
|
280
286
|
summaryLoading.value = true;
|
|
281
287
|
summaryError.value = null;
|
|
282
288
|
try {
|
|
@@ -353,6 +359,7 @@ async function loadTimelineEvents() {
|
|
|
353
359
|
historyError.value = null;
|
|
354
360
|
return;
|
|
355
361
|
}
|
|
362
|
+
historyBudget.spend();
|
|
356
363
|
if (!timelineEvents.value.length) historyLoading.value = true;
|
|
357
364
|
historyError.value = null;
|
|
358
365
|
try {
|
|
@@ -389,6 +396,7 @@ function startPollingIfNeeded() {
|
|
|
389
396
|
stopPolling();
|
|
390
397
|
if (isTerminal.value) return;
|
|
391
398
|
summaryTimer = setInterval(() => {
|
|
399
|
+
if (!summaryBudget.due(realtimeDelivering.value)) return;
|
|
392
400
|
void loadSummary().then(() => {
|
|
393
401
|
if (isTerminal.value) {
|
|
394
402
|
stopPolling();
|
|
@@ -399,9 +407,23 @@ function startPollingIfNeeded() {
|
|
|
399
407
|
});
|
|
400
408
|
}, DETAILS_POLL_MS);
|
|
401
409
|
historyTimer = setInterval(() => {
|
|
410
|
+
if (!historyBudget.due(realtimeDelivering.value)) return;
|
|
402
411
|
void loadTimelineEvents();
|
|
403
412
|
}, HISTORY_POLL_MS);
|
|
404
413
|
}
|
|
414
|
+
function refreshFromEvent() {
|
|
415
|
+
void loadSummary().then(() => {
|
|
416
|
+
if (isTerminal.value) stopPolling();
|
|
417
|
+
void loadDetails();
|
|
418
|
+
void loadSteps();
|
|
419
|
+
});
|
|
420
|
+
void loadTimelineEvents();
|
|
421
|
+
}
|
|
422
|
+
watch(runTick, () => {
|
|
423
|
+
const event = lastRunEvent.value;
|
|
424
|
+
if (event && event.topicId !== props.run.id) return;
|
|
425
|
+
refreshFromEvent();
|
|
426
|
+
});
|
|
405
427
|
function resetState() {
|
|
406
428
|
runData.value = null;
|
|
407
429
|
summaryError.value = null;
|
|
@@ -422,12 +444,42 @@ function resetState() {
|
|
|
422
444
|
actionError.value = null;
|
|
423
445
|
actionNotice.value = null;
|
|
424
446
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
447
|
+
function actionLabel(a) {
|
|
448
|
+
switch (a) {
|
|
449
|
+
case "cancel":
|
|
450
|
+
return t("integration.runs.action.cancel");
|
|
451
|
+
case "terminate":
|
|
452
|
+
return t("integration.runs.action.terminate");
|
|
453
|
+
case "retry":
|
|
454
|
+
return t("integration.runs.action.retry");
|
|
455
|
+
case "resume":
|
|
456
|
+
return t("integration.runs.action.resume");
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
function confirmQuestion(a) {
|
|
460
|
+
switch (a) {
|
|
461
|
+
case "cancel":
|
|
462
|
+
return t("integration.runs.confirm.cancel");
|
|
463
|
+
case "terminate":
|
|
464
|
+
return t("integration.runs.confirm.terminate");
|
|
465
|
+
case "retry":
|
|
466
|
+
return t("integration.runs.confirm.retry");
|
|
467
|
+
case "resume":
|
|
468
|
+
return t("integration.runs.confirm.resume");
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
function actionErrorFallback(a) {
|
|
472
|
+
switch (a) {
|
|
473
|
+
case "cancel":
|
|
474
|
+
return t("integration.runs.error.cancel");
|
|
475
|
+
case "terminate":
|
|
476
|
+
return t("integration.runs.error.terminate");
|
|
477
|
+
case "retry":
|
|
478
|
+
return t("integration.runs.error.retry");
|
|
479
|
+
case "resume":
|
|
480
|
+
return t("integration.runs.error.resume");
|
|
481
|
+
}
|
|
482
|
+
}
|
|
431
483
|
const apiStatusRaw = computed(() => pickStr(runData.value, ["status"]));
|
|
432
484
|
const isActive = computed(() => !isTerminal.value);
|
|
433
485
|
const canStop = computed(() => isActive.value && hasTemporal.value);
|
|
@@ -476,13 +528,13 @@ async function confirmAction() {
|
|
|
476
528
|
break;
|
|
477
529
|
}
|
|
478
530
|
const newId = pickStr(res, ["id"]);
|
|
479
|
-
actionNotice.value = (a === "retry" || a === "resume") && newId && newId !== String(props.run.id) ?
|
|
531
|
+
actionNotice.value = (a === "retry" || a === "resume") && newId && newId !== String(props.run.id) ? t("integration.runs.notice.started", { id: newId }) : t("integration.runs.notice.requested", { action: actionLabel(a) });
|
|
480
532
|
armed.value = null;
|
|
481
533
|
await loadAll();
|
|
482
534
|
startPollingIfNeeded();
|
|
483
535
|
emit("changed");
|
|
484
536
|
} catch (e) {
|
|
485
|
-
actionError.value = genericMsg(e,
|
|
537
|
+
actionError.value = genericMsg(e, actionErrorFallback(a));
|
|
486
538
|
} finally {
|
|
487
539
|
actionBusy.value = false;
|
|
488
540
|
}
|
|
@@ -498,7 +550,7 @@ async function confirmAction() {
|
|
|
498
550
|
<div v-if="hasActions" class="flex items-center gap-2">
|
|
499
551
|
<!-- confirm step: one click arms, second confirms -->
|
|
500
552
|
<template v-if="armed">
|
|
501
|
-
<span class="text-sm text-muted-foreground">{{
|
|
553
|
+
<span class="text-sm text-muted-foreground">{{ confirmQuestion(armed) }}</span>
|
|
502
554
|
<Button
|
|
503
555
|
size="sm"
|
|
504
556
|
:class="armed === 'terminate' ? 'bg-rose-600 hover:bg-rose-700 text-white' : ''"
|
|
@@ -506,14 +558,14 @@ async function confirmAction() {
|
|
|
506
558
|
@click="confirmAction"
|
|
507
559
|
>
|
|
508
560
|
<RefreshIcon v-if="actionBusy" :size="14" class="mr-1 animate-spin" />
|
|
509
|
-
|
|
561
|
+
{{ t("integration.common.action.confirm") }}
|
|
510
562
|
</Button>
|
|
511
|
-
<Button variant="ghost" size="sm" :disabled="actionBusy" @click="disarm">
|
|
563
|
+
<Button variant="ghost" size="sm" :disabled="actionBusy" @click="disarm">{{ t("integration.runs.action.back") }}</Button>
|
|
512
564
|
</template>
|
|
513
565
|
<template v-else>
|
|
514
|
-
<Button v-if="canStop" variant="outline" size="sm" @click="arm('cancel')">
|
|
515
|
-
<Button v-if="canStop" variant="outline" size="sm" class="text-rose-600 hover:bg-rose-500/10" @click="arm('terminate')">
|
|
516
|
-
<Button v-if="canResume" variant="outline" size="sm" @click="arm('resume')">
|
|
566
|
+
<Button v-if="canStop" variant="outline" size="sm" @click="arm('cancel')">{{ actionLabel("cancel") }}</Button>
|
|
567
|
+
<Button v-if="canStop" variant="outline" size="sm" class="text-rose-600 hover:bg-rose-500/10" @click="arm('terminate')">{{ actionLabel("terminate") }}</Button>
|
|
568
|
+
<Button v-if="canResume" variant="outline" size="sm" @click="arm('resume')">{{ actionLabel("resume") }}</Button>
|
|
517
569
|
</template>
|
|
518
570
|
</div>
|
|
519
571
|
|
|
@@ -529,7 +581,7 @@ async function confirmAction() {
|
|
|
529
581
|
<section class="rounded-md border border-black/[0.06] bg-white p-4 space-y-3">
|
|
530
582
|
<div class="grid gap-x-6 gap-y-3 sm:grid-cols-2 xl:grid-cols-4">
|
|
531
583
|
<div>
|
|
532
|
-
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
584
|
+
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.field.status") }}</div>
|
|
533
585
|
<div class="mt-0.5">
|
|
534
586
|
<Badge variant="outline" :class="['border text-xs font-medium uppercase', statusClass(dStatus ?? run.status)]">
|
|
535
587
|
{{ runStatusLabel(dStatus ?? run.status) }}
|
|
@@ -537,31 +589,31 @@ async function confirmAction() {
|
|
|
537
589
|
</div>
|
|
538
590
|
</div>
|
|
539
591
|
<div>
|
|
540
|
-
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
592
|
+
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.field.started") }}</div>
|
|
541
593
|
<div class="tabular-nums">{{ fmt(startedAt) }}</div>
|
|
542
594
|
</div>
|
|
543
595
|
<div>
|
|
544
|
-
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
596
|
+
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.field.completed") }}</div>
|
|
545
597
|
<div class="tabular-nums">{{ fmt(completedAt) }}</div>
|
|
546
598
|
</div>
|
|
547
599
|
<div>
|
|
548
|
-
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
600
|
+
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.field.historyLength") }}</div>
|
|
549
601
|
<div class="tabular-nums">{{ dHistoryLength ?? "\u2014" }}</div>
|
|
550
602
|
</div>
|
|
551
603
|
<div class="min-w-0">
|
|
552
|
-
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
604
|
+
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.field.workflow") }}</div>
|
|
553
605
|
<div class="truncate font-mono text-xs leading-5" :title="temporalWorkflowId ?? '\u2014'">{{ temporalWorkflowId ?? "\u2014" }}</div>
|
|
554
606
|
</div>
|
|
555
607
|
<div class="min-w-0">
|
|
556
|
-
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
608
|
+
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.field.runId") }}</div>
|
|
557
609
|
<div class="truncate font-mono text-xs leading-5" :title="temporalRunId ?? '\u2014'">{{ temporalRunId ?? "\u2014" }}</div>
|
|
558
610
|
</div>
|
|
559
611
|
<div class="min-w-0">
|
|
560
|
-
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
612
|
+
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.field.workflowType") }}</div>
|
|
561
613
|
<div class="truncate font-mono text-xs leading-5">{{ dWorkflowType ?? "\u2014" }}</div>
|
|
562
614
|
</div>
|
|
563
615
|
<div class="min-w-0">
|
|
564
|
-
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
616
|
+
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.field.taskQueue") }}</div>
|
|
565
617
|
<div class="truncate font-mono text-xs leading-5">{{ dTaskQueue ?? "\u2014" }}</div>
|
|
566
618
|
</div>
|
|
567
619
|
</div>
|
|
@@ -578,7 +630,7 @@ async function confirmAction() {
|
|
|
578
630
|
|
|
579
631
|
<!-- Result — full width below the overview. -->
|
|
580
632
|
<section v-if="hasResult" class="rounded-md border border-black/[0.06] bg-white p-4 space-y-2">
|
|
581
|
-
<h4 class="font-mono text-xs uppercase tracking-wide text-muted-foreground">
|
|
633
|
+
<h4 class="font-mono text-xs uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.result.title") }}</h4>
|
|
582
634
|
<div v-if="resultLinks.length" class="flex flex-wrap gap-1.5">
|
|
583
635
|
<a
|
|
584
636
|
v-for="link in resultLinks"
|
|
@@ -598,18 +650,18 @@ async function confirmAction() {
|
|
|
598
650
|
<!-- Stack Trace (non-terminal runs only, lazy) -->
|
|
599
651
|
<section v-if="!isTerminal" class="rounded-md border border-black/[0.06] bg-white p-4 space-y-3">
|
|
600
652
|
<div class="flex items-center gap-2 border-b border-black/[0.06] pb-2">
|
|
601
|
-
<h4 class="font-mono text-xs uppercase tracking-wide text-muted-foreground">
|
|
653
|
+
<h4 class="font-mono text-xs uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.stackTrace.title") }}</h4>
|
|
602
654
|
<div class="flex-1" />
|
|
603
655
|
<Button variant="outline" size="sm" :disabled="stackLoading" @click="loadStack">
|
|
604
|
-
{{ stackEnabled ? "
|
|
656
|
+
{{ stackEnabled ? t("integration.runs.detail.stackTrace.action.reload") : t("integration.runs.detail.stackTrace.action.load") }}
|
|
605
657
|
</Button>
|
|
606
658
|
</div>
|
|
607
659
|
|
|
608
660
|
<p v-if="!stackEnabled" class="text-xs text-muted-foreground">
|
|
609
|
-
|
|
661
|
+
{{ t("integration.runs.detail.stackTrace.hint") }}
|
|
610
662
|
</p>
|
|
611
663
|
<div v-else-if="stackLoading" class="flex items-center gap-2 text-muted-foreground">
|
|
612
|
-
<RefreshIcon :size="14" class="animate-spin" />
|
|
664
|
+
<RefreshIcon :size="14" class="animate-spin" /> {{ t("integration.runs.detail.stackTrace.loading") }}
|
|
613
665
|
</div>
|
|
614
666
|
<p v-else-if="stackError" class="text-rose-700">{{ stackError }}</p>
|
|
615
667
|
<pre
|
|
@@ -624,18 +676,18 @@ async function confirmAction() {
|
|
|
624
676
|
<!-- Steps (per-node projection) -->
|
|
625
677
|
<section v-if="hasTemporal" class="rounded-md border border-black/[0.06] bg-white p-4 space-y-3">
|
|
626
678
|
<div class="flex items-center gap-2 border-b border-black/[0.06] pb-2">
|
|
627
|
-
<h4 class="font-mono text-xs uppercase tracking-wide text-muted-foreground">
|
|
679
|
+
<h4 class="font-mono text-xs uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.steps.title") }}</h4>
|
|
628
680
|
<div class="flex-1" />
|
|
629
681
|
<Button variant="outline" size="sm" :disabled="stepsLoading" @click="toggleStepPayloads">
|
|
630
|
-
{{ stepsWithPayloads ? "
|
|
682
|
+
{{ stepsWithPayloads ? t("integration.runs.detail.steps.action.hidePayloads") : t("integration.runs.detail.steps.action.showPayloads") }}
|
|
631
683
|
</Button>
|
|
632
684
|
</div>
|
|
633
685
|
|
|
634
686
|
<p v-if="stepsError" class="text-rose-700">{{ stepsError }}</p>
|
|
635
687
|
<div v-else-if="stepsLoading && !steps.length" class="flex items-center gap-2 text-muted-foreground">
|
|
636
|
-
<RefreshIcon :size="14" class="animate-spin" />
|
|
688
|
+
<RefreshIcon :size="14" class="animate-spin" /> {{ t("integration.runs.detail.steps.loading") }}
|
|
637
689
|
</div>
|
|
638
|
-
<p v-else-if="!steps.length" class="text-muted-foreground">
|
|
690
|
+
<p v-else-if="!steps.length" class="text-muted-foreground">{{ t("integration.runs.detail.steps.empty") }}</p>
|
|
639
691
|
<ol v-else class="space-y-1">
|
|
640
692
|
<li
|
|
641
693
|
v-for="(st, i) in steps"
|
|
@@ -651,7 +703,7 @@ async function confirmAction() {
|
|
|
651
703
|
<div class="min-w-0 flex-1">
|
|
652
704
|
<div class="font-mono text-xs truncate">{{ st.node_slug || st.node_id }}</div>
|
|
653
705
|
<div class="text-[10px] text-muted-foreground truncate">
|
|
654
|
-
{{ st.node_id }}<template v-if="st.branch"> ·
|
|
706
|
+
{{ st.node_id }}<template v-if="st.branch"> · {{ t("integration.runs.detail.steps.branchLabel") }} {{ st.branch }}</template><template v-if="st.attempt"> · {{ t("integration.runs.detail.steps.attemptLabel") }} {{ st.attempt + 1 }}</template>
|
|
655
707
|
</div>
|
|
656
708
|
</div>
|
|
657
709
|
<span class="text-xs text-muted-foreground tabular-nums shrink-0">{{ fmtMs(st.duration_ms) }}</span>
|
|
@@ -663,16 +715,16 @@ async function confirmAction() {
|
|
|
663
715
|
<div v-if="expandedStep === i" class="px-3 pb-3 space-y-2">
|
|
664
716
|
<template v-if="stepsWithPayloads">
|
|
665
717
|
<div class="space-y-1">
|
|
666
|
-
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
718
|
+
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.steps.field.input") }}</div>
|
|
667
719
|
<pre class="rounded-md bg-muted/40 p-3 text-xs overflow-x-auto max-h-40">{{ st.input === void 0 ? "\u2014" : json(st.input) }}</pre>
|
|
668
720
|
</div>
|
|
669
721
|
<div class="space-y-1">
|
|
670
|
-
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">
|
|
722
|
+
<div class="text-[10px] uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.steps.field.output") }}</div>
|
|
671
723
|
<pre class="rounded-md bg-muted/40 p-3 text-xs overflow-x-auto max-h-40">{{ st.output === void 0 ? "\u2014" : json(st.output) }}</pre>
|
|
672
724
|
</div>
|
|
673
725
|
</template>
|
|
674
726
|
<p v-else class="text-xs text-muted-foreground">
|
|
675
|
-
|
|
727
|
+
{{ t("integration.runs.detail.steps.payloadHint") }}
|
|
676
728
|
</p>
|
|
677
729
|
</div>
|
|
678
730
|
</li>
|
|
@@ -683,14 +735,14 @@ async function confirmAction() {
|
|
|
683
735
|
opens the underlying events in a lightbox. -->
|
|
684
736
|
<section v-if="hasTemporal" class="rounded-md border border-black/[0.06] bg-white p-4 space-y-3">
|
|
685
737
|
<div class="flex items-center gap-2 border-b border-black/[0.06] pb-2">
|
|
686
|
-
<h4 class="font-mono text-xs uppercase tracking-wide text-muted-foreground">
|
|
738
|
+
<h4 class="font-mono text-xs uppercase tracking-wide text-muted-foreground">{{ t("integration.runs.detail.history.title") }}</h4>
|
|
687
739
|
</div>
|
|
688
740
|
|
|
689
741
|
<p v-if="historyError" class="text-rose-700">{{ historyError }}</p>
|
|
690
742
|
<div v-else-if="historyLoading && !timeline" class="flex items-center gap-2 text-muted-foreground">
|
|
691
|
-
<RefreshIcon :size="14" class="animate-spin" />
|
|
743
|
+
<RefreshIcon :size="14" class="animate-spin" /> {{ t("integration.runs.detail.history.loading") }}
|
|
692
744
|
</div>
|
|
693
|
-
<p v-else-if="!timeline" class="text-muted-foreground">
|
|
745
|
+
<p v-else-if="!timeline" class="text-muted-foreground">{{ t("integration.runs.detail.history.empty") }}</p>
|
|
694
746
|
<div v-else class="rounded-md border border-black/[0.05] bg-slate-50/60 p-2">
|
|
695
747
|
<div class="relative">
|
|
696
748
|
<div class="pointer-events-none absolute inset-y-0 left-1/4 border-l border-black/[0.05]" />
|
|
@@ -735,7 +787,7 @@ async function confirmAction() {
|
|
|
735
787
|
</section>
|
|
736
788
|
|
|
737
789
|
<p v-if="!hasTemporal" class="text-muted-foreground">
|
|
738
|
-
|
|
790
|
+
{{ t("integration.runs.detail.notHandedOff") }}
|
|
739
791
|
</p>
|
|
740
792
|
</template>
|
|
741
793
|
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, ref, useId, watch } from "vue";
|
|
3
|
-
import { Paperclip, TrashBinMinimalistic as
|
|
3
|
+
import { Paperclip, TrashBinMinimalistic as TrashBin } from "#solar-icons";
|
|
4
4
|
import { Input, Switch, Textarea } from "@revenexx/studio";
|
|
5
5
|
import { buildPayload, payloadFieldsFromBlob, splitPayload } from "../../data/payloadForm";
|
|
6
6
|
const props = defineProps({
|
|
7
7
|
blob: { type: Object, required: true }
|
|
8
8
|
});
|
|
9
9
|
const model = defineModel({ type: String, ...{ default: "{}" } });
|
|
10
|
+
const t = useIntegrationsT();
|
|
10
11
|
const fields = computed(() => payloadFieldsFromBlob(props.blob));
|
|
11
12
|
const uid = useId();
|
|
12
13
|
const fieldId = (path) => `${uid}-${path}`;
|
|
@@ -47,7 +48,7 @@ function toggleExpert(on) {
|
|
|
47
48
|
return;
|
|
48
49
|
}
|
|
49
50
|
if (!hydrateForm()) {
|
|
50
|
-
parseNote.value = "
|
|
51
|
+
parseNote.value = t("integration.runs.payload.parseError");
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
54
|
parseNote.value = null;
|
|
@@ -96,17 +97,17 @@ function prettyBytes(n) {
|
|
|
96
97
|
<div class="space-y-2">
|
|
97
98
|
<div v-if="fields.length" class="flex items-center justify-between">
|
|
98
99
|
<span class="text-xs font-medium text-muted-foreground">
|
|
99
|
-
{{ expert ? "
|
|
100
|
+
{{ expert ? t("integration.runs.payload.label.json") : t("integration.runs.payload.label.form") }}
|
|
100
101
|
</span>
|
|
101
102
|
<!-- The Switch is a `button role="switch"`, and HTML-AAM does not name a
|
|
102
103
|
button from a wrapping <label> — Chromium does, other engines need
|
|
103
104
|
not. The explicit name is what the promise rests on. -->
|
|
104
105
|
<label class="flex items-center gap-1.5 text-xs text-muted-foreground">
|
|
105
|
-
<Switch aria-label="
|
|
106
|
-
|
|
106
|
+
<Switch :aria-label="t('integration.runs.payload.expertToggle.label')" :model-value="expert" @update:model-value="toggleExpert" />
|
|
107
|
+
{{ t("integration.runs.payload.expertToggle.label") }}
|
|
107
108
|
</label>
|
|
108
109
|
</div>
|
|
109
|
-
<span v-else class="text-xs font-medium text-muted-foreground">
|
|
110
|
+
<span v-else class="text-xs font-medium text-muted-foreground">{{ t("integration.runs.payload.label.json") }}</span>
|
|
110
111
|
|
|
111
112
|
<!-- ── Form mode: fields derived from the blob's payload references ──── -->
|
|
112
113
|
<div v-if="!expert && fields.length" class="space-y-3">
|
|
@@ -127,7 +128,7 @@ function prettyBytes(n) {
|
|
|
127
128
|
@drop.prevent="onDrop(field.path, $event)"
|
|
128
129
|
>
|
|
129
130
|
<Paperclip :size="14" />
|
|
130
|
-
|
|
131
|
+
{{ t("integration.runs.payload.file.dropHint") }}
|
|
131
132
|
<input
|
|
132
133
|
type="file"
|
|
133
134
|
:aria-label="field.label"
|
|
@@ -142,15 +143,15 @@ function prettyBytes(n) {
|
|
|
142
143
|
<button
|
|
143
144
|
type="button"
|
|
144
145
|
class="flex size-6 shrink-0 items-center justify-center rounded text-muted-foreground transition hover:bg-muted/60 hover:text-rose-600"
|
|
145
|
-
title="
|
|
146
|
-
:aria-label="
|
|
146
|
+
:title="t('integration.runs.payload.file.remove.title')"
|
|
147
|
+
:aria-label="t('integration.runs.payload.file.remove.aria', { field: field.label })"
|
|
147
148
|
@click="detach(field.path)"
|
|
148
149
|
>
|
|
149
|
-
<
|
|
150
|
+
<TrashBin :size="13" />
|
|
150
151
|
</button>
|
|
151
152
|
</div>
|
|
152
153
|
<p v-if="files[field.path] && files[field.path].size > WARN_BYTES" class="text-xs text-amber-700">
|
|
153
|
-
|
|
154
|
+
{{ t("integration.runs.payload.file.tooLarge") }}
|
|
154
155
|
</p>
|
|
155
156
|
</template>
|
|
156
157
|
|
|
@@ -167,7 +168,7 @@ function prettyBytes(n) {
|
|
|
167
168
|
</template>
|
|
168
169
|
</div>
|
|
169
170
|
<p v-if="Object.keys(extras).length" class="text-xs text-muted-foreground">
|
|
170
|
-
|
|
171
|
+
{{ t("integration.runs.payload.extrasNote", { keys: Object.keys(extras).join(", ") }) }}
|
|
171
172
|
</p>
|
|
172
173
|
</div>
|
|
173
174
|
|
|
@@ -175,7 +176,7 @@ function prettyBytes(n) {
|
|
|
175
176
|
<template v-else>
|
|
176
177
|
<Textarea
|
|
177
178
|
v-model="model"
|
|
178
|
-
aria-label="
|
|
179
|
+
:aria-label="t('integration.runs.payload.label.json')"
|
|
179
180
|
:rows="8"
|
|
180
181
|
spellcheck="false"
|
|
181
182
|
class="font-mono text-xs"
|
|
@@ -17,6 +17,7 @@ defineProps({
|
|
|
17
17
|
runId: { type: [String, null], required: false }
|
|
18
18
|
});
|
|
19
19
|
const emit = defineEmits(["update:open", "view-run"]);
|
|
20
|
+
const t = useIntegrationsT();
|
|
20
21
|
</script>
|
|
21
22
|
|
|
22
23
|
<template>
|
|
@@ -25,16 +26,16 @@ const emit = defineEmits(["update:open", "view-run"]);
|
|
|
25
26
|
JSON <pre> scrolling INSIDE instead of blowing the dialog open. -->
|
|
26
27
|
<DialogContent class="max-w-[94vw] overflow-hidden sm:max-w-4xl">
|
|
27
28
|
<DialogHeader>
|
|
28
|
-
<DialogTitle>{{ mode === "async" ? "
|
|
29
|
+
<DialogTitle>{{ mode === "async" ? t("integration.runs.response.title.async") : t("integration.runs.response.title.sync") }}</DialogTitle>
|
|
29
30
|
<DialogDescription class="font-mono text-sm">
|
|
30
|
-
{{ mode === "async" ? "
|
|
31
|
+
{{ mode === "async" ? t("integration.runs.response.description.async") : t("integration.runs.response.description.sync") }}
|
|
31
32
|
</DialogDescription>
|
|
32
33
|
</DialogHeader>
|
|
33
34
|
|
|
34
35
|
<div class="min-w-0 max-w-full text-sm">
|
|
35
36
|
<div v-if="loading" class="flex items-center gap-2 py-6 text-muted-foreground">
|
|
36
37
|
<Loader2 :size="16" class="animate-spin" />
|
|
37
|
-
{{ mode === "async" ? "
|
|
38
|
+
{{ mode === "async" ? t("integration.runs.response.loading.async") : t("integration.runs.response.loading.sync") }}
|
|
38
39
|
</div>
|
|
39
40
|
|
|
40
41
|
<template v-else-if="error">
|
|
@@ -43,7 +44,7 @@ const emit = defineEmits(["update:open", "view-run"]);
|
|
|
43
44
|
</div>
|
|
44
45
|
<div v-if="runId" class="mt-3 flex justify-end">
|
|
45
46
|
<Button class="h-8 text-sm" @click="emit('view-run', runId)">
|
|
46
|
-
|
|
47
|
+
{{ t("integration.runs.response.action.viewRunWithId", { id: runId }) }}
|
|
47
48
|
</Button>
|
|
48
49
|
</div>
|
|
49
50
|
</template>
|
|
@@ -51,15 +52,15 @@ const emit = defineEmits(["update:open", "view-run"]);
|
|
|
51
52
|
<template v-else-if="mode === 'async'">
|
|
52
53
|
<div class="flex items-center gap-2 rounded-md border border-emerald-500/20 bg-emerald-500/5 px-3 py-2 text-emerald-700">
|
|
53
54
|
<CheckCircle2 :size="15" class="shrink-0" />
|
|
54
|
-
<span v-if="runId">
|
|
55
|
-
<span v-else>
|
|
55
|
+
<span v-if="runId">{{ t("integration.runs.response.async.startedWithId", { id: runId }) }}</span>
|
|
56
|
+
<span v-else>{{ t("integration.runs.response.async.started") }}</span>
|
|
56
57
|
</div>
|
|
57
58
|
<div class="mt-3 flex justify-end gap-2">
|
|
58
59
|
<Button variant="outline" class="h-8 text-sm" @click="emit('update:open', false)">
|
|
59
|
-
|
|
60
|
+
{{ t("integration.common.action.close") }}
|
|
60
61
|
</Button>
|
|
61
62
|
<Button v-if="runId" class="h-8 text-sm" @click="emit('view-run', runId)">
|
|
62
|
-
|
|
63
|
+
{{ t("integration.runs.response.action.viewRun") }}
|
|
63
64
|
</Button>
|
|
64
65
|
</div>
|
|
65
66
|
</template>
|
|
@@ -70,13 +71,13 @@ const emit = defineEmits(["update:open", "view-run"]);
|
|
|
70
71
|
>{{ JSON.stringify(response, null, 2) }}</pre>
|
|
71
72
|
<div v-if="runId" class="mt-3 flex justify-end">
|
|
72
73
|
<Button variant="outline" class="h-8 text-sm" @click="emit('view-run', runId)">
|
|
73
|
-
|
|
74
|
+
{{ t("integration.runs.response.action.viewRun") }}
|
|
74
75
|
</Button>
|
|
75
76
|
</div>
|
|
76
77
|
</template>
|
|
77
78
|
|
|
78
79
|
<p v-else class="py-6 text-muted-foreground">
|
|
79
|
-
|
|
80
|
+
{{ t("integration.runs.response.empty") }}
|
|
80
81
|
</p>
|
|
81
82
|
</div>
|
|
82
83
|
</DialogContent>
|
|
@@ -14,7 +14,6 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
|
|
|
14
14
|
onChanged?: (() => any) | undefined;
|
|
15
15
|
}>, {
|
|
16
16
|
loading: boolean;
|
|
17
|
-
emptyText: string;
|
|
18
17
|
pagination: boolean;
|
|
19
18
|
showWorkflow: boolean;
|
|
20
19
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|