amis 1.3.5-beta.6 → 1.4.1-echarts-5.3.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 (219) 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 -1
  15. package/lib/components/RichText.js +243 -8
  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.js +1 -1
  40. package/lib/locale/de-DE.js +1 -0
  41. package/lib/locale/de-DE.js.map +2 -2
  42. package/lib/locale/en-US.js +2 -1
  43. package/lib/locale/en-US.js.map +2 -2
  44. package/lib/locale/zh-CN.js +2 -1
  45. package/lib/locale/zh-CN.js.map +2 -2
  46. package/lib/renderers/Action.d.ts +9 -1
  47. package/lib/renderers/Action.js +5 -5
  48. package/lib/renderers/Action.js.map +2 -2
  49. package/lib/renderers/CRUD.d.ts +2 -2
  50. package/lib/renderers/CRUD.js +11 -20
  51. package/lib/renderers/CRUD.js.map +2 -2
  52. package/lib/renderers/Collapse.d.ts +1 -1
  53. package/lib/renderers/Collapse.js +5 -1
  54. package/lib/renderers/Collapse.js.map +2 -2
  55. package/lib/renderers/Dialog.d.ts +0 -252
  56. package/lib/renderers/Dialog.js +1 -1
  57. package/lib/renderers/Dialog.js.map +2 -2
  58. package/lib/renderers/DropDownButton.d.ts +8 -0
  59. package/lib/renderers/DropDownButton.js +6 -4
  60. package/lib/renderers/DropDownButton.js.map +2 -2
  61. package/lib/renderers/Form/ButtonGroupSelect.js +3 -0
  62. package/lib/renderers/Form/ButtonGroupSelect.js.map +2 -2
  63. package/lib/renderers/Form/DiffEditor.d.ts +0 -2
  64. package/lib/renderers/Form/Editor.d.ts +0 -2
  65. package/lib/renderers/Form/Editor.js +1 -1
  66. package/lib/renderers/Form/Editor.js.map +2 -2
  67. package/lib/renderers/Form/InputExcel.d.ts +5 -0
  68. package/lib/renderers/Form/InputExcel.js +24 -3
  69. package/lib/renderers/Form/InputExcel.js.map +2 -2
  70. package/lib/renderers/Form/InputImage.d.ts +8 -0
  71. package/lib/renderers/Form/InputImage.js +2 -1
  72. package/lib/renderers/Form/InputImage.js.map +2 -2
  73. package/lib/renderers/Form/InputTable.d.ts +23 -5
  74. package/lib/renderers/Form/InputTable.js +32 -3
  75. package/lib/renderers/Form/InputTable.js.map +2 -2
  76. package/lib/renderers/Json.js +5 -1
  77. package/lib/renderers/Json.js.map +2 -2
  78. package/lib/renderers/Nav.d.ts +52 -22
  79. package/lib/renderers/Nav.js +100 -15
  80. package/lib/renderers/Nav.js.map +2 -2
  81. package/lib/renderers/Page.js +4 -1
  82. package/lib/renderers/Page.js.map +2 -2
  83. package/lib/renderers/Service.d.ts +10 -1
  84. package/lib/renderers/Service.js +85 -3
  85. package/lib/renderers/Service.js.map +2 -2
  86. package/lib/renderers/Steps.d.ts +4 -4
  87. package/lib/renderers/Steps.js +5 -2
  88. package/lib/renderers/Steps.js.map +2 -2
  89. package/lib/renderers/Table/TableBody.d.ts +1 -1
  90. package/lib/renderers/Table/TableBody.js +5 -1
  91. package/lib/renderers/Table/TableBody.js.map +2 -2
  92. package/lib/renderers/Table/TableContent.d.ts +1 -1
  93. package/lib/renderers/Table/TableContent.js +4 -0
  94. package/lib/renderers/Table/TableContent.js.map +2 -2
  95. package/lib/renderers/Table/index.d.ts +8 -3
  96. package/lib/renderers/Table/index.js +80 -45
  97. package/lib/renderers/Table/index.js.map +2 -2
  98. package/lib/store/app.d.ts +0 -1
  99. package/lib/store/combo.d.ts +0 -2
  100. package/lib/store/crud.d.ts +3 -3
  101. package/lib/store/crud.js +41 -36
  102. package/lib/store/crud.js.map +2 -2
  103. package/lib/store/form.d.ts +0 -1
  104. package/lib/store/modal.d.ts +1 -1
  105. package/lib/store/modal.js +4 -0
  106. package/lib/store/modal.js.map +2 -2
  107. package/lib/store/root.d.ts +0 -1
  108. package/lib/store/service.d.ts +0 -1
  109. package/lib/store/service.js +0 -13
  110. package/lib/store/service.js.map +2 -2
  111. package/lib/store/table.d.ts +1 -2
  112. package/lib/store/table.js +44 -3
  113. package/lib/store/table.js.map +2 -2
  114. package/lib/themes/ang-ie11.css +597 -57
  115. package/lib/themes/ang.css +597 -57
  116. package/lib/themes/ang.css.map +1 -1
  117. package/lib/themes/antd-ie11.css +597 -57
  118. package/lib/themes/antd.css +597 -57
  119. package/lib/themes/antd.css.map +1 -1
  120. package/lib/themes/cxd-ie11.css +705 -177
  121. package/lib/themes/cxd.css +705 -177
  122. package/lib/themes/cxd.css.map +1 -1
  123. package/lib/themes/dark-ie11.css +597 -57
  124. package/lib/themes/dark.css +597 -57
  125. package/lib/themes/dark.css.map +1 -1
  126. package/lib/themes/default.css +705 -177
  127. package/lib/themes/default.css.map +1 -1
  128. package/lib/utils/api.js +12 -0
  129. package/lib/utils/api.js.map +2 -2
  130. package/lib/utils/attachmentAdpator.d.ts +7 -0
  131. package/lib/utils/attachmentAdpator.js +82 -0
  132. package/lib/utils/attachmentAdpator.js.map +13 -0
  133. package/lib/utils/helper.js.map +2 -2
  134. package/lib/utils/validations.js +62 -5
  135. package/lib/utils/validations.js.map +2 -2
  136. package/package.json +46 -39
  137. package/schema.json +343 -44
  138. package/scss/_mixins.scss +29 -0
  139. package/scss/_properties.scss +27 -11
  140. package/scss/components/_badge.scss +67 -2
  141. package/scss/components/_button.scss +35 -3
  142. package/scss/components/_image-gallery.scss +1 -1
  143. package/scss/components/_markdown.scss +266 -0
  144. package/scss/components/_nav.scss +109 -35
  145. package/scss/components/_spinner.scss +6 -2
  146. package/scss/components/form/_group.scss +4 -0
  147. package/scss/themes/_common.scss +1 -0
  148. package/scss/themes/_cxd-variables.scss +20 -20
  149. package/sdk/ang-ie11.css +741 -59
  150. package/sdk/ang.css +755 -59
  151. package/sdk/antd-ie11.css +731 -51
  152. package/sdk/antd.css +755 -59
  153. package/sdk/charts.js +13 -13
  154. package/sdk/color-picker.js +67 -67
  155. package/sdk/cropperjs.js +2 -2
  156. package/sdk/cxd-ie11.css +1200 -520
  157. package/sdk/cxd.css +863 -179
  158. package/sdk/dark-ie11.css +741 -59
  159. package/sdk/dark.css +755 -59
  160. package/sdk/exceljs.js +1 -1
  161. package/sdk/helper.css.map +1 -1
  162. package/sdk/locale/de-DE.js +1 -0
  163. package/sdk/markdown.js +69 -69
  164. package/sdk/papaparse.js +1 -1
  165. package/sdk/renderers/Form/CityDB.js +1 -1
  166. package/sdk/rest.js +22 -24
  167. package/sdk/rich-text.js +62 -64
  168. package/sdk/sdk-ie11.css +1200 -520
  169. package/sdk/sdk.css +863 -179
  170. package/sdk/sdk.js +1118 -1112
  171. package/sdk/thirds/hls.js/hls.js +1 -1
  172. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  173. package/sdk/tinymce.js +57 -57
  174. package/sdk.zip +0 -0
  175. package/src/components/Badge.tsx +111 -20
  176. package/src/components/Button.tsx +23 -7
  177. package/src/components/Checkbox.tsx +5 -2
  178. package/src/components/Drawer.tsx +3 -2
  179. package/src/components/Modal.tsx +3 -2
  180. package/src/components/RichText.tsx +284 -3
  181. package/src/components/Select.tsx +1 -0
  182. package/src/components/Steps.tsx +3 -3
  183. package/src/components/WithRemoteConfig.tsx +37 -2
  184. package/src/components/calendar/DaysView.tsx +2 -2
  185. package/src/components/condition-builder/Field.tsx +1 -2
  186. package/src/components/condition-builder/Value.tsx +3 -0
  187. package/src/components/condition-builder/types.ts +6 -0
  188. package/src/components/icons.tsx +2 -0
  189. package/src/factory.tsx +13 -3
  190. package/src/icons/loading-outline.svg +4 -0
  191. package/src/locale/de-DE.ts +1 -0
  192. package/src/locale/en-US.ts +2 -1
  193. package/src/locale/zh-CN.ts +2 -1
  194. package/src/renderers/Action.tsx +66 -13
  195. package/src/renderers/CRUD.tsx +13 -33
  196. package/src/renderers/Collapse.tsx +5 -1
  197. package/src/renderers/Dialog.tsx +1 -1
  198. package/src/renderers/DropDownButton.tsx +21 -4
  199. package/src/renderers/Form/ButtonGroupSelect.tsx +3 -0
  200. package/src/renderers/Form/Editor.tsx +19 -20
  201. package/src/renderers/Form/InputExcel.tsx +28 -3
  202. package/src/renderers/Form/InputImage.tsx +23 -8
  203. package/src/renderers/Form/InputTable.tsx +88 -9
  204. package/src/renderers/Json.tsx +10 -1
  205. package/src/renderers/Nav.tsx +165 -36
  206. package/src/renderers/Page.tsx +3 -1
  207. package/src/renderers/Service.tsx +101 -3
  208. package/src/renderers/Steps.tsx +12 -9
  209. package/src/renderers/Table/TableBody.tsx +3 -2
  210. package/src/renderers/Table/TableContent.tsx +3 -1
  211. package/src/renderers/Table/index.tsx +61 -13
  212. package/src/store/crud.ts +34 -38
  213. package/src/store/modal.ts +4 -0
  214. package/src/store/service.ts +0 -19
  215. package/src/store/table.ts +48 -0
  216. package/src/utils/api.ts +11 -0
  217. package/src/utils/attachmentAdpator.ts +90 -0
  218. package/src/utils/helper.ts +1 -0
  219. package/src/utils/validations.ts +80 -12
@@ -7,7 +7,12 @@ import {filter, evalExpression} from '../utils/tpl';
7
7
  import cx from 'classnames';
8
8
  import Scoped, {ScopedContext, IScopedContext} from '../Scoped';
9
9
  import {observer} from 'mobx-react';
10
- import {isApiOutdated, isEffectiveApi} from '../utils/api';
10
+ import {
11
+ buildApi,
12
+ isApiOutdated,
13
+ isEffectiveApi,
14
+ str2AsyncFunction
15
+ } from '../utils/api';
11
16
  import {Spinner} from '../components';
12
17
  import {autobind, isEmpty, isVisible, qsstringify} from '../utils/helper';
13
18
  import {
@@ -40,6 +45,11 @@ export interface ServiceSchema extends BaseSchema {
40
45
  */
41
46
  ws?: string;
42
47
 
48
+ /**
49
+ * 通过调用外部函数来获取数据
50
+ */
51
+ dataProvider?: string | Function;
52
+
43
53
  /**
44
54
  * 内容区域
45
55
  */
@@ -111,6 +121,8 @@ export default class Service extends React.Component<ServiceProps> {
111
121
  // 主要是用于关闭 socket
112
122
  socket: any;
113
123
 
124
+ dataProviderUnsubscribe?: Function;
125
+
114
126
  static defaultProps: Partial<ServiceProps> = {
115
127
  messages: {
116
128
  fetchFailed: 'fetchFailed'
@@ -130,6 +142,8 @@ export default class Service extends React.Component<ServiceProps> {
130
142
  this.initInterval = this.initInterval.bind(this);
131
143
  this.afterDataFetch = this.afterDataFetch.bind(this);
132
144
  this.afterSchemaFetch = this.afterSchemaFetch.bind(this);
145
+ this.runDataProvider = this.runDataProvider.bind(this);
146
+ this.dataProviderSetData = this.dataProviderSetData.bind(this);
133
147
  }
134
148
 
135
149
  componentDidMount() {
@@ -168,12 +182,21 @@ export default class Service extends React.Component<ServiceProps> {
168
182
  if (this.socket) {
169
183
  this.socket.close();
170
184
  }
171
- this.socket = store.fetchWSData(props.ws, this.afterDataFetch);
185
+ this.socket = this.fetchWSData(props.ws, store.data);
186
+ }
187
+
188
+ if (props.defaultData !== prevProps.defaultData) {
189
+ store.reInitData(props.defaultData);
190
+ }
191
+
192
+ if (props.dataProvider !== prevProps.dataProvider) {
193
+ this.runDataProvider();
172
194
  }
173
195
  }
174
196
 
175
197
  componentWillUnmount() {
176
198
  this.mounted = false;
199
+ this.runDataProviderUnsubscribe();
177
200
  clearTimeout(this.timer);
178
201
  if (this.socket && this.socket.close) {
179
202
  this.socket.close();
@@ -189,6 +212,7 @@ export default class Service extends React.Component<ServiceProps> {
189
212
  ws,
190
213
  initFetch,
191
214
  initFetchOn,
215
+ dataProvider,
192
216
  store,
193
217
  messages: {fetchSuccess, fetchFailed}
194
218
  } = this.props;
@@ -212,8 +236,82 @@ export default class Service extends React.Component<ServiceProps> {
212
236
  }
213
237
 
214
238
  if (ws) {
215
- this.socket = store.fetchWSData(ws, this.afterDataFetch);
239
+ this.socket = this.fetchWSData(ws, store.data);
216
240
  }
241
+
242
+ if (dataProvider) {
243
+ this.runDataProvider();
244
+ }
245
+ }
246
+
247
+ // 使用外部函数获取数据
248
+ async runDataProvider() {
249
+ this.runDataProviderUnsubscribe();
250
+ const {dataProvider, store} = this.props;
251
+ let dataProviderFunc = dataProvider;
252
+
253
+ if (typeof dataProvider === 'string' && dataProvider) {
254
+ dataProviderFunc = str2AsyncFunction(dataProvider, 'data', 'setData')!;
255
+ }
256
+ if (typeof dataProviderFunc === 'function') {
257
+ const unsubscribe = await dataProviderFunc(
258
+ store.data,
259
+ this.dataProviderSetData
260
+ );
261
+ if (typeof unsubscribe === 'function') {
262
+ this.dataProviderUnsubscribe = unsubscribe;
263
+ }
264
+ }
265
+ }
266
+
267
+ // 运行销毁外部函数的方法
268
+ runDataProviderUnsubscribe() {
269
+ if (typeof this.dataProviderUnsubscribe === 'function') {
270
+ try {
271
+ this.dataProviderUnsubscribe();
272
+ } catch (error) {
273
+ console.error(error);
274
+ }
275
+ }
276
+ }
277
+
278
+ // 外部函数回调更新数据
279
+ dataProviderSetData(data: any) {
280
+ if (!this.mounted) {
281
+ return;
282
+ }
283
+ const {store} = this.props;
284
+ store.updateData(data, undefined, false);
285
+ store.setHasRemoteData();
286
+ }
287
+
288
+ // 使用 websocket 获取使用,因为有异步所以放这里而不是 store 实现
289
+ fetchWSData(ws: string | Api, data: any) {
290
+ const {env, store} = this.props;
291
+ const wsApi = buildApi(ws, data);
292
+
293
+ env.wsFetcher(
294
+ wsApi,
295
+ (data: any) => {
296
+ let returndata = data;
297
+ if ('status' in data && 'data' in data) {
298
+ returndata = data.data;
299
+ if (data.status !== 0) {
300
+ store.updateMessage(data.msg, true);
301
+ env.notify('error', data.msg);
302
+ return;
303
+ }
304
+ }
305
+ store.updateData(returndata, undefined, false);
306
+ store.setHasRemoteData();
307
+ // 因为 WebSocket 只会获取纯数据,所以没有 msg 之类的
308
+ this.afterDataFetch({ok: true, data: returndata});
309
+ },
310
+ (error: any) => {
311
+ store.updateMessage(error, true);
312
+ env.notify('error', error);
313
+ }
314
+ );
217
315
  }
218
316
 
219
317
  afterDataFetch(result: any) {
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import {Renderer, RendererProps} from '../factory';
3
- import {BaseSchema} from '../Schema';
3
+ import {BaseSchema, SchemaCollection} from '../Schema';
4
4
  import Steps, {StepStatus} from '../components/Steps';
5
5
  import {
6
6
  RemoteOptionsProps,
@@ -14,12 +14,12 @@ export type StepSchema = {
14
14
  /**
15
15
  * 标题
16
16
  */
17
- title: string;
17
+ title: string | SchemaCollection;
18
18
 
19
19
  /**
20
20
  * 子标题
21
21
  */
22
- subTitle?: string;
22
+ subTitle?: string | SchemaCollection;
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 | SchemaCollection;
35
35
  } & Omit<BaseSchema, 'type'>;
36
36
 
37
37
  export interface StepsSchema extends BaseSchema {
@@ -82,7 +82,8 @@ export function StepsCmpt(props: StepsProps) {
82
82
  mode,
83
83
  data,
84
84
  source,
85
- config
85
+ config,
86
+ render
86
87
  } = props;
87
88
 
88
89
  const stepsRow =
@@ -90,7 +91,9 @@ export function StepsCmpt(props: StepsProps) {
90
91
  config ||
91
92
  steps ||
92
93
  [];
93
-
94
+ const resolveRender = (val?: string | SchemaCollection) => typeof val === 'string'
95
+ ? filter(val, data)
96
+ : val && render('inner', val);
94
97
  const value = getPropValue(props) ?? 0;
95
98
  const resolveValue =
96
99
  typeof value === 'string' && isNaN(+value)
@@ -105,9 +108,9 @@ export function StepsCmpt(props: StepsProps) {
105
108
  return {
106
109
  ...step,
107
110
  status: stepStatus,
108
- title: filter(step.title, data),
109
- subTitle: filter(step.subTitle || step.value, data),
110
- description: filter(step.description, data)
111
+ title: resolveRender(step.title),
112
+ subTitle: resolveRender(step.subTitle),
113
+ description: resolveRender(step.description)
111
114
  }
112
115
  });
113
116
 
@@ -24,7 +24,7 @@ export interface TableBodyProps extends LocaleProps {
24
24
  item: IRow,
25
25
  props: any
26
26
  ) => React.ReactNode;
27
- onCheck: (item: IRow) => void;
27
+ onCheck: (item: IRow, value: boolean, shift?: boolean) => void;
28
28
  onQuickChange?: (
29
29
  item: IRow,
30
30
  values: object,
@@ -45,6 +45,7 @@ export interface TableBodyProps extends LocaleProps {
45
45
  itemAction?: ActionSchema;
46
46
  }
47
47
 
48
+ @observer
48
49
  export class TableBody extends React.Component<TableBodyProps> {
49
50
  renderRows(
50
51
  rows: Array<any>,
@@ -128,7 +129,7 @@ export class TableBody extends React.Component<TableBodyProps> {
128
129
  />
129
130
  );
130
131
  }
131
- } else if (item.children.length) {
132
+ } else if (item.children.length && item.expanded) {
132
133
  // 嵌套表格
133
134
  doms.push(
134
135
  ...this.renderRows(item.children, columns, {
@@ -4,6 +4,7 @@ import {IColumn, IRow} from '../../store/table';
4
4
  import {SchemaNode, Action} from '../../types';
5
5
  import {TableBody} from './TableBody';
6
6
  import {LocaleProps} from '../../locale';
7
+ import {observer} from 'mobx-react';
7
8
  import {ActionSchema} from '../Action';
8
9
 
9
10
  export interface TableContentProps extends LocaleProps {
@@ -31,7 +32,7 @@ export interface TableContentProps extends LocaleProps {
31
32
  item: IRow,
32
33
  props: any
33
34
  ) => React.ReactNode;
34
- onCheck: (item: IRow) => void;
35
+ onCheck: (item: IRow, value: boolean, shift?: boolean) => void;
35
36
  onQuickChange?: (
36
37
  item: IRow,
37
38
  values: object,
@@ -51,6 +52,7 @@ export interface TableContentProps extends LocaleProps {
51
52
  itemAction?: ActionSchema;
52
53
  }
53
54
 
55
+ @observer
54
56
  export class TableContent extends React.Component<TableContentProps> {
55
57
  render() {
56
58
  const {
@@ -35,6 +35,7 @@ import {HeadCellSearchDropDown} from './HeadCellSearchDropdown';
35
35
  import {TableContent} from './TableContent';
36
36
  import {
37
37
  BaseSchema,
38
+ SchemaApi,
38
39
  SchemaClassName,
39
40
  SchemaObject,
40
41
  SchemaTokenizeableString,
@@ -346,6 +347,12 @@ export interface TableProps extends RendererProps {
346
347
  reUseRow?: boolean;
347
348
  }
348
349
 
350
+ type ExportExcelToolbar = SchemaNode & {
351
+ api?: SchemaApi;
352
+ columns?: string[];
353
+ filename?: string;
354
+ };
355
+
349
356
  /**
350
357
  * 将 url 转成绝对地址
351
358
  */
@@ -682,8 +689,14 @@ export default class Table extends React.Component<TableProps, object> {
682
689
  onAction(e, action, ctx);
683
690
  }
684
691
 
685
- handleCheck(item: IRow) {
686
- item.toggle();
692
+ handleCheck(item: IRow, value: boolean, shift?: boolean) {
693
+ const {store} = this.props;
694
+ if (shift) {
695
+ store.toggleShift(item);
696
+ } else {
697
+ item.toggle();
698
+ }
699
+
687
700
  this.syncSelected();
688
701
  }
689
702
 
@@ -2004,7 +2017,7 @@ export default class Table extends React.Component<TableProps, object> {
2004
2017
  );
2005
2018
  }
2006
2019
 
2007
- renderExportExcel(toolbar: SchemaNode) {
2020
+ renderExportExcel(toolbar: ExportExcelToolbar) {
2008
2021
  const {
2009
2022
  store,
2010
2023
  env,
@@ -2028,8 +2041,8 @@ export default class Table extends React.Component<TableProps, object> {
2028
2041
  let tmpStore;
2029
2042
  let filename = 'data';
2030
2043
  // 支持配置 api 远程获取
2031
- if (typeof toolbar === 'object' && (toolbar as Schema).api) {
2032
- const res = await env.fetcher((toolbar as Schema).api, data);
2044
+ if (typeof toolbar === 'object' && toolbar.api) {
2045
+ const res = await env.fetcher(toolbar.api, data);
2033
2046
  if (!res.data) {
2034
2047
  env.notify('warning', __('placeholder.noData'));
2035
2048
  return;
@@ -2047,8 +2060,8 @@ export default class Table extends React.Component<TableProps, object> {
2047
2060
  rows = store.rows;
2048
2061
  }
2049
2062
 
2050
- if (typeof toolbar === 'object' && (toolbar as Schema).filename) {
2051
- filename = filter((toolbar as Schema).filename, data, '| raw');
2063
+ if (typeof toolbar === 'object' && toolbar.filename) {
2064
+ filename = filter(toolbar.filename, data, '| raw');
2052
2065
  }
2053
2066
 
2054
2067
  if (rows.length === 0) {
@@ -2062,7 +2075,17 @@ export default class Table extends React.Component<TableProps, object> {
2062
2075
  });
2063
2076
  worksheet.views = [{state: 'frozen', xSplit: 0, ySplit: 1}];
2064
2077
 
2065
- const firstRowLabels = columns.map(column => {
2078
+ const filteredColumns = toolbar.columns
2079
+ ? columns.filter(column => {
2080
+ const filterColumnsNames = toolbar.columns!;
2081
+ if (filterColumnsNames.indexOf(column.name) !== -1) {
2082
+ return true;
2083
+ }
2084
+ return false;
2085
+ })
2086
+ : columns;
2087
+
2088
+ const firstRowLabels = filteredColumns.map(column => {
2066
2089
  return column.label;
2067
2090
  });
2068
2091
  const firstRow = worksheet.getRow(1);
@@ -2077,14 +2100,15 @@ export default class Table extends React.Component<TableProps, object> {
2077
2100
  column: firstRowLabels.length
2078
2101
  }
2079
2102
  };
2103
+ // 用于 mapping source 的情况
2104
+ const remoteMappingCache: any = {};
2080
2105
  // 数据从第二行开始
2081
2106
  let rowIndex = 1;
2082
2107
  for (const row of rows) {
2083
2108
  rowIndex += 1;
2084
2109
  const sheetRow = worksheet.getRow(rowIndex);
2085
2110
  let columIndex = 0;
2086
- const cols = columns as any[]; // 为啥 ts 4.4 得这么做?
2087
- for (const column of cols) {
2111
+ for (const column of filteredColumns) {
2088
2112
  columIndex += 1;
2089
2113
  const name = column.name!;
2090
2114
  const value = getVariable(row.data, name);
@@ -2170,7 +2194,30 @@ export default class Table extends React.Component<TableProps, object> {
2170
2194
  };
2171
2195
  } else if (type === 'mapping') {
2172
2196
  // 拷贝自 Mapping.tsx
2173
- const map = (column as MappingSchema).map;
2197
+ let map = (column as MappingSchema).map;
2198
+ const source = (column as MappingSchema).source;
2199
+ if (source) {
2200
+ let sourceValue = source;
2201
+ if (isPureVariable(source)) {
2202
+ sourceValue = resolveVariableAndFilter(
2203
+ source as string,
2204
+ data,
2205
+ '| raw'
2206
+ );
2207
+ }
2208
+
2209
+ const mapKey = JSON.stringify(source);
2210
+ if (mapKey in remoteMappingCache) {
2211
+ map = remoteMappingCache[mapKey];
2212
+ } else {
2213
+ const res = await env.fetcher(sourceValue, data);
2214
+ if (res.data) {
2215
+ remoteMappingCache[mapKey] = res.data;
2216
+ map = res.data;
2217
+ }
2218
+ }
2219
+ }
2220
+
2174
2221
  if (
2175
2222
  typeof value !== 'undefined' &&
2176
2223
  map &&
@@ -2183,9 +2230,10 @@ export default class Table extends React.Component<TableProps, object> {
2183
2230
  : value === false && map['0']
2184
2231
  ? map['0']
2185
2232
  : map['*']); // 兼容平台旧用法:即 value 为 true 时映射 1 ,为 false 时映射 0
2186
- sheetRow.getCell(columIndex).value = viewValue;
2233
+ sheetRow.getCell(columIndex).value =
2234
+ removeHTMLTag(viewValue);
2187
2235
  } else {
2188
- sheetRow.getCell(columIndex).value = value;
2236
+ sheetRow.getCell(columIndex).value = removeHTMLTag(value);
2189
2237
  }
2190
2238
  } else {
2191
2239
  if ((column as TplSchema).tpl) {
package/src/store/crud.ts CHANGED
@@ -482,6 +482,39 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
482
482
  self.reInitData(data);
483
483
  };
484
484
 
485
+ const exportAsCSV = async (
486
+ options: {loadDataOnce?: boolean; api?: Api; data?: any} = {}
487
+ ) => {
488
+ let items = options.loadDataOnce ? self.data.itemsRaw : self.data.items;
489
+
490
+ if (options.api) {
491
+ const env = getEnv(self);
492
+ const res = await env.fetcher(options.api, options.data);
493
+ if (!res.data) {
494
+ return;
495
+ }
496
+ if (Array.isArray(res.data)) {
497
+ items = res.data;
498
+ } else {
499
+ items = res.data.rows || res.data.items;
500
+ }
501
+ }
502
+
503
+ import('papaparse').then((papaparse: any) => {
504
+ const csvText = papaparse.unparse(items);
505
+ if (csvText) {
506
+ const blob = new Blob(
507
+ // 加上 BOM 这样 Excel 打开的时候就不会乱码
508
+ [new Uint8Array([0xef, 0xbb, 0xbf]), csvText],
509
+ {
510
+ type: 'text/plain;charset=utf-8'
511
+ }
512
+ );
513
+ saveAs(blob, 'data.csv');
514
+ }
515
+ });
516
+ };
517
+
485
518
  return {
486
519
  setPristineQuery,
487
520
  updateQuery,
@@ -495,44 +528,7 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
495
528
  setUnSelectedItems,
496
529
  setInnerModalOpened,
497
530
  initFromScope,
498
- async exportAsCSV(options: {loadDataOnce?: boolean; api?: Api} = {}) {
499
- let items = options.loadDataOnce ? self.data.itemsRaw : self.data.items;
500
-
501
- if (!options.loadDataOnce && options.api) {
502
- const json = await self.fetchData(
503
- options.api,
504
- {
505
- ...self.query,
506
- page: undefined,
507
- perPage: undefined,
508
- op: 'export-csv'
509
- },
510
- {
511
- autoAppend: true
512
- }
513
- );
514
- if (
515
- json.ok &&
516
- (Array.isArray(json.data.items) || Array.isArray(json.data.rows))
517
- ) {
518
- items = json.data.items || json.data.rows;
519
- }
520
- }
521
-
522
- import('papaparse').then((papaparse: any) => {
523
- const csvText = papaparse.unparse(items);
524
- if (csvText) {
525
- const blob = new Blob(
526
- // 加上 BOM 这样 Excel 打开的时候就不会乱码
527
- [new Uint8Array([0xef, 0xbb, 0xbf]), csvText],
528
- {
529
- type: 'text/plain;charset=utf-8'
530
- }
531
- );
532
- saveAs(blob, 'data.csv');
533
- }
534
- });
535
- }
531
+ exportAsCSV
536
532
  };
537
533
  });
538
534
 
@@ -24,6 +24,10 @@ export const ModalStore = ServiceStore.named('ModalStore')
24
24
  setFormData(obj: any) {
25
25
  self.form = obj;
26
26
  },
27
+ reset() {
28
+ self.form = {};
29
+ self.reInitData({}, true);
30
+ },
27
31
 
28
32
  setResizeCoord(value: number) {
29
33
  self.resizeCoord = value;
@@ -140,24 +140,6 @@ export const ServiceStore = iRendererStore
140
140
  }
141
141
  });
142
142
 
143
- const fetchWSData = (ws: string, afterDataFetch: (data: any) => any) => {
144
- const env = getEnv(self);
145
-
146
- env.wsFetcher(
147
- ws,
148
- (data: any) => {
149
- self.updateData(data, undefined, false);
150
- setHasRemoteData();
151
- // 因为 WebSocket 只会获取纯数据,所以没有 msg 之类的
152
- afterDataFetch({ok: true, data: data});
153
- },
154
- (error: any) => {
155
- updateMessage(error, true);
156
- env.notify('error', error);
157
- }
158
- );
159
- };
160
-
161
143
  const setHasRemoteData = () => {
162
144
  self.hasRemoteData = true;
163
145
  };
@@ -505,7 +487,6 @@ export const ServiceStore = iRendererStore
505
487
  markBusying,
506
488
  fetchInitData,
507
489
  fetchData,
508
- fetchWSData,
509
490
  reInitData,
510
491
  updateMessage,
511
492
  clearMessage,
@@ -984,11 +984,16 @@ export const TableStore = iRendererStore
984
984
  }
985
985
  }
986
986
 
987
+ // 记录最近一次点击的多选框,主要用于 shift 多选时判断上一个选的是什么
988
+ let lastCheckedRow: any = null;
989
+
987
990
  function toggle(row: IRow) {
988
991
  if (!row.checkable) {
989
992
  return;
990
993
  }
991
994
 
995
+ lastCheckedRow = row;
996
+
992
997
  const idx = self.selectedRows.indexOf(row);
993
998
 
994
999
  if (self.multiple) {
@@ -1000,6 +1005,48 @@ export const TableStore = iRendererStore
1000
1005
  }
1001
1006
  }
1002
1007
 
1008
+ // 按住 shift 的时候点击选项
1009
+ function toggleShift(row: IRow) {
1010
+ // 如果是同一个或非 multiple 模式下就和不用 shift 一样
1011
+ if (!lastCheckedRow || row === lastCheckedRow || !self.multiple) {
1012
+ toggle(row);
1013
+ return;
1014
+ }
1015
+
1016
+ const maxLength = self.maxKeepItemSelectionLength;
1017
+ const checkableRows = self.checkableRows;
1018
+ const lastCheckedRowIndex = checkableRows.findIndex(
1019
+ row => row === lastCheckedRow
1020
+ );
1021
+ const rowIndex = checkableRows.findIndex(rowItem => row === rowItem);
1022
+ const minIndex =
1023
+ lastCheckedRowIndex > rowIndex ? rowIndex : lastCheckedRowIndex;
1024
+ const maxIndex =
1025
+ lastCheckedRowIndex > rowIndex ? lastCheckedRowIndex : rowIndex;
1026
+
1027
+ const rows = checkableRows.slice(minIndex, maxIndex);
1028
+ rows.push(row); // 将当前行也加入进行判断
1029
+ for (const rowItem of rows) {
1030
+ const idx = self.selectedRows.indexOf(rowItem);
1031
+ if (idx === -1) {
1032
+ // 如果上一个是选中状态,则将之间的所有 check 都变成可选
1033
+ if (lastCheckedRow.checked) {
1034
+ if (maxLength && self.selectedRows.length < maxLength) {
1035
+ self.selectedRows.push(rowItem);
1036
+ } else {
1037
+ self.selectedRows.push(rowItem);
1038
+ }
1039
+ }
1040
+ } else {
1041
+ if (!lastCheckedRow.checked) {
1042
+ self.selectedRows.splice(idx, 1);
1043
+ }
1044
+ }
1045
+ }
1046
+
1047
+ lastCheckedRow = row;
1048
+ }
1049
+
1003
1050
  function updateCheckDisable() {
1004
1051
  if (!self.data) {
1005
1052
  return;
@@ -1134,6 +1181,7 @@ export const TableStore = iRendererStore
1134
1181
  updateSelected,
1135
1182
  toggleAll,
1136
1183
  toggle,
1184
+ toggleShift,
1137
1185
  toggleExpandAll,
1138
1186
  toggleExpanded,
1139
1187
  collapseAllAtDepth,
package/src/utils/api.ts CHANGED
@@ -22,6 +22,8 @@ interface ApiCacheConfig extends ApiObject {
22
22
 
23
23
  const apiCaches: Array<ApiCacheConfig> = [];
24
24
 
25
+ const isIE = !!(document as any).documentMode;
26
+
25
27
  export function normalizeApi(
26
28
  api: Api,
27
29
  defaultMethod: string = 'get'
@@ -293,6 +295,15 @@ export function wrapFetcher(
293
295
  api
294
296
  );
295
297
  }
298
+ // IE 下 get 请求会被缓存,所以自动加个时间戳
299
+ if (isIE && api && api.method?.toLocaleLowerCase() === 'get') {
300
+ const timeStamp = `_t=${Date.now()}`;
301
+ if (api.url.indexOf('?') === -1) {
302
+ api.url = api.url + `?${timeStamp}`;
303
+ } else {
304
+ api.url = api.url + `&${timeStamp}`;
305
+ }
306
+ }
296
307
  return wrapAdaptor(fn(api), api);
297
308
  };
298
309
  }