diff --git a/app/src/components/footer/Footer.tsx b/app/src/components/footer/Footer.tsx index c890087..fdac078 100644 --- a/app/src/components/footer/Footer.tsx +++ b/app/src/components/footer/Footer.tsx @@ -53,6 +53,7 @@ const Footer: React.FC = () => {
-
diff --git a/app/src/components/layout/controls/ControlsPlayer.tsx b/app/src/components/layout/controls/ControlsPlayer.tsx new file mode 100644 index 0000000..248c466 --- /dev/null +++ b/app/src/components/layout/controls/ControlsPlayer.tsx @@ -0,0 +1,56 @@ +import React, { useState } from "react"; +import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; +import useModuleStore from "../../../store/useModuleStore"; +import { PlayIcon } from "../../icons/ShortcutIcons"; +import InputToggle from "../../ui/inputs/InputToggle"; +import { EyeCloseIcon, WalkIcon } from "../../icons/ExportCommonIcons"; +import { ExitIcon } from "../../icons/SimulationIcons"; + +const ControlsPlayer = () => { + const { setIsPlaying } = usePlayButtonStore(); + const { activeModule } = useModuleStore(); + const [walkMode, setWalkMode] = useState(false); + + const changeCamMode = () => { + setWalkMode(!walkMode); + console.log("switch camera mode to first person"); + }; + return ( +
+
+ +
Running {activeModule}...
+
+ +
+
+ + +
+ +
+
+ +
+ Hide +
+
+
+ ); +}; + +export default ControlsPlayer; diff --git a/app/src/components/layout/sidebarLeft/Header.tsx b/app/src/components/layout/sidebarLeft/Header.tsx index f26f4fa..45df499 100644 --- a/app/src/components/layout/sidebarLeft/Header.tsx +++ b/app/src/components/layout/sidebarLeft/Header.tsx @@ -20,6 +20,7 @@ const Header: React.FC = () => { - -
-
- {multipleAction && selectedPointData && - selectedPointData.actions.map((action: any) => ( -
- - {selectedPointData.actions.length > 1 && ( - - )} -
- ))} - {!multipleAction && selectedPointData && ( -
- -
- )} -
- {multipleAction && ( - - )} -
- - + const handleRenameAction = (newName: string) => { + if (!selectedAction.actionId) return; + const event = renameAction( + selectedProduct.productId, + selectedAction.actionId, + newName ); + setSelectedAction(selectedAction.actionId, newName); + if (event) { + upsertProductOrEventApi({ + productName: selectedProduct.productName, + productId: selectedProduct.productId, + organization: organization, + eventDatas: event, + }); + } + }; + + const handleActionSelect = (actionUuid: string, actionName: string) => { + setSelectedAction(actionUuid, actionName); + }; + + return ( +
+
+
+
Actions
+ + +
+
+
+ {multipleAction && + selectedPointData && + selectedPointData.actions.map((action: any) => ( +
+ + {selectedPointData.actions.length > 1 && ( + + )} +
+ ))} + {!multipleAction && selectedPointData && ( +
+ +
+ )} +
+ {multipleAction && ( + + )} +
+
+
+ ); }; export default ActionsList; diff --git a/app/src/components/layout/sidebarRight/properties/eventProperties/trigger/Trigger.tsx b/app/src/components/layout/sidebarRight/properties/eventProperties/trigger/Trigger.tsx index da36384..b81dbf6 100644 --- a/app/src/components/layout/sidebarRight/properties/eventProperties/trigger/Trigger.tsx +++ b/app/src/components/layout/sidebarRight/properties/eventProperties/trigger/Trigger.tsx @@ -1,395 +1,512 @@ import React, { useEffect, useMemo, useRef, useState } from "react"; import * as THREE from "three"; import { - AddIcon, - RemoveIcon, - ResizeHeightIcon, + AddIcon, + RemoveIcon, + ResizeHeightIcon, } from "../../../../../icons/ExportCommonIcons"; import LabledDropdown from "../../../../../ui/inputs/LabledDropdown"; import RenameInput from "../../../../../ui/inputs/RenameInput"; import { handleResize } from "../../../../../../functions/handleResizePannel"; import { useProductStore } from "../../../../../../store/simulation/useProductStore"; -import { useSelectedAction, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore"; +import { + useSelectedAction, + useSelectedProduct, +} from "../../../../../../store/simulation/useSimulationStore"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/UpsertProductOrEventApi"; type TriggerProps = { - selectedPointData?: PointsScheme | undefined; - type?: 'Conveyor' | 'Vehicle' | 'RoboticArm' | 'Machine' | 'StorageUnit'; + selectedPointData?: PointsScheme | undefined; + type?: "Conveyor" | "Vehicle" | "RoboticArm" | "Machine" | "StorageUnit"; }; const Trigger = ({ selectedPointData, type }: TriggerProps) => { - const [currentAction, setCurrentAction] = useState(); - const { selectedProduct } = useSelectedProduct(); - const { getActionByUuid, getEventByModelUuid, getPointByUuid, getTriggerByUuid, addTrigger, removeTrigger, updateTrigger, renameTrigger, getProductById } = useProductStore(); - const [triggers, setTriggers] = useState([]); - const [selectedTrigger, setSelectedTrigger] = useState(); - const [activeOption, setActiveOption] = useState<"onComplete" | "onStart" | "onStop" | "delay" | "onError">("onComplete"); - const triggersContainerRef = useRef(null); - const { selectedAction } = useSelectedAction(); + const [currentAction, setCurrentAction] = useState(); + const { selectedProduct } = useSelectedProduct(); + const { + getActionByUuid, + getEventByModelUuid, + getPointByUuid, + getTriggerByUuid, + addTrigger, + removeTrigger, + updateTrigger, + renameTrigger, + getProductById, + } = useProductStore(); + const [triggers, setTriggers] = useState([]); + const [selectedTrigger, setSelectedTrigger] = useState< + TriggerSchema | undefined + >(); + const [activeOption, setActiveOption] = useState< + "onComplete" | "onStart" | "onStop" | "delay" | "onError" + >("onComplete"); + const triggersContainerRef = useRef(null); + const { selectedAction } = useSelectedAction(); - const email = localStorage.getItem('email') - const organization = (email!.split("@")[1]).split(".")[0]; + const email = localStorage.getItem("email"); + const organization = email!.split("@")[1].split(".")[0]; - useEffect(() => { - if (!selectedPointData || !selectedProduct) return; + useEffect(() => { + if (!selectedPointData || !selectedProduct) return; - let actionUuid: string | undefined; + let actionUuid: string | undefined; - if (type === 'Conveyor' || type === 'Vehicle' || type === 'Machine' || type === 'StorageUnit') { - actionUuid = (selectedPointData as ConveyorPointSchema | VehiclePointSchema | MachinePointSchema | StoragePointSchema).action?.actionUuid; - } else if (type === 'RoboticArm' && selectedAction && selectedAction.actionId) { - actionUuid = selectedAction.actionId; - } - - setCurrentAction(actionUuid); - }, [selectedPointData, selectedProduct, type, selectedAction]); - - const updateBackend = ( - productName: string, - productId: string, - organization: string, - eventData: EventsSchema - ) => { - upsertProductOrEventApi({ - productName: productName, - productId: productId, - organization: organization, - eventDatas: eventData - }) + if ( + type === "Conveyor" || + type === "Vehicle" || + type === "Machine" || + type === "StorageUnit" + ) { + actionUuid = ( + selectedPointData as + | ConveyorPointSchema + | VehiclePointSchema + | MachinePointSchema + | StoragePointSchema + ).action?.actionUuid; + } else if ( + type === "RoboticArm" && + selectedAction && + selectedAction.actionId + ) { + actionUuid = selectedAction.actionId; } - useEffect(() => { - if (!currentAction || !selectedProduct) return; - const action = getActionByUuid(selectedProduct.productId, currentAction); - const actionTriggers = action?.triggers || []; - setTriggers(actionTriggers); - setSelectedTrigger(actionTriggers[0]); - }, [currentAction, selectedProduct]); + setCurrentAction(actionUuid); + }, [selectedPointData, selectedProduct, type, selectedAction]); - const triggeredModel = useMemo(() => { - if (!selectedProduct || !selectedTrigger?.triggeredAsset?.triggeredModel?.modelUuid) return undefined; - return getEventByModelUuid(selectedProduct.productId, selectedTrigger.triggeredAsset.triggeredModel.modelUuid); - }, [selectedProduct, selectedTrigger]); + const updateBackend = ( + productName: string, + productId: string, + organization: string, + eventData: EventsSchema + ) => { + upsertProductOrEventApi({ + productName: productName, + productId: productId, + organization: organization, + eventDatas: eventData, + }); + }; - const triggeredPoint = useMemo(() => { - if (!selectedProduct || !triggeredModel || !selectedTrigger?.triggeredAsset?.triggeredPoint?.pointUuid) return undefined; - return getPointByUuid( - selectedProduct.productId, - triggeredModel.modelUuid, - selectedTrigger.triggeredAsset.triggeredPoint.pointUuid - ); - }, [selectedProduct, triggeredModel, selectedTrigger]); + useEffect(() => { + if (!currentAction || !selectedProduct) return; + const action = getActionByUuid(selectedProduct.productId, currentAction); + const actionTriggers = action?.triggers || []; + setTriggers(actionTriggers); + setSelectedTrigger(actionTriggers[0]); + }, [currentAction, selectedProduct]); - const triggeredAction = useMemo(() => { - if (!selectedProduct || !selectedTrigger?.triggeredAsset?.triggeredAction?.actionUuid) return undefined; - return getActionByUuid( - selectedProduct.productId, - selectedTrigger.triggeredAsset.triggeredAction.actionUuid - ); - }, [selectedProduct, selectedTrigger]); - - const modelOptions = getProductById(selectedProduct.productId)?.eventDatas || []; - - const pointOptions: PointsScheme[] = useMemo(() => { - if (!triggeredModel) return []; - - const model = modelOptions.find(m => m.modelUuid === triggeredModel.modelUuid); - if (!model) return []; - - if ('points' in model) { - return (model as ConveyorEventSchema).points; - } else if ('point' in model) { - return [(model as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point]; - } - return []; - }, [triggeredModel, modelOptions]); - - const actionOptions: any = useMemo(() => { - if (!triggeredPoint) return []; - const point = pointOptions.find((p) => p.uuid === triggeredPoint.uuid); - if (!point) return []; - - if ('action' in point) { - const typedPoint = point as ConveyorPointSchema | VehiclePointSchema | MachinePointSchema | StoragePointSchema; - return typedPoint.action ? [typedPoint.action] : []; - } else if ('actions' in point) { - const typedPoint = point as RoboticArmPointSchema; - return typedPoint.actions; - } - return []; - }, [triggeredPoint, pointOptions]); - - const handleModelSelect = (option: string, triggerUuid: string) => { - if (!selectedProduct) return; - - const selectedModel = modelOptions.find(m => m.modelName === option); - if (!selectedModel) return; - - const event = updateTrigger(selectedProduct.productId, triggerUuid, { - triggeredAsset: { - triggeredModel: { - modelName: selectedModel.modelName, - modelUuid: selectedModel.modelUuid - }, - triggeredPoint: null, - triggeredAction: null - } - }); - - if (event) { - const updatedTrigger = getTriggerByUuid(selectedProduct.productId, triggerUuid); - setSelectedTrigger(updatedTrigger); - - updateBackend( - selectedProduct.productName, - selectedProduct.productId, - organization, - event - ); - } - }; - - const handlePointSelect = (option: string, triggerUuid: string) => { - if (!selectedProduct || !selectedTrigger) return; - - const pointUuid = pointOptions.find(p => `Point ${p.uuid.slice(0, 4)}` === option)?.uuid; - if (!pointUuid) return; - - if (selectedTrigger.triggeredAsset?.triggeredModel) { - const event = updateTrigger(selectedProduct.productId, triggerUuid, { - triggeredAsset: { - ...selectedTrigger.triggeredAsset, - triggeredPoint: { - pointName: option, - pointUuid: pointUuid - }, - triggeredAction: null - } - }); - - if (event) { - const updatedTrigger = getTriggerByUuid(selectedProduct.productId, triggerUuid); - setSelectedTrigger(updatedTrigger); - - updateBackend( - selectedProduct.productName, - selectedProduct.productId, - organization, - event - ); - } - } - }; - - - const handleActionSelect = (option: string, triggerUuid: string) => { - if (!selectedProduct || !selectedTrigger) return; - - const selectedAction = actionOptions.find((a: any) => a.actionName === option); - - if (!selectedAction) return; - - if (selectedTrigger.triggeredAsset?.triggeredPoint) { - const event = updateTrigger(selectedProduct.productId, triggerUuid, { - triggeredAsset: { - ...selectedTrigger.triggeredAsset, - triggeredAction: { - actionName: option, - actionUuid: selectedAction.actionUuid - } - } - }); - - if (event) { - updateBackend( - selectedProduct.productName, - selectedProduct.productId, - organization, - event - ); - } - } - }; - - const handleAddTrigger = () => { - if (!selectedProduct || !currentAction) return; - - const newTrigger: TriggerSchema = { - triggerUuid: THREE.MathUtils.generateUUID(), - triggerName: `New Trigger ${triggers.length + 1}`, - triggerType: activeOption, - delay: 0, - triggeredAsset: null - }; - - const event = addTrigger(selectedProduct.productId, currentAction, newTrigger); - - if (event) { - updateBackend( - selectedProduct.productName, - selectedProduct.productId, - organization, - event - ); - } - - const updatedAction = getActionByUuid(selectedProduct.productId, currentAction); - const updatedTriggers = updatedAction?.triggers || []; - - setTriggers(updatedTriggers); - setSelectedTrigger(newTrigger); - }; - - const handleRemoveTrigger = (triggerUuid: string) => { - if (!selectedProduct || !currentAction) return; - - const event = removeTrigger(selectedProduct.productId, triggerUuid); - - if (event) { - updateBackend( - selectedProduct.productName, - selectedProduct.productId, - organization, - event - ); - } - - const index = triggers.findIndex(t => t.triggerUuid === triggerUuid); - const newTriggers = triggers.filter(t => t.triggerUuid !== triggerUuid); - setTriggers(newTriggers); - - if (selectedTrigger?.triggerUuid === triggerUuid) { - const nextTrigger = newTriggers[index] || newTriggers[index - 1]; - setSelectedTrigger(nextTrigger); - } - }; - - const handleTriggerRename = (triggerUuid: string, newName: string) => { - if (!selectedProduct) return; - const event = renameTrigger(selectedProduct.productId, triggerUuid, newName); - - if (event) { - updateBackend( - selectedProduct.productName, - selectedProduct.productId, - organization, - event - ); - } - }; - - const handleTriggerTypeChange = (option: string) => { - if (!selectedTrigger || !selectedProduct) return; - - const validTypes: Array = ["onComplete", "onStart", "onStop", "delay", "onError"]; - if (!validTypes.includes(option as TriggerSchema['triggerType'])) return; - - setActiveOption(option as TriggerSchema['triggerType']); - const event = updateTrigger(selectedProduct.productId, selectedTrigger.triggerUuid, { - triggerType: option as TriggerSchema['triggerType'] - }); - - if (event) { - updateBackend( - selectedProduct.productName, - selectedProduct.productId, - organization, - event - ); - } - }; - - return ( -
-
-
Trigger
- -
-
-
-
- {triggers.map((trigger) => ( -
setSelectedTrigger(trigger)} - > - - {triggers.length > 1 && ( - - )} -
- ))} -
- -
- - {selectedTrigger && ( -
-
{selectedTrigger.triggerName}
- - -
- (option.modelName))]} - onSelect={(option) => { handleModelSelect(option, selectedTrigger.triggerUuid) }} - /> - (`Point ${option.uuid.slice(0, 4)}`))]} - onSelect={(option) => { handlePointSelect(option, selectedTrigger.triggerUuid) }} - /> - (option.actionName))]} - onSelect={(option) => { handleActionSelect(option, selectedTrigger.triggerUuid) }} - /> -
-
- )} -
-
+ const triggeredModel = useMemo(() => { + if ( + !selectedProduct || + !selectedTrigger?.triggeredAsset?.triggeredModel?.modelUuid + ) + return undefined; + return getEventByModelUuid( + selectedProduct.productId, + selectedTrigger.triggeredAsset.triggeredModel.modelUuid ); + }, [selectedProduct, selectedTrigger]); + + const triggeredPoint = useMemo(() => { + if ( + !selectedProduct || + !triggeredModel || + !selectedTrigger?.triggeredAsset?.triggeredPoint?.pointUuid + ) + return undefined; + return getPointByUuid( + selectedProduct.productId, + triggeredModel.modelUuid, + selectedTrigger.triggeredAsset.triggeredPoint.pointUuid + ); + }, [selectedProduct, triggeredModel, selectedTrigger]); + + const triggeredAction = useMemo(() => { + if ( + !selectedProduct || + !selectedTrigger?.triggeredAsset?.triggeredAction?.actionUuid + ) + return undefined; + return getActionByUuid( + selectedProduct.productId, + selectedTrigger.triggeredAsset.triggeredAction.actionUuid + ); + }, [selectedProduct, selectedTrigger]); + + const modelOptions = + getProductById(selectedProduct.productId)?.eventDatas || []; + + const pointOptions: PointsScheme[] = useMemo(() => { + if (!triggeredModel) return []; + + const model = modelOptions.find( + (m) => m.modelUuid === triggeredModel.modelUuid + ); + if (!model) return []; + + if ("points" in model) { + return (model as ConveyorEventSchema).points; + } else if ("point" in model) { + return [ + ( + model as + | VehicleEventSchema + | RoboticArmEventSchema + | MachineEventSchema + | StorageEventSchema + ).point, + ]; + } + return []; + }, [triggeredModel, modelOptions]); + + const actionOptions: any = useMemo(() => { + if (!triggeredPoint) return []; + const point = pointOptions.find((p) => p.uuid === triggeredPoint.uuid); + if (!point) return []; + + if ("action" in point) { + const typedPoint = point as + | ConveyorPointSchema + | VehiclePointSchema + | MachinePointSchema + | StoragePointSchema; + return typedPoint.action ? [typedPoint.action] : []; + } else if ("actions" in point) { + const typedPoint = point as RoboticArmPointSchema; + return typedPoint.actions; + } + return []; + }, [triggeredPoint, pointOptions]); + + const handleModelSelect = (option: string, triggerUuid: string) => { + if (!selectedProduct) return; + + const selectedModel = modelOptions.find((m) => m.modelName === option); + if (!selectedModel) return; + + const event = updateTrigger(selectedProduct.productId, triggerUuid, { + triggeredAsset: { + triggeredModel: { + modelName: selectedModel.modelName, + modelUuid: selectedModel.modelUuid, + }, + triggeredPoint: null, + triggeredAction: null, + }, + }); + + if (event) { + const updatedTrigger = getTriggerByUuid( + selectedProduct.productId, + triggerUuid + ); + setSelectedTrigger(updatedTrigger); + + updateBackend( + selectedProduct.productName, + selectedProduct.productId, + organization, + event + ); + } + }; + + const handlePointSelect = (option: string, triggerUuid: string) => { + if (!selectedProduct || !selectedTrigger) return; + + const pointUuid = pointOptions.find( + (p) => `Point ${p.uuid.slice(0, 4)}` === option + )?.uuid; + if (!pointUuid) return; + + if (selectedTrigger.triggeredAsset?.triggeredModel) { + const event = updateTrigger(selectedProduct.productId, triggerUuid, { + triggeredAsset: { + ...selectedTrigger.triggeredAsset, + triggeredPoint: { + pointName: option, + pointUuid: pointUuid, + }, + triggeredAction: null, + }, + }); + + if (event) { + const updatedTrigger = getTriggerByUuid( + selectedProduct.productId, + triggerUuid + ); + setSelectedTrigger(updatedTrigger); + + updateBackend( + selectedProduct.productName, + selectedProduct.productId, + organization, + event + ); + } + } + }; + + const handleActionSelect = (option: string, triggerUuid: string) => { + if (!selectedProduct || !selectedTrigger) return; + + const selectedAction = actionOptions.find( + (a: any) => a.actionName === option + ); + + if (!selectedAction) return; + + if (selectedTrigger.triggeredAsset?.triggeredPoint) { + const event = updateTrigger(selectedProduct.productId, triggerUuid, { + triggeredAsset: { + ...selectedTrigger.triggeredAsset, + triggeredAction: { + actionName: option, + actionUuid: selectedAction.actionUuid, + }, + }, + }); + + if (event) { + updateBackend( + selectedProduct.productName, + selectedProduct.productId, + organization, + event + ); + } + } + }; + + const handleAddTrigger = () => { + if (!selectedProduct || !currentAction) return; + + const newTrigger: TriggerSchema = { + triggerUuid: THREE.MathUtils.generateUUID(), + triggerName: `New Trigger ${triggers.length + 1}`, + triggerType: activeOption, + delay: 0, + triggeredAsset: null, + }; + + const event = addTrigger( + selectedProduct.productId, + currentAction, + newTrigger + ); + + if (event) { + updateBackend( + selectedProduct.productName, + selectedProduct.productId, + organization, + event + ); + } + + const updatedAction = getActionByUuid( + selectedProduct.productId, + currentAction + ); + const updatedTriggers = updatedAction?.triggers || []; + + setTriggers(updatedTriggers); + setSelectedTrigger(newTrigger); + }; + + const handleRemoveTrigger = (triggerUuid: string) => { + if (!selectedProduct || !currentAction) return; + + const event = removeTrigger(selectedProduct.productId, triggerUuid); + + if (event) { + updateBackend( + selectedProduct.productName, + selectedProduct.productId, + organization, + event + ); + } + + const index = triggers.findIndex((t) => t.triggerUuid === triggerUuid); + const newTriggers = triggers.filter((t) => t.triggerUuid !== triggerUuid); + setTriggers(newTriggers); + + if (selectedTrigger?.triggerUuid === triggerUuid) { + const nextTrigger = newTriggers[index] || newTriggers[index - 1]; + setSelectedTrigger(nextTrigger); + } + }; + + const handleTriggerRename = (triggerUuid: string, newName: string) => { + if (!selectedProduct) return; + const event = renameTrigger( + selectedProduct.productId, + triggerUuid, + newName + ); + + if (event) { + updateBackend( + selectedProduct.productName, + selectedProduct.productId, + organization, + event + ); + } + }; + + const handleTriggerTypeChange = (option: string) => { + if (!selectedTrigger || !selectedProduct) return; + + const validTypes: Array = [ + "onComplete", + "onStart", + "onStop", + "delay", + "onError", + ]; + if (!validTypes.includes(option as TriggerSchema["triggerType"])) return; + + setActiveOption(option as TriggerSchema["triggerType"]); + const event = updateTrigger( + selectedProduct.productId, + selectedTrigger.triggerUuid, + { + triggerType: option as TriggerSchema["triggerType"], + } + ); + + if (event) { + updateBackend( + selectedProduct.productName, + selectedProduct.productId, + organization, + event + ); + } + }; + + return ( +
+
+
Trigger
+ +
+
+
+
+ {triggers.map((trigger) => ( +
setSelectedTrigger(trigger)} + > + + {triggers.length > 1 && ( + + )} +
+ ))} +
+ +
+ + {selectedTrigger && ( +
+
{selectedTrigger.triggerName}
+ + +
+ option.modelName)]} + onSelect={(option) => { + handleModelSelect(option, selectedTrigger.triggerUuid); + }} + /> + `Point ${option.uuid.slice(0, 4)}` + ), + ]} + onSelect={(option) => { + handlePointSelect(option, selectedTrigger.triggerUuid); + }} + /> + option.actionName), + ]} + onSelect={(option) => { + handleActionSelect(option, selectedTrigger.triggerUuid); + }} + /> +
+
+ )} +
+
+ ); }; export default Trigger; diff --git a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx index 6609e92..66e4948 100644 --- a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx +++ b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx @@ -22,6 +22,8 @@ import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertP import { deleteProductApi } from "../../../../services/simulation/deleteProductApi"; import { renameProductApi } from "../../../../services/simulation/renameProductApi"; import { determineExecutionMachineSequences } from "../../../../modules/simulation/simulator/functions/determineExecutionMachineSequences"; +import ComparePopUp from "../../../../modules/simulation/compare/compare"; +import { useCompareStore } from "../../../../store/builder/store"; interface Event { modelName: string; @@ -49,7 +51,7 @@ const Simulations: React.FC = () => { renameProduct, addEvent, removeEvent, - getProductById + getProductById, } = useProductStore(); const { selectedProduct, setSelectedProduct } = useSelectedProduct(); const { getEventByModelUuid } = useEventsStore(); @@ -58,7 +60,7 @@ const Simulations: React.FC = () => { const organization = email!.split("@")[1].split(".")[0]; const [openObjects, setOpenObjects] = useState(true); const [processes, setProcesses] = useState(); - + const { comparePopUp, setComparePopUp } = useCompareStore(); const handleAddProduct = () => { const id = generateUUID(); const name = `Product ${products.length + 1}`; @@ -122,21 +124,21 @@ const Simulations: React.FC = () => { const selectedProductData = getProductById(selectedProduct.productId); if (selectedProductData) { - determineExecutionMachineSequences([selectedProductData]) - .then((sequences) => { + determineExecutionMachineSequences([selectedProductData]).then( + (sequences) => { sequences.forEach((sequence) => { const events: Event[] = sequence.map((event) => ({ modelName: event.modelName, - modelId: event.modelUuid + modelId: event.modelUuid, })) || []; processes.push(events); - }) - setProcesses(processes) - }) - + }); + setProcesses(processes); + } + ); } - }, [selectedProduct.productId, products]) + }, [selectedProduct.productId, products]); return (
@@ -145,7 +147,11 @@ const Simulations: React.FC = () => {
Products
-
@@ -158,10 +164,11 @@ const Simulations: React.FC = () => { {products.map((product, index) => (
{/* eslint-disable-next-line */}
{
{products.length > 1 && (
{openObjects && - processes?.map((process, index) => + processes?.map((process, index) => (
{process.map((event, index) => ( ))}
- ) - } + ))}
@@ -233,7 +241,7 @@ const Simulations: React.FC = () => { Click 'Compare' to review and analyze the layout differences between them.
-
+
setComparePopUp(true)}>
@@ -258,6 +266,12 @@ const Simulations: React.FC = () => { /> )} + + {comparePopUp && ( + + + + )}
); }; diff --git a/app/src/components/layout/sidebarRight/versionHisory/VersionHistory.tsx b/app/src/components/layout/sidebarRight/versionHisory/VersionHistory.tsx index 73a630c..a782f78 100644 --- a/app/src/components/layout/sidebarRight/versionHisory/VersionHistory.tsx +++ b/app/src/components/layout/sidebarRight/versionHisory/VersionHistory.tsx @@ -57,13 +57,17 @@ const VersionHistory = () => {
Version History
- -
+
-
+
@@ -96,7 +100,7 @@ const VersionHistory = () => {
{versions.map((version, index) => ( ); @@ -125,7 +139,7 @@ const Tools: React.FC = () => { switch (tool) { case "cursor": if (toggleView) { - setToolMode('move'); + setToolMode("move"); } break; case "draw-wall": @@ -170,37 +184,33 @@ const Tools: React.FC = () => { ); }; - if (isPlaying && activeModule !== "simulation") { - return ( - - ); - } - const renderBuilderTools = () => ( <> {!toggleThreeD && (
setActiveTool("draw-wall")} /> setActiveTool("draw-zone")} /> setActiveTool("draw-aisle")} /> { )}
{ const renderSimulationTools = () => (
{ const renderVisualizationTools = () => (
{ const renderModeSwitcher = () => (
diff --git a/app/src/components/ui/inputs/InputToggle.tsx b/app/src/components/ui/inputs/InputToggle.tsx index 5e69291..d2968bf 100644 --- a/app/src/components/ui/inputs/InputToggle.tsx +++ b/app/src/components/ui/inputs/InputToggle.tsx @@ -24,7 +24,10 @@ const InputToggle: React.FC = ({ -
= ({ checked={value} readOnly /> -
+
); }; diff --git a/app/src/components/ui/inputs/LabledButton.tsx b/app/src/components/ui/inputs/LabledButton.tsx index 26f4d75..b9e2e04 100644 --- a/app/src/components/ui/inputs/LabledButton.tsx +++ b/app/src/components/ui/inputs/LabledButton.tsx @@ -16,7 +16,12 @@ const LabeledButton: React.FC = ({ return (
{label}
-
diff --git a/app/src/components/ui/inputs/MultiLevelDropDown.tsx b/app/src/components/ui/inputs/MultiLevelDropDown.tsx index fa30a55..3be1e17 100644 --- a/app/src/components/ui/inputs/MultiLevelDropDown.tsx +++ b/app/src/components/ui/inputs/MultiLevelDropDown.tsx @@ -16,7 +16,10 @@ const DropdownItem = ({ onClick={() => { if (!disabled) onClick(); }} - style={{ cursor: disabled ? "not-allowed": "default", opacity: disabled ? 0.5 : 1 }} + style={{ + cursor: disabled ? "not-allowed" : "default", + opacity: disabled ? 0.5 : 1, + }} > {label}
@@ -127,13 +130,17 @@ const MultiLevelDropdown = ({ const disabledFieldsList = Object.values(allSelections) .filter( (sel) => - !(sel.name === selectedValue?.name && sel.fields === selectedValue?.fields) + !( + sel.name === selectedValue?.name && + sel.fields === selectedValue?.fields + ) ) .map((sel) => `${sel.name}-${sel.fields}`); return (
)} diff --git a/app/src/components/ui/list/DropDownList.tsx b/app/src/components/ui/list/DropDownList.tsx index 5de5654..3ec828e 100644 --- a/app/src/components/ui/list/DropDownList.tsx +++ b/app/src/components/ui/list/DropDownList.tsx @@ -123,6 +123,7 @@ const DropDownList: React.FC = ({
)}
- - {remove && ( - )} diff --git a/app/src/components/ui/log/LogList.tsx b/app/src/components/ui/log/LogList.tsx index 2ec50f8..caaf957 100644 --- a/app/src/components/ui/log/LogList.tsx +++ b/app/src/components/ui/log/LogList.tsx @@ -38,6 +38,7 @@ const LogList: React.FC = () => {
Log List
))}
-
@@ -80,7 +87,9 @@ const LogList: React.FC = () => {
)) ) : ( -
There are no logs to display at the moment.
+
+ There are no logs to display at the moment. +
)}
diff --git a/app/src/components/ui/menu/EditWidgetOption.tsx b/app/src/components/ui/menu/EditWidgetOption.tsx index 558957b..cbc1e68 100644 --- a/app/src/components/ui/menu/EditWidgetOption.tsx +++ b/app/src/components/ui/menu/EditWidgetOption.tsx @@ -11,7 +11,7 @@ interface EditWidgetOptionProps { const EditWidgetOption: React.FC = ({ options, - onClick + onClick, }) => { const { top } = useTopData(); const { left } = useLeftData(); @@ -29,6 +29,7 @@ const EditWidgetOption: React.FC = ({
{options.map((option, index) => ( {/* Log out */} -
diff --git a/app/src/components/ui/simulation/AssetDetailsCard.tsx b/app/src/components/ui/simulation/AssetDetailsCard.tsx index 5a4b4da..15c5574 100644 --- a/app/src/components/ui/simulation/AssetDetailsCard.tsx +++ b/app/src/components/ui/simulation/AssetDetailsCard.tsx @@ -82,6 +82,7 @@ const AssetDetailsCard: React.FC = ({ )} {subModule === "analysis" && ( diff --git a/app/src/modules/market/Card.tsx b/app/src/modules/market/Card.tsx index b1b5faa..d70d2b4 100644 --- a/app/src/modules/market/Card.tsx +++ b/app/src/modules/market/Card.tsx @@ -7,7 +7,6 @@ import { VerifiedIcon, } from "../../components/icons/marketPlaceIcons"; - interface CardProps { assetName: string; uploadedOn: number; @@ -16,8 +15,8 @@ interface CardProps { views: number; image: string; description: string; - AssetID: string - modelUrl: string + AssetID: string; + modelUrl: string; onSelectCard: (cardData: { assetName: string; uploadedOn: number; @@ -40,14 +39,19 @@ const Card: React.FC = ({ AssetID, modelUrl, onSelectCard, - }) => { const handleCardSelect = () => { - console.log('assetName: ', assetName); - console.log('AssetID: ', AssetID); + console.log("assetName: ", assetName); + console.log("AssetID: ", AssetID); onSelectCard({ - assetName, uploadedOn, price, rating, views, description, AssetID + assetName, + uploadedOn, + price, + rating, + views, + description, + AssetID, }); }; @@ -89,12 +93,8 @@ const Card: React.FC = ({
{[...Array(5)].map((_, index) => ( - - {index < 3 ? ( - - ) : ( - - )} + + {index < 3 ? : } ))}
@@ -102,7 +102,11 @@ const Card: React.FC = ({ ₹ {price}/unit
- diff --git a/app/src/modules/market/FilterSearch.tsx b/app/src/modules/market/FilterSearch.tsx index e860b44..c7038eb 100644 --- a/app/src/modules/market/FilterSearch.tsx +++ b/app/src/modules/market/FilterSearch.tsx @@ -39,10 +39,14 @@ const FilterSearch: React.FC = ({ useEffect(() => { if (activeOption === "Alphabet ascending") { - const ascending = [...models].sort((a, b) => a.filename.localeCompare(b.filename)); + const ascending = [...models].sort((a, b) => + a.filename.localeCompare(b.filename) + ); setModels(ascending); } else if (activeOption === "Alphabet descending") { - const descending = [...models].sort((a, b) => b.filename.localeCompare(a.filename)); + const descending = [...models].sort((a, b) => + b.filename.localeCompare(a.filename) + ); setModels(descending); } }, [activeOption, models, setModels]); @@ -75,6 +79,7 @@ const FilterSearch: React.FC = ({
{[0, 1, 2, 3, 4].map((i) => ( +
+ + +
+ Save this version and proceed. +
+ + + ); +}; + +export default ComparePopUp; diff --git a/app/src/modules/visualization/template/Templates.tsx b/app/src/modules/visualization/template/Templates.tsx index d7f6b3f..b256a31 100644 --- a/app/src/modules/visualization/template/Templates.tsx +++ b/app/src/modules/visualization/template/Templates.tsx @@ -114,6 +114,7 @@ const Templates = () => { )} @@ -252,7 +259,11 @@ const DisplayZone: React.FC = ({ {/* Right Arrow */} {showRightArrow && ( - )} diff --git a/app/src/pages/Project.tsx b/app/src/pages/Project.tsx index 6857a5c..86d73cf 100644 --- a/app/src/pages/Project.tsx +++ b/app/src/pages/Project.tsx @@ -32,6 +32,7 @@ import RenderOverlay from "../components/templates/Overlay"; import LogList from "../components/ui/log/LogList"; import Footer from "../components/footer/Footer"; import SelectFloorPlan from "../components/temporary/SelectFloorPlan"; +import ControlsPlayer from "../components/layout/controls/ControlsPlayer"; const Project: React.FC = () => { let navigate = useNavigate(); @@ -70,7 +71,7 @@ const Project: React.FC = () => { const { toggleThreeD } = useThreeDStore(); // simulation store - const { isPlaying } = usePlayButtonStore(); + const { isPlaying, setIsPlaying } = usePlayButtonStore(); // collaboration store const { selectedUser } = useSelectedUserStore(); @@ -97,8 +98,10 @@ const Project: React.FC = () => { )} {activeModule === "market" && } - {activeModule !== "market" && } + {activeModule !== "market" && !isPlaying && } {isPlaying && activeModule === "simulation" && } + {isPlaying && activeModule !== "simulation" && } + {/* remove this later */} {activeModule === "builder" && !toggleThreeD && } diff --git a/app/src/pages/UserAuth.tsx b/app/src/pages/UserAuth.tsx index 8b162c6..cd837db 100644 --- a/app/src/pages/UserAuth.tsx +++ b/app/src/pages/UserAuth.tsx @@ -102,7 +102,7 @@ const UserAuth: React.FC = () => { )}

- @@ -139,6 +139,7 @@ const UserAuth: React.FC = () => { required /> diff --git a/app/src/store/builder/store.ts b/app/src/store/builder/store.ts index 06c7bfc..e5f0c9e 100644 --- a/app/src/store/builder/store.ts +++ b/app/src/store/builder/store.ts @@ -1,454 +1,479 @@ import * as THREE from "three"; import { create } from "zustand"; import { io } from "socket.io-client"; -import * as CONSTANTS from '../../types/world/worldConstants'; +import * as CONSTANTS from "../../types/world/worldConstants"; export const useSocketStore = create((set: any, get: any) => ({ - socket: null, - initializeSocket: (email: string, organization: string) => { - const existingSocket = get().socket; - if (existingSocket) { - return; - } + socket: null, + initializeSocket: (email: string, organization: string) => { + const existingSocket = get().socket; + if (existingSocket) { + return; + } - const socket = io( - `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`, - { - reconnection: true, - auth: { email, organization }, - } - ); + const socket = io( + `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`, + { + reconnection: true, + auth: { email, organization }, + } + ); - const visualizationSocket = io( - `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`, - { - reconnection: true, - auth: { email, organization }, - } - ); + const visualizationSocket = io( + `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`, + { + reconnection: true, + auth: { email, organization }, + } + ); - set({ socket, visualizationSocket }); - }, - disconnectSocket: () => { - set((state: any) => { - state.socket?.disconnect(); - state.visualizationSocket?.disconnect(); - return { socket: null }; - }); - }, + set({ socket, visualizationSocket }); + }, + disconnectSocket: () => { + set((state: any) => { + state.socket?.disconnect(); + state.visualizationSocket?.disconnect(); + return { socket: null }; + }); + }, })); export const useLoadingProgress = create<{ - loadingProgress: number; - setLoadingProgress: (x: number) => void; + loadingProgress: number; + setLoadingProgress: (x: number) => void; }>((set) => ({ - loadingProgress: 1, - setLoadingProgress: (x: number) => set({ loadingProgress: x }), + loadingProgress: 1, + setLoadingProgress: (x: number) => set({ loadingProgress: x }), })); export const useOrganization = create((set: any) => ({ - organization: "", - setOrganization: (x: any) => set(() => ({ organization: x })), + organization: "", + setOrganization: (x: any) => set(() => ({ organization: x })), })); export const useToggleView = create((set: any) => ({ - toggleView: false, - setToggleView: (x: any) => set(() => ({ toggleView: x })), + toggleView: false, + setToggleView: (x: any) => set(() => ({ toggleView: x })), })); export const useUpdateScene = create((set: any) => ({ - updateScene: false, - setUpdateScene: (x: any) => set(() => ({ updateScene: x })), + updateScene: false, + setUpdateScene: (x: any) => set(() => ({ updateScene: x })), })); export const useWalls = create((set: any) => ({ - walls: [], - setWalls: (x: any) => set(() => ({ walls: x })), + walls: [], + setWalls: (x: any) => set(() => ({ walls: x })), })); export const useRoomsState = create((set: any) => ({ - roomsState: [], - setRoomsState: (x: any) => set(() => ({ roomsState: x })), + roomsState: [], + setRoomsState: (x: any) => set(() => ({ roomsState: x })), })); export const useZones = create((set: any) => ({ - zones: [], - setZones: (callback: any) => - set((state: any) => ({ - zones: typeof callback === "function" ? callback(state.zones) : callback, - })), + zones: [], + setZones: (callback: any) => + set((state: any) => ({ + zones: typeof callback === "function" ? callback(state.zones) : callback, + })), })); interface ZonePointsState { - zonePoints: THREE.Vector3[]; - setZonePoints: (points: THREE.Vector3[]) => void; + zonePoints: THREE.Vector3[]; + setZonePoints: (points: THREE.Vector3[]) => void; } export const useZonePoints = create((set) => ({ - zonePoints: [], - setZonePoints: (points) => set({ zonePoints: points }), + zonePoints: [], + setZonePoints: (points) => set({ zonePoints: points }), })); export const useSelectedItem = create((set: any) => ({ - selectedItem: { name: "", id: "", type: undefined, category: '', subCatergory: '' }, - setSelectedItem: (x: any) => set(() => ({ selectedItem: x })), + selectedItem: { + name: "", + id: "", + type: undefined, + category: "", + subCatergory: "", + }, + setSelectedItem: (x: any) => set(() => ({ selectedItem: x })), })); export const useNavMesh = create((set: any) => ({ - navMesh: null, - setNavMesh: (x: any) => set({ navMesh: x }), + navMesh: null, + setNavMesh: (x: any) => set({ navMesh: x }), })); export const useSelectedAssets = create((set: any) => ({ - selectedAssets: [], - setSelectedAssets: (x: any) => set(() => ({ selectedAssets: x })), + selectedAssets: [], + setSelectedAssets: (x: any) => set(() => ({ selectedAssets: x })), })); export const useLayers = create((set: any) => ({ - Layers: 1, - setLayers: (x: any) => set(() => ({ Layers: x })), + Layers: 1, + setLayers: (x: any) => set(() => ({ Layers: x })), })); export const useCamPosition = create((set: any) => ({ - camPosition: { x: undefined, y: undefined, z: undefined }, - setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }), + camPosition: { x: undefined, y: undefined, z: undefined }, + setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }), })); export const useMenuVisible = create((set: any) => ({ - menuVisible: false, - setMenuVisible: (x: any) => set(() => ({ menuVisible: x })), + menuVisible: false, + setMenuVisible: (x: any) => set(() => ({ menuVisible: x })), })); export const useDeleteTool = create((set: any) => ({ - deleteTool: false, - setDeleteTool: (x: any) => set(() => ({ deleteTool: x })), + deleteTool: false, + setDeleteTool: (x: any) => set(() => ({ deleteTool: x })), })); export const useToolMode = create((set: any) => ({ - toolMode: null, - setToolMode: (x: any) => set(() => ({ toolMode: x })), + toolMode: null, + setToolMode: (x: any) => set(() => ({ toolMode: x })), })); export const useNewLines = create((set: any) => ({ - newLines: [], - setNewLines: (x: any) => set(() => ({ newLines: x })), + newLines: [], + setNewLines: (x: any) => set(() => ({ newLines: x })), })); export const useDeletedLines = create((set: any) => ({ - deletedLines: [], - setDeletedLines: (x: any) => set(() => ({ deletedLines: x })), + deletedLines: [], + setDeletedLines: (x: any) => set(() => ({ deletedLines: x })), })); export const useMovePoint = create((set: any) => ({ - movePoint: false, - setMovePoint: (x: any) => set(() => ({ movePoint: x })), + movePoint: false, + setMovePoint: (x: any) => set(() => ({ movePoint: x })), })); export const useDeletePointOrLine = create((set: any) => ({ - deletePointOrLine: false, - setDeletePointOrLine: (x: any) => set(() => ({ deletePointOrLine: x })), + deletePointOrLine: false, + setDeletePointOrLine: (x: any) => set(() => ({ deletePointOrLine: x })), })); export const useFloorItems = create((set: any) => ({ - floorItems: null, - setFloorItems: (callback: any) => - set((state: any) => ({ - floorItems: - typeof callback === "function" ? callback(state.floorItems) : callback, - })), + floorItems: null, + setFloorItems: (callback: any) => + set((state: any) => ({ + floorItems: + typeof callback === "function" ? callback(state.floorItems) : callback, + })), })); export const useWallItems = create((set: any) => ({ - wallItems: [], - setWallItems: (callback: any) => - set((state: any) => ({ - wallItems: - typeof callback === "function" ? callback(state.wallItems) : callback, - })), + wallItems: [], + setWallItems: (callback: any) => + set((state: any) => ({ + wallItems: + typeof callback === "function" ? callback(state.wallItems) : callback, + })), })); export const useSelectedWallItem = create((set: any) => ({ - selectedWallItem: null, - setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })), + selectedWallItem: null, + setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })), })); export const useSelectedFloorItem = create((set: any) => ({ - selectedFloorItem: null, - setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })), + selectedFloorItem: null, + setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })), })); export const useDeletableFloorItem = create((set: any) => ({ - deletableFloorItem: null, - setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })), + deletableFloorItem: null, + setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })), })); export const useSetScale = create((set: any) => ({ - scale: null, - setScale: (x: any) => set(() => ({ scale: x })), + scale: null, + setScale: (x: any) => set(() => ({ scale: x })), })); export const useRoofVisibility = create((set: any) => ({ - roofVisibility: false, - setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })), + roofVisibility: false, + setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })), })); export const useWallVisibility = create((set: any) => ({ - wallVisibility: false, - setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })), + wallVisibility: false, + setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })), })); export const useShadows = create((set: any) => ({ - shadows: false, - setShadows: (x: any) => set(() => ({ shadows: x })), + shadows: false, + setShadows: (x: any) => set(() => ({ shadows: x })), })); export const useSunPosition = create((set: any) => ({ - sunPosition: { x: undefined, y: undefined, z: undefined }, - setSunPosition: (newSuntPosition: any) => - set({ sunPosition: newSuntPosition }), + sunPosition: { x: undefined, y: undefined, z: undefined }, + setSunPosition: (newSuntPosition: any) => + set({ sunPosition: newSuntPosition }), })); export const useRemoveLayer = create((set: any) => ({ - removeLayer: false, - setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })), + removeLayer: false, + setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })), })); export const useRemovedLayer = create((set: any) => ({ - removedLayer: null, - setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })), + removedLayer: null, + setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })), })); export const useActiveLayer = create((set: any) => ({ - activeLayer: 1, - setActiveLayer: (x: any) => set({ activeLayer: x }), + activeLayer: 1, + setActiveLayer: (x: any) => set({ activeLayer: x }), })); interface RefTextUpdateState { - refTextupdate: number; - setRefTextUpdate: ( - callback: (currentValue: number) => number | number - ) => void; + refTextupdate: number; + setRefTextUpdate: ( + callback: (currentValue: number) => number | number + ) => void; } export const useRefTextUpdate = create((set) => ({ - refTextupdate: -1000, - setRefTextUpdate: (callback) => - set((state) => ({ - refTextupdate: - typeof callback === "function" - ? callback(state.refTextupdate) - : callback, - })), + refTextupdate: -1000, + setRefTextUpdate: (callback) => + set((state) => ({ + refTextupdate: + typeof callback === "function" + ? callback(state.refTextupdate) + : callback, + })), })); export const useResetCamera = create((set: any) => ({ - resetCamera: false, - setResetCamera: (x: any) => set({ resetCamera: x }), + resetCamera: false, + setResetCamera: (x: any) => set({ resetCamera: x }), })); export const useAddAction = create((set: any) => ({ - addAction: null, - setAddAction: (x: any) => set({ addAction: x }), + addAction: null, + setAddAction: (x: any) => set({ addAction: x }), })); export const useActiveTool = create((set: any) => ({ - activeTool: "cursor", - setActiveTool: (x: any) => set({ activeTool: x }), + activeTool: "cursor", + setActiveTool: (x: any) => set({ activeTool: x }), })); export const useActiveSubTool = create((set: any) => ({ - activeSubTool: "cursor", - setActiveSubTool: (x: any) => set({ activeSubTool: x }), + activeSubTool: "cursor", + setActiveSubTool: (x: any) => set({ activeSubTool: x }), })); export const use2DUndoRedo = create((set: any) => ({ - is2DUndoRedo: null, - set2DUndoRedo: (x: any) => set({ is2DUndoRedo: x }), + is2DUndoRedo: null, + set2DUndoRedo: (x: any) => set({ is2DUndoRedo: x }), })); export const useElevation = create((set: any) => ({ - elevation: 45, - setElevation: (x: any) => set({ elevation: x }), + elevation: 45, + setElevation: (x: any) => set({ elevation: x }), })); export const useAzimuth = create((set: any) => ({ - azimuth: -160, - setAzimuth: (x: any) => set({ azimuth: x }), + azimuth: -160, + setAzimuth: (x: any) => set({ azimuth: x }), })); export const useRenderDistance = create((set: any) => ({ - renderDistance: 40, - setRenderDistance: (x: any) => set({ renderDistance: x }), + renderDistance: 40, + setRenderDistance: (x: any) => set({ renderDistance: x }), })); export const useCamMode = create((set: any) => ({ - camMode: "ThirdPerson", - setCamMode: (x: any) => set({ camMode: x }), + camMode: "ThirdPerson", + setCamMode: (x: any) => set({ camMode: x }), })); export const useUserName = create((set: any) => ({ - userName: "", - setUserName: (x: any) => set({ userName: x }), + userName: "", + setUserName: (x: any) => set({ userName: x }), })); export const useObjectPosition = create((set: any) => ({ - objectPosition: { x: undefined, y: undefined, z: undefined }, - setObjectPosition: (newObjectPosition: any) => - set({ objectPosition: newObjectPosition }), + objectPosition: { x: undefined, y: undefined, z: undefined }, + setObjectPosition: (newObjectPosition: any) => + set({ objectPosition: newObjectPosition }), })); export const useObjectRotation = create((set: any) => ({ - objectRotation: { x: undefined, y: undefined, z: undefined }, - setObjectRotation: (newObjectRotation: any) => - set({ objectRotation: newObjectRotation }), + objectRotation: { x: undefined, y: undefined, z: undefined }, + setObjectRotation: (newObjectRotation: any) => + set({ objectRotation: newObjectRotation }), })); export const useDrieTemp = create((set: any) => ({ - drieTemp: undefined, - setDrieTemp: (x: any) => set({ drieTemp: x }), + drieTemp: undefined, + setDrieTemp: (x: any) => set({ drieTemp: x }), })); export const useActiveUsers = create((set: any) => ({ - activeUsers: [], - setActiveUsers: (callback: (prev: any[]) => any[] | any[]) => - set((state: { activeUsers: any[] }) => ({ - activeUsers: - typeof callback === "function" ? callback(state.activeUsers) : callback, - })), + activeUsers: [], + setActiveUsers: (callback: (prev: any[]) => any[] | any[]) => + set((state: { activeUsers: any[] }) => ({ + activeUsers: + typeof callback === "function" ? callback(state.activeUsers) : callback, + })), })); export const useDrieUIValue = create((set: any) => ({ - drieUIValue: { touch: null, temperature: null, humidity: null }, + drieUIValue: { touch: null, temperature: null, humidity: null }, - setDrieUIValue: (x: any) => - set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })), + setDrieUIValue: (x: any) => + set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })), - setTouch: (value: any) => - set((state: any) => ({ - drieUIValue: { ...state.drieUIValue, touch: value }, - })), - setTemperature: (value: any) => - set((state: any) => ({ - drieUIValue: { ...state.drieUIValue, temperature: value }, - })), - setHumidity: (value: any) => - set((state: any) => ({ - drieUIValue: { ...state.drieUIValue, humidity: value }, - })), + setTouch: (value: any) => + set((state: any) => ({ + drieUIValue: { ...state.drieUIValue, touch: value }, + })), + setTemperature: (value: any) => + set((state: any) => ({ + drieUIValue: { ...state.drieUIValue, temperature: value }, + })), + setHumidity: (value: any) => + set((state: any) => ({ + drieUIValue: { ...state.drieUIValue, humidity: value }, + })), })); export const useStartSimulation = create((set: any) => ({ - startSimulation: false, - setStartSimulation: (x: any) => set({ startSimulation: x }), + startSimulation: false, + setStartSimulation: (x: any) => set({ startSimulation: x }), })); export const useEyeDropMode = create((set: any) => ({ - eyeDropMode: false, - setEyeDropMode: (x: any) => set({ eyeDropMode: x }), + eyeDropMode: false, + setEyeDropMode: (x: any) => set({ eyeDropMode: x }), })); export const useEditingPoint = create((set: any) => ({ - editingPoint: false, - setEditingPoint: (x: any) => set({ editingPoint: x }), + editingPoint: false, + setEditingPoint: (x: any) => set({ editingPoint: x }), })); export const usezoneTarget = create((set: any) => ({ - zoneTarget: [], - setZoneTarget: (x: any) => set({ zoneTarget: x }), + zoneTarget: [], + setZoneTarget: (x: any) => set({ zoneTarget: x }), })); export const usezonePosition = create((set: any) => ({ - zonePosition: [], - setZonePosition: (x: any) => set({ zonePosition: x }), + zonePosition: [], + setZonePosition: (x: any) => set({ zonePosition: x }), })); interface EditPositionState { - Edit: boolean; - setEdit: (value: boolean) => void; + Edit: boolean; + setEdit: (value: boolean) => void; } export const useEditPosition = create((set) => ({ - Edit: false, - setEdit: (value) => set({ Edit: value }), + Edit: false, + setEdit: (value) => set({ Edit: value }), })); export const useAsset3dWidget = create((set: any) => ({ - widgetSelect: "", - setWidgetSelect: (x: any) => set({ widgetSelect: x }), + widgetSelect: "", + setWidgetSelect: (x: any) => set({ widgetSelect: x }), })); export const useWidgetSubOption = create((set: any) => ({ - widgetSubOption: "2D", - setWidgetSubOption: (x: any) => set({ widgetSubOption: x }), + widgetSubOption: "2D", + setWidgetSubOption: (x: any) => set({ widgetSubOption: x }), })); export const useLimitDistance = create((set: any) => ({ - limitDistance: true, - setLimitDistance: (x: any) => set({ limitDistance: x }), + limitDistance: true, + setLimitDistance: (x: any) => set({ limitDistance: x }), })); export const useTileDistance = create((set: any) => ({ - gridValue: { size: CONSTANTS.gridConfig.size, divisions: CONSTANTS.gridConfig.divisions }, - planeValue: { height: CONSTANTS.planeConfig.height, width: CONSTANTS.planeConfig.width }, + gridValue: { + size: CONSTANTS.gridConfig.size, + divisions: CONSTANTS.gridConfig.divisions, + }, + planeValue: { + height: CONSTANTS.planeConfig.height, + width: CONSTANTS.planeConfig.width, + }, - setGridValue: (value: any) => - set((state: any) => ({ - gridValue: { ...state.gridValue, ...value }, - })), + setGridValue: (value: any) => + set((state: any) => ({ + gridValue: { ...state.gridValue, ...value }, + })), - setPlaneValue: (value: any) => - set((state: any) => ({ - planeValue: { ...state.planeValue, ...value }, - })), + setPlaneValue: (value: any) => + set((state: any) => ({ + planeValue: { ...state.planeValue, ...value }, + })), })); export const usePlayAgv = create((set, get) => ({ - PlayAgv: [], - setPlayAgv: (updateFn: (prev: any[]) => any[]) => - set({ PlayAgv: updateFn(get().PlayAgv) }), + PlayAgv: [], + setPlayAgv: (updateFn: (prev: any[]) => any[]) => + set({ PlayAgv: updateFn(get().PlayAgv) }), })); // Define the Asset type type Asset = { - id: string; - name: string; - position?: [number, number, number]; // Optional: 3D position - rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation + id: string; + name: string; + position?: [number, number, number]; // Optional: 3D position + rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation }; // Zustand store type type ZoneAssetState = { - zoneAssetId: Asset | null; - setZoneAssetId: (asset: Asset | null) => void; + zoneAssetId: Asset | null; + setZoneAssetId: (asset: Asset | null) => void; }; // Zustand store export const useZoneAssetId = create((set) => ({ - zoneAssetId: null, - setZoneAssetId: (asset) => set({ zoneAssetId: asset }), + zoneAssetId: null, + setZoneAssetId: (asset) => set({ zoneAssetId: asset }), })); // version visible hidden interface VersionHistoryState { - viewVersionHistory: boolean; - setVersionHistory: (value: boolean) => void; + viewVersionHistory: boolean; + setVersionHistory: (value: boolean) => void; } const useVersionHistoryStore = create((set) => ({ - viewVersionHistory: false, - setVersionHistory: (value) => set({ viewVersionHistory: value }), + viewVersionHistory: false, + setVersionHistory: (value) => set({ viewVersionHistory: value }), })); export default useVersionHistoryStore; interface ShortcutStore { - showShortcuts: boolean; - setShowShortcuts: (value: boolean) => void; - toggleShortcuts: () => void; + showShortcuts: boolean; + setShowShortcuts: (value: boolean) => void; + toggleShortcuts: () => void; } export const useShortcutStore = create((set) => ({ - showShortcuts: false, - setShowShortcuts: (value) => set({ showShortcuts: value }), - toggleShortcuts: () => - set((state) => ({ showShortcuts: !state.showShortcuts })), -})); \ No newline at end of file + showShortcuts: false, + setShowShortcuts: (value) => set({ showShortcuts: value }), + toggleShortcuts: () => + set((state) => ({ showShortcuts: !state.showShortcuts })), +})); + +interface CompareStore { + comparePopUp: boolean; + setComparePopUp: (value: boolean) => void; + toggleComparePopUp: () => void; +} + +export const useCompareStore = create((set) => ({ + comparePopUp: false, + setComparePopUp: (value) => set({ comparePopUp: value }), + toggleComparePopUp: () => + set((state) => ({ comparePopUp: !state.comparePopUp })), +})); diff --git a/app/src/styles/components/footer/footer.scss b/app/src/styles/components/footer/footer.scss index 728e222..5b6467b 100644 --- a/app/src/styles/components/footer/footer.scss +++ b/app/src/styles/components/footer/footer.scss @@ -4,7 +4,7 @@ .footer-container { width: 100%; - position: absolute; + position: fixed; bottom: 0; left: 0; z-index: 3; @@ -12,6 +12,7 @@ display: flex; flex-direction: column; gap: 6px; + pointer-events: none; .footer-wrapper { display: flex; @@ -46,7 +47,7 @@ display: flex; gap: 6px; position: relative; - + pointer-events: all; // dummy .bg-dummy { background: var(--background-color-solid); diff --git a/app/src/styles/components/tools.scss b/app/src/styles/components/tools.scss index 05e991a..ba4bb9f 100644 --- a/app/src/styles/components/tools.scss +++ b/app/src/styles/components/tools.scss @@ -187,41 +187,77 @@ } -.exitPlay { - width: 30px; +.controls-player-container { + width: 663px; height: 30px; - border-radius: #{$border-radius-circle}; - background: var(--highlight-accent-color); + border-radius: 15px; + + background: var(--background-color); + backdrop-filter: blur(20px); cursor: pointer; @include flex-center; + justify-content: space-between; position: fixed; - bottom: 60px; + bottom: 40px; left: 50%; transform: translate(-50%, 0); color: var(--accent-color); z-index: 100; isolation: isolate; font-weight: 700; + padding: 8px; - &:hover { - font-weight: 500; - background: var(--accent-color); - color: var(--highlight-accent-color); + .controls-left, + .controls-right { + display: flex; + align-items: center; + gap: 12px; + font-size: var(--font-size-small); - &::after { - animation: pulse 1s ease-out infinite; + .label { + text-transform: capitalize; + font-size: var(--font-size-small); + } + + .walkMode-wrapper { + display: flex; + align-items: center; + gap: 4px; + + + .input-toggle-container { + padding: 0; + gap: 4px; + + .label { + + font-size: var(--font-size-small); + } + } + } + + .btn-wrapper { + background: var(--background-color); + backdrop-filter: blur(8px); + display: flex; + align-items: center; + justify-content: space-between; + gap: 5px; + border-radius: 15px; + padding: 2px 8px; + color: var(--highlight-text-color); + cursor: pointer; + font-size: var(--font-size-small); + + .icon { + width: 16px; + height: 16px; + @include flex-center; + } } } - &::after { - content: ""; - position: absolute; - height: 100%; - width: 100%; - background: var(--background-color-secondary); - border-radius: #{$border-radius-circle}; - z-index: -1; - } + } @keyframes pulse { diff --git a/app/src/styles/layout/compareLayoutPopUp.scss b/app/src/styles/layout/compareLayoutPopUp.scss new file mode 100644 index 0000000..d0900a5 --- /dev/null +++ b/app/src/styles/layout/compareLayoutPopUp.scss @@ -0,0 +1,267 @@ +.compare-container { + width: 100vw; + height: 100vh; + + background: var(--background-color-secondary); + backdrop-filter: blur(2px); + display: flex; + justify-content: center; + align-items: center; + + .compare-wrapper { + min-width: 312px; + min-height: 363px; + background: var(--background-color); + padding: 20px; + border-radius: 24px; + display: flex; + flex-direction: column; + gap: 12px; + backdrop-filter: blur(50px); + outline: 1px solid var(--border-color); + box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1); + position: relative; + + .grid-wrapper { + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; + border-radius: 20px; + position: relative; + + background-size: 52px 52px; + background-repeat: repeat; + + + + >* { + position: relative; + z-index: 2; + } + + .header { + text-align: center; + font-size: var(--font-size-small); + font-weight: 600; + margin-bottom: 8px; + } + + .cards-container { + margin-top: 30px; + display: flex; + justify-content: center; + align-items: center; + + .card { + background: var(--background-color); + backdrop-filter: blur(20px); + + width: 100px; + height: 100px; + margin: 10px; + border-radius: 10px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + position: absolute; + + } + + + } + + .card-layout-wrapper { + display: flex; + justify-content: center; + align-items: center; + padding: 10px; + + background: var(--background-color); + backdrop-filter: blur(20px); + border-radius: 20px; + outline: 1px solid var(--border-color); + } + + .card-layout-container { + width: 130px; + height: 130px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + display: flex; + flex-direction: column; + justify-content: space-around; + + align-items: center; + padding: 10px; + + outline: 1px solid var(--border-color); + outline-offset: -1px; + border-radius: 12px; + background: var(--background-color); + + .tab-header { + display: flex; + justify-content: space-between; + width: 100%; + + .label-tab { + font-size: var(--font-size-small); + font-weight: 500; + } + + .status { + width: 10px; + height: 10px; + border-radius: 50%; + background-color: #5a33a3; + } + + } + + + + .skeleton-wrapper { + + width: 100%; + display: flex; + flex-direction: column; + gap: 6px; + justify-content: center; + align-items: center; + + .skeleton { + height: 2.662480115890503px; + + &:nth-child(1) { + width: 40%; + } + + &:nth-child(2) { + width: 70%; + } + + &:nth-child(3) { + width: 40%; + } + } + + } + } + + .button-wrapper { + margin-top: 20px; + display: flex; + flex-direction: column; + align-items: center; + gap: 12px; + + .button-group { + display: flex; + gap: 8px; + + .btn { + padding: 10px 16px; + font-size: var(--font-size-small); + font-weight: 600; + border-radius: 30px; + cursor: pointer; + transition: all 0.3s ease; + user-select: none; + } + + .save { + background-color: #6f42c1; + color: white; + box-shadow: 0px 2px 8px rgba(111, 66, 193, 0.4); + + &:hover { + background-color: #5a33a3; + } + } + + .replace { + border: 1px solid #6f42c1; + color: #6f42c1; + background: transparent; + + &:hover { + background-color: rgba(111, 66, 193, 0.08); + } + } + } + + .cancel { + color: red; + font-size: var(--font-size-small); + font-weight: 500; + cursor: pointer; + } + } + } + + .footer { + font-size: var(--font-size-small); + opacity: 0.7; + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + } + } +} + + + + +.cards-container { + margin-top: 30px; + position: relative; + width: 100%; + height: 150px; + + .card { + position: absolute; + width: 100px; + height: 100px; + background: white; + border-radius: 10px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + z-index: 1; + + &:nth-child(1) { + left: 0; + transform: scale(1); + } + + &:nth-child(2) { + right: 0; + transform: scale(1); + } + + &:nth-child(4) { + left: 20px; + transform: scale(1); + } + + &:nth-child(5) { + right: 20px; + transform: scale(1); + } + } + + .card-layout-wrapper { + position: absolute; + left: 50%; + top: 0; + transform: translateX(-50%); + z-index: 2; + + display: flex; + justify-content: center; + align-items: center; + padding: 10px; + + background: var(--background-color); + backdrop-filter: blur(20px); + border-radius: 20px; + outline: 1px solid var(--border-color); + } +} \ No newline at end of file diff --git a/app/src/styles/main.scss b/app/src/styles/main.scss index 6c25a3e..1e3c460 100644 --- a/app/src/styles/main.scss +++ b/app/src/styles/main.scss @@ -33,7 +33,8 @@ @use 'layout/sidebar'; @use 'layout/popup'; @use 'layout/toast'; -@use 'layout/skeleton.scss'; +@use 'layout/skeleton'; +@use 'layout/compareLayoutPopUp'; // pages @use 'pages/dashboard'; diff --git a/app/src/styles/pages/realTimeViz.scss b/app/src/styles/pages/realTimeViz.scss index e454a34..5c7ba27 100644 --- a/app/src/styles/pages/realTimeViz.scss +++ b/app/src/styles/pages/realTimeViz.scss @@ -54,7 +54,7 @@ } } - .zone-wrapper { + .zone-container { display: flex; background: var(--background-color); backdrop-filter: blur(10px); @@ -117,6 +117,10 @@ } } + .zone-container.visualization-playing { + bottom: 70px; + } + .zone-wrapper.bottom { bottom: var(--bottomWidth); } @@ -363,6 +367,9 @@ } } + + + // Side Buttons .side-button-container { position: absolute; @@ -968,4 +975,4 @@ display: flex; justify-content: center; align-items: center; -} +} \ No newline at end of file