@htlkg/components 0.0.3 → 0.0.4
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/AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js +367 -0
- package/dist/AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js.map +1 -0
- package/dist/Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js +263 -0
- package/dist/Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js.map +1 -0
- package/dist/DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js +580 -0
- package/dist/DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js.map +1 -0
- package/dist/ProductBadge.vue_vue_type_script_setup_true_lang-Cmr2f4Cy.js +187 -0
- package/dist/ProductBadge.vue_vue_type_script_setup_true_lang-Cmr2f4Cy.js.map +1 -0
- package/dist/_plugin-vue_export-helper-1tPrXgE0.js +11 -0
- package/dist/_plugin-vue_export-helper-1tPrXgE0.js.map +1 -0
- package/dist/components.css +15 -0
- package/dist/composables/index.js +32 -765
- package/dist/composables/index.js.map +1 -1
- package/dist/data/index.js +18 -0
- package/dist/data/index.js.map +1 -0
- package/dist/domain/index.js +8 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/filterHelpers-DgRyoYSa.js +1386 -0
- package/dist/filterHelpers-DgRyoYSa.js.map +1 -0
- package/dist/forms/index.js +6 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/index-DGO_pNgG.js +79 -0
- package/dist/index-DGO_pNgG.js.map +1 -0
- package/dist/index-QK97OdqQ.js +25 -0
- package/dist/index-QK97OdqQ.js.map +1 -0
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation/index.js +8 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/overlays/index.js +8 -0
- package/dist/overlays/index.js.map +1 -0
- package/dist/stores/index.js +14 -0
- package/dist/stores/index.js.map +1 -0
- package/dist/useAdminPage-GhgXp0x8.js +1070 -0
- package/dist/useAdminPage-GhgXp0x8.js.map +1 -0
- package/dist/useTable-DutR1gkg.js +293 -0
- package/dist/useTable-DutR1gkg.js.map +1 -0
- package/package.json +37 -11
- package/src/composables/index.ts +52 -0
- package/src/composables/useAdminPage.ts +462 -0
- package/src/composables/useConfirmation.ts +358 -0
- package/src/composables/useStats.ts +361 -0
- package/src/composables/useWizard.ts +448 -0
- package/src/data/columnHelpers.ts +169 -0
- package/src/data/filterHelpers.ts +358 -0
- package/src/data/index.ts +11 -0
- package/src/forms/JsonSchemaForm.vue +4 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js","sources":["../src/overlays/Modal.vue","../src/overlays/Drawer.vue","../src/overlays/Notification.vue","../src/overlays/Alert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiModal as UiModal, type UiModalInterface } from '@hotelinking/ui';\n\ninterface Props {\n open?: boolean;\n title?: string;\n content?: string;\n modalName?: string;\n actions?: UiModalInterface['actions'];\n size?: 'small' | 'medium' | 'large';\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n open: false,\n title: '',\n content: '',\n modalName: 'modal',\n actions: () => [],\n size: 'medium'\n});\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'close': [];\n 'action': [action: any];\n}>();\n\n// Internal state synced with v-model\nconst isOpen = computed({\n get: () => props.open,\n set: (value: boolean) => {\n emit('update:open', value);\n if (!value) {\n emit('close');\n }\n }\n});\n\n// Convert to uiModal format\nconst modalConfig = computed<UiModalInterface>(() => ({\n title: props.title,\n content: props.content,\n modalName: props.modalName,\n open: isOpen.value,\n actions: props.actions\n}));\n\n// Handle modal actions from uiModal\n// uiModal emits: { modal: string, action: string }\nfunction handleModalAction(data: { modal: string; action: string }) {\n emit('action', data);\n \n // Close modal when clicking X, clicking outside, or any action\n // This matches uiModal behavior where any action closes the modal\n isOpen.value = false;\n}\n\n// Expose methods for parent components\ndefineExpose({\n open: () => { isOpen.value = true; },\n close: () => { isOpen.value = false; },\n toggle: () => { isOpen.value = !isOpen.value; }\n});\n</script>\n\n<template>\n <UiModal\n :title=\"modalConfig.title\"\n :content=\"modalConfig.content\"\n :modalName=\"modalConfig.modalName\"\n :open=\"modalConfig.open\"\n :actions=\"modalConfig.actions\"\n @modalAction=\"handleModalAction\"\n >\n <template v-if=\"$slots.default\" #default>\n <slot />\n </template>\n <template v-if=\"$slots.header\" #header>\n <slot name=\"header\" />\n </template>\n <template v-if=\"$slots.footer\" #footer>\n <slot name=\"footer\" />\n </template>\n </UiModal>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\ninterface Props {\n open?: boolean;\n position?: 'left' | 'right' | 'top' | 'bottom';\n title?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n open: false,\n position: 'right',\n title: ''\n});\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'close': [];\n}>();\n\nconst isOpen = computed({\n get: () => props.open,\n set: (value: boolean) => {\n emit('update:open', value);\n if (!value) emit('close');\n }\n});\n\nfunction close() {\n isOpen.value = false;\n}\n\n// Expose methods for parent components\ndefineExpose({\n open: () => { isOpen.value = true; },\n close: () => { isOpen.value = false; },\n toggle: () => { isOpen.value = !isOpen.value; }\n});\n</script>\n\n<template>\n <!-- Overlay -->\n <div\n v-if=\"isOpen\"\n class=\"fixed inset-0 bg-black bg-opacity-50 z-50\"\n @click=\"close\"\n >\n <!-- Drawer -->\n <div\n class=\"fixed bg-white shadow-xl z-51\"\n :class=\"{\n 'top-0 right-0 bottom-0 w-96 max-w-[90vw]': position === 'right',\n 'top-0 left-0 bottom-0 w-96 max-w-[90vw]': position === 'left',\n 'top-0 left-0 right-0 h-96 max-h-[90vh]': position === 'top',\n 'bottom-0 left-0 right-0 h-96 max-h-[90vh]': position === 'bottom'\n }\"\n @click.stop\n >\n <!-- Header -->\n <div class=\"flex justify-between items-center p-4 border-b border-gray-200\">\n <h3 class=\"text-lg font-medium\">{{ title }}</h3>\n <button\n @click=\"close\"\n class=\"text-2xl text-gray-500 hover:text-gray-700 bg-transparent border-none cursor-pointer\"\n >\n ×\n </button>\n </div>\n \n <!-- Content -->\n <div class=\"p-4 overflow-auto\">\n <slot />\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiNotification } from '@hotelinking/ui';\n\ninterface Props {\n title: string;\n message?: string;\n type?: 'info' | 'success' | 'warning' | 'danger';\n show?: boolean;\n fixed?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n message: '',\n type: 'info',\n show: false,\n fixed: true\n});\n\nconst emit = defineEmits<{\n 'update:show': [value: boolean];\n 'close': [];\n}>();\n\n// Internal state synced with v-model\nconst isVisible = computed({\n get: () => props.show,\n set: (value: boolean) => {\n emit('update:show', value);\n if (!value) {\n emit('close');\n }\n }\n});\n\n// Handle notification close\nfunction handleClose() {\n isVisible.value = false;\n}\n\n// Expose methods for parent components\ndefineExpose({\n show: () => { isVisible.value = true; },\n hide: () => { isVisible.value = false; },\n toggle: () => { isVisible.value = !isVisible.value; }\n});\n</script>\n\n<template>\n <uiNotification\n :show=\"isVisible\"\n :type=\"type\"\n :title=\"title\"\n :message=\"message\"\n :fixed=\"fixed\"\n @close-notification=\"handleClose\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiAlert, type UiAlertInterface } from '@hotelinking/ui';\n\ninterface Props {\n title: string;\n type?: UiAlertInterface['type'];\n actions?: UiAlertInterface['actions'];\n loading?: boolean;\n show?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n type: 'info',\n actions: () => [],\n loading: false,\n show: true\n});\n\nconst emit = defineEmits<{\n 'update:show': [value: boolean];\n 'alertEvent': [event: string];\n 'close': [];\n}>();\n\n// Internal state synced with v-model\nconst isVisible = computed({\n get: () => props.show,\n set: (value: boolean) => {\n emit('update:show', value);\n if (!value) {\n emit('close');\n }\n }\n});\n\n// Convert to uiAlert format\nconst alertConfig = computed<UiAlertInterface>(() => ({\n title: props.title,\n type: props.type,\n actions: props.actions,\n loading: props.loading\n}));\n\n// Handle alert action events from uiAlert\nfunction handleAlertEvent(event: string) {\n emit('alertEvent', event);\n}\n\n// Expose methods for parent components\ndefineExpose({\n show: () => { isVisible.value = true; },\n hide: () => { isVisible.value = false; },\n toggle: () => { isVisible.value = !isVisible.value; }\n});\n</script>\n\n<template>\n <div v-if=\"isVisible\">\n <uiAlert\n :title=\"alertConfig.title\"\n :type=\"alertConfig.type\"\n :actions=\"alertConfig.actions\"\n :loading=\"alertConfig.loading\"\n @alert-event=\"handleAlertEvent\"\n >\n <slot />\n </uiAlert>\n </div>\n</template>\n"],"names":["_createBlock","_unref","UiModal","$slots","_renderSlot","_createElementBlock","_createElementVNode","_hoisted_1","_toDisplayString","_createVNode"],"mappings":"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"}
|
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
import { defineComponent, computed, ref, createElementBlock, openBlock, createCommentVNode, createElementVNode, toDisplayString, Fragment, renderList, createBlock, unref, createTextVNode, renderSlot, createVNode, withCtx, watch } from "vue";
|
|
2
|
+
import _Ajv from "ajv";
|
|
3
|
+
import addFormats from "ajv-formats";
|
|
4
|
+
import { uiInput, uiTextArea, uiSelect, uiToggle, uiRangeSlider, uiButton, uiDateRange } from "@hotelinking/ui";
|
|
5
|
+
const _hoisted_1 = {
|
|
6
|
+
key: 0,
|
|
7
|
+
class: "mb-6"
|
|
8
|
+
};
|
|
9
|
+
const _hoisted_2 = {
|
|
10
|
+
key: 0,
|
|
11
|
+
class: "text-2xl font-bold text-gray-900 mb-2"
|
|
12
|
+
};
|
|
13
|
+
const _hoisted_3 = {
|
|
14
|
+
key: 1,
|
|
15
|
+
class: "text-gray-600"
|
|
16
|
+
};
|
|
17
|
+
const _hoisted_4 = {
|
|
18
|
+
key: 1,
|
|
19
|
+
class: "space-y-6"
|
|
20
|
+
};
|
|
21
|
+
const _hoisted_5 = {
|
|
22
|
+
key: 5,
|
|
23
|
+
class: "flex items-start"
|
|
24
|
+
};
|
|
25
|
+
const _hoisted_6 = ["id", "checked", "disabled", "onChange"];
|
|
26
|
+
const _hoisted_7 = ["for"];
|
|
27
|
+
const _hoisted_8 = { class: "text-sm font-medium text-gray-700" };
|
|
28
|
+
const _hoisted_9 = {
|
|
29
|
+
key: 0,
|
|
30
|
+
class: "text-red-500"
|
|
31
|
+
};
|
|
32
|
+
const _hoisted_10 = {
|
|
33
|
+
key: 0,
|
|
34
|
+
class: "text-sm text-gray-500"
|
|
35
|
+
};
|
|
36
|
+
const _hoisted_11 = {
|
|
37
|
+
key: 7,
|
|
38
|
+
class: "space-y-2"
|
|
39
|
+
};
|
|
40
|
+
const _hoisted_12 = { class: "block text-sm font-medium text-gray-700" };
|
|
41
|
+
const _hoisted_13 = {
|
|
42
|
+
key: 0,
|
|
43
|
+
class: "text-red-500"
|
|
44
|
+
};
|
|
45
|
+
const _hoisted_14 = {
|
|
46
|
+
key: 0,
|
|
47
|
+
class: "text-sm text-gray-500 mb-2"
|
|
48
|
+
};
|
|
49
|
+
const _hoisted_15 = {
|
|
50
|
+
key: 1,
|
|
51
|
+
class: "text-sm text-red-600 mb-2"
|
|
52
|
+
};
|
|
53
|
+
const _hoisted_16 = { class: "space-y-2" };
|
|
54
|
+
const _hoisted_17 = ["value", "disabled", "onInput"];
|
|
55
|
+
const _hoisted_18 = ["onClick", "disabled"];
|
|
56
|
+
const _hoisted_19 = ["onClick", "disabled"];
|
|
57
|
+
const _hoisted_20 = {
|
|
58
|
+
key: 8,
|
|
59
|
+
class: "border border-gray-200 rounded-lg p-4 space-y-4"
|
|
60
|
+
};
|
|
61
|
+
const _hoisted_21 = { class: "text-lg font-semibold text-gray-900 mb-1" };
|
|
62
|
+
const _hoisted_22 = {
|
|
63
|
+
key: 0,
|
|
64
|
+
class: "text-sm text-gray-600 mb-4"
|
|
65
|
+
};
|
|
66
|
+
const _hoisted_23 = { class: "space-y-4 pl-4 border-l-2 border-gray-200" };
|
|
67
|
+
const _hoisted_24 = { class: "text-sm text-gray-500" };
|
|
68
|
+
const _hoisted_25 = { class: "flex justify-end gap-3 pt-6 border-t" };
|
|
69
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
70
|
+
__name: "JsonSchemaForm",
|
|
71
|
+
props: {
|
|
72
|
+
schema: {},
|
|
73
|
+
modelValue: { default: () => ({}) },
|
|
74
|
+
uiSchema: { default: () => ({}) },
|
|
75
|
+
loading: { type: Boolean, default: false }
|
|
76
|
+
},
|
|
77
|
+
emits: ["update:modelValue", "validation-error", "submit"],
|
|
78
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
79
|
+
const Ajv = _Ajv.default ?? _Ajv;
|
|
80
|
+
const ajv = new Ajv({ allErrors: true });
|
|
81
|
+
addFormats(ajv);
|
|
82
|
+
const props = __props;
|
|
83
|
+
const emit = __emit;
|
|
84
|
+
const formData = computed({
|
|
85
|
+
get: () => props.modelValue,
|
|
86
|
+
set: (value) => {
|
|
87
|
+
emit("update:modelValue", value);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
const errors = ref({});
|
|
91
|
+
const touched = ref({});
|
|
92
|
+
function getWidget(fieldName) {
|
|
93
|
+
var _a;
|
|
94
|
+
const uiSchemaField = props.uiSchema[fieldName];
|
|
95
|
+
if (uiSchemaField == null ? void 0 : uiSchemaField["ui:widget"]) {
|
|
96
|
+
return uiSchemaField["ui:widget"];
|
|
97
|
+
}
|
|
98
|
+
const fieldSchema = (_a = props.schema.properties) == null ? void 0 : _a[fieldName];
|
|
99
|
+
if (!fieldSchema) return "text";
|
|
100
|
+
if (fieldSchema.type === "boolean") return "toggle";
|
|
101
|
+
if (fieldSchema.type === "number" || fieldSchema.type === "integer") {
|
|
102
|
+
return "number";
|
|
103
|
+
}
|
|
104
|
+
if (fieldSchema.type === "string") {
|
|
105
|
+
if (fieldSchema.enum) return "select";
|
|
106
|
+
if (fieldSchema.format === "email") return "email";
|
|
107
|
+
if (fieldSchema.format === "uri") return "url";
|
|
108
|
+
if (fieldSchema.minLength && fieldSchema.minLength > 100) return "textarea";
|
|
109
|
+
}
|
|
110
|
+
if (fieldSchema.type === "array") return "array";
|
|
111
|
+
if (fieldSchema.type === "object") return "object";
|
|
112
|
+
return "text";
|
|
113
|
+
}
|
|
114
|
+
function getInputType(fieldName) {
|
|
115
|
+
const widget = getWidget(fieldName);
|
|
116
|
+
if (widget === "password") return "password";
|
|
117
|
+
if (widget === "email") return "email";
|
|
118
|
+
if (widget === "number") return "number";
|
|
119
|
+
if (widget === "date") return "date";
|
|
120
|
+
if (widget === "datetime-local") return "datetime-local";
|
|
121
|
+
return "text";
|
|
122
|
+
}
|
|
123
|
+
function getFieldColor(fieldName) {
|
|
124
|
+
if (errors.value[fieldName]) return "red";
|
|
125
|
+
if (touched.value[fieldName]) {
|
|
126
|
+
const value = formData.value[fieldName];
|
|
127
|
+
if (isRequired(fieldName) && value !== void 0 && value !== null && value !== "") {
|
|
128
|
+
return "green";
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return "gray";
|
|
132
|
+
}
|
|
133
|
+
function isRequired(fieldName) {
|
|
134
|
+
var _a;
|
|
135
|
+
return ((_a = props.schema.required) == null ? void 0 : _a.includes(fieldName)) ?? false;
|
|
136
|
+
}
|
|
137
|
+
function getFieldLabel(fieldName) {
|
|
138
|
+
var _a;
|
|
139
|
+
const fieldSchema = (_a = props.schema.properties) == null ? void 0 : _a[fieldName];
|
|
140
|
+
return (fieldSchema == null ? void 0 : fieldSchema.title) || fieldName;
|
|
141
|
+
}
|
|
142
|
+
function getFieldDescription(fieldName) {
|
|
143
|
+
var _a;
|
|
144
|
+
const fieldSchema = (_a = props.schema.properties) == null ? void 0 : _a[fieldName];
|
|
145
|
+
return (fieldSchema == null ? void 0 : fieldSchema.description) || "";
|
|
146
|
+
}
|
|
147
|
+
function getPlaceholder(fieldName) {
|
|
148
|
+
var _a;
|
|
149
|
+
return ((_a = props.uiSchema[fieldName]) == null ? void 0 : _a["ui:placeholder"]) || "";
|
|
150
|
+
}
|
|
151
|
+
function validate() {
|
|
152
|
+
const validationErrors = [];
|
|
153
|
+
errors.value = {};
|
|
154
|
+
const validateFn = ajv.compile(props.schema);
|
|
155
|
+
const valid = validateFn(formData.value);
|
|
156
|
+
if (!valid && validateFn.errors) {
|
|
157
|
+
for (const error of validateFn.errors) {
|
|
158
|
+
const field = error.instancePath.replace(/^\//, "") || error.params.missingProperty || "form";
|
|
159
|
+
let message = "";
|
|
160
|
+
if (error.keyword === "required") {
|
|
161
|
+
const missingField = error.params.missingProperty;
|
|
162
|
+
message = `${getFieldLabel(missingField)} is required`;
|
|
163
|
+
errors.value[missingField] = message;
|
|
164
|
+
validationErrors.push({ field: missingField, message });
|
|
165
|
+
} else if (error.keyword === "type") {
|
|
166
|
+
message = `${getFieldLabel(field)} must be a ${error.params.type}`;
|
|
167
|
+
errors.value[field] = message;
|
|
168
|
+
validationErrors.push({ field, message });
|
|
169
|
+
} else if (error.keyword === "minimum") {
|
|
170
|
+
message = `${getFieldLabel(field)} must be at least ${error.params.limit}`;
|
|
171
|
+
errors.value[field] = message;
|
|
172
|
+
validationErrors.push({ field, message });
|
|
173
|
+
} else if (error.keyword === "maximum") {
|
|
174
|
+
message = `${getFieldLabel(field)} must be at most ${error.params.limit}`;
|
|
175
|
+
errors.value[field] = message;
|
|
176
|
+
validationErrors.push({ field, message });
|
|
177
|
+
} else if (error.keyword === "minLength") {
|
|
178
|
+
message = `${getFieldLabel(field)} must be at least ${error.params.limit} characters`;
|
|
179
|
+
errors.value[field] = message;
|
|
180
|
+
validationErrors.push({ field, message });
|
|
181
|
+
} else if (error.keyword === "maxLength") {
|
|
182
|
+
message = `${getFieldLabel(field)} must be at most ${error.params.limit} characters`;
|
|
183
|
+
errors.value[field] = message;
|
|
184
|
+
validationErrors.push({ field, message });
|
|
185
|
+
} else if (error.keyword === "format") {
|
|
186
|
+
message = `${getFieldLabel(field)} must be a valid ${error.params.format}`;
|
|
187
|
+
errors.value[field] = message;
|
|
188
|
+
validationErrors.push({ field, message });
|
|
189
|
+
} else if (error.keyword === "enum") {
|
|
190
|
+
message = `${getFieldLabel(field)} must be one of: ${error.params.allowedValues.join(", ")}`;
|
|
191
|
+
errors.value[field] = message;
|
|
192
|
+
validationErrors.push({ field, message });
|
|
193
|
+
} else {
|
|
194
|
+
message = error.message || "Invalid value";
|
|
195
|
+
errors.value[field] = message;
|
|
196
|
+
validationErrors.push({ field, message });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return validationErrors;
|
|
201
|
+
}
|
|
202
|
+
function handleSubmit(event) {
|
|
203
|
+
event.preventDefault();
|
|
204
|
+
const validationErrors = validate();
|
|
205
|
+
if (validationErrors.length > 0) {
|
|
206
|
+
emit("validation-error", validationErrors);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
emit("submit", formData.value);
|
|
210
|
+
}
|
|
211
|
+
function updateField(field, value) {
|
|
212
|
+
touched.value[field] = true;
|
|
213
|
+
const newData = {
|
|
214
|
+
...formData.value,
|
|
215
|
+
[field]: value
|
|
216
|
+
};
|
|
217
|
+
emit("update:modelValue", newData);
|
|
218
|
+
validateFieldWithValue(field, value);
|
|
219
|
+
}
|
|
220
|
+
function validateField(fieldName) {
|
|
221
|
+
validateFieldWithValue(fieldName, formData.value[fieldName]);
|
|
222
|
+
}
|
|
223
|
+
function validateFieldWithValue(fieldName, fieldValue) {
|
|
224
|
+
var _a;
|
|
225
|
+
const fieldSchema = (_a = props.schema.properties) == null ? void 0 : _a[fieldName];
|
|
226
|
+
if (!fieldSchema) return;
|
|
227
|
+
delete errors.value[fieldName];
|
|
228
|
+
if (isRequired(fieldName) && (fieldValue === void 0 || fieldValue === null || fieldValue === "")) {
|
|
229
|
+
errors.value[fieldName] = `${getFieldLabel(fieldName)} is required`;
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (fieldValue === void 0 || fieldValue === null || fieldValue === "") {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const singleFieldSchema = {
|
|
236
|
+
type: "object",
|
|
237
|
+
properties: {
|
|
238
|
+
[fieldName]: fieldSchema
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
const validateFn = ajv.compile(singleFieldSchema);
|
|
242
|
+
const valid = validateFn({ [fieldName]: fieldValue });
|
|
243
|
+
if (!valid && validateFn.errors) {
|
|
244
|
+
for (const error of validateFn.errors) {
|
|
245
|
+
let message = "";
|
|
246
|
+
if (error.keyword === "type") {
|
|
247
|
+
message = `${getFieldLabel(fieldName)} must be a ${error.params.type}`;
|
|
248
|
+
} else if (error.keyword === "minimum") {
|
|
249
|
+
message = `${getFieldLabel(fieldName)} must be at least ${error.params.limit}`;
|
|
250
|
+
} else if (error.keyword === "maximum") {
|
|
251
|
+
message = `${getFieldLabel(fieldName)} must be at most ${error.params.limit}`;
|
|
252
|
+
} else if (error.keyword === "minLength") {
|
|
253
|
+
message = `${getFieldLabel(fieldName)} must be at least ${error.params.limit} characters`;
|
|
254
|
+
} else if (error.keyword === "maxLength") {
|
|
255
|
+
message = `${getFieldLabel(fieldName)} must be at most ${error.params.limit} characters`;
|
|
256
|
+
} else if (error.keyword === "format") {
|
|
257
|
+
message = `${getFieldLabel(fieldName)} must be a valid ${error.params.format}`;
|
|
258
|
+
} else if (error.keyword === "enum") {
|
|
259
|
+
message = `${getFieldLabel(fieldName)} must be one of: ${error.params.allowedValues.join(", ")}`;
|
|
260
|
+
} else {
|
|
261
|
+
message = error.message || "Invalid value";
|
|
262
|
+
}
|
|
263
|
+
errors.value[fieldName] = message;
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function getSelectOptions(fieldName) {
|
|
269
|
+
var _a;
|
|
270
|
+
const fieldSchema = (_a = props.schema.properties) == null ? void 0 : _a[fieldName];
|
|
271
|
+
if (!(fieldSchema == null ? void 0 : fieldSchema.enum)) return [];
|
|
272
|
+
return fieldSchema.enum.map((value) => ({
|
|
273
|
+
id: String(value),
|
|
274
|
+
name: String(value),
|
|
275
|
+
label: String(value)
|
|
276
|
+
}));
|
|
277
|
+
}
|
|
278
|
+
function getSelectedOption(fieldName) {
|
|
279
|
+
const value = formData.value[fieldName];
|
|
280
|
+
if (!value) {
|
|
281
|
+
const options = getSelectOptions(fieldName);
|
|
282
|
+
return options.length > 0 ? options[0] : { id: "", name: "", label: "" };
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
id: String(value),
|
|
286
|
+
name: String(value),
|
|
287
|
+
label: String(value)
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
function addArrayItem(fieldName) {
|
|
291
|
+
const currentArray = formData.value[fieldName] || [];
|
|
292
|
+
updateField(fieldName, [...currentArray, ""]);
|
|
293
|
+
}
|
|
294
|
+
function removeArrayItem(fieldName, index) {
|
|
295
|
+
const currentArray = formData.value[fieldName] || [];
|
|
296
|
+
const newArray = currentArray.filter((_, i) => i !== index);
|
|
297
|
+
updateField(fieldName, newArray);
|
|
298
|
+
}
|
|
299
|
+
function updateArrayItem(fieldName, index, value) {
|
|
300
|
+
const currentArray = formData.value[fieldName] || [];
|
|
301
|
+
const newArray = [...currentArray];
|
|
302
|
+
newArray[index] = value;
|
|
303
|
+
updateField(fieldName, newArray);
|
|
304
|
+
}
|
|
305
|
+
__expose({
|
|
306
|
+
validate,
|
|
307
|
+
validateField,
|
|
308
|
+
reset: () => {
|
|
309
|
+
emit("update:modelValue", {});
|
|
310
|
+
errors.value = {};
|
|
311
|
+
touched.value = {};
|
|
312
|
+
},
|
|
313
|
+
// Expose internal state for testing
|
|
314
|
+
formData,
|
|
315
|
+
errors,
|
|
316
|
+
touched,
|
|
317
|
+
// Expose helper methods for testing
|
|
318
|
+
getFieldLabel,
|
|
319
|
+
getFieldDescription,
|
|
320
|
+
isRequired,
|
|
321
|
+
getWidget,
|
|
322
|
+
getInputType,
|
|
323
|
+
getFieldColor,
|
|
324
|
+
getPlaceholder,
|
|
325
|
+
getSelectOptions,
|
|
326
|
+
getSelectedOption,
|
|
327
|
+
updateField
|
|
328
|
+
});
|
|
329
|
+
return (_ctx, _cache) => {
|
|
330
|
+
return openBlock(), createElementBlock("form", {
|
|
331
|
+
onSubmit: handleSubmit,
|
|
332
|
+
class: "space-y-6"
|
|
333
|
+
}, [
|
|
334
|
+
__props.schema.title || __props.schema.description ? (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
335
|
+
__props.schema.title ? (openBlock(), createElementBlock("h2", _hoisted_2, toDisplayString(__props.schema.title), 1)) : createCommentVNode("", true),
|
|
336
|
+
__props.schema.description ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString(__props.schema.description), 1)) : createCommentVNode("", true)
|
|
337
|
+
])) : createCommentVNode("", true),
|
|
338
|
+
__props.schema.properties ? (openBlock(), createElementBlock("div", _hoisted_4, [
|
|
339
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.schema.properties, (fieldSchema, fieldName) => {
|
|
340
|
+
var _a, _b, _c, _d;
|
|
341
|
+
return openBlock(), createElementBlock("div", { key: fieldName }, [
|
|
342
|
+
["text", "email", "url", "password"].includes(getWidget(fieldName)) ? (openBlock(), createBlock(unref(uiInput), {
|
|
343
|
+
key: 0,
|
|
344
|
+
name: fieldName,
|
|
345
|
+
label: getFieldLabel(fieldName),
|
|
346
|
+
type: getInputType(fieldName),
|
|
347
|
+
value: formData.value[fieldName] || "",
|
|
348
|
+
placeholder: getPlaceholder(fieldName),
|
|
349
|
+
error: errors.value[fieldName],
|
|
350
|
+
color: getFieldColor(fieldName),
|
|
351
|
+
loading: __props.loading,
|
|
352
|
+
"required-text": isRequired(fieldName) ? "*" : void 0,
|
|
353
|
+
onInputChanged: ($event) => updateField(fieldName, $event.value)
|
|
354
|
+
}, null, 8, ["name", "label", "type", "value", "placeholder", "error", "color", "loading", "required-text", "onInputChanged"])) : getWidget(fieldName) === "number" ? (openBlock(), createBlock(unref(uiInput), {
|
|
355
|
+
key: 1,
|
|
356
|
+
name: fieldName,
|
|
357
|
+
label: getFieldLabel(fieldName),
|
|
358
|
+
type: "number",
|
|
359
|
+
value: String(formData.value[fieldName] ?? ""),
|
|
360
|
+
placeholder: getPlaceholder(fieldName),
|
|
361
|
+
error: errors.value[fieldName],
|
|
362
|
+
color: getFieldColor(fieldName),
|
|
363
|
+
loading: __props.loading,
|
|
364
|
+
"required-text": isRequired(fieldName) ? "*" : void 0,
|
|
365
|
+
min: (_b = (_a = __props.schema.properties) == null ? void 0 : _a[fieldName]) == null ? void 0 : _b.minimum,
|
|
366
|
+
max: (_d = (_c = __props.schema.properties) == null ? void 0 : _c[fieldName]) == null ? void 0 : _d.maximum,
|
|
367
|
+
onInputChanged: ($event) => updateField(fieldName, $event.value === "" ? null : Number($event.value))
|
|
368
|
+
}, null, 8, ["name", "label", "value", "placeholder", "error", "color", "loading", "required-text", "min", "max", "onInputChanged"])) : getWidget(fieldName) === "textarea" ? (openBlock(), createBlock(unref(uiTextArea), {
|
|
369
|
+
key: 2,
|
|
370
|
+
name: fieldName,
|
|
371
|
+
label: getFieldLabel(fieldName),
|
|
372
|
+
value: formData.value[fieldName] || "",
|
|
373
|
+
placeholder: getPlaceholder(fieldName),
|
|
374
|
+
error: errors.value[fieldName],
|
|
375
|
+
color: getFieldColor(fieldName),
|
|
376
|
+
loading: __props.loading,
|
|
377
|
+
"required-text": isRequired(fieldName) ? "*" : void 0,
|
|
378
|
+
rows: 4,
|
|
379
|
+
onInputChanged: ($event) => updateField(fieldName, $event.value)
|
|
380
|
+
}, null, 8, ["name", "label", "value", "placeholder", "error", "color", "loading", "required-text", "onInputChanged"])) : getWidget(fieldName) === "select" ? (openBlock(), createBlock(unref(uiSelect), {
|
|
381
|
+
key: 3,
|
|
382
|
+
label: getFieldLabel(fieldName),
|
|
383
|
+
items: getSelectOptions(fieldName),
|
|
384
|
+
select: getSelectedOption(fieldName),
|
|
385
|
+
placeholder: getPlaceholder(fieldName) || "Select an option",
|
|
386
|
+
error: errors.value[fieldName],
|
|
387
|
+
color: getFieldColor(fieldName),
|
|
388
|
+
loading: __props.loading,
|
|
389
|
+
"required-text": isRequired(fieldName) ? "*" : void 0,
|
|
390
|
+
onSelectChanged: (item) => updateField(fieldName, item.id)
|
|
391
|
+
}, null, 8, ["label", "items", "select", "placeholder", "error", "color", "loading", "required-text", "onSelectChanged"])) : getWidget(fieldName) === "toggle" ? (openBlock(), createBlock(unref(uiToggle), {
|
|
392
|
+
key: 4,
|
|
393
|
+
item: {
|
|
394
|
+
title: getFieldLabel(fieldName),
|
|
395
|
+
subtitle: getFieldDescription(fieldName),
|
|
396
|
+
action: fieldName
|
|
397
|
+
},
|
|
398
|
+
checked: formData.value[fieldName],
|
|
399
|
+
loading: __props.loading,
|
|
400
|
+
onToggleChanged: ($event) => updateField(fieldName, $event.active)
|
|
401
|
+
}, null, 8, ["item", "checked", "loading", "onToggleChanged"])) : getWidget(fieldName) === "checkbox" ? (openBlock(), createElementBlock("div", _hoisted_5, [
|
|
402
|
+
createElementVNode("input", {
|
|
403
|
+
id: fieldName,
|
|
404
|
+
type: "checkbox",
|
|
405
|
+
checked: formData.value[fieldName],
|
|
406
|
+
disabled: __props.loading,
|
|
407
|
+
onChange: ($event) => updateField(fieldName, $event.target.checked),
|
|
408
|
+
class: "h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded mt-1"
|
|
409
|
+
}, null, 40, _hoisted_6),
|
|
410
|
+
createElementVNode("label", {
|
|
411
|
+
for: fieldName,
|
|
412
|
+
class: "ml-2 block"
|
|
413
|
+
}, [
|
|
414
|
+
createElementVNode("span", _hoisted_8, [
|
|
415
|
+
createTextVNode(toDisplayString(getFieldLabel(fieldName)) + " ", 1),
|
|
416
|
+
isRequired(fieldName) ? (openBlock(), createElementBlock("span", _hoisted_9, "*")) : createCommentVNode("", true)
|
|
417
|
+
]),
|
|
418
|
+
getFieldDescription(fieldName) ? (openBlock(), createElementBlock("p", _hoisted_10, toDisplayString(getFieldDescription(fieldName)), 1)) : createCommentVNode("", true)
|
|
419
|
+
], 8, _hoisted_7)
|
|
420
|
+
])) : getWidget(fieldName) === "slider" ? (openBlock(), createBlock(unref(uiRangeSlider), {
|
|
421
|
+
key: 6,
|
|
422
|
+
label: getFieldLabel(fieldName),
|
|
423
|
+
min: __props.schema.properties[fieldName].minimum ?? 0,
|
|
424
|
+
max: __props.schema.properties[fieldName].maximum ?? 100,
|
|
425
|
+
"slider-value": formData.value[fieldName] ?? __props.schema.properties[fieldName].minimum ?? 0,
|
|
426
|
+
loading: __props.loading,
|
|
427
|
+
"required-text": isRequired(fieldName) ? "*" : void 0,
|
|
428
|
+
onSliderUpdated: ($event) => updateField(fieldName, $event)
|
|
429
|
+
}, null, 8, ["label", "min", "max", "slider-value", "loading", "required-text", "onSliderUpdated"])) : getWidget(fieldName) === "array" ? (openBlock(), createElementBlock("div", _hoisted_11, [
|
|
430
|
+
createElementVNode("label", _hoisted_12, [
|
|
431
|
+
createTextVNode(toDisplayString(getFieldLabel(fieldName)) + " ", 1),
|
|
432
|
+
isRequired(fieldName) ? (openBlock(), createElementBlock("span", _hoisted_13, "*")) : createCommentVNode("", true)
|
|
433
|
+
]),
|
|
434
|
+
getFieldDescription(fieldName) ? (openBlock(), createElementBlock("p", _hoisted_14, toDisplayString(getFieldDescription(fieldName)), 1)) : createCommentVNode("", true),
|
|
435
|
+
errors.value[fieldName] ? (openBlock(), createElementBlock("div", _hoisted_15, toDisplayString(errors.value[fieldName]), 1)) : createCommentVNode("", true),
|
|
436
|
+
createElementVNode("div", _hoisted_16, [
|
|
437
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(formData.value[fieldName] || [], (item, index) => {
|
|
438
|
+
return openBlock(), createElementBlock("div", {
|
|
439
|
+
key: index,
|
|
440
|
+
class: "flex gap-2"
|
|
441
|
+
}, [
|
|
442
|
+
createElementVNode("input", {
|
|
443
|
+
type: "text",
|
|
444
|
+
value: item,
|
|
445
|
+
disabled: __props.loading,
|
|
446
|
+
onInput: ($event) => updateArrayItem(fieldName, index, $event.target.value),
|
|
447
|
+
class: "flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
448
|
+
}, null, 40, _hoisted_17),
|
|
449
|
+
createElementVNode("button", {
|
|
450
|
+
type: "button",
|
|
451
|
+
onClick: ($event) => removeArrayItem(fieldName, index),
|
|
452
|
+
disabled: __props.loading,
|
|
453
|
+
class: "px-3 py-2 text-red-600 hover:text-red-800 border border-red-300 rounded-md"
|
|
454
|
+
}, " Remove ", 8, _hoisted_18)
|
|
455
|
+
]);
|
|
456
|
+
}), 128))
|
|
457
|
+
]),
|
|
458
|
+
createElementVNode("button", {
|
|
459
|
+
type: "button",
|
|
460
|
+
onClick: ($event) => addArrayItem(fieldName),
|
|
461
|
+
disabled: __props.loading,
|
|
462
|
+
class: "mt-2 px-4 py-2 text-sm text-blue-600 hover:text-blue-800 border border-blue-300 rounded-md"
|
|
463
|
+
}, " + Add Item ", 8, _hoisted_19)
|
|
464
|
+
])) : getWidget(fieldName) === "object" || getWidget(fieldName) === "card" ? (openBlock(), createElementBlock("div", _hoisted_20, [
|
|
465
|
+
createElementVNode("div", null, [
|
|
466
|
+
createElementVNode("h3", _hoisted_21, toDisplayString(getFieldLabel(fieldName)), 1),
|
|
467
|
+
getFieldDescription(fieldName) ? (openBlock(), createElementBlock("p", _hoisted_22, toDisplayString(getFieldDescription(fieldName)), 1)) : createCommentVNode("", true)
|
|
468
|
+
]),
|
|
469
|
+
createElementVNode("div", _hoisted_23, [
|
|
470
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(fieldSchema.properties, (subSchema, subName) => {
|
|
471
|
+
return openBlock(), createElementBlock("div", { key: subName }, [
|
|
472
|
+
createElementVNode("p", _hoisted_24, " Nested field: " + toDisplayString(subName) + " (type: " + toDisplayString(subSchema.type) + ") ", 1)
|
|
473
|
+
]);
|
|
474
|
+
}), 128))
|
|
475
|
+
])
|
|
476
|
+
])) : createCommentVNode("", true)
|
|
477
|
+
]);
|
|
478
|
+
}), 128))
|
|
479
|
+
])) : createCommentVNode("", true),
|
|
480
|
+
createElementVNode("div", _hoisted_25, [
|
|
481
|
+
renderSlot(_ctx.$slots, "actions", {}, () => [
|
|
482
|
+
createVNode(unref(uiButton), {
|
|
483
|
+
type: "submit",
|
|
484
|
+
color: "primary",
|
|
485
|
+
loading: __props.loading
|
|
486
|
+
}, {
|
|
487
|
+
default: withCtx(() => [..._cache[0] || (_cache[0] = [
|
|
488
|
+
createTextVNode(" Submit ", -1)
|
|
489
|
+
])]),
|
|
490
|
+
_: 1
|
|
491
|
+
}, 8, ["loading"])
|
|
492
|
+
])
|
|
493
|
+
])
|
|
494
|
+
], 32);
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
499
|
+
__name: "DateRange",
|
|
500
|
+
props: {
|
|
501
|
+
id: { default: () => `date-range-${Math.random().toString(36).substr(2, 9)}` },
|
|
502
|
+
modelValue: { default: () => ({
|
|
503
|
+
from: "",
|
|
504
|
+
to: (/* @__PURE__ */ new Date()).toISOString().slice(0, 16)
|
|
505
|
+
}) },
|
|
506
|
+
literals: { default: () => ({
|
|
507
|
+
from: "From",
|
|
508
|
+
to: "To",
|
|
509
|
+
search: "Search"
|
|
510
|
+
}) },
|
|
511
|
+
loading: { type: Boolean, default: false },
|
|
512
|
+
color: {},
|
|
513
|
+
error: {},
|
|
514
|
+
disabled: { type: Boolean },
|
|
515
|
+
label: {},
|
|
516
|
+
placeholder: {}
|
|
517
|
+
},
|
|
518
|
+
emits: ["update:modelValue", "search", "change"],
|
|
519
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
520
|
+
var _a, _b;
|
|
521
|
+
const props = __props;
|
|
522
|
+
const emit = __emit;
|
|
523
|
+
const internalValues = ref({
|
|
524
|
+
from: ((_a = props.modelValue) == null ? void 0 : _a.from) || "",
|
|
525
|
+
to: ((_b = props.modelValue) == null ? void 0 : _b.to) || (/* @__PURE__ */ new Date()).toISOString().slice(0, 16)
|
|
526
|
+
});
|
|
527
|
+
watch(() => props.modelValue, (newValue) => {
|
|
528
|
+
if (newValue) {
|
|
529
|
+
internalValues.value = {
|
|
530
|
+
from: newValue.from || "",
|
|
531
|
+
to: newValue.to || (/* @__PURE__ */ new Date()).toISOString().slice(0, 16)
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
}, { deep: true });
|
|
535
|
+
function handleSearch(dates) {
|
|
536
|
+
emit("update:modelValue", dates);
|
|
537
|
+
emit("search", dates);
|
|
538
|
+
emit("change", dates);
|
|
539
|
+
}
|
|
540
|
+
function reset() {
|
|
541
|
+
const resetValue = {
|
|
542
|
+
from: "",
|
|
543
|
+
to: (/* @__PURE__ */ new Date()).toISOString().slice(0, 16)
|
|
544
|
+
};
|
|
545
|
+
internalValues.value = resetValue;
|
|
546
|
+
emit("update:modelValue", resetValue);
|
|
547
|
+
}
|
|
548
|
+
function getValue() {
|
|
549
|
+
return internalValues.value;
|
|
550
|
+
}
|
|
551
|
+
function setValue(value) {
|
|
552
|
+
internalValues.value = value;
|
|
553
|
+
emit("update:modelValue", value);
|
|
554
|
+
}
|
|
555
|
+
__expose({
|
|
556
|
+
reset,
|
|
557
|
+
getValue,
|
|
558
|
+
setValue
|
|
559
|
+
});
|
|
560
|
+
return (_ctx, _cache) => {
|
|
561
|
+
return openBlock(), createBlock(unref(uiDateRange), {
|
|
562
|
+
id: __props.id,
|
|
563
|
+
loading: __props.loading,
|
|
564
|
+
literals: __props.literals,
|
|
565
|
+
values: internalValues.value,
|
|
566
|
+
color: __props.color,
|
|
567
|
+
error: __props.error,
|
|
568
|
+
disabled: __props.disabled,
|
|
569
|
+
label: __props.label,
|
|
570
|
+
placeholder: __props.placeholder,
|
|
571
|
+
onUiDateRangeButtonClicked: handleSearch
|
|
572
|
+
}, null, 8, ["id", "loading", "literals", "values", "color", "error", "disabled", "label", "placeholder"]);
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
export {
|
|
577
|
+
_sfc_main$1 as _,
|
|
578
|
+
_sfc_main as a
|
|
579
|
+
};
|
|
580
|
+
//# sourceMappingURL=DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js.map
|