Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/catalogue/demos/async.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { Catalogue } from 'dt-react-component';
import { useTreeData } from 'dt-react-component/catalogue/useTreeData';
import { insertChildIntoNode } from 'dt-react-component/catalogue/utils';
import { insertChildrenToNode } from 'dt-react-component/catalogue/utils';

interface DataNode {
title: string;
Expand Down Expand Up @@ -30,7 +30,7 @@ const App: React.FC = () => {
return;
}
setTimeout(() => {
const newData = insertChildIntoNode(treeData.data, key, [
const newData = insertChildrenToNode(treeData.data, key, [
{ title: 'Child Node', key: `${key}-0` },
{ title: 'Child Node', key: `${key}-1` },
]);
Expand Down
10 changes: 8 additions & 2 deletions src/catalogue/demos/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { cloneDeep } from 'lodash-es';
import shortid from 'shortid';

import {
appendNodeByKey,
findNodeByKey,
findParentNodeByKey,
insertChildrenToNode,
removeEditNode,
removeNodeByKey,
updateTreeNodeEdit,
Expand Down Expand Up @@ -83,7 +83,13 @@ export default () => {

const handleAdd = (key: ITreeNode<IData>['key']) => {
const newExpandedKeys = treeData.expandedKeys ? [...treeData.expandedKeys] : [];
const data = appendNodeByKey<IData>(treeData.data, key);
const data = insertChildrenToNode<IData>(treeData.data, key, [
{
key: 'new_',
title: '',
edit: true,
},
]);
if (!newExpandedKeys?.includes(key)) {
newExpandedKeys.push(key);
}
Expand Down
6 changes: 4 additions & 2 deletions src/catalogue/demos/drag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { cloneDeep } from 'lodash-es';
import shortid from 'shortid';

import {
appendNodeByKey,
findNodeByKey,
findParentNodeByKey,
insertChildrenToNode,
removeEditNode,
removeNodeByKey,
updateTreeNodeEdit,
Expand Down Expand Up @@ -77,7 +77,9 @@ export default () => {

const handleAdd = (key: ITreeNode<IData>['key']) => {
const newExpandedKeys = treeData.expandedKeys ? [...treeData.expandedKeys] : [];
const data = appendNodeByKey<IData>(treeData.data, key);
const data = insertChildrenToNode<IData>(treeData.data, key, [
{ key: 'new_', title: '', edit: true },
]);
if (!newExpandedKeys?.includes(key)) {
newExpandedKeys.push(key);
}
Expand Down
6 changes: 4 additions & 2 deletions src/catalogue/demos/operator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { cloneDeep } from 'lodash-es';
import shortid from 'shortid';

import {
appendNodeByKey,
findNodeByKey,
findParentNodeByKey,
insertChildrenToNode,
removeEditNode,
removeNodeByKey,
updateTreeNodeEdit,
Expand Down Expand Up @@ -130,7 +130,9 @@ export default () => {

const handleAdd = (key: ITreeNode<IData>['key']) => {
const newExpandedKeys = treeData.expandedKeys ? [...treeData.expandedKeys] : [];
const data = appendNodeByKey<IData>(treeData.data, key);
const data = insertChildrenToNode<IData>(treeData.data, key, [
{ key: 'new_', title: '', edit: true },
]);
if (!newExpandedKeys?.includes(key)) {
newExpandedKeys.push(key);
}
Expand Down
156 changes: 90 additions & 66 deletions src/catalogue/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import { FolderFilled, FolderOpenedFilled } from '@dtinsight/react-icons';

import { CatalogueProps } from './components/catalogue';
import { ITreeNode } from './useTreeData';

export const getIcon: ITreeNode['icon'] = ({ selected, expanded }) => {
Expand All @@ -15,12 +14,10 @@ export const getIcon: ITreeNode['icon'] = ({ selected, expanded }) => {
};

/**
* @description 轮询 Tree 数据,赋值搜索标识和leafIcon
* @description 轮询 data 数据,赋值搜索标识和leafIcon
*/
export const loopTree = <T extends Record<string, any>>(
data: CatalogueProps<T>['treeData']
): CatalogueProps<T>['treeData'] => {
return data?.map((item) => {
export const loopTree = <T extends Record<string, any>>(data: ITreeNode<T>[]): ITreeNode<T>[] =>
data?.map((item) => {
if (item.children) {
return {
icon: getIcon,
Expand All @@ -34,13 +31,12 @@ export const loopTree = <T extends Record<string, any>>(
children: undefined,
};
});
};

/**
* 查找 key 对应的节点
* @param data 遍历的数组
* @param key 当前 key 值
* @returns 找到的对应节点
* @description 查找 key 对应的节点
* @param {ITreeNode<U>[]} data - 遍历的数组
* @param {ITreeNode<U>['key']} key - 当前 key 值
* @returns {ITreeNode<U> | null}找到的对应节点
*/
export const findNodeByKey = <U,>(
data: ITreeNode<U>[],
Expand All @@ -59,16 +55,16 @@ export const findNodeByKey = <U,>(
};

/**
* 更新 key 对应节点为编辑状态
* @param data 遍历的数组
* @param key 当前 key 值
* @returns 更新之后 data
* @description 更新 key 对应节点为编辑状态
* @param {ITreeNode<U>[]} data - 遍历的数组
* @param {ITreeNode<U>['key']} key - 当前 key 值
* @returns {ITreeNode<U>[]} 更新之后 data
*/
export const updateTreeNodeEdit = <U,>(
data: ITreeNode<U>[],
key: ITreeNode<U>['key']
): ITreeNode<U>[] => {
return data.map((node) => {
): ITreeNode<U>[] =>
data.map((node) => {
if (node.key === key) {
return { ...node, edit: true };
}
Expand All @@ -77,13 +73,12 @@ export const updateTreeNodeEdit = <U,>(
}
return node;
});
};

/**
* 查找 key 对应的父级节点
* @param data 遍历的数组
* @param key 当前 key 值
* @returns 当前找到父级节点
* @description 查找 key 对应的父级节点
* @param {ITreeNode<U>[]} data - 遍历的数组
* @param {ITreeNode<U>['key']} key - 当前 key 值
* @returns {ITreeNode<U> | null}当前找到父级节点
*/
export const findParentNodeByKey = <U extends { edit?: boolean }>(
data: ITreeNode<U>[],
Expand All @@ -103,39 +98,16 @@ export const findParentNodeByKey = <U extends { edit?: boolean }>(
};

/**
* 在 key 节点中添加子节点
* @param data 遍历的数组
* @param key 当前 key 值
* @returns 插入新数据之后的 data
*/
export const appendNodeByKey = <U extends { edit?: boolean }>(
data: ITreeNode<U>[],
key: ITreeNode<U>['key']
): ITreeNode<U>[] => {
const newNode = { key: 'new_', title: '', edit: true };
return data.map((node) => {
if (node.key === key) {
const updatedChildren = node.children ? [...node.children, newNode] : [newNode];
return { ...node, children: updatedChildren };
}
if (node.children) {
return { ...node, children: appendNodeByKey(node.children, key) };
}
return node;
});
};

/**
* 移除 key 节点
* @param data 遍历的数组
* @param key 当前 key 值
* @returns 删除数据之后的 data
* @description 移除 key 节点
* @param {ITreeNode<U>[]} data - 遍历的数组
* @param {ITreeNode<U>['key']} key - 当前 key 值
* @returns {ITreeNode<U>[]} 删除数据之后的 data
*/
export const removeNodeByKey = <U,>(
data: ITreeNode<U>[],
key: ITreeNode<U>['key']
): ITreeNode<U>[] => {
return data
): ITreeNode<U>[] =>
data
.filter((node) => node.key !== key)
.map((node) => {
if (node.children) {
Expand All @@ -146,46 +118,98 @@ export const removeNodeByKey = <U,>(
}
return node;
});
};

/**
* 移除 edit 为 true 的节点
* @param treeData
* @returns 移除之后的数据
* @description 移除 edit 为 true 的节点
* @param {ITreeNode<U>[]} treeData - 遍历的数组
* @returns {ITreeNode<U>[]} 移除之后的数据
*/
export const removeEditNode = <U extends { edit?: boolean }>(
treeData: ITreeNode<U>[]
): ITreeNode<U>[] => {
return treeData
): ITreeNode<U>[] =>
treeData
.filter((node) => !node.edit)
.map((node) => ({
...node,
children: node.children ? removeEditNode(node.children) : undefined,
}));
};

/**
*
* @description 在指定节点的子节点列表中添加一组子节点,可以选择添加在开头或结尾
* @param {ITreeNode<U>[]} treeData - 要操作的树节点数组
* @param {ITreeNode<U>['key']} key - 要添加子节点的目标节点 key
* @param {ITreeNode<U>[]} children - 要添加的子节点数组
* @param {boolean} [insertBefore=true] - 是否将子节点添加到现有子节点之前,true 表示添加到开头,false 表示添加到结尾
* @returns {ITreeNode<U>[]} 更新后的树节点数组
*/

export const insertChildIntoNode = <U extends { edit?: boolean }>(
export const insertChildrenToNode = <U extends { edit?: boolean }>(
treeData: ITreeNode<U>[],
key: ITreeNode<U>['key'],
children: ITreeNode<U>[]
): ITreeNode<U>[] => {
return treeData.map((node) => {
children: ITreeNode<U>[],
insertBefore = true
): ITreeNode<U>[] =>
treeData.map((node) => {
if (node.key === key) {
const updatedChildren = insertBefore
? [...children, ...(node.children || [])]
: [...(node.children || []), ...children];
return {
...node,
children,
children: node.children ? updatedChildren : children,
};
}
if (node.children) {
return {
...node,
children: insertChildIntoNode(node.children, key, children),
children: insertChildrenToNode(node.children, key, children, insertBefore),
};
}
return node;
});

/**
* @description 在树节点数组中查找指定 key 的节点索引
* @param {ITreeNode<U>[]} treeData - 要搜索的树节点数组
* @param {ITreeNode<U>['key']} key - 要查找的节点 key
* @returns {number} 找到的节点索引,如果未找到则返回 -1
*/
export const findChildIndex = <U extends { edit?: boolean }>(
data: ITreeNode<U>[],
key: ITreeNode<U>['key']
): number => data.findIndex((item) => item.key === key);

/**
* @description 在树节点数组中,根据指定的 key 找到目标节点,并将新节点插入到目标节点之前或之后。
* @param {ITreeNode<U>[]} treeData - 要操作的树节点数组。
* @param {ITreeNode<U>['key']} currentKey - 目标节点的 key。
* @param {ITreeNode<U>} node - 要插入的新节点。
* @param {boolean} [insertBefore=true] - 是否将新节点插入到目标节点之前。true 表示之前,false 表示之后。
* @returns {ITreeNode<U>[]} 更新后的树节点数组。
*/
export const insertNodeAtKey = <U extends { edit?: boolean }>(
treeData: ITreeNode<U>[],
currentKey: ITreeNode<U>['key'],
node: ITreeNode<U>,
insertBefore = true
): ITreeNode<U>[] => {
const newTreeData: ITreeNode<U>[] = [];
for (const item of treeData) {
if (item.key === currentKey) {
if (insertBefore) {
newTreeData.push(node);
newTreeData.push(item);
} else {
newTreeData.push(item);
newTreeData.push(node);
}
} else {
newTreeData.push({
...item,
children: item.children
? insertNodeAtKey(item.children, currentKey, node, insertBefore)
: item.children,
});
}
}
return newTreeData;
};
Loading