This commit is contained in:
rizky 2024-07-30 03:48:40 -07:00
parent d1de16a753
commit ad7c4bf1a6
1 changed files with 145 additions and 75 deletions

View File

@ -43,87 +43,157 @@ export const treePrefix = (props: any) => {
return prefix;
};
export const sortTree = (list: any, parent_key: string, pk: string) => {
let meta = {} as Record<
string,
{ item: any; idx: string; depth: number; id_parent: any }
>;
export const sortTree = (list: any[], parent_key: string, pk: string) => {
const nodes: { [id: string]: any } = {};
const result: any[] = [];
if (list.length > 0 && !isEditor) {
const new_list = [];
const unlisted = {} as Record<string, any>;
for (const item of list) {
if (item[parent_key] === null) {
if (!meta[item[pk]]) {
meta[item[pk]] = {
item,
idx: new_list.length + "",
depth: 0,
id_parent: null,
};
item.__depth = 0;
new_list.push(item);
}
// First pass: Create nodes
list.forEach((node) => {
const id = node[pk];
nodes[id] = { ...node, __depth: 0, __children: [] };
});
// Second pass: Build the tree structure
list.forEach((node) => {
const id = node[pk];
const parentId = node[parent_key];
if (parentId === null || parentId === undefined) {
result.push(nodes[id]);
} else {
unlisted[item[pk]] = item;
}
}
let cyclic = {} as Record<string, number>;
while (Object.values(unlisted).length > 0) {
for (const item of Object.values(unlisted)) {
const parent = meta[item[parent_key]];
if (!cyclic[item[pk]]) {
cyclic[item[pk]] = 1;
if (nodes[parentId]) {
nodes[parentId].__children.push(nodes[id]);
} else {
cyclic[item[pk]]++;
// Handle the case where a parent is missing
result.push(nodes[id]);
}
if (cyclic[item[pk]] > 5) {
item.__depth = 0;
meta[item[pk]] = {
item,
depth: 0,
idx: new_list.length + "",
id_parent: null,
};
new_list.push(item);
delete unlisted[item[pk]];
continue;
}
});
// Function to flatten the tree
function flattenTree(node: any, depth: number = 0): any[] {
node.__depth = depth;
const children = node.__children || [];
delete node.__children;
return [
node,
...children
.sort((a: any, b: any) => {
if (
a.__children.length === 0 &&
b.__children.length === 0 &&
a.name &&
b.name
) {
return a.name.localeCompare(b.name);
}
if (item[parent_key] === item[pk]) {
item.__depth = 0;
meta[item[pk]] = {
item,
depth: 0,
idx: new_list.length + "",
id_parent: null,
};
new_list.push(item);
delete unlisted[item[pk]];
continue;
return (b.__children?.length || 0) - (a.__children?.length || 0);
})
.flatMap((child: any) => flattenTree(child, depth + 1)),
];
}
if (parent) {
item.__depth = parent.depth + 1;
// Flatten and assign indices
const flatResult = result.flatMap((node) => flattenTree(node));
flatResult.forEach((node, index) => {
node.idx = index;
});
meta[item[pk]] = {
item,
depth: parent.depth + 1,
idx: parent.idx + ".",
id_parent: item[parent_key],
};
delete unlisted[item[pk]];
}
}
}
const sorted = Object.values(meta)
.sort((a, b) => a.idx.localeCompare(b.idx))
.map((e) => e.item);
return sorted;
}
return list;
return flatResult;
};
// export const sortTree = (list: any[], parent_key: string, pk: string) => {
// let meta = {} as Record<
// string,
// { item: any; idx: string; depth: number; id_parent: any }
// >;
// let mode = "" as "" | "str" | "num";
// let _list = list.sort((a, b) => {
// if (!mode) {
// mode = typeof a[pk] === "string" ? "str" : "num";
// }
// if (mode === "str") return b[pk].toLocaleString(a[pk]);
// return a[pk] - b[pk];
// });
// if (_list.length > 0 && !isEditor) {
// const new_list = [];
// const unlisted = {} as Record<string, any>;
// for (const item of _list) {
// if (item[parent_key] === null) {
// if (!meta[item[pk]]) {
// meta[item[pk]] = {
// item,
// idx: new_list.length + "",
// depth: 0,
// id_parent: null,
// };
// item.__depth = 0;
// new_list.push(item);
// }
// } else {
// unlisted[item[pk]] = item;
// }
// }
// let cyclic = {} as Record<string, number>;
// while (Object.values(unlisted).length > 0) {
// for (const item of Object.values(unlisted)) {
// const parent = meta[item[parent_key]];
// if (!cyclic[item[pk]]) {
// cyclic[item[pk]] = 1;
// } else {
// cyclic[item[pk]]++;
// }
// if (cyclic[item[pk]] > 5) {
// item.__depth = 0;
// meta[item[pk]] = {
// item,
// depth: 0,
// idx: new_list.length + "",
// id_parent: null,
// };
// new_list.push(item);
// delete unlisted[item[pk]];
// continue;
// }
// if (item[parent_key] === item[pk]) {
// item.__depth = 0;
// meta[item[pk]] = {
// item,
// depth: 0,
// idx: new_list.length + "",
// id_parent: null,
// };
// new_list.push(item);
// delete unlisted[item[pk]];
// continue;
// }
// if (parent) {
// item.__depth = parent.depth + 1;
// meta[item[pk]] = {
// item,
// depth: parent.depth + 1,
// idx: parent.idx + ".",
// id_parent: item[parent_key],
// };
// delete unlisted[item[pk]];
// }
// }
// }
// const sorted = Object.values(meta)
// .sort((a, b) => a.idx.localeCompare(b.idx))
// .map((e) => e.item);
// return sorted;
// }
// return _list;
// };