amis 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/README.md +2 -1
  2. package/lib/RootRenderer.js +4 -1
  3. package/lib/RootRenderer.js.map +2 -2
  4. package/lib/components/Badge.d.ts +13 -1
  5. package/lib/components/Badge.js +16 -2
  6. package/lib/components/Badge.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 +0 -3
  15. package/lib/components/RichText.js +1 -22
  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/condition-builder/Field.js +0 -1
  25. package/lib/components/condition-builder/Field.js.map +2 -2
  26. package/lib/components/condition-builder/Value.js +2 -1
  27. package/lib/components/condition-builder/Value.js.map +2 -2
  28. package/lib/components/condition-builder/types.d.ts +5 -0
  29. package/lib/components/condition-builder/types.js.map +1 -1
  30. package/lib/env.d.ts +1 -1
  31. package/lib/env.js.map +1 -1
  32. package/lib/factory.d.ts +6 -2
  33. package/lib/factory.js +9 -4
  34. package/lib/factory.js.map +2 -2
  35. package/lib/index.d.ts +1 -0
  36. package/lib/index.js +2 -1
  37. package/lib/index.js.map +2 -2
  38. package/lib/locale/de-DE.js +1 -0
  39. package/lib/locale/de-DE.js.map +2 -2
  40. package/lib/locale/en-US.js +2 -1
  41. package/lib/locale/en-US.js.map +2 -2
  42. package/lib/locale/zh-CN.js +2 -1
  43. package/lib/locale/zh-CN.js.map +2 -2
  44. package/lib/renderers/Action.d.ts +6 -0
  45. package/lib/renderers/Action.js +9 -1
  46. package/lib/renderers/Action.js.map +2 -2
  47. package/lib/renderers/CRUD.d.ts +2 -2
  48. package/lib/renderers/CRUD.js +13 -21
  49. package/lib/renderers/CRUD.js.map +2 -2
  50. package/lib/renderers/Card.js +11 -11
  51. package/lib/renderers/Card.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/Copyable.js +30 -28
  56. package/lib/renderers/Copyable.js.map +2 -2
  57. package/lib/renderers/Dialog.d.ts +0 -252
  58. package/lib/renderers/Dialog.js +3 -2
  59. package/lib/renderers/Dialog.js.map +2 -2
  60. package/lib/renderers/Drawer.js +2 -1
  61. package/lib/renderers/Drawer.js.map +2 -2
  62. package/lib/renderers/DropDownButton.d.ts +4 -0
  63. package/lib/renderers/DropDownButton.js +2 -2
  64. package/lib/renderers/DropDownButton.js.map +2 -2
  65. package/lib/renderers/Form/ButtonGroupSelect.js +3 -0
  66. package/lib/renderers/Form/ButtonGroupSelect.js.map +2 -2
  67. package/lib/renderers/Form/Combo.d.ts +2 -0
  68. package/lib/renderers/Form/Combo.js +16 -1
  69. package/lib/renderers/Form/Combo.js.map +2 -2
  70. package/lib/renderers/Form/DiffEditor.d.ts +0 -2
  71. package/lib/renderers/Form/Editor.d.ts +0 -2
  72. package/lib/renderers/Form/Editor.js +1 -1
  73. package/lib/renderers/Form/Editor.js.map +2 -2
  74. package/lib/renderers/Form/InputExcel.d.ts +5 -0
  75. package/lib/renderers/Form/InputExcel.js +24 -3
  76. package/lib/renderers/Form/InputExcel.js.map +2 -2
  77. package/lib/renderers/Form/InputImage.d.ts +8 -0
  78. package/lib/renderers/Form/InputImage.js +2 -1
  79. package/lib/renderers/Form/InputImage.js.map +2 -2
  80. package/lib/renderers/Form/InputNumber.d.ts +19 -5
  81. package/lib/renderers/Form/InputNumber.js +69 -7
  82. package/lib/renderers/Form/InputNumber.js.map +2 -2
  83. package/lib/renderers/Form/InputRange.js +7 -2
  84. package/lib/renderers/Form/InputRange.js.map +2 -2
  85. package/lib/renderers/Form/InputTable.d.ts +23 -5
  86. package/lib/renderers/Form/InputTable.js +32 -3
  87. package/lib/renderers/Form/InputTable.js.map +2 -2
  88. package/lib/renderers/Form/NestedSelect.js +2 -3
  89. package/lib/renderers/Form/NestedSelect.js.map +2 -2
  90. package/lib/renderers/Form/Options.js +3 -1
  91. package/lib/renderers/Form/Options.js.map +2 -2
  92. package/lib/renderers/Form/index.js +0 -10
  93. package/lib/renderers/Form/index.js.map +2 -2
  94. package/lib/renderers/Form/wrapControl.js +3 -3
  95. package/lib/renderers/Form/wrapControl.js.map +2 -2
  96. package/lib/renderers/Json.js +5 -1
  97. package/lib/renderers/Json.js.map +2 -2
  98. package/lib/renderers/List.d.ts +5 -0
  99. package/lib/renderers/List.js +20 -14
  100. package/lib/renderers/List.js.map +2 -2
  101. package/lib/renderers/Page.d.ts +6 -0
  102. package/lib/renderers/Page.js +10 -2
  103. package/lib/renderers/Page.js.map +2 -2
  104. package/lib/renderers/Service.d.ts +10 -1
  105. package/lib/renderers/Service.js +85 -3
  106. package/lib/renderers/Service.js.map +2 -2
  107. package/lib/renderers/Steps.d.ts +4 -4
  108. package/lib/renderers/Steps.js +5 -2
  109. package/lib/renderers/Steps.js.map +2 -2
  110. package/lib/renderers/Table/TableBody.d.ts +5 -3
  111. package/lib/renderers/Table/TableBody.js +17 -11
  112. package/lib/renderers/Table/TableBody.js.map +2 -2
  113. package/lib/renderers/Table/TableCell.js +6 -2
  114. package/lib/renderers/Table/TableCell.js.map +2 -2
  115. package/lib/renderers/Table/TableContent.d.ts +3 -1
  116. package/lib/renderers/Table/TableContent.js +6 -2
  117. package/lib/renderers/Table/TableContent.js.map +2 -2
  118. package/lib/renderers/Table/TableRow.d.ts +1 -1
  119. package/lib/renderers/Table/TableRow.js +14 -13
  120. package/lib/renderers/Table/TableRow.js.map +2 -2
  121. package/lib/renderers/Table/index.d.ts +28 -3
  122. package/lib/renderers/Table/index.js +97 -54
  123. package/lib/renderers/Table/index.js.map +2 -2
  124. package/lib/schemaExtend.d.ts +1 -0
  125. package/lib/schemaExtend.js +59 -0
  126. package/lib/schemaExtend.js.map +13 -0
  127. package/lib/store/app.d.ts +0 -1
  128. package/lib/store/combo.d.ts +0 -2
  129. package/lib/store/crud.d.ts +3 -3
  130. package/lib/store/crud.js +41 -36
  131. package/lib/store/crud.js.map +2 -2
  132. package/lib/store/form.d.ts +0 -1
  133. package/lib/store/formItem.js +10 -6
  134. package/lib/store/formItem.js.map +2 -2
  135. package/lib/store/modal.d.ts +1 -1
  136. package/lib/store/modal.js +4 -0
  137. package/lib/store/modal.js.map +2 -2
  138. package/lib/store/root.d.ts +0 -1
  139. package/lib/store/service.d.ts +0 -1
  140. package/lib/store/service.js +0 -13
  141. package/lib/store/service.js.map +2 -2
  142. package/lib/store/table.d.ts +1 -2
  143. package/lib/store/table.js +44 -3
  144. package/lib/store/table.js.map +2 -2
  145. package/lib/themes/ang-ie11.css +278 -17
  146. package/lib/themes/ang.css +278 -17
  147. package/lib/themes/ang.css.map +1 -1
  148. package/lib/themes/antd-ie11.css +278 -17
  149. package/lib/themes/antd.css +278 -17
  150. package/lib/themes/antd.css.map +1 -1
  151. package/lib/themes/cxd-ie11.css +278 -17
  152. package/lib/themes/cxd.css +278 -17
  153. package/lib/themes/cxd.css.map +1 -1
  154. package/lib/themes/dark-ie11.css +278 -17
  155. package/lib/themes/dark.css +278 -17
  156. package/lib/themes/dark.css.map +1 -1
  157. package/lib/themes/default.css +278 -17
  158. package/lib/themes/default.css.map +1 -1
  159. package/lib/utils/api.js +12 -0
  160. package/lib/utils/api.js.map +2 -2
  161. package/lib/utils/attachmentAdpator.d.ts +7 -0
  162. package/lib/utils/attachmentAdpator.js +82 -0
  163. package/lib/utils/attachmentAdpator.js.map +13 -0
  164. package/lib/utils/helper.d.ts +2 -0
  165. package/lib/utils/helper.js +14 -1
  166. package/lib/utils/helper.js.map +2 -2
  167. package/lib/utils/resize-sensor.js +6 -0
  168. package/lib/utils/resize-sensor.js.map +2 -2
  169. package/lib/utils/tpl-builtin.d.ts +1 -0
  170. package/lib/utils/tpl-builtin.js +24 -8
  171. package/lib/utils/tpl-builtin.js.map +2 -2
  172. package/lib/utils/validations.js +62 -5
  173. package/lib/utils/validations.js.map +2 -2
  174. package/package.json +1 -1
  175. package/schema.json +369 -164
  176. package/scss/_properties.scss +6 -0
  177. package/scss/components/_badge.scss +15 -1
  178. package/scss/components/_list.scss +8 -0
  179. package/scss/components/_markdown.scss +266 -0
  180. package/scss/components/_spinner.scss +6 -2
  181. package/scss/components/_table.scss +4 -0
  182. package/scss/components/form/_form.scss +3 -17
  183. package/scss/components/form/_group.scss +4 -0
  184. package/scss/components/form/_nested-select.scss +4 -0
  185. package/scss/components/form/_number.scss +12 -1
  186. package/scss/themes/_common.scss +1 -0
  187. package/sdk/ang-ie11.css +324 -20
  188. package/sdk/ang.css +330 -20
  189. package/sdk/antd-ie11.css +324 -20
  190. package/sdk/antd.css +330 -20
  191. package/sdk/charts.js +15 -15
  192. package/sdk/color-picker.js +65 -69
  193. package/sdk/cropperjs.js +2 -2
  194. package/sdk/cxd-ie11.css +324 -20
  195. package/sdk/cxd.css +330 -20
  196. package/sdk/dark-ie11.css +324 -20
  197. package/sdk/dark.css +330 -20
  198. package/sdk/exceljs.js +1 -1
  199. package/sdk/locale/de-DE.js +1 -0
  200. package/sdk/markdown.js +69 -69
  201. package/sdk/papaparse.js +1 -1
  202. package/sdk/renderers/Form/CityDB.js +1 -1
  203. package/sdk/rest.js +27 -23
  204. package/sdk/rich-text.js +63 -63
  205. package/sdk/sdk-ie11.css +324 -20
  206. package/sdk/sdk.css +330 -20
  207. package/sdk/sdk.js +1146 -1138
  208. package/sdk/thirds/hls.js/hls.js +1 -1
  209. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  210. package/sdk/tinymce.js +57 -57
  211. package/src/RootRenderer.tsx +8 -3
  212. package/src/components/Badge.tsx +41 -6
  213. package/src/components/Checkbox.tsx +5 -2
  214. package/src/components/Drawer.tsx +3 -2
  215. package/src/components/Modal.tsx +3 -2
  216. package/src/components/RichText.tsx +2 -27
  217. package/src/components/Select.tsx +1 -0
  218. package/src/components/Steps.tsx +3 -3
  219. package/src/components/WithRemoteConfig.tsx +37 -2
  220. package/src/components/condition-builder/Field.tsx +1 -2
  221. package/src/components/condition-builder/Value.tsx +3 -0
  222. package/src/components/condition-builder/types.ts +6 -0
  223. package/src/env.tsx +1 -1
  224. package/src/factory.tsx +14 -4
  225. package/src/index.tsx +2 -0
  226. package/src/locale/de-DE.ts +1 -0
  227. package/src/locale/en-US.ts +2 -1
  228. package/src/locale/zh-CN.ts +2 -1
  229. package/src/renderers/Action.tsx +19 -1
  230. package/src/renderers/CRUD.tsx +15 -34
  231. package/src/renderers/Card.tsx +21 -15
  232. package/src/renderers/Collapse.tsx +5 -1
  233. package/src/renderers/Copyable.tsx +46 -44
  234. package/src/renderers/Dialog.tsx +3 -2
  235. package/src/renderers/Drawer.tsx +2 -1
  236. package/src/renderers/DropDownButton.tsx +8 -0
  237. package/src/renderers/Form/ButtonGroupSelect.tsx +3 -0
  238. package/src/renderers/Form/Combo.tsx +7 -0
  239. package/src/renderers/Form/Editor.tsx +19 -20
  240. package/src/renderers/Form/InputExcel.tsx +28 -3
  241. package/src/renderers/Form/InputImage.tsx +23 -8
  242. package/src/renderers/Form/InputNumber.tsx +113 -18
  243. package/src/renderers/Form/InputRange.tsx +5 -2
  244. package/src/renderers/Form/InputTable.tsx +88 -9
  245. package/src/renderers/Form/NestedSelect.tsx +1 -1
  246. package/src/renderers/Form/Options.tsx +3 -1
  247. package/src/renderers/Form/index.tsx +0 -15
  248. package/src/renderers/Form/wrapControl.tsx +2 -2
  249. package/src/renderers/Json.tsx +10 -1
  250. package/src/renderers/List.tsx +32 -19
  251. package/src/renderers/Page.tsx +19 -0
  252. package/src/renderers/Service.tsx +101 -3
  253. package/src/renderers/Steps.tsx +12 -9
  254. package/src/renderers/Table/TableBody.tsx +29 -10
  255. package/src/renderers/Table/TableCell.tsx +15 -1
  256. package/src/renderers/Table/TableContent.tsx +7 -1
  257. package/src/renderers/Table/TableRow.tsx +18 -17
  258. package/src/renderers/Table/index.tsx +117 -28
  259. package/src/schemaExtend.ts +66 -0
  260. package/src/store/crud.ts +34 -38
  261. package/src/store/formItem.ts +10 -6
  262. package/src/store/modal.ts +4 -0
  263. package/src/store/service.ts +0 -19
  264. package/src/store/table.ts +48 -0
  265. package/src/utils/api.ts +11 -0
  266. package/src/utils/attachmentAdpator.ts +90 -0
  267. package/src/utils/helper.ts +15 -0
  268. package/src/utils/resize-sensor.ts +7 -0
  269. package/src/utils/tpl-builtin.ts +36 -17
  270. package/src/utils/validations.ts +80 -12
@@ -116,12 +116,14 @@ export class RootRenderer extends React.Component<RootRendererProps> {
116
116
  );
117
117
  } else if (action.actionType === 'email') {
118
118
  const mailTo = filter(action.to, ctx);
119
- const mailInfo = mapValues(pick(action, 'to', 'cc', 'bcc', 'subject', 'body'), val => filter(val, ctx));
119
+ const mailInfo = mapValues(
120
+ pick(action, 'to', 'cc', 'bcc', 'subject', 'body'),
121
+ val => filter(val, ctx)
122
+ );
120
123
  const mailStr = qs.stringify(mailInfo);
121
124
  const mailto = `mailto:${mailTo}?${mailStr}`;
122
125
 
123
126
  window.open(mailto);
124
-
125
127
  } else if (action.actionType === 'dialog') {
126
128
  store.setCurrentAction(action);
127
129
  store.openDialog(ctx);
@@ -159,7 +161,10 @@ export class RootRenderer extends React.Component<RootRendererProps> {
159
161
  action.actionType === 'copy' &&
160
162
  (action.content || action.copy)
161
163
  ) {
162
- env.copy && env.copy(filter(action.content || action.copy, ctx, '| raw'));
164
+ env.copy &&
165
+ env.copy(filter(action.content || action.copy, ctx, '| raw'), {
166
+ format: action.copyFormat
167
+ });
163
168
  }
164
169
  }
165
170
 
@@ -17,7 +17,7 @@ export interface BadgeSchema extends BaseSchema {
17
17
  /**
18
18
  * 文本内容
19
19
  */
20
- text?: string;
20
+ text?: string | number;
21
21
 
22
22
  /**
23
23
  * 大小
@@ -29,11 +29,21 @@ export interface BadgeSchema extends BaseSchema {
29
29
  */
30
30
  mode?: 'text' | 'dot';
31
31
 
32
+ /**
33
+ * 角标位置,优先级大于position
34
+ */
35
+ offset?: [number | string, number | string];
36
+
32
37
  /**
33
38
  * 角标位置
34
39
  */
35
40
  position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
36
41
 
42
+ /**
43
+ * 封顶的数字值
44
+ */
45
+ overflowCount?: number;
46
+
37
47
  /**
38
48
  * 动态控制是否显示
39
49
  */
@@ -50,6 +60,11 @@ export interface BadgeSchema extends BaseSchema {
50
60
  style?: {
51
61
  [propName: string]: any;
52
62
  };
63
+
64
+ /**
65
+ * 提示类型
66
+ */
67
+ level?: 'info' | 'warning' | 'success' | 'danger';
53
68
  }
54
69
 
55
70
  export interface BadgeProps {
@@ -81,10 +96,13 @@ export class Badge extends React.Component<BadgeProps, object> {
81
96
  text,
82
97
  size,
83
98
  style,
99
+ offset,
84
100
  position = 'top-right',
101
+ overflowCount = 99,
85
102
  visibleOn,
86
103
  className,
87
- animation
104
+ animation,
105
+ level = 'danger'
88
106
  } = badge;
89
107
 
90
108
  if (visibleOn) {
@@ -111,6 +129,12 @@ export class Badge extends React.Component<BadgeProps, object> {
111
129
  height: size,
112
130
  lineHeight: size + 'px'
113
131
  };
132
+ // 当text、overflowCount都为number类型时,进行封顶值处理
133
+ if (typeof text === 'number' && typeof overflowCount === 'number') {
134
+ text = (
135
+ (text as number) > (overflowCount as number) ? `${overflowCount}+` : text
136
+ ) as string | number;
137
+ }
114
138
 
115
139
  if (!text) {
116
140
  isDisplay = false;
@@ -121,6 +145,17 @@ export class Badge extends React.Component<BadgeProps, object> {
121
145
  sizeStyle = {width: size, height: size};
122
146
  }
123
147
 
148
+ let offsetStyle = {};
149
+ // 如果设置了offset属性,offset在position为'top-right'的基础上进行translate定位
150
+ if (offset && offset.length) {
151
+ position = 'top-right';
152
+ const left = `calc(50% + ${parseInt(offset[0] as string, 10)}px)`;
153
+ const right = `calc(-50% + ${parseInt(offset[1] as string, 10)}px)`;
154
+ offsetStyle = {
155
+ transform: `translate(${left}, ${right})`,
156
+ };
157
+ }
158
+
124
159
  let animationBackground = 'var(--danger)';
125
160
 
126
161
  if (style && style.background) {
@@ -148,15 +183,15 @@ export class Badge extends React.Component<BadgeProps, object> {
148
183
  {isDisplay ? (
149
184
  mode === 'dot' ? (
150
185
  <span
151
- className={cx('Badge-dot', `Badge--${position}`)}
152
- style={{...sizeStyle, ...style}}
186
+ className={cx('Badge-dot', `Badge--${position}`, `Badge--${level}`)}
187
+ style={{...offsetStyle, ...sizeStyle, ...style}}
153
188
  >
154
189
  {animationElement}
155
190
  </span>
156
191
  ) : (
157
192
  <span
158
- className={cx('Badge-text', `Badge--${position}`)}
159
- style={{...sizeStyle, ...style}}
193
+ className={cx('Badge-text', `Badge--${position}`, `Badge--${level}`)}
194
+ style={{...offsetStyle, ...sizeStyle, ...style}}
160
195
  >
161
196
  {text}
162
197
  {animationElement}
@@ -15,7 +15,7 @@ interface CheckboxProps {
15
15
  label?: string;
16
16
  labelClassName?: string;
17
17
  className?: string;
18
- onChange?: (value: any) => void;
18
+ onChange?: (value: any, shift?: boolean) => void;
19
19
  value?: any;
20
20
  inline?: boolean;
21
21
  trueValue?: any;
@@ -48,7 +48,10 @@ export class Checkbox extends React.Component<CheckboxProps, any> {
48
48
  return;
49
49
  }
50
50
 
51
- onChange(e.currentTarget.checked ? trueValue : falseValue);
51
+ onChange(
52
+ e.currentTarget.checked ? trueValue : falseValue,
53
+ (e.nativeEvent as MouseEvent).shiftKey
54
+ );
52
55
  }
53
56
 
54
57
  render() {
@@ -8,7 +8,8 @@ import React from 'react';
8
8
  import Transition, {
9
9
  ENTERED,
10
10
  ENTERING,
11
- EXITING
11
+ EXITING,
12
+ EXITED
12
13
  } from 'react-transition-group/Transition';
13
14
  import Portal from 'react-overlays/Portal';
14
15
  import {Icon} from './icons';
@@ -230,7 +231,7 @@ export class Drawer extends React.Component<DrawerProps, DrawerState> {
230
231
  >
231
232
  <Icon icon="close" className="icon" />
232
233
  </a>
233
- {children}
234
+ {status === EXITED ? null : children}
234
235
  </div>
235
236
  </div>
236
237
  );
@@ -8,7 +8,8 @@ import React from 'react';
8
8
  import Transition, {
9
9
  ENTERED,
10
10
  ENTERING,
11
- EXITING
11
+ EXITING,
12
+ EXITED
12
13
  } from 'react-transition-group/Transition';
13
14
  import Portal from 'react-overlays/Portal';
14
15
  import {current, addModal, removeModal} from './ModalManager';
@@ -264,7 +265,7 @@ export class Modal extends React.Component<ModalProps, ModalState> {
264
265
  fadeStyles[status]
265
266
  )}
266
267
  >
267
- {children}
268
+ {status === EXITED ? null : children}
268
269
  </div>
269
270
  </div>
270
271
  </Portal>
@@ -46,8 +46,6 @@ import 'froala-editor/css/froala_style.min.css';
46
46
  import 'froala-editor/css/froala_editor.pkgd.min.css';
47
47
 
48
48
  export default class FroalaEditor extends React.Component<any, any> {
49
- oldModel: any = null;
50
-
51
49
  constructor(props: any) {
52
50
  super(props);
53
51
  Froala.VIDEO_PROVIDERS = [
@@ -58,29 +56,6 @@ export default class FroalaEditor extends React.Component<any, any> {
58
56
  html: '<span class="fr-video fr-dvb fr-draggable" contenteditable="false" draggable="true"><video class="fr-draggable" controls="" data-msg="ok" data-status="0" src="{url}" style="width: 600px;"></video></span>'
59
57
  }
60
58
  ];
61
-
62
- this.state = {
63
- model: this.props.model
64
- };
65
- this.handleModelChange = this.handleModelChange.bind(this);
66
- }
67
-
68
- componentDidUpdate() {
69
- if (JSON.stringify(this.oldModel) == JSON.stringify(this.props.model)) {
70
- return;
71
- }
72
- this.handleModelChange(this.props.model);
73
- }
74
-
75
- handleModelChange(model: string) {
76
- if (!this.props.onModelChange) {
77
- return;
78
- }
79
- this.oldModel = model;
80
- this.props.onModelChange(model);
81
- this.setState({
82
- model: model
83
- });
84
59
  }
85
60
 
86
61
  render() {
@@ -88,8 +63,8 @@ export default class FroalaEditor extends React.Component<any, any> {
88
63
  <FroalaEditorComponent
89
64
  tag="textarea"
90
65
  config={this.props.config}
91
- model={this.state.model}
92
- onModelChange={this.handleModelChange}
66
+ model={this.props.model}
67
+ onModelChange={this.props.onModelChange}
93
68
  />
94
69
  );
95
70
  }
@@ -1107,6 +1107,7 @@ export const SelectWithRemoteOptions = withRemoteConfig<Array<Options>>({
1107
1107
  > {
1108
1108
  render() {
1109
1109
  const {loading, config, deferLoad, updateConfig, ...rest} = this.props;
1110
+
1110
1111
  return (
1111
1112
  <EnhancedSelect
1112
1113
  {...rest}
@@ -14,12 +14,12 @@ export type StepSchema = {
14
14
  /**
15
15
  * 标题
16
16
  */
17
- title: string;
17
+ title?: string | JSX.Element;
18
18
 
19
19
  /**
20
20
  * 子标题
21
21
  */
22
- subTitle?: string;
22
+ subTitle?: string | JSX.Element;
23
23
 
24
24
  /**
25
25
  * 图标
@@ -31,7 +31,7 @@ export type StepSchema = {
31
31
  /**
32
32
  * 描述
33
33
  */
34
- description?: string;
34
+ description?: string | JSX.Element;
35
35
 
36
36
  status?: StepStatus;
37
37
  } & Omit<BaseSchema, 'type'>;
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import React from 'react';
6
6
  import hoistNonReactStatic from 'hoist-non-react-statics';
7
+ import debounce from 'lodash/debounce';
7
8
  import {Api, Payload} from '../types';
8
9
  import {SchemaApi, SchemaTokenizeableString} from '../Schema';
9
10
  import {withStore} from './WithStore';
@@ -97,6 +98,7 @@ export interface OutterProps {
97
98
  env?: RendererEnv;
98
99
  data: any;
99
100
  source?: SchemaApi | SchemaTokenizeableString;
101
+ autoComplete?: SchemaApi | SchemaTokenizeableString;
100
102
  deferApi?: SchemaApi;
101
103
  remoteConfigRef?: (
102
104
  instance:
@@ -182,10 +184,16 @@ export function withRemoteConfig<P = any>(
182
184
  static displayName = `WithRemoteConfig(${
183
185
  ComposedComponent.displayName || ComposedComponent.name
184
186
  })`;
185
- static ComposedComponent = ComposedComponent as React.ComponentType<T>;
187
+ static ComposedComponent =
188
+ ComposedComponent as React.ComponentType<T>;
186
189
  static contextType = EnvContext;
187
190
  toDispose: Array<() => void> = [];
188
191
 
192
+ loadOptions = debounce(this.loadAutoComplete.bind(this), 250, {
193
+ trailing: true,
194
+ leading: false
195
+ });
196
+
189
197
  constructor(
190
198
  props: FinalOutterProps & {
191
199
  store: IStore;
@@ -250,6 +258,7 @@ export function withRemoteConfig<P = any>(
250
258
  this.toDispose = [];
251
259
 
252
260
  this.props.remoteConfigRef?.(undefined);
261
+ this.loadOptions.cancel();
253
262
  }
254
263
 
255
264
  async loadConfig(ctx = this.props.data) {
@@ -261,6 +270,28 @@ export function withRemoteConfig<P = any>(
261
270
  }
262
271
  }
263
272
 
273
+ loadAutoComplete(input: string) {
274
+ const env: RendererEnv = this.props.env || this.context;
275
+ const {autoComplete, data, store} = this.props;
276
+
277
+ if (!env || !env.fetcher) {
278
+ throw new Error('fetcher is required');
279
+ }
280
+
281
+ const ctx = createObject(data, {
282
+ term: input,
283
+ value: input
284
+ });
285
+
286
+ if (!isEffectiveApi(autoComplete, ctx)) {
287
+ return Promise.resolve({
288
+ options: []
289
+ });
290
+ }
291
+
292
+ return store.load(env, autoComplete, ctx, config);
293
+ }
294
+
264
295
  setConfig(value: any, ctx?: any) {
265
296
  const {store} = this.props;
266
297
  store.setConfig(value, config, ctx);
@@ -321,13 +352,14 @@ export function withRemoteConfig<P = any>(
321
352
 
322
353
  render() {
323
354
  const store = this.props.store;
355
+ const env: RendererEnv = this.props.env || this.context;
324
356
  const injectedProps: RemoteOptionsProps<P> = {
325
357
  config: store.config,
326
358
  loading: store.fetching,
327
359
  deferLoad: this.deferLoadConfig,
328
360
  updateConfig: this.setConfig
329
361
  };
330
- const {remoteConfigRef, ...rest} = this.props;
362
+ const {remoteConfigRef, autoComplete, ...rest} = this.props;
331
363
 
332
364
  return (
333
365
  <ComposedComponent
@@ -335,6 +367,9 @@ export function withRemoteConfig<P = any>(
335
367
  T,
336
368
  React.ComponentProps<T>
337
369
  >)}
370
+ {...(env && isEffectiveApi(autoComplete) && this.loadOptions
371
+ ? {loadOptions: this.loadOptions}
372
+ : {})}
338
373
  {...injectedProps}
339
374
  />
340
375
  );
@@ -33,7 +33,6 @@ export class ConditionField extends React.Component<
33
33
  options: props.options
34
34
  };
35
35
  this.onSearch = this.onSearch.bind(this);
36
- this.onSearch = this.onSearch.bind(this);
37
36
  }
38
37
 
39
38
  onSearch(text: string) {
@@ -51,7 +50,7 @@ export class ConditionField extends React.Component<
51
50
  });
52
51
  return children.length > 0
53
52
  ? Object.assign({}, item, {children}) // 需要copy一份,防止覆盖原始数据
54
- : false;
53
+ : false;
55
54
  } else {
56
55
  return item.name.toLowerCase().includes(txt) ||
57
56
  item.label.toLowerCase().includes(txt)
@@ -92,11 +92,14 @@ export class Value extends React.Component<ValueProps> {
92
92
  />
93
93
  );
94
94
  } else if (field.type === 'select') {
95
+ const autoComplete = field.autoComplete;
96
+
95
97
  input = (
96
98
  <Select
97
99
  simpleValue
98
100
  options={field.options!}
99
101
  source={field.source}
102
+ autoComplete={autoComplete}
100
103
  searchable={field.searchable}
101
104
  value={value ?? field.defaultValue ?? ''}
102
105
  data={data}
@@ -145,6 +145,12 @@ interface SelectField extends BaseField {
145
145
  options?: Array<any>;
146
146
  source?: SchemaApi;
147
147
  searchable?: boolean;
148
+
149
+ /**
150
+ * 自动完成 API,当输入部分文字的时候,会将这些文字通过 ${term} 可以取到,发送给接口。
151
+ * 接口可以返回匹配到的选项,帮助用户输入。
152
+ */
153
+ autoComplete?: SchemaApi;
148
154
  }
149
155
 
150
156
  interface BooleanField extends BaseField {
package/src/env.tsx CHANGED
@@ -41,7 +41,7 @@ export interface RendererEnv {
41
41
  schema: Schema,
42
42
  props: any
43
43
  ) => null | RendererConfig;
44
- copy?: (contents: string) => void;
44
+ copy?: (contents: string, format?: any) => void;
45
45
  getModalContainer?: () => HTMLElement;
46
46
  theme: ThemeInstance;
47
47
  affixOffsetTop: number;
package/src/factory.tsx CHANGED
@@ -74,11 +74,16 @@ export interface RenderSchemaFilter {
74
74
  (schema: Schema, renderer: RendererConfig, props?: any): Schema;
75
75
  }
76
76
 
77
+ export interface wsObject {
78
+ url: string;
79
+ body?: any;
80
+ }
81
+
77
82
  export interface RenderOptions {
78
83
  session?: string;
79
84
  fetcher?: (config: fetcherConfig) => Promise<fetcherResult>;
80
85
  wsFetcher?: (
81
- ws: string,
86
+ ws: wsObject,
82
87
  onMessage: (data: any) => void,
83
88
  onError: (error: any) => void
84
89
  ) => void;
@@ -99,7 +104,7 @@ export interface RenderOptions {
99
104
  schema: Schema,
100
105
  props: any
101
106
  ) => null | RendererConfig;
102
- copy?: (contents: string) => void;
107
+ copy?: (contents: string, options?: any) => void;
103
108
  getModalContainer?: () => HTMLElement;
104
109
  loadRenderer?: (
105
110
  schema: Schema,
@@ -234,8 +239,13 @@ const defaultOptions: RenderOptions = {
234
239
  // 使用 WebSocket 来实时获取数据
235
240
  wsFetcher(ws, onMessage, onError) {
236
241
  if (ws) {
237
- const socket = new WebSocket(ws);
238
- socket.onmessage = (event: any) => {
242
+ const socket = new WebSocket(ws.url);
243
+ socket.onopen = event => {
244
+ if (ws.body) {
245
+ socket.send(JSON.stringify(ws.body));
246
+ }
247
+ };
248
+ socket.onmessage = event => {
239
249
  if (event.data) {
240
250
  onMessage(JSON.parse(event.data));
241
251
  }
package/src/index.tsx CHANGED
@@ -174,6 +174,8 @@ import './compat';
174
174
 
175
175
  import './envOverwrite';
176
176
 
177
+ import './schemaExtend';
178
+
177
179
  import './themes/ang';
178
180
  import './themes/cxd';
179
181
  import './themes/dark';
@@ -158,6 +158,7 @@ register('de-DE', {
158
158
  'System.requestError': 'Anfragefehler: ',
159
159
  'System.requestErrorStatus': 'Anfragefehler, Statuscode:',
160
160
  'Table.addRow': 'Zeile hinzufügen',
161
+ 'Table.copyRow': 'Zeile kopieren',
161
162
  'Table.columnsVisibility': 'Klicken, um die Sichtbarkeit der Spalten zu steuern',
162
163
  'Table.deleteRow': 'Aktuele Zeile löschen',
163
164
  'Table.discard': 'Verwerfen',
@@ -158,7 +158,8 @@ register('en-US', {
158
158
  'System.copy': 'Content copied',
159
159
  'System.requestError': 'Request error: ',
160
160
  'System.requestErrorStatus': 'Request error, status code: ',
161
- 'Table.addRow': 'Add a row',
161
+ 'Table.addRow': 'Add row',
162
+ 'Table.copyRow': 'Copy row',
162
163
  'Table.columnsVisibility': 'Click to control columns visibility',
163
164
  'Table.deleteRow': 'Delete current row',
164
165
  'Table.discard': 'Discard',
@@ -83,7 +83,7 @@ register('zh-CN', {
83
83
  'desc': '降序',
84
84
  'Dialog.close': '关闭',
85
85
  'Embed.invalidRoot': '选择器不对,页面上没有此元素',
86
- 'Embed.downloading': '文件即将开始下载。。',
86
+ 'Embed.downloading': '文件即将开始下载',
87
87
  'Excel.placeholder': '拖拽 Excel 到这,或点击上传',
88
88
  'fetchFailed': '初始化失败',
89
89
  'File.continueAdd': '继续添加',
@@ -163,6 +163,7 @@ register('zh-CN', {
163
163
  'System.requestError': '接口报错:',
164
164
  'System.requestErrorStatus': '接口出错,状态码是:',
165
165
  'Table.addRow': '新增一行',
166
+ 'Table.copyRow': '复制一行',
166
167
  'Table.columnsVisibility': '点击选择显示列',
167
168
  'Table.deleteRow': '删除当前行',
168
169
  'Table.discard': '放弃',
@@ -151,6 +151,14 @@ export interface AjaxActionSchema extends ButtonSchema {
151
151
  ignoreConfirm?: boolean;
152
152
  }
153
153
 
154
+ export interface DownloadActionSchema
155
+ extends Omit<AjaxActionSchema, 'actionType'> {
156
+ /**
157
+ * 指定为下载行为
158
+ */
159
+ actionType: 'download';
160
+ }
161
+
154
162
  export interface UrlActionSchema extends ButtonSchema {
155
163
  /**
156
164
  * 指定为打开链接
@@ -347,6 +355,7 @@ const ActionProps = [
347
355
  'mergeData',
348
356
  'index',
349
357
  'copy',
358
+ 'copyFormat',
350
359
  'payload',
351
360
  'requireSelected'
352
361
  ];
@@ -368,7 +377,7 @@ import {DialogSchema, DialogSchemaBase} from './Dialog';
368
377
  import {DrawerSchema, DrawerSchemaBase} from './Drawer';
369
378
  import {generateIcon} from '../utils/icon';
370
379
  import {BadgeSchema, withBadge} from '../components/Badge';
371
- import {str2AsyncFunction} from '../utils/api';
380
+ import {normalizeApi, str2AsyncFunction} from '../utils/api';
372
381
 
373
382
  // 构造一个假的 React 事件避免可能的报错,主要用于快捷键功能
374
383
  // 来自 https://stackoverflow.com/questions/27062455/reactjs-can-i-create-my-own-syntheticevent
@@ -534,6 +543,15 @@ export class Action extends React.Component<ActionProps, ActionState> {
534
543
 
535
544
  e.preventDefault();
536
545
  const action = pick(this.props, ActionProps) as ActionSchema;
546
+
547
+ // download 是一种 ajax 的简写
548
+ if (action.actionType === 'download') {
549
+ action.actionType = 'ajax';
550
+ const api = normalizeApi((action as AjaxActionSchema).api);
551
+ api.responseType = 'blob';
552
+ (action as AjaxActionSchema).api = api;
553
+ }
554
+
537
555
  onAction(e, action);
538
556
 
539
557
  if (countDown) {