@vc-shell/framework 1.0.117 → 1.0.119
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/CHANGELOG.md +37 -0
- package/dist/framework.mjs +8937 -8593
- package/dist/index.css +1 -1
- package/dist/shared/modules/dynamic/components/FIELD_MAP.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/factories.d.ts +5 -2
- package/dist/shared/modules/dynamic/components/factories.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/Button.d.ts +8 -4
- package/dist/shared/modules/dynamic/components/fields/Button.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/Card.d.ts +8 -4
- package/dist/shared/modules/dynamic/components/fields/Card.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/Checkbox.d.ts +8 -4
- package/dist/shared/modules/dynamic/components/fields/Checkbox.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/ContentField.d.ts +135 -0
- package/dist/shared/modules/dynamic/components/fields/ContentField.d.ts.map +1 -0
- package/dist/shared/modules/dynamic/components/fields/DynamicProperty.d.ts +8 -4
- package/dist/shared/modules/dynamic/components/fields/DynamicProperty.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/EditorField.d.ts +8 -4
- package/dist/shared/modules/dynamic/components/fields/EditorField.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/Fieldset.d.ts +8 -4
- package/dist/shared/modules/dynamic/components/fields/Fieldset.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/GalleryField.d.ts +8 -4
- package/dist/shared/modules/dynamic/components/fields/GalleryField.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/ImageField.d.ts +135 -0
- package/dist/shared/modules/dynamic/components/fields/ImageField.d.ts.map +1 -0
- package/dist/shared/modules/dynamic/components/fields/InputCurrency.d.ts +8 -4
- package/dist/shared/modules/dynamic/components/fields/InputCurrency.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/InputField.d.ts +13 -9
- package/dist/shared/modules/dynamic/components/fields/InputField.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/SelectField.d.ts +8 -4
- package/dist/shared/modules/dynamic/components/fields/SelectField.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/StatusField.d.ts +8 -4
- package/dist/shared/modules/dynamic/components/fields/StatusField.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/components/fields/VideoField.d.ts +135 -0
- package/dist/shared/modules/dynamic/components/fields/VideoField.d.ts.map +1 -0
- package/dist/shared/modules/dynamic/components/fields/props.d.ts +9 -5
- package/dist/shared/modules/dynamic/components/fields/props.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/factories/types/index.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/helpers/nodeBuilder.d.ts +2 -2
- package/dist/shared/modules/dynamic/helpers/nodeBuilder.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts +8 -0
- package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/types/index.d.ts +29 -2
- package/dist/shared/modules/dynamic/types/index.d.ts.map +1 -1
- package/dist/shared/modules/dynamic/types/models.d.ts +15 -2
- package/dist/shared/modules/dynamic/types/models.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/components/atoms/vc-col/index.d.ts +1 -80
- package/dist/ui/components/atoms/vc-col/index.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-col/vc-col.vue.d.ts +3 -3
- package/dist/ui/components/atoms/vc-col/vc-col.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-row/index.d.ts +1 -52
- package/dist/ui/components/atoms/vc-row/index.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-row/vc-row.vue.d.ts +3 -3
- package/dist/ui/components/atoms/vc-row/vc-row.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/index.d.ts +1 -0
- package/dist/ui/components/molecules/index.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-field/_internal/vc-field-type/vc-field-type.vue.d.ts +33 -0
- package/dist/ui/components/molecules/vc-field/_internal/vc-field-type/vc-field-type.vue.d.ts.map +1 -0
- package/dist/ui/components/molecules/vc-field/index.d.ts +2 -0
- package/dist/ui/components/molecules/vc-field/index.d.ts.map +1 -0
- package/dist/ui/components/molecules/vc-field/vc-field.vue.d.ts +45 -0
- package/dist/ui/components/molecules/vc-field/vc-field.vue.d.ts.map +1 -0
- package/dist/ui/components/organisms/vc-popup/vc-popup.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue.d.ts.map +1 -1
- package/dist/ui/types/index.d.ts +1 -0
- package/dist/ui/types/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/shared/modules/dynamic/components/FIELD_MAP.ts +7 -0
- package/shared/modules/dynamic/components/SchemaRender.ts +3 -3
- package/shared/modules/dynamic/components/factories.ts +35 -1
- package/shared/modules/dynamic/components/fields/ContentField.ts +25 -0
- package/shared/modules/dynamic/components/fields/EditorField.ts +3 -6
- package/shared/modules/dynamic/components/fields/Fieldset.ts +12 -5
- package/shared/modules/dynamic/components/fields/GalleryField.ts +8 -5
- package/shared/modules/dynamic/components/fields/ImageField.ts +30 -0
- package/shared/modules/dynamic/components/fields/InputField.ts +25 -3
- package/shared/modules/dynamic/components/fields/VideoField.ts +28 -0
- package/shared/modules/dynamic/components/fields/props.ts +5 -5
- package/shared/modules/dynamic/factories/types/index.ts +1 -1
- package/shared/modules/dynamic/helpers/nodeBuilder.ts +19 -14
- package/shared/modules/dynamic/pages/dynamic-blade-list.vue +39 -2
- package/shared/modules/dynamic/types/index.ts +35 -2
- package/shared/modules/dynamic/types/models.ts +22 -1
- package/ui/components/atoms/vc-col/index.ts +1 -10
- package/ui/components/atoms/vc-col/vc-col.vue +10 -5
- package/ui/components/atoms/vc-image/vc-image.vue +1 -1
- package/ui/components/atoms/vc-label/vc-label.vue +1 -1
- package/ui/components/atoms/vc-row/index.ts +1 -10
- package/ui/components/atoms/vc-row/vc-row.vue +8 -1
- package/ui/components/molecules/index.ts +1 -0
- package/ui/components/molecules/vc-field/_internal/vc-field-type/vc-field-type.vue +66 -0
- package/ui/components/molecules/vc-field/index.ts +1 -0
- package/ui/components/molecules/vc-field/vc-field.vue +67 -0
- package/ui/components/organisms/vc-popup/vc-popup.vue +5 -0
- package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +4 -2
- package/ui/types/index.ts +1 -0
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
import { ExtractPropTypes, h } from "vue";
|
|
1
|
+
import { ExtractPropTypes, h, VNode } from "vue";
|
|
2
2
|
import { InputField } from "../factories";
|
|
3
3
|
import componentProps from "./props";
|
|
4
4
|
import ValidationField from "./ValidationField";
|
|
5
|
-
import { InputSchema } from "../../types";
|
|
5
|
+
import { InputSchema, ControlSchema } from "../../types";
|
|
6
|
+
import { nodeBuilder } from "../../helpers/nodeBuilder";
|
|
7
|
+
|
|
8
|
+
const slotsMap = {
|
|
9
|
+
append: "append",
|
|
10
|
+
prepend: "prepend",
|
|
11
|
+
appendInner: "append-inner",
|
|
12
|
+
prependInner: "prepend-inner",
|
|
13
|
+
};
|
|
6
14
|
|
|
7
15
|
export default {
|
|
8
16
|
name: "InputField",
|
|
@@ -17,9 +25,23 @@ export default {
|
|
|
17
25
|
clearable: props.element.clearable || false,
|
|
18
26
|
},
|
|
19
27
|
options: props.baseOptions,
|
|
28
|
+
slots: Object.entries(slotsMap).reduce((acc, [key, value]: [keyof InputSchema, keyof InputSchema]) => {
|
|
29
|
+
if (props.element[key]) {
|
|
30
|
+
acc[value] = () =>
|
|
31
|
+
nodeBuilder({
|
|
32
|
+
controlSchema: props.element[key] as ControlSchema,
|
|
33
|
+
parentId: `${(props.element[key] as ControlSchema).id}`,
|
|
34
|
+
internalContext: props.fieldContext,
|
|
35
|
+
bladeContext: props.bladeContext,
|
|
36
|
+
currentLocale: props.currentLocale,
|
|
37
|
+
formData: props.formData,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return acc;
|
|
41
|
+
}, {} as Record<keyof InputSchema, () => VNode | false>),
|
|
20
42
|
});
|
|
21
43
|
|
|
22
|
-
const render = h(field.component, field.props);
|
|
44
|
+
const render = h(field.component, field.props, field.slots);
|
|
23
45
|
|
|
24
46
|
if (field.props.rules) {
|
|
25
47
|
return props.baseOptions.visibility
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ExtractPropTypes, h } from "vue";
|
|
2
|
+
import { VideoField } from "../factories";
|
|
3
|
+
import componentProps from "./props";
|
|
4
|
+
import { VideoSchema } from "../../types";
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
name: "VideoField",
|
|
8
|
+
props: componentProps,
|
|
9
|
+
setup(props: ExtractPropTypes<typeof componentProps> & { element: VideoSchema }) {
|
|
10
|
+
return () => {
|
|
11
|
+
const field = VideoField({
|
|
12
|
+
props: {
|
|
13
|
+
...props.baseProps,
|
|
14
|
+
source: props.baseProps.modelValue,
|
|
15
|
+
size: props.element.size,
|
|
16
|
+
rounded: props.element.rounded,
|
|
17
|
+
bordered: props.element.bordered,
|
|
18
|
+
clickable: props.element.clickable,
|
|
19
|
+
},
|
|
20
|
+
options: props.baseOptions,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const render = h(field.component, field.props);
|
|
24
|
+
|
|
25
|
+
return props.baseOptions.visibility ? render : null;
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComputedRef, PropType, UnwrapNestedRefs, VNodeArrayChildren } from "vue";
|
|
1
|
+
import { ComputedRef, MaybeRef, PropType, UnwrapNestedRefs, VNode, VNodeArrayChildren } from "vue";
|
|
2
2
|
import { DetailsBladeContext } from "../../factories";
|
|
3
3
|
import { IControlBaseOptions, IControlBaseProps } from "../../types/models";
|
|
4
4
|
import { ControlSchema } from "../../types";
|
|
@@ -21,12 +21,12 @@ export default {
|
|
|
21
21
|
default: () => ({} as DetailsBladeContext),
|
|
22
22
|
},
|
|
23
23
|
fields: {
|
|
24
|
-
type: Object as PropType<ComputedRef<
|
|
25
|
-
default: () => ({} as ComputedRef<
|
|
24
|
+
type: Object as PropType<ComputedRef<VNode[][]>>,
|
|
25
|
+
default: () => ({} as ComputedRef<VNode[][]>),
|
|
26
26
|
},
|
|
27
27
|
formData: {
|
|
28
|
-
type: Object,
|
|
29
|
-
default: () => ({}),
|
|
28
|
+
type: Object as PropType<MaybeRef<Record<string, unknown>>>,
|
|
29
|
+
default: () => ({} as MaybeRef<Record<string, unknown>>),
|
|
30
30
|
},
|
|
31
31
|
fieldContext: {
|
|
32
32
|
type: Object,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { ComputedRef, MaybeRef, Ref, UnwrapNestedRefs } from "vue";
|
|
2
|
+
import { ComputedRef, MaybeRef, Ref, UnwrapNestedRefs, UnwrapRef } from "vue";
|
|
3
3
|
import { AsyncAction } from "../../../../../core/composables";
|
|
4
4
|
import { SettingsSchema } from "../../types";
|
|
5
5
|
import { Asset, AssetsHandler, IBladeToolbar, IImage } from "../../../../../core/types";
|
|
@@ -19,10 +19,14 @@ function disabledHandler(
|
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function nodeBuilder<
|
|
22
|
+
function nodeBuilder<
|
|
23
|
+
Context extends Record<string, unknown>,
|
|
24
|
+
BContext extends UnwrapNestedRefs<DetailsBladeContext>,
|
|
25
|
+
FormData
|
|
26
|
+
>(args: {
|
|
23
27
|
controlSchema: ControlSchema;
|
|
24
28
|
parentId: string | number;
|
|
25
|
-
internalContext: Context
|
|
29
|
+
internalContext: MaybeRef<Context>;
|
|
26
30
|
bladeContext: BContext;
|
|
27
31
|
currentLocale: MaybeRef<string>;
|
|
28
32
|
formData: FormData;
|
|
@@ -32,7 +36,7 @@ function nodeBuilder<Context, BContext extends UnwrapNestedRefs<DetailsBladeCont
|
|
|
32
36
|
|
|
33
37
|
const baseProps = reactive<IControlBaseProps>({
|
|
34
38
|
key: `${parentId}`,
|
|
35
|
-
label: controlSchema.label ? unref(unwrapInterpolation(controlSchema.label, internalContext)) : undefined,
|
|
39
|
+
label: controlSchema.label ? unref(unwrapInterpolation(controlSchema.label, toValue(internalContext))) : undefined,
|
|
36
40
|
disabled:
|
|
37
41
|
("disabled" in bladeContext.scope && bladeContext.scope.disabled) ||
|
|
38
42
|
disabledHandler("disabled" in controlSchema && controlSchema.disabled, bladeContext),
|
|
@@ -40,14 +44,14 @@ function nodeBuilder<Context, BContext extends UnwrapNestedRefs<DetailsBladeCont
|
|
|
40
44
|
rules: controlSchema.rules,
|
|
41
45
|
placeholder: controlSchema.placeholder,
|
|
42
46
|
required: controlSchema.rules?.required,
|
|
43
|
-
modelValue: getModel(controlSchema.property, internalContext),
|
|
44
|
-
"onUpdate:modelValue": (e) => {
|
|
45
|
-
setModel({ property: controlSchema.property, value: e, context: internalContext });
|
|
47
|
+
modelValue: getModel(controlSchema.property, toValue(internalContext)),
|
|
48
|
+
"onUpdate:modelValue": (e: unknown) => {
|
|
49
|
+
setModel({ property: controlSchema.property, value: e, context: toValue(internalContext) });
|
|
46
50
|
|
|
47
51
|
if (_.has(controlSchema, "update.method")) {
|
|
48
52
|
controlSchema.update.method in bladeContext.scope &&
|
|
49
53
|
typeof bladeContext.scope[controlSchema.update.method] === "function"
|
|
50
|
-
? bladeContext.scope[controlSchema.update.method](e, controlSchema.property, internalContext)
|
|
54
|
+
? bladeContext.scope[controlSchema.update.method](e, controlSchema.property, toValue(internalContext))
|
|
51
55
|
: undefined;
|
|
52
56
|
}
|
|
53
57
|
},
|
|
@@ -57,7 +61,7 @@ function nodeBuilder<Context, BContext extends UnwrapNestedRefs<DetailsBladeCont
|
|
|
57
61
|
|
|
58
62
|
const baseOptions = reactive<IControlBaseOptions>({
|
|
59
63
|
visibility: computed(() =>
|
|
60
|
-
controlSchema.visibility?.method ?
|
|
64
|
+
controlSchema.visibility?.method ? bladeContext.scope[controlSchema.visibility?.method] : true
|
|
61
65
|
),
|
|
62
66
|
});
|
|
63
67
|
|
|
@@ -65,10 +69,11 @@ function nodeBuilder<Context, BContext extends UnwrapNestedRefs<DetailsBladeCont
|
|
|
65
69
|
|
|
66
70
|
const fieldsHandler = computed(() => {
|
|
67
71
|
if (!("fields" in controlSchema)) return null;
|
|
68
|
-
const fieldsModel = getModel(controlSchema.property, internalContext);
|
|
72
|
+
const fieldsModel = getModel(controlSchema.property, toValue(internalContext));
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
const model = toValue(fieldsModel);
|
|
75
|
+
if (model && Array.isArray(model)) {
|
|
76
|
+
return model.map((model: { [x: string]: unknown; id: string }) =>
|
|
72
77
|
controlSchema.fields.map((fieldItem) =>
|
|
73
78
|
nodeBuilder({
|
|
74
79
|
controlSchema: fieldItem,
|
|
@@ -86,7 +91,7 @@ function nodeBuilder<Context, BContext extends UnwrapNestedRefs<DetailsBladeCont
|
|
|
86
91
|
nodeBuilder({
|
|
87
92
|
controlSchema: field,
|
|
88
93
|
parentId: `fieldset-${parentId}-${field.id}`,
|
|
89
|
-
internalContext,
|
|
94
|
+
internalContext: reactive(unref(internalContext)),
|
|
90
95
|
bladeContext,
|
|
91
96
|
currentLocale,
|
|
92
97
|
formData,
|
|
@@ -100,10 +105,10 @@ function nodeBuilder<Context, BContext extends UnwrapNestedRefs<DetailsBladeCont
|
|
|
100
105
|
baseOptions,
|
|
101
106
|
bladeContext,
|
|
102
107
|
element: controlSchema,
|
|
103
|
-
currentLocale,
|
|
108
|
+
currentLocale: unref(currentLocale),
|
|
104
109
|
fields: fieldsHandler,
|
|
105
110
|
formData,
|
|
106
|
-
fieldContext: internalContext,
|
|
111
|
+
fieldContext: reactive(unref(internalContext)),
|
|
107
112
|
};
|
|
108
113
|
|
|
109
114
|
return h(component, elProps);
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
:expanded="expanded"
|
|
16
16
|
v-bind="bladeOptions?.table"
|
|
17
17
|
:state-key="tableData?.id"
|
|
18
|
-
:items="
|
|
18
|
+
:items="itemsProxy"
|
|
19
19
|
:multiselect="tableData?.multiselect"
|
|
20
20
|
:header="tableData?.header"
|
|
21
21
|
:sort="sort"
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
:total-label="$t(`${settings.localizationPrefix.trim().toUpperCase()}.PAGES.LIST.TABLE.TOTALS`)"
|
|
27
27
|
:total-count="pagination?.totalCount"
|
|
28
28
|
:active-filter-count="activeFilterCount"
|
|
29
|
+
:reorderable-rows="tableData?.reorderableRows"
|
|
29
30
|
@item-click="onItemClick"
|
|
30
31
|
@pagination-click="onPaginationClick"
|
|
31
32
|
@selection-changed="onSelectionChanged"
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
@load:change="onSearchList"
|
|
34
35
|
@scroll:ptr="reload"
|
|
35
36
|
@search:change="onSearchList"
|
|
37
|
+
@row:reorder="sortRows"
|
|
36
38
|
>
|
|
37
39
|
<template
|
|
38
40
|
v-if="isFilterVisible"
|
|
@@ -133,6 +135,8 @@ import { ITableColumns } from "../../../../core/types";
|
|
|
133
135
|
import { toolbarReducer } from "../helpers/toolbarReducer";
|
|
134
136
|
import { notification, usePopup } from "../../../components";
|
|
135
137
|
import { ListBaseBladeScope, ListBladeContext, UseList } from "../factories/types";
|
|
138
|
+
import { IParentCallArgs } from "../../../index";
|
|
139
|
+
import * as _ from "lodash-es";
|
|
136
140
|
|
|
137
141
|
export interface Props {
|
|
138
142
|
expanded?: boolean;
|
|
@@ -144,6 +148,7 @@ export interface Props {
|
|
|
144
148
|
}
|
|
145
149
|
|
|
146
150
|
export interface Emits {
|
|
151
|
+
(event: "parent:call", args: IParentCallArgs): void;
|
|
147
152
|
(event: "close:blade"): void;
|
|
148
153
|
(event: "collapse:blade"): void;
|
|
149
154
|
(event: "expand:blade"): void;
|
|
@@ -174,6 +179,8 @@ const selectedItemId = ref();
|
|
|
174
179
|
const sort = ref("createdDate:DESC");
|
|
175
180
|
const selectedIds = ref<string[]>([]);
|
|
176
181
|
const isDesktop = inject<Ref<boolean>>("isDesktop");
|
|
182
|
+
const itemsProxy = ref<Record<string, any>[]>();
|
|
183
|
+
const modified = ref(false);
|
|
177
184
|
|
|
178
185
|
const { moduleNotifications, markAsRead } = useNotifications(settings.value.pushNotificationType);
|
|
179
186
|
|
|
@@ -231,7 +238,7 @@ const {
|
|
|
231
238
|
const bladeContext = ref<ListBladeContext>({
|
|
232
239
|
load,
|
|
233
240
|
remove,
|
|
234
|
-
items,
|
|
241
|
+
items: computed(() => itemsProxy.value),
|
|
235
242
|
loading,
|
|
236
243
|
pagination,
|
|
237
244
|
query,
|
|
@@ -242,6 +249,12 @@ const bladeContext = ref<ListBladeContext>({
|
|
|
242
249
|
const toolbarComputed = toolbarReducer({
|
|
243
250
|
defaultToolbarSchema: settings.value.toolbar,
|
|
244
251
|
defaultToolbarBindings: {
|
|
252
|
+
save: {
|
|
253
|
+
clickHandler() {
|
|
254
|
+
emit("close:blade");
|
|
255
|
+
},
|
|
256
|
+
disabled: computed(() => !modified.value),
|
|
257
|
+
},
|
|
245
258
|
openAddBlade: {
|
|
246
259
|
async clickHandler() {
|
|
247
260
|
if (
|
|
@@ -274,10 +287,22 @@ onMounted(async () => {
|
|
|
274
287
|
await load({ ...query.value, sort: sort.value });
|
|
275
288
|
});
|
|
276
289
|
|
|
290
|
+
watch(
|
|
291
|
+
() => itemsProxy.value,
|
|
292
|
+
(newVal) => {
|
|
293
|
+
modified.value = !_.isEqual(newVal, items.value);
|
|
294
|
+
},
|
|
295
|
+
{ deep: true }
|
|
296
|
+
);
|
|
297
|
+
|
|
277
298
|
watch(sort, async (value) => {
|
|
278
299
|
await load({ ...query.value, sort: value });
|
|
279
300
|
});
|
|
280
301
|
|
|
302
|
+
watch(items, (newVal) => {
|
|
303
|
+
itemsProxy.value = newVal;
|
|
304
|
+
});
|
|
305
|
+
|
|
281
306
|
watch(
|
|
282
307
|
() => props.param,
|
|
283
308
|
(newVal) => {
|
|
@@ -465,8 +490,20 @@ function resolveTemplateComponent(name: keyof ListContentSchema) {
|
|
|
465
490
|
}
|
|
466
491
|
}
|
|
467
492
|
|
|
493
|
+
function sortRows(event: { dragIndex: number; dropIndex: number; value: any[] }) {
|
|
494
|
+
if (event.dragIndex !== event.dropIndex) {
|
|
495
|
+
const sorted = event.value.map((item, index) => {
|
|
496
|
+
item.sortOrder = index;
|
|
497
|
+
return item;
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
itemsProxy.value = sorted;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
468
504
|
defineExpose({
|
|
469
505
|
reload,
|
|
470
506
|
title,
|
|
507
|
+
...scope.value,
|
|
471
508
|
});
|
|
472
509
|
</script>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VcButton, VcIcon, VcInput, VcStatus } from "./../../../../ui/components";
|
|
1
|
+
import { VcButton, VcField, VcIcon, VcImage, VcInput, VcStatus, VcVideo } from "./../../../../ui/components";
|
|
2
2
|
import { ITableColumns, IValidationRules } from "../../../../core/types";
|
|
3
3
|
import type { ComponentProps, ComponentEmit, ComponentSlots } from "vue-component-type-helpers";
|
|
4
4
|
|
|
@@ -95,6 +95,7 @@ export interface ListContentSchema extends SchemaBase {
|
|
|
95
95
|
type?: string;
|
|
96
96
|
customTemplate?: GridTemplateOverride;
|
|
97
97
|
})[];
|
|
98
|
+
reorderableRows?: boolean;
|
|
98
99
|
mobileTemplate?: {
|
|
99
100
|
component: string;
|
|
100
101
|
};
|
|
@@ -148,6 +149,34 @@ export interface InputSchema extends SchemaBase {
|
|
|
148
149
|
component: "vc-input";
|
|
149
150
|
variant?: ComponentProps<typeof VcInput>["type"];
|
|
150
151
|
clearable?: boolean;
|
|
152
|
+
prepend?: ControlSchema;
|
|
153
|
+
append?: ControlSchema;
|
|
154
|
+
appendInner?: ControlSchema;
|
|
155
|
+
prependInner?: ControlSchema;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface VideoSchema extends SchemaBase {
|
|
159
|
+
component: "vc-video";
|
|
160
|
+
size?: ComponentProps<typeof VcVideo>["size"];
|
|
161
|
+
rounded?: boolean;
|
|
162
|
+
bordered?: boolean;
|
|
163
|
+
clickable?: boolean;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface FieldSchema extends SchemaBase {
|
|
167
|
+
component: "vc-field";
|
|
168
|
+
variant?: ComponentProps<typeof VcField>["type"];
|
|
169
|
+
copyable?: boolean;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface ImageSchema extends SchemaBase {
|
|
173
|
+
component: "vc-image";
|
|
174
|
+
aspect?: ComponentProps<typeof VcImage>["aspect"];
|
|
175
|
+
size?: ComponentProps<typeof VcImage>["size"];
|
|
176
|
+
background?: ComponentProps<typeof VcImage>["background"];
|
|
177
|
+
rounded?: boolean;
|
|
178
|
+
bordered?: boolean;
|
|
179
|
+
clickable?: boolean;
|
|
151
180
|
}
|
|
152
181
|
|
|
153
182
|
export interface StatusSchema extends SchemaBase {
|
|
@@ -209,6 +238,7 @@ export interface CheckboxSchema extends SchemaBase {
|
|
|
209
238
|
export interface FieldsetSchema extends SchemaBase {
|
|
210
239
|
component: "vc-fieldset";
|
|
211
240
|
columns?: number;
|
|
241
|
+
aspectRatio?: number[];
|
|
212
242
|
fields: Exclude<ControlSchema[], FieldsetSchema>;
|
|
213
243
|
remove?: {
|
|
214
244
|
method: string;
|
|
@@ -237,7 +267,10 @@ export type ControlSchema =
|
|
|
237
267
|
| FieldsetSchema
|
|
238
268
|
| ButtonSchema
|
|
239
269
|
| InputCurrencySchema
|
|
240
|
-
| StatusSchema
|
|
270
|
+
| StatusSchema
|
|
271
|
+
| FieldSchema
|
|
272
|
+
| VideoSchema
|
|
273
|
+
| ImageSchema;
|
|
241
274
|
|
|
242
275
|
export interface FilterBase {
|
|
243
276
|
columns: {
|
|
@@ -6,11 +6,14 @@ import {
|
|
|
6
6
|
VcCheckbox,
|
|
7
7
|
VcDynamicProperty,
|
|
8
8
|
VcEditor,
|
|
9
|
+
VcField,
|
|
9
10
|
VcGallery,
|
|
11
|
+
VcImage,
|
|
10
12
|
VcInput,
|
|
11
13
|
VcInputCurrency,
|
|
12
14
|
VcSelect,
|
|
13
15
|
VcStatus,
|
|
16
|
+
VcVideo,
|
|
14
17
|
} from "../../../../ui/components";
|
|
15
18
|
import type { ComponentProps, ComponentEmit, ComponentSlots } from "vue-component-type-helpers";
|
|
16
19
|
|
|
@@ -44,7 +47,9 @@ export type ControlType =
|
|
|
44
47
|
| ICheckbox
|
|
45
48
|
| IButton
|
|
46
49
|
| IInputCurrency
|
|
47
|
-
| IStatusField
|
|
50
|
+
| IStatusField
|
|
51
|
+
| IContentField
|
|
52
|
+
| IImageField;
|
|
48
53
|
|
|
49
54
|
export type ControlTypeWithSlots = Extract<
|
|
50
55
|
ControlType,
|
|
@@ -90,8 +95,24 @@ export type IStatusField = {
|
|
|
90
95
|
export type IInputField = {
|
|
91
96
|
props: ComponentProps<typeof VcInput> | IControlBaseProps;
|
|
92
97
|
options: IControlBaseOptions;
|
|
98
|
+
slots?: Partial<Pick<ComponentSlots<typeof VcInput>, "append" | "prepend" | "append-inner" | "prepend-inner">>;
|
|
93
99
|
} & FieldOpts<typeof VcInput>;
|
|
94
100
|
|
|
101
|
+
export type IContentField = {
|
|
102
|
+
props: ComponentProps<typeof VcField> | IControlBaseProps;
|
|
103
|
+
options: IControlBaseOptions;
|
|
104
|
+
} & FieldOpts<typeof VcField>;
|
|
105
|
+
|
|
106
|
+
export type IVideoField = {
|
|
107
|
+
props: ComponentProps<typeof VcVideo> | IControlBaseProps;
|
|
108
|
+
options: IControlBaseOptions;
|
|
109
|
+
} & FieldOpts<typeof VcVideo>;
|
|
110
|
+
|
|
111
|
+
export type IImageField = {
|
|
112
|
+
props: ComponentProps<typeof VcImage> | IControlBaseProps;
|
|
113
|
+
options: IControlBaseOptions;
|
|
114
|
+
} & FieldOpts<typeof VcImage>;
|
|
115
|
+
|
|
95
116
|
export type IInputCurrency = {
|
|
96
117
|
props: Partial<ComponentProps<typeof VcInputCurrency>> | IControlBaseProps;
|
|
97
118
|
options: IControlBaseOptions;
|
|
@@ -15,12 +15,17 @@ export interface Props {
|
|
|
15
15
|
withDefaults(defineProps<Props>(), {
|
|
16
16
|
size: "1",
|
|
17
17
|
});
|
|
18
|
+
|
|
19
|
+
defineSlots<{
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
default: (props: any) => any;
|
|
22
|
+
}>();
|
|
18
23
|
</script>
|
|
19
24
|
|
|
20
25
|
<style lang="scss">
|
|
21
|
-
.vc-col {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
+
// .vc-col {
|
|
27
|
+
// .vc-app_mobile & {
|
|
28
|
+
// @apply tw-grow #{!important};
|
|
29
|
+
// }
|
|
30
|
+
// }
|
|
26
31
|
</style>
|
|
@@ -4,10 +4,17 @@
|
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
defineSlots<{
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
|
+
default: (props: any) => any;
|
|
11
|
+
}>();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
7
14
|
<style lang="scss">
|
|
8
15
|
.vc-row {
|
|
9
16
|
.vc-app_mobile & {
|
|
10
|
-
display:
|
|
17
|
+
display: grid;
|
|
11
18
|
}
|
|
12
19
|
}
|
|
13
20
|
</style>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- Text -->
|
|
3
|
+
<template v-if="type === 'text'">
|
|
4
|
+
<div class="tw-flex tw-flex-row tw-justify-stretch tw-truncate">
|
|
5
|
+
<div class="tw-truncate">
|
|
6
|
+
<VcHint class="tw-text-s">{{ value }}</VcHint>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<!-- Date -->
|
|
12
|
+
<template v-if="type === 'date'">
|
|
13
|
+
<div class="tw-flex tw-flex-row tw-justify-stretch tw-truncate">
|
|
14
|
+
<div class="tw-truncate">
|
|
15
|
+
<VcHint class="tw-text-s"> {{ value.toLocaleDateString() }}</VcHint>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<!-- Date ago -->
|
|
21
|
+
<template v-if="type === 'date-ago'">
|
|
22
|
+
<div class="tw-flex tw-flex-row tw-justify-stretch tw-truncate">
|
|
23
|
+
<div class="tw-truncate">
|
|
24
|
+
<VcHint class="tw-text-s"> {{ moment(value).fromNow() ?? "N/A" }}</VcHint>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<!-- Link -->
|
|
30
|
+
<template v-if="type === 'link'">
|
|
31
|
+
<div class="tw-flex tw-flex-row tw-justify-stretch tw-truncate">
|
|
32
|
+
<div class="tw-truncate">
|
|
33
|
+
<VcLink
|
|
34
|
+
class="vc-link tw-text-s tw-truncate tw-w-full"
|
|
35
|
+
@click="onLinkClick"
|
|
36
|
+
>{{ value }}</VcLink
|
|
37
|
+
>
|
|
38
|
+
</div>
|
|
39
|
+
<slot></slot>
|
|
40
|
+
</div>
|
|
41
|
+
</template>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<script lang="ts" setup>
|
|
45
|
+
import moment from "moment";
|
|
46
|
+
|
|
47
|
+
export interface Props {
|
|
48
|
+
type: "text" | "date" | "date-ago" | "link";
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50
|
+
value: any;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface Emits {
|
|
54
|
+
(event: "click"): void;
|
|
55
|
+
(event: "copy"): void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
defineEmits<Emits>();
|
|
59
|
+
const props = defineProps<Props>();
|
|
60
|
+
|
|
61
|
+
function onLinkClick() {
|
|
62
|
+
location.href = props.value;
|
|
63
|
+
}
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<style lang="scss" scoped></style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as VcField } from "./vc-field.vue";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<!-- Field label -->
|
|
4
|
+
<VcLabel v-if="label">
|
|
5
|
+
<span>{{ label }}</span>
|
|
6
|
+
<template
|
|
7
|
+
v-if="tooltip"
|
|
8
|
+
#tooltip
|
|
9
|
+
>{{ tooltip }}</template
|
|
10
|
+
></VcLabel
|
|
11
|
+
>
|
|
12
|
+
<!-- <div> -->
|
|
13
|
+
<VcFieldType
|
|
14
|
+
:value="modelValue"
|
|
15
|
+
:type="type"
|
|
16
|
+
>
|
|
17
|
+
<VcButton
|
|
18
|
+
v-if="copyable"
|
|
19
|
+
icon="far fa-copy"
|
|
20
|
+
size="m"
|
|
21
|
+
class="tw-ml-2"
|
|
22
|
+
text
|
|
23
|
+
@click="copy(modelValue)"
|
|
24
|
+
></VcButton>
|
|
25
|
+
</VcFieldType>
|
|
26
|
+
</div>
|
|
27
|
+
<!-- </div> -->
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script lang="ts" setup>
|
|
31
|
+
import { VcLabel } from "./../../";
|
|
32
|
+
import VcFieldType from "./_internal/vc-field-type/vc-field-type.vue";
|
|
33
|
+
|
|
34
|
+
export interface Props {
|
|
35
|
+
/**
|
|
36
|
+
* Field label text
|
|
37
|
+
*/
|
|
38
|
+
label?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Field tooltip information
|
|
41
|
+
*/
|
|
42
|
+
tooltip?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Field type
|
|
45
|
+
*/
|
|
46
|
+
type?: "text" | "date" | "date-ago" | "link";
|
|
47
|
+
/**
|
|
48
|
+
* Field content
|
|
49
|
+
*/
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
51
|
+
modelValue?: any;
|
|
52
|
+
/**
|
|
53
|
+
* Add button for field content copying
|
|
54
|
+
*/
|
|
55
|
+
copyable?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
withDefaults(defineProps<Props>(), {
|
|
59
|
+
type: "text",
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
function copy(value: string) {
|
|
63
|
+
navigator.clipboard?.writeText(value);
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<style lang="scss" scoped></style>
|
|
@@ -47,6 +47,11 @@ import VcPopupError from "./_internal/vc-popup-error/vc-popup-error.vue";
|
|
|
47
47
|
import { defineComponent, PropType } from "vue";
|
|
48
48
|
|
|
49
49
|
export default defineComponent({
|
|
50
|
+
components: {
|
|
51
|
+
VcIcon,
|
|
52
|
+
VcPopupWarning,
|
|
53
|
+
VcPopupError,
|
|
54
|
+
},
|
|
50
55
|
props: {
|
|
51
56
|
title: {
|
|
52
57
|
type: String,
|