diff --git a/app/src/components/layout/sidebarLeft/SideBarLeft.tsx b/app/src/components/layout/sidebarLeft/SideBarLeft.tsx index 20dd25d..c54d9b2 100644 --- a/app/src/components/layout/sidebarLeft/SideBarLeft.tsx +++ b/app/src/components/layout/sidebarLeft/SideBarLeft.tsx @@ -1,6 +1,5 @@ import React, { useEffect, useState } from "react"; import ToggleHeader from "../../ui/inputs/ToggleHeader"; -// import Outline from "./Outline"; import Header from "./Header"; import { useToggleStore } from "../../../store/ui/useUIToggleStore"; import Assets from "./assetList/Assets"; @@ -9,7 +8,7 @@ import Widgets from "./visualization/widgets/Widgets"; import Templates from "../../../modules/visualization/template/Templates"; import Search from "../../ui/inputs/Search"; import { useIsComparing } from "../../../store/builder/store"; -import { Outline } from "../../../modules/builder/testUi/outline"; +import { AssetOutline } from "../../ui/list/OutlineList/AssetOutline"; const SideBarLeft: React.FC = () => { const [activeOption, setActiveOption] = useState("Widgets"); @@ -54,7 +53,7 @@ const SideBarLeft: React.FC = () => { return ( <> -
{activeOption === "Outline" ? : }
+
{activeOption === "Outline" ? : }
); } else { @@ -63,7 +62,7 @@ const SideBarLeft: React.FC = () => { {!isComparing && ( <> -
{activeOption === "Outline" ? : }
+
{activeOption === "Outline" ? : }
)} @@ -78,4 +77,4 @@ const SideBarLeft: React.FC = () => { export default SideBarLeft; -// sidebar-left-container opemn close sidebar-left-container smoothly +// sidebar-left-container open close sidebar-left-container smoothly diff --git a/app/src/modules/builder/testUi/outline.tsx b/app/src/components/ui/list/OutlineList/AssetOutline.tsx similarity index 84% rename from app/src/modules/builder/testUi/outline.tsx rename to app/src/components/ui/list/OutlineList/AssetOutline.tsx index d980df8..c99d2e9 100644 --- a/app/src/modules/builder/testUi/outline.tsx +++ b/app/src/components/ui/list/OutlineList/AssetOutline.tsx @@ -1,25 +1,15 @@ import { useState, useRef, DragEvent, useCallback } from "react"; import { useParams } from "react-router-dom"; -import { - EyeIcon, - LockIcon, - FolderIcon, - ChevronIcon, - CubeIcon, - AddIcon, - KebebIcon, - CollapseAllIcon, - FocusIcon, -} from "../../../components/icons/ExportCommonIcons"; -import RenameInput from "../../../components/ui/inputs/RenameInput"; -import { useSceneContext } from "../../scene/sceneContext"; -import { useSocketStore } from "../../../store/socket/useSocketStore"; -import useAssetResponseHandler from "../../collaboration/responseHandler/useAssetResponseHandler"; +import { EyeIcon, LockIcon, FolderIcon, ChevronIcon, CubeIcon, AddIcon, KebebIcon, CollapseAllIcon, FocusIcon } from "../../../icons/ExportCommonIcons"; +import RenameInput from "../../inputs/RenameInput"; +import { useSceneContext } from "../../../../modules/scene/sceneContext"; +import { useSocketStore } from "../../../../store/socket/useSocketStore"; +import useAssetResponseHandler from "../../../../modules/collaboration/responseHandler/useAssetResponseHandler"; -import { getUserData } from "../../../functions/getUserData"; -import { setAssetsApi } from "../../../services/factoryBuilder/asset/floorAsset/setAssetsApi"; +import { getUserData } from "../../../../functions/getUserData"; +import { setAssetsApi } from "../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi"; import clsx from "clsx"; -import { useContextActionStore } from "../../../store/builder/store"; +import { useContextActionStore } from "../../../../store/builder/store"; interface DragState { draggedItem: AssetGroupChild | null; @@ -63,8 +53,7 @@ const TreeNode = ({ 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); + const isMultiSelected = !isGroupNode && selectedAssets.length > 1 && hasSelectedAsset(item.modelUuid); // Determine the parent group of this item const getParentGroup = useCallback( @@ -123,10 +112,7 @@ const TreeNode = ({ const shouldShowHighlight = isDropTarget(); return ( -
+
{isGroupNode && ( - )} -
- {isGroupNode ? : } -
+
{isGroupNode ? : }
{}} canEdit={true} /> @@ -230,7 +211,7 @@ const TreeNode = ({ }; // Main Component -export const Outline = () => { +export const AssetOutline = () => { const [isOpen, setIsOpen] = useState(true); const { setContextAction } = useContextActionStore(); const lastSelectedRef = useRef<{ item: AssetGroupChild; index: number } | null>(null); @@ -242,25 +223,8 @@ export const Outline = () => { }); const [_, forceUpdate] = useState({}); const { scene, assetGroupStore, assetStore, versionStore, undoRedo3DStore } = useSceneContext(); - const { - addSelectedAsset, - clearSelectedAssets, - getAssetById, - peekToggleVisibility, - peekToggleLock, - toggleSelectedAsset, - selectedAssets, - } = assetStore(); - const { - groupHierarchy, - isGroup, - getGroupsContainingAsset, - getFlatGroupChildren, - setGroupExpanded, - addChildToGroup, - removeChildFromGroup, - getGroupsContainingGroup, - } = assetGroupStore(); + const { addSelectedAsset, clearSelectedAssets, getAssetById, peekToggleVisibility, peekToggleLock, toggleSelectedAsset, selectedAssets } = assetStore(); + const { groupHierarchy, isGroup, getGroupsContainingAsset, getFlatGroupChildren, setGroupExpanded, addChildToGroup, removeChildFromGroup, getGroupsContainingGroup } = assetGroupStore(); const { projectId } = useParams(); const { push3D } = undoRedo3DStore(); const { builderSocket } = useSocketStore(); @@ -304,11 +268,7 @@ export const Outline = () => { }) .then((data) => { if (!data.message || !data.data) { - echo.error( - `Error ${asset.isVisible ? "hiding" : "unhiding"} asset: ${ - asset.modelName - }` - ); + echo.error(`Error ${asset.isVisible ? "hiding" : "unhiding"} asset: ${asset.modelName}`); return; } if (data.message === "Model updated successfully" && data.data) { @@ -327,22 +287,14 @@ export const Outline = () => { }; updateAssetInScene(model, () => { - echo.info( - `${asset.isVisible ? "Hid" : "Unhid"} asset: ${model.modelName}` - ); + echo.info(`${asset.isVisible ? "Hid" : "Unhid"} asset: ${model.modelName}`); }); } else { - echo.error( - `Error ${asset.isVisible ? "hiding" : "unhiding"} asset: ${ - asset.modelName - }` - ); + echo.error(`Error ${asset.isVisible ? "hiding" : "unhiding"} asset: ${asset.modelName}`); } }) .catch(() => { - echo.error( - `Error ${asset.isVisible ? "hiding" : "unhiding"} asset: ${asset.modelName}` - ); + echo.error(`Error ${asset.isVisible ? "hiding" : "unhiding"} asset: ${asset.modelName}`); }); } else { const data = { @@ -387,11 +339,7 @@ export const Outline = () => { }) .then((data) => { if (!data.message || !data.data) { - echo.error( - `Error ${asset.isVisible ? "locking" : "unlocking"} asset: ${ - asset.modelName - }` - ); + echo.error(`Error ${asset.isVisible ? "locking" : "unlocking"} asset: ${asset.modelName}`); return; } if (data.message === "Model updated successfully" && data.data) { @@ -410,26 +358,14 @@ export const Outline = () => { }; updateAssetInScene(model, () => { - echo.info( - `${asset.isVisible ? "Locked" : "Unlocked"} asset: ${ - model.modelName - }` - ); + echo.info(`${asset.isVisible ? "Locked" : "Unlocked"} asset: ${model.modelName}`); }); } else { - echo.error( - `Error ${asset.isVisible ? "locking" : "unlocking"} asset: ${ - asset.modelName - }` - ); + echo.error(`Error ${asset.isVisible ? "locking" : "unlocking"} asset: ${asset.modelName}`); } }) .catch(() => { - echo.error( - `Error ${asset.isVisible ? "locking" : "unlocking"} asset: ${ - asset.modelName - }` - ); + echo.error(`Error ${asset.isVisible ? "locking" : "unlocking"} asset: ${asset.modelName}`); }); } else { const data = { @@ -461,16 +397,13 @@ export const Outline = () => { [setGroupExpanded] ); - const handleDragStart = useCallback( - (e: DragEvent, item: AssetGroupChild, parentGroupUuid: string | null) => { - dragStateRef.current.draggedItem = item; - dragStateRef.current.draggedItemParentGroupUuid = parentGroupUuid; + const handleDragStart = useCallback((e: DragEvent, item: AssetGroupChild, parentGroupUuid: string | null) => { + dragStateRef.current.draggedItem = item; + dragStateRef.current.draggedItemParentGroupUuid = parentGroupUuid; - e.dataTransfer.effectAllowed = "move"; - forceUpdate({}); - }, - [] - ); + e.dataTransfer.effectAllowed = "move"; + forceUpdate({}); + }, []); const handleDragOver = useCallback( (e: DragEvent, targetItem: AssetGroupChild) => { @@ -540,10 +473,7 @@ export const Outline = () => { } // Update target group - if ( - dragStateRef.current.targetGroupUuid !== targetGroupUuid || - dragStateRef.current.isRootTarget !== false - ) { + if (dragStateRef.current.targetGroupUuid !== targetGroupUuid || dragStateRef.current.isRootTarget !== false) { dragStateRef.current.targetGroupUuid = targetGroupUuid; dragStateRef.current.isRootTarget = false; forceUpdate({}); @@ -657,9 +587,7 @@ export const Outline = () => { // Update last selected reference const flattened = getFlattenedHierarchy(); - const index = flattened.findIndex( - (flatItem) => getItemId(flatItem) === getItemId(item) - ); + const index = flattened.findIndex((flatItem) => getItemId(flatItem) === getItemId(item)); lastSelectedRef.current = { item, index }; } } @@ -673,9 +601,7 @@ export const Outline = () => { // Update last selected reference const flattened = getFlattenedHierarchy(); - const index = flattened.findIndex( - (flatItem) => getItemId(flatItem) === getItemId(item) - ); + const index = flattened.findIndex((flatItem) => getItemId(flatItem) === getItemId(item)); lastSelectedRef.current = { item, index }; } } @@ -683,9 +609,7 @@ export const Outline = () => { // Shift+Click - range selection else if (isShiftClick) { const flattened = getFlattenedHierarchy(); - const clickedIndex = flattened.findIndex( - (flatItem) => getItemId(flatItem) === getItemId(item) - ); + const clickedIndex = flattened.findIndex((flatItem) => getItemId(flatItem) === getItemId(item)); if (clickedIndex === -1) return; @@ -731,14 +655,7 @@ export const Outline = () => { }); } }, - [ - scene, - isGroup, - clearSelectedAssets, - addSelectedAsset, - getFlattenedHierarchy, - toggleSelectedAsset, - ] + [scene, isGroup, clearSelectedAssets, addSelectedAsset, getFlattenedHierarchy, toggleSelectedAsset] ); const handleOptionClick = useCallback( @@ -860,11 +777,8 @@ export const Outline = () => { className="toolbar-button" title="Expand All" onClick={() => { - const { assetGroups, setGroupExpanded } = - assetGroupStore.getState(); - assetGroups.forEach((group) => - setGroupExpanded(group.groupUuid, true) - ); + const { assetGroups, setGroupExpanded } = assetGroupStore.getState(); + assetGroups.forEach((group) => setGroupExpanded(group.groupUuid, true)); }} > @@ -876,13 +790,7 @@ export const Outline = () => {
{isOpen && ( -
+
{groupHierarchy.map((item) => ( {
- 1 ? "multi-selection" : ""}`} - > - {selectedAssets.length > 1 - ? `${selectedAssets.length} items selected` - : `${groupHierarchy.length} root items`} + 1 ? "multi-selection" : ""}`}> + {selectedAssets.length > 1 ? `${selectedAssets.length} items selected` : `${groupHierarchy.length} root items`}
diff --git a/app/src/modules/builder/wall/wallCreator/wallCreator.tsx b/app/src/modules/builder/wall/wallCreator/wallCreator.tsx index 709cc50..c7697ed 100644 --- a/app/src/modules/builder/wall/wallCreator/wallCreator.tsx +++ b/app/src/modules/builder/wall/wallCreator/wallCreator.tsx @@ -61,7 +61,7 @@ function WallCreator() { const addWallToBackend = (wall: Wall) => { if (projectId) { - if (!builderSocket?.connected) { + if (builderSocket?.connected) { // API upsertWallApi(projectId, selectedVersion?.versionId || "", wall) @@ -104,7 +104,7 @@ function WallCreator() { organization: organization, }; - builderSocket.emit("v1:model-Wall:add", data); + // builderSocket.emit("v1:model-Wall:add", data); setTempPoints([]); setIsCreating(false); diff --git a/app/src/modules/scene/controls/assetControls/groupControls.tsx b/app/src/modules/scene/controls/assetControls/groupControls.tsx index ba04658..1b92838 100644 --- a/app/src/modules/scene/controls/assetControls/groupControls.tsx +++ b/app/src/modules/scene/controls/assetControls/groupControls.tsx @@ -11,14 +11,15 @@ import useCallBackOnKey from "../../../../utils/hooks/useCallBackOnKey"; import generateUniqueAssetGroupName from "../../../builder/asset/functions/generateUniqueAssetGroupName"; import { setAssetsApi } from "../../../../services/factoryBuilder/asset/floorAsset/setAssetsApi"; import { getAssetGroupsApi } from "../../../../services/factoryBuilder/group/assetGroup/getAssetGroupsApi"; +import { createAssetGroupApi } from "../../../../services/factoryBuilder/group/assetGroup/createAssetGroupApi"; function GroupControls() { const { projectId } = useParams(); const { builderSocket } = useSocketStore(); const { assetStore, undoRedo3DStore, versionStore, assetGroupStore } = useSceneContext(); - const { assetGroups, addGroup, buildHierarchy } = assetGroupStore(); + const { assetGroups, addGroup, setGroups, buildHierarchy } = assetGroupStore(); const { push3D } = undoRedo3DStore(); - const { assets, selectedAssets, pastedObjects, duplicatedObjects, movedObjects, rotatedObjects } = assetStore(); + const { assets, selectedAssets, pastedObjects, duplicatedObjects, movedObjects, rotatedObjects, getSelectedAssetUuids } = assetStore(); const { updateAssetInScene, removeAssetFromScene } = useAssetResponseHandler(); const { contextAction, setContextAction } = useContextActionStore(); const { selectedVersion } = versionStore(); @@ -29,6 +30,9 @@ function GroupControls() { getAssetGroupsApi(projectId, selectedVersion.versionId).then((data) => { console.log("data: ", data); + if (data && data.length > 0) { + setGroups(data); + } }); }, [projectId, selectedVersion]); @@ -43,18 +47,12 @@ function GroupControls() { setContextAction(null); groupSelection(); } - }, [contextAction]); + }, [contextAction, projectId, selectedVersion]); const groupSelection = () => { - const assetUuids: string[] = []; + const assetUuids: string[] = getSelectedAssetUuids(); - selectedAssets.forEach((selectedAsset) => { - if (selectedAsset.userData.modelUuid) { - assetUuids.push(selectedAsset.userData.modelUuid); - } - }); - - if (assetUuids.length > 0) { + if (assetUuids.length > 0 && projectId && selectedVersion) { const groupName = generateUniqueAssetGroupName({ baseName: "Group", existingGroups: assetGroups }); const assetGroup: AssetGroup = { @@ -67,7 +65,21 @@ function GroupControls() { return { type: "Asset", childrenUuid: assetUuid }; }), }; - addGroup(assetGroup); + console.log("assetGroup: ", assetGroup); + // addGroup(assetGroup); + + createAssetGroupApi({ + projectId, + versionId: selectedVersion.versionId, + groupUuid: assetGroup.groupUuid, + groupName: assetGroup.groupName, + isVisible: assetGroup.isVisible, + isExpanded: assetGroup.isExpanded, + isLocked: assetGroup.isLocked, + childrens: assetGroup.childrens, + }).then((data) => { + console.log("data: ", data); + }); } }; @@ -81,6 +93,8 @@ function GroupControls() { { dependencies: [pastedObjects, duplicatedObjects, movedObjects, rotatedObjects, selectedAssets, selectedVersion, builderSocket, projectId, userId, organization], noRepeat: true } ); + useCallBackOnKey(() => {}, "Alt+G", { dependencies: [], noRepeat: true }); + return null; } diff --git a/app/src/services/factoryBuilder/group/assetGroup/createAssetGroupApi.ts b/app/src/services/factoryBuilder/group/assetGroup/createAssetGroupApi.ts index d4b49cd..c6072c0 100644 --- a/app/src/services/factoryBuilder/group/assetGroup/createAssetGroupApi.ts +++ b/app/src/services/factoryBuilder/group/assetGroup/createAssetGroupApi.ts @@ -1,37 +1,44 @@ const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; -interface Props { +export const createAssetGroupApi = async ({ + projectId, + versionId, + groupUuid, + groupName, + isVisible, + isExpanded, + isLocked, + childrens, +}: { projectId: string; versionId: string; groupUuid: string; groupName: string; - isVisible: string; - isExpanded: string; - isLocked: string; + isVisible: boolean; + isExpanded: boolean; + isLocked: boolean; childrens: { type: "Asset" | "Group"; childrenUuid: string; }[]; -} - -export const createAssetGroupApi = async (props: Props) => { +}) => { try { - const response = await fetch(`${url_Backend_dwinzo}/api/V1/assetgroup/${props.projectId}/${props.versionId}`, { + const response = await fetch(`${url_Backend_dwinzo}/api/V1/assetgroup/${projectId}/${versionId}`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${localStorage.getItem("token") || ""}`, token: localStorage.getItem("token") || "", refresh_token: localStorage.getItem("refreshToken") || "", - body: JSON.stringify({ - groupUuid: props.groupUuid, - groupName: props.groupName, - isVisible: props.isVisible, - isExpanded: props.isExpanded, - isLocked: props.isLocked, - childrens: props.childrens, - }), }, + body: JSON.stringify({ + groupUuid: groupUuid, + groupName: groupName, + isVisible: isVisible, + isExpanded: isExpanded, + isLocked: isLocked, + childrens: childrens, + }), }); const newAccessToken = response.headers.get("x-access-token"); diff --git a/app/src/services/factoryBuilder/group/assetGroup/getAssetGroupsApi.ts b/app/src/services/factoryBuilder/group/assetGroup/getAssetGroupsApi.ts index 7ad4a08..8fa9c8d 100644 --- a/app/src/services/factoryBuilder/group/assetGroup/getAssetGroupsApi.ts +++ b/app/src/services/factoryBuilder/group/assetGroup/getAssetGroupsApi.ts @@ -2,7 +2,7 @@ let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_UR export const getAssetGroupsApi = async (projectId: string, versionId: string) => { try { - const response = await fetch(`${url_Backend_dwinzo}/api/V1/assetGroups/${projectId}/${versionId}`, { + const response = await fetch(`${url_Backend_dwinzo}/api/V1/assetgroups/${projectId}/${versionId}`, { method: "GET", headers: { Authorization: "Bearer ",