diff --git a/frontend/src/assets/styles/pages/_realTimeViz.scss b/frontend/src/assets/styles/pages/_realTimeViz.scss index 6e7f17c..ae31bb6 100644 --- a/frontend/src/assets/styles/pages/_realTimeViz.scss +++ b/frontend/src/assets/styles/pages/_realTimeViz.scss @@ -38,6 +38,34 @@ height: 600px; background-color: rgb(235, 235, 235); margin: 0 30px; + + .zoon-wrapper { + display: flex; + background-color: #E0DFFF80; + position: absolute; + bottom: 10px; + left: 50%; + transform: translate(-50%, 0); + gap: 6px; + padding: 4px; + border-radius: 8px; + max-width: 80%; + overflow: auto; + + &::-webkit-scrollbar { + display: none; + } + + .zone { + width: auto; + background-color: #FCFDFD; + border-radius: 6px; + padding: 4px 8px; + white-space: nowrap; + } + } + + } // + button @@ -388,6 +416,10 @@ flex-direction: column; gap: 5px; align-items: center; + + .active { + // background-color: red; + } } .icon { @@ -426,6 +458,7 @@ .extra-buttons { display: flex; flex-direction: row; + } } diff --git a/frontend/src/components/ui/inputs/regularDropDown.tsx b/frontend/src/components/ui/inputs/regularDropDown.tsx index 6ae8c7d..1108857 100644 --- a/frontend/src/components/ui/inputs/regularDropDown.tsx +++ b/frontend/src/components/ui/inputs/regularDropDown.tsx @@ -1,59 +1,47 @@ -import React, { useState, useEffect, useRef } from 'react'; -import { DropDownIcon } from '../../../assets/images/svgExports'; +import React, { useState, useEffect } from "react"; interface DropdownProps { header: string; options: string[]; - onSelect: (option: string) => void; // Callback for option selection + onSelect: (option: string) => void; } -const RegularDropDown: React.FC = ({ header, options, onSelect }) => { +const RegularDropDown: React.FC = ({ + header, + options, + onSelect, +}) => { const [isOpen, setIsOpen] = useState(false); const [selectedOption, setSelectedOption] = useState(null); - // Reference to the dropdown container - const dropdownRef = useRef(null); + // Reset selectedOption when the dropdown closes + useEffect(() => { + if (!isOpen) { + setSelectedOption(null); // Clear local state when the dropdown closes + } + }, [isOpen]); + + // Reset selectedOption when the header prop changes + useEffect(() => { + setSelectedOption(null); // Ensure the dropdown reflects the updated header + }, [header]); - // Toggle dropdown visibility const toggleDropdown = () => { - setIsOpen(prev => !prev); + setIsOpen((prev) => !prev); }; - // Handle option selection const handleOptionClick = (option: string) => { setSelectedOption(option); onSelect(option); // Call the onSelect function passed from the parent setIsOpen(false); // Close the dropdown after selection }; - // Handle clicks outside the dropdown - useEffect(() => { - const handleOuterClick = (event: MouseEvent) => { - if ( - dropdownRef.current && - !dropdownRef.current.contains(event.target as Node) - ) { - setIsOpen(false); // Close the dropdown if clicked outside - } - }; - - // Attach the event listener - document.addEventListener('mousedown', handleOuterClick); - - // Cleanup the event listener on component unmount - return () => { - document.removeEventListener('mousedown', handleOuterClick); - }; - }, []); - return ( -
+
{/* Dropdown Header */}
{selectedOption || header}
-
- -
+
{/* Dropdown Options */} @@ -63,7 +51,7 @@ const RegularDropDown: React.FC = ({ header, options, onSelect })
handleOptionClick(option)} // Handle option click + onClick={() => handleOptionClick(option)} > {option}
@@ -74,4 +62,4 @@ const RegularDropDown: React.FC = ({ header, options, onSelect }) ); }; -export default RegularDropDown; \ No newline at end of file +export default RegularDropDown; diff --git a/frontend/src/components/ui/sideBar/realTimeViz/data.tsx b/frontend/src/components/ui/sideBar/realTimeViz/data.tsx index c786ae1..8ea9663 100644 --- a/frontend/src/components/ui/sideBar/realTimeViz/data.tsx +++ b/frontend/src/components/ui/sideBar/realTimeViz/data.tsx @@ -21,7 +21,7 @@ const Data = () => { easing: "Connecter 1", children: [ { id: 1, easing: "Linear" }, - { id: 2, easing: "Linear" }, + { id: 2, easing: "Ease Out" }, { id: 3, easing: "Linear" }, ], }, @@ -70,21 +70,26 @@ const Data = () => { }); }; - const removeChild = (childId: number) => { - setGroups((groups) => - groups - .map((group) => ({ - ...group, - children: group.children.filter((c) => c.id !== childId), - })) - .filter((group) => group.children.length > 0) + const removeChild = (groupId: number, childId: number) => { + setGroups((currentGroups) => + currentGroups.map((group) => { + if (group.id === groupId) { + return { + ...group, + children: group.children.map((child) => + child.id === childId ? { ...child, easing: "Linear" } : child + ), + }; + } + return group; + }) ); }; return (
{selectedWidget}
- {groups.map((group, groupIndex) => ( + {groups.map((group) => (
@@ -107,6 +112,7 @@ const Data = () => { {group.children.map((child) => (
Input {child.id}
+ {/* Pass the current easing as the header */} {
handleLinkClick(child.id)}>
-
removeChild(child.id)}> +
removeChild(group.id, child.id)} + >
diff --git a/frontend/src/pages/realTimeVisualization/realTimeVisualization.tsx b/frontend/src/pages/realTimeVisualization/realTimeVisualization.tsx index 385e660..82a0cec 100644 --- a/frontend/src/pages/realTimeVisualization/realTimeVisualization.tsx +++ b/frontend/src/pages/realTimeVisualization/realTimeVisualization.tsx @@ -49,17 +49,11 @@ const DraggableWidget = ({ widget }: { widget: any }) => { }; const handlePointerDown = () => { - // Set selected chart when pointer down event occurs (i.e., when it's clicked, not dragged) if (!isDragging) { - setSelectedChartId(widget); // Update selected chart in the store + setSelectedChartId(widget); } }; - // Log to see the selectedChartId updates - useEffect(() => { - console.log("selectedChartID: ", selectedChartId); - }, [selectedChartId]); - return (
{ {...attributes} {...listeners} style={style} - onPointerDown={handlePointerDown} // Use onPointerDown instead of onPointerUp + onPointerDown={handlePointerDown} > { }; const RealTimeVisualization = () => { + const [zone, setZone] = useState([ + "Manufacturing unit", + "Assembly unit", + "Packing unit", + "Warehouse", + "Inventory", + ]); + const [activeSides, setActiveSides] = useState([]); const [panelOrder, setPanelOrder] = useState([]); const [selectedSide, setSelectedSide] = useState(null); + const [lockedPanels, setLockedPanels] = useState([]); + const [activeExtraButton, setActiveExtraButton] = useState<{ + [key in Side]?: string; + }>({}); const { draggedAsset, addWidget, widgets, setWidgets } = useWidgetStore(); - // Sensors for drag-and-drop (Pointer and Keyboard) const sensors = useSensors( useSensor(PointerSensor), useSensor(KeyboardSensor) ); - useEffect(() => {}, [widgets]); - const toggleSide = (side: Side) => { setActiveSides((prev) => { const newActive = prev.includes(side) @@ -102,17 +105,24 @@ const RealTimeVisualization = () => { : [...prev, side]; setPanelOrder(newActive); - // Reset selectedSide if the panel is being closed if (prev.includes(side)) { - setSelectedSide(null); // Hide extra buttons when the panel is closed + setSelectedSide(null); } else { - setSelectedSide(side); // Show extra buttons when the panel is opened + setSelectedSide(side); } return newActive; }); }; + const toggleLockPanel = (side: Side) => { + setLockedPanels((prev) => + prev.includes(side) + ? prev.filter((panel) => panel !== side) + : [...prev, side] + ); + }; + const getPanelStyle = (currentSide: Side) => { const currentIndex = panelOrder.indexOf(currentSide); const previousPanels = panelOrder.slice(0, currentIndex); @@ -159,9 +169,6 @@ const RealTimeVisualization = () => { } }; - const leftHeader = useMemo(() => ["Overview", "Widgets", "Templates"], []); - const rightHeader = useMemo(() => ["Data", "Design"], []); - const handleDragEnd = (event: any) => { const { active, over } = event; @@ -171,14 +178,11 @@ const RealTimeVisualization = () => { const newPanel = widgets.find((widget) => widget.id === over.id)?.panel || active.panel; - // Ensure widgets are reordered within the same panel or moved to a new panel if (active.panel === newPanel) { - // Reorder within the same panel const newIndex = widgets.findIndex((widget) => widget.id === over.id); const reorderedWidgets = arrayMove(widgets, oldIndex, newIndex); setWidgets(reorderedWidgets); } else { - // Move to a different panel const updatedWidgets = widgets.map((widget) => widget.id === active.id ? { ...widget, panel: newPanel } : widget ); @@ -200,12 +204,19 @@ const RealTimeVisualization = () => { onDragEnd={handleDragEnd} >
- +
+
+ {zone.map((zone, index) => ( +
{zone}
+ ))} +
{(["top", "right", "bottom", "left"] as Side[]).map((side) => (
- {/* Side Button */} - {/* Extra Buttons */}
-
+
+ setActiveExtraButton((prev) => ({ + ...prev, + [side]: "Disable Sorting", + })) + } + >
-
+
+ setActiveExtraButton((prev) => ({ + ...prev, + [side]: "Hide Panel", + })) + } + >
-
+
+ setActiveExtraButton((prev) => ({ + ...prev, + [side]: "Clean Panel", + })) + } + >
-
+
{ + toggleLockPanel(side); + setActiveExtraButton((prev) => ({ + ...prev, + [side]: "Lock Panel", + })); + }} + >
@@ -245,7 +304,13 @@ const RealTimeVisualization = () => { onDrop={(e) => handleDrop(e, side)} onDragOver={(e) => e.preventDefault()} > -
+
w.panel === side) @@ -255,9 +320,7 @@ const RealTimeVisualization = () => { {widgets .filter((w) => w.panel === side) .map((widget) => ( - <> - - + ))}
@@ -265,7 +328,7 @@ const RealTimeVisualization = () => { ))}
- +
);