adminforth 1.3.54-next.9 → 1.3.55-next.2

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 (224) hide show
  1. package/dist/auth.d.ts +31 -0
  2. package/dist/auth.d.ts.map +1 -0
  3. package/dist/auth.js +42 -56
  4. package/dist/auth.js.map +1 -0
  5. package/dist/basePlugin.d.ts +18 -0
  6. package/dist/basePlugin.d.ts.map +1 -0
  7. package/dist/basePlugin.js +1 -0
  8. package/dist/basePlugin.js.map +1 -0
  9. package/dist/dataConnectors/baseConnector.d.ts +94 -0
  10. package/dist/dataConnectors/baseConnector.d.ts.map +1 -0
  11. package/dist/dataConnectors/baseConnector.js +108 -122
  12. package/dist/dataConnectors/baseConnector.js.map +1 -0
  13. package/dist/dataConnectors/clickhouse.d.ts +92 -0
  14. package/dist/dataConnectors/clickhouse.d.ts.map +1 -0
  15. package/dist/dataConnectors/clickhouse.js +132 -149
  16. package/dist/dataConnectors/clickhouse.js.map +1 -0
  17. package/dist/dataConnectors/mongo.d.ts +93 -0
  18. package/dist/dataConnectors/mongo.d.ts.map +1 -0
  19. package/dist/dataConnectors/mongo.js +75 -101
  20. package/dist/dataConnectors/mongo.js.map +1 -0
  21. package/dist/dataConnectors/postgres.d.ts +71 -0
  22. package/dist/dataConnectors/postgres.d.ts.map +1 -0
  23. package/dist/dataConnectors/postgres.js +124 -143
  24. package/dist/dataConnectors/postgres.js.map +1 -0
  25. package/dist/dataConnectors/sqlite.d.ts +67 -0
  26. package/dist/dataConnectors/sqlite.d.ts.map +1 -0
  27. package/dist/dataConnectors/sqlite.js +113 -130
  28. package/dist/dataConnectors/sqlite.js.map +1 -0
  29. package/dist/index.d.ts +92 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +197 -217
  32. package/dist/index.js.map +1 -0
  33. package/dist/modules/codeInjector.d.ts +35 -0
  34. package/dist/modules/codeInjector.d.ts.map +1 -0
  35. package/dist/modules/codeInjector.js +480 -486
  36. package/dist/modules/codeInjector.js.map +1 -0
  37. package/dist/modules/configValidator.d.ts +12 -0
  38. package/dist/modules/configValidator.d.ts.map +1 -0
  39. package/dist/modules/configValidator.js +31 -22
  40. package/dist/modules/configValidator.js.map +1 -0
  41. package/dist/modules/operationalResource.d.ts +17 -0
  42. package/dist/modules/operationalResource.d.ts.map +1 -0
  43. package/dist/modules/operationalResource.js +50 -70
  44. package/dist/modules/operationalResource.js.map +1 -0
  45. package/dist/modules/restApi.d.ts +10 -0
  46. package/dist/modules/restApi.d.ts.map +1 -0
  47. package/dist/modules/restApi.js +104 -116
  48. package/dist/modules/restApi.js.map +1 -0
  49. package/dist/modules/styleGenerator.d.ts +9 -0
  50. package/dist/modules/styleGenerator.d.ts.map +1 -0
  51. package/dist/modules/styleGenerator.js +1 -0
  52. package/dist/modules/styleGenerator.js.map +1 -0
  53. package/dist/modules/styles.d.ts +96 -0
  54. package/dist/modules/styles.d.ts.map +1 -0
  55. package/dist/modules/styles.js +1 -0
  56. package/dist/modules/styles.js.map +1 -0
  57. package/dist/modules/utils.d.ts +39 -0
  58. package/dist/modules/utils.d.ts.map +1 -0
  59. package/dist/modules/utils.js +1 -0
  60. package/dist/modules/utils.js.map +1 -0
  61. package/dist/plugins/audit-log/types.d.ts +35 -0
  62. package/dist/plugins/audit-log/types.d.ts.map +1 -0
  63. package/dist/plugins/audit-log/types.js +2 -0
  64. package/dist/plugins/audit-log/types.js.map +1 -0
  65. package/dist/plugins/chat-gpt/types.d.ts +82 -0
  66. package/dist/plugins/chat-gpt/types.d.ts.map +1 -0
  67. package/dist/plugins/chat-gpt/types.js +2 -0
  68. package/dist/plugins/chat-gpt/types.js.map +1 -0
  69. package/dist/plugins/email-password-reset/types.d.ts +28 -0
  70. package/dist/plugins/email-password-reset/types.d.ts.map +1 -0
  71. package/dist/plugins/email-password-reset/types.js +2 -0
  72. package/dist/plugins/email-password-reset/types.js.map +1 -0
  73. package/dist/plugins/foreign-inline-list/types.d.ts +19 -0
  74. package/dist/plugins/foreign-inline-list/types.d.ts.map +1 -0
  75. package/dist/plugins/foreign-inline-list/types.js +2 -0
  76. package/dist/plugins/foreign-inline-list/types.js.map +1 -0
  77. package/dist/plugins/import-export/types.d.ts +3 -0
  78. package/dist/plugins/import-export/types.d.ts.map +1 -0
  79. package/dist/plugins/import-export/types.js +2 -0
  80. package/dist/plugins/import-export/types.js.map +1 -0
  81. package/dist/plugins/rich-editor/custom/async-queue.d.ts +8 -0
  82. package/dist/plugins/rich-editor/custom/async-queue.d.ts.map +1 -0
  83. package/dist/plugins/rich-editor/custom/async-queue.js +29 -0
  84. package/dist/plugins/rich-editor/custom/async-queue.js.map +1 -0
  85. package/dist/plugins/rich-editor/dist/custom/async-queue.d.ts +8 -0
  86. package/dist/plugins/rich-editor/dist/custom/async-queue.d.ts.map +1 -0
  87. package/dist/plugins/rich-editor/dist/custom/async-queue.js +29 -0
  88. package/dist/plugins/rich-editor/dist/custom/async-queue.js.map +1 -0
  89. package/dist/plugins/rich-editor/types.d.ts +153 -0
  90. package/dist/plugins/rich-editor/types.d.ts.map +1 -0
  91. package/dist/plugins/rich-editor/types.js +16 -0
  92. package/dist/plugins/rich-editor/types.js.map +1 -0
  93. package/dist/plugins/two-factors-auth/types.d.ts +18 -0
  94. package/dist/plugins/two-factors-auth/types.d.ts.map +1 -0
  95. package/dist/plugins/two-factors-auth/types.js +2 -0
  96. package/dist/plugins/two-factors-auth/types.js.map +1 -0
  97. package/dist/plugins/upload/types.d.ts +132 -0
  98. package/dist/plugins/upload/types.d.ts.map +1 -0
  99. package/dist/plugins/upload/types.js +2 -0
  100. package/dist/plugins/upload/types.js.map +1 -0
  101. package/dist/servers/express.d.ts +18 -0
  102. package/dist/servers/express.d.ts.map +1 -0
  103. package/dist/servers/express.js +30 -42
  104. package/dist/servers/express.js.map +1 -0
  105. package/dist/spa/index.html +2 -2
  106. package/dist/spa/package-lock.json +87 -1
  107. package/dist/spa/package.json +4 -1
  108. package/dist/spa/src/App.vue +154 -50
  109. package/dist/spa/src/components/AcceptModal.vue +1 -1
  110. package/dist/spa/src/components/Breadcrumbs.vue +1 -1
  111. package/dist/spa/src/components/CustomDatePicker.vue +1 -1
  112. package/dist/spa/src/components/CustomDateRangePicker.vue +1 -1
  113. package/dist/spa/src/components/CustomRangePicker.vue +9 -5
  114. package/dist/spa/src/components/Dropdown.vue +4 -4
  115. package/dist/spa/src/components/Filters.vue +2 -2
  116. package/dist/spa/src/components/MenuLink.vue +3 -0
  117. package/dist/spa/src/components/ResourceForm.vue +67 -36
  118. package/dist/spa/src/components/ResourceListTable.vue +216 -144
  119. package/dist/spa/src/components/SkeleteLoader.vue +4 -4
  120. package/dist/spa/src/components/Toast.vue +3 -2
  121. package/dist/spa/src/components/ValueRenderer.vue +81 -6
  122. package/dist/spa/src/composables/useFrontendApi.ts +1 -1
  123. package/dist/spa/src/composables/useStores.ts +18 -14
  124. package/dist/spa/src/index.scss +4 -0
  125. package/{spa → dist/spa}/src/renderers/CompactUUID.vue +4 -4
  126. package/{spa → dist/spa}/src/renderers/CountryFlag.vue +2 -2
  127. package/dist/spa/src/router/index.ts +4 -8
  128. package/dist/spa/src/spa_types/core.ts +2 -0
  129. package/dist/spa/src/stores/core.ts +6 -2
  130. package/dist/spa/src/stores/filters.ts +15 -10
  131. package/dist/spa/src/stores/toast.ts +22 -6
  132. package/dist/spa/src/types/AdminForthConfig.ts +340 -55
  133. package/dist/spa/src/types/FrontendAPI.ts +52 -30
  134. package/dist/spa/src/utils.ts +59 -2
  135. package/dist/spa/src/views/CreateView.vue +15 -4
  136. package/dist/spa/src/views/EditView.vue +20 -7
  137. package/dist/spa/src/views/ListView.vue +132 -38
  138. package/dist/spa/src/views/LoginView.vue +50 -18
  139. package/dist/spa/src/views/ShowView.vue +25 -15
  140. package/dist/types/AdminForthConfig.d.ts +1619 -0
  141. package/dist/types/AdminForthConfig.d.ts.map +1 -0
  142. package/dist/types/AdminForthConfig.js +1 -0
  143. package/dist/types/AdminForthConfig.js.map +1 -0
  144. package/{types/FrontendAPI.ts → dist/types/FrontendAPI.d.ts} +27 -52
  145. package/dist/types/FrontendAPI.d.ts.map +1 -0
  146. package/dist/types/FrontendAPI.js +1 -0
  147. package/dist/types/FrontendAPI.js.map +1 -0
  148. package/package.json +16 -6
  149. package/auth.ts +0 -140
  150. package/basePlugin.ts +0 -70
  151. package/dataConnectors/baseConnector.ts +0 -216
  152. package/dataConnectors/clickhouse.ts +0 -338
  153. package/dataConnectors/mongo.ts +0 -202
  154. package/dataConnectors/postgres.ts +0 -306
  155. package/dataConnectors/sqlite.ts +0 -254
  156. package/index.ts +0 -428
  157. package/modules/codeInjector.ts +0 -736
  158. package/modules/configValidator.ts +0 -571
  159. package/modules/operationalResource.ts +0 -98
  160. package/modules/restApi.ts +0 -718
  161. package/modules/styleGenerator.ts +0 -55
  162. package/modules/styles.ts +0 -126
  163. package/modules/utils.ts +0 -472
  164. package/servers/express.ts +0 -259
  165. package/spa/.eslintrc.cjs +0 -14
  166. package/spa/README.md +0 -39
  167. package/spa/env.d.ts +0 -1
  168. package/spa/index.html +0 -23
  169. package/spa/package-lock.json +0 -4602
  170. package/spa/package.json +0 -51
  171. package/spa/postcss.config.js +0 -6
  172. package/spa/public/assets/favicon.png +0 -0
  173. package/spa/src/App.vue +0 -418
  174. package/spa/src/assets/base.css +0 -2
  175. package/spa/src/assets/logo.svg +0 -19
  176. package/spa/src/components/AcceptModal.vue +0 -45
  177. package/spa/src/components/Breadcrumbs.vue +0 -41
  178. package/spa/src/components/BreadcrumbsWithButtons.vue +0 -26
  179. package/spa/src/components/CustomDatePicker.vue +0 -176
  180. package/spa/src/components/CustomDateRangePicker.vue +0 -218
  181. package/spa/src/components/CustomRangePicker.vue +0 -156
  182. package/spa/src/components/Dropdown.vue +0 -168
  183. package/spa/src/components/Filters.vue +0 -222
  184. package/spa/src/components/HelloWorld.vue +0 -17
  185. package/spa/src/components/MenuLink.vue +0 -27
  186. package/spa/src/components/ResourceForm.vue +0 -290
  187. package/spa/src/components/ResourceListTable.vue +0 -466
  188. package/spa/src/components/SingleSkeletLoader.vue +0 -13
  189. package/spa/src/components/SkeleteLoader.vue +0 -23
  190. package/spa/src/components/Toast.vue +0 -78
  191. package/spa/src/components/ValueRenderer.vue +0 -114
  192. package/spa/src/components/icons/IconCalendar.vue +0 -5
  193. package/spa/src/components/icons/IconCommunity.vue +0 -7
  194. package/spa/src/components/icons/IconDocumentation.vue +0 -7
  195. package/spa/src/components/icons/IconEcosystem.vue +0 -7
  196. package/spa/src/components/icons/IconSupport.vue +0 -7
  197. package/spa/src/components/icons/IconTime.vue +0 -5
  198. package/spa/src/components/icons/IconTooling.vue +0 -19
  199. package/spa/src/composables/useFrontendApi.ts +0 -26
  200. package/spa/src/composables/useStores.ts +0 -131
  201. package/spa/src/index.scss +0 -31
  202. package/spa/src/main.ts +0 -18
  203. package/spa/src/router/index.ts +0 -59
  204. package/spa/src/spa_types/core.ts +0 -53
  205. package/spa/src/stores/core.ts +0 -148
  206. package/spa/src/stores/filters.ts +0 -27
  207. package/spa/src/stores/modal.ts +0 -48
  208. package/spa/src/stores/toast.ts +0 -31
  209. package/spa/src/stores/user.ts +0 -72
  210. package/spa/src/utils.ts +0 -160
  211. package/spa/src/views/CreateView.vue +0 -167
  212. package/spa/src/views/EditView.vue +0 -170
  213. package/spa/src/views/ListView.vue +0 -352
  214. package/spa/src/views/LoginView.vue +0 -192
  215. package/spa/src/views/ResourceParent.vue +0 -17
  216. package/spa/src/views/ShowView.vue +0 -186
  217. package/spa/tailwind.config.js +0 -17
  218. package/spa/tsconfig.app.json +0 -14
  219. package/spa/tsconfig.json +0 -11
  220. package/spa/tsconfig.node.json +0 -19
  221. package/spa/vite.config.ts +0 -56
  222. package/tsconfig.json +0 -112
  223. package/types/AdminForthConfig.ts +0 -1762
  224. /package/{spa → dist/spa}/src/components/ThreeDotsMenu.vue +0 -0
@@ -1,290 +0,0 @@
1
- <template>
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
- <input
108
- v-else
109
- :type="!column.masked || unmasked[column.name] ? 'text' : 'password'"
110
- 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"
111
- placeholder="Text"
112
- :value="currentValues[column.name]"
113
- @input="setCurrentValue(column.name, $event.target.value)"
114
- autocomplete="false"
115
- data-lpignore="true"
116
- readonly
117
- onfocus="this.removeAttribute('readonly');"
118
- >
119
-
120
- <button
121
- v-if="column.masked"
122
- type="button"
123
- @click="unmasked[column.name] = !unmasked[column.name]"
124
- class="h-6 absolute inset-y-2 top-6 right-6 flex items-center pr-2 z-index-100 focus:outline-none"
125
- >
126
- <IconEyeSolid class="w-6 h-6 text-gray-400" v-if="!unmasked[column.name]" />
127
- <IconEyeSlashSolid class="w-6 h-6 text-gray-400" v-else />
128
- </button>
129
- </template>
130
- <div v-if="columnError(column) && validating" class="mt-1 text-xs text-red-500 dark:text-red-400">{{ columnError(column) }}</div>
131
- <div v-if="column.editingNote && column.editingNote[mode]" class="mt-1 text-xs text-gray-400 dark:text-gray-500">{{ column.editingNote[mode] }}</div>
132
-
133
- </td>
134
- </tr>
135
-
136
- </tbody>
137
- </table>
138
- </form>
139
- </div>
140
- </div>
141
-
142
- </template>
143
-
144
- <script setup>
145
-
146
- import CustomDatePicker from "@/components/CustomDatePicker.vue";
147
- import Dropdown from '@/components/Dropdown.vue';
148
- import { applyRegexValidation, callAdminForthApi, getCustomComponent } from '@/utils';
149
- import { IconExclamationCircleSolid, IconEyeSlashSolid, IconEyeSolid } from '@iconify-prerendered/vue-flowbite';
150
- import { computedAsync } from '@vueuse/core';
151
- import { initFlowbite } from 'flowbite';
152
- import { computed, onMounted, ref, watch } from 'vue';
153
- import { useRouter, useRoute } from 'vue-router';
154
-
155
- const router = useRouter();
156
- const route = useRoute();
157
- const props = defineProps({
158
- loading: Boolean,
159
- resource: Object,
160
- record: Object,
161
- validating: Boolean,
162
- source: String,
163
- });
164
-
165
- const unmasked = ref({});
166
-
167
- const mode = computed(() => route.name === 'resource-create' ? 'create' : 'edit');
168
-
169
- const emit = defineEmits(['update:record', 'update:isValid']);
170
-
171
- const currentValues = ref(null);
172
-
173
- const customComponentsInValidity = ref({});
174
- const customComponentsEmptiness = ref({});
175
-
176
-
177
- const columnError = (column) => {
178
- const val = computed(() => {
179
- if (!currentValues.value) {
180
- return null;
181
- }
182
- if (customComponentsInValidity.value[column.name]) {
183
- return customComponentsInValidity.value[column.name];
184
- }
185
-
186
- if (
187
- column.required[mode.value] &&
188
- (currentValues.value[column.name] === undefined || currentValues.value[column.name] === null || currentValues.value[column.name] === '') &&
189
- // if component is custum it might tell other criteria for emptiness by emitting 'update:emptiness'
190
- // components which do not emit 'update:emptiness' will have undefined value in customComponentsEmptiness
191
- (customComponentsEmptiness.value[column.name] !== false)
192
-
193
- ) {
194
- return 'This field is required';
195
- }
196
- if ( column.type === 'string' || column.type === 'text' ) {
197
- if ( column.maxLength && currentValues.value[column.name]?.length > column.maxLength ) {
198
- return `This field must be shorter than ${column.maxLength} characters`;
199
- }
200
-
201
- if ( column.minLength && currentValues.value[column.name]?.length < column.minLength ) {
202
- // if column.required[mode.value] is false, then we check if the field is empty
203
- let needToCheckEmpty = column.required[mode.value] || currentValues.value[column.name]?.length > 0;
204
- if (!needToCheckEmpty) {
205
- return null;
206
- }
207
- return `This field must be longer than ${column.minLength} characters`;
208
- }
209
- }
210
- if ( ['integer', 'decimal', 'float'].includes(column.type) ) {
211
- if ( column.minValue !== undefined
212
- && currentValues.value[column.name] !== null
213
- && currentValues.value[column.name] < column.minValue
214
- ) {
215
- return `This field must be greater than ${column.minValue}`;
216
- }
217
- if ( column.maxValue !== undefined && currentValues.value[column.name] > column.maxValue ) {
218
- return `This field must be less than ${column.maxValue}`;
219
- }
220
- }
221
- if (currentValues.value[column.name] && column.validation) {
222
- const error = applyRegexValidation(currentValues.value[column.name], column.validation);
223
- if (error) {
224
- return error;
225
- }
226
- }
227
-
228
- return null;
229
- });
230
- return val.value;
231
- };
232
-
233
-
234
- const setCurrentValue = (key, value) => {
235
- const col = props.resource.columns.find((column) => column.name === key);
236
- if (['integer', 'float'].includes(col.type) && (value || value === 0)) {
237
- currentValues.value[key] = +value;
238
- } else {
239
- currentValues.value[key] = value;
240
- }
241
- if (['text', 'richtext', 'string'].includes(col.type) && col.enforceLowerCase) {
242
- currentValues.value[key] = currentValues.value[key].toLowerCase();
243
- }
244
-
245
- currentValues.value = { ...currentValues.value };
246
- emit('update:record', currentValues.value);
247
- };
248
-
249
- onMounted(() => {
250
- currentValues.value = Object.assign({}, props.record);
251
- initFlowbite();
252
- emit('update:isValid', isValid.value);
253
- });
254
-
255
- const columnOptions = computedAsync(async () => {
256
- return (await Promise.all(
257
- Object.values(props.resource.columns).map(async (column) => {
258
- if (column.foreignResource) {
259
- const list = await callAdminForthApi({
260
- method: 'POST',
261
- path: `/get_resource_foreign_data`,
262
- body: {
263
- resourceId: router.currentRoute.value.params.resourceId,
264
- column: column.name,
265
- limit: 1000,
266
- offset: 0,
267
- },
268
- });
269
- return { [column.name]: list.items };
270
- }
271
- })
272
- )).reduce((acc, val) => Object.assign(acc, val), {})
273
-
274
- }, {});
275
-
276
-
277
- const editableColumns = computed(() => {
278
- const mode = props.record ? 'edit' : 'create';
279
- return props.resource?.columns?.filter(column => column.showIn.includes(mode));
280
- });
281
-
282
- const isValid = computed(() => {
283
- return editableColumns.value?.every(column => !columnError(column));
284
- });
285
-
286
- watch(() => isValid.value, (value) => {
287
- emit('update:isValid', value);
288
- });
289
-
290
- </script>