@finema/core 2.7.7 → 2.8.1
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 +1 -1
- package/dist/runtime/components/Empty.vue +15 -15
- package/dist/runtime/components/Empty.vue.d.ts +1 -0
- package/dist/runtime/components/Form/Fields.vue +78 -30
- package/dist/runtime/components/Form/InputDateTimeRange/date_range_time_field.types.d.ts +17 -0
- package/dist/runtime/components/Form/InputDateTimeRange/date_range_time_field.types.js +0 -0
- package/dist/runtime/components/Form/InputDateTimeRange/index.vue +112 -0
- package/dist/runtime/components/Form/InputDateTimeRange/index.vue.d.ts +4 -0
- package/dist/runtime/components/Form/types.d.ts +2 -1
- package/dist/runtime/styles/main.css +1 -1
- package/dist/runtime/theme/empty.d.ts +1 -1
- package/dist/runtime/theme/empty.js +1 -1
- package/package.json +1 -1
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
3
|
:class="theme.base({
|
|
4
4
|
class: [ui?.base, props.class]
|
|
5
|
-
})"
|
|
6
|
-
>
|
|
7
|
-
<Icon
|
|
8
|
-
:name="icon"
|
|
9
|
-
:class="theme.
|
|
10
|
-
class: [ui?.
|
|
11
|
-
})"
|
|
12
|
-
/>
|
|
13
|
-
<p
|
|
5
|
+
})"
|
|
6
|
+
>
|
|
7
|
+
<Icon
|
|
8
|
+
:name="icon"
|
|
9
|
+
:class="theme.iconSize({
|
|
10
|
+
class: [ui?.iconSize]
|
|
11
|
+
})"
|
|
12
|
+
/>
|
|
13
|
+
<p
|
|
14
14
|
:class="theme.message({
|
|
15
15
|
class: [ui?.message]
|
|
16
|
-
})"
|
|
17
|
-
v-html="message"
|
|
18
|
-
/>
|
|
19
|
-
</div>
|
|
16
|
+
})"
|
|
17
|
+
v-html="message"
|
|
18
|
+
/>
|
|
19
|
+
</div>
|
|
20
20
|
</template>
|
|
21
21
|
|
|
22
22
|
<script setup>
|
|
@@ -25,7 +25,7 @@ import { useUiConfig } from "#core/composables/useConfig";
|
|
|
25
25
|
import { emptyTheme } from "#core/theme/empty";
|
|
26
26
|
const props = defineProps({
|
|
27
27
|
message: { type: null, required: false, default: "\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25!" },
|
|
28
|
-
icon: { type: String, required: false },
|
|
28
|
+
icon: { type: String, required: false, default: "ph:table-thin" },
|
|
29
29
|
ui: { type: null, required: false },
|
|
30
30
|
class: { type: null, required: false }
|
|
31
31
|
});
|
|
@@ -7,5 +7,6 @@ type __VLS_Props = {
|
|
|
7
7
|
};
|
|
8
8
|
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
9
9
|
message: any;
|
|
10
|
+
icon: string;
|
|
10
11
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
11
12
|
export default _default;
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
3
|
:class="[theme.base({
|
|
4
4
|
class: [$props.class, ui?.base]
|
|
5
|
-
})]"
|
|
6
|
-
>
|
|
7
|
-
<component
|
|
8
|
-
:is="componentMap[option.type]
|
|
9
|
-
v-for="option in options.filter((item) => !item.isHide)"
|
|
10
|
-
:key="option.props.name"
|
|
11
|
-
:class="option.class"
|
|
12
|
-
:form="form"
|
|
13
|
-
v-bind="getFieldBinding(option)"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
</div>
|
|
5
|
+
})]"
|
|
6
|
+
>
|
|
7
|
+
<component
|
|
8
|
+
:is="componentMap[option.type]?.component"
|
|
9
|
+
v-for="option in options.filter((item) => !item.isHide)"
|
|
10
|
+
:key="option.props.name"
|
|
11
|
+
:class="option.class"
|
|
12
|
+
:form="form"
|
|
13
|
+
v-bind="{ ...getFieldBinding(option), ...componentMap[option.type]?.props }"
|
|
14
|
+
v-on="option.on ?? {}"
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
18
17
|
</template>
|
|
19
18
|
|
|
20
19
|
<script setup>
|
|
@@ -27,6 +26,7 @@ import FormInputCheckbox from "./InputCheckbox/index.vue";
|
|
|
27
26
|
import FormInputSelect from "./InputSelect/index.vue";
|
|
28
27
|
import FormInputSelectMultiple from "./InputSelectMultiple/index.vue";
|
|
29
28
|
import FormInputDateTime from "./InputDateTime/index.vue";
|
|
29
|
+
import FormInputDateTimeRange from "./InputDateTimeRange/index.vue";
|
|
30
30
|
import FormInputUploadDropzoneAuto from "./InputUploadDropzoneAuto/index.vue";
|
|
31
31
|
import { INPUT_TYPES } from "#core/components/Form/types";
|
|
32
32
|
import { formTheme } from "#core/theme/form";
|
|
@@ -39,32 +39,80 @@ const props = defineProps({
|
|
|
39
39
|
ui: { type: null, required: false }
|
|
40
40
|
});
|
|
41
41
|
const componentMap = {
|
|
42
|
-
[INPUT_TYPES.TEXT]:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
[INPUT_TYPES.
|
|
47
|
-
|
|
42
|
+
[INPUT_TYPES.TEXT]: {
|
|
43
|
+
component: FormInputText,
|
|
44
|
+
props: {}
|
|
45
|
+
},
|
|
46
|
+
[INPUT_TYPES.TEXTAREA]: {
|
|
47
|
+
component: FormInputTextarea,
|
|
48
|
+
props: {}
|
|
49
|
+
},
|
|
50
|
+
[INPUT_TYPES.TOGGLE]: {
|
|
51
|
+
component: FormInputToggle,
|
|
52
|
+
props: {}
|
|
53
|
+
},
|
|
54
|
+
[INPUT_TYPES.CHECKBOX]: {
|
|
55
|
+
component: FormInputCheckbox,
|
|
56
|
+
props: {}
|
|
57
|
+
},
|
|
58
|
+
[INPUT_TYPES.SELECT]: {
|
|
59
|
+
component: FormInputSelect,
|
|
60
|
+
props: {}
|
|
61
|
+
},
|
|
62
|
+
[INPUT_TYPES.SELECT_MULTIPLE]: {
|
|
63
|
+
component: FormInputSelectMultiple,
|
|
64
|
+
props: {}
|
|
65
|
+
},
|
|
48
66
|
// For INPUT_TYPES.COMPONENT, it will use option.component directly from the template
|
|
49
67
|
[INPUT_TYPES.COMPONENT]: void 0,
|
|
50
68
|
// Add other INPUT_TYPES here if they have dedicated components not covered by option.component
|
|
51
|
-
[INPUT_TYPES.NUMBER]:
|
|
69
|
+
[INPUT_TYPES.NUMBER]: {
|
|
70
|
+
component: FormInputNumber,
|
|
71
|
+
props: {}
|
|
72
|
+
},
|
|
52
73
|
// Example: Map to FormInputText or a specific Number input if exists
|
|
53
|
-
[INPUT_TYPES.PASSWORD]:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
74
|
+
[INPUT_TYPES.PASSWORD]: {
|
|
75
|
+
component: FormInputText,
|
|
76
|
+
props: {
|
|
77
|
+
type: "password"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
[INPUT_TYPES.EMAIL]: {
|
|
81
|
+
component: FormInputText,
|
|
82
|
+
props: {
|
|
83
|
+
type: "email"
|
|
84
|
+
}
|
|
85
|
+
},
|
|
57
86
|
[INPUT_TYPES.STATIC]: void 0,
|
|
58
87
|
[INPUT_TYPES.RADIO]: void 0,
|
|
59
|
-
[INPUT_TYPES.DATE_TIME]:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
88
|
+
[INPUT_TYPES.DATE_TIME]: {
|
|
89
|
+
component: FormInputDateTime,
|
|
90
|
+
props: {}
|
|
91
|
+
},
|
|
92
|
+
[INPUT_TYPES.DATE]: {
|
|
93
|
+
component: FormInputDateTime,
|
|
94
|
+
props: {
|
|
95
|
+
disabledTime: true
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
[INPUT_TYPES.DATE_RANGE]: {
|
|
99
|
+
component: FormInputDateTimeRange,
|
|
100
|
+
props: {
|
|
101
|
+
disabledTime: true
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
[INPUT_TYPES.DATE_TIME_RANGE]: {
|
|
105
|
+
component: FormInputDateTimeRange,
|
|
106
|
+
props: {}
|
|
107
|
+
},
|
|
63
108
|
[INPUT_TYPES.UPLOAD_FILE_CLASSIC]: void 0,
|
|
64
109
|
[INPUT_TYPES.UPLOAD_FILE_CLASSIC_AUTO]: void 0,
|
|
65
110
|
[INPUT_TYPES.UPLOAD_IMAGE_AUTO]: void 0,
|
|
66
111
|
[INPUT_TYPES.UPLOAD_DROPZONE]: void 0,
|
|
67
|
-
[INPUT_TYPES.UPLOAD_DROPZONE_AUTO]:
|
|
112
|
+
[INPUT_TYPES.UPLOAD_DROPZONE_AUTO]: {
|
|
113
|
+
component: FormInputUploadDropzoneAuto,
|
|
114
|
+
props: {}
|
|
115
|
+
},
|
|
68
116
|
[INPUT_TYPES.UPLOAD_DROPZONE_AUTO_MULTIPLE]: void 0,
|
|
69
117
|
[INPUT_TYPES.UPLOAD_DROPZONE_IMAGE_AUTO_MULTIPLE]: void 0,
|
|
70
118
|
[INPUT_TYPES.WYSIWYG]: void 0,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IDateTimeFieldProps } from '../InputDateTime/date_time_field.types.js';
|
|
2
|
+
import type { IFormFieldBase, INPUT_TYPES } from '#core/components/Form/types';
|
|
3
|
+
export interface ITimeOption {
|
|
4
|
+
hours?: number | string;
|
|
5
|
+
minutes?: number | string;
|
|
6
|
+
seconds?: number | string;
|
|
7
|
+
}
|
|
8
|
+
export interface IDateTimeRangeResponse {
|
|
9
|
+
start: Date | string;
|
|
10
|
+
end: Date | string;
|
|
11
|
+
}
|
|
12
|
+
export interface IDateTimeRangeFieldProps extends IDateTimeFieldProps {
|
|
13
|
+
isDisabledMultiCalendar?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export type IDateTimeRangeField = IFormFieldBase<INPUT_TYPES.DATE_RANGE | INPUT_TYPES.DATE_TIME_RANGE, IDateTimeRangeFieldProps, {
|
|
16
|
+
change: (value: IDateTimeRangeResponse) => void;
|
|
17
|
+
}>;
|
|
File without changes
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FieldWrapper v-bind="wrapperProps">
|
|
3
|
+
<Datepicker
|
|
4
|
+
ref="datepicker"
|
|
5
|
+
v-model="innerValueRef"
|
|
6
|
+
:disabled="wrapperProps.disabled"
|
|
7
|
+
cancel-text="ยกเลิก"
|
|
8
|
+
select-text="เลือก"
|
|
9
|
+
locale="th"
|
|
10
|
+
:format="format"
|
|
11
|
+
:enable-time-picker="!disabledTime"
|
|
12
|
+
:placeholder="wrapperProps.placeholder"
|
|
13
|
+
:min-date="minDate"
|
|
14
|
+
:max-date="maxDate"
|
|
15
|
+
:min-time="minTime"
|
|
16
|
+
:max-time="maxTime"
|
|
17
|
+
:start-time="startTime"
|
|
18
|
+
:multi-calendars="!isDisabledMultiCalendar"
|
|
19
|
+
:required="required"
|
|
20
|
+
time-picker-inline
|
|
21
|
+
range
|
|
22
|
+
:flow="['calendar', 'time']"
|
|
23
|
+
@update:model-value="onInput"
|
|
24
|
+
>
|
|
25
|
+
<template
|
|
26
|
+
v-if="appConfig.core?.is_thai_year"
|
|
27
|
+
#year="{ value }"
|
|
28
|
+
>
|
|
29
|
+
{{ value + 543 }}
|
|
30
|
+
</template>
|
|
31
|
+
<template
|
|
32
|
+
v-if="appConfig.core?.is_thai_year"
|
|
33
|
+
#year-overlay-value="{ value }"
|
|
34
|
+
>
|
|
35
|
+
{{ value + 543 }}
|
|
36
|
+
</template>
|
|
37
|
+
<template #dp-input="{ value: innerValue }">
|
|
38
|
+
<Input
|
|
39
|
+
:trailing-icon="innerValue ? void 0 : 'i-heroicons-calendar-days'"
|
|
40
|
+
type="text"
|
|
41
|
+
:model-value="innerValue"
|
|
42
|
+
:placeholder="wrapperProps.placeholder"
|
|
43
|
+
:readonly="true"
|
|
44
|
+
:ui="{
|
|
45
|
+
base: 'cursor-pointer select-none',
|
|
46
|
+
trailingIcon: 'cursor-pointer'
|
|
47
|
+
}"
|
|
48
|
+
/>
|
|
49
|
+
</template>
|
|
50
|
+
</Datepicker>
|
|
51
|
+
</FieldWrapper>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<script setup>
|
|
55
|
+
import Datepicker from "@vuepic/vue-datepicker";
|
|
56
|
+
import FieldWrapper from "#core/components/Form/FieldWrapper.vue";
|
|
57
|
+
import { TimeHelper, ref, useFieldHOC, useAppConfig } from "#imports";
|
|
58
|
+
import "@vuepic/vue-datepicker/dist/main.css";
|
|
59
|
+
const props = defineProps({
|
|
60
|
+
isDisabledMultiCalendar: { type: Boolean, required: false },
|
|
61
|
+
disabledTime: { type: Boolean, required: false },
|
|
62
|
+
minDate: { type: [Date, String], required: false },
|
|
63
|
+
maxDate: { type: [Date, String], required: false },
|
|
64
|
+
startTime: { type: Object, required: false },
|
|
65
|
+
minTime: { type: Object, required: false },
|
|
66
|
+
maxTime: { type: Object, required: false },
|
|
67
|
+
isReturnISO: { type: Boolean, required: false },
|
|
68
|
+
form: { type: Object, required: false },
|
|
69
|
+
name: { type: String, required: true },
|
|
70
|
+
errorMessage: { type: String, required: false },
|
|
71
|
+
label: { type: null, required: false },
|
|
72
|
+
description: { type: String, required: false },
|
|
73
|
+
hint: { type: String, required: false },
|
|
74
|
+
rules: { type: null, required: false },
|
|
75
|
+
autoFocus: { type: Boolean, required: false },
|
|
76
|
+
placeholder: { type: String, required: false },
|
|
77
|
+
disabled: { type: Boolean, required: false },
|
|
78
|
+
readonly: { type: Boolean, required: false },
|
|
79
|
+
required: { type: Boolean, required: false },
|
|
80
|
+
help: { type: String, required: false },
|
|
81
|
+
ui: { type: null, required: false }
|
|
82
|
+
});
|
|
83
|
+
const appConfig = useAppConfig();
|
|
84
|
+
const {
|
|
85
|
+
value,
|
|
86
|
+
wrapperProps
|
|
87
|
+
} = useFieldHOC(props);
|
|
88
|
+
const innerValueRef = ref([]);
|
|
89
|
+
const format = (date) => {
|
|
90
|
+
if (props.disabledTime) {
|
|
91
|
+
return date.length > 0 ? TimeHelper.displayDate(date[0]) + " - " + TimeHelper.displayDate(date[1] ?? date[0]) : "";
|
|
92
|
+
}
|
|
93
|
+
return date.length > 0 ? TimeHelper.displayDateTime(date[0]) + " - " + TimeHelper.displayDateTime(date[1] ?? date[0]) : "";
|
|
94
|
+
};
|
|
95
|
+
const onInput = (_value) => {
|
|
96
|
+
if (_value === null) {
|
|
97
|
+
value.value = null;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (props.disabledTime && !props.isReturnISO) {
|
|
101
|
+
value.value = {
|
|
102
|
+
start: TimeHelper.getDateFormTime(_value[0]),
|
|
103
|
+
end: TimeHelper.getDateFormTime(_value[1] || _value[0])
|
|
104
|
+
};
|
|
105
|
+
} else {
|
|
106
|
+
value.value = {
|
|
107
|
+
start: _value[0],
|
|
108
|
+
end: _value[1] || _value[0]
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
</script>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import '@vuepic/vue-datepicker/dist/main.css';
|
|
2
|
+
import type { IDateTimeRangeFieldProps } from './date_range_time_field.types.js';
|
|
3
|
+
declare const _default: import("vue").DefineComponent<IDateTimeRangeFieldProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<IDateTimeRangeFieldProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
4
|
+
export default _default;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Component } from '@nuxt/schema';
|
|
2
2
|
import type { FormContext } from 'vee-validate';
|
|
3
3
|
import type { IUploadDropzoneAutoField } from './InputUploadDropzoneAuto/types.js';
|
|
4
|
+
import type { IDateTimeRangeField } from './InputDateTimeRange/date_range_time_field.types.js';
|
|
4
5
|
import type { ITextField } from '#core/components/Form/InputText/types';
|
|
5
6
|
import type { ITextareaField } from '#core/components/Form/InputTextarea/types';
|
|
6
7
|
import type { IToggleField } from '#core/components/Form/InputToggle/types';
|
|
@@ -61,7 +62,7 @@ export interface IFormFieldBase<I extends INPUT_TYPES, P extends IFieldProps, O>
|
|
|
61
62
|
props: P;
|
|
62
63
|
on?: O;
|
|
63
64
|
}
|
|
64
|
-
export type IFormField = ITextField | INumberField | ITextareaField | IToggleField | ISelectField | ICheckboxField | ISelectMultipleField | IDateTimeField | IUploadDropzoneAutoField | IFormFieldBase<INPUT_TYPES.COMPONENT, any, any>;
|
|
65
|
+
export type IFormField = ITextField | INumberField | ITextareaField | IToggleField | ISelectField | ICheckboxField | ISelectMultipleField | IDateTimeField | IDateTimeRangeField | IUploadDropzoneAutoField | IFormFieldBase<INPUT_TYPES.COMPONENT, any, any>;
|
|
65
66
|
export interface IFileValue {
|
|
66
67
|
url: string;
|
|
67
68
|
path?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@import "tailwindcss";@import "@nuxt/ui"
|
|
1
|
+
@import "tailwindcss";@import "@nuxt/ui";:root{--dp-font-family:inherit!important}@theme static{--font-sans:"Noto Sans Thai","Noto Sans Thai Looped","Public Sans",sans-serif;--color-main:#232c5a;--color-main-50:#f4f4f7;--color-main-100:#e9eaef;--color-main-200:#c8cad6;--color-main-300:#a7abbd;--color-main-400:#656b8c;--color-main-500:#232c5a;--color-main-600:#202851;--color-main-700:#151a36;--color-main-800:#101429;--color-main-900:#0b0d1b;--color-main-950:#0b0d1b;--color-secondary:#ee8b36;--color-secondary-50:#fdf1e7;--color-secondary-100:#f9d6b8;--color-secondary-200:#f5bb89;--color-secondary-300:#f1a05a;--color-secondary-400:#ed852b;--color-secondary-500:#d46b12;--color-secondary-600:#a5540e;--color-secondary-700:#763c0a;--color-secondary-800:#472406;--color-secondary-900:#180c02;--color-info:#0d8cee;--color-info-50:#f3f9fe;--color-info-100:#e7f4fd;--color-info-200:#ebf6ff;--color-info-300:#9ed1f8;--color-info-400:#56aff3;--color-info-500:#0d8cee;--color-info-600:#0c7ed6;--color-info-700:#08548f;--color-info-800:#063f6b;--color-info-900:#042a47;--color-error:#f25555;--color-error-50:#fef7f7;--color-error-100:#feeeee;--color-error-200:#ffdfdf;--color-error-300:#fabbbb;--color-error-400:#f68888;--color-error-500:#f25555;--color-error-600:#da4d4d;--color-error-700:#913333;--color-error-800:#6d2626;--color-error-900:#491a1a;--color-success:#3fb061;--color-success-50:#f5fbf7;--color-success-100:#ecf7ef;--color-success-200:#daeee0;--color-success-300:#b2dfc0;--color-success-400:#79c890;--color-success-500:#3fb061;--color-success-600:#399e57;--color-success-700:#266a3a;--color-success-800:#1c4f2c;--color-success-900:#13351d;--color-warning:#ff9a35;--color-warning-50:#fffaf5;--color-warning-100:#fff5eb;--color-warning-200:#fef1cc;--color-warning-300:#ffd7ae;--color-warning-400:#ffb872;--color-warning-500:#ff9a35;--color-warning-600:#e68b30;--color-warning-700:#995c20;--color-warning-800:#734518;--color-warning-900:#4d2e10}#__nuxt,body,html{@apply w-full h-full}
|