@vc-shell/framework 1.0.215 → 1.0.217

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 (107) 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 +32316 -24274
  5. package/dist/index.css +1 -1
  6. package/dist/locales/en.json +8 -0
  7. package/dist/shared/modules/dynamic/components/FIELD_MAP.d.ts.map +1 -1
  8. package/dist/shared/modules/dynamic/components/factories.d.ts +2 -1
  9. package/dist/shared/modules/dynamic/components/factories.d.ts.map +1 -1
  10. package/dist/shared/modules/dynamic/components/fields/InputCurrency.d.ts.map +1 -1
  11. package/dist/shared/modules/dynamic/components/fields/RadioButtonGroup.d.ts +121 -0
  12. package/dist/shared/modules/dynamic/components/fields/RadioButtonGroup.d.ts.map +1 -0
  13. package/dist/shared/modules/dynamic/components/fields/storybook/RadioButtonGroup.stories.d.ts +362 -0
  14. package/dist/shared/modules/dynamic/components/fields/storybook/RadioButtonGroup.stories.d.ts.map +1 -0
  15. package/dist/shared/modules/dynamic/composables/useFilterBuilder/index.d.ts.map +1 -1
  16. package/dist/shared/modules/dynamic/factories/types/index.d.ts +1 -1
  17. package/dist/shared/modules/dynamic/factories/types/index.d.ts.map +1 -1
  18. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts.map +1 -1
  19. package/dist/shared/modules/dynamic/types/index.d.ts +67 -3
  20. package/dist/shared/modules/dynamic/types/index.d.ts.map +1 -1
  21. package/dist/shared/modules/dynamic/types/models.d.ts +4 -1
  22. package/dist/shared/modules/dynamic/types/models.d.ts.map +1 -1
  23. package/dist/tsconfig.tsbuildinfo +1 -1
  24. package/dist/ui/components/atoms/index.d.ts +0 -1
  25. package/dist/ui/components/atoms/index.d.ts.map +1 -1
  26. package/dist/ui/components/atoms/vc-card/vc-card.stories.d.ts +40 -28
  27. package/dist/ui/components/atoms/vc-card/vc-card.stories.d.ts.map +1 -1
  28. package/dist/ui/components/atoms/vc-switch/vc-switch.stories.d.ts +8 -8
  29. package/dist/ui/components/atoms/vc-switch/vc-switch.vue.d.ts +1 -1
  30. package/dist/ui/components/atoms/vc-switch/vc-switch.vue.d.ts.map +1 -1
  31. package/dist/ui/components/molecules/index.d.ts +2 -0
  32. package/dist/ui/components/molecules/index.d.ts.map +1 -1
  33. package/dist/ui/components/{atoms → molecules}/vc-checkbox/index.d.ts +16 -16
  34. package/dist/ui/components/{atoms → molecules}/vc-checkbox/index.d.ts.map +1 -1
  35. package/dist/ui/components/{atoms → molecules}/vc-checkbox/vc-checkbox.stories.d.ts +160 -160
  36. package/dist/ui/components/molecules/vc-checkbox/vc-checkbox.stories.d.ts.map +1 -0
  37. package/dist/ui/components/molecules/vc-checkbox/vc-checkbox.vue.d.ts.map +1 -0
  38. package/dist/ui/components/molecules/vc-input/vc-input.stories.d.ts +40 -28
  39. package/dist/ui/components/molecules/vc-input/vc-input.stories.d.ts.map +1 -1
  40. package/dist/ui/components/molecules/vc-input/vc-input.vue.d.ts +10 -0
  41. package/dist/ui/components/molecules/vc-input/vc-input.vue.d.ts.map +1 -1
  42. package/dist/ui/components/molecules/vc-input-currency/vc-input-currency.stories.d.ts +28 -28
  43. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.stories.d.ts +63 -63
  44. package/dist/ui/components/molecules/vc-multivalue/vc-multivalue.vue.d.ts +9 -9
  45. package/dist/ui/components/molecules/vc-radio-button/index.d.ts +2 -0
  46. package/dist/ui/components/molecules/vc-radio-button/index.d.ts.map +1 -0
  47. package/dist/ui/components/molecules/vc-radio-button/vc-radio-button.stories.d.ts +687 -0
  48. package/dist/ui/components/molecules/vc-radio-button/vc-radio-button.stories.d.ts.map +1 -0
  49. package/dist/ui/components/molecules/vc-radio-button/vc-radio-button.vue.d.ts +81 -0
  50. package/dist/ui/components/molecules/vc-radio-button/vc-radio-button.vue.d.ts.map +1 -0
  51. package/dist/ui/components/molecules/vc-select/vc-select.stories.d.ts +90 -90
  52. package/dist/ui/components/molecules/vc-select/vc-select.vue.d.ts +9 -9
  53. package/dist/ui/components/molecules/vc-select/vc-select.vue.d.ts.map +1 -1
  54. package/dist/ui/components/molecules/vc-textarea/vc-textarea.stories.d.ts +168 -168
  55. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue.d.ts +1 -0
  56. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue.d.ts.map +1 -1
  57. package/dist/ui/components/organisms/vc-blade/vc-blade.stories.d.ts +4 -4
  58. package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts +1 -1
  59. package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts.map +1 -1
  60. package/dist/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue.d.ts.map +1 -1
  61. package/dist/ui/components/organisms/vc-gallery/vc-gallery.stories.d.ts +6 -6
  62. package/dist/ui/components/organisms/vc-login-form/index.d.ts +1 -72
  63. package/dist/ui/components/organisms/vc-login-form/index.d.ts.map +1 -1
  64. package/dist/ui/components/organisms/vc-login-form/vc-login-form.vue.d.ts +4 -2
  65. package/dist/ui/components/organisms/vc-login-form/vc-login-form.vue.d.ts.map +1 -1
  66. package/dist/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue.d.ts +3 -0
  67. package/dist/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue.d.ts.map +1 -1
  68. package/dist/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue.d.ts.map +1 -1
  69. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
  70. package/package.json +5 -4
  71. package/shared/modules/dynamic/components/FIELD_MAP.ts +2 -0
  72. package/shared/modules/dynamic/components/factories.ts +10 -0
  73. package/shared/modules/dynamic/components/fields/InputCurrency.ts +4 -1
  74. package/shared/modules/dynamic/components/fields/RadioButtonGroup.ts +82 -0
  75. package/shared/modules/dynamic/components/fields/storybook/Checkbox.stories.ts +1 -1
  76. package/shared/modules/dynamic/components/fields/storybook/RadioButtonGroup.stories.ts +224 -0
  77. package/shared/modules/dynamic/composables/useFilterBuilder/index.ts +202 -33
  78. package/shared/modules/dynamic/factories/types/index.ts +1 -1
  79. package/shared/modules/dynamic/pages/dynamic-blade-form.vue +4 -3
  80. package/shared/modules/dynamic/pages/dynamic-blade-list.vue +1 -1
  81. package/shared/modules/dynamic/types/index.ts +72 -3
  82. package/shared/modules/dynamic/types/models.ts +5 -0
  83. package/ui/components/atoms/index.ts +0 -1
  84. package/ui/components/atoms/vc-label/vc-label.vue +1 -1
  85. package/ui/components/atoms/vc-switch/vc-switch.vue +1 -1
  86. package/ui/components/molecules/index.ts +2 -0
  87. package/ui/components/{atoms → molecules}/vc-checkbox/vc-checkbox.stories.ts +3 -3
  88. package/ui/components/molecules/vc-checkbox/vc-checkbox.vue +204 -0
  89. package/ui/components/molecules/vc-file-upload/vc-file-upload.vue +1 -1
  90. package/ui/components/molecules/vc-input/vc-input.vue +122 -33
  91. package/ui/components/molecules/vc-radio-button/index.ts +1 -0
  92. package/ui/components/molecules/vc-radio-button/vc-radio-button.stories.ts +97 -0
  93. package/ui/components/molecules/vc-radio-button/vc-radio-button.vue +197 -0
  94. package/ui/components/molecules/vc-select/vc-select.vue +1 -1
  95. package/ui/components/organisms/vc-blade/_internal/vc-blade-header/vc-blade-header.vue +42 -0
  96. package/ui/components/organisms/vc-blade/vc-blade.vue +4 -2
  97. package/ui/components/organisms/vc-dynamic-property/vc-dynamic-property.vue +4 -4
  98. package/ui/components/organisms/vc-login-form/index.ts +1 -10
  99. package/ui/components/organisms/vc-login-form/vc-login-form.vue +20 -0
  100. package/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue +8 -0
  101. package/ui/components/organisms/vc-table/_internal/vc-table-filter/vc-table-filter.vue +16 -22
  102. package/ui/components/organisms/vc-table/vc-table.vue +23 -3
  103. package/dist/ui/components/atoms/vc-checkbox/vc-checkbox.stories.d.ts.map +0 -1
  104. package/dist/ui/components/atoms/vc-checkbox/vc-checkbox.vue.d.ts.map +0 -1
  105. package/ui/components/atoms/vc-checkbox/vc-checkbox.vue +0 -146
  106. /package/dist/ui/components/{atoms → molecules}/vc-checkbox/vc-checkbox.vue.d.ts +0 -0
  107. /package/ui/components/{atoms → molecules}/vc-checkbox/index.ts +0 -0
@@ -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="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,
@@ -156,6 +156,7 @@ const { onBeforeClose } = useBladeNavigation();
156
156
  const title = ref();
157
157
  const isReady = ref(false);
158
158
  const activeWidgetExposed = ref<CoreBladeExposed>();
159
+ const isBladeEditable = computed(() => refDefault(toRef(toValue(scope ?? {}), "isBladeEditable"), true).value);
159
160
  const settings = computed(() => props.model?.settings);
160
161
 
161
162
  const { moduleNotifications, markAsRead } = useNotifications(settings.value?.pushNotificationType);
@@ -357,7 +358,7 @@ onBeforeClose(async () => {
357
358
  });
358
359
 
359
360
  provide("bladeContext", toReactive(bladeContext));
360
- provide("isBladeEditable", toRef(toValue(scope ?? {}), "isBladeEditable"));
361
+ provide("isBladeEditable", isBladeEditable);
361
362
 
362
363
  defineExpose({
363
364
  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')"
@@ -770,6 +770,33 @@ export interface CheckboxSchema extends Omit<SchemaBase, "multilanguage" | "plac
770
770
  falseValue?: boolean;
771
771
  }
772
772
 
773
+ export interface RadioButtonSchema extends Omit<SchemaBase, "multilanguage" | "placeholder"> {
774
+ /**
775
+ * Component type for radio button.
776
+ * @type {"vc-radio-button-group"}
777
+ */
778
+ component: "vc-radio-button-group";
779
+ /**
780
+ * Allows to select a boolean value.
781
+ */
782
+ binary?: boolean;
783
+ /**
784
+ * List of options to be displayed as radio-buttons.
785
+ * @description Array of should be defined in the blade `scope`.
786
+ */
787
+ options: string;
788
+ /**
789
+ * Name of property that holds radio button value.
790
+ * @type {string}
791
+ */
792
+ optionValue?: string;
793
+ /**
794
+ * Name of property that holds radio button label.
795
+ * @type {string}
796
+ */
797
+ optionLabel?: string;
798
+ }
799
+
773
800
  /**
774
801
  * Fieldset schema interface.
775
802
  * @interface
@@ -963,13 +990,17 @@ export type ControlSchema =
963
990
  | SwitchSchema
964
991
  | TableSchema
965
992
  | CustomComponentSchema
966
- | RatingSchema;
993
+ | RatingSchema
994
+ | RadioButtonSchema;
967
995
 
968
996
  export interface FilterBase {
969
997
  columns: {
970
- title: string;
998
+ /**
999
+ * @deprecated use 'label' in 'controls' instead
1000
+ */
1001
+ title?: string;
971
1002
  id: string;
972
- controls: (FilterCheckbox | FilterDateInput)[];
1003
+ controls: (FilterCheckbox | FilterDateInput | FilterSwitch | FilterSelect | FilterRadio)[];
973
1004
  }[];
974
1005
  }
975
1006
 
@@ -977,6 +1008,8 @@ export type FilterCheckbox = {
977
1008
  id: string;
978
1009
  field: string;
979
1010
  multiple?: boolean;
1011
+ label?: string;
1012
+ tooltip?: string;
980
1013
  data: string;
981
1014
  optionValue: string;
982
1015
  optionLabel: string;
@@ -987,9 +1020,45 @@ export type FilterDateInput = {
987
1020
  id: string;
988
1021
  field: string;
989
1022
  label?: string;
1023
+ tooltip?: string;
990
1024
  component: InputSchema["component"];
991
1025
  };
992
1026
 
1027
+ export type FilterSwitch = {
1028
+ id: string;
1029
+ field: string;
1030
+ data: string;
1031
+ label?: string;
1032
+ tooltip?: string;
1033
+ multiple?: boolean;
1034
+ optionValue: string;
1035
+ optionLabel: string;
1036
+ component: SwitchSchema["component"];
1037
+ };
1038
+
1039
+ export type FilterSelect = {
1040
+ id: string;
1041
+ field: string;
1042
+ label?: string;
1043
+ tooltip?: string;
1044
+ data: string;
1045
+ multiple?: boolean;
1046
+ component: SelectSchema["component"];
1047
+ optionValue: string;
1048
+ optionLabel: string;
1049
+ };
1050
+
1051
+ export type FilterRadio = {
1052
+ id: string;
1053
+ field: string;
1054
+ label?: string;
1055
+ tooltip?: string;
1056
+ data: string;
1057
+ optionValue: string;
1058
+ optionLabel: string;
1059
+ component: RadioButtonSchema["component"];
1060
+ };
1061
+
993
1062
  export type FilterSchema = FilterBase;
994
1063
 
995
1064
  export interface OverridesSchema {