amis 1.9.1-beta.19 → 1.9.1-beta.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. package/lib/components/Radios.d.ts +10 -10
  2. package/lib/components/ResultBox.d.ts +44 -40
  3. package/lib/components/ResultBox.js +43 -7
  4. package/lib/components/ResultBox.js.map +2 -2
  5. package/lib/components/ResultTableList.js +16 -17
  6. package/lib/components/ResultTableList.js.map +2 -2
  7. package/lib/components/Select.d.ts +498 -294
  8. package/lib/components/Select.js +64 -12
  9. package/lib/components/Select.js.map +2 -2
  10. package/lib/components/TableSelection.d.ts +42 -40
  11. package/lib/components/TableSelection.js +7 -2
  12. package/lib/components/TableSelection.js.map +2 -2
  13. package/lib/components/TooltipWrapper.d.ts +1 -1
  14. package/lib/components/TooltipWrapper.js.map +2 -2
  15. package/lib/components/TransferDropDown.d.ts +43 -40
  16. package/lib/components/TransferDropDown.js +2 -2
  17. package/lib/components/TransferDropDown.js.map +2 -2
  18. package/lib/helper.css.map +1 -1
  19. package/lib/index.js +1 -1
  20. package/lib/locale/de-DE.js +1 -1
  21. package/lib/locale/de-DE.js.map +2 -2
  22. package/lib/locale/en-US.js +1 -1
  23. package/lib/locale/en-US.js.map +2 -2
  24. package/lib/renderers/CRUD.js +2 -2
  25. package/lib/renderers/CRUD.js.map +2 -2
  26. package/lib/renderers/Form/DiffEditor.d.ts +66 -20
  27. package/lib/renderers/Form/Editor.d.ts +66 -20
  28. package/lib/renderers/Form/Group.js +1 -1
  29. package/lib/renderers/Form/Group.js.map +2 -2
  30. package/lib/renderers/Form/InputImage.js.map +2 -2
  31. package/lib/renderers/Form/InputTag.d.ts +8 -0
  32. package/lib/renderers/Form/InputTag.js +2 -2
  33. package/lib/renderers/Form/InputTag.js.map +2 -2
  34. package/lib/renderers/Form/Options.js +7 -7
  35. package/lib/renderers/Form/Options.js.map +2 -2
  36. package/lib/renderers/Form/Select.d.ts +24 -0
  37. package/lib/renderers/Form/Select.js +5 -3
  38. package/lib/renderers/Form/Select.js.map +2 -2
  39. package/lib/renderers/Form/Transfer.d.ts +1 -0
  40. package/lib/renderers/Form/Transfer.js +4 -0
  41. package/lib/renderers/Form/Transfer.js.map +2 -2
  42. package/lib/renderers/Form/TreeSelect.d.ts +0 -1
  43. package/lib/renderers/Form/TreeSelect.js +1 -9
  44. package/lib/renderers/Form/TreeSelect.js.map +2 -2
  45. package/lib/renderers/Form/index.js +9 -4
  46. package/lib/renderers/Form/index.js.map +2 -2
  47. package/lib/renderers/QRCode.d.ts +16 -0
  48. package/lib/renderers/QRCode.js +25 -1
  49. package/lib/renderers/QRCode.js.map +2 -2
  50. package/lib/renderers/Table/exportExcel.js +51 -37
  51. package/lib/renderers/Table/exportExcel.js.map +2 -2
  52. package/lib/renderers/Table/index.d.ts +2 -0
  53. package/lib/renderers/Table/index.js +37 -5
  54. package/lib/renderers/Table/index.js.map +2 -2
  55. package/lib/renderers/Tpl.d.ts +4 -0
  56. package/lib/renderers/Tpl.js +6 -3
  57. package/lib/renderers/Tpl.js.map +2 -2
  58. package/lib/store/combo.d.ts +72 -22
  59. package/lib/store/form.d.ts +30 -9
  60. package/lib/store/form.js +28 -10
  61. package/lib/store/form.js.map +2 -2
  62. package/lib/store/formItem.d.ts +3 -1
  63. package/lib/store/formItem.js +3 -5
  64. package/lib/store/formItem.js.map +2 -2
  65. package/lib/store/table.d.ts +60 -18
  66. package/lib/themes/ang-ie11.css +94 -13
  67. package/lib/themes/ang.css +99 -13
  68. package/lib/themes/ang.css.map +1 -1
  69. package/lib/themes/antd-ie11.css +94 -13
  70. package/lib/themes/antd.css +99 -13
  71. package/lib/themes/antd.css.map +1 -1
  72. package/lib/themes/cxd-ie11.css +94 -13
  73. package/lib/themes/cxd.css +101 -13
  74. package/lib/themes/cxd.css.map +1 -1
  75. package/lib/themes/dark-ie11.css +94 -13
  76. package/lib/themes/dark.css +99 -13
  77. package/lib/themes/dark.css.map +1 -1
  78. package/lib/themes/default-ie11.css +94 -13
  79. package/lib/themes/default.css +101 -13
  80. package/lib/themes/default.css.map +1 -1
  81. package/lib/utils/helper.d.ts +1 -0
  82. package/lib/utils/helper.js +11 -1
  83. package/lib/utils/helper.js.map +2 -2
  84. package/package.json +1 -1
  85. package/schema.json +94 -28
  86. package/scss/_mixins.scss +1 -1
  87. package/scss/_properties.scss +11 -6
  88. package/scss/components/_result-box.scss +34 -2
  89. package/scss/components/form/_select.scss +88 -32
  90. package/scss/components/form/_selection.scss +9 -6
  91. package/scss/themes/_cxd-variables.scss +2 -0
  92. package/scss/themes/cxd.scss +0 -2
  93. package/sdk/ang-ie11.css +108 -13
  94. package/sdk/ang.css +113 -13
  95. package/sdk/antd-ie11.css +108 -13
  96. package/sdk/antd.css +113 -13
  97. package/sdk/barcode.js +51 -51
  98. package/sdk/charts.js +14 -14
  99. package/sdk/codemirror.js +7 -7
  100. package/sdk/color-picker.js +65 -65
  101. package/sdk/cropperjs.js +2 -2
  102. package/sdk/cxd-ie11.css +108 -13
  103. package/sdk/cxd.css +115 -13
  104. package/sdk/dark-ie11.css +108 -13
  105. package/sdk/dark.css +113 -13
  106. package/sdk/exceljs.js +1 -1
  107. package/sdk/helper.css.map +1 -1
  108. package/sdk/locale/de-DE.js +2 -2
  109. package/sdk/markdown.js +69 -69
  110. package/sdk/papaparse.js +1 -1
  111. package/sdk/renderers/Form/CityDB.js +1 -1
  112. package/sdk/rest.js +16 -16
  113. package/sdk/rich-text.js +62 -62
  114. package/sdk/sdk-ie11.css +108 -13
  115. package/sdk/sdk.css +115 -13
  116. package/sdk/sdk.js +1341 -1341
  117. package/sdk/thirds/hls.js/hls.js +1 -1
  118. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  119. package/sdk/tinymce.js +57 -57
  120. package/src/components/ResultBox.tsx +98 -12
  121. package/src/components/ResultTableList.tsx +32 -33
  122. package/src/components/Select.tsx +149 -17
  123. package/src/components/TableSelection.tsx +15 -8
  124. package/src/components/TooltipWrapper.tsx +20 -14
  125. package/src/components/TransferDropDown.tsx +9 -1
  126. package/src/locale/de-DE.ts +2 -2
  127. package/src/locale/en-US.ts +2 -2
  128. package/src/renderers/CRUD.tsx +2 -2
  129. package/src/renderers/Form/Group.tsx +1 -1
  130. package/src/renderers/Form/InputImage.tsx +4 -2
  131. package/src/renderers/Form/InputTag.tsx +14 -0
  132. package/src/renderers/Form/Options.tsx +7 -9
  133. package/src/renderers/Form/Select.tsx +41 -2
  134. package/src/renderers/Form/Transfer.tsx +6 -0
  135. package/src/renderers/Form/TreeSelect.tsx +14 -16
  136. package/src/renderers/Form/index.tsx +13 -2
  137. package/src/renderers/QRCode.tsx +50 -1
  138. package/src/renderers/Table/exportExcel.ts +30 -13
  139. package/src/renderers/Table/index.tsx +42 -6
  140. package/src/renderers/Tpl.tsx +11 -1
  141. package/src/store/form.ts +31 -24
  142. package/src/store/formItem.ts +65 -52
  143. package/src/utils/helper.ts +11 -1
@@ -63,7 +63,7 @@ export interface TooltipObject {
63
63
  /**
64
64
  * 浮层内容可通过JSX渲染
65
65
  */
66
- children?: () => JSX.Element | JSX.Element;
66
+ children?: () => JSX.Element;
67
67
  /**
68
68
  * 挂载容器元素
69
69
  */
@@ -98,7 +98,7 @@ export interface TooltipWrapperProps {
98
98
  /**
99
99
  * 显示&隐藏时触发
100
100
  */
101
- onVisibleChange?: (visible: boolean) => void;
101
+ onVisibleChange?: (visible: boolean) => void;
102
102
  }
103
103
 
104
104
  interface TooltipWrapperState {
@@ -153,25 +153,31 @@ export class TooltipWrapper extends React.Component<
153
153
  }
154
154
 
155
155
  show() {
156
- this.setState({
157
- show: true
158
- }, () => {
159
- if (this.props.onVisibleChange) {
160
- this.props.onVisibleChange(true);
156
+ this.setState(
157
+ {
158
+ show: true
159
+ },
160
+ () => {
161
+ if (this.props.onVisibleChange) {
162
+ this.props.onVisibleChange(true);
163
+ }
161
164
  }
162
- });
165
+ );
163
166
  }
164
167
 
165
168
  hide() {
166
169
  waitToHide = null;
167
170
  this.moutned &&
168
- this.setState({
169
- show: false
170
- }, () => {
171
- if (this.props.onVisibleChange) {
172
- this.props.onVisibleChange(false);
171
+ this.setState(
172
+ {
173
+ show: false
174
+ },
175
+ () => {
176
+ if (this.props.onVisibleChange) {
177
+ this.props.onVisibleChange(false);
178
+ }
173
179
  }
174
- });
180
+ );
175
181
  }
176
182
 
177
183
  getChildProps() {
@@ -9,6 +9,8 @@ import InputBox from './InputBox';
9
9
  import PopOverContainer from './PopOverContainer';
10
10
  import {isMobile} from '../utils/helper';
11
11
 
12
+ import type {TooltipObject} from './TooltipWrapper';
13
+
12
14
  export interface TransferDropDownProps extends TransferProps {
13
15
  // 新的属性?
14
16
  multiple?: boolean;
@@ -16,6 +18,8 @@ export interface TransferDropDownProps extends TransferProps {
16
18
  useMobileUI?: boolean;
17
19
  popOverContainer?: any;
18
20
  itemRender: (value: any) => JSX.Element | string;
21
+ maxTagCount?: number;
22
+ overflowTagPopover?: TooltipObject;
19
23
  }
20
24
 
21
25
  export class TransferDropDown extends Transfer<TransferDropDownProps> {
@@ -33,7 +37,9 @@ export class TransferDropDown extends Transfer<TransferDropDownProps> {
33
37
  multiple,
34
38
  borderMode,
35
39
  useMobileUI,
36
- popOverContainer
40
+ popOverContainer,
41
+ maxTagCount,
42
+ overflowTagPopover
37
43
  } = this.props;
38
44
  const {inputValue, searchResult} = this.state;
39
45
 
@@ -109,6 +115,8 @@ export class TransferDropDown extends Transfer<TransferDropDownProps> {
109
115
  placeholder={__('Select.placeholder')}
110
116
  disabled={disabled}
111
117
  clearable={clearable}
118
+ maxTagCount={maxTagCount}
119
+ overflowTagPopover={overflowTagPopover}
112
120
  ref={ref}
113
121
  itemRender={itemRender}
114
122
  useMobileUI={useMobileUI}
@@ -132,7 +132,7 @@ register('de-DE', {
132
132
  'File.retry': 'Wiederholen',
133
133
  'File.start': 'Hochladen beginnen',
134
134
  'File.upload': 'Hochladen',
135
- 'Image.upload':'Hochladen',
135
+ 'Image.upload': 'Hochladen',
136
136
  'File.uploadFailed': 'Zurückgegebene Daten der Upload-API sind leer',
137
137
  'File.uploading': 'Wird hochgeladen...',
138
138
  'FormItem.autoUpdateloadFaild': 'Die Schnittstelle hat einen Fehler zurückgegeben, bitte sorgfältig prüfen',
@@ -333,5 +333,5 @@ register('de-DE', {
333
333
  'JSONSchema.description': 'Description',
334
334
  'JSONSchema.key': 'Key',
335
335
  'JSONSchema.array_items': 'Items',
336
- 'TimeNow': 'Jetzt',
336
+ 'TimeNow': 'Jetzt'
337
337
  });
@@ -134,7 +134,7 @@ register('en-US', {
134
134
  'File.sizeLimit': 'The maximum file size is {{maxSize}} B',
135
135
  'File.start': 'Start upload',
136
136
  'File.upload': 'Upload',
137
- 'Image.upload':'Upload image',
137
+ 'Image.upload': 'Upload image',
138
138
  'File.uploadFailed': 'return data of udpload api is empty',
139
139
  'File.uploading': 'Uploading',
140
140
  'FormItem.autoUpdateloadFaild': 'return data of autoUpdate api is error',
@@ -336,5 +336,5 @@ register('en-US', {
336
336
  'JSONSchema.description': 'Description',
337
337
  'JSONSchema.key': 'Key',
338
338
  'JSONSchema.array_items': 'Items',
339
- 'TimeNow': 'Now',
339
+ 'TimeNow': 'Now'
340
340
  });
@@ -490,8 +490,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
490
490
  // 另外autoGenerateFilter时,table 里面会单独处理这块逻辑
491
491
  // 所以这里应该忽略 autoGenerateFilter 情况
492
492
  if (
493
- (!this.props.filter || (store.filterTogggable && !store.filterVisible)) &&
494
- !autoGenerateFilter
493
+ (!this.props.filter && !autoGenerateFilter) ||
494
+ (store.filterTogggable && !store.filterVisible)
495
495
  ) {
496
496
  this.handleFilterInit({});
497
497
  }
@@ -89,7 +89,7 @@ export class ControlGroupRenderer extends React.Component<InputGroupProps> {
89
89
  const subSchema: any = control;
90
90
 
91
91
  return render(`${index}`, subSchema, {
92
- disabled,
92
+ disabled: control.disabled || disabled,
93
93
  formMode: subFormMode || mode || formMode,
94
94
  formHorizontal: subFormHorizontal || horizontal || formHorizontal,
95
95
  ...otherProps
@@ -1569,7 +1569,7 @@ export default class ImageControl extends React.Component<
1569
1569
  />
1570
1570
  </a>
1571
1571
  ) : null}
1572
-
1572
+
1573
1573
  {!disabled ? (
1574
1574
  <a
1575
1575
  data-tooltip={__('Select.clear')}
@@ -1636,7 +1636,9 @@ export default class ImageControl extends React.Component<
1636
1636
  ) : (
1637
1637
  <>
1638
1638
  <Icon icon="plus-fine" className="icon" />
1639
- <span className={cx('ImageControl-addBtn-text')}>{__('Image.upload')}</span>
1639
+ <span className={cx('ImageControl-addBtn-text')}>
1640
+ {__('Image.upload')}
1641
+ </span>
1640
1642
  </>
1641
1643
  )}
1642
1644
 
@@ -32,6 +32,16 @@ export interface TagControlSchema extends FormOptionsControl {
32
32
  * 是否为下拉模式
33
33
  */
34
34
  dropdown?: boolean;
35
+
36
+ /**
37
+ * 标签的最大展示数量,超出数量后以收纳浮层的方式展示,仅在多选模式开启后生效
38
+ */
39
+ maxTagCount?: number;
40
+
41
+ /**
42
+ * 收纳标签的Popover配置
43
+ */
44
+ overflowTagPopover?: object;
35
45
  }
36
46
 
37
47
  // declare function matchSorter(items:Array<any>, input:any, options:any): Array<any>;
@@ -316,6 +326,8 @@ export default class TagControl extends React.PureComponent<
316
326
  dropdown,
317
327
  options,
318
328
  optionsTip,
329
+ maxTagCount,
330
+ overflowTagPopover,
319
331
  translate: __
320
332
  } = this.props;
321
333
 
@@ -359,6 +371,8 @@ export default class TagControl extends React.PureComponent<
359
371
  onResultChange={this.handleChange}
360
372
  itemRender={this.renderItem}
361
373
  clearable={clearable}
374
+ maxTagCount={maxTagCount}
375
+ overflowTagPopover={overflowTagPopover}
362
376
  allowInput
363
377
  >
364
378
  {loading ? <Spinner size="sm" /> : undefined}
@@ -320,10 +320,14 @@ export function registerOptionsControl(config: OptionsConfig) {
320
320
 
321
321
  this.toDispose.push(
322
322
  reaction(
323
- () => JSON.stringify(formItem.options),
324
- () => this.mounted && this.syncAutoFill(formItem.tmpValue)
323
+ () =>
324
+ JSON.stringify(formItem.getSelectedOptions(formItem.tmpValue)),
325
+ () =>
326
+ this.mounted &&
327
+ this.syncAutoFill(formItem.getSelectedOptions(formItem.tmpValue))
325
328
  )
326
329
  );
330
+
327
331
  // 默认全选。这里会和默认值\回填值逻辑冲突,所以如果有配置source则不执行默认全选
328
332
  if (
329
333
  multiple &&
@@ -361,10 +365,6 @@ export function registerOptionsControl(config: OptionsConfig) {
361
365
  componentDidMount() {
362
366
  this.mounted = true;
363
367
  this.normalizeValue();
364
-
365
- if (this.props.value) {
366
- this.syncAutoFill(this.props.value);
367
- }
368
368
  }
369
369
 
370
370
  shouldComponentUpdate(nextProps: OptionsProps) {
@@ -448,7 +448,6 @@ export function registerOptionsControl(config: OptionsConfig) {
448
448
 
449
449
  if (prevProps.value !== props.value || formItem?.expressionsInOptions) {
450
450
  formItem.syncOptions(undefined, props.data);
451
- this.syncAutoFill(props.value);
452
451
  }
453
452
  }
454
453
 
@@ -482,7 +481,7 @@ export function registerOptionsControl(config: OptionsConfig) {
482
481
  }
483
482
  }
484
483
 
485
- syncAutoFill(value: any) {
484
+ syncAutoFill(selectedOptions: Array<any>) {
486
485
  const {autoFill, multiple, onBulkChange, data} = this.props;
487
486
  const formItem = this.props.formItem as IFormItemStore;
488
487
 
@@ -492,7 +491,6 @@ export function registerOptionsControl(config: OptionsConfig) {
492
491
  !isEmpty(autoFill) &&
493
492
  formItem.filteredOptions.length
494
493
  ) {
495
- const selectedOptions = formItem.getSelectedOptions(value);
496
494
  const toSync = dataMapping(
497
495
  autoFill,
498
496
  multiple
@@ -18,6 +18,9 @@ import Spinner from '../../components/Spinner';
18
18
  import {BaseTransferRenderer, TransferControlSchema} from './Transfer';
19
19
  import TransferDropDown from '../../components/TransferDropDown';
20
20
 
21
+ import type {TooltipObject} from '../../components/TooltipWrapper';
22
+ import type {SchemaClassName} from '../../Schema';
23
+
21
24
  /**
22
25
  * Select 下拉选择框。
23
26
  * 文档:https://baidu.gitee.io/amis/docs/components/form/select
@@ -85,18 +88,46 @@ export interface SelectControlSchema extends FormOptionsControl {
85
88
  * 搜索 API
86
89
  */
87
90
  searchApi?: SchemaApi;
91
+
92
+ /**
93
+ * 单个选项的高度,主要用于虚拟渲染
94
+ */
95
+ itemHeight?: number;
96
+
97
+ /**
98
+ * 在选项数量达到多少时开启虚拟渲染
99
+ */
100
+ virtualThreshold?: number;
101
+
88
102
  /**
89
103
  * 可多选条件下,是否可全选
90
104
  */
91
105
  checkAll?: boolean;
106
+
92
107
  /**
93
108
  * 可多选条件下,是否默认全选中所有值
94
109
  */
95
110
  defaultCheckAll?: boolean;
111
+
96
112
  /**
97
113
  * 可多选条件下,全选项文案,默认 ”全选“
98
114
  */
99
115
  checkAllLabel?: string;
116
+
117
+ /**
118
+ * 标签的最大展示数量,超出数量后以收纳浮层的方式展示,仅在多选模式开启后生效
119
+ */
120
+ maxTagCount?: number;
121
+
122
+ /**
123
+ * 收纳标签的Popover配置
124
+ */
125
+ overflowTagPopover?: object;
126
+
127
+ /**
128
+ * 选项的自定义CSS类名
129
+ */
130
+ optionClassName?: SchemaClassName;
100
131
  }
101
132
 
102
133
  export interface SelectProps extends OptionsControlProps {
@@ -104,6 +135,8 @@ export interface SelectProps extends OptionsControlProps {
104
135
  searchable?: boolean;
105
136
  defaultOpen?: boolean;
106
137
  useMobileUI?: boolean;
138
+ maxTagCount?: number;
139
+ overflowTagPopover?: TooltipObject;
107
140
  }
108
141
 
109
142
  export type SelectRendererEvent =
@@ -322,9 +355,11 @@ export default class SelectControl extends React.Component<SelectProps, any> {
322
355
 
323
356
  @autobind
324
357
  renderMenu(option: Option, state: any) {
325
- const {menuTpl, render, data} = this.props;
358
+ const {menuTpl, render, data, optionClassName} = this.props;
326
359
 
327
360
  return render(`menu/${state.index}`, menuTpl, {
361
+ showNativeTitle: true,
362
+ className: cx('Select-option-content', optionClassName),
328
363
  data: createObject(createObject(data, state), option)
329
364
  });
330
365
  }
@@ -476,7 +511,9 @@ class TransferDropdownRenderer extends BaseTransferRenderer<TransferDropDownProp
476
511
  leftMode,
477
512
  borderMode,
478
513
  useMobileUI,
479
- popOverContainer
514
+ popOverContainer,
515
+ maxTagCount,
516
+ overflowTagPopover
480
517
  } = this.props;
481
518
 
482
519
  // 目前 LeftOptions 没有接口可以动态加载
@@ -520,6 +557,8 @@ class TransferDropdownRenderer extends BaseTransferRenderer<TransferDropDownProp
520
557
  borderMode={borderMode}
521
558
  useMobileUI={useMobileUI}
522
559
  popOverContainer={popOverContainer}
560
+ maxTagCount={maxTagCount}
561
+ overflowTagPopover={overflowTagPopover}
523
562
  />
524
563
 
525
564
  <Spinner overlay key="info" show={loading} />
@@ -150,6 +150,12 @@ export class BaseTransferRenderer<
150
150
  > extends React.Component<T> {
151
151
  tranferRef?: BaseTransfer;
152
152
 
153
+ reload() {
154
+ const {reloadOptions} = this.props;
155
+
156
+ reloadOptions?.();
157
+ }
158
+
153
159
  @autobind
154
160
  async handleChange(value: Array<Option> | Option, optionModified?: boolean) {
155
161
  const {
@@ -112,7 +112,6 @@ export interface TreeSelectProps extends OptionsControlProps {
112
112
 
113
113
  export interface TreeSelectState {
114
114
  isOpened: boolean;
115
- isFocused: boolean;
116
115
  inputValue: string;
117
116
  }
118
117
 
@@ -157,8 +156,7 @@ export default class TreeSelectControl extends React.Component<
157
156
 
158
157
  this.state = {
159
158
  inputValue: '',
160
- isOpened: false,
161
- isFocused: false
159
+ isOpened: false
162
160
  };
163
161
 
164
162
  this.open = this.open.bind(this);
@@ -206,22 +204,23 @@ export default class TreeSelectControl extends React.Component<
206
204
 
207
205
  handleFocus(e: any) {
208
206
  const {dispatchEvent, value, data} = this.props;
209
- this.setState({
210
- isFocused: true
211
- });
212
- dispatchEvent('focus', createObject(data, {
213
- value
214
- }));
207
+
208
+ dispatchEvent(
209
+ 'focus',
210
+ createObject(data, {
211
+ value
212
+ })
213
+ );
215
214
  }
216
215
 
217
216
  handleBlur(e: any) {
218
217
  const {dispatchEvent, value, data} = this.props;
219
- this.setState({
220
- isFocused: false
221
- });
222
- dispatchEvent('blur', createObject(data, {
223
- value
224
- }));
218
+ dispatchEvent(
219
+ 'blur',
220
+ createObject(data, {
221
+ value
222
+ })
223
+ );
225
224
  }
226
225
 
227
226
  handleKeyPress(e: React.KeyboardEvent) {
@@ -645,7 +644,6 @@ export default class TreeSelectControl extends React.Component<
645
644
  'TreeSelect--searchable':
646
645
  searchable || isEffectiveApi(autoComplete),
647
646
  'is-opened': this.state.isOpened,
648
- 'is-focused': this.state.isFocused,
649
647
  'is-disabled': disabled
650
648
  })}
651
649
  result={
@@ -63,7 +63,7 @@ export interface FormSchemaHorizontal {
63
63
  right?: number;
64
64
  leftFixed?: boolean | number | 'xs' | 'sm' | 'md' | 'lg';
65
65
  justify?: boolean; // 两端对齐
66
- labelAlign?: 'left' | 'right' // label对齐方式
66
+ labelAlign?: 'left' | 'right'; // label对齐方式
67
67
  }
68
68
 
69
69
  /**
@@ -988,7 +988,14 @@ export default class Form extends React.Component<FormProps, object> {
988
988
  data = store.data;
989
989
  }
990
990
  if (Array.isArray(action.required) && action.required.length) {
991
- return store.validateFields(action.required).then(async result => {
991
+ store.clearErrors(); // 如果是按钮指定了required,则校验前先清空一下遗留的校验报错
992
+
993
+ const fields = action.required.map(item => ({
994
+ name: item,
995
+ rules: {isRequired: true}
996
+ }));
997
+
998
+ return store.validateFields(fields).then(async result => {
992
999
  if (!result) {
993
1000
  const dispatcher = await dispatchEvent(
994
1001
  'validateError',
@@ -997,6 +1004,9 @@ export default class Form extends React.Component<FormProps, object> {
997
1004
  if (!dispatcher?.prevented) {
998
1005
  env.notify('error', __('Form.validateFailed'));
999
1006
  }
1007
+
1008
+ /** 抛异常是为了在dialog中catch这个错误,避免弹窗直接关闭 */
1009
+ return Promise.reject(__('Form.validateFailed'));
1000
1010
  } else {
1001
1011
  dispatchEvent('validateSucc', this.props.data);
1002
1012
  this.handleAction(
@@ -1006,6 +1016,7 @@ export default class Form extends React.Component<FormProps, object> {
1006
1016
  throwErrors,
1007
1017
  delegate
1008
1018
  );
1019
+ return;
1009
1020
  }
1010
1021
  });
1011
1022
  }
@@ -1,11 +1,22 @@
1
1
  import React from 'react';
2
2
  import cx from 'classnames';
3
+ import mapValues from 'lodash/mapValues';
3
4
  import {Renderer, RendererProps} from '../factory';
4
5
  import {FormItem, FormControlProps} from './Form/Item';
5
6
  import {filter} from '../utils/tpl';
6
7
  import {QRCodeSVG} from 'qrcode.react';
7
8
  import {BaseSchema, SchemaClassName} from '../Schema';
8
- import {getPropValue} from '../utils/helper';
9
+ import {getPropValue, isObject, isNumeric} from '../utils/helper';
10
+ import {isPureVariable, resolveVariableAndFilter} from '../utils/tpl-builtin';
11
+
12
+ export interface QRCodeImageSettings {
13
+ src: string;
14
+ height: number;
15
+ width: number;
16
+ excavate: boolean;
17
+ x?: number;
18
+ y?: number;
19
+ }
9
20
 
10
21
  /**
11
22
  * 二维码展示控件。
@@ -49,6 +60,11 @@ export interface QRCodeSchema extends BaseSchema {
49
60
  * 占位符
50
61
  */
51
62
  placeholder?: string;
63
+
64
+ /**
65
+ * 图片配置
66
+ */
67
+ imageSettings?: QRCodeImageSettings;
52
68
  }
53
69
 
54
70
  export interface QRCodeProps
@@ -65,6 +81,38 @@ export default class QRCode extends React.Component<QRCodeProps, any> {
65
81
  placeholder: '-'
66
82
  };
67
83
 
84
+ /**
85
+ * 获取图片配置
86
+ */
87
+ getImageSettings(): QRCodeImageSettings | undefined {
88
+ const {imageSettings, data} = this.props;
89
+
90
+ if (
91
+ !imageSettings ||
92
+ !isObject(imageSettings) ||
93
+ !imageSettings.src ||
94
+ typeof imageSettings.src !== 'string'
95
+ ) {
96
+ return undefined;
97
+ }
98
+
99
+ if (isPureVariable(imageSettings.src)) {
100
+ imageSettings.src = resolveVariableAndFilter(
101
+ imageSettings.src,
102
+ data,
103
+ '| raw'
104
+ );
105
+ }
106
+
107
+ return mapValues(imageSettings, (value: any, key: string) => {
108
+ if (!!~['width', 'height', 'x', 'y'].indexOf(key)) {
109
+ /** 处理非数字格式的输入,QRCodeSVG内部会对空值进行默认赋值 */
110
+ return isNumeric(value) ? Number(value) : null;
111
+ }
112
+ return value;
113
+ });
114
+ }
115
+
68
116
  render() {
69
117
  const {
70
118
  className,
@@ -102,6 +150,7 @@ export default class QRCode extends React.Component<QRCodeProps, any> {
102
150
  bgColor={backgroundColor}
103
151
  fgColor={foregroundColor}
104
152
  level={level || 'L'}
153
+ imageSettings={this.getImageSettings()}
105
154
  />
106
155
  )}
107
156
  </div>
@@ -91,6 +91,10 @@ export async function exportExcel(
91
91
  // 自定义导出列配置
92
92
  if (toolbar.exportColumns && Array.isArray(toolbar.exportColumns)) {
93
93
  columns = toolbar.exportColumns;
94
+ // 因为后面列 props 都是从 pristine 里获取,所以这里归一一下
95
+ for (const column of columns) {
96
+ column.pristine = column;
97
+ }
94
98
  }
95
99
 
96
100
  const filteredColumns = exportColumnNames
@@ -123,14 +127,15 @@ export async function exportExcel(
123
127
  // 数据从第二行开始
124
128
  let rowIndex = 1;
125
129
  for (const row of rows) {
130
+ const rowData = createObject(data, row.data);
126
131
  rowIndex += 1;
127
132
  const sheetRow = worksheet.getRow(rowIndex);
128
133
  let columIndex = 0;
129
134
  for (const column of filteredColumns) {
130
135
  columIndex += 1;
131
136
  const name = column.name!;
132
- const value = getVariable(row.data, name);
133
- if (typeof value === 'undefined' && !(column as TplSchema).tpl) {
137
+ const value = getVariable(rowData, name);
138
+ if (typeof value === 'undefined' && !column.pristine.tpl) {
134
139
  continue;
135
140
  }
136
141
  // 处理合并单元格
@@ -199,21 +204,33 @@ export async function exportExcel(
199
204
  console.warn(e.stack);
200
205
  }
201
206
  } else if (type == 'link') {
202
- const linkURL = getAbsoluteUrl(value);
207
+ const href = column.pristine.href;
208
+ const linkURL =
209
+ (typeof href === 'string' && href
210
+ ? filter(href, rowData, '| raw')
211
+ : undefined) || value;
212
+ const body = column.pristine.body;
213
+ // 没法支持嵌套了
214
+ const text =
215
+ typeof body === 'string' && body
216
+ ? filter(body, rowData, '| raw')
217
+ : undefined;
218
+
219
+ const absoluteURL = getAbsoluteUrl(linkURL);
203
220
  sheetRow.getCell(columIndex).value = {
204
- text: value,
205
- hyperlink: linkURL
221
+ text: text || absoluteURL,
222
+ hyperlink: absoluteURL
206
223
  };
207
- } else if (type === 'mapping') {
224
+ } else if (type === 'mapping' || (type as any) === 'static-mapping') {
208
225
  // 拷贝自 Mapping.tsx
209
- let map = (column as MappingSchema).map;
210
- const source = (column as MappingSchema).source;
226
+ let map = column.pristine.map;
227
+ const source = column.pristine.source;
211
228
  if (source) {
212
229
  let sourceValue = source;
213
230
  if (isPureVariable(source)) {
214
231
  sourceValue = resolveVariableAndFilter(
215
232
  source as string,
216
- data,
233
+ rowData,
217
234
  '| raw'
218
235
  );
219
236
  }
@@ -222,7 +239,7 @@ export async function exportExcel(
222
239
  if (mapKey in remoteMappingCache) {
223
240
  map = remoteMappingCache[mapKey];
224
241
  } else {
225
- const res = await env.fetcher(sourceValue, data);
242
+ const res = await env.fetcher(sourceValue, rowData);
226
243
  if (res.data) {
227
244
  remoteMappingCache[mapKey] = res.data;
228
245
  map = res.data;
@@ -248,7 +265,7 @@ export async function exportExcel(
248
265
  fromNow,
249
266
  format = 'YYYY-MM-DD',
250
267
  valueFormat = 'X'
251
- } = column as DateSchema;
268
+ } = column.pristine;
252
269
  if (value) {
253
270
  let ISODate = moment(value, moment.ISO_8601);
254
271
  let NormalDate = moment(value, valueFormat);
@@ -267,9 +284,9 @@ export async function exportExcel(
267
284
  sheetRow.getCell(columIndex).value = viewValue;
268
285
  }
269
286
  } else {
270
- if ((column as TplSchema).tpl) {
287
+ if (column.pristine.tpl) {
271
288
  sheetRow.getCell(columIndex).value = removeHTMLTag(
272
- filter((column as TplSchema).tpl, createObject(data, row.data))
289
+ filter(column.pristine.tpl, rowData)
273
290
  );
274
291
  } else {
275
292
  sheetRow.getCell(columIndex).value = value;