@arronqzy/vue-blueprint 0.1.0 → 0.1.1
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/package.json +4 -3
- package/src/BlueprintNodeConfigSidebar.vue +58 -57
- package/src/components/BlueprintContextMenu.vue +5 -3
- package/src/components/BlueprintExecutionLogPanel.vue +29 -27
- package/src/components/BlueprintMetaDialog.vue +17 -11
- package/src/components/BlueprintNodeSwitchTaskDialog.vue +16 -8
- package/src/components/ClockNodeConfigPanel.vue +12 -14
- package/src/components/FetchNodeConfigPanel.vue +31 -29
- package/src/components/FetchUrlAutocomplete.vue +4 -1
- package/src/components/JsonNodeConfigPanel.vue +8 -9
- package/src/components/LogicNodeConfigPanel.vue +8 -9
- package/src/components/ViewElementMultiSelect.vue +5 -2
- package/src/composables/useBlueprintPageLifecycle.ts +27 -0
- package/src/fetch-config-task-store.ts +8 -2
- package/src/graph/document.ts +51 -14
- package/src/graph/node-summary.ts +32 -18
- package/src/index.ts +1 -1
- package/src/library/blueprint-io.ts +12 -3
- package/src/library/swagger-docs.ts +15 -5
- package/src/nodes/AndFlowNode.vue +8 -5
- package/src/nodes/BlueprintFlowNode.vue +5 -2
- package/src/nodes/BlueprintNodeCard.vue +5 -2
- package/src/nodes/BlueprintNodeShell.vue +5 -2
- package/src/nodes/ClockFlowNode.vue +6 -3
- package/src/nodes/FetchFlowNode.vue +5 -2
- package/src/nodes/JsonFlowNode.vue +5 -2
- package/src/nodes/LifecycleFlowNode.vue +6 -3
- package/src/nodes/LogicFlowNode.vue +5 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arronqzy/vue-blueprint",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Vue 3 blueprint editor for Abuilder (Vue Flow + Ant Design Vue)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"dayjs": "^1.11.13",
|
|
21
21
|
"vue": "^3.5.13",
|
|
22
22
|
"@arronqzy/blueprint-dsl": "1.0.3",
|
|
23
|
+
"@arronqzy/i18n": "0.1.1",
|
|
23
24
|
"@arronqzy/vue-rx-store": "0.1.0"
|
|
24
25
|
},
|
|
25
26
|
"peerDependencies": {
|
|
@@ -30,8 +31,8 @@
|
|
|
30
31
|
"eslint": "^8.57.0",
|
|
31
32
|
"typescript": "^5.5.4",
|
|
32
33
|
"vue-tsc": "^2.2.0",
|
|
33
|
-
"@arronqzy/
|
|
34
|
-
"@arronqzy/
|
|
34
|
+
"@arronqzy/typescript-config": "1.0.0",
|
|
35
|
+
"@arronqzy/eslint-config": "0.0.0"
|
|
35
36
|
},
|
|
36
37
|
"publishConfig": {
|
|
37
38
|
"access": "public"
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { computed, watch } from "vue";
|
|
3
4
|
import { Checkbox, Input, Select } from "ant-design-vue";
|
|
4
5
|
import {
|
|
5
6
|
LIFECYCLE_NODE_TYPE,
|
|
6
|
-
PAGE_LIFECYCLE_LABELS,
|
|
7
7
|
PAGE_LIFECYCLE_PHASES,
|
|
8
8
|
type PageLifecyclePhase,
|
|
9
9
|
} from "@arronqzy/blueprint-dsl";
|
|
@@ -14,14 +14,18 @@ import JsonNodeConfigPanel from "./components/JsonNodeConfigPanel.vue";
|
|
|
14
14
|
import LogicNodeConfigPanel from "./components/LogicNodeConfigPanel.vue";
|
|
15
15
|
import ViewElementMultiSelect from "./components/ViewElementMultiSelect.vue";
|
|
16
16
|
import {
|
|
17
|
+
getLifecyclePhaseLabel,
|
|
17
18
|
patchNodeConfigSource,
|
|
18
19
|
pruneViewElementIds,
|
|
19
20
|
resolveBlueprintConfigSource,
|
|
20
21
|
resolveViewElementIds,
|
|
21
22
|
type BlueprintConfigSource,
|
|
22
23
|
type BlueprintGraphNode,
|
|
24
|
+
type BlueprintNodeRole,
|
|
23
25
|
} from "./graph/document";
|
|
24
26
|
|
|
27
|
+
const { t } = useI18n();
|
|
28
|
+
|
|
25
29
|
export type BlueprintViewElementOption = {
|
|
26
30
|
id: string;
|
|
27
31
|
label: string;
|
|
@@ -76,15 +80,19 @@ const viewElementLabelById = computed(
|
|
|
76
80
|
() => new Map(props.viewElementOptions.map((opt) => [opt.id, opt.label]))
|
|
77
81
|
);
|
|
78
82
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
83
|
+
const ROLE_LABEL_KEYS: Record<BlueprintNodeRole, string> = {
|
|
84
|
+
blueprint: "blueprint.config.roleBlueprint",
|
|
85
|
+
lifecycle: "blueprint.config.roleLifecycle",
|
|
86
|
+
and: "blueprint.config.roleAnd",
|
|
87
|
+
fetch: "blueprint.config.roleFetch",
|
|
88
|
+
json: "blueprint.config.roleJson",
|
|
89
|
+
logic: "blueprint.config.roleLogic",
|
|
90
|
+
clock: "blueprint.config.roleClock",
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const roleLabel = computed(() =>
|
|
94
|
+
t(ROLE_LABEL_KEYS[props.node.role] ?? "blueprint.config.roleLogic")
|
|
95
|
+
);
|
|
88
96
|
|
|
89
97
|
watch(
|
|
90
98
|
[
|
|
@@ -130,14 +138,14 @@ function handleConfigSourceChange(value: string) {
|
|
|
130
138
|
<template>
|
|
131
139
|
<div class="flex h-full min-h-0 flex-col overflow-hidden bg-background text-foreground">
|
|
132
140
|
<div class="shrink-0 border-b border-border px-3 py-2">
|
|
133
|
-
<div class="text-xs font-semibold"
|
|
141
|
+
<div class="text-xs font-semibold">{{ t("blueprint.config.title") }}</div>
|
|
134
142
|
<div class="mt-0.5 text-[11px] text-muted-foreground">
|
|
135
143
|
{{ roleLabel }} · {{ node.id }}
|
|
136
144
|
</div>
|
|
137
145
|
</div>
|
|
138
146
|
<div class="min-h-0 flex-1 space-y-3 overflow-auto p-3 text-xs">
|
|
139
147
|
<label class="block space-y-1">
|
|
140
|
-
<span class="text-muted-foreground"
|
|
148
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.nodeName") }}</span>
|
|
141
149
|
<Input
|
|
142
150
|
size="small"
|
|
143
151
|
:value="node.label"
|
|
@@ -146,30 +154,30 @@ function handleConfigSourceChange(value: string) {
|
|
|
146
154
|
</label>
|
|
147
155
|
|
|
148
156
|
<label class="block space-y-1">
|
|
149
|
-
<span class="text-muted-foreground"
|
|
157
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.configType") }}</span>
|
|
150
158
|
<Select
|
|
151
159
|
size="small"
|
|
152
160
|
class="w-full"
|
|
153
161
|
:value="configSource"
|
|
154
162
|
@change="(v) => handleConfigSourceChange(String(v))"
|
|
155
163
|
>
|
|
156
|
-
<Select.Option value="blueprint"
|
|
157
|
-
<Select.Option value="logic"
|
|
158
|
-
<Select.Option value="and"
|
|
159
|
-
<Select.Option value="lifecycle"
|
|
160
|
-
<Select.Option value="fetch"
|
|
161
|
-
<Select.Option value="json">
|
|
162
|
-
<Select.Option value="clock"
|
|
163
|
-
<Select.Option value="view"
|
|
164
|
+
<Select.Option value="blueprint">{{ t("blueprint.config.configBlueprint") }}</Select.Option>
|
|
165
|
+
<Select.Option value="logic">{{ t("blueprint.config.configLogic") }}</Select.Option>
|
|
166
|
+
<Select.Option value="and">{{ t("blueprint.config.configAnd") }}</Select.Option>
|
|
167
|
+
<Select.Option value="lifecycle">{{ t("blueprint.config.configLifecycle") }}</Select.Option>
|
|
168
|
+
<Select.Option value="fetch">{{ t("blueprint.config.configFetch") }}</Select.Option>
|
|
169
|
+
<Select.Option value="json">{{ t("blueprint.config.configJson") }}</Select.Option>
|
|
170
|
+
<Select.Option value="clock">{{ t("blueprint.config.configClock") }}</Select.Option>
|
|
171
|
+
<Select.Option value="view">{{ t("blueprint.config.configView") }}</Select.Option>
|
|
164
172
|
</Select>
|
|
165
173
|
</label>
|
|
166
174
|
|
|
167
175
|
<div v-if="configSource === 'view'" class="block space-y-1">
|
|
168
|
-
<span class="text-muted-foreground"
|
|
176
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.linkedViewNodes") }}</span>
|
|
169
177
|
<ViewElementMultiSelect
|
|
170
178
|
:options="viewElementOptions"
|
|
171
179
|
:value="linkedViewElementIds"
|
|
172
|
-
placeholder="
|
|
180
|
+
:placeholder="t('blueprint.config.selectViewNode')"
|
|
173
181
|
@change="
|
|
174
182
|
(next) =>
|
|
175
183
|
onUpdateNode(node.id, {
|
|
@@ -180,14 +188,17 @@ function handleConfigSourceChange(value: string) {
|
|
|
180
188
|
"
|
|
181
189
|
/>
|
|
182
190
|
<p v-if="linkedViewElementIds.length === 0" class="text-[11px] text-muted-foreground">
|
|
183
|
-
|
|
191
|
+
{{ t("blueprint.config.viewMultiHint") }}
|
|
184
192
|
</p>
|
|
185
193
|
<p v-else class="text-[11px] text-muted-foreground">
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
194
|
+
{{
|
|
195
|
+
t("blueprint.config.linkedViewCount", {
|
|
196
|
+
count: linkedViewElementIds.length,
|
|
197
|
+
names: linkedViewElementIds
|
|
198
|
+
.map((id) => viewElementLabelById.get(id) ?? id)
|
|
199
|
+
.join("、"),
|
|
200
|
+
})
|
|
201
|
+
}}
|
|
191
202
|
</p>
|
|
192
203
|
</div>
|
|
193
204
|
|
|
@@ -195,15 +206,10 @@ function handleConfigSourceChange(value: string) {
|
|
|
195
206
|
v-if="configSource === 'blueprint'"
|
|
196
207
|
class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5"
|
|
197
208
|
>
|
|
198
|
-
<div class="font-medium text-foreground"
|
|
199
|
-
<p class="text-[11px] text-muted-foreground">
|
|
200
|
-
选中蓝图库中的蓝图后,当输入端收到<strong>真信号</strong>
|
|
201
|
-
时才会执行该蓝图;执行完成后从输出端发出
|
|
202
|
-
<strong>真信号</strong>(含嵌套蓝图输出值与当前节点信息),执行失败则发出
|
|
203
|
-
<strong>假信号</strong>。
|
|
204
|
-
</p>
|
|
209
|
+
<div class="font-medium text-foreground">{{ t("blueprint.config.blueprintAttrs") }}</div>
|
|
210
|
+
<p class="text-[11px] text-muted-foreground">{{ t("blueprint.config.blueprintAttrsHint") }}</p>
|
|
205
211
|
<label class="block space-y-1">
|
|
206
|
-
<span class="text-muted-foreground"
|
|
212
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.refLibrary") }}</span>
|
|
207
213
|
<Select
|
|
208
214
|
size="small"
|
|
209
215
|
class="w-full"
|
|
@@ -217,7 +223,7 @@ function handleConfigSourceChange(value: string) {
|
|
|
217
223
|
})
|
|
218
224
|
"
|
|
219
225
|
>
|
|
220
|
-
<Select.Option value="__none__"
|
|
226
|
+
<Select.Option value="__none__">{{ t("blueprint.config.unlinked") }}</Select.Option>
|
|
221
227
|
<Select.Option
|
|
222
228
|
v-for="opt in blueprintLibraryOptions"
|
|
223
229
|
:key="opt.id"
|
|
@@ -228,7 +234,7 @@ function handleConfigSourceChange(value: string) {
|
|
|
228
234
|
</Select>
|
|
229
235
|
</label>
|
|
230
236
|
<p v-if="!node.libraryBlueprintId" class="text-[11px] text-muted-foreground">
|
|
231
|
-
|
|
237
|
+
{{ t("blueprint.config.selectLibraryFirst") }}
|
|
232
238
|
</p>
|
|
233
239
|
<label class="flex items-start gap-2 pt-1">
|
|
234
240
|
<Checkbox
|
|
@@ -237,7 +243,7 @@ function handleConfigSourceChange(value: string) {
|
|
|
237
243
|
@update:checked="(v) => onUpdateAllowFalseSignalPropagation?.(Boolean(v))"
|
|
238
244
|
/>
|
|
239
245
|
<span class="text-[11px] leading-relaxed text-muted-foreground">
|
|
240
|
-
|
|
246
|
+
{{ t("blueprint.config.allowFalsePropagateBlueprint") }}
|
|
241
247
|
</span>
|
|
242
248
|
</label>
|
|
243
249
|
</div>
|
|
@@ -246,17 +252,17 @@ function handleConfigSourceChange(value: string) {
|
|
|
246
252
|
v-if="configSource === 'lifecycle'"
|
|
247
253
|
class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5"
|
|
248
254
|
>
|
|
249
|
-
<div class="font-medium text-foreground"
|
|
255
|
+
<div class="font-medium text-foreground">{{ t("blueprint.config.lifecycleHook") }}</div>
|
|
250
256
|
<p class="text-[11px] text-muted-foreground">
|
|
251
|
-
|
|
257
|
+
{{ t("blueprint.config.lifecycleNoInput") }}
|
|
252
258
|
{{
|
|
253
259
|
node.lifecyclePhase === "blueprintActivated"
|
|
254
|
-
? "
|
|
255
|
-
: "
|
|
260
|
+
? t("blueprint.config.lifecycleBlueprintActivatedHint")
|
|
261
|
+
: t("blueprint.config.lifecyclePageHint")
|
|
256
262
|
}}
|
|
257
263
|
</p>
|
|
258
264
|
<label class="block space-y-1">
|
|
259
|
-
<span class="text-muted-foreground"
|
|
265
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.listenPhase") }}</span>
|
|
260
266
|
<Select
|
|
261
267
|
size="small"
|
|
262
268
|
class="w-full"
|
|
@@ -272,12 +278,12 @@ function handleConfigSourceChange(value: string) {
|
|
|
272
278
|
"
|
|
273
279
|
>
|
|
274
280
|
<Select.Option v-for="phase in PAGE_LIFECYCLE_PHASES" :key="phase" :value="phase">
|
|
275
|
-
{{
|
|
281
|
+
{{ getLifecyclePhaseLabel(t, phase) }}
|
|
276
282
|
</Select.Option>
|
|
277
283
|
</Select>
|
|
278
284
|
</label>
|
|
279
285
|
<p v-if="node.parentId" class="text-[11px] text-muted-foreground">
|
|
280
|
-
|
|
286
|
+
{{ t("blueprint.config.parentBlueprintNode", { id: node.parentId }) }}
|
|
281
287
|
</p>
|
|
282
288
|
</div>
|
|
283
289
|
|
|
@@ -301,19 +307,14 @@ function handleConfigSourceChange(value: string) {
|
|
|
301
307
|
v-if="configSource === 'and'"
|
|
302
308
|
class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5"
|
|
303
309
|
>
|
|
304
|
-
<div class="font-medium text-foreground"
|
|
305
|
-
<p class="text-[11px] text-muted-foreground">
|
|
306
|
-
左侧两个输入口 <strong>inA</strong>、<strong>inB</strong>。
|
|
307
|
-
每个输入口可连 n 条线,同端口任一为真则该端口视为真(或)。
|
|
308
|
-
仅当 <strong>inA 与 inB 均为真信号</strong> 时,从输出口发出真信号;
|
|
309
|
-
否则发出假信号。
|
|
310
|
-
</p>
|
|
310
|
+
<div class="font-medium text-foreground">{{ t("blueprint.config.andTitle") }}</div>
|
|
311
|
+
<p class="text-[11px] text-muted-foreground">{{ t("blueprint.config.andHint") }}</p>
|
|
311
312
|
</div>
|
|
312
313
|
|
|
313
314
|
<template v-if="configSource === 'logic'">
|
|
314
315
|
<LogicNodeConfigPanel :node="node" :on-update-node="onUpdateNode" />
|
|
315
316
|
<p v-if="node.parentId" class="text-[11px] text-muted-foreground">
|
|
316
|
-
|
|
317
|
+
{{ t("blueprint.config.parentBlueprintNode", { id: node.parentId }) }}
|
|
317
318
|
</p>
|
|
318
319
|
</template>
|
|
319
320
|
|
|
@@ -321,7 +322,7 @@ function handleConfigSourceChange(value: string) {
|
|
|
321
322
|
v-if="configSource !== 'blueprint' && configSource !== 'and'"
|
|
322
323
|
class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5"
|
|
323
324
|
>
|
|
324
|
-
<div class="font-medium text-foreground"
|
|
325
|
+
<div class="font-medium text-foreground">{{ t("blueprint.config.taskChain") }}</div>
|
|
325
326
|
<label class="flex items-start gap-2">
|
|
326
327
|
<Checkbox
|
|
327
328
|
:checked="allowFalseSignalPropagation"
|
|
@@ -329,7 +330,7 @@ function handleConfigSourceChange(value: string) {
|
|
|
329
330
|
@update:checked="(v) => onUpdateAllowFalseSignalPropagation?.(Boolean(v))"
|
|
330
331
|
/>
|
|
331
332
|
<span class="text-[11px] leading-relaxed text-muted-foreground">
|
|
332
|
-
|
|
333
|
+
{{ t("blueprint.config.allowFalsePropagateDefault") }}
|
|
333
334
|
</span>
|
|
334
335
|
</label>
|
|
335
336
|
</div>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { onUnmounted, ref, watch } from "vue";
|
|
3
4
|
|
|
5
|
+
const { t } = useI18n();
|
|
4
6
|
export type BlueprintContextMenuState =
|
|
5
7
|
| {
|
|
6
8
|
kind: "pane";
|
|
@@ -84,7 +86,7 @@ onUnmounted(() => {
|
|
|
84
86
|
emit('close');
|
|
85
87
|
"
|
|
86
88
|
>
|
|
87
|
-
|
|
89
|
+
{{ t("blueprint.toolbar.addNode") }}
|
|
88
90
|
</button>
|
|
89
91
|
|
|
90
92
|
<button
|
|
@@ -96,7 +98,7 @@ onUnmounted(() => {
|
|
|
96
98
|
emit('close');
|
|
97
99
|
"
|
|
98
100
|
>
|
|
99
|
-
|
|
101
|
+
{{ t("blueprint.toolbar.deleteNode") }}
|
|
100
102
|
</button>
|
|
101
103
|
|
|
102
104
|
<button
|
|
@@ -108,7 +110,7 @@ onUnmounted(() => {
|
|
|
108
110
|
emit('close');
|
|
109
111
|
"
|
|
110
112
|
>
|
|
111
|
-
|
|
113
|
+
{{ t("blueprint.toolbar.deleteEdge") }}
|
|
112
114
|
</button>
|
|
113
115
|
</div>
|
|
114
116
|
</template>
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { computed, nextTick, ref, watch } from "vue";
|
|
3
4
|
import { Button, Checkbox, Input, Tooltip } from "ant-design-vue";
|
|
4
5
|
import {
|
|
5
|
-
PAGE_LIFECYCLE_LABELS,
|
|
6
6
|
type ExecutionTraceEntry,
|
|
7
7
|
type PageLifecyclePhase,
|
|
8
8
|
} from "@arronqzy/blueprint-dsl";
|
|
9
|
+
import { getLifecyclePhaseLabel } from "../graph/document";
|
|
9
10
|
|
|
10
11
|
import type { ExecutionLogSettings } from "../library/execution-log-settings";
|
|
11
12
|
import { cn } from "../utils/cn";
|
|
12
13
|
|
|
14
|
+
const { t } = useI18n();
|
|
15
|
+
|
|
13
16
|
export type BlueprintExecutionLogPanelProps = {
|
|
14
17
|
entries: ExecutionTraceEntry[];
|
|
15
18
|
settings: ExecutionLogSettings;
|
|
@@ -53,8 +56,7 @@ function formatJson(value: unknown) {
|
|
|
53
56
|
const phaseLabel = computed(() => {
|
|
54
57
|
if (!props.lifecyclePhase) return null;
|
|
55
58
|
return (
|
|
56
|
-
|
|
57
|
-
props.lifecyclePhase
|
|
59
|
+
getLifecyclePhaseLabel(t, props.lifecyclePhase as PageLifecyclePhase)
|
|
58
60
|
);
|
|
59
61
|
});
|
|
60
62
|
|
|
@@ -111,31 +113,31 @@ watch(
|
|
|
111
113
|
<div class="shrink-0 border-b border-border px-3 py-2">
|
|
112
114
|
<div class="flex items-start justify-between gap-2">
|
|
113
115
|
<div class="min-w-0">
|
|
114
|
-
<div class="text-xs font-semibold"
|
|
116
|
+
<div class="text-xs font-semibold">{{ t("blueprint.log.title") }}</div>
|
|
115
117
|
<div class="mt-0.5 text-[11px] text-muted-foreground">
|
|
116
|
-
{{ phaseLabel ?
|
|
118
|
+
{{ phaseLabel ? t("blueprint.log.simulateSceneWithPhase", { phaseLabel }) : t("blueprint.log.selectLifecycleToDebug") }}
|
|
117
119
|
</div>
|
|
118
120
|
</div>
|
|
119
121
|
<div class="flex shrink-0 items-center gap-1">
|
|
120
122
|
<Tooltip
|
|
121
123
|
v-if="onClearAllSaved"
|
|
122
|
-
title="
|
|
124
|
+
:title="t('blueprint.log.clearIdbTooltip')"
|
|
123
125
|
>
|
|
124
126
|
<Button
|
|
125
127
|
size="small"
|
|
126
128
|
class="h-7 w-7 shrink-0"
|
|
127
|
-
aria-label="
|
|
129
|
+
:aria-label="t('blueprint.log.clearIdbAria')"
|
|
128
130
|
:disabled="!hasSavedRuns"
|
|
129
131
|
@click="() => void onClearAllSaved?.()"
|
|
130
132
|
>
|
|
131
133
|
🗄✕
|
|
132
134
|
</Button>
|
|
133
135
|
</Tooltip>
|
|
134
|
-
<Tooltip title="
|
|
136
|
+
<Tooltip :title="t('blueprint.log.clearCurrentTooltip')">
|
|
135
137
|
<Button
|
|
136
138
|
size="small"
|
|
137
139
|
class="h-7 w-7 shrink-0"
|
|
138
|
-
aria-label="
|
|
140
|
+
:aria-label="t('blueprint.log.clearCurrentAria')"
|
|
139
141
|
:disabled="entries.length === 0"
|
|
140
142
|
@click="onClear"
|
|
141
143
|
>
|
|
@@ -149,7 +151,7 @@ watch(
|
|
|
149
151
|
<div class="relative min-h-0 flex-1">
|
|
150
152
|
<div ref="scrollRef" class="h-full overflow-auto p-3" @scroll="handleScroll">
|
|
151
153
|
<p v-if="entries.length === 0" class="text-[11px] text-muted-foreground">
|
|
152
|
-
|
|
154
|
+
{{ t("blueprint.log.emptyHint") }}
|
|
153
155
|
</p>
|
|
154
156
|
<div v-else class="space-y-0">
|
|
155
157
|
<div v-for="(entry, index) in entries" :key="entry.id">
|
|
@@ -170,13 +172,13 @@ watch(
|
|
|
170
172
|
|
|
171
173
|
<div class="mt-2 grid gap-2">
|
|
172
174
|
<div>
|
|
173
|
-
<div class="mb-1 text-[10px] font-medium text-muted-foreground"
|
|
175
|
+
<div class="mb-1 text-[10px] font-medium text-muted-foreground">{{ t("blueprint.log.input") }}</div>
|
|
174
176
|
<pre
|
|
175
177
|
class="max-h-32 overflow-auto rounded border border-border/60 bg-background p-2 font-mono text-[10px] leading-relaxed text-foreground"
|
|
176
178
|
>{{ formatJson(entry.inputs) }}</pre>
|
|
177
179
|
</div>
|
|
178
180
|
<div>
|
|
179
|
-
<div class="mb-1 text-[10px] font-medium text-muted-foreground"
|
|
181
|
+
<div class="mb-1 text-[10px] font-medium text-muted-foreground">{{ t("blueprint.log.output") }}</div>
|
|
180
182
|
<pre
|
|
181
183
|
class="max-h-32 overflow-auto rounded border p-2 font-mono text-[10px] leading-relaxed"
|
|
182
184
|
:class="
|
|
@@ -211,7 +213,7 @@ watch(
|
|
|
211
213
|
@click="() => void scrollToBottom('smooth')"
|
|
212
214
|
>
|
|
213
215
|
<span class="shrink-0">↓</span>
|
|
214
|
-
<span class="truncate"
|
|
216
|
+
<span class="truncate">{{ t("blueprint.log.hasNewLogs") }}</span>
|
|
215
217
|
<span v-if="latestEntryPreview" class="truncate opacity-90">
|
|
216
218
|
· {{ latestEntryPreview }}
|
|
217
219
|
</span>
|
|
@@ -221,41 +223,41 @@ watch(
|
|
|
221
223
|
|
|
222
224
|
<div class="shrink-0 space-y-2 border-t border-border p-3 text-xs">
|
|
223
225
|
<div class="grid grid-cols-2 gap-2">
|
|
224
|
-
<Tooltip title="
|
|
226
|
+
<Tooltip :title="t('blueprint.log.saveLogTooltip')">
|
|
225
227
|
<Button size="small" block :disabled="entries.length === 0" @click="onSave">
|
|
226
|
-
|
|
228
|
+
{{ t("blueprint.log.saveLog") }}
|
|
227
229
|
</Button>
|
|
228
230
|
</Tooltip>
|
|
229
|
-
<Tooltip title="
|
|
231
|
+
<Tooltip :title="t('blueprint.log.exportJsonTooltip')">
|
|
230
232
|
<Button size="small" block :disabled="entries.length === 0" @click="onExport">
|
|
231
|
-
|
|
233
|
+
{{ t("blueprint.log.exportJson") }}
|
|
232
234
|
</Button>
|
|
233
235
|
</Tooltip>
|
|
234
236
|
</div>
|
|
235
237
|
|
|
236
|
-
<Tooltip title="
|
|
238
|
+
<Tooltip :title="t('blueprint.log.autoSaveTooltip')">
|
|
237
239
|
<label class="flex cursor-default items-center gap-2">
|
|
238
240
|
<Checkbox
|
|
239
241
|
:checked="settings.autoSave"
|
|
240
242
|
@update:checked="(v) => onUpdateSettings({ autoSave: Boolean(v) })"
|
|
241
243
|
/>
|
|
242
244
|
<span class="text-[11px] text-muted-foreground">
|
|
243
|
-
|
|
245
|
+
{{ t("blueprint.log.autoSaveAfterRun") }}
|
|
244
246
|
</span>
|
|
245
247
|
</label>
|
|
246
248
|
</Tooltip>
|
|
247
249
|
|
|
248
250
|
<div class="grid grid-cols-2 gap-2">
|
|
249
|
-
<Tooltip title="
|
|
251
|
+
<Tooltip :title="t('blueprint.log.maxSavedCountTooltip')">
|
|
250
252
|
<div class="space-y-1">
|
|
251
|
-
<span class="text-[11px] text-muted-foreground"
|
|
253
|
+
<span class="text-[11px] text-muted-foreground">{{ t("blueprint.log.maxSavedCount") }}</span>
|
|
252
254
|
<Input
|
|
253
255
|
type="number"
|
|
254
256
|
size="small"
|
|
255
257
|
:min="1"
|
|
256
258
|
:step="1"
|
|
257
259
|
:value="settings.maxSavedRuns"
|
|
258
|
-
aria-label="
|
|
260
|
+
:aria-label="t('blueprint.log.maxSavedCountAria')"
|
|
259
261
|
@update:value="
|
|
260
262
|
(v) =>
|
|
261
263
|
onUpdateSettings({
|
|
@@ -265,16 +267,16 @@ watch(
|
|
|
265
267
|
/>
|
|
266
268
|
</div>
|
|
267
269
|
</Tooltip>
|
|
268
|
-
<Tooltip title="
|
|
270
|
+
<Tooltip :title="t('blueprint.log.retentionDaysTooltip')">
|
|
269
271
|
<div class="space-y-1">
|
|
270
|
-
<span class="text-[11px] text-muted-foreground"
|
|
272
|
+
<span class="text-[11px] text-muted-foreground">{{ t("blueprint.log.retentionDays") }}</span>
|
|
271
273
|
<Input
|
|
272
274
|
type="number"
|
|
273
275
|
size="small"
|
|
274
276
|
:min="1"
|
|
275
277
|
:step="1"
|
|
276
278
|
:value="settings.retentionDays"
|
|
277
|
-
aria-label="
|
|
279
|
+
:aria-label="t('blueprint.log.retentionDaysAria')"
|
|
278
280
|
@update:value="
|
|
279
281
|
(v) =>
|
|
280
282
|
onUpdateSettings({
|
|
@@ -286,8 +288,8 @@ watch(
|
|
|
286
288
|
</Tooltip>
|
|
287
289
|
</div>
|
|
288
290
|
|
|
289
|
-
<Tooltip title="
|
|
290
|
-
<Button size="small" block @click="onApplyRetention"
|
|
291
|
+
<Tooltip :title="t('blueprint.log.cleanupTooltip')">
|
|
292
|
+
<Button size="small" block @click="onApplyRetention">{{ t("blueprint.log.cleanupExpired") }}</Button>
|
|
291
293
|
</Tooltip>
|
|
292
294
|
</div>
|
|
293
295
|
</div>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { ref, watch } from "vue";
|
|
3
4
|
import { Button, Input, Modal } from "ant-design-vue";
|
|
4
5
|
|
|
5
6
|
import type { BlueprintMetaDraft } from "../library/types";
|
|
6
7
|
|
|
8
|
+
const { t } = useI18n();
|
|
7
9
|
export type BlueprintMetaDialogProps = {
|
|
8
10
|
open: boolean;
|
|
9
11
|
mode: "export" | "save";
|
|
@@ -26,16 +28,20 @@ watch(
|
|
|
26
28
|
}
|
|
27
29
|
);
|
|
28
30
|
|
|
29
|
-
const title = () =>
|
|
31
|
+
const title = () =>
|
|
32
|
+
props.mode === "export"
|
|
33
|
+
? t("blueprint.dialog.exportTitle")
|
|
34
|
+
: t("blueprint.dialog.saveTitle");
|
|
30
35
|
const description = () =>
|
|
31
36
|
props.mode === "export"
|
|
32
|
-
? "
|
|
33
|
-
: "
|
|
34
|
-
const confirmLabel = () =>
|
|
37
|
+
? t("blueprint.dialog.exportDescription")
|
|
38
|
+
: t("blueprint.dialog.saveDescription");
|
|
39
|
+
const confirmLabel = () =>
|
|
40
|
+
props.mode === "export" ? t("blueprint.dialog.export") : t("blueprint.dialog.save");
|
|
35
41
|
|
|
36
42
|
function handleConfirm() {
|
|
37
43
|
props.onConfirm({
|
|
38
|
-
name: name.value.trim() || "
|
|
44
|
+
name: name.value.trim() || t("blueprint.dialog.unnamedBlueprint"),
|
|
39
45
|
remark: remark.value.trim(),
|
|
40
46
|
});
|
|
41
47
|
props.onOpenChange(false);
|
|
@@ -47,33 +53,33 @@ function handleConfirm() {
|
|
|
47
53
|
:open="open"
|
|
48
54
|
:title="title()"
|
|
49
55
|
:ok-text="confirmLabel()"
|
|
50
|
-
cancel-text="
|
|
56
|
+
:cancel-text="t('common.cancel')"
|
|
51
57
|
@update:open="onOpenChange"
|
|
52
58
|
@ok="handleConfirm"
|
|
53
59
|
>
|
|
54
60
|
<p class="mb-3 text-xs text-muted-foreground">{{ description() }}</p>
|
|
55
61
|
<div class="space-y-3">
|
|
56
62
|
<label class="block space-y-1">
|
|
57
|
-
<span class="text-sm"
|
|
63
|
+
<span class="text-sm">{{ t("blueprint.dialog.blueprintName") }}</span>
|
|
58
64
|
<Input
|
|
59
65
|
id="blueprint-meta-name"
|
|
60
66
|
v-model:value="name"
|
|
61
|
-
placeholder="
|
|
67
|
+
:placeholder="t('blueprint.dialog.namePlaceholder')"
|
|
62
68
|
autofocus
|
|
63
69
|
/>
|
|
64
70
|
</label>
|
|
65
71
|
<label class="block space-y-1">
|
|
66
|
-
<span class="text-sm"
|
|
72
|
+
<span class="text-sm">{{ t("blueprint.dialog.remark") }}</span>
|
|
67
73
|
<Input.TextArea
|
|
68
74
|
id="blueprint-meta-remark"
|
|
69
75
|
v-model:value="remark"
|
|
70
|
-
placeholder="
|
|
76
|
+
:placeholder="t('blueprint.dialog.remarkPlaceholder')"
|
|
71
77
|
:rows="3"
|
|
72
78
|
/>
|
|
73
79
|
</label>
|
|
74
80
|
</div>
|
|
75
81
|
<template #footer>
|
|
76
|
-
<Button @click="onOpenChange(false)"
|
|
82
|
+
<Button @click="onOpenChange(false)">{{ t("common.cancel") }}</Button>
|
|
77
83
|
<Button type="primary" @click="handleConfirm">{{ confirmLabel() }}</Button>
|
|
78
84
|
</template>
|
|
79
85
|
</Modal>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { computed } from "vue";
|
|
3
4
|
import { Button, Modal } from "ant-design-vue";
|
|
4
5
|
|
|
6
|
+
const { t } = useI18n();
|
|
5
7
|
export type BlueprintNodeSwitchTaskDialogProps = {
|
|
6
8
|
open: boolean;
|
|
7
9
|
fromNodeId: string;
|
|
@@ -14,28 +16,34 @@ export type BlueprintNodeSwitchTaskDialogProps = {
|
|
|
14
16
|
const props = defineProps<BlueprintNodeSwitchTaskDialogProps>();
|
|
15
17
|
|
|
16
18
|
const targetLabel = computed(() =>
|
|
17
|
-
props.toNodeId === null
|
|
19
|
+
props.toNodeId === null
|
|
20
|
+
? t("blueprint.dialog.cancelSelection")
|
|
21
|
+
: t("blueprint.dialog.nodeTarget", { id: props.toNodeId })
|
|
18
22
|
);
|
|
19
23
|
</script>
|
|
20
24
|
|
|
21
25
|
<template>
|
|
22
26
|
<Modal
|
|
23
27
|
:open="open"
|
|
24
|
-
title="
|
|
28
|
+
:title="t('blueprint.dialog.taskRunningTitle')"
|
|
25
29
|
:footer="null"
|
|
26
30
|
@update:open="onOpenChange"
|
|
27
31
|
>
|
|
28
32
|
<p class="text-sm text-muted-foreground">
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
{{
|
|
34
|
+
t("blueprint.dialog.taskRunningDescription", {
|
|
35
|
+
fromNodeId,
|
|
36
|
+
target: targetLabel,
|
|
37
|
+
})
|
|
38
|
+
}}
|
|
31
39
|
</p>
|
|
32
40
|
<p class="mt-2 text-xs text-muted-foreground">
|
|
33
|
-
|
|
41
|
+
{{ t("blueprint.dialog.taskSwitchHint") }}
|
|
34
42
|
</p>
|
|
35
43
|
<div class="mt-4 flex flex-wrap justify-end gap-2">
|
|
36
|
-
<Button @click="onOpenChange(false)"
|
|
37
|
-
<Button @click="onCancelTaskAndSwitch"
|
|
38
|
-
<Button type="primary" @click="onKeepTaskAndSwitch"
|
|
44
|
+
<Button @click="onOpenChange(false)">{{ t("blueprint.dialog.stayOnNode") }}</Button>
|
|
45
|
+
<Button @click="onCancelTaskAndSwitch">{{ t("blueprint.dialog.cancelAndSwitch") }}</Button>
|
|
46
|
+
<Button type="primary" @click="onKeepTaskAndSwitch">{{ t("blueprint.dialog.keepAndSwitch") }}</Button>
|
|
39
47
|
</div>
|
|
40
48
|
</Modal>
|
|
41
49
|
</template>
|