@finema/core 1.2.2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -38
- package/dist/module.d.mts +30 -0
- package/dist/module.d.ts +30 -0
- package/dist/module.json +2 -2
- package/dist/module.mjs +151 -4
- package/dist/runtime/components/Button/Group.vue +31 -0
- package/dist/runtime/components/Button/index.vue +17 -0
- package/dist/runtime/components/Dialog/index.vue +63 -0
- package/dist/runtime/components/Form/FieldWrapper.vue +10 -0
- package/dist/runtime/components/Form/Fields.vue +41 -0
- package/dist/runtime/components/Form/InputSelect/SelectMenu.vue +11 -0
- package/dist/runtime/components/Form/InputSelect/index.vue +11 -0
- package/dist/runtime/components/Form/InputStatic/index.vue +16 -0
- package/dist/runtime/components/Form/InputStatic/types.d.ts +4 -0
- package/dist/runtime/components/Form/InputText/index.vue +28 -0
- package/dist/runtime/components/Form/InputText/types.d.ts +10 -0
- package/dist/runtime/components/Form/InputText/types.mjs +0 -0
- package/dist/runtime/components/Form/InputToggle/index.vue +14 -0
- package/dist/runtime/components/Form/InputToggle/types.d.ts +6 -0
- package/dist/runtime/components/Form/InputToggle/types.mjs +0 -0
- package/dist/runtime/components/Form/index.vue +6 -0
- package/dist/runtime/components/Form/types.d.ts +47 -0
- package/dist/runtime/components/Form/types.mjs +8 -0
- package/dist/runtime/components/Icon.vue +11 -0
- package/dist/runtime/components/Loader.vue +6 -0
- package/dist/runtime/components/Modal/index.vue +145 -0
- package/dist/runtime/components/Slideover/index.vue +109 -0
- package/dist/runtime/components/Table/ColumnImage.vue +13 -0
- package/dist/runtime/components/Table/ColumnNumber.vue +14 -0
- package/dist/runtime/components/Table/index.vue +84 -0
- package/dist/runtime/components/Table/types.d.ts +57 -0
- package/dist/runtime/components/Table/types.mjs +10 -0
- package/dist/runtime/{lib/api → composables}/loaderList.d.ts +0 -1
- package/dist/runtime/{lib/api → composables}/loaderList.mjs +2 -2
- package/dist/runtime/{lib/api → composables}/loaderObject.d.ts +0 -1
- package/dist/runtime/{lib/api → composables}/loaderObject.mjs +2 -2
- package/dist/runtime/{lib/api → composables}/loaderPage.d.ts +4 -2
- package/dist/runtime/{lib/api → composables}/loaderPage.mjs +17 -8
- package/dist/runtime/composables/useConfig.d.ts +3 -0
- package/dist/runtime/composables/useConfig.mjs +9 -0
- package/dist/runtime/composables/useDialog.d.ts +26 -0
- package/dist/runtime/composables/useDialog.mjs +81 -0
- package/dist/runtime/composables/useForm.d.ts +24 -0
- package/dist/runtime/composables/useForm.mjs +44 -0
- package/dist/runtime/composables/useTable.d.ts +18 -0
- package/dist/runtime/composables/useTable.mjs +35 -0
- package/dist/runtime/composables/useWatch.d.ts +3 -0
- package/dist/runtime/composables/useWatch.mjs +22 -0
- package/dist/runtime/core.config.d.ts +4 -0
- package/dist/runtime/core.config.mjs +4 -0
- package/dist/runtime/{lib/api → helpers}/apiListHelper.d.ts +3 -3
- package/dist/runtime/{lib/api → helpers}/apiListHelper.mjs +3 -3
- package/dist/runtime/{lib/api → helpers}/apiObjectHelper.d.ts +3 -3
- package/dist/runtime/{lib/api → helpers}/apiObjectHelper.mjs +3 -3
- package/dist/runtime/{lib/api → helpers}/apiPageHelper.d.ts +4 -4
- package/dist/runtime/{lib/api → helpers}/apiPageHelper.mjs +7 -6
- package/dist/runtime/plugin.mjs +1 -1
- package/dist/runtime/types/common.d.ts +6 -8
- package/dist/runtime/types/common.mjs +0 -0
- package/dist/runtime/types/config.d.ts +1 -0
- package/dist/runtime/types/config.mjs +0 -0
- package/dist/runtime/types/lib.d.ts +63 -76
- package/dist/runtime/types/lib.mjs +0 -0
- package/dist/runtime/{lib/api → types}/loaderTypes.d.ts +1 -1
- package/dist/runtime/types/loaderTypes.mjs +0 -0
- package/dist/runtime/types/utils.d.ts +9 -0
- package/dist/runtime/ui.config.d.ts +2 -0
- package/dist/runtime/ui.config.mjs +44 -0
- package/dist/runtime/ui.css +14 -0
- package/dist/runtime/utils/StringHelper.mjs +1 -1
- package/dist/runtime/utils/lodash.d.ts +7 -0
- package/dist/runtime/utils/lodash.mjs +1 -0
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +13 -12
- package/dist/runtime/composables/useLibs.d.ts +0 -24
- package/dist/runtime/composables/useLibs.mjs +0 -4
- package/dist/runtime/composables/useUtils.d.ts +0 -10
- package/dist/runtime/composables/useUtils.mjs +0 -12
- package/dist/runtime/lib/api/config.d.ts +0 -4
- package/dist/runtime/lib/api/config.mjs +0 -4
- package/dist/runtime/lib/index.d.ts +0 -8
- package/dist/runtime/lib/index.mjs +0 -8
- /package/dist/runtime/{lib/api/loaderTypes.mjs → components/Form/InputStatic/types.mjs} +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type Component } from '@nuxt/schema';
|
|
2
|
+
import { type FormContext, type RuleExpression } from 'vee-validate';
|
|
3
|
+
import { type ITextField } from '#core/components/Form/InputText/types';
|
|
4
|
+
import { type IStaticField } from '#core/components/Form/InputStatic/types';
|
|
5
|
+
export declare const enum INPUT_TYPES {
|
|
6
|
+
TEXT = "TEXT",
|
|
7
|
+
PASSWORD = "PASSWORD",
|
|
8
|
+
STATIC = "STATIC",
|
|
9
|
+
TOGGLE = "TOGGLE",
|
|
10
|
+
SELECT = "SELECT"
|
|
11
|
+
}
|
|
12
|
+
export interface IOption {
|
|
13
|
+
label: string;
|
|
14
|
+
value: any;
|
|
15
|
+
}
|
|
16
|
+
export interface IRadioOption {
|
|
17
|
+
label: string | any;
|
|
18
|
+
value: any;
|
|
19
|
+
}
|
|
20
|
+
export interface IFieldProps {
|
|
21
|
+
form?: FormContext;
|
|
22
|
+
name: string;
|
|
23
|
+
label?: string | any;
|
|
24
|
+
rules?: RuleExpression<any> | any;
|
|
25
|
+
autoFocus?: boolean;
|
|
26
|
+
class?: any;
|
|
27
|
+
classInner?: any;
|
|
28
|
+
classInputInner?: any;
|
|
29
|
+
placeholder?: string;
|
|
30
|
+
isDisabled?: boolean;
|
|
31
|
+
isReadOnly?: boolean;
|
|
32
|
+
isLoading?: boolean;
|
|
33
|
+
help?: string;
|
|
34
|
+
isHideLabel?: boolean;
|
|
35
|
+
customErrorMessage?: string | any;
|
|
36
|
+
transform?: (value: any, oldValue: any, e: InputEvent) => any;
|
|
37
|
+
getInstance?: (el: HTMLElement) => void;
|
|
38
|
+
}
|
|
39
|
+
export interface IFormFieldBase<I extends INPUT_TYPES, P extends object = never, O extends object = never> {
|
|
40
|
+
type: I | INPUT_TYPES;
|
|
41
|
+
component?: Component;
|
|
42
|
+
class?: any;
|
|
43
|
+
isHide?: boolean;
|
|
44
|
+
props: IFieldProps & P;
|
|
45
|
+
on?: O;
|
|
46
|
+
}
|
|
47
|
+
export type IFormField = ITextField | IStaticField;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export var INPUT_TYPES = /* @__PURE__ */ ((INPUT_TYPES2) => {
|
|
2
|
+
INPUT_TYPES2["TEXT"] = "TEXT";
|
|
3
|
+
INPUT_TYPES2["PASSWORD"] = "PASSWORD";
|
|
4
|
+
INPUT_TYPES2["STATIC"] = "STATIC";
|
|
5
|
+
INPUT_TYPES2["TOGGLE"] = "TOGGLE";
|
|
6
|
+
INPUT_TYPES2["SELECT"] = "SELECT";
|
|
7
|
+
return INPUT_TYPES2;
|
|
8
|
+
})(INPUT_TYPES || {});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<UModal
|
|
3
|
+
v-bind="attrs"
|
|
4
|
+
:model-value="modelValue"
|
|
5
|
+
:overlay="overlay"
|
|
6
|
+
:transition="transition"
|
|
7
|
+
:prevent-close="preventClose"
|
|
8
|
+
:fullscreen="fullscreen"
|
|
9
|
+
:initial-focus="modalWrapper"
|
|
10
|
+
:ui="ui"
|
|
11
|
+
@update:model-value="$emit('update:modelValue', $event)"
|
|
12
|
+
>
|
|
13
|
+
<div
|
|
14
|
+
v-if="title"
|
|
15
|
+
:class="[ui.header, { 'flex items-center justify-between': !isHideCloseBtn }]"
|
|
16
|
+
>
|
|
17
|
+
<h1 class="text-xl font-medium">{{ title }}</h1>
|
|
18
|
+
<Icon
|
|
19
|
+
v-if="!isHideCloseBtn"
|
|
20
|
+
name="i-heroicons-x-mark"
|
|
21
|
+
class="h-6 w-6 cursor-pointer"
|
|
22
|
+
@click="close"
|
|
23
|
+
/>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
v-if="(!title && !isHideCloseBtn && preventClose) || fullscreen"
|
|
28
|
+
class="absolute right-0 m-4"
|
|
29
|
+
>
|
|
30
|
+
<Icon
|
|
31
|
+
v-if="!isHideCloseBtn"
|
|
32
|
+
name="i-heroicons-x-mark"
|
|
33
|
+
class="h-6 w-6 cursor-pointer"
|
|
34
|
+
@click="close"
|
|
35
|
+
/>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div ref="modalWrapper" :class="['overflow-y-auto', ui.innerWrapper]">
|
|
39
|
+
<slot />
|
|
40
|
+
</div>
|
|
41
|
+
</UModal>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<script lang="ts" setup>
|
|
45
|
+
import { type PropType, defineShortcuts, ref, toRef, watch } from '#imports'
|
|
46
|
+
import type { Strategy } from '#core/types/utils'
|
|
47
|
+
import { useUI } from '#ui/composables/useUI'
|
|
48
|
+
import { modal } from '#core/ui.config'
|
|
49
|
+
import { useUiConfig } from '#core/composables/useConfig'
|
|
50
|
+
|
|
51
|
+
const config = useUiConfig<typeof modal>(modal, 'modal')
|
|
52
|
+
|
|
53
|
+
const props = defineProps({
|
|
54
|
+
modelValue: {
|
|
55
|
+
type: Boolean,
|
|
56
|
+
default: false,
|
|
57
|
+
},
|
|
58
|
+
overlay: {
|
|
59
|
+
type: Boolean,
|
|
60
|
+
default: true,
|
|
61
|
+
},
|
|
62
|
+
transition: {
|
|
63
|
+
type: Boolean,
|
|
64
|
+
default: true,
|
|
65
|
+
},
|
|
66
|
+
preventClose: {
|
|
67
|
+
type: Boolean,
|
|
68
|
+
default: false,
|
|
69
|
+
},
|
|
70
|
+
fullscreen: {
|
|
71
|
+
type: Boolean,
|
|
72
|
+
default: false,
|
|
73
|
+
},
|
|
74
|
+
scrollable: {
|
|
75
|
+
type: Boolean,
|
|
76
|
+
default: false,
|
|
77
|
+
},
|
|
78
|
+
title: {
|
|
79
|
+
type: String,
|
|
80
|
+
default: '',
|
|
81
|
+
},
|
|
82
|
+
isHideCloseBtn: {
|
|
83
|
+
type: Boolean,
|
|
84
|
+
default: false,
|
|
85
|
+
},
|
|
86
|
+
size: {
|
|
87
|
+
type: String as PropType<keyof typeof modal.size>,
|
|
88
|
+
default: () => modal.default.size,
|
|
89
|
+
},
|
|
90
|
+
position: {
|
|
91
|
+
type: String as PropType<keyof typeof modal.position>,
|
|
92
|
+
default: () => modal.default.position,
|
|
93
|
+
},
|
|
94
|
+
fixHeightSize: {
|
|
95
|
+
type: String as PropType<keyof typeof modal.fixHeightSize>,
|
|
96
|
+
default: () => modal.default.fixHeightSize,
|
|
97
|
+
},
|
|
98
|
+
class: {
|
|
99
|
+
type: [String, Array, Object] as PropType<any>,
|
|
100
|
+
default: undefined,
|
|
101
|
+
},
|
|
102
|
+
ui: {
|
|
103
|
+
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
|
|
104
|
+
default: undefined,
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
const emits = defineEmits(['update:modelValue'])
|
|
109
|
+
|
|
110
|
+
defineShortcuts({
|
|
111
|
+
escape: {
|
|
112
|
+
usingInput: true,
|
|
113
|
+
handler: () => {
|
|
114
|
+
if (props.preventClose) return
|
|
115
|
+
emits('update:modelValue', false)
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
const modalWrapper = ref<HTMLElement | null>(null)
|
|
121
|
+
|
|
122
|
+
const close = () => {
|
|
123
|
+
emits('update:modelValue', false)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const { ui, attrs } = useUI('modal', toRef(props, 'ui'), config, toRef(props, 'class'))
|
|
127
|
+
|
|
128
|
+
watch(
|
|
129
|
+
() => props.modelValue,
|
|
130
|
+
() => {
|
|
131
|
+
if (props.modelValue) {
|
|
132
|
+
const size = config.size[props.size]
|
|
133
|
+
const fixHeightSize = config.fixHeightSize[props.fixHeightSize]
|
|
134
|
+
const position = config.position[props.position]
|
|
135
|
+
|
|
136
|
+
ui.value.width = size
|
|
137
|
+
ui.value.container = position
|
|
138
|
+
|
|
139
|
+
if (props.scrollable) {
|
|
140
|
+
ui.value.height = fixHeightSize
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
</script>
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<USlideover
|
|
3
|
+
v-bind="attrs"
|
|
4
|
+
:model-value="modelValue"
|
|
5
|
+
:prevent-close="preventClose"
|
|
6
|
+
:overlay="overlay"
|
|
7
|
+
:transition="transition"
|
|
8
|
+
:side="side"
|
|
9
|
+
:initial-focus="emptyFocusRef"
|
|
10
|
+
:ui="ui"
|
|
11
|
+
@update:model-value="$emit('update:modelValue', $event)"
|
|
12
|
+
>
|
|
13
|
+
<div v-if="!isHideCloseBtn && preventClose" class="absolute right-0 m-4">
|
|
14
|
+
<Icon
|
|
15
|
+
v-if="!isHideCloseBtn"
|
|
16
|
+
name="i-heroicons-x-mark"
|
|
17
|
+
class="h-6 w-6 cursor-pointer"
|
|
18
|
+
@click="close"
|
|
19
|
+
/>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div :class="['overflow-y-auto', ui.bodyWrapper]">
|
|
23
|
+
<slot />
|
|
24
|
+
</div>
|
|
25
|
+
</USlideover>
|
|
26
|
+
|
|
27
|
+
<div ref="emptyFocusRef" />
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script lang="ts" setup>
|
|
31
|
+
import { ref, type PropType, toRef, defineShortcuts, watch } from '#imports'
|
|
32
|
+
import type { Strategy } from '#core/types/utils'
|
|
33
|
+
import { useUI } from '#ui/composables/useUI'
|
|
34
|
+
import { slideover } from '#core/ui.config'
|
|
35
|
+
import { useUiConfig } from '#core/composables/useConfig'
|
|
36
|
+
|
|
37
|
+
const config = useUiConfig<typeof slideover>(slideover, 'slideover')
|
|
38
|
+
|
|
39
|
+
const props = defineProps({
|
|
40
|
+
modelValue: {
|
|
41
|
+
type: Boolean as PropType<boolean>,
|
|
42
|
+
default: false,
|
|
43
|
+
},
|
|
44
|
+
side: {
|
|
45
|
+
type: String as PropType<'left' | 'right'>,
|
|
46
|
+
default: 'right',
|
|
47
|
+
validator: (value: string) => ['left', 'right'].includes(value),
|
|
48
|
+
},
|
|
49
|
+
overlay: {
|
|
50
|
+
type: Boolean,
|
|
51
|
+
default: true,
|
|
52
|
+
},
|
|
53
|
+
preventClose: {
|
|
54
|
+
type: Boolean,
|
|
55
|
+
default: false,
|
|
56
|
+
},
|
|
57
|
+
isHideCloseBtn: {
|
|
58
|
+
type: Boolean,
|
|
59
|
+
default: false,
|
|
60
|
+
},
|
|
61
|
+
transition: {
|
|
62
|
+
type: Boolean,
|
|
63
|
+
default: true,
|
|
64
|
+
},
|
|
65
|
+
size: {
|
|
66
|
+
type: String as PropType<keyof typeof slideover.size>,
|
|
67
|
+
default: () => slideover.default.size,
|
|
68
|
+
},
|
|
69
|
+
class: {
|
|
70
|
+
type: [String, Array, Object] as PropType<any>,
|
|
71
|
+
default: undefined,
|
|
72
|
+
},
|
|
73
|
+
ui: {
|
|
74
|
+
type: Object as PropType<Partial<typeof config & { strategy?: Strategy }>>,
|
|
75
|
+
default: undefined,
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const emits = defineEmits(['update:modelValue'])
|
|
80
|
+
|
|
81
|
+
const emptyFocusRef = ref<HTMLElement | null>(null)
|
|
82
|
+
|
|
83
|
+
defineShortcuts({
|
|
84
|
+
escape: {
|
|
85
|
+
usingInput: true,
|
|
86
|
+
handler: () => {
|
|
87
|
+
if (props.preventClose) return
|
|
88
|
+
emits('update:modelValue', false)
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const close = () => {
|
|
94
|
+
emits('update:modelValue', false)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const { ui, attrs } = useUI('slideover', toRef(props, 'ui'), config, toRef(props, 'class'))
|
|
98
|
+
|
|
99
|
+
watch(
|
|
100
|
+
() => props.modelValue,
|
|
101
|
+
() => {
|
|
102
|
+
if (props.modelValue) {
|
|
103
|
+
const size = config.size[props.size]
|
|
104
|
+
|
|
105
|
+
ui.value.width = size
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
</script>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template><img class="h-12" :src="getValue" /></template>
|
|
2
|
+
<script lang="ts" setup>
|
|
3
|
+
import { computed } from 'vue'
|
|
4
|
+
import { type IColumn } from '#core/components/Table/types'
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{
|
|
7
|
+
value: any
|
|
8
|
+
row: any
|
|
9
|
+
column: IColumn
|
|
10
|
+
}>()
|
|
11
|
+
|
|
12
|
+
const getValue = computed(() => props.value)
|
|
13
|
+
</script>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<template>{{ getValue }}</template>
|
|
2
|
+
<script lang="ts" setup>
|
|
3
|
+
import { StringHelper } from '../../utils/StringHelper'
|
|
4
|
+
import { computed } from 'vue'
|
|
5
|
+
import { type IColumn } from '#core/components/Table/types'
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
value: any
|
|
9
|
+
row: any
|
|
10
|
+
column: IColumn
|
|
11
|
+
}>()
|
|
12
|
+
|
|
13
|
+
const getValue = computed(() => StringHelper.withComma(props.value))
|
|
14
|
+
</script>
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div
|
|
4
|
+
v-if="!options.isHideToolbar"
|
|
5
|
+
class="flex border-b border-gray-200 px-3 py-3.5 dark:border-gray-700"
|
|
6
|
+
>
|
|
7
|
+
<UInput v-model="q" placeholder="Search..." />
|
|
8
|
+
</div>
|
|
9
|
+
<UTable
|
|
10
|
+
:loading="options.status.isLoading"
|
|
11
|
+
:columns="options.columns"
|
|
12
|
+
:rows="options.rawData"
|
|
13
|
+
v-bind="$attrs"
|
|
14
|
+
>
|
|
15
|
+
<template #empty-state>
|
|
16
|
+
<div class="flex flex-col items-center justify-center gap-3 py-6">
|
|
17
|
+
<span class="text-sm italic">No one here!</span>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
<template
|
|
21
|
+
v-for="column in options.columns"
|
|
22
|
+
#[`${column.key}-data`]="{ row }"
|
|
23
|
+
:key="column.key"
|
|
24
|
+
>
|
|
25
|
+
<ColumnNumber
|
|
26
|
+
v-if="column.type === COLUMN_TYPES.NUMBER"
|
|
27
|
+
:value="row[column.key]"
|
|
28
|
+
:column="column"
|
|
29
|
+
:row="row"
|
|
30
|
+
/>
|
|
31
|
+
<ColumnImage
|
|
32
|
+
v-if="column.type === COLUMN_TYPES.IMAGE"
|
|
33
|
+
:value="row[column.key]"
|
|
34
|
+
:column="column"
|
|
35
|
+
:row="row"
|
|
36
|
+
/>
|
|
37
|
+
<template v-else>
|
|
38
|
+
<span :title="row[column.key]">{{ row[column.key] ?? '-' }}</span>
|
|
39
|
+
</template>
|
|
40
|
+
</template>
|
|
41
|
+
<template v-for="(_, slot) of $slots" #[slot]="scope">
|
|
42
|
+
<slot :name="slot" v-bind="scope" />
|
|
43
|
+
</template>
|
|
44
|
+
</UTable>
|
|
45
|
+
<div class="mt-4 flex justify-end">
|
|
46
|
+
<UPagination
|
|
47
|
+
v-model="page"
|
|
48
|
+
:page-count="options.pageOptions.totalPage"
|
|
49
|
+
:total="options.pageOptions.totalCount"
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</template>
|
|
54
|
+
<script lang="ts" setup>
|
|
55
|
+
import { type PropType } from 'vue'
|
|
56
|
+
import { COLUMN_TYPES, type ITableOptions } from '#core/components/Table/types'
|
|
57
|
+
import { _debounce, ref, watch } from '#imports'
|
|
58
|
+
import ColumnNumber from '#core/components/Table/ColumnNumber.vue'
|
|
59
|
+
import ColumnImage from '#core/components/Table/ColumnImage.vue'
|
|
60
|
+
|
|
61
|
+
const emits = defineEmits<{
|
|
62
|
+
(event: 'pageChange', page: number): void
|
|
63
|
+
(event: 'search', q: string): void
|
|
64
|
+
}>()
|
|
65
|
+
|
|
66
|
+
const props = defineProps({
|
|
67
|
+
options: { type: Object as PropType<ITableOptions>, required: true },
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
const q = ref(props.options?.pageOptions.search ?? '')
|
|
71
|
+
|
|
72
|
+
const page = ref(props.options?.pageOptions.currentPage)
|
|
73
|
+
|
|
74
|
+
watch(
|
|
75
|
+
q,
|
|
76
|
+
_debounce((value) => {
|
|
77
|
+
emits('search', value)
|
|
78
|
+
}, 500)
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
watch(page, () => {
|
|
82
|
+
emits('pageChange', page.value)
|
|
83
|
+
})
|
|
84
|
+
</script>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type IPageOptions, type IStatus } from '#core/types/lib';
|
|
2
|
+
export declare const enum COLUMN_TYPES {
|
|
3
|
+
VALUE = "VALUE",
|
|
4
|
+
COMPONENT = "COMPONENT",
|
|
5
|
+
DATE = "DATE",
|
|
6
|
+
DATE_TIME = "DATE_TIME",
|
|
7
|
+
NUMBER = "NUMBER",
|
|
8
|
+
IMAGE = "IMAGE",
|
|
9
|
+
ACTION = "ACTION"
|
|
10
|
+
}
|
|
11
|
+
export interface IColumn {
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
key: string;
|
|
14
|
+
sortable?: boolean;
|
|
15
|
+
direction?: 'asc' | 'desc';
|
|
16
|
+
class?: string;
|
|
17
|
+
type?: COLUMN_TYPES;
|
|
18
|
+
}
|
|
19
|
+
export interface IRowItem<T = object> {
|
|
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<T = object> = Record<number, IRowItem<T>>;
|
|
29
|
+
export interface ITableOptions<T = object> {
|
|
30
|
+
rawData: T[];
|
|
31
|
+
primary: string;
|
|
32
|
+
isHideBottomPagination?: boolean;
|
|
33
|
+
isHideTopPagination?: boolean;
|
|
34
|
+
isNotChangeRoute: boolean;
|
|
35
|
+
status: IStatus;
|
|
36
|
+
pageOptions: IPageOptions;
|
|
37
|
+
columns: IColumn[];
|
|
38
|
+
isHideToolbar?: boolean;
|
|
39
|
+
isShowCheckbox?: boolean;
|
|
40
|
+
deleteStatus?: IStatus;
|
|
41
|
+
onRowClick?: (index: number, columns: Array<{
|
|
42
|
+
value: string;
|
|
43
|
+
}>) => void;
|
|
44
|
+
onCheckBoxClick?: (index: number[]) => void;
|
|
45
|
+
disabledCheckIndexes?: number[];
|
|
46
|
+
}
|
|
47
|
+
export interface ISimpleTableOptions<T = object> {
|
|
48
|
+
rawData: T[];
|
|
49
|
+
primary: string;
|
|
50
|
+
status: IStatus;
|
|
51
|
+
columns: IColumn[];
|
|
52
|
+
isHideBottomPagination?: boolean;
|
|
53
|
+
onRowClick?: (index: number, columns: Array<{
|
|
54
|
+
value: string;
|
|
55
|
+
}>) => void;
|
|
56
|
+
onCheckBoxClick?: (index: number[]) => void;
|
|
57
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export var COLUMN_TYPES = /* @__PURE__ */ ((COLUMN_TYPES2) => {
|
|
2
|
+
COLUMN_TYPES2["VALUE"] = "VALUE";
|
|
3
|
+
COLUMN_TYPES2["COMPONENT"] = "COMPONENT";
|
|
4
|
+
COLUMN_TYPES2["DATE"] = "DATE";
|
|
5
|
+
COLUMN_TYPES2["DATE_TIME"] = "DATE_TIME";
|
|
6
|
+
COLUMN_TYPES2["NUMBER"] = "NUMBER";
|
|
7
|
+
COLUMN_TYPES2["IMAGE"] = "IMAGE";
|
|
8
|
+
COLUMN_TYPES2["ACTION"] = "ACTION";
|
|
9
|
+
return COLUMN_TYPES2;
|
|
10
|
+
})(COLUMN_TYPES || {});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ref } from "vue";
|
|
2
|
-
import { ObjectHelper } from "
|
|
3
|
-
import { apiListHelper } from "
|
|
2
|
+
import { ObjectHelper } from "../utils/ObjectHelper.mjs";
|
|
3
|
+
import { apiListHelper } from "#core/helpers/apiListHelper";
|
|
4
4
|
export const useListLoader = (loaderOptions) => {
|
|
5
5
|
const status = ref(ObjectHelper.createStatus());
|
|
6
6
|
const items = ref([]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ref } from "vue";
|
|
2
|
-
import { ObjectHelper } from "
|
|
3
|
-
import { apiObjectHelper } from "
|
|
2
|
+
import { ObjectHelper } from "../utils/ObjectHelper.mjs";
|
|
3
|
+
import { apiObjectHelper } from "#core/helpers/apiObjectHelper";
|
|
4
4
|
export const useObjectLoader = (loaderOptions) => {
|
|
5
5
|
const status = ref(ObjectHelper.createStatus());
|
|
6
6
|
const data = ref(null);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export declare const initPageOptions: (options: {
|
|
2
|
+
limit: number;
|
|
3
|
+
primary: string;
|
|
4
|
+
}) => {
|
|
3
5
|
currentPageCount: number;
|
|
4
6
|
currentPage: number;
|
|
5
7
|
totalPage: number;
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { ref } from "vue";
|
|
2
|
-
import { ObjectHelper } from "
|
|
2
|
+
import { ObjectHelper } from "../utils/ObjectHelper.mjs";
|
|
3
3
|
import {
|
|
4
4
|
apiAddHelper,
|
|
5
5
|
apiDeleteHelper,
|
|
6
6
|
apiFetchHelper,
|
|
7
7
|
apiFindHelper,
|
|
8
8
|
updateHelper
|
|
9
|
-
} from "
|
|
10
|
-
import {
|
|
11
|
-
export const initPageOptions = () => ({
|
|
9
|
+
} from "#core/helpers/apiPageHelper";
|
|
10
|
+
import { useCoreConfig } from "./useConfig.mjs";
|
|
11
|
+
export const initPageOptions = (options) => ({
|
|
12
12
|
currentPageCount: 0,
|
|
13
13
|
currentPage: 1,
|
|
14
14
|
totalPage: 0,
|
|
15
15
|
totalCount: 0,
|
|
16
|
-
limit:
|
|
16
|
+
limit: options.limit,
|
|
17
17
|
search: "",
|
|
18
|
-
primary:
|
|
18
|
+
primary: options.primary
|
|
19
19
|
});
|
|
20
20
|
export const usePageLoader = (loaderOptions) => {
|
|
21
|
+
const config = useCoreConfig();
|
|
21
22
|
const fetchStatus = ref(ObjectHelper.createStatus());
|
|
22
23
|
const fetchItems = ref([]);
|
|
23
24
|
const findItem = ref(null);
|
|
@@ -28,7 +29,12 @@ export const usePageLoader = (loaderOptions) => {
|
|
|
28
29
|
const addStatus = ref(ObjectHelper.createStatus());
|
|
29
30
|
const updateStatus = ref(ObjectHelper.createStatus());
|
|
30
31
|
const deleteStatus = ref(ObjectHelper.createStatus());
|
|
31
|
-
const fetchOptions = ref(
|
|
32
|
+
const fetchOptions = ref(
|
|
33
|
+
initPageOptions({
|
|
34
|
+
limit: config.limit_per_page,
|
|
35
|
+
primary: config.default_primary_key
|
|
36
|
+
})
|
|
37
|
+
);
|
|
32
38
|
const addOptions = ref({});
|
|
33
39
|
const findOptions = ref({});
|
|
34
40
|
const updateOptions = ref({});
|
|
@@ -42,7 +48,10 @@ export const usePageLoader = (loaderOptions) => {
|
|
|
42
48
|
deleteItem.value = null;
|
|
43
49
|
updateItem.value = null;
|
|
44
50
|
fetchStatus.value = ObjectHelper.createStatus();
|
|
45
|
-
fetchOptions.value = initPageOptions(
|
|
51
|
+
fetchOptions.value = initPageOptions({
|
|
52
|
+
limit: config.limit_per_page,
|
|
53
|
+
primary: config.default_primary_key
|
|
54
|
+
});
|
|
46
55
|
findOptions.value = {};
|
|
47
56
|
addOptions.value = {};
|
|
48
57
|
deleteOptions.value = {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { mergeConfig } from "#ui/utils";
|
|
2
|
+
import { core } from "#core/core.config";
|
|
3
|
+
import appConfig from "#build/app.config";
|
|
4
|
+
export const useCoreConfig = () => {
|
|
5
|
+
return mergeConfig(appConfig.core.strategy, appConfig.core, core);
|
|
6
|
+
};
|
|
7
|
+
export const useUiConfig = (config, name) => {
|
|
8
|
+
return mergeConfig(appConfig.ui.strategy, appConfig.ui[name], config);
|
|
9
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const enum DialogType {
|
|
2
|
+
ERROR = "error",
|
|
3
|
+
INFO = "info",
|
|
4
|
+
SUCCESS = "success",
|
|
5
|
+
WARNING = "warning"
|
|
6
|
+
}
|
|
7
|
+
export interface IDialogMetaItem {
|
|
8
|
+
title: string;
|
|
9
|
+
message?: string;
|
|
10
|
+
type?: DialogType;
|
|
11
|
+
confirmText?: string;
|
|
12
|
+
cancelText?: string;
|
|
13
|
+
isShowCancelBtn?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface IDialog {
|
|
16
|
+
isShow: boolean;
|
|
17
|
+
meta: IDialogMetaItem | undefined;
|
|
18
|
+
openDialog: (meta: IDialogMetaItem) => void;
|
|
19
|
+
closeDialogCancel: () => void;
|
|
20
|
+
closeDialogProceed: () => void;
|
|
21
|
+
error: (payload: IDialogMetaItem) => Promise<boolean>;
|
|
22
|
+
info: (payload: IDialogMetaItem) => Promise<boolean>;
|
|
23
|
+
success: (payload: IDialogMetaItem) => Promise<boolean>;
|
|
24
|
+
warning: (payload: IDialogMetaItem) => Promise<boolean>;
|
|
25
|
+
}
|
|
26
|
+
export declare const useDialog: () => IDialog;
|