@vc-shell/framework 1.0.116 → 1.0.118

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.
Files changed (141) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/core/composables/useApiClient/index.ts +2 -2
  3. package/core/plugins/modularity/index.ts +1 -0
  4. package/core/plugins/signalR/index.ts +13 -8
  5. package/core/plugins/validation/rules.ts +3 -3
  6. package/core/types/index.ts +1 -1
  7. package/dist/core/composables/useApiClient/index.d.ts +2 -2
  8. package/dist/core/composables/useApiClient/index.d.ts.map +1 -1
  9. package/dist/core/plugins/modularity/index.d.ts.map +1 -1
  10. package/dist/core/plugins/signalR/index.d.ts.map +1 -1
  11. package/dist/core/types/index.d.ts +1 -1
  12. package/dist/core/types/index.d.ts.map +1 -1
  13. package/dist/framework.mjs +12698 -12500
  14. package/dist/shared/components/blade-navigation/components/vc-blade-navigation/index.d.ts +1 -0
  15. package/dist/shared/components/blade-navigation/components/vc-blade-navigation/index.d.ts.map +1 -1
  16. package/dist/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue.d.ts +1 -0
  17. package/dist/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue.d.ts.map +1 -1
  18. package/dist/shared/components/blade-navigation/types/index.d.ts +3 -1
  19. package/dist/shared/components/blade-navigation/types/index.d.ts.map +1 -1
  20. package/dist/shared/components/notifications/composables/useContainer/index.d.ts.map +1 -1
  21. package/dist/shared/components/popup-handler/composables/usePopup/index.d.ts +2 -2
  22. package/dist/shared/components/popup-handler/composables/usePopup/index.d.ts.map +1 -1
  23. package/dist/shared/components/popup-handler/plugin.d.ts +2 -1
  24. package/dist/shared/components/popup-handler/plugin.d.ts.map +1 -1
  25. package/dist/shared/components/popup-handler/types/index.d.ts +11 -10
  26. package/dist/shared/components/popup-handler/types/index.d.ts.map +1 -1
  27. package/dist/shared/modules/assets-manager/components/assets-manager/assets-manager.vue.d.ts.map +1 -1
  28. package/dist/shared/modules/dynamic/components/FIELD_MAP.d.ts +5 -2202
  29. package/dist/shared/modules/dynamic/components/FIELD_MAP.d.ts.map +1 -1
  30. package/dist/shared/modules/dynamic/components/SchemaRender.d.ts +4 -4
  31. package/dist/shared/modules/dynamic/components/factories.d.ts +4 -1
  32. package/dist/shared/modules/dynamic/components/factories.d.ts.map +1 -1
  33. package/dist/shared/modules/dynamic/components/fields/Button.d.ts +1 -1
  34. package/dist/shared/modules/dynamic/components/fields/Card.d.ts +1 -1
  35. package/dist/shared/modules/dynamic/components/fields/Checkbox.d.ts +1 -1
  36. package/dist/shared/modules/dynamic/components/fields/ContentField.d.ts +131 -0
  37. package/dist/shared/modules/dynamic/components/fields/ContentField.d.ts.map +1 -0
  38. package/dist/shared/modules/dynamic/components/fields/DynamicProperty.d.ts +4 -2
  39. package/dist/shared/modules/dynamic/components/fields/DynamicProperty.d.ts.map +1 -1
  40. package/dist/shared/modules/dynamic/components/fields/EditorField.d.ts +1 -1
  41. package/dist/shared/modules/dynamic/components/fields/Fieldset.d.ts +1 -1
  42. package/dist/shared/modules/dynamic/components/fields/GalleryField.d.ts +2 -2
  43. package/dist/shared/modules/dynamic/components/fields/ImageField.d.ts +131 -0
  44. package/dist/shared/modules/dynamic/components/fields/ImageField.d.ts.map +1 -0
  45. package/dist/shared/modules/dynamic/components/fields/InputCurrency.d.ts +1 -1
  46. package/dist/shared/modules/dynamic/components/fields/InputField.d.ts +1 -1
  47. package/dist/shared/modules/dynamic/components/fields/SelectField.d.ts +3 -3
  48. package/dist/shared/modules/dynamic/components/fields/SelectField.d.ts.map +1 -1
  49. package/dist/shared/modules/dynamic/components/fields/StatusField.d.ts +1 -1
  50. package/dist/shared/modules/dynamic/components/fields/VideoField.d.ts +131 -0
  51. package/dist/shared/modules/dynamic/components/fields/VideoField.d.ts.map +1 -0
  52. package/dist/shared/modules/dynamic/components/fields/props.d.ts +1 -1
  53. package/dist/shared/modules/dynamic/composables/useFilterBuilder/index.d.ts.map +1 -1
  54. package/dist/shared/modules/dynamic/factories/types/index.d.ts.map +1 -1
  55. package/dist/shared/modules/dynamic/helpers/nodeBuilder.d.ts +3 -3
  56. package/dist/shared/modules/dynamic/helpers/nodeBuilder.d.ts.map +1 -1
  57. package/dist/shared/modules/dynamic/helpers/override.d.ts +2 -2
  58. package/dist/shared/modules/dynamic/helpers/override.d.ts.map +1 -1
  59. package/dist/shared/modules/dynamic/helpers/toolbarReducer.d.ts.map +1 -1
  60. package/dist/shared/modules/dynamic/helpers/unrefNested.d.ts +1 -1
  61. package/dist/shared/modules/dynamic/helpers/unrefNested.d.ts.map +1 -1
  62. package/dist/shared/modules/dynamic/index.d.ts.map +1 -1
  63. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts.map +1 -1
  64. package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts +8 -0
  65. package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts.map +1 -1
  66. package/dist/shared/modules/dynamic/types/index.d.ts +24 -2
  67. package/dist/shared/modules/dynamic/types/index.d.ts.map +1 -1
  68. package/dist/shared/modules/dynamic/types/models.d.ts +19 -5
  69. package/dist/shared/modules/dynamic/types/models.d.ts.map +1 -1
  70. package/dist/shared/pages/LoginPage/components/login/Login.vue.d.ts +4 -3
  71. package/dist/shared/pages/LoginPage/components/login/Login.vue.d.ts.map +1 -1
  72. package/dist/tsconfig.tsbuildinfo +1 -1
  73. package/dist/ui/components/molecules/index.d.ts +1 -0
  74. package/dist/ui/components/molecules/index.d.ts.map +1 -1
  75. package/dist/ui/components/molecules/vc-field/_internal/vc-field-type/vc-field-type.vue.d.ts +33 -0
  76. package/dist/ui/components/molecules/vc-field/_internal/vc-field-type/vc-field-type.vue.d.ts.map +1 -0
  77. package/dist/ui/components/molecules/vc-field/index.d.ts +2 -0
  78. package/dist/ui/components/molecules/vc-field/index.d.ts.map +1 -0
  79. package/dist/ui/components/molecules/vc-field/vc-field.vue.d.ts +45 -0
  80. package/dist/ui/components/molecules/vc-field/vc-field.vue.d.ts.map +1 -0
  81. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts.map +1 -1
  82. package/dist/ui/components/molecules/vc-select/index.d.ts +1 -177
  83. package/dist/ui/components/molecules/vc-select/index.d.ts.map +1 -1
  84. package/dist/ui/components/molecules/vc-select/vc-select.vue.d.ts +9 -6
  85. package/dist/ui/components/molecules/vc-select/vc-select.vue.d.ts.map +1 -1
  86. package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts +9 -9
  87. package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts.map +1 -1
  88. package/dist/ui/components/organisms/vc-gallery/_internal/vc-gallery-item/vc-gallery-item.vue.d.ts +3 -0
  89. package/dist/ui/components/organisms/vc-gallery/_internal/vc-gallery-item/vc-gallery-item.vue.d.ts.map +1 -1
  90. package/dist/ui/components/organisms/vc-popup/vc-popup.vue.d.ts +40 -46
  91. package/dist/ui/components/organisms/vc-popup/vc-popup.vue.d.ts.map +1 -1
  92. package/dist/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue.d.ts.map +1 -1
  93. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts +6 -6
  94. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
  95. package/dist/ui/types/index.d.ts +1 -0
  96. package/dist/ui/types/index.d.ts.map +1 -1
  97. package/package.json +7 -6
  98. package/shared/components/blade-navigation/types/index.ts +3 -1
  99. package/shared/components/notifications/composables/useContainer/index.ts +4 -2
  100. package/shared/components/popup-handler/composables/usePopup/index.ts +36 -18
  101. package/shared/components/popup-handler/plugin.ts +3 -3
  102. package/shared/components/popup-handler/types/index.ts +17 -8
  103. package/shared/modules/assets-manager/components/assets-manager/assets-manager.vue +7 -6
  104. package/shared/modules/dynamic/components/FIELD_MAP.ts +13 -1
  105. package/shared/modules/dynamic/components/SchemaRender.ts +6 -6
  106. package/shared/modules/dynamic/components/factories.ts +34 -1
  107. package/shared/modules/dynamic/components/fields/Card.ts +2 -2
  108. package/shared/modules/dynamic/components/fields/ContentField.ts +25 -0
  109. package/shared/modules/dynamic/components/fields/DynamicProperty.ts +31 -11
  110. package/shared/modules/dynamic/components/fields/GalleryField.ts +1 -1
  111. package/shared/modules/dynamic/components/fields/ImageField.ts +30 -0
  112. package/shared/modules/dynamic/components/fields/SelectField.ts +9 -3
  113. package/shared/modules/dynamic/components/fields/ValidationField.ts +3 -3
  114. package/shared/modules/dynamic/components/fields/VideoField.ts +28 -0
  115. package/shared/modules/dynamic/composables/useFilterBuilder/index.ts +21 -15
  116. package/shared/modules/dynamic/factories/types/index.ts +1 -1
  117. package/shared/modules/dynamic/helpers/nodeBuilder.ts +12 -11
  118. package/shared/modules/dynamic/helpers/override.ts +4 -4
  119. package/shared/modules/dynamic/helpers/setters.ts +1 -1
  120. package/shared/modules/dynamic/helpers/toolbarReducer.ts +3 -1
  121. package/shared/modules/dynamic/helpers/unrefNested.ts +2 -2
  122. package/shared/modules/dynamic/index.ts +2 -1
  123. package/shared/modules/dynamic/pages/dynamic-blade-form.vue +4 -1
  124. package/shared/modules/dynamic/pages/dynamic-blade-list.vue +51 -9
  125. package/shared/modules/dynamic/types/index.ts +30 -2
  126. package/shared/modules/dynamic/types/models.ts +25 -4
  127. package/shared/pages/LoginPage/components/login/Login.vue +4 -2
  128. package/ui/components/molecules/index.ts +1 -0
  129. package/ui/components/molecules/vc-field/_internal/vc-field-type/vc-field-type.vue +66 -0
  130. package/ui/components/molecules/vc-field/index.ts +1 -0
  131. package/ui/components/molecules/vc-field/vc-field.vue +67 -0
  132. package/ui/components/molecules/vc-input/vc-input.vue +1 -1
  133. package/ui/components/molecules/vc-multivalue/vc-multivalue.vue +8 -8
  134. package/ui/components/molecules/vc-select/index.ts +1 -3
  135. package/ui/components/molecules/vc-select/vc-select.vue +17 -14
  136. package/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +4 -4
  137. package/ui/components/organisms/vc-gallery/_internal/vc-gallery-item/vc-gallery-item.vue +4 -3
  138. package/ui/components/organisms/vc-popup/vc-popup.vue +23 -25
  139. package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +4 -2
  140. package/ui/components/organisms/vc-table/vc-table.vue +49 -31
  141. package/ui/types/index.ts +1 -0
@@ -1,8 +1,14 @@
1
- import { h, resolveComponent, ExtractPropTypes, Component } from "vue";
1
+ import { h, resolveComponent, ExtractPropTypes, Component, VNode } from "vue";
2
2
  import { SelectField } from "../factories";
3
3
  import componentProps from "./props";
4
4
  import ValidationField from "./ValidationField";
5
5
  import { SelectSchema } from "../../types";
6
+ import { VcSelect } from "../../../../../ui/components";
7
+ import type { ComponentSlots } from "vue-component-type-helpers";
8
+
9
+ type TScope =
10
+ | Parameters<ComponentSlots<typeof VcSelect>["option"]>["0"]
11
+ | Parameters<ComponentSlots<typeof VcSelect>["selected-item"]>["0"];
6
12
 
7
13
  export default {
8
14
  name: "SelectField",
@@ -25,10 +31,10 @@ export default {
25
31
  slots:
26
32
  props.element.customTemplate &&
27
33
  ["selected-item", "option"].reduce((obj, slot) => {
28
- obj[slot] = (scope) =>
34
+ obj[slot] = (scope: TScope) =>
29
35
  h(resolveComponent(props.element.customTemplate.component), { context: scope, slotName: slot });
30
36
  return obj;
31
- }, {}),
37
+ }, {} as Record<string, (scope: TScope) => VNode>),
32
38
  });
33
39
 
34
40
  const render = h(field.component as unknown as Component, field.props, field.slots);
@@ -1,4 +1,4 @@
1
- import { computed, h, unref, useSlots, defineComponent } from "vue";
1
+ import { computed, h, unref, useSlots, defineComponent, ComputedRef } from "vue";
2
2
  import { unrefNested } from "../../helpers/unrefNested";
3
3
  import { Field } from "vee-validate";
4
4
  import { reactify } from "@vueuse/core";
@@ -20,7 +20,7 @@ export default defineComponent({
20
20
  : String(props.props.key)
21
21
  );
22
22
 
23
- const fieldNameLang = reactify((name) => {
23
+ const fieldNameLang = reactify((name: string) => {
24
24
  return props.props.multilanguage ? name + "_" + props.props.currentLanguage : name;
25
25
  });
26
26
 
@@ -37,7 +37,7 @@ export default defineComponent({
37
37
  ).value,
38
38
  },
39
39
  {
40
- default: ({ errorMessage, errors }) => {
40
+ default: ({ errorMessage, errors }: { errorMessage: ComputedRef<string | undefined>; errors: string[] }) => {
41
41
  return slots.default().map((slot) =>
42
42
  h(slot, {
43
43
  ...props.props,
@@ -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
+ };
@@ -60,7 +60,7 @@ export default <Query>(args: { data: Data; query: MaybeRef<Query>; load: AsyncAc
60
60
  const _data = args.data;
61
61
 
62
62
  const isFilterVisible = ref(true);
63
- const filter = reactive({});
63
+ const filter: Record<string, unknown> = reactive({});
64
64
 
65
65
  const controls = ref<Control[]>([]);
66
66
 
@@ -74,21 +74,27 @@ export default <Query>(args: { data: Data; query: MaybeRef<Query>; load: AsyncAc
74
74
  onMounted(() => createFilterControls());
75
75
 
76
76
  function isItemSelected(value: string, field: string) {
77
- return filter[field]?.some((x) => x === value);
77
+ const item = filter[field];
78
+ if (Array.isArray(item) && typeof item !== "string") {
79
+ return item.some((x) => x === value);
80
+ }
78
81
  }
79
82
 
80
83
  function selectFilterItem(e: boolean, value: string, field: string) {
81
- const isSelected = filter[field]?.includes(value);
82
-
83
- if (!Array.isArray(filter[field])) {
84
+ const item = filter[field];
85
+ let isSelected = false;
86
+
87
+ if (Array.isArray(item)) {
88
+ isSelected = item.includes(value);
89
+
90
+ if (e && !isSelected) {
91
+ item.push(value);
92
+ } else if (!e && isSelected) {
93
+ filter[field] = item.filter((x) => x !== value);
94
+ }
95
+ } else {
84
96
  filter[field] = [];
85
97
  }
86
-
87
- if (e && !isSelected) {
88
- filter[field]?.push(value);
89
- } else if (!e && isSelected) {
90
- filter[field] = filter[field].filter((x) => x !== value);
91
- }
92
98
  }
93
99
 
94
100
  function createFilterControls() {
@@ -109,7 +115,7 @@ export default <Query>(args: { data: Data; query: MaybeRef<Query>; load: AsyncAc
109
115
  }
110
116
 
111
117
  return obj;
112
- }, {});
118
+ }, {} as Record<string, ReturnType<typeof Checkbox> | ReturnType<typeof InputField>>);
113
119
 
114
120
  return {
115
121
  title: item.title,
@@ -125,7 +131,7 @@ export default <Query>(args: { data: Data; query: MaybeRef<Query>; load: AsyncAc
125
131
  props: {
126
132
  classNames: "tw-mb-2",
127
133
  modelValue: computed(() => isItemSelected(currC.value, control.field)),
128
- "onUpdate:modelValue": (e) => selectFilterItem(e, currC.value, control.field),
134
+ "onUpdate:modelValue": (e: boolean) => selectFilterItem(e, currC.value, control.field),
129
135
  },
130
136
  slots: {
131
137
  default: () => currC.displayName,
@@ -136,7 +142,7 @@ export default <Query>(args: { data: Data; query: MaybeRef<Query>; load: AsyncAc
136
142
  });
137
143
 
138
144
  return obj;
139
- }, {});
145
+ }, {} as Record<string, ReturnType<typeof Checkbox>>);
140
146
  }
141
147
 
142
148
  function createInput(control: RawControl) {
@@ -146,7 +152,7 @@ export default <Query>(args: { data: Data; query: MaybeRef<Query>; load: AsyncAc
146
152
  classNames: "tw-mb-3",
147
153
  label: control.label,
148
154
  modelValue: computed(() => filter[control.field]),
149
- "onUpdate:modelValue": (e) => (filter[control.field] = e),
155
+ "onUpdate:modelValue": (e: unknown) => (filter[control.field] = e),
150
156
  },
151
157
  options: {
152
158
  visibility: computed(() => true),
@@ -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";
@@ -1,4 +1,4 @@
1
- import { unref, computed, toValue, h, UnwrapNestedRefs, MaybeRef, reactive } from "vue";
1
+ import { unref, computed, toValue, h, UnwrapNestedRefs, MaybeRef, reactive, Ref, VNode } from "vue";
2
2
  import FIELD_MAP from "../components/FIELD_MAP";
3
3
  import { ControlSchema } from "../types";
4
4
  import { IControlBaseProps, IControlBaseOptions } from "../types/models";
@@ -7,6 +7,7 @@ import { setModel } from "./setters";
7
7
  import { unwrapInterpolation } from "./unwrapInterpolation";
8
8
  import { DetailsBladeContext } from "../factories";
9
9
  import * as _ from "lodash-es";
10
+ import { unrefNested } from "./unrefNested";
10
11
 
11
12
  function disabledHandler(
12
13
  disabled: { method?: string } | boolean,
@@ -22,17 +23,17 @@ function disabledHandler(
22
23
  function nodeBuilder<Context, BContext extends UnwrapNestedRefs<DetailsBladeContext>, FormData>(args: {
23
24
  controlSchema: ControlSchema;
24
25
  parentId: string | number;
25
- internalContext: Context;
26
+ internalContext: MaybeRef<Context>;
26
27
  bladeContext: BContext;
27
28
  currentLocale: MaybeRef<string>;
28
29
  formData: FormData;
29
- }) {
30
+ }): VNode | false {
30
31
  const { controlSchema, parentId, internalContext, bladeContext, currentLocale, formData } = args;
31
32
  if (!controlSchema) return false;
32
33
 
33
34
  const baseProps = reactive<IControlBaseProps>({
34
35
  key: `${parentId}`,
35
- label: controlSchema.label ? unref(unwrapInterpolation(controlSchema.label, internalContext)) : undefined,
36
+ label: controlSchema.label ? unref(unwrapInterpolation(controlSchema.label, toValue(internalContext))) : undefined,
36
37
  disabled:
37
38
  ("disabled" in bladeContext.scope && bladeContext.scope.disabled) ||
38
39
  disabledHandler("disabled" in controlSchema && controlSchema.disabled, bladeContext),
@@ -40,14 +41,14 @@ function nodeBuilder<Context, BContext extends UnwrapNestedRefs<DetailsBladeCont
40
41
  rules: controlSchema.rules,
41
42
  placeholder: controlSchema.placeholder,
42
43
  required: controlSchema.rules?.required,
43
- modelValue: getModel(controlSchema.property, internalContext),
44
+ modelValue: getModel(controlSchema.property, toValue(internalContext)),
44
45
  "onUpdate:modelValue": (e) => {
45
- setModel({ property: controlSchema.property, value: e, context: internalContext });
46
+ setModel({ property: controlSchema.property, value: e, context: toValue(internalContext) });
46
47
 
47
48
  if (_.has(controlSchema, "update.method")) {
48
49
  controlSchema.update.method in bladeContext.scope &&
49
50
  typeof bladeContext.scope[controlSchema.update.method] === "function"
50
- ? bladeContext.scope[controlSchema.update.method](e, controlSchema.property, internalContext)
51
+ ? bladeContext.scope[controlSchema.update.method](e, controlSchema.property, toValue(internalContext))
51
52
  : undefined;
52
53
  }
53
54
  },
@@ -61,14 +62,14 @@ function nodeBuilder<Context, BContext extends UnwrapNestedRefs<DetailsBladeCont
61
62
  ),
62
63
  });
63
64
 
64
- const component = FIELD_MAP[controlSchema.component];
65
+ const component = FIELD_MAP[controlSchema.component as keyof typeof FIELD_MAP];
65
66
 
66
67
  const fieldsHandler = computed(() => {
67
68
  if (!("fields" in controlSchema)) return null;
68
- const fieldsModel = getModel(controlSchema.property, internalContext);
69
+ const fieldsModel = getModel(controlSchema.property, toValue(internalContext));
69
70
 
70
71
  if (toValue(fieldsModel) && Array.isArray(toValue(fieldsModel))) {
71
- return toValue(fieldsModel).map((model) =>
72
+ return toValue(fieldsModel).map((model: { [x: string]: unknown; id: string }) =>
72
73
  controlSchema.fields.map((fieldItem) =>
73
74
  nodeBuilder({
74
75
  controlSchema: fieldItem,
@@ -106,7 +107,7 @@ function nodeBuilder<Context, BContext extends UnwrapNestedRefs<DetailsBladeCont
106
107
  fieldContext: internalContext,
107
108
  };
108
109
 
109
- return h(component, elProps);
110
+ return h(component, unrefNested(elProps));
110
111
  }
111
112
 
112
113
  export { nodeBuilder };
@@ -1,7 +1,7 @@
1
1
  import * as _ from "lodash-es";
2
2
  import { DynamicSchema, OverridesSchema, OverridesUpsert } from "../types";
3
3
 
4
- export const handleOverrides = (overrides, schemaCopy: { [key: string]: DynamicSchema }) => {
4
+ export const handleOverrides = (overrides: OverridesSchema, schemaCopy: { [key: string]: DynamicSchema }) => {
5
5
  let schema = _.cloneDeep(schemaCopy);
6
6
 
7
7
  // REMOVE
@@ -49,10 +49,10 @@ const upsertHelper = (overrides: OverridesSchema, schemaCopy: { [key: string]: D
49
49
  );
50
50
  obj[name] = clonedSchema;
51
51
  return obj;
52
- }, {});
52
+ }, {} as Record<string, DynamicSchema>);
53
53
  };
54
54
 
55
- const removeHelper = (overrides, schemaCopy: { [key: string]: DynamicSchema }) => {
55
+ const removeHelper = (overrides: OverridesSchema, schemaCopy: { [key: string]: DynamicSchema }) => {
56
56
  return Object.entries(schemaCopy).reduce((obj, [name, schema]) => {
57
57
  const clonedSchema = _.cloneDeep(schema);
58
58
  overrides.remove
@@ -66,5 +66,5 @@ const removeHelper = (overrides, schemaCopy: { [key: string]: DynamicSchema }) =
66
66
  }, {});
67
67
  obj[name] = clonedSchema;
68
68
  return obj;
69
- }, {});
69
+ }, {} as Record<string, DynamicSchema>);
70
70
  };
@@ -9,7 +9,7 @@ function setModel(args: {
9
9
  }) {
10
10
  const { property, value, option, context } = args;
11
11
 
12
- _.set(context, property, option ? value[option] : value);
12
+ _.set(context, property, option ? value[option as keyof typeof value] : value);
13
13
  }
14
14
 
15
15
  export { setModel };
@@ -15,7 +15,9 @@ export const toolbarReducer = (args: {
15
15
  const toolbarMethodsMerge = _.merge(ref({}), ref(args.defaultToolbarBindings), ref(args.customToolbarConfig));
16
16
  return computed(() =>
17
17
  args.defaultToolbarSchema.reduce((acc, curr) => {
18
- const toolbarItemCtx = toolbarMethodsMerge.value[curr.method];
18
+ const toolbarItemCtx = toolbarMethodsMerge.value[
19
+ curr.method as keyof typeof toolbarMethodsMerge.value
20
+ ] as IBladeToolbar;
19
21
  if (toolbarItemCtx) {
20
22
  const context =
21
23
  typeof toolbarItemCtx === "function"
@@ -1,10 +1,10 @@
1
1
  import { unref } from "vue";
2
2
 
3
- export function unrefNested<T>(field: T) {
3
+ export function unrefNested<T extends Record<string, unknown>>(field: T) {
4
4
  const unreffedProps = {} as T;
5
5
 
6
6
  if (field) {
7
- Object.keys(field).forEach((key) => {
7
+ Object.keys(field).forEach((key: keyof T) => {
8
8
  unreffedProps[key] = unref(field[key]);
9
9
  });
10
10
 
@@ -66,6 +66,7 @@ const register = (
66
66
  const defineBladeComponent = defineComponent({
67
67
  ...bladeComponent,
68
68
  name: bladeName,
69
+ isWorkspace: "isWorkspace" in json.settings && json.settings.isWorkspace,
69
70
  setup: (props, ctx) =>
70
71
  (bladeComponent as DefineComponent).setup(
71
72
  reactiveComputed(() => ({
@@ -139,7 +140,7 @@ export const createDynamicAppModule = <T extends BladeMenu>(args: {
139
140
  const blade = register(
140
141
  {
141
142
  app,
142
- component: bladePages[JsonSchema.settings.component],
143
+ component: bladePages[JsonSchema.settings.component as keyof typeof bladePages],
143
144
  composables: { ...args.composables },
144
145
  json: JsonSchema,
145
146
  options,
@@ -190,7 +190,10 @@ const bladeMultilanguage = reactiveComputed(() => {
190
190
  });
191
191
 
192
192
  const bladeWidgets = computed(() => {
193
- return widgets.value?.children?.map((x) => resolveComponent(x));
193
+ return widgets.value?.children?.map((x) => {
194
+ if (typeof x === "string") return resolveComponent(x);
195
+ else throw new Error(`Component is required in widget: ${x}`);
196
+ });
194
197
  });
195
198
 
196
199
  const bladeOptions = reactive({
@@ -15,7 +15,7 @@
15
15
  :expanded="expanded"
16
16
  v-bind="bladeOptions?.table"
17
17
  :state-key="tableData?.id"
18
- :items="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"
@@ -122,6 +124,8 @@ import {
122
124
  unref,
123
125
  watch,
124
126
  UnwrapRef,
127
+ ShallowRef,
128
+ ConcreteComponent,
125
129
  } from "vue";
126
130
  import { useI18n } from "vue-i18n";
127
131
  import { DynamicGridSchema, ListContentSchema } from "../types";
@@ -131,6 +135,8 @@ import { ITableColumns } from "../../../../core/types";
131
135
  import { toolbarReducer } from "../helpers/toolbarReducer";
132
136
  import { notification, usePopup } from "../../../components";
133
137
  import { ListBaseBladeScope, ListBladeContext, UseList } from "../factories/types";
138
+ import { IParentCallArgs } from "../../../index";
139
+ import * as _ from "lodash-es";
134
140
 
135
141
  export interface Props {
136
142
  expanded?: boolean;
@@ -142,6 +148,7 @@ export interface Props {
142
148
  }
143
149
 
144
150
  export interface Emits {
151
+ (event: "parent:call", args: IParentCallArgs): void;
145
152
  (event: "close:blade"): void;
146
153
  (event: "collapse:blade"): void;
147
154
  (event: "expand:blade"): void;
@@ -172,6 +179,8 @@ const selectedItemId = ref();
172
179
  const sort = ref("createdDate:DESC");
173
180
  const selectedIds = ref<string[]>([]);
174
181
  const isDesktop = inject<Ref<boolean>>("isDesktop");
182
+ const itemsProxy = ref<Record<string, any>[]>();
183
+ const modified = ref(false);
175
184
 
176
185
  const { moduleNotifications, markAsRead } = useNotifications(settings.value.pushNotificationType);
177
186
 
@@ -229,7 +238,7 @@ const {
229
238
  const bladeContext = ref<ListBladeContext>({
230
239
  load,
231
240
  remove,
232
- items,
241
+ items: computed(() => itemsProxy.value),
233
242
  loading,
234
243
  pagination,
235
244
  query,
@@ -240,6 +249,12 @@ const bladeContext = ref<ListBladeContext>({
240
249
  const toolbarComputed = toolbarReducer({
241
250
  defaultToolbarSchema: settings.value.toolbar,
242
251
  defaultToolbarBindings: {
252
+ save: {
253
+ clickHandler() {
254
+ emit("close:blade");
255
+ },
256
+ disabled: computed(() => !modified.value),
257
+ },
243
258
  openAddBlade: {
244
259
  async clickHandler() {
245
260
  if (
@@ -272,10 +287,22 @@ onMounted(async () => {
272
287
  await load({ ...query.value, sort: sort.value });
273
288
  });
274
289
 
290
+ watch(
291
+ () => itemsProxy.value,
292
+ (newVal) => {
293
+ modified.value = !_.isEqual(newVal, items.value);
294
+ },
295
+ { deep: true }
296
+ );
297
+
275
298
  watch(sort, async (value) => {
276
299
  await load({ ...query.value, sort: value });
277
300
  });
278
301
 
302
+ watch(items, (newVal) => {
303
+ itemsProxy.value = newVal;
304
+ });
305
+
279
306
  watch(
280
307
  () => props.param,
281
308
  (newVal) => {
@@ -429,7 +456,7 @@ async function resetSearch() {
429
456
  });
430
457
  }
431
458
 
432
- function templateOverrideComponents(): Record<string, VNode> {
459
+ function templateOverrideComponents(): Record<string, ShallowRef<ConcreteComponent>> {
433
460
  return {
434
461
  ...table.value.columns?.reduce((acc, curr) => {
435
462
  if ("customTemplate" in curr) {
@@ -446,22 +473,37 @@ function templateOverrideComponents(): Record<string, VNode> {
446
473
  }
447
474
  }
448
475
  return acc;
449
- }, {}),
476
+ }, {} as Record<string, ShallowRef<ConcreteComponent>>),
450
477
  };
451
478
  }
452
479
 
453
- function resolveTemplateComponent(name: string) {
480
+ function resolveTemplateComponent(name: keyof ListContentSchema) {
454
481
  if (!tableData.value) return;
455
- const componentName = tableData.value[name]?.component;
456
- if (componentName) {
457
- const component = resolveComponent(componentName);
482
+ const value = tableData.value[name];
483
+ if (value && typeof value === "object" && "component" in value) {
484
+ const componentName = value.component;
485
+ if (componentName) {
486
+ const component = resolveComponent(componentName);
487
+
488
+ if (component && typeof component !== "string") return shallowRef(component);
489
+ }
490
+ }
491
+ }
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
+ });
458
499
 
459
- if (component && typeof component !== "string") return shallowRef(component);
500
+ itemsProxy.value = sorted;
460
501
  }
461
502
  }
462
503
 
463
504
  defineExpose({
464
505
  reload,
465
506
  title,
507
+ ...scope.value,
466
508
  });
467
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
  };
@@ -150,6 +151,30 @@ export interface InputSchema extends SchemaBase {
150
151
  clearable?: boolean;
151
152
  }
152
153
 
154
+ export interface VideoSchema extends SchemaBase {
155
+ component: "vc-video";
156
+ size?: ComponentProps<typeof VcVideo>["size"];
157
+ rounded?: boolean;
158
+ bordered?: boolean;
159
+ clickable?: boolean;
160
+ }
161
+
162
+ export interface FieldSchema extends SchemaBase {
163
+ component: "vc-field";
164
+ variant?: ComponentProps<typeof VcField>["type"];
165
+ copyable?: boolean;
166
+ }
167
+
168
+ export interface ImageSchema extends SchemaBase {
169
+ component: "vc-image";
170
+ aspect?: ComponentProps<typeof VcImage>["aspect"];
171
+ size?: ComponentProps<typeof VcImage>["size"];
172
+ background?: ComponentProps<typeof VcImage>["background"];
173
+ rounded?: boolean;
174
+ bordered?: boolean;
175
+ clickable?: boolean;
176
+ }
177
+
153
178
  export interface StatusSchema extends SchemaBase {
154
179
  component: "vc-status";
155
180
  outline?: boolean;
@@ -237,7 +262,10 @@ export type ControlSchema =
237
262
  | FieldsetSchema
238
263
  | ButtonSchema
239
264
  | InputCurrencySchema
240
- | StatusSchema;
265
+ | StatusSchema
266
+ | FieldSchema
267
+ | VideoSchema
268
+ | ImageSchema;
241
269
 
242
270
  export interface FilterBase {
243
271
  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,
@@ -54,7 +59,7 @@ export type ControlTypeCtr = Extract<ControlType, ISelectField | IInputField | I
54
59
 
55
60
  export interface IControlBaseProps {
56
61
  key?: string | number | symbol;
57
- rules?: string | Record<string, unknown>;
62
+ rules?: Record<string, unknown>;
58
63
  label?: string;
59
64
  placeholder?: string;
60
65
  disabled?: boolean;
@@ -92,6 +97,21 @@ export type IInputField = {
92
97
  options: IControlBaseOptions;
93
98
  } & FieldOpts<typeof VcInput>;
94
99
 
100
+ export type IContentField = {
101
+ props: ComponentProps<typeof VcField> | IControlBaseProps;
102
+ options: IControlBaseOptions;
103
+ } & FieldOpts<typeof VcField>;
104
+
105
+ export type IVideoField = {
106
+ props: ComponentProps<typeof VcVideo> | IControlBaseProps;
107
+ options: IControlBaseOptions;
108
+ } & FieldOpts<typeof VcVideo>;
109
+
110
+ export type IImageField = {
111
+ props: ComponentProps<typeof VcImage> | IControlBaseProps;
112
+ options: IControlBaseOptions;
113
+ } & FieldOpts<typeof VcImage>;
114
+
95
115
  export type IInputCurrency = {
96
116
  props: Partial<ComponentProps<typeof VcInputCurrency>> | IControlBaseProps;
97
117
  options: IControlBaseOptions;
@@ -112,7 +132,8 @@ export type ICheckbox = {
112
132
  export type IDynamicProperties = {
113
133
  props:
114
134
  | (ComponentProps<typeof VcDynamicProperty> & FromGenericEventsToProps<ComponentEmit<typeof VcDynamicProperty>>)
115
- | IControlBaseProps;
135
+ | (ComponentProps<typeof VcDynamicProperty> &
136
+ Omit<IControlBaseProps, keyof ComponentProps<typeof VcDynamicProperty> | "onUpdate:modelValue" | "rules">);
116
137
  options: IControlBaseOptions;
117
138
  } & FieldOpts<typeof VcDynamicProperty>;
118
139
 
@@ -122,7 +143,7 @@ export type IEditorField = {
122
143
  } & FieldOpts<typeof VcEditor>;
123
144
 
124
145
  export type IGallery = {
125
- props: ComponentProps<typeof VcGallery> | IControlBaseProps;
146
+ props: (ComponentProps<typeof VcGallery> & { rules: Record<string, unknown> }) | IControlBaseProps;
126
147
  options: IControlBaseOptions;
127
148
  } & FieldOpts<typeof VcGallery>;
128
149
 
@@ -185,11 +185,13 @@ import AzureAdIcon from "./../../../../../assets/img/AzureAd.svg";
185
185
  import { ExternalSignInProviderInfo } from "./../../../../../core/api/platform";
186
186
  import { useI18n } from "vue-i18n";
187
187
 
188
+ type ForgotPasswordFunc = (args: { loginOrEmail: string }) => Promise<void>;
189
+
188
190
  export interface Props {
189
191
  logo: string;
190
192
  background: string;
191
193
  title: string;
192
- composable?: () => { forgotPassword: (args: { loginOrEmail: string }) => Promise<void> };
194
+ composable?: () => { forgotPassword: ForgotPasswordFunc };
193
195
  }
194
196
 
195
197
  const props = defineProps<Props>();
@@ -210,7 +212,7 @@ const isDirty = useIsFormDirty();
210
212
  const customizationLoading = ref(false);
211
213
  const loadingForgotPassword = ref(false);
212
214
  const loginProviders = ref<ExternalSignInProviderInfo[]>();
213
- let forgotPassword;
215
+ let forgotPassword: ForgotPasswordFunc;
214
216
 
215
217
  if (props.composable && typeof props.composable === "function") {
216
218
  useLogin = props.composable;
@@ -12,3 +12,4 @@ export * from "./vc-select";
12
12
  export * from "./vc-slider";
13
13
  export * from "./vc-textarea";
14
14
  export * from "./vc-multivalue";
15
+ export * from "./vc-field";