@mouseless/baked 1.6.0 → 1.6.2
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/Bake.vue +1 -1
- package/dist/runtime/components/Button.vue +2 -1
- package/dist/runtime/components/DataContainer.vue +31 -14
- package/dist/runtime/components/FormPage.vue +1 -0
- package/dist/runtime/components/Input.d.vue.ts +9 -1
- package/dist/runtime/components/Input.vue +25 -6
- package/dist/runtime/components/Input.vue.d.ts +9 -1
- package/dist/runtime/components/InputNumber.vue +7 -7
- package/dist/runtime/components/InputText.vue +7 -7
- package/dist/runtime/components/Inputs.d.vue.ts +7 -0
- package/dist/runtime/components/Inputs.vue +5 -19
- package/dist/runtime/components/Inputs.vue.d.ts +7 -0
- package/dist/runtime/components/Labeler.vue +1 -4
- package/dist/runtime/components/Message.vue +17 -4
- package/dist/runtime/components/NavLink.vue +5 -2
- package/dist/runtime/components/Select.vue +8 -9
- package/dist/runtime/components/SelectButton.vue +8 -8
- package/dist/runtime/components/SimpleForm.vue +26 -19
- package/dist/runtime/components/Validation.d.vue.ts +1 -0
- package/dist/runtime/components/Validation.vue +24 -5
- package/dist/runtime/components/Validation.vue.d.ts +1 -0
- package/dist/runtime/composables/useContext.d.ts +7 -1
- package/dist/runtime/composables/useContext.js +32 -2
- package/dist/runtime/composables/useReactionHandler.js +2 -1
- package/dist/runtime/composables/useRedirect.d.ts +1 -1
- package/dist/runtime/composables/useRedirect.js +7 -1
- package/dist/runtime/composables/useValidation.d.ts +8 -0
- package/dist/runtime/composables/useValidation.js +42 -4
- package/package.json +3 -2
package/dist/module.json
CHANGED
|
@@ -73,7 +73,7 @@ const errorHandled = context.provideError(rawError);
|
|
|
73
73
|
const error = normalizeError(rawError);
|
|
74
74
|
context.providePath(path);
|
|
75
75
|
context.provideDataDescriptor(descriptor.data);
|
|
76
|
-
context.provideParentContext({ ...contextData.parent, data });
|
|
76
|
+
context.provideParentContext({ ...contextData.parent, data, grand: contextData.parent });
|
|
77
77
|
if (shouldLoad) {
|
|
78
78
|
context.provideLoading(loading);
|
|
79
79
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
:label="l(label)"
|
|
7
7
|
:rounded
|
|
8
8
|
:severity
|
|
9
|
+
:size
|
|
9
10
|
:variant
|
|
10
11
|
@click="$emit('submit')"
|
|
11
12
|
/>
|
|
@@ -21,6 +22,6 @@ const { schema } = defineProps({
|
|
|
21
22
|
ready: { type: Boolean, default: true }
|
|
22
23
|
});
|
|
23
24
|
defineEmits(["submit"]);
|
|
24
|
-
const { icon, label, rounded, severity = "secondary", variant } = schema;
|
|
25
|
+
const { icon, label, rounded, severity = "secondary", size, variant } = schema;
|
|
25
26
|
const executing = context.injectExecuting();
|
|
26
27
|
</script>
|
|
@@ -7,19 +7,36 @@
|
|
|
7
7
|
"
|
|
8
8
|
>
|
|
9
9
|
<div
|
|
10
|
-
v-if="
|
|
11
|
-
class="
|
|
12
|
-
py-2 px-4
|
|
13
|
-
bg-transparent
|
|
14
|
-
rounded-none text-sm
|
|
15
|
-
flex gap-2 items-center justify-end
|
|
16
|
-
"
|
|
10
|
+
v-if="actions.length || inputs.length"
|
|
11
|
+
class="w-full flex justify-between py-2 px-4"
|
|
17
12
|
>
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
<div
|
|
14
|
+
class="
|
|
15
|
+
min-w-min flex gap-2 row-span-2 items-end text-nowrap
|
|
16
|
+
max-xs:text-xs max-md:text-sm
|
|
17
|
+
md:max-md:items-center
|
|
18
|
+
"
|
|
19
|
+
>
|
|
20
|
+
<Bake
|
|
21
|
+
v-for="action in actions"
|
|
22
|
+
:key="action.schema.name"
|
|
23
|
+
:name="`actions/${action.schema.name}`"
|
|
24
|
+
:descriptor="action"
|
|
25
|
+
/>
|
|
26
|
+
</div>
|
|
27
|
+
<div
|
|
28
|
+
class="
|
|
29
|
+
bg-transparent
|
|
30
|
+
rounded-none text-sm
|
|
31
|
+
flex gap-2 items-center justify-end
|
|
32
|
+
"
|
|
33
|
+
>
|
|
34
|
+
<Inputs
|
|
35
|
+
:inputs="inputs"
|
|
36
|
+
@ready="onReady"
|
|
37
|
+
@changed="onChanged"
|
|
38
|
+
/>
|
|
39
|
+
</div>
|
|
23
40
|
</div>
|
|
24
41
|
<div
|
|
25
42
|
class="p-4 [contain:inline-size]"
|
|
@@ -49,7 +66,7 @@ const { localize: lc } = useLocalization({ group: "DataContainer" });
|
|
|
49
66
|
const { schema } = defineProps({
|
|
50
67
|
schema: { type: null, required: true }
|
|
51
68
|
});
|
|
52
|
-
const { content, inputs } = schema;
|
|
69
|
+
const { actions = [], content, inputs } = schema;
|
|
53
70
|
const contextData = context.injectContextData();
|
|
54
71
|
const loaded = ref(true);
|
|
55
72
|
const ready = ref(inputs.length === 0);
|
|
@@ -68,5 +85,5 @@ function onChanged(event) {
|
|
|
68
85
|
</script>
|
|
69
86
|
|
|
70
87
|
<style>
|
|
71
|
-
.p-panel-content:has(.b-component--DataContainer) .b-component--DataContainer{@apply border-none rounded-none}.b-component--DataContainer div{@apply [&:has(.p-datatable)]:p-0}
|
|
88
|
+
.p-panel-content:has(.b-component--DataContainer) .b-component--DataContainer{@apply border-none rounded-none}.b-component--DataContainer div{@apply [&:has(.p-datatable)]:p-0}.b-component--DataContainer .p-button{@apply self-stretch}.b-component--DataContainer .p-button .p-button-icon+.p-button-label{@apply max-sm:hidden}
|
|
72
89
|
</style>
|
|
@@ -5,6 +5,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
5
5
|
type: ObjectConstructor;
|
|
6
6
|
required: true;
|
|
7
7
|
};
|
|
8
|
+
formMode: {
|
|
9
|
+
type: BooleanConstructor;
|
|
10
|
+
};
|
|
8
11
|
modelValue: {
|
|
9
12
|
type: import("vue").PropType<any>;
|
|
10
13
|
required: true;
|
|
@@ -16,10 +19,15 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
16
19
|
type: ObjectConstructor;
|
|
17
20
|
required: true;
|
|
18
21
|
};
|
|
22
|
+
formMode: {
|
|
23
|
+
type: BooleanConstructor;
|
|
24
|
+
};
|
|
19
25
|
modelValue: {
|
|
20
26
|
type: import("vue").PropType<any>;
|
|
21
27
|
required: true;
|
|
22
28
|
};
|
|
23
29
|
}>> & Readonly<{
|
|
24
30
|
"onUpdate:modelValue"?: ((value: any) => any) | undefined;
|
|
25
|
-
}>, {
|
|
31
|
+
}>, {
|
|
32
|
+
formMode: boolean;
|
|
33
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
v-model="model"
|
|
4
4
|
:name="schema.name"
|
|
5
5
|
:descriptor="schema.component"
|
|
6
|
+
:invalid
|
|
7
|
+
@blur="onBlur"
|
|
6
8
|
/>
|
|
7
9
|
</template>
|
|
8
10
|
|
|
9
11
|
<script setup>
|
|
10
|
-
import { computed, watch } from "vue";
|
|
12
|
+
import { computed, ref, watch } from "vue";
|
|
11
13
|
import { useRoute, useRouter } from "#app";
|
|
12
14
|
import { useDataMounter, useContext } from "#imports";
|
|
13
15
|
import { Bake } from "#components";
|
|
@@ -15,15 +17,32 @@ const context = useContext();
|
|
|
15
17
|
const { mount: mountData, onAfterMount: onAfterMountData } = useDataMounter();
|
|
16
18
|
const route = useRoute();
|
|
17
19
|
const router = useRouter();
|
|
18
|
-
const { schema } = defineProps({
|
|
19
|
-
schema: { type: Object, required: true }
|
|
20
|
+
const { schema, formMode } = defineProps({
|
|
21
|
+
schema: { type: Object, required: true },
|
|
22
|
+
formMode: { type: Boolean }
|
|
20
23
|
});
|
|
21
24
|
const model = defineModel({ type: null, required: true });
|
|
22
25
|
const validations = context.injectValidations();
|
|
26
|
+
const mutableValidations = context.injectMutableValidations();
|
|
23
27
|
const defaultValue = mountData(schema.default);
|
|
24
28
|
const query = schema.queryBound ? computed(() => route.query[schema.name]) : void 0;
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
let validation = void 0;
|
|
30
|
+
let mutableValidation = void 0;
|
|
31
|
+
let touched = void 0;
|
|
32
|
+
let invalidInForm = void 0;
|
|
33
|
+
let invalid = void 0;
|
|
34
|
+
let onBlur = void 0;
|
|
35
|
+
if (validations) {
|
|
36
|
+
validation = computed(() => validations.value[schema.name]);
|
|
37
|
+
mutableValidation = ref({ valid: true });
|
|
38
|
+
touched = ref(false);
|
|
39
|
+
invalidInForm = computed(() => !validation.value?.valid && (validation.value?.persist || touched.value));
|
|
40
|
+
invalid = computed(() => !mutableValidation.value.valid || invalidInForm.value);
|
|
41
|
+
onBlur = () => touched.value = true;
|
|
42
|
+
mutableValidations[schema.name] = mutableValidation;
|
|
43
|
+
context.provideValidation(validation);
|
|
44
|
+
context.provideMutableValidation(mutableValidation);
|
|
45
|
+
}
|
|
27
46
|
onAfterMountData(async () => {
|
|
28
47
|
if (!checkValue(model.value)) {
|
|
29
48
|
if (schema.queryBound && checkValue(query.value)) {
|
|
@@ -43,7 +62,7 @@ onAfterMountData(async () => {
|
|
|
43
62
|
}, { immediate: true });
|
|
44
63
|
}
|
|
45
64
|
watch(model, async (newValue) => {
|
|
46
|
-
if (!checkValue(newValue)) {
|
|
65
|
+
if (!checkValue(newValue) && !formMode) {
|
|
47
66
|
newValue = schema.required ? defaultValue.value : void 0;
|
|
48
67
|
}
|
|
49
68
|
await set(newValue);
|
|
@@ -5,6 +5,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
5
5
|
type: ObjectConstructor;
|
|
6
6
|
required: true;
|
|
7
7
|
};
|
|
8
|
+
formMode: {
|
|
9
|
+
type: BooleanConstructor;
|
|
10
|
+
};
|
|
8
11
|
modelValue: {
|
|
9
12
|
type: import("vue").PropType<any>;
|
|
10
13
|
required: true;
|
|
@@ -16,10 +19,15 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
16
19
|
type: ObjectConstructor;
|
|
17
20
|
required: true;
|
|
18
21
|
};
|
|
22
|
+
formMode: {
|
|
23
|
+
type: BooleanConstructor;
|
|
24
|
+
};
|
|
19
25
|
modelValue: {
|
|
20
26
|
type: import("vue").PropType<any>;
|
|
21
27
|
required: true;
|
|
22
28
|
};
|
|
23
29
|
}>> & Readonly<{
|
|
24
30
|
"onUpdate:modelValue"?: ((value: any) => any) | undefined;
|
|
25
|
-
}>, {
|
|
31
|
+
}>, {
|
|
32
|
+
formMode: boolean;
|
|
33
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<AwaitLoading
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
<AwaitLoading
|
|
3
|
+
:skeleton="{
|
|
4
|
+
height: label?.mode === 'ifta' ? '3.6rem' : '2.6rem',
|
|
5
|
+
class: 'min-w-60'
|
|
6
|
+
}"
|
|
7
|
+
>
|
|
8
8
|
<Validation>
|
|
9
9
|
<Labeler
|
|
10
10
|
:label
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
</template>
|
|
24
24
|
|
|
25
25
|
<script setup>
|
|
26
|
-
import { InputNumber
|
|
26
|
+
import { InputNumber } from "primevue";
|
|
27
27
|
import { useContext } from "#imports";
|
|
28
28
|
import { AwaitLoading, Labeler, Validation } from "#components";
|
|
29
29
|
const context = useContext();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<AwaitLoading
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
<AwaitLoading
|
|
3
|
+
:skeleton="{
|
|
4
|
+
height: label?.mode === 'ifta' ? '3.6rem' : '2.6rem',
|
|
5
|
+
class: 'min-w-60'
|
|
6
|
+
}"
|
|
7
|
+
>
|
|
8
8
|
<Validation>
|
|
9
9
|
<Labeler
|
|
10
10
|
:label
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
<script setup>
|
|
25
25
|
import { ref, watch } from "vue";
|
|
26
|
-
import { InputText
|
|
26
|
+
import { InputText } from "primevue";
|
|
27
27
|
import { useContext } from "#imports";
|
|
28
28
|
import { AwaitLoading, Labeler, Validation } from "#components";
|
|
29
29
|
const context = useContext();
|
|
@@ -5,6 +5,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
5
5
|
type: ArrayConstructor;
|
|
6
6
|
required: true;
|
|
7
7
|
};
|
|
8
|
+
formMode: {
|
|
9
|
+
type: BooleanConstructor;
|
|
10
|
+
};
|
|
8
11
|
inputClass: {
|
|
9
12
|
type: StringConstructor;
|
|
10
13
|
default: string;
|
|
@@ -17,6 +20,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
17
20
|
type: ArrayConstructor;
|
|
18
21
|
required: true;
|
|
19
22
|
};
|
|
23
|
+
formMode: {
|
|
24
|
+
type: BooleanConstructor;
|
|
25
|
+
};
|
|
20
26
|
inputClass: {
|
|
21
27
|
type: StringConstructor;
|
|
22
28
|
default: string;
|
|
@@ -25,5 +31,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
25
31
|
onReady?: ((...args: any[]) => any) | undefined;
|
|
26
32
|
onChanged?: ((...args: any[]) => any) | undefined;
|
|
27
33
|
}>, {
|
|
34
|
+
formMode: boolean;
|
|
28
35
|
inputClass: string;
|
|
29
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -4,26 +4,24 @@
|
|
|
4
4
|
:key="input.name"
|
|
5
5
|
v-model="models[input.name]"
|
|
6
6
|
:schema="input"
|
|
7
|
+
:form-mode
|
|
7
8
|
:class="inputClass"
|
|
8
|
-
:invalid="invalid(input.name)"
|
|
9
|
-
@blur="() => touched(input.name)"
|
|
10
9
|
/>
|
|
11
10
|
</template>
|
|
12
11
|
|
|
13
12
|
<script setup>
|
|
14
|
-
import { computed, reactive,
|
|
13
|
+
import { computed, reactive, watch } from "vue";
|
|
15
14
|
import { useContext, useRoute } from "#imports";
|
|
16
15
|
import { Input } from "#components";
|
|
17
16
|
const context = useContext();
|
|
18
17
|
const route = useRoute();
|
|
19
|
-
const { inputs } = defineProps({
|
|
18
|
+
const { inputs, formMode } = defineProps({
|
|
20
19
|
inputs: { type: Array, required: true },
|
|
20
|
+
formMode: { type: Boolean },
|
|
21
21
|
inputClass: { type: String, default: "" }
|
|
22
22
|
});
|
|
23
23
|
const emit = defineEmits(["ready", "changed"]);
|
|
24
24
|
const parentPath = context.injectPath();
|
|
25
|
-
const validations = context.injectValidations();
|
|
26
|
-
const inputEvents = ref({});
|
|
27
25
|
const models = reactive({});
|
|
28
26
|
const values = computed(
|
|
29
27
|
() => inputs.reduce((result, input) => {
|
|
@@ -33,7 +31,7 @@ const values = computed(
|
|
|
33
31
|
);
|
|
34
32
|
context.providePath(`${parentPath}/inputs`);
|
|
35
33
|
watch(values, (newValues) => {
|
|
36
|
-
if (inputs.filter((i) => i.default || i.defaultSelfManaged).some((i) => !checkValue(newValues[i.name]))) {
|
|
34
|
+
if (!formMode && inputs.filter((i) => i.default || i.defaultSelfManaged).some((i) => !checkValue(newValues[i.name]))) {
|
|
37
35
|
return;
|
|
38
36
|
}
|
|
39
37
|
emitChanged();
|
|
@@ -64,16 +62,4 @@ function getValue(input) {
|
|
|
64
62
|
return models[input.name];
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
|
-
function touched(key) {
|
|
68
|
-
inputEvents.value[key] = { touched: true };
|
|
69
|
-
}
|
|
70
|
-
function invalid(input) {
|
|
71
|
-
if (!Object.values(validations.value).length) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
if (!validations.value[input]?.valid && validations.value[input]?.persist) {
|
|
75
|
-
return true;
|
|
76
|
-
}
|
|
77
|
-
return !validations.value[input]?.valid && inputEvents.value[input]?.touched || false;
|
|
78
|
-
}
|
|
79
65
|
</script>
|
|
@@ -5,6 +5,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
5
5
|
type: ArrayConstructor;
|
|
6
6
|
required: true;
|
|
7
7
|
};
|
|
8
|
+
formMode: {
|
|
9
|
+
type: BooleanConstructor;
|
|
10
|
+
};
|
|
8
11
|
inputClass: {
|
|
9
12
|
type: StringConstructor;
|
|
10
13
|
default: string;
|
|
@@ -17,6 +20,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
17
20
|
type: ArrayConstructor;
|
|
18
21
|
required: true;
|
|
19
22
|
};
|
|
23
|
+
formMode: {
|
|
24
|
+
type: BooleanConstructor;
|
|
25
|
+
};
|
|
20
26
|
inputClass: {
|
|
21
27
|
type: StringConstructor;
|
|
22
28
|
default: string;
|
|
@@ -25,5 +31,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
25
31
|
onReady?: ((...args: any[]) => any) | undefined;
|
|
26
32
|
onChanged?: ((...args: any[]) => any) | undefined;
|
|
27
33
|
}>, {
|
|
34
|
+
formMode: boolean;
|
|
28
35
|
inputClass: string;
|
|
29
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
class="
|
|
3
|
+
class="
|
|
4
|
+
b-message
|
|
5
|
+
grid grid-cols-[1fr_auto] gap-2
|
|
6
|
+
items-center
|
|
7
|
+
"
|
|
4
8
|
:class="[`message-${severity}`, `message-${variant}`]"
|
|
5
9
|
>
|
|
6
10
|
<div class="min-h-0">
|
|
@@ -25,18 +29,27 @@
|
|
|
25
29
|
<slot name="content" />
|
|
26
30
|
</div>
|
|
27
31
|
</div>
|
|
32
|
+
<div
|
|
33
|
+
v-if="action"
|
|
34
|
+
class="b-message-action px-2"
|
|
35
|
+
>
|
|
36
|
+
<Bake
|
|
37
|
+
name="action"
|
|
38
|
+
:descriptor="{ ...action, schema: { ...action.schema, severity } }"
|
|
39
|
+
/>
|
|
40
|
+
</div>
|
|
28
41
|
</div>
|
|
29
42
|
</template>
|
|
30
43
|
|
|
31
44
|
<script setup>
|
|
32
45
|
import { computed, useLocalization } from "#imports";
|
|
33
|
-
import { AwaitLoading } from "#components";
|
|
46
|
+
import { AwaitLoading, Bake } from "#components";
|
|
34
47
|
const { localize: l } = useLocalization();
|
|
35
48
|
const { schema, data } = defineProps({
|
|
36
49
|
schema: { type: null, required: true },
|
|
37
50
|
data: { type: null, required: true }
|
|
38
51
|
});
|
|
39
|
-
const { icon, localizeMessage, severity = "info", size, variant = "outlined" } = schema;
|
|
52
|
+
const { action, icon, localizeMessage, severity = "info", size, variant = "outlined" } = schema;
|
|
40
53
|
const sizeClass = computed(() => {
|
|
41
54
|
switch (size) {
|
|
42
55
|
case "small":
|
|
@@ -50,7 +63,7 @@ const sizeClass = computed(() => {
|
|
|
50
63
|
</script>
|
|
51
64
|
|
|
52
65
|
<style scoped>
|
|
53
|
-
.message-outlined{@apply border rounded-md}.message-outlined .b-message-body{@apply py-[0.50rem] px-[0.75rem] min-w-[10rem] min-h-[1.5rem]}.message-simple{@apply !bg-transparent}.message-simple .b-message-body{@apply px-0}.message-info{@apply bg-blue-50/95 text-blue-600 border-blue-200
|
|
66
|
+
.message-outlined{@apply border rounded-md}.message-outlined .b-message-body{@apply py-[0.50rem] px-[0.75rem] min-w-[10rem] min-h-[1.5rem]}.message-simple{@apply !bg-transparent}.message-simple .b-message-icon{@apply text-sm}.message-simple .b-message-body{@apply px-0}.message-info{@apply bg-blue-50/95 text-blue-600 border-blue-200
|
|
54
67
|
dark:bg-blue-950/95 dark:text-blue-500 dark:border-blue-700/65}.message-error{@apply bg-red-50/95 text-red-600 border-red-200
|
|
55
68
|
dark:bg-red-950/95 dark:text-red-500 dark:border-red-700/65}.message-warn{@apply bg-yellow-50/95 text-yellow-600 border-yellow-200
|
|
56
69
|
dark:bg-yellow-950/95 dark:text-yellow-500 dark:border-yellow-700/65}.message-success{@apply bg-green-50/95 text-green-600 border-green-200
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<AwaitLoading :skeleton="{ height: '1.5rem' }">
|
|
3
3
|
<Button
|
|
4
|
+
v-if="data"
|
|
4
5
|
:icon
|
|
5
|
-
:label
|
|
6
|
+
:label
|
|
6
7
|
:to
|
|
7
8
|
as="router-link"
|
|
8
9
|
link
|
|
9
10
|
class="m-0 p-0"
|
|
10
11
|
/>
|
|
12
|
+
<span v-else>-</span>
|
|
11
13
|
</AwaitLoading>
|
|
12
14
|
</template>
|
|
13
15
|
|
|
@@ -22,9 +24,10 @@ const { schema, data } = defineProps({
|
|
|
22
24
|
schema: { type: null, required: true },
|
|
23
25
|
data: { type: null, required: true }
|
|
24
26
|
});
|
|
25
|
-
const { icon, path, query: queryData, params: paramsData } = schema;
|
|
27
|
+
const { icon, labelProp, path, query: queryData, params: paramsData } = schema;
|
|
26
28
|
const query = mountData(queryData);
|
|
27
29
|
const params = mountData(paramsData);
|
|
30
|
+
const label = computed(() => labelProp ? data?.[labelProp] : data);
|
|
28
31
|
const to = computed(() => ({
|
|
29
32
|
path: params.value ? pathBuilder.build(path, params.value, { forRoute: true }) : path,
|
|
30
33
|
query: query.value
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<AwaitLoading
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
<AwaitLoading
|
|
3
|
+
:skeleton="{
|
|
4
|
+
height: label?.mode === 'ifta' ? '3.6rem' : '2.6rem',
|
|
5
|
+
class: 'min-w-40'
|
|
6
|
+
}"
|
|
7
|
+
>
|
|
8
8
|
<Validation>
|
|
9
9
|
<Labeler
|
|
10
10
|
:label
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
:auto-filter-focus="filter"
|
|
22
22
|
:filter-fields="[optionLabel]"
|
|
23
23
|
reset-filter-on-hide
|
|
24
|
-
class="w-full"
|
|
25
24
|
>
|
|
26
25
|
<template #value="slotProps">
|
|
27
26
|
<span>{{ getValueLabel(slotProps) }}</span>
|
|
@@ -37,7 +36,7 @@
|
|
|
37
36
|
|
|
38
37
|
<script setup>
|
|
39
38
|
import { ref, watch } from "vue";
|
|
40
|
-
import { Select
|
|
39
|
+
import { Select } from "primevue";
|
|
41
40
|
import { useContext, useUiStates, useLocalization } from "#imports";
|
|
42
41
|
import { AwaitLoading, Labeler, Validation } from "#components";
|
|
43
42
|
const context = useContext();
|
|
@@ -97,5 +96,5 @@ function setSelected(value) {
|
|
|
97
96
|
</script>
|
|
98
97
|
|
|
99
98
|
<style>
|
|
100
|
-
.b-component--Select .p-placeholder{opacity:0}.b-component--Select .p-select-label{font-size:inherit}
|
|
99
|
+
.b-component--Select .p-placeholder{opacity:0}.b-component--Select .p-select-label{font-size:inherit}.p-popover-content .b-component--Select{@apply max-md:w-full}
|
|
101
100
|
</style>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<AwaitLoading
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
<AwaitLoading
|
|
3
|
+
:skeleton="{
|
|
4
|
+
height: label?.mode === 'ifta' ? '3.6rem' : '2.6rem',
|
|
5
|
+
class: 'min-w-60'
|
|
6
|
+
}"
|
|
7
|
+
>
|
|
8
8
|
<Validation>
|
|
9
9
|
<Labeler
|
|
10
10
|
:label="{
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
|
|
47
47
|
<script setup>
|
|
48
48
|
import { ref, watch } from "vue";
|
|
49
|
-
import { SelectButton
|
|
49
|
+
import { SelectButton } from "primevue";
|
|
50
50
|
import { useContext, useLocalization, useUiStates } from "#imports";
|
|
51
51
|
import { AwaitLoading, Labeler, Validation } from "#components";
|
|
52
52
|
const context = useContext();
|
|
@@ -109,7 +109,7 @@ function setSelected(value) {
|
|
|
109
109
|
</script>
|
|
110
110
|
|
|
111
111
|
<style>
|
|
112
|
-
.p-togglebutton-content{@apply whitespace-nowrap}.p-popover-content .b-component--SelectButton .p-selectbutton{@apply max-sm:flex max-sm:flex-col}.p-popover-content .b-component--SelectButton .p-selectbutton .p-togglebutton:first-child{@apply max-sm:rounded-t-lg max-sm:rounded-es-none}.p-popover-content .b-component--SelectButton .p-selectbutton .p-togglebutton:last-child{@apply max-sm:rounded-b-lg max-sm:rounded-se-none}
|
|
112
|
+
.p-togglebutton-content{@apply whitespace-nowrap}.p-popover-content .b-component--SelectButton .p-selectbutton,.p-popover-content .b-component--SelectButton.p-selectbutton{@apply max-sm:flex max-sm:flex-col}.p-popover-content .b-component--SelectButton .p-selectbutton .p-togglebutton:first-child,.p-popover-content .b-component--SelectButton.p-selectbutton .p-togglebutton:first-child{@apply max-sm:rounded-t-lg max-sm:rounded-es-none}.p-popover-content .b-component--SelectButton .p-selectbutton .p-togglebutton:last-child,.p-popover-content .b-component--SelectButton.p-selectbutton .p-togglebutton:last-child{@apply max-sm:rounded-b-lg max-sm:rounded-se-none}
|
|
113
113
|
</style>
|
|
114
114
|
|
|
115
115
|
<style scoped>
|
|
@@ -55,34 +55,41 @@
|
|
|
55
55
|
<template v-else>
|
|
56
56
|
<div
|
|
57
57
|
v-bind="$attrs"
|
|
58
|
-
class="flex flex-col gap-
|
|
58
|
+
class="flex flex-col gap-4"
|
|
59
|
+
:class="{ 'gap-8': !horizontal }"
|
|
59
60
|
>
|
|
60
|
-
<
|
|
61
|
+
<h2 class="font-bold text-xl truncate">
|
|
61
62
|
{{ l(title) }}
|
|
62
|
-
</
|
|
63
|
-
<div
|
|
63
|
+
</h2>
|
|
64
|
+
<div
|
|
65
|
+
class="flex gap-4"
|
|
66
|
+
:class="{ 'flex-col': !horizontal }"
|
|
67
|
+
>
|
|
64
68
|
<Inputs
|
|
65
69
|
v-if="inputs"
|
|
66
70
|
:inputs
|
|
71
|
+
form-mode
|
|
67
72
|
input-class="w-full"
|
|
68
73
|
@ready="onReady"
|
|
69
74
|
@changed="onChanged"
|
|
70
75
|
/>
|
|
76
|
+
<Button
|
|
77
|
+
ref="submitRef"
|
|
78
|
+
v-tooltip.top="{
|
|
79
|
+
disabled: !showValidationSummary,
|
|
80
|
+
value: messages,
|
|
81
|
+
pt: { text: 'text-sm' }
|
|
82
|
+
}"
|
|
83
|
+
:schema="submit"
|
|
84
|
+
:ready
|
|
85
|
+
class="min-w-min"
|
|
86
|
+
:class="{ 'mt-4': !horizontal && inputs.length }"
|
|
87
|
+
@submit="$emit('submit', model)"
|
|
88
|
+
/>
|
|
89
|
+
<ErrorPopover ref="errorPopoverRef">
|
|
90
|
+
<InlineError :error />
|
|
91
|
+
</ErrorPopover>
|
|
71
92
|
</div>
|
|
72
|
-
<Button
|
|
73
|
-
ref="submitRef"
|
|
74
|
-
v-tooltip.left="{
|
|
75
|
-
disabled: !showValidationSummary,
|
|
76
|
-
value: messages,
|
|
77
|
-
pt: { text: 'text-sm' }
|
|
78
|
-
}"
|
|
79
|
-
:schema="submit"
|
|
80
|
-
:ready
|
|
81
|
-
@submit="$emit('submit', model)"
|
|
82
|
-
/>
|
|
83
|
-
<ErrorPopover ref="errorPopoverRef">
|
|
84
|
-
<InlineError :error />
|
|
85
|
-
</ErrorPopover>
|
|
86
93
|
</div>
|
|
87
94
|
</template>
|
|
88
95
|
</template>
|
|
@@ -99,7 +106,7 @@ const { schema } = defineProps({
|
|
|
99
106
|
schema: { type: null, required: true }
|
|
100
107
|
});
|
|
101
108
|
const emit = defineEmits(["submit"]);
|
|
102
|
-
const { dialogOptions, inputs, submit, title, validations = [], showValidationSummary = false } = schema;
|
|
109
|
+
const { dialogOptions, inputs, horizontal, submit, title, validations = [], showValidationSummary = false } = schema;
|
|
103
110
|
const model = ref({});
|
|
104
111
|
const readyData = ref({});
|
|
105
112
|
const submitted = ref(false);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<template v-if="!validation">
|
|
2
|
+
<template v-if="validationHandled || !validation">
|
|
3
3
|
<slot />
|
|
4
4
|
</template>
|
|
5
5
|
<div
|
|
@@ -10,15 +10,19 @@
|
|
|
10
10
|
<slot
|
|
11
11
|
name="message"
|
|
12
12
|
:validation
|
|
13
|
+
:mutable-validation
|
|
13
14
|
>
|
|
14
15
|
<Message
|
|
15
|
-
v-if="
|
|
16
|
+
v-if="message"
|
|
17
|
+
:key="`${severity}:${icon}`"
|
|
18
|
+
icon="pi pi-info-circle"
|
|
16
19
|
:schema="{
|
|
17
|
-
severity
|
|
20
|
+
severity,
|
|
18
21
|
variant: 'simple',
|
|
19
|
-
size: 'small'
|
|
22
|
+
size: 'small',
|
|
23
|
+
icon
|
|
20
24
|
}"
|
|
21
|
-
:data="
|
|
25
|
+
:data="message || ''"
|
|
22
26
|
class="ml-3"
|
|
23
27
|
/>
|
|
24
28
|
</slot>
|
|
@@ -26,8 +30,23 @@
|
|
|
26
30
|
</template>
|
|
27
31
|
|
|
28
32
|
<script setup>
|
|
33
|
+
import { computed } from "vue";
|
|
29
34
|
import { useContext } from "#imports";
|
|
30
35
|
import { Message } from "#components";
|
|
31
36
|
const context = useContext();
|
|
37
|
+
const validationHandled = context.injectValidationHandled();
|
|
32
38
|
const validation = context.injectValidation();
|
|
39
|
+
const mutableValidation = context.injectMutableValidation();
|
|
40
|
+
context.provideValidationHandled(true);
|
|
41
|
+
const message = computed(() => {
|
|
42
|
+
if (mutableValidation?.value.message) {
|
|
43
|
+
return mutableValidation.value.message;
|
|
44
|
+
}
|
|
45
|
+
if (validation.value?.message && validation.value?.persist) {
|
|
46
|
+
return validation.value.message;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
});
|
|
50
|
+
const severity = computed(() => mutableValidation?.value.severity || validation?.value.severity);
|
|
51
|
+
const icon = computed(() => mutableValidation?.value.icon || validation?.value.icon);
|
|
33
52
|
</script>
|
|
@@ -17,12 +17,18 @@ export default function _default(): {
|
|
|
17
17
|
provideExecuting: (value: any) => void;
|
|
18
18
|
injectLoading: () => import("vue").Ref<boolean, boolean>;
|
|
19
19
|
provideLoading: (value: any) => void;
|
|
20
|
+
injectMutableValidations: () => {};
|
|
21
|
+
provideMutableValidations: (value: any) => void;
|
|
22
|
+
injectMutableValidation: () => null;
|
|
23
|
+
provideMutableValidation: (value: any) => void;
|
|
20
24
|
injectPageContext: () => any;
|
|
21
25
|
providePageContext: (value: any) => void;
|
|
22
26
|
injectParentContext: () => null;
|
|
23
27
|
provideParentContext: (value: any) => void;
|
|
24
|
-
injectValidations: () =>
|
|
28
|
+
injectValidations: () => null;
|
|
25
29
|
provideValidations: (value: any) => void;
|
|
26
30
|
injectValidation: () => null;
|
|
27
31
|
provideValidation: (value: any) => void;
|
|
32
|
+
injectValidationHandled: () => boolean;
|
|
33
|
+
provideValidationHandled: (value: any) => void;
|
|
28
34
|
};
|
|
@@ -71,6 +71,22 @@ export default function() {
|
|
|
71
71
|
provide("__bake_loading", value);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
function injectMutableValidations() {
|
|
75
|
+
return inject("__bake_mutable_validations", {});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function provideMutableValidations(value) {
|
|
79
|
+
provide("__bake_mutable_validations", value);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function injectMutableValidation() {
|
|
83
|
+
return inject("__bake_mutable_validation", null);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function provideMutableValidation(value) {
|
|
87
|
+
provide("__bake_mutable_validation", value);
|
|
88
|
+
}
|
|
89
|
+
|
|
74
90
|
function injectPageContext() {
|
|
75
91
|
return inject("__bake_page_context");
|
|
76
92
|
}
|
|
@@ -88,7 +104,7 @@ export default function() {
|
|
|
88
104
|
}
|
|
89
105
|
|
|
90
106
|
function injectValidations() {
|
|
91
|
-
return inject("__bake_validations",
|
|
107
|
+
return inject("__bake_validations", null);
|
|
92
108
|
}
|
|
93
109
|
|
|
94
110
|
function provideValidations(value) {
|
|
@@ -103,6 +119,14 @@ export default function() {
|
|
|
103
119
|
provide("__bake_validation", value);
|
|
104
120
|
}
|
|
105
121
|
|
|
122
|
+
function injectValidationHandled() {
|
|
123
|
+
return inject("__bake_validation_handled", false);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function provideValidationHandled(value) {
|
|
127
|
+
provide("__bake_validation_handled", value);
|
|
128
|
+
}
|
|
129
|
+
|
|
106
130
|
return {
|
|
107
131
|
injectPath,
|
|
108
132
|
providePath,
|
|
@@ -117,6 +141,10 @@ export default function() {
|
|
|
117
141
|
provideExecuting,
|
|
118
142
|
injectLoading,
|
|
119
143
|
provideLoading,
|
|
144
|
+
injectMutableValidations,
|
|
145
|
+
provideMutableValidations,
|
|
146
|
+
injectMutableValidation,
|
|
147
|
+
provideMutableValidation,
|
|
120
148
|
injectPageContext,
|
|
121
149
|
providePageContext,
|
|
122
150
|
injectParentContext,
|
|
@@ -124,6 +152,8 @@ export default function() {
|
|
|
124
152
|
injectValidations,
|
|
125
153
|
provideValidations,
|
|
126
154
|
injectValidation,
|
|
127
|
-
provideValidation
|
|
155
|
+
provideValidation,
|
|
156
|
+
injectValidationHandled,
|
|
157
|
+
provideValidationHandled
|
|
128
158
|
};
|
|
129
159
|
}
|
|
@@ -74,7 +74,8 @@ function On({ evaluate, eventId, events }) {
|
|
|
74
74
|
|
|
75
75
|
function When({ contextData, evaluate }) {
|
|
76
76
|
function bind({ trigger, react }) {
|
|
77
|
-
watch(() => contextData.page[trigger.when], async value => {
|
|
77
|
+
watch(() => contextData[trigger.key ?? "page"][trigger.when], async value => {
|
|
78
|
+
react(false);
|
|
78
79
|
react(await evaluate(trigger.constraint, value));
|
|
79
80
|
}, { immediate: true });
|
|
80
81
|
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { useRouter } from "#app";
|
|
2
|
+
import { usePathBuilder } from "#imports";
|
|
2
3
|
|
|
3
4
|
export default function() {
|
|
4
5
|
const router = useRouter();
|
|
6
|
+
const { build } = usePathBuilder();
|
|
5
7
|
|
|
6
|
-
async function run({ route, back, expected, actual } = {}) {
|
|
8
|
+
async function run({ route, back, expected, actual, ...params } = {}) {
|
|
7
9
|
if(expected && actual !== expected) { return; }
|
|
8
10
|
|
|
11
|
+
if(route && Object.keys(params).length > 0) {
|
|
12
|
+
route = build(route, params, { forRoute: true });
|
|
13
|
+
}
|
|
14
|
+
|
|
9
15
|
if(back) {
|
|
10
16
|
router.back();
|
|
11
17
|
} else {
|
|
@@ -8,4 +8,12 @@ export default function _default(): {
|
|
|
8
8
|
messages: import("vue").ComputedRef<string>;
|
|
9
9
|
validations: import("vue").ComputedRef<any>;
|
|
10
10
|
};
|
|
11
|
+
injectMutable: () => {
|
|
12
|
+
clear: () => void;
|
|
13
|
+
setError: (message: any) => void;
|
|
14
|
+
setMessage: (message: any, { persist, severity, icon }?: {
|
|
15
|
+
persist?: boolean | undefined;
|
|
16
|
+
severity?: string | undefined;
|
|
17
|
+
}) => void;
|
|
18
|
+
} | null;
|
|
11
19
|
};
|
|
@@ -26,15 +26,19 @@ export default function() {
|
|
|
26
26
|
}), {})
|
|
27
27
|
);
|
|
28
28
|
|
|
29
|
+
const mutableValidations = {};
|
|
30
|
+
|
|
29
31
|
context.provideValidations(validations);
|
|
32
|
+
context.provideMutableValidations(mutableValidations);
|
|
30
33
|
|
|
31
34
|
const isValid = computed(() =>
|
|
32
|
-
Object.values(validations.value).every(v => v.valid)
|
|
35
|
+
Object.values(validations.value).every(v => v.valid) &&
|
|
36
|
+
Object.values(mutableValidations).every(v => v.value.valid)
|
|
33
37
|
);
|
|
34
38
|
|
|
35
39
|
const messages = computed(() =>
|
|
36
|
-
Object.values(validations.value)
|
|
37
|
-
.filter(v => v.message)
|
|
40
|
+
[...Object.values(validations.value), ...Object.values(mutableValidations).map(v => v.value)]
|
|
41
|
+
.filter(v => v.message && v.severity === "error")
|
|
38
42
|
.map((v, i) => `${i > 0 ? "\n" : ""} - ${v.message}`)
|
|
39
43
|
.join("")
|
|
40
44
|
);
|
|
@@ -42,7 +46,41 @@ export default function() {
|
|
|
42
46
|
return { isValid, messages, validations };
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
function injectMutable() {
|
|
50
|
+
const ref = context.injectMutableValidation();
|
|
51
|
+
if(!ref) { return null; }
|
|
52
|
+
|
|
53
|
+
return MutableValidation(ref);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
validate,
|
|
58
|
+
injectMutable
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function MutableValidation(ref) {
|
|
63
|
+
function clear() {
|
|
64
|
+
ref.value.valid = true;
|
|
65
|
+
delete ref.value.message;
|
|
66
|
+
delete ref.value.severity;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function setError(message) {
|
|
70
|
+
setMessage(message, { persist: true, severity: "error" });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function setMessage(message, { persist = false, severity = "secondary", icon } = {}) {
|
|
74
|
+
ref.value.valid = severity !== "error";
|
|
75
|
+
ref.value.message = message;
|
|
76
|
+
ref.value.persist = persist;
|
|
77
|
+
ref.value.severity = severity;
|
|
78
|
+
ref.value.icon = icon;
|
|
79
|
+
}
|
|
80
|
+
|
|
45
81
|
return {
|
|
46
|
-
|
|
82
|
+
clear,
|
|
83
|
+
setError,
|
|
84
|
+
setMessage
|
|
47
85
|
};
|
|
48
86
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mouseless/baked",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "Baked is an opinionated framework for .NET and Vue. This is the UI package of Baked project.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"baked",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"@nuxtjs/tailwindcss": "6.14.0",
|
|
48
48
|
"@primeuix/themes": "2.0.3",
|
|
49
49
|
"async-mutex": "0.5.0",
|
|
50
|
+
"playwright": "^1.60.0",
|
|
50
51
|
"primeicons": "7.0.0",
|
|
51
52
|
"primevue": "4.5.5"
|
|
52
53
|
},
|
|
@@ -71,4 +72,4 @@
|
|
|
71
72
|
"@oxc-parser/binding-linux-x64-musl": "0.133.0",
|
|
72
73
|
"@oxc-parser/binding-win32-x64-msvc": "0.133.0"
|
|
73
74
|
}
|
|
74
|
-
}
|
|
75
|
+
}
|