diff --git a/packages/amis-editor-core/scss/control/_key-value-map-control.scss b/packages/amis-editor-core/scss/control/_key-value-map-control.scss new file mode 100644 index 000000000..68ff24478 --- /dev/null +++ b/packages/amis-editor-core/scss/control/_key-value-map-control.scss @@ -0,0 +1,42 @@ +.ae-KeyValMapControl-wrapper { + .ae-KeyValMapControlItem-Main { + width: 100%; + display: flex; + justify-content: space-between; + } + + .ae-KeyValMapControlItem-input { + flex: 1; + margin-right: 10px; + } + + .ae-ExtendMore { + position: relative; + + .cxd-Container-body { + margin-top: 20px; + } + } + + .ae-KeyValMapControlItem-closeBtn { + position: absolute; + top: 0; + right: 0; + font-size: 18px; + color: #151b26; + padding-right: 0.625rem; + z-index: 1; + } + + .ae-KeyValMapControlItem-EditLabel { + margin-top: 10px; + } + + .ae-KeyValMapControl-footer > * { + width: calc(50% - 0.375rem); + } + + .ae-KeyValMapControl-footer > *:first-child { + margin-right: 0.75rem; + } +} diff --git a/packages/amis-editor-core/scss/editor.scss b/packages/amis-editor-core/scss/editor.scss index d697afcc5..57f71dfd0 100644 --- a/packages/amis-editor-core/scss/editor.scss +++ b/packages/amis-editor-core/scss/editor.scss @@ -38,6 +38,7 @@ @import './control/tree_option_control'; @import './control/_inpupt-file'; @import './control/_nav-control'; +@import './control/_key-value-map-control'; @import './control/_status'; @import './control/_icon-button-group-control'; @import './control/_flex-setting-control'; diff --git a/packages/amis-editor/src/index.tsx b/packages/amis-editor/src/index.tsx index 54762b0e9..fca06c842 100644 --- a/packages/amis-editor/src/index.tsx +++ b/packages/amis-editor/src/index.tsx @@ -6,6 +6,7 @@ export * from './plugin'; import './renderer/OptionControl'; import './renderer/NavSourceControl'; +import './renderer/KeyValueMapControl'; import './renderer/NavBadgeControl'; import './renderer/NavDefaultActive'; import './renderer/MapSourceControl'; diff --git a/packages/amis-editor/src/plugin/Cards.tsx b/packages/amis-editor/src/plugin/Cards.tsx index 0f3d35e30..003361d3b 100644 --- a/packages/amis-editor/src/plugin/Cards.tsx +++ b/packages/amis-editor/src/plugin/Cards.tsx @@ -30,6 +30,7 @@ export class CardsPlugin extends BasePlugin { isBaseComponent = true; description = '功能类似于表格,但是用一个个小卡片来展示数据。当前组件需要配置数据源,不自带数据拉取,请优先使用 「CRUD」 组件。'; + searchKeywords = '卡片组'; docLink = '/amis/zh-CN/components/cards'; tags = ['展示']; icon = 'fa fa-window-maximize'; diff --git a/packages/amis-editor/src/plugin/DropDownButton.tsx b/packages/amis-editor/src/plugin/DropDownButton.tsx index 27b32f24d..a0585dae8 100644 --- a/packages/amis-editor/src/plugin/DropDownButton.tsx +++ b/packages/amis-editor/src/plugin/DropDownButton.tsx @@ -24,6 +24,7 @@ export class DropDownButtonPlugin extends BasePlugin { name = '下拉按钮'; isBaseComponent = true; description = '下拉按钮,更多的按钮通过点击后展示开来。'; + searchKeywords = '下拉菜单'; tags = ['表单项']; icon = 'fa fa-chevron-down'; pluginIcon = 'dropdown-btn-plugin'; diff --git a/packages/amis-editor/src/plugin/Each.tsx b/packages/amis-editor/src/plugin/Each.tsx index f37a7b08b..5652acff5 100644 --- a/packages/amis-editor/src/plugin/Each.tsx +++ b/packages/amis-editor/src/plugin/Each.tsx @@ -23,6 +23,7 @@ export class EachPlugin extends BasePlugin { name = '循环 Each'; isBaseComponent = true; description = '功能渲染器,可以基于现有变量循环输出渲染器。'; + searchKeywords = '循环渲染器'; tags = ['功能']; icon = 'fa fa-repeat'; pluginIcon = 'each-plugin'; diff --git a/packages/amis-editor/src/plugin/Form/DiffEditor.tsx b/packages/amis-editor/src/plugin/Form/DiffEditor.tsx index 9229b001a..004b2d812 100644 --- a/packages/amis-editor/src/plugin/Form/DiffEditor.tsx +++ b/packages/amis-editor/src/plugin/Form/DiffEditor.tsx @@ -27,6 +27,7 @@ export class DiffEditorControlPlugin extends BasePlugin { description = `左右两边的代码做对比,支持的语言包括:${availableLanguages .slice(0, 10) .join(',')}等等`; + searchKeywords = '对比编辑器'; docLink = '/amis/zh-CN/components/form/diff-editor'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/FieldSet.tsx b/packages/amis-editor/src/plugin/Form/FieldSet.tsx index 83d9c8a19..7ee952559 100644 --- a/packages/amis-editor/src/plugin/Form/FieldSet.tsx +++ b/packages/amis-editor/src/plugin/Form/FieldSet.tsx @@ -15,6 +15,7 @@ export class FieldSetControlPlugin extends BasePlugin { isBaseComponent = true; icon = 'fa fa-toggle-down'; description = '多个表单项的组合,可配置是否折叠'; + searchKeywords = '表单项集合'; docLink = '/amis/zh-CN/components/form/fieldset'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/Hidden.tsx b/packages/amis-editor/src/plugin/Form/Hidden.tsx index 1c0b49b85..811876b1f 100644 --- a/packages/amis-editor/src/plugin/Form/Hidden.tsx +++ b/packages/amis-editor/src/plugin/Form/Hidden.tsx @@ -14,6 +14,7 @@ export class HiddenControlPlugin extends BasePlugin { icon = 'fa fa-eye-slash'; pluginIcon = 'hidden-plugin'; description = '隐藏表单项'; + searchKeywords = '隐藏字段'; docLink = '/amis/zh-CN/components/form/hidden'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/InputCity.tsx b/packages/amis-editor/src/plugin/Form/InputCity.tsx index de9fa91c0..19d3209fe 100644 --- a/packages/amis-editor/src/plugin/Form/InputCity.tsx +++ b/packages/amis-editor/src/plugin/Form/InputCity.tsx @@ -32,6 +32,7 @@ export class CityControlPlugin extends BasePlugin { icon = 'fa fa-building-o'; pluginIcon = 'input-city-plugin'; description = '可配置是否选择区域或者城市'; + searchKeywords = '城市选择器'; docLink = '/amis/zh-CN/components/form/input-city'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/InputColor.tsx b/packages/amis-editor/src/plugin/Form/InputColor.tsx index c5cac60ff..505be252a 100644 --- a/packages/amis-editor/src/plugin/Form/InputColor.tsx +++ b/packages/amis-editor/src/plugin/Form/InputColor.tsx @@ -68,6 +68,7 @@ export class ColorControlPlugin extends BasePlugin { pluginIcon = 'input-color-plugin'; description = '支持hex、hls、rgb、rgba格式,默认为hex格式'; + searchKeywords = '颜色选择器'; docLink = '/amis/zh-CN/components/form/input-color'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/InputDate.tsx b/packages/amis-editor/src/plugin/Form/InputDate.tsx index 74907dd9b..b46398f27 100644 --- a/packages/amis-editor/src/plugin/Form/InputDate.tsx +++ b/packages/amis-editor/src/plugin/Form/InputDate.tsx @@ -148,7 +148,7 @@ export class DateControlPlugin extends BasePlugin { isBaseComponent = true; // 添加源对应组件中文名称 & type字段 searchKeywords = - '日期框、input-datetime、日期时间框、input-time、时间框、input-month、月份框、input-quarter、季度框、input-year、年框'; + '日期框、input-datetime、日期时间框、input-time、时间框、input-month、月份框、input-quarter、季度框、input-year、年框、年份框、年份选择'; description = '年月日选择,支持相对值设定,如+2days两天后'; docLink = '/amis/zh-CN/components/form/input-date'; tags = ['表单项']; diff --git a/packages/amis-editor/src/plugin/Form/InputDateRange.tsx b/packages/amis-editor/src/plugin/Form/InputDateRange.tsx index ba959dae5..6479a342f 100644 --- a/packages/amis-editor/src/plugin/Form/InputDateRange.tsx +++ b/packages/amis-editor/src/plugin/Form/InputDateRange.tsx @@ -193,7 +193,7 @@ export class DateRangeControlPlugin extends BasePlugin { isBaseComponent = true; // 添加源对应组件中文名称 & type字段 searchKeywords = - '日期范围框、input-datetime-range、日期时间范围、input-time-range、时间范围、input-month-range、月份范围、input-quarter-range、季度范围、input-year-range、年范围'; + '日期范围框、input-datetime-range、日期时间范围、input-time-range、时间范围、input-month-range、月份范围、input-quarter-range、季度范围、input-year-range、年范围、年份范围'; description = '日期范围选择,可通过minDatemaxDate设定最小、最大日期'; docLink = '/amis/zh-CN/components/form/input-date-range'; diff --git a/packages/amis-editor/src/plugin/Form/InputGroup.tsx b/packages/amis-editor/src/plugin/Form/InputGroup.tsx index d9a291505..ab6194d37 100644 --- a/packages/amis-editor/src/plugin/Form/InputGroup.tsx +++ b/packages/amis-editor/src/plugin/Form/InputGroup.tsx @@ -22,6 +22,7 @@ export class InputGroupControlPlugin extends BasePlugin { icon = 'fa fa-object-group'; pluginIcon = 'input-group-plugin'; description = '输入组合,支持多种类型的控件组合'; + searchKeywords = '输入框组合'; docLink = '/amis/zh-CN/components/form/input-group'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/InputNumber.tsx b/packages/amis-editor/src/plugin/Form/InputNumber.tsx index 7f05dabc5..601cfaaa3 100644 --- a/packages/amis-editor/src/plugin/Form/InputNumber.tsx +++ b/packages/amis-editor/src/plugin/Form/InputNumber.tsx @@ -32,6 +32,7 @@ export class NumberControlPlugin extends BasePlugin { icon = 'fa fa-sort-numeric-asc'; pluginIcon = 'input-number-plugin'; description = '支持设定最大值和最小值,以及步长与精度'; + searchKeywords = '数字输入框'; docLink = '/amis/zh-CN/components/form/input-number'; tags = ['表单项']; scaffold = { @@ -222,35 +223,7 @@ export class NumberControlPlugin extends BasePlugin { }, getSchemaTpl('prefix'), getSchemaTpl('suffix'), - getSchemaTpl('combo-container', { - type: 'combo', - label: '单位选项', - mode: 'normal', - name: 'unitOptions', - flat: true, - items: [ - { - placeholder: '单位选项', - type: i18nEnabled ? 'input-text-i18n' : 'input-text', - name: 'text' - } - ], - draggable: false, - multiple: true, - pipeIn: (value: any) => { - if (!isObject(value)) { - return Array.isArray(value) ? value : []; - } - const res = value.map((item: any) => item.value); - return res; - }, - pipeOut: (value: any[]) => { - if (!value.length) { - return undefined; - } - return value; - } - }), + getSchemaTpl('keyValueMapControl'), getSchemaTpl('labelRemark'), getSchemaTpl('remark'), getSchemaTpl('placeholder'), diff --git a/packages/amis-editor/src/plugin/Form/InputRepeat.tsx b/packages/amis-editor/src/plugin/Form/InputRepeat.tsx index 0c3c2d374..095bbc332 100644 --- a/packages/amis-editor/src/plugin/Form/InputRepeat.tsx +++ b/packages/amis-editor/src/plugin/Form/InputRepeat.tsx @@ -14,6 +14,7 @@ export class RepeatControlPlugin extends BasePlugin { icon = 'fa fa-repeat'; pluginIcon = 'input-repeat-plugin'; description = '选择重复的频率,如每时、每天、每周等'; + searchKeywords = '重复频率选择器'; docLink = '/amis/zh-CN/components/form/input-repeat'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/InputTable.tsx b/packages/amis-editor/src/plugin/Form/InputTable.tsx index 369f34743..04ce9c7c3 100644 --- a/packages/amis-editor/src/plugin/Form/InputTable.tsx +++ b/packages/amis-editor/src/plugin/Form/InputTable.tsx @@ -1004,7 +1004,34 @@ export class TableControlPlugin extends BasePlugin { }, getSchemaTpl('description'), getSchemaTpl('placeholder'), - getSchemaTpl('labelRemark') + getSchemaTpl('labelRemark'), + { + name: 'columnsTogglable', + label: tipedLabel( + '列显示开关', + '是否展示表格列的显隐控件,“自动”即列数量大于5时自动开启' + ), + type: 'button-group-select', + pipeIn: defaultValue('auto'), + size: 'sm', + labelAlign: 'left', + options: [ + { + label: '自动', + value: 'auto' + }, + + { + label: '开启', + value: true + }, + + { + label: '关闭', + value: false + } + ] + } ] }, { diff --git a/packages/amis-editor/src/plugin/Form/InputTag.tsx b/packages/amis-editor/src/plugin/Form/InputTag.tsx index 5e7105577..33f00747f 100644 --- a/packages/amis-editor/src/plugin/Form/InputTag.tsx +++ b/packages/amis-editor/src/plugin/Form/InputTag.tsx @@ -25,6 +25,7 @@ export class TagControlPlugin extends BasePlugin { icon = 'fa fa-tag'; pluginIcon = 'input-tag-plugin'; description = '配置 options 可以实现选择选项'; + searchKeywords = '标签选择器'; docLink = '/amis/zh-CN/components/form/input-tag'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/InputText.tsx b/packages/amis-editor/src/plugin/Form/InputText.tsx index c0cf0bdc4..bd98971ea 100644 --- a/packages/amis-editor/src/plugin/Form/InputText.tsx +++ b/packages/amis-editor/src/plugin/Form/InputText.tsx @@ -31,7 +31,7 @@ export class TextControlPlugin extends BasePlugin { order = -600; // 添加源对应组件中文名称 & type字段 searchKeywords = - '文本框、邮箱框、input-email、URL框、input-url、密码框、input-password'; + '文本框、邮箱框、input-email、URL框、input-url、密码框、input-password、密码输入框'; // 组件名称 name = '文本框'; diff --git a/packages/amis-editor/src/plugin/Form/InputTree.tsx b/packages/amis-editor/src/plugin/Form/InputTree.tsx index 27e919840..e52b2f3e1 100644 --- a/packages/amis-editor/src/plugin/Form/InputTree.tsx +++ b/packages/amis-editor/src/plugin/Form/InputTree.tsx @@ -29,7 +29,8 @@ export class TreeControlPlugin extends BasePlugin { icon = 'fa fa-list-alt'; pluginIcon = 'input-tree-plugin'; description = '树型结构选择,支持 [内嵌模式] 与 [浮层模式] 的外观切换'; - searchKeywords = 'tree、树下拉、树下拉框、tree-select'; + searchKeywords = + 'tree、树下拉、树下拉框、tree-select、树形选择框、树形选择器'; docLink = '/amis/zh-CN/components/form/input-tree'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/Picker.tsx b/packages/amis-editor/src/plugin/Form/Picker.tsx index 3687a0dad..c0db280c5 100644 --- a/packages/amis-editor/src/plugin/Form/Picker.tsx +++ b/packages/amis-editor/src/plugin/Form/Picker.tsx @@ -32,6 +32,7 @@ export class PickerControlPlugin extends BasePlugin { pluginIcon = 'picker-plugin'; description = '通过 pickerSchema 配置可供选取的数据源进行选择需要的数据,支持多选'; + searchKeywords = '列表选择器'; docLink = '/amis/zh-CN/components/form/picker'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/Select.tsx b/packages/amis-editor/src/plugin/Form/Select.tsx index 7d1f3c43d..a61e7fc5a 100644 --- a/packages/amis-editor/src/plugin/Form/Select.tsx +++ b/packages/amis-editor/src/plugin/Form/Select.tsx @@ -21,6 +21,9 @@ export class SelectControlPlugin extends BasePlugin { icon = 'fa fa-th-list'; pluginIcon = 'select-plugin'; description = '支持多选,输入提示,可使用 source 获取选项'; + + searchKeywords = '选择器'; + docLink = '/amis/zh-CN/components/form/select'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/Textarea.tsx b/packages/amis-editor/src/plugin/Form/Textarea.tsx index 7c2b5322a..d4d9dd6a7 100644 --- a/packages/amis-editor/src/plugin/Form/Textarea.tsx +++ b/packages/amis-editor/src/plugin/Form/Textarea.tsx @@ -19,6 +19,7 @@ export class TextareaControlPlugin extends BasePlugin { icon = 'fa fa-paragraph'; pluginIcon = 'textarea-plugin'; description = '支持换行输入'; + searchKeywords = '多行文本输入框'; docLink = '/amis/zh-CN/components/form/textarea'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Form/UUID.tsx b/packages/amis-editor/src/plugin/Form/UUID.tsx index 3da6c6e16..641223751 100644 --- a/packages/amis-editor/src/plugin/Form/UUID.tsx +++ b/packages/amis-editor/src/plugin/Form/UUID.tsx @@ -19,6 +19,7 @@ export class UUIDControlPlugin extends BasePlugin { icon = 'fa fa-eye-slash'; pluginIcon = 'uuid-plugin'; description = '自动生成的 UUID'; + searchKeywords = 'uuid字段'; docLink = '/amis/zh-CN/components/form/uuid'; tags = ['表单项']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Grid.tsx b/packages/amis-editor/src/plugin/Grid.tsx index 5790ec7cb..b0a2f6748 100644 --- a/packages/amis-editor/src/plugin/Grid.tsx +++ b/packages/amis-editor/src/plugin/Grid.tsx @@ -30,6 +30,7 @@ export class GridPlugin extends BasePlugin { name = '分栏'; isBaseComponent = true; description = '分栏布局'; + searchKeywords = '水平分栏'; docLink = '/amis/zh-CN/components/grid'; tags = ['布局容器']; order = -2; diff --git a/packages/amis-editor/src/plugin/Log.tsx b/packages/amis-editor/src/plugin/Log.tsx index 756cdb2d1..6a69d913b 100644 --- a/packages/amis-editor/src/plugin/Log.tsx +++ b/packages/amis-editor/src/plugin/Log.tsx @@ -17,6 +17,7 @@ export class LogPlugin extends BasePlugin { icon = 'fa fa-file-text-o'; pluginIcon = 'log-plugin'; description = '用来实时显示日志'; + searchKeywords = '实时日志'; docLink = '/amis/zh-CN/components/log'; tags = ['展示']; previewSchema = { diff --git a/packages/amis-editor/src/plugin/Service.tsx b/packages/amis-editor/src/plugin/Service.tsx index cdec64520..d75a8a694 100644 --- a/packages/amis-editor/src/plugin/Service.tsx +++ b/packages/amis-editor/src/plugin/Service.tsx @@ -23,6 +23,9 @@ export class ServicePlugin extends BasePlugin { isBaseComponent = true; description = '功能性容器,可以用来加载数据或者加载渲染器配置。加载到的数据在容器可以使用。'; + + searchKeywords = '功能型容器'; + docLink = '/amis/zh-CN/components/service'; tags = ['数据容器']; icon = 'fa fa-server'; diff --git a/packages/amis-editor/src/plugin/Table.tsx b/packages/amis-editor/src/plugin/Table.tsx index 12754a096..2968b8a77 100644 --- a/packages/amis-editor/src/plugin/Table.tsx +++ b/packages/amis-editor/src/plugin/Table.tsx @@ -560,15 +560,14 @@ export class TablePlugin extends BasePlugin { body: [ { name: 'columnsTogglable', - label: '展示列显示开关', + label: tipedLabel( + '列显示开关', + '是否展示表格列的显隐控件,“自动”即列数量大于5时自动开启' + ), type: 'button-group-select', pipeIn: defaultValue('auto'), size: 'sm', labelAlign: 'left', - horizontal: { - left: 5, - right: 7 - }, options: [ { label: '自动', @@ -584,8 +583,7 @@ export class TablePlugin extends BasePlugin { label: '关闭', value: false } - ], - description: '自动即列数量大于5个时自动开启' + ] }, getSchemaTpl('switch', { diff --git a/packages/amis-editor/src/plugin/TableView.tsx b/packages/amis-editor/src/plugin/TableView.tsx index 25b70bcd1..d6b45a0c3 100644 --- a/packages/amis-editor/src/plugin/TableView.tsx +++ b/packages/amis-editor/src/plugin/TableView.tsx @@ -96,6 +96,7 @@ export class TableViewPlugin extends BasePlugin { icon = 'fa fa-columns'; pluginIcon = 'table-view-plugin'; description = '表格类型的展现'; + searchKeywords = '表格展现'; docLink = '/amis/zh-CN/components/table-view'; tags = ['功能']; scaffold = { diff --git a/packages/amis-editor/src/plugin/Tasks.tsx b/packages/amis-editor/src/plugin/Tasks.tsx index 16c89f443..0365b0958 100644 --- a/packages/amis-editor/src/plugin/Tasks.tsx +++ b/packages/amis-editor/src/plugin/Tasks.tsx @@ -16,6 +16,7 @@ export class TasksPlugin extends BasePlugin { name = '异步任务'; isBaseComponent = true; description = '用来做异步任务呈现或者操作。'; + searchKeywords = '任务操作集合'; docLink = '/amis/zh-CN/components/tasks'; tags = ['功能']; icon = ''; diff --git a/packages/amis-editor/src/plugin/TooltipWrapper.tsx b/packages/amis-editor/src/plugin/TooltipWrapper.tsx index 0743f2214..7fc0cdf68 100644 --- a/packages/amis-editor/src/plugin/TooltipWrapper.tsx +++ b/packages/amis-editor/src/plugin/TooltipWrapper.tsx @@ -17,6 +17,7 @@ export class TooltipWrapperPlugin extends BasePlugin { name = '文字提示'; description = '类似容器,可以将多个渲染器放置在一起,当用户鼠标悬停或者点击容器时,显示文字提示浮层'; + searchKeywords = '文字提示容器'; docLink = '/amis/zh-CN/components/tooltip'; tags = ['功能']; icon = 'fa fa-comment-alt'; diff --git a/packages/amis-editor/src/renderer/KeyValueMapControl.tsx b/packages/amis-editor/src/renderer/KeyValueMapControl.tsx new file mode 100644 index 000000000..337fbad8d --- /dev/null +++ b/packages/amis-editor/src/renderer/KeyValueMapControl.tsx @@ -0,0 +1,306 @@ +import React from 'react'; +import {FormItem, Button, render as amisRender} from 'amis'; +import {autobind, getI18nEnabled} from 'amis-editor-core'; +import type {FormControlProps} from 'amis-core'; +import uniqBy from 'lodash/uniqBy'; + +export interface KeyValueControlProps extends FormControlProps {} +export interface KeyValueControlState { + unitOptions: Array<{label: string; value: string; editing?: boolean}>; +} + +@FormItem({ + type: 'ae-keyValueMapControl' +}) +export class KeyValueMapControl extends React.Component< + KeyValueControlProps, + KeyValueControlState +> { + constructor(props: KeyValueControlProps) { + super(props); + + this.state = { + unitOptions: this.transformOptions(props) + }; + } + + transformOptions(props: KeyValueControlProps) { + const {value} = props; + if (Array.isArray(value)) { + return value.map(item => + typeof item === 'string' + ? { + label: item, + value: item + } + : item + ); + } else { + return []; + } + } + + /** + * 增加 + */ + @autobind + handleAdd() { + const {unitOptions} = this.state; + unitOptions.push({ + label: '', + value: '', + editing: false + }); + this.setState({unitOptions}, () => { + this.onChange(); + }); + } + + /** + * 批量增加 + */ + @autobind + handleBatchAdd(values: {batchOption: string}[], action: any) { + const unitOptions = this.state.unitOptions.concat(); + const addedOptions: Array<{label: string; value: string}> = + values[0].batchOption.split('\n').map(option => { + const item = option.trim(); + if (~item.indexOf(' ')) { + let [label, value] = item.split(' '); + return {label: label.trim(), value: value.trim()}; + } + return {label: item, value: item}; + }); + const newOptionsUniqByLabel = uniqBy( + [...unitOptions, ...addedOptions], + 'label' + ); + const newOptions = uniqBy(newOptionsUniqByLabel, 'value'); + + this.setState({unitOptions: newOptions}, () => this.onChange()); + } + + /** + * 编辑文本 + */ + @autobind + handleEditLabel(index: number, value: string) { + const unitOptions = this.state.unitOptions.concat(); + unitOptions.splice(index, 1, {...unitOptions[index], label: value}); + this.setState({unitOptions}, () => this.onChange()); + } + + /** + * 编辑值 + */ + @autobind + handleValueChange(index: number, value: string) { + const unitOptions = this.state.unitOptions.concat(); + unitOptions.splice(index, 1, {...unitOptions[index], value: value}); + this.setState({unitOptions}, () => this.onChange()); + } + + /** + * 修改编辑状态 + */ + toggleEdit(index: number) { + const {unitOptions} = this.state; + unitOptions[index].editing = !unitOptions[index].editing; + this.setState({unitOptions}); + } + + /** + * 删除选项 + */ + handleDelete(index: number) { + const unitOptions = this.state.unitOptions.concat(); + unitOptions.splice(index, 1); + this.setState({unitOptions}, () => this.onChange()); + } + + /** + * 更新unitOptions字段的统一出口 + */ + onChange() { + const {onBulkChange} = this.props; + const {unitOptions} = this.state; + const options = unitOptions.map(item => ({ + label: item.label, + value: item.value + })); + + onBulkChange && onBulkChange({unitOptions: options}); + return; + } + + renderOption(props: any, index: number) { + const {label, value, editing} = props; + const {render} = this.props; + const i18nEnabled = getI18nEnabled(); + + const editDom = editing ? ( +
+ {render('option', { + type: 'container', + className: 'ae-ExtendMore right mb-2', + body: [ + { + type: 'button', + className: 'ae-KeyValMapControlItem-closeBtn', + label: '×', + level: 'link', + onClick: () => this.toggleEdit(index) + }, + { + type: i18nEnabled ? 'input-text-i18n' : 'input-text', + placeholder: '显示文本', + label: '文本', + mode: 'horizontal', + value: label, + name: 'optionLabel', + labelClassName: 'ae-KeyValMapControlItem-EditLabel', + valueClassName: 'ae-KeyValMapControlItem-EditValue', + onChange: (v: string) => this.handleEditLabel(index, v) + }, + { + type: i18nEnabled ? 'input-text-i18n' : 'input-text', + placeholder: '值内容', + label: '值', + mode: 'horizontal', + value: value, + name: 'optionValue', + labelClassName: 'ae-KeyValMapControlItem-EditLabel', + valueClassName: 'ae-KeyValMapControlItem-EditValue', + onChange: (v: string) => this.handleValueChange(index, v) + } + ] + })} +
+ ) : null; + + const operationBtn = [ + { + type: 'button', + className: 'ae-KeyValMapControlItem-action', + label: '编辑', + onClick: () => this.toggleEdit(index) + }, + { + type: 'button', + className: 'ae-KeyValMapControlItem-action', + label: '删除', + onClick: () => this.handleDelete(index) + } + ]; + + return ( +
+
+ {amisRender({ + type: i18nEnabled ? 'input-text-i18n' : 'input-text', + className: 'ae-KeyValMapControlItem-input', + value: label, + placeholder: '请输入文本/值', + clearable: false, + onChange: (value: string) => { + this.handleEditLabel(index, value); + } + })} + {render( + 'dropdown', + { + type: 'dropdown-button', + className: 'ae-KeyValMapControlItem-dropdown', + btnClassName: 'px-2', + icon: 'fa fa-ellipsis-h', + hideCaret: true, + closeOnClick: true, + align: 'right', + menuClassName: 'ae-KeyValMapControlItem-ulmenu', + buttons: operationBtn + }, + { + popOverContainer: null // amis 渲染挂载节点会使用 this.target + } + )} +
+ {editDom} +
+ ); + } + + buildBatchAddSchema() { + return { + type: 'action', + actionType: 'dialog', + label: '批量添加', + dialog: { + title: '批量添加选项', + headerClassName: 'font-bold', + closeOnEsc: true, + closeOnOutside: false, + showCloseButton: true, + onConfirm: this.handleBatchAdd, + body: [ + { + type: 'alert', + level: 'warning', + body: [ + { + type: 'tpl', + tpl: '每个选项单列一行,将所有值不重复的项加为新的选项;
每行可通过空格来分别设置label和value,例:"张三 zhangsan"' + } + ], + showIcon: true, + className: 'mb-2.5' + }, + { + type: 'form', + wrapWithPanel: false, + mode: 'normal', + wrapperComponent: 'div', + resetAfterSubmit: true, + autoFocus: true, + preventEnterSubmit: true, + horizontal: { + left: 0, + right: 12 + }, + body: [ + { + name: 'batchOption', + type: 'textarea', + label: '', + placeholder: '请输入选项内容', + trimContents: true, + minRows: 10, + maxRows: 50, + required: true + } + ] + } + ] + } + }; + } + + render() { + const {unitOptions} = this.state; + const {render} = this.props; + return ( +
+ {unitOptions.length && ( +
+ {unitOptions.map((item, index) => this.renderOption(item, index))} +
+ )} +
+ + {render('inner', this.buildBatchAddSchema())} +
+
+ ); + } +} diff --git a/packages/amis-editor/src/tpl/options.tsx b/packages/amis-editor/src/tpl/options.tsx index 84c7690d0..4aeb39575 100644 --- a/packages/amis-editor/src/tpl/options.tsx +++ b/packages/amis-editor/src/tpl/options.tsx @@ -446,3 +446,12 @@ setSchemaTpl('dataMap', { }) ] }); +/** + * key value映射类组件 + */ +setSchemaTpl('keyValueMapControl', { + type: 'ae-keyValueMapControl', + label: '单位选项', + name: 'unitOptions', + mode: 'normal' +});