@mouseless/baked 1.5.3 → 1.6.0
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/module.mjs +2 -1
- package/dist/runtime/components/AwaitLoading.d.ts +7 -4
- package/dist/runtime/components/AwaitLoading.js +39 -11
- package/dist/runtime/components/Bake.d.vue.ts +1 -3
- package/dist/runtime/components/Bake.vue +100 -59
- package/dist/runtime/components/Bake.vue.d.ts +1 -3
- package/dist/runtime/components/DataContainer.vue +4 -7
- package/dist/runtime/components/DataPanel.vue +5 -7
- package/dist/runtime/components/DataTable.vue +12 -3
- package/dist/runtime/components/ErrorPage.vue +6 -5
- package/dist/runtime/components/ErrorPopover.d.vue.ts +15 -0
- package/dist/runtime/components/ErrorPopover.vue +22 -0
- package/dist/runtime/components/ErrorPopover.vue.d.ts +15 -0
- package/dist/runtime/components/FormPage.vue +35 -8
- package/dist/runtime/components/InlineError.d.vue.ts +15 -0
- package/dist/runtime/components/InlineError.vue +27 -0
- package/dist/runtime/components/InlineError.vue.d.ts +15 -0
- package/dist/runtime/components/Input.vue +8 -1
- package/dist/runtime/components/InputNumber.vue +16 -16
- package/dist/runtime/components/InputText.vue +15 -15
- package/dist/runtime/components/Inputs.vue +17 -1
- package/dist/runtime/components/Labeler.d.vue.ts +9 -25
- package/dist/runtime/components/Labeler.vue +31 -21
- package/dist/runtime/components/Labeler.vue.d.ts +9 -25
- package/dist/runtime/components/Layout.vue +5 -1
- package/dist/runtime/components/LoadingError.d.vue.ts +13 -0
- package/dist/runtime/components/LoadingError.vue +27 -0
- package/dist/runtime/components/LoadingError.vue.d.ts +13 -0
- package/dist/runtime/components/Message.d.vue.ts +8 -1
- package/dist/runtime/components/Message.vue +48 -17
- package/dist/runtime/components/Message.vue.d.ts +8 -1
- package/dist/runtime/components/NavLink.vue +1 -1
- package/dist/runtime/components/Paginator.vue +1 -3
- package/dist/runtime/components/Select.vue +32 -31
- package/dist/runtime/components/SelectButton.vue +38 -32
- package/dist/runtime/components/SimpleForm.vue +45 -11
- package/dist/runtime/components/TabbedPage.vue +5 -7
- package/dist/runtime/components/Validation.d.vue.ts +16 -0
- package/dist/runtime/components/Validation.vue +33 -0
- package/dist/runtime/components/Validation.vue.d.ts +16 -0
- package/dist/runtime/composables/useBakeError.d.ts +13 -0
- package/dist/runtime/composables/useBakeError.js +51 -0
- package/dist/runtime/composables/useContext.d.ts +8 -0
- package/dist/runtime/composables/useContext.js +47 -2
- package/dist/runtime/composables/useDataMounter.d.ts +4 -2
- package/dist/runtime/composables/useDataMounter.js +15 -6
- package/dist/runtime/composables/useDefaultValidation.d.ts +4 -0
- package/dist/runtime/composables/useDefaultValidation.js +37 -0
- package/dist/runtime/composables/useValidation.d.ts +11 -0
- package/dist/runtime/composables/useValidation.js +48 -0
- package/dist/runtime/plugins/errorHandling.js +2 -2
- package/package.json +14 -14
|
@@ -5,33 +5,33 @@
|
|
|
5
5
|
<Skeleton class="min-h-10" />
|
|
6
6
|
</div>
|
|
7
7
|
</template>
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
:variant="labelVariant"
|
|
13
|
-
>
|
|
14
|
-
<Select
|
|
15
|
-
v-bind="$attrs"
|
|
16
|
-
v-model="selected"
|
|
17
|
-
:input-id="path"
|
|
18
|
-
:options="data"
|
|
19
|
-
:placeholder="l(label)"
|
|
20
|
-
:show-clear
|
|
21
|
-
:filter
|
|
22
|
-
:auto-filter-focus="filter"
|
|
23
|
-
:filter-fields="[optionLabel]"
|
|
24
|
-
reset-filter-on-hide
|
|
25
|
-
class="w-full"
|
|
8
|
+
<Validation>
|
|
9
|
+
<Labeler
|
|
10
|
+
:label
|
|
11
|
+
:path
|
|
26
12
|
>
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
13
|
+
<Select
|
|
14
|
+
v-bind="$attrs"
|
|
15
|
+
v-model="selected"
|
|
16
|
+
:input-id="path"
|
|
17
|
+
:options="data"
|
|
18
|
+
:placeholder
|
|
19
|
+
:show-clear
|
|
20
|
+
:filter
|
|
21
|
+
:auto-filter-focus="filter"
|
|
22
|
+
:filter-fields="[optionLabel]"
|
|
23
|
+
reset-filter-on-hide
|
|
24
|
+
class="w-full"
|
|
25
|
+
>
|
|
26
|
+
<template #value="slotProps">
|
|
27
|
+
<span>{{ getValueLabel(slotProps) }}</span>
|
|
28
|
+
</template>
|
|
29
|
+
<template #option="slotProps">
|
|
30
|
+
<span>{{ getOptionLabel(slotProps) }}</span>
|
|
31
|
+
</template>
|
|
32
|
+
</Select>
|
|
33
|
+
</Labeler>
|
|
34
|
+
</Validation>
|
|
35
35
|
</AwaitLoading>
|
|
36
36
|
</template>
|
|
37
37
|
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
import { ref, watch } from "vue";
|
|
40
40
|
import { Select, Skeleton } from "primevue";
|
|
41
41
|
import { useContext, useUiStates, useLocalization } from "#imports";
|
|
42
|
-
import { AwaitLoading, Labeler } from "#components";
|
|
42
|
+
import { AwaitLoading, Labeler, Validation } from "#components";
|
|
43
43
|
const context = useContext();
|
|
44
44
|
const { localize: l } = useLocalization();
|
|
45
45
|
const { value: { selectStates } } = useUiStates();
|
|
@@ -48,9 +48,10 @@ const { schema, data } = defineProps({
|
|
|
48
48
|
data: { type: null, required: true }
|
|
49
49
|
});
|
|
50
50
|
const model = defineModel({ type: null, required: true });
|
|
51
|
-
const { filter, label,
|
|
51
|
+
const { filter, label, localizeOptionLabels, optionLabel, optionValue, showClear, stateful, targetProp } = schema;
|
|
52
52
|
const path = context.injectPath();
|
|
53
53
|
const selected = ref();
|
|
54
|
+
const placeholder = label?.text ? l(label.text) : null;
|
|
54
55
|
watch(
|
|
55
56
|
[() => data, getModel],
|
|
56
57
|
([_data, _model]) => {
|
|
@@ -65,11 +66,11 @@ watch(
|
|
|
65
66
|
watch(selected, (newSelected) => setModel(newSelected));
|
|
66
67
|
function getOptionLabel(slotProps) {
|
|
67
68
|
const result = slotProps.option[optionLabel] ?? slotProps.option;
|
|
68
|
-
return
|
|
69
|
+
return localizeOptionLabels ? l(result) : result;
|
|
69
70
|
}
|
|
70
71
|
function getValueLabel(slotProps) {
|
|
71
|
-
const result = slotProps.value?.[optionLabel] ?? slotProps.value ??
|
|
72
|
-
return (
|
|
72
|
+
const result = slotProps.value?.[optionLabel] ?? slotProps.value ?? placeholder;
|
|
73
|
+
return (localizeOptionLabels ? l(result) : result) ?? "\xA0";
|
|
73
74
|
}
|
|
74
75
|
function getModel() {
|
|
75
76
|
return targetProp ? model.value?.[targetProp] : model.value;
|
|
@@ -5,35 +5,42 @@
|
|
|
5
5
|
<Skeleton class="min-h-10" />
|
|
6
6
|
</div>
|
|
7
7
|
</template>
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
<Validation>
|
|
9
|
+
<Labeler
|
|
10
|
+
:label="{
|
|
11
|
+
...label,
|
|
12
|
+
mode: label?.mode === 'ifta' ? label.mode : null,
|
|
13
|
+
text: label?.mode === 'ifta' ? label.text : null
|
|
14
|
+
}"
|
|
15
|
+
:path
|
|
16
|
+
:dt="{
|
|
17
|
+
colorScheme: {
|
|
18
|
+
light: {
|
|
19
|
+
top: '-1rem',
|
|
20
|
+
},
|
|
21
|
+
dark: {
|
|
22
|
+
top: '-1rem'
|
|
23
|
+
}
|
|
19
24
|
}
|
|
20
|
-
}
|
|
21
|
-
}"
|
|
22
|
-
>
|
|
23
|
-
<SelectButton
|
|
24
|
-
v-if="data"
|
|
25
|
-
v-model="selected"
|
|
26
|
-
:options="data"
|
|
27
|
-
:allow-empty
|
|
28
|
-
:data-key="optionValue"
|
|
29
|
-
:option-label
|
|
30
|
-
:pt="{ pcToggleButton: { root: { class: 'text-[length:inherit]' } } }"
|
|
25
|
+
}"
|
|
31
26
|
>
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
<SelectButton
|
|
28
|
+
v-if="data"
|
|
29
|
+
v-bind="$attrs"
|
|
30
|
+
v-model="selected"
|
|
31
|
+
:options="data"
|
|
32
|
+
:allow-empty
|
|
33
|
+
:data-key="optionValue"
|
|
34
|
+
:option-label
|
|
35
|
+
class="!w-auto"
|
|
36
|
+
pt:pc-toggle-button:root="text-[length:inherit]"
|
|
37
|
+
>
|
|
38
|
+
<template #option="slotProps">
|
|
39
|
+
<span>{{ getOptionLabel(slotProps) }}</span>
|
|
40
|
+
</template>
|
|
41
|
+
</SelectButton>
|
|
42
|
+
</Labeler>
|
|
43
|
+
</Validation>
|
|
37
44
|
</AwaitLoading>
|
|
38
45
|
</template>
|
|
39
46
|
|
|
@@ -41,7 +48,7 @@
|
|
|
41
48
|
import { ref, watch } from "vue";
|
|
42
49
|
import { SelectButton, Skeleton } from "primevue";
|
|
43
50
|
import { useContext, useLocalization, useUiStates } from "#imports";
|
|
44
|
-
import { AwaitLoading, Labeler } from "#components";
|
|
51
|
+
import { AwaitLoading, Labeler, Validation } from "#components";
|
|
45
52
|
const context = useContext();
|
|
46
53
|
const { localize: l } = useLocalization();
|
|
47
54
|
const { value: { selectButtonStates } } = useUiStates();
|
|
@@ -53,8 +60,7 @@ const model = defineModel({ type: null, required: true });
|
|
|
53
60
|
const {
|
|
54
61
|
allowEmpty = false,
|
|
55
62
|
label,
|
|
56
|
-
|
|
57
|
-
localizeLabel,
|
|
63
|
+
localizeOptionLabels,
|
|
58
64
|
optionLabel,
|
|
59
65
|
optionValue,
|
|
60
66
|
stateful,
|
|
@@ -76,7 +82,7 @@ watch(
|
|
|
76
82
|
watch(selected, (newSelected) => setModel(newSelected));
|
|
77
83
|
function getOptionLabel(slotProps) {
|
|
78
84
|
const result = slotProps.option[optionLabel] ?? slotProps.option;
|
|
79
|
-
return
|
|
85
|
+
return localizeOptionLabels ? l(result) : result;
|
|
80
86
|
}
|
|
81
87
|
function getModel() {
|
|
82
88
|
return targetProp ? model.value?.[targetProp] : model.value;
|
|
@@ -107,5 +113,5 @@ function setSelected(value) {
|
|
|
107
113
|
</style>
|
|
108
114
|
|
|
109
115
|
<style scoped>
|
|
110
|
-
|
|
116
|
+
.p-iftalabel:has(.p-selectbutton){@apply mt-4}
|
|
111
117
|
</style>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<template v-if="dialogOptions">
|
|
3
3
|
<Button
|
|
4
|
+
ref="submitRef"
|
|
4
5
|
:schema="dialogOptions.open"
|
|
5
6
|
v-bind="$attrs"
|
|
6
7
|
@click="visible = true"
|
|
@@ -47,6 +48,9 @@
|
|
|
47
48
|
/>
|
|
48
49
|
</template>
|
|
49
50
|
</Dialog>
|
|
51
|
+
<ErrorPopover ref="errorPopoverRef">
|
|
52
|
+
<InlineError :error />
|
|
53
|
+
</ErrorPopover>
|
|
50
54
|
</template>
|
|
51
55
|
<template v-else>
|
|
52
56
|
<div
|
|
@@ -66,43 +70,73 @@
|
|
|
66
70
|
/>
|
|
67
71
|
</div>
|
|
68
72
|
<Button
|
|
73
|
+
ref="submitRef"
|
|
74
|
+
v-tooltip.left="{
|
|
75
|
+
disabled: !showValidationSummary,
|
|
76
|
+
value: messages,
|
|
77
|
+
pt: { text: 'text-sm' }
|
|
78
|
+
}"
|
|
69
79
|
:schema="submit"
|
|
70
80
|
:ready
|
|
71
|
-
@submit="$emit('submit',
|
|
81
|
+
@submit="$emit('submit', model)"
|
|
72
82
|
/>
|
|
83
|
+
<ErrorPopover ref="errorPopoverRef">
|
|
84
|
+
<InlineError :error />
|
|
85
|
+
</ErrorPopover>
|
|
73
86
|
</div>
|
|
74
87
|
</template>
|
|
75
88
|
</template>
|
|
76
89
|
|
|
77
90
|
<script setup>
|
|
78
|
-
import { ref } from "vue";
|
|
91
|
+
import { computed, ref, watch } from "vue";
|
|
79
92
|
import { Dialog } from "primevue";
|
|
80
|
-
import { useLocalization } from "#imports";
|
|
81
|
-
import { Button, Inputs } from "#components";
|
|
93
|
+
import { useBakeError, useLocalization, useValidation } from "#imports";
|
|
94
|
+
import { Button, ErrorPopover, InlineError, Inputs } from "#components";
|
|
95
|
+
const { handle: handleError } = useBakeError();
|
|
82
96
|
const { localize: l } = useLocalization();
|
|
97
|
+
const { validate } = useValidation();
|
|
83
98
|
const { schema } = defineProps({
|
|
84
99
|
schema: { type: null, required: true }
|
|
85
100
|
});
|
|
86
101
|
const emit = defineEmits(["submit"]);
|
|
87
|
-
const { dialogOptions, inputs, submit, title } = schema;
|
|
88
|
-
const
|
|
89
|
-
const
|
|
102
|
+
const { dialogOptions, inputs, submit, title, validations = [], showValidationSummary = false } = schema;
|
|
103
|
+
const model = ref({});
|
|
104
|
+
const readyData = ref({});
|
|
90
105
|
const submitted = ref(false);
|
|
91
106
|
const visible = ref(false);
|
|
107
|
+
const submitRef = ref();
|
|
108
|
+
const errorPopoverRef = ref();
|
|
109
|
+
const { error } = handleError();
|
|
110
|
+
const ready = computed(() => Object.values(readyData.value).every((v) => v) && isValid.value);
|
|
111
|
+
const { isValid, messages } = validate({
|
|
112
|
+
inputs,
|
|
113
|
+
model,
|
|
114
|
+
composables: validations
|
|
115
|
+
});
|
|
116
|
+
watch(error, (newError) => {
|
|
117
|
+
if (newError) {
|
|
118
|
+
errorPopoverRef.value.show(submitRef);
|
|
119
|
+
} else {
|
|
120
|
+
errorPopoverRef.value.hide();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
92
123
|
function onReady(value) {
|
|
93
|
-
|
|
124
|
+
readyData.value = value;
|
|
94
125
|
}
|
|
95
126
|
function onChanged({ values }) {
|
|
96
|
-
|
|
127
|
+
model.value = values;
|
|
97
128
|
}
|
|
98
129
|
function execute() {
|
|
130
|
+
if (!ready.value) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
99
133
|
submitted.value = true;
|
|
100
134
|
visible.value = false;
|
|
101
135
|
}
|
|
102
136
|
function emitSubmit() {
|
|
103
|
-
if (submitted.value) {
|
|
137
|
+
if (submitted.value && ready.value) {
|
|
104
138
|
submitted.value = false;
|
|
105
|
-
emit("submit",
|
|
139
|
+
emit("submit", model.value);
|
|
106
140
|
}
|
|
107
141
|
}
|
|
108
142
|
</script>
|
|
@@ -40,11 +40,9 @@
|
|
|
40
40
|
</Bake>
|
|
41
41
|
<Message
|
|
42
42
|
v-if="showRequiredMessage"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<span class="ml-3">{{ lc("Select required values to view this page") }}</span>
|
|
47
|
-
</Message>
|
|
43
|
+
:schema="{ severity: 'info', icon: 'pi pi-info-circle' }"
|
|
44
|
+
:data="lc('Select required values to view this page')"
|
|
45
|
+
/>
|
|
48
46
|
<div
|
|
49
47
|
v-if="ready"
|
|
50
48
|
class="pt-4 flex flex-col gap-4 items-center"
|
|
@@ -70,9 +68,9 @@
|
|
|
70
68
|
|
|
71
69
|
<script setup>
|
|
72
70
|
import { computed, onBeforeUnmount, onMounted, reactive, ref } from "vue";
|
|
73
|
-
import {
|
|
71
|
+
import { Tab, TabList, Tabs } from "primevue";
|
|
74
72
|
import { useContext, useLocalization, useReactionHandler } from "#imports";
|
|
75
|
-
import { Bake, Contents, DeferredTabContent, Inputs } from "#components";
|
|
73
|
+
import { Bake, Contents, DeferredTabContent, Inputs, Message } from "#components";
|
|
76
74
|
const context = useContext();
|
|
77
75
|
const { localize: l } = useLocalization();
|
|
78
76
|
const { localize: lc } = useLocalization({ group: "TabbedPage" });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
4
|
+
type __VLS_WithSlots<T, S> = T & (new () => {
|
|
5
|
+
$slots: S;
|
|
6
|
+
});
|
|
7
|
+
declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
8
|
+
type __VLS_Slots = {
|
|
9
|
+
default?: ((props: {}) => any) | undefined;
|
|
10
|
+
} & {
|
|
11
|
+
default?: ((props: {}) => any) | undefined;
|
|
12
|
+
} & {
|
|
13
|
+
message?: ((props: {
|
|
14
|
+
validation: any;
|
|
15
|
+
}) => any) | undefined;
|
|
16
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<template v-if="!validation">
|
|
3
|
+
<slot />
|
|
4
|
+
</template>
|
|
5
|
+
<div
|
|
6
|
+
v-else
|
|
7
|
+
class="b-Validation flex flex-col gap-2"
|
|
8
|
+
>
|
|
9
|
+
<slot />
|
|
10
|
+
<slot
|
|
11
|
+
name="message"
|
|
12
|
+
:validation
|
|
13
|
+
>
|
|
14
|
+
<Message
|
|
15
|
+
v-if="validation.message && validation.persist"
|
|
16
|
+
:schema="{
|
|
17
|
+
severity: validation.severity,
|
|
18
|
+
variant: 'simple',
|
|
19
|
+
size: 'small'
|
|
20
|
+
}"
|
|
21
|
+
:data="validation.message || ''"
|
|
22
|
+
class="ml-3"
|
|
23
|
+
/>
|
|
24
|
+
</slot>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<script setup>
|
|
29
|
+
import { useContext } from "#imports";
|
|
30
|
+
import { Message } from "#components";
|
|
31
|
+
const context = useContext();
|
|
32
|
+
const validation = context.injectValidation();
|
|
33
|
+
</script>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
4
|
+
type __VLS_WithSlots<T, S> = T & (new () => {
|
|
5
|
+
$slots: S;
|
|
6
|
+
});
|
|
7
|
+
declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
8
|
+
type __VLS_Slots = {
|
|
9
|
+
default?: ((props: {}) => any) | undefined;
|
|
10
|
+
} & {
|
|
11
|
+
default?: ((props: {}) => any) | undefined;
|
|
12
|
+
} & {
|
|
13
|
+
message?: ((props: {
|
|
14
|
+
validation: any;
|
|
15
|
+
}) => any) | undefined;
|
|
16
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default function _default(): {
|
|
2
|
+
handle: () => {
|
|
3
|
+
error: import("vue").ComputedRef<{
|
|
4
|
+
title: any;
|
|
5
|
+
detail: any;
|
|
6
|
+
} | null>;
|
|
7
|
+
rawError: any;
|
|
8
|
+
};
|
|
9
|
+
normalize: (error: any) => import("vue").ComputedRef<{
|
|
10
|
+
title: any;
|
|
11
|
+
detail: any;
|
|
12
|
+
} | null>;
|
|
13
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { computed, unref } from "vue";
|
|
2
|
+
import { useContext } from "#imports";
|
|
3
|
+
|
|
4
|
+
export default function() {
|
|
5
|
+
const context = useContext();
|
|
6
|
+
|
|
7
|
+
function handle() {
|
|
8
|
+
const data = context.injectError({ handle: true });
|
|
9
|
+
|
|
10
|
+
return NormalizedError(data);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function normalize(error) {
|
|
14
|
+
return NormalizedError(error).error;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
handle,
|
|
19
|
+
normalize
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function NormalizedError(rawError) {
|
|
24
|
+
const error = computed(() => {
|
|
25
|
+
const e = unref(rawError);
|
|
26
|
+
if(!e) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if(e.name === "FetchError") {
|
|
31
|
+
const messages = e.data?.errors
|
|
32
|
+
? Object.values(e.data.errors).flat().join(" ")
|
|
33
|
+
: null;
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
title: e.data?.title ?? e.statusCode ?? "ERROR",
|
|
37
|
+
detail: messages ?? e.data?.detail ?? e.message ?? e.cause ?? "An error occured."
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
title: e.statusCode ?? e.status ?? "ERROR",
|
|
43
|
+
detail: e.message ?? e.cause ?? "An error occured."
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
error,
|
|
49
|
+
rawError
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -7,6 +7,10 @@ export default function _default(): {
|
|
|
7
7
|
};
|
|
8
8
|
injectDataDescriptor: () => null;
|
|
9
9
|
provideDataDescriptor: (value: any) => void;
|
|
10
|
+
injectError: ({ handle }?: {
|
|
11
|
+
handle?: boolean | undefined;
|
|
12
|
+
}) => import("vue").Ref<{}, {}>;
|
|
13
|
+
provideError: (error: any) => import("vue").Ref<boolean, boolean>;
|
|
10
14
|
injectEvents: () => any;
|
|
11
15
|
provideEvents: (value: any) => void;
|
|
12
16
|
injectExecuting: () => import("vue").Ref<boolean, boolean>;
|
|
@@ -17,4 +21,8 @@ export default function _default(): {
|
|
|
17
21
|
providePageContext: (value: any) => void;
|
|
18
22
|
injectParentContext: () => null;
|
|
19
23
|
provideParentContext: (value: any) => void;
|
|
24
|
+
injectValidations: () => import("vue").Ref<{}, {}>;
|
|
25
|
+
provideValidations: (value: any) => void;
|
|
26
|
+
injectValidation: () => null;
|
|
27
|
+
provideValidation: (value: any) => void;
|
|
20
28
|
};
|
|
@@ -24,6 +24,29 @@ export default function() {
|
|
|
24
24
|
return provide("__bake_data_descriptor", value);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
function injectError({ handle = false } = {}) {
|
|
28
|
+
const { error, handled } = inject("__bake_error", {
|
|
29
|
+
error: ref({}),
|
|
30
|
+
handled: ref(false)
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if(handle) {
|
|
34
|
+
handled.value = true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return error;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function provideError(error) {
|
|
41
|
+
const handled = ref(false);
|
|
42
|
+
provide("__bake_error", {
|
|
43
|
+
error,
|
|
44
|
+
handled
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return handled;
|
|
48
|
+
}
|
|
49
|
+
|
|
27
50
|
function injectEvents() {
|
|
28
51
|
return inject("__bake_events");
|
|
29
52
|
}
|
|
@@ -64,12 +87,30 @@ export default function() {
|
|
|
64
87
|
provide("__bake_parent_context", value);
|
|
65
88
|
}
|
|
66
89
|
|
|
90
|
+
function injectValidations() {
|
|
91
|
+
return inject("__bake_validations", ref({}));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function provideValidations(value) {
|
|
95
|
+
provide("__bake_validations", value);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function injectValidation() {
|
|
99
|
+
return inject("__bake_validation", null);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function provideValidation(value) {
|
|
103
|
+
provide("__bake_validation", value);
|
|
104
|
+
}
|
|
105
|
+
|
|
67
106
|
return {
|
|
68
107
|
injectPath,
|
|
69
108
|
providePath,
|
|
70
109
|
injectContextData,
|
|
71
110
|
injectDataDescriptor,
|
|
72
111
|
provideDataDescriptor,
|
|
112
|
+
injectError,
|
|
113
|
+
provideError,
|
|
73
114
|
injectEvents,
|
|
74
115
|
provideEvents,
|
|
75
116
|
injectExecuting,
|
|
@@ -79,6 +120,10 @@ export default function() {
|
|
|
79
120
|
injectPageContext,
|
|
80
121
|
providePageContext,
|
|
81
122
|
injectParentContext,
|
|
82
|
-
provideParentContext
|
|
123
|
+
provideParentContext,
|
|
124
|
+
injectValidations,
|
|
125
|
+
provideValidations,
|
|
126
|
+
injectValidation,
|
|
127
|
+
provideValidation
|
|
83
128
|
};
|
|
84
|
-
}
|
|
129
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export default function _default(): {
|
|
2
|
-
mount: (schema: any
|
|
1
|
+
export default function _default({ defaultInlineError }?: {}): {
|
|
2
|
+
mount: (schema: any, { inlineError }?: {
|
|
3
|
+
inlineError?: any;
|
|
4
|
+
}) => import("vue").Ref<null, null>;
|
|
3
5
|
onAfterMount: (callback: any) => void;
|
|
4
6
|
onBeforeMount: (callback: any) => void;
|
|
5
7
|
};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { onMounted, ref } from "vue";
|
|
2
2
|
import { useContext, useDataFetcher } from "#imports";
|
|
3
3
|
|
|
4
|
-
export default function() {
|
|
4
|
+
export default function({ defaultInlineError } = {}) {
|
|
5
5
|
const context = useContext();
|
|
6
6
|
const dataFetcher = useDataFetcher();
|
|
7
|
+
|
|
7
8
|
const contextData = context.injectContextData();
|
|
9
|
+
const error = context.injectError();
|
|
10
|
+
|
|
8
11
|
const mounts = [];
|
|
9
12
|
let onAfterMountCallback = null;
|
|
10
13
|
let onBeforeMountCallback = null;
|
|
@@ -15,8 +18,14 @@ export default function() {
|
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
await Promise.all(
|
|
18
|
-
mounts.map(async({ value, schema }) => {
|
|
19
|
-
|
|
21
|
+
mounts.map(async({ value, schema, inlineError }) => {
|
|
22
|
+
try {
|
|
23
|
+
value.value = await dataFetcher.fetch({ data: schema, contextData });
|
|
24
|
+
} catch (err) {
|
|
25
|
+
if(!inlineError || err.statusCode !== 400) { throw err; }
|
|
26
|
+
|
|
27
|
+
error.value = err;
|
|
28
|
+
}
|
|
20
29
|
})
|
|
21
30
|
);
|
|
22
31
|
|
|
@@ -25,7 +34,7 @@ export default function() {
|
|
|
25
34
|
}
|
|
26
35
|
});
|
|
27
36
|
|
|
28
|
-
function mount(schema) {
|
|
37
|
+
function mount(schema, { inlineError = defaultInlineError } = {}) {
|
|
29
38
|
const value = ref(null);
|
|
30
39
|
|
|
31
40
|
if(!schema) {
|
|
@@ -36,7 +45,7 @@ export default function() {
|
|
|
36
45
|
|
|
37
46
|
const shouldLoad = dataFetcher.shouldLoad(schema);
|
|
38
47
|
if(shouldLoad) {
|
|
39
|
-
mounts.push({ value, schema });
|
|
48
|
+
mounts.push({ value, schema, inlineError });
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
return value;
|
|
@@ -55,4 +64,4 @@ export default function() {
|
|
|
55
64
|
onAfterMount,
|
|
56
65
|
onBeforeMount
|
|
57
66
|
};
|
|
58
|
-
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useLocalization } from "#imports";
|
|
2
|
+
|
|
3
|
+
const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1);
|
|
4
|
+
|
|
5
|
+
export default function useDefaultValidation({ inputs, model }) {
|
|
6
|
+
const { localize: lc } = useLocalization({ group: "useDefaultValidation" });
|
|
7
|
+
const { localize: l } = useLocalization();
|
|
8
|
+
|
|
9
|
+
const result = {};
|
|
10
|
+
const validation = {
|
|
11
|
+
valid: false,
|
|
12
|
+
persist: false,
|
|
13
|
+
severity: "error",
|
|
14
|
+
message: ""
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
inputs.map(input => {
|
|
18
|
+
const value = model?.[input.name];
|
|
19
|
+
const isEmpty = value === undefined || value === null || String(value).trim() === "";
|
|
20
|
+
const label = input.component?.schema?.label?.text || capitalize(input.name);
|
|
21
|
+
|
|
22
|
+
result[input.name] = {
|
|
23
|
+
...validation,
|
|
24
|
+
required: !!input.required,
|
|
25
|
+
valid: !input.required || !isEmpty,
|
|
26
|
+
persist: !(input.required && isEmpty)
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
if(input.required && isEmpty) {
|
|
30
|
+
result[input.name].message = lc("{label} cannot be empty", { label: l(label) });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return input;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export default function _default(): {
|
|
2
|
+
validate: ({ model, inputs, composables }: {
|
|
3
|
+
model: any;
|
|
4
|
+
inputs: any;
|
|
5
|
+
composables?: never[] | undefined;
|
|
6
|
+
}) => {
|
|
7
|
+
isValid: import("vue").ComputedRef<boolean>;
|
|
8
|
+
messages: import("vue").ComputedRef<string>;
|
|
9
|
+
validations: import("vue").ComputedRef<any>;
|
|
10
|
+
};
|
|
11
|
+
};
|