@shwfed/nuxt 0.11.3 → 0.11.5
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 +1 -1
- package/dist/runtime/components/fields.vue +29 -0
- package/dist/runtime/components/fields.vue.d.ts +1 -1
- package/dist/runtime/components/ui/app/OverlayHost.vue +0 -34
- package/dist/runtime/components/ui/buttons/Buttons.vue +25 -9
- package/dist/runtime/components/ui/fields/Fields.d.vue.ts +6 -1
- package/dist/runtime/components/ui/fields/Fields.vue +58 -5
- package/dist/runtime/components/ui/fields/Fields.vue.d.ts +6 -1
- package/dist/runtime/composables/useOverlay.d.ts +0 -10
- package/dist/runtime/composables/useOverlay.js +0 -21
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect } from 'effect';
|
|
2
2
|
import { type FieldsConfigInput } from './ui/fields/Fields.vue.js';
|
|
3
3
|
export { CalendarFieldC, EmptyFieldC, FieldC, FieldsBodyC, FieldsBodyInputC, FieldsConfigC, FieldsConfigInputC, NumberFieldC, SelectFieldC, SlotFieldC, StringFieldC, CURRENT_COMPATIBILITY_DATE, KIND, SUPPORTED_COMPATIBILITY_DATES, createFieldsConfig, } from './ui/fields/Fields.vue.js';
|
|
4
|
-
export type { EmptyField, Field, FieldsBody, FieldsBodyInput, FieldsConfig, FieldsConfigInput, SlotField, } from './ui/fields/Fields.vue.js';
|
|
4
|
+
export type { EmptyField, Field, FieldsInstance, FieldsBody, FieldsBodyInput, FieldsConfig, FieldsConfigInput, SlotField, } from './ui/fields/Fields.vue.js';
|
|
5
5
|
declare const _default: typeof __VLS_export;
|
|
6
6
|
export default _default;
|
|
7
7
|
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { Effect } from "effect";
|
|
3
|
+
import { ref } from "vue";
|
|
3
4
|
import UiFields, {
|
|
4
5
|
createFieldsConfig
|
|
5
6
|
} from "./ui/fields/Fields.vue";
|
|
@@ -23,6 +24,33 @@ function handleConfigUpdate(config2) {
|
|
|
23
24
|
function handleInitialValueReady() {
|
|
24
25
|
emit("initial-value-ready");
|
|
25
26
|
}
|
|
27
|
+
const fieldsRef = ref(null);
|
|
28
|
+
defineExpose(new Proxy({}, {
|
|
29
|
+
get(_target, property) {
|
|
30
|
+
return fieldsRef.value ? Reflect.get(fieldsRef.value, property) : void 0;
|
|
31
|
+
},
|
|
32
|
+
has(_target, property) {
|
|
33
|
+
return fieldsRef.value ? Reflect.has(fieldsRef.value, property) : false;
|
|
34
|
+
},
|
|
35
|
+
ownKeys() {
|
|
36
|
+
return fieldsRef.value ? Reflect.ownKeys(fieldsRef.value) : [];
|
|
37
|
+
},
|
|
38
|
+
getOwnPropertyDescriptor(_target, property) {
|
|
39
|
+
if (!fieldsRef.value || !Reflect.has(fieldsRef.value, property)) {
|
|
40
|
+
return void 0;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
configurable: true,
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get() {
|
|
46
|
+
if (!fieldsRef.value) {
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
return Reflect.get(fieldsRef.value, property);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
26
54
|
</script>
|
|
27
55
|
|
|
28
56
|
<script>
|
|
@@ -47,6 +75,7 @@ export {
|
|
|
47
75
|
|
|
48
76
|
<template>
|
|
49
77
|
<UiFields
|
|
78
|
+
ref="fieldsRef"
|
|
50
79
|
v-bind="$attrs"
|
|
51
80
|
v-model="modelValue"
|
|
52
81
|
:config="config"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect } from 'effect';
|
|
2
2
|
import { type FieldsConfigInput } from './ui/fields/Fields.vue.js';
|
|
3
3
|
export { CalendarFieldC, EmptyFieldC, FieldC, FieldsBodyC, FieldsBodyInputC, FieldsConfigC, FieldsConfigInputC, NumberFieldC, SelectFieldC, SlotFieldC, StringFieldC, CURRENT_COMPATIBILITY_DATE, KIND, SUPPORTED_COMPATIBILITY_DATES, createFieldsConfig, } from './ui/fields/Fields.vue.js';
|
|
4
|
-
export type { EmptyField, Field, FieldsBody, FieldsBodyInput, FieldsConfig, FieldsConfigInput, SlotField, } from './ui/fields/Fields.vue.js';
|
|
4
|
+
export type { EmptyField, Field, FieldsInstance, FieldsBody, FieldsBodyInput, FieldsConfig, FieldsConfigInput, SlotField, } from './ui/fields/Fields.vue.js';
|
|
5
5
|
declare const _default: typeof __VLS_export;
|
|
6
6
|
export default _default;
|
|
7
7
|
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
@@ -28,17 +28,6 @@ function handleOpenUpdate(sessionId, open) {
|
|
|
28
28
|
reason: "dismiss"
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
|
-
function patchFooter(sessionId, definitionId, nextProps) {
|
|
32
|
-
if (!definitionId) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
overlay.patchSync(sessionId, {
|
|
36
|
-
footer: {
|
|
37
|
-
id: definitionId,
|
|
38
|
-
props: nextProps
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
31
|
const renderedSessions = computed(() => {
|
|
43
32
|
const nextSessions = [];
|
|
44
33
|
for (const session of overlay.sessions) {
|
|
@@ -46,7 +35,6 @@ const renderedSessions = computed(() => {
|
|
|
46
35
|
if (!definition) {
|
|
47
36
|
continue;
|
|
48
37
|
}
|
|
49
|
-
const footerDefinition = session.footer ? overlay.definitions[session.footer.id] : void 0;
|
|
50
38
|
nextSessions.push({
|
|
51
39
|
sessionId: session.sessionId,
|
|
52
40
|
definitionId: session.definitionId,
|
|
@@ -59,11 +47,6 @@ const renderedSessions = computed(() => {
|
|
|
59
47
|
},
|
|
60
48
|
descriptionSrOnly: session.shell.descriptionSrOnly,
|
|
61
49
|
props: session.props,
|
|
62
|
-
footer: session.footer && footerDefinition ? {
|
|
63
|
-
definitionId: session.footer.id,
|
|
64
|
-
props: session.footer.props,
|
|
65
|
-
definition: footerDefinition
|
|
66
|
-
} : void 0,
|
|
67
50
|
definition
|
|
68
51
|
});
|
|
69
52
|
}
|
|
@@ -115,23 +98,6 @@ const renderedSessions = computed(() => {
|
|
|
115
98
|
close: (value) => overlay.closeSync(session.sessionId, value),
|
|
116
99
|
patch: (nextProps) => overlay.patchSync(session.sessionId, { props: nextProps }),
|
|
117
100
|
isDesktop: modalSlotProps.isDesktop
|
|
118
|
-
}"
|
|
119
|
-
/>
|
|
120
|
-
</template>
|
|
121
|
-
|
|
122
|
-
<template
|
|
123
|
-
v-if="session.footer"
|
|
124
|
-
#footer="modalSlotProps"
|
|
125
|
-
>
|
|
126
|
-
<OverlayBody
|
|
127
|
-
:render="session.footer.definition.render"
|
|
128
|
-
:slot-props="{
|
|
129
|
-
props: session.footer.props,
|
|
130
|
-
shell: session.shell,
|
|
131
|
-
sessionId: session.sessionId,
|
|
132
|
-
close: (value) => overlay.closeSync(session.sessionId, value),
|
|
133
|
-
patch: (nextProps) => patchFooter(session.sessionId, session.footer?.definitionId, nextProps),
|
|
134
|
-
isDesktop: modalSlotProps.isDesktop
|
|
135
101
|
}"
|
|
136
102
|
/>
|
|
137
103
|
</template>
|
|
@@ -54,16 +54,32 @@ watch(currentConfig, (value) => {
|
|
|
54
54
|
}, { immediate: true });
|
|
55
55
|
const modalDefinitions = computed(() => {
|
|
56
56
|
const nextDefinitions = [];
|
|
57
|
-
for (const
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
for (const group of displayConfig.value.groups) {
|
|
58
|
+
for (const item of group.items) {
|
|
59
|
+
if (isDropdownItem(item)) {
|
|
60
|
+
for (const child of item.items) {
|
|
61
|
+
const render2 = slots[child.id];
|
|
62
|
+
if (render2) {
|
|
63
|
+
nextDefinitions.push({
|
|
64
|
+
definitionId: child.id,
|
|
65
|
+
ownerId: overlayOwnerId,
|
|
66
|
+
render: render2,
|
|
67
|
+
shell: getModalShell(child.modal)
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const render = slots[item.id];
|
|
74
|
+
if (render) {
|
|
75
|
+
nextDefinitions.push({
|
|
76
|
+
definitionId: item.id,
|
|
77
|
+
ownerId: overlayOwnerId,
|
|
78
|
+
render,
|
|
79
|
+
shell: getModalShell(item.modal)
|
|
80
|
+
});
|
|
81
|
+
}
|
|
60
82
|
}
|
|
61
|
-
nextDefinitions.push({
|
|
62
|
-
definitionId: slotName,
|
|
63
|
-
ownerId: overlayOwnerId,
|
|
64
|
-
render,
|
|
65
|
-
shell: getModalShell(findButtonAction(slotName)?.modal)
|
|
66
|
-
});
|
|
67
83
|
}
|
|
68
84
|
return nextDefinitions;
|
|
69
85
|
});
|
|
@@ -2,6 +2,9 @@ import { Effect } from 'effect';
|
|
|
2
2
|
import type { CSSProperties } from 'vue';
|
|
3
3
|
export { CalendarFieldC, CURRENT_COMPATIBILITY_DATE, EmptyFieldC, FieldC, FieldsBodyC, FieldsBodyInputC, FieldsConfigC, FieldsConfigInputC, KIND, NumberFieldC, SelectFieldC, SlotFieldC, SUPPORTED_COMPATIBILITY_DATES, StringFieldC, ValidationRuleC, createFieldsConfig, validationC, } from './schema.js';
|
|
4
4
|
export type { EmptyField, Field, FieldsBody, FieldsBodyInput, FieldsConfig, FieldsConfigInput, SlotField, ValidationRule, } from './schema.js';
|
|
5
|
+
export type FieldsInstance = {
|
|
6
|
+
valid: import('effect').Effect.Effect<boolean, never>;
|
|
7
|
+
};
|
|
5
8
|
declare const _default: typeof __VLS_export;
|
|
6
9
|
export default _default;
|
|
7
10
|
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
@@ -127,7 +130,9 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
127
130
|
}> | undefined>;
|
|
128
131
|
} & {
|
|
129
132
|
modelValue?: Record<string, unknown>;
|
|
130
|
-
}, {
|
|
133
|
+
}, {
|
|
134
|
+
valid: Effect.Effect<boolean, never, never>;
|
|
135
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
131
136
|
"update:modelValue": (value: Record<string, unknown>) => any;
|
|
132
137
|
"update:config": (args_0: Readonly<{
|
|
133
138
|
fields: readonly ({
|
|
@@ -41,8 +41,10 @@ const displayConfig = ref(defaultConfig);
|
|
|
41
41
|
const validationErrors = ref({});
|
|
42
42
|
const calendarOpen = ref({});
|
|
43
43
|
const selectOpen = ref({});
|
|
44
|
+
const isReady = ref(false);
|
|
44
45
|
const hasInitializedFieldValues = ref(false);
|
|
45
46
|
const hasEmittedInitialValueReady = ref(false);
|
|
47
|
+
const readyResolvers = [];
|
|
46
48
|
function cloneConfig(config2) {
|
|
47
49
|
const nextConfig = {
|
|
48
50
|
kind: config2.kind,
|
|
@@ -214,6 +216,24 @@ function handleSelectCommandValueChange(field, state, value) {
|
|
|
214
216
|
function clearFieldValidation(path) {
|
|
215
217
|
Reflect.deleteProperty(validationErrors.value, path);
|
|
216
218
|
}
|
|
219
|
+
function markReady() {
|
|
220
|
+
if (isReady.value) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
isReady.value = true;
|
|
224
|
+
while (readyResolvers.length > 0) {
|
|
225
|
+
const resolve = readyResolvers.shift();
|
|
226
|
+
resolve?.();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function waitForReady() {
|
|
230
|
+
if (isReady.value) {
|
|
231
|
+
return Promise.resolve();
|
|
232
|
+
}
|
|
233
|
+
return new Promise((resolve) => {
|
|
234
|
+
readyResolvers.push(resolve);
|
|
235
|
+
});
|
|
236
|
+
}
|
|
217
237
|
function snapshotValidationContext(field) {
|
|
218
238
|
const form = structuredClone(toRaw(modelValue.value));
|
|
219
239
|
return {
|
|
@@ -221,10 +241,9 @@ function snapshotValidationContext(field) {
|
|
|
221
241
|
form
|
|
222
242
|
};
|
|
223
243
|
}
|
|
224
|
-
function
|
|
244
|
+
function getValidationFailure(field) {
|
|
225
245
|
if (!field.validation?.length || isFieldHidden(field) || isFieldDisabled(field)) {
|
|
226
|
-
|
|
227
|
-
return;
|
|
246
|
+
return void 0;
|
|
228
247
|
}
|
|
229
248
|
const context = {
|
|
230
249
|
value: getFieldValue(field),
|
|
@@ -232,14 +251,39 @@ function validateField(field) {
|
|
|
232
251
|
};
|
|
233
252
|
for (const rule of field.validation) {
|
|
234
253
|
if (!$dsl.evaluate`${rule.expression}`(context)) {
|
|
235
|
-
|
|
254
|
+
return {
|
|
236
255
|
message: rule.message,
|
|
237
256
|
context: snapshotValidationContext(field)
|
|
238
257
|
};
|
|
239
|
-
return;
|
|
240
258
|
}
|
|
241
259
|
}
|
|
260
|
+
return void 0;
|
|
261
|
+
}
|
|
262
|
+
function syncFieldValidation(field) {
|
|
263
|
+
const failure = getValidationFailure(field);
|
|
264
|
+
if (failure) {
|
|
265
|
+
validationErrors.value[field.path] = failure;
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
242
268
|
clearFieldValidation(field.path);
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
function validateField(field) {
|
|
272
|
+
syncFieldValidation(field);
|
|
273
|
+
}
|
|
274
|
+
function validateFields() {
|
|
275
|
+
const nextValidationErrors = {};
|
|
276
|
+
for (const field of displayConfig.value.fields) {
|
|
277
|
+
if (isPassiveField(field)) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
const failure = getValidationFailure(field);
|
|
281
|
+
if (failure) {
|
|
282
|
+
nextValidationErrors[field.path] = failure;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
validationErrors.value = nextValidationErrors;
|
|
286
|
+
return Object.keys(nextValidationErrors).length === 0;
|
|
243
287
|
}
|
|
244
288
|
function isFieldInvalid(field) {
|
|
245
289
|
return validationErrors.value[field.path] !== void 0;
|
|
@@ -274,6 +318,14 @@ function handleConfiguratorConfirm(nextConfig) {
|
|
|
274
318
|
displayConfig.value = cloneConfig(nextConfig);
|
|
275
319
|
emit("update:config", nextConfig);
|
|
276
320
|
}
|
|
321
|
+
const fieldsApi = {
|
|
322
|
+
valid: Effect.async((resume) => {
|
|
323
|
+
void waitForReady().then(() => {
|
|
324
|
+
resume(Effect.sync(() => validateFields()));
|
|
325
|
+
});
|
|
326
|
+
})
|
|
327
|
+
};
|
|
328
|
+
defineExpose(fieldsApi);
|
|
277
329
|
watch(config, (value) => {
|
|
278
330
|
if (!value) {
|
|
279
331
|
return;
|
|
@@ -287,6 +339,7 @@ watch(config, (value) => {
|
|
|
287
339
|
hasEmittedInitialValueReady.value = true;
|
|
288
340
|
emit("initial-value-ready");
|
|
289
341
|
}
|
|
342
|
+
markReady();
|
|
290
343
|
}, { immediate: true });
|
|
291
344
|
watchEffect(() => {
|
|
292
345
|
const activePaths = /* @__PURE__ */ new Set();
|
|
@@ -2,6 +2,9 @@ import { Effect } from 'effect';
|
|
|
2
2
|
import type { CSSProperties } from 'vue';
|
|
3
3
|
export { CalendarFieldC, CURRENT_COMPATIBILITY_DATE, EmptyFieldC, FieldC, FieldsBodyC, FieldsBodyInputC, FieldsConfigC, FieldsConfigInputC, KIND, NumberFieldC, SelectFieldC, SlotFieldC, SUPPORTED_COMPATIBILITY_DATES, StringFieldC, ValidationRuleC, createFieldsConfig, validationC, } from './schema.js';
|
|
4
4
|
export type { EmptyField, Field, FieldsBody, FieldsBodyInput, FieldsConfig, FieldsConfigInput, SlotField, ValidationRule, } from './schema.js';
|
|
5
|
+
export type FieldsInstance = {
|
|
6
|
+
valid: import('effect').Effect.Effect<boolean, never>;
|
|
7
|
+
};
|
|
5
8
|
declare const _default: typeof __VLS_export;
|
|
6
9
|
export default _default;
|
|
7
10
|
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
@@ -127,7 +130,9 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
|
127
130
|
}> | undefined>;
|
|
128
131
|
} & {
|
|
129
132
|
modelValue?: Record<string, unknown>;
|
|
130
|
-
}, {
|
|
133
|
+
}, {
|
|
134
|
+
valid: Effect.Effect<boolean, never, never>;
|
|
135
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
131
136
|
"update:modelValue": (value: Record<string, unknown>) => any;
|
|
132
137
|
"update:config": (args_0: Readonly<{
|
|
133
138
|
fields: readonly ({
|
|
@@ -14,19 +14,13 @@ export type OverlayShellProps = Readonly<{
|
|
|
14
14
|
dismissible?: boolean;
|
|
15
15
|
}>;
|
|
16
16
|
export type OverlayBodyProps = Readonly<Record<string, unknown>>;
|
|
17
|
-
export type OverlaySectionReferenceInput = Readonly<{
|
|
18
|
-
id: string;
|
|
19
|
-
props?: Record<string, unknown>;
|
|
20
|
-
}>;
|
|
21
17
|
export type OverlaySessionInput = Readonly<{
|
|
22
18
|
shell?: Partial<OverlayShellProps>;
|
|
23
19
|
props?: Record<string, unknown>;
|
|
24
|
-
footer?: OverlaySectionReferenceInput;
|
|
25
20
|
}>;
|
|
26
21
|
export type OverlaySessionPatch = Readonly<{
|
|
27
22
|
shell?: Partial<OverlayShellProps>;
|
|
28
23
|
props?: Record<string, unknown>;
|
|
29
|
-
footer?: OverlaySectionReferenceInput | null;
|
|
30
24
|
}>;
|
|
31
25
|
export type OverlaySlotProps = Readonly<{
|
|
32
26
|
props: OverlayBodyProps;
|
|
@@ -51,10 +45,6 @@ type OverlaySession = {
|
|
|
51
45
|
definitionId: string;
|
|
52
46
|
shell: OverlayShellState;
|
|
53
47
|
props: Record<string, unknown>;
|
|
54
|
-
footer?: {
|
|
55
|
-
id: string;
|
|
56
|
-
props: Record<string, unknown>;
|
|
57
|
-
};
|
|
58
48
|
deferred: Deferred.Deferred<OverlayResult, never>;
|
|
59
49
|
};
|
|
60
50
|
export type OverlayHandle = Readonly<{
|
|
@@ -112,18 +112,6 @@ function createOverlayRuntime() {
|
|
|
112
112
|
...patch.props
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
|
-
if (Reflect.has(patch, "footer")) {
|
|
116
|
-
if (patch.footer === null || patch.footer === void 0) {
|
|
117
|
-
session.footer = void 0;
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
session.footer = {
|
|
121
|
-
id: patch.footer.id,
|
|
122
|
-
props: {
|
|
123
|
-
...patch.footer.props
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
115
|
}
|
|
128
116
|
function closeSync(sessionId, value) {
|
|
129
117
|
void Effect.runPromise(closeInternal(sessionId, value));
|
|
@@ -175,9 +163,6 @@ function createOverlayRuntime() {
|
|
|
175
163
|
if (!definition) {
|
|
176
164
|
return yield* Effect.fail(createDefinitionNotFoundError(definitionId));
|
|
177
165
|
}
|
|
178
|
-
if (options?.footer && !getDefinition(options.footer.id)) {
|
|
179
|
-
return yield* Effect.fail(createDefinitionNotFoundError(options.footer.id));
|
|
180
|
-
}
|
|
181
166
|
const buttonActionOption = yield* Effect.serviceOption(ButtonActionService);
|
|
182
167
|
const buttonAction = Option.match(buttonActionOption, {
|
|
183
168
|
onNone: () => void 0,
|
|
@@ -206,12 +191,6 @@ function createOverlayRuntime() {
|
|
|
206
191
|
props: {
|
|
207
192
|
...options?.props
|
|
208
193
|
},
|
|
209
|
-
footer: options?.footer ? {
|
|
210
|
-
id: options.footer.id,
|
|
211
|
-
props: {
|
|
212
|
-
...options.footer.props
|
|
213
|
-
}
|
|
214
|
-
} : void 0,
|
|
215
194
|
deferred
|
|
216
195
|
};
|
|
217
196
|
sessions.value.push(session);
|