amis 1.3.5-beta.3 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/lib/components/Badge.d.ts +15 -2
  2. package/lib/components/Badge.js +47 -4
  3. package/lib/components/Badge.js.map +2 -2
  4. package/lib/components/Button.d.ts +24 -22
  5. package/lib/components/Button.js +13 -7
  6. package/lib/components/Button.js.map +2 -2
  7. package/lib/components/Checkbox.d.ts +1 -1
  8. package/lib/components/Checkbox.js +1 -1
  9. package/lib/components/Checkbox.js.map +2 -2
  10. package/lib/components/Drawer.js +1 -1
  11. package/lib/components/Drawer.js.map +2 -2
  12. package/lib/components/Modal.js +1 -1
  13. package/lib/components/Modal.js.map +2 -2
  14. package/lib/components/RichText.d.ts +6 -4
  15. package/lib/components/RichText.js +241 -27
  16. package/lib/components/RichText.js.map +2 -2
  17. package/lib/components/Select.d.ts +7 -0
  18. package/lib/components/Select.js.map +2 -2
  19. package/lib/components/Steps.d.ts +3 -3
  20. package/lib/components/Steps.js.map +1 -1
  21. package/lib/components/WithRemoteConfig.d.ts +8 -0
  22. package/lib/components/WithRemoteConfig.js +28 -2
  23. package/lib/components/WithRemoteConfig.js.map +2 -2
  24. package/lib/components/calendar/DaysView.js +2 -2
  25. package/lib/components/calendar/DaysView.js.map +2 -2
  26. package/lib/components/condition-builder/Field.js +0 -1
  27. package/lib/components/condition-builder/Field.js.map +2 -2
  28. package/lib/components/condition-builder/Value.js +2 -1
  29. package/lib/components/condition-builder/Value.js.map +2 -2
  30. package/lib/components/condition-builder/types.d.ts +5 -0
  31. package/lib/components/condition-builder/types.js.map +1 -1
  32. package/lib/components/icons.js +2 -0
  33. package/lib/components/icons.js.map +2 -2
  34. package/lib/factory.d.ts +5 -1
  35. package/lib/factory.js +9 -4
  36. package/lib/factory.js.map +2 -2
  37. package/lib/helper.css.map +1 -1
  38. package/lib/icons/loading-outline.js +7 -0
  39. package/lib/index.d.ts +1 -0
  40. package/lib/index.js +2 -1
  41. package/lib/index.js.map +2 -2
  42. package/lib/locale/de-DE.js +1 -0
  43. package/lib/locale/de-DE.js.map +2 -2
  44. package/lib/locale/en-US.js +2 -1
  45. package/lib/locale/en-US.js.map +2 -2
  46. package/lib/locale/zh-CN.js +2 -1
  47. package/lib/locale/zh-CN.js.map +2 -2
  48. package/lib/renderers/Action.d.ts +15 -1
  49. package/lib/renderers/Action.js +13 -6
  50. package/lib/renderers/Action.js.map +2 -2
  51. package/lib/renderers/CRUD.d.ts +2 -2
  52. package/lib/renderers/CRUD.js +11 -20
  53. package/lib/renderers/CRUD.js.map +2 -2
  54. package/lib/renderers/Card.js +11 -11
  55. package/lib/renderers/Card.js.map +2 -2
  56. package/lib/renderers/Collapse.d.ts +1 -1
  57. package/lib/renderers/Collapse.js +5 -1
  58. package/lib/renderers/Collapse.js.map +2 -2
  59. package/lib/renderers/Dialog.d.ts +0 -252
  60. package/lib/renderers/Dialog.js +3 -2
  61. package/lib/renderers/Dialog.js.map +2 -2
  62. package/lib/renderers/Drawer.js +2 -1
  63. package/lib/renderers/Drawer.js.map +2 -2
  64. package/lib/renderers/DropDownButton.d.ts +8 -0
  65. package/lib/renderers/DropDownButton.js +6 -4
  66. package/lib/renderers/DropDownButton.js.map +2 -2
  67. package/lib/renderers/Form/ButtonGroupSelect.js +3 -0
  68. package/lib/renderers/Form/ButtonGroupSelect.js.map +2 -2
  69. package/lib/renderers/Form/Combo.d.ts +2 -0
  70. package/lib/renderers/Form/Combo.js +16 -1
  71. package/lib/renderers/Form/Combo.js.map +2 -2
  72. package/lib/renderers/Form/DiffEditor.d.ts +0 -2
  73. package/lib/renderers/Form/Editor.d.ts +0 -2
  74. package/lib/renderers/Form/Editor.js +1 -1
  75. package/lib/renderers/Form/Editor.js.map +2 -2
  76. package/lib/renderers/Form/InputExcel.d.ts +5 -0
  77. package/lib/renderers/Form/InputExcel.js +24 -3
  78. package/lib/renderers/Form/InputExcel.js.map +2 -2
  79. package/lib/renderers/Form/InputImage.d.ts +8 -0
  80. package/lib/renderers/Form/InputImage.js +2 -1
  81. package/lib/renderers/Form/InputImage.js.map +2 -2
  82. package/lib/renderers/Form/InputNumber.d.ts +19 -5
  83. package/lib/renderers/Form/InputNumber.js +69 -7
  84. package/lib/renderers/Form/InputNumber.js.map +2 -2
  85. package/lib/renderers/Form/InputRange.js +7 -2
  86. package/lib/renderers/Form/InputRange.js.map +2 -2
  87. package/lib/renderers/Form/InputTable.d.ts +23 -5
  88. package/lib/renderers/Form/InputTable.js +32 -3
  89. package/lib/renderers/Form/InputTable.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/Nav.d.ts +52 -22
  102. package/lib/renderers/Nav.js +100 -15
  103. package/lib/renderers/Nav.js.map +2 -2
  104. package/lib/renderers/Page.d.ts +6 -0
  105. package/lib/renderers/Page.js +11 -3
  106. package/lib/renderers/Page.js.map +2 -2
  107. package/lib/renderers/Service.d.ts +10 -1
  108. package/lib/renderers/Service.js +85 -3
  109. package/lib/renderers/Service.js.map +2 -2
  110. package/lib/renderers/Steps.d.ts +4 -4
  111. package/lib/renderers/Steps.js +5 -2
  112. package/lib/renderers/Steps.js.map +2 -2
  113. package/lib/renderers/Table/TableBody.d.ts +5 -3
  114. package/lib/renderers/Table/TableBody.js +17 -11
  115. package/lib/renderers/Table/TableBody.js.map +2 -2
  116. package/lib/renderers/Table/TableCell.js +6 -2
  117. package/lib/renderers/Table/TableCell.js.map +2 -2
  118. package/lib/renderers/Table/TableContent.d.ts +3 -1
  119. package/lib/renderers/Table/TableContent.js +6 -2
  120. package/lib/renderers/Table/TableContent.js.map +2 -2
  121. package/lib/renderers/Table/TableRow.d.ts +1 -1
  122. package/lib/renderers/Table/TableRow.js +14 -13
  123. package/lib/renderers/Table/TableRow.js.map +2 -2
  124. package/lib/renderers/Table/index.d.ts +28 -3
  125. package/lib/renderers/Table/index.js +92 -52
  126. package/lib/renderers/Table/index.js.map +2 -2
  127. package/lib/schemaExtend.d.ts +1 -0
  128. package/lib/schemaExtend.js +59 -0
  129. package/lib/schemaExtend.js.map +13 -0
  130. package/lib/store/app.d.ts +0 -1
  131. package/lib/store/combo.d.ts +0 -2
  132. package/lib/store/crud.d.ts +3 -3
  133. package/lib/store/crud.js +41 -36
  134. package/lib/store/crud.js.map +2 -2
  135. package/lib/store/form.d.ts +0 -1
  136. package/lib/store/formItem.js +10 -6
  137. package/lib/store/formItem.js.map +2 -2
  138. package/lib/store/modal.d.ts +1 -1
  139. package/lib/store/modal.js +4 -0
  140. package/lib/store/modal.js.map +2 -2
  141. package/lib/store/root.d.ts +0 -1
  142. package/lib/store/service.d.ts +0 -1
  143. package/lib/store/service.js +0 -13
  144. package/lib/store/service.js.map +2 -2
  145. package/lib/store/table.d.ts +1 -2
  146. package/lib/store/table.js +44 -3
  147. package/lib/store/table.js.map +2 -2
  148. package/lib/themes/ang-ie11.css +624 -71
  149. package/lib/themes/ang.css +624 -71
  150. package/lib/themes/ang.css.map +1 -1
  151. package/lib/themes/antd-ie11.css +624 -71
  152. package/lib/themes/antd.css +624 -71
  153. package/lib/themes/antd.css.map +1 -1
  154. package/lib/themes/cxd-ie11.css +732 -191
  155. package/lib/themes/cxd.css +732 -191
  156. package/lib/themes/cxd.css.map +1 -1
  157. package/lib/themes/dark-ie11.css +624 -71
  158. package/lib/themes/dark.css +624 -71
  159. package/lib/themes/dark.css.map +1 -1
  160. package/lib/themes/default.css +732 -191
  161. package/lib/themes/default.css.map +1 -1
  162. package/lib/utils/api.js +12 -0
  163. package/lib/utils/api.js.map +2 -2
  164. package/lib/utils/attachmentAdpator.d.ts +7 -0
  165. package/lib/utils/attachmentAdpator.js +82 -0
  166. package/lib/utils/attachmentAdpator.js.map +13 -0
  167. package/lib/utils/helper.d.ts +2 -0
  168. package/lib/utils/helper.js +14 -1
  169. package/lib/utils/helper.js.map +2 -2
  170. package/lib/utils/resize-sensor.js +6 -0
  171. package/lib/utils/resize-sensor.js.map +2 -2
  172. package/lib/utils/tpl-builtin.d.ts +1 -0
  173. package/lib/utils/tpl-builtin.js +24 -8
  174. package/lib/utils/tpl-builtin.js.map +2 -2
  175. package/lib/utils/validations.js +62 -5
  176. package/lib/utils/validations.js.map +2 -2
  177. package/package.json +1 -2
  178. package/schema.json +561 -171
  179. package/scss/_mixins.scss +29 -0
  180. package/scss/_properties.scss +29 -11
  181. package/scss/components/_badge.scss +67 -2
  182. package/scss/components/_button.scss +35 -3
  183. package/scss/components/_image-gallery.scss +1 -1
  184. package/scss/components/_list.scss +8 -0
  185. package/scss/components/_markdown.scss +266 -0
  186. package/scss/components/_nav.scss +109 -35
  187. package/scss/components/_spinner.scss +6 -2
  188. package/scss/components/_table.scss +4 -0
  189. package/scss/components/form/_form.scss +3 -17
  190. package/scss/components/form/_group.scss +4 -0
  191. package/scss/components/form/_number.scss +12 -1
  192. package/scss/themes/_common.scss +1 -0
  193. package/scss/themes/_cxd-variables.scss +20 -20
  194. package/sdk/ang-ie11.css +769 -76
  195. package/sdk/ang.css +785 -76
  196. package/sdk/antd-ie11.css +759 -68
  197. package/sdk/antd.css +785 -76
  198. package/sdk/charts.js +13 -13
  199. package/sdk/color-picker.js +67 -67
  200. package/sdk/cropperjs.js +2 -2
  201. package/sdk/cxd-ie11.css +1243 -552
  202. package/sdk/cxd.css +893 -196
  203. package/sdk/dark-ie11.css +769 -76
  204. package/sdk/dark.css +785 -76
  205. package/sdk/exceljs.js +1 -1
  206. package/sdk/helper.css.map +1 -1
  207. package/sdk/locale/de-DE.js +1 -0
  208. package/sdk/markdown.js +69 -69
  209. package/sdk/papaparse.js +1 -1
  210. package/sdk/renderers/Form/CityDB.js +1 -1
  211. package/sdk/rest.js +22 -24
  212. package/sdk/rich-text.js +62 -64
  213. package/sdk/sdk-ie11.css +1243 -552
  214. package/sdk/sdk.css +893 -196
  215. package/sdk/sdk.js +1123 -1111
  216. package/sdk/thirds/hls.js/hls.js +1 -1
  217. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  218. package/sdk/tinymce.js +57 -57
  219. package/sdk.zip +0 -0
  220. package/src/components/Badge.tsx +111 -20
  221. package/src/components/Button.tsx +23 -7
  222. package/src/components/Checkbox.tsx +5 -2
  223. package/src/components/Drawer.tsx +3 -2
  224. package/src/components/Modal.tsx +3 -2
  225. package/src/components/RichText.tsx +280 -24
  226. package/src/components/Select.tsx +1 -0
  227. package/src/components/Steps.tsx +3 -3
  228. package/src/components/WithRemoteConfig.tsx +37 -2
  229. package/src/components/calendar/DaysView.tsx +2 -2
  230. package/src/components/condition-builder/Field.tsx +1 -2
  231. package/src/components/condition-builder/Value.tsx +3 -0
  232. package/src/components/condition-builder/types.ts +6 -0
  233. package/src/components/icons.tsx +2 -0
  234. package/src/factory.tsx +13 -3
  235. package/src/icons/loading-outline.svg +4 -0
  236. package/src/index.tsx +2 -0
  237. package/src/locale/de-DE.ts +1 -0
  238. package/src/locale/en-US.ts +2 -1
  239. package/src/locale/zh-CN.ts +2 -1
  240. package/src/renderers/Action.tsx +84 -14
  241. package/src/renderers/CRUD.tsx +13 -33
  242. package/src/renderers/Card.tsx +21 -15
  243. package/src/renderers/Collapse.tsx +5 -1
  244. package/src/renderers/Dialog.tsx +3 -2
  245. package/src/renderers/Drawer.tsx +2 -1
  246. package/src/renderers/DropDownButton.tsx +21 -4
  247. package/src/renderers/Form/ButtonGroupSelect.tsx +3 -0
  248. package/src/renderers/Form/Combo.tsx +7 -0
  249. package/src/renderers/Form/Editor.tsx +19 -20
  250. package/src/renderers/Form/InputExcel.tsx +28 -3
  251. package/src/renderers/Form/InputImage.tsx +23 -8
  252. package/src/renderers/Form/InputNumber.tsx +113 -18
  253. package/src/renderers/Form/InputRange.tsx +5 -2
  254. package/src/renderers/Form/InputTable.tsx +88 -9
  255. package/src/renderers/Form/Options.tsx +3 -1
  256. package/src/renderers/Form/index.tsx +0 -15
  257. package/src/renderers/Form/wrapControl.tsx +2 -2
  258. package/src/renderers/Json.tsx +10 -1
  259. package/src/renderers/List.tsx +32 -19
  260. package/src/renderers/Nav.tsx +165 -36
  261. package/src/renderers/Page.tsx +20 -1
  262. package/src/renderers/Service.tsx +101 -3
  263. package/src/renderers/Steps.tsx +12 -9
  264. package/src/renderers/Table/TableBody.tsx +29 -10
  265. package/src/renderers/Table/TableCell.tsx +15 -1
  266. package/src/renderers/Table/TableContent.tsx +7 -1
  267. package/src/renderers/Table/TableRow.tsx +18 -17
  268. package/src/renderers/Table/index.tsx +112 -27
  269. package/src/schemaExtend.ts +66 -0
  270. package/src/store/crud.ts +34 -38
  271. package/src/store/formItem.ts +10 -6
  272. package/src/store/modal.ts +4 -0
  273. package/src/store/service.ts +0 -19
  274. package/src/store/table.ts +48 -0
  275. package/src/utils/api.ts +11 -0
  276. package/src/utils/attachmentAdpator.ts +90 -0
  277. package/src/utils/helper.ts +16 -0
  278. package/src/utils/resize-sensor.ts +7 -0
  279. package/src/utils/tpl-builtin.ts +36 -17
  280. package/src/utils/validations.ts +80 -12
@@ -30,6 +30,26 @@ export interface TableControlSchema
30
30
  */
31
31
  addable?: boolean;
32
32
 
33
+ /**
34
+ * 可复制新增
35
+ */
36
+ copyable?: boolean;
37
+
38
+ /**
39
+ * 复制按钮文字
40
+ */
41
+ copyBtnLabel?: string;
42
+
43
+ /**
44
+ * 复制按钮图标
45
+ */
46
+ copyBtnIcon?: string;
47
+
48
+ /**
49
+ * 是否显示复制按钮
50
+ */
51
+ copyAddBtn?: boolean;
52
+
33
53
  /**
34
54
  * 是否可以拖拽排序
35
55
  */
@@ -41,12 +61,12 @@ export interface TableControlSchema
41
61
  addApi?: SchemaApi;
42
62
 
43
63
  /**
44
- * 新增按钮
64
+ * 新增按钮文字
45
65
  */
46
66
  addBtnLabel?: string;
47
67
 
48
68
  /**
49
- * 新增图标
69
+ * 新增按钮图标
50
70
  */
51
71
  addBtnIcon?: string;
52
72
 
@@ -73,12 +93,12 @@ export interface TableControlSchema
73
93
  /**
74
94
  * 更新按钮名称
75
95
  */
76
- updateBtnLabel?: string;
96
+ editBtnLabel?: string;
77
97
 
78
98
  /**
79
99
  * 更新按钮图标
80
100
  */
81
- updateBtnIcon?: string;
101
+ editBtnIcon?: string;
82
102
 
83
103
  /**
84
104
  * 确认按钮文字
@@ -172,7 +192,8 @@ export default class FormTable extends React.Component<TableProps, TableState> {
172
192
  placeholder: '空',
173
193
  scaffold: {},
174
194
  addBtnIcon: 'plus',
175
- updateBtnIcon: 'pencil',
195
+ copyBtnIcon: 'copy',
196
+ editBtnIcon: 'pencil',
176
197
  deleteBtnIcon: 'minus',
177
198
  confirmBtnIcon: 'check',
178
199
  cancelBtnIcon: 'close',
@@ -188,6 +209,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
188
209
  'showAddBtn',
189
210
  'addable',
190
211
  'removable',
212
+ 'copyable',
191
213
  'editable',
192
214
  'addApi',
193
215
  'updateApi',
@@ -423,6 +445,26 @@ export default class FormTable extends React.Component<TableProps, TableState> {
423
445
  return onAction && onAction(action, ctx, ...rest);
424
446
  }
425
447
 
448
+ copyItem(index: number) {
449
+ const {needConfirm} = this.props;
450
+ const items = this.state.items.concat();
451
+
452
+ items.splice(index + 1, 0, items[index]);
453
+ index = Math.min(index + 1, items.length - 1);
454
+ this.setState(
455
+ {
456
+ items
457
+ },
458
+ () => {
459
+ if (needConfirm === false) {
460
+ this.emitValue();
461
+ } else {
462
+ this.startEdit(index, true);
463
+ }
464
+ }
465
+ );
466
+ }
467
+
426
468
  addItem(index: number) {
427
469
  const {needConfirm, scaffold, columns} = this.props;
428
470
  const items = this.state.items.concat();
@@ -653,6 +695,38 @@ export default class FormTable extends React.Component<TableProps, TableState> {
653
695
  });
654
696
  }
655
697
 
698
+ if (props.copyable && props.showCopyBtn !== false) {
699
+ btns.push({
700
+ children: ({
701
+ key,
702
+ rowIndex,
703
+ offset
704
+ }: {
705
+ key: any;
706
+ rowIndex: number;
707
+ offset: number;
708
+ }) =>
709
+ ~this.state.editIndex && needConfirm !== false ? null : (
710
+ <Button
711
+ classPrefix={ns}
712
+ size="sm"
713
+ key={key}
714
+ level="link"
715
+ tooltip={__('Table.copyRow')}
716
+ tooltipContainer={
717
+ env && env.getModalContainer ? env.getModalContainer : undefined
718
+ }
719
+ onClick={this.copyItem.bind(this, rowIndex + offset, undefined)}
720
+ >
721
+ {props.copyBtnLabel ? <span>{props.copyBtnLabel}</span> : null}
722
+ {props.copyBtnIcon ? (
723
+ <Icon icon={props.copyBtnIcon} className="icon" />
724
+ ) : null}
725
+ </Button>
726
+ )
727
+ });
728
+ }
729
+
656
730
  if (props.needConfirm === false) {
657
731
  columns = columns.map(column => {
658
732
  const quickEdit = column.quickEdit;
@@ -716,11 +790,16 @@ export default class FormTable extends React.Component<TableProps, TableState> {
716
790
  }
717
791
  onClick={() => this.startEdit(rowIndex + offset)}
718
792
  >
719
- {props.updateBtnLabel ? (
720
- <span>{props.updateBtnLabel}</span>
793
+ {props.updateBtnLabel || props.editBtnLabel ? (
794
+ <span>{props.updateBtnLabel || props.editBtnLabel}</span>
721
795
  ) : null}
722
- {props.updateBtnIcon ? (
723
- <Icon icon={props.updateBtnIcon} className="icon" />
796
+ {/* 兼容之前的写法 */}
797
+ {typeof props.updateBtnIcon !== 'undefined' ? (
798
+ props.updateBtnIcon ? (
799
+ <Icon icon={props.updateBtnIcon} className="icon" />
800
+ ) : null
801
+ ) : props.editBtnIcon ? (
802
+ <Icon icon={props.editBtnIcon} className="icon" />
724
803
  ) : null}
725
804
  </Button>
726
805
  )
@@ -272,6 +272,7 @@ export function registerOptionsControl(config: OptionsConfig) {
272
272
 
273
273
  reaction?: () => void;
274
274
  input: any;
275
+ mounted = false;
275
276
 
276
277
  constructor(props: OptionsProps) {
277
278
  super(props);
@@ -303,7 +304,7 @@ export function registerOptionsControl(config: OptionsConfig) {
303
304
 
304
305
  this.reaction = reaction(
305
306
  () => JSON.stringify([formItem.loading, formItem.filteredOptions]),
306
- () => this.forceUpdate()
307
+ () => this.mounted && this.forceUpdate()
307
308
  );
308
309
  // 默认全选。这里会和默认值\回填值逻辑冲突,所以如果有配置source则不执行默认全选
309
310
  if (
@@ -340,6 +341,7 @@ export function registerOptionsControl(config: OptionsConfig) {
340
341
  }
341
342
 
342
343
  componentDidMount() {
344
+ this.mounted = true;
343
345
  this.normalizeValue();
344
346
 
345
347
  if (this.props.value) {
@@ -1514,23 +1514,8 @@ export default class Form extends React.Component<FormProps, object> {
1514
1514
  formStore
1515
1515
  } = this.props;
1516
1516
 
1517
- // trace(true);
1518
- // console.log('Form');
1519
-
1520
1517
  let body: JSX.Element = this.renderBody();
1521
1518
 
1522
- // props有formStore 说明是嵌套表单 || 不允许在表单的按钮组中再直接套表单
1523
- if (formStore) {
1524
- body = (
1525
- <>
1526
- <Alert level="warning" showCloseButton>
1527
- <p>{__('Form.nestedError')}</p>
1528
- </Alert>
1529
- {body}
1530
- </>
1531
- );
1532
- }
1533
-
1534
1519
  if (wrapWithPanel) {
1535
1520
  body = render(
1536
1521
  'body',
@@ -506,8 +506,8 @@ export function wrapControl<
506
506
 
507
507
  if (
508
508
  // 如果配置了 minLength 或者 maxLength 就切成及时验证
509
- // (typeof maxLength && maxLength) ||
510
- // (typeof minLength && minLength) ||
509
+ (typeof maxLength && maxLength) ||
510
+ (typeof minLength && minLength) ||
511
511
  validateOnChange === true ||
512
512
  (validateOnChange !== false && (formSubmited || validated))
513
513
  ) {
@@ -97,6 +97,15 @@ export class JSONField extends React.Component<JSONProps, object> {
97
97
  }
98
98
  }
99
99
 
100
+ let jsonThemeValue = jsonTheme;
101
+ if (isPureVariable(jsonTheme)) {
102
+ jsonThemeValue = resolveVariableAndFilter(
103
+ jsonTheme,
104
+ this.props.data,
105
+ '| raw'
106
+ );
107
+ }
108
+
100
109
  // JsonView 只支持对象,所以不是对象格式需要转成对象格式。
101
110
  if (data && ~['string', 'number'].indexOf(typeof data)) {
102
111
  data = {
@@ -112,7 +121,7 @@ export class JSONField extends React.Component<JSONProps, object> {
112
121
  <JsonView
113
122
  name={false}
114
123
  src={data}
115
- theme={(jsonTheme as any) ?? 'rjv-default'}
124
+ theme={(jsonThemeValue as any) ?? 'rjv-default'}
116
125
  shouldCollapse={this.shouldExpandNode}
117
126
  enableClipboard={false}
118
127
  iconStyle="square"
@@ -15,7 +15,8 @@ import {
15
15
  difference,
16
16
  isVisible,
17
17
  isDisabled,
18
- noop
18
+ noop,
19
+ isClickOnInput
19
20
  } from '../utils/helper';
20
21
  import {
21
22
  isPureVariable,
@@ -215,6 +216,11 @@ export interface ListSchema extends BaseSchema {
215
216
  * 大小
216
217
  */
217
218
  size?: 'sm' | 'base';
219
+
220
+ /**
221
+ * 点击列表项的行为
222
+ */
223
+ itemAction?: ActionSchema;
218
224
  }
219
225
 
220
226
  export interface Column {
@@ -919,6 +925,7 @@ export default class List extends React.Component<ListProps, object> {
919
925
  onAction,
920
926
  hideCheckToggler,
921
927
  checkOnItemClick,
928
+ itemAction,
922
929
  affixHeader,
923
930
  classnames: cx,
924
931
  size,
@@ -969,6 +976,7 @@ export default class List extends React.Component<ListProps, object> {
969
976
  itemIndex: item.index,
970
977
  hideCheckToggler,
971
978
  checkOnItemClick,
979
+ itemAction,
972
980
  selected: item.checked,
973
981
  onCheck: this.handleCheck,
974
982
  dragging: store.dragging,
@@ -1018,6 +1026,7 @@ export interface ListItemProps
1018
1026
  itemIndex?: number;
1019
1027
  checkable?: boolean;
1020
1028
  checkOnItemClick?: boolean;
1029
+ itemAction?: ActionSchema;
1021
1030
  }
1022
1031
  export class ListItem extends React.Component<ListItemProps> {
1023
1032
  static defaultProps: Partial<ListItemProps> = {
@@ -1025,7 +1034,11 @@ export class ListItem extends React.Component<ListItemProps> {
1025
1034
  titleClassName: 'h5'
1026
1035
  };
1027
1036
 
1028
- static propsList: Array<string> = ['avatarClassName', 'titleClassName'];
1037
+ static propsList: Array<string> = [
1038
+ 'avatarClassName',
1039
+ 'titleClassName',
1040
+ 'itemAction'
1041
+ ];
1029
1042
 
1030
1043
  constructor(props: ListItemProps) {
1031
1044
  super(props);
@@ -1037,20 +1050,15 @@ export class ListItem extends React.Component<ListItemProps> {
1037
1050
  }
1038
1051
 
1039
1052
  handleClick(e: React.MouseEvent<HTMLDivElement>) {
1040
- const target: HTMLElement = e.target as HTMLElement;
1041
- const ns = this.props.classPrefix;
1042
- let formItem;
1043
-
1044
- if (
1045
- !e.currentTarget.contains(target) ||
1046
- ~['INPUT', 'TEXTAREA'].indexOf(target.tagName) ||
1047
- ((formItem = target.closest(`button, a, .${ns}Form-item`)) &&
1048
- e.currentTarget.contains(formItem))
1049
- ) {
1053
+ if (isClickOnInput(e)) {
1054
+ return;
1055
+ }
1056
+ const {itemAction, onAction, item} = this.props;
1057
+ if (itemAction) {
1058
+ onAction && onAction(e, itemAction, item?.data);
1050
1059
  return;
1051
1060
  }
1052
1061
 
1053
- const item = this.props.item;
1054
1062
  this.props.onCheck && this.props.onCheck(item);
1055
1063
  }
1056
1064
 
@@ -1160,10 +1168,7 @@ export class ListItem extends React.Component<ListItemProps> {
1160
1168
  ))}
1161
1169
  </div>
1162
1170
  );
1163
- } else */ if (
1164
- typeof node === 'string' ||
1165
- typeof node === 'number'
1166
- ) {
1171
+ } else */ if (typeof node === 'string' || typeof node === 'number') {
1167
1172
  return render(region, node, {key}) as JSX.Element;
1168
1173
  }
1169
1174
 
@@ -1261,7 +1266,8 @@ export class ListItem extends React.Component<ListItemProps> {
1261
1266
  render,
1262
1267
  checkable,
1263
1268
  classnames: cx,
1264
- actionsPosition
1269
+ actionsPosition,
1270
+ itemAction
1265
1271
  } = this.props;
1266
1272
 
1267
1273
  const avatar = filter(avatarTpl, data);
@@ -1271,9 +1277,16 @@ export class ListItem extends React.Component<ListItemProps> {
1271
1277
 
1272
1278
  return (
1273
1279
  <div
1274
- onClick={checkOnItemClick && checkable ? this.handleClick : undefined}
1280
+ onClick={
1281
+ (checkOnItemClick && checkable) || itemAction
1282
+ ? this.handleClick
1283
+ : undefined
1284
+ }
1275
1285
  className={cx(
1276
1286
  `ListItem ListItem--actions-at-${actionsPosition || 'right'}`,
1287
+ {
1288
+ 'ListItem--hasItemAction': itemAction
1289
+ },
1277
1290
  className
1278
1291
  )}
1279
1292
  >
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
+ import Sortable from 'sortablejs';
2
3
  import {Renderer, RendererEnv, RendererProps} from '../factory';
3
4
  import getExprProperties from '../utils/filter-schema';
4
5
  import {filter, evalExpression} from '../utils/tpl';
5
6
  import {
7
+ guid,
6
8
  autobind,
7
9
  createObject,
8
10
  findTree,
@@ -22,6 +24,9 @@ import {
22
24
  } from '../components/WithRemoteConfig';
23
25
  import {Payload} from '../types';
24
26
  import Spinner from '../components/Spinner';
27
+ import cloneDeep from 'lodash/cloneDeep';
28
+ import {isEffectiveApi} from '../utils/api';
29
+ import {Badge, BadgeSchema} from '../components/Badge';
25
30
 
26
31
  export type NavItemSchema = {
27
32
  /**
@@ -45,6 +50,11 @@ export type NavItemSchema = {
45
50
  deferApi?: SchemaApi;
46
51
 
47
52
  children?: Array<NavItemSchema>;
53
+
54
+ /**
55
+ * 角标
56
+ */
57
+ badge?: BadgeSchema
48
58
  } & Omit<BaseSchema, 'type'>;
49
59
 
50
60
  /**
@@ -81,6 +91,26 @@ export interface NavSchema extends BaseSchema {
81
91
  * true 为垂直排列,false 为水平排列类似如 tabs。
82
92
  */
83
93
  stacked?: boolean;
94
+
95
+ /**
96
+ * 更多操作菜单列表
97
+ */
98
+ itemActions?: SchemaCollection;
99
+
100
+ /**
101
+ * 可拖拽
102
+ */
103
+ draggable?: boolean;
104
+
105
+ /**
106
+ * 保存排序的 api
107
+ */
108
+ saveOrderApi?: SchemaApi;
109
+
110
+ /**
111
+ * 角标
112
+ */
113
+ badge?: BadgeSchema;
84
114
  }
85
115
 
86
116
  export interface Link {
@@ -97,6 +127,7 @@ export interface Link {
97
127
  loading?: boolean;
98
128
  loaded?: boolean;
99
129
  [propName: string]: any;
130
+ badge?: BadgeSchema
100
131
  }
101
132
  export interface Links extends Array<Link> {}
102
133
 
@@ -113,7 +144,9 @@ export interface NavigationProps
113
144
  togglerClassName?: string;
114
145
  links?: Array<Link>;
115
146
  loading?: boolean;
116
- render: RendererProps['render']
147
+ render: RendererProps['render'];
148
+ env: RendererEnv;
149
+ reload?: any;
117
150
  }
118
151
 
119
152
  export class Navigation extends React.Component<
@@ -123,6 +156,9 @@ export class Navigation extends React.Component<
123
156
  static defaultProps = {
124
157
  indentSize: 24
125
158
  };
159
+ sortable: Sortable[] = [];
160
+ id: string;
161
+ dragRef?: HTMLElement;
126
162
 
127
163
  @autobind
128
164
  handleClick(link: Link) {
@@ -134,15 +170,85 @@ export class Navigation extends React.Component<
134
170
  this.props.onToggle?.(target);
135
171
  }
136
172
 
173
+ @autobind
174
+ dragRefFn(ref: any) {
175
+ const {draggable} = this.props;
176
+ if (ref && draggable) {
177
+ this.id = guid();
178
+ this.initDragging(ref);
179
+ }
180
+ }
181
+
182
+ initDragging(ref: HTMLElement) {
183
+ const ns = this.props.classPrefix;
184
+ this.sortable.push(new Sortable(
185
+ ref,
186
+ {
187
+ group: `nav-${this.id}`,
188
+ animation: 150,
189
+ handle: `.${ns}Nav-itemDrager`,
190
+ ghostClass: `${ns}Nav-item--dragging`,
191
+ onEnd: async (e: any) => {
192
+ // 没有移动
193
+ if (e.newIndex === e.oldIndex) {
194
+ return;
195
+ }
196
+ const id = e.item.getAttribute('data-id');
197
+ const parentNode = e.to
198
+ if (
199
+ e.newIndex < e.oldIndex &&
200
+ e.oldIndex < parentNode.childNodes.length - 1
201
+ ) {
202
+ parentNode.insertBefore(e.item, parentNode.childNodes[e.oldIndex + 1]);
203
+ } else if (e.oldIndex < parentNode.childNodes.length - 1) {
204
+ parentNode.insertBefore(e.item, parentNode.childNodes[e.oldIndex]);
205
+ } else {
206
+ parentNode.appendChild(e.item);
207
+ }
208
+ const links = cloneDeep(this.props.links) as Link[];
209
+ let parent = links;
210
+ someTree(links, (item: Link, key, level, paths: Link[]) => {
211
+ if (item.id === id) {
212
+ const len = paths.length - 1;
213
+ parent = (~len ? paths[len].children : links) as Link[];
214
+ return true;
215
+ }
216
+ return false;
217
+ });
218
+ parent.splice(e.newIndex, 0, parent.splice(e.oldIndex, 1)[0]);
219
+ const {saveOrderApi, env} = this.props;
220
+ if (saveOrderApi && isEffectiveApi(saveOrderApi)) {
221
+ await env.fetcher(saveOrderApi as SchemaApi, {data: links}, {method: 'post'});
222
+ this.props.reload();
223
+ } else {
224
+ console.warn('请配置saveOrderApi');
225
+ }
226
+ }
227
+ }
228
+ ));
229
+ }
230
+
137
231
  renderItem(link: Link, index: number, depth = 1) {
138
232
  if (link.hidden === true || link.visible === false) {
139
233
  return null;
140
234
  }
141
235
  const isActive: boolean = !!link.active;
142
- const {disabled, togglerClassName, classnames: cx, indentSize} = this.props;
236
+ const {
237
+ disabled,
238
+ togglerClassName,
239
+ classnames: cx,
240
+ indentSize,
241
+ render,
242
+ itemActions,
243
+ draggable,
244
+ links,
245
+ badge: defaultBadge
246
+ } = this.props;
143
247
  const hasSub =
144
248
  (link.defer && !link.loaded) || (link.children && link.children.length);
145
-
249
+ const id = guid();
250
+ link.id = id;
251
+ const badge = defaultBadge ? Object.assign(defaultBadge, link.badge) : link.badge;
146
252
  return (
147
253
  <li
148
254
  key={index}
@@ -152,42 +258,62 @@ export class Navigation extends React.Component<
152
258
  'is-unfolded': link.unfolded,
153
259
  'has-sub': hasSub
154
260
  })}
261
+ data-id={id}
155
262
  >
156
- <a
157
- onClick={this.handleClick.bind(this, link)}
158
- style={{paddingLeft: depth * (parseInt(indentSize as any, 10) ?? 24)}}
159
- >
160
- {generateIcon(cx, link.icon, 'Nav-itemIcon')}
263
+ <Badge classnames={cx} badge={badge} data={link}>
264
+ <a
265
+ onClick={this.handleClick.bind(this, link)}
266
+ style={{paddingLeft: depth * (parseInt(indentSize as any, 10) ?? 24)}}
267
+ >
268
+ {!disabled && draggable && links && links.length > 1 ? (
269
+ <div className={cx('Nav-itemDrager')} >
270
+ <a
271
+ key="drag"
272
+ data-position="bottom"
273
+ >
274
+ <Icon icon="drag-bar" className="icon" />
275
+ </a>
276
+ </div>
277
+ ) : null}
278
+ {link.loading ? (
279
+ <Spinner
280
+ size="sm"
281
+ show
282
+ icon="reload"
283
+ spinnerClassName={cx('Nav-spinner')}
284
+ />
285
+ ) : hasSub ? (
286
+ <span
287
+ onClick={() => this.toggleLink(link)}
288
+ className={cx('Nav-itemToggler', togglerClassName)}
289
+ >
290
+ <Icon icon="caret" className="icon" />
291
+ </span>
292
+ ) : null}
293
+ {generateIcon(cx, link.icon, 'Nav-itemIcon')}
294
+ {
295
+ link.label && (typeof link.label === 'string'
296
+ ? link.label
297
+ : render('inline', link.label as SchemaCollection))
298
+ }
299
+ </a>
161
300
  {
162
- link.label && (typeof link.label === 'string'
163
- ? link.label
164
- : this.props.render('inline', link.label as SchemaCollection))
301
+ // 更多操作
302
+ itemActions
303
+ ? <div className={cx('Nav-item-atcions')}>
304
+ {
305
+ render('inline', itemActions, {data: link})
306
+ }
307
+ </div> : null
165
308
  }
166
- </a>
167
-
168
- {link.loading ? (
169
- <Spinner
170
- size="sm"
171
- show
172
- icon="reload"
173
- spinnerClassName={cx('Nav-spinner')}
174
- />
175
- ) : hasSub ? (
176
- <span
177
- onClick={() => this.toggleLink(link)}
178
- className={cx('Nav-itemToggler', togglerClassName)}
179
- >
180
- <Icon icon="caret" className="icon" />
181
- </span>
182
- ) : null}
183
-
184
- {Array.isArray(link.children) && link.children.length ? (
185
- <ul className={cx('Nav-subItems')}>
186
- {link.children.map((link, index) =>
187
- this.renderItem(link, index, depth + 1)
188
- )}
189
- </ul>
190
- ) : null}
309
+ {Array.isArray(link.children) && link.children.length ? (
310
+ <ul className={cx('Nav-subItems')} ref={this.dragRefFn}>
311
+ {link.children.map((link, index) =>
312
+ this.renderItem(link, index, depth + 1)
313
+ )}
314
+ </ul>
315
+ ) : null}
316
+ </Badge>
191
317
  </li>
192
318
  );
193
319
  }
@@ -198,6 +324,7 @@ export class Navigation extends React.Component<
198
324
  return (
199
325
  <ul
200
326
  className={cx('Nav', className, stacked ? 'Nav--stacked' : 'Nav--tabs')}
327
+ ref={this.dragRefFn}
201
328
  >
202
329
  {Array.isArray(links)
203
330
  ? links.map((item, index) => this.renderItem(item, index))
@@ -310,6 +437,7 @@ const ConditionBuilderWithRemoteOptions = withRemoteConfig({
310
437
  data?: any;
311
438
  unfoldedField?: string;
312
439
  foldedField?: string;
440
+ reload?: any;
313
441
  }
314
442
  > {
315
443
  constructor(props: any) {
@@ -442,6 +570,7 @@ export class NavigationRenderer extends React.Component<RendererProps> {
442
570
  return (
443
571
  <ConditionBuilderWithRemoteOptions
444
572
  {...rest}
573
+ reload={this.reload}
445
574
  remoteConfigRef={this.remoteConfigRef}
446
575
  />
447
576
  );