Merge pull request #7493 from sqzhou/master

fix: transfer组件disabled的选项 在全选父级的时候,仍然可以被选到
This commit is contained in:
hsm-lv 2023-07-18 11:15:43 +08:00 committed by GitHub
commit 637eab4522
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 142 additions and 8 deletions

View File

@ -26,7 +26,8 @@ import {
hasAbility,
getTreeParent,
getTreeAncestors,
flattenTree
flattenTree,
flattenTreeWithLeafNodes
} from 'amis-core';
import {Option, Options, value2array} from './Select';
import {themeable, ThemeProps, highlight} from 'amis-core';
@ -488,32 +489,65 @@ export class TreeSelector extends React.Component<
// cascade 为 true 表示父节点跟子节点没有级联关系。
if (autoCheckChildren) {
const children = item.children ? item.children.concat([]) : [];
const hasDisabled = flattenTree(children).some(item => item?.disabled);
if (onlyChildren) {
// 父级选中的时候,子节点也都选中,但是自己不选中
!~idx && children.length && value.pop();
// 这个 isAllChecked 主要是判断如果有disabled的item项这时父节点还是选中的话针对性的处理逻辑
const isAllChecked = flattenTreeWithLeafNodes(children)
.filter(item => !item?.disabled)
.every(v => ~value.indexOf(v));
while (children.length) {
let child = children.shift();
let index = value.indexOf(child);
if (child.children && child.children.length) {
children.push.apply(children, child.children);
} else if (!~index && child.value !== 'undefined') {
continue;
}
if (hasDisabled && isAllChecked) {
if (
~index &&
children.value !== 'undefined' &&
!child?.disabled
) {
value.splice(index, 1);
}
continue;
}
if (!~index && child.value !== 'undefined' && !child?.disabled) {
value.push(child);
}
}
} else {
// 这个 isAllChecked 主要是判断如果有disabled的item项这时父节点还是选中的话针对性的处理逻辑
const isAllChecked = flattenTree(children)
.filter(item => !item?.disabled)
.every(v => ~value.indexOf(v));
// 只要父节点选择了,子节点就不需要了,全部去掉勾选. withChildren时相反
while (children.length) {
let child = children.shift();
let index = value.indexOf(child);
if (~index) {
value.splice(index, 1);
}
if (!child?.disabled) {
// 判断下下面是否有禁用项
if (!hasDisabled) {
if (~index) {
value.splice(index, 1);
}
if (withChildren || cascade) {
value.push(child);
if (withChildren || cascade) {
value.push(child);
}
} else {
isAllChecked ? value.splice(index, 1) : value.push(child);
}
}
if (child.children && child.children.length) {
@ -557,7 +591,7 @@ export class TreeSelector extends React.Component<
while (children.length) {
let child = children.shift();
let index = value.indexOf(child);
if (~index) {
if (~index && !child?.disabled) {
value.splice(index, 1);
}
if (child.children && child.children.length) {

View File

@ -430,3 +430,103 @@ test('Tree: add child & cancel', async () => {
expect(!!container.querySelector('[icon="close"]')).toBeFalsy()
);
});
test('Tree: item disabled', async () => {
const onSubmit = jest.fn();
const {container, findByText, findByPlaceholderText} = render(
amisRender(
{
"type": "form",
"api": "/api/mock2/form/saveForm",
"body": [
{
"label": "树型展示",
"type": "transfer",
"name": "transfer",
"selectMode": "tree",
"searchable": true,
"options": [
{
"label": "法师",
"children": [
{
"label": "诸葛亮",
"value": "zhugeliang"
}
]
},
{
"label": "战士",
"children": [
{
"label": "曹操",
"value": "caocao"
},
{
"label": "曹操1",
"value": "caocao1",
"children": [
{
"label": "李白1",
"value": "libai1"
},
{
"label": "韩信1",
"value": "hanxin1"
},
{
"label": "云中君1",
"value": "yunzhongjun1"
}
]
},
{
"disabled": true,
"label": "钟无艳",
"value": "zhongwuyan"
}
]
},
{
"label": "打野",
"children": [
{
"label": "李白",
"value": "libai"
},
{
"label": "韩信",
"value": "hanxin"
},
{
"label": "云中君",
"value": "yunzhongjun"
}
]
}
]
}
]
},
{onSubmit},
makeEnv({})
)
);
const node = await findByText('战士');
const submitBtn = await findByText('提交');
fireEvent.click(node);
fireEvent.click(submitBtn);
await wait(100);
expect(onSubmit.mock.calls[0][0]).toEqual({
transfer: 'caocao,libai1,hanxin1,yunzhongjun1'
});
fireEvent.click(node);
fireEvent.click(submitBtn);
await wait(100);
expect(onSubmit.mock.calls[1][0]).toEqual({
transfer: ''
});
});