@vc-shell/framework 1.0.214 → 1.0.216

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 (112) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/core/composables/useSettings/index.ts +1 -1
  3. package/dist/core/composables/useSettings/index.d.ts.map +1 -1
  4. package/dist/framework.js +32321 -24260
  5. package/dist/index.css +1 -1
  6. package/dist/locales/en.json +8 -0
  7. package/dist/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue.d.ts.map +1 -1
  8. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts +1 -1
  9. package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
  10. package/dist/shared/components/blade-navigation/types/index.d.ts +2 -0
  11. package/dist/shared/components/blade-navigation/types/index.d.ts.map +1 -1
  12. package/dist/shared/modules/dynamic/components/FIELD_MAP.d.ts.map +1 -1
  13. package/dist/shared/modules/dynamic/components/factories.d.ts +2 -1
  14. package/dist/shared/modules/dynamic/components/factories.d.ts.map +1 -1
  15. package/dist/shared/modules/dynamic/components/fields/InputCurrency.d.ts.map +1 -1
  16. package/dist/shared/modules/dynamic/components/fields/RadioButtonGroup.d.ts +121 -0
  17. package/dist/shared/modules/dynamic/components/fields/RadioButtonGroup.d.ts.map +1 -0
  18. package/dist/shared/modules/dynamic/components/fields/storybook/RadioButtonGroup.stories.d.ts +362 -0
  19. package/dist/shared/modules/dynamic/components/fields/storybook/RadioButtonGroup.stories.d.ts.map +1 -0
  20. package/dist/shared/modules/dynamic/composables/useFilterBuilder/index.d.ts.map +1 -1
  21. package/dist/shared/modules/dynamic/factories/types/index.d.ts +1 -1
  22. package/dist/shared/modules/dynamic/factories/types/index.d.ts.map +1 -1
  23. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts.map +1 -1
  24. package/dist/shared/modules/dynamic/types/index.d.ts +67 -3
  25. package/dist/shared/modules/dynamic/types/index.d.ts.map +1 -1
  26. package/dist/shared/modules/dynamic/types/models.d.ts +4 -1
  27. package/dist/shared/modules/dynamic/types/models.d.ts.map +1 -1
  28. package/dist/tsconfig.tsbuildinfo +1 -1
  29. package/dist/ui/components/atoms/index.d.ts +0 -1
  30. package/dist/ui/components/atoms/index.d.ts.map +1 -1
  31. package/dist/ui/components/atoms/vc-card/vc-card.stories.d.ts +40 -28
  32. package/dist/ui/components/atoms/vc-card/vc-card.stories.d.ts.map +1 -1
  33. package/dist/ui/components/atoms/vc-switch/vc-switch.stories.d.ts +6 -6
  34. package/dist/ui/components/molecules/index.d.ts +2 -0
  35. package/dist/ui/components/molecules/index.d.ts.map +1 -1
  36. package/dist/ui/components/{atoms → molecules}/vc-checkbox/index.d.ts +16 -16
  37. package/dist/ui/components/{atoms → molecules}/vc-checkbox/index.d.ts.map +1 -1
  38. package/dist/ui/components/{atoms → molecules}/vc-checkbox/vc-checkbox.stories.d.ts +160 -160
  39. package/dist/ui/components/molecules/vc-checkbox/vc-checkbox.stories.d.ts.map +1 -0
  40. package/dist/ui/components/molecules/vc-checkbox/vc-checkbox.vue.d.ts.map +1 -0
  41. package/dist/ui/components/molecules/vc-input/vc-input.stories.d.ts +40 -28
  42. package/dist/ui/components/molecules/vc-input/vc-input.stories.d.ts.map +1 -1
  43. package/dist/ui/components/molecules/vc-input/vc-input.vue.d.ts +10 -0
  44. package/dist/ui/components/molecules/vc-input/vc-input.vue.d.ts.map +1 -1
  45. package/dist/ui/components/molecules/vc-input-currency/vc-input-currency.stories.d.ts +28 -28
  46. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.stories.d.ts +63 -63
  47. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts +9 -9
  48. package/dist/ui/components/molecules/vc-radio-button/index.d.ts +2 -0
  49. package/dist/ui/components/molecules/vc-radio-button/index.d.ts.map +1 -0
  50. package/dist/ui/components/molecules/vc-radio-button/vc-radio-button.stories.d.ts +687 -0
  51. package/dist/ui/components/molecules/vc-radio-button/vc-radio-button.stories.d.ts.map +1 -0
  52. package/dist/ui/components/molecules/vc-radio-button/vc-radio-button.vue.d.ts +81 -0
  53. package/dist/ui/components/molecules/vc-radio-button/vc-radio-button.vue.d.ts.map +1 -0
  54. package/dist/ui/components/molecules/vc-select/vc-select.stories.d.ts +90 -90
  55. package/dist/ui/components/molecules/vc-select/vc-select.vue.d.ts +9 -9
  56. package/dist/ui/components/molecules/vc-select/vc-select.vue.d.ts.map +1 -1
  57. package/dist/ui/components/molecules/vc-textarea/vc-textarea.stories.d.ts +168 -168
  58. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue.d.ts +1 -0
  59. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue.d.ts.map +1 -1
  60. package/dist/ui/components/organisms/vc-blade/vc-blade.stories.d.ts +4 -4
  61. package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts +1 -1
  62. package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts.map +1 -1
  63. package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts.map +1 -1
  64. package/dist/ui/components/organisms/vc-gallery/vc-gallery.stories.d.ts +6 -6
  65. package/dist/ui/components/organisms/vc-login-form/index.d.ts +1 -72
  66. package/dist/ui/components/organisms/vc-login-form/index.d.ts.map +1 -1
  67. package/dist/ui/components/organisms/vc-login-form/vc-login-form.vue.d.ts +4 -2
  68. package/dist/ui/components/organisms/vc-login-form/vc-login-form.vue.d.ts.map +1 -1
  69. package/dist/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue.d.ts +3 -0
  70. package/dist/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue.d.ts.map +1 -1
  71. package/dist/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue.d.ts.map +1 -1
  72. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
  73. package/package.json +5 -4
  74. package/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +71 -42
  75. package/shared/components/blade-navigation/composables/useBladeNavigation/index.ts +9 -3
  76. package/shared/components/blade-navigation/types/index.ts +2 -0
  77. package/shared/modules/dynamic/components/FIELD_MAP.ts +2 -0
  78. package/shared/modules/dynamic/components/factories.ts +10 -0
  79. package/shared/modules/dynamic/components/fields/InputCurrency.ts +4 -1
  80. package/shared/modules/dynamic/components/fields/RadioButtonGroup.ts +82 -0
  81. package/shared/modules/dynamic/components/fields/storybook/Checkbox.stories.ts +1 -1
  82. package/shared/modules/dynamic/components/fields/storybook/RadioButtonGroup.stories.ts +224 -0
  83. package/shared/modules/dynamic/composables/useFilterBuilder/index.ts +202 -33
  84. package/shared/modules/dynamic/factories/types/index.ts +1 -1
  85. package/shared/modules/dynamic/pages/dynamic-blade-form.vue +3 -3
  86. package/shared/modules/dynamic/pages/dynamic-blade-list.vue +1 -1
  87. package/shared/modules/dynamic/types/index.ts +72 -3
  88. package/shared/modules/dynamic/types/models.ts +5 -0
  89. package/ui/components/atoms/index.ts +0 -1
  90. package/ui/components/atoms/vc-label/vc-label.vue +1 -1
  91. package/ui/components/molecules/index.ts +2 -0
  92. package/ui/components/{atoms → molecules}/vc-checkbox/vc-checkbox.stories.ts +3 -3
  93. package/ui/components/molecules/vc-checkbox/vc-checkbox.vue +204 -0
  94. package/ui/components/molecules/vc-file-upload/vc-file-upload.vue +1 -1
  95. package/ui/components/molecules/vc-input/vc-input.vue +122 -33
  96. package/ui/components/molecules/vc-radio-button/index.ts +1 -0
  97. package/ui/components/molecules/vc-radio-button/vc-radio-button.stories.ts +97 -0
  98. package/ui/components/molecules/vc-radio-button/vc-radio-button.vue +197 -0
  99. package/ui/components/molecules/vc-select/vc-select.vue +1 -1
  100. package/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue +42 -0
  101. package/ui/components/organisms/vc-blade/vc-blade.vue +4 -2
  102. package/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +4 -4
  103. package/ui/components/organisms/vc-login-form/index.ts +1 -10
  104. package/ui/components/organisms/vc-login-form/vc-login-form.vue +20 -0
  105. package/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue +8 -0
  106. package/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue +16 -22
  107. package/ui/components/organisms/vc-table/vc-table.vue +23 -3
  108. package/dist/ui/components/atoms/vc-checkbox/vc-checkbox.stories.d.ts.map +0 -1
  109. package/dist/ui/components/atoms/vc-checkbox/vc-checkbox.vue.d.ts.map +0 -1
  110. package/ui/components/atoms/vc-checkbox/vc-checkbox.vue +0 -146
  111. /package/dist/ui/components/{atoms → molecules}/vc-checkbox/vc-checkbox.vue.d.ts +0 -0
  112. /package/ui/components/{atoms → molecules}/vc-checkbox/index.ts +0 -0
@@ -0,0 +1,82 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { Component, ExtractPropTypes, h, toValue, unref } from "vue";
3
+ import { unrefNested } from "../../helpers/unrefNested";
4
+ import componentProps from "./props";
5
+ import ValidationField from "./ValidationField";
6
+ import { RadioButton } from "../factories";
7
+ import { RadioButtonSchema } from "../../types";
8
+ import { getModel } from "../../helpers/getters";
9
+ import * as _ from "lodash-es";
10
+ import { VcLabel, VcHint } from "../../../../../ui/components";
11
+
12
+ export default {
13
+ name: "RadioButtonGroup",
14
+ props: componentProps,
15
+ setup(props: ExtractPropTypes<typeof componentProps> & { element: RadioButtonSchema }) {
16
+ return () => {
17
+ const label = unrefNested(props.baseProps).label;
18
+ const options: any[] =
19
+ toValue(getModel(props.element.options, props.fieldContext ?? {})) ||
20
+ toValue(unref(props.bladeContext.scope)?.[props.element.options]);
21
+
22
+ const fields = options.map((opt) =>
23
+ RadioButton({
24
+ props: Object.assign(
25
+ {},
26
+ {
27
+ value: props.element.optionValue ? toValue(getModel(props.element.optionValue, opt ?? {})) : opt,
28
+ binary: props.element.binary,
29
+ label: props.element.optionLabel ? toValue(getModel(props.element.optionLabel, opt ?? {})) : opt,
30
+ },
31
+ _.omit(unrefNested(props.baseProps), "label"),
32
+ {
33
+ class: unrefNested(props.baseProps).classNames ?? "",
34
+ },
35
+ ),
36
+ }),
37
+ );
38
+
39
+ const render = [
40
+ label
41
+ ? h(
42
+ VcLabel,
43
+ { required: props.element.rules?.required },
44
+ {
45
+ default: () => label,
46
+ tooltip: unrefNested(props.baseProps).tooltip ? () => unrefNested(props.baseProps).tooltip : undefined,
47
+ },
48
+ )
49
+ : undefined,
50
+ fields.map((field) => h(field.component as Component, field.props)),
51
+ h({
52
+ props: ["error", "errorMessage"],
53
+ components: { VcHint },
54
+ template: `
55
+ <VcHint v-if="error" class="vc-textarea__error">
56
+ {{ errorMessage }}
57
+ </VcHint>
58
+ `,
59
+ }),
60
+ ];
61
+
62
+ if (props.element.rules) {
63
+ return h(
64
+ ValidationField,
65
+ {
66
+ props: {
67
+ rules: props.element.rules,
68
+ modelValue: unrefNested(props.baseProps).modelValue,
69
+ label: unrefNested(props.baseProps).label,
70
+ name: unrefNested(props.baseProps).name,
71
+ },
72
+ index: props.elIndex,
73
+ rows: props.rows,
74
+ },
75
+ () => render,
76
+ );
77
+ } else {
78
+ return render;
79
+ }
80
+ };
81
+ },
82
+ };
@@ -7,7 +7,7 @@ import { SchemaBaseArgTypes } from "./common/args";
7
7
  import { CheckboxSchema } from "../../..";
8
8
 
9
9
  export default {
10
- title: "DynamicViews/atoms/VcCheckbox",
10
+ title: "DynamicViews/molecules/VcCheckbox",
11
11
  component: page,
12
12
  args: {
13
13
  id: "checkboxId",
@@ -0,0 +1,224 @@
1
+ import { Meta, StoryFn } from "@storybook/vue3";
2
+ import { computed, reactive, ref } from "vue";
3
+ import page from "./pages/DynamicRender";
4
+ import { template, templateWithVisibilityToggle } from "./common/templates";
5
+ import * as _ from "lodash-es";
6
+ import { SchemaBaseArgTypes } from "./common/args";
7
+ import { RadioButtonSchema } from "../../..";
8
+
9
+ export default {
10
+ title: "DynamicViews/molecules/VcRadioButtonGroup",
11
+ component: page,
12
+ args: {
13
+ id: "radioButton",
14
+ component: "vc-radio-button-group",
15
+ property: "selectedProduct",
16
+ options: "products",
17
+ },
18
+ argTypes: {
19
+ ..._.omit(SchemaBaseArgTypes, ["multilanguage", "placeholder", "tooltip"]),
20
+ component: {
21
+ description: "Component type.",
22
+ type: {
23
+ required: true,
24
+ name: "string",
25
+ },
26
+ table: {
27
+ type: {
28
+ summary: "vc-radio-button",
29
+ },
30
+ defaultValue: {
31
+ summary: "vc-radio-button",
32
+ },
33
+ },
34
+ },
35
+ },
36
+ parameters: {
37
+ docs: {
38
+ canvas: {
39
+ sourceState: "none",
40
+ },
41
+ },
42
+ },
43
+ } satisfies Meta<RadioButtonSchema>;
44
+
45
+ export const Template: StoryFn<RadioButtonSchema> = (args) => ({
46
+ components: { page },
47
+ setup: () => {
48
+ const context = reactive({
49
+ item: {
50
+ selectedProduct: undefined,
51
+ },
52
+ scope: {
53
+ products: ["Product 1"],
54
+ },
55
+ });
56
+
57
+ return { args, context };
58
+ },
59
+ template,
60
+ });
61
+
62
+ export const Group: StoryFn<RadioButtonSchema> = (args) => ({
63
+ components: { page },
64
+ setup: () => {
65
+ const context = reactive({
66
+ item: {
67
+ selectedProduct: undefined,
68
+ },
69
+ scope: {
70
+ products: [
71
+ { id: 1, name: "Product 1" },
72
+ { id: 2, name: "Product 2" },
73
+ { id: 3, name: "Product 3" },
74
+ ],
75
+ },
76
+ });
77
+ return { args, context };
78
+ },
79
+ template,
80
+ });
81
+ Group.args = {
82
+ id: "radioButton",
83
+ component: "vc-radio-button-group",
84
+ property: "selectedProduct",
85
+ options: "products",
86
+ optionValue: "name",
87
+ optionLabel: "name",
88
+ };
89
+
90
+ export const StringGroup: StoryFn<RadioButtonSchema> = (args) => ({
91
+ components: { page },
92
+ setup: () => {
93
+ const context = reactive({
94
+ item: {
95
+ selectedProduct: undefined,
96
+ },
97
+ scope: {
98
+ products: ["Product 1", "Product 2", "Product 3"],
99
+ },
100
+ });
101
+ return { args, context };
102
+ },
103
+ template,
104
+ });
105
+ StringGroup.args = {
106
+ id: "radioButton",
107
+ component: "vc-radio-button-group",
108
+ property: "selectedProduct",
109
+ options: "products",
110
+ };
111
+
112
+ export const WithLabel = StringGroup.bind({});
113
+ WithLabel.args = {
114
+ label: "Select one product",
115
+ };
116
+
117
+ export const WithTooltip = StringGroup.bind({});
118
+ WithTooltip.args = {
119
+ label: "Select one product",
120
+ tooltip: "This is tooltip!",
121
+ };
122
+
123
+ export const Disabled: StoryFn<RadioButtonSchema> = (args) => ({
124
+ components: { page },
125
+ setup: () => {
126
+ const context = reactive({
127
+ item: {
128
+ selectedProduct: undefined,
129
+ },
130
+ scope: {
131
+ products: ["Product 1"],
132
+ disabledFn: computed(() => true),
133
+ },
134
+ });
135
+ return { args, context };
136
+ },
137
+ template,
138
+ });
139
+ Disabled.args = {
140
+ disabled: {
141
+ method: "disabledFn",
142
+ },
143
+ };
144
+
145
+ export const Binary: StoryFn<RadioButtonSchema> = (args) => ({
146
+ components: { page },
147
+ setup: () => {
148
+ const context = reactive({
149
+ item: {
150
+ selectedProduct: true,
151
+ },
152
+ scope: {
153
+ products: ["Product 1"],
154
+ },
155
+ });
156
+ return { args, context };
157
+ },
158
+ template,
159
+ });
160
+ Binary.args = {
161
+ binary: true,
162
+ };
163
+
164
+ export const WithVisibilityMethod: StoryFn<RadioButtonSchema> = (args) => ({
165
+ components: { page },
166
+ setup: () => {
167
+ const isVisible = ref(false);
168
+ const toggle = () => {
169
+ isVisible.value = !isVisible.value;
170
+ };
171
+
172
+ const context = reactive({
173
+ item: {
174
+ selectedProduct: true,
175
+ },
176
+ scope: {
177
+ products: ["Product 1"],
178
+ visibilityFn: isVisible,
179
+ },
180
+ });
181
+ return { args, context, toggle };
182
+ },
183
+ template: templateWithVisibilityToggle,
184
+ });
185
+ WithVisibilityMethod.args = {
186
+ visibility: {
187
+ method: "visibilityFn",
188
+ },
189
+ };
190
+
191
+ export const HorizontalSeparator = Template.bind({});
192
+ HorizontalSeparator.args = {
193
+ horizontalSeparator: true,
194
+ };
195
+
196
+ export const WithUpdateMethod: StoryFn<RadioButtonSchema> = (args) => ({
197
+ components: { page },
198
+ setup: () => {
199
+ const context = reactive({
200
+ item: {
201
+ selectedProduct: true,
202
+ },
203
+ scope: {
204
+ products: ["Product 1", "Product 2", "Product 3"],
205
+ updateFn: (value: string) => alert(`Value updated to: ${value}`),
206
+ },
207
+ });
208
+ return { args, context };
209
+ },
210
+ template,
211
+ });
212
+ WithUpdateMethod.args = {
213
+ update: {
214
+ method: "updateFn",
215
+ },
216
+ };
217
+
218
+ export const WithRequiredRule = Template.bind({});
219
+ WithRequiredRule.args = {
220
+ label: "Select one product",
221
+ rules: {
222
+ required: true,
223
+ },
224
+ };
@@ -7,7 +7,6 @@ import {
7
7
  MaybeRef,
8
8
  unref,
9
9
  Component,
10
- onMounted,
11
10
  RendererElement,
12
11
  RendererNode,
13
12
  VNode,
@@ -18,17 +17,29 @@ import {
18
17
  watchPostEffect,
19
18
  } from "vue";
20
19
  import * as _ from "lodash-es";
21
- import { Checkbox, InputField } from "../../components/factories";
20
+ import { Checkbox, InputField, Switch, SelectField, RadioButton } from "../../components/factories";
22
21
  import { AsyncAction } from "../../../../../core/composables";
23
- import { VcButton, VcCol, VcContainer, VcRow } from "../../../../../ui/components";
22
+ import { VcButton, VcCol, VcContainer, VcLabel, VcRow } from "../../../../../ui/components";
24
23
  import { useI18n } from "vue-i18n";
25
- import { FilterBase, FilterCheckbox, FilterDateInput } from "../../types";
24
+ import { FilterBase, FilterCheckbox, FilterDateInput, FilterRadio, FilterSelect, FilterSwitch } from "../../types";
26
25
 
27
26
  interface Control {
28
27
  title: string;
29
- fields: {
30
- [x: string]: ReturnType<typeof Checkbox> | ReturnType<typeof InputField>;
31
- };
28
+ fields: Record<
29
+ string,
30
+ {
31
+ fields: Record<
32
+ string,
33
+ | ReturnType<typeof Checkbox>
34
+ | ReturnType<typeof InputField>
35
+ | ReturnType<typeof Switch>
36
+ | ReturnType<typeof SelectField>
37
+ | ReturnType<typeof RadioButton>
38
+ >;
39
+ label?: string | ComputedRef<string> | undefined;
40
+ tooltip?: string | ComputedRef<string> | undefined;
41
+ }
42
+ >;
32
43
  }
33
44
 
34
45
  export interface UseFilterBuilder {
@@ -111,43 +122,178 @@ export default <Query>(args: {
111
122
  const fields = createCheckboxFromData(filterDataFromScope, control);
112
123
 
113
124
  if (fields) {
114
- obj = fields;
125
+ obj[control.field] = {
126
+ fields,
127
+ label: computed(() => t(control.label ?? "")),
128
+ tooltip: computed(() => t(control.tooltip ?? "")),
129
+ };
115
130
  }
116
131
  }
132
+
117
133
  if (control.component === "vc-input") {
118
- obj[control.field] = createInput(control);
134
+ obj[control.field] = {
135
+ fields: {
136
+ [control.field]: createInput(control),
137
+ },
138
+ };
139
+ }
140
+
141
+ if (control.component === "vc-switch") {
142
+ const filterData = control.data;
143
+ const filterDataFromScope = unref(args.scope)?.[filterData] ?? [];
144
+ const fields = createSwitchFromData(filterDataFromScope, control);
145
+
146
+ if (fields) {
147
+ obj[control.field] = {
148
+ fields,
149
+ };
150
+ }
151
+ }
152
+
153
+ if (control.component === "vc-select") {
154
+ const filterData = control.data;
155
+ const filterDataFromScope = unref(args.scope)?.[filterData] ?? [];
156
+ const fields = createSelectFromData(filterDataFromScope, control);
157
+
158
+ if (fields) {
159
+ obj[control.field] = {
160
+ fields,
161
+ };
162
+ }
163
+ }
164
+
165
+ if (control.component === "vc-radio-button-group") {
166
+ const filterData = control.data;
167
+ const filterDataFromScope = unref(args.scope)?.[filterData] ?? [];
168
+ const fields = createRadioButtonGroupFromData(filterDataFromScope, control);
169
+
170
+ if (fields) {
171
+ obj[control.field] = {
172
+ fields,
173
+ label: computed(() => t(control.label ?? "")),
174
+ tooltip: computed(() => t(control.tooltip ?? "")),
175
+ };
176
+ }
119
177
  }
120
178
 
121
179
  return obj;
122
180
  },
123
- {} as Record<string, ReturnType<typeof Checkbox> | ReturnType<typeof InputField>>,
181
+ {} as Record<
182
+ string,
183
+ {
184
+ fields: Record<
185
+ string,
186
+ | ReturnType<typeof Checkbox>
187
+ | ReturnType<typeof InputField>
188
+ | ReturnType<typeof Switch>
189
+ | ReturnType<typeof SelectField>
190
+ | ReturnType<typeof RadioButton>
191
+ >;
192
+ label?: string | ComputedRef<string>;
193
+ tooltip?: string | ComputedRef<string>;
194
+ }
195
+ >,
124
196
  );
125
197
 
126
198
  return {
127
- title: item.title,
199
+ title: item.title ?? "",
128
200
  fields: ctr,
129
201
  };
130
202
  });
131
203
  }
132
204
 
133
- function createCheckboxFromData(data: MaybeRef<Record<string, string>[]>, control: FilterCheckbox) {
205
+ function createRadioButtonGroupFromData(data: MaybeRef<Record<string, string>[]>, control: FilterRadio) {
134
206
  if (!(toValue(data) && toValue(data).length)) return;
135
207
  return toValue(data).reduce(
136
208
  (obj, currC) => {
137
- obj[currC[control.optionValue]] = Checkbox({
209
+ obj[currC[control.optionValue]] = {
210
+ ...RadioButton({
211
+ props: {
212
+ class: "tw-mb-2",
213
+ value: currC[control.optionValue],
214
+ label: currC[control.optionLabel],
215
+ modelValue: computed(() => filter.value[control.field]),
216
+ "onUpdate:modelValue": (e: string) => {
217
+ filter.value[control.field] = e;
218
+ },
219
+ },
220
+ }),
221
+ };
222
+
223
+ return obj;
224
+ },
225
+ {} as Record<string, ReturnType<typeof RadioButton>>,
226
+ );
227
+ }
228
+
229
+ function createSelectFromData(data: MaybeRef<Record<string, string>[]>, control: FilterSelect) {
230
+ if (!(toValue(data) && toValue(data).length)) return;
231
+
232
+ return {
233
+ [control.field]: SelectField({
234
+ props: {
235
+ class: "tw-mb-2",
236
+ label: computed(() => t(control.label ?? "")) as unknown as string,
237
+ tooltip: computed(() => t(control.tooltip ?? "")) as unknown as string,
238
+ options: toValue(data),
239
+ multiple: control.multiple,
240
+ optionLabel: control.optionLabel,
241
+ optionValue: control.optionValue,
242
+ clearable: false,
243
+ modelValue: computed(() => filter.value[control.field]),
244
+ "onUpdate:modelValue": (e: string | string[]) => {
245
+ if (Array.isArray(e) && e.length === 0) {
246
+ filter.value[control.field] = undefined;
247
+ return;
248
+ }
249
+ filter.value[control.field] = e;
250
+ },
251
+ },
252
+ }),
253
+ };
254
+ }
255
+
256
+ function createSwitchFromData(data: MaybeRef<Record<string, string>[]>, control: FilterSwitch) {
257
+ if (!(toValue(data) && toValue(data).length)) return;
258
+ return toValue(data).reduce(
259
+ (obj, currC) => {
260
+ obj[currC[control.optionValue]] = Switch({
138
261
  props: {
139
262
  class: "tw-mb-2",
263
+ label: toValue(currC[control.optionLabel]),
264
+ tooltip: computed(() => t(control.tooltip ?? "")) as unknown as string,
140
265
  modelValue: computed(() => isItemSelected(currC[control.optionValue], control.field)),
141
266
  "onUpdate:modelValue": (e: boolean) =>
142
267
  selectFilterItem(e, currC[control.optionValue], control.field, control.multiple),
143
268
  },
144
- slots: {
145
- default: () => toValue(currC[control.optionLabel]),
146
- },
147
269
  });
148
270
 
149
271
  return obj;
150
272
  },
273
+ {} as Record<string, ReturnType<typeof Switch>>,
274
+ );
275
+ }
276
+
277
+ function createCheckboxFromData(data: MaybeRef<Record<string, string>[]>, control: FilterCheckbox) {
278
+ if (!(toValue(data) && toValue(data).length)) return;
279
+ return toValue(data).reduce(
280
+ (obj, currC) => {
281
+ obj[currC[control.optionValue]] = {
282
+ ...Checkbox({
283
+ props: {
284
+ class: "tw-mb-2",
285
+ modelValue: computed(() => isItemSelected(currC[control.optionValue], control.field)),
286
+ "onUpdate:modelValue": (e: boolean) =>
287
+ selectFilterItem(e, currC[control.optionValue], control.field, control.multiple),
288
+ },
289
+ slots: {
290
+ default: () => toValue(currC[control.optionLabel]),
291
+ },
292
+ }),
293
+ };
294
+
295
+ return obj;
296
+ },
151
297
  {} as Record<string, ReturnType<typeof Checkbox>>,
152
298
  );
153
299
  }
@@ -158,6 +304,7 @@ export default <Query>(args: {
158
304
  type: "date",
159
305
  class: "tw-mb-3",
160
306
  label: toValue(computed(() => t(control.label ?? ""))),
307
+ tooltip: toValue(computed(() => t(control.tooltip ?? ""))),
161
308
  modelValue: computed(() => filter.value[control.field]),
162
309
  "onUpdate:modelValue": (e: unknown) => (filter.value[control.field] = e),
163
310
  },
@@ -197,24 +344,46 @@ export default <Query>(args: {
197
344
  },
198
345
  () => [
199
346
  h(VcRow, () =>
200
- Object.values(controls.value).map(({ title, fields }) =>
201
- h(VcCol, { class: "tw-p-2 !tw-flex-auto" }, () => [
202
- h(
203
- "div",
204
- { class: "tw-mb-4 tw-text-[#a1c0d4] tw-font-bold tw-text-[17px]" },
205
- unref(computed(() => t(title))),
206
- ),
207
- Object.values(fields).map((item) => {
208
- if ("component" in item && item.component) {
209
- return h(
210
- item.component as Component,
211
- { ...item.props, class: item.props.class },
212
- "slots" in item && item.slots ? { ...item.slots } : {},
213
- );
214
- }
347
+ Object.values(controls.value).map(({ title, fields }) => {
348
+ return h(VcCol, { class: "tw-p-2" }, () => [
349
+ title
350
+ ? h(
351
+ "div",
352
+ { class: "tw-mb-4 tw-text-[#a1c0d4] tw-font-bold tw-text-[17px]" },
353
+ unref(computed(() => t(title))),
354
+ )
355
+ : undefined,
356
+ Object.values(fields)?.map((items) => {
357
+ return items.label
358
+ ? h(
359
+ VcLabel,
360
+ {
361
+ class: "tw-mb-2",
362
+ },
363
+ {
364
+ default: () => items.label,
365
+ tooltip: items.tooltip ? () => items.tooltip : undefined,
366
+ },
367
+ )
368
+ : undefined;
215
369
  }),
216
- ]),
217
- ),
370
+ Object.values(fields)?.map((items) => {
371
+ return Object.values(items.fields).map((item) => {
372
+ if ("component" in item && item.component) {
373
+ return [
374
+ h(
375
+ item.component as Component,
376
+ { ...item.props, class: item.props.class },
377
+ "slots" in item && item.slots ? { ...item.slots } : {},
378
+ ),
379
+ ];
380
+ } else {
381
+ return item;
382
+ }
383
+ });
384
+ }),
385
+ ]);
386
+ }),
218
387
  ),
219
388
  h(VcRow, () =>
220
389
  h(VcCol, { class: "tw-p-2 !tw-flex-auto" }, () =>
@@ -95,7 +95,7 @@ export type TListItemClickArgs<Item extends Record<string, any> = Record<string,
95
95
 
96
96
  export interface DetailsBaseBladeScope extends BaseBladeScope {
97
97
  disabled?: ComputedRef<boolean | undefined> | Ref<boolean | undefined>;
98
- isBladeEditable?: ComputedRef<boolean | undefined> | Ref<boolean | undefined>;
98
+ isBladeEditable?: ComputedRef<boolean | undefined> | Ref<boolean | undefined> | boolean;
99
99
  multilanguage?: {
100
100
  loading: ComputedRef<boolean>;
101
101
  currentLocale: Ref<string>;
@@ -7,7 +7,7 @@
7
7
  :width="settings?.width || '50%'"
8
8
  :toolbar-items="toolbarComputed"
9
9
  :title="title"
10
- :has-unsaved-changes="isFormModified"
10
+ :modified="toValue(scope)?.isBladeEditable ? isFormModified : undefined"
11
11
  @close="$emit('close:blade')"
12
12
  @expand="$emit('expand:blade')"
13
13
  @collapse="$emit('collapse:blade')"
@@ -84,7 +84,7 @@ import {
84
84
  toRef,
85
85
  } from "vue";
86
86
  import { DynamicDetailsSchema, FormContentSchema, SettingsSchema } from "../types";
87
- import { reactiveComputed, toReactive, useMounted, useTemplateRefsList } from "@vueuse/core";
87
+ import { reactiveComputed, refDefault, toReactive, useMounted, useTemplateRefsList } from "@vueuse/core";
88
88
  import {
89
89
  DetailsBladeContext,
90
90
  DetailsBaseBladeScope,
@@ -357,7 +357,7 @@ onBeforeClose(async () => {
357
357
  });
358
358
 
359
359
  provide("bladeContext", toReactive(bladeContext));
360
- provide("isBladeEditable", toRef(toValue(scope ?? {}), "isBladeEditable"));
360
+ provide("isBladeEditable", refDefault(toRef(toValue(scope ?? {}), "isBladeEditable"), true));
361
361
 
362
362
  defineExpose({
363
363
  title: bladeTitle ?? "",
@@ -10,7 +10,7 @@
10
10
  :class="{
11
11
  'tw-flex tw-flex-auto': isWidgetView,
12
12
  }"
13
- :has-unsaved-changes="unref(scope)?.modified"
13
+ :modified="unref(scope)?.modified"
14
14
  @close="$emit('close:blade')"
15
15
  @expand="$emit('expand:blade')"
16
16
  @collapse="$emit('collapse:blade')"