@shwfed/config 3.0.12 → 3.0.14
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/dist/module.json +1 -1
- package/dist/runtime/components/actions/buttons/2026-04-18/com.shwfed.actions.button.http.request.json/config.d.vue.ts +2 -2
- package/dist/runtime/components/actions/buttons/2026-04-18/com.shwfed.actions.button.http.request.json/config.vue.d.ts +2 -2
- package/dist/runtime/components/actions/buttons/2026-04-18/com.shwfed.actions.button.http.request.json.confirm/config.d.vue.ts +2 -2
- package/dist/runtime/components/actions/buttons/2026-04-18/com.shwfed.actions.button.http.request.json.confirm/config.vue.d.ts +2 -2
- package/dist/runtime/components/actions/buttons/2026-06-08/com.shwfed.actions.button.http.request.json.batch/config.d.vue.ts +2 -2
- package/dist/runtime/components/actions/buttons/2026-06-08/com.shwfed.actions.button.http.request.json.batch/config.vue.d.ts +2 -2
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/config.d.vue.ts +8 -8
- package/dist/runtime/components/actions/buttons/2026-06-25/com.shwfed.actions.button.state.write/config.vue.d.ts +8 -8
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.digital/config.d.vue.ts +10 -8
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.digital/config.vue +272 -286
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.digital/config.vue.d.ts +10 -8
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.digital/runtime.d.vue.ts +10 -8
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.digital/runtime.vue +91 -291
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.digital/runtime.vue.d.ts +10 -8
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.digital/schema.d.ts +4 -28
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.digital/schema.js +14 -33
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/config.d.vue.ts +96 -0
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/config.vue +385 -0
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/config.vue.d.ts +96 -0
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/items-colgroup.d.vue.ts +3 -0
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/items-colgroup.vue +20 -0
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/items-colgroup.vue.d.ts +3 -0
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/runtime.d.vue.ts +96 -0
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/runtime.vue +177 -0
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/runtime.vue.d.ts +96 -0
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/schema.d.ts +102 -0
- package/dist/runtime/components/config/blocks/2026-07-17/com.shwfed.block.invoice.realestate.lease/schema.js +186 -0
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/config.d.vue.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.textarea/config.vue.d.ts +2 -2
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.d.vue.ts +22 -22
- package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.vue.d.ts +22 -22
- package/dist/runtime/components/form/utils/validation.js +9 -7
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-07-16/com.shwfed.table.column.upload/config.vue +57 -247
- package/dist/runtime/components/table/columns/2026-07-16/com.shwfed.table.column.upload/prompt.md +2 -2
- package/dist/runtime/components/table/columns/2026-07-16/com.shwfed.table.column.upload/runtime.vue +29 -126
- package/dist/runtime/components/table/columns/2026-07-16/com.shwfed.table.column.upload/schema.d.ts +5 -27
- package/dist/runtime/components/table/columns/2026-07-16/com.shwfed.table.column.upload/schema.js +10 -37
- package/dist/runtime/components/ui/invoice/InvoiceSheet.d.vue.ts +66 -0
- package/dist/runtime/components/ui/invoice/InvoiceSheet.vue +182 -0
- package/dist/runtime/components/ui/invoice/InvoiceSheet.vue.d.ts +66 -0
- package/dist/runtime/components/ui/invoice/index.d.ts +1 -0
- package/dist/runtime/components/ui/invoice/index.js +1 -0
- package/dist/runtime/components/ui/invoice-config/InvoiceConfigShell.d.vue.ts +36 -0
- package/dist/runtime/components/ui/invoice-config/InvoiceConfigShell.vue +41 -0
- package/dist/runtime/components/ui/invoice-config/InvoiceConfigShell.vue.d.ts +36 -0
- package/dist/runtime/components/{config/blocks/2026-07-17/com.shwfed.block.invoice.digital/expr-field.vue → ui/invoice-config/InvoiceExprField.vue} +4 -4
- package/dist/runtime/components/{config/blocks/2026-07-17/com.shwfed.block.invoice.digital/json-scope-provider.vue → ui/invoice-config/InvoiceJsonScope.vue} +3 -3
- package/dist/runtime/components/{config/blocks/2026-07-17/com.shwfed.block.invoice.digital/row-scope-provider.vue → ui/invoice-config/InvoiceRowScope.vue} +2 -2
- package/dist/runtime/components/ui/invoice-config/index.d.ts +4 -0
- package/dist/runtime/components/ui/invoice-config/index.js +4 -0
- package/dist/runtime/share/invoice-eval.d.ts +13 -0
- package/dist/runtime/share/invoice-eval.js +88 -0
- package/dist/runtime/share/invoice.d.ts +68 -0
- package/dist/runtime/share/invoice.js +35 -0
- package/dist/runtime/share/slot-renderer.vue +83 -24
- package/dist/runtime/vendor/cel-js/CLAUDE.md +3 -1
- package/dist/runtime/vendor/cel-js/PROMPT.md +31 -2
- package/dist/runtime/vendor/cel-js/lib/functions.js +28 -1
- package/dist/runtime/vendor/cel-js/lib/registry.js +2 -1
- package/package.json +1 -1
- /package/dist/runtime/components/{config/blocks/2026-07-17/com.shwfed.block.invoice.digital/expr-field.d.vue.ts → ui/invoice-config/InvoiceExprField.d.vue.ts} +0 -0
- /package/dist/runtime/components/{config/blocks/2026-07-17/com.shwfed.block.invoice.digital/expr-field.vue.d.ts → ui/invoice-config/InvoiceExprField.vue.d.ts} +0 -0
- /package/dist/runtime/components/{config/blocks/2026-07-17/com.shwfed.block.invoice.digital/json-scope-provider.d.vue.ts → ui/invoice-config/InvoiceJsonScope.d.vue.ts} +0 -0
- /package/dist/runtime/components/{config/blocks/2026-07-17/com.shwfed.block.invoice.digital/json-scope-provider.vue.d.ts → ui/invoice-config/InvoiceJsonScope.vue.d.ts} +0 -0
- /package/dist/runtime/components/{config/blocks/2026-07-17/com.shwfed.block.invoice.digital/row-scope-provider.d.vue.ts → ui/invoice-config/InvoiceRowScope.d.vue.ts} +0 -0
- /package/dist/runtime/components/{config/blocks/2026-07-17/com.shwfed.block.invoice.digital/row-scope-provider.vue.d.ts → ui/invoice-config/InvoiceRowScope.vue.d.ts} +0 -0
- /package/dist/runtime/{components/config/blocks/2026-07-17/com.shwfed.block.invoice.digital → share}/rmb.d.ts +0 -0
- /package/dist/runtime/{components/config/blocks/2026-07-17/com.shwfed.block.invoice.digital → share}/rmb.js +0 -0
package/dist/runtime/components/table/columns/2026-07-16/com.shwfed.table.column.upload/config.vue
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, defineComponent, ref
|
|
2
|
+
import { computed, defineComponent, ref } from "vue";
|
|
3
3
|
import { Icon } from "@iconify/vue";
|
|
4
|
-
import {
|
|
5
|
-
useTreeDnd
|
|
6
|
-
} from "../../../../../composables/useTreeDnd";
|
|
7
4
|
import { provideCELContext } from "../../../../../utils/cel-context";
|
|
8
5
|
import TriggersField from "../../../../actions/components/triggers-field.vue";
|
|
9
6
|
import { ExpressionEditor } from "../../../../ui/expression-editor";
|
|
10
7
|
import { Separator } from "../../../../ui/separator";
|
|
11
8
|
import { Switch } from "../../../../ui/switch";
|
|
12
|
-
import { Button } from "../../../../ui/button";
|
|
13
9
|
import { Field, FieldLabel } from "../../../../ui/field";
|
|
14
10
|
import { IconPicker } from "../../../../ui/icon-picker";
|
|
15
11
|
import { Locale } from "../../../../ui/locale";
|
|
@@ -35,7 +31,7 @@ import {
|
|
|
35
31
|
SelectValue
|
|
36
32
|
} from "../../../../ui/select";
|
|
37
33
|
import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
|
|
38
|
-
import { FILE_VAR, FILES_VAR,
|
|
34
|
+
import { FILE_VAR, FILES_VAR, UPLOAD_JSON_VAR, schema } from "./schema";
|
|
39
35
|
defineOptions({ name: "ShwfedTableUploadRendererConfig" });
|
|
40
36
|
const value = defineModel({ type: Object, ...{ required: true } });
|
|
41
37
|
const fieldSchema = schema(() => {
|
|
@@ -49,7 +45,6 @@ const ROW_VARS = {
|
|
|
49
45
|
const UPLOAD_REQUEST_VARS = { ...ROW_VARS, files: FILES_VAR };
|
|
50
46
|
const UPLOAD_HANDLE_VARS = { ...ROW_VARS, json: UPLOAD_JSON_VAR };
|
|
51
47
|
const UPLOAD_FILENAME_VARS = { ...ROW_VARS, file: FILE_VAR };
|
|
52
|
-
const TEMPLATE_DOWNLOAD_VARS = { ...ROW_VARS, json: JSON_VAR };
|
|
53
48
|
const bindingText = computed({
|
|
54
49
|
get: () => value.value.binding ?? "",
|
|
55
50
|
set: (next) => {
|
|
@@ -131,110 +126,22 @@ const uploadFilenameText = computed({
|
|
|
131
126
|
}
|
|
132
127
|
}
|
|
133
128
|
});
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (
|
|
137
|
-
const {
|
|
129
|
+
function updateAddIcon(icon) {
|
|
130
|
+
const trimmed = icon.trim();
|
|
131
|
+
if (trimmed.length === 0) {
|
|
132
|
+
const { addIcon: _omit, ...rest } = value.value;
|
|
138
133
|
value.value = rest;
|
|
139
134
|
} else {
|
|
140
|
-
value.value = { ...value.value,
|
|
135
|
+
value.value = { ...value.value, addIcon: trimmed };
|
|
141
136
|
}
|
|
142
137
|
}
|
|
143
|
-
function
|
|
144
|
-
if (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
const rowKeys = ref([]);
|
|
151
|
-
watch(
|
|
152
|
-
() => templates.value.length,
|
|
153
|
-
(len) => {
|
|
154
|
-
if (len === rowKeys.value.length) return;
|
|
155
|
-
rowKeys.value = Array.from({ length: len }, () => makeId());
|
|
156
|
-
},
|
|
157
|
-
{ immediate: true }
|
|
158
|
-
);
|
|
159
|
-
function addTemplate() {
|
|
160
|
-
setTemplates([...templates.value, { request: "" }]);
|
|
161
|
-
rowKeys.value = [...rowKeys.value, makeId()];
|
|
162
|
-
}
|
|
163
|
-
function removeTemplate(index) {
|
|
164
|
-
setTemplates(templates.value.filter((_, i) => i !== index));
|
|
165
|
-
rowKeys.value = rowKeys.value.filter((_, i) => i !== index);
|
|
166
|
-
}
|
|
167
|
-
function move(from, to) {
|
|
168
|
-
if (from === to) return;
|
|
169
|
-
if (from < 0 || to < 0 || from >= templates.value.length || to >= templates.value.length) return;
|
|
170
|
-
const next = [...templates.value];
|
|
171
|
-
const [entry] = next.splice(from, 1);
|
|
172
|
-
if (!entry) return;
|
|
173
|
-
next.splice(to, 0, entry);
|
|
174
|
-
setTemplates(next);
|
|
175
|
-
const keys = [...rowKeys.value];
|
|
176
|
-
const [key] = keys.splice(from, 1);
|
|
177
|
-
if (!key) return;
|
|
178
|
-
keys.splice(to, 0, key);
|
|
179
|
-
rowKeys.value = keys;
|
|
180
|
-
}
|
|
181
|
-
function patchTemplate(index, patch) {
|
|
182
|
-
setTemplates(templates.value.map((entry, i) => i === index ? patch(entry) : entry));
|
|
183
|
-
}
|
|
184
|
-
const TEMPLATE_ROW_KIND = "shwfed-table-upload-template";
|
|
185
|
-
const rowId = (i) => rowKeys.value[i] ?? `idx-${i}`;
|
|
186
|
-
function onTemplateRowDrop(e) {
|
|
187
|
-
if (e.source.kind !== TEMPLATE_ROW_KIND || e.target.kind !== TEMPLATE_ROW_KIND) return;
|
|
188
|
-
const from = rowKeys.value.findIndex((k) => k === e.source.id);
|
|
189
|
-
const to = rowKeys.value.findIndex((k) => k === e.target.id);
|
|
190
|
-
if (from < 0 || to < 0) return;
|
|
191
|
-
if (e.instruction === "reorder-above") move(from, from < to ? to - 1 : to);
|
|
192
|
-
else if (e.instruction === "reorder-below") move(from, from <= to ? to : to + 1);
|
|
193
|
-
}
|
|
194
|
-
const templateDnd = useTreeDnd({ onRowDrop: onTemplateRowDrop });
|
|
195
|
-
const pickDragHandle = (el) => el.querySelector(".drag-handle");
|
|
196
|
-
function templateRowConfig(i) {
|
|
197
|
-
return {
|
|
198
|
-
kind: TEMPLATE_ROW_KIND,
|
|
199
|
-
canDrop: (src) => src.kind === TEMPLATE_ROW_KIND,
|
|
200
|
-
blockInstructions: (src) => {
|
|
201
|
-
const block = ["make-child", "reparent"];
|
|
202
|
-
if (src.id === rowId(i)) block.push("reorder-above", "reorder-below");
|
|
203
|
-
return block;
|
|
204
|
-
},
|
|
205
|
-
dragHandle: pickDragHandle
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
function updateTemplateRequest(index, request) {
|
|
209
|
-
patchTemplate(index, (entry) => ({ ...entry, request }));
|
|
210
|
-
}
|
|
211
|
-
function updateTemplateDownload(index, download) {
|
|
212
|
-
patchTemplate(index, (entry) => {
|
|
213
|
-
if (download.length === 0) {
|
|
214
|
-
const { download: _omit, ...rest } = entry;
|
|
215
|
-
return rest;
|
|
216
|
-
}
|
|
217
|
-
return { ...entry, download };
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
function updateTemplateIcon(index, icon) {
|
|
221
|
-
patchTemplate(index, (entry) => {
|
|
222
|
-
const trimmed = icon.trim();
|
|
223
|
-
if (trimmed.length === 0) {
|
|
224
|
-
const { icon: _omit, ...rest } = entry;
|
|
225
|
-
return rest;
|
|
226
|
-
}
|
|
227
|
-
return { ...entry, icon: trimmed };
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
function updateTemplateLabel(index, label) {
|
|
231
|
-
patchTemplate(index, (entry) => {
|
|
232
|
-
if (label == null || label.length === 0) {
|
|
233
|
-
const { label: _omit, ...rest } = entry;
|
|
234
|
-
return rest;
|
|
235
|
-
}
|
|
236
|
-
return { ...entry, label };
|
|
237
|
-
});
|
|
138
|
+
function updateAddLabel(label) {
|
|
139
|
+
if (label == null || label.length === 0) {
|
|
140
|
+
const { addLabel: _omit, ...rest } = value.value;
|
|
141
|
+
value.value = rest;
|
|
142
|
+
} else {
|
|
143
|
+
value.value = { ...value.value, addLabel: label };
|
|
144
|
+
}
|
|
238
145
|
}
|
|
239
146
|
const MIME_GROUPS = [
|
|
240
147
|
{ id: "pdf", label: "PDF", mimes: ["application/pdf"] },
|
|
@@ -424,25 +331,6 @@ const DownloadScope = defineComponent({
|
|
|
424
331
|
@update:model-value="(v) => value = { ...value, tooltip: v }"
|
|
425
332
|
/>
|
|
426
333
|
</Field>
|
|
427
|
-
<Field orientation="vertical">
|
|
428
|
-
<FieldLabel class="text-xs text-zinc-500">
|
|
429
|
-
<template
|
|
430
|
-
v-if="fieldDescription('placeholder')"
|
|
431
|
-
#tooltip
|
|
432
|
-
>
|
|
433
|
-
<Markdown
|
|
434
|
-
:source="fieldDescription('placeholder')"
|
|
435
|
-
block
|
|
436
|
-
class="prose prose-sm prose-zinc"
|
|
437
|
-
/>
|
|
438
|
-
</template>
|
|
439
|
-
{{ fieldTitle("placeholder") }}
|
|
440
|
-
</FieldLabel>
|
|
441
|
-
<Locale
|
|
442
|
-
:model-value="value.placeholder"
|
|
443
|
-
@update:model-value="(v) => value = { ...value, placeholder: v }"
|
|
444
|
-
/>
|
|
445
|
-
</Field>
|
|
446
334
|
</div>
|
|
447
335
|
|
|
448
336
|
<div class="grid grid-cols-3 gap-x-6 gap-y-4">
|
|
@@ -622,6 +510,49 @@ const DownloadScope = defineComponent({
|
|
|
622
510
|
</Field>
|
|
623
511
|
</div>
|
|
624
512
|
|
|
513
|
+
<!-- Add button appearance -->
|
|
514
|
+
<div class="grid grid-cols-2 gap-x-6 gap-y-4">
|
|
515
|
+
<Field orientation="vertical">
|
|
516
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
517
|
+
<template
|
|
518
|
+
v-if="fieldDescription('addIcon')"
|
|
519
|
+
#tooltip
|
|
520
|
+
>
|
|
521
|
+
<Markdown
|
|
522
|
+
:source="fieldDescription('addIcon')"
|
|
523
|
+
block
|
|
524
|
+
class="prose prose-sm prose-zinc"
|
|
525
|
+
/>
|
|
526
|
+
</template>
|
|
527
|
+
{{ fieldTitle("addIcon") }}
|
|
528
|
+
</FieldLabel>
|
|
529
|
+
<IconPicker
|
|
530
|
+
:model-value="value.addIcon ?? ''"
|
|
531
|
+
@update:model-value="updateAddIcon"
|
|
532
|
+
/>
|
|
533
|
+
</Field>
|
|
534
|
+
|
|
535
|
+
<Field orientation="vertical">
|
|
536
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
537
|
+
<template
|
|
538
|
+
v-if="fieldDescription('addLabel')"
|
|
539
|
+
#tooltip
|
|
540
|
+
>
|
|
541
|
+
<Markdown
|
|
542
|
+
:source="fieldDescription('addLabel')"
|
|
543
|
+
block
|
|
544
|
+
class="prose prose-sm prose-zinc"
|
|
545
|
+
/>
|
|
546
|
+
</template>
|
|
547
|
+
{{ fieldTitle("addLabel") }}
|
|
548
|
+
</FieldLabel>
|
|
549
|
+
<Locale
|
|
550
|
+
:model-value="value.addLabel"
|
|
551
|
+
@update:model-value="updateAddLabel"
|
|
552
|
+
/>
|
|
553
|
+
</Field>
|
|
554
|
+
</div>
|
|
555
|
+
|
|
625
556
|
<Separator />
|
|
626
557
|
|
|
627
558
|
<!-- Immediate upload -->
|
|
@@ -772,127 +703,6 @@ const DownloadScope = defineComponent({
|
|
|
772
703
|
|
|
773
704
|
<Separator />
|
|
774
705
|
|
|
775
|
-
<!-- Download templates -->
|
|
776
|
-
<Field orientation="vertical">
|
|
777
|
-
<FieldLabel class="text-xs text-zinc-500">
|
|
778
|
-
<template #tooltip>
|
|
779
|
-
<Markdown
|
|
780
|
-
:source="fieldDescription('templates') ?? '\u4E0B\u8F7D\u6A21\u677F\u5217\u8868\uFF1B\u6BCF\u4E00\u9879\u6E32\u67D3\u4E00\u4E2A\u4E0B\u8F7D\u6309\u94AE'"
|
|
781
|
-
block
|
|
782
|
-
class="prose prose-sm prose-zinc"
|
|
783
|
-
/>
|
|
784
|
-
</template>
|
|
785
|
-
{{ fieldTitle("templates") }}
|
|
786
|
-
</FieldLabel>
|
|
787
|
-
|
|
788
|
-
<div class="flex flex-col gap-2">
|
|
789
|
-
<div
|
|
790
|
-
v-for="(template, index) in templates"
|
|
791
|
-
:key="rowKeys[index]"
|
|
792
|
-
:ref="templateDnd.rowRef(rowId(index), templateRowConfig(index))"
|
|
793
|
-
data-slot="upload-template"
|
|
794
|
-
class="relative flex items-start gap-2 rounded border border-zinc-200 bg-zinc-50/40 p-2"
|
|
795
|
-
:data-instruction="templateDnd.instructionFor(rowId(index)) ?? void 0"
|
|
796
|
-
>
|
|
797
|
-
<Icon
|
|
798
|
-
icon="fluent:re-order-dots-vertical-20-regular"
|
|
799
|
-
class="drag-handle mt-2.5 size-4 shrink-0 cursor-grab text-zinc-400"
|
|
800
|
-
data-slot="upload-template-drag-handle"
|
|
801
|
-
/>
|
|
802
|
-
|
|
803
|
-
<div class="flex min-w-0 flex-1 flex-col gap-2">
|
|
804
|
-
<div class="grid grid-cols-2 gap-2">
|
|
805
|
-
<Field orientation="vertical">
|
|
806
|
-
<FieldLabel class="text-xs text-zinc-500">
|
|
807
|
-
<template #tooltip>
|
|
808
|
-
<Markdown
|
|
809
|
-
source="返回 `HttpRequest` 的 CEL 表达式。未配置「下载请求」时直接发起并下载其响应"
|
|
810
|
-
block
|
|
811
|
-
class="prose prose-sm prose-zinc"
|
|
812
|
-
/>
|
|
813
|
-
</template>
|
|
814
|
-
请求
|
|
815
|
-
</FieldLabel>
|
|
816
|
-
<ExpressionEditor
|
|
817
|
-
:model-value="template.request"
|
|
818
|
-
placeholder="例:http.get('https://api.example.com/template.xlsx')"
|
|
819
|
-
result-type="HttpRequest"
|
|
820
|
-
:extra-vars="ROW_VARS"
|
|
821
|
-
class="min-h-10"
|
|
822
|
-
@update:model-value="(v) => updateTemplateRequest(index, v)"
|
|
823
|
-
/>
|
|
824
|
-
</Field>
|
|
825
|
-
|
|
826
|
-
<Field orientation="vertical">
|
|
827
|
-
<FieldLabel class="text-xs text-zinc-500">
|
|
828
|
-
<template #tooltip>
|
|
829
|
-
<Markdown
|
|
830
|
-
source="可选的第二步:用第一步响应 `json` 中的凭据构造真正的下载请求,例如 `json.data.key`"
|
|
831
|
-
block
|
|
832
|
-
class="prose prose-sm prose-zinc"
|
|
833
|
-
/>
|
|
834
|
-
</template>
|
|
835
|
-
下载请求
|
|
836
|
-
</FieldLabel>
|
|
837
|
-
<ExpressionEditor
|
|
838
|
-
:model-value="template.download ?? ''"
|
|
839
|
-
placeholder="例:http.get('https://api.example.com/download').query('key', json.data.key)"
|
|
840
|
-
result-type="HttpRequest"
|
|
841
|
-
:extra-vars="TEMPLATE_DOWNLOAD_VARS"
|
|
842
|
-
class="min-h-10"
|
|
843
|
-
@update:model-value="(v) => updateTemplateDownload(index, v)"
|
|
844
|
-
/>
|
|
845
|
-
</Field>
|
|
846
|
-
</div>
|
|
847
|
-
|
|
848
|
-
<div class="grid grid-cols-2 gap-2">
|
|
849
|
-
<Field orientation="vertical">
|
|
850
|
-
<FieldLabel class="text-xs text-zinc-500">
|
|
851
|
-
模板按钮图标
|
|
852
|
-
</FieldLabel>
|
|
853
|
-
<IconPicker
|
|
854
|
-
:model-value="template.icon ?? ''"
|
|
855
|
-
@update:model-value="(v) => updateTemplateIcon(index, v)"
|
|
856
|
-
/>
|
|
857
|
-
</Field>
|
|
858
|
-
|
|
859
|
-
<Field orientation="vertical">
|
|
860
|
-
<FieldLabel class="text-xs text-zinc-500">
|
|
861
|
-
模板按钮文本
|
|
862
|
-
</FieldLabel>
|
|
863
|
-
<Locale
|
|
864
|
-
:model-value="template.label"
|
|
865
|
-
@update:model-value="(v) => updateTemplateLabel(index, v)"
|
|
866
|
-
/>
|
|
867
|
-
</Field>
|
|
868
|
-
</div>
|
|
869
|
-
</div>
|
|
870
|
-
|
|
871
|
-
<Button
|
|
872
|
-
variant="ghost"
|
|
873
|
-
size="sm"
|
|
874
|
-
class="absolute top-1 right-1 size-6 p-0 text-red-600 hover:text-red-700"
|
|
875
|
-
aria-label="移除模板"
|
|
876
|
-
@click="removeTemplate(index)"
|
|
877
|
-
>
|
|
878
|
-
<Icon icon="fluent:delete-20-regular" />
|
|
879
|
-
</Button>
|
|
880
|
-
</div>
|
|
881
|
-
|
|
882
|
-
<Button
|
|
883
|
-
type="button"
|
|
884
|
-
data-slot="upload-template-add"
|
|
885
|
-
class="w-full justify-center"
|
|
886
|
-
@click="addTemplate"
|
|
887
|
-
>
|
|
888
|
-
<Icon icon="fluent:add-20-regular" />
|
|
889
|
-
<span>增加</span>
|
|
890
|
-
</Button>
|
|
891
|
-
</div>
|
|
892
|
-
</Field>
|
|
893
|
-
|
|
894
|
-
<Separator />
|
|
895
|
-
|
|
896
706
|
<div class="grid grid-cols-2 gap-x-6 gap-y-4">
|
|
897
707
|
<Field orientation="vertical">
|
|
898
708
|
<FieldLabel class="text-xs text-zinc-500">
|
package/dist/runtime/components/table/columns/2026-07-16/com.shwfed.table.column.upload/prompt.md
CHANGED
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
三个表达式各有各的变量:`request` 见 `files`(本次选择)、`handle` 见 `json`(上传响应)、`filename` 见 `file`(单个存量项)——都在行作用域(`row`/`index`)之上,不要混用。
|
|
11
11
|
|
|
12
|
-
`templates` 在上传区旁渲染「下载模板」按钮:只配 `request` 则直接下载其响应;再配 `download` 则是两步式——第二步经 `json` 引用第一步响应(如用 `json.data.key` 拼真正的下载地址)。
|
|
13
|
-
|
|
14
12
|
`download`(文件下载)给每个**文件项**渲染一个下载按钮,点击时执行一条「触发操作」列表(复用 actions 的操作子系统),列表里的表达式可用 `file` 引用被点击的那一项。分两种情况:
|
|
15
13
|
|
|
16
14
|
- **已上传/回填的对象项**:走操作列表,如放一个 `http.download` 操作、请求写 `http.get('/api/file').query('key', file.cacheKey)`;或两步式——先一个 `发送请求` 行取凭据、再一个 `下载文件` 行经 `steps[?"<步骤标识>"]` 引用其响应。凡下载要用到的字段,都必须已由 `upload.handle` 落进文件项。
|
|
17
15
|
- **尚未上传的本地文件**(延迟模式刚选中的原始 `File`):内存里没有服务端标识,故绕过列表、直接从 blob 下载。
|
|
18
16
|
|
|
19
17
|
下载按钮在只读表格/表单里仍显示(查看已提交记录并下载附件是主要场景)。约束类字段(`accept` / `maxFileSize` / `maxTotalSize` / `maxFiles` / `multiple`)按需设置即可。`disabled` / `readonly` 是行作用域 CEL(返回 `bool`)。
|
|
18
|
+
|
|
19
|
+
单元格只有一个「添加文件」按钮(无拖放区,单元格高度只有一行):`addLabel` / `addIcon` 可改其文案与图标。数量达上限即隐藏该按钮——不开 `multiple` 时上限就是 1,要换文件得先删除已有的那个。
|
package/dist/runtime/components/table/columns/2026-07-16/com.shwfed.table.column.upload/runtime.vue
CHANGED
|
@@ -48,24 +48,6 @@ const EXTENSIONS = {
|
|
|
48
48
|
"application/msword": [".doc"],
|
|
49
49
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": [".docx"]
|
|
50
50
|
};
|
|
51
|
-
const SHORT_NAMES = {
|
|
52
|
-
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "XLSX",
|
|
53
|
-
"application/vnd.ms-excel": "XLS",
|
|
54
|
-
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "PPTX",
|
|
55
|
-
"application/vnd.ms-powerpoint": "PPT",
|
|
56
|
-
"application/zip": "ZIP",
|
|
57
|
-
"application/x-zip-compressed": "ZIP",
|
|
58
|
-
"application/vnd.rar": "RAR",
|
|
59
|
-
"application/x-rar-compressed": "RAR",
|
|
60
|
-
"application/pdf": "PDF",
|
|
61
|
-
"application/ofd": "OFD",
|
|
62
|
-
"application/xml": "XML",
|
|
63
|
-
"image/png": "PNG",
|
|
64
|
-
"image/jpg": "JPG",
|
|
65
|
-
"image/jpeg": "JPEG",
|
|
66
|
-
"application/msword": "DOC",
|
|
67
|
-
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "DOCX"
|
|
68
|
-
};
|
|
69
51
|
defineOptions({ name: "ShwfedTableUploadRendererRuntime" });
|
|
70
52
|
const props = defineProps({
|
|
71
53
|
column: { type: null, required: true },
|
|
@@ -76,7 +58,6 @@ const { locale, t } = useI18n({
|
|
|
76
58
|
messages: {
|
|
77
59
|
zh: {
|
|
78
60
|
"upload-add-file": "\u6DFB\u52A0\u6587\u4EF6",
|
|
79
|
-
"upload-accept-hint": "\u4EC5\u63A5\u53D7 {types}",
|
|
80
61
|
"upload-rejected-mime": "\u300C{name}\u300D\u7C7B\u578B\u4E0D\u88AB\u5141\u8BB8",
|
|
81
62
|
"upload-rejected-size": "\u300C{name}\u300D\u8D85\u51FA\u5355\u6587\u4EF6\u5927\u5C0F\u9650\u5236",
|
|
82
63
|
"upload-rejected-total": "\u300C{name}\u300D\u52A0\u5165\u540E\u5C06\u8D85\u51FA\u603B\u5927\u5C0F\u9650\u5236",
|
|
@@ -86,7 +67,6 @@ const { locale, t } = useI18n({
|
|
|
86
67
|
},
|
|
87
68
|
en: {
|
|
88
69
|
"upload-add-file": "Add file",
|
|
89
|
-
"upload-accept-hint": "Only {types} are accepted",
|
|
90
70
|
"upload-rejected-mime": "{name} is not an allowed file type",
|
|
91
71
|
"upload-rejected-size": "{name} exceeds the maximum file size",
|
|
92
72
|
"upload-rejected-total": "{name} would exceed the total size limit",
|
|
@@ -96,7 +76,6 @@ const { locale, t } = useI18n({
|
|
|
96
76
|
},
|
|
97
77
|
ja: {
|
|
98
78
|
"upload-add-file": "\u30D5\u30A1\u30A4\u30EB\u3092\u8FFD\u52A0",
|
|
99
|
-
"upload-accept-hint": "{types} \u306E\u307F\u53D7\u3051\u4ED8\u3051\u307E\u3059",
|
|
100
79
|
"upload-rejected-mime": "\u300C{name}\u300D\u306F\u8A31\u53EF\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F\u3067\u306F\u3042\u308A\u307E\u305B\u3093",
|
|
101
80
|
"upload-rejected-size": "\u300C{name}\u300D\u306F\u30D5\u30A1\u30A4\u30EB\u30B5\u30A4\u30BA\u306E\u4E0A\u9650\u3092\u8D85\u3048\u3066\u3044\u307E\u3059",
|
|
102
81
|
"upload-rejected-total": "\u300C{name}\u300D\u3092\u8FFD\u52A0\u3059\u308B\u3068\u5408\u8A08\u30B5\u30A4\u30BA\u306E\u4E0A\u9650\u3092\u8D85\u3048\u307E\u3059",
|
|
@@ -110,9 +89,6 @@ const formState = useFormState();
|
|
|
110
89
|
const inherited = injectCELContext();
|
|
111
90
|
const $cel = (expression, context) => _rawCel(expression, celScope(inherited, context));
|
|
112
91
|
const eventChannel = useEventChannel();
|
|
113
|
-
const placeholderText = computed(
|
|
114
|
-
() => props.column.placeholder ? getLocalizedText(props.column.placeholder, locale.value) : void 0
|
|
115
|
-
);
|
|
116
92
|
function evalBool(expression, label) {
|
|
117
93
|
if (!expression) return false;
|
|
118
94
|
try {
|
|
@@ -160,19 +136,24 @@ function entryIcon(entry) {
|
|
|
160
136
|
if (entry instanceof File) return ICONS[entry.type] ?? "fluent:document-20-regular";
|
|
161
137
|
return "fluent:document-20-regular";
|
|
162
138
|
}
|
|
139
|
+
const addIcon = computed(() => props.column.addIcon ?? "fluent:add-20-regular");
|
|
140
|
+
const addLabel = computed(
|
|
141
|
+
() => (props.column.addLabel ? getLocalizedText(props.column.addLabel, locale.value) : void 0) ?? t("upload-add-file")
|
|
142
|
+
);
|
|
163
143
|
const inputRef = ref();
|
|
164
144
|
const acceptAttr = computed(() => {
|
|
165
145
|
const list = props.column.accept;
|
|
166
146
|
return list && list.length > 0 ? list.join(",") : void 0;
|
|
167
147
|
});
|
|
168
|
-
const
|
|
169
|
-
const
|
|
170
|
-
if (
|
|
171
|
-
return
|
|
148
|
+
const effectiveMaxFiles = computed(() => {
|
|
149
|
+
const configured = props.column.maxFiles;
|
|
150
|
+
if (props.column.multiple !== true) return Math.min(1, configured ?? 1);
|
|
151
|
+
return configured;
|
|
152
|
+
});
|
|
153
|
+
const isFull = computed(() => {
|
|
154
|
+
const cap = effectiveMaxFiles.value;
|
|
155
|
+
return cap !== void 0 && entries.value.length >= cap;
|
|
172
156
|
});
|
|
173
|
-
const isFull = computed(
|
|
174
|
-
() => props.column.maxFiles !== void 0 && entries.value.length >= props.column.maxFiles
|
|
175
|
-
);
|
|
176
157
|
const canAdd = computed(() => !isDisabled.value && !isReadonly.value && !isFull.value && !uploading.value);
|
|
177
158
|
function isMimeAllowed(file) {
|
|
178
159
|
const list = props.column.accept;
|
|
@@ -197,7 +178,7 @@ function partition(incoming) {
|
|
|
197
178
|
rejected.push({ file, reason: "size" });
|
|
198
179
|
continue;
|
|
199
180
|
}
|
|
200
|
-
if (
|
|
181
|
+
if (effectiveMaxFiles.value !== void 0 && count >= effectiveMaxFiles.value) {
|
|
201
182
|
rejected.push({ file, reason: "count" });
|
|
202
183
|
continue;
|
|
203
184
|
}
|
|
@@ -264,13 +245,6 @@ function onAddClick() {
|
|
|
264
245
|
if (!canAdd.value) return;
|
|
265
246
|
inputRef.value?.click();
|
|
266
247
|
}
|
|
267
|
-
function onKeydown(event) {
|
|
268
|
-
if (!canAdd.value) return;
|
|
269
|
-
if (event.key === "Enter" || event.key === " ") {
|
|
270
|
-
event.preventDefault();
|
|
271
|
-
inputRef.value?.click();
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
248
|
function onDelete(index) {
|
|
275
249
|
if (isDisabled.value || isReadonly.value || uploading.value) return;
|
|
276
250
|
const next = [...entries.value];
|
|
@@ -287,34 +261,6 @@ function saveFile(file) {
|
|
|
287
261
|
a.remove();
|
|
288
262
|
URL.revokeObjectURL(url);
|
|
289
263
|
}
|
|
290
|
-
const templates = computed(() => props.column.templates ?? []);
|
|
291
|
-
function templateIcon(template) {
|
|
292
|
-
return template.icon ?? "fluent:arrow-download-20-regular";
|
|
293
|
-
}
|
|
294
|
-
function templateLabelText(template) {
|
|
295
|
-
return (template.label ? getLocalizedText(template.label, locale.value) : void 0) ?? "\u4E0B\u8F7D\u6A21\u677F";
|
|
296
|
-
}
|
|
297
|
-
async function onDownloadTemplate(template) {
|
|
298
|
-
const program = Effect.gen(function* () {
|
|
299
|
-
const requestBuilder = yield* $cel(template.request, {});
|
|
300
|
-
if (!template.download) {
|
|
301
|
-
return yield* requestBuilder.file();
|
|
302
|
-
}
|
|
303
|
-
const json = yield* requestBuilder.json();
|
|
304
|
-
const downloadBuilder = yield* $cel(template.download, { json });
|
|
305
|
-
return yield* downloadBuilder.file();
|
|
306
|
-
});
|
|
307
|
-
try {
|
|
308
|
-
const file = await Effect.runPromise(Effect.provide(program, Fetch.layer));
|
|
309
|
-
if (!(file instanceof File)) {
|
|
310
|
-
console.error(`[shwfed-table] template request for ${props.column.id} did not produce a File`);
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
saveFile(file);
|
|
314
|
-
} catch (err) {
|
|
315
|
-
console.error(`[shwfed-table] failed to download template for ${props.column.id}:`, err);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
264
|
const downloadEnabled = computed(() => props.column.download != null);
|
|
319
265
|
const downloadIcon = computed(() => props.column.download?.icon ?? "fluent:arrow-download-20-regular");
|
|
320
266
|
const downloadLabel = computed(
|
|
@@ -343,9 +289,15 @@ async function onDownloadEntry(entry) {
|
|
|
343
289
|
</script>
|
|
344
290
|
|
|
345
291
|
<template>
|
|
346
|
-
|
|
292
|
+
<!--
|
|
293
|
+
The cell's own content (one add button, or a short file list) is usually
|
|
294
|
+
shorter than the row, which is sized by its tallest neighbour — so the
|
|
295
|
+
wrapper fills the height and centres, rather than letting the button pin to
|
|
296
|
+
the top edge.
|
|
297
|
+
-->
|
|
298
|
+
<div class="p-[0.125rem] w-full h-full flex items-center">
|
|
347
299
|
<div
|
|
348
|
-
class="flex flex-col gap-1.5"
|
|
300
|
+
class="flex w-full flex-col gap-1.5"
|
|
349
301
|
:data-disabled="isDisabled || void 0"
|
|
350
302
|
:data-readonly="isReadonly || void 0"
|
|
351
303
|
>
|
|
@@ -418,53 +370,26 @@ async function onDownloadEntry(entry) {
|
|
|
418
370
|
</ul>
|
|
419
371
|
|
|
420
372
|
<!--
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
373
|
+
Add button — the only affordance for picking files, empty cell or not.
|
|
374
|
+
A cell is one grid row tall, so the dashed drop zone this replaces made
|
|
375
|
+
empty rows tower over their neighbours. `isFull` hides it (nothing left
|
|
376
|
+
to add); `isDisabled` keeps it rendered but inert, per the schema.
|
|
424
377
|
-->
|
|
425
|
-
<div
|
|
426
|
-
v-else
|
|
427
|
-
role="button"
|
|
428
|
-
:tabindex="canAdd ? 0 : -1"
|
|
429
|
-
data-slot="upload-zone"
|
|
430
|
-
:data-disabled="isDisabled || void 0"
|
|
431
|
-
:aria-disabled="isDisabled || void 0"
|
|
432
|
-
class="flex min-h-16 w-full flex-col items-center justify-center gap-1 rounded border border-dashed border-zinc-200 bg-zinc-50/60 px-2 py-2 outline-none transition-colors duration-180 ease-out focus-visible:border-(--primary) data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-60"
|
|
433
|
-
:class="canAdd && 'cursor-pointer hover:border-zinc-400 hover:bg-zinc-100'"
|
|
434
|
-
@click="onAddClick"
|
|
435
|
-
@keydown="onKeydown"
|
|
436
|
-
>
|
|
437
|
-
<Icon
|
|
438
|
-
:icon="uploading ? 'fluent:spinner-ios-20-regular' : 'fluent:cloud-arrow-up-20-regular'"
|
|
439
|
-
class="size-5 text-zinc-400"
|
|
440
|
-
:class="uploading && 'animate-spin'"
|
|
441
|
-
/>
|
|
442
|
-
<p class="text-[0.7rem] text-zinc-500">
|
|
443
|
-
{{ uploading ? t("upload-uploading") : placeholderText ?? t("upload-add-file") }}
|
|
444
|
-
</p>
|
|
445
|
-
<p
|
|
446
|
-
v-if="acceptHint"
|
|
447
|
-
class="text-[0.65rem] text-zinc-400"
|
|
448
|
-
>
|
|
449
|
-
{{ t("upload-accept-hint", { types: acceptHint }) }}
|
|
450
|
-
</p>
|
|
451
|
-
</div>
|
|
452
|
-
|
|
453
|
-
<!-- Add button — only when the list is non-empty and adding is allowed. -->
|
|
454
378
|
<Button
|
|
455
|
-
v-if="
|
|
379
|
+
v-if="!isReadonly && !isFull"
|
|
456
380
|
type="button"
|
|
457
381
|
variant="default"
|
|
458
382
|
size="sm"
|
|
459
383
|
data-slot="upload-zone-add"
|
|
460
384
|
class="h-6 w-full shrink-0 text-[0.75rem]"
|
|
385
|
+
:disabled="isDisabled || uploading"
|
|
461
386
|
@click="onAddClick"
|
|
462
387
|
>
|
|
463
388
|
<Icon
|
|
464
|
-
:icon="uploading ? 'fluent:spinner-ios-20-regular' :
|
|
389
|
+
:icon="uploading ? 'fluent:spinner-ios-20-regular' : addIcon"
|
|
465
390
|
:class="uploading && 'animate-spin'"
|
|
466
391
|
/>
|
|
467
|
-
{{ uploading ? t("upload-uploading") :
|
|
392
|
+
{{ uploading ? t("upload-uploading") : addLabel }}
|
|
468
393
|
</Button>
|
|
469
394
|
|
|
470
395
|
<input
|
|
@@ -476,28 +401,6 @@ async function onDownloadEntry(entry) {
|
|
|
476
401
|
:disabled="isDisabled || isReadonly"
|
|
477
402
|
@change="onPickerChange"
|
|
478
403
|
>
|
|
479
|
-
|
|
480
|
-
<div
|
|
481
|
-
v-if="templates.length > 0 && !isReadonly"
|
|
482
|
-
class="flex flex-wrap justify-end gap-1"
|
|
483
|
-
>
|
|
484
|
-
<Button
|
|
485
|
-
v-for="(template, index) in templates"
|
|
486
|
-
:key="index"
|
|
487
|
-
type="button"
|
|
488
|
-
variant="link"
|
|
489
|
-
size="sm"
|
|
490
|
-
data-slot="upload-zone-template"
|
|
491
|
-
class="h-5 px-1 text-[0.7rem]"
|
|
492
|
-
@click="onDownloadTemplate(template)"
|
|
493
|
-
>
|
|
494
|
-
<Icon
|
|
495
|
-
:icon="templateIcon(template)"
|
|
496
|
-
class="size-3.5"
|
|
497
|
-
/>
|
|
498
|
-
{{ templateLabelText(template) }}
|
|
499
|
-
</Button>
|
|
500
|
-
</div>
|
|
501
404
|
</div>
|
|
502
405
|
</div>
|
|
503
406
|
</template>
|