@nocobase/client 0.7.0-alpha.82 → 0.7.0-alpha.83

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 (65) hide show
  1. package/es/block-provider/hooks/index.d.ts +3 -0
  2. package/es/block-provider/hooks/index.js +233 -168
  3. package/es/collection-manager/Configuration/AddFieldAction.js +27 -9
  4. package/es/collection-manager/Configuration/EditFieldAction.js +25 -8
  5. package/es/locale/en_US.d.ts +10 -0
  6. package/es/locale/en_US.js +11 -1
  7. package/es/locale/index.d.ts +44 -0
  8. package/es/locale/zh_CN.d.ts +34 -0
  9. package/es/locale/zh_CN.js +35 -1
  10. package/es/schema-component/antd/action/Action.Designer.js +33 -13
  11. package/es/schema-component/antd/action/utils.d.ts +2 -0
  12. package/es/schema-component/antd/action/utils.js +60 -0
  13. package/es/schema-component/antd/date-picker/util.d.ts +2 -1
  14. package/es/schema-component/antd/date-picker/util.js +4 -2
  15. package/es/schema-initializer/buttons/FormActionInitializers.d.ts +84 -0
  16. package/es/schema-initializer/buttons/FormActionInitializers.js +63 -0
  17. package/es/schema-initializer/buttons/ReadPrettyFormActionInitializers.d.ts +26 -0
  18. package/es/schema-initializer/buttons/ReadPrettyFormActionInitializers.js +21 -0
  19. package/es/schema-initializer/buttons/TableActionColumnInitializers.js +21 -0
  20. package/es/schema-settings/SchemaSettings.js +48 -16
  21. package/es/workflow/triggers/collection.js +1 -0
  22. package/es/workflow/triggers/index.js +2 -0
  23. package/es/workflow/triggers/schedule.d.ts +25 -0
  24. package/es/workflow/triggers/schedule.js +531 -0
  25. package/lib/block-provider/hooks/index.d.ts +3 -0
  26. package/lib/block-provider/hooks/index.js +238 -169
  27. package/lib/collection-manager/Configuration/AddFieldAction.js +27 -9
  28. package/lib/collection-manager/Configuration/EditFieldAction.js +25 -8
  29. package/lib/locale/en_US.d.ts +10 -0
  30. package/lib/locale/en_US.js +11 -1
  31. package/lib/locale/index.d.ts +44 -0
  32. package/lib/locale/zh_CN.d.ts +34 -0
  33. package/lib/locale/zh_CN.js +35 -1
  34. package/lib/schema-component/antd/action/Action.Designer.js +34 -13
  35. package/lib/schema-component/antd/action/utils.d.ts +2 -0
  36. package/lib/schema-component/antd/action/utils.js +67 -0
  37. package/lib/schema-component/antd/date-picker/util.d.ts +2 -1
  38. package/lib/schema-component/antd/date-picker/util.js +6 -1
  39. package/lib/schema-initializer/buttons/FormActionInitializers.d.ts +84 -0
  40. package/lib/schema-initializer/buttons/FormActionInitializers.js +63 -0
  41. package/lib/schema-initializer/buttons/ReadPrettyFormActionInitializers.d.ts +26 -0
  42. package/lib/schema-initializer/buttons/ReadPrettyFormActionInitializers.js +21 -0
  43. package/lib/schema-initializer/buttons/TableActionColumnInitializers.js +21 -0
  44. package/lib/schema-settings/SchemaSettings.js +49 -16
  45. package/lib/workflow/triggers/collection.js +1 -0
  46. package/lib/workflow/triggers/index.js +3 -0
  47. package/lib/workflow/triggers/schedule.d.ts +25 -0
  48. package/lib/workflow/triggers/schedule.js +554 -0
  49. package/package.json +4 -4
  50. package/src/block-provider/hooks/index.ts +106 -69
  51. package/src/collection-manager/Configuration/AddFieldAction.tsx +18 -0
  52. package/src/collection-manager/Configuration/EditFieldAction.tsx +19 -0
  53. package/src/locale/en_US.ts +11 -1
  54. package/src/locale/zh_CN.ts +39 -1
  55. package/src/schema-component/antd/action/Action.Designer.tsx +33 -1
  56. package/src/schema-component/antd/action/utils.ts +68 -0
  57. package/src/schema-component/antd/date-picker/util.ts +4 -3
  58. package/src/schema-initializer/SchemaInitializer.tsx +2 -2
  59. package/src/schema-initializer/buttons/FormActionInitializers.tsx +66 -0
  60. package/src/schema-initializer/buttons/ReadPrettyFormActionInitializers.tsx +22 -0
  61. package/src/schema-initializer/buttons/TableActionColumnInitializers.tsx +22 -0
  62. package/src/schema-settings/SchemaSettings.tsx +40 -29
  63. package/src/workflow/triggers/collection.tsx +1 -1
  64. package/src/workflow/triggers/index.tsx +2 -0
  65. package/src/workflow/triggers/schedule.tsx +422 -0
@@ -7,6 +7,7 @@ import { Alert, Button, Dropdown, Menu, MenuItemProps, Modal, Select, Space, Swi
7
7
  import classNames from 'classnames';
8
8
  import { cloneDeep } from 'lodash';
9
9
  import React, { createContext, useContext, useMemo, useState } from 'react';
10
+ import { createPortal } from 'react-dom';
10
11
  import { useTranslation } from 'react-i18next';
11
12
  import {
12
13
  ActionContext,
@@ -19,7 +20,7 @@ import {
19
20
  useActionContext,
20
21
  useAPIClient,
21
22
  useCollection,
22
- useCompile
23
+ useCompile,
23
24
  } from '..';
24
25
  import { useSchemaTemplateManager } from '../schema-templates';
25
26
  import { useBlockTemplateContext } from '../schema-templates/BlockTemplate';
@@ -466,7 +467,7 @@ SchemaSettings.PopupItem = (props) => {
466
467
  };
467
468
 
468
469
  SchemaSettings.ActionModalItem = React.memo((props: any) => {
469
- const { title, onSubmit, initialValues, initialSchema, modalTip, ...others } = props;
470
+ const { title, onSubmit, initialValues, initialSchema, schema, modalTip, components, ...others } = props;
470
471
  const [visible, setVisible] = useState(false);
471
472
  const [schemaUid, setSchemaUid] = useState<string>(props.uid);
472
473
  const { t } = useTranslation();
@@ -487,13 +488,14 @@ SchemaSettings.ActionModalItem = React.memo((props: any) => {
487
488
  setVisible(false);
488
489
  };
489
490
 
490
- const submitHandler = () => {
491
+ const submitHandler = async () => {
492
+ await form.submit();
491
493
  onSubmit?.(cloneDeep(form.values));
492
494
  setVisible(false);
493
495
  };
494
496
 
495
497
  const openAssignedFieldValueHandler = async () => {
496
- if (!schemaUid && initialSchema['x-uid']) {
498
+ if (!schemaUid && initialSchema?.['x-uid']) {
497
499
  fieldSchema['x-action-settings'].schemaUid = initialSchema['x-uid'];
498
500
  dn.emit('patch', { schema: fieldSchema });
499
501
  await api.resource('uiSchemas').insert({ values: initialSchema });
@@ -509,31 +511,40 @@ SchemaSettings.ActionModalItem = React.memo((props: any) => {
509
511
  <SchemaSettings.Item {...others} onClick={openAssignedFieldValueHandler}>
510
512
  {props.children || props.title}
511
513
  </SchemaSettings.Item>
512
-
513
- <Modal
514
- width={'50%'}
515
- title={compile(title)}
516
- {...others}
517
- destroyOnClose
518
- visible={visible}
519
- onCancel={cancelHandler}
520
- footer={
521
- <Space>
522
- <Button onClick={cancelHandler}>{t('Cancel')}</Button>
523
- <Button type="primary" onClick={submitHandler}>
524
- {t('Submit')}
525
- </Button>
526
- </Space>
527
- }
528
- >
529
- <FormProvider form={form}>
530
- <FormLayout layout={'vertical'}>
531
- {modalTip && <Alert message={modalTip} />}
532
- {modalTip && <br />}
533
- {visible && <RemoteSchemaComponent noForm uid={schemaUid} />}
534
- </FormLayout>
535
- </FormProvider>
536
- </Modal>
514
+ {createPortal(
515
+ <div
516
+ onClick={(e) => {
517
+ e.stopPropagation();
518
+ }}
519
+ >
520
+ <Modal
521
+ width={'50%'}
522
+ title={compile(title)}
523
+ {...others}
524
+ destroyOnClose
525
+ visible={visible}
526
+ onCancel={cancelHandler}
527
+ footer={
528
+ <Space>
529
+ <Button onClick={cancelHandler}>{t('Cancel')}</Button>
530
+ <Button type="primary" onClick={submitHandler}>
531
+ {t('Submit')}
532
+ </Button>
533
+ </Space>
534
+ }
535
+ >
536
+ <FormProvider form={form}>
537
+ <FormLayout layout={'vertical'}>
538
+ {modalTip && <Alert message={modalTip} />}
539
+ {modalTip && <br />}
540
+ {visible && schemaUid && <RemoteSchemaComponent noForm components={components} uid={schemaUid} />}
541
+ {visible && schema && <SchemaComponent components={components} schema={schema} />}
542
+ </FormLayout>
543
+ </FormProvider>
544
+ </Modal>
545
+ </div>,
546
+ document.body,
547
+ )}
537
548
  </>
538
549
  );
539
550
  });
@@ -26,7 +26,7 @@ const FieldsSelect = observer((props) => {
26
26
  && (field.uiSchema ? !field.uiSchema['x-read-pretty'] : true)
27
27
  ))
28
28
  .map(field => (
29
- <Select.Option value={field.name}>{compile(field.uiSchema?.title)}</Select.Option>
29
+ <Select.Option key={field.name} value={field.name}>{compile(field.uiSchema?.title)}</Select.Option>
30
30
  ))}
31
31
  </Select>
32
32
  );
@@ -8,6 +8,7 @@ import { message, Tag } from "antd";
8
8
  import { SchemaComponent, useActionContext, useAPIClient, useCompile, useRecord, useRequest, useResourceActionContext } from '../../';
9
9
  import collection from './collection';
10
10
  import { nodeCardClass, nodeMetaClass } from "../style";
11
+ import schedule from "./schedule";
11
12
 
12
13
 
13
14
  function useUpdateConfigAction() {
@@ -50,6 +51,7 @@ export interface Trigger {
50
51
  export const triggers = new Registry<Trigger>();
51
52
 
52
53
  triggers.register(collection.type, collection);
54
+ triggers.register(schedule.type, schedule);
53
55
 
54
56
  export const TriggerConfig = () => {
55
57
  const { t } = useTranslation();
@@ -0,0 +1,422 @@
1
+ import React, { useState } from 'react';
2
+ import { InputNumber, Select } from 'antd';
3
+ import { observer, useForm, useFormEffects } from '@formily/react';
4
+
5
+ import { useCollectionDataSource, useCollectionManager } from '../../collection-manager';
6
+ import { SchemaComponent, useCompile, DatePicker } from '../../schema-component';
7
+
8
+ import { useFlowContext } from '../WorkflowCanvas';
9
+ import { BaseTypeSet } from '../calculators';
10
+ import { collection } from '../schemas/collection';
11
+ import { useTranslation } from 'react-i18next';
12
+ import { onFieldValueChange } from '@formily/core';
13
+ import { css } from '@emotion/css';
14
+
15
+ const DateFieldsSelect: React.FC<any> = observer((props) => {
16
+ const compile = useCompile();
17
+ const { getCollectionFields } = useCollectionManager();
18
+ const { values } = useForm();
19
+ const fields = getCollectionFields(values?.config?.collection);
20
+
21
+ return (
22
+ <Select {...props}>
23
+ {fields
24
+ .filter(field => (
25
+ !field.hidden
26
+ && (field.uiSchema ? field.type === 'date' : false)
27
+ ))
28
+ .map(field => (
29
+ <Select.Option key={field.name} value={field.name}>{compile(field.uiSchema?.title)}</Select.Option>
30
+ ))}
31
+ </Select>
32
+ );
33
+ });
34
+
35
+ const OnField = ({ value, onChange }) => {
36
+ const { t } = useTranslation();
37
+ const [dir, setDir] = useState(value.offset ? value.offset / Math.abs(value.offset) : 0);
38
+
39
+ return (
40
+ <fieldset className={css`
41
+ display: flex;
42
+ gap: .5em;
43
+ `}>
44
+ <DateFieldsSelect value={value.field} onChange={field => onChange({ ...value, field })} />
45
+ {value.field
46
+ ? (
47
+ <Select value={dir} onChange={(v) => {
48
+ setDir(v);
49
+ onChange({ ...value, offset: Math.abs(value.offset) * v });
50
+ }}>
51
+ <Select.Option value={0}>{t('Exactly at')}</Select.Option>
52
+ <Select.Option value={-1}>{t('Before')}</Select.Option>
53
+ <Select.Option value={1}>{t('After')}</Select.Option>
54
+ </Select>
55
+ )
56
+ : null}
57
+ {dir
58
+ ? (
59
+ <>
60
+ <InputNumber value={Math.abs(value.offset)} onChange={(v) => onChange({ ...value, offset: v * dir })}/>
61
+ <Select value={value.unit || 86400000} onChange={unit => onChange({ ...value, unit })}>
62
+ <Select.Option value={86400000}>{t('Days')}</Select.Option>
63
+ <Select.Option value={3600000}>{t('Hours')}</Select.Option>
64
+ <Select.Option value={60000}>{t('Minutes')}</Select.Option>
65
+ <Select.Option value={1000}>{t('Seconds')}</Select.Option>
66
+ </Select>
67
+ </>
68
+ )
69
+ : null}
70
+ </fieldset>
71
+ );
72
+ }
73
+
74
+ function EndsByField({ value, onChange }) {
75
+ const { t } = useTranslation();
76
+ const [type, setType] = useState(typeof value === 'object' && !(value instanceof Date) ? 'field' : 'date');
77
+ return (
78
+ <fieldset className={css`
79
+ display: flex;
80
+ gap: .5em;
81
+ `}>
82
+ <Select value={type} onChange={t => {
83
+ onChange(t === 'field' ? {} : null);
84
+ setType(t);
85
+ }}>
86
+ <Select.Option value={'field'}>{t('By field')}</Select.Option>
87
+ <Select.Option value={'date'}>{t('By custom date')}</Select.Option>
88
+ </Select>
89
+ {type === 'field'
90
+ ? (
91
+ <OnField value={value} onChange={onChange} />
92
+ )
93
+ : (
94
+ <DatePicker showTime value={value} onChange={onChange} />
95
+ )
96
+ }
97
+ </fieldset>
98
+ );
99
+ }
100
+
101
+ function parseCronRule(cron: string) {
102
+ if (!cron) {
103
+ return {
104
+ mode: 0
105
+ }
106
+ }
107
+ const rules = cron.split(/\s+/).slice(1).map(v => v.split('/'));
108
+ let index = rules.findIndex(rule => rule[0] === '*');
109
+ if (index === -1) {
110
+ return {
111
+ mode: 0
112
+ }
113
+ }
114
+ // fix days of week
115
+ if (index === 3 && rules[4][0] === '*') {
116
+ index = 4;
117
+ }
118
+ return {
119
+ mode: index + 1,
120
+ step: rules[index][1] ?? 1
121
+ };
122
+ }
123
+
124
+ const CronUnits = [
125
+ { value: 1, option: 'By minute', unitText: 'Minutes' },
126
+ { value: 2, option: 'By hour', unitText: 'Hours' },
127
+ { value: 3, option: 'By date', unitText: 'Days', conflict: true, startFrom: 1 },
128
+ { value: 4, option: 'By month', unitText: 'Months', startFrom: 1 },
129
+ { value: 5, option: 'By day of week', unitText: 'Days', conflict: true },
130
+ ];
131
+
132
+ function getChangedCron({ mode, step }) {
133
+ const m = mode - 1;
134
+ const left = [0, ...Array(m).fill(null).map((_, i) => {
135
+ if (CronUnits[m].conflict && CronUnits[i].conflict) {
136
+ return '?';
137
+ }
138
+ return i === 3 ? '*' : CronUnits[i].startFrom ?? 0;
139
+ })].join(' ');
140
+ const right = Array(5 - mode).fill(null).map((_, i) => {
141
+ if (CronUnits[m].conflict && CronUnits[mode + i].conflict || mode === 4) {
142
+ return '?';
143
+ }
144
+ return '*';
145
+ }).join(' ');
146
+ return `${left} ${!step || step == 1 ? '*' : `*/${step}`}${right ? ` ${right}` : ''}`;
147
+ }
148
+
149
+ const CronField = ({ value = '', onChange }) => {
150
+ const { t } = useTranslation();
151
+ const cron = parseCronRule(value);
152
+ const unit = CronUnits[cron.mode - 1];
153
+ return (
154
+ <fieldset className={css`
155
+ display: flex;
156
+ gap: .5em;
157
+ `}>
158
+ <Select
159
+ value={cron.mode}
160
+ onChange={v => onChange(v ? getChangedCron({ step: cron.step, mode: v }) : '')}
161
+ >
162
+ <Select.Option value={0}>{t('No repeat')}</Select.Option>
163
+ {CronUnits.map(item => (
164
+ <Select.Option key={item.value} value={item.value}>{t(item.option)}</Select.Option>
165
+ ))}
166
+ </Select>
167
+ {cron.mode
168
+ ? (
169
+ <InputNumber
170
+ value={cron.step}
171
+ onChange={v => onChange(getChangedCron({ step: v, mode: cron.mode }))}
172
+ min={1}
173
+ addonBefore={t('Every')}
174
+ addonAfter={t(unit.unitText)}
175
+ />
176
+ )
177
+ : null}
178
+ </fieldset>
179
+ );
180
+ }
181
+
182
+ const ModeFieldsets = {
183
+ 0: {
184
+ startsOn: {
185
+ type: 'datetime',
186
+ name: 'startsOn',
187
+ title: '{{t("Starts on")}}',
188
+ 'x-decorator': 'FormItem',
189
+ 'x-component': 'DatePicker',
190
+ 'x-component-props': {
191
+ showTime: true
192
+ },
193
+ required: true
194
+ },
195
+ cron: {
196
+ type: 'string',
197
+ name: 'cron',
198
+ title: '{{t("Repeat mode")}}',
199
+ 'x-decorator': 'FormItem',
200
+ 'x-component': 'CronField',
201
+ 'x-reactions': [
202
+ {
203
+ target: 'config.endsOn',
204
+ fulfill: {
205
+ state: {
206
+ visible: '{{!!$self.value}}',
207
+ },
208
+ }
209
+ },
210
+ {
211
+ target: 'config.limit',
212
+ fulfill: {
213
+ state: {
214
+ visible: '{{!!$self.value}}',
215
+ },
216
+ }
217
+ }
218
+ ]
219
+ },
220
+ endsOn: {
221
+ type: 'datetime',
222
+ name: 'endsOn',
223
+ title: '{{t("Ends on")}}',
224
+ 'x-decorator': 'FormItem',
225
+ 'x-component': 'DatePicker',
226
+ 'x-component-props': {
227
+ showTime: true
228
+ }
229
+ },
230
+ limit: {
231
+ type: 'number',
232
+ name: 'limit',
233
+ title: '{{t("Repeat limit")}}',
234
+ 'x-decorator': 'FormItem',
235
+ 'x-component': 'InputNumber',
236
+ 'x-component-props': {
237
+ placeholder: '{{t("No limit")}}',
238
+ min: 0
239
+ }
240
+ }
241
+ },
242
+ 1: {
243
+ collection: {
244
+ ...collection,
245
+ 'x-reactions': [
246
+ ...collection['x-reactions'],
247
+ {
248
+ // only full path works
249
+ target: 'config.startsOn',
250
+ fulfill: {
251
+ state: {
252
+ visible: '{{!!$self.value}}',
253
+ },
254
+ }
255
+ }
256
+ ]
257
+ },
258
+ startsOn: {
259
+ type: 'object',
260
+ title: '{{t("Starts on")}}',
261
+ 'x-decorator': 'FormItem',
262
+ 'x-component': 'OnField',
263
+ required: true
264
+ },
265
+ cron: {
266
+ type: 'string',
267
+ name: 'cron',
268
+ title: '{{t("Repeat mode")}}',
269
+ 'x-decorator': 'FormItem',
270
+ 'x-component': 'CronField',
271
+ 'x-reactions': [
272
+ {
273
+ target: 'config.endsOn',
274
+ fulfill: {
275
+ state: {
276
+ visible: '{{!!$self.value}}',
277
+ },
278
+ }
279
+ },
280
+ {
281
+ target: 'config.limit',
282
+ fulfill: {
283
+ state: {
284
+ visible: '{{!!$self.value}}',
285
+ },
286
+ }
287
+ }
288
+ ]
289
+ },
290
+ endsOn: {
291
+ type: 'object',
292
+ title: '{{t("Ends on")}}',
293
+ 'x-decorator': 'FormItem',
294
+ 'x-component': 'EndsByField'
295
+ },
296
+ limit: {
297
+ type: 'number',
298
+ name: 'limit',
299
+ title: '{{t("Repeat limit")}}',
300
+ 'x-decorator': 'FormItem',
301
+ 'x-component': 'InputNumber',
302
+ 'x-component-props': {
303
+ placeholder: '{{t("No limit")}}',
304
+ min: 0
305
+ }
306
+ }
307
+ }
308
+ };
309
+
310
+ const ScheduleConfig = () => {
311
+ const { values = {}, clearFormGraph } = useForm();
312
+ const { config = {} } = values;
313
+ const [mode, setMode] = useState(config.mode);
314
+ useFormEffects(() => {
315
+ onFieldValueChange('config.mode', (field) => {
316
+ setMode(field.value);
317
+ clearFormGraph('config.collection');
318
+ clearFormGraph('config.startsOn');
319
+ clearFormGraph('config.cron');
320
+ clearFormGraph('config.endsOn');
321
+ })
322
+ });
323
+
324
+ return (
325
+ <>
326
+ <SchemaComponent
327
+ schema={{
328
+ type: 'number',
329
+ title: '{{t("Trigger mode")}}',
330
+ name: 'mode',
331
+ 'x-decorator': 'FormItem',
332
+ 'x-component': 'Radio.Group',
333
+ 'x-component-props': {
334
+ options: [
335
+ { value: 0, label: '{{t("Based on certain date")}}' },
336
+ { value: 1, label: '{{t("Based on date field of collection")}}' },
337
+ ]
338
+ },
339
+ required: true
340
+ }}
341
+ />
342
+ <SchemaComponent
343
+ schema={{
344
+ type: 'void',
345
+ properties: {
346
+ [`mode-${mode}`]: {
347
+ type: 'void',
348
+ 'x-component': 'fieldset',
349
+ 'x-component-props': {
350
+ className: css`
351
+ .ant-select{
352
+ width: auto;
353
+ min-width: 4em;
354
+ }
355
+
356
+ .ant-input-number{
357
+ width: 4em;
358
+ }
359
+
360
+ .ant-picker{
361
+ width: auto;
362
+ }
363
+ `
364
+ },
365
+ properties: ModeFieldsets[mode]
366
+ }
367
+ }
368
+ }}
369
+ components={{
370
+ DateFieldsSelect,
371
+ OnField,
372
+ CronField,
373
+ EndsByField
374
+ }}
375
+ />
376
+ </>
377
+ );
378
+ };
379
+
380
+ export default {
381
+ title: '{{t("Schedule event")}}',
382
+ type: 'schedule',
383
+ fieldset: {
384
+ config: {
385
+ type: 'object',
386
+ name: 'config',
387
+ 'x-component': 'ScheduleConfig',
388
+ 'x-component-props': {
389
+ }
390
+ }
391
+ },
392
+ scope: {
393
+ useCollectionDataSource
394
+ },
395
+ components: {
396
+ // FieldsSelect
397
+ ScheduleConfig
398
+ },
399
+ getter({ type, options, onChange }) {
400
+ const { t } = useTranslation();
401
+ const compile = useCompile();
402
+ const { collections = [] } = useCollectionManager();
403
+ const { workflow } = useFlowContext();
404
+ const collection = collections.find(item => item.name === workflow.config.collection) ?? { fields: [] };
405
+
406
+ return (
407
+ <Select
408
+ placeholder={t('Fields')}
409
+ value={options?.path?.replace(/^data\./, '')}
410
+ onChange={(path) => {
411
+ onChange({ type, options: { ...options, path: `data.${path}` } });
412
+ }}
413
+ >
414
+ {collection.fields
415
+ .filter(field => BaseTypeSet.has(field?.uiSchema?.type))
416
+ .map(field => (
417
+ <Select.Option key={field.name} value={field.name}>{compile(field.uiSchema.title)}</Select.Option>
418
+ ))}
419
+ </Select>
420
+ );
421
+ }
422
+ };