@arronqzy/vue-blueprint 0.1.0 → 0.1.2
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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { computed } from "vue";
|
|
3
4
|
import { Checkbox, Input } from "ant-design-vue";
|
|
4
5
|
import type { ClockNodeConfig } from "@arronqzy/blueprint-dsl";
|
|
@@ -6,6 +7,8 @@ import type { ClockNodeConfig } from "@arronqzy/blueprint-dsl";
|
|
|
6
7
|
import type { BlueprintGraphNode } from "../graph/document";
|
|
7
8
|
import { resolveNodeClockConfig } from "../graph/document";
|
|
8
9
|
|
|
10
|
+
const { t } = useI18n();
|
|
11
|
+
|
|
9
12
|
export type ClockNodeConfigPanelProps = {
|
|
10
13
|
node: BlueprintGraphNode;
|
|
11
14
|
onUpdateNode: (
|
|
@@ -57,15 +60,11 @@ function handleEmitImmediatelyChange(checked: boolean) {
|
|
|
57
60
|
|
|
58
61
|
<template>
|
|
59
62
|
<div class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5">
|
|
60
|
-
<div class="font-medium text-foreground"
|
|
61
|
-
<p class="text-[11px] text-muted-foreground">
|
|
62
|
-
收到<strong>真信号</strong>后才开始计时输出;每次输出向下游发出
|
|
63
|
-
<strong>真信号</strong>,值包含当前时间(formatted / timestamp / isoTime)。
|
|
64
|
-
假信号会原样向下游传递。
|
|
65
|
-
</p>
|
|
63
|
+
<div class="font-medium text-foreground">{{ t("blueprint.config.clockTitle") }}</div>
|
|
64
|
+
<p class="text-[11px] text-muted-foreground">{{ t("blueprint.config.clockHint") }}</p>
|
|
66
65
|
|
|
67
66
|
<label class="block space-y-1">
|
|
68
|
-
<span class="text-muted-foreground"
|
|
67
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.clockIntervalSeconds") }}</span>
|
|
69
68
|
<Input
|
|
70
69
|
type="number"
|
|
71
70
|
:min="0"
|
|
@@ -75,12 +74,12 @@ function handleEmitImmediatelyChange(checked: boolean) {
|
|
|
75
74
|
@update:value="handleIntervalChange"
|
|
76
75
|
/>
|
|
77
76
|
<p class="text-[11px] text-muted-foreground">
|
|
78
|
-
|
|
77
|
+
{{ t("blueprint.config.clockIntervalHint") }}
|
|
79
78
|
</p>
|
|
80
79
|
</label>
|
|
81
80
|
|
|
82
81
|
<label class="block space-y-1">
|
|
83
|
-
<span class="text-muted-foreground"
|
|
82
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.outputCount") }}</span>
|
|
84
83
|
<Input
|
|
85
84
|
type="number"
|
|
86
85
|
:min="1"
|
|
@@ -90,7 +89,7 @@ function handleEmitImmediatelyChange(checked: boolean) {
|
|
|
90
89
|
@update:value="handleOutputCountChange"
|
|
91
90
|
/>
|
|
92
91
|
<p class="text-[11px] text-muted-foreground">
|
|
93
|
-
|
|
92
|
+
{{ t("blueprint.config.outputCountHint") }}
|
|
94
93
|
</p>
|
|
95
94
|
</label>
|
|
96
95
|
|
|
@@ -101,13 +100,12 @@ function handleEmitImmediatelyChange(checked: boolean) {
|
|
|
101
100
|
@update:checked="handleEmitImmediatelyChange"
|
|
102
101
|
/>
|
|
103
102
|
<span class="text-[11px] leading-relaxed text-muted-foreground">
|
|
104
|
-
|
|
105
|
-
秒依次执行;仅输出 1 次时也会立刻执行。关闭则每次(含首次)都先等待 m 秒。
|
|
103
|
+
{{ t("blueprint.config.emitImmediately") }}
|
|
106
104
|
</span>
|
|
107
105
|
</label>
|
|
108
106
|
|
|
109
107
|
<label class="block space-y-1">
|
|
110
|
-
<span class="text-muted-foreground"
|
|
108
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.timeFormat") }}</span>
|
|
111
109
|
<Input
|
|
112
110
|
size="small"
|
|
113
111
|
:value="clockConfig.timeFormat"
|
|
@@ -117,7 +115,7 @@ function handleEmitImmediatelyChange(checked: boolean) {
|
|
|
117
115
|
@input="handleFormatChange"
|
|
118
116
|
/>
|
|
119
117
|
<p class="text-[11px] text-muted-foreground">
|
|
120
|
-
|
|
118
|
+
{{ t("blueprint.config.timeFormatHint") }}
|
|
121
119
|
</p>
|
|
122
120
|
</label>
|
|
123
121
|
</div>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { computed, ref } from "vue";
|
|
3
4
|
import { Button, Input, Select } from "ant-design-vue";
|
|
4
5
|
import type {
|
|
@@ -28,6 +29,8 @@ import {
|
|
|
28
29
|
} from "../fetch-config-task-store";
|
|
29
30
|
import FetchUrlAutocomplete from "./FetchUrlAutocomplete.vue";
|
|
30
31
|
|
|
32
|
+
const { t } = useI18n();
|
|
33
|
+
|
|
31
34
|
export type FetchNodeConfigPanelProps = {
|
|
32
35
|
node: BlueprintGraphNode;
|
|
33
36
|
onUpdateNode: (
|
|
@@ -74,7 +77,7 @@ function setUrlInputMode(mode: "swagger" | "manual") {
|
|
|
74
77
|
function handleLoadSwagger() {
|
|
75
78
|
const docsUrl = fetchConfig.value.swaggerDocsUrl?.trim();
|
|
76
79
|
if (!docsUrl) {
|
|
77
|
-
validationError.value = "
|
|
80
|
+
validationError.value = t("blueprint.config.fillSwaggerUrlFirst");
|
|
78
81
|
return;
|
|
79
82
|
}
|
|
80
83
|
|
|
@@ -104,7 +107,7 @@ function handleAbortSwagger() {
|
|
|
104
107
|
function handleSendFetchDebug() {
|
|
105
108
|
const url = fetchConfig.value.url?.trim();
|
|
106
109
|
if (!url) {
|
|
107
|
-
fetchValidationError.value = "
|
|
110
|
+
fetchValidationError.value = t("blueprint.config.fillRequestUrlFirst");
|
|
108
111
|
return;
|
|
109
112
|
}
|
|
110
113
|
|
|
@@ -160,14 +163,13 @@ function handleHeadersBlur(event: Event) {
|
|
|
160
163
|
|
|
161
164
|
<template>
|
|
162
165
|
<div class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5">
|
|
163
|
-
<div class="font-medium text-foreground"
|
|
166
|
+
<div class="font-medium text-foreground">{{ t("blueprint.config.fetchTitle") }}</div>
|
|
164
167
|
<p class="text-[11px] text-muted-foreground">
|
|
165
|
-
|
|
166
|
-
URL。
|
|
168
|
+
{{ t("blueprint.config.fetchHint") }}
|
|
167
169
|
</p>
|
|
168
170
|
|
|
169
171
|
<label class="block space-y-1">
|
|
170
|
-
<span class="text-muted-foreground">
|
|
172
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.swaggerUrlOptional") }}</span>
|
|
171
173
|
<div class="flex gap-1.5">
|
|
172
174
|
<Input
|
|
173
175
|
size="small"
|
|
@@ -184,8 +186,8 @@ function handleHeadersBlur(event: Event) {
|
|
|
184
186
|
v-if="loadingSwagger"
|
|
185
187
|
size="small"
|
|
186
188
|
class="h-8 w-8 shrink-0 text-destructive"
|
|
187
|
-
title="
|
|
188
|
-
aria-label="
|
|
189
|
+
:title="t('blueprint.config.abortParse')"
|
|
190
|
+
:aria-label="t('blueprint.config.abortSwaggerAria')"
|
|
189
191
|
@click="handleAbortSwagger"
|
|
190
192
|
>
|
|
191
193
|
■
|
|
@@ -194,24 +196,24 @@ function handleHeadersBlur(event: Event) {
|
|
|
194
196
|
v-else
|
|
195
197
|
size="small"
|
|
196
198
|
class="h-8 w-8 shrink-0"
|
|
197
|
-
title="
|
|
199
|
+
:title="t('blueprint.config.parseSwagger')"
|
|
198
200
|
@click="handleLoadSwagger"
|
|
199
201
|
>
|
|
200
202
|
➤
|
|
201
203
|
</Button>
|
|
202
204
|
</div>
|
|
203
205
|
<p v-if="loadingSwagger" class="text-[11px] text-muted-foreground">
|
|
204
|
-
|
|
206
|
+
{{ t("blueprint.config.parsingSwagger") }}
|
|
205
207
|
</p>
|
|
206
208
|
<p v-if="swaggerError" class="text-[11px] text-destructive">{{ swaggerError }}</p>
|
|
207
209
|
<p v-if="endpoints.length > 0" class="text-[11px] text-muted-foreground">
|
|
208
|
-
|
|
210
|
+
{{ t("blueprint.config.parsedEndpoints", { count: endpoints.length }) }}
|
|
209
211
|
</p>
|
|
210
212
|
</label>
|
|
211
213
|
|
|
212
214
|
<label class="block space-y-1">
|
|
213
215
|
<div class="flex items-center justify-between gap-2">
|
|
214
|
-
<span class="text-muted-foreground"
|
|
216
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.requestUrl") }}</span>
|
|
215
217
|
<div v-if="hasSwaggerEndpoints" class="flex rounded-md border border-border p-0.5">
|
|
216
218
|
<button
|
|
217
219
|
type="button"
|
|
@@ -224,7 +226,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
224
226
|
"
|
|
225
227
|
@click="setUrlInputMode('swagger')"
|
|
226
228
|
>
|
|
227
|
-
|
|
229
|
+
{{ t("blueprint.config.suggestApi") }}
|
|
228
230
|
</button>
|
|
229
231
|
<button
|
|
230
232
|
type="button"
|
|
@@ -237,7 +239,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
237
239
|
"
|
|
238
240
|
@click="setUrlInputMode('manual')"
|
|
239
241
|
>
|
|
240
|
-
|
|
242
|
+
{{ t("blueprint.config.manualInput") }}
|
|
241
243
|
</button>
|
|
242
244
|
</div>
|
|
243
245
|
</div>
|
|
@@ -248,7 +250,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
248
250
|
:class="loadingSwagger && 'pointer-events-none opacity-60'"
|
|
249
251
|
>
|
|
250
252
|
<label class="block space-y-1">
|
|
251
|
-
<span class="text-muted-foreground">
|
|
253
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.apiHostBaseUrl") }}</span>
|
|
252
254
|
<Input
|
|
253
255
|
size="small"
|
|
254
256
|
:value="fetchConfig.apiBaseUrl ?? ''"
|
|
@@ -260,7 +262,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
260
262
|
/>
|
|
261
263
|
</label>
|
|
262
264
|
<label class="block space-y-1">
|
|
263
|
-
<span class="text-muted-foreground"
|
|
265
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.selectEndpoint") }}</span>
|
|
264
266
|
<div class="flex gap-1.5">
|
|
265
267
|
<div class="min-w-0 flex-1">
|
|
266
268
|
<FetchUrlAutocomplete
|
|
@@ -268,7 +270,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
268
270
|
:api-base-url="fetchConfig.apiBaseUrl ?? ''"
|
|
269
271
|
:endpoints="endpoints"
|
|
270
272
|
select-only
|
|
271
|
-
placeholder="
|
|
273
|
+
:placeholder="t('blueprint.config.selectOrSearchEndpoint')"
|
|
272
274
|
@change="
|
|
273
275
|
(url) => onUpdateNode(node.id, patchFetchConfig(node, { url }))
|
|
274
276
|
"
|
|
@@ -288,7 +290,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
288
290
|
v-if="loadingFetchDebug"
|
|
289
291
|
size="small"
|
|
290
292
|
class="h-8 w-8 shrink-0"
|
|
291
|
-
title="
|
|
293
|
+
:title="t('blueprint.config.abortRequest')"
|
|
292
294
|
@click="handleAbortFetchDebug"
|
|
293
295
|
>
|
|
294
296
|
■
|
|
@@ -298,7 +300,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
298
300
|
size="small"
|
|
299
301
|
class="h-8 w-8 shrink-0"
|
|
300
302
|
:disabled="loadingSwagger"
|
|
301
|
-
title="
|
|
303
|
+
:title="t('blueprint.config.sendDebugRequest')"
|
|
302
304
|
@click="handleSendFetchDebug"
|
|
303
305
|
>
|
|
304
306
|
➤
|
|
@@ -319,7 +321,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
319
321
|
v-if="loadingFetchDebug"
|
|
320
322
|
size="small"
|
|
321
323
|
class="h-8 w-8 shrink-0"
|
|
322
|
-
title="
|
|
324
|
+
:title="t('blueprint.config.abortRequest')"
|
|
323
325
|
@click="handleAbortFetchDebug"
|
|
324
326
|
>
|
|
325
327
|
■
|
|
@@ -329,7 +331,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
329
331
|
size="small"
|
|
330
332
|
class="h-8 w-8 shrink-0"
|
|
331
333
|
:disabled="loadingSwagger"
|
|
332
|
-
title="
|
|
334
|
+
:title="t('blueprint.config.sendDebugRequest')"
|
|
333
335
|
@click="handleSendFetchDebug"
|
|
334
336
|
>
|
|
335
337
|
➤
|
|
@@ -337,7 +339,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
337
339
|
</div>
|
|
338
340
|
|
|
339
341
|
<p v-if="loadingFetchDebug" class="text-[11px] text-muted-foreground">
|
|
340
|
-
|
|
342
|
+
{{ t("blueprint.config.sendingDebug") }}
|
|
341
343
|
</p>
|
|
342
344
|
<p v-if="fetchValidationError" class="text-[11px] text-destructive">
|
|
343
345
|
{{ fetchValidationError }}
|
|
@@ -348,7 +350,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
348
350
|
class="rounded-md border border-destructive/40 bg-destructive/5 p-2"
|
|
349
351
|
>
|
|
350
352
|
<p class="text-[11px] text-destructive">
|
|
351
|
-
{{ fetchDebugTask.error ?? "
|
|
353
|
+
{{ fetchDebugTask.error ?? t("blueprint.config.requestFailed") }}
|
|
352
354
|
</p>
|
|
353
355
|
</div>
|
|
354
356
|
<div
|
|
@@ -366,7 +368,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
366
368
|
>
|
|
367
369
|
▼
|
|
368
370
|
</span>
|
|
369
|
-
<span class="text-[11px] font-medium text-foreground"
|
|
371
|
+
<span class="text-[11px] font-medium text-foreground">{{ t("blueprint.config.debugResponse") }}</span>
|
|
370
372
|
<span
|
|
371
373
|
class="rounded px-1.5 py-0.5 font-mono text-[10px]"
|
|
372
374
|
:class="
|
|
@@ -396,7 +398,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
396
398
|
</label>
|
|
397
399
|
|
|
398
400
|
<label class="block space-y-1">
|
|
399
|
-
<span class="text-muted-foreground"
|
|
401
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.requestMethod") }}</span>
|
|
400
402
|
<Select
|
|
401
403
|
size="small"
|
|
402
404
|
class="w-full"
|
|
@@ -416,7 +418,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
416
418
|
</label>
|
|
417
419
|
|
|
418
420
|
<label class="block space-y-1">
|
|
419
|
-
<span class="text-muted-foreground"
|
|
421
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.requestHeadersJson") }}</span>
|
|
420
422
|
<textarea
|
|
421
423
|
:key="`${node.id}-headers-${JSON.stringify(fetchConfig.headers)}`"
|
|
422
424
|
:value="JSON.stringify(fetchConfig.headers ?? {}, null, 2)"
|
|
@@ -428,7 +430,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
428
430
|
</label>
|
|
429
431
|
|
|
430
432
|
<label class="block space-y-1">
|
|
431
|
-
<span class="text-muted-foreground"
|
|
433
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.requestBody") }}</span>
|
|
432
434
|
<textarea
|
|
433
435
|
:value="fetchConfig.body ?? ''"
|
|
434
436
|
rows="4"
|
|
@@ -519,7 +521,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
519
521
|
|
|
520
522
|
<div class="grid grid-cols-2 gap-2">
|
|
521
523
|
<label class="block space-y-1">
|
|
522
|
-
<span class="text-muted-foreground"
|
|
524
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.responseParse") }}</span>
|
|
523
525
|
<Select
|
|
524
526
|
size="small"
|
|
525
527
|
class="w-full"
|
|
@@ -538,7 +540,7 @@ function handleHeadersBlur(event: Event) {
|
|
|
538
540
|
</Select>
|
|
539
541
|
</label>
|
|
540
542
|
<label class="block space-y-1">
|
|
541
|
-
<span class="text-muted-foreground"
|
|
543
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.timeoutMs") }}</span>
|
|
542
544
|
<Input
|
|
543
545
|
type="number"
|
|
544
546
|
size="small"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { computed, onUnmounted, ref, watch } from "vue";
|
|
3
4
|
import {
|
|
4
5
|
buildEndpointSuggestions,
|
|
@@ -8,6 +9,8 @@ import {
|
|
|
8
9
|
|
|
9
10
|
import { cn } from "../utils/cn";
|
|
10
11
|
|
|
12
|
+
const { t } = useI18n();
|
|
13
|
+
|
|
11
14
|
const props = withDefaults(
|
|
12
15
|
defineProps<{
|
|
13
16
|
value: string;
|
|
@@ -155,7 +158,7 @@ function handleKeyDown(event: KeyboardEvent) {
|
|
|
155
158
|
v-if="filtered.length === 0"
|
|
156
159
|
class="px-2 py-1.5 text-[11px] text-muted-foreground"
|
|
157
160
|
>
|
|
158
|
-
|
|
161
|
+
{{ t("blueprint.config.noMatchingEndpoint") }}
|
|
159
162
|
</div>
|
|
160
163
|
<button
|
|
161
164
|
v-for="(item, index) in filtered"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { computed, ref } from "vue";
|
|
3
4
|
import { validateJsonString } from "@arronqzy/blueprint-dsl";
|
|
4
5
|
import type { JsonNodeConfig } from "@arronqzy/blueprint-dsl";
|
|
@@ -6,6 +7,8 @@ import type { JsonNodeConfig } from "@arronqzy/blueprint-dsl";
|
|
|
6
7
|
import type { BlueprintGraphNode } from "../graph/document";
|
|
7
8
|
import { resolveNodeJsonConfig } from "../graph/document";
|
|
8
9
|
|
|
10
|
+
const { t } = useI18n();
|
|
11
|
+
|
|
9
12
|
export type JsonNodeConfigPanelProps = {
|
|
10
13
|
node: BlueprintGraphNode;
|
|
11
14
|
onUpdateNode: (
|
|
@@ -45,15 +48,11 @@ function handleChange(event: Event) {
|
|
|
45
48
|
|
|
46
49
|
<template>
|
|
47
50
|
<div class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5">
|
|
48
|
-
<div class="font-medium text-foreground">
|
|
49
|
-
<p class="text-[11px] text-muted-foreground">
|
|
50
|
-
收到<strong>真信号</strong>后,将下方 JSON 解析为 JavaScript object(或
|
|
51
|
-
array)并从输出口发出<strong>真信号</strong>;解析失败则发出
|
|
52
|
-
<strong>假信号</strong>。
|
|
53
|
-
</p>
|
|
51
|
+
<div class="font-medium text-foreground">{{ t("blueprint.config.jsonTitle") }}</div>
|
|
52
|
+
<p class="text-[11px] text-muted-foreground">{{ t("blueprint.config.jsonHint") }}</p>
|
|
54
53
|
|
|
55
54
|
<label class="block space-y-1">
|
|
56
|
-
<span class="text-muted-foreground">
|
|
55
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.jsonContent") }}</span>
|
|
57
56
|
<textarea
|
|
58
57
|
:value="jsonConfig.jsonString"
|
|
59
58
|
rows="12"
|
|
@@ -65,9 +64,9 @@ function handleChange(event: Event) {
|
|
|
65
64
|
@input="handleChange"
|
|
66
65
|
/>
|
|
67
66
|
<p v-if="parseError" class="text-[11px] text-destructive">
|
|
68
|
-
|
|
67
|
+
{{ t("blueprint.config.jsonFormatError", { error: parseError }) }}
|
|
69
68
|
</p>
|
|
70
|
-
<p v-else class="text-[11px] text-muted-foreground">
|
|
69
|
+
<p v-else class="text-[11px] text-muted-foreground">{{ t("blueprint.config.jsonFormatOk") }}</p>
|
|
71
70
|
</label>
|
|
72
71
|
</div>
|
|
73
72
|
</template>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { computed, ref } from "vue";
|
|
3
4
|
import { validateLogicSourceCode } from "@arronqzy/blueprint-dsl";
|
|
4
5
|
import type { LogicNodeConfig } from "@arronqzy/blueprint-dsl";
|
|
@@ -6,6 +7,8 @@ import type { LogicNodeConfig } from "@arronqzy/blueprint-dsl";
|
|
|
6
7
|
import type { BlueprintGraphNode } from "../graph/document";
|
|
7
8
|
import { resolveNodeLogicConfig } from "../graph/document";
|
|
8
9
|
|
|
10
|
+
const { t } = useI18n();
|
|
11
|
+
|
|
9
12
|
export type LogicNodeConfigPanelProps = {
|
|
10
13
|
node: BlueprintGraphNode;
|
|
11
14
|
onUpdateNode: (
|
|
@@ -45,15 +48,11 @@ function handleChange(event: Event) {
|
|
|
45
48
|
|
|
46
49
|
<template>
|
|
47
50
|
<div class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5">
|
|
48
|
-
<div class="font-medium text-foreground"
|
|
49
|
-
<p class="text-[11px] text-muted-foreground">
|
|
50
|
-
收到<strong>真信号</strong>后,将输入数据传入下方 <code>update</code>
|
|
51
|
-
函数并执行;返回值作为<strong>真信号</strong>输出。代码语法错误或运行时报错则发出
|
|
52
|
-
<strong>假信号</strong>(错误信息为输出值)。
|
|
53
|
-
</p>
|
|
51
|
+
<div class="font-medium text-foreground">{{ t("blueprint.config.logicTitle") }}</div>
|
|
52
|
+
<p class="text-[11px] text-muted-foreground">{{ t("blueprint.config.logicHint") }}</p>
|
|
54
53
|
|
|
55
54
|
<label class="block space-y-1">
|
|
56
|
-
<span class="text-muted-foreground">
|
|
55
|
+
<span class="text-muted-foreground">{{ t("blueprint.config.jsCode") }}</span>
|
|
57
56
|
<textarea
|
|
58
57
|
:value="logicConfig.sourceCode"
|
|
59
58
|
rows="14"
|
|
@@ -65,9 +64,9 @@ function handleChange(event: Event) {
|
|
|
65
64
|
@input="handleChange"
|
|
66
65
|
/>
|
|
67
66
|
<p v-if="parseError" class="text-[11px] text-destructive">
|
|
68
|
-
|
|
67
|
+
{{ t("blueprint.config.jsError", { error: parseError }) }}
|
|
69
68
|
</p>
|
|
70
|
-
<p v-else class="text-[11px] text-muted-foreground">
|
|
69
|
+
<p v-else class="text-[11px] text-muted-foreground">{{ t("blueprint.config.jsSyntaxOk") }}</p>
|
|
71
70
|
</label>
|
|
72
71
|
</div>
|
|
73
72
|
</template>
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from "@arronqzy/i18n/vue";
|
|
2
3
|
import { computed } from "vue";
|
|
3
4
|
import { Select } from "ant-design-vue";
|
|
4
5
|
|
|
6
|
+
const { t } = useI18n();
|
|
7
|
+
|
|
5
8
|
export type ViewElementMultiSelectOption = {
|
|
6
9
|
id: string;
|
|
7
10
|
label: string;
|
|
@@ -15,7 +18,7 @@ const props = withDefaults(
|
|
|
15
18
|
disabled?: boolean;
|
|
16
19
|
}>(),
|
|
17
20
|
{
|
|
18
|
-
placeholder:
|
|
21
|
+
placeholder: undefined,
|
|
19
22
|
disabled: false,
|
|
20
23
|
}
|
|
21
24
|
);
|
|
@@ -37,7 +40,7 @@ const emptyOptions = computed(() => props.options.length === 0);
|
|
|
37
40
|
show-search
|
|
38
41
|
:value="value"
|
|
39
42
|
:disabled="disabled || emptyOptions"
|
|
40
|
-
:placeholder="emptyOptions ? '
|
|
43
|
+
:placeholder="emptyOptions ? t('blueprint.config.noViewOnCanvas') : (placeholder ?? t('blueprint.config.selectViewNode'))"
|
|
41
44
|
:options="selectOptions"
|
|
42
45
|
:filter-option="
|
|
43
46
|
(input, option) =>
|
|
@@ -241,4 +241,31 @@ export function useBlueprintPageLifecycle(options: UseBlueprintPageLifecycleOpti
|
|
|
241
241
|
onUnmounted(() => {
|
|
242
242
|
teardownBoot();
|
|
243
243
|
});
|
|
244
|
+
|
|
245
|
+
async function triggerBlueprintNode(nodeId: string, inputValue?: unknown) {
|
|
246
|
+
const id = nodeId.trim();
|
|
247
|
+
if (!id) return;
|
|
248
|
+
const opts = runnerOptionsRef.value;
|
|
249
|
+
const libraryNameById = toValue(opts.libraryNameById);
|
|
250
|
+
const rootLibraryBlueprintId = toValue(opts.rootLibraryBlueprintId ?? null);
|
|
251
|
+
if (opts.resolveLibraryBlueprint) {
|
|
252
|
+
const result = await detectBlueprintReferenceCycle({
|
|
253
|
+
rootGraph: documentToRunnableGraph(graphRef.value.document, {
|
|
254
|
+
libraryNameById,
|
|
255
|
+
}),
|
|
256
|
+
rootLibraryBlueprintId,
|
|
257
|
+
resolveLibraryBlueprint: opts.resolveLibraryBlueprint,
|
|
258
|
+
resolveBlueprintName: (libId) =>
|
|
259
|
+
resolveBlueprintName(libraryNameById, libId),
|
|
260
|
+
});
|
|
261
|
+
if (!result.ok) {
|
|
262
|
+
opts.onExecutionBlocked?.(result.message);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const runner = createRunner(graphRef.value, opts);
|
|
267
|
+
await runner.triggerNode(id, inputValue);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return { triggerBlueprintNode };
|
|
244
271
|
}
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
ParsedSwaggerDocument,
|
|
6
6
|
} from "@arronqzy/blueprint-dsl";
|
|
7
7
|
import { executeFetch } from "@arronqzy/blueprint-dsl";
|
|
8
|
+
import { resolveLocale, tForLocale } from "@arronqzy/i18n";
|
|
8
9
|
|
|
9
10
|
import { loadSwaggerDocument } from "./library/swagger-docs";
|
|
10
11
|
|
|
@@ -152,7 +153,9 @@ export function startSwaggerLoadTask(params: {
|
|
|
152
153
|
}
|
|
153
154
|
|
|
154
155
|
const message =
|
|
155
|
-
error instanceof Error
|
|
156
|
+
error instanceof Error
|
|
157
|
+
? error.message
|
|
158
|
+
: tForLocale(resolveLocale())("blueprint.config.swaggerParseFailed");
|
|
156
159
|
swaggerTasks.set(params.nodeId, {
|
|
157
160
|
record: { status: "error", error: message },
|
|
158
161
|
abortController,
|
|
@@ -195,7 +198,10 @@ export function startFetchDebugTask(params: {
|
|
|
195
198
|
return;
|
|
196
199
|
}
|
|
197
200
|
|
|
198
|
-
const message =
|
|
201
|
+
const message =
|
|
202
|
+
error instanceof Error
|
|
203
|
+
? error.message
|
|
204
|
+
: tForLocale(resolveLocale())("blueprint.config.requestFailed");
|
|
199
205
|
fetchDebugTasks.set(params.nodeId, {
|
|
200
206
|
record: { status: "error", error: message },
|
|
201
207
|
abortController,
|
package/src/graph/document.ts
CHANGED
|
@@ -133,35 +133,72 @@ export function resolveRunnableNodeType(
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
import type { TranslateFn } from "@arronqzy/i18n";
|
|
137
|
+
import { resolveLocale, tForLocale } from "@arronqzy/i18n";
|
|
138
|
+
|
|
139
|
+
/** 画布节点顶部(拖拽区)配置类型对应的 i18n key */
|
|
140
|
+
export const BLUEPRINT_CONFIG_TYPE_LABEL_KEYS: Record<
|
|
138
141
|
BlueprintConfigSource,
|
|
139
142
|
string
|
|
140
143
|
> = {
|
|
141
|
-
blueprint: "
|
|
142
|
-
logic: "
|
|
143
|
-
and: "
|
|
144
|
-
lifecycle: "
|
|
145
|
-
view: "
|
|
146
|
-
fetch: "
|
|
147
|
-
json: "
|
|
148
|
-
clock: "
|
|
144
|
+
blueprint: "blueprint.node.typeBlueprint",
|
|
145
|
+
logic: "blueprint.node.typeLogic",
|
|
146
|
+
and: "blueprint.node.typeAnd",
|
|
147
|
+
lifecycle: "blueprint.node.typeLifecycle",
|
|
148
|
+
view: "blueprint.node.typeView",
|
|
149
|
+
fetch: "blueprint.node.typeFetch",
|
|
150
|
+
json: "blueprint.node.typeJson",
|
|
151
|
+
clock: "blueprint.node.typeClock",
|
|
149
152
|
};
|
|
150
153
|
|
|
154
|
+
export const BLUEPRINT_LIFECYCLE_PHASE_KEYS: Record<PageLifecyclePhase, string> =
|
|
155
|
+
{
|
|
156
|
+
created: "blueprint.node.phaseCreated",
|
|
157
|
+
beforeMount: "blueprint.node.phaseBeforeMount",
|
|
158
|
+
mounted: "blueprint.node.phaseMounted",
|
|
159
|
+
updated: "blueprint.node.phaseUpdated",
|
|
160
|
+
beforeDestroy: "blueprint.node.phaseBeforeDestroy",
|
|
161
|
+
destroy: "blueprint.node.phaseDestroy",
|
|
162
|
+
activated: "blueprint.node.phaseActivated",
|
|
163
|
+
deactivated: "blueprint.node.phaseDeactivated",
|
|
164
|
+
blueprintActivated: "blueprint.node.phaseBlueprintActivated",
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
function defaultTranslate(): TranslateFn {
|
|
168
|
+
return tForLocale(resolveLocale());
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function getBlueprintNodeTypeLabel(
|
|
172
|
+
t: TranslateFn,
|
|
173
|
+
type: BlueprintConfigSource
|
|
174
|
+
): string {
|
|
175
|
+
return t(BLUEPRINT_CONFIG_TYPE_LABEL_KEYS[type]);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function getLifecyclePhaseLabel(
|
|
179
|
+
t: TranslateFn,
|
|
180
|
+
phase: PageLifecyclePhase
|
|
181
|
+
): string {
|
|
182
|
+
const key = BLUEPRINT_LIFECYCLE_PHASE_KEYS[phase];
|
|
183
|
+
return key ? t(key) : phase;
|
|
184
|
+
}
|
|
185
|
+
|
|
151
186
|
export function resolveBlueprintNodeTypeLabel(
|
|
152
187
|
node: Pick<
|
|
153
188
|
BlueprintGraphNode,
|
|
154
189
|
"role" | "nodeType" | "configSource" | "viewElementId" | "viewElementIds"
|
|
155
|
-
|
|
190
|
+
>,
|
|
191
|
+
t: TranslateFn = defaultTranslate()
|
|
156
192
|
): string {
|
|
157
|
-
return
|
|
193
|
+
return getBlueprintNodeTypeLabel(t, resolveBlueprintConfigSource(node));
|
|
158
194
|
}
|
|
159
195
|
|
|
160
196
|
/** 新建节点时的默认显示名称(与类型文案一致) */
|
|
161
197
|
export function defaultBlueprintNodeLabel(
|
|
162
|
-
configSource: BlueprintConfigSource
|
|
198
|
+
configSource: BlueprintConfigSource,
|
|
199
|
+
t: TranslateFn = defaultTranslate()
|
|
163
200
|
): string {
|
|
164
|
-
return
|
|
201
|
+
return getBlueprintNodeTypeLabel(t, configSource);
|
|
165
202
|
}
|
|
166
203
|
|
|
167
204
|
export function resolveNodeFetchConfig(
|