adminforth 1.3.56-next.2 → 1.3.56-next.20

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 (36) hide show
  1. package/dist/dataConnectors/clickhouse.d.ts.map +1 -1
  2. package/dist/dataConnectors/clickhouse.js.map +1 -1
  3. package/dist/modules/configValidator.d.ts.map +1 -1
  4. package/dist/modules/configValidator.js +12 -0
  5. package/dist/modules/configValidator.js.map +1 -1
  6. package/dist/modules/restApi.d.ts.map +1 -1
  7. package/dist/modules/restApi.js +32 -6
  8. package/dist/modules/restApi.js.map +1 -1
  9. package/dist/modules/styles.js +2 -2
  10. package/dist/modules/styles.js.map +1 -1
  11. package/dist/spa/index.html +2 -2
  12. package/dist/spa/src/App.vue +12 -22
  13. package/dist/spa/src/components/AfTooltip.vue +43 -0
  14. package/dist/spa/src/components/BreadcrumbsWithButtons.vue +3 -4
  15. package/dist/spa/src/components/Dropdown.vue +2 -2
  16. package/dist/spa/src/components/GroupsTable.vue +168 -0
  17. package/dist/spa/src/components/ResourceForm.vue +70 -156
  18. package/dist/spa/src/components/ResourceListTable.vue +121 -124
  19. package/dist/spa/src/components/ValueRenderer.vue +1 -4
  20. package/dist/spa/src/composables/useStores.ts +1 -1
  21. package/dist/spa/src/renderers/CompactField.vue +48 -0
  22. package/dist/spa/src/renderers/CompactUUID.vue +1 -1
  23. package/dist/spa/src/renderers/CountryFlag.vue +16 -21
  24. package/dist/spa/src/renderers/HumanNumber.vue +62 -0
  25. package/dist/spa/src/stores/core.ts +18 -1
  26. package/dist/spa/src/stores/user.ts +0 -1
  27. package/dist/spa/src/types/AdminForthConfig.ts +41 -14
  28. package/dist/spa/src/views/CreateView.vue +1 -1
  29. package/dist/spa/src/views/EditView.vue +1 -1
  30. package/dist/spa/src/views/ListView.vue +1 -6
  31. package/dist/spa/src/views/ResourceParent.vue +36 -2
  32. package/dist/spa/src/views/ShowView.vue +3 -3
  33. package/dist/types/AdminForthConfig.d.ts +34 -11
  34. package/dist/types/AdminForthConfig.d.ts.map +1 -1
  35. package/dist/types/AdminForthConfig.js.map +1 -1
  36. package/package.json +3 -1
@@ -1,14 +1,13 @@
1
1
  <template>
2
2
  <div>
3
- <div class="flex items-center justify-between mb-3 flex-wrap gap-y-2">
3
+ <div class="flex items-center justify-between mb-3 flex-wrap gap-y-2 gap-2">
4
4
  <Breadcrumbs />
5
5
  <div class="flex items-center space-x-1 flex-wrap gap-y-1">
6
6
  <slot></slot>
7
7
  </div>
8
8
  </div>
9
- <div class="flex items-center justify-between mb-3 flex-wrap gap-y-2">
10
- <div class="p-4 mb-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400" role="alert"
11
- v-if="coreStore.resourceColumnsError">
9
+ <div class="flex items-center justify-between mb-3 flex-wrap gap-y-2 gap-2" v-if="coreStore.resourceColumnsError">
10
+ <div class="p-4 mb-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400" role="alert">
12
11
  <span class="font-medium">Error!</span> {{ coreStore.resourceColumnsError }}
13
12
  </div>
14
13
  </div>
@@ -35,11 +35,11 @@
35
35
  <IconCaretUpSolid v-else class="h-5 w-5 text-gray-400" />
36
36
  </div>
37
37
  </div>
38
- <div v-if="showDropdown" class="absolute z-10 mt-1 w-full bg-white shadow-lg dark:shadow-black rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
38
+ <div v-if="showDropdown" class="absolute z-10 mt-1 w-full bg-white shadow-lg dark:shadow-black dark:bg-gray-700 dark:border-gray-600 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
39
39
  <div
40
40
  v-for="item in filteredItems"
41
41
  :key="item.value"
42
- class="px-4 py-2 cursor-pointer hover:bg-gray-100"
42
+ class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600"
43
43
  :class="{ 'bg-lightPrimaryOpacity': selectedItems.includes(item) }"
44
44
  @click="toogleItem(item)"
45
45
  >
@@ -0,0 +1,168 @@
1
+ <template>
2
+ <div class="shadow-resourseFormShadow dark:shadow-darkResourseFormShadow dark:shadow-2xl">
3
+ <div v-if="group.groupName" class="text-md font-semibold px-6 py-3 flex flex-1 items-center dark:border-gray-600 text-gray-700 bg-lightFormHeading dark:bg-gray-700 dark:text-gray-400 rounded-t-lg">
4
+ {{ group.groupName }}
5
+ </div>
6
+ <table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
7
+ <thead class="text-xs text-gray-700 uppercase dark:text-gray-400 bg-lightFormHeading dark:bg-gray-700 block md:table-row-group ">
8
+ <tr>
9
+ <th scope="col" class="px-6 py-3 hidden md:table-cell">
10
+ Field
11
+ </th>
12
+ <th scope="col" class="px-6 py-3 w-5/6 hidden md:table-cell">
13
+ Value
14
+ </th>
15
+ </tr>
16
+ </thead>
17
+ <tbody>
18
+ <tr
19
+ v-for="(column, i) in group.columns"
20
+ :key="column.name"
21
+ v-if="currentValues !== null"
22
+ class="bg-ligftForm dark:bg-gray-800 dark:border-gray-700 block md:table-row"
23
+ :class="{ 'border-b': i !== group.columns.length - 1 }"
24
+ >
25
+ <td class="px-6 py-4 whitespace-nowrap flex items-center block md:table-cell" :class="{'rounded-bl-lg border-b-none': i === group.columns.length - 1}"> <!--align-top-->
26
+ <span class="flex items-center gap-1">
27
+ {{ column.label }}
28
+ <AfTooltip v-if="column.required[mode]">
29
+
30
+ <IconExclamationCircleSolid v-if="column.required[mode]" class="w-4 h-4"
31
+ :class="(columnError(column) && validating) ? 'text-red-500 dark:text-red-400' : 'text-gray-400 dark:text-gray-500'"
32
+ />
33
+
34
+ <template #tooltip>
35
+ Required field
36
+ </template>
37
+ </AfTooltip>
38
+ </span>
39
+
40
+
41
+ </td>
42
+ <td class="px-6 py-4 whitespace-nowrap whitespace-pre-wrap relative block md:table-cell rounded-br-lg" :class="{'rounded-br-lg': i === group.columns.length - 1}">
43
+ <template v-if="column?.components?.[props.source]?.file">
44
+ <component
45
+ :is="getCustomComponent(column.components[props.source])"
46
+ :column="column"
47
+ :value="currentValues[column.name]"
48
+ @update:value="setCurrentValue(column.name, $event)"
49
+ :meta="column.components[props.source].meta"
50
+ :record="currentValues"
51
+ @update:inValidity="customComponentsInValidity[column.name] = $event"
52
+ @update:emptiness="customComponentsEmptiness[column.name] = $event"
53
+ />
54
+ </template>
55
+ <template v-else>
56
+ <Dropdown
57
+ single
58
+ v-if="column.foreignResource"
59
+ :options="columnOptions[column.name] || []"
60
+ :placeholder = "columnOptions[column.name]?.length ?'Select...': 'There are no options available'"
61
+ :modelValue="currentValues[column.name]"
62
+ @update:modelValue="setCurrentValue(column.name, $event)"
63
+ ></Dropdown>
64
+ <Dropdown
65
+ single
66
+ v-else-if="column.enum"
67
+ :options="column.enum"
68
+ :modelValue="currentValues[column.name]"
69
+ @update:modelValue="setCurrentValue(column.name, $event)"
70
+ />
71
+ <Dropdown
72
+ single
73
+ v-else-if="column.type === 'boolean'"
74
+ :options="[{ label: 'Yes', value: true }, { label: 'No', value: false }, { label: 'Unset', value: null }]"
75
+ :modelValue="currentValues[column.name]"
76
+ @update:modelValue="setCurrentValue(column.name, $event)"
77
+ />
78
+ <input
79
+ v-else-if="['integer'].includes(column.type)"
80
+ type="number"
81
+ step="1"
82
+ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-40 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
83
+ placeholder="0"
84
+ :value="currentValues[column.name]"
85
+ @input="setCurrentValue(column.name, $event.target.value)"
86
+ >
87
+ <CustomDatePicker
88
+ v-else-if="['datetime'].includes(column.type)"
89
+ :column="column"
90
+ :valueStart="currentValues[column.name]"
91
+ auto-hide
92
+ @update:valueStart="setCurrentValue(column.name, $event)"
93
+ />
94
+ <input
95
+ v-else-if="['decimal', 'float'].includes(column.type)"
96
+ type="number"
97
+ step="0.1"
98
+ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-40 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
99
+ placeholder="0.0"
100
+ :value="currentValues[column.name]"
101
+ @input="setCurrentValue(column.name, $event.target.value)"
102
+ />
103
+ <textarea
104
+ v-else-if="['text', 'richtext'].includes(column.type)"
105
+ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
106
+ placeholder="Text"
107
+ :value="currentValues[column.name]"
108
+ @input="setCurrentValue(column.name, $event.target.value)"
109
+ >
110
+ </textarea>
111
+ <textarea
112
+ v-else-if="['json'].includes(column.type)"
113
+ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
114
+ placeholder="Text"
115
+ :value="currentValues[column.name]"
116
+ @input="setCurrentValue(column.name, $event.target.value)"
117
+ >
118
+ </textarea>
119
+ <input
120
+ v-else
121
+ :type="!column.masked || unmasked[column.name] ? 'text' : 'password'"
122
+ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
123
+ placeholder="Text"
124
+ :value="currentValues[column.name]"
125
+ @input="setCurrentValue(column.name, $event.target.value)"
126
+ autocomplete="false"
127
+ data-lpignore="true"
128
+ readonly
129
+ onfocus="this.removeAttribute('readonly');"
130
+ >
131
+
132
+ <button
133
+ v-if="column.masked"
134
+ type="button"
135
+ @click="unmasked[column.name] = !unmasked[column.name]"
136
+ class="h-6 absolute inset-y-2 top-6 right-6 flex items-center pr-2 z-index-100 focus:outline-none"
137
+ >
138
+ <IconEyeSolid class="w-6 h-6 text-gray-400" v-if="!unmasked[column.name]" />
139
+ <IconEyeSlashSolid class="w-6 h-6 text-gray-400" v-else />
140
+ </button>
141
+ </template>
142
+ <div v-if="columnError(column) && validating" class="mt-1 text-xs text-red-500 dark:text-red-400">{{ columnError(column) }}</div>
143
+ <div v-if="column.editingNote && column.editingNote[mode]" class="mt-1 text-xs text-gray-400 dark:text-gray-500">{{ column.editingNote[mode] }}</div>
144
+ </td>
145
+ </tr>
146
+ </tbody>
147
+ </table>
148
+ </div>
149
+ </template>
150
+
151
+ <script setup>
152
+ import { defineProps } from 'vue';
153
+ import { IconExclamationCircleSolid, IconEyeSlashSolid, IconEyeSolid } from '@iconify-prerendered/vue-flowbite';
154
+ import CustomDatePicker from "@/components/CustomDatePicker.vue";
155
+ import Dropdown from '@/components/Dropdown.vue';
156
+ import AfTooltip from "./AfTooltip.vue";
157
+
158
+ const props = defineProps({
159
+ group: Object,
160
+ mode: String,
161
+ validating: Boolean,
162
+ currentValues: Object,
163
+ unmasked: Object,
164
+ columnError: Function,
165
+ setCurrentValue: Function,
166
+ columnOptions: Object
167
+ });
168
+ </script>
@@ -1,164 +1,62 @@
1
1
  <template>
2
2
  <div class="rounded-default">
3
- <div
4
- class="relative shadow-resourseFormShadow dark:shadow-darkResourseFormShadow sm:rounded-lg dark:shadow-2xl rounded-default"
5
- >
6
- <form autocomplete="off" @submit.prevent>
7
- <table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 ">
8
- <thead class="text-xs text-gray-700 uppercase bg-lightFormHeading dark:bg-gray-700 dark:text-gray-400 block md:table-row-group">
9
- <tr>
10
- <th scope="col" class="px-6 py-3 hidden md:table-cell">
11
- Field
12
- </th>
13
- <th scope="col" class="px-6 py-3 w-5/6 hidden md:table-cell">
14
- Value
15
- </th>
16
- </tr>
17
- </thead>
18
- <tbody>
19
- <tr v-for="column, i in editableColumns" :key="column.name"
20
- v-if="currentValues !== null"
21
- class="bg-ligftForm dark:bg-gray-800 dark:border-gray-700 block md:table-row"
22
- :class="{ 'border-b': i !== editableColumns.length - 1 }"
23
- >
24
- <td class="px-6 py-4 sm:pb-0 whitespace-nowrap flex items-center block md:table-cell"> <!--align-top-->
25
- {{ column.label }}
26
- <span :data-tooltip-target="`tooltip-show-${i}`" class="ml-1 relative inline-block">
27
- <IconExclamationCircleSolid v-if="column.required[mode]" class="w-4 h-4"
28
- :class="(columnError(column) && validating) ? 'text-red-500 dark:text-red-400' : 'text-gray-400 dark:text-gray-500'"
29
- />
30
- </span>
31
- <div :id="`tooltip-show-${i}`"
32
- role="tooltip"
33
- class="ml-1 absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
34
- Required field
35
- <div class="tooltip-arrow" data-popper-arrow></div>
36
- </div>
37
- </td>
38
- <td class="px-6 py-4 whitespace-nowrap whitespace-pre-wrap relative block md:table-cell">
39
- <template v-if="column?.components?.[props.source]?.file">
40
- <component
41
- :is="getCustomComponent(column.components[props.source])"
42
- :column="column"
43
- :value="currentValues[column.name]"
44
- @update:value="setCurrentValue(column.name, $event)"
45
- :meta="column.components[props.source].meta"
46
- :record="currentValues"
47
- @update:inValidity="customComponentsInValidity[column.name] = $event"
48
- @update:emptiness="customComponentsEmptiness[column.name] = $event"
49
- />
50
- </template>
51
- <template v-else>
52
- <Dropdown
53
- single
54
- v-if="column.foreignResource"
55
- :options="columnOptions[column.name] || []"
56
- :placeholder = "columnOptions[column.name]?.length ?'Select...': 'There are no options available'"
57
- :modelValue="currentValues[column.name]"
58
- @update:modelValue="setCurrentValue(column.name, $event)"
59
- ></Dropdown>
60
- <Dropdown
61
- single
62
- v-else-if="column.enum"
63
- :options="column.enum"
64
- :modelValue="currentValues[column.name]"
65
- @update:modelValue="setCurrentValue(column.name, $event)"
66
- />
67
- <Dropdown
68
- single
69
- v-else-if="column.type === 'boolean'"
70
- :options="[{ label: 'Yes', value: true }, { label: 'No', value: false }, { label: 'Unset', value: null }]"
71
- :modelValue="currentValues[column.name]"
72
- @update:modelValue="setCurrentValue(column.name, $event)"
73
- />
74
- <input
75
- v-else-if="['integer'].includes(column.type)"
76
- type="number"
77
- step="1"
78
- class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-40 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
79
- placeholder="0"
80
- :value="currentValues[column.name]"
81
- @input="setCurrentValue(column.name, $event.target.value)"
82
- >
83
- <CustomDatePicker
84
- v-else-if="['datetime'].includes(column.type)"
85
- :column="column"
86
- :valueStart="currentValues[column.name]"
87
- auto-hide
88
- @update:valueStart="setCurrentValue(column.name, $event)"
89
- />
90
- <input
91
- v-else-if="['decimal', 'float'].includes(column.type)"
92
- type="number"
93
- step="0.1"
94
- class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-40 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
95
- placeholder="0.0"
96
- :value="currentValues[column.name]"
97
- @input="setCurrentValue(column.name, $event.target.value)"
98
- />
99
- <textarea
100
- v-else-if="['text', 'richtext'].includes(column.type)"
101
- class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
102
- placeholder="Text"
103
- :value="currentValues[column.name]"
104
- @input="setCurrentValue(column.name, $event.target.value)"
105
- >
106
- </textarea>
107
- <textarea
108
- v-else-if="['json'].includes(column.type)"
109
- class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
110
- placeholder="Text"
111
- :value="currentValues[column.name]"
112
- @input="setCurrentValue(column.name, $event.target.value)"
113
- >
114
- </textarea>
115
- <input
116
- v-else
117
- :type="!column.masked || unmasked[column.name] ? 'text' : 'password'"
118
- class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
119
- placeholder="Text"
120
- :value="currentValues[column.name]"
121
- @input="setCurrentValue(column.name, $event.target.value)"
122
- autocomplete="false"
123
- data-lpignore="true"
124
- readonly
125
- onfocus="this.removeAttribute('readonly');"
126
- >
127
-
128
- <button
129
- v-if="column.masked"
130
- type="button"
131
- @click="unmasked[column.name] = !unmasked[column.name]"
132
- class="h-6 absolute inset-y-2 top-6 right-6 flex items-center pr-2 z-index-100 focus:outline-none"
133
- >
134
- <IconEyeSolid class="w-6 h-6 text-gray-400" v-if="!unmasked[column.name]" />
135
- <IconEyeSlashSolid class="w-6 h-6 text-gray-400" v-else />
136
- </button>
137
- </template>
138
- <div v-if="columnError(column) && validating" class="mt-1 text-xs text-red-500 dark:text-red-400">{{ columnError(column) }}</div>
139
- <div v-if="column.editingNote && column.editingNote[mode]" class="mt-1 text-xs text-gray-400 dark:text-gray-500">{{ column.editingNote[mode] }}</div>
140
-
141
- </td>
142
- </tr>
143
-
144
- </tbody>
145
- </table>
146
- </form>
147
- </div>
3
+ <form autocomplete="off" @submit.prevent>
4
+ <div v-if="!coreStore.resource.options.createEditGroups || coreStore.resource.options.createEditGroups.length === 0">
5
+ <GroupsTable
6
+ :group="{groupName: '', columns: editableColumns}"
7
+ :currentValues="currentValues"
8
+ :editableColumns="editableColumns"
9
+ :mode="mode"
10
+ :unmasked="unmasked"
11
+ :columnOptions="columnOptions"
12
+ :validating="validating"
13
+ :columnError="columnError"
14
+ :setCurrentValue="setCurrentValue"
15
+ />
16
+ </div>
17
+ <div v-else class="flex flex-col gap-4">
18
+ <template v-for="group in groupedColumns" :key="group.groupName" class="flex flex-col gap-4">
19
+ <GroupsTable
20
+ :group="group"
21
+ :currentValues="currentValues"
22
+ :editableColumns="editableColumns"
23
+ :mode="mode"
24
+ :unmasked="unmasked"
25
+ :columnOptions="columnOptions"
26
+ :validating="validating"
27
+ :columnError="columnError"
28
+ :setCurrentValue="setCurrentValue"
29
+ />
30
+ </template>
31
+ <div v-if="otherColumns.length > 0">
32
+ <GroupsTable
33
+ :group="{groupName: 'Other', columns: otherColumns}"
34
+ :currentValues="currentValues"
35
+ :editableColumns="editableColumns"
36
+ :mode="mode"
37
+ :unmasked="unmasked"
38
+ :columnOptions="columnOptions"
39
+ :validating="validating"
40
+ :columnError="columnError"
41
+ :setCurrentValue="setCurrentValue"
42
+ />
43
+ </div>
44
+ </div>
45
+ </form>
148
46
  </div>
149
47
 
150
48
  </template>
151
49
 
152
50
  <script setup>
153
51
 
154
- import CustomDatePicker from "@/components/CustomDatePicker.vue";
155
- import Dropdown from '@/components/Dropdown.vue';
156
- import { applyRegexValidation, callAdminForthApi, getCustomComponent } from '@/utils';
157
- import { IconExclamationCircleSolid, IconEyeSlashSolid, IconEyeSolid } from '@iconify-prerendered/vue-flowbite';
52
+ import { applyRegexValidation, callAdminForthApi} from '@/utils';
158
53
  import { computedAsync } from '@vueuse/core';
159
- import { initFlowbite } from 'flowbite';
160
54
  import { computed, onMounted, ref, watch } from 'vue';
161
55
  import { useRouter, useRoute } from 'vue-router';
56
+ import { useCoreStore } from "@/stores/core";
57
+ import GroupsTable from '@/components/GroupsTable.vue';
58
+
59
+ const coreStore = useCoreStore();
162
60
 
163
61
  const router = useRouter();
164
62
  const route = useRoute();
@@ -179,7 +77,6 @@ const currentValues = ref(null);
179
77
 
180
78
  const customComponentsInValidity = ref({});
181
79
  const customComponentsEmptiness = ref({});
182
-
183
80
 
184
81
  const columnError = (column) => {
185
82
  const val = computed(() => {
@@ -281,9 +178,6 @@ onMounted(() => {
281
178
  currentValues.value[column.name] = JSON.stringify(currentValues.value[column.name], null, 2);
282
179
  }
283
180
  });
284
- console.log('currentValues', currentValues.value);
285
-
286
- initFlowbite();
287
181
  emit('update:isValid', isValid.value);
288
182
  });
289
183
 
@@ -310,14 +204,34 @@ const columnOptions = computedAsync(async () => {
310
204
 
311
205
 
312
206
  const editableColumns = computed(() => {
313
- const mode = props.record ? 'edit' : 'create';
314
- return props.resource?.columns?.filter(column => column.showIn.includes(mode));
207
+ return props.resource?.columns?.filter(column => column.showIn.includes(mode.value));
315
208
  });
316
209
 
317
210
  const isValid = computed(() => {
318
211
  return editableColumns.value?.every(column => !columnError(column));
319
212
  });
320
213
 
214
+
215
+ const groups = coreStore.resource.options.createEditGroups;
216
+
217
+ const groupedColumns = computed(() => {
218
+ if (!groups || groups.length === 0) return [];
219
+
220
+ return groups.map(group => ({
221
+ ...group,
222
+ columns: props.resource.columns.filter(col => group.columns.includes(col.name) && editableColumns.value.includes(col))
223
+ }));
224
+ });
225
+
226
+ const getOtherColumns = () => {
227
+ if (!groups || groups.length === 0) return;
228
+
229
+ const groupedColumnNames = new Set(groupedColumns.value.flatMap(group => group.columns.map(col => col.name)));
230
+ return editableColumns.value.filter(col => !groupedColumnNames.has(col.name));
231
+ };
232
+
233
+ const otherColumns = getOtherColumns();
234
+
321
235
  watch(() => isValid.value, (value) => {
322
236
  emit('update:isValid', value);
323
237
  });