@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,195 @@
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 { cloneDeep } from 'lodash';
11
+ import type { ReactNode } from 'react';
12
+
13
+ export interface FieldValidationConfigureParam {
14
+ key: string;
15
+ label: ReactNode;
16
+ componentType?: 'checkbox' | 'datePicker' | 'inputNumber' | 'multipleSelect' | 'radio' | 'singleSelect' | 'text';
17
+ defaultValue?: unknown;
18
+ options?: Array<{ label: ReactNode; value: string | number | boolean }>;
19
+ required?: boolean;
20
+ }
21
+
22
+ export interface FieldValidationConfigureItem {
23
+ key: string;
24
+ label: ReactNode;
25
+ hasValue?: boolean;
26
+ params?: FieldValidationConfigureParam[];
27
+ paramsType?: string;
28
+ }
29
+
30
+ export type FieldValidationConfigureInput = FieldValidationConfigureItem | string;
31
+
32
+ const requiredValidationItem: FieldValidationConfigureItem = {
33
+ key: 'required',
34
+ label: 'Required',
35
+ hasValue: false,
36
+ params: [],
37
+ };
38
+
39
+ export function RangeValidationItems(valueKind: 'date' | 'number'): FieldValidationConfigureItem[] {
40
+ const componentType = valueKind === 'date' ? 'datePicker' : 'inputNumber';
41
+ const valueKey = valueKind === 'date' ? 'date' : 'limit';
42
+
43
+ return [
44
+ {
45
+ key: 'greater',
46
+ label: 'Greater than',
47
+ hasValue: true,
48
+ params: [{ key: valueKey, label: valueKind === 'date' ? 'Date' : 'Limit', componentType, required: true }],
49
+ },
50
+ {
51
+ key: 'less',
52
+ label: 'Less than',
53
+ hasValue: true,
54
+ params: [{ key: valueKey, label: valueKind === 'date' ? 'Date' : 'Limit', componentType, required: true }],
55
+ },
56
+ {
57
+ key: 'max',
58
+ label: valueKind === 'date' ? 'Max value' : 'Max value',
59
+ hasValue: true,
60
+ params: [{ key: valueKey, label: valueKind === 'date' ? 'Date' : 'Limit', componentType, required: true }],
61
+ },
62
+ {
63
+ key: 'min',
64
+ label: valueKind === 'date' ? 'Min value' : 'Min value',
65
+ hasValue: true,
66
+ params: [{ key: valueKey, label: valueKind === 'date' ? 'Date' : 'Limit', componentType, required: true }],
67
+ },
68
+ ];
69
+ }
70
+
71
+ export class FieldValidationConfigureRegistry {
72
+ protected items = new Map<string, FieldValidationConfigureItem>();
73
+ protected groups = new Map<string, FieldValidationConfigureInput[]>();
74
+
75
+ register(item: FieldValidationConfigureItem) {
76
+ this.items.set(item.key, cloneDeep(item));
77
+ }
78
+
79
+ registerMany(items: FieldValidationConfigureItem[] = []) {
80
+ items.forEach((item) => this.register(item));
81
+ }
82
+
83
+ registerGroup(name: string, items: FieldValidationConfigureInput[] = []) {
84
+ this.groups.set(name, items);
85
+ }
86
+
87
+ addToGroup(name: string, items: FieldValidationConfigureInput[] = []) {
88
+ this.groups.set(name, [...(this.groups.get(name) || []), ...items]);
89
+ }
90
+
91
+ get(name: string) {
92
+ return cloneDeep(this.items.get(name));
93
+ }
94
+
95
+ getGroup(name: string) {
96
+ return (this.groups.get(name) || [])
97
+ .map((item) => (typeof item === 'string' ? this.get(item) : cloneDeep(item)))
98
+ .filter(Boolean) as FieldValidationConfigureItem[];
99
+ }
100
+ }
101
+
102
+ export const fieldValidationConfigureRegistry = new FieldValidationConfigureRegistry();
103
+
104
+ export function registerFieldValidationConfigure(item: FieldValidationConfigureItem) {
105
+ fieldValidationConfigureRegistry.register(item);
106
+ }
107
+
108
+ export function registerFieldValidationConfigureGroup(name: string, items: FieldValidationConfigureInput[] = []) {
109
+ fieldValidationConfigureRegistry.registerGroup(name, items);
110
+ }
111
+
112
+ export function addFieldValidationConfiguresToGroup(name: string, items: FieldValidationConfigureInput[] = []) {
113
+ fieldValidationConfigureRegistry.addToGroup(name, items);
114
+ }
115
+
116
+ fieldValidationConfigureRegistry.registerMany([
117
+ requiredValidationItem,
118
+ {
119
+ key: 'pattern',
120
+ label: 'Pattern',
121
+ hasValue: true,
122
+ params: [{ key: 'regex', label: 'Regular Expression', componentType: 'text', required: true }],
123
+ },
124
+ { key: 'email', label: 'Email', hasValue: false, params: [], paramsType: 'object' },
125
+ { key: 'uuid', label: 'UUID', hasValue: false, params: [], paramsType: 'object' },
126
+ {
127
+ key: 'length',
128
+ label: 'Length',
129
+ hasValue: true,
130
+ params: [{ key: 'limit', label: 'Limit', componentType: 'inputNumber', required: true }],
131
+ },
132
+ { key: 'uri', label: 'URI', hasValue: false, params: [], paramsType: 'object' },
133
+ {
134
+ key: 'multiple',
135
+ label: 'Multiple',
136
+ hasValue: true,
137
+ params: [{ key: 'base', label: 'Base', componentType: 'inputNumber', required: true }],
138
+ },
139
+ { key: 'integer', label: 'Integer', hasValue: false, params: [] },
140
+ {
141
+ key: 'precision',
142
+ label: 'Precision',
143
+ hasValue: true,
144
+ params: [{ key: 'limit', label: 'Limit', componentType: 'inputNumber', required: true }],
145
+ },
146
+ { key: 'unsafe', label: 'Unsafe integer', hasValue: false, params: [] },
147
+ {
148
+ key: 'timestamp',
149
+ label: 'Timestamp',
150
+ hasValue: true,
151
+ params: [
152
+ {
153
+ key: 'type',
154
+ label: 'Type',
155
+ componentType: 'singleSelect',
156
+ options: [
157
+ { label: 'JavaScript', value: 'javascript' },
158
+ { label: 'Unix', value: 'unix' },
159
+ ],
160
+ defaultValue: 'javascript',
161
+ },
162
+ ],
163
+ },
164
+ ]);
165
+
166
+ fieldValidationConfigureRegistry.registerGroup('string', [
167
+ 'required',
168
+ {
169
+ key: 'max',
170
+ label: 'Max length',
171
+ hasValue: true,
172
+ params: [{ key: 'limit', label: 'Limit', componentType: 'inputNumber', required: true }],
173
+ },
174
+ {
175
+ key: 'min',
176
+ label: 'Min length',
177
+ hasValue: true,
178
+ params: [{ key: 'limit', label: 'Limit', componentType: 'inputNumber', required: true }],
179
+ },
180
+ 'pattern',
181
+ 'email',
182
+ 'uuid',
183
+ 'length',
184
+ 'uri',
185
+ ]);
186
+ fieldValidationConfigureRegistry.registerGroup('number', [
187
+ 'required',
188
+ ...RangeValidationItems('number'),
189
+ 'multiple',
190
+ 'integer',
191
+ 'precision',
192
+ 'unsafe',
193
+ ]);
194
+ fieldValidationConfigureRegistry.registerGroup('date', ['required', ...RangeValidationItems('date'), 'timestamp']);
195
+ fieldValidationConfigureRegistry.registerGroup('object', ['required']);
@@ -0,0 +1,176 @@
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 * as standardFieldFilterOperatorGroups from './operators';
11
+ import type { FieldFilterOperator } from './operators';
12
+
13
+ export * from './operators';
14
+
15
+ export type FieldFilterOperatorPreset = keyof typeof standardFieldFilterOperatorGroups;
16
+
17
+ export type FieldFilterOperatorGroupName = FieldFilterOperatorPreset | (string & {});
18
+
19
+ export type FieldFilterOperatorReference<TMeta = unknown> = FieldFilterOperator<TMeta> | string;
20
+
21
+ export type FieldFilterOperatorList<TMeta = unknown> = FieldFilterOperator<TMeta>[] | FieldFilterOperatorGroupName;
22
+
23
+ export type FieldFilterable<TMeta = unknown> = {
24
+ operators?: FieldFilterOperatorList<TMeta>;
25
+ operatorGroup?: string;
26
+ children?: unknown[];
27
+ nested?: boolean;
28
+ [key: string]: unknown;
29
+ };
30
+
31
+ export class FieldFilterOperatorRegistry {
32
+ protected operators: Record<string, FieldFilterOperator> = {};
33
+ protected groups: Record<string, FieldFilterOperator[]> = {};
34
+
35
+ constructor(groups: Record<string, FieldFilterOperator[]> = {}) {
36
+ Object.entries(groups).forEach(([name, operatorList]) => {
37
+ this.registerGroup(name, operatorList);
38
+ });
39
+ }
40
+
41
+ register(operator: FieldFilterOperator) {
42
+ this.operators[operator.value] = operator;
43
+ return this;
44
+ }
45
+
46
+ registerMany(operators: FieldFilterOperator[] = []) {
47
+ operators.forEach((operator) => {
48
+ this.register(operator);
49
+ });
50
+ return this;
51
+ }
52
+
53
+ registerGroup(name: string, operators: FieldFilterOperatorReference[] = []) {
54
+ const operatorList = this.resolveOperatorReferences(operators);
55
+ this.registerMany(operatorList);
56
+ this.groups[name] = operatorList;
57
+ return this;
58
+ }
59
+
60
+ addToGroup(name: string, operators: FieldFilterOperatorReference[] = []) {
61
+ const operatorList = this.resolveOperatorReferences(operators);
62
+ this.registerMany(operatorList);
63
+ if (!this.groups[name]) {
64
+ this.groups[name] = [];
65
+ }
66
+ operatorList.forEach((operator) => {
67
+ if (!this.groups[name].some((item) => item.value === operator.value)) {
68
+ this.groups[name].push(operator);
69
+ }
70
+ });
71
+ return this;
72
+ }
73
+
74
+ get(name: string) {
75
+ return this.operators[name];
76
+ }
77
+
78
+ getGroup(name: string) {
79
+ return this.groups[name] || [];
80
+ }
81
+
82
+ getGroups() {
83
+ return this.groups;
84
+ }
85
+
86
+ resolveOperators<TMeta = unknown>(operators?: FieldFilterOperatorList<TMeta>): FieldFilterOperator<TMeta>[] {
87
+ if (!operators) {
88
+ return [];
89
+ }
90
+
91
+ if (typeof operators === 'string') {
92
+ return this.getGroup(operators) as FieldFilterOperator<TMeta>[];
93
+ }
94
+
95
+ return operators;
96
+ }
97
+
98
+ protected resolveOperatorReferences(operators: FieldFilterOperatorReference[] = []) {
99
+ return operators
100
+ .map((operator) => (typeof operator === 'string' ? this.get(operator) : operator))
101
+ .filter((operator): operator is FieldFilterOperator => Boolean(operator));
102
+ }
103
+ }
104
+
105
+ export const filterOperatorRegistry = new FieldFilterOperatorRegistry(standardFieldFilterOperatorGroups);
106
+
107
+ export const fieldFilterOperators = filterOperatorRegistry.getGroups() as Record<string, FieldFilterOperator[]> &
108
+ typeof standardFieldFilterOperatorGroups;
109
+
110
+ export const fieldFilterOperatorPresets = fieldFilterOperators;
111
+
112
+ export function resolveFilterOperators<TMeta = unknown>(
113
+ operators?: FieldFilterOperatorList<TMeta>,
114
+ ): FieldFilterOperator<TMeta>[] {
115
+ return filterOperatorRegistry.resolveOperators(operators);
116
+ }
117
+
118
+ export function normalizeFilterableOperators<TMeta = unknown>(filterable?: FieldFilterable<TMeta>) {
119
+ if (!filterable) {
120
+ return filterable;
121
+ }
122
+
123
+ if (filterable.operatorGroup) {
124
+ filterable.operators = resolveFilterOperators(filterable.operatorGroup);
125
+ }
126
+
127
+ const rawOperators = (filterable as { operators?: unknown }).operators;
128
+ if (typeof rawOperators === 'string') {
129
+ filterable.operatorGroup = rawOperators;
130
+ filterable.operators = resolveFilterOperators(rawOperators);
131
+ }
132
+
133
+ if (Array.isArray(filterable.children)) {
134
+ filterable.children.forEach((child) => {
135
+ if (child && typeof child === 'object') {
136
+ normalizeFilterableOperators(child as FieldFilterable<TMeta>);
137
+ }
138
+ });
139
+ }
140
+
141
+ return filterable;
142
+ }
143
+
144
+ export function createFilterable<TPreset extends FieldFilterOperatorGroupName>(
145
+ preset: TPreset,
146
+ options: Omit<FieldFilterable, 'operators'> = {},
147
+ ): FieldFilterable {
148
+ return {
149
+ ...options,
150
+ operatorGroup: preset,
151
+ operators: resolveFilterOperators(preset),
152
+ };
153
+ }
154
+
155
+ export function createTypedFilterable<TMeta = unknown>(
156
+ groups: Array<{
157
+ types: string[];
158
+ operators: FieldFilterOperatorList<TMeta>;
159
+ }>,
160
+ resolveType: (meta: TMeta) => string,
161
+ ): FieldFilterable<TMeta> {
162
+ return {
163
+ operators: groups.flatMap(({ types, operators: operatorList }) =>
164
+ resolveFilterOperators(operatorList).map((operator) => ({
165
+ ...operator,
166
+ visible: (meta: TMeta) => {
167
+ const matches = types.includes(resolveType(meta));
168
+ if (typeof operator.visible === 'function') {
169
+ return operator.visible(meta) && matches;
170
+ }
171
+ return matches;
172
+ },
173
+ })),
174
+ ),
175
+ };
176
+ }
@@ -7,7 +7,18 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
- export const string = [
10
+ export type FieldFilterOperator<TMeta = unknown> = {
11
+ label: string;
12
+ value: string;
13
+ selected?: boolean;
14
+ noValue?: boolean;
15
+ schema?: Record<string, unknown>;
16
+ onlyFilterAction?: boolean;
17
+ visible?: (meta: TMeta) => boolean;
18
+ [key: string]: unknown;
19
+ };
20
+
21
+ export const string: FieldFilterOperator[] = [
11
22
  { label: '{{t("contains")}}', value: '$includes', selected: true },
12
23
  { label: '{{t("does not contain")}}', value: '$notIncludes' },
13
24
  { label: '{{t("is")}}', value: '$eq' },
@@ -16,7 +27,7 @@ export const string = [
16
27
  { label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
17
28
  ];
18
29
 
19
- export const array = [
30
+ export const array: FieldFilterOperator[] = [
20
31
  {
21
32
  label: '{{t("is")}}',
22
33
  value: '$match',
@@ -54,12 +65,12 @@ export const array = [
54
65
  { label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
55
66
  ];
56
67
 
57
- export const object = [
68
+ export const object: FieldFilterOperator[] = [
58
69
  { label: '{{t("is")}}', value: '$eq', selected: true },
59
70
  { label: '{{t("is not")}}', value: '$ne' },
60
71
  ];
61
72
 
62
- export const datetime = [
73
+ export const datetime: FieldFilterOperator[] = [
63
74
  {
64
75
  label: "{{ t('is') }}",
65
76
  value: '$dateOn',
@@ -70,7 +81,7 @@ export const datetime = [
70
81
  isRange: false,
71
82
  },
72
83
  },
73
- onlyFilterAction: true, //schema 仅在Filter.Action生效,筛选表单中不生效
84
+ onlyFilterAction: true,
74
85
  },
75
86
  {
76
87
  label: "{{ t('is not') }}",
@@ -141,7 +152,7 @@ export const datetime = [
141
152
  { label: "{{ t('is not empty') }}", value: '$notEmpty', noValue: true },
142
153
  ];
143
154
 
144
- export const number = [
155
+ export const number: FieldFilterOperator[] = [
145
156
  { label: '{{t("=")}}', value: '$eq', selected: true },
146
157
  { label: '{{t("≠")}}', value: '$ne' },
147
158
  { label: '{{t(">")}}', value: '$gt' },
@@ -152,14 +163,14 @@ export const number = [
152
163
  { label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
153
164
  ];
154
165
 
155
- export const id = [
166
+ export const id: FieldFilterOperator[] = [
156
167
  { label: '{{t("is")}}', value: '$eq', selected: true },
157
168
  { label: '{{t("is not")}}', value: '$ne' },
158
169
  { label: '{{t("exists")}}', value: '$exists', noValue: true },
159
170
  { label: '{{t("not exists")}}', value: '$notExists', noValue: true },
160
171
  ];
161
172
 
162
- export const enumType = [
173
+ export const enumType: FieldFilterOperator[] = [
163
174
  {
164
175
  label: '{{t("is")}}',
165
176
  value: '$eq',
@@ -191,14 +202,14 @@ export const enumType = [
191
202
  { label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
192
203
  ];
193
204
 
194
- export const time = [
205
+ export const time: FieldFilterOperator[] = [
195
206
  { label: '{{t("is")}}', value: '$eq', selected: true },
196
207
  { label: '{{t("is not")}}', value: '$neq' },
197
208
  { label: '{{t("is empty")}}', value: '$empty', noValue: true },
198
209
  { label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
199
210
  ];
200
211
 
201
- export const boolean = [
212
+ export const boolean: FieldFilterOperator[] = [
202
213
  {
203
214
  label: '{{t("Yes")}}',
204
215
  value: '$isTruly',
@@ -246,7 +257,7 @@ export const boolean = [
246
257
  { label: "{{ t('is not empty') }}", value: '$notEmpty', noValue: true },
247
258
  ];
248
259
 
249
- export const tableoid = [
260
+ export const tableoid: FieldFilterOperator[] = [
250
261
  {
251
262
  label: '{{t("is any of")}}',
252
263
  value: '$childIn',
@@ -265,7 +276,7 @@ export const tableoid = [
265
276
  },
266
277
  ];
267
278
 
268
- export const collection = [
279
+ export const collection: FieldFilterOperator[] = [
269
280
  {
270
281
  label: '{{t("is")}}',
271
282
  value: '$eq',
@@ -297,7 +308,7 @@ export const collection = [
297
308
  { label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
298
309
  ];
299
310
 
300
- export const bigField = [
311
+ export const bigField: FieldFilterOperator[] = [
301
312
  {
302
313
  label: '{{t("contains")}}',
303
314
  value: '$includes',
@@ -7,8 +7,7 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
- import { ISchema } from '@formily/react';
11
- import { defaultProps, operators } from './properties';
10
+ import { defaultProps } from './properties';
12
11
  import { CollectionFieldInterface } from '../../collection-field-interface/CollectionFieldInterface';
13
12
 
14
13
  export class CheckboxFieldInterface extends CollectionFieldInterface {
@@ -30,12 +29,6 @@ export class CheckboxFieldInterface extends CollectionFieldInterface {
30
29
  ...defaultProps,
31
30
  };
32
31
  filterable = {
33
- operators: operators.boolean,
32
+ operators: 'boolean',
34
33
  };
35
- schemaInitialize(schema: ISchema, { block }: { block: string }): void {
36
- if (['Table', 'Kanban'].includes(block)) {
37
- schema['x-component-props'] = schema['x-component-props'] || {};
38
- schema['x-component-props']['ellipsis'] = true;
39
- }
40
- }
41
34
  }
@@ -7,8 +7,7 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
- import { ISchema } from '@formily/react';
11
- import { dataSource, defaultProps, operators } from './properties';
10
+ import { dataSource, defaultProps } from './properties';
12
11
  import { CollectionFieldInterface } from '../../collection-field-interface/CollectionFieldInterface';
13
12
 
14
13
  export class CheckboxGroupFieldInterface extends CollectionFieldInterface {
@@ -33,13 +32,6 @@ export class CheckboxGroupFieldInterface extends CollectionFieldInterface {
33
32
  'uiSchema.enum': dataSource,
34
33
  };
35
34
  filterable = {
36
- operators: operators.array,
35
+ operators: 'array',
37
36
  };
38
-
39
- schemaInitialize(schema: ISchema, { block }: { block: string }): void {
40
- if (['Table', 'Kanban'].includes(block)) {
41
- schema['x-component-props'] = schema['x-component-props'] || {};
42
- schema['x-component-props']['ellipsis'] = true;
43
- }
44
- }
45
37
  }
@@ -7,8 +7,7 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
- import { ISchema } from '@formily/react';
11
- import { collectionDataSource, defaultProps, operators } from './properties';
10
+ import { collectionDataSource, defaultProps } from './properties';
12
11
  import { CollectionFieldInterface } from '../../collection-field-interface/CollectionFieldInterface';
13
12
 
14
13
  export class CollectionSelectFieldInterface extends CollectionFieldInterface {
@@ -36,18 +35,6 @@ export class CollectionSelectFieldInterface extends CollectionFieldInterface {
36
35
  };
37
36
 
38
37
  filterable = {
39
- operators: operators.collection,
38
+ operators: 'collection',
40
39
  };
41
-
42
- schemaInitialize(schema: ISchema, { block }): void {
43
- const props = (schema['x-component-props'] = schema['x-component-props'] || {});
44
- props.style = {
45
- ...(props.style || {}),
46
- width: '100%',
47
- };
48
-
49
- if (['Table', 'Kanban'].includes(block)) {
50
- props['ellipsis'] = true;
51
- }
52
- }
53
40
  }
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { CollectionFieldInterface } from '../../collection-field-interface/CollectionFieldInterface';
11
- import { defaultProps, operators } from './properties';
11
+ import { defaultProps } from './properties';
12
12
 
13
13
  export class ColorFieldInterface extends CollectionFieldInterface {
14
14
  name = 'color';
@@ -29,6 +29,6 @@ export class ColorFieldInterface extends CollectionFieldInterface {
29
29
  ...defaultProps,
30
30
  };
31
31
  filterable = {
32
- operators: operators.string,
32
+ operators: 'string',
33
33
  };
34
34
  }
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { CollectionFieldInterface } from '../../collection-field-interface/CollectionFieldInterface';
11
- import { dateTimeProps, defaultProps, operators } from './properties';
11
+ import { dateTimeProps, defaultProps } from './properties';
12
12
 
13
13
  export class CreatedAtFieldInterface extends CollectionFieldInterface {
14
14
  name = 'createdAt';
@@ -35,7 +35,7 @@ export class CreatedAtFieldInterface extends CollectionFieldInterface {
35
35
  ...dateTimeProps,
36
36
  };
37
37
  filterable = {
38
- operators: operators.datetime,
38
+ operators: 'datetime',
39
39
  };
40
40
  titleUsable = true;
41
41
  }
@@ -7,10 +7,8 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
- import { ISchema } from '@formily/react';
11
- import { cloneDeep } from 'lodash';
12
10
  import { CollectionFieldInterface } from '../../collection-field-interface/CollectionFieldInterface';
13
- import { defaultProps, recordPickerViewer } from './properties';
11
+ import { defaultProps } from './properties';
14
12
 
15
13
  export class CreatedByFieldInterface extends CollectionFieldInterface {
16
14
  name = 'createdBy';
@@ -67,14 +65,5 @@ export class CreatedByFieldInterface extends CollectionFieldInterface {
67
65
  // ],
68
66
  };
69
67
 
70
- schemaInitialize(schema: ISchema, { block }: { block: string }): void {
71
- schema['properties'] = {
72
- viewer: cloneDeep(recordPickerViewer),
73
- };
74
- if (['Table', 'Kanban'].includes(block)) {
75
- schema['x-component-props'] = schema['x-component-props'] || {};
76
- schema['x-component-props']['ellipsis'] = true;
77
- }
78
- }
79
68
  description = '{{t("Store the creation user of each record")}}';
80
69
  }
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { CollectionFieldInterface } from '../../collection-field-interface/CollectionFieldInterface';
11
- import { dateTimeProps, defaultProps, operators } from './properties';
11
+ import { dateTimeProps, defaultProps } from './properties';
12
12
 
13
13
  export class DateFieldInterface extends CollectionFieldInterface {
14
14
  name = 'date';
@@ -40,9 +40,15 @@ export class DateFieldInterface extends CollectionFieldInterface {
40
40
  'x-component': 'Checkbox',
41
41
  'x-visible': false,
42
42
  },
43
+ 'uiSchema.x-component-props.timeFormat': {
44
+ type: 'string',
45
+ 'x-decorator': 'FormItem',
46
+ 'x-component': 'Radio.Group',
47
+ 'x-visible': false,
48
+ },
43
49
  };
44
50
  filterable = {
45
- operators: operators.datetime,
51
+ operators: 'datetime',
46
52
  };
47
53
  titleUsable = true;
48
54
  }
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { CollectionFieldInterface } from '../../collection-field-interface/CollectionFieldInterface';
11
- import { dateTimeProps, defaultProps, operators } from './properties';
11
+ import { dateTimeProps, defaultProps } from './properties';
12
12
 
13
13
  export class DatetimeFieldInterface extends CollectionFieldInterface {
14
14
  name = 'datetime';
@@ -60,7 +60,7 @@ export class DatetimeFieldInterface extends CollectionFieldInterface {
60
60
  },
61
61
  };
62
62
  filterable = {
63
- operators: operators.datetime,
63
+ operators: 'datetime',
64
64
  };
65
65
  titleUsable = true;
66
66
  }