amis 1.9.0-beta.10 → 1.9.0-beta.12

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 (92) hide show
  1. package/lib/actions/LinkAction.d.ts +8 -1
  2. package/lib/actions/LinkAction.js +9 -12
  3. package/lib/actions/LinkAction.js.map +2 -2
  4. package/lib/actions/ToastAction.js +2 -1
  5. package/lib/actions/ToastAction.js.map +2 -2
  6. package/lib/components/Tree.d.ts +170 -84
  7. package/lib/components/Tree.js +25 -23
  8. package/lib/components/Tree.js.map +2 -2
  9. package/lib/index.js +1 -1
  10. package/lib/renderers/Action.js +1 -1
  11. package/lib/renderers/Action.js.map +2 -2
  12. package/lib/renderers/CRUD.d.ts +1 -0
  13. package/lib/renderers/CRUD.js +2 -2
  14. package/lib/renderers/CRUD.js.map +2 -2
  15. package/lib/renderers/Dialog.js +2 -2
  16. package/lib/renderers/Dialog.js.map +2 -2
  17. package/lib/renderers/Drawer.js +2 -2
  18. package/lib/renderers/Drawer.js.map +2 -2
  19. package/lib/renderers/Form/InputFile.d.ts +4 -0
  20. package/lib/renderers/Form/InputFile.js +47 -21
  21. package/lib/renderers/Form/InputFile.js.map +2 -2
  22. package/lib/renderers/Form/InputTree.d.ts +9 -1
  23. package/lib/renderers/Form/InputTree.js +2 -2
  24. package/lib/renderers/Form/InputTree.js.map +2 -2
  25. package/lib/renderers/Form/Picker.d.ts +2 -1
  26. package/lib/renderers/Form/Picker.js +8 -2
  27. package/lib/renderers/Form/Picker.js.map +2 -2
  28. package/lib/renderers/Form/index.js +6 -3
  29. package/lib/renderers/Form/index.js.map +2 -2
  30. package/lib/renderers/Service.d.ts +2 -0
  31. package/lib/renderers/Service.js +23 -3
  32. package/lib/renderers/Service.js.map +2 -2
  33. package/lib/renderers/Wizard.js +5 -8
  34. package/lib/renderers/Wizard.js.map +2 -2
  35. package/lib/themes/ang-ie11.css +27 -15
  36. package/lib/themes/ang.css +39 -25
  37. package/lib/themes/ang.css.map +1 -1
  38. package/lib/themes/antd-ie11.css +27 -15
  39. package/lib/themes/antd.css +39 -25
  40. package/lib/themes/antd.css.map +1 -1
  41. package/lib/themes/cxd-ie11.css +42 -30
  42. package/lib/themes/cxd.css +44 -26
  43. package/lib/themes/cxd.css.map +1 -1
  44. package/lib/themes/dark-ie11.css +27 -15
  45. package/lib/themes/dark.css +39 -25
  46. package/lib/themes/dark.css.map +1 -1
  47. package/lib/themes/default-ie11.css +42 -30
  48. package/lib/themes/default.css +44 -26
  49. package/lib/themes/default.css.map +1 -1
  50. package/package.json +2 -3
  51. package/schema.json +174 -235
  52. package/scss/_properties.scss +2 -0
  53. package/scss/components/form/_tree.scss +41 -46
  54. package/scss/themes/_cxd-variables.scss +7 -2
  55. package/sdk/ang-ie11.css +33 -20
  56. package/sdk/ang.css +45 -30
  57. package/sdk/antd-ie11.css +33 -20
  58. package/sdk/antd.css +45 -30
  59. package/sdk/barcode.js +51 -51
  60. package/sdk/charts.js +15 -15
  61. package/sdk/codemirror.js +7 -7
  62. package/sdk/color-picker.js +65 -65
  63. package/sdk/cropperjs.js +2 -2
  64. package/sdk/cxd-ie11.css +48 -35
  65. package/sdk/cxd.css +50 -31
  66. package/sdk/dark-ie11.css +33 -20
  67. package/sdk/dark.css +45 -30
  68. package/sdk/exceljs.js +1 -1
  69. package/sdk/markdown.js +69 -69
  70. package/sdk/papaparse.js +1 -1
  71. package/sdk/renderers/Form/CityDB.js +1 -1
  72. package/sdk/rest.js +16 -16
  73. package/sdk/rich-text.js +62 -62
  74. package/sdk/sdk-ie11.css +48 -35
  75. package/sdk/sdk.css +50 -31
  76. package/sdk/sdk.js +1265 -1293
  77. package/sdk/thirds/hls.js/hls.js +1 -1
  78. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  79. package/sdk/tinymce.js +57 -57
  80. package/src/actions/LinkAction.ts +21 -14
  81. package/src/actions/ToastAction.ts +6 -1
  82. package/src/components/Tree.tsx +36 -36
  83. package/src/renderers/Action.tsx +1 -4
  84. package/src/renderers/CRUD.tsx +4 -6
  85. package/src/renderers/Dialog.tsx +2 -2
  86. package/src/renderers/Drawer.tsx +2 -2
  87. package/src/renderers/Form/InputFile.tsx +27 -15
  88. package/src/renderers/Form/InputTree.tsx +12 -1
  89. package/src/renderers/Form/Picker.tsx +13 -3
  90. package/src/renderers/Form/index.tsx +6 -6
  91. package/src/renderers/Service.tsx +40 -5
  92. package/src/renderers/Wizard.tsx +4 -7
@@ -1,3 +1,4 @@
1
+ import {buildApi} from '../utils/api';
1
2
  import {isEmpty, isObject, qsstringify} from '../utils/helper';
2
3
  import {RendererEvent} from '../utils/renderer-event';
3
4
  import {filter} from '../utils/tpl';
@@ -10,7 +11,15 @@ import {
10
11
 
11
12
  export interface ILinkAction extends ListenerAction {
12
13
  link: string;
14
+ url?: never;
15
+ params?: {
16
+ [key: string]: string;
17
+ };
18
+ }
19
+
20
+ export interface IUrlAction extends ListenerAction {
13
21
  url: string;
22
+ link?: never;
14
23
  params?: {
15
24
  [key: string]: string;
16
25
  };
@@ -25,7 +34,7 @@ export interface ILinkAction extends ListenerAction {
25
34
  */
26
35
  export class LinkAction implements Action {
27
36
  async run(
28
- action: ILinkAction,
37
+ action: ILinkAction | IUrlAction,
29
38
  renderer: ListenerContext,
30
39
  event: RendererEvent<any>
31
40
  ) {
@@ -33,21 +42,19 @@ export class LinkAction implements Action {
33
42
  throw new Error('env.jumpTo is required!');
34
43
  }
35
44
 
36
- let url = (action.url || action.link) as string;
37
-
38
- // 处理参数
39
- if (!isEmpty(action.params)) {
40
- if (!isObject(action.params)) {
41
- throw new Error('action.params must be an object');
45
+ // 通过buildApi兼容较复杂的url情况
46
+ let urlObj = buildApi(
47
+ {
48
+ url: (action.url || action.link) as string,
49
+ method: 'get'
50
+ },
51
+ {...action.params, ...action.args},
52
+ {
53
+ autoAppend: true
42
54
  }
43
- url = `${/\?/.test(url) ? '&' : '?'}${qsstringify(action.params)}`;
44
- }
45
-
46
- renderer.props.env.jumpTo(
47
- filter(url, action.args, '| raw'),
48
- action,
49
- action.args
50
55
  );
56
+
57
+ renderer.props.env.jumpTo(urlObj.url, action, action.args);
51
58
  }
52
59
  }
53
60
 
@@ -5,6 +5,7 @@ import {
5
5
  ListenerContext,
6
6
  registerAction
7
7
  } from './Action';
8
+ import {resolveVariableAndFilter} from '../utils/tpl-builtin';
8
9
 
9
10
  export interface IToastAction extends ListenerAction {
10
11
  msg: string;
@@ -31,7 +32,11 @@ export class ToastAction implements Action {
31
32
  renderer: ListenerContext,
32
33
  event: RendererEvent<any>
33
34
  ) {
34
- event.context.env.notify?.(action.msgType || 'info', action.msg, action);
35
+ event.context.env.notify?.(
36
+ action.msgType || 'info',
37
+ resolveVariableAndFilter(action.msg, event?.data, '| raw'),
38
+ action
39
+ );
35
40
  }
36
41
  }
37
42
 
@@ -88,14 +88,21 @@ interface TreeSelectorProps extends ThemeProps, LocaleProps {
88
88
  pathSeparator?: string;
89
89
  // 已选择节点路径
90
90
  nodePath: any[];
91
-
92
- // 这个配置名字没取好,目前的含义是,如果这个配置成true,点父级的时候,子级点不会自选中。
93
- // 否则点击父级,子节点选中。
91
+ // ui级联关系,true代表级联选中,false代表不级联,默认为true
92
+ autoCheckChildren: boolean;
93
+
94
+ /*
95
+ * 该属性代表数据级联关系,autoCheckChildren为true时生效,默认为false,具体数据级联关系如下:
96
+ * 1.casacde为false,ui行为为级联选中子节点,子节点禁用;值只包含父节点的值
97
+ * 2.cascade为false,withChildren为true,ui行为为级联选中子节点,子节点禁用;值包含父子节点的值
98
+ * 3.cascade为true,ui行为级联选中子节点,子节点可反选,值包含父子节点的值,此时withChildren属性失效
99
+ * 4.cascade不论为true还是false,onlyChildren为true,ui行为级联选中子节点,子节点可反选,值只包含子节点的值
100
+ */
94
101
  cascade?: boolean;
102
+
95
103
  selfDisabledAffectChildren?: boolean;
96
104
  minLength?: number;
97
105
  maxLength?: number;
98
-
99
106
  // 是否为内建 增、改、删。当有复杂表单的时候直接抛出去让外层能统一处理
100
107
  bultinCUD?: boolean;
101
108
  rootCreatable?: boolean;
@@ -157,6 +164,7 @@ export class TreeSelector extends React.Component<
157
164
  hideRoot: true,
158
165
  rootLabel: 'Tree.root',
159
166
  rootValue: 0,
167
+ autoCheckChildren: true,
160
168
  cascade: false,
161
169
  selfDisabledAffectChildren: true,
162
170
  rootCreateTip: 'Tree.addRoot',
@@ -182,7 +190,6 @@ export class TreeSelector extends React.Component<
182
190
 
183
191
  constructor(props: TreeSelectorProps) {
184
192
  super(props);
185
-
186
193
  this.state = {
187
194
  value: value2array(
188
195
  props.value,
@@ -279,7 +286,7 @@ export class TreeSelector extends React.Component<
279
286
  } else if (foldedField && typeof node[foldedField] !== 'undefined') {
280
287
  ret = !node[foldedField];
281
288
  } else {
282
- ret = !!props.initiallyOpen;
289
+ ret = !!props.initiallyOpen && !initFoldedLevel;
283
290
  if (!ret && level <= (expandLevel as number)) {
284
291
  ret = true;
285
292
  }
@@ -412,15 +419,12 @@ export class TreeSelector extends React.Component<
412
419
  const props = this.props;
413
420
  const value = this.state.value.concat();
414
421
  const idx = value.indexOf(item);
415
- const onlyChildren = props.onlyChildren;
416
-
422
+ const {onlyChildren, withChildren, cascade, autoCheckChildren} = props;
417
423
  if (checked) {
418
424
  ~idx || value.push(item);
419
-
420
425
  // cascade 为 true 表示父节点跟子节点没有级联关系。
421
- if (!props.cascade) {
426
+ if (autoCheckChildren) {
422
427
  const children = item.children ? item.children.concat([]) : [];
423
-
424
428
  if (onlyChildren) {
425
429
  // 父级选中的时候,子节点也都选中,但是自己不选中
426
430
  !~idx && children.length && value.pop();
@@ -445,7 +449,7 @@ export class TreeSelector extends React.Component<
445
449
  value.splice(index, 1);
446
450
  }
447
451
 
448
- if (props.withChildren) {
452
+ if (withChildren || cascade) {
449
453
  value.push(child);
450
454
  }
451
455
 
@@ -464,7 +468,7 @@ export class TreeSelector extends React.Component<
464
468
  if (
465
469
  parent.children.every((child: any) => ~value.indexOf(child))
466
470
  ) {
467
- if (!props.withChildren) {
471
+ if (!cascade && !withChildren) {
468
472
  parent.children.forEach((child: any) => {
469
473
  const index = value.indexOf(child);
470
474
  if (~index) {
@@ -483,19 +487,18 @@ export class TreeSelector extends React.Component<
483
487
  }
484
488
  } else {
485
489
  ~idx && value.splice(idx, 1);
486
-
487
- if (!props.cascade && (props.withChildren || onlyChildren)) {
488
- const children = item.children ? item.children.concat([]) : [];
489
- while (children.length) {
490
- let child = children.shift();
491
- let index = value.indexOf(child);
492
-
493
- if (~index) {
494
- value.splice(index, 1);
495
- }
496
-
497
- if (child.children && child.children.length) {
498
- children.push.apply(children, child.children);
490
+ if (autoCheckChildren) {
491
+ if (cascade || withChildren || onlyChildren) {
492
+ const children = item.children ? item.children.concat([]) : [];
493
+ while (children.length) {
494
+ let child = children.shift();
495
+ let index = value.indexOf(child);
496
+ if (~index) {
497
+ value.splice(index, 1);
498
+ }
499
+ if (child.children && child.children.length) {
500
+ children.push.apply(children, child.children);
501
+ }
499
502
  }
500
503
  }
501
504
  }
@@ -664,7 +667,6 @@ export class TreeSelector extends React.Component<
664
667
  @autobind
665
668
  getDropInfo(e: React.DragEvent<Element>, node: Option): IDropInfo {
666
669
  let rect = e.currentTarget.getBoundingClientRect();
667
-
668
670
  const dragNode = this.dragNode;
669
671
  const deltaX = Math.min(50, rect.width * 0.3);
670
672
  const gap = node?.children?.length ? 0 : 16;
@@ -676,7 +678,6 @@ export class TreeSelector extends React.Component<
676
678
  let top = targetOffset.top - offset.top;
677
679
 
678
680
  let {clientX, clientY} = e;
679
-
680
681
  let position: IDropInfo['position'] =
681
682
  clientY >= rect.top + rect.height / 2 ? 'bottom' : 'top';
682
683
  let indicator;
@@ -788,6 +789,7 @@ export class TreeSelector extends React.Component<
788
789
  valueField,
789
790
  iconField,
790
791
  disabledField,
792
+ autoCheckChildren,
791
793
  cascade,
792
794
  selfDisabledAffectChildren,
793
795
  onlyChildren,
@@ -818,7 +820,6 @@ export class TreeSelector extends React.Component<
818
820
  if (!isVisible(item as any, options)) {
819
821
  return null;
820
822
  }
821
-
822
823
  const checked = !!~value.indexOf(item);
823
824
  const selfDisabled = item[disabledField];
824
825
  let selfChecked = !!uncheckable || checked;
@@ -829,16 +830,15 @@ export class TreeSelector extends React.Component<
829
830
  childrenItems = this.renderList(
830
831
  item.children,
831
832
  value,
832
- cascade
833
- ? false
834
- : uncheckable ||
835
- (selfDisabledAffectChildren ? selfDisabled : false) ||
836
- (multiple && checked)
833
+ (!autoCheckChildren || cascade)
834
+ ? false: (uncheckable
835
+ || (selfDisabledAffectChildren ? selfDisabled : false)
836
+ || (multiple && checked))
837
837
  );
838
838
  selfChildrenChecked = !!childrenItems.childrenChecked;
839
839
  if (
840
840
  !selfChecked &&
841
- onlyChildren &&
841
+ onlyChildren && autoCheckChildren &&
842
842
  item.children.length === childrenItems.childrenChecked
843
843
  ) {
844
844
  selfChecked = true;
@@ -864,7 +864,7 @@ export class TreeSelector extends React.Component<
864
864
  <Checkbox
865
865
  size="sm"
866
866
  disabled={nodeDisabled}
867
- checked={selfChecked || (!cascade && selfChildrenChecked)}
867
+ checked={selfChecked || (autoCheckChildren && selfChildrenChecked)}
868
868
  partial={!selfChecked}
869
869
  onChange={this.handleCheck.bind(this, item, !selfChecked)}
870
870
  />
@@ -867,10 +867,7 @@ export class ActionRenderer extends React.Component<
867
867
  const {env, onAction, data, ignoreConfirm, dispatchEvent} = this.props;
868
868
 
869
869
  // 触发渲染器事件
870
- const rendererEvent = await dispatchEvent(
871
- e as React.MouseEvent<any>,
872
- createObject(data, action)
873
- );
870
+ const rendererEvent = await dispatchEvent(e as React.MouseEvent<any>, data);
874
871
 
875
872
  // 阻止原有动作执行
876
873
  if (rendererEvent?.prevented) {
@@ -404,6 +404,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
404
404
 
405
405
  control: any;
406
406
  lastQuery: any;
407
+ lastData: any;
408
+
407
409
  timer: ReturnType<typeof setTimeout>;
408
410
  mounted: boolean;
409
411
  constructor(props: CRUDProps) {
@@ -571,15 +573,11 @@ export default class CRUD extends React.Component<CRUDProps, any> {
571
573
  ) {
572
574
  dataInvalid = true;
573
575
  } else if (!props.api && isPureVariable(props.source)) {
574
- const prev = resolveVariableAndFilter(
575
- prevProps.source,
576
- prevProps.data,
577
- '| raw'
578
- );
579
576
  const next = resolveVariableAndFilter(props.source, props.data, '| raw');
580
577
 
581
- if (prev !== next) {
578
+ if (!this.lastData || this.lastData !== next) {
582
579
  store.initFromScope(props.data, props.source);
580
+ this.lastData = next;
583
581
  }
584
582
  }
585
583
 
@@ -751,7 +751,7 @@ export class DialogRenderer extends Dialog {
751
751
  ) {
752
752
  const rendererEvent = await dispatchEvent(
753
753
  'cancel',
754
- createObject(this.props.data, {data})
754
+ createObject(this.props.data, data)
755
755
  );
756
756
  if (rendererEvent?.prevented) {
757
757
  return;
@@ -762,7 +762,7 @@ export class DialogRenderer extends Dialog {
762
762
  } else if (action.actionType === 'confirm') {
763
763
  const rendererEvent = await dispatchEvent(
764
764
  'confirm',
765
- createObject(this.props.data, {data})
765
+ createObject(this.props.data, data)
766
766
  );
767
767
  if (rendererEvent?.prevented) {
768
768
  return;
@@ -849,7 +849,7 @@ export class DrawerRenderer extends Drawer {
849
849
  if (action.actionType === 'close' || action.actionType === 'cancel') {
850
850
  const rendererEvent = await dispatchEvent(
851
851
  'cancel',
852
- createObject(this.props.data, {data})
852
+ createObject(this.props.data, data)
853
853
  );
854
854
  if (rendererEvent?.prevented) {
855
855
  return;
@@ -860,7 +860,7 @@ export class DrawerRenderer extends Drawer {
860
860
  } else if (action.actionType === 'confirm') {
861
861
  const rendererEvent = await dispatchEvent(
862
862
  'confirm',
863
- createObject(this.props.data, {data})
863
+ createObject(this.props.data, data)
864
864
  );
865
865
  if (rendererEvent?.prevented) {
866
866
  return;
@@ -2,8 +2,6 @@ import React from 'react';
2
2
  import {FormItem, FormControlProps, FormBaseControl} from './Item';
3
3
  import find from 'lodash/find';
4
4
  import isPlainObject from 'lodash/isPlainObject';
5
- // @ts-ignore
6
- import mapLimit from 'async/mapLimit';
7
5
  import ImageControl from './InputImage';
8
6
  import {Payload, ApiObject, ApiString, Action} from '../../types';
9
7
  import {filter} from '../../utils/tpl';
@@ -83,6 +81,11 @@ export interface FileControlSchema extends FormBaseControl {
83
81
  */
84
82
  chunkSize?: number;
85
83
 
84
+ /**
85
+ * 分块上传的并发数
86
+ */
87
+ concurrency?: number;
88
+
86
89
  /**
87
90
  * 分割符
88
91
  */
@@ -302,6 +305,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
302
305
  startChunkApi: '/api/upload/startChunk',
303
306
  chunkApi: '/api/upload/chunk',
304
307
  finishChunkApi: '/api/upload/finishChunk',
308
+ concurrency: 3,
305
309
  accept: '',
306
310
  multiple: false,
307
311
  autoUpload: true,
@@ -979,6 +983,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
979
983
  onProgress: (progress: number) => void
980
984
  ): Promise<Payload> {
981
985
  const chunkSize = config.chunkSize || 5 * 1024 * 1024;
986
+ const concurrency = this.props.concurrency;
982
987
  const self = this;
983
988
  let startProgress = 0.2;
984
989
  let endProgress = 0.9;
@@ -1020,7 +1025,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
1020
1025
 
1021
1026
  self._send(file, startApi).then(startChunk).catch(reject);
1022
1027
 
1023
- function startChunk(ret: Payload) {
1028
+ async function startChunk(ret: Payload) {
1024
1029
  onProgress(startProgress);
1025
1030
  const tasks = getTasks(file);
1026
1031
  progressArr = tasks.map(() => 0);
@@ -1036,18 +1041,25 @@ export default class FileControl extends React.Component<FileProps, FileState> {
1036
1041
  total: tasks.length
1037
1042
  };
1038
1043
 
1039
- mapLimit(
1040
- tasks,
1041
- 3,
1042
- uploadPartFile(state, config),
1043
- function (err: any, results: any) {
1044
- if (err) {
1045
- reject(err);
1046
- } else {
1047
- finishChunk(results, state);
1048
- }
1049
- }
1050
- );
1044
+ let results: any[] = [];
1045
+ while (tasks.length) {
1046
+ const res = await Promise.all(
1047
+ tasks.splice(0, concurrency).map(async task => {
1048
+ return await uploadPartFile(state, config)(
1049
+ task,
1050
+ (err: any, value: any) => {
1051
+ if (err) {
1052
+ reject(err);
1053
+ throw new Error(err);
1054
+ }
1055
+ return value;
1056
+ }
1057
+ );
1058
+ })
1059
+ );
1060
+ results = results.concat(res);
1061
+ }
1062
+ finishChunk(results, state);
1051
1063
  }
1052
1064
 
1053
1065
  function updateProgress(partNumber: number, progress: number) {
@@ -39,7 +39,16 @@ export interface TreeControlSchema extends FormOptionsControl {
39
39
  showIcon?: boolean;
40
40
 
41
41
  /**
42
- * 父子之间是否完全独立。
42
+ * ui级联关系,true代表级联选中,false代表不级联,默认为true
43
+ */
44
+ autoCheckChildren?: boolean;
45
+
46
+ /**
47
+ * 该属性代表数据级联关系,autoCheckChildren为true时生效,默认为false,具体数据级联关系如下:
48
+ * 1.casacde为false,ui行为为级联选中子节点,子节点禁用;值只包含父节点的值
49
+ * 2.cascade为false,withChildren为true,ui行为为级联选中子节点,子节点禁用;值包含父子节点的值
50
+ * 3.cascade为true,ui行为级联选中子节点,子节点可反选,值包含父子节点的值,此时withChildren属性失效
51
+ * 4.cascade不论为true还是false,onlyChildren为true,ui行为级联选中子节点,子节点可反选,值只包含子节点的值
43
52
  */
44
53
  cascade?: boolean;
45
54
 
@@ -166,6 +175,7 @@ export default class TreeControl extends React.Component<TreeProps> {
166
175
  loading,
167
176
  hideRoot,
168
177
  rootLabel,
178
+ autoCheckChildren,
169
179
  cascade,
170
180
  rootValue,
171
181
  showIcon,
@@ -222,6 +232,7 @@ export default class TreeControl extends React.Component<TreeProps> {
222
232
  showIcon={showIcon}
223
233
  showRadio={showRadio}
224
234
  showOutline={showOutline}
235
+ autoCheckChildren={autoCheckChildren}
225
236
  cascade={cascade}
226
237
  foldedField="collapsed"
227
238
  value={value || ''}
@@ -22,7 +22,11 @@ import Html from '../../components/Html';
22
22
  import {filter} from '../../utils/tpl';
23
23
  import {Icon} from '../../components/icons';
24
24
  import {isEmpty} from '../../utils/helper';
25
- import {dataMapping} from '../../utils/tpl-builtin';
25
+ import {
26
+ dataMapping,
27
+ isPureVariable,
28
+ resolveVariableAndFilter
29
+ } from '../../utils/tpl-builtin';
26
30
  import {SchemaCollection, SchemaTpl} from '../../Schema';
27
31
  import {CRUDSchema} from '../CRUD';
28
32
  import {isApiOutdated, isEffectiveApi} from '../../utils/api';
@@ -162,13 +166,18 @@ export default class PickerControl extends React.PureComponent<
162
166
  op: 'loadOptions'
163
167
  });
164
168
 
165
- isEffectiveApi(source, ctx) &&
169
+ if (isPureVariable(source)) {
170
+ formItem.setOptions(resolveVariableAndFilter(source, data, '| raw'));
171
+ } else if (isEffectiveApi(source, ctx)) {
166
172
  formItem.loadOptions(source, ctx, {
167
173
  autoAppend: true
168
174
  });
175
+ }
169
176
  }
170
177
 
171
178
  buildSchema(props: PickerProps) {
179
+ const isScopeData = isPureVariable(props.source);
180
+
172
181
  return {
173
182
  checkOnItemClick: true,
174
183
  ...props.pickerSchema,
@@ -176,7 +185,8 @@ export default class PickerControl extends React.PureComponent<
176
185
  type: 'crud',
177
186
  pickerMode: true,
178
187
  syncLocation: false,
179
- api: props.source,
188
+ api: isScopeData ? null : props.source,
189
+ source: isScopeData ? props.source : null,
180
190
  keepItemSelectionOnPageChange: true,
181
191
  valueField: props.valueField,
182
192
  labelField: props.labelField,
@@ -657,12 +657,15 @@ export default class Form extends React.Component<FormProps, object> {
657
657
  };
658
658
  }
659
659
 
660
- persistData && store.getLocalPersistData();
660
+ if (persistData) {
661
+ store.getLocalPersistData();
662
+ data = cloneObject(store.data);
663
+ }
661
664
 
662
665
  // 派发init事件,参数为初始化数据
663
666
  const dispatcher = dispatchEvent(
664
667
  'inited',
665
- createObject(this.props.data, {formData: data})
668
+ createObject(this.props.data, data)
666
669
  );
667
670
  if (!dispatcher?.prevented) {
668
671
  onInit && onInit(data, this.props);
@@ -874,10 +877,7 @@ export default class Form extends React.Component<FormProps, object> {
874
877
  if (!isAlive(store)) {
875
878
  return;
876
879
  }
877
- const dispatcher = dispatchEvent(
878
- 'change',
879
- createObject(data, {formData: store.data})
880
- );
880
+ const dispatcher = dispatchEvent('change', createObject(data, store.data));
881
881
  if (!dispatcher?.prevented) {
882
882
  onChange &&
883
883
  onChange(
@@ -31,6 +31,9 @@ import {
31
31
  } from '../Schema';
32
32
  import {IIRendererStore} from '../store';
33
33
 
34
+ import type {ScopedComponentType} from '../Scoped';
35
+ import type {ListenerAction} from '../actions/Action';
36
+
34
37
  /**
35
38
  * Service 服务类控件。
36
39
  * 文档:https://baidu.gitee.io/amis/docs/components/service
@@ -209,6 +212,32 @@ export default class Service extends React.Component<ServiceProps> {
209
212
  }
210
213
  }
211
214
 
215
+ doAction(action: ListenerAction, args: any) {
216
+ if (action?.actionType === 'rebuild') {
217
+ const {
218
+ schemaApi,
219
+ store,
220
+ dataProvider,
221
+ messages: {fetchSuccess, fetchFailed}
222
+ } = this.props;
223
+
224
+ store.updateData(args);
225
+ clearTimeout(this.timer);
226
+ if (isEffectiveApi(schemaApi, store.data)) {
227
+ store
228
+ .fetchSchema(schemaApi, store.data, {
229
+ successMessage: fetchSuccess,
230
+ errorMessage: fetchFailed
231
+ })
232
+ .then(this.afterSchemaFetch);
233
+ }
234
+
235
+ if (dataProvider) {
236
+ this.runDataProvider();
237
+ }
238
+ }
239
+ }
240
+
212
241
  @autobind
213
242
  initFetch() {
214
243
  const {
@@ -331,7 +360,10 @@ export default class Service extends React.Component<ServiceProps> {
331
360
  // 初始化接口返回的是整个 response,
332
361
  // 保存 ajax 请求的时候返回时数据部分。
333
362
  const data = result?.hasOwnProperty('ok') ? result.data : result;
334
- const {onBulkChange} = this.props;
363
+ const {onBulkChange, dispatchEvent} = this.props;
364
+
365
+ dispatchEvent?.('fetchInited', data);
366
+
335
367
  if (!isEmpty(data) && onBulkChange) {
336
368
  onBulkChange(data);
337
369
  }
@@ -340,7 +372,10 @@ export default class Service extends React.Component<ServiceProps> {
340
372
  }
341
373
 
342
374
  afterSchemaFetch(schema: any) {
343
- const {onBulkChange, formStore} = this.props;
375
+ const {onBulkChange, formStore, dispatchEvent} = this.props;
376
+
377
+ dispatchEvent?.('fetchSchemaInited', schema);
378
+
344
379
  if (formStore && schema?.data && onBulkChange) {
345
380
  onBulkChange && onBulkChange(schema.data);
346
381
  }
@@ -586,7 +621,7 @@ export class ServiceRenderer extends Service {
586
621
  super(props);
587
622
 
588
623
  const scoped = context;
589
- scoped.registerComponent(this);
624
+ scoped.registerComponent(this as ScopedComponentType);
590
625
  }
591
626
 
592
627
  reload(subpath?: string, query?: any, ctx?: any, silent?: boolean) {
@@ -613,7 +648,7 @@ export class ServiceRenderer extends Service {
613
648
  componentWillUnmount() {
614
649
  super.componentWillUnmount();
615
650
  const scoped = this.context as IScopedContext;
616
- scoped.unRegisterComponent(this);
651
+ scoped.unRegisterComponent(this as ScopedComponentType);
617
652
  }
618
653
 
619
654
  reloadTarget(target: string, data?: any) {
@@ -622,6 +657,6 @@ export class ServiceRenderer extends Service {
622
657
  }
623
658
 
624
659
  setData(values: object) {
625
- return super.afterDataFetch(values);
660
+ return this.props.store.updateData(values);
626
661
  }
627
662
  }
@@ -342,7 +342,7 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
342
342
 
343
343
  const rendererEvent = await dispatchEvent(
344
344
  action,
345
- createObject(data, value ? value : {})
345
+ value ? createObject(data, value) : data
346
346
  );
347
347
 
348
348
  return rendererEvent?.prevented ?? false;
@@ -350,9 +350,7 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
350
350
 
351
351
  async handleInitEvent(data: any) {
352
352
  const {onInit} = this.props;
353
- (await this.dispatchEvent('inited', {formData: data})) &&
354
- onInit &&
355
- onInit(data);
353
+ (await this.dispatchEvent('inited', data)) && onInit && onInit(data);
356
354
  }
357
355
 
358
356
  @autobind
@@ -390,8 +388,7 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
390
388
  if (index != this.state.currentStep) {
391
389
  if (
392
390
  await this.dispatchEvent('stepChange', {
393
- step: index,
394
- formData: this.props.store.data
391
+ step: index
395
392
  })
396
393
  ) {
397
394
  return;
@@ -812,7 +809,7 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
812
809
  store
813
810
  .saveRemote(action.api || step.api!, store.data, {
814
811
  onSuccess: () => {
815
- this.dispatchEvent('stepSubmitSucc', {formData: store.data});
812
+ this.dispatchEvent('stepSubmitSucc');
816
813
 
817
814
  if (
818
815
  !isEffectiveApi(finnalAsyncApi, store.data) ||