Commit 52af1dd0d494e66c0af20f886dcc2b983cbb096f

Authored by 无木
1 parent 897bed97

feat(basic-table): add `ApiTreeSelect` edit component

为表格添加ApiTreeSelect编辑组件,修复一些其它的已知问题
CHANGELOG.zh_CN.md
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 - **NoticeList** 添加分页、超长自动省略、标题点击事件、标题删除线等功能 3 - **NoticeList** 添加分页、超长自动省略、标题点击事件、标题删除线等功能
4 - **MixSider** 优化 Mix 菜单布局时 底部折叠按钮 的样式,与其它菜单布局时的风格保持一致 4 - **MixSider** 优化 Mix 菜单布局时 底部折叠按钮 的样式,与其它菜单布局时的风格保持一致
5 - **ApiTreeSelect** 扩展`antdv`的`TreeSelect`组件,支持远程数据源,用法类似`ApiSelect` 5 - **ApiTreeSelect** 扩展`antdv`的`TreeSelect`组件,支持远程数据源,用法类似`ApiSelect`
  6 +- **BasicTable** 新增`ApiTreeSelect`编辑组件
6 - 可以为不同的用户指定不同的后台首页: 7 - 可以为不同的用户指定不同的后台首页:
7 - 在`getUserInfo`接口返回的用户信息中增加`homePath`字段(可选)即可为当前用户定制首页路径 8 - 在`getUserInfo`接口返回的用户信息中增加`homePath`字段(可选)即可为当前用户定制首页路径
8 9
@@ -14,6 +15,8 @@ @@ -14,6 +15,8 @@
14 - 新增`headerTop`插槽 15 - 新增`headerTop`插槽
15 - 修复操作列的按钮在 disabled 状态下的颜色显示 16 - 修复操作列的按钮在 disabled 状态下的颜色显示
16 - 修复可编辑单元格的值不能直接通过修改`dataSource`来更新显示的问题 17 - 修复可编辑单元格的值不能直接通过修改`dataSource`来更新显示的问题
  18 + - 修复使用`ApiSelect`编辑组件时的数据回显问题
  19 + - 修复在部分场景下编辑组件可能会报`onXXX`类型错误的问题
17 - **TableAction** 20 - **TableAction**
18 - 仅在 `action.tooltip`存在的情况下 才创建 Tooltip 组件 21 - 仅在 `action.tooltip`存在的情况下 才创建 Tooltip 组件
19 - 修复组件内的圆形按钮内容没有居中的问题 22 - 修复组件内的圆形按钮内容没有居中的问题
src/components/Form/index.ts
@@ -8,5 +8,6 @@ export { useForm } from './src/hooks/useForm'; @@ -8,5 +8,6 @@ export { useForm } from './src/hooks/useForm';
8 8
9 export { default as ApiSelect } from './src/components/ApiSelect.vue'; 9 export { default as ApiSelect } from './src/components/ApiSelect.vue';
10 export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue'; 10 export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue';
  11 +export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue';
11 12
12 export { BasicForm }; 13 export { BasicForm };
src/components/Table/src/componentMap.ts
@@ -9,7 +9,7 @@ import { @@ -9,7 +9,7 @@ import {
9 TimePicker, 9 TimePicker,
10 } from 'ant-design-vue'; 10 } from 'ant-design-vue';
11 import type { ComponentType } from './types/componentType'; 11 import type { ComponentType } from './types/componentType';
12 -import { ApiSelect } from '/@/components/Form'; 12 +import { ApiSelect, ApiTreeSelect } from '/@/components/Form';
13 13
14 const componentMap = new Map<ComponentType, Component>(); 14 const componentMap = new Map<ComponentType, Component>();
15 15
@@ -17,6 +17,7 @@ componentMap.set(&#39;Input&#39;, Input); @@ -17,6 +17,7 @@ componentMap.set(&#39;Input&#39;, Input);
17 componentMap.set('InputNumber', InputNumber); 17 componentMap.set('InputNumber', InputNumber);
18 componentMap.set('Select', Select); 18 componentMap.set('Select', Select);
19 componentMap.set('ApiSelect', ApiSelect); 19 componentMap.set('ApiSelect', ApiSelect);
  20 +componentMap.set('ApiTreeSelect', ApiTreeSelect);
20 componentMap.set('Switch', Switch); 21 componentMap.set('Switch', Switch);
21 componentMap.set('Checkbox', Checkbox); 22 componentMap.set('Checkbox', Checkbox);
22 componentMap.set('DatePicker', DatePicker); 23 componentMap.set('DatePicker', DatePicker);
src/components/Table/src/components/editable/CellComponent.ts
@@ -19,7 +19,7 @@ export const CellComponent: FunctionalComponent = ( @@ -19,7 +19,7 @@ export const CellComponent: FunctionalComponent = (
19 const Comp = componentMap.get(component) as typeof defineComponent; 19 const Comp = componentMap.get(component) as typeof defineComponent;
20 20
21 const DefaultComp = h(Comp, attrs); 21 const DefaultComp = h(Comp, attrs);
22 - if (!rule) { 22 + if (!rule || !popoverVisible) {
23 return DefaultComp; 23 return DefaultComp;
24 } 24 }
25 return h( 25 return h(
src/components/Table/src/components/editable/EditableCell.vue
@@ -45,6 +45,7 @@ @@ -45,6 +45,7 @@
45 import { isString, isBoolean, isFunction, isNumber, isArray } from '/@/utils/is'; 45 import { isString, isBoolean, isFunction, isNumber, isArray } from '/@/utils/is';
46 import { createPlaceholderMessage } from './helper'; 46 import { createPlaceholderMessage } from './helper';
47 import { set, omit } from 'lodash-es'; 47 import { set, omit } from 'lodash-es';
  48 + import { treeToList } from '/@/utils/helper/treeHelper';
48 49
49 export default defineComponent({ 50 export default defineComponent({
50 name: 'EditableCell', 51 name: 'EditableCell',
@@ -276,9 +277,23 @@ @@ -276,9 +277,23 @@
276 } 277 }
277 } 278 }
278 279
279 - // only ApiSelect 280 + // only ApiSelect or TreeSelect
280 function handleOptionsChange(options: LabelValueOptions) { 281 function handleOptionsChange(options: LabelValueOptions) {
281 - optionsRef.value = options; 282 + const { replaceFields } = props.column?.editComponentProps ?? {};
  283 + const component = unref(getComponent);
  284 + if (component === 'ApiTreeSelect') {
  285 + const { title = 'title', value = 'value', children = 'children' } = replaceFields || {};
  286 + let listOptions: Recordable[] = treeToList(options, { children });
  287 + listOptions = listOptions.map((item) => {
  288 + return {
  289 + label: item[title],
  290 + value: item[value],
  291 + };
  292 + });
  293 + optionsRef.value = listOptions as LabelValueOptions;
  294 + } else {
  295 + optionsRef.value = options;
  296 + }
282 } 297 }
283 298
284 function initCbs(cbs: 'submitCbs' | 'validCbs' | 'cancelCbs', handle: Fn) { 299 function initCbs(cbs: 'submitCbs' | 'validCbs' | 'cancelCbs', handle: Fn) {
src/components/Table/src/types/componentType.ts
@@ -3,6 +3,7 @@ export type ComponentType = @@ -3,6 +3,7 @@ export type ComponentType =
3 | 'InputNumber' 3 | 'InputNumber'
4 | 'Select' 4 | 'Select'
5 | 'ApiSelect' 5 | 'ApiSelect'
  6 + | 'ApiTreeSelect'
6 | 'Checkbox' 7 | 'Checkbox'
7 | 'Switch' 8 | 'Switch'
8 | 'DatePicker' 9 | 'DatePicker'
src/views/demo/table/EditCellTable.vue
@@ -8,12 +8,12 @@ @@ -8,12 +8,12 @@
8 </div> 8 </div>
9 </template> 9 </template>
10 <script lang="ts"> 10 <script lang="ts">
11 - import { defineComponent, ref } from 'vue'; 11 + import { defineComponent } from 'vue';
12 import { BasicTable, useTable, BasicColumn } from '/@/components/Table'; 12 import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
13 import { optionsListApi } from '/@/api/demo/select'; 13 import { optionsListApi } from '/@/api/demo/select';
14 14
15 import { demoListApi } from '/@/api/demo/table'; 15 import { demoListApi } from '/@/api/demo/table';
16 - const optionsData = ref([]); 16 + import { treeOptionsListApi } from '/@/api/demo/tree';
17 const columns: BasicColumn[] = [ 17 const columns: BasicColumn[] = [
18 { 18 {
19 title: '输入框', 19 title: '输入框',
@@ -88,17 +88,18 @@ @@ -88,17 +88,18 @@
88 resultField: 'list', 88 resultField: 'list',
89 labelField: 'name', 89 labelField: 'name',
90 valueField: 'id', 90 valueField: 'id',
91 - onOptionsChange(options) {  
92 - optionsData.value = options;  
93 - },  
94 }, 91 },
95 - editValueMap(value: any) {  
96 - const found = optionsData.value.find((option) => option.id === value);  
97 - if (found) {  
98 - return found.name;  
99 - } else {  
100 - return value;  
101 - } 92 + width: 200,
  93 + },
  94 + {
  95 + title: '远程下拉树',
  96 + dataIndex: 'name7',
  97 + edit: true,
  98 + editComponent: 'ApiTreeSelect',
  99 + editRule: false,
  100 + editComponentProps: {
  101 + api: treeOptionsListApi,
  102 + resultField: 'list',
102 }, 103 },
103 width: 200, 104 width: 200,
104 }, 105 },
src/views/demo/table/EditRowTable.vue
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 import { optionsListApi } from '/@/api/demo/select'; 20 import { optionsListApi } from '/@/api/demo/select';
21 21
22 import { demoListApi } from '/@/api/demo/table'; 22 import { demoListApi } from '/@/api/demo/table';
23 - const optionsData = ref([]); 23 + import { treeOptionsListApi } from '/@/api/demo/tree';
24 24
25 const columns: BasicColumn[] = [ 25 const columns: BasicColumn[] = [
26 { 26 {
@@ -100,17 +100,18 @@ @@ -100,17 +100,18 @@
100 resultField: 'list', 100 resultField: 'list',
101 labelField: 'name', 101 labelField: 'name',
102 valueField: 'id', 102 valueField: 'id',
103 - onOptionsChange(options) {  
104 - optionsData.value = options;  
105 - },  
106 }, 103 },
107 - editValueMap(value: any) {  
108 - const found = optionsData.value.find((option) => option.id === value);  
109 - if (found) {  
110 - return found.name;  
111 - } else {  
112 - return value;  
113 - } 104 + width: 200,
  105 + },
  106 + {
  107 + title: '远程下拉树',
  108 + dataIndex: 'name7',
  109 + editRow: true,
  110 + editComponent: 'ApiTreeSelect',
  111 + editRule: false,
  112 + editComponentProps: {
  113 + api: treeOptionsListApi,
  114 + resultField: 'list',
114 }, 115 },
115 width: 200, 116 width: 200,
116 }, 117 },