@shwfed/nuxt 0.11.35 → 0.11.37
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/fields.d.vue.ts +10 -0
- package/dist/runtime/components/fields.vue.d.ts +10 -0
- package/dist/runtime/components/modal.vue +2 -2
- package/dist/runtime/components/ui/button-configurator/ButtonConfiguratorDialog.vue +3 -3
- package/dist/runtime/components/ui/command/CommandDialog.vue +3 -3
- package/dist/runtime/components/ui/dialog/DialogScrollContent.d.vue.ts +8 -3
- package/dist/runtime/components/ui/dialog/DialogScrollContent.vue +167 -14
- package/dist/runtime/components/ui/dialog/DialogScrollContent.vue.d.ts +8 -3
- package/dist/runtime/components/ui/fields/Fields.d.vue.ts +20 -0
- package/dist/runtime/components/ui/fields/Fields.vue +55 -3
- package/dist/runtime/components/ui/fields/Fields.vue.d.ts +20 -0
- package/dist/runtime/components/ui/fields/schema.d.ts +60 -0
- package/dist/runtime/components/ui/fields/schema.js +2 -0
- package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.d.vue.ts +10 -0
- package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue +76 -3
- package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue.d.ts +10 -0
- package/dist/runtime/components/ui/menu-tabs-configurator/MenuTabsConfiguratorDialog.vue +3 -3
- package/dist/runtime/components/ui/table-configurator/TableConfiguratorDialog.vue +3 -3
- package/dist/runtime/plugins/api/index.js +16 -0
- package/dist/runtime/plugins/cel/env.js +6 -0
- package/dist/runtime/plugins/cel/http-request.d.ts +16 -0
- package/dist/runtime/plugins/cel/http-request.js +36 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -171,6 +171,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
171
171
|
message: string;
|
|
172
172
|
}[] | undefined;
|
|
173
173
|
maxCount?: string | undefined;
|
|
174
|
+
template?: string | undefined;
|
|
175
|
+
templateName?: readonly {
|
|
176
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
177
|
+
message: string;
|
|
178
|
+
}[] | undefined;
|
|
174
179
|
style?: string | undefined;
|
|
175
180
|
initialValue?: string | undefined;
|
|
176
181
|
hidden?: string | undefined;
|
|
@@ -359,6 +364,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
359
364
|
message: string;
|
|
360
365
|
}[] | undefined;
|
|
361
366
|
maxCount?: string | undefined;
|
|
367
|
+
template?: string | undefined;
|
|
368
|
+
templateName?: readonly {
|
|
369
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
370
|
+
message: string;
|
|
371
|
+
}[] | undefined;
|
|
362
372
|
style?: string | undefined;
|
|
363
373
|
initialValue?: string | undefined;
|
|
364
374
|
hidden?: string | undefined;
|
|
@@ -171,6 +171,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
171
171
|
message: string;
|
|
172
172
|
}[] | undefined;
|
|
173
173
|
maxCount?: string | undefined;
|
|
174
|
+
template?: string | undefined;
|
|
175
|
+
templateName?: readonly {
|
|
176
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
177
|
+
message: string;
|
|
178
|
+
}[] | undefined;
|
|
174
179
|
style?: string | undefined;
|
|
175
180
|
initialValue?: string | undefined;
|
|
176
181
|
hidden?: string | undefined;
|
|
@@ -359,6 +364,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
359
364
|
message: string;
|
|
360
365
|
}[] | undefined;
|
|
361
366
|
maxCount?: string | undefined;
|
|
367
|
+
template?: string | undefined;
|
|
368
|
+
templateName?: readonly {
|
|
369
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
370
|
+
message: string;
|
|
371
|
+
}[] | undefined;
|
|
362
372
|
style?: string | undefined;
|
|
363
373
|
initialValue?: string | undefined;
|
|
364
374
|
hidden?: string | undefined;
|
|
@@ -4,10 +4,10 @@ import { computed, ref, useAttrs, useSlots } from "vue";
|
|
|
4
4
|
import {
|
|
5
5
|
Dialog,
|
|
6
6
|
DialogClose,
|
|
7
|
-
DialogContent,
|
|
8
7
|
DialogDescription,
|
|
9
8
|
DialogFooter,
|
|
10
9
|
DialogHeader,
|
|
10
|
+
DialogScrollContent,
|
|
11
11
|
DialogTitle,
|
|
12
12
|
DialogTrigger
|
|
13
13
|
} from "./ui/dialog";
|
|
@@ -39,7 +39,7 @@ const isDesktop = useMediaQuery(props.breakpoint);
|
|
|
39
39
|
const desktopComponents = {
|
|
40
40
|
Root: Dialog,
|
|
41
41
|
Trigger: DialogTrigger,
|
|
42
|
-
Content:
|
|
42
|
+
Content: DialogScrollContent,
|
|
43
43
|
Header: DialogHeader,
|
|
44
44
|
Title: DialogTitle,
|
|
45
45
|
Description: DialogDescription,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
ButtonsStyleC
|
|
14
14
|
} from "../buttons/schema";
|
|
15
15
|
import { Checkbox } from "../checkbox";
|
|
16
|
-
import { Dialog,
|
|
16
|
+
import { Dialog, DialogDescription, DialogFooter, DialogHeader, DialogScrollContent, DialogTitle } from "../dialog";
|
|
17
17
|
import { IconPicker } from "../icon-picker";
|
|
18
18
|
import { Input } from "../input";
|
|
19
19
|
import Locale from "../locale/Locale.vue";
|
|
@@ -848,7 +848,7 @@ function confirmChanges() {
|
|
|
848
848
|
:open="open"
|
|
849
849
|
@update:open="open = $event"
|
|
850
850
|
>
|
|
851
|
-
<
|
|
851
|
+
<DialogScrollContent class="flex h-[min(40rem,calc(100vh-4rem))] w-[calc(100%-2rem)] max-w-[calc(100%-2rem)] flex-col overflow-hidden p-0 sm:w-[72rem] sm:max-w-[72rem]">
|
|
852
852
|
<DialogHeader class="gap-1 border-b border-zinc-200 px-6 py-5">
|
|
853
853
|
<div class="flex items-center gap-3">
|
|
854
854
|
<DialogTitle class="text-xl font-semibold text-zinc-800">
|
|
@@ -1382,7 +1382,7 @@ function confirmChanges() {
|
|
|
1382
1382
|
</Button>
|
|
1383
1383
|
</div>
|
|
1384
1384
|
</DialogFooter>
|
|
1385
|
-
</
|
|
1385
|
+
</DialogScrollContent>
|
|
1386
1386
|
</Dialog>
|
|
1387
1387
|
</template>
|
|
1388
1388
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useForwardPropsEmits } from "reka-ui";
|
|
3
|
-
import { Dialog,
|
|
3
|
+
import { Dialog, DialogDescription, DialogHeader, DialogScrollContent, DialogTitle } from "../dialog";
|
|
4
4
|
import Command from "./Command.vue";
|
|
5
5
|
const props = defineProps({
|
|
6
6
|
open: { type: Boolean, required: false },
|
|
@@ -18,7 +18,7 @@ const forwarded = useForwardPropsEmits(props, emits);
|
|
|
18
18
|
v-slot="slotProps"
|
|
19
19
|
v-bind="forwarded"
|
|
20
20
|
>
|
|
21
|
-
<
|
|
21
|
+
<DialogScrollContent
|
|
22
22
|
:show-close-button="false"
|
|
23
23
|
class="overflow-hidden p-0"
|
|
24
24
|
>
|
|
@@ -29,6 +29,6 @@ const forwarded = useForwardPropsEmits(props, emits);
|
|
|
29
29
|
<Command>
|
|
30
30
|
<slot v-bind="slotProps" />
|
|
31
31
|
</Command>
|
|
32
|
-
</
|
|
32
|
+
</DialogScrollContent>
|
|
33
33
|
</Dialog>
|
|
34
34
|
</template>
|
|
@@ -2,10 +2,11 @@ import type { DialogContentProps } from 'reka-ui';
|
|
|
2
2
|
import type { HTMLAttributes } from 'vue';
|
|
3
3
|
type __VLS_Props = DialogContentProps & {
|
|
4
4
|
class?: HTMLAttributes['class'];
|
|
5
|
+
showCloseButton?: boolean;
|
|
5
6
|
};
|
|
6
|
-
declare var
|
|
7
|
+
declare var __VLS_23: {};
|
|
7
8
|
type __VLS_Slots = {} & {
|
|
8
|
-
default?: (props: typeof
|
|
9
|
+
default?: (props: typeof __VLS_23) => any;
|
|
9
10
|
};
|
|
10
11
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
12
|
escapeKeyDown: (event: KeyboardEvent) => any;
|
|
@@ -14,6 +15,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
14
15
|
interactOutside: (event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any;
|
|
15
16
|
openAutoFocus: (event: Event) => any;
|
|
16
17
|
closeAutoFocus: (event: Event) => any;
|
|
18
|
+
"after-close": () => any;
|
|
17
19
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
18
20
|
onEscapeKeyDown?: ((event: KeyboardEvent) => any) | undefined;
|
|
19
21
|
onPointerDownOutside?: ((event: import("reka-ui").PointerDownOutsideEvent) => any) | undefined;
|
|
@@ -21,7 +23,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
21
23
|
onInteractOutside?: ((event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any) | undefined;
|
|
22
24
|
onOpenAutoFocus?: ((event: Event) => any) | undefined;
|
|
23
25
|
onCloseAutoFocus?: ((event: Event) => any) | undefined;
|
|
24
|
-
|
|
26
|
+
"onAfter-close"?: (() => any) | undefined;
|
|
27
|
+
}>, {
|
|
28
|
+
showCloseButton: boolean;
|
|
29
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
30
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
26
31
|
declare const _default: typeof __VLS_export;
|
|
27
32
|
export default _default;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { Icon } from "@iconify/vue";
|
|
3
2
|
import { reactiveOmit } from "@vueuse/core";
|
|
3
|
+
import { Icon } from "@iconify/vue";
|
|
4
|
+
import {
|
|
5
|
+
computed,
|
|
6
|
+
onBeforeUnmount,
|
|
7
|
+
shallowRef,
|
|
8
|
+
useAttrs,
|
|
9
|
+
watchEffect
|
|
10
|
+
} from "vue";
|
|
4
11
|
import {
|
|
5
12
|
DialogClose,
|
|
6
13
|
DialogContent,
|
|
@@ -17,11 +24,158 @@ const props = defineProps({
|
|
|
17
24
|
disableOutsidePointerEvents: { type: Boolean, required: false },
|
|
18
25
|
asChild: { type: Boolean, required: false },
|
|
19
26
|
as: { type: null, required: false },
|
|
20
|
-
class: { type: null, required: false }
|
|
27
|
+
class: { type: null, required: false },
|
|
28
|
+
showCloseButton: { type: Boolean, required: false, default: true }
|
|
29
|
+
});
|
|
30
|
+
const emit = defineEmits(["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "openAutoFocus", "closeAutoFocus", "after-close"]);
|
|
31
|
+
const attrs = useAttrs();
|
|
32
|
+
const delegatedProps = reactiveOmit(props, "class", "showCloseButton");
|
|
33
|
+
const forwarded = useForwardPropsEmits(delegatedProps, emit);
|
|
34
|
+
const contentElement = shallowRef(null);
|
|
35
|
+
let closeFallbackTimer;
|
|
36
|
+
let hasEmittedAfterClose = false;
|
|
37
|
+
function isClosedContentTarget(target) {
|
|
38
|
+
return target instanceof HTMLElement && target.dataset.state === "closed";
|
|
39
|
+
}
|
|
40
|
+
function isPointerDownOutsideEvent(event) {
|
|
41
|
+
if (!("detail" in event) || typeof event.detail !== "object" || event.detail === null) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (!("originalEvent" in event.detail)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return event.detail.originalEvent instanceof MouseEvent;
|
|
48
|
+
}
|
|
49
|
+
function clearCloseFallbackTimer() {
|
|
50
|
+
if (closeFallbackTimer === void 0) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
window.clearTimeout(closeFallbackTimer);
|
|
54
|
+
closeFallbackTimer = void 0;
|
|
55
|
+
}
|
|
56
|
+
function emitAfterClose() {
|
|
57
|
+
if (hasEmittedAfterClose) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
hasEmittedAfterClose = true;
|
|
61
|
+
clearCloseFallbackTimer();
|
|
62
|
+
emit("after-close");
|
|
63
|
+
}
|
|
64
|
+
function parseDurationMs(value) {
|
|
65
|
+
const normalizedValue = value.trim();
|
|
66
|
+
if (normalizedValue.endsWith("ms")) {
|
|
67
|
+
const duration = Number.parseFloat(normalizedValue.slice(0, -2));
|
|
68
|
+
return Number.isFinite(duration) ? duration : 0;
|
|
69
|
+
}
|
|
70
|
+
if (normalizedValue.endsWith("s")) {
|
|
71
|
+
const duration = Number.parseFloat(normalizedValue.slice(0, -1));
|
|
72
|
+
return Number.isFinite(duration) ? duration * 1e3 : 0;
|
|
73
|
+
}
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
function getLongestMotionMs(element) {
|
|
77
|
+
const style = window.getComputedStyle(element);
|
|
78
|
+
const animationDurations = style.animationDuration.split(",");
|
|
79
|
+
const animationDelays = style.animationDelay.split(",");
|
|
80
|
+
const transitionDurations = style.transitionDuration.split(",");
|
|
81
|
+
const transitionDelays = style.transitionDelay.split(",");
|
|
82
|
+
let longestMotionMs = 0;
|
|
83
|
+
for (const [index, durationValue] of animationDurations.entries()) {
|
|
84
|
+
const durationMs = parseDurationMs(durationValue);
|
|
85
|
+
const delayMs = parseDurationMs(animationDelays[index] ?? animationDelays[0] ?? "0s");
|
|
86
|
+
longestMotionMs = Math.max(longestMotionMs, durationMs + delayMs);
|
|
87
|
+
}
|
|
88
|
+
for (const [index, durationValue] of transitionDurations.entries()) {
|
|
89
|
+
const durationMs = parseDurationMs(durationValue);
|
|
90
|
+
const delayMs = parseDurationMs(transitionDelays[index] ?? transitionDelays[0] ?? "0s");
|
|
91
|
+
longestMotionMs = Math.max(longestMotionMs, durationMs + delayMs);
|
|
92
|
+
}
|
|
93
|
+
return longestMotionMs;
|
|
94
|
+
}
|
|
95
|
+
function syncCloseFallback() {
|
|
96
|
+
const element = contentElement.value;
|
|
97
|
+
clearCloseFallbackTimer();
|
|
98
|
+
if (!element) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (element.dataset.state !== "closed") {
|
|
102
|
+
hasEmittedAfterClose = false;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const motionMs = getLongestMotionMs(element);
|
|
106
|
+
closeFallbackTimer = window.setTimeout(() => {
|
|
107
|
+
emitAfterClose();
|
|
108
|
+
}, motionMs > 0 ? motionMs : 0);
|
|
109
|
+
}
|
|
110
|
+
function handleCloseMotionEnd(event) {
|
|
111
|
+
if (hasEmittedAfterClose || event.target !== event.currentTarget || !isClosedContentTarget(event.currentTarget)) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
emitAfterClose();
|
|
115
|
+
}
|
|
116
|
+
function setContentElement(target) {
|
|
117
|
+
if (target instanceof HTMLElement) {
|
|
118
|
+
contentElement.value = target;
|
|
119
|
+
syncCloseFallback();
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (target && "$el" in target && target.$el instanceof HTMLElement) {
|
|
123
|
+
contentElement.value = target.$el;
|
|
124
|
+
syncCloseFallback();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
contentElement.value = null;
|
|
128
|
+
clearCloseFallbackTimer();
|
|
129
|
+
}
|
|
130
|
+
function callEventHandlers(eventHandler, event) {
|
|
131
|
+
if (typeof eventHandler === "function") {
|
|
132
|
+
eventHandler(event);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (!Array.isArray(eventHandler)) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
for (const handler of eventHandler) {
|
|
139
|
+
if (typeof handler === "function") {
|
|
140
|
+
handler(event);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function handlePointerDownOutside(event) {
|
|
145
|
+
if (isPointerDownOutsideEvent(event) && event.detail.originalEvent.target instanceof HTMLElement) {
|
|
146
|
+
const target = event.detail.originalEvent.target;
|
|
147
|
+
if (event.detail.originalEvent.offsetX > target.clientWidth || event.detail.originalEvent.offsetY > target.clientHeight) {
|
|
148
|
+
event.preventDefault();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
callEventHandlers(Reflect.get(forwarded, "onPointerDownOutside"), event);
|
|
152
|
+
callEventHandlers(Reflect.get(attrs, "onPointerDownOutside"), event);
|
|
153
|
+
}
|
|
154
|
+
const contentBindings = computed(() => ({
|
|
155
|
+
...attrs,
|
|
156
|
+
...forwarded,
|
|
157
|
+
onPointerDownOutside: handlePointerDownOutside
|
|
158
|
+
}));
|
|
159
|
+
watchEffect((onCleanup) => {
|
|
160
|
+
const element = contentElement.value;
|
|
161
|
+
if (!element) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const observer = new MutationObserver(() => {
|
|
165
|
+
syncCloseFallback();
|
|
166
|
+
});
|
|
167
|
+
observer.observe(element, {
|
|
168
|
+
attributes: true,
|
|
169
|
+
attributeFilter: ["data-state"]
|
|
170
|
+
});
|
|
171
|
+
syncCloseFallback();
|
|
172
|
+
onCleanup(() => {
|
|
173
|
+
observer.disconnect();
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
onBeforeUnmount(() => {
|
|
177
|
+
clearCloseFallbackTimer();
|
|
21
178
|
});
|
|
22
|
-
const emits = defineEmits(["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "openAutoFocus", "closeAutoFocus"]);
|
|
23
|
-
const delegatedProps = reactiveOmit(props, "class");
|
|
24
|
-
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|
25
179
|
</script>
|
|
26
180
|
|
|
27
181
|
<template>
|
|
@@ -30,25 +184,24 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|
|
30
184
|
class="fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
|
31
185
|
>
|
|
32
186
|
<DialogContent
|
|
187
|
+
:ref="setContentElement"
|
|
188
|
+
data-slot="dialog-content"
|
|
33
189
|
:class="
|
|
34
190
|
cn(
|
|
35
191
|
'relative z-50 grid w-full max-w-lg my-8 gap-4 border border-zinc-200 bg-white p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',
|
|
36
192
|
props.class
|
|
37
193
|
)
|
|
38
194
|
"
|
|
39
|
-
v-bind="
|
|
40
|
-
@
|
|
41
|
-
|
|
42
|
-
const target = originalEvent.target;
|
|
43
|
-
if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) {
|
|
44
|
-
event.preventDefault();
|
|
45
|
-
}
|
|
46
|
-
}"
|
|
195
|
+
v-bind="contentBindings"
|
|
196
|
+
@animationend="handleCloseMotionEnd"
|
|
197
|
+
@transitionend="handleCloseMotionEnd"
|
|
47
198
|
>
|
|
48
199
|
<slot />
|
|
49
200
|
|
|
50
201
|
<DialogClose
|
|
51
|
-
|
|
202
|
+
v-if="showCloseButton"
|
|
203
|
+
data-slot="dialog-close"
|
|
204
|
+
class="data-[state=open]:bg-zinc-100 data-[state=open]:text-zinc-700 absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
|
52
205
|
>
|
|
53
206
|
<Icon icon="fluent:dismiss-20-filled" />
|
|
54
207
|
<span class="sr-only">Close</span>
|
|
@@ -2,10 +2,11 @@ import type { DialogContentProps } from 'reka-ui';
|
|
|
2
2
|
import type { HTMLAttributes } from 'vue';
|
|
3
3
|
type __VLS_Props = DialogContentProps & {
|
|
4
4
|
class?: HTMLAttributes['class'];
|
|
5
|
+
showCloseButton?: boolean;
|
|
5
6
|
};
|
|
6
|
-
declare var
|
|
7
|
+
declare var __VLS_23: {};
|
|
7
8
|
type __VLS_Slots = {} & {
|
|
8
|
-
default?: (props: typeof
|
|
9
|
+
default?: (props: typeof __VLS_23) => any;
|
|
9
10
|
};
|
|
10
11
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
12
|
escapeKeyDown: (event: KeyboardEvent) => any;
|
|
@@ -14,6 +15,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
14
15
|
interactOutside: (event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any;
|
|
15
16
|
openAutoFocus: (event: Event) => any;
|
|
16
17
|
closeAutoFocus: (event: Event) => any;
|
|
18
|
+
"after-close": () => any;
|
|
17
19
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
18
20
|
onEscapeKeyDown?: ((event: KeyboardEvent) => any) | undefined;
|
|
19
21
|
onPointerDownOutside?: ((event: import("reka-ui").PointerDownOutsideEvent) => any) | undefined;
|
|
@@ -21,7 +23,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
21
23
|
onInteractOutside?: ((event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any) | undefined;
|
|
22
24
|
onOpenAutoFocus?: ((event: Event) => any) | undefined;
|
|
23
25
|
onCloseAutoFocus?: ((event: Event) => any) | undefined;
|
|
24
|
-
|
|
26
|
+
"onAfter-close"?: (() => any) | undefined;
|
|
27
|
+
}>, {
|
|
28
|
+
showCloseButton: boolean;
|
|
29
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
30
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
26
31
|
declare const _default: typeof __VLS_export;
|
|
27
32
|
export default _default;
|
|
@@ -165,6 +165,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
165
165
|
message: string;
|
|
166
166
|
}[] | undefined;
|
|
167
167
|
maxCount?: string | undefined;
|
|
168
|
+
template?: string | undefined;
|
|
169
|
+
templateName?: readonly {
|
|
170
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
171
|
+
message: string;
|
|
172
|
+
}[] | undefined;
|
|
168
173
|
style?: string | undefined;
|
|
169
174
|
initialValue?: string | undefined;
|
|
170
175
|
hidden?: string | undefined;
|
|
@@ -352,6 +357,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
352
357
|
message: string;
|
|
353
358
|
}[] | undefined;
|
|
354
359
|
maxCount?: string | undefined;
|
|
360
|
+
template?: string | undefined;
|
|
361
|
+
templateName?: readonly {
|
|
362
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
363
|
+
message: string;
|
|
364
|
+
}[] | undefined;
|
|
355
365
|
style?: string | undefined;
|
|
356
366
|
initialValue?: string | undefined;
|
|
357
367
|
hidden?: string | undefined;
|
|
@@ -535,6 +545,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
535
545
|
message: string;
|
|
536
546
|
}[] | undefined;
|
|
537
547
|
maxCount?: string | undefined;
|
|
548
|
+
template?: string | undefined;
|
|
549
|
+
templateName?: readonly {
|
|
550
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
551
|
+
message: string;
|
|
552
|
+
}[] | undefined;
|
|
538
553
|
style?: string | undefined;
|
|
539
554
|
initialValue?: string | undefined;
|
|
540
555
|
hidden?: string | undefined;
|
|
@@ -720,6 +735,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
720
735
|
message: string;
|
|
721
736
|
}[] | undefined;
|
|
722
737
|
maxCount?: string | undefined;
|
|
738
|
+
template?: string | undefined;
|
|
739
|
+
templateName?: readonly {
|
|
740
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
741
|
+
message: string;
|
|
742
|
+
}[] | undefined;
|
|
723
743
|
style?: string | undefined;
|
|
724
744
|
initialValue?: string | undefined;
|
|
725
745
|
hidden?: string | undefined;
|
|
@@ -226,6 +226,24 @@ function getFileIcon(filename) {
|
|
|
226
226
|
const ext = filename.split(".").pop()?.toLowerCase() ?? "";
|
|
227
227
|
return FILE_EXTENSION_ICONS[ext] ?? "vscode-icons:default-file";
|
|
228
228
|
}
|
|
229
|
+
const MIME_TO_ICON = {
|
|
230
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "vscode-icons:file-type-excel",
|
|
231
|
+
"application/vnd.ms-excel": "vscode-icons:file-type-excel",
|
|
232
|
+
"application/pdf": "vscode-icons:file-type-pdf2",
|
|
233
|
+
"application/msword": "vscode-icons:file-type-word",
|
|
234
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "vscode-icons:file-type-word",
|
|
235
|
+
"application/vnd.ms-powerpoint": "vscode-icons:file-type-powerpoint",
|
|
236
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "vscode-icons:file-type-powerpoint",
|
|
237
|
+
"application/x-zip-compressed": "vscode-icons:file-type-zip",
|
|
238
|
+
"application/zip": "vscode-icons:file-type-zip",
|
|
239
|
+
"image/png": "vscode-icons:file-type-image",
|
|
240
|
+
"image/jpg": "vscode-icons:file-type-image",
|
|
241
|
+
"image/jpeg": "vscode-icons:file-type-image"
|
|
242
|
+
};
|
|
243
|
+
function getUploadTemplateIcon(field) {
|
|
244
|
+
const first = field.accept?.[0];
|
|
245
|
+
return (first && MIME_TO_ICON[first]) ?? "fluent:arrow-download-20-regular";
|
|
246
|
+
}
|
|
229
247
|
function getUploadAcceptString(field) {
|
|
230
248
|
if (!field.accept || field.accept.length === 0) {
|
|
231
249
|
return void 0;
|
|
@@ -298,6 +316,24 @@ function handleUploadDrop(field, event) {
|
|
|
298
316
|
function handleUploadDragOver(event) {
|
|
299
317
|
event.preventDefault();
|
|
300
318
|
}
|
|
319
|
+
const templateDownloading = ref({});
|
|
320
|
+
async function handleTemplateDownload(field) {
|
|
321
|
+
if (!field.template || templateDownloading.value[field.id]) return;
|
|
322
|
+
templateDownloading.value[field.id] = true;
|
|
323
|
+
try {
|
|
324
|
+
const file = await $dsl.evaluate`${field.template}`();
|
|
325
|
+
const url = URL.createObjectURL(file);
|
|
326
|
+
const a = document.createElement("a");
|
|
327
|
+
a.href = url;
|
|
328
|
+
a.download = file.name;
|
|
329
|
+
a.click();
|
|
330
|
+
URL.revokeObjectURL(url);
|
|
331
|
+
} catch (e) {
|
|
332
|
+
console.error("[Fields] template download failed:", e);
|
|
333
|
+
} finally {
|
|
334
|
+
templateDownloading.value[field.id] = false;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
301
337
|
function stringifySelectValue(value) {
|
|
302
338
|
try {
|
|
303
339
|
return JSON.stringify(value);
|
|
@@ -673,6 +709,19 @@ export {
|
|
|
673
709
|
:icon="field.icon ?? 'fluent:cloud-arrow-up-20-regular'"
|
|
674
710
|
class="text-4xl text-zinc-400"
|
|
675
711
|
/>
|
|
712
|
+
<button
|
|
713
|
+
v-if="field.template"
|
|
714
|
+
type="button"
|
|
715
|
+
class="inline-flex items-center gap-1.5 rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm text-zinc-600 transition-colors hover:border-[--el-color-primary] hover:text-[--el-color-primary] disabled:opacity-50"
|
|
716
|
+
:disabled="templateDownloading[field.id]"
|
|
717
|
+
@click.prevent.stop="handleTemplateDownload(field)"
|
|
718
|
+
>
|
|
719
|
+
<Icon
|
|
720
|
+
:icon="templateDownloading[field.id] ? 'svg-spinners:ring-resize' : getUploadTemplateIcon(field)"
|
|
721
|
+
class="text-base"
|
|
722
|
+
/>
|
|
723
|
+
{{ getLocalizedText(field.templateName, locale) ?? t("upload-download-template") }}
|
|
724
|
+
</button>
|
|
676
725
|
<p
|
|
677
726
|
v-if="field.description"
|
|
678
727
|
class="text-sm text-zinc-600"
|
|
@@ -1105,7 +1154,8 @@ export {
|
|
|
1105
1154
|
"upload-click-or-drag": "点击或拖拽文件到此处上传",
|
|
1106
1155
|
"upload-accept-description": "仅接受 {formats} 格式文件",
|
|
1107
1156
|
"upload-accept-or": "或",
|
|
1108
|
-
"upload-accept-all": "接受所有格式文件"
|
|
1157
|
+
"upload-accept-all": "接受所有格式文件",
|
|
1158
|
+
"upload-download-template": "下载模板"
|
|
1109
1159
|
},
|
|
1110
1160
|
"ja": {
|
|
1111
1161
|
"clear": "クリア",
|
|
@@ -1115,7 +1165,8 @@ export {
|
|
|
1115
1165
|
"upload-click-or-drag": "クリックまたはファイルをここにドラッグしてアップロード",
|
|
1116
1166
|
"upload-accept-description": "{formats} 形式のファイルのみ受け付けます",
|
|
1117
1167
|
"upload-accept-or": "または",
|
|
1118
|
-
"upload-accept-all": "すべての形式を受け付けます"
|
|
1168
|
+
"upload-accept-all": "すべての形式を受け付けます",
|
|
1169
|
+
"upload-download-template": "テンプレートをダウンロード"
|
|
1119
1170
|
},
|
|
1120
1171
|
"en": {
|
|
1121
1172
|
"clear": "Clear",
|
|
@@ -1125,7 +1176,8 @@ export {
|
|
|
1125
1176
|
"upload-click-or-drag": "Click or drag files here to upload",
|
|
1126
1177
|
"upload-accept-description": "Only {formats} format files accepted",
|
|
1127
1178
|
"upload-accept-or": "or",
|
|
1128
|
-
"upload-accept-all": "All formats accepted"
|
|
1179
|
+
"upload-accept-all": "All formats accepted",
|
|
1180
|
+
"upload-download-template": "Download Template"
|
|
1129
1181
|
}
|
|
1130
1182
|
}
|
|
1131
1183
|
</i18n>
|
|
@@ -165,6 +165,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
165
165
|
message: string;
|
|
166
166
|
}[] | undefined;
|
|
167
167
|
maxCount?: string | undefined;
|
|
168
|
+
template?: string | undefined;
|
|
169
|
+
templateName?: readonly {
|
|
170
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
171
|
+
message: string;
|
|
172
|
+
}[] | undefined;
|
|
168
173
|
style?: string | undefined;
|
|
169
174
|
initialValue?: string | undefined;
|
|
170
175
|
hidden?: string | undefined;
|
|
@@ -352,6 +357,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
352
357
|
message: string;
|
|
353
358
|
}[] | undefined;
|
|
354
359
|
maxCount?: string | undefined;
|
|
360
|
+
template?: string | undefined;
|
|
361
|
+
templateName?: readonly {
|
|
362
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
363
|
+
message: string;
|
|
364
|
+
}[] | undefined;
|
|
355
365
|
style?: string | undefined;
|
|
356
366
|
initialValue?: string | undefined;
|
|
357
367
|
hidden?: string | undefined;
|
|
@@ -535,6 +545,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
535
545
|
message: string;
|
|
536
546
|
}[] | undefined;
|
|
537
547
|
maxCount?: string | undefined;
|
|
548
|
+
template?: string | undefined;
|
|
549
|
+
templateName?: readonly {
|
|
550
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
551
|
+
message: string;
|
|
552
|
+
}[] | undefined;
|
|
538
553
|
style?: string | undefined;
|
|
539
554
|
initialValue?: string | undefined;
|
|
540
555
|
hidden?: string | undefined;
|
|
@@ -720,6 +735,11 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
720
735
|
message: string;
|
|
721
736
|
}[] | undefined;
|
|
722
737
|
maxCount?: string | undefined;
|
|
738
|
+
template?: string | undefined;
|
|
739
|
+
templateName?: readonly {
|
|
740
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
741
|
+
message: string;
|
|
742
|
+
}[] | undefined;
|
|
723
743
|
style?: string | undefined;
|
|
724
744
|
initialValue?: string | undefined;
|
|
725
745
|
hidden?: string | undefined;
|
|
@@ -217,6 +217,16 @@ export declare const UploadFieldC: z.ZodObject<{
|
|
|
217
217
|
message: z.ZodString;
|
|
218
218
|
}, z.core.$strip>>>>;
|
|
219
219
|
maxCount: z.ZodOptional<z.ZodString>;
|
|
220
|
+
template: z.ZodOptional<z.ZodString>;
|
|
221
|
+
templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
222
|
+
locale: z.ZodEnum<{
|
|
223
|
+
en: "en";
|
|
224
|
+
ja: "ja";
|
|
225
|
+
ko: "ko";
|
|
226
|
+
zh: "zh";
|
|
227
|
+
}>;
|
|
228
|
+
message: z.ZodString;
|
|
229
|
+
}, z.core.$strip>>>>;
|
|
220
230
|
style: z.ZodOptional<z.ZodString>;
|
|
221
231
|
initialValue: z.ZodOptional<z.ZodString>;
|
|
222
232
|
hidden: z.ZodOptional<z.ZodString>;
|
|
@@ -437,6 +447,16 @@ export declare const FieldC: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
437
447
|
message: z.ZodString;
|
|
438
448
|
}, z.core.$strip>>>>;
|
|
439
449
|
maxCount: z.ZodOptional<z.ZodString>;
|
|
450
|
+
template: z.ZodOptional<z.ZodString>;
|
|
451
|
+
templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
452
|
+
locale: z.ZodEnum<{
|
|
453
|
+
en: "en";
|
|
454
|
+
ja: "ja";
|
|
455
|
+
ko: "ko";
|
|
456
|
+
zh: "zh";
|
|
457
|
+
}>;
|
|
458
|
+
message: z.ZodString;
|
|
459
|
+
}, z.core.$strip>>>>;
|
|
440
460
|
style: z.ZodOptional<z.ZodString>;
|
|
441
461
|
initialValue: z.ZodOptional<z.ZodString>;
|
|
442
462
|
hidden: z.ZodOptional<z.ZodString>;
|
|
@@ -671,6 +691,16 @@ export declare const FieldsBodyC: z.ZodReadonly<z.ZodObject<{
|
|
|
671
691
|
message: z.ZodString;
|
|
672
692
|
}, z.core.$strip>>>>;
|
|
673
693
|
maxCount: z.ZodOptional<z.ZodString>;
|
|
694
|
+
template: z.ZodOptional<z.ZodString>;
|
|
695
|
+
templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
696
|
+
locale: z.ZodEnum<{
|
|
697
|
+
en: "en";
|
|
698
|
+
ja: "ja";
|
|
699
|
+
ko: "ko";
|
|
700
|
+
zh: "zh";
|
|
701
|
+
}>;
|
|
702
|
+
message: z.ZodString;
|
|
703
|
+
}, z.core.$strip>>>>;
|
|
674
704
|
style: z.ZodOptional<z.ZodString>;
|
|
675
705
|
initialValue: z.ZodOptional<z.ZodString>;
|
|
676
706
|
hidden: z.ZodOptional<z.ZodString>;
|
|
@@ -899,6 +929,16 @@ export declare const FieldsBodyInputC: z.ZodReadonly<z.ZodObject<{
|
|
|
899
929
|
message: z.ZodString;
|
|
900
930
|
}, z.core.$strip>>>>;
|
|
901
931
|
maxCount: z.ZodOptional<z.ZodString>;
|
|
932
|
+
template: z.ZodOptional<z.ZodString>;
|
|
933
|
+
templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
934
|
+
locale: z.ZodEnum<{
|
|
935
|
+
en: "en";
|
|
936
|
+
ja: "ja";
|
|
937
|
+
ko: "ko";
|
|
938
|
+
zh: "zh";
|
|
939
|
+
}>;
|
|
940
|
+
message: z.ZodString;
|
|
941
|
+
}, z.core.$strip>>>>;
|
|
902
942
|
style: z.ZodOptional<z.ZodString>;
|
|
903
943
|
initialValue: z.ZodOptional<z.ZodString>;
|
|
904
944
|
hidden: z.ZodOptional<z.ZodString>;
|
|
@@ -1127,6 +1167,16 @@ export declare const FieldsConfigC: z.ZodReadonly<z.ZodObject<{
|
|
|
1127
1167
|
message: z.ZodString;
|
|
1128
1168
|
}, z.core.$strip>>>>;
|
|
1129
1169
|
maxCount: z.ZodOptional<z.ZodString>;
|
|
1170
|
+
template: z.ZodOptional<z.ZodString>;
|
|
1171
|
+
templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
1172
|
+
locale: z.ZodEnum<{
|
|
1173
|
+
en: "en";
|
|
1174
|
+
ja: "ja";
|
|
1175
|
+
ko: "ko";
|
|
1176
|
+
zh: "zh";
|
|
1177
|
+
}>;
|
|
1178
|
+
message: z.ZodString;
|
|
1179
|
+
}, z.core.$strip>>>>;
|
|
1130
1180
|
style: z.ZodOptional<z.ZodString>;
|
|
1131
1181
|
initialValue: z.ZodOptional<z.ZodString>;
|
|
1132
1182
|
hidden: z.ZodOptional<z.ZodString>;
|
|
@@ -1357,6 +1407,16 @@ export declare const FieldsConfigInputC: z.ZodReadonly<z.ZodObject<{
|
|
|
1357
1407
|
message: z.ZodString;
|
|
1358
1408
|
}, z.core.$strip>>>>;
|
|
1359
1409
|
maxCount: z.ZodOptional<z.ZodString>;
|
|
1410
|
+
template: z.ZodOptional<z.ZodString>;
|
|
1411
|
+
templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
1412
|
+
locale: z.ZodEnum<{
|
|
1413
|
+
en: "en";
|
|
1414
|
+
ja: "ja";
|
|
1415
|
+
ko: "ko";
|
|
1416
|
+
zh: "zh";
|
|
1417
|
+
}>;
|
|
1418
|
+
message: z.ZodString;
|
|
1419
|
+
}, z.core.$strip>>>>;
|
|
1360
1420
|
style: z.ZodOptional<z.ZodString>;
|
|
1361
1421
|
initialValue: z.ZodOptional<z.ZodString>;
|
|
1362
1422
|
hidden: z.ZodOptional<z.ZodString>;
|
|
@@ -133,6 +133,8 @@ export const UploadFieldC = z.object({
|
|
|
133
133
|
accept: z.array(z.string()).readonly().optional().describe("\u5141\u8BB8\u4E0A\u4F20\u7684 MIME \u7C7B\u578B\u6570\u7EC4\uFF0C\u540C\u65F6\u63A7\u5236\u6587\u4EF6\u9009\u62E9\u8FC7\u6EE4\u548C\u533A\u57DF\u63CF\u8FF0\u6587\u5B57"),
|
|
134
134
|
description: localeC.optional().describe("\u4E0A\u4F20\u533A\u57DF\u7684\u63D0\u793A\u6587\u672C\u7684\u672C\u5730\u5316\u663E\u793A\u6587\u672C\uFF0C\u66FF\u6362\u9ED8\u8BA4\u7684\u300C\u70B9\u51FB\u6216\u62D6\u62FD\u5230\u6B64\u5904\u4E0A\u4F20\u300D"),
|
|
135
135
|
maxCount: expressionC(["int", "dyn"], inheritedFieldContext).optional().describe("\u8FD4\u56DE\u6574\u6570\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u9650\u5236\u6700\u5927\u53EF\u4E0A\u4F20\u6587\u4EF6\u6570\u91CF\uFF0C\u53EF\u4F7F\u7528 form\u3001row\u3001index \u548C id \u53D8\u91CF"),
|
|
136
|
+
template: expressionC(["File", "dyn"]).optional().describe('\u8FD4\u56DE File \u7684 CEL \u8868\u8FBE\u5F0F\uFF08\u5982 http.post("/url").file()\uFF09\uFF0C\u914D\u7F6E\u540E\u5728\u4E0A\u4F20\u533A\u57DF\u663E\u793A\u300C\u4E0B\u8F7D\u6A21\u677F\u300D\u6309\u94AE'),
|
|
137
|
+
templateName: localeC.optional().describe("\u4E0B\u8F7D\u6A21\u677F\u6309\u94AE\u7684\u672C\u5730\u5316\u663E\u793A\u6587\u672C\uFF0C\u7559\u7A7A\u65F6\u663E\u793A\u9ED8\u8BA4\u6587\u672C\u300C\u4E0B\u8F7D\u6A21\u677F\u300D"),
|
|
136
138
|
style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u5B57\u6BB5\u7684\u5E03\u5C40\u4E0E\u5916\u89C2"),
|
|
137
139
|
initialValue: expressionC(["list(dyn)", "dyn"], inheritedFieldContext).optional().describe("\u8FD4\u56DE\u6570\u7EC4\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form\u3001row\u3001index \u548C id \u53D8\u91CF"),
|
|
138
140
|
hidden: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row\u3001index \u548C id \u53D8\u91CF"),
|
|
@@ -166,6 +166,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
166
166
|
message: string;
|
|
167
167
|
}[] | undefined;
|
|
168
168
|
maxCount?: string | undefined;
|
|
169
|
+
template?: string | undefined;
|
|
170
|
+
templateName?: readonly {
|
|
171
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
172
|
+
message: string;
|
|
173
|
+
}[] | undefined;
|
|
169
174
|
style?: string | undefined;
|
|
170
175
|
initialValue?: string | undefined;
|
|
171
176
|
hidden?: string | undefined;
|
|
@@ -349,6 +354,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
349
354
|
message: string;
|
|
350
355
|
}[] | undefined;
|
|
351
356
|
maxCount?: string | undefined;
|
|
357
|
+
template?: string | undefined;
|
|
358
|
+
templateName?: readonly {
|
|
359
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
360
|
+
message: string;
|
|
361
|
+
}[] | undefined;
|
|
352
362
|
style?: string | undefined;
|
|
353
363
|
initialValue?: string | undefined;
|
|
354
364
|
hidden?: string | undefined;
|
|
@@ -23,10 +23,10 @@ import { cn } from "../../../utils/cn";
|
|
|
23
23
|
import { Button } from "../button";
|
|
24
24
|
import {
|
|
25
25
|
Dialog,
|
|
26
|
-
DialogContent,
|
|
27
26
|
DialogDescription,
|
|
28
27
|
DialogFooter,
|
|
29
28
|
DialogHeader,
|
|
29
|
+
DialogScrollContent,
|
|
30
30
|
DialogTitle
|
|
31
31
|
} from "../dialog";
|
|
32
32
|
import {
|
|
@@ -301,6 +301,7 @@ function normalizeField(field) {
|
|
|
301
301
|
contentStyle: normalizeOptionalString(field.contentStyle ?? ""),
|
|
302
302
|
accept: normalizedAccept.length > 0 ? normalizedAccept : void 0,
|
|
303
303
|
maxCount: normalizeOptionalString(field.maxCount ?? ""),
|
|
304
|
+
template: normalizeOptionalString(field.template ?? ""),
|
|
304
305
|
initialValue: normalizeOptionalString(field.initialValue ?? ""),
|
|
305
306
|
hidden: normalizeOptionalString(field.hidden ?? ""),
|
|
306
307
|
disabled: normalizeOptionalString(field.disabled ?? ""),
|
|
@@ -907,6 +908,22 @@ function updateSelectedUploadDescription(value) {
|
|
|
907
908
|
};
|
|
908
909
|
});
|
|
909
910
|
}
|
|
911
|
+
function updateSelectedUploadTemplateName(value) {
|
|
912
|
+
const selected = selectedField.value;
|
|
913
|
+
if (!selected || selected.field.type !== "upload") {
|
|
914
|
+
return;
|
|
915
|
+
}
|
|
916
|
+
clearFieldError(selected.draftId, "templateName");
|
|
917
|
+
updateDraftField(selected.draftId, (field) => {
|
|
918
|
+
if (field.type !== "upload") {
|
|
919
|
+
return field;
|
|
920
|
+
}
|
|
921
|
+
return {
|
|
922
|
+
...field,
|
|
923
|
+
templateName: value
|
|
924
|
+
};
|
|
925
|
+
});
|
|
926
|
+
}
|
|
910
927
|
function updateSelectedUploadMaxCount(value) {
|
|
911
928
|
const selected = selectedField.value;
|
|
912
929
|
if (!selected || selected.field.type !== "upload") {
|
|
@@ -923,6 +940,22 @@ function updateSelectedUploadMaxCount(value) {
|
|
|
923
940
|
};
|
|
924
941
|
});
|
|
925
942
|
}
|
|
943
|
+
function updateSelectedUploadTemplate(value) {
|
|
944
|
+
const selected = selectedField.value;
|
|
945
|
+
if (!selected || selected.field.type !== "upload") {
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
clearFieldError(selected.draftId, "template");
|
|
949
|
+
updateDraftField(selected.draftId, (field) => {
|
|
950
|
+
if (field.type !== "upload") {
|
|
951
|
+
return field;
|
|
952
|
+
}
|
|
953
|
+
return {
|
|
954
|
+
...field,
|
|
955
|
+
template: normalizeOptionalString(String(value))
|
|
956
|
+
};
|
|
957
|
+
});
|
|
958
|
+
}
|
|
926
959
|
function addValidationRule() {
|
|
927
960
|
const selected = selectedField.value;
|
|
928
961
|
if (!selected || isPassiveField(selected.field)) {
|
|
@@ -1434,7 +1467,7 @@ function confirmChanges() {
|
|
|
1434
1467
|
:open="open"
|
|
1435
1468
|
@update:open="handleOpenChange"
|
|
1436
1469
|
>
|
|
1437
|
-
<
|
|
1470
|
+
<DialogScrollContent
|
|
1438
1471
|
class="flex h-[min(42rem,calc(100vh-4rem))] w-[calc(100%-2rem)] max-h-[calc(100vh-4rem)] max-w-[calc(100%-2rem)] flex-col overflow-hidden p-0 sm:w-[80vw] sm:max-w-[80vw]"
|
|
1439
1472
|
:show-close-button="true"
|
|
1440
1473
|
>
|
|
@@ -2298,6 +2331,37 @@ function confirmChanges() {
|
|
|
2298
2331
|
{{ validationErrors[getFieldErrorKey(selectedField.draftId, "maxCount")] }}
|
|
2299
2332
|
</p>
|
|
2300
2333
|
</label>
|
|
2334
|
+
|
|
2335
|
+
<label class="flex flex-col gap-2 md:col-span-2">
|
|
2336
|
+
<span class="text-xs font-medium text-zinc-500">
|
|
2337
|
+
{{ t("field-upload-template") }}
|
|
2338
|
+
</span>
|
|
2339
|
+
<Textarea
|
|
2340
|
+
data-slot="fields-configurator-field-upload-template-input"
|
|
2341
|
+
:model-value="selectedField.field.template ?? ''"
|
|
2342
|
+
:aria-invalid="validationErrors[getFieldErrorKey(selectedField.draftId, 'template')] ? 'true' : void 0"
|
|
2343
|
+
:placeholder="t('field-upload-template-placeholder')"
|
|
2344
|
+
class="min-h-20 font-mono text-sm"
|
|
2345
|
+
@update:model-value="updateSelectedUploadTemplate"
|
|
2346
|
+
/>
|
|
2347
|
+
<p
|
|
2348
|
+
v-if="validationErrors[getFieldErrorKey(selectedField.draftId, 'template')]"
|
|
2349
|
+
class="text-xs text-red-500"
|
|
2350
|
+
>
|
|
2351
|
+
{{ validationErrors[getFieldErrorKey(selectedField.draftId, "template")] }}
|
|
2352
|
+
</p>
|
|
2353
|
+
</label>
|
|
2354
|
+
|
|
2355
|
+
<div class="flex flex-col gap-2 md:col-span-2">
|
|
2356
|
+
<span class="text-xs font-medium text-zinc-500">
|
|
2357
|
+
{{ t("field-upload-template-name") }}
|
|
2358
|
+
</span>
|
|
2359
|
+
<Locale
|
|
2360
|
+
data-slot="fields-configurator-field-upload-template-name-locale"
|
|
2361
|
+
:model-value="selectedField.field.templateName"
|
|
2362
|
+
@update:model-value="updateSelectedUploadTemplateName"
|
|
2363
|
+
/>
|
|
2364
|
+
</div>
|
|
2301
2365
|
</section>
|
|
2302
2366
|
|
|
2303
2367
|
<section
|
|
@@ -2478,7 +2542,7 @@ function confirmChanges() {
|
|
|
2478
2542
|
</Button>
|
|
2479
2543
|
</div>
|
|
2480
2544
|
</DialogFooter>
|
|
2481
|
-
</
|
|
2545
|
+
</DialogScrollContent>
|
|
2482
2546
|
</Dialog>
|
|
2483
2547
|
</template>
|
|
2484
2548
|
|
|
@@ -2582,6 +2646,9 @@ function confirmChanges() {
|
|
|
2582
2646
|
"field-upload-description": "上传提示文本",
|
|
2583
2647
|
"field-upload-max-count": "最大文件数量",
|
|
2584
2648
|
"field-upload-max-count-placeholder": "例如 5",
|
|
2649
|
+
"field-upload-template": "下载模板表达式",
|
|
2650
|
+
"field-upload-template-placeholder": "例如 http.post(\"/api/v1/example/download_template\").file()",
|
|
2651
|
+
"field-upload-template-name": "下载模板按钮名称",
|
|
2585
2652
|
"field-validation": "校验规则",
|
|
2586
2653
|
"field-validation-description": "字段失焦时按顺序执行,命中第一个失败规则后停止。",
|
|
2587
2654
|
"add-validation-rule": "新增规则",
|
|
@@ -2699,6 +2766,9 @@ function confirmChanges() {
|
|
|
2699
2766
|
"field-upload-description": "アップロード説明文",
|
|
2700
2767
|
"field-upload-max-count": "最大ファイル数",
|
|
2701
2768
|
"field-upload-max-count-placeholder": "例: 5",
|
|
2769
|
+
"field-upload-template": "テンプレートダウンロード式",
|
|
2770
|
+
"field-upload-template-placeholder": "例: http.post(\"/api/v1/example/download_template\").file()",
|
|
2771
|
+
"field-upload-template-name": "テンプレートボタン名",
|
|
2702
2772
|
"field-validation": "検証ルール",
|
|
2703
2773
|
"field-validation-description": "フォーカスを外したときに順番に評価し、最初の失敗で停止します。",
|
|
2704
2774
|
"add-validation-rule": "ルールを追加",
|
|
@@ -2816,6 +2886,9 @@ function confirmChanges() {
|
|
|
2816
2886
|
"field-upload-description": "Upload description",
|
|
2817
2887
|
"field-upload-max-count": "Max file count",
|
|
2818
2888
|
"field-upload-max-count-placeholder": "For example 5",
|
|
2889
|
+
"field-upload-template": "Template download expression",
|
|
2890
|
+
"field-upload-template-placeholder": "e.g. http.post(\"/api/v1/example/download_template\").file()",
|
|
2891
|
+
"field-upload-template-name": "Template button name",
|
|
2819
2892
|
"field-validation": "Validation rules",
|
|
2820
2893
|
"field-validation-description": "Rules run on blur in order and stop at the first failure.",
|
|
2821
2894
|
"add-validation-rule": "Add rule",
|
|
@@ -166,6 +166,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
166
166
|
message: string;
|
|
167
167
|
}[] | undefined;
|
|
168
168
|
maxCount?: string | undefined;
|
|
169
|
+
template?: string | undefined;
|
|
170
|
+
templateName?: readonly {
|
|
171
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
172
|
+
message: string;
|
|
173
|
+
}[] | undefined;
|
|
169
174
|
style?: string | undefined;
|
|
170
175
|
initialValue?: string | undefined;
|
|
171
176
|
hidden?: string | undefined;
|
|
@@ -349,6 +354,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
349
354
|
message: string;
|
|
350
355
|
}[] | undefined;
|
|
351
356
|
maxCount?: string | undefined;
|
|
357
|
+
template?: string | undefined;
|
|
358
|
+
templateName?: readonly {
|
|
359
|
+
locale: "en" | "ja" | "ko" | "zh";
|
|
360
|
+
message: string;
|
|
361
|
+
}[] | undefined;
|
|
352
362
|
style?: string | undefined;
|
|
353
363
|
initialValue?: string | undefined;
|
|
354
364
|
hidden?: string | undefined;
|
|
@@ -7,10 +7,10 @@ import { cn } from "../../../utils/cn";
|
|
|
7
7
|
import { Button } from "../button";
|
|
8
8
|
import {
|
|
9
9
|
Dialog,
|
|
10
|
-
DialogContent,
|
|
11
10
|
DialogDescription,
|
|
12
11
|
DialogFooter,
|
|
13
12
|
DialogHeader,
|
|
13
|
+
DialogScrollContent,
|
|
14
14
|
DialogTitle
|
|
15
15
|
} from "../dialog";
|
|
16
16
|
import { ExpressionEditor } from "../expression-editor";
|
|
@@ -258,7 +258,7 @@ watch(normalizedSearch, async () => {
|
|
|
258
258
|
:open="open"
|
|
259
259
|
@update:open="open = $event"
|
|
260
260
|
>
|
|
261
|
-
<
|
|
261
|
+
<DialogScrollContent
|
|
262
262
|
data-slot="menu-tabs-configurator-dialog"
|
|
263
263
|
class="flex h-[min(42rem,calc(100vh-4rem))] w-[calc(100%-2rem)] max-h-[calc(100vh-4rem)] max-w-[calc(100%-2rem)] flex-col overflow-hidden p-0 sm:w-[80vw] sm:max-w-[80vw]"
|
|
264
264
|
>
|
|
@@ -419,7 +419,7 @@ watch(normalizedSearch, async () => {
|
|
|
419
419
|
{{ t("confirm") }}
|
|
420
420
|
</Button>
|
|
421
421
|
</DialogFooter>
|
|
422
|
-
</
|
|
422
|
+
</DialogScrollContent>
|
|
423
423
|
</Dialog>
|
|
424
424
|
</template>
|
|
425
425
|
|
|
@@ -13,10 +13,10 @@ import { Button } from "../button";
|
|
|
13
13
|
import { Checkbox } from "../checkbox";
|
|
14
14
|
import {
|
|
15
15
|
Dialog,
|
|
16
|
-
DialogContent,
|
|
17
16
|
DialogDescription,
|
|
18
17
|
DialogFooter,
|
|
19
18
|
DialogHeader,
|
|
19
|
+
DialogScrollContent,
|
|
20
20
|
DialogTitle
|
|
21
21
|
} from "../dialog";
|
|
22
22
|
import { Input } from "../input";
|
|
@@ -1625,7 +1625,7 @@ function confirmChanges() {
|
|
|
1625
1625
|
:open="open"
|
|
1626
1626
|
@update:open="handleOpenChange"
|
|
1627
1627
|
>
|
|
1628
|
-
<
|
|
1628
|
+
<DialogScrollContent
|
|
1629
1629
|
class="flex h-[min(42rem,calc(100vh-4rem))] w-[calc(100%-2rem)] max-h-[calc(100vh-4rem)] max-w-[calc(100%-2rem)] flex-col overflow-hidden p-0 sm:w-[80vw] sm:max-w-[80vw]"
|
|
1630
1630
|
:show-close-button="true"
|
|
1631
1631
|
@pointer-down-outside="(event) => event.preventDefault()"
|
|
@@ -2437,7 +2437,7 @@ function confirmChanges() {
|
|
|
2437
2437
|
</Button>
|
|
2438
2438
|
</div>
|
|
2439
2439
|
</DialogFooter>
|
|
2440
|
-
</
|
|
2440
|
+
</DialogScrollContent>
|
|
2441
2441
|
</Dialog>
|
|
2442
2442
|
</template>
|
|
2443
2443
|
|
|
@@ -2,6 +2,7 @@ import { defineNuxtPlugin, useNuxtApp, useRuntimeConfig } from "#app";
|
|
|
2
2
|
import { useNavigatorLanguage } from "@vueuse/core";
|
|
3
3
|
import { Effect } from "effect";
|
|
4
4
|
import z from "zod";
|
|
5
|
+
import { setFileHandler } from "../cel/http-request.js";
|
|
5
6
|
let isRedirectingAfterTokenExpiry = false;
|
|
6
7
|
const processedResponses = /* @__PURE__ */ new WeakSet();
|
|
7
8
|
export default defineNuxtPlugin({
|
|
@@ -121,6 +122,21 @@ export default defineNuxtPlugin({
|
|
|
121
122
|
data
|
|
122
123
|
});
|
|
123
124
|
}
|
|
125
|
+
setFileHandler(async (request) => {
|
|
126
|
+
const headers = new Headers(request.headers);
|
|
127
|
+
applyRequestHeaders(headers);
|
|
128
|
+
const response = await fetch(createRequestUrl(request.url, request.query), {
|
|
129
|
+
method: request.method,
|
|
130
|
+
headers,
|
|
131
|
+
body: createRequestBody(request.body, headers)
|
|
132
|
+
});
|
|
133
|
+
await handleExpiredFetchResponse(response);
|
|
134
|
+
if (!response.ok) throw new Error(`Download failed: ${response.status}`);
|
|
135
|
+
const blob = await response.blob();
|
|
136
|
+
const disposition = response.headers.get("Content-Disposition");
|
|
137
|
+
const filename = disposition?.split(/filename=/i)[1]?.replaceAll(/"|'/g, "") ?? "download";
|
|
138
|
+
return new File([blob], decodeURIComponent(filename), { type: blob.type });
|
|
139
|
+
});
|
|
124
140
|
const api = $fetch.create({
|
|
125
141
|
baseURL: config.api.host,
|
|
126
142
|
onRequest: ({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Environment, EvaluationError, Optional } from "../../vendor/cel/index.js";
|
|
2
|
+
import { Http, HttpRequest, getFileHandler } from "./http-request.js";
|
|
2
3
|
import { startOfDay, startOfWeek, startOfYear, startOfMonth, endOfDay, endOfWeek, endOfYear, endOfMonth, addYears, addMonths, addDays, addWeeks, setDate, setMonth, setYear, formatDate, isBefore, isAfter, isEqual } from "date-fns";
|
|
3
4
|
import { TZDate } from "@date-fns/tz";
|
|
4
5
|
import { BigNumber } from "bignumber.js";
|
|
@@ -184,5 +185,10 @@ export function createEnvironment(f = identity) {
|
|
|
184
185
|
return Optional.none();
|
|
185
186
|
}
|
|
186
187
|
});
|
|
188
|
+
env.registerType("Http", Http).registerType("HttpRequest", HttpRequest).registerType("File", File).registerConstant("http", "Http", new Http()).registerFunction("Http.get(string): HttpRequest", (_, url) => new HttpRequest(url, "GET")).registerFunction("Http.post(string): HttpRequest", (_, url) => new HttpRequest(url, "POST")).registerFunction("Http.put(string): HttpRequest", (_, url) => new HttpRequest(url, "PUT")).registerFunction("Http.delete(string): HttpRequest", (_, url) => new HttpRequest(url, "DELETE")).registerFunction("HttpRequest.header(string, string): HttpRequest", (r, k, v) => r.withHeader(k, v)).registerFunction("HttpRequest.query(string, string): HttpRequest", (r, k, v) => r.withQuery(k, v)).registerFunction("HttpRequest.body(dyn): HttpRequest", (r, body) => r.withBody(body)).registerFunction("HttpRequest.file(): File", async (request) => {
|
|
189
|
+
const handler = getFileHandler();
|
|
190
|
+
if (!handler) throw new EvaluationError("HttpRequest.file() handler not initialized");
|
|
191
|
+
return handler(request);
|
|
192
|
+
});
|
|
187
193
|
return f(env);
|
|
188
194
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class Http {
|
|
2
|
+
readonly kind: "Http";
|
|
3
|
+
}
|
|
4
|
+
export declare class HttpRequest {
|
|
5
|
+
readonly url: string;
|
|
6
|
+
readonly method: string;
|
|
7
|
+
readonly headers: Record<string, string>;
|
|
8
|
+
readonly query: Record<string, string>;
|
|
9
|
+
readonly body: unknown;
|
|
10
|
+
constructor(url: string, method?: string, headers?: Record<string, string>, query?: Record<string, string>, body?: unknown);
|
|
11
|
+
withHeader(key: string, value: string): HttpRequest;
|
|
12
|
+
withQuery(key: string, value: string): HttpRequest;
|
|
13
|
+
withBody(body: unknown): HttpRequest;
|
|
14
|
+
}
|
|
15
|
+
export declare function getFileHandler(): ((request: HttpRequest) => Promise<File>) | null;
|
|
16
|
+
export declare function setFileHandler(fn: (request: HttpRequest) => Promise<File>): void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export class Http {
|
|
2
|
+
kind = "Http";
|
|
3
|
+
}
|
|
4
|
+
export class HttpRequest {
|
|
5
|
+
url;
|
|
6
|
+
method;
|
|
7
|
+
headers;
|
|
8
|
+
query;
|
|
9
|
+
body;
|
|
10
|
+
constructor(url, method = "GET", headers = {}, query = {}, body = void 0) {
|
|
11
|
+
this.url = url;
|
|
12
|
+
this.method = method;
|
|
13
|
+
this.headers = headers;
|
|
14
|
+
this.query = query;
|
|
15
|
+
this.body = body;
|
|
16
|
+
Object.freeze(this);
|
|
17
|
+
}
|
|
18
|
+
withHeader(key, value) {
|
|
19
|
+
return new HttpRequest(this.url, this.method, { ...this.headers, [key]: value }, this.query, this.body);
|
|
20
|
+
}
|
|
21
|
+
withQuery(key, value) {
|
|
22
|
+
return new HttpRequest(this.url, this.method, this.headers, { ...this.query, [key]: value }, this.body);
|
|
23
|
+
}
|
|
24
|
+
withBody(body) {
|
|
25
|
+
return new HttpRequest(this.url, this.method, this.headers, this.query, body);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const httpState = {
|
|
29
|
+
fileHandler: null
|
|
30
|
+
};
|
|
31
|
+
export function getFileHandler() {
|
|
32
|
+
return httpState.fileHandler;
|
|
33
|
+
}
|
|
34
|
+
export function setFileHandler(fn) {
|
|
35
|
+
httpState.fileHandler = fn;
|
|
36
|
+
}
|