Added outlineListData for asset hierarchy

This commit is contained in:
2025-10-24 15:13:42 +05:30
parent c22fd8ae38
commit 5b4017a7c3
5 changed files with 44 additions and 42 deletions

View File

@@ -3,17 +3,7 @@ import { AddIcon, ChevronIcon, CollapseAllIcon } from "../../icons/ExportIcons";
import { OutlinePanelProps } from "./OutlinePanel";
import TreeNode from "./TreeNode";
import Search from "./Search";
export interface AssetGroupChild {
groupUuid?: string;
groupName?: string;
isExpanded?: boolean;
children?: AssetGroupChild[];
modelUuid?: string;
modelName?: string;
isVisible?: boolean;
isLocked?: boolean;
}
import { AssetGroupChild } from "../../data/OutlineListData";
type DropAction = "above" | "child" | "below" | "none";
@@ -39,19 +29,27 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
height,
width,
search,
data,
}) => {
const [selectedId, setSelectedId] = useState<string | null>(null);
const [isPanelOpen, setIsPanelOpen] = useState(true);
const [draggedNode, setDraggedNode] = useState<AssetGroupChild | null>(null);
const [searchValue, setSearchValue] = useState("");
const [hierarchy, setHierarchy] = useState<AssetGroupChild[]>([
{ modelUuid: "a1", modelName: "Asset 1", isVisible: true, isLocked: false, children: [] },
{ modelUuid: "a2", modelName: "Asset 2", isVisible: true, isLocked: false, children: [] },
{ modelUuid: "a3", modelName: "Asset 3", isVisible: true, isLocked: false, children: [] },
{ modelUuid: "a4", modelName: "Asset 4", isVisible: true, isLocked: false, children: [] },
{ modelUuid: "a5", modelName: "Asset 5", isVisible: true, isLocked: false, children: [] },
{ modelUuid: "a6", modelName: "Asset 6", isVisible: true, isLocked: false, children: [] },
]);
const [hierarchy, setHierarchy] = useState<AssetGroupChild[]>(data);
useEffect(() => {
const handleClickOutside = (event: MouseEvent): void => {
const target = event.target as HTMLElement;
if (!target.closest(".outline-card")) {
setSelectedId(null);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);
const handleDragStart = (item: AssetGroupChild) => {
setDraggedNode(item);
@@ -120,10 +118,8 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
const updatedHierarchy = [...hierarchy];
// remove old reference
if (!removeFromHierarchy(draggedItem, updatedHierarchy)) return;
// insert in new location
if (!insertByDropAction(draggedItem, targetId, dropAction, updatedHierarchy)) {
updatedHierarchy.push(draggedItem);
}
@@ -215,19 +211,6 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
}
return false;
};
useEffect(() => {
const handleClickOutside = (event: MouseEvent): void => {
const target = event.target as HTMLElement;
if (!target.closest(".outline-card")) {
setSelectedId(null);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);
const filterHierarchy = (items: AssetGroupChild[], query: string): AssetGroupChild[] => {
if (!query.trim()) return items;
@@ -240,7 +223,6 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
const filteredChildren = item.children ? filterHierarchy(item.children, query) : [];
// If this node or any of its children match, keep it
if (matches || filteredChildren.length > 0) {
return { ...item, children: filteredChildren };
}
@@ -248,6 +230,7 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
})
.filter(Boolean) as AssetGroupChild[];
};
const filteredHierarchy = filterHierarchy(hierarchy, searchValue);
const handleRename = (id: string, newName: string) => {
@@ -311,7 +294,6 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
</div>
)}
{/* List */}
{isPanelOpen && (
<div className="outline-content">
{filteredHierarchy.map((node) => (

View File

@@ -1,5 +1,6 @@
import React from "react";
import { OutlineList } from "./OutlineList ";
import { AssetGroupChild } from "../../data/OutlineListData";
export interface OutlinePanelProps {
textColor?: string;
@@ -11,6 +12,7 @@ export interface OutlinePanelProps {
height?: string;
width?: string;
search?: boolean;
data: AssetGroupChild[];
}
const OutlinePanel: React.FC<OutlinePanelProps> = (props) => {

View File

@@ -1,5 +1,5 @@
import { useState } from "react";
import { AssetGroupChild, DEFAULT_PRAMS } from "./OutlineList ";
import { DEFAULT_PRAMS } from "./OutlineList ";
import clsx from "clsx";
import {
ChevronIcon,
@@ -10,6 +10,7 @@ import {
KebebIcon,
LockIcon,
} from "../../icons/ExportIcons";
import { AssetGroupChild } from "../../data/OutlineListData";
interface TreeNodeProps {
item: AssetGroupChild;
@@ -120,15 +121,12 @@ const TreeNode: React.FC<TreeNodeProps> = ({
id={item.modelUuid || item.groupUuid}
onClick={toggleSelect}
>
{/* 👇 Flex container for the entire row */}
<div
className="node-wrapper"
style={{ display: "flex", alignItems: "center", width: "100%" }}
>
{/* Indentation spacer — only affects left side */}
<div style={{ width: `${level * 20}px`, flexShrink: 0 }} />
{/* Expand button (only for groups) */}
{isGroupNode ? (
<button
className="expand-button"
@@ -140,7 +138,7 @@ const TreeNode: React.FC<TreeNodeProps> = ({
<ChevronIcon isOpen={isExpanded} />
</button>
) : (
<div style={{ width: "20px", flexShrink: 0 }} /> // match expand button width
<div style={{ width: "20px", flexShrink: 0 }} />
)}
<div className="node-icon" style={{ flexShrink: 0 }}>
@@ -185,7 +183,6 @@ const TreeNode: React.FC<TreeNodeProps> = ({
)}
</div>
{/* Controls (always visible, never shrink) */}
<div
className="node-controls"
style={{ display: "flex", gap: "4px", flexShrink: 0 }}

View File

@@ -0,0 +1,19 @@
export const OutlineListData = [
{ modelUuid: "a1", modelName: "Asset 1", isVisible: true, isLocked: false, children: [] },
{ modelUuid: "a2", modelName: "Asset 2", isVisible: true, isLocked: false, children: [] },
{ modelUuid: "a3", modelName: "Asset 3", isVisible: true, isLocked: false, children: [] },
{ modelUuid: "a4", modelName: "Asset 4", isVisible: true, isLocked: false, children: [] },
{ modelUuid: "a5", modelName: "Asset 5", isVisible: true, isLocked: false, children: [] },
{ modelUuid: "a6", modelName: "Asset 6", isVisible: true, isLocked: false, children: [] },
];
export interface AssetGroupChild {
groupUuid?: string;
groupName?: string;
isExpanded?: boolean;
children?: AssetGroupChild[];
modelUuid?: string;
modelName?: string;
isVisible?: boolean;
isLocked?: boolean;
}

View File

@@ -1,4 +1,5 @@
import OutlinePanel from "../components/ui/OutlinePanel";
import { OutlineListData } from "../data/OutlineListData";
const SceneView = () => {
return (
@@ -11,6 +12,7 @@ const SceneView = () => {
// eyeIconColor=""
// backgroundColor=""
search={true}
data={OutlineListData}
/>
);
};