@nocobase/client-v2 2.1.0-alpha.40 → 2.1.0-alpha.45

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 (278) hide show
  1. package/es/Application.d.ts +7 -0
  2. package/es/BaseApplication.d.ts +13 -0
  3. package/es/RouterManager.d.ts +1 -0
  4. package/es/collection-field-interface/CollectionFieldInterface.d.ts +51 -15
  5. package/es/collection-field-interface/CollectionFieldInterfaceManager.d.ts +82 -3
  6. package/es/collection-manager/field-configure.d.ts +80 -0
  7. package/es/collection-manager/field-validation.d.ts +43 -0
  8. package/es/collection-manager/filter-operators/index.d.ts +46 -0
  9. package/es/collection-manager/filter-operators/operators.d.ts +30 -0
  10. package/es/collection-manager/interfaces/checkbox.d.ts +1 -41
  11. package/es/collection-manager/interfaces/checkboxGroup.d.ts +12 -44
  12. package/es/collection-manager/interfaces/collection.d.ts +12 -51
  13. package/es/collection-manager/interfaces/color.d.ts +1 -16
  14. package/es/collection-manager/interfaces/createdAt.d.ts +1 -44
  15. package/es/collection-manager/interfaces/createdBy.d.ts +0 -4
  16. package/es/collection-manager/interfaces/dateOnly.d.ts +7 -44
  17. package/es/collection-manager/interfaces/datetime.d.ts +1 -44
  18. package/es/collection-manager/interfaces/datetimeNoTz.d.ts +1 -44
  19. package/es/collection-manager/interfaces/email.d.ts +1 -29
  20. package/es/collection-manager/interfaces/id.d.ts +1 -16
  21. package/es/collection-manager/interfaces/index.d.ts +2 -3
  22. package/es/collection-manager/interfaces/input.d.ts +1 -102
  23. package/es/collection-manager/interfaces/integer.d.ts +1 -95
  24. package/es/collection-manager/interfaces/json.d.ts +16 -7
  25. package/es/collection-manager/interfaces/m2m.d.ts +11 -19
  26. package/es/collection-manager/interfaces/m2o.d.ts +11 -19
  27. package/es/collection-manager/interfaces/markdown.d.ts +1 -63
  28. package/es/collection-manager/interfaces/multipleSelect.d.ts +12 -44
  29. package/es/collection-manager/interfaces/nanoid.d.ts +1 -34
  30. package/es/collection-manager/interfaces/number.d.ts +1 -87
  31. package/es/collection-manager/interfaces/o2m.d.ts +12 -24
  32. package/es/collection-manager/interfaces/obo.d.ts +207 -0
  33. package/es/collection-manager/interfaces/oho.d.ts +207 -0
  34. package/es/collection-manager/interfaces/password.d.ts +1 -56
  35. package/es/collection-manager/interfaces/percent.d.ts +1 -84
  36. package/es/collection-manager/interfaces/phone.d.ts +1 -25
  37. package/es/collection-manager/interfaces/properties/index.d.ts +0 -28
  38. package/es/collection-manager/interfaces/radioGroup.d.ts +1 -29
  39. package/es/collection-manager/interfaces/richText.d.ts +1 -63
  40. package/es/collection-manager/interfaces/select.d.ts +12 -44
  41. package/es/collection-manager/interfaces/snowflake-id.d.ts +1 -34
  42. package/es/collection-manager/interfaces/tableoid.d.ts +1 -10
  43. package/es/collection-manager/interfaces/textarea.d.ts +1 -51
  44. package/es/collection-manager/interfaces/time.d.ts +1 -16
  45. package/es/collection-manager/interfaces/types.d.ts +3 -12
  46. package/es/collection-manager/interfaces/unixTimestamp.d.ts +1 -44
  47. package/es/collection-manager/interfaces/updatedAt.d.ts +1 -44
  48. package/es/collection-manager/interfaces/updatedBy.d.ts +0 -4
  49. package/es/collection-manager/interfaces/url.d.ts +1 -20
  50. package/es/collection-manager/interfaces/uuid.d.ts +1 -34
  51. package/es/collection-manager/template-fields.d.ts +53 -0
  52. package/es/components/KeepAlive.d.ts +22 -0
  53. package/es/components/RouterBridge.d.ts +9 -0
  54. package/es/components/form/DialogFormLayout.d.ts +5 -29
  55. package/es/components/form/VariableInput.d.ts +53 -2
  56. package/es/components/form/filter/CollectionFilter.d.ts +49 -0
  57. package/es/components/form/filter/CollectionFilterItem.d.ts +49 -0
  58. package/es/components/form/filter/DateFilterDynamicComponent.d.ts +57 -0
  59. package/es/components/form/filter/FilterValueInput.d.ts +29 -0
  60. package/es/components/form/filter/index.d.ts +11 -0
  61. package/es/components/form/filter/useFilterActionProps.d.ts +96 -0
  62. package/es/components/form/index.d.ts +1 -0
  63. package/es/data-source/ExtendCollectionsProvider.d.ts +50 -0
  64. package/es/data-source/index.d.ts +9 -0
  65. package/es/flow/FlowPage.d.ts +2 -1
  66. package/es/flow/admin-shell/AdminLayoutRouteCoordinator.d.ts +8 -40
  67. package/es/flow/admin-shell/BaseLayoutModel.d.ts +89 -0
  68. package/es/flow/admin-shell/BaseLayoutRouteCoordinator.d.ts +74 -0
  69. package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +12 -0
  70. package/es/flow/admin-shell/admin-layout/AdminLayoutModel.d.ts +7 -92
  71. package/es/flow/admin-shell/admin-layout/AppListRender.d.ts +11 -0
  72. package/es/flow/admin-shell/admin-layout/index.d.ts +3 -0
  73. package/es/flow/admin-shell/admin-layout/useApplications.d.ts +3 -2
  74. package/es/flow/admin-shell/useAdminLayoutRoutePage.d.ts +2 -2
  75. package/es/flow/admin-shell/useLayoutRoutePage.d.ts +23 -0
  76. package/es/flow/components/FlowRoute.d.ts +10 -1
  77. package/es/flow/components/filter/index.d.ts +2 -0
  78. package/es/flow/components/filter/useFilterOptions.d.ts +66 -0
  79. package/es/flow/index.d.ts +4 -0
  80. package/es/flow/models/base/PageModel/PageModel.d.ts +3 -1
  81. package/es/flow/models/blocks/assign-form/assignFieldValuesFlow.d.ts +84 -0
  82. package/es/flow/models/blocks/assign-form/index.d.ts +1 -0
  83. package/es/flow/models/blocks/form/FormActionGroupModel.d.ts +1 -0
  84. package/es/flow/models/blocks/form/FormActionModel.d.ts +9 -2
  85. package/es/flow/models/blocks/table/TableBlockModel.d.ts +10 -0
  86. package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.d.ts +1 -1
  87. package/es/flow-compat/passwordUtils.d.ts +1 -1
  88. package/es/index.d.ts +6 -0
  89. package/es/index.mjs +552 -459
  90. package/es/layout-manager/LayoutContentRoute.d.ts +14 -0
  91. package/es/layout-manager/LayoutManager.d.ts +22 -0
  92. package/es/layout-manager/LayoutRoute.d.ts +14 -0
  93. package/es/layout-manager/index.d.ts +13 -0
  94. package/es/layout-manager/types.d.ts +20 -0
  95. package/es/layout-manager/utils.d.ts +14 -0
  96. package/es/nocobase-buildin-plugin/index.d.ts +3 -10
  97. package/es/settings-center/index.d.ts +1 -1
  98. package/es/settings-center/plugin-manager/BulkEnableButton.d.ts +15 -0
  99. package/es/settings-center/plugin-manager/PluginCard.d.ts +15 -0
  100. package/es/settings-center/plugin-manager/PluginDetail.d.ts +16 -0
  101. package/es/settings-center/{PluginManagerPage.d.ts → plugin-manager/index.d.ts} +1 -7
  102. package/es/settings-center/plugin-manager/types.d.ts +34 -0
  103. package/lib/index.js +552 -459
  104. package/package.json +8 -7
  105. package/src/Application.tsx +51 -12
  106. package/src/BaseApplication.tsx +32 -0
  107. package/src/PluginSettingsManager.ts +1 -1
  108. package/src/RouterManager.tsx +17 -1
  109. package/src/__tests__/PluginSettingsManager.test.ts +41 -2
  110. package/src/__tests__/app.test.tsx +17 -1
  111. package/src/__tests__/globalDeps.test.ts +1 -0
  112. package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +45 -2
  113. package/src/__tests__/plugin-manager.test.tsx +177 -0
  114. package/src/__tests__/settings-center.test.tsx +24 -2
  115. package/src/collection-field-interface/CollectionFieldInterface.ts +71 -77
  116. package/src/collection-field-interface/CollectionFieldInterfaceManager.ts +201 -4
  117. package/src/collection-manager/field-configure.ts +548 -0
  118. package/src/collection-manager/field-validation.ts +195 -0
  119. package/src/collection-manager/filter-operators/index.ts +176 -0
  120. package/src/collection-manager/{interfaces/properties → filter-operators}/operators.ts +24 -13
  121. package/src/collection-manager/interfaces/checkbox.ts +2 -9
  122. package/src/collection-manager/interfaces/checkboxGroup.ts +2 -10
  123. package/src/collection-manager/interfaces/collection.ts +2 -15
  124. package/src/collection-manager/interfaces/color.ts +2 -2
  125. package/src/collection-manager/interfaces/createdAt.ts +2 -2
  126. package/src/collection-manager/interfaces/createdBy.ts +1 -12
  127. package/src/collection-manager/interfaces/dateOnly.ts +8 -2
  128. package/src/collection-manager/interfaces/datetime.ts +2 -2
  129. package/src/collection-manager/interfaces/datetimeNoTz.ts +2 -2
  130. package/src/collection-manager/interfaces/email.ts +2 -9
  131. package/src/collection-manager/interfaces/id.ts +1 -2
  132. package/src/collection-manager/interfaces/index.ts +2 -3
  133. package/src/collection-manager/interfaces/input.ts +2 -133
  134. package/src/collection-manager/interfaces/integer.ts +2 -71
  135. package/src/collection-manager/interfaces/json.tsx +17 -11
  136. package/src/collection-manager/interfaces/m2m.tsx +0 -21
  137. package/src/collection-manager/interfaces/m2o.tsx +0 -22
  138. package/src/collection-manager/interfaces/markdown.ts +2 -51
  139. package/src/collection-manager/interfaces/multipleSelect.ts +2 -14
  140. package/src/collection-manager/interfaces/nanoid.ts +2 -2
  141. package/src/collection-manager/interfaces/number.ts +2 -85
  142. package/src/collection-manager/interfaces/o2m.tsx +1 -22
  143. package/src/collection-manager/interfaces/obo.tsx +145 -0
  144. package/src/collection-manager/interfaces/oho.tsx +145 -0
  145. package/src/collection-manager/interfaces/password.ts +2 -44
  146. package/src/collection-manager/interfaces/percent.ts +2 -74
  147. package/src/collection-manager/interfaces/phone.ts +2 -2
  148. package/src/collection-manager/interfaces/properties/index.ts +0 -133
  149. package/src/collection-manager/interfaces/radioGroup.ts +2 -2
  150. package/src/collection-manager/interfaces/richText.ts +2 -51
  151. package/src/collection-manager/interfaces/select.ts +2 -14
  152. package/src/collection-manager/interfaces/snowflake-id.ts +2 -2
  153. package/src/collection-manager/interfaces/tableoid.ts +1 -2
  154. package/src/collection-manager/interfaces/textarea.ts +2 -51
  155. package/src/collection-manager/interfaces/time.ts +2 -2
  156. package/src/collection-manager/interfaces/types.ts +4 -12
  157. package/src/collection-manager/interfaces/unixTimestamp.tsx +2 -2
  158. package/src/collection-manager/interfaces/updatedAt.ts +2 -2
  159. package/src/collection-manager/interfaces/updatedBy.ts +1 -12
  160. package/src/collection-manager/interfaces/url.ts +2 -4
  161. package/src/collection-manager/interfaces/uuid.ts +2 -2
  162. package/src/collection-manager/template-fields.ts +109 -0
  163. package/src/components/KeepAlive.tsx +131 -0
  164. package/src/components/README.md +90 -6
  165. package/src/components/README.zh-CN.md +90 -7
  166. package/src/components/RouterBridge.tsx +28 -4
  167. package/src/components/__tests__/KeepAlive.test.tsx +63 -0
  168. package/src/components/__tests__/RouterBridge.test.tsx +27 -0
  169. package/src/components/form/DialogFormLayout.tsx +5 -29
  170. package/src/components/form/VariableInput.tsx +101 -28
  171. package/src/components/form/__tests__/VariableInput.test.ts +85 -0
  172. package/src/components/form/filter/CollectionFilter.tsx +111 -0
  173. package/src/components/form/filter/CollectionFilterItem.tsx +184 -0
  174. package/src/components/form/filter/DateFilterDynamicComponent.tsx +283 -0
  175. package/src/components/form/filter/FilterValueInput.tsx +198 -0
  176. package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +247 -0
  177. package/src/components/form/filter/__tests__/DateFilterDynamicComponent.test.tsx +148 -0
  178. package/src/components/form/filter/__tests__/FilterValueInput.test.tsx +243 -0
  179. package/src/components/form/filter/__tests__/compileFilterGroup.test.ts +146 -0
  180. package/src/components/form/filter/index.ts +13 -0
  181. package/src/components/form/filter/useFilterActionProps.ts +203 -0
  182. package/src/components/form/index.tsx +1 -0
  183. package/src/data-source/ExtendCollectionsProvider.tsx +144 -0
  184. package/src/data-source/__tests__/ExtendCollectionsProvider.test.tsx +264 -0
  185. package/src/data-source/index.ts +10 -0
  186. package/src/flow/FlowPage.tsx +35 -7
  187. package/src/flow/__tests__/FlowPage.test.tsx +79 -0
  188. package/src/flow/__tests__/FlowRoute.test.tsx +529 -2
  189. package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +191 -0
  190. package/src/flow/actions/__tests__/openView.subModelKey.test.tsx +33 -0
  191. package/src/flow/actions/aclCheck.tsx +4 -0
  192. package/src/flow/actions/aclCheckRefresh.tsx +4 -0
  193. package/src/flow/actions/dateTimeFormat.tsx +12 -8
  194. package/src/flow/actions/linkageRules.tsx +122 -0
  195. package/src/flow/actions/openView.tsx +28 -4
  196. package/src/flow/admin-shell/AdminLayoutRouteCoordinator.ts +11 -329
  197. package/src/flow/admin-shell/BaseLayoutModel.tsx +455 -0
  198. package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +502 -0
  199. package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +547 -3
  200. package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +35 -7
  201. package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +160 -0
  202. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +0 -12
  203. package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +28 -201
  204. package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +11 -2
  205. package/src/flow/admin-shell/admin-layout/AppListRender.tsx +139 -0
  206. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +1 -26
  207. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +149 -27
  208. package/src/flow/admin-shell/admin-layout/index.ts +3 -0
  209. package/src/flow/admin-shell/admin-layout/useApplications.tsx +34 -1
  210. package/src/flow/admin-shell/useAdminLayoutRoutePage.ts +10 -26
  211. package/src/flow/admin-shell/useLayoutRoutePage.ts +61 -0
  212. package/src/flow/components/AdminLayout.tsx +4 -154
  213. package/src/flow/components/FlowRoute.tsx +105 -15
  214. package/src/flow/components/filter/index.ts +3 -0
  215. package/src/flow/components/filter/useFilterOptions.ts +102 -0
  216. package/src/flow/index.ts +4 -0
  217. package/src/flow/models/actions/UpdateRecordActionModel.tsx +14 -95
  218. package/src/flow/models/actions/UpdateRecordActionUtils.ts +4 -7
  219. package/src/flow/models/actions/__tests__/AssignFormRefill.test.ts +26 -1
  220. package/src/flow/models/base/ActionModel.tsx +8 -1
  221. package/src/flow/models/base/PageModel/PageModel.tsx +51 -18
  222. package/src/flow/models/base/PageModel/RootPageModel.tsx +6 -13
  223. package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +102 -1
  224. package/src/flow/models/base/RouteModel.tsx +1 -1
  225. package/src/flow/models/blocks/assign-form/AssignFormItemModel.tsx +63 -2
  226. package/src/flow/models/blocks/assign-form/assignFieldValuesFlow.tsx +206 -0
  227. package/src/flow/models/blocks/assign-form/index.ts +1 -0
  228. package/src/flow/models/blocks/form/FormActionGroupModel.tsx +14 -0
  229. package/src/flow/models/blocks/form/FormActionModel.tsx +30 -3
  230. package/src/flow/models/blocks/form/FormItemModel.tsx +8 -1
  231. package/src/flow/models/blocks/form/__tests__/FormActionGroupModel.test.ts +46 -0
  232. package/src/flow/models/blocks/form/__tests__/submitHandler.test.ts +71 -0
  233. package/src/flow/models/blocks/form/submitHandler.ts +8 -1
  234. package/src/flow/models/blocks/form/submitValues.ts +4 -1
  235. package/src/flow/models/blocks/table/TableBlockModel.tsx +118 -16
  236. package/src/flow/models/blocks/table/__tests__/TableBlockModel.rowSelection.test.tsx +114 -0
  237. package/src/flow/models/fields/AssociationFieldModel/SubFormFieldModel.tsx +7 -1
  238. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +1 -1
  239. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.tsx +6 -5
  240. package/src/flow/models/fields/ClickableFieldModel.tsx +9 -1
  241. package/src/flow/models/fields/CollectionSelectorFieldModel.tsx +8 -2
  242. package/src/flow/models/fields/DisplayEnumFieldModel.tsx +8 -2
  243. package/src/flow/models/fields/DisplayTimeFieldModel.tsx +1 -1
  244. package/src/flow/models/fields/TimeFieldModel.tsx +1 -1
  245. package/src/flow/models/fields/__tests__/TimeFieldModel.test.tsx +61 -0
  246. package/src/flow/models/fields/mobile-components/MobileDatePicker.tsx +19 -3
  247. package/src/flow/models/fields/mobile-components/__tests__/MobileDatePicker.test.tsx +94 -0
  248. package/src/flow/models/topbar/TopbarActionModel.tsx +1 -1
  249. package/src/flow/utils/__tests__/dateTimeFormat.test.ts +91 -0
  250. package/src/index.ts +6 -0
  251. package/src/layout-manager/LayoutContentRoute.tsx +90 -0
  252. package/src/layout-manager/LayoutManager.tsx +185 -0
  253. package/src/layout-manager/LayoutRoute.tsx +138 -0
  254. package/src/layout-manager/__tests__/LayoutManager.test.tsx +335 -0
  255. package/src/layout-manager/__tests__/LayoutRoute.test.tsx +473 -0
  256. package/src/layout-manager/index.ts +14 -0
  257. package/src/layout-manager/types.ts +22 -0
  258. package/src/layout-manager/utils.ts +37 -0
  259. package/src/nocobase-buildin-plugin/index.tsx +69 -67
  260. package/src/nocobase-buildin-plugin/plugins/LocalePlugin.ts +1 -0
  261. package/src/settings-center/index.ts +1 -1
  262. package/src/settings-center/plugin-manager/BulkEnableButton.tsx +111 -0
  263. package/src/settings-center/plugin-manager/PluginCard.tsx +270 -0
  264. package/src/settings-center/plugin-manager/PluginDetail.tsx +195 -0
  265. package/src/settings-center/plugin-manager/index.tsx +254 -0
  266. package/src/settings-center/plugin-manager/types.ts +35 -0
  267. package/src/settings-center/utils.tsx +8 -1
  268. package/src/theme/__tests__/globalStyles.test.ts +24 -0
  269. package/src/theme/globalStyles.ts +10 -0
  270. package/src/utils/globalDeps.ts +2 -0
  271. package/es/collection-manager/interfaces/linkTo.d.ts +0 -90
  272. package/es/collection-manager/interfaces/o2o.d.ts +0 -621
  273. package/es/collection-manager/interfaces/properties/operators.d.ts +0 -294
  274. package/es/collection-manager/interfaces/subTable.d.ts +0 -172
  275. package/src/collection-manager/interfaces/linkTo.ts +0 -120
  276. package/src/collection-manager/interfaces/o2o.tsx +0 -561
  277. package/src/collection-manager/interfaces/subTable.ts +0 -218
  278. package/src/settings-center/PluginManagerPage.tsx +0 -162
@@ -0,0 +1,548 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import type { ComponentType, ReactNode } from 'react';
11
+ import { getPickerFormat } from '@nocobase/utils/client';
12
+ import { get, has } from 'lodash';
13
+
14
+ export type FieldConfigureComponentType =
15
+ | 'Input'
16
+ | 'Input.TextArea'
17
+ | 'InputNumber'
18
+ | 'Checkbox'
19
+ | 'Checkbox.Group'
20
+ | 'ColorPicker'
21
+ | 'DatePicker'
22
+ | 'Radio.Group'
23
+ | 'Select'
24
+ | 'CollectionSelect'
25
+ | 'RemoteSelect'
26
+ | 'TargetKey'
27
+ | 'SourceKey'
28
+ | 'ExpiresRadio'
29
+ | 'ArrayTable'
30
+ | 'FieldValidation'
31
+ | 'ForeignKey'
32
+ | 'Input.JSON'
33
+ | 'Markdown'
34
+ | 'Percent'
35
+ | 'RichText'
36
+ | 'SourceCollection'
37
+ | 'Space'
38
+ | 'ThroughCollection'
39
+ | 'TimePicker'
40
+ | 'UnixTimestamp'
41
+ | (string & {});
42
+
43
+ export const CollectionSelect = 'CollectionSelect';
44
+
45
+ export interface FieldConfigureRuntimeContext {
46
+ createOnly?: boolean;
47
+ editMainOnly?: boolean;
48
+ createMainOnly?: boolean;
49
+ disabledJSONB?: boolean;
50
+ primaryKeyOnly?: boolean;
51
+ showReverseFieldConfig?: boolean;
52
+ [key: string]: unknown;
53
+ }
54
+
55
+ export interface FieldConfigureRuntimeState {
56
+ componentProps?: Record<string, unknown>;
57
+ dataSource?: unknown;
58
+ disabled?: boolean;
59
+ hidden?: boolean;
60
+ hasValue?: boolean;
61
+ value?: unknown;
62
+ }
63
+
64
+ export interface FieldConfigureEffectContext {
65
+ changedName?: string;
66
+ context: FieldConfigureRuntimeContext;
67
+ getValue: (name: string) => unknown;
68
+ setValue: (name: string, value: unknown) => void;
69
+ values: Record<string, unknown>;
70
+ }
71
+
72
+ export interface FieldConfigureItem {
73
+ name: string;
74
+ title?: ReactNode;
75
+ component?: FieldConfigureComponentType;
76
+ Component?: ComponentType<any>;
77
+ componentProps?: Record<string, unknown>;
78
+ defaultValue?: unknown;
79
+ description?: ReactNode;
80
+ hidden?: boolean | string | ((context: FieldConfigureEffectContext) => boolean);
81
+ disabled?: boolean | string | ((context: FieldConfigureEffectContext) => boolean);
82
+ options?: Array<{ label: ReactNode; value: string | number | boolean }>;
83
+ required?: boolean;
84
+ dependencies?: string[];
85
+ effect?: (context: FieldConfigureEffectContext) => void;
86
+ schema?: Record<string, unknown>;
87
+ layout?: {
88
+ row?: string;
89
+ column?: string;
90
+ columnIndex?: number;
91
+ span?: number;
92
+ };
93
+ }
94
+
95
+ const commonConfigurePropertyNames = new Set(['name', 'uiSchema.title']);
96
+ const propertyLayoutComponents = new Set(['Grid', 'Grid.Row', 'Grid.Col', 'div']);
97
+
98
+ function getExpressionContext(context: FieldConfigureEffectContext) {
99
+ return {
100
+ ...context.context,
101
+ ...context.values,
102
+ };
103
+ }
104
+
105
+ export function evaluateFieldConfigureExpression(value: unknown, context: FieldConfigureEffectContext) {
106
+ if (typeof value === 'boolean') {
107
+ return value;
108
+ }
109
+ if (typeof value !== 'string') {
110
+ return false;
111
+ }
112
+
113
+ const expression = value.replace(/^\s*\{\{\s*/, '').replace(/\s*\}\}\s*$/, '');
114
+ const expressionContext = getExpressionContext(context);
115
+ const evaluateToken = (token: string) => {
116
+ const trimmed = token.trim().replace(/^\$/, '');
117
+ if (!trimmed) {
118
+ return false;
119
+ }
120
+ if (trimmed.startsWith('!')) {
121
+ return !evaluateToken(trimmed.slice(1).trim());
122
+ }
123
+ if (trimmed === 'true') {
124
+ return true;
125
+ }
126
+ if (trimmed === 'false') {
127
+ return false;
128
+ }
129
+ const callExpression = trimmed.match(/^([A-Za-z_$][\w$]*)\((.*)\)$/);
130
+ if (callExpression) {
131
+ const [, functionName, rawArgs] = callExpression;
132
+ const fn = get(expressionContext, functionName);
133
+ if (typeof fn !== 'function') {
134
+ return false;
135
+ }
136
+ const args = rawArgs
137
+ .split(',')
138
+ .map((arg) => arg.trim())
139
+ .filter(Boolean)
140
+ .map((arg) => arg.replace(/^['"]|['"]$/g, ''));
141
+ return !!fn(...args);
142
+ }
143
+ return !!get(expressionContext, trimmed);
144
+ };
145
+
146
+ return expression.split('||').some((orPart) => orPart.split('&&').every((andPart) => evaluateToken(andPart)));
147
+ }
148
+
149
+ function normalizeConfigureStateExpression(value: unknown) {
150
+ if (typeof value === 'string') {
151
+ return (context: FieldConfigureEffectContext) => evaluateFieldConfigureExpression(value, context);
152
+ }
153
+ return value as FieldConfigureItem['hidden'];
154
+ }
155
+
156
+ function normalizeConfigureHiddenExpression(schema: Record<string, any>) {
157
+ if (schema?.['x-hidden'] !== undefined) {
158
+ return normalizeConfigureStateExpression(schema['x-hidden']);
159
+ }
160
+ if (schema?.['x-visible'] !== undefined) {
161
+ return (context: FieldConfigureEffectContext) => !evaluateFieldConfigureExpression(schema['x-visible'], context);
162
+ }
163
+ return undefined;
164
+ }
165
+
166
+ function collectConfigureLeafProperties(
167
+ properties: Record<string, any>,
168
+ prefix = '',
169
+ layout?: FieldConfigureItem['layout'],
170
+ ): Array<{ name: string; schema: any; layout?: FieldConfigureItem['layout'] }> {
171
+ return Object.entries(properties || {}).flatMap(([key, schema]) => {
172
+ const name = prefix ? `${prefix}.${key}` : key;
173
+ const childProperties = schema?.properties;
174
+ const component = schema?.['x-component'];
175
+
176
+ if (childProperties && component === 'Grid.Row') {
177
+ const columns = Object.entries(childProperties).filter(
178
+ ([, childSchema]) => (childSchema as Record<string, any>)?.['x-component'] === 'Grid.Col',
179
+ );
180
+ const span = columns.length > 0 ? Math.floor(24 / columns.length) : 24;
181
+
182
+ return columns.flatMap(([columnKey, columnSchema], columnIndex) =>
183
+ collectConfigureLeafProperties((columnSchema as Record<string, any>)?.properties || {}, prefix, {
184
+ row: name,
185
+ column: columnKey,
186
+ columnIndex,
187
+ span,
188
+ }),
189
+ );
190
+ }
191
+
192
+ if (childProperties && (!component || propertyLayoutComponents.has(component))) {
193
+ return collectConfigureLeafProperties(childProperties, prefix, layout);
194
+ }
195
+
196
+ return [{ name, schema, layout }];
197
+ });
198
+ }
199
+
200
+ function isConvertibleConfigureProperty(name: string, schema: Record<string, any>) {
201
+ if (commonConfigurePropertyNames.has(name)) {
202
+ return false;
203
+ }
204
+ return !!schema?.['x-component'] || schema?.default !== undefined || schema?.['x-hidden'] !== undefined;
205
+ }
206
+
207
+ export function configurePropertiesToItems(
208
+ properties: Record<string, any> = {},
209
+ options: { components?: Record<string, ComponentType<any>> } = {},
210
+ ): FieldConfigureItem[] {
211
+ return collectConfigureLeafProperties(properties)
212
+ .filter(({ name, schema }) => isConvertibleConfigureProperty(name, schema))
213
+ .map(({ name, schema, layout }) => {
214
+ const component = schema?.['x-component'] as FieldConfigureComponentType | undefined;
215
+ return {
216
+ name,
217
+ title: schema?.title || schema?.['x-content'],
218
+ component,
219
+ Component: component ? options.components?.[component] : undefined,
220
+ componentProps: schema?.['x-component-props'],
221
+ defaultValue: schema?.default,
222
+ description: schema?.description,
223
+ hidden: normalizeConfigureHiddenExpression(schema),
224
+ disabled: normalizeConfigureStateExpression(schema?.['x-disabled']) as FieldConfigureItem['disabled'],
225
+ options: Array.isArray(schema?.enum) ? schema.enum : undefined,
226
+ required: schema?.required,
227
+ schema,
228
+ layout,
229
+ };
230
+ });
231
+ }
232
+
233
+ const DATE_FORMAT_OPTIONS = [
234
+ { label: 'MMMM Do YYYY', value: 'MMMM Do YYYY' },
235
+ { label: 'YYYY-MM-DD', value: 'YYYY-MM-DD' },
236
+ { label: 'MM/DD/YY', value: 'MM/DD/YY' },
237
+ { label: 'YYYY/MM/DD', value: 'YYYY/MM/DD' },
238
+ { label: 'DD/MM/YYYY', value: 'DD/MM/YYYY' },
239
+ { label: '{{t("Custom")}}', value: 'custom' },
240
+ ];
241
+
242
+ const TIME_FORMAT_OPTIONS = [
243
+ { label: '{{t("12 hour")}}', value: 'hh:mm:ss a' },
244
+ { label: '{{t("24 hour")}}', value: 'HH:mm:ss' },
245
+ ];
246
+
247
+ function getPicker(values: Record<string, unknown>) {
248
+ return get(values, 'uiSchema.x-component-props.picker') || 'date';
249
+ }
250
+
251
+ function getShowTime(values: Record<string, unknown>) {
252
+ return get(values, 'uiSchema.x-component-props.showTime');
253
+ }
254
+
255
+ export function getCoreFieldConfigureState(
256
+ name: string,
257
+ values: Record<string, unknown>,
258
+ context: FieldConfigureRuntimeContext = {},
259
+ ): FieldConfigureRuntimeState {
260
+ if (name === 'unique' || name === 'primaryKey') {
261
+ return {
262
+ disabled: !context.createMainOnly || !!context.primaryKeyOnly,
263
+ };
264
+ }
265
+
266
+ if (name === 'autoIncrement') {
267
+ return {
268
+ disabled: !context.createMainOnly,
269
+ };
270
+ }
271
+
272
+ if (name.startsWith('reverseField.')) {
273
+ return {
274
+ disabled: !context.showReverseFieldConfig,
275
+ hidden: !context.showReverseFieldConfig,
276
+ };
277
+ }
278
+
279
+ if (name === 'autoCreateReverseField' && get(values, 'reverseField.key')) {
280
+ return {
281
+ disabled: true,
282
+ };
283
+ }
284
+
285
+ if (name === 'uiSchema.x-component-props.dateFormat') {
286
+ return {
287
+ componentProps: {
288
+ picker: getPicker(values),
289
+ },
290
+ };
291
+ }
292
+
293
+ if (name === 'uiSchema.x-component-props.showTime') {
294
+ return {
295
+ hidden: getPicker(values) !== 'date',
296
+ };
297
+ }
298
+
299
+ if (name === 'uiSchema.x-component-props.timeFormat') {
300
+ return {
301
+ hidden: getPicker(values) !== 'date' || getShowTime(values) === false,
302
+ };
303
+ }
304
+
305
+ if (name === 'defaultValue') {
306
+ const shouldHide =
307
+ !!get(values, 'primaryKey') ||
308
+ !!get(values, 'unique') ||
309
+ !!get(values, 'autoIncrement') ||
310
+ !!get(values, 'defaultToCurrentTime');
311
+
312
+ return {
313
+ hidden: shouldHide,
314
+ ...(shouldHide ? { value: null, hasValue: true } : null),
315
+ componentProps: {
316
+ gmt: get(values, 'uiSchema.x-component-props.gmt'),
317
+ showTime: get(values, 'uiSchema.x-component-props.showTime'),
318
+ dateFormat: get(values, 'uiSchema.x-component-props.dateFormat'),
319
+ timeFormat: get(values, 'uiSchema.x-component-props.timeFormat'),
320
+ picker: get(values, 'uiSchema.x-component-props.picker'),
321
+ format: get(values, 'uiSchema.x-component-props.format'),
322
+ },
323
+ dataSource: get(values, 'uiSchema.enum'),
324
+ };
325
+ }
326
+
327
+ if ((name === 'precision' || name === 'scale') && get(values, 'type') !== 'decimal') {
328
+ return {
329
+ hidden: true,
330
+ };
331
+ }
332
+
333
+ return {};
334
+ }
335
+
336
+ export function runCoreFieldConfigureEffects(options: FieldConfigureEffectContext) {
337
+ const { context, getValue, setValue, values } = options;
338
+ const primaryKey = !!getValue('primaryKey');
339
+ const unique = !!getValue('unique');
340
+
341
+ if (context.createMainOnly && primaryKey && (!options.changedName || options.changedName === 'primaryKey')) {
342
+ if (getValue('unique') !== false) {
343
+ setValue('unique', false);
344
+ }
345
+ if (has(values, 'autoIncrement') && getValue('autoIncrement') !== true) {
346
+ setValue('autoIncrement', true);
347
+ }
348
+ }
349
+
350
+ if (context.createMainOnly && unique && primaryKey && options.changedName === 'unique') {
351
+ setValue('primaryKey', false);
352
+ }
353
+
354
+ if (get(values, 'reverseField.key') && getValue('autoCreateReverseField') !== true) {
355
+ setValue('autoCreateReverseField', true);
356
+ }
357
+
358
+ if (
359
+ options.changedName === 'uiSchema.x-component-props.picker' ||
360
+ ['primaryKey', 'unique', 'autoIncrement', 'defaultToCurrentTime'].includes(options.changedName || '')
361
+ ) {
362
+ if (
363
+ getValue('defaultValue') != null &&
364
+ (!!getValue('primaryKey') ||
365
+ !!getValue('unique') ||
366
+ !!getValue('autoIncrement') ||
367
+ !!getValue('defaultToCurrentTime') ||
368
+ options.changedName === 'uiSchema.x-component-props.picker')
369
+ ) {
370
+ setValue('defaultValue', null);
371
+ }
372
+ }
373
+
374
+ const hasDateTimeConfigure =
375
+ has(values, 'uiSchema.x-component-props.picker') ||
376
+ has(values, 'uiSchema.x-component-props.dateFormat') ||
377
+ has(values, 'uiSchema.x-component-props.showTime') ||
378
+ has(values, 'uiSchema.x-component-props.timeFormat');
379
+
380
+ if (!hasDateTimeConfigure) {
381
+ return;
382
+ }
383
+
384
+ const picker = getPicker(values);
385
+ if (
386
+ options.changedName === 'uiSchema.x-component-props.picker' &&
387
+ has(values, 'uiSchema.x-component-props.dateFormat') &&
388
+ get(values, 'uiSchema.x-component-props.dateFormat') !== getPickerFormat(picker as string)
389
+ ) {
390
+ setValue('uiSchema.x-component-props.dateFormat', getPickerFormat(picker as string));
391
+ }
392
+
393
+ if (has(values, 'uiSchema.x-component-props.showTime') && picker !== 'date' && getShowTime(values) !== false) {
394
+ setValue('uiSchema.x-component-props.showTime', false);
395
+ }
396
+
397
+ if (
398
+ has(values, 'uiSchema.x-component-props.timeFormat') &&
399
+ getShowTime(values) &&
400
+ !get(values, 'uiSchema.x-component-props.timeFormat')
401
+ ) {
402
+ setValue('uiSchema.x-component-props.timeFormat', 'HH:mm:ss');
403
+ }
404
+ }
405
+
406
+ export function indexConfigureItems(options: { autoIncrement?: boolean } = {}): FieldConfigureItem[] {
407
+ const items: FieldConfigureItem[] = [
408
+ {
409
+ name: 'primaryKey',
410
+ title: '{{t("Primary")}}',
411
+ component: 'Checkbox',
412
+ },
413
+ {
414
+ name: 'unique',
415
+ title: '{{t("Unique")}}',
416
+ component: 'Checkbox',
417
+ },
418
+ ];
419
+
420
+ if (options.autoIncrement) {
421
+ items.push({
422
+ name: 'autoIncrement',
423
+ title: '{{t("Auto increment")}}',
424
+ component: 'Checkbox',
425
+ });
426
+ }
427
+
428
+ return items;
429
+ }
430
+
431
+ export function dateTimeFormatConfigureItems(
432
+ options: {
433
+ includePicker?: boolean;
434
+ hidden?: FieldConfigureItem['hidden'];
435
+ showTimeDefault?: boolean;
436
+ } = {},
437
+ ): FieldConfigureItem[] {
438
+ const items: FieldConfigureItem[] = [];
439
+
440
+ if (options.includePicker !== false) {
441
+ items.push({
442
+ name: 'uiSchema.x-component-props.picker',
443
+ title: '{{t("Picker")}}',
444
+ component: 'Radio.Group',
445
+ defaultValue: 'date',
446
+ options: [
447
+ { label: '{{t("Date")}}', value: 'date' },
448
+ { label: '{{t("Month")}}', value: 'month' },
449
+ { label: '{{t("Quarter")}}', value: 'quarter' },
450
+ { label: '{{t("Year")}}', value: 'year' },
451
+ ],
452
+ hidden: options.hidden,
453
+ });
454
+ }
455
+
456
+ items.push(
457
+ {
458
+ name: 'uiSchema.x-component-props.dateFormat',
459
+ title: '{{t("Date format")}}',
460
+ component: 'ExpiresRadio',
461
+ defaultValue: 'YYYY-MM-DD',
462
+ options: DATE_FORMAT_OPTIONS,
463
+ componentProps: {
464
+ defaultValue: 'dddd',
465
+ formats: ['MMMM Do YYYY', 'YYYY-MM-DD', 'MM/DD/YY', 'YYYY/MM/DD', 'DD/MM/YYYY'],
466
+ },
467
+ hidden: options.hidden,
468
+ },
469
+ {
470
+ name: 'uiSchema.x-component-props.showTime',
471
+ title: '{{t("Show time")}}',
472
+ component: 'Checkbox',
473
+ defaultValue: options.showTimeDefault,
474
+ hidden: options.hidden,
475
+ },
476
+ {
477
+ name: 'uiSchema.x-component-props.timeFormat',
478
+ title: '{{t("Time format")}}',
479
+ component: 'Radio.Group',
480
+ defaultValue: 'HH:mm:ss',
481
+ options: TIME_FORMAT_OPTIONS,
482
+ hidden: (context) => {
483
+ if (typeof options.hidden === 'function' && options.hidden(context)) {
484
+ return true;
485
+ }
486
+ if (typeof options.hidden === 'boolean') {
487
+ return options.hidden;
488
+ }
489
+ return getShowTime(context.values) === false;
490
+ },
491
+ },
492
+ );
493
+
494
+ return items;
495
+ }
496
+
497
+ export function reverseFieldConfigureItems(): FieldConfigureItem[] {
498
+ return [
499
+ {
500
+ name: 'autoCreateReverseField',
501
+ title: '{{t("Create inverse field in the target collection")}}',
502
+ component: 'Checkbox',
503
+ defaultValue: false,
504
+ },
505
+ {
506
+ name: 'reverseField.type',
507
+ title: '{{t("Inverse relationship type")}}',
508
+ component: 'Select',
509
+ required: true,
510
+ options: [
511
+ { label: "{{t('HasOne')}}", value: 'hasOne' },
512
+ { label: "{{t('HasMany')}}", value: 'hasMany' },
513
+ { label: "{{t('BelongsTo')}}", value: 'belongsTo' },
514
+ { label: "{{t('BelongsToMany')}}", value: 'belongsToMany' },
515
+ ],
516
+ hidden: ({ context, values }) => !context.showReverseFieldConfig && !get(values, 'autoCreateReverseField'),
517
+ disabled: ({ context }) => !context.showReverseFieldConfig,
518
+ },
519
+ {
520
+ name: 'reverseField.uiSchema.title',
521
+ title: '{{t("Inverse field display name")}}',
522
+ component: 'Input',
523
+ required: true,
524
+ hidden: ({ context, values }) => !context.showReverseFieldConfig && !get(values, 'autoCreateReverseField'),
525
+ disabled: ({ context }) => !context.showReverseFieldConfig,
526
+ },
527
+ {
528
+ name: 'reverseField.name',
529
+ title: '{{t("Inverse field name")}}',
530
+ component: 'Input',
531
+ required: true,
532
+ description:
533
+ "{{t('Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.')}}",
534
+ hidden: ({ context, values }) => !context.showReverseFieldConfig && !get(values, 'autoCreateReverseField'),
535
+ disabled: ({ context }) => !context.showReverseFieldConfig,
536
+ },
537
+ ];
538
+ }
539
+
540
+ export const reverseFieldConfigureItem = reverseFieldConfigureItems;
541
+
542
+ export function OptionsEditor(options: { name?: string; title?: ReactNode } = {}): FieldConfigureItem {
543
+ return {
544
+ name: options.name || 'uiSchema.enum',
545
+ title: options.title || '{{t("Options")}}',
546
+ component: 'ArrayTable',
547
+ };
548
+ }