@arronqzy/vue-blueprint 0.1.18 → 0.1.20
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arronqzy/vue-blueprint",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"description": "Vue 3 blueprint editor for Abuilder (Vue Flow + Ant Design Vue)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"dayjs": "^1.11.13",
|
|
21
21
|
"vue": "^3.5.13",
|
|
22
22
|
"@arronqzy/blueprint-dsl": "1.0.17",
|
|
23
|
-
"@arronqzy/
|
|
24
|
-
"@arronqzy/
|
|
23
|
+
"@arronqzy/vue-rx-store": "0.1.6",
|
|
24
|
+
"@arronqzy/i18n": "0.1.17"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"vue": "^3.4.0"
|
|
@@ -244,6 +244,7 @@ async function handleFiles(files: FileList | null) {
|
|
|
244
244
|
:title="t('blueprint.apiCollection.managerTitle')"
|
|
245
245
|
:footer="null"
|
|
246
246
|
width="960px"
|
|
247
|
+
:mask-style="{ background: 'transparent' }"
|
|
247
248
|
:body-style="{ maxHeight: '90vh', display: 'flex', flexDirection: 'column' }"
|
|
248
249
|
@update:open="onOpenChange"
|
|
249
250
|
>
|
|
@@ -350,47 +351,48 @@ async function handleFiles(files: FileList | null) {
|
|
|
350
351
|
: t('blueprint.apiCollection.createTitle')
|
|
351
352
|
"
|
|
352
353
|
:footer="null"
|
|
353
|
-
width="
|
|
354
|
+
width="620px"
|
|
354
355
|
:style="{ top: '4vh' }"
|
|
356
|
+
:mask-style="{ background: 'transparent' }"
|
|
357
|
+
destroy-on-close
|
|
355
358
|
@update:open="(v) => (editorOpen = v)"
|
|
356
359
|
>
|
|
357
|
-
<p class="mb-
|
|
360
|
+
<p class="mb-2 text-xs text-muted-foreground">
|
|
358
361
|
{{ t("blueprint.apiCollection.editorDescription") }}
|
|
359
362
|
</p>
|
|
360
363
|
|
|
361
|
-
<div class="
|
|
362
|
-
<
|
|
363
|
-
<span class="text-xs">{{ t("blueprint.apiCollection.jsonEditor") }}</span>
|
|
364
|
-
<label class="flex cursor-pointer items-center gap-2 text-[11px] text-muted-foreground">
|
|
365
|
-
<Checkbox v-model:checked="editorPersistLocal" />
|
|
366
|
-
{{ t("blueprint.apiCollection.persistLocal") }}
|
|
367
|
-
</label>
|
|
368
|
-
</div>
|
|
369
|
-
<Input.TextArea
|
|
370
|
-
v-model:value="editorJson"
|
|
371
|
-
:rows="28"
|
|
372
|
-
:spellcheck="false"
|
|
373
|
-
class="!min-h-[62vh] font-mono text-[12px] leading-relaxed"
|
|
374
|
-
:status="editorError ? 'error' : undefined"
|
|
375
|
-
/>
|
|
376
|
-
<p v-if="editorError" class="text-[11px] text-destructive">{{ editorError }}</p>
|
|
377
|
-
</div>
|
|
378
|
-
|
|
379
|
-
<div class="mt-4 flex flex-wrap justify-end gap-2">
|
|
380
|
-
<Button @click="downloadApiCollectionTemplate()">
|
|
364
|
+
<div class="mb-2 flex flex-wrap items-center gap-1.5 border-b border-border/60 pb-2">
|
|
365
|
+
<Button size="small" @click="downloadApiCollectionTemplate()">
|
|
381
366
|
{{ t("blueprint.apiCollection.downloadTemplate") }}
|
|
382
367
|
</Button>
|
|
383
368
|
<Button
|
|
369
|
+
size="small"
|
|
384
370
|
:disabled="busy || !onSyncCollection"
|
|
385
371
|
:title="t('blueprint.apiCollection.syncHint')"
|
|
386
372
|
@click="void handleSyncFromEditor()"
|
|
387
373
|
>
|
|
388
374
|
{{ t("blueprint.apiCollection.sync") }}
|
|
389
375
|
</Button>
|
|
390
|
-
<Button @click="editorOpen = false">{{ t("common.cancel") }}</Button>
|
|
391
|
-
<Button type="primary" :disabled="busy" @click="void handleSaveEditor()">
|
|
376
|
+
<Button size="small" @click="editorOpen = false">{{ t("common.cancel") }}</Button>
|
|
377
|
+
<Button size="small" type="primary" :disabled="busy" @click="void handleSaveEditor()">
|
|
392
378
|
{{ t("common.save") }}
|
|
393
379
|
</Button>
|
|
380
|
+
<label class="ml-auto flex cursor-pointer items-center gap-1.5 text-[11px] text-muted-foreground">
|
|
381
|
+
<Checkbox v-model:checked="editorPersistLocal" />
|
|
382
|
+
{{ t("blueprint.apiCollection.persistLocal") }}
|
|
383
|
+
</label>
|
|
384
|
+
</div>
|
|
385
|
+
|
|
386
|
+
<div class="flex flex-col gap-2">
|
|
387
|
+
<span class="text-xs">{{ t("blueprint.apiCollection.jsonEditor") }}</span>
|
|
388
|
+
<Input.TextArea
|
|
389
|
+
v-model:value="editorJson"
|
|
390
|
+
:rows="16"
|
|
391
|
+
:spellcheck="false"
|
|
392
|
+
class="!h-[min(68vh,640px)] !min-h-[320px] font-mono text-[12px] leading-relaxed"
|
|
393
|
+
:status="editorError ? 'error' : undefined"
|
|
394
|
+
/>
|
|
395
|
+
<p v-if="editorError" class="text-[11px] text-destructive">{{ editorError }}</p>
|
|
394
396
|
</div>
|
|
395
397
|
</Modal>
|
|
396
398
|
</template>
|
package/src/index.ts
CHANGED
|
@@ -70,18 +70,48 @@ export type UpsertApiCollectionInput = {
|
|
|
70
70
|
persistLocal: boolean;
|
|
71
71
|
/** 未写 document.name 时用文件名 */
|
|
72
72
|
fallbackName?: string;
|
|
73
|
+
/** 省略时写入当前已 hydrate 的 nameSpace */
|
|
74
|
+
nameSpace?: string | null;
|
|
73
75
|
};
|
|
74
76
|
|
|
75
77
|
export type UpsertApiCollectionResult =
|
|
76
78
|
| { ok: true; record: ApiCollectionRecord }
|
|
77
79
|
| { ok: false; error: string };
|
|
78
80
|
|
|
81
|
+
function isCurrentNameSpace(nameSpace?: string | null): boolean {
|
|
82
|
+
return normalizeAppNameSpace(nameSpace) === normalizeAppNameSpace(nameSpaceRef);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** 写入接口集合;persistLocal 时落 IndexedDB,同一 nameSpace 下刷新内存列表 */
|
|
86
|
+
export async function putApiCollection(
|
|
87
|
+
record: ApiCollectionRecord,
|
|
88
|
+
nameSpace?: string | null
|
|
89
|
+
): Promise<ApiCollectionRecord> {
|
|
90
|
+
if (record.persistLocal) {
|
|
91
|
+
await putApiCollectionRecord(record, nameSpace);
|
|
92
|
+
} else if (isCurrentNameSpace(nameSpace)) {
|
|
93
|
+
const existing = records.find((item) => item.id === record.id);
|
|
94
|
+
if (existing?.persistLocal) {
|
|
95
|
+
await deleteApiCollectionRecord(record.id, nameSpace);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (isCurrentNameSpace(nameSpace)) {
|
|
99
|
+
const next = records.filter((item) => item.id !== record.id);
|
|
100
|
+
next.push(record);
|
|
101
|
+
records = sortRecords(next);
|
|
102
|
+
emit();
|
|
103
|
+
}
|
|
104
|
+
return record;
|
|
105
|
+
}
|
|
106
|
+
|
|
79
107
|
export async function upsertApiCollectionFromJson(
|
|
80
108
|
input: UpsertApiCollectionInput
|
|
81
109
|
): Promise<UpsertApiCollectionResult> {
|
|
82
110
|
const parsed = parseApiCollectionJson(input.rawJson);
|
|
83
111
|
if (!parsed.ok) return parsed;
|
|
84
112
|
|
|
113
|
+
const targetNameSpace =
|
|
114
|
+
input.nameSpace !== undefined ? input.nameSpace : nameSpaceRef;
|
|
85
115
|
const document: ApiCollectionDocument = {
|
|
86
116
|
...parsed.document,
|
|
87
117
|
name:
|
|
@@ -90,11 +120,18 @@ export async function upsertApiCollectionFromJson(
|
|
|
90
120
|
parsed.document.name,
|
|
91
121
|
};
|
|
92
122
|
const now = Date.now();
|
|
93
|
-
const
|
|
123
|
+
const existingInMemory = input.id
|
|
94
124
|
? records.find((item) => item.id === input.id) ?? null
|
|
95
125
|
: null;
|
|
126
|
+
const existingPersisted =
|
|
127
|
+
input.id && !isCurrentNameSpace(targetNameSpace)
|
|
128
|
+
? await listApiCollectionRecords(targetNameSpace).then(
|
|
129
|
+
(list) => list.find((item) => item.id === input.id) ?? null
|
|
130
|
+
)
|
|
131
|
+
: null;
|
|
132
|
+
const existing = existingInMemory ?? existingPersisted;
|
|
96
133
|
const record: ApiCollectionRecord = {
|
|
97
|
-
id: existing?.id ?? createApiCollectionId(),
|
|
134
|
+
id: existing?.id ?? input.id ?? createApiCollectionId(),
|
|
98
135
|
name: document.name,
|
|
99
136
|
persistLocal: input.persistLocal,
|
|
100
137
|
document,
|
|
@@ -103,16 +140,7 @@ export async function upsertApiCollectionFromJson(
|
|
|
103
140
|
updatedAt: now,
|
|
104
141
|
};
|
|
105
142
|
|
|
106
|
-
|
|
107
|
-
await putApiCollectionRecord(record, nameSpaceRef);
|
|
108
|
-
} else if (existing?.persistLocal) {
|
|
109
|
-
await deleteApiCollectionRecord(record.id, nameSpaceRef);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const next = records.filter((item) => item.id !== record.id);
|
|
113
|
-
next.push(record);
|
|
114
|
-
records = sortRecords(next);
|
|
115
|
-
emit();
|
|
143
|
+
await putApiCollection(record, targetNameSpace);
|
|
116
144
|
return { ok: true, record };
|
|
117
145
|
}
|
|
118
146
|
|
|
@@ -129,10 +157,6 @@ export async function removeApiCollection(id: string): Promise<void> {
|
|
|
129
157
|
emit();
|
|
130
158
|
}
|
|
131
159
|
|
|
132
|
-
function isCurrentNameSpace(nameSpace?: string | null): boolean {
|
|
133
|
-
return normalizeAppNameSpace(nameSpace) === normalizeAppNameSpace(nameSpaceRef);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
160
|
/** 按 nameSpace 删除接口集合;若该 nameSpace 正在被编辑器使用,内存列表同步移除 */
|
|
137
161
|
export async function deleteApiCollection(
|
|
138
162
|
id: string,
|