@finema/core 1.4.52 → 1.4.54
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/Form/InputDateTime/index.vue +3 -2
- package/dist/runtime/components/Form/InputUploadFileClassic/index.vue +85 -20
- package/dist/runtime/components/Table/Base.vue +2 -4
- package/dist/runtime/components/Table/ColumnImage.vue +3 -1
- package/dist/runtime/components/Table/ColumnText.vue +25 -0
- package/dist/runtime/components/Table/types.d.ts +4 -18
- package/dist/runtime/components/Table/types.mjs +0 -1
- package/dist/runtime/composables/useForm.d.ts +2 -2
- package/dist/runtime/composables/useTable.d.ts +2 -2
- package/dist/runtime/composables/useTable.mjs +2 -3
- package/dist/runtime/utils/lodash.d.ts +9 -0
- package/dist/runtime/utils/lodash.mjs +5 -1
- package/package.json +8 -2
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
:start-time="startTime"
|
|
17
17
|
:required="isRequired"
|
|
18
18
|
time-picker-inline
|
|
19
|
+
@update:model-value="value = $event"
|
|
19
20
|
>
|
|
20
21
|
<template #dp-input="{ value: innerValue }">
|
|
21
22
|
<UInput
|
|
@@ -43,9 +44,9 @@ const { value, wrapperProps } = useFieldHOC<string>(props)
|
|
|
43
44
|
|
|
44
45
|
const format = (date: Date) => {
|
|
45
46
|
if (props.disabledTime) {
|
|
46
|
-
return TimeHelper.
|
|
47
|
+
return TimeHelper.displayDate(date)
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
return TimeHelper.
|
|
50
|
+
return TimeHelper.displayDateTime(date)
|
|
50
51
|
}
|
|
51
52
|
</script>
|
|
@@ -1,36 +1,101 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<FieldWrapper v-bind="wrapperProps">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
<div :class="[ui.base]">
|
|
4
|
+
<input
|
|
5
|
+
ref="fileInput"
|
|
6
|
+
type="file"
|
|
7
|
+
class="hidden"
|
|
8
|
+
:accept="acceptFile"
|
|
9
|
+
:required="isRequired"
|
|
10
|
+
:disabled="isDisabled"
|
|
11
|
+
@change="handleChange"
|
|
12
|
+
/>
|
|
13
|
+
<div :class="[ui.wrapper]">
|
|
14
|
+
<div :class="[ui.selectFileBox]">
|
|
15
|
+
<Button size="2xs" @click="handleOpenFile">{{ selectFileLabel || 'Choose File' }}</Button>
|
|
16
|
+
<p :class="ui.placeholder">
|
|
17
|
+
{{ value?.name ?? placeholder ?? 'No file chosen' }}
|
|
18
|
+
</p>
|
|
19
|
+
<Badge v-if="value" size="xs" variant="outline">
|
|
20
|
+
{{ isSelectedFileUseMb ? `${selectedFileSizeMb} MB` : `${selectedFileSizeKb} KB` }}
|
|
21
|
+
</Badge>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
19
25
|
</FieldWrapper>
|
|
20
26
|
</template>
|
|
21
27
|
<script lang="ts" setup>
|
|
22
28
|
import { useFieldHOC } from '#core/composables/useForm'
|
|
23
29
|
import FieldWrapper from '#core/components/Form/FieldWrapper.vue'
|
|
24
30
|
import { type IUploadFileClassicFieldProps } from '#core/components/Form/InputUploadFileClassic/types'
|
|
31
|
+
import { useUiConfig } from '#core/composables/useConfig'
|
|
32
|
+
import { uploadFileInputClassicAuto } from '#core/ui.config'
|
|
33
|
+
import { computed, ref, toRef, useUI } from '#imports'
|
|
34
|
+
import i18next from 'i18next'
|
|
25
35
|
|
|
36
|
+
const config = useUiConfig<typeof uploadFileInputClassicAuto>(
|
|
37
|
+
uploadFileInputClassicAuto,
|
|
38
|
+
'uploadFileInputClassicAuto'
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
const emits = defineEmits(['change'])
|
|
26
42
|
const props = withDefaults(defineProps<IUploadFileClassicFieldProps>(), {})
|
|
27
43
|
|
|
28
|
-
const { value, wrapperProps } = useFieldHOC<File | undefined>(props)
|
|
44
|
+
const { value, wrapperProps, setErrors } = useFieldHOC<File | undefined>(props)
|
|
45
|
+
const selectedFileSizeKb = computed(() => ((value.value?.size || 0) / 1000).toFixed(2))
|
|
46
|
+
const selectedFileSizeMb = computed(() => ((value.value?.size || 0) / 1000 / 1000).toFixed(2))
|
|
29
47
|
|
|
30
|
-
const
|
|
48
|
+
const isSelectedFileUseMb = computed(() => (value.value?.size || 0) / 1000 > 1024)
|
|
49
|
+
const isAcceptFileUseMb = computed(() => acceptFileSizeKb.value && acceptFileSizeKb.value > 1024)
|
|
50
|
+
const acceptFileSizeMb = computed(() => ((acceptFileSizeKb.value || 0) / 1024).toFixed(2))
|
|
51
|
+
const acceptFileSizeKb = computed(() => props.maxSize)
|
|
52
|
+
const acceptFile = computed(() =>
|
|
53
|
+
typeof props.accept === 'string' ? props.accept : props.accept?.join(',')
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
const fileInput = ref<HTMLInputElement>()
|
|
57
|
+
|
|
58
|
+
const handleOpenFile = () => {
|
|
59
|
+
fileInput.value?.click()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const { ui } = useUI('uploadFileInputClassicAuto', toRef(props, 'ui'), config)
|
|
63
|
+
|
|
64
|
+
const checkMaxSize = (file: File): boolean => {
|
|
65
|
+
if (acceptFileSizeKb.value) {
|
|
66
|
+
return file.size / 1000 <= acceptFileSizeKb.value
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return true
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const handleCheckFileCondition = (file: File | undefined): boolean => {
|
|
73
|
+
if (!file) return false
|
|
74
|
+
|
|
75
|
+
const maxSize = checkMaxSize(file)
|
|
76
|
+
|
|
77
|
+
if (!maxSize) {
|
|
78
|
+
if (isAcceptFileUseMb.value) {
|
|
79
|
+
setErrors(i18next.t('custom:invalid_file_size_mb', { size: acceptFileSizeMb.value }))
|
|
80
|
+
} else {
|
|
81
|
+
setErrors(i18next.t('custom:invalid_file_size_kb', { size: acceptFileSizeKb.value }))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return false
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
setErrors('')
|
|
88
|
+
|
|
89
|
+
return true
|
|
90
|
+
}
|
|
31
91
|
|
|
32
92
|
const handleChange = (e: Event) => {
|
|
33
|
-
|
|
34
|
-
|
|
93
|
+
const file = (e.target as HTMLInputElement).files?.[0]
|
|
94
|
+
const result = handleCheckFileCondition(file)
|
|
95
|
+
|
|
96
|
+
if (result && file) {
|
|
97
|
+
value.value = file
|
|
98
|
+
emits('change', file)
|
|
99
|
+
}
|
|
35
100
|
}
|
|
36
101
|
</script>
|
|
@@ -42,10 +42,7 @@
|
|
|
42
42
|
:column="column"
|
|
43
43
|
:row="row"
|
|
44
44
|
/>
|
|
45
|
-
|
|
46
|
-
<template v-else>
|
|
47
|
-
<span :title="row[column.key]">{{ row[column.key] ?? '-' }}</span>
|
|
48
|
-
</template>
|
|
45
|
+
<ColumnText v-else :value="row[column.key]" :column="column" :row="row" />
|
|
49
46
|
</template>
|
|
50
47
|
|
|
51
48
|
<template v-for="(_, slot) of $slots" #[slot]="scope">
|
|
@@ -80,6 +77,7 @@ import { StringHelper } from '#core/utils/StringHelper'
|
|
|
80
77
|
import { ref, watch } from '#imports'
|
|
81
78
|
import ColumnDateTime from '#core/components/Table/ColumnDateTime.vue'
|
|
82
79
|
import ColumnDate from '#core/components/Table/ColumnDate.vue'
|
|
80
|
+
import ColumnText from '#core/components/Table/ColumnText.vue'
|
|
83
81
|
|
|
84
82
|
const emits = defineEmits(['pageChange'])
|
|
85
83
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<template>{{ getValue }}</template>
|
|
2
|
+
<script lang="ts" setup>
|
|
3
|
+
import { computed } from 'vue'
|
|
4
|
+
import { type IColumn } from '#core/components/Table/types'
|
|
5
|
+
import { StringHelper } from '#imports'
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
value: any
|
|
9
|
+
row: any
|
|
10
|
+
column: IColumn<{
|
|
11
|
+
max?: number
|
|
12
|
+
}>
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const getValue = computed<string>(() => {
|
|
16
|
+
const value = props.value
|
|
17
|
+
const max = props.column.props?.max
|
|
18
|
+
|
|
19
|
+
if (max) {
|
|
20
|
+
return StringHelper.truncate(value, max)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return value ?? '-'
|
|
24
|
+
})
|
|
25
|
+
</script>
|
|
@@ -4,10 +4,9 @@ export declare const enum COLUMN_TYPES {
|
|
|
4
4
|
DATE = "DATE",
|
|
5
5
|
DATE_TIME = "DATE_TIME",
|
|
6
6
|
NUMBER = "NUMBER",
|
|
7
|
-
IMAGE = "IMAGE"
|
|
8
|
-
ACTION = "ACTION"
|
|
7
|
+
IMAGE = "IMAGE"
|
|
9
8
|
}
|
|
10
|
-
export interface IColumn {
|
|
9
|
+
export interface IColumn<P extends Record<string, any> = Record<string, any>, O extends Record<string, any> = Record<string, any>> {
|
|
11
10
|
[key: string]: any;
|
|
12
11
|
key: string;
|
|
13
12
|
sortable?: boolean;
|
|
@@ -15,27 +14,14 @@ export interface IColumn {
|
|
|
15
14
|
class?: string;
|
|
16
15
|
component?: any;
|
|
17
16
|
type?: COLUMN_TYPES;
|
|
17
|
+
props?: P;
|
|
18
|
+
on?: O;
|
|
18
19
|
}
|
|
19
|
-
export interface IRowItem {
|
|
20
|
-
value: string | any;
|
|
21
|
-
type?: COLUMN_TYPES;
|
|
22
|
-
title?: string;
|
|
23
|
-
className?: string;
|
|
24
|
-
isSelect?: boolean;
|
|
25
|
-
props?: Record<string, any>;
|
|
26
|
-
on?: Record<string, any>;
|
|
27
|
-
}
|
|
28
|
-
export type IRow = Record<number, IRowItem>;
|
|
29
20
|
export interface IBaseTableOptions<T = object> {
|
|
30
21
|
rawData: T[];
|
|
31
22
|
primary: string;
|
|
32
23
|
status: IStatus;
|
|
33
24
|
columns: IColumn[];
|
|
34
|
-
onRowClick?: (index: number, columns: Array<{
|
|
35
|
-
value: string;
|
|
36
|
-
}>) => void;
|
|
37
|
-
onCheckBoxClick?: (index: number[]) => void;
|
|
38
|
-
disabledCheckIndexes?: number[];
|
|
39
25
|
}
|
|
40
26
|
export interface ITableOptions<T = object> extends IBaseTableOptions<T> {
|
|
41
27
|
pageOptions: IPageOptions;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type ComputedRef } from 'vue';
|
|
2
2
|
import { type FieldContext, type FieldOptions } from 'vee-validate';
|
|
3
|
-
import { type IFieldProps
|
|
3
|
+
import { type IFieldProps } from '../components/Form/types';
|
|
4
4
|
interface IFieldContext<TValue> extends FieldContext<TValue> {
|
|
5
5
|
wrapperProps: ComputedRef<IFieldProps>;
|
|
6
6
|
}
|
|
7
7
|
export declare const useFieldHOC: <TValue = unknown>(newFormProps: IFieldProps, opts?: Partial<FieldOptions<TValue>> | undefined) => IFieldContext<TValue>;
|
|
8
|
-
export declare const createFormFields: (fields: () =>
|
|
8
|
+
export declare const createFormFields: <T extends unknown>(fields: () => T[]) => ComputedRef<T[]>;
|
|
9
9
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ComputedRef } from 'vue';
|
|
2
2
|
import { type Store } from 'pinia';
|
|
3
3
|
import { type IStatus } from '#imports';
|
|
4
|
-
import { type IColumn, type
|
|
4
|
+
import { type IColumn, type ISimpleTableOptions, type ITableOptions } from '../components/Table/types';
|
|
5
5
|
import { type IUsePageLoader } from '../helpers/apiPageHelper';
|
|
6
6
|
export interface IUseTable<T = object> {
|
|
7
7
|
repo: IUsePageLoader<T> | Store<any, any>;
|
|
@@ -16,4 +16,4 @@ export interface IUseTableSimple<T = object> {
|
|
|
16
16
|
}
|
|
17
17
|
export declare const useTable: <T = object>(options: IUseTable<T>) => ComputedRef<ITableOptions<T>>;
|
|
18
18
|
export declare const useTableSimple: <T = object>(options: IUseTableSimple<T>) => ComputedRef<ISimpleTableOptions<T>>;
|
|
19
|
-
export declare const createTableOptions: <T = object>(repo: IUsePageLoader<T>, columns: IColumn[],
|
|
19
|
+
export declare const createTableOptions: <T = object>(repo: IUsePageLoader<T>, columns: IColumn[], options: Partial<ITableOptions<T>>) => ITableOptions<T>;
|
|
@@ -5,7 +5,6 @@ export const useTable = (options) => computed(() => {
|
|
|
5
5
|
return createTableOptions(
|
|
6
6
|
options.repo,
|
|
7
7
|
options.columns(),
|
|
8
|
-
get(options.repo.fetchItems),
|
|
9
8
|
typeof options.options === "function" ? options.options() : options.options ?? {}
|
|
10
9
|
);
|
|
11
10
|
});
|
|
@@ -20,7 +19,7 @@ export const useTableSimple = (options) => computed(() => {
|
|
|
20
19
|
...typeof options.options === "function" ? options.options() : options.options ?? {}
|
|
21
20
|
};
|
|
22
21
|
});
|
|
23
|
-
export const createTableOptions = (repo, columns,
|
|
22
|
+
export const createTableOptions = (repo, columns, options) => {
|
|
24
23
|
const config = useCoreConfig();
|
|
25
24
|
return {
|
|
26
25
|
rawData: get(repo.fetchItems),
|
|
@@ -29,7 +28,7 @@ export const createTableOptions = (repo, columns, rows, options) => {
|
|
|
29
28
|
status: get(repo.fetchStatus),
|
|
30
29
|
deleteStatus: get(repo.deleteStatus),
|
|
31
30
|
primary: get(repo.fetchOptions).primary ?? config.default_primary_key,
|
|
32
|
-
|
|
31
|
+
isPreventRouteChange: false,
|
|
33
32
|
...options
|
|
34
33
|
};
|
|
35
34
|
};
|
|
@@ -106,6 +106,15 @@ export declare const _fromPairs: {
|
|
|
106
106
|
(pairs: import("lodash").List<any[]> | null | undefined): import("lodash").Dictionary<any>;
|
|
107
107
|
};
|
|
108
108
|
export declare const _xor: <T>(...arrays: (import("lodash").List<T> | null | undefined)[]) => T[];
|
|
109
|
+
export declare const _omit: {
|
|
110
|
+
<T extends object, K extends import("lodash").PropertyName[]>(object: T | null | undefined, ...paths: K): Pick<T, Exclude<keyof T, K[number]>>;
|
|
111
|
+
<T_1 extends object, K_1 extends keyof T_1>(object: T_1 | null | undefined, ...paths: import("lodash").Many<K_1>[]): import("lodash").Omit<T_1, K_1>;
|
|
112
|
+
<T_2 extends object>(object: T_2 | null | undefined, ...paths: import("lodash").Many<import("lodash").PropertyName>[]): Partial<T_2>;
|
|
113
|
+
};
|
|
114
|
+
export declare const _pick: {
|
|
115
|
+
<T extends object, U extends keyof T>(object: T, ...props: import("lodash").Many<U>[]): Pick<T, U>;
|
|
116
|
+
<T_1>(object: T_1 | null | undefined, ...props: import("lodash").Many<import("lodash").PropertyPath>[]): Partial<T_1>;
|
|
117
|
+
};
|
|
109
118
|
export declare const _clone: (object: any) => any;
|
|
110
119
|
export declare const _debounce: <T extends (...args: any[]) => any>(func: T, wait?: number) => import("lodash").DebouncedFunc<T>;
|
|
111
120
|
export declare const _deepMerge: (target: any, ...sources: any[]) => any;
|
|
@@ -27,7 +27,9 @@ import {
|
|
|
27
27
|
xor,
|
|
28
28
|
debounce,
|
|
29
29
|
intersection,
|
|
30
|
-
get
|
|
30
|
+
get,
|
|
31
|
+
omit,
|
|
32
|
+
pick
|
|
31
33
|
} from "lodash-es";
|
|
32
34
|
export const _get = get;
|
|
33
35
|
export const _range = range;
|
|
@@ -57,6 +59,8 @@ export const _toPairs = toPairs;
|
|
|
57
59
|
export const _orderBy = orderBy;
|
|
58
60
|
export const _fromPairs = fromPairs;
|
|
59
61
|
export const _xor = xor;
|
|
62
|
+
export const _omit = omit;
|
|
63
|
+
export const _pick = pick;
|
|
60
64
|
export const _clone = (object) => {
|
|
61
65
|
try {
|
|
62
66
|
return JSON.parse(JSON.stringify(object || {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finema/core",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.54",
|
|
4
4
|
"repository": "https://gitlab.finema.co/finema/ui-kit",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Finema Dev Core Team",
|
|
@@ -74,10 +74,16 @@
|
|
|
74
74
|
"stylelint": "^16.1.0",
|
|
75
75
|
"stylelint-config-prettier-scss": "^1.0.0",
|
|
76
76
|
"stylelint-config-standard-scss": "^13.0.0",
|
|
77
|
-
"vitest": "^1.2.2"
|
|
77
|
+
"vitest": "^1.2.2",
|
|
78
|
+
"vue": "3.4.8"
|
|
78
79
|
},
|
|
79
80
|
"lint-staged": {
|
|
80
81
|
"*.{ts,vue,tsx,js}": "eslint --fix --cache",
|
|
81
82
|
"*.{html,json}": "prettier --write"
|
|
83
|
+
},
|
|
84
|
+
"pnpm": {
|
|
85
|
+
"overrides": {
|
|
86
|
+
"vue": "3.4.8"
|
|
87
|
+
}
|
|
82
88
|
}
|
|
83
89
|
}
|