diff --git a/app/src/components/ui/list/OutlineList/AssetOutline.tsx b/app/src/components/ui/list/OutlineList/AssetOutline.tsx index c99d2e9..0536262 100644 --- a/app/src/components/ui/list/OutlineList/AssetOutline.tsx +++ b/app/src/components/ui/list/OutlineList/AssetOutline.tsx @@ -1,15 +1,17 @@ -import { useState, useRef, DragEvent, useCallback } from "react"; +import { useState, useRef, DragEvent, useCallback, useMemo } from "react"; import { useParams } from "react-router-dom"; -import { EyeIcon, LockIcon, FolderIcon, ChevronIcon, CubeIcon, AddIcon, KebebIcon, CollapseAllIcon, FocusIcon } from "../../../icons/ExportCommonIcons"; +import { EyeIcon, LockIcon, FolderIcon, ChevronIcon, CubeIcon, AddIcon, KebebIcon, CollapseAllIcon, FocusIcon, DeleteIcon } from "../../../icons/ExportCommonIcons"; import RenameInput from "../../inputs/RenameInput"; +import clsx from "clsx"; import { useSceneContext } from "../../../../modules/scene/sceneContext"; import { useSocketStore } from "../../../../store/socket/useSocketStore"; import useAssetResponseHandler from "../../../../modules/collaboration/responseHandler/useAssetResponseHandler"; +import useZoomMesh from "../../../../modules/builder/hooks/useZoomMesh"; import { getUserData } from "../../../../functions/getUserData"; +import { useOuterClick } from "../../../../utils/useOuterClick"; + import { setAssetsApi } from "../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi"; -import clsx from "clsx"; -import { useContextActionStore } from "../../../../store/builder/store"; interface DragState { draggedItem: AssetGroupChild | null; @@ -18,7 +20,7 @@ interface DragState { isRootTarget: boolean; } -// Tree Node Component +// Enhanced Tree Node Component with Group Selection const TreeNode = ({ item, level = 0, @@ -44,7 +46,7 @@ const TreeNode = ({ }) => { const { assetGroupStore, assetStore } = useSceneContext(); const { hasSelectedAsset, selectedAssets } = assetStore(); - const { isGroup, getGroupsContainingAsset, getGroupsContainingGroup } = assetGroupStore(); + const { isGroup, hasSelectedGroup, selectedGroups, getParentGroup } = assetGroupStore(); const isGroupNode = isGroup(item); const itemId = isGroupNode ? item.groupUuid : item.modelUuid; @@ -52,31 +54,26 @@ const TreeNode = ({ const isVisible = item.isVisible; const isLocked = item.isLocked; const isExpanded = isGroupNode ? item.isExpanded : false; - const isSelected = !isGroupNode ? hasSelectedAsset(item.modelUuid) : false; - const isMultiSelected = !isGroupNode && selectedAssets.length > 1 && hasSelectedAsset(item.modelUuid); - // Determine the parent group of this item - const getParentGroup = useCallback( - (currentItem: AssetGroupChild): string | null => { - if (isGroup(currentItem)) { - const parents = getGroupsContainingGroup(currentItem.groupUuid); - return parents.length > 0 ? parents[0].groupUuid : null; - } else { - const parents = getGroupsContainingAsset(currentItem.modelUuid); - return parents.length > 0 ? parents[0].groupUuid : null; - } - }, - [getGroupsContainingAsset, getGroupsContainingGroup, isGroup] - ); + const isSelected = isGroupNode ? hasSelectedGroup(item.groupUuid) : hasSelectedAsset(item.modelUuid); + + const getMultiSelectionState = (item: AssetGroupChild) => { + const totalSelectedItems = selectedGroups.length + selectedAssets.length; + + if (totalSelectedItems <= 1) return false; + + if (isGroup(item)) { + return selectedGroups.includes(item.groupUuid); + } else { + return hasSelectedAsset(item.modelUuid); + } + }; + + const isMultiSelected = getMultiSelectionState(item); - // Check if this node should be highlighted as a drop target const isDropTarget = useCallback(() => { if (!dragState.draggedItem || !dragState.targetGroupUuid || !isGroupNode) return false; - - // Get the group UUID this item belongs to or is const thisGroupUuid = item.groupUuid; - - // Highlight if this is the target group or belongs to the target group return thisGroupUuid === dragState.targetGroupUuid; }, [dragState, isGroupNode, item]); @@ -112,9 +109,11 @@ const TreeNode = ({ const shouldShowHighlight = isDropTarget(); return ( -
Assets