Merge pull request 'dev-contextMenu' (#1) from dev-contextMenu into main-demo

Reviewed-on: http://185.100.212.76:7778/Dwinzo-Beta/Dwinzo_Demo/pulls/1
This commit was merged in pull request #1.
This commit is contained in:
2025-08-14 04:58:00 +00:00
20 changed files with 803 additions and 153 deletions

View File

@@ -3,6 +3,7 @@ import {
useLoadingProgress,
useRenameModeStore,
useSaveVersion,
useSelectedAssets,
useSelectedComment,
useSelectedFloorItem,
useSocketStore,
@@ -58,6 +59,7 @@ function MainScene() {
const { setFloatingWidget } = useFloatingWidget();
const { clearComparisonProduct } = useComparisonProduct();
const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
const { selectedAssets,setSelectedAssets } = useSelectedAssets();
const { assetStore, productStore } = useSceneContext();
const { products } = productStore();
const { setName } = assetStore();
@@ -97,18 +99,40 @@ function MainScene() {
const handleObjectRename = async (newName: string) => {
if (!projectId) return
let response = await setAssetsApi({
modelUuid: selectedFloorItem.userData.modelUuid,
modelName: newName,
projectId
});
selectedFloorItem.userData = {
...selectedFloorItem.userData,
modelName: newName
};
setSelectedFloorItem(selectedFloorItem);
setIsRenameMode(false);
setName(selectedFloorItem.userData.modelUuid, response.modelName);
if (selectedFloorItem) {
console.log('selectedFloorItem.userData.modelUuid: ', selectedFloorItem.userData.modelUuid);
console.log(' newName: ', newName);
console.log('projectId: ', projectId);
setAssetsApi({
modelUuid: selectedFloorItem.userData.modelUuid,
modelName: newName,
projectId,
versionId: selectedVersion?.versionId || ''
}).then(() => {
selectedFloorItem.userData = {
...selectedFloorItem.userData,
modelName: newName
};
setSelectedFloorItem(selectedFloorItem);
setIsRenameMode(false);
setName(selectedFloorItem.userData.modelUuid, newName);
})
} else if (selectedAssets.length === 1) {
setAssetsApi({
modelUuid: selectedAssets[0].userData.modelUuid,
modelName: newName,
projectId,
versionId: selectedVersion?.versionId || ''
}).then(() => {
selectedAssets[0].userData = {
...selectedAssets[0].userData,
modelName: newName
};
setSelectedAssets(selectedAssets);
setIsRenameMode(false);
setName(selectedAssets[0].userData.modelUuid, newName);
})
}
}
return (
@@ -135,7 +159,7 @@ function MainScene() {
{(isPlaying) &&
activeModule !== "simulation" && <ControlsPlayer />}
{isRenameMode && selectedFloorItem?.userData.modelName && <RenameTooltip name={selectedFloorItem?.userData.modelName} onSubmit={handleObjectRename} />}
{isRenameMode && (selectedFloorItem?.userData.modelName || selectedAssets.length === 1) && <RenameTooltip name={selectedFloorItem?.userData.modelName || selectedAssets[0].userData.modelName} onSubmit={handleObjectRename} />}
{/* remove this later */}
{activeModule === "builder" && !toggleThreeD && <SelectFloorPlan />}
</>
@@ -188,7 +212,7 @@ function MainScene() {
{activeModule !== "market" && !selectedUser && <Footer />}
<VersionSaved />
{(commentPositionState !== null || selectedComment !== null) && <ThreadChat/>}
{(commentPositionState !== null || selectedComment !== null) && <ThreadChat />}
</>
);

View File

@@ -1,23 +1,62 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import Search from "../../ui/inputs/Search";
import DropDownList from "../../ui/list/DropDownList";
import { useSceneContext } from "../../../modules/scene/sceneContext";
import { isPointInsidePolygon } from "../../../functions/isPointInsidePolygon";
interface ZoneData {
id: string;
name: string;
assets: { id: string; name: string; position?: []; rotation?: {} }[];
}
const Outline: React.FC = () => {
const [searchValue, setSearchValue] = useState<string>("");
const [zoneDataList, setZoneDataList] = useState<ZoneData[]>([]);
const [buildingsList, setBuildingsList] = useState<{ id: string; name: string }[]>([]);
const [isLayersOpen, setIsLayersOpen] = useState(true);
const [isBuildingsOpen, setIsBuildingsOpen] = useState(false);
const [isZonesOpen, setIsZonesOpen] = useState(false);
const { assetStore, zoneStore } = useSceneContext();
const { assets } = assetStore();
const { zones } = zoneStore();
useEffect(() => {
const updatedZoneList: ZoneData[] = zones?.map((zone: any) => {
const polygon2D = zone.points.map((p: any) => [p.position[0], p.position[2]]);
const assetsInZone = assets.filter((item: any) => {
const [x, , z] = item.position;
return isPointInsidePolygon([x, z], polygon2D as [number, number][]);
})
.map((item: any) => ({
id: item.modelUuid,
name: item.modelName,
position: item.position,
rotation: item.rotation,
}));
return {
id: zone.zoneUuid,
name: zone.zoneName,
assets: assetsInZone,
};
});
setZoneDataList(updatedZoneList);
}, [zones, assets]);
const handleSearchChange = (value: string) => {
setSearchValue(value);
// console.log(value); // Log the search value if needed
};
const dropdownItems = [
{ id: "1", name: "Ground Floor", active: true },
// { id: "2", name: "Floor 1" },
]; // Example dropdown items
const dropdownItems = [{ id: "1", name: "Ground Floor" }];
return (
<div className="outline-container">
<Search onChange={handleSearchChange} />
{searchValue ? (
<div className="searched-content">
<p>Results for "{searchValue}"</p>
@@ -28,7 +67,8 @@ const Outline: React.FC = () => {
<DropDownList
value="Layers"
items={dropdownItems}
defaultOpen={true}
isOpen={isLayersOpen}
onToggle={() => setIsLayersOpen((prev) => !prev)}
showKebabMenu={false}
showFocusIcon={true}
remove
@@ -36,10 +76,18 @@ const Outline: React.FC = () => {
</section>
<section className="outline-section overflow">
<DropDownList
value="Scene"
items={dropdownItems}
defaultOpen={true}
listType="outline"
value="Buildings"
items={buildingsList}
isOpen={isBuildingsOpen}
onToggle={() => setIsBuildingsOpen((prev) => !prev)}
showKebabMenu={false}
showAddIcon={false}
/>
<DropDownList
value="Zones"
items={zoneDataList}
isOpen={isZonesOpen}
onToggle={() => setIsZonesOpen((prev) => !prev)}
showKebabMenu={false}
showAddIcon={false}
/>

View File

@@ -42,11 +42,11 @@ const ZoneProperties: React.FC = () => {
let response = await zoneCameraUpdate(zonesdata, organization, projectId, selectedVersion?.versionId || "");
// console.log('response: ', response);
//
if (response.message === "zone updated") {
setEdit(false);
} else {
// console.log(response);
//
}
} catch (error) {
echo.error("Failed to set zone view");
@@ -75,7 +75,7 @@ const ZoneProperties: React.FC = () => {
// )
// );
} else {
// console.log(response?.message);
//
}
}
function handleVectorChange(
@@ -85,7 +85,7 @@ const ZoneProperties: React.FC = () => {
setSelectedZone((prev) => ({ ...prev, [key]: newValue }));
}
const checkZoneNameDuplicate = (name: string) => {
console.log('zones: ', zones);
return zones.some(
(zone: any) =>
zone.zoneName?.trim().toLowerCase() === name?.trim().toLowerCase() &&