This commit is contained in:
rizky 2024-08-09 00:30:23 -07:00
parent 2058499de0
commit 09c3eb5e9a
3 changed files with 71 additions and 32 deletions

View File

@ -611,6 +611,7 @@ export const TableList: FC<TableListProp> = ({
"c-flex c-items-center c-cursor-pointer" "c-flex c-items-center c-cursor-pointer"
)} )}
onClick={(e) => { onClick={(e) => {
console.log(props.row);
if (!local.pk) return; if (!local.pk) return;
if (props?.row?.__children?.length > 0) { if (props?.row?.__children?.length > 0) {
e.stopPropagation(); e.stopPropagation();
@ -641,7 +642,7 @@ export const TableList: FC<TableListProp> = ({
)} )}
</div> </div>
{props.row?.__parent && {props.row?.__parent &&
props.row?.__children?.length === 0 && ( (props.row?.__children || []).length === 0 && (
<div <div
className={cx( className={cx(
" c-border-l c-border-b c-border-black c-w-[10px] c-h-[15px]", " c-border-l c-border-b c-border-black c-w-[10px] c-h-[15px]",

View File

@ -42,53 +42,88 @@ export const treePrefix = (props: any) => {
} }
return prefix; return prefix;
}; };
export const sortTree = (list: any[], parent_key: string, pk: string) => { export const sortTree = (list: any[], parent_key: string, pk: string) => {
const nodes: { [id: string]: any } = {}; const nodes: { [id: string]: any } = {};
const result: any[] = [];
// First pass: Create nodes
list.forEach((node) => { list.forEach((node) => {
const id = node[pk]; const id = node[pk];
nodes[id] = { ...node, __depth: 0, __children: [], __parent: null }; nodes[id] = { ...node, __depth: 0, __children: [] };
}); });
// Second pass: Build relationships let mode = "";
list.forEach((node) => { const final = list;
// .sort((a, b) => {
// if (!mode) mode = typeof a[pk];
// if (mode === "string")
// return (a?.[parent_key] || "").localeCompare(b?.[parent_key] || "");
// return (a?.[parent_key] || 0) - (b?.[parent_key] || 0);
// });
final.forEach((node, idx) => {
const id = node[pk]; const id = node[pk];
const parentId = node[parent_key]; const parentId = node[parent_key];
if (parentId && parentId !== id && nodes[parentId]) { if (parentId === null || parentId === undefined) {
nodes[id].__parent = nodes[parentId]; result.push(nodes[id]);
nodes[parentId].__children.push(nodes[id]); } else {
if (nodes[parentId]) {
nodes[parentId].__children.push(nodes[id]);
} else {
// Handle the case where a parent is missing
result.push(nodes[id]);
}
} }
}); });
// Function to calculate depth const added = new Set<any>();
const calculateDepth = (node: any, visited: Set<string> = new Set()): number => {
if (visited.has(node.id)) return 0; // Prevent cycles
visited.add(node.id);
if (!node.__parent) return 0;
return 1 + calculateDepth(node.__parent, visited);
};
// Calculate depths // Function to flatten the tree
Object.values(nodes).forEach((node: any) => { function flattenTree(
node.__depth = calculateDepth(node); node: any,
}); depth: number = 0,
parent: any = null
): any[] {
node.__depth = depth;
const children = node.__children || [];
node.__parent = parent;
// Sort nodes if (!added.has(node[pk])) {
const sortedNodes = Object.values(nodes).sort((a: any, b: any) => { added.add(node[pk]);
if (a.__depth !== b.__depth) return a.__depth - b.__depth;
if (a.__children.length !== b.__children.length) {
return b.__children.length - a.__children.length;
} }
return a.name.localeCompare(b.name);
});
// Assign indices return [
sortedNodes.forEach((node: any, index: number) => { 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);
}
return (b.__children?.length || 0) - (a.__children?.length || 0);
})
.flatMap((child: any) => flattenTree(child, depth + 1, node)),
];
}
// Flatten and assign indices
const flatResult = result.flatMap((node) => flattenTree(node));
for (const item of list) {
if (!added.has(item[pk])) {
flatResult.push(item);
}
}
flatResult.forEach((node, index) => {
node.idx = index; node.idx = index;
}); });
return sortedNodes; return flatResult;
}; };

View File

@ -21,6 +21,9 @@ const events = {
}, },
field: { field: {
on_change: async (fm: FMLocal, field: FieldLocal) => {}, on_change: async (fm: FMLocal, field: FieldLocal) => {},
relation_load: async (fm: FMLocal, field: FieldLocal) => {
return {} as Record<string, any>;
},
}, },
tablelist: { tablelist: {
after_load: async <T extends Prisma.ModelName>( after_load: async <T extends Prisma.ModelName>(