amis 1.9.0 → 1.9.1-beta.3

Sign up to get free protection for your applications and to get access to all the features.
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(