amis 1.9.0 → 1.9.1-beta.3

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 (269) hide show
  1. package/lib/RootRenderer.js +10 -2
  2. package/lib/RootRenderer.js.map +2 -2
  3. package/lib/Schema.d.ts +3 -2
  4. package/lib/Schema.js.map +1 -1
  5. package/lib/actions/Action.d.ts +1 -0
  6. package/lib/actions/Action.js +7 -6
  7. package/lib/actions/Action.js.map +2 -2
  8. package/lib/components/Button.d.ts +11 -10
  9. package/lib/components/Button.js +2 -2
  10. package/lib/components/Button.js.map +2 -2
  11. package/lib/components/CalendarMobile.d.ts +40 -40
  12. package/lib/components/Checkbox.js +1 -1
  13. package/lib/components/Checkbox.js.map +2 -2
  14. package/lib/components/ContextMenu.d.ts +4 -0
  15. package/lib/components/ContextMenu.js +23 -7
  16. package/lib/components/ContextMenu.js.map +2 -2
  17. package/lib/components/DatePicker.d.ts +40 -40
  18. package/lib/components/DateRangePicker.d.ts +40 -40
  19. package/lib/components/Form.d.ts +22 -0
  20. package/lib/components/Form.js +44 -0
  21. package/lib/components/Form.js.map +13 -0
  22. package/lib/components/FormField.d.ts +65 -0
  23. package/lib/components/FormField.js +48 -0
  24. package/lib/components/FormField.js.map +13 -0
  25. package/lib/components/InputBox.d.ts +10 -10
  26. package/lib/components/InputBox.js +4 -3
  27. package/lib/components/InputBox.js.map +2 -2
  28. package/lib/components/InputBoxWithSuggestion.d.ts +280 -0
  29. package/lib/components/InputBoxWithSuggestion.js +65 -0
  30. package/lib/components/InputBoxWithSuggestion.js.map +13 -0
  31. package/lib/components/ListGroup.d.ts +10 -10
  32. package/lib/components/PickerContainer.d.ts +4 -2
  33. package/lib/components/PickerContainer.js +28 -5
  34. package/lib/components/PickerContainer.js.map +2 -2
  35. package/lib/components/Radios.d.ts +10 -10
  36. package/lib/components/ResultBox.d.ts +40 -40
  37. package/lib/components/Select.d.ts +195 -202
  38. package/lib/components/Select.js +7 -3
  39. package/lib/components/Select.js.map +2 -2
  40. package/lib/components/Textarea.d.ts +568 -2
  41. package/lib/components/Textarea.js +129 -1
  42. package/lib/components/Textarea.js.map +2 -2
  43. package/lib/components/Toast.js +11 -9
  44. package/lib/components/Toast.js.map +2 -2
  45. package/lib/components/UserSelect.d.ts +500 -0
  46. package/lib/components/UserSelect.js +559 -0
  47. package/lib/components/UserSelect.js.map +13 -0
  48. package/lib/components/UserTabSelect.d.ts +320 -0
  49. package/lib/components/UserTabSelect.js +163 -0
  50. package/lib/components/UserTabSelect.js.map +13 -0
  51. package/lib/components/WithRemoteConfig.d.ts +7 -0
  52. package/lib/components/WithRemoteConfig.js +17 -11
  53. package/lib/components/WithRemoteConfig.js.map +2 -2
  54. package/lib/components/calendar/DaysView.d.ts +26 -1
  55. package/lib/components/calendar/DaysView.js +60 -19
  56. package/lib/components/calendar/DaysView.js.map +2 -2
  57. package/lib/components/calendar/TimeView.d.ts +1 -1
  58. package/lib/components/calendar/TimeView.js +10 -3
  59. package/lib/components/calendar/TimeView.js.map +2 -2
  60. package/lib/components/formula/Picker.js +4 -4
  61. package/lib/components/formula/Picker.js.map +2 -2
  62. package/lib/components/icons.d.ts +7 -1
  63. package/lib/components/icons.js +17 -1
  64. package/lib/components/icons.js.map +2 -2
  65. package/lib/components/index.d.ts +2 -1
  66. package/lib/components/index.js +3 -1
  67. package/lib/components/index.js.map +2 -2
  68. package/lib/components/json-schema/Array.d.ts +3 -0
  69. package/lib/components/json-schema/Array.js +125 -0
  70. package/lib/components/json-schema/Array.js.map +13 -0
  71. package/lib/components/json-schema/Item.d.ts +3 -0
  72. package/lib/components/json-schema/Item.js +34 -0
  73. package/lib/components/json-schema/Item.js.map +13 -0
  74. package/lib/components/json-schema/Object.d.ts +3 -0
  75. package/lib/components/json-schema/Object.js +178 -0
  76. package/lib/components/json-schema/Object.js.map +13 -0
  77. package/lib/components/json-schema/index.d.ts +279 -0
  78. package/lib/components/json-schema/index.js +16 -0
  79. package/lib/components/json-schema/index.js.map +13 -0
  80. package/lib/components/schema-editor/Array.js +2 -2
  81. package/lib/components/schema-editor/Array.js.map +2 -2
  82. package/lib/components/schema-editor/Common.d.ts +2 -0
  83. package/lib/components/schema-editor/Common.js +39 -3
  84. package/lib/components/schema-editor/Common.js.map +2 -2
  85. package/lib/components/schema-editor/Object.js +2 -2
  86. package/lib/components/schema-editor/Object.js.map +2 -2
  87. package/lib/components/schema-editor/index.d.ts +45 -41
  88. package/lib/components/schema-editor/index.js +5 -5
  89. package/lib/components/schema-editor/index.js.map +2 -2
  90. package/lib/helper.css +125 -124
  91. package/lib/helper.css.map +1 -1
  92. package/lib/hooks/use-validation-resolver.d.ts +1 -0
  93. package/lib/hooks/use-validation-resolver.js +49 -0
  94. package/lib/hooks/use-validation-resolver.js.map +13 -0
  95. package/lib/icons/department.js +17 -0
  96. package/lib/icons/menu.js +9 -0
  97. package/lib/icons/post.js +15 -0
  98. package/lib/icons/role.js +14 -0
  99. package/lib/icons/user-remove.js +12 -0
  100. package/lib/index.d.ts +2 -0
  101. package/lib/index.js +3 -1
  102. package/lib/index.js.map +2 -2
  103. package/lib/locale/de-DE.js +11 -1
  104. package/lib/locale/de-DE.js.map +2 -2
  105. package/lib/locale/en-US.js +12 -1
  106. package/lib/locale/en-US.js.map +2 -2
  107. package/lib/locale/zh-CN.js +14 -3
  108. package/lib/locale/zh-CN.js.map +2 -2
  109. package/lib/renderers/Action.js +25 -11
  110. package/lib/renderers/Action.js.map +2 -2
  111. package/lib/renderers/CRUD.js +5 -1
  112. package/lib/renderers/CRUD.js.map +2 -2
  113. package/lib/renderers/Dialog.js +9 -3
  114. package/lib/renderers/Dialog.js.map +2 -2
  115. package/lib/renderers/Drawer.js +5 -1
  116. package/lib/renderers/Drawer.js.map +2 -2
  117. package/lib/renderers/Form/InputDate.d.ts +2 -2
  118. package/lib/renderers/Form/InputDate.js.map +2 -2
  119. package/lib/renderers/Form/InputFile.js +5 -12
  120. package/lib/renderers/Form/InputFile.js.map +2 -2
  121. package/lib/renderers/Form/InputText.d.ts +1 -1
  122. package/lib/renderers/Form/InputText.js.map +1 -1
  123. package/lib/renderers/Form/JSONSchema.d.ts +23 -0
  124. package/lib/renderers/Form/JSONSchema.js +44 -0
  125. package/lib/renderers/Form/JSONSchema.js.map +13 -0
  126. package/lib/renderers/Form/JSONSchemaEditor.d.ts +2 -3
  127. package/lib/renderers/Form/JSONSchemaEditor.js +9 -24
  128. package/lib/renderers/Form/JSONSchemaEditor.js.map +2 -2
  129. package/lib/renderers/Form/Textarea.d.ts +1 -8
  130. package/lib/renderers/Form/Textarea.js +11 -75
  131. package/lib/renderers/Form/Textarea.js.map +2 -2
  132. package/lib/renderers/Form/UserSelect.d.ts +54 -0
  133. package/lib/renderers/Form/UserSelect.js +197 -0
  134. package/lib/renderers/Form/UserSelect.js.map +13 -0
  135. package/lib/renderers/Form/index.d.ts +1 -1
  136. package/lib/renderers/Form/index.js +88 -42
  137. package/lib/renderers/Form/index.js.map +2 -2
  138. package/lib/renderers/Link.d.ts +1 -1
  139. package/lib/renderers/Link.js +15 -29
  140. package/lib/renderers/Link.js.map +2 -2
  141. package/lib/renderers/Log.d.ts +28 -0
  142. package/lib/renderers/Log.js +110 -20
  143. package/lib/renderers/Log.js.map +2 -2
  144. package/lib/renderers/Page.js +5 -1
  145. package/lib/renderers/Page.js.map +2 -2
  146. package/lib/renderers/Service.js +5 -1
  147. package/lib/renderers/Service.js.map +2 -2
  148. package/lib/renderers/Wizard.js +37 -14
  149. package/lib/renderers/Wizard.js.map +2 -2
  150. package/lib/store/form.js +65 -45
  151. package/lib/store/form.js.map +2 -2
  152. package/lib/themes/ang-ie11.css +576 -24
  153. package/lib/themes/ang.css +553 -12
  154. package/lib/themes/ang.css.map +1 -1
  155. package/lib/themes/antd-ie11.css +576 -24
  156. package/lib/themes/antd.css +553 -12
  157. package/lib/themes/antd.css.map +1 -1
  158. package/lib/themes/cxd-ie11.css +576 -24
  159. package/lib/themes/cxd.css +553 -12
  160. package/lib/themes/cxd.css.map +1 -1
  161. package/lib/themes/dark-ie11.css +576 -24
  162. package/lib/themes/dark.css +553 -12
  163. package/lib/themes/dark.css.map +1 -1
  164. package/lib/themes/default-ie11.css +576 -24
  165. package/lib/themes/default.css +553 -12
  166. package/lib/themes/default.css.map +1 -1
  167. package/lib/utils/api.js +1 -1
  168. package/lib/utils/api.js.map +2 -2
  169. package/lib/utils/renderer-event.js.map +2 -2
  170. package/package.json +2 -1
  171. package/schema.json +542 -4
  172. package/scss/_properties.scss +20 -8
  173. package/scss/components/_input-box.scss +22 -1
  174. package/scss/components/_json-schema.scss +124 -0
  175. package/scss/components/_log.scss +37 -5
  176. package/scss/components/form/_date-range.scss +1 -0
  177. package/scss/components/form/_select.scss +9 -0
  178. package/scss/components/form/_transfer.scss +19 -3
  179. package/scss/components/form/_user-select.scss +422 -0
  180. package/scss/helper/background/_background-color.scss +125 -124
  181. package/scss/themes/_common.scss +2 -0
  182. package/sdk/ang-ie11.css +670 -24
  183. package/sdk/ang.css +647 -12
  184. package/sdk/antd-ie11.css +670 -24
  185. package/sdk/antd.css +647 -12
  186. package/sdk/barcode.js +51 -51
  187. package/sdk/charts.js +14 -14
  188. package/sdk/codemirror.js +7 -7
  189. package/sdk/color-picker.js +65 -65
  190. package/sdk/cropperjs.js +2 -2
  191. package/sdk/cxd-ie11.css +670 -24
  192. package/sdk/cxd.css +647 -12
  193. package/sdk/dark-ie11.css +670 -24
  194. package/sdk/dark.css +647 -12
  195. package/sdk/exceljs.js +1 -1
  196. package/sdk/helper.css +125 -124
  197. package/sdk/helper.css.map +1 -1
  198. package/sdk/locale/de-DE.js +11 -1
  199. package/sdk/markdown.js +69 -69
  200. package/sdk/papaparse.js +1 -1
  201. package/sdk/renderers/Form/CityDB.js +1 -1
  202. package/sdk/rest.js +16 -16
  203. package/sdk/rich-text.js +62 -62
  204. package/sdk/sdk-ie11.css +670 -24
  205. package/sdk/sdk.css +647 -12
  206. package/sdk/sdk.js +1651 -1637
  207. package/sdk/thirds/hls.js/hls.js +1 -1
  208. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  209. package/sdk/tinymce.js +57 -57
  210. package/src/RootRenderer.tsx +27 -15
  211. package/src/Schema.ts +5 -1
  212. package/src/actions/Action.ts +5 -4
  213. package/src/components/Button.tsx +3 -0
  214. package/src/components/Checkbox.tsx +2 -1
  215. package/src/components/ContextMenu.tsx +25 -7
  216. package/src/components/Form.tsx +70 -0
  217. package/src/components/FormField.tsx +127 -0
  218. package/src/components/InputBox.tsx +4 -1
  219. package/src/components/InputBoxWithSuggestion.tsx +113 -0
  220. package/src/components/PickerContainer.tsx +20 -5
  221. package/src/components/Select.tsx +18 -10
  222. package/src/components/Textarea.tsx +234 -2
  223. package/src/components/Toast.tsx +19 -18
  224. package/src/components/UserSelect.tsx +850 -0
  225. package/src/components/UserTabSelect.tsx +261 -0
  226. package/src/components/WithRemoteConfig.tsx +22 -7
  227. package/src/components/calendar/DaysView.tsx +117 -49
  228. package/src/components/calendar/TimeView.tsx +11 -6
  229. package/src/components/formula/Picker.tsx +2 -1
  230. package/src/components/icons.tsx +17 -1
  231. package/src/components/index.tsx +3 -1
  232. package/src/components/json-schema/Array.tsx +216 -0
  233. package/src/components/json-schema/Item.tsx +47 -0
  234. package/src/components/json-schema/Object.tsx +339 -0
  235. package/src/components/json-schema/index.tsx +44 -0
  236. package/src/components/schema-editor/Array.tsx +3 -1
  237. package/src/components/schema-editor/Common.tsx +61 -4
  238. package/src/components/schema-editor/Object.tsx +3 -1
  239. package/src/components/schema-editor/index.tsx +12 -5
  240. package/src/hooks/use-validation-resolver.ts +45 -0
  241. package/src/icons/department.svg +17 -0
  242. package/src/icons/menu.svg +2 -0
  243. package/src/icons/post.svg +15 -0
  244. package/src/icons/role.svg +14 -0
  245. package/src/icons/user-remove.svg +12 -0
  246. package/src/index.tsx +2 -0
  247. package/src/locale/de-DE.ts +11 -1
  248. package/src/locale/en-US.ts +12 -1
  249. package/src/locale/zh-CN.ts +14 -3
  250. package/src/renderers/Action.tsx +10 -9
  251. package/src/renderers/CRUD.tsx +5 -1
  252. package/src/renderers/Dialog.tsx +9 -3
  253. package/src/renderers/Drawer.tsx +5 -1
  254. package/src/renderers/Form/InputDate.tsx +9 -4
  255. package/src/renderers/Form/InputFile.tsx +5 -15
  256. package/src/renderers/Form/InputText.tsx +1 -1
  257. package/src/renderers/Form/JSONSchema.tsx +56 -0
  258. package/src/renderers/Form/JSONSchemaEditor.tsx +8 -27
  259. package/src/renderers/Form/Textarea.tsx +7 -117
  260. package/src/renderers/Form/UserSelect.tsx +263 -0
  261. package/src/renderers/Form/index.tsx +28 -18
  262. package/src/renderers/Link.tsx +5 -17
  263. package/src/renderers/Log.tsx +213 -19
  264. package/src/renderers/Page.tsx +6 -1
  265. package/src/renderers/Service.tsx +5 -1
  266. package/src/renderers/Wizard.tsx +24 -10
  267. package/src/store/form.ts +24 -17
  268. package/src/utils/api.ts +1 -1
  269. package/src/utils/renderer-event.ts +0 -2
@@ -663,7 +663,7 @@ export default class Form extends React.Component<FormProps, object> {
663
663
  }
664
664
 
665
665
  // 派发init事件,参数为初始化数据
666
- const dispatcher = dispatchEvent(
666
+ const dispatcher = await dispatchEvent(
667
667
  'inited',
668
668
  createObject(this.props.data, data)
669
669
  );
@@ -767,7 +767,7 @@ export default class Form extends React.Component<FormProps, object> {
767
767
  if (result) {
768
768
  dispatchEvent('validateSucc', data);
769
769
  } else {
770
- dispatchEvent('validateFail', data);
770
+ dispatchEvent('validateError', data);
771
771
  }
772
772
  return result;
773
773
  });
@@ -794,9 +794,7 @@ export default class Form extends React.Component<FormProps, object> {
794
794
  submit(fn?: (values: object) => Promise<any>): Promise<any> {
795
795
  const {store, messages, translate: __, dispatchEvent, data} = this.props;
796
796
  this.flush();
797
- const validateErrCb = () => {
798
- dispatchEvent('validateFail', data);
799
- };
797
+ const validateErrCb = () => dispatchEvent('validateError', data);
800
798
  return store.submit(
801
799
  fn,
802
800
  this.hooks['validate'] || [],
@@ -871,13 +869,13 @@ export default class Form extends React.Component<FormProps, object> {
871
869
  };
872
870
  }
873
871
 
874
- emitChange(submit: boolean) {
872
+ async emitChange(submit: boolean) {
875
873
  const {onChange, store, submitOnChange, dispatchEvent, data} = this.props;
876
874
 
877
875
  if (!isAlive(store)) {
878
876
  return;
879
877
  }
880
- const dispatcher = dispatchEvent('change', createObject(data, store.data));
878
+ const dispatcher = await dispatchEvent('change', createObject(data, store.data));
881
879
  if (!dispatcher?.prevented) {
882
880
  onChange &&
883
881
  onChange(
@@ -980,10 +978,12 @@ export default class Form extends React.Component<FormProps, object> {
980
978
  data = store.data;
981
979
  }
982
980
  if (Array.isArray(action.required) && action.required.length) {
983
- return store.validateFields(action.required).then(result => {
981
+ return store.validateFields(action.required).then(async result => {
984
982
  if (!result) {
985
- dispatchEvent('validateError', this.props.data);
986
- env.notify('error', __('Form.validateFailed'));
983
+ const dispatcher = await dispatchEvent('validateError', this.props.data);
984
+ if (!dispatcher?.prevented) {
985
+ env.notify('error', __('Form.validateFailed'));
986
+ }
987
987
  } else {
988
988
  dispatchEvent('validateSucc', this.props.data);
989
989
  this.handleAction(
@@ -1039,9 +1039,9 @@ export default class Form extends React.Component<FormProps, object> {
1039
1039
  .saveRemote(action.api || (api as Api), values, {
1040
1040
  successMessage: saveSuccess,
1041
1041
  errorMessage: saveFailed,
1042
- onSuccess: (result: Payload) => {
1042
+ onSuccess: async (result: Payload) => {
1043
1043
  // result为提交接口返回的内容
1044
- dispatchEvent(
1044
+ const dispatcher = await dispatchEvent(
1045
1045
  'submitSucc',
1046
1046
  createObject(this.props.data, {result})
1047
1047
  );
@@ -1049,20 +1049,30 @@ export default class Form extends React.Component<FormProps, object> {
1049
1049
  !isEffectiveApi(finnalAsyncApi, store.data) ||
1050
1050
  store.data[finishedField || 'finished']
1051
1051
  ) {
1052
- return;
1052
+ return {
1053
+ cbResult: null,
1054
+ dispatcher
1055
+ };
1053
1056
  }
1054
- return until(
1057
+ const cbResult = until(
1055
1058
  () => store.checkRemote(finnalAsyncApi as Api, store.data),
1056
1059
  (ret: any) => ret && ret[finishedField || 'finished'],
1057
1060
  cancel => (this.asyncCancel = cancel),
1058
1061
  checkInterval
1059
- );
1062
+ )
1063
+ return {
1064
+ cbResult,
1065
+ dispatcher
1066
+ };
1060
1067
  },
1061
- onFailed: (result: Payload) => {
1062
- dispatchEvent(
1068
+ onFailed: async (result: Payload) => {
1069
+ const dispatcher = await dispatchEvent(
1063
1070
  'submitFail',
1064
1071
  createObject(this.props.data, {error: result})
1065
1072
  );
1073
+ return {
1074
+ dispatcher
1075
+ };
1066
1076
  }
1067
1077
  })
1068
1078
  .then(async response => {
@@ -1183,7 +1193,7 @@ export default class Form extends React.Component<FormProps, object> {
1183
1193
  })
1184
1194
  .catch(e => {
1185
1195
  onFailed && onFailed(e, store.errors);
1186
- if (throwErrors) {
1196
+ if (throwErrors || action.countDown) {
1187
1197
  throw e;
1188
1198
  }
1189
1199
  });
@@ -63,8 +63,10 @@ export class LinkCmpt extends React.Component<LinkProps, object> {
63
63
  htmlTarget: ''
64
64
  };
65
65
 
66
- async handleClick(href: string) {
67
- const {env, blank, body, dispatchEvent, data} = this.props;
66
+ @autobind
67
+ handleClick(e: React.MouseEvent<any>) {
68
+ const {env, href, blank, body} = this.props;
69
+
68
70
  env?.tracker(
69
71
  {
70
72
  eventType: 'url',
@@ -73,21 +75,6 @@ export class LinkCmpt extends React.Component<LinkProps, object> {
73
75
  },
74
76
  this.props
75
77
  );
76
- // 触发渲染器事件
77
- const rendererEvent = await dispatchEvent(
78
- 'click',
79
- createObject(data, {
80
- // 注意:每个组件都必须把数据链带上
81
- url: href,
82
- blank,
83
- label: body
84
- })
85
- );
86
-
87
- // 阻止原有动作执行
88
- if (rendererEvent?.prevented) {
89
- return;
90
- }
91
78
  }
92
79
 
93
80
  getHref() {}
@@ -123,6 +110,7 @@ export class LinkCmpt extends React.Component<LinkProps, object> {
123
110
  htmlTarget={htmlTarget || (blank ? '_blank' : '_self')}
124
111
  icon={icon}
125
112
  rightIcon={rightIcon}
113
+ onClick={this.handleClick}
126
114
  >
127
115
  {body ? render('body', body) : value || __('link')}
128
116
  </Link>
@@ -3,10 +3,22 @@
3
3
  */
4
4
  import React from 'react';
5
5
  import {Renderer, RendererProps} from '../factory';
6
- import {BaseSchema, SchemaTpl} from '../Schema';
6
+ import {BaseSchema} from '../Schema';
7
7
  import Ansi from 'ansi-to-react';
8
- import {filter} from '../utils/tpl';
9
8
  import {buildApi, isApiOutdated} from '../utils/api';
9
+ import VirtualList from '../components/virtual-list';
10
+ import Button from '../components/Button';
11
+ import {
12
+ InputClearIcon,
13
+ LeftArrowIcon,
14
+ MinusIcon,
15
+ PauseIcon,
16
+ PlusIcon,
17
+ ReloadIcon,
18
+ RightArrowIcon
19
+ } from '../components/icons';
20
+
21
+ export type LogOperation = 'stop' | 'restart' | 'showLineNumber' | 'clear';
10
22
 
11
23
  /**
12
24
  * 日志展示组件
@@ -42,6 +54,26 @@ export interface LogSchema extends BaseSchema {
42
54
  * 返回内容字符编码
43
55
  */
44
56
  encoding?: string;
57
+
58
+ /**
59
+ * 限制最大日志数量
60
+ */
61
+ maxLength?: number;
62
+
63
+ /**
64
+ * 每行高度
65
+ */
66
+ rowHeight?: number;
67
+
68
+ /**
69
+ * 关闭 ANSI 颜色支持
70
+ */
71
+ disableColor?: boolean;
72
+
73
+ /**
74
+ * 一些可操作选项
75
+ */
76
+ operation?: Array<LogOperation>;
45
77
  }
46
78
 
47
79
  export interface LogProps
@@ -51,6 +83,9 @@ export interface LogProps
51
83
  export interface LogState {
52
84
  lastLine: string;
53
85
  logs: string[];
86
+ refresh: boolean;
87
+ showLineNumber: boolean;
88
+ showOperation: boolean;
54
89
  }
55
90
 
56
91
  export class Log extends React.Component<LogProps, LogState> {
@@ -69,7 +104,10 @@ export class Log extends React.Component<LogProps, LogState> {
69
104
 
70
105
  state: LogState = {
71
106
  lastLine: '',
72
- logs: []
107
+ logs: [],
108
+ refresh: true,
109
+ showLineNumber: false,
110
+ showOperation: false
73
111
  };
74
112
 
75
113
  constructor(props: LogProps) {
@@ -124,8 +162,38 @@ export class Log extends React.Component<LogProps, LogState> {
124
162
  }
125
163
  }
126
164
 
165
+ refresh = () => {
166
+ let origin = this.state.refresh;
167
+ this.setState({
168
+ refresh: !origin
169
+ });
170
+ if (!origin) {
171
+ this.clear();
172
+ this.loadLogs();
173
+ }
174
+ };
175
+
176
+ clear = () => {
177
+ this.setState({
178
+ logs: [],
179
+ lastLine: ''
180
+ });
181
+ };
182
+
183
+ changeShowLineNumber = () => {
184
+ this.setState({
185
+ showLineNumber: !this.state.showLineNumber
186
+ });
187
+ };
188
+
189
+ changeShowOperation = () => {
190
+ this.setState({
191
+ showOperation: !this.state.showOperation
192
+ });
193
+ };
194
+
127
195
  async loadLogs() {
128
- const {source, data, env, translate: __, encoding} = this.props;
196
+ const {source, data, env, translate: __, encoding, maxLength} = this.props;
129
197
  // 因为这里返回结果是流式的,和普通 api 请求不一样,如果直接用 fetcher 经过 responseAdaptor 可能会导致出错,所以就直接 fetch 了
130
198
  const api = buildApi(source, data);
131
199
  if (!api.url) {
@@ -146,6 +214,12 @@ export class Log extends React.Component<LogProps, LogState> {
146
214
  let lastline = '';
147
215
  let logs: string[] = [];
148
216
  for (;;) {
217
+ if (!this.state.refresh) {
218
+ await reader.cancel('click cancel button').then(() => {
219
+ this.props.env.notify('success', '日志已经停止刷新');
220
+ return;
221
+ });
222
+ }
149
223
  let {done, value} = await reader.read();
150
224
  if (value) {
151
225
  let text = new TextDecoder(encoding).decode(value, {stream: true});
@@ -162,6 +236,11 @@ export class Log extends React.Component<LogProps, LogState> {
162
236
  lines[0] = lastline + lines[0];
163
237
  // 最后一个要么是空,要么是下一行的数据
164
238
  lastline = lines.pop() || '';
239
+ if (maxLength) {
240
+ if (logs.length + lines.length > maxLength) {
241
+ logs.splice(0, logs.length + lines.length - maxLength);
242
+ }
243
+ }
165
244
  logs = logs.concat(lines);
166
245
  this.setState({
167
246
  logs: logs,
@@ -180,6 +259,21 @@ export class Log extends React.Component<LogProps, LogState> {
180
259
  }
181
260
  }
182
261
 
262
+ /**
263
+ * 渲染某一行
264
+ */
265
+ renderLine(index: number, line: string, showLineNumber: boolean) {
266
+ const {classnames: cx, disableColor} = this.props;
267
+ return (
268
+ <div className={cx('Log-line')} key={index}>
269
+ {showLineNumber && (
270
+ <span className={cx('Log-line-number')}>{index + 1} </span>
271
+ )}
272
+ {disableColor ? line : <Ansi useClasses>{line}</Ansi>}
273
+ </div>
274
+ );
275
+ }
276
+
183
277
  render() {
184
278
  const {
185
279
  source,
@@ -187,32 +281,132 @@ export class Log extends React.Component<LogProps, LogState> {
187
281
  classnames: cx,
188
282
  placeholder,
189
283
  height,
190
- translate: __
284
+ rowHeight,
285
+ disableColor,
286
+ translate: __,
287
+ operation,
288
+ env
191
289
  } = this.props;
192
290
 
291
+ const {refresh, showLineNumber, showOperation} = this.state;
292
+
193
293
  let loading = __(placeholder);
194
294
 
195
295
  if (!source) {
196
296
  loading = __('Log.mustHaveSource');
197
297
  }
298
+ let lines: any;
198
299
 
199
- const lines = this.state.logs.map((line, index) => {
200
- return (
201
- <div className={cx('Log-line')} key={index}>
202
- <Ansi useClasses>{line}</Ansi>
203
- </div>
300
+ const logs = this.state.lastLine
301
+ ? this.state.logs.concat([this.state.lastLine])
302
+ : this.state.logs;
303
+
304
+ // 如果设置 rowHeight 就开启延迟渲染
305
+ const useVirtualRender = rowHeight;
306
+
307
+ if (useVirtualRender) {
308
+ lines = (
309
+ <VirtualList
310
+ height={height as number}
311
+ itemCount={logs.length}
312
+ itemSize={rowHeight}
313
+ renderItem={({index, style}) => (
314
+ <div
315
+ className={cx('Log-line')}
316
+ key={index}
317
+ style={{...style, whiteSpace: 'nowrap'}}
318
+ >
319
+ {showLineNumber && (
320
+ <span className={cx('Log-line-number')}>{index + 1} </span>
321
+ )}
322
+ {disableColor ? (
323
+ logs[index]
324
+ ) : (
325
+ <Ansi useClasses>{logs[index]}</Ansi>
326
+ )}
327
+ </div>
328
+ )}
329
+ />
204
330
  );
205
- });
331
+ } else {
332
+ lines = logs.map((line, index) => {
333
+ return this.renderLine(index, line, showLineNumber);
334
+ });
335
+ }
206
336
 
207
337
  return (
208
- <div
209
- ref={this.logRef}
210
- className={cx('Log', className)}
211
- style={{height: height}}
212
- >
213
- {lines.length ? lines : loading}
214
- <div className={cx('Log-line')} key="last">
215
- <code>{this.state.lastLine}</code>
338
+ <div className={cx('Log', className)}>
339
+ <div
340
+ ref={this.logRef}
341
+ className={cx('Log-body')}
342
+ style={{height: useVirtualRender ? 'auto' : height}}
343
+ >
344
+ {useVirtualRender ? lines : lines.length ? lines : loading}
345
+ </div>
346
+ <div className={cx('Log-operation')}>
347
+ {operation &&
348
+ operation?.length > 0 &&
349
+ (showOperation ? (
350
+ <>
351
+ {operation.includes('stop') && (
352
+ <Button
353
+ size="sm"
354
+ title="__('stop')"
355
+ disabled={!refresh}
356
+ onClick={this.refresh}
357
+ >
358
+ <PauseIcon />
359
+ </Button>
360
+ )}
361
+
362
+ {operation.includes('restart') && (
363
+ <Button
364
+ size="sm"
365
+ title={__('reload')}
366
+ disabled={refresh}
367
+ onClick={this.refresh}
368
+ >
369
+ <ReloadIcon />
370
+ </Button>
371
+ )}
372
+
373
+ {operation.includes('showLineNumber') && (
374
+ <Button
375
+ size="sm"
376
+ title={
377
+ showLineNumber
378
+ ? __('Log.notShowLineNumber')
379
+ : __('Log.showLineNumber')
380
+ }
381
+ onClick={this.changeShowLineNumber}
382
+ >
383
+ {showLineNumber ? <MinusIcon /> : <PlusIcon />}
384
+ </Button>
385
+ )}
386
+
387
+ {operation.includes('clear') && (
388
+ <Button size="sm" title={__('clear')} onClick={this.clear}>
389
+ <InputClearIcon />
390
+ </Button>
391
+ )}
392
+
393
+ <Button
394
+ size="sm"
395
+ title={__('Log.collapse')}
396
+ onClick={this.changeShowOperation}
397
+ >
398
+ <LeftArrowIcon />
399
+ </Button>
400
+ </>
401
+ ) : (
402
+ <div
403
+ title={__('Log.expand')}
404
+ className={cx('Log-operation-hidden')}
405
+ onClick={this.changeShowOperation}
406
+ >
407
+ <RightArrowIcon />
408
+ </div>
409
+ ))}
216
410
  </div>
217
411
  </div>
218
412
  );
@@ -467,6 +467,7 @@ export default class Page extends React.Component<PageProps> {
467
467
  store.openDrawer(ctx);
468
468
  } else if (action.actionType === 'ajax') {
469
469
  store.setCurrentAction(action);
470
+
470
471
  return store
471
472
  .saveRemote(action.api as string, ctx, {
472
473
  successMessage:
@@ -486,7 +487,11 @@ export default class Page extends React.Component<PageProps> {
486
487
  redirect && env.jumpTo(redirect, action);
487
488
  action.reload && this.reloadTarget(action.reload, store.data);
488
489
  })
489
- .catch(() => {});
490
+ .catch((e) => {
491
+ if (throwErrors || action.countDown) {
492
+ throw e;
493
+ }
494
+ });
490
495
  } else {
491
496
  return onAction(e, action, ctx, throwErrors, delegate || this.context);
492
497
  }
@@ -523,7 +523,11 @@ export default class Service extends React.Component<ServiceProps> {
523
523
  redirect && env.jumpTo(redirect, action);
524
524
  action.reload && this.reloadTarget(action.reload, store.data);
525
525
  })
526
- .catch(() => {});
526
+ .catch((e) => {
527
+ if (throwErrors || action.countDown) {
528
+ throw e;
529
+ }
530
+ });
527
531
  } else {
528
532
  onAction(e, action, data, throwErrors, delegate || this.context);
529
533
  }
@@ -718,23 +718,41 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
718
718
 
719
719
  formStore
720
720
  .saveRemote(action.api || step.api || api!, store.data, {
721
- onSuccess: () => {
722
- this.dispatchEvent('submitSucc', store.data);
721
+ onSuccess: async (result: any) => {
722
+ const dispatcher = await this.dispatchEvent(
723
+ 'submitSucc',
724
+ createObject(this.props.data, {result})
725
+ );
723
726
 
724
727
  if (
725
728
  !isEffectiveApi(finnalAsyncApi, store.data) ||
726
729
  store.data[finishedField || 'finished']
727
730
  ) {
728
- return;
731
+ return {
732
+ cbResult: null,
733
+ dispatcher
734
+ };
729
735
  }
730
736
 
731
- return until(
737
+ const cbResult = until(
732
738
  () => store.checkRemote(finnalAsyncApi as Api, store.data),
733
739
  (ret: any) => ret && ret[finishedField || 'finished'],
734
740
  cancel => (this.asyncCancel = cancel)
735
741
  );
742
+ return {
743
+ cbResult,
744
+ dispatcher
745
+ };
736
746
  },
737
- onFailed: error => this.dispatchEvent('submitFail', {error})
747
+ onFailed: async (error: any) => {
748
+ const dispatcher = await this.dispatchEvent(
749
+ 'submitFail',
750
+ createObject(this.props.data, {error})
751
+ );
752
+ return {
753
+ dispatcher
754
+ };
755
+ }
738
756
  })
739
757
  .then(async value => {
740
758
  const feedback = action.feedback;
@@ -778,11 +796,7 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
778
796
 
779
797
  return value;
780
798
  })
781
- .catch(error => {
782
- this.dispatchEvent('submitFail', {error});
783
- store.markSaving(false);
784
- console.error(error);
785
- });
799
+ .catch(error => {});
786
800
  } else {
787
801
  onFinished && onFinished(store.data, action);
788
802
  this.setState({completeStep: steps.length});
package/src/store/form.ts CHANGED
@@ -326,10 +326,7 @@ export const FormStore = ServiceStore.named('FormStore')
326
326
  }
327
327
 
328
328
  if (!json.ok) {
329
- // 验证错误
330
- if (options && options.onFailed) {
331
- options.onFailed(json);
332
- }
329
+
333
330
  if (json.status === 422 && json.errors) {
334
331
  setFormItemErrors(json.errors);
335
332
 
@@ -349,18 +346,19 @@ export const FormStore = ServiceStore.named('FormStore')
349
346
  throw new ServerError(self.msg, json);
350
347
  } else {
351
348
  updateSavedData();
352
- if (options && options.onSuccess) {
353
- const ret = options.onSuccess(json);
354
-
355
- if (ret && ret.then) {
356
- yield ret;
357
- }
349
+ let ret = options && options.onSuccess && options.onSuccess(json);
350
+ if (ret?.then) {
351
+ ret = yield ret;
352
+ }
353
+ if (ret?.cbResult?.then) {
354
+ yield ret.cbResult;
358
355
  }
359
356
  self.markSaving(false);
360
357
  self.updateMessage(
361
358
  json.msg ?? self.__(options && options.successMessage)
362
359
  );
363
- self.msg &&
360
+ if (!ret?.dispatcher?.prevented) {
361
+ self.msg &&
364
362
  getEnv(self).notify(
365
363
  'success',
366
364
  self.msg,
@@ -371,15 +369,21 @@ export const FormStore = ServiceStore.named('FormStore')
371
369
  }
372
370
  : undefined
373
371
  );
372
+ }
374
373
  return json.data;
375
374
  }
376
375
  } catch (e) {
377
376
  self.markSaving(false);
378
-
377
+ let ret = options && options.onFailed && options.onFailed(e.response || {});
378
+ if (ret?.then) {
379
+ ret = yield ret;
380
+ }
379
381
  if (!isAlive(self) || self.disposed) {
380
382
  return;
381
383
  }
382
-
384
+ if (ret?.dispatcher?.prevented) {
385
+ return;
386
+ }
383
387
  if (e.type === 'ServerError') {
384
388
  const result = (e as ServerError).response;
385
389
  getEnv(self).notify(
@@ -395,7 +399,6 @@ export const FormStore = ServiceStore.named('FormStore')
395
399
  } else {
396
400
  getEnv(self).notify('error', e.message);
397
401
  }
398
-
399
402
  throw e;
400
403
  }
401
404
  });
@@ -479,9 +482,13 @@ export const FormStore = ServiceStore.named('FormStore')
479
482
  ) {
480
483
  let msg = failedMessage ?? self.__('Form.validateFailed');
481
484
  const env = getEnv(self);
482
-
483
- msg && env.notify('error', msg);
484
- validateErrCb && validateErrCb();
485
+ let dispatcher: any = validateErrCb && validateErrCb();
486
+ if (dispatcher?.then) {
487
+ dispatcher = yield dispatcher;
488
+ }
489
+ if (!dispatcher?.prevented){
490
+ msg && env.notify('error', msg);
491
+ }
485
492
  throw new Error(msg);
486
493
  }
487
494
 
package/src/utils/api.ts CHANGED
@@ -307,7 +307,7 @@ export function responseAdaptor(ret: fetcherResult, api: ApiObject) {
307
307
  if (data.hasOwnProperty('errorCode')) {
308
308
  // 阿里 Java 规范
309
309
  data.status = data.errorCode;
310
- data.msg = data.errorMessage;
310
+ data.msg = data.errorMessage || data.errorMsg;
311
311
  } else if (data.hasOwnProperty('errno')) {
312
312
  data.status = data.errno;
313
313
  data.msg = data.errmsg || data.errstr || data.msg;
@@ -138,7 +138,6 @@ export async function dispatchEvent(
138
138
 
139
139
  unbindEvent = bindEvent(renderer);
140
140
  }
141
-
142
141
  // 没有可处理的监听
143
142
  if (!rendererEventListeners.length) {
144
143
  return Promise.resolve();
@@ -152,7 +151,6 @@ export async function dispatchEvent(
152
151
  data,
153
152
  scoped
154
153
  });
155
-
156
154
  // 过滤&排序
157
155
  const listeners = rendererEventListeners
158
156
  .filter(