amis 1.9.1-beta.11 → 1.9.1-beta.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. package/lib/RootRenderer.js +14 -0
  2. package/lib/RootRenderer.js.map +2 -2
  3. package/lib/SchemaRenderer.js +8 -3
  4. package/lib/SchemaRenderer.js.map +2 -2
  5. package/lib/components/Alert2.d.ts +10 -10
  6. package/lib/components/DateRangePicker.js +11 -9
  7. package/lib/components/DateRangePicker.js.map +2 -2
  8. package/lib/components/SearchBox.d.ts +40 -40
  9. package/lib/components/Select.d.ts +193 -193
  10. package/lib/components/Select.js +2 -4
  11. package/lib/components/Select.js.map +2 -2
  12. package/lib/components/virtual-list/index.js +1 -1
  13. package/lib/components/virtual-list/index.js.map +1 -1
  14. package/lib/index.js +1 -1
  15. package/lib/locale/de-DE.js +1 -0
  16. package/lib/locale/de-DE.js.map +2 -2
  17. package/lib/locale/en-US.js +1 -0
  18. package/lib/locale/en-US.js.map +2 -2
  19. package/lib/locale/zh-CN.js +5 -2
  20. package/lib/locale/zh-CN.js.map +2 -2
  21. package/lib/renderers/Action.d.ts +6 -0
  22. package/lib/renderers/Action.js.map +2 -2
  23. package/lib/renderers/CRUD.js +2 -1
  24. package/lib/renderers/CRUD.js.map +2 -2
  25. package/lib/renderers/Card.js +5 -4
  26. package/lib/renderers/Card.js.map +2 -2
  27. package/lib/renderers/Carousel.d.ts +1 -1
  28. package/lib/renderers/Carousel.js +5 -1
  29. package/lib/renderers/Carousel.js.map +2 -2
  30. package/lib/renderers/Form/InputImage.js +1 -1
  31. package/lib/renderers/Form/InputImage.js.map +2 -2
  32. package/lib/renderers/Form/InputText.js +1 -1
  33. package/lib/renderers/Form/InputText.js.map +2 -2
  34. package/lib/renderers/Form/Options.js +1 -0
  35. package/lib/renderers/Form/Options.js.map +2 -2
  36. package/lib/renderers/Form/Select.d.ts +12 -0
  37. package/lib/renderers/Form/Select.js +1 -3
  38. package/lib/renderers/Form/Select.js.map +2 -2
  39. package/lib/renderers/Form/wrapControl.js +72 -19
  40. package/lib/renderers/Form/wrapControl.js.map +2 -2
  41. package/lib/renderers/Service.js +1 -0
  42. package/lib/renderers/Service.js.map +2 -2
  43. package/lib/renderers/Table/TableContent.d.ts +2 -2
  44. package/lib/renderers/Table/TableContent.js +4 -16
  45. package/lib/renderers/Table/TableContent.js.map +2 -2
  46. package/lib/renderers/Table/index.d.ts +2 -5
  47. package/lib/renderers/Table/index.js +2 -2
  48. package/lib/renderers/Table/index.js.map +2 -2
  49. package/lib/store/table.js +7 -3
  50. package/lib/store/table.js.map +2 -2
  51. package/lib/themes/ang-ie11.css +0 -1
  52. package/lib/themes/ang.css +0 -1
  53. package/lib/themes/ang.css.map +1 -1
  54. package/lib/themes/antd-ie11.css +0 -1
  55. package/lib/themes/antd.css +0 -1
  56. package/lib/themes/antd.css.map +1 -1
  57. package/lib/themes/cxd-ie11.css +8 -1
  58. package/lib/themes/cxd.css +8 -1
  59. package/lib/themes/cxd.css.map +1 -1
  60. package/lib/themes/dark-ie11.css +0 -1
  61. package/lib/themes/dark.css +0 -1
  62. package/lib/themes/dark.css.map +1 -1
  63. package/lib/themes/default-ie11.css +8 -1
  64. package/lib/themes/default.css +8 -1
  65. package/lib/themes/default.css.map +1 -1
  66. package/lib/types.d.ts +1 -1
  67. package/lib/types.js.map +1 -1
  68. package/lib/utils/formula.d.ts +16 -0
  69. package/lib/utils/formula.js +207 -0
  70. package/lib/utils/formula.js.map +13 -0
  71. package/lib/utils/grammar.d.ts +4 -0
  72. package/lib/utils/grammar.js +47 -0
  73. package/lib/utils/grammar.js.map +13 -0
  74. package/lib/utils/helper.js +1 -0
  75. package/lib/utils/helper.js.map +2 -2
  76. package/lib/utils/tpl.js +3 -0
  77. package/lib/utils/tpl.js.map +2 -2
  78. package/package.json +1 -1
  79. package/schema.json +278 -222
  80. package/scss/components/_collapse.scss +1 -1
  81. package/scss/themes/cxd.scss +12 -0
  82. package/sdk/ang-ie11.css +0 -1
  83. package/sdk/ang.css +0 -1
  84. package/sdk/antd-ie11.css +0 -1
  85. package/sdk/antd.css +0 -1
  86. package/sdk/barcode.js +51 -51
  87. package/sdk/charts.js +14 -14
  88. package/sdk/codemirror.js +7 -7
  89. package/sdk/color-picker.js +65 -65
  90. package/sdk/cropperjs.js +2 -2
  91. package/sdk/cxd-ie11.css +9 -1
  92. package/sdk/cxd.css +9 -1
  93. package/sdk/dark-ie11.css +0 -1
  94. package/sdk/dark.css +0 -1
  95. package/sdk/exceljs.js +1 -1
  96. package/sdk/locale/de-DE.js +1 -0
  97. package/sdk/markdown.js +69 -69
  98. package/sdk/papaparse.js +1 -1
  99. package/sdk/renderers/Form/CityDB.js +1 -1
  100. package/sdk/rest.js +16 -16
  101. package/sdk/rich-text.js +62 -62
  102. package/sdk/sdk-ie11.css +9 -1
  103. package/sdk/sdk.css +9 -1
  104. package/sdk/sdk.js +1695 -1665
  105. package/sdk/thirds/hls.js/hls.js +1 -1
  106. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  107. package/sdk/tinymce.js +57 -57
  108. package/src/RootRenderer.tsx +14 -0
  109. package/src/SchemaRenderer.tsx +4 -2
  110. package/src/components/DateRangePicker.tsx +73 -60
  111. package/src/components/Select.tsx +2 -4
  112. package/src/components/virtual-list/index.tsx +1 -1
  113. package/src/locale/de-DE.ts +1 -0
  114. package/src/locale/en-US.ts +1 -0
  115. package/src/locale/zh-CN.ts +5 -2
  116. package/src/renderers/Action.tsx +8 -0
  117. package/src/renderers/CRUD.tsx +2 -1
  118. package/src/renderers/Card.tsx +10 -5
  119. package/src/renderers/Carousel.tsx +10 -4
  120. package/src/renderers/Form/InputImage.tsx +1 -1
  121. package/src/renderers/Form/InputText.tsx +1 -0
  122. package/src/renderers/Form/Options.tsx +1 -0
  123. package/src/renderers/Form/Select.tsx +13 -3
  124. package/src/renderers/Form/wrapControl.tsx +90 -22
  125. package/src/renderers/Service.tsx +1 -0
  126. package/src/renderers/Table/TableContent.tsx +22 -34
  127. package/src/renderers/Table/index.tsx +4 -8
  128. package/src/store/table.ts +10 -3
  129. package/src/types.ts +1 -0
  130. package/src/utils/formula.ts +240 -0
  131. package/src/utils/grammar.ts +53 -0
  132. package/src/utils/helper.ts +2 -1
  133. package/src/utils/tpl.ts +2 -0
@@ -12,6 +12,9 @@ import {filter} from './utils/tpl';
12
12
  import qs from 'qs';
13
13
  import pick from 'lodash/pick';
14
14
  import mapValues from 'lodash/mapValues';
15
+ import {saveAs} from 'file-saver';
16
+ import {normalizeApi} from './utils/api';
17
+ import {AjaxActionSchema} from './renderers/Action';
15
18
 
16
19
  export interface RootRendererProps extends RootProps {
17
20
  location?: any;
@@ -218,6 +221,17 @@ export class RootRenderer extends React.Component<RootRendererProps> {
218
221
  env.copy(filter(action.content || action.copy, ctx, '| raw'), {
219
222
  format: action.copyFormat
220
223
  });
224
+ } else if (action.actionType === 'saveAs') {
225
+ // 使用 saveAs 实现下载
226
+ // 不支持 env,除非以后将 saveAs 代码拷过来改
227
+ const api = normalizeApi((action as AjaxActionSchema).api);
228
+ if (typeof api.url === 'string') {
229
+ let fileName = action.fileName || 'data.txt';
230
+ if (api.url.indexOf('.') !== -1) {
231
+ fileName = api.url.split('/').pop();
232
+ }
233
+ saveAs(api.url, fileName);
234
+ }
221
235
  }
222
236
  }
223
237
 
@@ -17,7 +17,7 @@ import {ScopedContext} from './Scoped';
17
17
  import {Schema, SchemaNode} from './types';
18
18
  import {DebugWrapper} from './utils/debug';
19
19
  import getExprProperties from './utils/filter-schema';
20
- import {anyChanged, chainEvents, autobind} from './utils/helper';
20
+ import {anyChanged, chainEvents, autobind, createObject} from './utils/helper';
21
21
  import {SimpleMap} from './utils/SimpleMap';
22
22
 
23
23
  import {bindEvent, dispatchEvent, RendererEvent} from './utils/renderer-event';
@@ -302,7 +302,7 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
302
302
  const isSFC = !(schema.component.prototype instanceof React.Component);
303
303
  const {
304
304
  data: defaultData,
305
- value: defaultValue,
305
+ value: defaultValue, // render时的value改放defaultValue中
306
306
  activeKey: defaultActiveKey,
307
307
  key: propKey,
308
308
  ...restSchema
@@ -313,6 +313,7 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
313
313
  ...rest,
314
314
  ...restSchema,
315
315
  ...exprProps,
316
+ // value: defaultValue, // 备注: 此处并没有将value传递给渲染器
316
317
  defaultData,
317
318
  defaultValue,
318
319
  defaultActiveKey,
@@ -388,6 +389,7 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
388
389
  ...restSchema,
389
390
  ...chainEvents(rest, restSchema),
390
391
  ...exprProps,
392
+ // value: defaultValue, // 备注: 此处并没有将value传递给渲染器
391
393
  defaultData: restSchema.defaultData ?? defaultData,
392
394
  defaultValue: restSchema.defaultValue ?? defaultValue,
393
395
  defaultActiveKey: defaultActiveKey,
@@ -1147,7 +1147,11 @@ export class DateRangePicker extends React.Component<
1147
1147
  props.className += ' rdtBetween';
1148
1148
  }
1149
1149
 
1150
- return <td {...props}><span>{currentDate.date()}</span></td>;
1150
+ return (
1151
+ <td {...props}>
1152
+ <span>{currentDate.date()}</span>
1153
+ </td>
1154
+ );
1151
1155
  }
1152
1156
 
1153
1157
  renderMonth(props: any, month: number, year: number, date: any) {
@@ -1227,67 +1231,71 @@ export class DateRangePicker extends React.Component<
1227
1231
  const __ = this.props.translate;
1228
1232
 
1229
1233
  const {startDate, endDate, editState} = this.state;
1230
-
1234
+
1231
1235
  // timeRange需要单独选择范围
1232
1236
  const isTimeRange = type === 'input-datetime-range' || viewMode === 'time';
1233
1237
 
1234
1238
  return (
1235
1239
  <div className={`${ns}DateRangePicker-wrap`} ref={this.calendarRef}>
1236
1240
  {this.renderRanges(ranges)}
1237
- {(!isTimeRange || editState === 'start' && !embed) && <Calendar
1238
- className={`${ns}DateRangePicker-start`}
1239
- value={startDate}
1240
- // 区分的原因是 time-range 左侧就只能选起始时间,而其它都能在左侧同时同时选择起始和结束
1241
- // TODO: 后续得把 time-range 代码拆分出来
1242
- onChange={
1243
- type === 'input-datetime-range'
1244
- ? this.handleStartDateChange
1245
- : viewMode === 'time'
1246
- ? this.handleTimeStartChange
1247
- : this.handleDateChange
1248
- }
1249
- requiredConfirm={false}
1250
- dateFormat={dateFormat}
1251
- inputFormat={inputFormat}
1252
- timeFormat={timeFormat}
1253
- isValidDate={this.checkStartIsValidDate}
1254
- viewMode={viewMode}
1255
- input={false}
1256
- onClose={this.close}
1257
- renderDay={this.renderDay}
1258
- renderMonth={this.renderMonth}
1259
- renderQuarter={this.renderQuarter}
1260
- renderYear={this.renderYear}
1261
- locale={locale}
1262
- timeRangeHeader="开始时间"
1263
- />}
1264
- {(!isTimeRange || editState === 'end' && !embed) && <Calendar
1265
- className={`${ns}DateRangePicker-end`}
1266
- value={endDate}
1267
- onChange={
1268
- type === 'input-datetime-range'
1269
- ? this.handeleEndDateChange
1270
- : viewMode === 'time'
1271
- ? this.handleTimeEndChange
1272
- : this.handleDateChange
1273
- }
1274
- requiredConfirm={false}
1275
- dateFormat={dateFormat}
1276
- inputFormat={inputFormat}
1277
- timeFormat={timeFormat}
1278
- viewDate={this.nextMonth}
1279
- isEndDate
1280
- isValidDate={this.checkEndIsValidDate}
1281
- viewMode={viewMode}
1282
- input={false}
1283
- onClose={this.close}
1284
- renderDay={this.renderDay}
1285
- renderMonth={this.renderMonth}
1286
- renderQuarter={this.renderQuarter}
1287
- renderYear={this.renderYear}
1288
- locale={locale}
1289
- timeRangeHeader="结束时间"
1290
- />}
1241
+ {(!isTimeRange || (editState === 'start' && !embed)) && (
1242
+ <Calendar
1243
+ className={`${ns}DateRangePicker-start`}
1244
+ value={startDate}
1245
+ // 区分的原因是 time-range 左侧就只能选起始时间,而其它都能在左侧同时同时选择起始和结束
1246
+ // TODO: 后续得把 time-range 代码拆分出来
1247
+ onChange={
1248
+ type === 'input-datetime-range'
1249
+ ? this.handleStartDateChange
1250
+ : viewMode === 'time'
1251
+ ? this.handleTimeStartChange
1252
+ : this.handleDateChange
1253
+ }
1254
+ requiredConfirm={false}
1255
+ dateFormat={dateFormat}
1256
+ inputFormat={inputFormat}
1257
+ timeFormat={timeFormat}
1258
+ isValidDate={this.checkStartIsValidDate}
1259
+ viewMode={viewMode}
1260
+ input={false}
1261
+ onClose={this.close}
1262
+ renderDay={this.renderDay}
1263
+ renderMonth={this.renderMonth}
1264
+ renderQuarter={this.renderQuarter}
1265
+ renderYear={this.renderYear}
1266
+ locale={locale}
1267
+ timeRangeHeader="开始时间"
1268
+ />
1269
+ )}
1270
+ {(!isTimeRange || (editState === 'end' && !embed)) && (
1271
+ <Calendar
1272
+ className={`${ns}DateRangePicker-end`}
1273
+ value={endDate}
1274
+ onChange={
1275
+ type === 'input-datetime-range'
1276
+ ? this.handeleEndDateChange
1277
+ : viewMode === 'time'
1278
+ ? this.handleTimeEndChange
1279
+ : this.handleDateChange
1280
+ }
1281
+ requiredConfirm={false}
1282
+ dateFormat={dateFormat}
1283
+ inputFormat={inputFormat}
1284
+ timeFormat={timeFormat}
1285
+ viewDate={this.nextMonth}
1286
+ isEndDate
1287
+ isValidDate={this.checkEndIsValidDate}
1288
+ viewMode={viewMode}
1289
+ input={false}
1290
+ onClose={this.close}
1291
+ renderDay={this.renderDay}
1292
+ renderMonth={this.renderMonth}
1293
+ renderQuarter={this.renderQuarter}
1294
+ renderYear={this.renderYear}
1295
+ locale={locale}
1296
+ timeRangeHeader="结束时间"
1297
+ />
1298
+ )}
1291
1299
 
1292
1300
  {embed ? null : (
1293
1301
  <div key="button" className={`${ns}DateRangePicker-actions`}>
@@ -1297,7 +1305,9 @@ export class DateRangePicker extends React.Component<
1297
1305
  <a
1298
1306
  className={cx('Button', 'Button--primary', 'm-l-sm', {
1299
1307
  'is-disabled':
1300
- (!this.state.startDate && isTimeRange && editState === 'start') ||
1308
+ (!this.state.startDate &&
1309
+ isTimeRange &&
1310
+ editState === 'start') ||
1301
1311
  (!this.state.endDate && isTimeRange && editState === 'end') ||
1302
1312
  this.state.endDate?.isBefore(this.state.startDate)
1303
1313
  })}
@@ -1414,7 +1424,7 @@ export class DateRangePicker extends React.Component<
1414
1424
  >
1415
1425
  <Input
1416
1426
  className={cx('DateRangePicker-input', {
1417
- isActive: this.state.editState === 'start'
1427
+ isActive: this.state.editState === 'start' && isOpened
1418
1428
  })}
1419
1429
  onChange={this.startInputChange}
1420
1430
  onClick={this.openStart}
@@ -1427,7 +1437,7 @@ export class DateRangePicker extends React.Component<
1427
1437
  <span className={cx('DateRangePicker-input-separator')}>-</span>
1428
1438
  <Input
1429
1439
  className={cx('DateRangePicker-input', {
1430
- isActive: this.state.editState === 'end'
1440
+ isActive: this.state.editState === 'end' && isOpened
1431
1441
  })}
1432
1442
  onChange={this.endInputChange}
1433
1443
  onClick={this.openEnd}
@@ -1445,7 +1455,10 @@ export class DateRangePicker extends React.Component<
1445
1455
  ) : null}
1446
1456
 
1447
1457
  <a className={`${ns}DateRangePicker-toggler`}>
1448
- <Icon icon={viewMode === 'time' ? 'clock' : 'date'} className="icon" />
1458
+ <Icon
1459
+ icon={viewMode === 'time' ? 'clock' : 'date'}
1460
+ className="icon"
1461
+ />
1449
1462
  </a>
1450
1463
 
1451
1464
  {isOpened ? (
@@ -1124,10 +1124,8 @@ export class Select extends React.Component<SelectProps, SelectState> {
1124
1124
  isOpen={this.state.isOpen}
1125
1125
  inputValue={inputValue}
1126
1126
  onChange={
1127
- /*展示 Checkbox 的时候,会出发多次 onChange 原因待查*/ multiple ||
1128
- checkAll
1129
- ? noop
1130
- : this.handleChange
1127
+ /*展示 Checkbox 的时候,会出发多次 onChange 原因待查*/
1128
+ multiple ? noop : this.handleChange
1131
1129
  }
1132
1130
  onStateChange={this.handleStateChange}
1133
1131
  itemToString={item => (item ? `${item[labelField]}` : '')}
@@ -94,7 +94,7 @@ const STYLE_ITEM: {
94
94
  position: 'absolute' as ItemPosition,
95
95
  top: 0,
96
96
  left: 0,
97
- width: '100%'
97
+ width: 'auto'
98
98
  };
99
99
 
100
100
  const STYLE_STICKY_ITEM = {
@@ -132,6 +132,7 @@ register('de-DE', {
132
132
  'File.retry': 'Wiederholen',
133
133
  'File.start': 'Hochladen beginnen',
134
134
  'File.upload': 'Hochladen',
135
+ 'Image.upload':'Hochladen',
135
136
  'File.uploadFailed': 'Zurückgegebene Daten der Upload-API sind leer',
136
137
  'File.uploading': 'Wird hochgeladen...',
137
138
  'FormItem.autoUpdateloadFaild': 'Die Schnittstelle hat einen Fehler zurückgegeben, bitte sorgfältig prüfen',
@@ -134,6 +134,7 @@ register('en-US', {
134
134
  'File.sizeLimit': 'The maximum file size is {{maxSize}} B',
135
135
  'File.start': 'Start upload',
136
136
  'File.upload': 'Upload',
137
+ 'Image.upload':'Upload image',
137
138
  'File.uploadFailed': 'return data of udpload api is empty',
138
139
  'File.uploading': 'Uploading',
139
140
  'FormItem.autoUpdateloadFaild': 'return data of autoUpdate api is error',
@@ -138,7 +138,8 @@ register('zh-CN', {
138
138
  'File.retry': '重试上传',
139
139
  'File.sizeLimit': '文件大小不超过 {{maxSize}} B',
140
140
  'File.start': '开始上传',
141
- 'File.upload': '上传文件',
141
+ 'File.upload': '文件上传',
142
+ 'Image.upload': '图片上传',
142
143
  'File.uploadFailed': '接口返回错误,请仔细检查',
143
144
  'File.uploading': '上传中...',
144
145
  'FormItem.autoUpdateloadFaild': '接口返回错误,请仔细检查',
@@ -312,6 +313,8 @@ register('zh-CN', {
312
313
  'Condition.formula_placeholder': '请输入公式',
313
314
  'Condition.fun_error': '方法未定义',
314
315
  'InputTable.uniqueError': '列`{{label}}`没有通过唯一验证',
316
+ 'Timeline.collapseText': '展开',
317
+ 'Timeline.expandText': '折叠',
315
318
  'collapse': '展开',
316
319
  'expand': '折叠',
317
320
  'FormulaEditor.btnLabel': '公式编辑',
@@ -344,5 +347,5 @@ register('zh-CN', {
344
347
  'JSONSchema.add_prop': '添加属性',
345
348
  'JSONSchema.array_items': '成员类型',
346
349
  'Required': '必填',
347
- 'TimeNow': '此刻',
350
+ 'TimeNow': '此刻'
348
351
  });
@@ -184,6 +184,14 @@ export interface DownloadActionSchema
184
184
  actionType: 'download';
185
185
  }
186
186
 
187
+ export interface SaveAsActionSchema
188
+ extends Omit<AjaxActionSchema, 'actionType'> {
189
+ /**
190
+ * 指定为保存到本地
191
+ */
192
+ actionType: 'saveAs';
193
+ }
194
+
187
195
  export interface UrlActionSchema extends ButtonSchema {
188
196
  /**
189
197
  * 指定为打开链接
@@ -2154,7 +2154,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
2154
2154
  onSearchableFromInit: this.handleFilterInit,
2155
2155
  headerToolbarRender: this.renderHeaderToolbar,
2156
2156
  footerToolbarRender: this.renderFooterToolbar,
2157
- data: store.mergedData
2157
+ data: store.mergedData,
2158
+ loading: store.loading
2158
2159
  }
2159
2160
  )}
2160
2161
 
@@ -354,13 +354,18 @@ export class CardRenderer extends React.Component<CardProps> {
354
354
  } = this.props;
355
355
 
356
356
  const toolbars: Array<JSX.Element> = [];
357
-
358
357
  if (header) {
359
- const {highlightClassName, highlight: highlightTpl} = header;
360
- const highlight = !!evalExpression(highlightTpl!, data as object);
361
- if (highlight) {
358
+ const {highlightClassName, highlight} = header;
359
+ if (
360
+ typeof highlight === 'string'
361
+ ? evalExpression(highlight, data)
362
+ : highlight
363
+ ) {
362
364
  toolbars.push(
363
- <i className={cx('Card-highlight', highlightClassName)} />
365
+ <i
366
+ key="highlight"
367
+ className={cx('Card-highlight', highlightClassName)}
368
+ />
364
369
  );
365
370
  }
366
371
  }
@@ -5,7 +5,7 @@ import Transition, {
5
5
  EXITING
6
6
  } from 'react-transition-group/Transition';
7
7
  import {Renderer, RendererProps} from '../factory';
8
- import {resolveVariable} from '../utils/tpl-builtin';
8
+ import {resolveVariableAndFilter} from '../utils/tpl-builtin';
9
9
  import {
10
10
  autobind,
11
11
  createObject,
@@ -15,7 +15,7 @@ import {
15
15
  } from '../utils/helper';
16
16
  import {Action} from '../types';
17
17
  import {Icon} from '../components/icons';
18
- import {BaseSchema, SchemaCollection, SchemaName, SchemaTpl} from '../Schema';
18
+ import {BaseSchema, SchemaCollection, SchemaName} from '../Schema';
19
19
  import Html from '../components/Html';
20
20
  import Image from '../renderers/Image';
21
21
  import {ScopedContext, IScopedContext} from '../Scoped';
@@ -38,7 +38,7 @@ export interface CarouselSchema extends BaseSchema {
38
38
  /**
39
39
  * 轮播间隔时间
40
40
  */
41
- interval?: number;
41
+ interval?: number | string;
42
42
 
43
43
  /**
44
44
  * 动画时长
@@ -211,7 +211,13 @@ export class Carousel extends React.Component<CarouselProps, CarouselState> {
211
211
 
212
212
  this.clearAutoTimeout();
213
213
  if (this.props.auto) {
214
- this.intervalTimeout = setTimeout(this.autoSlide, this.props.interval);
214
+ const interval = this.props.interval;
215
+ this.intervalTimeout = setTimeout(
216
+ this.autoSlide,
217
+ typeof interval === 'string'
218
+ ? resolveVariableAndFilter(interval, this.props.data) || 5000
219
+ : interval
220
+ );
215
221
  }
216
222
  }
217
223
 
@@ -1636,7 +1636,7 @@ export default class ImageControl extends React.Component<
1636
1636
  ) : (
1637
1637
  <>
1638
1638
  <Icon icon="plus-fine" className="icon" />
1639
- <span className={cx('ImageControl-addBtn-text')}>{__('File.upload')}</span>
1639
+ <span className={cx('ImageControl-addBtn-text')}>{__('Image.upload')}</span>
1640
1640
  </>
1641
1641
  )}
1642
1642
 
@@ -727,6 +727,7 @@ export default class TextControl extends React.PureComponent<
727
727
  <Spinner
728
728
  show
729
729
  icon="reload"
730
+ size="sm"
730
731
  spinnerClassName={cx('TextControl-spinner')}
731
732
  />
732
733
  ) : null}
@@ -935,6 +935,7 @@ export function registerOptionsControl(config: OptionsConfig) {
935
935
  type: 'text',
936
936
  name: labelField || 'label',
937
937
  label: false,
938
+ required: true,
938
939
  placeholder: __('Options.addPlaceholder')
939
940
  }
940
941
  ];
@@ -85,6 +85,18 @@ export interface SelectControlSchema extends FormOptionsControl {
85
85
  * 搜索 API
86
86
  */
87
87
  searchApi?: SchemaApi;
88
+ /**
89
+ * 可多选条件下,是否可全选
90
+ */
91
+ checkAll?: boolean;
92
+ /**
93
+ * 可多选条件下,是否默认全选中所有值
94
+ */
95
+ defaultCheckAll?: boolean;
96
+ /**
97
+ * 可多选条件下,全选项文案,默认 ”全选“
98
+ */
99
+ checkAllLabel?: string;
88
100
  }
89
101
 
90
102
  export interface SelectProps extends OptionsControlProps {
@@ -412,9 +424,7 @@ export default class SelectControl extends React.Component<SelectProps, any> {
412
424
  onFocus={(e: any) => this.dispatchEvent('focus', e)}
413
425
  onAdd={() => this.dispatchEvent('add')}
414
426
  onEdit={(item: any) => this.dispatchEvent('edit', item)}
415
- onDelete={(item: any) =>
416
- this.dispatchEvent('delete', item)
417
- }
427
+ onDelete={(item: any) => this.dispatchEvent('delete', item)}
418
428
  loading={loading}
419
429
  noResultsText={noResultsText}
420
430
  renderMenu={menuTpl ? this.renderMenu : undefined}
@@ -1,19 +1,25 @@
1
1
  import React from 'react';
2
2
  import {IFormStore, IFormItemStore} from '../../store/form';
3
3
  import debouce from 'lodash/debounce';
4
+ import isEqual from 'lodash/isEqual';
4
5
 
5
6
  import {RendererProps, Renderer} from '../../factory';
6
7
  import {ComboStore, IComboStore, IUniqueGroup} from '../../store/combo';
7
8
  import {
8
9
  anyChanged,
9
10
  promisify,
10
- isObject,
11
11
  guid,
12
12
  isEmpty,
13
13
  autobind,
14
14
  getVariable,
15
15
  createObject
16
16
  } from '../../utils/helper';
17
+ import {
18
+ isNeedFormula,
19
+ isExpression,
20
+ FormulaExec,
21
+ replaceExpression
22
+ } from '../../utils/formula';
17
23
  import {IIRendererStore, IRendererStore} from '../../store';
18
24
  import {ScopedContext, IScopedContext} from '../../Scoped';
19
25
  import {reaction} from 'mobx';
@@ -193,12 +199,27 @@ export function wrapControl<
193
199
  combo.bindUniuqueItem(model);
194
200
  }
195
201
 
196
- // 同步 value
197
- model.changeTmpValue(
198
- propValue ?? store?.getValueByName(model.name) ?? value
199
- );
202
+ if (propValue !== undefined && propValue !== null) {
203
+ // 同步 value: 优先使用 props 中的 value
204
+ model.changeTmpValue(propValue);
205
+ } else {
206
+ // 备注: 此处的 value 是 schema 中的 value(和props.defaultValue相同)
207
+ const curTmpValue = isExpression(value)
208
+ ? FormulaExec['formula'](value, data) // 对组件默认值进行运算
209
+ : store?.getValueByName(model.name) ?? replaceExpression(value); // 优先使用公式表达式
210
+ // 同步 value
211
+ model.changeTmpValue(curTmpValue);
212
+
213
+ if (
214
+ onChange &&
215
+ value !== undefined &&
216
+ curTmpValue !== undefined
217
+ ) {
218
+ // 组件默认值支持表达式需要: 避免初始化时上下文中丢失组件默认值
219
+ onChange(model.tmpValue, model.name, false, true);
220
+ }
221
+ }
200
222
 
201
- // 如果没有初始值,通过 onChange 设置过去
202
223
  if (
203
224
  onChange &&
204
225
  typeof propValue === 'undefined' &&
@@ -208,6 +229,7 @@ export function wrapControl<
208
229
  // 对应 issue 为 https://github.com/baidu/amis/issues/2674
209
230
  store?.storeType !== TableStore.name
210
231
  ) {
232
+ // 如果没有初始值,通过 onChange 设置过去
211
233
  onChange(model.tmpValue, model.name, false, true);
212
234
  }
213
235
  }
@@ -258,6 +280,7 @@ export function wrapControl<
258
280
  'validations',
259
281
  'validationErrors',
260
282
  'value',
283
+ 'defaultValue',
261
284
  'required',
262
285
  'unique',
263
286
  'multiple',
@@ -301,30 +324,75 @@ export function wrapControl<
301
324
  });
302
325
  }
303
326
 
327
+ // 此处需要同时考虑 defaultValue 和 value
304
328
  if (model && typeof props.value !== 'undefined') {
305
- // 自己控制的 value 优先
306
- if (
307
- props.value !== prevProps.value &&
308
- props.value !== model.tmpValue
309
- ) {
329
+ // 渲染器中的 value 优先
330
+ if (props.value !== prevProps.value && props.value !== model.tmpValue) {
331
+ // 外部直接传入的 value 无需执行运算器
310
332
  model.changeTmpValue(props.value);
311
333
  }
312
334
  } else if (
313
- // 然后才是查看关联的 name 属性值是否变化
314
335
  model &&
315
- props.data !== prevProps.data &&
316
- (!model.emitedValue || model.emitedValue === model.tmpValue)
336
+ typeof props.defaultValue !== 'undefined' &&
337
+ isExpression(props.defaultValue)
317
338
  ) {
318
- model.changeEmitedValue(undefined);
319
- const value = getVariable(props.data, model.name);
320
- const prevValue = getVariable(prevProps.data, model.name);
339
+ // 渲染器中的 defaultValue 优先(备注: SchemaRenderer中会将 value 改成 defaultValue)
340
+ if (
341
+ props.defaultValue !== prevProps.defaultValue ||
342
+ (!isEqual(props.data, prevProps.data) &&
343
+ isNeedFormula(props.defaultValue, props.data, prevProps.data))
344
+ ) {
345
+ const curResult = FormulaExec['formula'](
346
+ props.defaultValue,
347
+ props.data
348
+ );
349
+ const prevResult = FormulaExec['formula'](
350
+ prevProps.defaultValue,
351
+ prevProps.data
352
+ );
353
+ if (curResult !== prevResult && curResult !== model.tmpValue) {
354
+ // 识别上下文变动、自身数值变动、公式运算结果变动
355
+ model.changeTmpValue(curResult);
356
+ if (props.onChange) {
357
+ props.onChange(curResult, model.name, false);
358
+ }
359
+ }
360
+ }
361
+ } else if (model) {
362
+ const valueByName = getVariable(props.data, model.name);
363
+
321
364
  if (
322
- (value !== prevValue ||
323
- getVariable(props.data, model.name, false) !==
324
- getVariable(prevProps.data, model.name, false)) &&
325
- value !== model.tmpValue
365
+ valueByName !== undefined &&
366
+ props.defaultValue === prevProps.defaultValue
326
367
  ) {
327
- model.changeTmpValue(value);
368
+ // value 非公式表达式时,name 值优先,若 defaultValue 主动变动时,则使用 defaultValue
369
+ if (
370
+ // 然后才是查看关联的 name 属性值是否变化
371
+ props.data !== prevProps.data &&
372
+ (!model.emitedValue || model.emitedValue === model.tmpValue)
373
+ ) {
374
+ model.changeEmitedValue(undefined);
375
+ const prevValueByName = getVariable(props.data, model.name);
376
+ if (
377
+ (valueByName !== prevValueByName ||
378
+ getVariable(props.data, model.name, false) !==
379
+ getVariable(prevProps.data, model.name, false)) &&
380
+ valueByName !== model.tmpValue
381
+ ) {
382
+ model.changeTmpValue(valueByName);
383
+ }
384
+ }
385
+ } else if (
386
+ typeof props.defaultValue !== 'undefined' &&
387
+ props.defaultValue !== prevProps.defaultValue &&
388
+ props.defaultValue !== model.tmpValue
389
+ ) {
390
+ // 组件默认值非公式
391
+ const curValue = replaceExpression(props.defaultValue);
392
+ model.changeTmpValue(curValue);
393
+ if (props.onChange) {
394
+ props.onChange(curValue, model.name, false);
395
+ }
328
396
  }
329
397
  }
330
398
  }
@@ -559,6 +559,7 @@ export default class Service extends React.Component<ServiceProps> {
559
559
 
560
560
  return render('body', store.schema || schema, {
561
561
  key: store.schemaKey || 'body',
562
+ loading: store.loading,
562
563
  onQuery: this.handleQuery,
563
564
  onAction: this.handleAction,
564
565
  onChange: this.handleChange