amis 1.9.0 → 1.9.1-beta.3

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 (269) hide show
  1. package/lib/RootRenderer.js +10 -2
  2. package/lib/RootRenderer.js.map +2 -2
  3. package/lib/Schema.d.ts +3 -2
  4. package/lib/Schema.js.map +1 -1
  5. package/lib/actions/Action.d.ts +1 -0
  6. package/lib/actions/Action.js +7 -6
  7. package/lib/actions/Action.js.map +2 -2
  8. package/lib/components/Button.d.ts +11 -10
  9. package/lib/components/Button.js +2 -2
  10. package/lib/components/Button.js.map +2 -2
  11. package/lib/components/CalendarMobile.d.ts +40 -40
  12. package/lib/components/Checkbox.js +1 -1
  13. package/lib/components/Checkbox.js.map +2 -2
  14. package/lib/components/ContextMenu.d.ts +4 -0
  15. package/lib/components/ContextMenu.js +23 -7
  16. package/lib/components/ContextMenu.js.map +2 -2
  17. package/lib/components/DatePicker.d.ts +40 -40
  18. package/lib/components/DateRangePicker.d.ts +40 -40
  19. package/lib/components/Form.d.ts +22 -0
  20. package/lib/components/Form.js +44 -0
  21. package/lib/components/Form.js.map +13 -0
  22. package/lib/components/FormField.d.ts +65 -0
  23. package/lib/components/FormField.js +48 -0
  24. package/lib/components/FormField.js.map +13 -0
  25. package/lib/components/InputBox.d.ts +10 -10
  26. package/lib/components/InputBox.js +4 -3
  27. package/lib/components/InputBox.js.map +2 -2
  28. package/lib/components/InputBoxWithSuggestion.d.ts +280 -0
  29. package/lib/components/InputBoxWithSuggestion.js +65 -0
  30. package/lib/components/InputBoxWithSuggestion.js.map +13 -0
  31. package/lib/components/ListGroup.d.ts +10 -10
  32. package/lib/components/PickerContainer.d.ts +4 -2
  33. package/lib/components/PickerContainer.js +28 -5
  34. package/lib/components/PickerContainer.js.map +2 -2
  35. package/lib/components/Radios.d.ts +10 -10
  36. package/lib/components/ResultBox.d.ts +40 -40
  37. package/lib/components/Select.d.ts +195 -202
  38. package/lib/components/Select.js +7 -3
  39. package/lib/components/Select.js.map +2 -2
  40. package/lib/components/Textarea.d.ts +568 -2
  41. package/lib/components/Textarea.js +129 -1
  42. package/lib/components/Textarea.js.map +2 -2
  43. package/lib/components/Toast.js +11 -9
  44. package/lib/components/Toast.js.map +2 -2
  45. package/lib/components/UserSelect.d.ts +500 -0
  46. package/lib/components/UserSelect.js +559 -0
  47. package/lib/components/UserSelect.js.map +13 -0
  48. package/lib/components/UserTabSelect.d.ts +320 -0
  49. package/lib/components/UserTabSelect.js +163 -0
  50. package/lib/components/UserTabSelect.js.map +13 -0
  51. package/lib/components/WithRemoteConfig.d.ts +7 -0
  52. package/lib/components/WithRemoteConfig.js +17 -11
  53. package/lib/components/WithRemoteConfig.js.map +2 -2
  54. package/lib/components/calendar/DaysView.d.ts +26 -1
  55. package/lib/components/calendar/DaysView.js +60 -19
  56. package/lib/components/calendar/DaysView.js.map +2 -2
  57. package/lib/components/calendar/TimeView.d.ts +1 -1
  58. package/lib/components/calendar/TimeView.js +10 -3
  59. package/lib/components/calendar/TimeView.js.map +2 -2
  60. package/lib/components/formula/Picker.js +4 -4
  61. package/lib/components/formula/Picker.js.map +2 -2
  62. package/lib/components/icons.d.ts +7 -1
  63. package/lib/components/icons.js +17 -1
  64. package/lib/components/icons.js.map +2 -2
  65. package/lib/components/index.d.ts +2 -1
  66. package/lib/components/index.js +3 -1
  67. package/lib/components/index.js.map +2 -2
  68. package/lib/components/json-schema/Array.d.ts +3 -0
  69. package/lib/components/json-schema/Array.js +125 -0
  70. package/lib/components/json-schema/Array.js.map +13 -0
  71. package/lib/components/json-schema/Item.d.ts +3 -0
  72. package/lib/components/json-schema/Item.js +34 -0
  73. package/lib/components/json-schema/Item.js.map +13 -0
  74. package/lib/components/json-schema/Object.d.ts +3 -0
  75. package/lib/components/json-schema/Object.js +178 -0
  76. package/lib/components/json-schema/Object.js.map +13 -0
  77. package/lib/components/json-schema/index.d.ts +279 -0
  78. package/lib/components/json-schema/index.js +16 -0
  79. package/lib/components/json-schema/index.js.map +13 -0
  80. package/lib/components/schema-editor/Array.js +2 -2
  81. package/lib/components/schema-editor/Array.js.map +2 -2
  82. package/lib/components/schema-editor/Common.d.ts +2 -0
  83. package/lib/components/schema-editor/Common.js +39 -3
  84. package/lib/components/schema-editor/Common.js.map +2 -2
  85. package/lib/components/schema-editor/Object.js +2 -2
  86. package/lib/components/schema-editor/Object.js.map +2 -2
  87. package/lib/components/schema-editor/index.d.ts +45 -41
  88. package/lib/components/schema-editor/index.js +5 -5
  89. package/lib/components/schema-editor/index.js.map +2 -2
  90. package/lib/helper.css +125 -124
  91. package/lib/helper.css.map +1 -1
  92. package/lib/hooks/use-validation-resolver.d.ts +1 -0
  93. package/lib/hooks/use-validation-resolver.js +49 -0
  94. package/lib/hooks/use-validation-resolver.js.map +13 -0
  95. package/lib/icons/department.js +17 -0
  96. package/lib/icons/menu.js +9 -0
  97. package/lib/icons/post.js +15 -0
  98. package/lib/icons/role.js +14 -0
  99. package/lib/icons/user-remove.js +12 -0
  100. package/lib/index.d.ts +2 -0
  101. package/lib/index.js +3 -1
  102. package/lib/index.js.map +2 -2
  103. package/lib/locale/de-DE.js +11 -1
  104. package/lib/locale/de-DE.js.map +2 -2
  105. package/lib/locale/en-US.js +12 -1
  106. package/lib/locale/en-US.js.map +2 -2
  107. package/lib/locale/zh-CN.js +14 -3
  108. package/lib/locale/zh-CN.js.map +2 -2
  109. package/lib/renderers/Action.js +25 -11
  110. package/lib/renderers/Action.js.map +2 -2
  111. package/lib/renderers/CRUD.js +5 -1
  112. package/lib/renderers/CRUD.js.map +2 -2
  113. package/lib/renderers/Dialog.js +9 -3
  114. package/lib/renderers/Dialog.js.map +2 -2
  115. package/lib/renderers/Drawer.js +5 -1
  116. package/lib/renderers/Drawer.js.map +2 -2
  117. package/lib/renderers/Form/InputDate.d.ts +2 -2
  118. package/lib/renderers/Form/InputDate.js.map +2 -2
  119. package/lib/renderers/Form/InputFile.js +5 -12
  120. package/lib/renderers/Form/InputFile.js.map +2 -2
  121. package/lib/renderers/Form/InputText.d.ts +1 -1
  122. package/lib/renderers/Form/InputText.js.map +1 -1
  123. package/lib/renderers/Form/JSONSchema.d.ts +23 -0
  124. package/lib/renderers/Form/JSONSchema.js +44 -0
  125. package/lib/renderers/Form/JSONSchema.js.map +13 -0
  126. package/lib/renderers/Form/JSONSchemaEditor.d.ts +2 -3
  127. package/lib/renderers/Form/JSONSchemaEditor.js +9 -24
  128. package/lib/renderers/Form/JSONSchemaEditor.js.map +2 -2
  129. package/lib/renderers/Form/Textarea.d.ts +1 -8
  130. package/lib/renderers/Form/Textarea.js +11 -75
  131. package/lib/renderers/Form/Textarea.js.map +2 -2
  132. package/lib/renderers/Form/UserSelect.d.ts +54 -0
  133. package/lib/renderers/Form/UserSelect.js +197 -0
  134. package/lib/renderers/Form/UserSelect.js.map +13 -0
  135. package/lib/renderers/Form/index.d.ts +1 -1
  136. package/lib/renderers/Form/index.js +88 -42
  137. package/lib/renderers/Form/index.js.map +2 -2
  138. package/lib/renderers/Link.d.ts +1 -1
  139. package/lib/renderers/Link.js +15 -29
  140. package/lib/renderers/Link.js.map +2 -2
  141. package/lib/renderers/Log.d.ts +28 -0
  142. package/lib/renderers/Log.js +110 -20
  143. package/lib/renderers/Log.js.map +2 -2
  144. package/lib/renderers/Page.js +5 -1
  145. package/lib/renderers/Page.js.map +2 -2
  146. package/lib/renderers/Service.js +5 -1
  147. package/lib/renderers/Service.js.map +2 -2
  148. package/lib/renderers/Wizard.js +37 -14
  149. package/lib/renderers/Wizard.js.map +2 -2
  150. package/lib/store/form.js +65 -45
  151. package/lib/store/form.js.map +2 -2
  152. package/lib/themes/ang-ie11.css +576 -24
  153. package/lib/themes/ang.css +553 -12
  154. package/lib/themes/ang.css.map +1 -1
  155. package/lib/themes/antd-ie11.css +576 -24
  156. package/lib/themes/antd.css +553 -12
  157. package/lib/themes/antd.css.map +1 -1
  158. package/lib/themes/cxd-ie11.css +576 -24
  159. package/lib/themes/cxd.css +553 -12
  160. package/lib/themes/cxd.css.map +1 -1
  161. package/lib/themes/dark-ie11.css +576 -24
  162. package/lib/themes/dark.css +553 -12
  163. package/lib/themes/dark.css.map +1 -1
  164. package/lib/themes/default-ie11.css +576 -24
  165. package/lib/themes/default.css +553 -12
  166. package/lib/themes/default.css.map +1 -1
  167. package/lib/utils/api.js +1 -1
  168. package/lib/utils/api.js.map +2 -2
  169. package/lib/utils/renderer-event.js.map +2 -2
  170. package/package.json +2 -1
  171. package/schema.json +542 -4
  172. package/scss/_properties.scss +20 -8
  173. package/scss/components/_input-box.scss +22 -1
  174. package/scss/components/_json-schema.scss +124 -0
  175. package/scss/components/_log.scss +37 -5
  176. package/scss/components/form/_date-range.scss +1 -0
  177. package/scss/components/form/_select.scss +9 -0
  178. package/scss/components/form/_transfer.scss +19 -3
  179. package/scss/components/form/_user-select.scss +422 -0
  180. package/scss/helper/background/_background-color.scss +125 -124
  181. package/scss/themes/_common.scss +2 -0
  182. package/sdk/ang-ie11.css +670 -24
  183. package/sdk/ang.css +647 -12
  184. package/sdk/antd-ie11.css +670 -24
  185. package/sdk/antd.css +647 -12
  186. package/sdk/barcode.js +51 -51
  187. package/sdk/charts.js +14 -14
  188. package/sdk/codemirror.js +7 -7
  189. package/sdk/color-picker.js +65 -65
  190. package/sdk/cropperjs.js +2 -2
  191. package/sdk/cxd-ie11.css +670 -24
  192. package/sdk/cxd.css +647 -12
  193. package/sdk/dark-ie11.css +670 -24
  194. package/sdk/dark.css +647 -12
  195. package/sdk/exceljs.js +1 -1
  196. package/sdk/helper.css +125 -124
  197. package/sdk/helper.css.map +1 -1
  198. package/sdk/locale/de-DE.js +11 -1
  199. package/sdk/markdown.js +69 -69
  200. package/sdk/papaparse.js +1 -1
  201. package/sdk/renderers/Form/CityDB.js +1 -1
  202. package/sdk/rest.js +16 -16
  203. package/sdk/rich-text.js +62 -62
  204. package/sdk/sdk-ie11.css +670 -24
  205. package/sdk/sdk.css +647 -12
  206. package/sdk/sdk.js +1651 -1637
  207. package/sdk/thirds/hls.js/hls.js +1 -1
  208. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  209. package/sdk/tinymce.js +57 -57
  210. package/src/RootRenderer.tsx +27 -15
  211. package/src/Schema.ts +5 -1
  212. package/src/actions/Action.ts +5 -4
  213. package/src/components/Button.tsx +3 -0
  214. package/src/components/Checkbox.tsx +2 -1
  215. package/src/components/ContextMenu.tsx +25 -7
  216. package/src/components/Form.tsx +70 -0
  217. package/src/components/FormField.tsx +127 -0
  218. package/src/components/InputBox.tsx +4 -1
  219. package/src/components/InputBoxWithSuggestion.tsx +113 -0
  220. package/src/components/PickerContainer.tsx +20 -5
  221. package/src/components/Select.tsx +18 -10
  222. package/src/components/Textarea.tsx +234 -2
  223. package/src/components/Toast.tsx +19 -18
  224. package/src/components/UserSelect.tsx +850 -0
  225. package/src/components/UserTabSelect.tsx +261 -0
  226. package/src/components/WithRemoteConfig.tsx +22 -7
  227. package/src/components/calendar/DaysView.tsx +117 -49
  228. package/src/components/calendar/TimeView.tsx +11 -6
  229. package/src/components/formula/Picker.tsx +2 -1
  230. package/src/components/icons.tsx +17 -1
  231. package/src/components/index.tsx +3 -1
  232. package/src/components/json-schema/Array.tsx +216 -0
  233. package/src/components/json-schema/Item.tsx +47 -0
  234. package/src/components/json-schema/Object.tsx +339 -0
  235. package/src/components/json-schema/index.tsx +44 -0
  236. package/src/components/schema-editor/Array.tsx +3 -1
  237. package/src/components/schema-editor/Common.tsx +61 -4
  238. package/src/components/schema-editor/Object.tsx +3 -1
  239. package/src/components/schema-editor/index.tsx +12 -5
  240. package/src/hooks/use-validation-resolver.ts +45 -0
  241. package/src/icons/department.svg +17 -0
  242. package/src/icons/menu.svg +2 -0
  243. package/src/icons/post.svg +15 -0
  244. package/src/icons/role.svg +14 -0
  245. package/src/icons/user-remove.svg +12 -0
  246. package/src/index.tsx +2 -0
  247. package/src/locale/de-DE.ts +11 -1
  248. package/src/locale/en-US.ts +12 -1
  249. package/src/locale/zh-CN.ts +14 -3
  250. package/src/renderers/Action.tsx +10 -9
  251. package/src/renderers/CRUD.tsx +5 -1
  252. package/src/renderers/Dialog.tsx +9 -3
  253. package/src/renderers/Drawer.tsx +5 -1
  254. package/src/renderers/Form/InputDate.tsx +9 -4
  255. package/src/renderers/Form/InputFile.tsx +5 -15
  256. package/src/renderers/Form/InputText.tsx +1 -1
  257. package/src/renderers/Form/JSONSchema.tsx +56 -0
  258. package/src/renderers/Form/JSONSchemaEditor.tsx +8 -27
  259. package/src/renderers/Form/Textarea.tsx +7 -117
  260. package/src/renderers/Form/UserSelect.tsx +263 -0
  261. package/src/renderers/Form/index.tsx +28 -18
  262. package/src/renderers/Link.tsx +5 -17
  263. package/src/renderers/Log.tsx +213 -19
  264. package/src/renderers/Page.tsx +6 -1
  265. package/src/renderers/Service.tsx +5 -1
  266. package/src/renderers/Wizard.tsx +24 -10
  267. package/src/store/form.ts +24 -17
  268. package/src/utils/api.ts +1 -1
  269. package/src/utils/renderer-event.ts +0 -2
@@ -275,6 +275,7 @@ export class FormulaPicker extends React.Component<
275
275
  variables,
276
276
  functions,
277
277
  children,
278
+ variableMode,
278
279
  ...rest
279
280
  } = this.props;
280
281
  const {isOpened, value, editorValue, isError} = this.state;
@@ -377,7 +378,7 @@ export class FormulaPicker extends React.Component<
377
378
  {...rest}
378
379
  variables={this.state.variables ?? variables}
379
380
  functions={this.state.functions ?? functions}
380
- variableMode={this.state.variableMode}
381
+ variableMode={this.state.variableMode ?? variableMode}
381
382
  value={editorValue}
382
383
  onChange={this.handleEditorChange}
383
384
  />
@@ -84,6 +84,11 @@ import FunctionIcon from '../icons/function.svg';
84
84
  import InputClearIcon from '../icons/input-clear.svg';
85
85
  import SliderHandleIcon from '../icons/slider-handle-icon.svg';
86
86
  import TrashIcon from '../icons/trash.svg';
87
+ import MenuIcon from '../icons/menu.svg';
88
+ import UserRemove from '../icons/user-remove.svg';
89
+ import Role from '../icons/role.svg';
90
+ import Department from '../icons/department.svg';
91
+ import Post from '../icons/post.svg';
87
92
  import DotIcon from '../icons/dot.svg';
88
93
 
89
94
  // 兼容原来的用法,后续不直接试用。
@@ -195,6 +200,11 @@ registerIcon('cloud-upload', CloudUploadIcon);
195
200
  registerIcon('image', ImageIcon);
196
201
  registerIcon('refresh', RefreshIcon);
197
202
  registerIcon('trash', TrashIcon);
203
+ registerIcon('menu', MenuIcon);
204
+ registerIcon('user-remove', UserRemove);
205
+ registerIcon('role', Role);
206
+ registerIcon('department', Department);
207
+ registerIcon('post', Post);
198
208
  registerIcon('dot', DotIcon);
199
209
 
200
210
  export function Icon({
@@ -227,11 +237,17 @@ export {
227
237
  MuteIcon,
228
238
  PlayIcon,
229
239
  PauseIcon,
240
+ ReloadIcon,
230
241
  LeftArrowIcon,
231
242
  RightArrowIcon,
232
243
  CheckIcon,
233
244
  PlusIcon,
234
245
  MinusIcon,
235
246
  PencilIcon,
236
- FunctionIcon
247
+ FunctionIcon,
248
+ MenuIcon,
249
+ UserRemove,
250
+ Role,
251
+ Department,
252
+ Post
237
253
  };
@@ -62,6 +62,7 @@ import Table from './table';
62
62
  import SchemaVariableListPicker from './schema-editor/SchemaVariableListPicker';
63
63
  import SchemaVariableList from './schema-editor/SchemaVariableList';
64
64
  import FormulaPicker from './formula/Picker';
65
+ import InputJSONSchema from './json-schema';
65
66
 
66
67
  export {
67
68
  NotFound,
@@ -127,5 +128,6 @@ export {
127
128
  Table,
128
129
  SchemaVariableListPicker,
129
130
  SchemaVariableList,
130
- FormulaPicker
131
+ FormulaPicker,
132
+ InputJSONSchema
131
133
  };
@@ -0,0 +1,216 @@
1
+ import React from 'react';
2
+ import {guid} from '../../utils/helper';
3
+ import Button from '../Button';
4
+ import {Icon} from '../icons';
5
+ import type {InputJSONSchemaItemProps} from './index';
6
+ import {InputJSONSchemaItem} from './Item';
7
+
8
+ type JSONSchemaArrayMember = {
9
+ key: string;
10
+ index: number;
11
+ schema?: any;
12
+ invalid?: boolean;
13
+ };
14
+ export function InputJSONSchemaArray(props: InputJSONSchemaItemProps) {
15
+ const {
16
+ classnames: cx,
17
+ value,
18
+ onChange,
19
+ disabled,
20
+ translate: __,
21
+ collapsable,
22
+ renderValue
23
+ } = props;
24
+ const buildMembers = React.useCallback((schema: any, value) => {
25
+ const members: Array<JSONSchemaArrayMember> = [];
26
+
27
+ let len = Array.isArray(value) ? value.length : 1;
28
+
29
+ if (typeof schema.minContains === 'number') {
30
+ len = Math.max(len, schema.minContains);
31
+ }
32
+
33
+ const maxContains =
34
+ typeof schema.maxContains === 'number' ? schema.maxContains : 0;
35
+
36
+ while (len--) {
37
+ members.push({
38
+ key: guid(),
39
+ index: members.length,
40
+ schema: schema.items,
41
+ invalid: maxContains ? maxContains < members.length : false
42
+ });
43
+ }
44
+
45
+ return members;
46
+ }, []);
47
+
48
+ const [members, setMembers] = React.useState<Array<JSONSchemaArrayMember>>(
49
+ buildMembers(props.schema, value)
50
+ );
51
+
52
+ const membersRef = React.useRef(members);
53
+ membersRef.current = members;
54
+
55
+ const [collapsed, setCollapsed] = React.useState<boolean>(
56
+ collapsable ? true : false
57
+ );
58
+ const toggleCollapsed = () => {
59
+ setCollapsed(!collapsed);
60
+ };
61
+
62
+ const onMemberChange = (member: JSONSchemaArrayMember, memberValue: any) => {
63
+ const newValue = Array.isArray(props.value) ? props.value.concat() : [];
64
+ newValue[member.index] = memberValue;
65
+ onChange?.(newValue);
66
+ };
67
+ const onMemberDelete = (member: JSONSchemaArrayMember) => {
68
+ const idx = members.indexOf(member);
69
+ if (!~idx) {
70
+ throw new Error('member object not found');
71
+ }
72
+
73
+ const m = members.concat();
74
+ m.splice(idx, 1);
75
+ setMembers(m);
76
+
77
+ const newValue = Array.isArray(props.value) ? props.value.concat() : [];
78
+ newValue.splice(member.index, 1);
79
+ onChange?.(newValue);
80
+ };
81
+
82
+ React.useEffect(() => {
83
+ setMembers(buildMembers(props.schema, props.value));
84
+ }, [JSON.stringify(props.schema)]);
85
+
86
+ React.useEffect(() => {
87
+ const value = props.value;
88
+ const schema = props.schema;
89
+ let len = Array.isArray(value) ? value.length : 1;
90
+
91
+ if (typeof schema.minContains === 'number') {
92
+ len = Math.max(len, schema.minContains);
93
+ }
94
+
95
+ if (typeof schema.maxContains === 'number') {
96
+ len = Math.min(schema.maxContains, len);
97
+ }
98
+ const m = membersRef.current!.concat();
99
+
100
+ if (m.length !== len) {
101
+ while (m.length !== len) {
102
+ if (m.length > len) {
103
+ m.pop();
104
+ } else {
105
+ m.push({
106
+ key: guid(),
107
+ index: m.length,
108
+ schema: schema.items
109
+ });
110
+ }
111
+ }
112
+ setMembers(m);
113
+ }
114
+ }, [JSON.stringify(props.value)]);
115
+
116
+ const handleAdd = React.useCallback(() => {
117
+ const m = members.concat();
118
+ m.push({
119
+ key: guid(),
120
+ index: members.length,
121
+ schema: props.schema.items,
122
+ invalid: false
123
+ });
124
+ setMembers(m);
125
+ }, [members]);
126
+
127
+ const maxContains =
128
+ typeof props.schema?.maxContains === 'number'
129
+ ? props.schema.maxContains
130
+ : 0;
131
+
132
+ const minContains =
133
+ typeof props.schema?.minContains === 'number'
134
+ ? props.schema.minContains
135
+ : 0;
136
+
137
+ // todo additionalProperties 还有其他格式
138
+ const allowAdd = !maxContains || maxContains > members.length;
139
+ const allowDelete = !minContains || minContains < members.length;
140
+
141
+ return (
142
+ <>
143
+ {collapsable ? (
144
+ <a
145
+ className={cx('JSONSchemaObject-caret', {
146
+ 'is-collapsed': collapsed
147
+ })}
148
+ onClick={toggleCollapsed}
149
+ >
150
+ <Icon icon="caret" className="icon" />
151
+ </a>
152
+ ) : null}
153
+
154
+ <div
155
+ className={cx('JSONSchemaObject', {
156
+ 'is-expanded': collapsable && !collapsed
157
+ })}
158
+ >
159
+ {collapsed ? (
160
+ renderValue ? (
161
+ <InputJSONSchemaItem
162
+ {...props}
163
+ value={value}
164
+ onChange={onChange}
165
+ schema={{
166
+ type: 'string'
167
+ }}
168
+ placeholder={props.schema?.description}
169
+ />
170
+ ) : null
171
+ ) : (
172
+ members.map(member => {
173
+ return (
174
+ <div key={member.key} className={cx('JSONSchemaMember')}>
175
+ <div className={cx('JSONSchemaMember-value')}>
176
+ <InputJSONSchemaItem
177
+ {...props}
178
+ value={value?.[member.index]}
179
+ onChange={onMemberChange.bind(null, member)}
180
+ schema={
181
+ member.schema || {
182
+ type: 'string'
183
+ }
184
+ }
185
+ collapsable
186
+ />
187
+ </div>
188
+ {allowDelete ? (
189
+ <Button
190
+ className={cx('SchemaEditor-btn')}
191
+ onClick={onMemberDelete.bind(null, member)}
192
+ iconOnly
193
+ disabled={disabled || !!value?.$ref}
194
+ >
195
+ <Icon icon="remove" className="icon" />
196
+ </Button>
197
+ ) : null}
198
+ </div>
199
+ );
200
+ })
201
+ )}
202
+
203
+ {!collapsed ? (
204
+ <Button
205
+ level="link"
206
+ onClick={handleAdd}
207
+ size="xs"
208
+ disabled={disabled || !allowAdd}
209
+ >
210
+ {__('JSONSchema.add_prop')}
211
+ </Button>
212
+ ) : null}
213
+ </div>
214
+ </>
215
+ );
216
+ }
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import InputBox from '../InputBox';
3
+ import NumberInput from '../NumberInput';
4
+ import Switch from '../Switch';
5
+ import {InputJSONSchemaArray} from './Array';
6
+ import type {InputJSONSchemaItemProps} from './index';
7
+ import {InputJSONSchemaObject} from './Object';
8
+
9
+ export function InputJSONSchemaItem(props: InputJSONSchemaItemProps) {
10
+ const schema = props.schema;
11
+ if (schema.type === 'object') {
12
+ return <InputJSONSchemaObject {...props} />;
13
+ } else if (schema.type === 'array') {
14
+ return <InputJSONSchemaArray {...props} />;
15
+ } else if (props.renderValue) {
16
+ return props.renderValue(props.value, props.onChange, schema, props);
17
+ } else if (schema.type == 'number') {
18
+ return (
19
+ <NumberInput
20
+ value={props.value}
21
+ onChange={props.onChange}
22
+ placeholder={props.placeholder}
23
+ />
24
+ );
25
+ } else if (schema.type == 'integer') {
26
+ return (
27
+ <NumberInput
28
+ value={props.value}
29
+ onChange={props.onChange}
30
+ precision={0}
31
+ placeholder={props.placeholder}
32
+ />
33
+ );
34
+ } else if (schema.type == 'boolean') {
35
+ return (
36
+ <Switch value={props.value} onChange={props.onChange} className="mt-2" />
37
+ );
38
+ }
39
+
40
+ return (
41
+ <InputBox
42
+ value={props.value}
43
+ onChange={props.onChange}
44
+ placeholder={props.placeholder}
45
+ />
46
+ );
47
+ }
@@ -0,0 +1,339 @@
1
+ import React from 'react';
2
+ import {guid} from '../../utils/helper';
3
+ import Button from '../Button';
4
+ import {Icon} from '../icons';
5
+ import InputBox from '../InputBox';
6
+ import InputBoxWithSuggestion from '../InputBoxWithSuggestion';
7
+ import Select from '../Select';
8
+ import type {InputJSONSchemaItemProps} from './index';
9
+ import {InputJSONSchemaItem} from './Item';
10
+
11
+ type JSONSchemaObjectMember = {
12
+ key: string;
13
+ name: string;
14
+ nameMutable?: boolean;
15
+ schema?: any;
16
+ invalid?: boolean;
17
+ required?: boolean;
18
+ };
19
+ export function InputJSONSchemaObject(props: InputJSONSchemaItemProps) {
20
+ const {
21
+ classnames: cx,
22
+ value,
23
+ onChange,
24
+ disabled,
25
+ translate: __,
26
+ renderKey,
27
+ collapsable,
28
+ renderValue
29
+ } = props;
30
+ const buildMembers = React.useCallback((schema: any, value: any) => {
31
+ const members: Array<JSONSchemaObjectMember> = [];
32
+ const required = Array.isArray(schema.required) ? schema.required : [];
33
+
34
+ Object.keys(schema.properties || {}).forEach(key => {
35
+ const child = schema.properties[key];
36
+ members.push({
37
+ key: guid(),
38
+ name: key,
39
+ nameMutable: !required.includes(key),
40
+ required: required.includes(key),
41
+ schema: child
42
+ });
43
+ });
44
+
45
+ const keys = Object.keys(value || {});
46
+ for (let key of keys) {
47
+ const exists = members.find(m => m.name === key);
48
+ if (!exists) {
49
+ members.push({
50
+ key: guid(),
51
+ name: key,
52
+ nameMutable: true,
53
+ schema: {
54
+ type: 'string'
55
+ }
56
+ });
57
+ }
58
+ }
59
+
60
+ if (!members.length) {
61
+ members.push({
62
+ key: guid(),
63
+ name: '',
64
+ nameMutable: true,
65
+ schema: {
66
+ type: 'string'
67
+ }
68
+ });
69
+ }
70
+
71
+ return members;
72
+ }, []);
73
+
74
+ const [members, setMembers] = React.useState<Array<JSONSchemaObjectMember>>(
75
+ buildMembers(props.schema, props.value)
76
+ );
77
+ const membersRef = React.useRef<Array<JSONSchemaObjectMember>>();
78
+ membersRef.current = members;
79
+
80
+ const [collapsed, setCollapsed] = React.useState<boolean>(
81
+ collapsable ? true : false
82
+ );
83
+ const toggleCollapsed = () => {
84
+ setCollapsed(!collapsed);
85
+ };
86
+
87
+ const onMemberChange = (member: JSONSchemaObjectMember, memberValue: any) => {
88
+ const newValue = {
89
+ ...props.value,
90
+ [member.name]: memberValue
91
+ };
92
+ onChange?.(newValue);
93
+ };
94
+ const onMemberKeyChange = (
95
+ member: JSONSchemaObjectMember,
96
+ memberValue: any
97
+ ) => {
98
+ const idx = members.indexOf(member);
99
+ if (!~idx) {
100
+ throw new Error('member object not found');
101
+ }
102
+
103
+ const newValue = {
104
+ ...props.value
105
+ };
106
+ const m = members.concat();
107
+ m.splice(idx, 1, {
108
+ ...member,
109
+ schema: props.schema?.properties?.[memberValue] || {
110
+ type: 'string'
111
+ },
112
+ name: memberValue,
113
+ invalid:
114
+ !memberValue ||
115
+ members.some((a, b) => a.name === memberValue && b !== idx)
116
+ });
117
+
118
+ setMembers(m);
119
+
120
+ newValue[memberValue] = newValue[member.name];
121
+ delete newValue[member.name];
122
+ onChange?.(newValue);
123
+ };
124
+ const onMemberDelete = (member: JSONSchemaObjectMember) => {
125
+ const idx = members.indexOf(member);
126
+ if (!~idx) {
127
+ throw new Error('member object not found');
128
+ }
129
+
130
+ const m = members.concat();
131
+ m.splice(idx, 1);
132
+ setMembers(m);
133
+
134
+ const newValue = {
135
+ ...props.value
136
+ };
137
+ delete newValue[member.name];
138
+ onChange?.(newValue);
139
+ };
140
+
141
+ React.useEffect(() => {
142
+ setMembers(buildMembers(props.schema, props.value));
143
+ }, [JSON.stringify(props.schema)]);
144
+
145
+ React.useEffect(() => {
146
+ const value = props.value;
147
+ const m = membersRef.current!.concat();
148
+ const keys = Object.keys(value || {});
149
+ for (let key of keys) {
150
+ const exists = m.find(m => m.name === key);
151
+ if (!exists) {
152
+ m.push({
153
+ key: guid(),
154
+ name: key,
155
+ nameMutable: true,
156
+ schema: {
157
+ type: 'string'
158
+ }
159
+ });
160
+ }
161
+ }
162
+ if (m.length !== membersRef.current!.length) {
163
+ setMembers(m);
164
+ }
165
+ }, [JSON.stringify(props.value)]);
166
+
167
+ const handleAdd = React.useCallback(() => {
168
+ const m = members.concat();
169
+ m.push({
170
+ key: guid(),
171
+ name: '',
172
+ invalid: true,
173
+ nameMutable: true
174
+ });
175
+ setMembers(m);
176
+ }, [members]);
177
+
178
+ const options: Array<any> = [];
179
+ const properties: any = props.schema?.properties || {};
180
+ Object.keys(properties).forEach(key => {
181
+ options.push({
182
+ label: properties[key]?.title || key,
183
+ value: key
184
+ });
185
+ });
186
+ // todo additionalProperties 还有其他格式
187
+ const allowAdd = !(
188
+ props.schema.additionalProperties === false &&
189
+ options.every(o => members.find(m => m.name === o.value))
190
+ );
191
+ const allowInput = props.schema.additionalProperties !== false;
192
+
193
+ return (
194
+ <>
195
+ {collapsable ? (
196
+ <a
197
+ className={cx('JSONSchemaObject-caret', {
198
+ 'is-collapsed': collapsed
199
+ })}
200
+ onClick={toggleCollapsed}
201
+ >
202
+ <Icon icon="caret" className="icon" />
203
+ </a>
204
+ ) : null}
205
+
206
+ <div
207
+ className={cx('JSONSchemaObject', {
208
+ 'is-expanded': collapsable && !collapsed
209
+ })}
210
+ >
211
+ {collapsed ? (
212
+ renderValue ? (
213
+ <InputJSONSchemaItem
214
+ {...props}
215
+ value={value}
216
+ onChange={onChange}
217
+ schema={{
218
+ type: 'string'
219
+ }}
220
+ placeholder={props.schema?.description}
221
+ />
222
+ ) : null
223
+ ) : (
224
+ members.map(member => {
225
+ const filtedOptions = options.filter(
226
+ o => !members.find(m => m !== member && m.name === o.value)
227
+ );
228
+
229
+ return (
230
+ <div key={member.key} className={cx('JSONSchemaMember')}>
231
+ <div className={cx('JSONSchemaMember-key')}>
232
+ {member.nameMutable ? (
233
+ <>
234
+ {renderKey ? (
235
+ renderKey(
236
+ member.name,
237
+ onMemberKeyChange.bind(null, member),
238
+ member.schema,
239
+ props
240
+ )
241
+ ) : filtedOptions.length ? (
242
+ allowInput ? (
243
+ <InputBoxWithSuggestion
244
+ value={member.name}
245
+ hasError={member.invalid}
246
+ onChange={onMemberKeyChange.bind(null, member)}
247
+ clearable={false}
248
+ placeholder={__('JSONSchema.key')}
249
+ options={filtedOptions}
250
+ />
251
+ ) : (
252
+ <Select
253
+ simpleValue
254
+ block
255
+ value={member.name}
256
+ hasError={member.invalid}
257
+ onChange={onMemberKeyChange.bind(null, member)}
258
+ clearable={false}
259
+ placeholder={__('JSONSchema.key')}
260
+ options={filtedOptions}
261
+ />
262
+ )
263
+ ) : (
264
+ <InputBox
265
+ value={member.name}
266
+ hasError={member.invalid}
267
+ onChange={onMemberKeyChange.bind(null, member)}
268
+ clearable={false}
269
+ placeholder={__('JSONSchema.key')}
270
+ />
271
+ )}
272
+ </>
273
+ ) : (
274
+ <span>
275
+ {member.required ? (
276
+ <span className={cx(`Form-star`)}>*</span>
277
+ ) : null}
278
+ {member.schema?.title || member.name}
279
+
280
+ {/* {member.schema?.description ? (
281
+ <TooltipWrapper
282
+ tooltipTheme="dark"
283
+ tooltip={member.schema.description}
284
+ trigger="click"
285
+ rootClose
286
+ >
287
+ <div className={cx(`Remark`, `Remark--warning`)}>
288
+ <span className={cx('Remark-icon icon')}>
289
+ <Icon icon="question-mark" />
290
+ </span>
291
+ </div>
292
+ </TooltipWrapper>
293
+ ) : null} */}
294
+ </span>
295
+ )}
296
+ </div>
297
+ <div className={cx('JSONSchemaMember-value')}>
298
+ <InputJSONSchemaItem
299
+ {...props}
300
+ value={value?.[member.name]}
301
+ onChange={onMemberChange.bind(null, member)}
302
+ schema={
303
+ member.schema || {
304
+ type: 'string'
305
+ }
306
+ }
307
+ placeholder={member.schema?.description}
308
+ collapsable
309
+ />
310
+ </div>
311
+ {!member.required ? (
312
+ <Button
313
+ className={cx('SchemaEditor-btn')}
314
+ onClick={onMemberDelete.bind(null, member)}
315
+ iconOnly
316
+ disabled={disabled || !!value?.$ref}
317
+ >
318
+ <Icon icon="remove" className="icon" />
319
+ </Button>
320
+ ) : null}
321
+ </div>
322
+ );
323
+ })
324
+ )}
325
+
326
+ {allowAdd && !collapsed ? (
327
+ <Button
328
+ level="link"
329
+ onClick={handleAdd}
330
+ size="xs"
331
+ disabled={disabled}
332
+ >
333
+ {__('JSONSchema.add_prop')}
334
+ </Button>
335
+ ) : null}
336
+ </div>
337
+ </>
338
+ );
339
+ }