@revenexx/studio-integrations 2.3.0 → 2.4.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 +6 -0
- package/dist/module.json +1 -1
- package/dist/runtime/components/Integrations/WorkflowContextMenu.d.vue.ts +2 -0
- package/dist/runtime/components/Integrations/WorkflowContextMenu.vue +3 -2
- package/dist/runtime/components/Integrations/WorkflowContextMenu.vue.d.ts +2 -0
- package/dist/runtime/components/Integrations/WorkflowEditor.d.vue.ts +6 -3
- package/dist/runtime/components/Integrations/WorkflowEditor.vue +3 -23
- package/dist/runtime/components/Integrations/WorkflowEditor.vue.d.ts +6 -3
- package/dist/runtime/i18n/messages/de.json +2 -0
- package/dist/runtime/i18n/messages/en.json +2 -0
- package/dist/runtime/pages/integrations/workflows/[id].vue +29 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @revenexx/studio-integrations
|
|
2
2
|
|
|
3
|
+
## 2.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 22eb158: Run in the workflow editor no longer starts the saved version while the canvas shows unsaved changes (PO-567). A changed setting used to be run as its old value, with nothing on screen to say so. Run now stands in the header beside Save rather than in the canvas's control pane, and while there is unsaved work it reads **Save & run** (German **Speichern & Run**): the press saves first and runs the workflow as it then stands. A save that is refused, or waits on the question whether to keep the work as paused, starts no run. The canvas's right-click menu names the save the same way. The header's dispatch badge now shows the mode as entered in the settings, as the name beside it already did, because that is the mode the next run goes out in. `WorkflowEditor` loses its `runWaiting` prop and gains `runSaves`.
|
|
8
|
+
|
|
3
9
|
## 2.3.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/dist/module.json
CHANGED
|
@@ -11,6 +11,8 @@ type __VLS_Props = {
|
|
|
11
11
|
targetIsTrigger?: boolean;
|
|
12
12
|
/** Busy flag for the Run item. */
|
|
13
13
|
runBusy?: boolean;
|
|
14
|
+
/** The workflow has unsaved work, so the Run item saves it first — and says so. */
|
|
15
|
+
runSaves?: boolean;
|
|
14
16
|
};
|
|
15
17
|
declare var __VLS_14: {};
|
|
16
18
|
type __VLS_Slots = {} & {
|
|
@@ -16,7 +16,8 @@ const props = defineProps({
|
|
|
16
16
|
selectionCount: { type: Number, required: true },
|
|
17
17
|
totalNodes: { type: Number, required: true },
|
|
18
18
|
targetIsTrigger: { type: Boolean, required: false },
|
|
19
|
-
runBusy: { type: Boolean, required: false }
|
|
19
|
+
runBusy: { type: Boolean, required: false },
|
|
20
|
+
runSaves: { type: Boolean, required: false }
|
|
20
21
|
});
|
|
21
22
|
const emit = defineEmits(["action", "update:open"]);
|
|
22
23
|
const t = useIntegrationsT();
|
|
@@ -33,7 +34,7 @@ const sections = computed(() => {
|
|
|
33
34
|
{ id: "duplicate", label: t("integration.canvas.contextMenu.item.duplicate"), shortcut: primaryShortcut("duplicate"), disabled: props.targetIsTrigger }
|
|
34
35
|
],
|
|
35
36
|
[
|
|
36
|
-
{ id: "run", label: t("integration.canvas.contextMenu.item.runWorkflow"), shortcut: primaryShortcut("run"), disabled: props.runBusy },
|
|
37
|
+
{ id: "run", label: t(props.runSaves ? "integration.canvas.contextMenu.item.saveAndRunWorkflow" : "integration.canvas.contextMenu.item.runWorkflow"), shortcut: primaryShortcut("run"), disabled: props.runBusy },
|
|
37
38
|
{ id: "tidy-up", label: t("integration.canvas.contextMenu.item.tidyUp"), shortcut: primaryShortcut("tidyUp") }
|
|
38
39
|
],
|
|
39
40
|
[
|
|
@@ -11,6 +11,8 @@ type __VLS_Props = {
|
|
|
11
11
|
targetIsTrigger?: boolean;
|
|
12
12
|
/** Busy flag for the Run item. */
|
|
13
13
|
runBusy?: boolean;
|
|
14
|
+
/** The workflow has unsaved work, so the Run item saves it first — and says so. */
|
|
15
|
+
runSaves?: boolean;
|
|
14
16
|
};
|
|
15
17
|
declare var __VLS_14: {};
|
|
16
18
|
type __VLS_Slots = {} & {
|
|
@@ -20,10 +20,13 @@ type __VLS_Props = {
|
|
|
20
20
|
* keystrokes.
|
|
21
21
|
*/
|
|
22
22
|
draft?: WorkflowBlob | null;
|
|
23
|
-
/**
|
|
23
|
+
/** A run is being triggered — the context menu's Run item and the shortcut stand down. */
|
|
24
24
|
runBusy?: boolean;
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/**
|
|
26
|
+
* The workflow has unsaved work, so Run saves it first. Only the context menu
|
|
27
|
+
* reads it, to say so: Run itself stands in the page header, beside Save.
|
|
28
|
+
*/
|
|
29
|
+
runSaves?: boolean;
|
|
27
30
|
/**
|
|
28
31
|
* One of the page's own lightboxes is open above the editor (settings,
|
|
29
32
|
* duplicate, run payload, the sync response, the deactivation prompt). The
|
|
@@ -13,10 +13,8 @@ import { MiniMap } from "@vue-flow/minimap";
|
|
|
13
13
|
import {
|
|
14
14
|
Widget as LayoutGrid,
|
|
15
15
|
MagicStick as Sparkles,
|
|
16
|
-
Play,
|
|
17
16
|
MinusCircle as ZoomOut,
|
|
18
|
-
AddCircle as ZoomIn
|
|
19
|
-
RefreshCircle as Loader2
|
|
17
|
+
AddCircle as ZoomIn
|
|
20
18
|
} from "#solar-icons";
|
|
21
19
|
import {
|
|
22
20
|
Dialog,
|
|
@@ -65,7 +63,7 @@ const props = defineProps({
|
|
|
65
63
|
workflow: { type: Object, required: true },
|
|
66
64
|
draft: { type: [Object, null], required: false },
|
|
67
65
|
runBusy: { type: Boolean, required: false },
|
|
68
|
-
|
|
66
|
+
runSaves: { type: Boolean, required: false },
|
|
69
67
|
overlayOpen: { type: Boolean, required: false }
|
|
70
68
|
});
|
|
71
69
|
const emit = defineEmits(["change", "run", "toggleActive", "openSettings"]);
|
|
@@ -1420,6 +1418,7 @@ const edgeTypes = {
|
|
|
1420
1418
|
:total-nodes="vfNodes.length"
|
|
1421
1419
|
:target-is-trigger="!!menu.targetId && blob.triggers.some((t2) => t2.id === menu.targetId)"
|
|
1422
1420
|
:run-busy="runBusy"
|
|
1421
|
+
:run-saves="runSaves"
|
|
1423
1422
|
@action="onMenuAction"
|
|
1424
1423
|
>
|
|
1425
1424
|
<!-- `pan-activation-key-code` is null rather than left at its default, which
|
|
@@ -1695,25 +1694,6 @@ const edgeTypes = {
|
|
|
1695
1694
|
<TooltipProvider :delay-duration="250">
|
|
1696
1695
|
<div class="rounded-lg border border-gray-400/10 outline-1 outline-white/30 backdrop-blur-sm">
|
|
1697
1696
|
<div class="flex items-center gap-0.5 whitespace-nowrap border border-white bg-white rounded-lg bg-gradient-to-br from-white via-violet-50/40 to-white px-2 py-1">
|
|
1698
|
-
<!-- Smart Run: the page decides what "run" means — a workflow that
|
|
1699
|
-
consumes trigger.payload, or leaves the mode to the caller, opens
|
|
1700
|
-
the run dialog; one that asks neither fires immediately. One
|
|
1701
|
-
button either way. -->
|
|
1702
|
-
<IntegrationsEditorTip :label="runWaiting ? t('integration.editor.tool.run.tooltipWaiting') : t('integration.editor.tool.run.tooltip')" :shortcut="primaryShortcut('run')">
|
|
1703
|
-
<button
|
|
1704
|
-
type="button"
|
|
1705
|
-
class="relative flex h-8 items-center gap-1.5 rounded-lg bg-gradient-to-b from-emerald-500 to-emerald-600 px-3.5 text-sm font-medium text-white transition after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:shadow-[inset_0_1px_0_rgba(255,255,255,0.3),inset_0_-2px_0_rgba(0,0,0,0.25)] hover:from-emerald-600 hover:to-emerald-600 active:translate-y-px disabled:opacity-60"
|
|
1706
|
-
:disabled="runBusy"
|
|
1707
|
-
@click="emit('run')"
|
|
1708
|
-
>
|
|
1709
|
-
<Loader2 v-if="runBusy" :size="14" class="animate-spin" />
|
|
1710
|
-
<Play v-else :size="14" />
|
|
1711
|
-
{{ runWaiting ? t("integration.editor.run.waitingForBuild") : t("integration.editor.run.button") }}
|
|
1712
|
-
</button>
|
|
1713
|
-
</IntegrationsEditorTip>
|
|
1714
|
-
|
|
1715
|
-
<div class="mx-1 h-5 w-px bg-black/10" />
|
|
1716
|
-
|
|
1717
1697
|
<div class="flex items-center gap-0.5 rounded-lg bg-black/[0.05] p-0.5 shadow-[inset_0_1px_2px_rgba(15,23,42,0.12)]">
|
|
1718
1698
|
<!-- Icon-only, and the tooltip is not an accessible name: each one
|
|
1719
1699
|
says what it does itself, and whether it is the active mode. -->
|
|
@@ -20,10 +20,13 @@ type __VLS_Props = {
|
|
|
20
20
|
* keystrokes.
|
|
21
21
|
*/
|
|
22
22
|
draft?: WorkflowBlob | null;
|
|
23
|
-
/**
|
|
23
|
+
/** A run is being triggered — the context menu's Run item and the shortcut stand down. */
|
|
24
24
|
runBusy?: boolean;
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/**
|
|
26
|
+
* The workflow has unsaved work, so Run saves it first. Only the context menu
|
|
27
|
+
* reads it, to say so: Run itself stands in the page header, beside Save.
|
|
28
|
+
*/
|
|
29
|
+
runSaves?: boolean;
|
|
27
30
|
/**
|
|
28
31
|
* One of the page's own lightboxes is open above the editor (settings,
|
|
29
32
|
* duplicate, run payload, the sync response, the deactivation prompt). The
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"integration.canvas.contextMenu.item.paste": "Einfügen",
|
|
54
54
|
"integration.canvas.contextMenu.item.rename": "Umbenennen",
|
|
55
55
|
"integration.canvas.contextMenu.item.runWorkflow": "Workflow ausführen",
|
|
56
|
+
"integration.canvas.contextMenu.item.saveAndRunWorkflow": "Speichern & Workflow ausführen",
|
|
56
57
|
"integration.canvas.contextMenu.item.selectAll": "Alle auswählen",
|
|
57
58
|
"integration.canvas.contextMenu.item.tidyUp": "Aufräumen",
|
|
58
59
|
"integration.canvas.edge.action.delete": "Verbindung löschen",
|
|
@@ -439,6 +440,7 @@
|
|
|
439
440
|
"integration.editor.run.error.syncFailed": "Synchroner Run fehlgeschlagen",
|
|
440
441
|
"integration.editor.run.error.syncTimeout": "Synchroner Run: Zeitüberschreitung",
|
|
441
442
|
"integration.editor.run.loading": "Run wird geladen…",
|
|
443
|
+
"integration.editor.run.saveAndRun": "Speichern & Run",
|
|
442
444
|
"integration.editor.run.waitingForBuild": "Warten auf Build…",
|
|
443
445
|
"integration.editor.runPayload.action.latestEvent": "Letztes reales Event",
|
|
444
446
|
"integration.editor.runPayload.action.latestEvent.title": "Letztes empfangenes Event dieses Topics einfügen",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"integration.canvas.contextMenu.item.paste": "Paste",
|
|
54
54
|
"integration.canvas.contextMenu.item.rename": "Rename",
|
|
55
55
|
"integration.canvas.contextMenu.item.runWorkflow": "Run workflow",
|
|
56
|
+
"integration.canvas.contextMenu.item.saveAndRunWorkflow": "Save & run workflow",
|
|
56
57
|
"integration.canvas.contextMenu.item.selectAll": "Select all",
|
|
57
58
|
"integration.canvas.contextMenu.item.tidyUp": "Tidy up",
|
|
58
59
|
"integration.canvas.edge.action.delete": "Delete this connection",
|
|
@@ -439,6 +440,7 @@
|
|
|
439
440
|
"integration.editor.run.error.syncFailed": "Sync run failed",
|
|
440
441
|
"integration.editor.run.error.syncTimeout": "Sync run timed out",
|
|
441
442
|
"integration.editor.run.loading": "Loading run…",
|
|
443
|
+
"integration.editor.run.saveAndRun": "Save & run",
|
|
442
444
|
"integration.editor.run.waitingForBuild": "Waiting for build…",
|
|
443
445
|
"integration.editor.runPayload.action.latestEvent": "Latest real event",
|
|
444
446
|
"integration.editor.runPayload.action.latestEvent.title": "Insert the latest received event of this topic",
|
|
@@ -400,7 +400,11 @@ async function run(mode) {
|
|
|
400
400
|
}
|
|
401
401
|
const payloadDriven = computed(() => payloadFieldsFromBlob(shownBlob.value ?? { nodes: [] }).length > 0);
|
|
402
402
|
async function runFromEditor() {
|
|
403
|
-
if (!workflow.value) return;
|
|
403
|
+
if (!workflow.value || saving.value) return;
|
|
404
|
+
if (isDirty.value) {
|
|
405
|
+
await save();
|
|
406
|
+
if (isDirty.value) return;
|
|
407
|
+
}
|
|
404
408
|
if (payloadDriven.value || workflow.value.execution_mode === "caller_decides") {
|
|
405
409
|
runPayloadOpen.value = true;
|
|
406
410
|
return;
|
|
@@ -817,14 +821,12 @@ async function confirmDeactivate() {
|
|
|
817
821
|
<WorkflowIconView :icon="shownIcon" :size="16" />
|
|
818
822
|
</span>
|
|
819
823
|
<span class="truncate" :title="shownName">{{ shownName }}</span>
|
|
820
|
-
<!-- The
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
<Badge variant="outline" class="ml-1.5 shrink-0 border text-xs font-medium uppercase text-muted-foreground" :title="t('integration.editor.header.executionMode.title', { mode: modeLabel(workflow.execution_mode) })">
|
|
827
|
-
{{ modeLabel(workflow.execution_mode) }}
|
|
824
|
+
<!-- The DRAFTED mode, like the name beside it: Run over a draft saves
|
|
825
|
+
it first (PO-567), so this is the mode the next run goes out in. The
|
|
826
|
+
saved one would read ASYNC over a button about to fire a sync run;
|
|
827
|
+
the unsaved marker says the platform does not have it yet. -->
|
|
828
|
+
<Badge variant="outline" class="ml-1.5 shrink-0 border text-xs font-medium uppercase text-muted-foreground" :title="t('integration.editor.header.executionMode.title', { mode: modeLabel(draftedMode) })">
|
|
829
|
+
{{ modeLabel(draftedMode) }}
|
|
828
830
|
</Badge>
|
|
829
831
|
</template>
|
|
830
832
|
</span>
|
|
@@ -927,8 +929,23 @@ async function confirmDeactivate() {
|
|
|
927
929
|
<Save v-else :size="12" />
|
|
928
930
|
{{ saving ? t("integration.editor.action.save.saving") : t("integration.editor.action.save.label") }}
|
|
929
931
|
</Button>
|
|
932
|
+
<!-- Run stands beside Save because a run goes to the workflow the
|
|
933
|
+
platform holds, not to the draft on the canvas: with the two at
|
|
934
|
+
opposite ends of the screen, a changed value was run as the old one
|
|
935
|
+
and nothing said so. While there is a draft the press saves it first,
|
|
936
|
+
and the name says that it will (PO-567). -->
|
|
937
|
+
<Button
|
|
938
|
+
class="h-7 bg-emerald-600 text-sm text-white hover:bg-emerald-700"
|
|
939
|
+
:disabled="saving || running || syncLoading || waitingForBuild"
|
|
940
|
+
:title="waitingForBuild ? t('integration.editor.tool.run.tooltipWaiting') : t('integration.editor.tool.run.tooltip')"
|
|
941
|
+
@click="runFromEditor"
|
|
942
|
+
>
|
|
943
|
+
<Loader2 v-if="running || syncLoading || waitingForBuild" :size="12" class="animate-spin" />
|
|
944
|
+
<Play v-else :size="12" />
|
|
945
|
+
{{ waitingForBuild ? t("integration.editor.run.waitingForBuild") : isDirty ? t("integration.editor.run.saveAndRun") : t("integration.editor.run.button") }}
|
|
946
|
+
</Button>
|
|
930
947
|
<!-- Activation is a standing state, not a transport control. The play
|
|
931
|
-
symbol belongs to Run,
|
|
948
|
+
symbol belongs to Run, the button just before this one,
|
|
932
949
|
where pressing it makes one thing happen now; arming a workflow's
|
|
933
950
|
triggers looks like nothing happening at all. So this states the
|
|
934
951
|
state in the words the workflows list uses — Active, Paused — and
|
|
@@ -1064,8 +1081,8 @@ async function confirmDeactivate() {
|
|
|
1064
1081
|
ref="editorRef"
|
|
1065
1082
|
:workflow="workflow"
|
|
1066
1083
|
:draft="draft?.blob ?? null"
|
|
1067
|
-
:run-busy="running || syncLoading || waitingForBuild"
|
|
1068
|
-
:run-
|
|
1084
|
+
:run-busy="saving || running || syncLoading || waitingForBuild"
|
|
1085
|
+
:run-saves="isDirty"
|
|
1069
1086
|
:overlay-open="settingsOpen || duplicateOpen || importOpen || !!exporter?.open || deleteOpen || syncOpen || runPayloadOpen || deactivationOpen || leaveOpen"
|
|
1070
1087
|
@change="onChange"
|
|
1071
1088
|
@run="runFromEditor"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revenexx/studio-integrations",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.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": {
|