@kne/form-creator 0.1.2

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.
@@ -0,0 +1,4228 @@
1
+ import { useState, useMemo, useEffect, createElement, Fragment } from 'react';
2
+ import { Space, Tag, Button, Typography, Flex, Dropdown, Empty, message, Checkbox as Checkbox$1, Input as Input$1, InputNumber as InputNumber$1, Card, Tooltip } from 'antd';
3
+ import { createWithIntlProvider, useIntl } from '@kne/react-intl';
4
+ import { useIsMobile, RESPONSIVE_BOUNDARY_CLASS } from '@kne/responsive-utils';
5
+ import { ArrowUpOutlined, ArrowDownOutlined, EditOutlined, DeleteOutlined, PlusOutlined, SettingOutlined, FormOutlined, UnorderedListOutlined, TableOutlined, AppstoreOutlined, OrderedListOutlined, ApartmentOutlined, QuestionCircleOutlined } from '@ant-design/icons';
6
+ import { hooks, Input, TextArea, InputNumber, Select, RadioGroup, CheckboxGroup, Switch, Checkbox, DatePicker, useFormContext, Slider, SubmitButton, ResetButton, CancelButton } from '@kne/react-form-antd';
7
+ import SelectList, { SelectTableList, SelectTree, SelectCascader } from '@kne/super-select';
8
+ import { SelectFunction, SelectIndustry, SelectAddress } from '@kne/super-select-plus';
9
+ import '@kne/super-select/dist/index.css';
10
+ import '@kne/super-select-plus/dist/index.css';
11
+ import { jsxs, jsx } from 'react/jsx-runtime';
12
+ import FormInfo, { FormModal, Form, Steps, MultiField, TableList, List } from '@kne/form-info';
13
+ import '@kne/form-info/dist/index.css';
14
+ import '@kne/info-page/dist/index.css';
15
+
16
+ function _extends() {
17
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
18
+ for (var e = 1; e < arguments.length; e++) {
19
+ var t = arguments[e];
20
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
21
+ }
22
+ return n;
23
+ }, _extends.apply(null, arguments);
24
+ }
25
+ function _objectWithoutPropertiesLoose(r, e) {
26
+ if (null == r) return {};
27
+ var t = {};
28
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
29
+ if (-1 !== e.indexOf(n)) continue;
30
+ t[n] = r[n];
31
+ }
32
+ return t;
33
+ }
34
+
35
+ const locale$1 = {
36
+ addField: '添加填写项',
37
+ editField: '编辑填写项',
38
+ deleteField: '删除填写项',
39
+ moveUp: '上移',
40
+ moveDown: '下移',
41
+ fieldListTitle: '填写项配置',
42
+ fieldListSubtitle: '通过列表管理填写项,右侧实时预览表单效果',
43
+ blockListTitle: '表单结构',
44
+ blockListSubtitle: '添加不同类型的内容模块来搭建你的表单',
45
+ emptyFieldList: '暂无填写项,点击上方添加',
46
+ emptyBlockList: '暂无内容,点击"添加模块"开始搭建表单',
47
+ addBlock: '添加模块',
48
+ editBlock: '编辑模块',
49
+ deleteBlock: '删除模块',
50
+ untitledBlock: '未命名模块',
51
+ expandBlock: '展开',
52
+ collapseBlock: '收起',
53
+ fieldCount: '{count} 个填写项',
54
+ stepCount: '{count} 个步骤',
55
+ blockKind_formInfo: '基础表单',
56
+ blockKind_list: '可增减列表',
57
+ blockKind_tableList: '表格列表',
58
+ blockKind_multiField: '同类多值',
59
+ blockKind_steps: '分步表单',
60
+ blockTitle: '模块标题',
61
+ blockTitlePlaceholder: '例如:基本信息',
62
+ blockSubtitle: '模块副标题',
63
+ blockSubtitlePlaceholder: '例如:请填写员工基本信息',
64
+ blockName: '数据标识',
65
+ blockNameRequired: '请填写数据标识',
66
+ blockGap: '间距',
67
+ blockBordered: '显示边框',
68
+ blockImportant: '突出显示',
69
+ blockAddText: '添加按钮文案',
70
+ blockAddTextPlaceholder: '例如:添加一条工作经历',
71
+ blockMaxLength: '最多条数',
72
+ blockMinLength: '最少条数',
73
+ blockAutoStep: '填写完成后自动进入下一步',
74
+ multiFieldType: '填写项类型',
75
+ multiFieldSummary: '填写类型:{type}',
76
+ multiFieldEditorHint: '同类多值模块会根据你选择的填写项类型,自动生成可增减的多个输入框。',
77
+ stepListTitle: '步骤列表',
78
+ addStep: '添加步骤',
79
+ editStep: '编辑步骤',
80
+ deleteStep: '删除步骤',
81
+ stepTitle: '步骤标题',
82
+ stepTitlePlaceholder: '默认第 x 步,可自定义',
83
+ emptyStepList: '暂无步骤,点击"添加步骤"开始搭建',
84
+ untitledStep: '第{index}步',
85
+ stepPrev: '上一步',
86
+ stepNext: '下一步',
87
+ stepComplete: '完成',
88
+ fieldType: '填写项类型',
89
+ fieldName: '数据标识',
90
+ fieldNamePlaceholder: '已自动生成,可修改',
91
+ fieldLabel: '显示名称',
92
+ fieldLabelPlaceholder: '例如:姓名',
93
+ fieldTips: '标签提示',
94
+ fieldTipsPlaceholder: '鼠标悬停标签旁图标时显示',
95
+ fieldDescription: '字段说明',
96
+ fieldDescriptionPlaceholder: '显示在输入框下方的补充说明',
97
+ fieldRule: '填写规则',
98
+ fieldPlaceholder: '输入提示语',
99
+ fieldOptions: '选项配置',
100
+ fieldBlock: '占满整行',
101
+ fieldHidden: '隐藏该项',
102
+ fieldHiddenTag: '已隐藏',
103
+ fieldBlockTag: '整行',
104
+ fieldNameDuplicate: '该数据标识已被使用,请换一个',
105
+ untitledField: '未命名填写项',
106
+ previewTitle: '表单预览',
107
+ previewHint: '左侧的配置变化会实时同步到这里',
108
+ confirm: '确定',
109
+ cancel: '取消',
110
+ submit: '提交',
111
+ reset: '重置',
112
+ formActionsSection: '表单按钮',
113
+ formActionsShowSubmit: '显示提交按钮',
114
+ formActionsShowReset: '显示重置按钮',
115
+ formActionsShowCancel: '显示取消按钮',
116
+ formActionsSubmitText: '提交文案',
117
+ formActionsResetText: '重置文案',
118
+ formActionsCancelText: '取消文案',
119
+ formActionsSubmitTextHint: '默认「提交」',
120
+ formActionsResetTextHint: '默认「重置」',
121
+ formActionsCancelTextHint: '默认「取消」',
122
+ formActionsAlign: '按钮位置',
123
+ formActionsAlignCenter: '居中',
124
+ formActionsAlignStart: '靠左',
125
+ formActionsAlignEnd: '靠右',
126
+ formActionsGap: '按钮间距',
127
+ formActionsGapHint: '默认 16',
128
+ formActionsLayoutSection: '布局',
129
+ fieldBasicSection: '基本设置',
130
+ optionLabelPlaceholder: '显示文字',
131
+ optionValuePlaceholder: '对应值',
132
+ optionDescPlaceholder: '补充说明(可选)',
133
+ addOption: '添加一个选项',
134
+ builtinDataHint: '该类型自带数据,无需手动配置选项',
135
+ optionsEditorHint: '至少填写显示文字和对应值',
136
+ optionsTreeEditorHint: '点「添加子级」可挂下级选项;左侧竖线表示层级',
137
+ addChildOption: '添加子级',
138
+ fieldColumns: '表格有哪些列',
139
+ columnTitlePlaceholder: '列标题,例如:姓名',
140
+ columnNamePlaceholder: '已自动生成,可修改',
141
+ columnWidthPlaceholder: '列宽(可选)',
142
+ addColumn: '添加一列',
143
+ columnsEditorHint: '列标题用于表头展示;数据名已自动生成,需要时可改',
144
+ fieldTableRows: '表格数据',
145
+ tableRowsNeedColumnsHint: '请先在上方填写列的数据名,再来配置每一行数据',
146
+ tableRowTitle: '第 {index} 行',
147
+ tableRowLabelPlaceholder: '选中后显示的文字',
148
+ addTableRow: '添加一行数据',
149
+ tableRowsEditorHint: '「对应值」是选中后真正保存的内容;其余按列填写,会显示在表格里',
150
+ superSelectPropsSection: '选择设置',
151
+ superSelectSingle: '只能选一项',
152
+ superSelectIsPopup: '以下拉方式打开(关闭则为弹窗)',
153
+ superSelectAllowClear: '允许清空已选内容',
154
+ superSelectAllowSelectedAll: '显示全选',
155
+ superSelectOnlyLastLevel: '只能选择最后一级',
156
+ superSelectMaxLength: '最多可选数量',
157
+ superSelectMaxLengthPlaceholder: '不限制可留空',
158
+ superSelectPlaceholderHint: '例如:请选择',
159
+ superSelectSearchPlaceholder: '搜索框提示语',
160
+ superSelectSearchPlaceholderHint: '例如:搜索...',
161
+ fieldPropsSection: '填写项设置',
162
+ fieldPlaceholderHint: '例如:请输入 / 请选择',
163
+ propAllowClear: '允许清空',
164
+ propMaxLength: '最多可输入字数',
165
+ propOptionalNumber: '不限制可留空',
166
+ propRows: '默认显示行数',
167
+ propShowCount: '显示字数统计',
168
+ propMin: '最小值',
169
+ propMax: '最大值',
170
+ propStep: '每次增减幅度',
171
+ propPrecision: '小数位数',
172
+ propSelectMode: '选择方式',
173
+ propSelectModeSingle: '只能选一项',
174
+ propSelectModeMultiple: '可以选择多项',
175
+ propDateRange: '选择日期范围(开始~结束)',
176
+ propDatePickerType: '日期类型',
177
+ propDatePickerDate: '日期',
178
+ propDatePickerWeek: '周',
179
+ propDatePickerMonth: '月份',
180
+ propDatePickerQuarter: '季度',
181
+ propDatePickerYear: '年份',
182
+ propDateFormat: '显示格式',
183
+ propShowTime: '同时选择时间',
184
+ propSwitchOnText: '打开时显示的文字',
185
+ propSwitchOffText: '关闭时显示的文字',
186
+ propSwitchOnTextHint: '例如:开',
187
+ propSwitchOffTextHint: '例如:关',
188
+ ruleLen: '长度限制',
189
+ ruleLenRange: '长度范围',
190
+ ruleLenMin: '最少字数',
191
+ ruleLenMax: '最多字数',
192
+ ruleEditorHint: '勾选需要的填写规则,可同时选多个',
193
+ formSettingsTitle: '表单设置',
194
+ formTitlePlaceholder: '表单标题(可选)',
195
+ formSubtitlePlaceholder: '表单副标题(可选)',
196
+ formColumnPlaceholder: '每行显示列数'
197
+ };
198
+
199
+ const locale = {
200
+ addField: 'Add Field',
201
+ editField: 'Edit Field',
202
+ deleteField: 'Delete',
203
+ moveUp: 'Move Up',
204
+ moveDown: 'Move Down',
205
+ fieldListTitle: 'Field Configuration',
206
+ fieldListSubtitle: 'Manage fields and preview the form on the right',
207
+ blockListTitle: 'Form Structure',
208
+ blockListSubtitle: 'Add different content sections to build your form',
209
+ emptyFieldList: 'No fields yet. Click to add one.',
210
+ emptyBlockList: 'No content yet. Click "Add Section" to start building.',
211
+ addBlock: 'Add Section',
212
+ editBlock: 'Edit Section',
213
+ deleteBlock: 'Delete Section',
214
+ untitledBlock: 'Untitled Section',
215
+ expandBlock: 'Expand',
216
+ collapseBlock: 'Collapse',
217
+ fieldCount: '{count} fields',
218
+ stepCount: '{count} steps',
219
+ blockKind_formInfo: 'Basic Form',
220
+ blockKind_list: 'Repeatable List',
221
+ blockKind_tableList: 'Table List',
222
+ blockKind_multiField: 'Multi-Value',
223
+ blockKind_steps: 'Step-by-Step',
224
+ blockTitle: 'Section Title',
225
+ blockTitlePlaceholder: 'e.g. Basic Info',
226
+ blockSubtitle: 'Section Subtitle',
227
+ blockSubtitlePlaceholder: 'e.g. Please fill in employee info',
228
+ blockName: 'Data Key',
229
+ blockNameRequired: 'Data key is required',
230
+ blockGap: 'Spacing',
231
+ blockBordered: 'Show Border',
232
+ blockImportant: 'Highlight',
233
+ blockAddText: 'Add Button Label',
234
+ blockAddTextPlaceholder: 'e.g. Add Work Experience',
235
+ blockMaxLength: 'Max Entries',
236
+ blockMinLength: 'Min Entries',
237
+ blockAutoStep: 'Auto proceed to next step after completion',
238
+ multiFieldType: 'Field Type',
239
+ multiFieldSummary: 'Field type: {type}',
240
+ multiFieldEditorHint: 'This section auto-generates repeatable inputs based on the field type you choose.',
241
+ stepListTitle: 'Steps',
242
+ addStep: 'Add Step',
243
+ editStep: 'Edit Step',
244
+ deleteStep: 'Delete Step',
245
+ stepTitle: 'Step Title',
246
+ stepTitlePlaceholder: 'Defaults to Step x',
247
+ emptyStepList: 'No steps yet. Click "Add Step" to start.',
248
+ untitledStep: 'Step {index}',
249
+ stepPrev: 'Previous',
250
+ stepNext: 'Next',
251
+ stepComplete: 'Done',
252
+ fieldType: 'Field Type',
253
+ fieldName: 'Data Key',
254
+ fieldNamePlaceholder: 'Auto-generated, editable',
255
+ fieldLabel: 'Display Name',
256
+ fieldLabelPlaceholder: 'e.g. Full Name',
257
+ fieldTips: 'Label Tips',
258
+ fieldTipsPlaceholder: 'Shown when hovering the icon next to the label',
259
+ fieldDescription: 'Description',
260
+ fieldDescriptionPlaceholder: 'Helper text shown below the input',
261
+ fieldRule: 'Validation',
262
+ fieldPlaceholder: 'Hint Text',
263
+ fieldOptions: 'Options',
264
+ fieldBlock: 'Full Width',
265
+ fieldHidden: 'Hidden',
266
+ fieldHiddenTag: 'Hidden',
267
+ fieldBlockTag: 'Full Width',
268
+ fieldNameDuplicate: 'This data key is already in use, please choose another',
269
+ untitledField: 'Untitled Field',
270
+ previewTitle: 'Form Preview',
271
+ previewHint: 'Changes on the left are reflected here in real time',
272
+ confirm: 'OK',
273
+ cancel: 'Cancel',
274
+ submit: 'Submit',
275
+ reset: 'Reset',
276
+ formActionsSection: 'Form Actions',
277
+ formActionsShowSubmit: 'Show submit button',
278
+ formActionsShowReset: 'Show reset button',
279
+ formActionsShowCancel: 'Show cancel button',
280
+ formActionsSubmitText: 'Submit label',
281
+ formActionsResetText: 'Reset label',
282
+ formActionsCancelText: 'Cancel label',
283
+ formActionsSubmitTextHint: 'Default: Submit',
284
+ formActionsResetTextHint: 'Default: Reset',
285
+ formActionsCancelTextHint: 'Default: Cancel',
286
+ formActionsAlign: 'Button alignment',
287
+ formActionsAlignCenter: 'Center',
288
+ formActionsAlignStart: 'Left',
289
+ formActionsAlignEnd: 'Right',
290
+ formActionsGap: 'Button gap',
291
+ formActionsGapHint: 'Default: 16',
292
+ formActionsLayoutSection: 'Layout',
293
+ fieldBasicSection: 'Basic Settings',
294
+ optionLabelPlaceholder: 'Display text',
295
+ optionValuePlaceholder: 'Value',
296
+ optionDescPlaceholder: 'Description (optional)',
297
+ addOption: 'Add Option',
298
+ builtinDataHint: 'This type comes with built-in data, no manual options needed',
299
+ optionsEditorHint: 'Enter at least the display text and value',
300
+ optionsTreeEditorHint: 'Use “Add Child” for nested options; the left line shows hierarchy',
301
+ addChildOption: 'Add Child',
302
+ fieldColumns: 'Table Columns',
303
+ columnTitlePlaceholder: 'Column title, e.g. Name',
304
+ columnNamePlaceholder: 'Auto-generated, editable',
305
+ columnWidthPlaceholder: 'Width (optional)',
306
+ addColumn: 'Add Column',
307
+ columnsEditorHint: 'Title is shown in the header; data key is auto-generated and editable',
308
+ fieldTableRows: 'Table Rows',
309
+ tableRowsNeedColumnsHint: 'Fill in each column’s data key above before configuring rows',
310
+ tableRowTitle: 'Row {index}',
311
+ tableRowLabelPlaceholder: 'Text shown after selection',
312
+ addTableRow: 'Add Row',
313
+ tableRowsEditorHint: '“Value” is what gets saved; other fields appear as table columns',
314
+ superSelectPropsSection: 'Selection Settings',
315
+ superSelectSingle: 'Single select only',
316
+ superSelectIsPopup: 'Open as dropdown (off = modal)',
317
+ superSelectAllowClear: 'Allow clearing selection',
318
+ superSelectAllowSelectedAll: 'Show select all',
319
+ superSelectOnlyLastLevel: 'Only allow selecting leaf nodes',
320
+ superSelectMaxLength: 'Max selections',
321
+ superSelectMaxLengthPlaceholder: 'Leave empty for unlimited',
322
+ superSelectPlaceholderHint: 'e.g. Please select',
323
+ superSelectSearchPlaceholder: 'Search hint',
324
+ superSelectSearchPlaceholderHint: 'e.g. Search...',
325
+ fieldPropsSection: 'Field Settings',
326
+ fieldPlaceholderHint: 'e.g. Please enter / Please select',
327
+ propAllowClear: 'Allow clear',
328
+ propMaxLength: 'Max characters',
329
+ propOptionalNumber: 'Leave empty for no limit',
330
+ propRows: 'Visible rows',
331
+ propShowCount: 'Show character count',
332
+ propMin: 'Minimum',
333
+ propMax: 'Maximum',
334
+ propStep: 'Step',
335
+ propPrecision: 'Decimal places',
336
+ propSelectMode: 'Selection mode',
337
+ propSelectModeSingle: 'Single',
338
+ propSelectModeMultiple: 'Multiple',
339
+ propDateRange: 'Date range (start – end)',
340
+ propDatePickerType: 'Picker type',
341
+ propDatePickerDate: 'Date',
342
+ propDatePickerWeek: 'Week',
343
+ propDatePickerMonth: 'Month',
344
+ propDatePickerQuarter: 'Quarter',
345
+ propDatePickerYear: 'Year',
346
+ propDateFormat: 'Display format',
347
+ propShowTime: 'Include time',
348
+ propSwitchOnText: 'Text when on',
349
+ propSwitchOffText: 'Text when off',
350
+ propSwitchOnTextHint: 'e.g. On',
351
+ propSwitchOffTextHint: 'e.g. Off',
352
+ ruleLen: 'Length Limit',
353
+ ruleLenRange: 'Length Range',
354
+ ruleLenMin: 'Min',
355
+ ruleLenMax: 'Max',
356
+ ruleEditorHint: 'Check the validation rules you need; you can select multiple',
357
+ formSettingsTitle: 'Form Settings',
358
+ formTitlePlaceholder: 'Form title (optional)',
359
+ formSubtitlePlaceholder: 'Form subtitle (optional)',
360
+ formColumnPlaceholder: 'Columns per row'
361
+ };
362
+
363
+ const withLocale = createWithIntlProvider({
364
+ defaultLocale: 'zh-CN',
365
+ messages: {
366
+ 'zh-CN': locale$1,
367
+ 'en-US': locale
368
+ },
369
+ namespace: 'form-creator'
370
+ });
371
+
372
+ const createFieldId = () => `field_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
373
+
374
+ /** 生成可编辑的默认数据标识,如 field_xxxx / col_xxxx */
375
+ const createDataKey = (prefix = 'field') => `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
376
+ const isAutoDataKey = (value, prefix = 'field') => new RegExp(`^${prefix}_[a-z0-9]+_[a-z0-9]+$`, 'i').test(String(value || '').trim());
377
+ const createEmptyColumn = () => ({
378
+ title: '',
379
+ name: createDataKey('col'),
380
+ width: undefined
381
+ });
382
+ const defaultSchema = () => ({
383
+ title: '',
384
+ subtitle: '',
385
+ column: 2,
386
+ gap: 24,
387
+ blocks: [],
388
+ actions: defaultFormActions()
389
+ });
390
+
391
+ /** 表单底部提交 / 重置 / 取消按钮(写入 Schema,SchemaRenderer 识别) */
392
+ const defaultFormActions = () => ({
393
+ showSubmit: true,
394
+ showReset: true,
395
+ showCancel: false,
396
+ submitText: '',
397
+ resetText: '',
398
+ cancelText: '',
399
+ align: 'center',
400
+ gap: 16
401
+ });
402
+ const FORM_ACTIONS_ALIGN = ['center', 'start', 'end'];
403
+ const normalizeFormActions = (actions = {}) => {
404
+ const base = defaultFormActions();
405
+ if (!actions || typeof actions !== 'object') {
406
+ return base;
407
+ }
408
+ const align = FORM_ACTIONS_ALIGN.includes(actions.align) ? actions.align : base.align;
409
+ const gapValue = actions.gap != null && actions.gap !== '' ? Number(actions.gap) : base.gap;
410
+ const gap = Number.isFinite(gapValue) && gapValue >= 0 ? gapValue : base.gap;
411
+ return _extends({
412
+ showSubmit: actions.showSubmit !== false,
413
+ showReset: actions.showReset !== false,
414
+ showCancel: !!actions.showCancel,
415
+ submitText: actions.submitText != null ? String(actions.submitText) : '',
416
+ resetText: actions.resetText != null ? String(actions.resetText) : '',
417
+ cancelText: actions.cancelText != null ? String(actions.cancelText) : '',
418
+ align,
419
+ gap
420
+ }, actions.submitButtonProps && typeof actions.submitButtonProps === 'object' ? {
421
+ submitButtonProps: _extends({}, actions.submitButtonProps)
422
+ } : {}, actions.resetButtonProps && typeof actions.resetButtonProps === 'object' ? {
423
+ resetButtonProps: _extends({}, actions.resetButtonProps)
424
+ } : {}, actions.cancelButtonProps && typeof actions.cancelButtonProps === 'object' ? {
425
+ cancelButtonProps: _extends({}, actions.cancelButtonProps)
426
+ } : {});
427
+ };
428
+ const createField$1 = (overrides = {}) => _extends({
429
+ id: createFieldId(),
430
+ type: 'Input',
431
+ name: createDataKey('field'),
432
+ label: '',
433
+ tips: '',
434
+ description: '',
435
+ rule: '',
436
+ block: false,
437
+ hidden: false,
438
+ props: {}
439
+ }, overrides);
440
+ const createBlock = (kind, overrides = {}) => {
441
+ const base = {
442
+ id: createFieldId(),
443
+ kind,
444
+ title: '',
445
+ subtitle: '',
446
+ column: 2,
447
+ gap: 24,
448
+ bordered: false,
449
+ important: false,
450
+ name: ['list', 'tableList', 'multiField'].includes(kind) ? createDataKey('block') : '',
451
+ label: '',
452
+ addText: '',
453
+ maxLength: undefined,
454
+ minLength: undefined,
455
+ fieldType: 'Input',
456
+ autoStep: true,
457
+ list: [],
458
+ items: []
459
+ };
460
+ if (kind === 'steps') {
461
+ return _extends({}, base, {
462
+ list: undefined,
463
+ items: [createStep()]
464
+ }, overrides);
465
+ }
466
+ if (kind === 'multiField') {
467
+ return _extends({}, base, {
468
+ list: undefined
469
+ }, overrides);
470
+ }
471
+ return _extends({}, base, overrides);
472
+ };
473
+ const createStep = (overrides = {}) => _extends({
474
+ id: createFieldId(),
475
+ title: '',
476
+ column: 2,
477
+ list: []
478
+ }, overrides);
479
+ const normalizeField = field => _extends({}, createField$1(), field, {
480
+ props: _extends({}, field.props || {})
481
+ });
482
+ const normalizeStep = step => _extends({}, createStep(), step, {
483
+ list: Array.isArray(step.list) ? step.list.map(normalizeField) : []
484
+ });
485
+ const normalizeBlock = block => {
486
+ const kind = block.kind || 'formInfo';
487
+ const normalized = _extends({}, createBlock(kind), block);
488
+ if (kind === 'steps') {
489
+ normalized.items = Array.isArray(block.items) ? block.items.map(normalizeStep) : [createStep()];
490
+ delete normalized.list;
491
+ return normalized;
492
+ }
493
+ if (kind === 'multiField') {
494
+ normalized.list = undefined;
495
+ normalized.items = undefined;
496
+ return normalized;
497
+ }
498
+ normalized.list = Array.isArray(block.list) ? block.list.map(normalizeField) : [];
499
+ normalized.items = undefined;
500
+ return normalized;
501
+ };
502
+ const normalizeSchema = (schema = {}) => {
503
+ const base = defaultSchema();
504
+ if (Array.isArray(schema.blocks)) {
505
+ return _extends({}, base, schema, {
506
+ actions: normalizeFormActions(schema.actions),
507
+ blocks: schema.blocks.map(normalizeBlock)
508
+ });
509
+ }
510
+ if (Array.isArray(schema.list) && schema.list.length) {
511
+ return _extends({}, base, schema, {
512
+ actions: normalizeFormActions(schema.actions),
513
+ blocks: [normalizeBlock({
514
+ kind: 'formInfo',
515
+ title: schema.title,
516
+ subtitle: schema.subtitle,
517
+ column: schema.column,
518
+ gap: schema.gap,
519
+ list: schema.list
520
+ })]
521
+ });
522
+ }
523
+ return _extends({}, base, schema, {
524
+ actions: normalizeFormActions(schema.actions),
525
+ blocks: []
526
+ });
527
+ };
528
+ const moveItem = (list, id, direction) => {
529
+ const index = list.findIndex(item => item.id === id);
530
+ if (index < 0) {
531
+ return list;
532
+ }
533
+ const targetIndex = direction === 'up' ? index - 1 : index + 1;
534
+ if (targetIndex < 0 || targetIndex >= list.length) {
535
+ return list;
536
+ }
537
+ const next = [...list];
538
+ const [item] = next.splice(index, 1);
539
+ next.splice(targetIndex, 0, item);
540
+ return next;
541
+ };
542
+ const isFieldNameUnique = (fields, name, excludeId) => {
543
+ if (!name) {
544
+ return false;
545
+ }
546
+ return !fields.some(item => item.name === name && item.id !== excludeId);
547
+ };
548
+ const collectSchemaFields = (schema, {
549
+ blockId,
550
+ stepId
551
+ } = {}) => {
552
+ const blocks = schema.blocks || [];
553
+ const fields = [];
554
+ blocks.forEach(block => {
555
+ if (blockId && block.id !== blockId) {
556
+ return;
557
+ }
558
+ if (block.kind === 'steps') {
559
+ (block.items || []).forEach(step => {
560
+ if (stepId !== undefined && step.id !== stepId) {
561
+ return;
562
+ }
563
+ fields.push(...(step.list || []));
564
+ });
565
+ return;
566
+ }
567
+ if (block.kind !== 'multiField') {
568
+ fields.push(...(block.list || []));
569
+ }
570
+ });
571
+ return fields;
572
+ };
573
+ const updateBlocks = (schema, updater) => _extends({}, schema, {
574
+ blocks: updater(schema.blocks || [])
575
+ });
576
+ const findBlock = (schema, blockId) => (schema.blocks || []).find(block => block.id === blockId);
577
+ const mapBlocks = (schema, blockId, updater) => updateBlocks(schema, blocks => blocks.map(block => {
578
+ if (block.id !== blockId) {
579
+ return block;
580
+ }
581
+ return updater(block);
582
+ }));
583
+ const hasRenderableContent = schema => {
584
+ const blocks = schema.blocks || [];
585
+ return blocks.some(block => {
586
+ if (block.kind === 'steps') {
587
+ return (block.items || []).some(step => (step.list || []).length > 0);
588
+ }
589
+ if (block.kind === 'multiField') {
590
+ return !!block.name;
591
+ }
592
+ return (block.list || []).length > 0 || block.title;
593
+ });
594
+ };
595
+
596
+ const BLOCK_KINDS = {
597
+ formInfo: {
598
+ label: '基础表单',
599
+ color: 'blue',
600
+ hasFieldList: true,
601
+ description: '最常用的表单模块,可设置标题、列数和间距'
602
+ },
603
+ list: {
604
+ label: '可增减列表',
605
+ color: 'cyan',
606
+ hasFieldList: true,
607
+ requiresName: true,
608
+ description: '用户可以动态添加或删除多条记录,例如工作经历'
609
+ },
610
+ tableList: {
611
+ label: '表格列表',
612
+ color: 'geekblue',
613
+ hasFieldList: true,
614
+ requiresName: true,
615
+ description: '以表格形式展示的可增减列表'
616
+ },
617
+ multiField: {
618
+ label: '同类多值',
619
+ color: 'purple',
620
+ requiresName: true,
621
+ description: '同一种填写项可以输入多个值,例如多个手机号'
622
+ },
623
+ steps: {
624
+ label: '分步表单',
625
+ color: 'gold',
626
+ hasSteps: true,
627
+ description: '将表单拆分成多个步骤,引导用户逐步填写'
628
+ }
629
+ };
630
+ const getBlockKindOptions = () => Object.entries(BLOCK_KINDS).map(([value, config]) => ({
631
+ label: config.label,
632
+ value
633
+ }));
634
+ const getBlockDefinition = kind => BLOCK_KINDS[kind];
635
+ const blockToFormValues = block => {
636
+ var _block$column, _block$gap, _block$maxLength, _block$minLength;
637
+ return {
638
+ kind: block.kind,
639
+ title: block.title || '',
640
+ subtitle: block.subtitle || '',
641
+ column: (_block$column = block.column) != null ? _block$column : 2,
642
+ gap: (_block$gap = block.gap) != null ? _block$gap : 24,
643
+ bordered: !!block.bordered,
644
+ important: !!block.important,
645
+ name: block.name || '',
646
+ label: block.label || '',
647
+ addText: block.addText || '',
648
+ maxLength: (_block$maxLength = block.maxLength) != null ? _block$maxLength : null,
649
+ minLength: (_block$minLength = block.minLength) != null ? _block$minLength : null,
650
+ fieldType: block.fieldType || 'Input',
651
+ autoStep: block.autoStep !== false
652
+ };
653
+ };
654
+ const formValuesToBlock = (values, existingBlock = {}) => {
655
+ var _values$column, _values$gap, _values$maxLength, _values$minLength;
656
+ return _extends({}, existingBlock, {
657
+ kind: values.kind || existingBlock.kind,
658
+ title: values.title,
659
+ subtitle: values.subtitle,
660
+ column: (_values$column = values.column) != null ? _values$column : 2,
661
+ gap: (_values$gap = values.gap) != null ? _values$gap : 24,
662
+ bordered: !!values.bordered,
663
+ important: !!values.important,
664
+ name: values.name,
665
+ label: values.label,
666
+ addText: values.addText || undefined,
667
+ maxLength: (_values$maxLength = values.maxLength) != null ? _values$maxLength : undefined,
668
+ minLength: (_values$minLength = values.minLength) != null ? _values$minLength : undefined,
669
+ fieldType: values.fieldType || 'Input',
670
+ autoStep: values.autoStep !== false
671
+ });
672
+ };
673
+ const stepToFormValues = step => {
674
+ var _step$column;
675
+ return {
676
+ title: step.title || '',
677
+ column: (_step$column = step.column) != null ? _step$column : 2
678
+ };
679
+ };
680
+ const formValuesToStep = (values, existingStep = {}) => {
681
+ var _values$column2;
682
+ return _extends({}, existingStep, {
683
+ title: values.title,
684
+ column: (_values$column2 = values.column) != null ? _values$column2 : 2
685
+ });
686
+ };
687
+
688
+ const _excluded$3 = ["children"];
689
+ const mapOptionItem = item => {
690
+ if (!item || typeof item !== 'object') {
691
+ return item;
692
+ }
693
+ const {
694
+ children
695
+ } = item,
696
+ rest = _objectWithoutPropertiesLoose(item, _excluded$3);
697
+ const next = _extends({}, rest);
698
+ if (Array.isArray(children) && children.length) {
699
+ next.children = children.map(mapOptionItem);
700
+ }
701
+ return next;
702
+ };
703
+ const createApiFromOptions = (options = []) => ({
704
+ loader: () => ({
705
+ pageData: options.map(mapOptionItem)
706
+ })
707
+ });
708
+
709
+ const _excluded$2 = ["options", "api", "placeholder"];
710
+ const {
711
+ useOnChange: useOnChange$1
712
+ } = hooks;
713
+ const hasNestedOptions = options => Array.isArray(options) && options.some(item => Array.isArray(item == null ? void 0 : item.children) && item.children.length);
714
+ const createField = (Component, {
715
+ preferOptions: _preferOptions = false,
716
+ placeholderPrefix: _placeholderPrefix = '请选择'
717
+ } = {}) => {
718
+ const Field = props => {
719
+ const {
720
+ options,
721
+ api,
722
+ placeholder
723
+ } = props,
724
+ rest = _objectWithoutPropertiesLoose(props, _excluded$2);
725
+ const useOptionsDirectly = _preferOptions || hasNestedOptions(options);
726
+ const mergedApi = api || (!useOptionsDirectly && Array.isArray(options) && options.length ? createApiFromOptions(options) : undefined);
727
+ const resolvedPlaceholder = placeholder != null && String(placeholder).trim() ? placeholder : `${_placeholderPrefix}${props.label || ''}`;
728
+ const render = useOnChange$1(Object.assign({}, {
729
+ isPopup: true,
730
+ placeholder: resolvedPlaceholder
731
+ }, rest, useOptionsDirectly && Array.isArray(options) ? {
732
+ options
733
+ } : {}, mergedApi ? {
734
+ api: mergedApi
735
+ } : {}));
736
+ return render(Component);
737
+ };
738
+ Field.field = Component;
739
+ return Field;
740
+ };
741
+ const SuperSelectList = createField(SelectList);
742
+ const SuperSelectTableList = createField(SelectTableList, {
743
+ preferOptions: true
744
+ });
745
+ const SuperSelectTree = createField(SelectTree, {
746
+ preferOptions: true
747
+ });
748
+ const SuperSelectCascader = createField(SelectCascader, {
749
+ preferOptions: true
750
+ });
751
+ const SelectFunctionField = createField(SelectFunction);
752
+ const SelectIndustryField = createField(SelectIndustry);
753
+ const SelectAddressField = createField(SelectAddress);
754
+
755
+ const RULE_PRESET_ITEMS = [{
756
+ value: 'REQ',
757
+ label: '必填'
758
+ }, {
759
+ value: 'TEL',
760
+ label: '手机号格式'
761
+ }, {
762
+ value: 'EMAIL',
763
+ label: '邮箱格式'
764
+ }];
765
+ const DEFAULT_RULE_CONFIG = () => ({
766
+ presets: [],
767
+ lenMin: '',
768
+ lenMax: ''
769
+ });
770
+ const RULE_LEN_PRESET = 'LEN';
771
+
772
+ /** 注册填写项校验规则 preset,会在规则勾选面板中展示 */
773
+ const registerRulePreset = item => {
774
+ if (!(item != null && item.value)) {
775
+ return;
776
+ }
777
+ const index = RULE_PRESET_ITEMS.findIndex(rule => rule.value === item.value);
778
+ const next = {
779
+ value: item.value,
780
+ label: item.label || item.value
781
+ };
782
+ if (index >= 0) {
783
+ RULE_PRESET_ITEMS[index] = next;
784
+ } else {
785
+ RULE_PRESET_ITEMS.push(next);
786
+ }
787
+ };
788
+ const getRulePresetItems = () => RULE_PRESET_ITEMS.slice();
789
+ const parseRuleString = rule => {
790
+ const config = DEFAULT_RULE_CONFIG();
791
+ if (!rule) {
792
+ return config;
793
+ }
794
+ const tokens = String(rule).trim().split(/\s+/).filter(Boolean);
795
+ tokens.forEach(token => {
796
+ if (RULE_PRESET_ITEMS.some(item => item.value === token)) {
797
+ config.presets.push(token);
798
+ return;
799
+ }
800
+ const lenMatch = token.match(/^LEN-(\d+)-(\d+)$/);
801
+ if (lenMatch) {
802
+ config.lenMin = lenMatch[1];
803
+ config.lenMax = lenMatch[2];
804
+ config.presets.push('LEN');
805
+ }
806
+ });
807
+ return config;
808
+ };
809
+ const buildRuleString = ({
810
+ presets: _presets = [],
811
+ lenMin,
812
+ lenMax
813
+ } = {}) => {
814
+ const parts = [];
815
+ RULE_PRESET_ITEMS.forEach(item => {
816
+ if (_presets.includes(item.value)) {
817
+ parts.push(item.value);
818
+ }
819
+ });
820
+ if (_presets.includes('LEN') && lenMin !== '' && lenMax !== '') {
821
+ parts.push(`LEN-${lenMin}-${lenMax}`);
822
+ }
823
+ return parts.join(' ') || undefined;
824
+ };
825
+
826
+ const registry = new Map();
827
+ const defineField = (type, definition) => {
828
+ registry.set(type, _extends({
829
+ type
830
+ }, definition));
831
+ };
832
+ const FIELD_GROUPS = [{
833
+ label: '基础字段',
834
+ types: ['Input', 'TextArea', 'InputNumber', 'Switch', 'Checkbox', 'DatePicker']
835
+ }, {
836
+ label: '选择字段',
837
+ types: ['Select', 'RadioGroup', 'CheckboxGroup']
838
+ }, {
839
+ label: '高级选择',
840
+ types: ['SuperSelectList', 'SuperSelectTableList', 'SuperSelectTree', 'SuperSelectCascader']
841
+ }, {
842
+ label: '业务选择',
843
+ types: ['SelectFunction', 'SelectIndustry', 'SelectAddress']
844
+ }];
845
+ defineField('Input', {
846
+ label: '单行文本',
847
+ group: '基础字段',
848
+ component: Input,
849
+ defaultProps: {
850
+ allowClear: true
851
+ },
852
+ hasFieldProps: true
853
+ });
854
+ defineField('TextArea', {
855
+ label: '多行文本',
856
+ group: '基础字段',
857
+ component: TextArea,
858
+ defaultProps: {
859
+ rows: 3
860
+ },
861
+ defaults: {
862
+ block: true
863
+ },
864
+ hasFieldProps: true
865
+ });
866
+ defineField('InputNumber', {
867
+ label: '数字',
868
+ group: '基础字段',
869
+ component: InputNumber,
870
+ defaultProps: {},
871
+ hasFieldProps: true
872
+ });
873
+ defineField('Select', {
874
+ label: '下拉选择',
875
+ group: '选择字段',
876
+ component: Select,
877
+ defaultProps: {
878
+ options: [],
879
+ allowClear: true
880
+ },
881
+ hasOptions: true,
882
+ hasFieldProps: true
883
+ });
884
+ defineField('RadioGroup', {
885
+ label: '单选组',
886
+ group: '选择字段',
887
+ component: RadioGroup,
888
+ defaultProps: {
889
+ options: []
890
+ },
891
+ hasOptions: true
892
+ });
893
+ defineField('CheckboxGroup', {
894
+ label: '复选组',
895
+ group: '选择字段',
896
+ component: CheckboxGroup,
897
+ defaultProps: {
898
+ options: []
899
+ },
900
+ hasOptions: true
901
+ });
902
+ defineField('SuperSelectList', {
903
+ label: '普通下拉',
904
+ group: 'SuperSelect',
905
+ component: SuperSelectList,
906
+ defaultProps: {
907
+ options: [],
908
+ isPopup: true,
909
+ allowClear: true,
910
+ labelKey: 'label',
911
+ valueKey: 'value'
912
+ },
913
+ isSuperSelect: true,
914
+ hasOptions: true,
915
+ optionsAllowDescription: true
916
+ });
917
+ defineField('SuperSelectTableList', {
918
+ label: '表格选择',
919
+ group: 'SuperSelect',
920
+ component: SuperSelectTableList,
921
+ defaultProps: {
922
+ options: [],
923
+ columns: [],
924
+ isPopup: true,
925
+ allowClear: true,
926
+ labelKey: 'label',
927
+ valueKey: 'value'
928
+ },
929
+ isSuperSelect: true,
930
+ hasOptions: true,
931
+ hasColumns: true,
932
+ optionsAllowDescription: true
933
+ });
934
+ defineField('SuperSelectTree', {
935
+ label: '树形选择',
936
+ group: 'SuperSelect',
937
+ component: SuperSelectTree,
938
+ defaultProps: {
939
+ options: [],
940
+ isPopup: true,
941
+ allowClear: true,
942
+ labelKey: 'label',
943
+ valueKey: 'value'
944
+ },
945
+ isSuperSelect: true,
946
+ hasOptions: true,
947
+ optionsAllowChildren: true,
948
+ optionsAllowDescription: true
949
+ });
950
+ defineField('SuperSelectCascader', {
951
+ label: '级联选择',
952
+ group: 'SuperSelect',
953
+ component: SuperSelectCascader,
954
+ defaultProps: {
955
+ options: [],
956
+ isPopup: true,
957
+ allowClear: true,
958
+ labelKey: 'label',
959
+ valueKey: 'value',
960
+ onlyAllowLastLevel: false
961
+ },
962
+ isSuperSelect: true,
963
+ hasOptions: true,
964
+ hasOnlyLastLevel: true,
965
+ optionsAllowChildren: true,
966
+ optionsAllowDescription: true
967
+ });
968
+ defineField('SelectFunction', {
969
+ label: '职能选择',
970
+ group: 'SuperSelectPlus',
971
+ component: SelectFunctionField,
972
+ defaultProps: {
973
+ isPopup: true,
974
+ allowClear: true
975
+ },
976
+ isSuperSelect: true,
977
+ hasBuiltinData: true
978
+ });
979
+ defineField('SelectIndustry', {
980
+ label: '行业选择',
981
+ group: 'SuperSelectPlus',
982
+ component: SelectIndustryField,
983
+ defaultProps: {
984
+ isPopup: true,
985
+ allowClear: true
986
+ },
987
+ isSuperSelect: true,
988
+ hasBuiltinData: true
989
+ });
990
+ defineField('SelectAddress', {
991
+ label: '地址选择',
992
+ group: 'SuperSelectPlus',
993
+ component: SelectAddressField,
994
+ defaultProps: {
995
+ isPopup: true,
996
+ allowClear: true
997
+ },
998
+ isSuperSelect: true,
999
+ hasBuiltinData: true
1000
+ });
1001
+ defineField('Switch', {
1002
+ label: '开关',
1003
+ group: '基础字段',
1004
+ component: Switch,
1005
+ defaultProps: {},
1006
+ hasFieldProps: true
1007
+ });
1008
+ defineField('Checkbox', {
1009
+ label: '复选框',
1010
+ group: '基础字段',
1011
+ component: Checkbox,
1012
+ defaultProps: {
1013
+ children: ''
1014
+ }
1015
+ });
1016
+ defineField('DatePicker', {
1017
+ label: '日期',
1018
+ group: '基础字段',
1019
+ component: DatePicker,
1020
+ defaultProps: {
1021
+ format: 'YYYY-MM-DD',
1022
+ picker: 'date',
1023
+ allowClear: true,
1024
+ range: false,
1025
+ showTime: false
1026
+ },
1027
+ hasFieldProps: true,
1028
+ resolveComponent: props => props != null && props.range ? DatePicker.RangePicker || DatePicker : DatePicker
1029
+ });
1030
+
1031
+ /**
1032
+ * 扩展字段额外参数声明(propsSchema 项):
1033
+ * - name: props 键名
1034
+ * - label: 编辑器展示名
1035
+ * - type: 'string' | 'number' | 'boolean' | 'select'
1036
+ * - placeholder?: string
1037
+ * - defaultValue?: any
1038
+ * - min / max?: number(type=number)
1039
+ * - options?: { label, value }[](type=select)
1040
+ *
1041
+ * registerField(type, definition) 还可传:
1042
+ * - groupName?: string 自定义类型下拉分组名;不传则归入「扩展字段」
1043
+ */
1044
+ const registerField = (type, definition) => {
1045
+ var _definition$hasFieldP;
1046
+ const propsSchema = Array.isArray(definition == null ? void 0 : definition.propsSchema) ? definition.propsSchema : undefined;
1047
+ const groupName = (definition == null ? void 0 : definition.groupName) != null && String(definition.groupName).trim() ? String(definition.groupName).trim() : undefined;
1048
+ defineField(type, _extends({}, definition, {
1049
+ propsSchema,
1050
+ groupName,
1051
+ hasFieldProps: (_definition$hasFieldP = definition.hasFieldProps) != null ? _definition$hasFieldP : !!(propsSchema && propsSchema.length)
1052
+ }));
1053
+ };
1054
+ const pickFromPropsSchema = (props = {}, propsSchema = [], defaultProps = {}) => {
1055
+ const next = {};
1056
+ propsSchema.forEach(item => {
1057
+ if (!(item != null && item.name)) {
1058
+ return;
1059
+ }
1060
+ const key = item.name;
1061
+ const fallback = item.defaultValue !== undefined ? item.defaultValue : defaultProps[key];
1062
+ if (item.type === 'boolean') {
1063
+ next[key] = props[key] !== undefined ? !!props[key] : !!fallback;
1064
+ return;
1065
+ }
1066
+ if (item.type === 'number') {
1067
+ next[key] = props[key] != null && props[key] !== '' ? props[key] : fallback != null ? fallback : null;
1068
+ return;
1069
+ }
1070
+ if (item.type === 'select') {
1071
+ next[key] = props[key] !== undefined ? props[key] : fallback;
1072
+ return;
1073
+ }
1074
+ next[key] = props[key] != null ? props[key] : fallback != null ? fallback : '';
1075
+ });
1076
+ return next;
1077
+ };
1078
+ const applyFromPropsSchema = (props, values = {}, propsSchema = []) => {
1079
+ propsSchema.forEach(item => {
1080
+ if (!(item != null && item.name)) {
1081
+ return;
1082
+ }
1083
+ const key = item.name;
1084
+ const value = values[key];
1085
+ if (item.type === 'boolean') {
1086
+ props[key] = !!value;
1087
+ return;
1088
+ }
1089
+ if (item.type === 'number') {
1090
+ setOptionalNumber(props, key, value);
1091
+ return;
1092
+ }
1093
+ if (item.type === 'select') {
1094
+ if (value !== undefined && value !== null && value !== '') {
1095
+ props[key] = value;
1096
+ } else if (item.defaultValue !== undefined) {
1097
+ props[key] = item.defaultValue;
1098
+ } else {
1099
+ delete props[key];
1100
+ }
1101
+ return;
1102
+ }
1103
+ setOptionalString(props, key, value);
1104
+ });
1105
+ };
1106
+ const getFieldDefinition = type => registry.get(type);
1107
+ const getFieldComponent = (type, field) => {
1108
+ const definition = registry.get(type);
1109
+ if (!definition) {
1110
+ return undefined;
1111
+ }
1112
+ if (typeof definition.resolveComponent === 'function') {
1113
+ return definition.resolveComponent((field == null ? void 0 : field.props) || {});
1114
+ }
1115
+ return definition.component;
1116
+ };
1117
+ const getFieldTypes = () => {
1118
+ const grouped = FIELD_GROUPS.map(group => ({
1119
+ label: group.label,
1120
+ options: group.types.map(type => registry.get(type)).filter(Boolean).map(({
1121
+ type,
1122
+ label
1123
+ }) => ({
1124
+ label,
1125
+ value: type
1126
+ }))
1127
+ }));
1128
+ const builtinTypes = new Set(FIELD_GROUPS.flatMap(group => group.types));
1129
+ const registered = Array.from(registry.values()).filter(item => !builtinTypes.has(item.type));
1130
+ const customGroups = new Map();
1131
+ const fallback = [];
1132
+ registered.forEach(item => {
1133
+ const option = {
1134
+ label: item.label,
1135
+ value: item.type
1136
+ };
1137
+ const groupName = item.groupName != null && String(item.groupName).trim() ? String(item.groupName).trim() : '';
1138
+ if (!groupName) {
1139
+ fallback.push(option);
1140
+ return;
1141
+ }
1142
+ if (!customGroups.has(groupName)) {
1143
+ customGroups.set(groupName, []);
1144
+ }
1145
+ customGroups.get(groupName).push(option);
1146
+ });
1147
+ customGroups.forEach((options, label) => {
1148
+ grouped.push({
1149
+ label,
1150
+ options
1151
+ });
1152
+ });
1153
+ if (fallback.length) {
1154
+ grouped.push({
1155
+ label: '扩展字段',
1156
+ options: fallback
1157
+ });
1158
+ }
1159
+ return grouped;
1160
+ };
1161
+ const normalizeOptions = (options, {
1162
+ allowChildren: _allowChildren = false,
1163
+ columns: _columns = []
1164
+ } = {}) => {
1165
+ if (!Array.isArray(options)) {
1166
+ return [];
1167
+ }
1168
+ const columnNames = (_columns || []).map(item => item == null ? void 0 : item.name).filter(Boolean);
1169
+ return options.map(item => {
1170
+ var _item$label, _item$value, _item$description;
1171
+ const next = {
1172
+ label: (_item$label = item == null ? void 0 : item.label) != null ? _item$label : '',
1173
+ value: (_item$value = item == null ? void 0 : item.value) != null ? _item$value : '',
1174
+ description: (_item$description = item == null ? void 0 : item.description) != null ? _item$description : ''
1175
+ };
1176
+ columnNames.forEach(name => {
1177
+ var _item$name;
1178
+ next[name] = (_item$name = item == null ? void 0 : item[name]) != null ? _item$name : '';
1179
+ });
1180
+ if (!String(next.label).trim() && columnNames[0] && String(next[columnNames[0]] || '').trim()) {
1181
+ next.label = String(next[columnNames[0]]);
1182
+ }
1183
+ if (!String(next.value).trim() && String(next.label).trim()) {
1184
+ next.value = next.label;
1185
+ }
1186
+ if (_allowChildren && Array.isArray(item == null ? void 0 : item.children) && item.children.length) {
1187
+ next.children = normalizeOptions(item.children, {
1188
+ allowChildren: true,
1189
+ columns: _columns
1190
+ });
1191
+ }
1192
+ return next;
1193
+ }).filter(item => {
1194
+ if (item.label || item.value || item.children && item.children.length) {
1195
+ return true;
1196
+ }
1197
+ return columnNames.some(name => String(item[name] || '').trim());
1198
+ });
1199
+ };
1200
+ const normalizeColumns = columns => {
1201
+ if (!Array.isArray(columns)) {
1202
+ return [];
1203
+ }
1204
+ return columns.map((item, index) => {
1205
+ var _item$title;
1206
+ const title = (_item$title = item == null ? void 0 : item.title) != null ? _item$title : '';
1207
+ const name = String((item == null ? void 0 : item.name) || (item == null ? void 0 : item.dataIndex) || (item == null ? void 0 : item.key) || '').trim() || `col_${index + 1}`;
1208
+ const next = {
1209
+ title,
1210
+ name,
1211
+ key: name
1212
+ };
1213
+ if ((item == null ? void 0 : item.width) != null && item.width !== '') {
1214
+ next.width = Number(item.width);
1215
+ }
1216
+ return next;
1217
+ }).filter(item => String(item.title || '').trim() || String(item.name || '').trim());
1218
+ };
1219
+ const pickSuperSelectFormValues = (field, definition) => {
1220
+ const props = field.props || {};
1221
+ const columns = normalizeColumns(props.columns);
1222
+ return {
1223
+ single: !!props.single,
1224
+ isPopup: props.isPopup !== false,
1225
+ allowClear: props.allowClear !== false,
1226
+ allowSelectedAll: !!props.allowSelectedAll,
1227
+ onlyAllowLastLevel: !!props.onlyAllowLastLevel,
1228
+ maxLength: props.maxLength,
1229
+ placeholder: props.placeholder || '',
1230
+ searchPlaceholder: props.searchPlaceholder || '',
1231
+ columns: columns.length ? columns : [createEmptyColumn()]
1232
+ };
1233
+ };
1234
+ const applySuperSelectProps = (props, values, definition) => {
1235
+ props.single = !!values.single;
1236
+ props.isPopup = values.isPopup !== false;
1237
+ props.allowClear = values.allowClear !== false;
1238
+ props.allowSelectedAll = !values.single && !!values.allowSelectedAll;
1239
+ if (!values.single && values.maxLength != null && values.maxLength !== '') {
1240
+ props.maxLength = Number(values.maxLength);
1241
+ } else {
1242
+ delete props.maxLength;
1243
+ }
1244
+ if (values.placeholder) {
1245
+ props.placeholder = values.placeholder;
1246
+ } else {
1247
+ delete props.placeholder;
1248
+ }
1249
+ if (values.searchPlaceholder) {
1250
+ props.searchPlaceholder = values.searchPlaceholder;
1251
+ } else {
1252
+ delete props.searchPlaceholder;
1253
+ }
1254
+
1255
+ // labelKey / valueKey 固定用类型默认值,不开放给用户编辑
1256
+ if (!definition.hasBuiltinData) {
1257
+ var _definition$defaultPr, _definition$defaultPr2;
1258
+ props.labelKey = ((_definition$defaultPr = definition.defaultProps) == null ? void 0 : _definition$defaultPr.labelKey) || 'label';
1259
+ props.valueKey = ((_definition$defaultPr2 = definition.defaultProps) == null ? void 0 : _definition$defaultPr2.valueKey) || 'value';
1260
+ }
1261
+ if (definition.hasOnlyLastLevel) {
1262
+ props.onlyAllowLastLevel = !!values.onlyAllowLastLevel;
1263
+ } else {
1264
+ delete props.onlyAllowLastLevel;
1265
+ }
1266
+ if (definition.hasColumns) {
1267
+ props.columns = normalizeColumns(values.columns);
1268
+ } else {
1269
+ delete props.columns;
1270
+ }
1271
+ };
1272
+ const setOptionalNumber = (props, key, value) => {
1273
+ if (value != null && value !== '') {
1274
+ props[key] = Number(value);
1275
+ } else {
1276
+ delete props[key];
1277
+ }
1278
+ };
1279
+ const setOptionalString = (props, key, value) => {
1280
+ if (value != null && String(value).trim()) {
1281
+ props[key] = value;
1282
+ } else {
1283
+ delete props[key];
1284
+ }
1285
+ };
1286
+ const pickFieldProps = (field, definition) => {
1287
+ var _props$rows, _definition$propsSche;
1288
+ const props = field.props || {};
1289
+ const type = (definition == null ? void 0 : definition.type) || field.type;
1290
+ switch (type) {
1291
+ case 'Input':
1292
+ return {
1293
+ placeholder: props.placeholder || '',
1294
+ allowClear: props.allowClear !== false,
1295
+ maxLength: props.maxLength
1296
+ };
1297
+ case 'TextArea':
1298
+ return {
1299
+ placeholder: props.placeholder || '',
1300
+ rows: (_props$rows = props.rows) != null ? _props$rows : 3,
1301
+ maxLength: props.maxLength,
1302
+ showCount: !!props.showCount
1303
+ };
1304
+ case 'InputNumber':
1305
+ return {
1306
+ placeholder: props.placeholder || '',
1307
+ min: props.min,
1308
+ max: props.max,
1309
+ step: props.step,
1310
+ precision: props.precision
1311
+ };
1312
+ case 'Select':
1313
+ return {
1314
+ placeholder: props.placeholder || '',
1315
+ allowClear: props.allowClear !== false,
1316
+ mode: props.mode === 'multiple' || props.mode === 'tags' ? 'multiple' : 'single'
1317
+ };
1318
+ case 'DatePicker':
1319
+ {
1320
+ const raw = props.placeholder;
1321
+ const placeholder = Array.isArray(raw) ? raw[0] || '' : raw || '';
1322
+ return {
1323
+ placeholder,
1324
+ allowClear: props.allowClear !== false,
1325
+ format: props.format || 'YYYY-MM-DD',
1326
+ picker: props.picker || 'date',
1327
+ showTime: !!props.showTime,
1328
+ range: !!props.range
1329
+ };
1330
+ }
1331
+ case 'Switch':
1332
+ return {
1333
+ checkedChildren: props.checkedChildren || '',
1334
+ unCheckedChildren: props.unCheckedChildren || ''
1335
+ };
1336
+ default:
1337
+ if (definition != null && (_definition$propsSche = definition.propsSchema) != null && _definition$propsSche.length) {
1338
+ return pickFromPropsSchema(props, definition.propsSchema, definition.defaultProps || {});
1339
+ }
1340
+ return {};
1341
+ }
1342
+ };
1343
+ const applyFieldProps = (props, values, definition) => {
1344
+ var _values$rows, _definition$propsSche2;
1345
+ const type = definition.type;
1346
+ switch (type) {
1347
+ case 'Input':
1348
+ setOptionalString(props, 'placeholder', values.placeholder);
1349
+ props.allowClear = values.allowClear !== false;
1350
+ setOptionalNumber(props, 'maxLength', values.maxLength);
1351
+ break;
1352
+ case 'TextArea':
1353
+ setOptionalString(props, 'placeholder', values.placeholder);
1354
+ props.rows = (_values$rows = values.rows) != null ? _values$rows : 3;
1355
+ setOptionalNumber(props, 'maxLength', values.maxLength);
1356
+ if (values.showCount) {
1357
+ props.showCount = true;
1358
+ } else {
1359
+ delete props.showCount;
1360
+ }
1361
+ break;
1362
+ case 'InputNumber':
1363
+ setOptionalString(props, 'placeholder', values.placeholder);
1364
+ setOptionalNumber(props, 'min', values.min);
1365
+ setOptionalNumber(props, 'max', values.max);
1366
+ setOptionalNumber(props, 'step', values.step);
1367
+ setOptionalNumber(props, 'precision', values.precision);
1368
+ break;
1369
+ case 'Select':
1370
+ setOptionalString(props, 'placeholder', values.placeholder);
1371
+ props.allowClear = values.allowClear !== false;
1372
+ if (values.mode === 'multiple') {
1373
+ props.mode = 'multiple';
1374
+ } else {
1375
+ delete props.mode;
1376
+ }
1377
+ break;
1378
+ case 'DatePicker':
1379
+ {
1380
+ props.allowClear = values.allowClear !== false;
1381
+ props.picker = values.picker || 'date';
1382
+ props.format = values.format || 'YYYY-MM-DD';
1383
+ props.range = !!values.range;
1384
+ if (values.showTime && props.picker === 'date') {
1385
+ props.showTime = true;
1386
+ } else {
1387
+ delete props.showTime;
1388
+ }
1389
+ if (values.range) {
1390
+ // RangePicker 用数组 placeholder;单框用字符串
1391
+ const raw = values.placeholder;
1392
+ const text = (Array.isArray(raw) ? raw[0] : raw) || '请选择日期';
1393
+ props.placeholder = [text, text];
1394
+ } else {
1395
+ setOptionalString(props, 'placeholder', values.placeholder);
1396
+ }
1397
+ break;
1398
+ }
1399
+ case 'Switch':
1400
+ setOptionalString(props, 'checkedChildren', values.checkedChildren);
1401
+ setOptionalString(props, 'unCheckedChildren', values.unCheckedChildren);
1402
+ break;
1403
+ default:
1404
+ if (definition != null && (_definition$propsSche2 = definition.propsSchema) != null && _definition$propsSche2.length) {
1405
+ applyFromPropsSchema(props, values, definition.propsSchema);
1406
+ }
1407
+ break;
1408
+ }
1409
+ };
1410
+ const fieldToFormValues = field => {
1411
+ var _field$props, _field$props2, _field$props3;
1412
+ const definition = getFieldDefinition(field.type);
1413
+ const ruleConfig = parseRuleString(field.rule);
1414
+ const allowChildren = !!(definition != null && definition.optionsAllowChildren);
1415
+ const columns = definition != null && definition.hasColumns ? normalizeColumns((_field$props = field.props) == null ? void 0 : _field$props.columns) : [];
1416
+ const options = normalizeOptions((_field$props2 = field.props) == null ? void 0 : _field$props2.options, {
1417
+ allowChildren,
1418
+ columns
1419
+ });
1420
+ const rawPlaceholder = (_field$props3 = field.props) == null ? void 0 : _field$props3.placeholder;
1421
+ const placeholder = Array.isArray(rawPlaceholder) ? rawPlaceholder[0] || '' : rawPlaceholder || '';
1422
+ return {
1423
+ type: field.type,
1424
+ name: field.name,
1425
+ label: field.label,
1426
+ tips: field.tips || '',
1427
+ description: field.description || '',
1428
+ block: !!field.block,
1429
+ hidden: !!field.hidden,
1430
+ placeholder,
1431
+ options: options.length ? options : [{
1432
+ label: '',
1433
+ value: ''
1434
+ }],
1435
+ ruleConfig,
1436
+ hasOptions: !!(definition != null && definition.hasOptions),
1437
+ selectProps: definition != null && definition.isSuperSelect ? pickSuperSelectFormValues(field) : undefined,
1438
+ fieldProps: definition != null && definition.hasFieldProps ? pickFieldProps(field, definition) : undefined
1439
+ };
1440
+ };
1441
+ const formValuesToField = (values, existingField = {}) => {
1442
+ var _ref, _values$block, _definition$defaults;
1443
+ const definition = getFieldDefinition(values.type) || getFieldDefinition('Input');
1444
+ // 不沿用旧类型残留 props,避免切换填写项类型后参数串味
1445
+ const props = _extends({}, definition.defaultProps || {});
1446
+ if (definition.isSuperSelect) {
1447
+ applySuperSelectProps(props, values.selectProps || values, definition);
1448
+ } else if (definition.hasFieldProps) {
1449
+ applyFieldProps(props, values.fieldProps || values, definition);
1450
+ } else if (values.placeholder) {
1451
+ props.placeholder = values.placeholder;
1452
+ } else {
1453
+ delete props.placeholder;
1454
+ }
1455
+ if (definition.hasOptions) {
1456
+ props.options = normalizeOptions(values.options, {
1457
+ allowChildren: !!definition.optionsAllowChildren,
1458
+ columns: definition.hasColumns ? props.columns || [] : []
1459
+ });
1460
+ } else {
1461
+ delete props.options;
1462
+ }
1463
+ if (values.type === 'Checkbox' && values.label) {
1464
+ props.children = values.label;
1465
+ }
1466
+ const rule = buildRuleString(values.ruleConfig);
1467
+ return {
1468
+ id: existingField.id,
1469
+ type: values.type,
1470
+ name: values.name,
1471
+ label: values.label,
1472
+ tips: values.tips != null && String(values.tips).trim() ? values.tips : '',
1473
+ description: values.description != null && String(values.description).trim() ? values.description : '',
1474
+ rule,
1475
+ block: (_ref = (_values$block = values.block) != null ? _values$block : (_definition$defaults = definition.defaults) == null ? void 0 : _definition$defaults.block) != null ? _ref : false,
1476
+ hidden: !!values.hidden,
1477
+ props
1478
+ };
1479
+ };
1480
+
1481
+ var style = {"kne-responsive-boundary":"kne-form-creator_gh14z","kne-responsive-scroll":"kne-form-creator_Kfn6L","form-creator":"kne-form-creator_Xrjrk","editor-pane":"kne-form-creator_Skfuv","preview-pane":"kne-form-creator_v4Lsp","editor-header":"kne-form-creator_WaSS-","block-list-panel":"kne-form-creator_lx8An","form-actions-setting-btn":"kne-form-creator_NekU2","panel-toolbar":"kne-form-creator_t0WxZ","add-block-btn":"kne-form-creator_16Zre","add-inline-btn":"kne-form-creator_iCYdB","ant-btn-disabled":"kne-form-creator_LdGtv","block-list":"kne-form-creator_wK5eK","block-section":"kne-form-creator_15IiK","block-kind-formInfo":"kne-form-creator_D0hoK","block-kind-list":"kne-form-creator_JdPhy","block-kind-tableList":"kne-form-creator_gzd64","block-kind-multiField":"kne-form-creator_t0iOJ","block-kind-steps":"kne-form-creator_QNF9W","step-section":"kne-form-creator_22ajp","block-section-header":"kne-form-creator_wS4rL","block-header-left":"kne-form-creator_t4awC","block-title":"kne-form-creator_wSVJf","block-summary":"kne-form-creator_GzeW8","block-header-actions":"kne-form-creator_Ue-nT","block-body":"kne-form-creator_je1H0","section-toolbar":"kne-form-creator_LUO8S","section-toolbar-label":"kne-form-creator_7KQ79","field-list":"kne-form-creator_-B7WZ","step-list":"kne-form-creator_kc1pH","step-section-header":"kne-form-creator_wkhEX","step-section-title":"kne-form-creator_NBinE","step-index":"kne-form-creator_CCKZZ","field-row":"kne-form-creator_XMkdt","field-row-index":"kne-form-creator_a-cDo","field-row-main":"kne-form-creator_ftlwp","inline-empty":"kne-form-creator_yP-RF","action-group":"kne-form-creator_773yo","hover-reveal":"kne-form-creator_S234h","action-btn":"kne-form-creator_mLgqh","add-block-dropdown":"kne-form-creator_vmS-e","add-block-option":"kne-form-creator_gjg2Y","add-block-option-icon":"kne-form-creator_qh1hh","add-block-option-text":"kne-form-creator_G8iJO","add-block-option-title":"kne-form-creator_ETSvm","add-block-option-desc":"kne-form-creator_O0C3l","field-empty":"kne-form-creator_Nmpfl","field-label-tips-icon":"kne-form-creator_0VVaO","preview-header":"kne-form-creator_c4BT0","preview-title":"kne-form-creator_fPkK4","preview-body":"kne-form-creator_6JntQ","schema-form":"kne-form-creator_MxCWP","schema-body":"kne-form-creator_q9ydz","schema-actions":"kne-form-creator_Y4eEH","schema-actions-inner":"kne-form-creator_FT9Zf","field-editor-form":"kne-form-creator_PGPHL","form-actions-editor":"kne-form-creator_fchMy","form-actions-switch-field":"kne-form-creator_6JE9x","form-actions-layout-panel":"kne-form-creator_rtm9D","form-actions-align-group":"kne-form-creator_51ZsV","form-actions-layout-title":"kne-form-creator_hFeiC","form-actions-gap-slider":"kne-form-creator_Gq0bk","editor-section":"kne-form-creator_jJy85","section-divider":"kne-form-creator_zA7L-","rule-editor":"kne-form-creator_bAlGU","options-editor":"kne-form-creator_AK4yO","super-select-props":"kne-form-creator_Iawhh","field-props-editor":"kne-form-creator_Gabf2","columns-editor":"kne-form-creator_DQW1N","prop-row":"kne-form-creator_7K54P","prop-label":"kne-form-creator_HAAyH","options-item":"kne-form-creator_dnOd2","table-row-card":"kne-form-creator_cwCYp","tree-options-editor":"kne-form-creator_s3nHO","tree-options-list":"kne-form-creator_Djs-E","tree-option-node":"kne-form-creator_XAcut","tree-option-row":"kne-form-creator_4K4Rj","tree-option-fields":"kne-form-creator_-4cjc","tree-option-actions":"kne-form-creator_IjCNI","tree-option-children":"kne-form-creator_pVPGJ","tree-add-sibling":"kne-form-creator_bl46P","rule-checkbox-group":"kne-form-creator_tDgVP","rule-len-row":"kne-form-creator_ATsae","rule-len-input":"kne-form-creator_jY4Ld","rule-len-sep":"kne-form-creator_jBDC8","options-list":"kne-form-creator_GUBNS","options-row":"kne-form-creator_uohD0","options-tip":"kne-form-creator_vrTmK","icon-square-btn":"kne-form-creator_DZjCf","icon-square-btn-sm":"kne-form-creator_GAh-t","is-mobile":"kne-form-creator_LtgJz"};
1482
+
1483
+ const {
1484
+ Text: Text$4
1485
+ } = Typography;
1486
+ const TYPE_TAG_COLORS = {
1487
+ Input: 'blue',
1488
+ TextArea: 'blue',
1489
+ InputNumber: 'cyan',
1490
+ Select: 'geekblue',
1491
+ RadioGroup: 'purple',
1492
+ CheckboxGroup: 'purple',
1493
+ SuperSelectList: 'gold',
1494
+ SuperSelectTableList: 'gold',
1495
+ SuperSelectTree: 'gold',
1496
+ SuperSelectCascader: 'gold',
1497
+ SelectFunction: 'orange',
1498
+ SelectIndustry: 'orange',
1499
+ SelectAddress: 'orange',
1500
+ Switch: 'green',
1501
+ Checkbox: 'green',
1502
+ DatePicker: 'lime'
1503
+ };
1504
+ const FieldRow = ({
1505
+ field,
1506
+ index,
1507
+ total,
1508
+ onEdit,
1509
+ onDelete,
1510
+ onMove
1511
+ }) => {
1512
+ const {
1513
+ formatMessage
1514
+ } = useIntl();
1515
+ const definition = getFieldDefinition(field.type);
1516
+ return /*#__PURE__*/jsxs("div", {
1517
+ className: style['field-row'],
1518
+ children: [/*#__PURE__*/jsx("span", {
1519
+ className: style['field-row-index'],
1520
+ children: index + 1
1521
+ }), /*#__PURE__*/jsx("div", {
1522
+ className: style['field-row-main'],
1523
+ children: /*#__PURE__*/jsxs(Space, {
1524
+ size: 6,
1525
+ wrap: true,
1526
+ children: [/*#__PURE__*/jsx(Text$4, {
1527
+ strong: true,
1528
+ ellipsis: true,
1529
+ children: field.label || formatMessage({
1530
+ id: 'untitledField'
1531
+ })
1532
+ }), /*#__PURE__*/jsx(Tag, {
1533
+ bordered: false,
1534
+ color: TYPE_TAG_COLORS[field.type] || 'default',
1535
+ children: (definition == null ? void 0 : definition.label) || field.type
1536
+ }), field.hidden ? /*#__PURE__*/jsx(Tag, {
1537
+ bordered: false,
1538
+ children: formatMessage({
1539
+ id: 'fieldHiddenTag'
1540
+ })
1541
+ }) : null, field.block ? /*#__PURE__*/jsx(Tag, {
1542
+ bordered: false,
1543
+ color: "processing",
1544
+ children: formatMessage({
1545
+ id: 'fieldBlockTag'
1546
+ })
1547
+ }) : null]
1548
+ })
1549
+ }), /*#__PURE__*/jsxs("div", {
1550
+ className: style['action-group'],
1551
+ children: [/*#__PURE__*/jsx(Button, {
1552
+ type: "text",
1553
+ size: "small",
1554
+ className: style['action-btn'],
1555
+ title: formatMessage({
1556
+ id: 'moveUp'
1557
+ }),
1558
+ icon: /*#__PURE__*/jsx(ArrowUpOutlined, {}),
1559
+ disabled: index === 0,
1560
+ onClick: () => onMove(field.id, 'up')
1561
+ }), /*#__PURE__*/jsx(Button, {
1562
+ type: "text",
1563
+ size: "small",
1564
+ className: style['action-btn'],
1565
+ title: formatMessage({
1566
+ id: 'moveDown'
1567
+ }),
1568
+ icon: /*#__PURE__*/jsx(ArrowDownOutlined, {}),
1569
+ disabled: index === total - 1,
1570
+ onClick: () => onMove(field.id, 'down')
1571
+ }), /*#__PURE__*/jsx(Button, {
1572
+ type: "text",
1573
+ size: "small",
1574
+ className: style['action-btn'],
1575
+ title: formatMessage({
1576
+ id: 'editField'
1577
+ }),
1578
+ icon: /*#__PURE__*/jsx(EditOutlined, {}),
1579
+ onClick: () => onEdit(field)
1580
+ }), /*#__PURE__*/jsx(Button, {
1581
+ type: "text",
1582
+ size: "small",
1583
+ danger: true,
1584
+ className: style['action-btn'],
1585
+ title: formatMessage({
1586
+ id: 'deleteField'
1587
+ }),
1588
+ icon: /*#__PURE__*/jsx(DeleteOutlined, {}),
1589
+ onClick: () => onDelete(field.id)
1590
+ })]
1591
+ })]
1592
+ });
1593
+ };
1594
+
1595
+ const _excluded$1 = ["title", "danger"];
1596
+ const {
1597
+ Text: Text$3
1598
+ } = Typography;
1599
+ const ActionGroup = ({
1600
+ children
1601
+ }) => /*#__PURE__*/jsx("div", {
1602
+ className: style['action-group'],
1603
+ children: children
1604
+ });
1605
+ const IconBtn = _ref => {
1606
+ let {
1607
+ title,
1608
+ danger
1609
+ } = _ref,
1610
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$1);
1611
+ return /*#__PURE__*/jsx(Button, _extends({
1612
+ type: "text",
1613
+ size: "small",
1614
+ title: title,
1615
+ danger: danger,
1616
+ className: style['action-btn']
1617
+ }, props));
1618
+ };
1619
+ const BlockListPanel = ({
1620
+ blocks,
1621
+ onAddBlock,
1622
+ onEditBlock,
1623
+ onDeleteBlock,
1624
+ onMoveBlock,
1625
+ onAddField,
1626
+ onEditField,
1627
+ onDeleteField,
1628
+ onMoveField,
1629
+ onAddStep,
1630
+ onEditStep,
1631
+ onDeleteStep,
1632
+ onMoveStep,
1633
+ onOpenFormActions
1634
+ }) => {
1635
+ const {
1636
+ formatMessage
1637
+ } = useIntl();
1638
+ const [addMenuOpen, setAddMenuOpen] = useState(false);
1639
+ const addBlockOptions = [{
1640
+ key: 'formInfo',
1641
+ icon: /*#__PURE__*/jsx(FormOutlined, {})
1642
+ }, {
1643
+ key: 'list',
1644
+ icon: /*#__PURE__*/jsx(UnorderedListOutlined, {})
1645
+ }, {
1646
+ key: 'tableList',
1647
+ icon: /*#__PURE__*/jsx(TableOutlined, {})
1648
+ }, {
1649
+ key: 'multiField',
1650
+ icon: /*#__PURE__*/jsx(AppstoreOutlined, {})
1651
+ }, {
1652
+ key: 'steps',
1653
+ icon: /*#__PURE__*/jsx(OrderedListOutlined, {})
1654
+ }];
1655
+ const renderFieldList = (fields, blockId, stepId) => {
1656
+ if (!(fields || []).length) {
1657
+ return /*#__PURE__*/jsx(Text$3, {
1658
+ type: "secondary",
1659
+ className: style['inline-empty'],
1660
+ children: formatMessage({
1661
+ id: 'emptyFieldList'
1662
+ })
1663
+ });
1664
+ }
1665
+ return /*#__PURE__*/jsx("div", {
1666
+ className: style['field-list'],
1667
+ children: fields.map((field, fieldIndex) => /*#__PURE__*/jsx(FieldRow, {
1668
+ field: field,
1669
+ index: fieldIndex,
1670
+ total: fields.length,
1671
+ onEdit: fieldItem => onEditField(blockId, fieldItem, stepId),
1672
+ onDelete: fieldId => onDeleteField(blockId, fieldId, stepId),
1673
+ onMove: (fieldId, direction) => onMoveField(blockId, fieldId, direction, stepId)
1674
+ }, field.id))
1675
+ });
1676
+ };
1677
+ const renderBlockChildren = block => {
1678
+ if (block.kind === 'steps') {
1679
+ return /*#__PURE__*/jsxs("div", {
1680
+ className: style['block-body'],
1681
+ children: [/*#__PURE__*/jsxs("div", {
1682
+ className: style['section-toolbar'],
1683
+ children: [/*#__PURE__*/jsx(Text$3, {
1684
+ type: "secondary",
1685
+ className: style['section-toolbar-label'],
1686
+ children: formatMessage({
1687
+ id: 'stepListTitle'
1688
+ })
1689
+ }), /*#__PURE__*/jsx(Button, {
1690
+ type: "text",
1691
+ size: "small",
1692
+ icon: /*#__PURE__*/jsx(PlusOutlined, {}),
1693
+ className: `${style['add-inline-btn']} ${style['hover-reveal']}`,
1694
+ onClick: () => onAddStep(block.id),
1695
+ children: formatMessage({
1696
+ id: 'addStep'
1697
+ })
1698
+ })]
1699
+ }), (block.items || []).length ? /*#__PURE__*/jsx("div", {
1700
+ className: style['step-list'],
1701
+ children: (block.items || []).map((step, stepIndex) => {
1702
+ var _step$list, _block$items;
1703
+ return /*#__PURE__*/jsxs("div", {
1704
+ className: style['step-section'],
1705
+ children: [/*#__PURE__*/jsxs("div", {
1706
+ className: style['step-section-header'],
1707
+ children: [/*#__PURE__*/jsxs(Space, {
1708
+ size: 8,
1709
+ className: style['step-section-title'],
1710
+ children: [/*#__PURE__*/jsx("span", {
1711
+ className: style['step-index'],
1712
+ children: stepIndex + 1
1713
+ }), /*#__PURE__*/jsx(Text$3, {
1714
+ strong: true,
1715
+ children: step.title || formatMessage({
1716
+ id: 'untitledStep'
1717
+ }, {
1718
+ index: stepIndex + 1
1719
+ })
1720
+ }), /*#__PURE__*/jsx(Text$3, {
1721
+ type: "secondary",
1722
+ children: formatMessage({
1723
+ id: 'fieldCount'
1724
+ }, {
1725
+ count: ((_step$list = step.list) == null ? void 0 : _step$list.length) || 0
1726
+ })
1727
+ })]
1728
+ }), /*#__PURE__*/jsxs(ActionGroup, {
1729
+ children: [/*#__PURE__*/jsx(IconBtn, {
1730
+ title: formatMessage({
1731
+ id: 'moveUp'
1732
+ }),
1733
+ icon: /*#__PURE__*/jsx(ArrowUpOutlined, {}),
1734
+ disabled: stepIndex === 0,
1735
+ onClick: () => onMoveStep(block.id, step.id, 'up')
1736
+ }), /*#__PURE__*/jsx(IconBtn, {
1737
+ title: formatMessage({
1738
+ id: 'moveDown'
1739
+ }),
1740
+ icon: /*#__PURE__*/jsx(ArrowDownOutlined, {}),
1741
+ disabled: stepIndex === (((_block$items = block.items) == null ? void 0 : _block$items.length) || 0) - 1,
1742
+ onClick: () => onMoveStep(block.id, step.id, 'down')
1743
+ }), /*#__PURE__*/jsx(IconBtn, {
1744
+ title: formatMessage({
1745
+ id: 'editStep'
1746
+ }),
1747
+ icon: /*#__PURE__*/jsx(EditOutlined, {}),
1748
+ onClick: () => onEditStep(block.id, step)
1749
+ }), /*#__PURE__*/jsx(IconBtn, {
1750
+ title: formatMessage({
1751
+ id: 'deleteStep'
1752
+ }),
1753
+ danger: true,
1754
+ icon: /*#__PURE__*/jsx(DeleteOutlined, {}),
1755
+ onClick: () => onDeleteStep(block.id, step.id)
1756
+ })]
1757
+ }), /*#__PURE__*/jsx(Button, {
1758
+ type: "text",
1759
+ size: "small",
1760
+ icon: /*#__PURE__*/jsx(PlusOutlined, {}),
1761
+ className: `${style['add-inline-btn']} ${style['hover-reveal']}`,
1762
+ onClick: () => onAddField(block.id, step.id),
1763
+ children: formatMessage({
1764
+ id: 'addField'
1765
+ })
1766
+ })]
1767
+ }), renderFieldList(step.list, block.id, step.id)]
1768
+ }, step.id);
1769
+ })
1770
+ }) : /*#__PURE__*/jsx(Text$3, {
1771
+ type: "secondary",
1772
+ className: style['inline-empty'],
1773
+ children: formatMessage({
1774
+ id: 'emptyStepList'
1775
+ })
1776
+ })]
1777
+ });
1778
+ }
1779
+ if (block.kind === 'multiField') {
1780
+ return /*#__PURE__*/jsx("div", {
1781
+ className: style['block-body'],
1782
+ children: /*#__PURE__*/jsx(Text$3, {
1783
+ type: "secondary",
1784
+ children: formatMessage({
1785
+ id: 'multiFieldEditorHint'
1786
+ })
1787
+ })
1788
+ });
1789
+ }
1790
+ return /*#__PURE__*/jsx("div", {
1791
+ className: style['block-body'],
1792
+ children: renderFieldList(block.list, block.id)
1793
+ });
1794
+ };
1795
+ return /*#__PURE__*/jsxs("div", {
1796
+ className: style['block-list-panel'],
1797
+ children: [/*#__PURE__*/jsxs(Flex, {
1798
+ justify: "flex-end",
1799
+ gap: 8,
1800
+ align: "center",
1801
+ className: style['panel-toolbar'],
1802
+ children: [/*#__PURE__*/jsx(Dropdown, {
1803
+ open: addMenuOpen,
1804
+ onOpenChange: setAddMenuOpen,
1805
+ trigger: ['click'],
1806
+ dropdownRender: () => /*#__PURE__*/jsx("div", {
1807
+ className: style['add-block-dropdown'],
1808
+ children: addBlockOptions.map(opt => {
1809
+ const definition = getBlockDefinition(opt.key);
1810
+ return /*#__PURE__*/jsxs("div", {
1811
+ role: "button",
1812
+ tabIndex: 0,
1813
+ className: style['add-block-option'],
1814
+ onClick: () => {
1815
+ onAddBlock(opt.key);
1816
+ setAddMenuOpen(false);
1817
+ },
1818
+ onKeyDown: e => {
1819
+ if (e.key === 'Enter' || e.key === ' ') {
1820
+ onAddBlock(opt.key);
1821
+ setAddMenuOpen(false);
1822
+ }
1823
+ },
1824
+ children: [/*#__PURE__*/jsx("div", {
1825
+ className: style['add-block-option-icon'],
1826
+ children: opt.icon
1827
+ }), /*#__PURE__*/jsxs("div", {
1828
+ className: style['add-block-option-text'],
1829
+ children: [/*#__PURE__*/jsx("div", {
1830
+ className: style['add-block-option-title'],
1831
+ children: formatMessage({
1832
+ id: `blockKind_${opt.key}`
1833
+ })
1834
+ }), /*#__PURE__*/jsx("div", {
1835
+ className: style['add-block-option-desc'],
1836
+ children: definition == null ? void 0 : definition.description
1837
+ })]
1838
+ })]
1839
+ }, opt.key);
1840
+ })
1841
+ }),
1842
+ children: /*#__PURE__*/jsx(Button, {
1843
+ type: "primary",
1844
+ size: "small",
1845
+ icon: /*#__PURE__*/jsx(PlusOutlined, {}),
1846
+ className: style['add-block-btn'],
1847
+ children: formatMessage({
1848
+ id: 'addBlock'
1849
+ })
1850
+ })
1851
+ }), /*#__PURE__*/jsx(Button, {
1852
+ type: "default",
1853
+ size: "small",
1854
+ shape: "circle",
1855
+ icon: /*#__PURE__*/jsx(SettingOutlined, {}),
1856
+ className: style['form-actions-setting-btn'],
1857
+ title: formatMessage({
1858
+ id: 'formActionsSection'
1859
+ }),
1860
+ onClick: onOpenFormActions
1861
+ })]
1862
+ }), !blocks.length ? /*#__PURE__*/jsx(Empty, {
1863
+ className: style['field-empty'],
1864
+ image: Empty.PRESENTED_IMAGE_SIMPLE,
1865
+ description: formatMessage({
1866
+ id: 'emptyBlockList'
1867
+ })
1868
+ }) : /*#__PURE__*/jsx("div", {
1869
+ className: style['block-list'],
1870
+ children: blocks.map((block, blockIndex) => {
1871
+ var _block$items2, _block$list;
1872
+ const definition = getBlockDefinition(block.kind);
1873
+ const canAddField = block.kind !== 'steps' && block.kind !== 'multiField';
1874
+ const summary = block.kind === 'steps' ? formatMessage({
1875
+ id: 'stepCount'
1876
+ }, {
1877
+ count: ((_block$items2 = block.items) == null ? void 0 : _block$items2.length) || 0
1878
+ }) : block.kind === 'multiField' ? formatMessage({
1879
+ id: 'multiFieldSummary'
1880
+ }, {
1881
+ type: block.fieldType
1882
+ }) : formatMessage({
1883
+ id: 'fieldCount'
1884
+ }, {
1885
+ count: ((_block$list = block.list) == null ? void 0 : _block$list.length) || 0
1886
+ });
1887
+ return /*#__PURE__*/jsxs("section", {
1888
+ className: `${style['block-section']} ${style[`block-kind-${block.kind}`] || ''}`.trim(),
1889
+ children: [/*#__PURE__*/jsxs("header", {
1890
+ className: style['block-section-header'],
1891
+ children: [/*#__PURE__*/jsxs("div", {
1892
+ className: style['block-header-left'],
1893
+ children: [/*#__PURE__*/jsx(Tag, {
1894
+ bordered: false,
1895
+ color: (definition == null ? void 0 : definition.color) || 'default',
1896
+ children: (definition == null ? void 0 : definition.label) || block.kind
1897
+ }), /*#__PURE__*/jsx(Text$3, {
1898
+ strong: true,
1899
+ ellipsis: true,
1900
+ className: style['block-title'],
1901
+ children: block.title || block.label || block.name || formatMessage({
1902
+ id: 'untitledBlock'
1903
+ })
1904
+ }), /*#__PURE__*/jsx("span", {
1905
+ className: style['block-summary'],
1906
+ children: summary
1907
+ })]
1908
+ }), /*#__PURE__*/jsxs(Space, {
1909
+ size: 4,
1910
+ wrap: true,
1911
+ className: style['block-header-actions'],
1912
+ children: [/*#__PURE__*/jsxs(ActionGroup, {
1913
+ children: [/*#__PURE__*/jsx(IconBtn, {
1914
+ title: formatMessage({
1915
+ id: 'moveUp'
1916
+ }),
1917
+ icon: /*#__PURE__*/jsx(ArrowUpOutlined, {}),
1918
+ disabled: blockIndex === 0,
1919
+ onClick: () => onMoveBlock(block.id, 'up')
1920
+ }), /*#__PURE__*/jsx(IconBtn, {
1921
+ title: formatMessage({
1922
+ id: 'moveDown'
1923
+ }),
1924
+ icon: /*#__PURE__*/jsx(ArrowDownOutlined, {}),
1925
+ disabled: blockIndex === blocks.length - 1,
1926
+ onClick: () => onMoveBlock(block.id, 'down')
1927
+ }), /*#__PURE__*/jsx(IconBtn, {
1928
+ title: formatMessage({
1929
+ id: 'editBlock'
1930
+ }),
1931
+ icon: /*#__PURE__*/jsx(SettingOutlined, {}),
1932
+ onClick: () => onEditBlock(block)
1933
+ }), /*#__PURE__*/jsx(IconBtn, {
1934
+ title: formatMessage({
1935
+ id: 'deleteBlock'
1936
+ }),
1937
+ danger: true,
1938
+ icon: /*#__PURE__*/jsx(DeleteOutlined, {}),
1939
+ onClick: () => onDeleteBlock(block.id)
1940
+ })]
1941
+ }), canAddField ? /*#__PURE__*/jsx(Button, {
1942
+ type: "text",
1943
+ size: "small",
1944
+ icon: /*#__PURE__*/jsx(PlusOutlined, {}),
1945
+ className: `${style['add-inline-btn']} ${style['hover-reveal']}`,
1946
+ onClick: () => onAddField(block.id),
1947
+ children: formatMessage({
1948
+ id: 'addField'
1949
+ })
1950
+ }) : null]
1951
+ })]
1952
+ }), renderBlockChildren(block)]
1953
+ }, block.id);
1954
+ })
1955
+ })]
1956
+ });
1957
+ };
1958
+
1959
+ const BlockConfigFields = ({
1960
+ kind
1961
+ }) => {
1962
+ const {
1963
+ formatMessage
1964
+ } = useIntl();
1965
+ const definition = getBlockDefinition(kind);
1966
+ const fieldTypeOptions = useMemo(() => getFieldTypes(), []);
1967
+ const list = [];
1968
+ if (kind === 'formInfo' || kind === 'list' || kind === 'tableList') {
1969
+ list.push(/*#__PURE__*/jsx(Input, {
1970
+ name: "title",
1971
+ label: formatMessage({
1972
+ id: 'blockTitle'
1973
+ }),
1974
+ placeholder: formatMessage({
1975
+ id: 'blockTitlePlaceholder'
1976
+ })
1977
+ }, "title"), kind === 'formInfo' ? /*#__PURE__*/jsx(Input, {
1978
+ name: "subtitle",
1979
+ label: formatMessage({
1980
+ id: 'blockSubtitle'
1981
+ }),
1982
+ placeholder: formatMessage({
1983
+ id: 'blockSubtitlePlaceholder'
1984
+ })
1985
+ }, "subtitle") : null, kind !== 'formInfo' ? /*#__PURE__*/jsx(Input, {
1986
+ name: "name",
1987
+ label: formatMessage({
1988
+ id: 'blockName'
1989
+ }),
1990
+ rule: "REQ",
1991
+ placeholder: formatMessage({
1992
+ id: 'fieldNamePlaceholder'
1993
+ })
1994
+ }, "name") : null, /*#__PURE__*/jsx(InputNumber, {
1995
+ name: "column",
1996
+ label: formatMessage({
1997
+ id: 'formColumnPlaceholder'
1998
+ }),
1999
+ min: 1,
2000
+ max: 4
2001
+ }, "column"), kind === 'formInfo' ? /*#__PURE__*/jsx(InputNumber, {
2002
+ name: "gap",
2003
+ label: formatMessage({
2004
+ id: 'blockGap'
2005
+ }),
2006
+ min: 0,
2007
+ max: 48
2008
+ }, "gap") : null, /*#__PURE__*/jsx(Checkbox, {
2009
+ name: "bordered",
2010
+ children: formatMessage({
2011
+ id: 'blockBordered'
2012
+ })
2013
+ }, "bordered"), kind === 'list' ? /*#__PURE__*/jsx(Checkbox, {
2014
+ name: "important",
2015
+ children: formatMessage({
2016
+ id: 'blockImportant'
2017
+ })
2018
+ }, "important") : null, kind !== 'formInfo' ? /*#__PURE__*/jsx(Input, {
2019
+ name: "addText",
2020
+ label: formatMessage({
2021
+ id: 'blockAddText'
2022
+ }),
2023
+ placeholder: formatMessage({
2024
+ id: 'blockAddTextPlaceholder'
2025
+ })
2026
+ }, "addText") : null, kind !== 'formInfo' ? /*#__PURE__*/jsx(InputNumber, {
2027
+ name: "maxLength",
2028
+ label: formatMessage({
2029
+ id: 'blockMaxLength'
2030
+ }),
2031
+ min: 1
2032
+ }, "maxLength") : null, kind !== 'formInfo' ? /*#__PURE__*/jsx(InputNumber, {
2033
+ name: "minLength",
2034
+ label: formatMessage({
2035
+ id: 'blockMinLength'
2036
+ }),
2037
+ min: 0
2038
+ }, "minLength") : null);
2039
+ }
2040
+ if (kind === 'multiField') {
2041
+ list.push(/*#__PURE__*/jsx(Input, {
2042
+ name: "name",
2043
+ label: formatMessage({
2044
+ id: 'blockName'
2045
+ }),
2046
+ rule: "REQ",
2047
+ placeholder: formatMessage({
2048
+ id: 'fieldNamePlaceholder'
2049
+ })
2050
+ }, "name"), /*#__PURE__*/jsx(Input, {
2051
+ name: "label",
2052
+ label: formatMessage({
2053
+ id: 'fieldLabel'
2054
+ }),
2055
+ rule: "REQ",
2056
+ placeholder: formatMessage({
2057
+ id: 'fieldLabelPlaceholder'
2058
+ })
2059
+ }, "label"), /*#__PURE__*/jsx(Select, {
2060
+ name: "fieldType",
2061
+ label: formatMessage({
2062
+ id: 'multiFieldType'
2063
+ }),
2064
+ rule: "REQ",
2065
+ options: fieldTypeOptions
2066
+ }, "fieldType"), /*#__PURE__*/jsx(Input, {
2067
+ name: "addText",
2068
+ label: formatMessage({
2069
+ id: 'blockAddText'
2070
+ }),
2071
+ placeholder: formatMessage({
2072
+ id: 'blockAddTextPlaceholder'
2073
+ })
2074
+ }, "addText"));
2075
+ }
2076
+ if (kind === 'steps') {
2077
+ list.push(/*#__PURE__*/jsx(Input, {
2078
+ name: "title",
2079
+ label: formatMessage({
2080
+ id: 'blockTitle'
2081
+ }),
2082
+ placeholder: formatMessage({
2083
+ id: 'blockTitlePlaceholder'
2084
+ })
2085
+ }, "title"), /*#__PURE__*/jsx(Input, {
2086
+ name: "subtitle",
2087
+ label: formatMessage({
2088
+ id: 'blockSubtitle'
2089
+ }),
2090
+ placeholder: formatMessage({
2091
+ id: 'blockSubtitlePlaceholder'
2092
+ })
2093
+ }, "subtitle"), /*#__PURE__*/jsx(Checkbox, {
2094
+ name: "bordered",
2095
+ children: formatMessage({
2096
+ id: 'blockBordered'
2097
+ })
2098
+ }, "bordered"), /*#__PURE__*/jsx(Checkbox, {
2099
+ name: "autoStep",
2100
+ children: formatMessage({
2101
+ id: 'blockAutoStep'
2102
+ })
2103
+ }, "autoStep"));
2104
+ }
2105
+ return /*#__PURE__*/jsx("div", {
2106
+ className: style['field-editor-form'],
2107
+ children: /*#__PURE__*/jsx(FormInfo, {
2108
+ title: (definition == null ? void 0 : definition.label) || kind,
2109
+ subtitle: definition == null ? void 0 : definition.description,
2110
+ column: 1,
2111
+ list: list.filter(Boolean)
2112
+ })
2113
+ });
2114
+ };
2115
+ const BlockEditorModal = ({
2116
+ open,
2117
+ block,
2118
+ onCancel,
2119
+ onSave,
2120
+ renderModal
2121
+ }) => {
2122
+ const {
2123
+ formatMessage
2124
+ } = useIntl();
2125
+ const isMobile = useIsMobile();
2126
+ const isEdit = !!(block != null && block.id);
2127
+ const formData = useMemo(() => blockToFormValues(block || createBlock('formInfo')), [block, open]);
2128
+ const handleSubmit = async values => {
2129
+ if (((block == null ? void 0 : block.kind) === 'list' || (block == null ? void 0 : block.kind) === 'tableList' || (block == null ? void 0 : block.kind) === 'multiField') && !values.name) {
2130
+ message.error(formatMessage({
2131
+ id: 'blockNameRequired'
2132
+ }));
2133
+ return false;
2134
+ }
2135
+ onSave(formValuesToBlock(values, block || createBlock(values.kind || 'formInfo')));
2136
+ };
2137
+ return /*#__PURE__*/jsx(FormModal, _extends({
2138
+ destroyOnHidden: true,
2139
+ destroyOnClose: true,
2140
+ title: formatMessage({
2141
+ id: isEdit ? 'editBlock' : 'addBlock'
2142
+ }),
2143
+ open: open,
2144
+ onCancel: onCancel,
2145
+ width: isMobile ? 'calc(100vw - 32px)' : 720
2146
+ }, renderModal ? {
2147
+ renderModal
2148
+ } : {}, {
2149
+ formProps: {
2150
+ data: formData,
2151
+ onSubmit: handleSubmit
2152
+ },
2153
+ okText: formatMessage({
2154
+ id: 'confirm'
2155
+ }),
2156
+ cancelText: formatMessage({
2157
+ id: 'cancel'
2158
+ }),
2159
+ children: /*#__PURE__*/jsx(BlockConfigFields, {
2160
+ kind: (block == null ? void 0 : block.kind) || 'formInfo'
2161
+ })
2162
+ }), open ? block != null && block.id ? `edit-${block.id}` : `add-${(block == null ? void 0 : block.kind) || 'formInfo'}-${formData.name || 'new'}` : 'closed');
2163
+ };
2164
+
2165
+ const StepEditorModal = ({
2166
+ open,
2167
+ step,
2168
+ onCancel,
2169
+ onSave,
2170
+ renderModal
2171
+ }) => {
2172
+ const {
2173
+ formatMessage
2174
+ } = useIntl();
2175
+ const isMobile = useIsMobile();
2176
+ const formData = useMemo(() => stepToFormValues(step || createStep()), [step, open]);
2177
+ return /*#__PURE__*/jsx(FormModal, _extends({
2178
+ destroyOnHidden: true,
2179
+ destroyOnClose: true,
2180
+ title: formatMessage({
2181
+ id: step != null && step.id ? 'editStep' : 'addStep'
2182
+ }),
2183
+ open: open,
2184
+ onCancel: onCancel,
2185
+ width: isMobile ? 'calc(100vw - 32px)' : 560
2186
+ }, renderModal ? {
2187
+ renderModal
2188
+ } : {}, {
2189
+ formProps: {
2190
+ data: formData,
2191
+ onSubmit: values => {
2192
+ onSave(formValuesToStep(values, step || createStep()));
2193
+ }
2194
+ },
2195
+ okText: formatMessage({
2196
+ id: 'confirm'
2197
+ }),
2198
+ cancelText: formatMessage({
2199
+ id: 'cancel'
2200
+ }),
2201
+ children: /*#__PURE__*/jsx(FormInfo, {
2202
+ column: 1,
2203
+ list: [/*#__PURE__*/jsx(Input, {
2204
+ name: "title",
2205
+ label: formatMessage({
2206
+ id: 'stepTitle'
2207
+ }),
2208
+ rule: "REQ",
2209
+ placeholder: formatMessage({
2210
+ id: 'stepTitlePlaceholder'
2211
+ })
2212
+ }, "title"), /*#__PURE__*/jsx(InputNumber, {
2213
+ name: "column",
2214
+ label: formatMessage({
2215
+ id: 'formColumnPlaceholder'
2216
+ }),
2217
+ min: 1,
2218
+ max: 4
2219
+ }, "column")]
2220
+ })
2221
+ }), open ? step != null && step.id ? `edit-${step.id}` : `add-step-${formData.title || 'new'}` : 'closed');
2222
+ };
2223
+
2224
+ const {
2225
+ Text: Text$2
2226
+ } = Typography;
2227
+ const {
2228
+ useOnChange
2229
+ } = hooks;
2230
+ const RulePresetsGroup = props => {
2231
+ const render = useOnChange(props);
2232
+ return render(Checkbox$1.Group);
2233
+ };
2234
+ RulePresetsGroup.field = Checkbox$1.Group;
2235
+ const RulePresetEditor = () => {
2236
+ const {
2237
+ formatMessage
2238
+ } = useIntl();
2239
+ const options = [...RULE_PRESET_ITEMS.map(item => ({
2240
+ label: item.label,
2241
+ value: item.value
2242
+ })), {
2243
+ label: formatMessage({
2244
+ id: 'ruleLen'
2245
+ }),
2246
+ value: RULE_LEN_PRESET
2247
+ }];
2248
+ const list = [/*#__PURE__*/jsx(RulePresetsGroup, {
2249
+ name: "rulePresets",
2250
+ block: true,
2251
+ options: options
2252
+ }, "rulePresets"), /*#__PURE__*/jsx(InputNumber, {
2253
+ name: "lenMin",
2254
+ label: formatMessage({
2255
+ id: 'ruleLenMin'
2256
+ }),
2257
+ min: 0,
2258
+ display: ({
2259
+ openApi
2260
+ }) => {
2261
+ var _openApi$data;
2262
+ return ((openApi == null || (_openApi$data = openApi.data) == null ? void 0 : _openApi$data.rulePresets) || []).includes(RULE_LEN_PRESET);
2263
+ }
2264
+ }, "lenMin"), /*#__PURE__*/jsx(InputNumber, {
2265
+ name: "lenMax",
2266
+ label: formatMessage({
2267
+ id: 'ruleLenMax'
2268
+ }),
2269
+ min: 0,
2270
+ display: ({
2271
+ openApi
2272
+ }) => {
2273
+ var _openApi$data2;
2274
+ return ((openApi == null || (_openApi$data2 = openApi.data) == null ? void 0 : _openApi$data2.rulePresets) || []).includes(RULE_LEN_PRESET);
2275
+ }
2276
+ }, "lenMax"), /*#__PURE__*/jsx("div", {
2277
+ block: true,
2278
+ children: /*#__PURE__*/jsx(Text$2, {
2279
+ type: "secondary",
2280
+ children: formatMessage({
2281
+ id: 'ruleEditorHint'
2282
+ })
2283
+ })
2284
+ }, "rule-hint")];
2285
+ return /*#__PURE__*/jsx(FormInfo, {
2286
+ title: formatMessage({
2287
+ id: 'fieldRule'
2288
+ }),
2289
+ column: 1,
2290
+ list: list
2291
+ });
2292
+ };
2293
+
2294
+ const {
2295
+ Text: Text$1
2296
+ } = Typography;
2297
+ const createOptionKey = () => createDataKey('opt');
2298
+ const EMPTY_OPTION = () => ({
2299
+ _key: createOptionKey(),
2300
+ label: '',
2301
+ value: ''
2302
+ });
2303
+ const createEmptyTableRow = columns => {
2304
+ const row = {
2305
+ label: '',
2306
+ value: ''
2307
+ };
2308
+ (columns || []).forEach(column => {
2309
+ if (column != null && column.name) {
2310
+ row[column.name] = '';
2311
+ }
2312
+ });
2313
+ return row;
2314
+ };
2315
+ const ensureOptionKeys = (list = []) => list.map(item => _extends({}, item, {
2316
+ _key: item._key || createOptionKey(),
2317
+ children: Array.isArray(item.children) ? ensureOptionKeys(item.children) : undefined
2318
+ }));
2319
+ const hasMissingOptionKey = (list = []) => list.some(item => !(item != null && item._key) || Array.isArray(item.children) && hasMissingOptionKey(item.children));
2320
+
2321
+ /** 扁平选项(非树) */
2322
+ const FlatOptionRows = ({
2323
+ list,
2324
+ onChange,
2325
+ allowDescription
2326
+ }) => {
2327
+ const {
2328
+ formatMessage
2329
+ } = useIntl();
2330
+ const rows = list.length ? ensureOptionKeys(list) : [EMPTY_OPTION()];
2331
+ const commit = next => onChange(next);
2332
+ const updateItem = (index, patch) => {
2333
+ commit(rows.map((item, itemIndex) => itemIndex === index ? _extends({}, item, patch) : item));
2334
+ };
2335
+ return /*#__PURE__*/jsxs("div", {
2336
+ className: style['options-list'],
2337
+ children: [rows.map((item, index) => /*#__PURE__*/jsxs(Flex, {
2338
+ gap: 8,
2339
+ align: "start",
2340
+ className: style['options-row'],
2341
+ children: [/*#__PURE__*/jsx(Input$1, {
2342
+ value: item.label,
2343
+ placeholder: formatMessage({
2344
+ id: 'optionLabelPlaceholder'
2345
+ }),
2346
+ onChange: event => updateItem(index, {
2347
+ label: event.target.value
2348
+ })
2349
+ }), /*#__PURE__*/jsx(Input$1, {
2350
+ value: item.value,
2351
+ placeholder: formatMessage({
2352
+ id: 'optionValuePlaceholder'
2353
+ }),
2354
+ onChange: event => updateItem(index, {
2355
+ value: event.target.value
2356
+ })
2357
+ }), allowDescription ? /*#__PURE__*/jsx(Input$1, {
2358
+ value: item.description || '',
2359
+ placeholder: formatMessage({
2360
+ id: 'optionDescPlaceholder'
2361
+ }),
2362
+ onChange: event => updateItem(index, {
2363
+ description: event.target.value
2364
+ })
2365
+ }) : null, /*#__PURE__*/jsx(Button, {
2366
+ type: "text",
2367
+ danger: true,
2368
+ className: style['icon-square-btn-sm'],
2369
+ icon: /*#__PURE__*/jsx(DeleteOutlined, {}),
2370
+ disabled: rows.length === 1,
2371
+ onClick: () => {
2372
+ const next = rows.filter((_, itemIndex) => itemIndex !== index);
2373
+ commit(next.length ? next : [EMPTY_OPTION()]);
2374
+ }
2375
+ })]
2376
+ }, item._key)), /*#__PURE__*/jsx(Button, {
2377
+ type: "dashed",
2378
+ block: true,
2379
+ icon: /*#__PURE__*/jsx(PlusOutlined, {}),
2380
+ onClick: () => commit([...rows, EMPTY_OPTION()]),
2381
+ children: formatMessage({
2382
+ id: 'addOption'
2383
+ })
2384
+ })]
2385
+ });
2386
+ };
2387
+
2388
+ /** 树形 / 级联选项 */
2389
+ const TreeOptionNode = ({
2390
+ item,
2391
+ index,
2392
+ siblings,
2393
+ onChangeSiblings,
2394
+ allowDescription,
2395
+ depth,
2396
+ maxDepth: _maxDepth = 4
2397
+ }) => {
2398
+ const {
2399
+ formatMessage
2400
+ } = useIntl();
2401
+ const children = Array.isArray(item.children) ? item.children : [];
2402
+ const canAddChild = depth < _maxDepth;
2403
+ const updateSelf = patch => {
2404
+ onChangeSiblings(siblings.map((row, i) => i === index ? _extends({}, row, patch) : row));
2405
+ };
2406
+ const removeSelf = () => {
2407
+ onChangeSiblings(siblings.filter((_, i) => i !== index));
2408
+ };
2409
+ const addChild = () => {
2410
+ updateSelf({
2411
+ children: [...children, EMPTY_OPTION()]
2412
+ });
2413
+ };
2414
+ const changeChildren = nextChildren => {
2415
+ if (!nextChildren.length) {
2416
+ updateSelf({
2417
+ children: undefined
2418
+ });
2419
+ return;
2420
+ }
2421
+ updateSelf({
2422
+ children: nextChildren
2423
+ });
2424
+ };
2425
+ return /*#__PURE__*/jsxs("div", {
2426
+ className: style['tree-option-node'],
2427
+ "data-depth": depth,
2428
+ children: [/*#__PURE__*/jsxs("div", {
2429
+ className: style['tree-option-row'],
2430
+ children: [/*#__PURE__*/jsxs("div", {
2431
+ className: style['tree-option-fields'],
2432
+ children: [/*#__PURE__*/jsx(Input$1, {
2433
+ value: item.label,
2434
+ placeholder: formatMessage({
2435
+ id: 'optionLabelPlaceholder'
2436
+ }),
2437
+ onChange: e => updateSelf({
2438
+ label: e.target.value
2439
+ })
2440
+ }), /*#__PURE__*/jsx(Input$1, {
2441
+ value: item.value,
2442
+ placeholder: formatMessage({
2443
+ id: 'optionValuePlaceholder'
2444
+ }),
2445
+ onChange: e => updateSelf({
2446
+ value: e.target.value
2447
+ })
2448
+ }), allowDescription ? /*#__PURE__*/jsx(Input$1, {
2449
+ value: item.description || '',
2450
+ placeholder: formatMessage({
2451
+ id: 'optionDescPlaceholder'
2452
+ }),
2453
+ onChange: e => updateSelf({
2454
+ description: e.target.value
2455
+ })
2456
+ }) : null]
2457
+ }), /*#__PURE__*/jsxs("div", {
2458
+ className: style['tree-option-actions'],
2459
+ children: [canAddChild ? /*#__PURE__*/jsx(Button, {
2460
+ type: "link",
2461
+ size: "small",
2462
+ icon: /*#__PURE__*/jsx(ApartmentOutlined, {}),
2463
+ onClick: addChild,
2464
+ children: formatMessage({
2465
+ id: 'addChildOption'
2466
+ })
2467
+ }) : null, /*#__PURE__*/jsx(Button, {
2468
+ type: "text",
2469
+ danger: true,
2470
+ size: "small",
2471
+ className: style['icon-square-btn-sm'],
2472
+ icon: /*#__PURE__*/jsx(DeleteOutlined, {}),
2473
+ disabled: siblings.length === 1 && depth === 0,
2474
+ onClick: removeSelf
2475
+ })]
2476
+ })]
2477
+ }), children.length ? /*#__PURE__*/jsx("div", {
2478
+ className: style['tree-option-children'],
2479
+ children: children.map((child, childIndex) => /*#__PURE__*/jsx(TreeOptionNode, {
2480
+ item: child,
2481
+ index: childIndex,
2482
+ siblings: children,
2483
+ onChangeSiblings: changeChildren,
2484
+ allowDescription: allowDescription,
2485
+ depth: depth + 1,
2486
+ maxDepth: _maxDepth
2487
+ }, child._key))
2488
+ }) : null]
2489
+ });
2490
+ };
2491
+ const TreeOptionsEditor = ({
2492
+ value: _value = [],
2493
+ onChange,
2494
+ allowDescription
2495
+ }) => {
2496
+ const {
2497
+ formatMessage
2498
+ } = useIntl();
2499
+ useEffect(() => {
2500
+ if (!_value.length) {
2501
+ return;
2502
+ }
2503
+ if (hasMissingOptionKey(_value)) {
2504
+ onChange(ensureOptionKeys(_value));
2505
+ }
2506
+ }, [_value, onChange]);
2507
+ const rows = _value.length ? hasMissingOptionKey(_value) ? ensureOptionKeys(_value) : _value : [EMPTY_OPTION()];
2508
+ const commit = next => {
2509
+ onChange(next.length ? ensureOptionKeys(next) : [EMPTY_OPTION()]);
2510
+ };
2511
+ return /*#__PURE__*/jsxs("div", {
2512
+ className: style['tree-options-editor'],
2513
+ children: [/*#__PURE__*/jsx("div", {
2514
+ className: style['tree-options-list'],
2515
+ children: rows.map((item, index) => /*#__PURE__*/jsx(TreeOptionNode, {
2516
+ item: item,
2517
+ index: index,
2518
+ siblings: rows,
2519
+ onChangeSiblings: commit,
2520
+ allowDescription: allowDescription,
2521
+ depth: 0
2522
+ }, item._key))
2523
+ }), /*#__PURE__*/jsx(Button, {
2524
+ type: "dashed",
2525
+ block: true,
2526
+ icon: /*#__PURE__*/jsx(PlusOutlined, {}),
2527
+ onClick: () => commit([...rows, EMPTY_OPTION()]),
2528
+ children: formatMessage({
2529
+ id: 'addOption'
2530
+ })
2531
+ })]
2532
+ });
2533
+ };
2534
+ const ColumnsEditor = ({
2535
+ value: _value2 = [],
2536
+ onChange
2537
+ }) => {
2538
+ const {
2539
+ formatMessage
2540
+ } = useIntl();
2541
+ const list = _value2.length ? _value2 : [createEmptyColumn()];
2542
+ const updateItem = (index, patch) => {
2543
+ onChange(list.map((item, itemIndex) => itemIndex === index ? _extends({}, item, patch) : item));
2544
+ };
2545
+ return /*#__PURE__*/jsx(FormInfo, {
2546
+ title: formatMessage({
2547
+ id: 'fieldColumns'
2548
+ }),
2549
+ column: 1,
2550
+ list: [/*#__PURE__*/jsxs("div", {
2551
+ block: true,
2552
+ className: style['columns-editor'],
2553
+ children: [/*#__PURE__*/jsx("div", {
2554
+ className: style['options-list'],
2555
+ children: list.map((item, index) => {
2556
+ var _item$width;
2557
+ return /*#__PURE__*/jsxs(Flex, {
2558
+ gap: 8,
2559
+ align: "start",
2560
+ className: style['options-row'],
2561
+ children: [/*#__PURE__*/jsx(Input$1, {
2562
+ value: item.title || '',
2563
+ placeholder: formatMessage({
2564
+ id: 'columnTitlePlaceholder'
2565
+ }),
2566
+ onChange: e => {
2567
+ const title = e.target.value;
2568
+ const patch = {
2569
+ title
2570
+ };
2571
+ if ((!item.name || isAutoDataKey(item.name, 'col')) && !item.name) {
2572
+ patch.name = createDataKey('col');
2573
+ patch.key = patch.name;
2574
+ }
2575
+ updateItem(index, patch);
2576
+ }
2577
+ }), /*#__PURE__*/jsx(Input$1, {
2578
+ value: item.name || '',
2579
+ placeholder: formatMessage({
2580
+ id: 'columnNamePlaceholder'
2581
+ }),
2582
+ onChange: e => {
2583
+ const name = e.target.value;
2584
+ updateItem(index, {
2585
+ name,
2586
+ key: name.trim() || item.key
2587
+ });
2588
+ }
2589
+ }), /*#__PURE__*/jsx(InputNumber$1, {
2590
+ min: 40,
2591
+ style: {
2592
+ width: 120
2593
+ },
2594
+ value: (_item$width = item.width) != null ? _item$width : null,
2595
+ placeholder: formatMessage({
2596
+ id: 'columnWidthPlaceholder'
2597
+ }),
2598
+ onChange: width => updateItem(index, {
2599
+ width: width != null ? width : undefined
2600
+ })
2601
+ }), /*#__PURE__*/jsx(Button, {
2602
+ type: "text",
2603
+ danger: true,
2604
+ className: style['icon-square-btn-sm'],
2605
+ icon: /*#__PURE__*/jsx(DeleteOutlined, {}),
2606
+ disabled: list.length === 1,
2607
+ onClick: () => {
2608
+ const next = list.filter((_, i) => i !== index);
2609
+ onChange(next.length ? next : [createEmptyColumn()]);
2610
+ }
2611
+ })]
2612
+ }, item.name || index);
2613
+ })
2614
+ }), /*#__PURE__*/jsx(Button, {
2615
+ type: "dashed",
2616
+ block: true,
2617
+ icon: /*#__PURE__*/jsx(PlusOutlined, {}),
2618
+ onClick: () => onChange([...list, createEmptyColumn()]),
2619
+ children: formatMessage({
2620
+ id: 'addColumn'
2621
+ })
2622
+ }), /*#__PURE__*/jsx(Space, {
2623
+ size: 4,
2624
+ className: style['options-tip'],
2625
+ children: formatMessage({
2626
+ id: 'columnsEditorHint'
2627
+ })
2628
+ })]
2629
+ }, "columns-editor")]
2630
+ });
2631
+ };
2632
+ const TableRowsEditor = ({
2633
+ columns: _columns = [],
2634
+ value: _value3 = [],
2635
+ onChange
2636
+ }) => {
2637
+ const {
2638
+ formatMessage
2639
+ } = useIntl();
2640
+ const usableColumns = _columns.filter(column => (column == null ? void 0 : column.name) && String(column.name).trim());
2641
+ const list = _value3.length ? _value3 : [createEmptyTableRow(usableColumns)];
2642
+ const updateItem = (index, patch) => {
2643
+ onChange(list.map((item, itemIndex) => itemIndex === index ? _extends({}, item, patch) : item));
2644
+ };
2645
+ if (!usableColumns.length) {
2646
+ return /*#__PURE__*/jsx(FormInfo, {
2647
+ title: formatMessage({
2648
+ id: 'fieldTableRows'
2649
+ }),
2650
+ column: 1,
2651
+ list: [/*#__PURE__*/jsx("div", {
2652
+ block: true,
2653
+ children: /*#__PURE__*/jsx(Text$1, {
2654
+ type: "secondary",
2655
+ children: formatMessage({
2656
+ id: 'tableRowsNeedColumnsHint'
2657
+ })
2658
+ })
2659
+ }, "table-rows-empty")]
2660
+ });
2661
+ }
2662
+ return /*#__PURE__*/jsx(FormInfo, {
2663
+ title: formatMessage({
2664
+ id: 'fieldTableRows'
2665
+ }),
2666
+ column: 1,
2667
+ list: [/*#__PURE__*/jsxs("div", {
2668
+ block: true,
2669
+ className: style['table-rows-editor'],
2670
+ children: [/*#__PURE__*/jsx(Space, {
2671
+ direction: "vertical",
2672
+ size: 12,
2673
+ style: {
2674
+ width: '100%'
2675
+ },
2676
+ children: list.map((item, index) => /*#__PURE__*/jsx(Card, {
2677
+ size: "small",
2678
+ className: style['table-row-card'],
2679
+ title: formatMessage({
2680
+ id: 'tableRowTitle'
2681
+ }, {
2682
+ index: index + 1
2683
+ }),
2684
+ extra: /*#__PURE__*/jsx(Button, {
2685
+ type: "text",
2686
+ danger: true,
2687
+ className: style['icon-square-btn-sm'],
2688
+ icon: /*#__PURE__*/jsx(DeleteOutlined, {}),
2689
+ disabled: list.length === 1,
2690
+ onClick: () => {
2691
+ const next = list.filter((_, i) => i !== index);
2692
+ onChange(next.length ? next : [createEmptyTableRow(usableColumns)]);
2693
+ }
2694
+ }),
2695
+ children: /*#__PURE__*/jsxs(Space, {
2696
+ direction: "vertical",
2697
+ size: 8,
2698
+ style: {
2699
+ width: '100%'
2700
+ },
2701
+ children: [/*#__PURE__*/jsxs(Flex, {
2702
+ gap: 8,
2703
+ children: [/*#__PURE__*/jsx(Input$1, {
2704
+ value: item.value || '',
2705
+ placeholder: formatMessage({
2706
+ id: 'optionValuePlaceholder'
2707
+ }),
2708
+ onChange: e => updateItem(index, {
2709
+ value: e.target.value
2710
+ })
2711
+ }), /*#__PURE__*/jsx(Input$1, {
2712
+ value: item.label || '',
2713
+ placeholder: formatMessage({
2714
+ id: 'tableRowLabelPlaceholder'
2715
+ }),
2716
+ onChange: e => updateItem(index, {
2717
+ label: e.target.value
2718
+ })
2719
+ })]
2720
+ }), /*#__PURE__*/jsx(Flex, {
2721
+ gap: 8,
2722
+ wrap: "wrap",
2723
+ children: usableColumns.map(column => /*#__PURE__*/jsx(Input$1, {
2724
+ style: {
2725
+ minWidth: 140,
2726
+ flex: 1
2727
+ },
2728
+ value: item[column.name] || '',
2729
+ placeholder: column.title || column.name,
2730
+ onChange: e => updateItem(index, {
2731
+ [column.name]: e.target.value
2732
+ })
2733
+ }, column.name))
2734
+ })]
2735
+ })
2736
+ }, index))
2737
+ }), /*#__PURE__*/jsx(Button, {
2738
+ type: "dashed",
2739
+ block: true,
2740
+ icon: /*#__PURE__*/jsx(PlusOutlined, {}),
2741
+ style: {
2742
+ marginTop: 12
2743
+ },
2744
+ onClick: () => onChange([...list, createEmptyTableRow(usableColumns)]),
2745
+ children: formatMessage({
2746
+ id: 'addTableRow'
2747
+ })
2748
+ }), /*#__PURE__*/jsx(Space, {
2749
+ size: 4,
2750
+ className: style['options-tip'],
2751
+ children: formatMessage({
2752
+ id: 'tableRowsEditorHint'
2753
+ })
2754
+ })]
2755
+ }, "table-rows-editor")]
2756
+ });
2757
+ };
2758
+ const OptionsEditor = ({
2759
+ value: _value4 = [],
2760
+ onChange,
2761
+ allowDescription: _allowDescription = false,
2762
+ allowChildren: _allowChildren = false,
2763
+ hasColumns: _hasColumns = false,
2764
+ columns: _columns2 = [],
2765
+ onColumnsChange
2766
+ }) => {
2767
+ const {
2768
+ formatMessage
2769
+ } = useIntl();
2770
+ if (_hasColumns) {
2771
+ const handleColumnsChange = nextColumns => {
2772
+ const prevColumns = _columns2 || [];
2773
+ const migrated = (_value4 || []).map(row => {
2774
+ const nextRow = _extends({}, row);
2775
+ prevColumns.forEach((prevCol, index) => {
2776
+ const nextCol = nextColumns[index];
2777
+ const prevName = prevCol == null ? void 0 : prevCol.name;
2778
+ const nextName = nextCol == null ? void 0 : nextCol.name;
2779
+ if (prevName && nextName && prevName !== nextName && Object.prototype.hasOwnProperty.call(row, prevName)) {
2780
+ nextRow[nextName] = row[prevName];
2781
+ delete nextRow[prevName];
2782
+ }
2783
+ });
2784
+ return nextRow;
2785
+ });
2786
+ onColumnsChange(nextColumns);
2787
+ if (migrated.length) {
2788
+ onChange(migrated);
2789
+ }
2790
+ };
2791
+ return /*#__PURE__*/jsxs("div", {
2792
+ className: style['options-editor'],
2793
+ children: [/*#__PURE__*/jsx(ColumnsEditor, {
2794
+ value: _columns2,
2795
+ onChange: handleColumnsChange
2796
+ }), /*#__PURE__*/jsx(TableRowsEditor, {
2797
+ columns: _columns2,
2798
+ value: _value4,
2799
+ onChange: onChange
2800
+ })]
2801
+ });
2802
+ }
2803
+ return /*#__PURE__*/jsx(FormInfo, {
2804
+ title: formatMessage({
2805
+ id: 'fieldOptions'
2806
+ }),
2807
+ column: 1,
2808
+ list: [/*#__PURE__*/jsxs("div", {
2809
+ block: true,
2810
+ className: style['options-editor'],
2811
+ children: [_allowChildren ? /*#__PURE__*/jsx(TreeOptionsEditor, {
2812
+ value: _value4,
2813
+ onChange: onChange,
2814
+ allowDescription: _allowDescription
2815
+ }) : /*#__PURE__*/jsx(FlatOptionRows, {
2816
+ list: _value4.length ? _value4 : [EMPTY_OPTION()],
2817
+ onChange: onChange,
2818
+ allowDescription: _allowDescription
2819
+ }), /*#__PURE__*/jsx(Space, {
2820
+ size: 4,
2821
+ className: style['options-tip'],
2822
+ children: formatMessage({
2823
+ id: _allowChildren ? 'optionsTreeEditorHint' : 'optionsEditorHint'
2824
+ })
2825
+ })]
2826
+ }, "options-editor")]
2827
+ });
2828
+ };
2829
+
2830
+ const SuperSelectPropsEditor = ({
2831
+ definition
2832
+ }) => {
2833
+ const {
2834
+ formatMessage
2835
+ } = useIntl();
2836
+ const {
2837
+ openApi
2838
+ } = useFormContext();
2839
+ const list = useMemo(() => {
2840
+ const items = [/*#__PURE__*/jsx(Checkbox, {
2841
+ name: "single",
2842
+ onChange: checked => {
2843
+ if (checked) {
2844
+ openApi == null || openApi.setFields == null || openApi.setFields([{
2845
+ name: 'allowSelectedAll',
2846
+ value: false
2847
+ }, {
2848
+ name: 'maxLength',
2849
+ value: undefined
2850
+ }], {
2851
+ runValidate: false
2852
+ });
2853
+ }
2854
+ },
2855
+ children: formatMessage({
2856
+ id: 'superSelectSingle'
2857
+ })
2858
+ }, "single"), /*#__PURE__*/jsx(Checkbox, {
2859
+ name: "isPopup",
2860
+ children: formatMessage({
2861
+ id: 'superSelectIsPopup'
2862
+ })
2863
+ }, "isPopup"), /*#__PURE__*/jsx(Checkbox, {
2864
+ name: "allowClear",
2865
+ children: formatMessage({
2866
+ id: 'superSelectAllowClear'
2867
+ })
2868
+ }, "allowClear"), /*#__PURE__*/jsx(Checkbox, {
2869
+ name: "allowSelectedAll",
2870
+ display: ({
2871
+ openApi
2872
+ }) => {
2873
+ var _openApi$data;
2874
+ return !(openApi != null && (_openApi$data = openApi.data) != null && _openApi$data.single);
2875
+ },
2876
+ children: formatMessage({
2877
+ id: 'superSelectAllowSelectedAll'
2878
+ })
2879
+ }, "allowSelectedAll")];
2880
+ if (definition != null && definition.hasOnlyLastLevel) {
2881
+ items.push(/*#__PURE__*/jsx(Checkbox, {
2882
+ name: "onlyAllowLastLevel",
2883
+ children: formatMessage({
2884
+ id: 'superSelectOnlyLastLevel'
2885
+ })
2886
+ }, "onlyAllowLastLevel"));
2887
+ }
2888
+ items.push(/*#__PURE__*/jsx(InputNumber, {
2889
+ name: "maxLength",
2890
+ label: formatMessage({
2891
+ id: 'superSelectMaxLength'
2892
+ }),
2893
+ min: 1,
2894
+ placeholder: formatMessage({
2895
+ id: 'superSelectMaxLengthPlaceholder'
2896
+ }),
2897
+ display: ({
2898
+ openApi
2899
+ }) => {
2900
+ var _openApi$data2;
2901
+ return !(openApi != null && (_openApi$data2 = openApi.data) != null && _openApi$data2.single);
2902
+ }
2903
+ }, "maxLength"), /*#__PURE__*/jsx(Input, {
2904
+ name: "placeholder",
2905
+ label: formatMessage({
2906
+ id: 'fieldPlaceholder'
2907
+ }),
2908
+ placeholder: formatMessage({
2909
+ id: 'superSelectPlaceholderHint'
2910
+ })
2911
+ }, "placeholder"), /*#__PURE__*/jsx(Input, {
2912
+ name: "searchPlaceholder",
2913
+ label: formatMessage({
2914
+ id: 'superSelectSearchPlaceholder'
2915
+ }),
2916
+ placeholder: formatMessage({
2917
+ id: 'superSelectSearchPlaceholderHint'
2918
+ })
2919
+ }, "searchPlaceholder"));
2920
+ return items;
2921
+ }, [definition, formatMessage, openApi]);
2922
+ return /*#__PURE__*/jsx(FormInfo, {
2923
+ title: formatMessage({
2924
+ id: 'superSelectPropsSection'
2925
+ }),
2926
+ column: 1,
2927
+ list: list
2928
+ });
2929
+ };
2930
+
2931
+ const BUILTIN_PROP_TYPES = ['Input', 'TextArea', 'InputNumber', 'Select', 'DatePicker', 'Switch'];
2932
+ const buildPropsSchemaList = (schema, formatMessage) => (schema || []).filter(item => item == null ? void 0 : item.name).map(item => {
2933
+ if (item.type === 'boolean') {
2934
+ return /*#__PURE__*/jsx(Checkbox, {
2935
+ name: item.name,
2936
+ children: item.label || item.name
2937
+ }, item.name);
2938
+ }
2939
+ if (item.type === 'number') {
2940
+ return /*#__PURE__*/jsx(InputNumber, {
2941
+ name: item.name,
2942
+ label: item.label || item.name,
2943
+ min: item.min,
2944
+ max: item.max,
2945
+ placeholder: item.placeholder || formatMessage({
2946
+ id: 'propOptionalNumber'
2947
+ })
2948
+ }, item.name);
2949
+ }
2950
+ if (item.type === 'select') {
2951
+ return /*#__PURE__*/jsx(Select, {
2952
+ name: item.name,
2953
+ label: item.label || item.name,
2954
+ options: item.options || [],
2955
+ placeholder: item.placeholder,
2956
+ allowClear: item.allowClear !== false
2957
+ }, item.name);
2958
+ }
2959
+ return /*#__PURE__*/jsx(Input, {
2960
+ name: item.name,
2961
+ label: item.label || item.name,
2962
+ placeholder: item.placeholder
2963
+ }, item.name);
2964
+ });
2965
+ const buildBuiltinList = (type, formatMessage) => {
2966
+ const placeholder = /*#__PURE__*/jsx(Input, {
2967
+ name: "placeholder",
2968
+ label: formatMessage({
2969
+ id: 'fieldPlaceholder'
2970
+ }),
2971
+ placeholder: formatMessage({
2972
+ id: 'fieldPlaceholderHint'
2973
+ })
2974
+ }, "placeholder");
2975
+ const allowClear = /*#__PURE__*/jsx(Checkbox, {
2976
+ name: "allowClear",
2977
+ children: formatMessage({
2978
+ id: 'propAllowClear'
2979
+ })
2980
+ }, "allowClear");
2981
+ switch (type) {
2982
+ case 'Input':
2983
+ return [placeholder, allowClear, /*#__PURE__*/jsx(InputNumber, {
2984
+ name: "maxLength",
2985
+ label: formatMessage({
2986
+ id: 'propMaxLength'
2987
+ }),
2988
+ min: 1,
2989
+ placeholder: formatMessage({
2990
+ id: 'propOptionalNumber'
2991
+ })
2992
+ }, "maxLength")];
2993
+ case 'TextArea':
2994
+ return [placeholder, /*#__PURE__*/jsx(InputNumber, {
2995
+ name: "rows",
2996
+ label: formatMessage({
2997
+ id: 'propRows'
2998
+ }),
2999
+ min: 2,
3000
+ max: 20
3001
+ }, "rows"), /*#__PURE__*/jsx(InputNumber, {
3002
+ name: "maxLength",
3003
+ label: formatMessage({
3004
+ id: 'propMaxLength'
3005
+ }),
3006
+ min: 1,
3007
+ placeholder: formatMessage({
3008
+ id: 'propOptionalNumber'
3009
+ })
3010
+ }, "maxLength"), /*#__PURE__*/jsx(Checkbox, {
3011
+ name: "showCount",
3012
+ children: formatMessage({
3013
+ id: 'propShowCount'
3014
+ })
3015
+ }, "showCount")];
3016
+ case 'InputNumber':
3017
+ return [placeholder, /*#__PURE__*/jsx(InputNumber, {
3018
+ name: "min",
3019
+ label: formatMessage({
3020
+ id: 'propMin'
3021
+ }),
3022
+ placeholder: formatMessage({
3023
+ id: 'propOptionalNumber'
3024
+ })
3025
+ }, "min"), /*#__PURE__*/jsx(InputNumber, {
3026
+ name: "max",
3027
+ label: formatMessage({
3028
+ id: 'propMax'
3029
+ }),
3030
+ placeholder: formatMessage({
3031
+ id: 'propOptionalNumber'
3032
+ })
3033
+ }, "max"), /*#__PURE__*/jsx(InputNumber, {
3034
+ name: "step",
3035
+ label: formatMessage({
3036
+ id: 'propStep'
3037
+ }),
3038
+ min: 0,
3039
+ placeholder: formatMessage({
3040
+ id: 'propOptionalNumber'
3041
+ })
3042
+ }, "step"), /*#__PURE__*/jsx(InputNumber, {
3043
+ name: "precision",
3044
+ label: formatMessage({
3045
+ id: 'propPrecision'
3046
+ }),
3047
+ min: 0,
3048
+ max: 10,
3049
+ placeholder: formatMessage({
3050
+ id: 'propOptionalNumber'
3051
+ })
3052
+ }, "precision")];
3053
+ case 'Select':
3054
+ return [placeholder, allowClear, /*#__PURE__*/jsx(Select, {
3055
+ name: "mode",
3056
+ label: formatMessage({
3057
+ id: 'propSelectMode'
3058
+ }),
3059
+ options: [{
3060
+ label: formatMessage({
3061
+ id: 'propSelectModeSingle'
3062
+ }),
3063
+ value: 'single'
3064
+ }, {
3065
+ label: formatMessage({
3066
+ id: 'propSelectModeMultiple'
3067
+ }),
3068
+ value: 'multiple'
3069
+ }]
3070
+ }, "mode")];
3071
+ case 'DatePicker':
3072
+ return [/*#__PURE__*/jsx(Checkbox, {
3073
+ name: "range",
3074
+ children: formatMessage({
3075
+ id: 'propDateRange'
3076
+ })
3077
+ }, "range"), placeholder, allowClear, /*#__PURE__*/jsx(Select, {
3078
+ name: "picker",
3079
+ label: formatMessage({
3080
+ id: 'propDatePickerType'
3081
+ }),
3082
+ options: [{
3083
+ label: formatMessage({
3084
+ id: 'propDatePickerDate'
3085
+ }),
3086
+ value: 'date'
3087
+ }, {
3088
+ label: formatMessage({
3089
+ id: 'propDatePickerWeek'
3090
+ }),
3091
+ value: 'week'
3092
+ }, {
3093
+ label: formatMessage({
3094
+ id: 'propDatePickerMonth'
3095
+ }),
3096
+ value: 'month'
3097
+ }, {
3098
+ label: formatMessage({
3099
+ id: 'propDatePickerQuarter'
3100
+ }),
3101
+ value: 'quarter'
3102
+ }, {
3103
+ label: formatMessage({
3104
+ id: 'propDatePickerYear'
3105
+ }),
3106
+ value: 'year'
3107
+ }]
3108
+ }, "picker"), /*#__PURE__*/jsx(Select, {
3109
+ name: "format",
3110
+ label: formatMessage({
3111
+ id: 'propDateFormat'
3112
+ }),
3113
+ options: [{
3114
+ label: 'YYYY-MM-DD',
3115
+ value: 'YYYY-MM-DD'
3116
+ }, {
3117
+ label: 'YYYY/MM/DD',
3118
+ value: 'YYYY/MM/DD'
3119
+ }, {
3120
+ label: 'YYYY年MM月DD日',
3121
+ value: 'YYYY年MM月DD日'
3122
+ }, {
3123
+ label: 'YYYY-MM-DD HH:mm:ss',
3124
+ value: 'YYYY-MM-DD HH:mm:ss'
3125
+ }, {
3126
+ label: 'YYYY-MM',
3127
+ value: 'YYYY-MM'
3128
+ }, {
3129
+ label: 'YYYY',
3130
+ value: 'YYYY'
3131
+ }]
3132
+ }, "format"), /*#__PURE__*/jsx(Checkbox, {
3133
+ name: "showTime",
3134
+ display: ({
3135
+ openApi
3136
+ }) => {
3137
+ var _openApi$data;
3138
+ return ((openApi == null || (_openApi$data = openApi.data) == null ? void 0 : _openApi$data.picker) || 'date') === 'date';
3139
+ },
3140
+ children: formatMessage({
3141
+ id: 'propShowTime'
3142
+ })
3143
+ }, "showTime")];
3144
+ case 'Switch':
3145
+ return [/*#__PURE__*/jsx(Input, {
3146
+ name: "checkedChildren",
3147
+ label: formatMessage({
3148
+ id: 'propSwitchOnText'
3149
+ }),
3150
+ placeholder: formatMessage({
3151
+ id: 'propSwitchOnTextHint'
3152
+ })
3153
+ }, "checkedChildren"), /*#__PURE__*/jsx(Input, {
3154
+ name: "unCheckedChildren",
3155
+ label: formatMessage({
3156
+ id: 'propSwitchOffText'
3157
+ }),
3158
+ placeholder: formatMessage({
3159
+ id: 'propSwitchOffTextHint'
3160
+ })
3161
+ }, "unCheckedChildren")];
3162
+ default:
3163
+ return [];
3164
+ }
3165
+ };
3166
+ const FieldPropsEditor = ({
3167
+ type,
3168
+ definition: definitionProp
3169
+ }) => {
3170
+ const {
3171
+ formatMessage
3172
+ } = useIntl();
3173
+ const definition = definitionProp || getFieldDefinition(type);
3174
+ const list = useMemo(() => {
3175
+ var _definition$propsSche;
3176
+ if (!type) {
3177
+ return [];
3178
+ }
3179
+ if (definition != null && (_definition$propsSche = definition.propsSchema) != null && _definition$propsSche.length) {
3180
+ return buildPropsSchemaList(definition.propsSchema, formatMessage);
3181
+ }
3182
+ return buildBuiltinList(type, formatMessage);
3183
+ }, [type, definition, formatMessage]);
3184
+ if (!list.length) {
3185
+ return null;
3186
+ }
3187
+ return /*#__PURE__*/jsx(FormInfo, {
3188
+ title: formatMessage({
3189
+ id: 'fieldPropsSection'
3190
+ }),
3191
+ column: 1,
3192
+ list: list
3193
+ });
3194
+ };
3195
+ const hasFieldPropsEditor = (type, definition) => {
3196
+ var _def$propsSchema;
3197
+ const def = definition || getFieldDefinition(type);
3198
+ if (def != null && (_def$propsSchema = def.propsSchema) != null && _def$propsSchema.length) {
3199
+ return true;
3200
+ }
3201
+ return BUILTIN_PROP_TYPES.includes(type);
3202
+ };
3203
+
3204
+ const _excluded = ["columns"];
3205
+ const {
3206
+ Text
3207
+ } = Typography;
3208
+ const getDefaultSelectProps = () => ({
3209
+ single: false,
3210
+ isPopup: true,
3211
+ allowClear: true,
3212
+ allowSelectedAll: false,
3213
+ onlyAllowLastLevel: false,
3214
+ maxLength: undefined,
3215
+ placeholder: '',
3216
+ searchPlaceholder: '',
3217
+ columns: [createEmptyColumn()]
3218
+ });
3219
+ const omitColumns = (_ref = {}) => {
3220
+ let rest = _objectWithoutPropertiesLoose(_ref, _excluded);
3221
+ return rest;
3222
+ };
3223
+ const FieldConfigFields = ({
3224
+ initialType,
3225
+ options,
3226
+ onOptionsChange,
3227
+ columns,
3228
+ onColumnsChange
3229
+ }) => {
3230
+ const {
3231
+ formatMessage
3232
+ } = useIntl();
3233
+ const {
3234
+ openApi
3235
+ } = useFormContext();
3236
+ const [fieldType, setFieldType] = useState(initialType);
3237
+ const fieldTypeOptions = useMemo(() => getFieldTypes(), []);
3238
+ const definition = getFieldDefinition(fieldType);
3239
+ useEffect(() => {
3240
+ setFieldType(initialType);
3241
+ }, [initialType]);
3242
+ const applyTypeDefaults = nextType => {
3243
+ var _nextDefinition$props;
3244
+ const nextDefinition = getFieldDefinition(nextType);
3245
+ let nextValues = {};
3246
+ if (nextDefinition != null && nextDefinition.isSuperSelect) {
3247
+ nextValues = omitColumns(getDefaultSelectProps());
3248
+ } else if (nextDefinition != null && nextDefinition.hasFieldProps || nextDefinition != null && (_nextDefinition$props = nextDefinition.propsSchema) != null && _nextDefinition$props.length) {
3249
+ nextValues = pickFieldProps({
3250
+ type: nextType,
3251
+ props: nextDefinition.defaultProps || {}
3252
+ }, nextDefinition);
3253
+ }
3254
+ const entries = Object.entries(nextValues).map(([name, value]) => ({
3255
+ name,
3256
+ value
3257
+ }));
3258
+ if (!entries.length || !(openApi != null && openApi.setFields)) {
3259
+ return;
3260
+ }
3261
+ // 等新类型的 Form Field 挂载后再写入默认值
3262
+ requestAnimationFrame(() => {
3263
+ openApi.setFields(entries, {
3264
+ runValidate: false
3265
+ });
3266
+ });
3267
+ };
3268
+ const list = [/*#__PURE__*/jsx(Select, {
3269
+ name: "type",
3270
+ label: formatMessage({
3271
+ id: 'fieldType'
3272
+ }),
3273
+ rule: "REQ",
3274
+ options: fieldTypeOptions,
3275
+ onChange: nextType => {
3276
+ setFieldType(nextType);
3277
+ applyTypeDefaults(nextType);
3278
+ }
3279
+ }, "type"), /*#__PURE__*/jsx(Input, {
3280
+ name: "name",
3281
+ label: formatMessage({
3282
+ id: 'fieldName'
3283
+ }),
3284
+ rule: "REQ",
3285
+ placeholder: formatMessage({
3286
+ id: 'fieldNamePlaceholder'
3287
+ })
3288
+ }, "name"), /*#__PURE__*/jsx(Input, {
3289
+ name: "label",
3290
+ label: formatMessage({
3291
+ id: 'fieldLabel'
3292
+ }),
3293
+ rule: "REQ",
3294
+ placeholder: formatMessage({
3295
+ id: 'fieldLabelPlaceholder'
3296
+ })
3297
+ }, "label"), /*#__PURE__*/jsx(Input, {
3298
+ name: "tips",
3299
+ label: formatMessage({
3300
+ id: 'fieldTips'
3301
+ }),
3302
+ placeholder: formatMessage({
3303
+ id: 'fieldTipsPlaceholder'
3304
+ })
3305
+ }, "tips"), /*#__PURE__*/jsx(TextArea, {
3306
+ name: "description",
3307
+ label: formatMessage({
3308
+ id: 'fieldDescription'
3309
+ }),
3310
+ placeholder: formatMessage({
3311
+ id: 'fieldDescriptionPlaceholder'
3312
+ }),
3313
+ rows: 2
3314
+ }, "description")];
3315
+ list.push(/*#__PURE__*/jsx(Checkbox, {
3316
+ name: "block",
3317
+ children: formatMessage({
3318
+ id: 'fieldBlock'
3319
+ })
3320
+ }, "block"), /*#__PURE__*/jsx(Checkbox, {
3321
+ name: "hidden",
3322
+ children: formatMessage({
3323
+ id: 'fieldHidden'
3324
+ })
3325
+ }, "hidden"));
3326
+ return /*#__PURE__*/jsxs("div", {
3327
+ className: style['field-editor-form'],
3328
+ children: [/*#__PURE__*/jsx(FormInfo, {
3329
+ title: formatMessage({
3330
+ id: 'fieldBasicSection'
3331
+ }),
3332
+ column: 1,
3333
+ list: list
3334
+ }), definition != null && definition.isSuperSelect ? /*#__PURE__*/jsx(SuperSelectPropsEditor, {
3335
+ definition: definition
3336
+ }) : hasFieldPropsEditor(fieldType, definition) ? /*#__PURE__*/jsx(FieldPropsEditor, {
3337
+ type: fieldType,
3338
+ definition: definition
3339
+ }) : null, /*#__PURE__*/jsx(RulePresetEditor, {}), definition != null && definition.hasBuiltinData ? /*#__PURE__*/jsx(Text, {
3340
+ type: "secondary",
3341
+ children: formatMessage({
3342
+ id: 'builtinDataHint'
3343
+ })
3344
+ }) : definition != null && definition.hasOptions ? /*#__PURE__*/jsx(OptionsEditor, {
3345
+ value: options,
3346
+ onChange: onOptionsChange,
3347
+ allowDescription: definition.optionsAllowDescription,
3348
+ allowChildren: definition.optionsAllowChildren,
3349
+ hasColumns: definition.hasColumns,
3350
+ columns: columns,
3351
+ onColumnsChange: onColumnsChange
3352
+ }) : null]
3353
+ });
3354
+ };
3355
+ const FieldEditorModal = ({
3356
+ open,
3357
+ field,
3358
+ fieldList,
3359
+ onCancel,
3360
+ onSave,
3361
+ renderModal
3362
+ }) => {
3363
+ const {
3364
+ formatMessage
3365
+ } = useIntl();
3366
+ const isMobile = useIsMobile();
3367
+ const isEdit = !!(field != null && field.id);
3368
+ const editorValues = useMemo(() => fieldToFormValues(field || createField$1()), [field, open]);
3369
+ const formData = useMemo(() => {
3370
+ const ruleConfig = editorValues.ruleConfig || {
3371
+ presets: [],
3372
+ lenMin: '',
3373
+ lenMax: ''
3374
+ };
3375
+ return _extends({
3376
+ type: editorValues.type,
3377
+ name: editorValues.name,
3378
+ label: editorValues.label,
3379
+ tips: editorValues.tips,
3380
+ description: editorValues.description,
3381
+ block: editorValues.block,
3382
+ hidden: editorValues.hidden
3383
+ }, editorValues.fieldProps || {}, omitColumns(editorValues.selectProps || {}), {
3384
+ rulePresets: ruleConfig.presets || [],
3385
+ lenMin: ruleConfig.lenMin === '' ? undefined : ruleConfig.lenMin,
3386
+ lenMax: ruleConfig.lenMax === '' ? undefined : ruleConfig.lenMax
3387
+ });
3388
+ }, [editorValues]);
3389
+ const [options, setOptions] = useState([{
3390
+ label: '',
3391
+ value: ''
3392
+ }]);
3393
+ const [columns, setColumns] = useState(() => [createEmptyColumn()]);
3394
+ useEffect(() => {
3395
+ var _editorValues$options, _editorValues$selectP;
3396
+ if (!open) {
3397
+ return;
3398
+ }
3399
+ setOptions((_editorValues$options = editorValues.options) != null && _editorValues$options.length ? editorValues.options : [{
3400
+ label: '',
3401
+ value: ''
3402
+ }]);
3403
+ setColumns((_editorValues$selectP = editorValues.selectProps) != null && (_editorValues$selectP = _editorValues$selectP.columns) != null && _editorValues$selectP.length ? editorValues.selectProps.columns : [createEmptyColumn()]);
3404
+ }, [open, editorValues]);
3405
+ const handleSubmit = async values => {
3406
+ var _values$lenMin, _values$lenMax;
3407
+ if (!isFieldNameUnique(fieldList, values.name, field == null ? void 0 : field.id)) {
3408
+ message.error(formatMessage({
3409
+ id: 'fieldNameDuplicate'
3410
+ }));
3411
+ return false;
3412
+ }
3413
+ const definition = getFieldDefinition(values.type);
3414
+ const normalizedColumns = definition != null && definition.hasColumns ? normalizeColumns(columns) : [];
3415
+ const nextField = formValuesToField(_extends({}, values, {
3416
+ ruleConfig: {
3417
+ presets: values.rulePresets || [],
3418
+ lenMin: (_values$lenMin = values.lenMin) != null ? _values$lenMin : '',
3419
+ lenMax: (_values$lenMax = values.lenMax) != null ? _values$lenMax : ''
3420
+ },
3421
+ options: normalizeOptions(options, {
3422
+ allowChildren: !!(definition != null && definition.optionsAllowChildren),
3423
+ columns: normalizedColumns
3424
+ }),
3425
+ selectProps: _extends({}, values, {
3426
+ columns: normalizedColumns
3427
+ }),
3428
+ fieldProps: values
3429
+ }), field || createField$1());
3430
+ if (!nextField.id) {
3431
+ nextField.id = createField$1().id;
3432
+ }
3433
+ onSave(nextField);
3434
+ };
3435
+ const modalKey = open ? field != null && field.id ? `edit-${field.id}` : `add-${formData.name}` : 'closed';
3436
+ return /*#__PURE__*/jsx(FormModal, _extends({
3437
+ destroyOnHidden: true,
3438
+ destroyOnClose: true,
3439
+ title: formatMessage({
3440
+ id: isEdit ? 'editField' : 'addField'
3441
+ }),
3442
+ open: open,
3443
+ onCancel: onCancel,
3444
+ width: isMobile ? 'calc(100vw - 32px)' : 760
3445
+ }, renderModal ? {
3446
+ renderModal
3447
+ } : {}, {
3448
+ formProps: {
3449
+ data: formData,
3450
+ onSubmit: handleSubmit
3451
+ },
3452
+ okText: formatMessage({
3453
+ id: 'confirm'
3454
+ }),
3455
+ cancelText: formatMessage({
3456
+ id: 'cancel'
3457
+ }),
3458
+ children: /*#__PURE__*/jsx(FieldConfigFields, {
3459
+ initialType: formData.type,
3460
+ options: options,
3461
+ onOptionsChange: setOptions,
3462
+ columns: columns,
3463
+ onColumnsChange: setColumns
3464
+ })
3465
+ }), modalKey);
3466
+ };
3467
+
3468
+ const FormActionsEditor = ({
3469
+ open,
3470
+ value,
3471
+ onCancel,
3472
+ onSave,
3473
+ renderModal
3474
+ }) => {
3475
+ const {
3476
+ formatMessage
3477
+ } = useIntl();
3478
+ const isMobile = useIsMobile();
3479
+ const formData = useMemo(() => normalizeFormActions(value), [value, open]);
3480
+ const alignOptions = useMemo(() => [{
3481
+ label: formatMessage({
3482
+ id: 'formActionsAlignStart'
3483
+ }),
3484
+ value: 'start'
3485
+ }, {
3486
+ label: formatMessage({
3487
+ id: 'formActionsAlignCenter'
3488
+ }),
3489
+ value: 'center'
3490
+ }, {
3491
+ label: formatMessage({
3492
+ id: 'formActionsAlignEnd'
3493
+ }),
3494
+ value: 'end'
3495
+ }], [formatMessage]);
3496
+ const gapMarks = useMemo(() => ({
3497
+ 0: '0',
3498
+ 16: '16',
3499
+ 32: '32',
3500
+ 48: '48',
3501
+ 64: '64'
3502
+ }), []);
3503
+ return /*#__PURE__*/jsx(FormModal, _extends({
3504
+ destroyOnHidden: true,
3505
+ destroyOnClose: true,
3506
+ title: formatMessage({
3507
+ id: 'formActionsSection'
3508
+ }),
3509
+ open: open,
3510
+ onCancel: onCancel,
3511
+ width: isMobile ? 'calc(100vw - 32px)' : 520
3512
+ }, renderModal ? {
3513
+ renderModal
3514
+ } : {}, {
3515
+ formProps: {
3516
+ data: formData,
3517
+ onSubmit: values => {
3518
+ onSave == null || onSave(normalizeFormActions(values));
3519
+ }
3520
+ },
3521
+ okText: formatMessage({
3522
+ id: 'confirm'
3523
+ }),
3524
+ cancelText: formatMessage({
3525
+ id: 'cancel'
3526
+ }),
3527
+ children: /*#__PURE__*/jsxs("div", {
3528
+ className: style['form-actions-editor'],
3529
+ children: [/*#__PURE__*/jsx(FormInfo, {
3530
+ column: 2,
3531
+ list: [/*#__PURE__*/jsx(Switch, {
3532
+ name: "showSubmit",
3533
+ label: formatMessage({
3534
+ id: 'formActionsShowSubmit'
3535
+ }),
3536
+ className: style['form-actions-switch-field']
3537
+ }, "showSubmit"), /*#__PURE__*/jsx(Input, {
3538
+ name: "submitText",
3539
+ label: formatMessage({
3540
+ id: 'formActionsSubmitText'
3541
+ }),
3542
+ placeholder: formatMessage({
3543
+ id: 'formActionsSubmitTextHint'
3544
+ }),
3545
+ display: ({
3546
+ openApi
3547
+ }) => {
3548
+ var _openApi$data;
3549
+ return Boolean(openApi == null || (_openApi$data = openApi.data) == null ? void 0 : _openApi$data.showSubmit);
3550
+ }
3551
+ }, "submitText")]
3552
+ }), /*#__PURE__*/jsx(FormInfo, {
3553
+ column: 2,
3554
+ list: [/*#__PURE__*/jsx(Switch, {
3555
+ name: "showReset",
3556
+ label: formatMessage({
3557
+ id: 'formActionsShowReset'
3558
+ }),
3559
+ className: style['form-actions-switch-field']
3560
+ }, "showReset"), /*#__PURE__*/jsx(Input, {
3561
+ name: "resetText",
3562
+ label: formatMessage({
3563
+ id: 'formActionsResetText'
3564
+ }),
3565
+ placeholder: formatMessage({
3566
+ id: 'formActionsResetTextHint'
3567
+ }),
3568
+ display: ({
3569
+ openApi
3570
+ }) => {
3571
+ var _openApi$data2;
3572
+ return Boolean(openApi == null || (_openApi$data2 = openApi.data) == null ? void 0 : _openApi$data2.showReset);
3573
+ }
3574
+ }, "resetText")]
3575
+ }), /*#__PURE__*/jsx(FormInfo, {
3576
+ column: 2,
3577
+ list: [/*#__PURE__*/jsx(Switch, {
3578
+ name: "showCancel",
3579
+ label: formatMessage({
3580
+ id: 'formActionsShowCancel'
3581
+ }),
3582
+ className: style['form-actions-switch-field']
3583
+ }, "showCancel"), /*#__PURE__*/jsx(Input, {
3584
+ name: "cancelText",
3585
+ label: formatMessage({
3586
+ id: 'formActionsCancelText'
3587
+ }),
3588
+ placeholder: formatMessage({
3589
+ id: 'formActionsCancelTextHint'
3590
+ }),
3591
+ display: ({
3592
+ openApi
3593
+ }) => {
3594
+ var _openApi$data3;
3595
+ return Boolean(openApi == null || (_openApi$data3 = openApi.data) == null ? void 0 : _openApi$data3.showCancel);
3596
+ }
3597
+ }, "cancelText")]
3598
+ }), /*#__PURE__*/jsxs("div", {
3599
+ className: style['form-actions-layout-panel'],
3600
+ children: [/*#__PURE__*/jsx("div", {
3601
+ className: style['form-actions-layout-title'],
3602
+ children: formatMessage({
3603
+ id: 'formActionsLayoutSection'
3604
+ })
3605
+ }), /*#__PURE__*/jsx(FormInfo, {
3606
+ column: 1,
3607
+ list: [/*#__PURE__*/jsx(RadioGroup, {
3608
+ name: "align",
3609
+ label: formatMessage({
3610
+ id: 'formActionsAlign'
3611
+ }),
3612
+ optionType: "button",
3613
+ buttonStyle: "solid",
3614
+ options: alignOptions,
3615
+ className: style['form-actions-align-group']
3616
+ }, "align"), /*#__PURE__*/jsx(Slider, {
3617
+ name: "gap",
3618
+ label: formatMessage({
3619
+ id: 'formActionsGap'
3620
+ }),
3621
+ min: 0,
3622
+ max: 64,
3623
+ step: 1,
3624
+ marks: gapMarks,
3625
+ tooltip: {
3626
+ formatter: v => `${v != null ? v : 0}px`
3627
+ },
3628
+ className: style['form-actions-gap-slider']
3629
+ }, "gap")]
3630
+ })]
3631
+ })]
3632
+ })
3633
+ }), open ? 'form-actions-open' : 'form-actions-closed');
3634
+ };
3635
+
3636
+ const buildLabelTips = tips => {
3637
+ if (tips == null || !String(tips).trim()) {
3638
+ return undefined;
3639
+ }
3640
+ return /*#__PURE__*/createElement(Tooltip, {
3641
+ title: tips
3642
+ }, /*#__PURE__*/createElement(QuestionCircleOutlined, {
3643
+ className: style['field-label-tips-icon']
3644
+ }));
3645
+ };
3646
+ const renderFieldElements = (fields = [], preview = false) => fields.filter(field => !field.hidden).map(field => {
3647
+ var _props$options;
3648
+ const Component = getFieldComponent(field.type, field);
3649
+ if (!Component) {
3650
+ return null;
3651
+ }
3652
+ const definition = getFieldDefinition(field.type);
3653
+ const props = _extends({}, field.props || {});
3654
+ if (definition != null && definition.optionsAllowDescription && (_props$options = props.options) != null && _props$options.length && !props.api && !definition.optionsAllowChildren) {
3655
+ props.api = createApiFromOptions(props.options);
3656
+ }
3657
+
3658
+ // 空字符串会盖掉 react-form-antd / SuperSelect 的默认「请输入/请选择」占位
3659
+ if (!Array.isArray(props.placeholder) && props.placeholder != null && !String(props.placeholder).trim()) {
3660
+ delete props.placeholder;
3661
+ }
3662
+
3663
+ // schema 内部标记,不传给 antd
3664
+ delete props.range;
3665
+ const description = field.description != null && String(field.description).trim() ? field.description : undefined;
3666
+ return /*#__PURE__*/createElement(Component, _extends({
3667
+ key: field.id,
3668
+ name: field.name,
3669
+ label: field.label,
3670
+ rule: field.rule || undefined,
3671
+ block: field.block || undefined
3672
+ }, props, {
3673
+ labelTips: buildLabelTips(field.tips),
3674
+ description
3675
+ }));
3676
+ }).filter(Boolean);
3677
+ const renderBlockElement = (block, preview = false, {
3678
+ isMobile: _isMobile = false,
3679
+ formatMessage
3680
+ } = {}) => {
3681
+ const fields = renderFieldElements(block.list, preview);
3682
+ const bordered = _isMobile ? false : block.bordered || undefined;
3683
+ switch (block.kind) {
3684
+ case 'formInfo':
3685
+ return /*#__PURE__*/createElement(FormInfo, {
3686
+ key: block.id,
3687
+ title: block.title || undefined,
3688
+ subtitle: block.subtitle || undefined,
3689
+ column: block.column,
3690
+ gap: block.gap,
3691
+ bordered,
3692
+ list: fields
3693
+ });
3694
+ case 'list':
3695
+ return /*#__PURE__*/createElement(List, _extends({
3696
+ key: block.id,
3697
+ name: block.name,
3698
+ title: block.title || undefined,
3699
+ important: block.important || undefined,
3700
+ bordered,
3701
+ maxLength: block.maxLength,
3702
+ minLength: block.minLength
3703
+ }, block.addText ? {
3704
+ addText: block.addText
3705
+ } : {}, typeof block.itemTitle === 'function' || block.itemTitle ? {
3706
+ itemTitle: block.itemTitle
3707
+ } : {}, {
3708
+ list: fields
3709
+ }));
3710
+ case 'tableList':
3711
+ return /*#__PURE__*/createElement(TableList, _extends({
3712
+ key: block.id,
3713
+ name: block.name,
3714
+ title: block.title || undefined,
3715
+ bordered,
3716
+ maxLength: block.maxLength,
3717
+ minLength: block.minLength
3718
+ }, block.addText ? {
3719
+ addText: block.addText
3720
+ } : {}, {
3721
+ list: fields
3722
+ }));
3723
+ case 'multiField':
3724
+ {
3725
+ const FieldComponent = getFieldComponent(block.fieldType);
3726
+ if (!FieldComponent) {
3727
+ return null;
3728
+ }
3729
+ return /*#__PURE__*/createElement(MultiField, _extends({
3730
+ key: block.id,
3731
+ name: block.name,
3732
+ label: block.label,
3733
+ field: FieldComponent,
3734
+ block: block.block || undefined
3735
+ }, block.addText ? {
3736
+ addText: block.addText
3737
+ } : {}));
3738
+ }
3739
+ case 'steps':
3740
+ {
3741
+ const _bordered = _isMobile ? false : block.bordered || undefined;
3742
+ return /*#__PURE__*/createElement(Steps, {
3743
+ key: block.id,
3744
+ title: block.title || undefined,
3745
+ subtitle: block.subtitle || undefined,
3746
+ bordered: _bordered,
3747
+ items: (block.items || []).map(step => ({
3748
+ key: step.id,
3749
+ title: step.title,
3750
+ column: step.column,
3751
+ gap: block.gap,
3752
+ list: renderFieldElements(step.list, preview),
3753
+ fieldNames: (step.list || []).filter(field => field && !field.hidden && field.name).map(field => field.name)
3754
+ }))
3755
+ });
3756
+ }
3757
+ default:
3758
+ return null;
3759
+ }
3760
+ };
3761
+ const renderSchemaInner = (schema, {
3762
+ preview: _preview = false,
3763
+ className,
3764
+ isMobile: _isMobile2 = false,
3765
+ formatMessage,
3766
+ children,
3767
+ actionNode
3768
+ } = {}) => {
3769
+ const normalized = normalizeSchema(schema);
3770
+ const blocks = normalized.blocks || [];
3771
+ const contentChildren = blocks.map(block => renderBlockElement(block, _preview, {
3772
+ isMobile: _isMobile2,
3773
+ formatMessage
3774
+ })).filter(Boolean);
3775
+ if (!contentChildren.length && !children && !actionNode) {
3776
+ return null;
3777
+ }
3778
+ const body = /*#__PURE__*/createElement(Fragment, null, ...contentChildren, children, actionNode || null);
3779
+ return className ? /*#__PURE__*/createElement('div', {
3780
+ className
3781
+ }, body) : body;
3782
+ };
3783
+ const renderSchemaContent = (schema, {
3784
+ preview: _preview2 = false,
3785
+ formProps: _formProps = {},
3786
+ className,
3787
+ isMobile: _isMobile3 = false,
3788
+ formatMessage,
3789
+ children,
3790
+ actionNode
3791
+ } = {}) => {
3792
+ const normalized = normalizeSchema(schema);
3793
+ const blocks = normalized.blocks || [];
3794
+ const contentChildren = blocks.map(block => renderBlockElement(block, _preview2, {
3795
+ isMobile: _isMobile3,
3796
+ formatMessage
3797
+ })).filter(Boolean);
3798
+ if (!contentChildren.length && !children) {
3799
+ return null;
3800
+ }
3801
+ const formClassName = [style['schema-form'], _formProps.className, className].filter(Boolean).join(' ');
3802
+ return /*#__PURE__*/createElement(Form, _extends({}, _formProps, {
3803
+ className: formClassName
3804
+ }), /*#__PURE__*/createElement('div', {
3805
+ className: style['schema-body']
3806
+ }, ...contentChildren, children), actionNode || null);
3807
+ };
3808
+
3809
+ const resolveActionNode = ({
3810
+ schema,
3811
+ formatMessage,
3812
+ actions,
3813
+ showActions: _showActions = true,
3814
+ submitText,
3815
+ resetText,
3816
+ cancelText,
3817
+ submitButtonProps,
3818
+ resetButtonProps,
3819
+ cancelButtonProps,
3820
+ showSubmit,
3821
+ showReset,
3822
+ showCancel,
3823
+ actionsAlign,
3824
+ actionsGap
3825
+ }) => {
3826
+ if (_showActions === false || actions === false || actions === null) {
3827
+ return null;
3828
+ }
3829
+ const normalized = normalizeSchema(schema);
3830
+ const schemaActions = normalizeFormActions(normalized.actions);
3831
+ const resolvedShowSubmit = showSubmit != null ? showSubmit : schemaActions.showSubmit;
3832
+ const resolvedShowReset = showReset != null ? showReset : schemaActions.showReset;
3833
+ const resolvedShowCancel = showCancel != null ? showCancel : schemaActions.showCancel;
3834
+ const resolvedAlign = actionsAlign || schemaActions.align || 'center';
3835
+ const resolvedGap = actionsGap != null ? actionsGap : schemaActions.gap;
3836
+ const resolvedSubmitText = (submitText != null && String(submitText).trim() ? submitText : null) || (schemaActions.submitText && String(schemaActions.submitText).trim() ? schemaActions.submitText : null) || formatMessage({
3837
+ id: 'submit'
3838
+ });
3839
+ const resolvedResetText = (resetText != null && String(resetText).trim() ? resetText : null) || (schemaActions.resetText && String(schemaActions.resetText).trim() ? schemaActions.resetText : null) || formatMessage({
3840
+ id: 'reset'
3841
+ });
3842
+ const resolvedCancelText = (cancelText != null && String(cancelText).trim() ? cancelText : null) || (schemaActions.cancelText && String(schemaActions.cancelText).trim() ? schemaActions.cancelText : null) || formatMessage({
3843
+ id: 'cancel'
3844
+ });
3845
+ const resolvedSubmitButtonProps = _extends({}, schemaActions.submitButtonProps || {}, submitButtonProps || {});
3846
+ const resolvedResetButtonProps = _extends({}, schemaActions.resetButtonProps || {}, resetButtonProps || {});
3847
+ const resolvedCancelButtonProps = _extends({}, schemaActions.cancelButtonProps || {}, cancelButtonProps || {});
3848
+ const flexProps = {
3849
+ className: style['schema-actions-inner'],
3850
+ justify: resolvedAlign,
3851
+ gap: resolvedGap != null ? resolvedGap : 16,
3852
+ wrap: 'wrap'
3853
+ };
3854
+ if (actions !== undefined) {
3855
+ return /*#__PURE__*/createElement('div', {
3856
+ className: style['schema-actions']
3857
+ }, /*#__PURE__*/createElement(Flex, flexProps, actions));
3858
+ }
3859
+ if (!resolvedShowSubmit && !resolvedShowReset && !resolvedShowCancel) {
3860
+ return null;
3861
+ }
3862
+ return /*#__PURE__*/createElement('div', {
3863
+ className: style['schema-actions']
3864
+ }, /*#__PURE__*/createElement(Flex, flexProps, resolvedShowSubmit ? /*#__PURE__*/createElement(SubmitButton, _extends({
3865
+ type: 'primary'
3866
+ }, resolvedSubmitButtonProps), resolvedSubmitText) : null, resolvedShowReset ? /*#__PURE__*/createElement(ResetButton, resolvedResetButtonProps, resolvedResetText) : null, resolvedShowCancel ? /*#__PURE__*/createElement(CancelButton, resolvedCancelButtonProps, resolvedCancelText) : null));
3867
+ };
3868
+ const SchemaRendererInner = withLocale(props => {
3869
+ const {
3870
+ schema,
3871
+ preview = false,
3872
+ className,
3873
+ children,
3874
+ showActions = true,
3875
+ actions,
3876
+ submitText,
3877
+ resetText,
3878
+ cancelText,
3879
+ submitButtonProps,
3880
+ resetButtonProps,
3881
+ cancelButtonProps,
3882
+ showSubmit,
3883
+ showReset,
3884
+ showCancel,
3885
+ actionsAlign,
3886
+ actionsGap
3887
+ } = props;
3888
+ const {
3889
+ formatMessage
3890
+ } = useIntl();
3891
+ const isMobile = useIsMobile();
3892
+ const normalized = normalizeSchema(schema);
3893
+ if (!hasRenderableContent(normalized)) {
3894
+ return null;
3895
+ }
3896
+ const actionNode = resolveActionNode({
3897
+ schema: normalized,
3898
+ formatMessage,
3899
+ showActions,
3900
+ actions,
3901
+ submitText,
3902
+ resetText,
3903
+ cancelText,
3904
+ submitButtonProps,
3905
+ resetButtonProps,
3906
+ cancelButtonProps,
3907
+ showSubmit,
3908
+ showReset,
3909
+ showCancel,
3910
+ actionsAlign,
3911
+ actionsGap
3912
+ });
3913
+ return renderSchemaInner(normalized, {
3914
+ preview,
3915
+ className,
3916
+ isMobile,
3917
+ formatMessage,
3918
+ children,
3919
+ actionNode
3920
+ });
3921
+ });
3922
+ const SchemaRenderer = withLocale(props => {
3923
+ const {
3924
+ schema,
3925
+ formProps = {},
3926
+ preview = false,
3927
+ className,
3928
+ children,
3929
+ showActions = true,
3930
+ actions,
3931
+ submitText,
3932
+ resetText,
3933
+ cancelText,
3934
+ submitButtonProps,
3935
+ resetButtonProps,
3936
+ cancelButtonProps,
3937
+ showSubmit,
3938
+ showReset,
3939
+ showCancel,
3940
+ actionsAlign,
3941
+ actionsGap
3942
+ } = props;
3943
+ const {
3944
+ formatMessage
3945
+ } = useIntl();
3946
+ const isMobile = useIsMobile();
3947
+ const normalized = normalizeSchema(schema);
3948
+ if (!hasRenderableContent(normalized)) {
3949
+ return null;
3950
+ }
3951
+ const actionNode = resolveActionNode({
3952
+ schema: normalized,
3953
+ formatMessage,
3954
+ showActions,
3955
+ actions,
3956
+ submitText,
3957
+ resetText,
3958
+ cancelText,
3959
+ submitButtonProps,
3960
+ resetButtonProps,
3961
+ cancelButtonProps,
3962
+ showSubmit,
3963
+ showReset,
3964
+ showCancel,
3965
+ actionsAlign,
3966
+ actionsGap
3967
+ });
3968
+ return renderSchemaContent(normalized, {
3969
+ preview,
3970
+ formProps,
3971
+ className,
3972
+ isMobile,
3973
+ formatMessage,
3974
+ children,
3975
+ actionNode
3976
+ });
3977
+ });
3978
+
3979
+ const FormCreator = withLocale(({
3980
+ value,
3981
+ defaultValue,
3982
+ onChange,
3983
+ showPreview: _showPreview = true,
3984
+ className,
3985
+ formProps,
3986
+ renderModal
3987
+ }) => {
3988
+ const {
3989
+ formatMessage
3990
+ } = useIntl();
3991
+ const isMobile = useIsMobile();
3992
+ const [innerSchema, setInnerSchema] = useState(() => normalizeSchema(defaultValue || defaultSchema()));
3993
+ const [blockEditorOpen, setBlockEditorOpen] = useState(false);
3994
+ const [editingBlock, setEditingBlock] = useState(null);
3995
+ const [stepEditorOpen, setStepEditorOpen] = useState(false);
3996
+ const [stepContext, setStepContext] = useState(null);
3997
+ const [fieldEditorOpen, setFieldEditorOpen] = useState(false);
3998
+ const [fieldContext, setFieldContext] = useState(null);
3999
+ const [editingField, setEditingField] = useState(null);
4000
+ const [formActionsOpen, setFormActionsOpen] = useState(false);
4001
+ const schema = useMemo(() => normalizeSchema(value != null ? value : innerSchema), [value, innerSchema]);
4002
+ const updateSchema = nextSchema => {
4003
+ const normalized = normalizeSchema(nextSchema);
4004
+ if (value === undefined) {
4005
+ setInnerSchema(normalized);
4006
+ }
4007
+ onChange == null || onChange(normalized);
4008
+ };
4009
+ const handleAddBlock = kind => {
4010
+ setEditingBlock(createBlock(kind));
4011
+ setBlockEditorOpen(true);
4012
+ };
4013
+ const handleEditBlock = block => {
4014
+ setEditingBlock(block);
4015
+ setBlockEditorOpen(true);
4016
+ };
4017
+ const handleSaveBlock = block => {
4018
+ const exists = schema.blocks.some(item => item.id === block.id);
4019
+ updateSchema(_extends({}, schema, {
4020
+ blocks: exists ? schema.blocks.map(item => item.id === block.id ? block : item) : [...schema.blocks, block]
4021
+ }));
4022
+ setBlockEditorOpen(false);
4023
+ setEditingBlock(null);
4024
+ };
4025
+ const handleDeleteBlock = blockId => {
4026
+ updateSchema(_extends({}, schema, {
4027
+ blocks: schema.blocks.filter(item => item.id !== blockId)
4028
+ }));
4029
+ };
4030
+ const handleMoveBlock = (blockId, direction) => {
4031
+ updateSchema(_extends({}, schema, {
4032
+ blocks: moveItem(schema.blocks, blockId, direction)
4033
+ }));
4034
+ };
4035
+ const handleAddStep = blockId => {
4036
+ setStepContext({
4037
+ blockId,
4038
+ step: createStep()
4039
+ });
4040
+ setStepEditorOpen(true);
4041
+ };
4042
+ const handleEditStep = (blockId, step) => {
4043
+ setStepContext({
4044
+ blockId,
4045
+ step
4046
+ });
4047
+ setStepEditorOpen(true);
4048
+ };
4049
+ const handleSaveStep = step => {
4050
+ const {
4051
+ blockId
4052
+ } = stepContext;
4053
+ updateSchema(mapBlocks(schema, blockId, block => {
4054
+ const exists = (block.items || []).some(item => item.id === step.id);
4055
+ return _extends({}, block, {
4056
+ items: exists ? block.items.map(item => item.id === step.id ? step : item) : [...(block.items || []), step]
4057
+ });
4058
+ }));
4059
+ setStepEditorOpen(false);
4060
+ setStepContext(null);
4061
+ };
4062
+ const handleDeleteStep = (blockId, stepId) => {
4063
+ updateSchema(mapBlocks(schema, blockId, block => _extends({}, block, {
4064
+ items: (block.items || []).filter(item => item.id !== stepId)
4065
+ })));
4066
+ };
4067
+ const handleMoveStep = (blockId, stepId, direction) => {
4068
+ updateSchema(mapBlocks(schema, blockId, block => _extends({}, block, {
4069
+ items: moveItem(block.items || [], stepId, direction)
4070
+ })));
4071
+ };
4072
+ const handleAddField = (blockId, stepId) => {
4073
+ setFieldContext({
4074
+ blockId,
4075
+ stepId
4076
+ });
4077
+ setEditingField(null);
4078
+ setFieldEditorOpen(true);
4079
+ };
4080
+ const handleEditField = (blockId, field, stepId) => {
4081
+ setFieldContext({
4082
+ blockId,
4083
+ stepId
4084
+ });
4085
+ setEditingField(field);
4086
+ setFieldEditorOpen(true);
4087
+ };
4088
+ const handleSaveField = field => {
4089
+ const {
4090
+ blockId,
4091
+ stepId
4092
+ } = fieldContext;
4093
+ updateSchema(mapBlocks(schema, blockId, block => {
4094
+ if (block.kind === 'steps') {
4095
+ return _extends({}, block, {
4096
+ items: (block.items || []).map(step => {
4097
+ if (step.id !== stepId) {
4098
+ return step;
4099
+ }
4100
+ const exists = (step.list || []).some(item => item.id === field.id);
4101
+ return _extends({}, step, {
4102
+ list: exists ? step.list.map(item => item.id === field.id ? field : item) : [...(step.list || []), field]
4103
+ });
4104
+ })
4105
+ });
4106
+ }
4107
+ const exists = (block.list || []).some(item => item.id === field.id);
4108
+ return _extends({}, block, {
4109
+ list: exists ? block.list.map(item => item.id === field.id ? field : item) : [...(block.list || []), field]
4110
+ });
4111
+ }));
4112
+ setFieldEditorOpen(false);
4113
+ setFieldContext(null);
4114
+ setEditingField(null);
4115
+ };
4116
+ const handleDeleteField = (blockId, fieldId, stepId) => {
4117
+ updateSchema(mapBlocks(schema, blockId, block => {
4118
+ if (block.kind === 'steps') {
4119
+ return _extends({}, block, {
4120
+ items: (block.items || []).map(step => step.id === stepId ? _extends({}, step, {
4121
+ list: (step.list || []).filter(item => item.id !== fieldId)
4122
+ }) : step)
4123
+ });
4124
+ }
4125
+ return _extends({}, block, {
4126
+ list: (block.list || []).filter(item => item.id !== fieldId)
4127
+ });
4128
+ }));
4129
+ };
4130
+ const handleMoveField = (blockId, fieldId, direction, stepId) => {
4131
+ updateSchema(mapBlocks(schema, blockId, block => {
4132
+ if (block.kind === 'steps') {
4133
+ return _extends({}, block, {
4134
+ items: (block.items || []).map(step => step.id === stepId ? _extends({}, step, {
4135
+ list: moveItem(step.list || [], fieldId, direction)
4136
+ }) : step)
4137
+ });
4138
+ }
4139
+ return _extends({}, block, {
4140
+ list: moveItem(block.list || [], fieldId, direction)
4141
+ });
4142
+ }));
4143
+ };
4144
+ const currentFieldScope = fieldContext ? collectSchemaFields(schema, {
4145
+ blockId: fieldContext.blockId,
4146
+ stepId: fieldContext.stepId
4147
+ }) : [];
4148
+ return /*#__PURE__*/jsxs("div", {
4149
+ className: [style['form-creator'], RESPONSIVE_BOUNDARY_CLASS, isMobile ? style['is-mobile'] : '', className].filter(Boolean).join(' '),
4150
+ children: [/*#__PURE__*/jsx("div", {
4151
+ className: style['editor-pane'],
4152
+ children: /*#__PURE__*/jsx(BlockListPanel, {
4153
+ blocks: schema.blocks,
4154
+ onAddBlock: handleAddBlock,
4155
+ onEditBlock: handleEditBlock,
4156
+ onDeleteBlock: handleDeleteBlock,
4157
+ onMoveBlock: handleMoveBlock,
4158
+ onAddField: handleAddField,
4159
+ onEditField: handleEditField,
4160
+ onDeleteField: handleDeleteField,
4161
+ onMoveField: handleMoveField,
4162
+ onAddStep: handleAddStep,
4163
+ onEditStep: handleEditStep,
4164
+ onDeleteStep: handleDeleteStep,
4165
+ onMoveStep: handleMoveStep,
4166
+ onOpenFormActions: () => setFormActionsOpen(true)
4167
+ })
4168
+ }), _showPreview ? /*#__PURE__*/jsx("div", {
4169
+ className: style['preview-pane'],
4170
+ children: /*#__PURE__*/jsx("div", {
4171
+ className: style['preview-body'],
4172
+ children: hasRenderableContent(schema) ? /*#__PURE__*/jsx(SchemaRenderer, {
4173
+ schema: schema,
4174
+ preview: true,
4175
+ formProps: formProps
4176
+ }) : /*#__PURE__*/jsx(Empty, {
4177
+ image: Empty.PRESENTED_IMAGE_SIMPLE,
4178
+ description: formatMessage({
4179
+ id: 'emptyBlockList'
4180
+ })
4181
+ })
4182
+ })
4183
+ }) : null, /*#__PURE__*/jsx(BlockEditorModal, {
4184
+ open: blockEditorOpen,
4185
+ block: editingBlock,
4186
+ renderModal: renderModal,
4187
+ onCancel: () => {
4188
+ setBlockEditorOpen(false);
4189
+ setEditingBlock(null);
4190
+ },
4191
+ onSave: handleSaveBlock
4192
+ }), /*#__PURE__*/jsx(StepEditorModal, {
4193
+ open: stepEditorOpen,
4194
+ step: stepContext == null ? void 0 : stepContext.step,
4195
+ renderModal: renderModal,
4196
+ onCancel: () => {
4197
+ setStepEditorOpen(false);
4198
+ setStepContext(null);
4199
+ },
4200
+ onSave: handleSaveStep
4201
+ }), /*#__PURE__*/jsx(FieldEditorModal, {
4202
+ open: fieldEditorOpen,
4203
+ field: editingField,
4204
+ fieldList: currentFieldScope,
4205
+ renderModal: renderModal,
4206
+ onCancel: () => {
4207
+ setFieldEditorOpen(false);
4208
+ setFieldContext(null);
4209
+ setEditingField(null);
4210
+ },
4211
+ onSave: handleSaveField
4212
+ }), /*#__PURE__*/jsx(FormActionsEditor, {
4213
+ open: formActionsOpen,
4214
+ value: schema.actions,
4215
+ renderModal: renderModal,
4216
+ onCancel: () => setFormActionsOpen(false),
4217
+ onSave: actions => {
4218
+ updateSchema(_extends({}, schema, {
4219
+ actions
4220
+ }));
4221
+ setFormActionsOpen(false);
4222
+ }
4223
+ })]
4224
+ });
4225
+ });
4226
+
4227
+ export { FormCreator, RULE_LEN_PRESET, RULE_PRESET_ITEMS, SchemaRenderer, SchemaRendererInner, applyFromPropsSchema, blockToFormValues, buildRuleString, collectSchemaFields, createBlock, createField$1 as createField, createFieldId, createStep, FormCreator as default, defaultFormActions, defaultSchema, fieldToFormValues, findBlock, formValuesToBlock, formValuesToField, getBlockDefinition, getBlockKindOptions, getFieldComponent, getFieldDefinition, getFieldTypes, getRulePresetItems, hasRenderableContent, isFieldNameUnique, mapBlocks, moveItem, normalizeBlock, normalizeFormActions, normalizeOptions, normalizeSchema, parseRuleString, pickFieldProps, pickFromPropsSchema, registerField, registerRulePreset, updateBlocks };
4228
+ //# sourceMappingURL=index.modern.js.map