amis 1.3.5-beta.3 → 1.4.1

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 (280) hide show
  1. package/lib/components/Badge.d.ts +15 -2
  2. package/lib/components/Badge.js +47 -4
  3. package/lib/components/Badge.js.map +2 -2
  4. package/lib/components/Button.d.ts +24 -22
  5. package/lib/components/Button.js +13 -7
  6. package/lib/components/Button.js.map +2 -2
  7. package/lib/components/Checkbox.d.ts +1 -1
  8. package/lib/components/Checkbox.js +1 -1
  9. package/lib/components/Checkbox.js.map +2 -2
  10. package/lib/components/Drawer.js +1 -1
  11. package/lib/components/Drawer.js.map +2 -2
  12. package/lib/components/Modal.js +1 -1
  13. package/lib/components/Modal.js.map +2 -2
  14. package/lib/components/RichText.d.ts +6 -4
  15. package/lib/components/RichText.js +241 -27
  16. package/lib/components/RichText.js.map +2 -2
  17. package/lib/components/Select.d.ts +7 -0
  18. package/lib/components/Select.js.map +2 -2
  19. package/lib/components/Steps.d.ts +3 -3
  20. package/lib/components/Steps.js.map +1 -1
  21. package/lib/components/WithRemoteConfig.d.ts +8 -0
  22. package/lib/components/WithRemoteConfig.js +28 -2
  23. package/lib/components/WithRemoteConfig.js.map +2 -2
  24. package/lib/components/calendar/DaysView.js +2 -2
  25. package/lib/components/calendar/DaysView.js.map +2 -2
  26. package/lib/components/condition-builder/Field.js +0 -1
  27. package/lib/components/condition-builder/Field.js.map +2 -2
  28. package/lib/components/condition-builder/Value.js +2 -1
  29. package/lib/components/condition-builder/Value.js.map +2 -2
  30. package/lib/components/condition-builder/types.d.ts +5 -0
  31. package/lib/components/condition-builder/types.js.map +1 -1
  32. package/lib/components/icons.js +2 -0
  33. package/lib/components/icons.js.map +2 -2
  34. package/lib/factory.d.ts +5 -1
  35. package/lib/factory.js +9 -4
  36. package/lib/factory.js.map +2 -2
  37. package/lib/helper.css.map +1 -1
  38. package/lib/icons/loading-outline.js +7 -0
  39. package/lib/index.d.ts +1 -0
  40. package/lib/index.js +2 -1
  41. package/lib/index.js.map +2 -2
  42. package/lib/locale/de-DE.js +1 -0
  43. package/lib/locale/de-DE.js.map +2 -2
  44. package/lib/locale/en-US.js +2 -1
  45. package/lib/locale/en-US.js.map +2 -2
  46. package/lib/locale/zh-CN.js +2 -1
  47. package/lib/locale/zh-CN.js.map +2 -2
  48. package/lib/renderers/Action.d.ts +15 -1
  49. package/lib/renderers/Action.js +13 -6
  50. package/lib/renderers/Action.js.map +2 -2
  51. package/lib/renderers/CRUD.d.ts +2 -2
  52. package/lib/renderers/CRUD.js +11 -20
  53. package/lib/renderers/CRUD.js.map +2 -2
  54. package/lib/renderers/Card.js +11 -11
  55. package/lib/renderers/Card.js.map +2 -2
  56. package/lib/renderers/Collapse.d.ts +1 -1
  57. package/lib/renderers/Collapse.js +5 -1
  58. package/lib/renderers/Collapse.js.map +2 -2
  59. package/lib/renderers/Dialog.d.ts +0 -252
  60. package/lib/renderers/Dialog.js +3 -2
  61. package/lib/renderers/Dialog.js.map +2 -2
  62. package/lib/renderers/Drawer.js +2 -1
  63. package/lib/renderers/Drawer.js.map +2 -2
  64. package/lib/renderers/DropDownButton.d.ts +8 -0
  65. package/lib/renderers/DropDownButton.js +6 -4
  66. package/lib/renderers/DropDownButton.js.map +2 -2
  67. package/lib/renderers/Form/ButtonGroupSelect.js +3 -0
  68. package/lib/renderers/Form/ButtonGroupSelect.js.map +2 -2
  69. package/lib/renderers/Form/Combo.d.ts +2 -0
  70. package/lib/renderers/Form/Combo.js +16 -1
  71. package/lib/renderers/Form/Combo.js.map +2 -2
  72. package/lib/renderers/Form/DiffEditor.d.ts +0 -2
  73. package/lib/renderers/Form/Editor.d.ts +0 -2
  74. package/lib/renderers/Form/Editor.js +1 -1
  75. package/lib/renderers/Form/Editor.js.map +2 -2
  76. package/lib/renderers/Form/InputExcel.d.ts +5 -0
  77. package/lib/renderers/Form/InputExcel.js +24 -3
  78. package/lib/renderers/Form/InputExcel.js.map +2 -2
  79. package/lib/renderers/Form/InputImage.d.ts +8 -0
  80. package/lib/renderers/Form/InputImage.js +2 -1
  81. package/lib/renderers/Form/InputImage.js.map +2 -2
  82. package/lib/renderers/Form/InputNumber.d.ts +19 -5
  83. package/lib/renderers/Form/InputNumber.js +69 -7
  84. package/lib/renderers/Form/InputNumber.js.map +2 -2
  85. package/lib/renderers/Form/InputRange.js +7 -2
  86. package/lib/renderers/Form/InputRange.js.map +2 -2
  87. package/lib/renderers/Form/InputTable.d.ts +23 -5
  88. package/lib/renderers/Form/InputTable.js +32 -3
  89. package/lib/renderers/Form/InputTable.js.map +2 -2
  90. package/lib/renderers/Form/Options.js +3 -1
  91. package/lib/renderers/Form/Options.js.map +2 -2
  92. package/lib/renderers/Form/index.js +0 -10
  93. package/lib/renderers/Form/index.js.map +2 -2
  94. package/lib/renderers/Form/wrapControl.js +3 -3
  95. package/lib/renderers/Form/wrapControl.js.map +2 -2
  96. package/lib/renderers/Json.js +5 -1
  97. package/lib/renderers/Json.js.map +2 -2
  98. package/lib/renderers/List.d.ts +5 -0
  99. package/lib/renderers/List.js +20 -14
  100. package/lib/renderers/List.js.map +2 -2
  101. package/lib/renderers/Nav.d.ts +52 -22
  102. package/lib/renderers/Nav.js +100 -15
  103. package/lib/renderers/Nav.js.map +2 -2
  104. package/lib/renderers/Page.d.ts +6 -0
  105. package/lib/renderers/Page.js +11 -3
  106. package/lib/renderers/Page.js.map +2 -2
  107. package/lib/renderers/Service.d.ts +10 -1
  108. package/lib/renderers/Service.js +85 -3
  109. package/lib/renderers/Service.js.map +2 -2
  110. package/lib/renderers/Steps.d.ts +4 -4
  111. package/lib/renderers/Steps.js +5 -2
  112. package/lib/renderers/Steps.js.map +2 -2
  113. package/lib/renderers/Table/TableBody.d.ts +5 -3
  114. package/lib/renderers/Table/TableBody.js +17 -11
  115. package/lib/renderers/Table/TableBody.js.map +2 -2
  116. package/lib/renderers/Table/TableCell.js +6 -2
  117. package/lib/renderers/Table/TableCell.js.map +2 -2
  118. package/lib/renderers/Table/TableContent.d.ts +3 -1
  119. package/lib/renderers/Table/TableContent.js +6 -2
  120. package/lib/renderers/Table/TableContent.js.map +2 -2
  121. package/lib/renderers/Table/TableRow.d.ts +1 -1
  122. package/lib/renderers/Table/TableRow.js +14 -13
  123. package/lib/renderers/Table/TableRow.js.map +2 -2
  124. package/lib/renderers/Table/index.d.ts +28 -3
  125. package/lib/renderers/Table/index.js +92 -52
  126. package/lib/renderers/Table/index.js.map +2 -2
  127. package/lib/schemaExtend.d.ts +1 -0
  128. package/lib/schemaExtend.js +59 -0
  129. package/lib/schemaExtend.js.map +13 -0
  130. package/lib/store/app.d.ts +0 -1
  131. package/lib/store/combo.d.ts +0 -2
  132. package/lib/store/crud.d.ts +3 -3
  133. package/lib/store/crud.js +41 -36
  134. package/lib/store/crud.js.map +2 -2
  135. package/lib/store/form.d.ts +0 -1
  136. package/lib/store/formItem.js +10 -6
  137. package/lib/store/formItem.js.map +2 -2
  138. package/lib/store/modal.d.ts +1 -1
  139. package/lib/store/modal.js +4 -0
  140. package/lib/store/modal.js.map +2 -2
  141. package/lib/store/root.d.ts +0 -1
  142. package/lib/store/service.d.ts +0 -1
  143. package/lib/store/service.js +0 -13
  144. package/lib/store/service.js.map +2 -2
  145. package/lib/store/table.d.ts +1 -2
  146. package/lib/store/table.js +44 -3
  147. package/lib/store/table.js.map +2 -2
  148. package/lib/themes/ang-ie11.css +624 -71
  149. package/lib/themes/ang.css +624 -71
  150. package/lib/themes/ang.css.map +1 -1
  151. package/lib/themes/antd-ie11.css +624 -71
  152. package/lib/themes/antd.css +624 -71
  153. package/lib/themes/antd.css.map +1 -1
  154. package/lib/themes/cxd-ie11.css +732 -191
  155. package/lib/themes/cxd.css +732 -191
  156. package/lib/themes/cxd.css.map +1 -1
  157. package/lib/themes/dark-ie11.css +624 -71
  158. package/lib/themes/dark.css +624 -71
  159. package/lib/themes/dark.css.map +1 -1
  160. package/lib/themes/default.css +732 -191
  161. package/lib/themes/default.css.map +1 -1
  162. package/lib/utils/api.js +12 -0
  163. package/lib/utils/api.js.map +2 -2
  164. package/lib/utils/attachmentAdpator.d.ts +7 -0
  165. package/lib/utils/attachmentAdpator.js +82 -0
  166. package/lib/utils/attachmentAdpator.js.map +13 -0
  167. package/lib/utils/helper.d.ts +2 -0
  168. package/lib/utils/helper.js +14 -1
  169. package/lib/utils/helper.js.map +2 -2
  170. package/lib/utils/resize-sensor.js +6 -0
  171. package/lib/utils/resize-sensor.js.map +2 -2
  172. package/lib/utils/tpl-builtin.d.ts +1 -0
  173. package/lib/utils/tpl-builtin.js +24 -8
  174. package/lib/utils/tpl-builtin.js.map +2 -2
  175. package/lib/utils/validations.js +62 -5
  176. package/lib/utils/validations.js.map +2 -2
  177. package/package.json +1 -2
  178. package/schema.json +561 -171
  179. package/scss/_mixins.scss +29 -0
  180. package/scss/_properties.scss +29 -11
  181. package/scss/components/_badge.scss +67 -2
  182. package/scss/components/_button.scss +35 -3
  183. package/scss/components/_image-gallery.scss +1 -1
  184. package/scss/components/_list.scss +8 -0
  185. package/scss/components/_markdown.scss +266 -0
  186. package/scss/components/_nav.scss +109 -35
  187. package/scss/components/_spinner.scss +6 -2
  188. package/scss/components/_table.scss +4 -0
  189. package/scss/components/form/_form.scss +3 -17
  190. package/scss/components/form/_group.scss +4 -0
  191. package/scss/components/form/_number.scss +12 -1
  192. package/scss/themes/_common.scss +1 -0
  193. package/scss/themes/_cxd-variables.scss +20 -20
  194. package/sdk/ang-ie11.css +769 -76
  195. package/sdk/ang.css +785 -76
  196. package/sdk/antd-ie11.css +759 -68
  197. package/sdk/antd.css +785 -76
  198. package/sdk/charts.js +13 -13
  199. package/sdk/color-picker.js +67 -67
  200. package/sdk/cropperjs.js +2 -2
  201. package/sdk/cxd-ie11.css +1243 -552
  202. package/sdk/cxd.css +893 -196
  203. package/sdk/dark-ie11.css +769 -76
  204. package/sdk/dark.css +785 -76
  205. package/sdk/exceljs.js +1 -1
  206. package/sdk/helper.css.map +1 -1
  207. package/sdk/locale/de-DE.js +1 -0
  208. package/sdk/markdown.js +69 -69
  209. package/sdk/papaparse.js +1 -1
  210. package/sdk/renderers/Form/CityDB.js +1 -1
  211. package/sdk/rest.js +22 -24
  212. package/sdk/rich-text.js +62 -64
  213. package/sdk/sdk-ie11.css +1243 -552
  214. package/sdk/sdk.css +893 -196
  215. package/sdk/sdk.js +1123 -1111
  216. package/sdk/thirds/hls.js/hls.js +1 -1
  217. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  218. package/sdk/tinymce.js +57 -57
  219. package/sdk.zip +0 -0
  220. package/src/components/Badge.tsx +111 -20
  221. package/src/components/Button.tsx +23 -7
  222. package/src/components/Checkbox.tsx +5 -2
  223. package/src/components/Drawer.tsx +3 -2
  224. package/src/components/Modal.tsx +3 -2
  225. package/src/components/RichText.tsx +280 -24
  226. package/src/components/Select.tsx +1 -0
  227. package/src/components/Steps.tsx +3 -3
  228. package/src/components/WithRemoteConfig.tsx +37 -2
  229. package/src/components/calendar/DaysView.tsx +2 -2
  230. package/src/components/condition-builder/Field.tsx +1 -2
  231. package/src/components/condition-builder/Value.tsx +3 -0
  232. package/src/components/condition-builder/types.ts +6 -0
  233. package/src/components/icons.tsx +2 -0
  234. package/src/factory.tsx +13 -3
  235. package/src/icons/loading-outline.svg +4 -0
  236. package/src/index.tsx +2 -0
  237. package/src/locale/de-DE.ts +1 -0
  238. package/src/locale/en-US.ts +2 -1
  239. package/src/locale/zh-CN.ts +2 -1
  240. package/src/renderers/Action.tsx +84 -14
  241. package/src/renderers/CRUD.tsx +13 -33
  242. package/src/renderers/Card.tsx +21 -15
  243. package/src/renderers/Collapse.tsx +5 -1
  244. package/src/renderers/Dialog.tsx +3 -2
  245. package/src/renderers/Drawer.tsx +2 -1
  246. package/src/renderers/DropDownButton.tsx +21 -4
  247. package/src/renderers/Form/ButtonGroupSelect.tsx +3 -0
  248. package/src/renderers/Form/Combo.tsx +7 -0
  249. package/src/renderers/Form/Editor.tsx +19 -20
  250. package/src/renderers/Form/InputExcel.tsx +28 -3
  251. package/src/renderers/Form/InputImage.tsx +23 -8
  252. package/src/renderers/Form/InputNumber.tsx +113 -18
  253. package/src/renderers/Form/InputRange.tsx +5 -2
  254. package/src/renderers/Form/InputTable.tsx +88 -9
  255. package/src/renderers/Form/Options.tsx +3 -1
  256. package/src/renderers/Form/index.tsx +0 -15
  257. package/src/renderers/Form/wrapControl.tsx +2 -2
  258. package/src/renderers/Json.tsx +10 -1
  259. package/src/renderers/List.tsx +32 -19
  260. package/src/renderers/Nav.tsx +165 -36
  261. package/src/renderers/Page.tsx +20 -1
  262. package/src/renderers/Service.tsx +101 -3
  263. package/src/renderers/Steps.tsx +12 -9
  264. package/src/renderers/Table/TableBody.tsx +29 -10
  265. package/src/renderers/Table/TableCell.tsx +15 -1
  266. package/src/renderers/Table/TableContent.tsx +7 -1
  267. package/src/renderers/Table/TableRow.tsx +18 -17
  268. package/src/renderers/Table/index.tsx +112 -27
  269. package/src/schemaExtend.ts +66 -0
  270. package/src/store/crud.ts +34 -38
  271. package/src/store/formItem.ts +10 -6
  272. package/src/store/modal.ts +4 -0
  273. package/src/store/service.ts +0 -19
  274. package/src/store/table.ts +48 -0
  275. package/src/utils/api.ts +11 -0
  276. package/src/utils/attachmentAdpator.ts +90 -0
  277. package/src/utils/helper.ts +16 -0
  278. package/src/utils/resize-sensor.ts +7 -0
  279. package/src/utils/tpl-builtin.ts +36 -17
  280. package/src/utils/validations.ts +80 -12
@@ -14,12 +14,12 @@ export type StepSchema = {
14
14
  /**
15
15
  * 标题
16
16
  */
17
- title: string;
17
+ title?: string | JSX.Element;
18
18
 
19
19
  /**
20
20
  * 子标题
21
21
  */
22
- subTitle?: string;
22
+ subTitle?: string | JSX.Element;
23
23
 
24
24
  /**
25
25
  * 图标
@@ -31,7 +31,7 @@ export type StepSchema = {
31
31
  /**
32
32
  * 描述
33
33
  */
34
- description?: string;
34
+ description?: string | JSX.Element;
35
35
 
36
36
  status?: StepStatus;
37
37
  } & Omit<BaseSchema, 'type'>;
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import React from 'react';
6
6
  import hoistNonReactStatic from 'hoist-non-react-statics';
7
+ import debounce from 'lodash/debounce';
7
8
  import {Api, Payload} from '../types';
8
9
  import {SchemaApi, SchemaTokenizeableString} from '../Schema';
9
10
  import {withStore} from './WithStore';
@@ -97,6 +98,7 @@ export interface OutterProps {
97
98
  env?: RendererEnv;
98
99
  data: any;
99
100
  source?: SchemaApi | SchemaTokenizeableString;
101
+ autoComplete?: SchemaApi | SchemaTokenizeableString;
100
102
  deferApi?: SchemaApi;
101
103
  remoteConfigRef?: (
102
104
  instance:
@@ -182,10 +184,16 @@ export function withRemoteConfig<P = any>(
182
184
  static displayName = `WithRemoteConfig(${
183
185
  ComposedComponent.displayName || ComposedComponent.name
184
186
  })`;
185
- static ComposedComponent = ComposedComponent as React.ComponentType<T>;
187
+ static ComposedComponent =
188
+ ComposedComponent as React.ComponentType<T>;
186
189
  static contextType = EnvContext;
187
190
  toDispose: Array<() => void> = [];
188
191
 
192
+ loadOptions = debounce(this.loadAutoComplete.bind(this), 250, {
193
+ trailing: true,
194
+ leading: false
195
+ });
196
+
189
197
  constructor(
190
198
  props: FinalOutterProps & {
191
199
  store: IStore;
@@ -250,6 +258,7 @@ export function withRemoteConfig<P = any>(
250
258
  this.toDispose = [];
251
259
 
252
260
  this.props.remoteConfigRef?.(undefined);
261
+ this.loadOptions.cancel();
253
262
  }
254
263
 
255
264
  async loadConfig(ctx = this.props.data) {
@@ -261,6 +270,28 @@ export function withRemoteConfig<P = any>(
261
270
  }
262
271
  }
263
272
 
273
+ loadAutoComplete(input: string) {
274
+ const env: RendererEnv = this.props.env || this.context;
275
+ const {autoComplete, data, store} = this.props;
276
+
277
+ if (!env || !env.fetcher) {
278
+ throw new Error('fetcher is required');
279
+ }
280
+
281
+ const ctx = createObject(data, {
282
+ term: input,
283
+ value: input
284
+ });
285
+
286
+ if (!isEffectiveApi(autoComplete, ctx)) {
287
+ return Promise.resolve({
288
+ options: []
289
+ });
290
+ }
291
+
292
+ return store.load(env, autoComplete, ctx, config);
293
+ }
294
+
264
295
  setConfig(value: any, ctx?: any) {
265
296
  const {store} = this.props;
266
297
  store.setConfig(value, config, ctx);
@@ -321,13 +352,14 @@ export function withRemoteConfig<P = any>(
321
352
 
322
353
  render() {
323
354
  const store = this.props.store;
355
+ const env: RendererEnv = this.props.env || this.context;
324
356
  const injectedProps: RemoteOptionsProps<P> = {
325
357
  config: store.config,
326
358
  loading: store.fetching,
327
359
  deferLoad: this.deferLoadConfig,
328
360
  updateConfig: this.setConfig
329
361
  };
330
- const {remoteConfigRef, ...rest} = this.props;
362
+ const {remoteConfigRef, autoComplete, ...rest} = this.props;
331
363
 
332
364
  return (
333
365
  <ComposedComponent
@@ -335,6 +367,9 @@ export function withRemoteConfig<P = any>(
335
367
  T,
336
368
  React.ComponentProps<T>
337
369
  >)}
370
+ {...(env && isEffectiveApi(autoComplete) && this.loadOptions
371
+ ? {loadOptions: this.loadOptions}
372
+ : {})}
338
373
  {...injectedProps}
339
374
  />
340
375
  );
@@ -100,8 +100,8 @@ export class CustomDaysView extends DaysView {
100
100
  confirm = () => {
101
101
  let date = (this.props.selectedDate || this.props.viewDate).clone();
102
102
 
103
- // 如果 minDate 是可用的,且比当前日期早,则用 minDate
104
- if (this.props.minDate?.isValid() && this.props.minDate?.isBefore(date)) {
103
+ // 如果 minDate 是可用的,且比当前日期晚,则用 minDate
104
+ if (this.props.minDate?.isValid() && this.props.minDate?.isAfter(date)) {
105
105
  date = this.props.minDate.clone();
106
106
  }
107
107
 
@@ -33,7 +33,6 @@ export class ConditionField extends React.Component<
33
33
  options: props.options
34
34
  };
35
35
  this.onSearch = this.onSearch.bind(this);
36
- this.onSearch = this.onSearch.bind(this);
37
36
  }
38
37
 
39
38
  onSearch(text: string) {
@@ -51,7 +50,7 @@ export class ConditionField extends React.Component<
51
50
  });
52
51
  return children.length > 0
53
52
  ? Object.assign({}, item, {children}) // 需要copy一份,防止覆盖原始数据
54
- : false;
53
+ : false;
55
54
  } else {
56
55
  return item.name.toLowerCase().includes(txt) ||
57
56
  item.label.toLowerCase().includes(txt)
@@ -92,11 +92,14 @@ export class Value extends React.Component<ValueProps> {
92
92
  />
93
93
  );
94
94
  } else if (field.type === 'select') {
95
+ const autoComplete = field.autoComplete;
96
+
95
97
  input = (
96
98
  <Select
97
99
  simpleValue
98
100
  options={field.options!}
99
101
  source={field.source}
102
+ autoComplete={autoComplete}
100
103
  searchable={field.searchable}
101
104
  value={value ?? field.defaultValue ?? ''}
102
105
  data={data}
@@ -145,6 +145,12 @@ interface SelectField extends BaseField {
145
145
  options?: Array<any>;
146
146
  source?: SchemaApi;
147
147
  searchable?: boolean;
148
+
149
+ /**
150
+ * 自动完成 API,当输入部分文字的时候,会将这些文字通过 ${term} 可以取到,发送给接口。
151
+ * 接口可以返回匹配到的选项,帮助用户输入。
152
+ */
153
+ autoComplete?: SchemaApi;
148
154
  }
149
155
 
150
156
  interface BooleanField extends BaseField {
@@ -61,6 +61,7 @@ import EllipsisVIcon from '../icons/ellipsis-v.svg';
61
61
  import ExpandAltIcon from '../icons/expand-alt.svg';
62
62
  import CompressAltIcon from '../icons/compress-alt.svg';
63
63
  import TransparentIcon from '../icons/transparent.svg';
64
+ import LoadingOutline from '../icons/loading-outline.svg';
64
65
 
65
66
  // 兼容原来的用法,后续不直接试用。
66
67
 
@@ -149,6 +150,7 @@ registerIcon('ellipsis-v', EllipsisVIcon);
149
150
  registerIcon('expand-alt', ExpandAltIcon);
150
151
  registerIcon('compress-alt', CompressAltIcon);
151
152
  registerIcon('transparent', TransparentIcon);
153
+ registerIcon('loading-outline', LoadingOutline);
152
154
 
153
155
  export function Icon({
154
156
  icon,
package/src/factory.tsx CHANGED
@@ -74,11 +74,16 @@ export interface RenderSchemaFilter {
74
74
  (schema: Schema, renderer: RendererConfig, props?: any): Schema;
75
75
  }
76
76
 
77
+ export interface wsObject {
78
+ url: string;
79
+ body?: any;
80
+ }
81
+
77
82
  export interface RenderOptions {
78
83
  session?: string;
79
84
  fetcher?: (config: fetcherConfig) => Promise<fetcherResult>;
80
85
  wsFetcher?: (
81
- ws: string,
86
+ ws: wsObject,
82
87
  onMessage: (data: any) => void,
83
88
  onError: (error: any) => void
84
89
  ) => void;
@@ -234,8 +239,13 @@ const defaultOptions: RenderOptions = {
234
239
  // 使用 WebSocket 来实时获取数据
235
240
  wsFetcher(ws, onMessage, onError) {
236
241
  if (ws) {
237
- const socket = new WebSocket(ws);
238
- socket.onmessage = (event: any) => {
242
+ const socket = new WebSocket(ws.url);
243
+ socket.onopen = event => {
244
+ if (ws.body) {
245
+ socket.send(JSON.stringify(ws.body));
246
+ }
247
+ };
248
+ socket.onmessage = event => {
239
249
  if (event.data) {
240
250
  onMessage(JSON.parse(event.data));
241
251
  }
@@ -0,0 +1,4 @@
1
+ <svg viewBox="0 0 1024 1024" focusable="false" data-icon="loading" width="1em" height="1em" fill="currentColor" aria-hidden="true">
2
+ <path d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z">
3
+ </path>
4
+ </svg>
package/src/index.tsx CHANGED
@@ -174,6 +174,8 @@ import './compat';
174
174
 
175
175
  import './envOverwrite';
176
176
 
177
+ import './schemaExtend';
178
+
177
179
  import './themes/ang';
178
180
  import './themes/cxd';
179
181
  import './themes/dark';
@@ -158,6 +158,7 @@ register('de-DE', {
158
158
  'System.requestError': 'Anfragefehler: ',
159
159
  'System.requestErrorStatus': 'Anfragefehler, Statuscode:',
160
160
  'Table.addRow': 'Zeile hinzufügen',
161
+ 'Table.copyRow': 'Zeile kopieren',
161
162
  'Table.columnsVisibility': 'Klicken, um die Sichtbarkeit der Spalten zu steuern',
162
163
  'Table.deleteRow': 'Aktuele Zeile löschen',
163
164
  'Table.discard': 'Verwerfen',
@@ -158,7 +158,8 @@ register('en-US', {
158
158
  'System.copy': 'Content copied',
159
159
  'System.requestError': 'Request error: ',
160
160
  'System.requestErrorStatus': 'Request error, status code: ',
161
- 'Table.addRow': 'Add a row',
161
+ 'Table.addRow': 'Add row',
162
+ 'Table.copyRow': 'Copy row',
162
163
  'Table.columnsVisibility': 'Click to control columns visibility',
163
164
  'Table.deleteRow': 'Delete current row',
164
165
  'Table.discard': 'Discard',
@@ -83,7 +83,7 @@ register('zh-CN', {
83
83
  'desc': '降序',
84
84
  'Dialog.close': '关闭',
85
85
  'Embed.invalidRoot': '选择器不对,页面上没有此元素',
86
- 'Embed.downloading': '文件即将开始下载。。',
86
+ 'Embed.downloading': '文件即将开始下载',
87
87
  'Excel.placeholder': '拖拽 Excel 到这,或点击上传',
88
88
  'fetchFailed': '初始化失败',
89
89
  'File.continueAdd': '继续添加',
@@ -163,6 +163,7 @@ register('zh-CN', {
163
163
  'System.requestError': '接口报错:',
164
164
  'System.requestErrorStatus': '接口出错,状态码是:',
165
165
  'Table.addRow': '新增一行',
166
+ 'Table.copyRow': '复制一行',
166
167
  'Table.columnsVisibility': '点击选择显示列',
167
168
  'Table.deleteRow': '删除当前行',
168
169
  'Table.discard': '放弃',
@@ -35,6 +35,10 @@ export interface ButtonSchema extends BaseSchema {
35
35
  * 右侧 icon 上的 css 类名
36
36
  */
37
37
  rightIconClassName?: SchemaClassName;
38
+ /**
39
+ * loading 上的css 类名
40
+ */
41
+ loadingClassName?: SchemaClassName;
38
42
 
39
43
  /**
40
44
  * 按钮文字
@@ -131,6 +135,10 @@ export interface ButtonSchema extends BaseSchema {
131
135
  * 键盘快捷键
132
136
  */
133
137
  hotKey?: string;
138
+ /**
139
+ * 是否显示loading效果
140
+ */
141
+ loadingOn?: string;
134
142
  }
135
143
 
136
144
  export interface AjaxActionSchema extends ButtonSchema {
@@ -151,6 +159,14 @@ export interface AjaxActionSchema extends ButtonSchema {
151
159
  ignoreConfirm?: boolean;
152
160
  }
153
161
 
162
+ export interface DownloadActionSchema
163
+ extends Omit<AjaxActionSchema, 'actionType'> {
164
+ /**
165
+ * 指定为下载行为
166
+ */
167
+ actionType: 'download';
168
+ }
169
+
154
170
  export interface UrlActionSchema extends ButtonSchema {
155
171
  /**
156
172
  * 指定为打开链接
@@ -369,7 +385,7 @@ import {DialogSchema, DialogSchemaBase} from './Dialog';
369
385
  import {DrawerSchema, DrawerSchemaBase} from './Drawer';
370
386
  import {generateIcon} from '../utils/icon';
371
387
  import {BadgeSchema, withBadge} from '../components/Badge';
372
- import {str2AsyncFunction} from '../utils/api';
388
+ import {normalizeApi, str2AsyncFunction} from '../utils/api';
373
389
 
374
390
  // 构造一个假的 React 事件避免可能的报错,主要用于快捷键功能
375
391
  // 来自 https://stackoverflow.com/questions/27062455/reactjs-can-i-create-my-own-syntheticevent
@@ -408,44 +424,80 @@ export const createSyntheticEvent = <T extends Element, E extends Event>(
408
424
  export interface ActionProps
409
425
  extends Omit<
410
426
  ButtonSchema,
411
- 'className' | 'iconClassName' | 'rightIconClassName'
427
+ 'className' | 'iconClassName' | 'rightIconClassName' | 'loadingClassName'
412
428
  >,
413
429
  ThemeProps,
414
430
  Omit<
415
431
  AjaxActionSchema,
416
- 'type' | 'className' | 'iconClassName' | 'rightIconClassName'
432
+ | 'type'
433
+ | 'className'
434
+ | 'iconClassName'
435
+ | 'rightIconClassName'
436
+ | 'loadingClassName'
417
437
  >,
418
438
  Omit<
419
439
  UrlActionSchema,
420
- 'type' | 'className' | 'iconClassName' | 'rightIconClassName'
440
+ | 'type'
441
+ | 'className'
442
+ | 'iconClassName'
443
+ | 'rightIconClassName'
444
+ | 'loadingClassName'
421
445
  >,
422
446
  Omit<
423
447
  LinkActionSchema,
424
- 'type' | 'className' | 'iconClassName' | 'rightIconClassName'
448
+ | 'type'
449
+ | 'className'
450
+ | 'iconClassName'
451
+ | 'rightIconClassName'
452
+ | 'loadingClassName'
425
453
  >,
426
454
  Omit<
427
455
  DialogActionSchema,
428
- 'type' | 'className' | 'iconClassName' | 'rightIconClassName'
456
+ | 'type'
457
+ | 'className'
458
+ | 'iconClassName'
459
+ | 'rightIconClassName'
460
+ | 'loadingClassName'
429
461
  >,
430
462
  Omit<
431
463
  DrawerActionSchema,
432
- 'type' | 'className' | 'iconClassName' | 'rightIconClassName'
464
+ | 'type'
465
+ | 'className'
466
+ | 'iconClassName'
467
+ | 'rightIconClassName'
468
+ | 'loadingClassName'
433
469
  >,
434
470
  Omit<
435
471
  CopyActionSchema,
436
- 'type' | 'className' | 'iconClassName' | 'rightIconClassName'
472
+ | 'type'
473
+ | 'className'
474
+ | 'iconClassName'
475
+ | 'rightIconClassName'
476
+ | 'loadingClassName'
437
477
  >,
438
478
  Omit<
439
479
  ReloadActionSchema,
440
- 'type' | 'className' | 'iconClassName' | 'rightIconClassName'
480
+ | 'type'
481
+ | 'className'
482
+ | 'iconClassName'
483
+ | 'rightIconClassName'
484
+ | 'loadingClassName'
441
485
  >,
442
486
  Omit<
443
487
  EmailActionSchema,
444
- 'type' | 'className' | 'iconClassName' | 'rightIconClassName'
488
+ | 'type'
489
+ | 'className'
490
+ | 'iconClassName'
491
+ | 'rightIconClassName'
492
+ | 'loadingClassName'
445
493
  >,
446
494
  Omit<
447
495
  OtherActionSchema,
448
- 'type' | 'className' | 'iconClassName' | 'rightIconClassName'
496
+ | 'type'
497
+ | 'className'
498
+ | 'iconClassName'
499
+ | 'rightIconClassName'
500
+ | 'loadingClassName'
449
501
  > {
450
502
  actionType: any;
451
503
  onAction?: (
@@ -535,6 +587,15 @@ export class Action extends React.Component<ActionProps, ActionState> {
535
587
 
536
588
  e.preventDefault();
537
589
  const action = pick(this.props, ActionProps) as ActionSchema;
590
+
591
+ // download 是一种 ajax 的简写
592
+ if (action.actionType === 'download') {
593
+ action.actionType = 'ajax';
594
+ const api = normalizeApi((action as AjaxActionSchema).api);
595
+ api.responseType = 'blob';
596
+ (action as AjaxActionSchema).api = api;
597
+ }
598
+
538
599
  onAction(e, action);
539
600
 
540
601
  if (countDown) {
@@ -602,6 +663,7 @@ export class Action extends React.Component<ActionProps, ActionState> {
602
663
  iconClassName,
603
664
  rightIcon,
604
665
  rightIconClassName,
666
+ loadingClassName,
605
667
  primary,
606
668
  size,
607
669
  level,
@@ -621,7 +683,10 @@ export class Action extends React.Component<ActionProps, ActionState> {
621
683
  isMenuItem,
622
684
  active,
623
685
  activeLevel,
686
+ tooltipTrigger,
624
687
  tooltipContainer,
688
+ tooltipRootClose,
689
+ loading,
625
690
  classnames: cx
626
691
  } = this.props;
627
692
 
@@ -661,6 +726,8 @@ export class Action extends React.Component<ActionProps, ActionState> {
661
726
  ? activeLevel
662
727
  : level || (primary ? 'primary' : undefined)
663
728
  }
729
+ loadingClassName={loadingClassName}
730
+ loading={loading}
664
731
  onClick={this.handleAction}
665
732
  type={type && ~allowedType.indexOf(type) ? type : 'button'}
666
733
  disabled={disabled}
@@ -668,12 +735,14 @@ export class Action extends React.Component<ActionProps, ActionState> {
668
735
  overrideClassName={isMenuItem}
669
736
  tooltip={filterContents(tooltip, data)}
670
737
  disabledTip={filterContents(disabledTip, data)}
671
- placement={tooltipPlacement}
738
+ tooltipPlacement={tooltipPlacement}
672
739
  tooltipContainer={tooltipContainer}
740
+ tooltipTrigger={tooltipTrigger}
741
+ tooltipRootClose={tooltipRootClose}
673
742
  block={block}
674
743
  iconOnly={!!(icon && !label && level !== 'link')}
675
744
  >
676
- {iconElement}
745
+ {!loading ? iconElement : ''}
677
746
  {label ? <span>{filter(String(label), data)}</span> : null}
678
747
  {rightIconElement}
679
748
  </Button>
@@ -719,13 +788,14 @@ export class ActionRenderer extends React.Component<
719
788
  }
720
789
 
721
790
  render() {
722
- const {env, disabled, btnDisabled, ...rest} = this.props;
791
+ const {env, disabled, btnDisabled, loading, ...rest} = this.props;
723
792
 
724
793
  return (
725
794
  <Action
726
795
  {...(rest as any)}
727
796
  disabled={disabled || btnDisabled}
728
797
  onAction={this.handleAction}
798
+ loading={loading}
729
799
  isCurrentUrl={this.isCurrentAction}
730
800
  tooltipContainer={
731
801
  env.getModalContainer ? env.getModalContainer : undefined
@@ -1057,7 +1057,10 @@ export default class CRUD extends React.Component<CRUDProps, any> {
1057
1057
  (!stopAutoRefreshWhen ||
1058
1058
  !(
1059
1059
  (stopAutoRefreshWhenModalIsOpen && store.hasModalOpened) ||
1060
- evalExpression(stopAutoRefreshWhen, data)
1060
+ evalExpression(
1061
+ stopAutoRefreshWhen,
1062
+ createObject(store.data, store.query)
1063
+ )
1061
1064
  )) &&
1062
1065
  (this.timer = setTimeout(
1063
1066
  silentPolling
@@ -1497,15 +1500,11 @@ export default class CRUD extends React.Component<CRUDProps, any> {
1497
1500
  hasBulkActions() {
1498
1501
  const {bulkActions, itemActions, store} = this.props;
1499
1502
 
1500
- if (
1501
- (!bulkActions || !bulkActions.length) &&
1502
- (!itemActions || !itemActions.length)
1503
- ) {
1503
+ if (!bulkActions || !bulkActions.length) {
1504
1504
  return false;
1505
1505
  }
1506
1506
 
1507
1507
  let bulkBtns: Array<ActionSchema> = [];
1508
- let itemBtns: Array<ActionSchema> = [];
1509
1508
  const ctx = store.mergedData;
1510
1509
 
1511
1510
  if (bulkActions && bulkActions.length) {
@@ -1517,21 +1516,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
1517
1516
  .filter(item => !item.hidden && item.visible !== false);
1518
1517
  }
1519
1518
 
1520
- const itemData = createObject(
1521
- store.data,
1522
- store.selectedItems.length ? store.selectedItems[0] : {}
1523
- );
1524
-
1525
- if (itemActions && itemActions.length) {
1526
- itemBtns = itemActions
1527
- .map(item => ({
1528
- ...item,
1529
- ...getExprProperties(item as Schema, itemData)
1530
- }))
1531
- .filter(item => !item.hidden && item.visible !== false);
1532
- }
1533
-
1534
- return bulkBtns.length || itemBtns.length;
1519
+ return bulkBtns.length;
1535
1520
  }
1536
1521
 
1537
1522
  renderBulkActions(childProps: any) {
@@ -1539,11 +1524,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
1539
1524
 
1540
1525
  const items = childProps.items;
1541
1526
 
1542
- if (
1543
- !items.length ||
1544
- ((!bulkActions || !bulkActions.length) &&
1545
- (!itemActions || !itemActions.length))
1546
- ) {
1527
+ if (!items.length || !bulkActions || !bulkActions.length) {
1547
1528
  return null;
1548
1529
  }
1549
1530
 
@@ -1595,7 +1576,6 @@ export default class CRUD extends React.Component<CRUDProps, any> {
1595
1576
  render(
1596
1577
  `bulk-action/${index}`,
1597
1578
  {
1598
- size: 'sm',
1599
1579
  ...omit(btn, ['visibleOn', 'hiddenOn', 'disabledOn']),
1600
1580
  type: 'button',
1601
1581
  ignoreConfirm: true
@@ -1619,7 +1599,6 @@ export default class CRUD extends React.Component<CRUDProps, any> {
1619
1599
  render(
1620
1600
  `bulk-action/${index}`,
1621
1601
  {
1622
- size: 'sm',
1623
1602
  ...omit(btn, ['visibleOn', 'hiddenOn', 'disabledOn']),
1624
1603
  type: 'button'
1625
1604
  },
@@ -1776,16 +1755,17 @@ export default class CRUD extends React.Component<CRUDProps, any> {
1776
1755
  );
1777
1756
  }
1778
1757
 
1779
- renderExportCSV() {
1758
+ renderExportCSV(toolbar: Schema) {
1780
1759
  const {
1781
1760
  store,
1782
1761
  classPrefix: ns,
1783
1762
  classnames: cx,
1784
1763
  translate: __,
1785
- loadDataOnce,
1786
- api
1764
+ loadDataOnce
1787
1765
  } = this.props;
1788
1766
 
1767
+ const api = (toolbar as Schema).api;
1768
+
1789
1769
  return (
1790
1770
  <Button
1791
1771
  classPrefix={ns}
@@ -1797,7 +1777,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
1797
1777
  }
1798
1778
  size="sm"
1799
1779
  >
1800
- {__('CRUD.exportCSV')}
1780
+ {toolbar.label || __('CRUD.exportCSV')}
1801
1781
  </Button>
1802
1782
  );
1803
1783
  }
@@ -1827,7 +1807,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
1827
1807
  } else if (type === 'filter-toggler') {
1828
1808
  return this.renderFilterToggler();
1829
1809
  } else if (type === 'export-csv') {
1830
- return this.renderExportCSV();
1810
+ return this.renderExportCSV(toolbar as Schema);
1831
1811
  } else if (Array.isArray(toolbar)) {
1832
1812
  const children: Array<any> = toolbar
1833
1813
  .map((toolbar, index) => ({