amis 1.3.5-beta.7 → 1.4.0

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 (176) hide show
  1. package/lib/components/Badge.d.ts +13 -1
  2. package/lib/components/Badge.js +16 -2
  3. package/lib/components/Badge.js.map +2 -2
  4. package/lib/components/Checkbox.d.ts +1 -1
  5. package/lib/components/Checkbox.js +1 -1
  6. package/lib/components/Checkbox.js.map +2 -2
  7. package/lib/components/Drawer.js +1 -1
  8. package/lib/components/Drawer.js.map +2 -2
  9. package/lib/components/Modal.js +1 -1
  10. package/lib/components/Modal.js.map +2 -2
  11. package/lib/components/Select.d.ts +7 -0
  12. package/lib/components/Select.js.map +2 -2
  13. package/lib/components/Steps.d.ts +3 -3
  14. package/lib/components/Steps.js.map +1 -1
  15. package/lib/components/WithRemoteConfig.d.ts +8 -0
  16. package/lib/components/WithRemoteConfig.js +28 -2
  17. package/lib/components/WithRemoteConfig.js.map +2 -2
  18. package/lib/components/condition-builder/Field.js +0 -1
  19. package/lib/components/condition-builder/Field.js.map +2 -2
  20. package/lib/components/condition-builder/Value.js +2 -1
  21. package/lib/components/condition-builder/Value.js.map +2 -2
  22. package/lib/components/condition-builder/types.d.ts +5 -0
  23. package/lib/components/condition-builder/types.js.map +1 -1
  24. package/lib/factory.d.ts +5 -1
  25. package/lib/factory.js +9 -4
  26. package/lib/factory.js.map +2 -2
  27. package/lib/index.js +1 -1
  28. package/lib/locale/de-DE.js +1 -0
  29. package/lib/locale/de-DE.js.map +2 -2
  30. package/lib/locale/en-US.js +2 -1
  31. package/lib/locale/en-US.js.map +2 -2
  32. package/lib/locale/zh-CN.js +2 -1
  33. package/lib/locale/zh-CN.js.map +2 -2
  34. package/lib/renderers/CRUD.js +5 -15
  35. package/lib/renderers/CRUD.js.map +2 -2
  36. package/lib/renderers/Collapse.d.ts +1 -1
  37. package/lib/renderers/Collapse.js +5 -1
  38. package/lib/renderers/Collapse.js.map +2 -2
  39. package/lib/renderers/Dialog.d.ts +0 -252
  40. package/lib/renderers/Dialog.js +1 -1
  41. package/lib/renderers/Dialog.js.map +2 -2
  42. package/lib/renderers/DropDownButton.d.ts +4 -0
  43. package/lib/renderers/DropDownButton.js +2 -2
  44. package/lib/renderers/DropDownButton.js.map +2 -2
  45. package/lib/renderers/Form/DiffEditor.d.ts +0 -2
  46. package/lib/renderers/Form/Editor.d.ts +0 -2
  47. package/lib/renderers/Form/Editor.js +1 -1
  48. package/lib/renderers/Form/Editor.js.map +2 -2
  49. package/lib/renderers/Form/InputExcel.d.ts +5 -0
  50. package/lib/renderers/Form/InputExcel.js +24 -3
  51. package/lib/renderers/Form/InputExcel.js.map +2 -2
  52. package/lib/renderers/Form/InputImage.d.ts +8 -0
  53. package/lib/renderers/Form/InputImage.js +2 -1
  54. package/lib/renderers/Form/InputImage.js.map +2 -2
  55. package/lib/renderers/Form/InputTable.d.ts +23 -5
  56. package/lib/renderers/Form/InputTable.js +32 -3
  57. package/lib/renderers/Form/InputTable.js.map +2 -2
  58. package/lib/renderers/Json.js +5 -1
  59. package/lib/renderers/Json.js.map +2 -2
  60. package/lib/renderers/Page.js +3 -0
  61. package/lib/renderers/Page.js.map +2 -2
  62. package/lib/renderers/Service.d.ts +10 -1
  63. package/lib/renderers/Service.js +85 -3
  64. package/lib/renderers/Service.js.map +2 -2
  65. package/lib/renderers/Steps.d.ts +4 -4
  66. package/lib/renderers/Steps.js +5 -2
  67. package/lib/renderers/Steps.js.map +2 -2
  68. package/lib/renderers/Table/TableBody.d.ts +1 -1
  69. package/lib/renderers/Table/TableBody.js.map +1 -1
  70. package/lib/renderers/Table/TableContent.d.ts +1 -1
  71. package/lib/renderers/Table/TableContent.js.map +1 -1
  72. package/lib/renderers/Table/index.d.ts +8 -3
  73. package/lib/renderers/Table/index.js +80 -45
  74. package/lib/renderers/Table/index.js.map +2 -2
  75. package/lib/store/app.d.ts +0 -1
  76. package/lib/store/combo.d.ts +0 -2
  77. package/lib/store/crud.d.ts +0 -1
  78. package/lib/store/form.d.ts +0 -1
  79. package/lib/store/modal.d.ts +1 -1
  80. package/lib/store/modal.js +4 -0
  81. package/lib/store/modal.js.map +2 -2
  82. package/lib/store/root.d.ts +0 -1
  83. package/lib/store/service.d.ts +0 -1
  84. package/lib/store/service.js +0 -13
  85. package/lib/store/service.js.map +2 -2
  86. package/lib/store/table.d.ts +1 -2
  87. package/lib/store/table.js +44 -3
  88. package/lib/store/table.js.map +2 -2
  89. package/lib/themes/ang-ie11.css +247 -3
  90. package/lib/themes/ang.css +247 -3
  91. package/lib/themes/ang.css.map +1 -1
  92. package/lib/themes/antd-ie11.css +247 -3
  93. package/lib/themes/antd.css +247 -3
  94. package/lib/themes/antd.css.map +1 -1
  95. package/lib/themes/cxd-ie11.css +247 -3
  96. package/lib/themes/cxd.css +247 -3
  97. package/lib/themes/cxd.css.map +1 -1
  98. package/lib/themes/dark-ie11.css +247 -3
  99. package/lib/themes/dark.css +247 -3
  100. package/lib/themes/dark.css.map +1 -1
  101. package/lib/themes/default.css +247 -3
  102. package/lib/themes/default.css.map +1 -1
  103. package/lib/utils/api.js +12 -0
  104. package/lib/utils/api.js.map +2 -2
  105. package/lib/utils/attachmentAdpator.d.ts +7 -0
  106. package/lib/utils/attachmentAdpator.js +82 -0
  107. package/lib/utils/attachmentAdpator.js.map +13 -0
  108. package/lib/utils/validations.js +62 -5
  109. package/lib/utils/validations.js.map +2 -2
  110. package/package.json +1 -1
  111. package/schema.json +150 -36
  112. package/scss/_properties.scss +4 -0
  113. package/scss/components/_badge.scss +15 -1
  114. package/scss/components/_markdown.scss +266 -0
  115. package/scss/components/_spinner.scss +6 -2
  116. package/scss/components/form/_group.scss +4 -0
  117. package/scss/themes/_common.scss +1 -0
  118. package/sdk/ang-ie11.css +292 -3
  119. package/sdk/ang.css +296 -3
  120. package/sdk/antd-ie11.css +292 -3
  121. package/sdk/antd.css +296 -3
  122. package/sdk/charts.js +13 -13
  123. package/sdk/color-picker.js +65 -69
  124. package/sdk/cropperjs.js +2 -2
  125. package/sdk/cxd-ie11.css +292 -3
  126. package/sdk/cxd.css +296 -3
  127. package/sdk/dark-ie11.css +292 -3
  128. package/sdk/dark.css +296 -3
  129. package/sdk/exceljs.js +1 -1
  130. package/sdk/locale/de-DE.js +1 -0
  131. package/sdk/markdown.js +69 -69
  132. package/sdk/papaparse.js +1 -1
  133. package/sdk/renderers/Form/CityDB.js +1 -1
  134. package/sdk/rest.js +27 -23
  135. package/sdk/rich-text.js +63 -63
  136. package/sdk/sdk-ie11.css +292 -3
  137. package/sdk/sdk.css +296 -3
  138. package/sdk/sdk.js +1144 -1142
  139. package/sdk/thirds/hls.js/hls.js +1 -1
  140. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  141. package/sdk/tinymce.js +57 -57
  142. package/src/components/Badge.tsx +41 -6
  143. package/src/components/Checkbox.tsx +5 -2
  144. package/src/components/Drawer.tsx +3 -2
  145. package/src/components/Modal.tsx +3 -2
  146. package/src/components/Select.tsx +1 -0
  147. package/src/components/Steps.tsx +3 -3
  148. package/src/components/WithRemoteConfig.tsx +37 -2
  149. package/src/components/condition-builder/Field.tsx +1 -2
  150. package/src/components/condition-builder/Value.tsx +3 -0
  151. package/src/components/condition-builder/types.ts +6 -0
  152. package/src/factory.tsx +13 -3
  153. package/src/locale/de-DE.ts +1 -0
  154. package/src/locale/en-US.ts +2 -1
  155. package/src/locale/zh-CN.ts +2 -1
  156. package/src/renderers/CRUD.tsx +7 -28
  157. package/src/renderers/Collapse.tsx +5 -1
  158. package/src/renderers/Dialog.tsx +1 -1
  159. package/src/renderers/DropDownButton.tsx +8 -0
  160. package/src/renderers/Form/Editor.tsx +19 -20
  161. package/src/renderers/Form/InputExcel.tsx +28 -3
  162. package/src/renderers/Form/InputImage.tsx +23 -8
  163. package/src/renderers/Form/InputTable.tsx +88 -9
  164. package/src/renderers/Json.tsx +10 -1
  165. package/src/renderers/Page.tsx +2 -0
  166. package/src/renderers/Service.tsx +101 -3
  167. package/src/renderers/Steps.tsx +12 -9
  168. package/src/renderers/Table/TableBody.tsx +1 -1
  169. package/src/renderers/Table/TableContent.tsx +1 -1
  170. package/src/renderers/Table/index.tsx +61 -13
  171. package/src/store/modal.ts +4 -0
  172. package/src/store/service.ts +0 -19
  173. package/src/store/table.ts +48 -0
  174. package/src/utils/api.ts +11 -0
  175. package/src/utils/attachmentAdpator.ts +90 -0
  176. package/src/utils/validations.ts +80 -12
@@ -17,7 +17,7 @@ export interface BadgeSchema extends BaseSchema {
17
17
  /**
18
18
  * 文本内容
19
19
  */
20
- text?: string;
20
+ text?: string | number;
21
21
 
22
22
  /**
23
23
  * 大小
@@ -29,11 +29,21 @@ export interface BadgeSchema extends BaseSchema {
29
29
  */
30
30
  mode?: 'text' | 'dot';
31
31
 
32
+ /**
33
+ * 角标位置,优先级大于position
34
+ */
35
+ offset?: [number | string, number | string];
36
+
32
37
  /**
33
38
  * 角标位置
34
39
  */
35
40
  position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
36
41
 
42
+ /**
43
+ * 封顶的数字值
44
+ */
45
+ overflowCount?: number;
46
+
37
47
  /**
38
48
  * 动态控制是否显示
39
49
  */
@@ -50,6 +60,11 @@ export interface BadgeSchema extends BaseSchema {
50
60
  style?: {
51
61
  [propName: string]: any;
52
62
  };
63
+
64
+ /**
65
+ * 提示类型
66
+ */
67
+ level?: 'info' | 'warning' | 'success' | 'danger';
53
68
  }
54
69
 
55
70
  export interface BadgeProps {
@@ -81,10 +96,13 @@ export class Badge extends React.Component<BadgeProps, object> {
81
96
  text,
82
97
  size,
83
98
  style,
99
+ offset,
84
100
  position = 'top-right',
101
+ overflowCount = 99,
85
102
  visibleOn,
86
103
  className,
87
- animation
104
+ animation,
105
+ level = 'danger'
88
106
  } = badge;
89
107
 
90
108
  if (visibleOn) {
@@ -111,6 +129,12 @@ export class Badge extends React.Component<BadgeProps, object> {
111
129
  height: size,
112
130
  lineHeight: size + 'px'
113
131
  };
132
+ // 当text、overflowCount都为number类型时,进行封顶值处理
133
+ if (typeof text === 'number' && typeof overflowCount === 'number') {
134
+ text = (
135
+ (text as number) > (overflowCount as number) ? `${overflowCount}+` : text
136
+ ) as string | number;
137
+ }
114
138
 
115
139
  if (!text) {
116
140
  isDisplay = false;
@@ -121,6 +145,17 @@ export class Badge extends React.Component<BadgeProps, object> {
121
145
  sizeStyle = {width: size, height: size};
122
146
  }
123
147
 
148
+ let offsetStyle = {};
149
+ // 如果设置了offset属性,offset在position为'top-right'的基础上进行translate定位
150
+ if (offset && offset.length) {
151
+ position = 'top-right';
152
+ const left = `calc(50% + ${parseInt(offset[0] as string, 10)}px)`;
153
+ const right = `calc(-50% + ${parseInt(offset[1] as string, 10)}px)`;
154
+ offsetStyle = {
155
+ transform: `translate(${left}, ${right})`,
156
+ };
157
+ }
158
+
124
159
  let animationBackground = 'var(--danger)';
125
160
 
126
161
  if (style && style.background) {
@@ -148,15 +183,15 @@ export class Badge extends React.Component<BadgeProps, object> {
148
183
  {isDisplay ? (
149
184
  mode === 'dot' ? (
150
185
  <span
151
- className={cx('Badge-dot', `Badge--${position}`)}
152
- style={{...sizeStyle, ...style}}
186
+ className={cx('Badge-dot', `Badge--${position}`, `Badge--${level}`)}
187
+ style={{...offsetStyle, ...sizeStyle, ...style}}
153
188
  >
154
189
  {animationElement}
155
190
  </span>
156
191
  ) : (
157
192
  <span
158
- className={cx('Badge-text', `Badge--${position}`)}
159
- style={{...sizeStyle, ...style}}
193
+ className={cx('Badge-text', `Badge--${position}`, `Badge--${level}`)}
194
+ style={{...offsetStyle, ...sizeStyle, ...style}}
160
195
  >
161
196
  {text}
162
197
  {animationElement}
@@ -15,7 +15,7 @@ interface CheckboxProps {
15
15
  label?: string;
16
16
  labelClassName?: string;
17
17
  className?: string;
18
- onChange?: (value: any) => void;
18
+ onChange?: (value: any, shift?: boolean) => void;
19
19
  value?: any;
20
20
  inline?: boolean;
21
21
  trueValue?: any;
@@ -48,7 +48,10 @@ export class Checkbox extends React.Component<CheckboxProps, any> {
48
48
  return;
49
49
  }
50
50
 
51
- onChange(e.currentTarget.checked ? trueValue : falseValue);
51
+ onChange(
52
+ e.currentTarget.checked ? trueValue : falseValue,
53
+ (e.nativeEvent as MouseEvent).shiftKey
54
+ );
52
55
  }
53
56
 
54
57
  render() {
@@ -8,7 +8,8 @@ import React from 'react';
8
8
  import Transition, {
9
9
  ENTERED,
10
10
  ENTERING,
11
- EXITING
11
+ EXITING,
12
+ EXITED
12
13
  } from 'react-transition-group/Transition';
13
14
  import Portal from 'react-overlays/Portal';
14
15
  import {Icon} from './icons';
@@ -230,7 +231,7 @@ export class Drawer extends React.Component<DrawerProps, DrawerState> {
230
231
  >
231
232
  <Icon icon="close" className="icon" />
232
233
  </a>
233
- {children}
234
+ {status === EXITED ? null : children}
234
235
  </div>
235
236
  </div>
236
237
  );
@@ -8,7 +8,8 @@ import React from 'react';
8
8
  import Transition, {
9
9
  ENTERED,
10
10
  ENTERING,
11
- EXITING
11
+ EXITING,
12
+ EXITED
12
13
  } from 'react-transition-group/Transition';
13
14
  import Portal from 'react-overlays/Portal';
14
15
  import {current, addModal, removeModal} from './ModalManager';
@@ -264,7 +265,7 @@ export class Modal extends React.Component<ModalProps, ModalState> {
264
265
  fadeStyles[status]
265
266
  )}
266
267
  >
267
- {children}
268
+ {status === EXITED ? null : children}
268
269
  </div>
269
270
  </div>
270
271
  </Portal>
@@ -1107,6 +1107,7 @@ export const SelectWithRemoteOptions = withRemoteConfig<Array<Options>>({
1107
1107
  > {
1108
1108
  render() {
1109
1109
  const {loading, config, deferLoad, updateConfig, ...rest} = this.props;
1110
+
1110
1111
  return (
1111
1112
  <EnhancedSelect
1112
1113
  {...rest}
@@ -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
  );
@@ -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 {
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
  }
@@ -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': '放弃',
@@ -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, createObject(store.data, store.query))
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
  },
@@ -7,6 +7,7 @@ import {
7
7
  SchemaCollection,
8
8
  SchemaTpl
9
9
  } from '../Schema';
10
+ import {isClickOnInput} from '../utils/helper';
10
11
 
11
12
  /**
12
13
  * Collapse 折叠渲染器,格式说明。
@@ -134,7 +135,10 @@ export default class Collapse extends React.Component<
134
135
  }
135
136
  }
136
137
 
137
- toggleCollapsed() {
138
+ toggleCollapsed(e: React.MouseEvent<HTMLElement>) {
139
+ if (isClickOnInput(e)) {
140
+ return;
141
+ }
138
142
  this.props.collapsable !== false &&
139
143
  this.setState({
140
144
  collapsed: !this.state.collapsed
@@ -318,7 +318,7 @@ export default class Dialog extends React.Component<DialogProps> {
318
318
  handleExited() {
319
319
  const {lazySchema, store} = this.props;
320
320
  if (isAlive(store)) {
321
- store.setFormData({});
321
+ store.reset();
322
322
  store.setEntered(false);
323
323
  if (typeof lazySchema === 'function') {
324
324
  store.setSchema('');
@@ -76,6 +76,11 @@ export interface DropdownButtonSchema extends BaseSchema {
76
76
  * 是否只显示图标。
77
77
  */
78
78
  iconOnly?: boolean;
79
+
80
+ /**
81
+ * 触发条件,默认是 click
82
+ */
83
+ trigger?: 'click' | 'hover';
79
84
  }
80
85
 
81
86
  export interface DropDownButtonProps
@@ -266,6 +271,7 @@ export default class DropDownButton extends React.Component<
266
271
  iconOnly,
267
272
  icon,
268
273
  isActived,
274
+ trigger,
269
275
  data
270
276
  } = this.props;
271
277
 
@@ -281,6 +287,8 @@ export default class DropDownButton extends React.Component<
281
287
  },
282
288
  className
283
289
  )}
290
+ onMouseEnter={trigger === 'hover' ? this.open : () => {}}
291
+ onMouseLeave={trigger === 'hover' ? this.close : () => {}}
284
292
  ref={this.domRef}
285
293
  >
286
294
  <TooltipWrapper
@@ -118,7 +118,7 @@ export default class EditorControl extends React.Component<EditorProps, any> {
118
118
  static defaultProps: Partial<EditorProps> = {
119
119
  language: 'javascript',
120
120
  editorTheme: 'vs',
121
- allowFullscreen: false,
121
+ allowFullscreen: true,
122
122
  options: {
123
123
  automaticLayout: true,
124
124
  selectOnLineNumbers: true,
@@ -294,26 +294,25 @@ export const availableLanguages = [
294
294
  'yaml'
295
295
  ];
296
296
 
297
- export const EditorControls: Array<
298
- typeof EditorControl
299
- > = availableLanguages.map((lang: string) => {
300
- @FormItem({
301
- type: `${lang}-editor`,
302
- sizeMutable: false
303
- })
304
- class EditorControlRenderer extends EditorControl {
305
- static lang = lang;
306
- static displayName = `${lang[0].toUpperCase()}${lang.substring(
307
- 1
308
- )}EditorControlRenderer`;
309
- static defaultProps = {
310
- ...EditorControl.defaultProps,
311
- language: lang
312
- };
313
- }
297
+ export const EditorControls: Array<typeof EditorControl> =
298
+ availableLanguages.map((lang: string) => {
299
+ @FormItem({
300
+ type: `${lang}-editor`,
301
+ sizeMutable: false
302
+ })
303
+ class EditorControlRenderer extends EditorControl {
304
+ static lang = lang;
305
+ static displayName = `${lang[0].toUpperCase()}${lang.substring(
306
+ 1
307
+ )}EditorControlRenderer`;
308
+ static defaultProps = {
309
+ ...EditorControl.defaultProps,
310
+ language: lang
311
+ };
312
+ }
314
313
 
315
- return EditorControlRenderer;
316
- });
314
+ return EditorControlRenderer;
315
+ });
317
316
 
318
317
  @FormItem({
319
318
  type: 'js-editor',
@@ -28,6 +28,11 @@ export interface InputExcelControlSchema extends FormBaseControl {
28
28
  * 是否包含空内容,主要用于二维数组模式
29
29
  */
30
30
  includeEmpty: boolean;
31
+
32
+ /**
33
+ * 纯文本模式
34
+ */
35
+ plainText: boolean;
31
36
  }
32
37
 
33
38
  export interface ExcelProps
@@ -48,12 +53,15 @@ export default class ExcelControl extends React.PureComponent<
48
53
  static defaultProps: Partial<ExcelProps> = {
49
54
  allSheets: false,
50
55
  parseMode: 'object',
51
- includeEmpty: true
56
+ includeEmpty: true,
57
+ plainText: true
52
58
  };
53
59
  state: ExcelControlState = {
54
60
  open: false
55
61
  };
56
62
 
63
+ ExcelJS: any;
64
+
57
65
  @autobind
58
66
  handleDrop(files: File[]) {
59
67
  const {allSheets, onChange} = this.props;
@@ -63,6 +71,7 @@ export default class ExcelControl extends React.PureComponent<
63
71
  reader.onload = async () => {
64
72
  if (reader.result) {
65
73
  import('exceljs').then(async (ExcelJS: any) => {
74
+ this.ExcelJS = ExcelJS;
66
75
  const workbook = new ExcelJS.Workbook();
67
76
  await workbook.xlsx.load(reader.result);
68
77
  if (allSheets) {
@@ -88,7 +97,7 @@ export default class ExcelControl extends React.PureComponent<
88
97
  */
89
98
  readWorksheet(worksheet: any) {
90
99
  const result: any[] = [];
91
- const {parseMode} = this.props;
100
+ const {parseMode, plainText} = this.props;
92
101
 
93
102
  if (parseMode === 'array') {
94
103
  worksheet.eachRow((row: any, rowNumber: number) => {
@@ -107,7 +116,23 @@ export default class ExcelControl extends React.PureComponent<
107
116
  const data: any = {};
108
117
  row.eachCell((cell: any, colNumber: any) => {
109
118
  if (firstRowValues[colNumber]) {
110
- data[firstRowValues[colNumber]] = cell.value;
119
+ let value = cell.value;
120
+ if (plainText) {
121
+ const ExcelValueType = this.ExcelJS.ValueType;
122
+ if (cell.type === ExcelValueType.Hyperlink) {
123
+ value = cell.value.hyperlink;
124
+ } else if (cell.type === ExcelValueType.Formula) {
125
+ value = cell.value.result;
126
+ } else if (cell.type === ExcelValueType.RichText) {
127
+ value = cell.value.richText
128
+ .map((item: any) => item.text)
129
+ .join('');
130
+ } else if (cell.type === ExcelValueType.Error) {
131
+ value = '';
132
+ }
133
+ }
134
+
135
+ data[firstRowValues[colNumber]] = value;
111
136
  }
112
137
  });
113
138
  result.push(data);