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