mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-02 15:27:18 +00:00
216 lines
6.0 KiB
JavaScript
216 lines
6.0 KiB
JavaScript
/* eslint-disable valid-jsdoc */
|
|
export function normalizeToArray(values) {
|
|
if (values !== undefined && values !== null) {
|
|
if (Array.isArray(values)) {
|
|
return [...values];
|
|
}
|
|
|
|
return [values];
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* 判断子节点是否是选中状态,如果 checkable={false} 则向下递归,
|
|
* @param {Node} child
|
|
* @param {Array} checkedValues
|
|
*/
|
|
export function isNodeChecked(node, checkedValues) {
|
|
if (node.disabled || node.checkboxDisabled) return true;
|
|
/* istanbul ignore next */
|
|
if (node.checkable === false) {
|
|
return (
|
|
!node.children ||
|
|
node.children.length === 0 ||
|
|
node.children.every(c => isNodeChecked(c, checkedValues))
|
|
);
|
|
}
|
|
return checkedValues.indexOf(node.value) > -1;
|
|
}
|
|
|
|
/**
|
|
* 遍历所有可用的子节点
|
|
* @param {Node}
|
|
* @param {Function} callback
|
|
*/
|
|
export function forEachEnableNode(node, callback = () => {}) {
|
|
if (node.disabled || node.checkboxDisabled) return;
|
|
// eslint-disable-next-line callback-return
|
|
callback(node);
|
|
if (node.children && node.children.length > 0) {
|
|
node.children.forEach(child => forEachEnableNode(child, callback));
|
|
}
|
|
}
|
|
/**
|
|
* 判断节点是否禁用checked
|
|
* @param {Node} node
|
|
* @returns {Boolean}
|
|
*/
|
|
export function isNodeDisabledChecked(node) {
|
|
if (node.disabled || node.checkboxDisabled) return true;
|
|
/* istanbul ignore next */
|
|
if (node.checkable === false) {
|
|
return (
|
|
!node.children ||
|
|
node.children.length === 0 ||
|
|
node.children.every(isNodeDisabledChecked)
|
|
);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* 递归获取一个 checkable = {true} 的父节点,当 checkable={false} 时继续往上查找
|
|
* @param {Node} node
|
|
* @param {Map} _p2n
|
|
* @return {Node}
|
|
*/
|
|
export function getCheckableParentNode(node, _p2n) {
|
|
let parentPos = node.pos.split(['-']);
|
|
if (parentPos.length === 2) return node;
|
|
parentPos.splice(parentPos.length - 1, 1);
|
|
parentPos = parentPos.join('-');
|
|
const parentNode = _p2n[parentPos];
|
|
if (parentNode.disabled || parentNode.checkboxDisabled) return false;
|
|
/* istanbul ignore next */
|
|
if (parentNode.checkable === false) {
|
|
return getCheckableParentNode(parentNode, _p2n);
|
|
}
|
|
|
|
return parentNode;
|
|
}
|
|
/**
|
|
* 过滤子节点
|
|
* @param {Array} values
|
|
* @param {Object} _v2n
|
|
*/
|
|
export function filterChildValue(values, _v2n, _p2n) {
|
|
const newValues = [];
|
|
values.forEach(value => {
|
|
const node = getCheckableParentNode(_v2n[value], _p2n);
|
|
if (
|
|
!node ||
|
|
node.checkable === false ||
|
|
node === _v2n[value] ||
|
|
values.indexOf(node.value) === -1
|
|
) {
|
|
newValues.push(value);
|
|
}
|
|
});
|
|
return newValues;
|
|
}
|
|
|
|
export function filterParentValue(values, _v2n) {
|
|
const newValues = [];
|
|
|
|
for (let i = 0; i < values.length; i++) {
|
|
const node = _v2n[values[i]];
|
|
if (
|
|
!node.children ||
|
|
node.children.length === 0 ||
|
|
node.children.every(isNodeDisabledChecked)
|
|
) {
|
|
newValues.push(values[i]);
|
|
}
|
|
}
|
|
|
|
return newValues;
|
|
}
|
|
|
|
export function isDescendantOrSelf(currentPos, targetPos) {
|
|
if (!currentPos || !targetPos) {
|
|
return false;
|
|
}
|
|
|
|
const currentNums = currentPos.split('-');
|
|
const targetNums = targetPos.split('-');
|
|
|
|
return (
|
|
currentNums.length <= targetNums.length &&
|
|
currentNums.every((num, index) => {
|
|
return num === targetNums[index];
|
|
})
|
|
);
|
|
}
|
|
|
|
export function isSiblingOrSelf(currentPos, targetPos) {
|
|
const currentNums = currentPos.split('-').slice(0, -1);
|
|
const targetNums = targetPos.split('-').slice(0, -1);
|
|
|
|
return (
|
|
currentNums.length === targetNums.length &&
|
|
currentNums.every((num, index) => {
|
|
return num === targetNums[index];
|
|
})
|
|
);
|
|
}
|
|
|
|
// eslint-disable-next-line max-statements
|
|
export function getAllCheckedValues(checkedValues, _v2n, _p2n) {
|
|
checkedValues = normalizeToArray(checkedValues);
|
|
const filteredValues = checkedValues.filter(value => !!_v2n[value]);
|
|
const flatValues = [
|
|
...filterChildValue(filteredValues, _v2n, _p2n),
|
|
...filteredValues.filter(
|
|
value => _v2n[value].disabled || _v2n[value].checkboxDisabled
|
|
),
|
|
];
|
|
const removeValue = child => {
|
|
if (child.disabled || child.checkboxDisabled) return;
|
|
if (
|
|
child.checkable === false &&
|
|
child.children &&
|
|
child.children.length > 0
|
|
) {
|
|
return child.children.forEach(removeValue);
|
|
}
|
|
flatValues.splice(flatValues.indexOf(child.value), 1);
|
|
};
|
|
|
|
const addParentValue = (i, parent) => flatValues.splice(i, 0, parent.value);
|
|
|
|
const values = [...flatValues];
|
|
for (let i = 0; i < values.length; i++) {
|
|
const pos = _v2n[values[i]].pos;
|
|
const nums = pos.split('-');
|
|
if (nums.length === 2) {
|
|
break;
|
|
}
|
|
for (let j = nums.length - 2; j > 0; j--) {
|
|
const parentPos = nums.slice(0, j + 1).join('-');
|
|
const parent = _p2n[parentPos];
|
|
if (
|
|
parent.checkable === false ||
|
|
parent.disabled ||
|
|
parent.checkboxDisabled
|
|
)
|
|
continue;
|
|
const parentChecked = parent.children.every(child =>
|
|
isNodeChecked(child, flatValues)
|
|
);
|
|
if (parentChecked) {
|
|
parent.children.forEach(removeValue);
|
|
addParentValue(i, parent);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
const newValues = [];
|
|
flatValues.forEach(value => {
|
|
if (_v2n[value].disabled || _v2n[value].checkboxDisabled) {
|
|
newValues.push(value);
|
|
return;
|
|
}
|
|
forEachEnableNode(_v2n[value], node => {
|
|
if (node.checkable === false) return;
|
|
newValues.push(node.value);
|
|
});
|
|
});
|
|
|
|
return newValues;
|
|
}
|