Merge remote-tracking branch 'origin/ui' into simulation
This commit is contained in:
commit
d8bf2ea956
|
@ -42,11 +42,14 @@ const Design = () => {
|
|||
const [elementColor, setElementColor] = useState("#6f42c1");
|
||||
const [showColorPicker, setShowColorPicker] = useState(false);
|
||||
const [chartElements, setChartElements] = useState<ChartElement[]>([]);
|
||||
const [selectedElementToStyle, setSelectedElementToStyle] = useState<string | null>(null);
|
||||
const [selectedElementToStyle, setSelectedElementToStyle] = useState<
|
||||
string | null
|
||||
>(null);
|
||||
const [nameInput, setNameInput] = useState("");
|
||||
const chartRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const { selectedChartId, setSelectedChartId, widgets, setWidgets } = useWidgetStore();
|
||||
const { selectedChartId, setSelectedChartId, widgets, setWidgets } =
|
||||
useWidgetStore();
|
||||
|
||||
// Initialize name input and extract elements when selectedChartId changes
|
||||
useEffect(() => {
|
||||
|
@ -65,13 +68,16 @@ const Design = () => {
|
|||
})
|
||||
.map((el, index) => {
|
||||
const tagName = el.tagName.toLowerCase();
|
||||
const className = typeof el.className === "string" ? el.className : "";
|
||||
const className =
|
||||
typeof el.className === "string" ? el.className : "";
|
||||
const textContent = el.textContent?.trim() || "";
|
||||
|
||||
let selector = tagName;
|
||||
|
||||
if (className && typeof className === "string") {
|
||||
const classList = className.split(/\s+/).filter((c) => c.length > 0);
|
||||
const classList = className
|
||||
.split(/\s+/)
|
||||
.filter((c) => c.length > 0);
|
||||
if (classList.length > 0) {
|
||||
selector += "." + classList.join(".");
|
||||
}
|
||||
|
@ -126,7 +132,13 @@ const Design = () => {
|
|||
|
||||
useEffect(() => {
|
||||
applyStyles();
|
||||
}, [selectedFont, selectedSize, selectedWeight, elementColor, selectedElementToStyle]);
|
||||
}, [
|
||||
selectedFont,
|
||||
selectedSize,
|
||||
selectedWeight,
|
||||
elementColor,
|
||||
selectedElementToStyle,
|
||||
]);
|
||||
|
||||
const handleUpdateWidget = (updatedProperties: Partial<Widget>) => {
|
||||
if (!selectedChartId) return;
|
||||
|
@ -138,7 +150,9 @@ const Design = () => {
|
|||
setSelectedChartId(updatedChartId);
|
||||
|
||||
const updatedWidgets = widgets.map((widget) =>
|
||||
widget.id === selectedChartId.id ? { ...widget, ...updatedProperties } : widget
|
||||
widget.id === selectedChartId.id
|
||||
? { ...widget, ...updatedProperties }
|
||||
: widget
|
||||
);
|
||||
setWidgets(updatedWidgets);
|
||||
};
|
||||
|
@ -155,12 +169,12 @@ const Design = () => {
|
|||
};
|
||||
|
||||
const defaultChartData = {
|
||||
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"],
|
||||
labels: ["January", "February", "March", "April", "May", "June", "July"],
|
||||
datasets: [
|
||||
{
|
||||
data: [65, 59, 80, 81, 56, 55, 40],
|
||||
backgroundColor: elementColor,
|
||||
borderColor: "#ffffff",
|
||||
backgroundColor: "#6f42c1",
|
||||
borderColor: "#b392f0",
|
||||
borderWidth: 1,
|
||||
},
|
||||
],
|
||||
|
|
|
@ -59,7 +59,6 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
setHiddenPanels,
|
||||
hiddenPanels,
|
||||
}) => {
|
||||
|
||||
const { visualizationSocket } = useSocketStore();
|
||||
|
||||
// Local state to track hidden panels
|
||||
|
@ -132,10 +131,10 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
let deletePanel = {
|
||||
organization: organization,
|
||||
panelName: side,
|
||||
zoneId: selectedZone.zoneId
|
||||
}
|
||||
zoneId: selectedZone.zoneId,
|
||||
};
|
||||
if (visualizationSocket) {
|
||||
visualizationSocket.emit("v2:viz-panel:delete", deletePanel)
|
||||
visualizationSocket.emit("v2:viz-panel:delete", deletePanel);
|
||||
}
|
||||
setSelectedZone(updatedZone);
|
||||
|
||||
|
@ -151,6 +150,8 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
//
|
||||
// }
|
||||
} else {
|
||||
setHiddenPanels(hiddenPanels.filter((panel) => panel !== side));
|
||||
|
||||
// Panel does not exist: Create panel
|
||||
try {
|
||||
// Get email and organization safely with a default fallback
|
||||
|
@ -170,10 +171,10 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
let addPanel = {
|
||||
organization: organization,
|
||||
zoneId: selectedZone.zoneId,
|
||||
panelOrder: newActiveSides
|
||||
}
|
||||
panelOrder: newActiveSides,
|
||||
};
|
||||
if (visualizationSocket) {
|
||||
visualizationSocket.emit("v2:viz-panel:add", addPanel)
|
||||
visualizationSocket.emit("v2:viz-panel:add", addPanel);
|
||||
}
|
||||
setSelectedZone(updatedZone);
|
||||
// API call to create panels
|
||||
|
@ -184,13 +185,10 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
// } else {
|
||||
//
|
||||
// }
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
|
@ -198,7 +196,8 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
<div key={side} className={`side-button-container ${side}`}>
|
||||
{/* "+" Button */}
|
||||
<button
|
||||
className={`side-button ${side}${selectedZone.activeSides.includes(side) ? " active" : ""
|
||||
className={`side-button ${side}${
|
||||
selectedZone.activeSides.includes(side) ? " active" : ""
|
||||
}`}
|
||||
onClick={() => handlePlusButtonClick(side)}
|
||||
title={
|
||||
|
@ -217,7 +216,8 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
<div className="extra-Bs">
|
||||
{/* Hide Panel */}
|
||||
<div
|
||||
className={`icon ${hiddenPanels.includes(side) ? "active" : ""
|
||||
className={`icon ${
|
||||
hiddenPanels.includes(side) ? "active" : ""
|
||||
}`}
|
||||
title={
|
||||
hiddenPanels.includes(side) ? "Show Panel" : "Hide Panel"
|
||||
|
@ -225,7 +225,11 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
onClick={() => toggleVisibility(side)}
|
||||
>
|
||||
<EyeIcon
|
||||
fill={hiddenPanels.includes(side) ? "var(--primary-color)" : "var(--text-color)"}
|
||||
fill={
|
||||
hiddenPanels.includes(side)
|
||||
? "var(--primary-color)"
|
||||
: "var(--text-color)"
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -240,7 +244,8 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
|
||||
{/* Lock/Unlock Panel */}
|
||||
<div
|
||||
className={`icon ${selectedZone.lockedPanels.includes(side) ? "active" : ""
|
||||
className={`icon ${
|
||||
selectedZone.lockedPanels.includes(side) ? "active" : ""
|
||||
}`}
|
||||
title={
|
||||
selectedZone.lockedPanels.includes(side)
|
||||
|
|
|
@ -96,16 +96,16 @@ export const DraggableWidget = ({
|
|||
let deleteWidget = {
|
||||
zoneId: selectedZone.zoneId,
|
||||
widgetID: widget.id,
|
||||
organization: organization
|
||||
}
|
||||
console.log('deleteWidget: ', deleteWidget);
|
||||
organization: organization,
|
||||
};
|
||||
console.log("deleteWidget: ", deleteWidget);
|
||||
if (visualizationSocket) {
|
||||
visualizationSocket.emit("v2:viz-widget:delete", deleteWidget)
|
||||
visualizationSocket.emit("v2:viz-widget:delete", deleteWidget);
|
||||
}
|
||||
const updatedWidgets = selectedZone.widgets.filter(
|
||||
(w: Widget) => w.id !== widget.id
|
||||
);
|
||||
console.log('updatedWidgets: ', updatedWidgets);
|
||||
console.log("updatedWidgets: ", updatedWidgets);
|
||||
setSelectedZone((prevZone: any) => ({
|
||||
...prevZone,
|
||||
widgets: updatedWidgets,
|
||||
|
@ -168,10 +168,10 @@ export const DraggableWidget = ({
|
|||
let duplicateWidget = {
|
||||
organization: organization,
|
||||
zoneId: selectedZone.zoneId,
|
||||
widget: duplicatedWidget
|
||||
}
|
||||
widget: duplicatedWidget,
|
||||
};
|
||||
if (visualizationSocket) {
|
||||
visualizationSocket.emit("v2:viz-widget:add", duplicateWidget)
|
||||
visualizationSocket.emit("v2:viz-widget:add", duplicateWidget);
|
||||
}
|
||||
setSelectedZone((prevZone: any) => ({
|
||||
...prevZone,
|
||||
|
@ -245,13 +245,75 @@ export const DraggableWidget = ({
|
|||
// });
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
|
||||
const [canvasDimensions, setCanvasDimensions] = useState({
|
||||
width: 0,
|
||||
height: 0,
|
||||
});
|
||||
// Track canvas dimensions
|
||||
useEffect(() => {
|
||||
const canvas = document.getElementById("real-time-vis-canvas");
|
||||
if (!canvas) return;
|
||||
|
||||
const updateCanvasDimensions = () => {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
setCanvasDimensions({
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
});
|
||||
};
|
||||
|
||||
// Initial measurement
|
||||
updateCanvasDimensions();
|
||||
|
||||
// Set up ResizeObserver to track changes
|
||||
const resizeObserver = new ResizeObserver(updateCanvasDimensions);
|
||||
resizeObserver.observe(canvas);
|
||||
|
||||
return () => {
|
||||
resizeObserver.unobserve(canvas);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = document.getElementById("real-time-vis-canvas");
|
||||
if (!canvas) return;
|
||||
|
||||
const updateCanvasDimensions = () => {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
setCanvasDimensions({
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
});
|
||||
};
|
||||
|
||||
// Initial measurement
|
||||
updateCanvasDimensions();
|
||||
|
||||
// Set up ResizeObserver to track changes
|
||||
const resizeObserver = new ResizeObserver(updateCanvasDimensions);
|
||||
resizeObserver.observe(canvas);
|
||||
|
||||
return () => {
|
||||
resizeObserver.unobserve(canvas);
|
||||
};
|
||||
}, []);
|
||||
|
||||
console.log("selectedChartId: ", widget);
|
||||
return (
|
||||
<>
|
||||
<style>
|
||||
{`
|
||||
:root {
|
||||
--realTimeViz-container-width: ${canvasDimensions.width * 0.25}px;
|
||||
--realTimeViz-container-height: ${canvasDimensions.height}px;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<div
|
||||
draggable
|
||||
key={widget.id}
|
||||
className={`chart-container ${(selectedChartId?.id === widget.id) && !isPlaying && "activeChart"
|
||||
className={`chart-container ${
|
||||
selectedChartId?.id === widget.id && !isPlaying && "activeChart"
|
||||
}`}
|
||||
onPointerDown={handlePointerDown}
|
||||
onDragStart={handleDragStart}
|
||||
|
@ -259,7 +321,13 @@ export const DraggableWidget = ({
|
|||
onDragOver={handleDragOver}
|
||||
onDrop={handleDrop}
|
||||
style={{
|
||||
pointerEvents: isPanelHidden ? "none" : "auto",
|
||||
// Apply styles based on panel position
|
||||
width: ["top", "bottom"].includes(widget.panel)
|
||||
? `calc(${canvasDimensions.width * 0.16}px - 2px)` // For top/bottom panels, set width
|
||||
: undefined, // Don't set width if it's left or right
|
||||
height: ["left", "right"].includes(widget.panel)
|
||||
? `calc(${canvasDimensions.height * 0.25}px - 2px)` // For left/right panels, set height
|
||||
: undefined, // Don't set height if it's top or bottom
|
||||
}}
|
||||
ref={chartWidget}
|
||||
onClick={() => setSelectedChartId(widget)}
|
||||
|
@ -273,7 +341,8 @@ export const DraggableWidget = ({
|
|||
{openKebabId === widget.id && (
|
||||
<div className="kebab-options" ref={widgetRef}>
|
||||
<div
|
||||
className={`edit btn ${isPanelFull(widget.panel) ? "btn-blur" : ""
|
||||
className={`edit btn ${
|
||||
isPanelFull(widget.panel) ? "btn-blur" : ""
|
||||
}`}
|
||||
onClick={isPanelFull(widget.panel) ? undefined : duplicateWidget}
|
||||
>
|
||||
|
@ -348,3 +417,5 @@ export const DraggableWidget = ({
|
|||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// in style if widget .panel is top or bottom set width if left or right set height
|
||||
|
|
|
@ -65,6 +65,7 @@ const DroppedObjects: React.FC = () => {
|
|||
);
|
||||
const [offset, setOffset] = useState<[number, number] | null>(null);
|
||||
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
||||
|
||||
const [activeEdges, setActiveEdges] = useState<{
|
||||
vertical: "top" | "bottom";
|
||||
horizontal: "left" | "right";
|
||||
|
@ -84,7 +85,6 @@ const DroppedObjects: React.FC = () => {
|
|||
// });
|
||||
const kebabRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
|
||||
// Clean up animation frame on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
|
@ -95,7 +95,10 @@ const DroppedObjects: React.FC = () => {
|
|||
}, []);
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (kebabRef.current && !kebabRef.current.contains(event.target as Node)) {
|
||||
if (
|
||||
kebabRef.current &&
|
||||
!kebabRef.current.contains(event.target as Node)
|
||||
) {
|
||||
setOpenKebabId(null);
|
||||
}
|
||||
};
|
||||
|
@ -113,7 +116,6 @@ const DroppedObjects: React.FC = () => {
|
|||
if (zoneEntries.length === 0) return null;
|
||||
const [zoneName, zone] = zoneEntries[0];
|
||||
|
||||
|
||||
function handleDuplicate(zoneName: string, index: number) {
|
||||
setOpenKebabId(null);
|
||||
duplicateObject(zoneName, index); // Call the duplicateObject method from the store
|
||||
|
@ -132,7 +134,7 @@ const DroppedObjects: React.FC = () => {
|
|||
}
|
||||
|
||||
if (visualizationSocket) {
|
||||
visualizationSocket.emit("v2:viz-float:delete", deleteFloatingWidget)
|
||||
visualizationSocket.emit("v2:viz-float:delete", deleteFloatingWidget);
|
||||
}
|
||||
deleteObject(zoneName, id);
|
||||
|
||||
|
@ -148,7 +150,10 @@ const DroppedObjects: React.FC = () => {
|
|||
}
|
||||
|
||||
const handlePointerDown = (event: React.PointerEvent, index: number) => {
|
||||
if ((event.target as HTMLElement).closest(".kebab-options") || (event.target as HTMLElement).closest(".kebab")) {
|
||||
if (
|
||||
(event.target as HTMLElement).closest(".kebab-options") ||
|
||||
(event.target as HTMLElement).closest(".kebab")
|
||||
) {
|
||||
return; // Prevent dragging when clicking on the kebab menu or its options
|
||||
}
|
||||
const obj = zone.objects[index];
|
||||
|
@ -449,7 +454,6 @@ const DroppedObjects: React.FC = () => {
|
|||
// position: boundedPosition,
|
||||
// });
|
||||
|
||||
|
||||
let updateFloatingWidget = {
|
||||
organization: organization,
|
||||
widget: {
|
||||
|
@ -460,7 +464,7 @@ const DroppedObjects: React.FC = () => {
|
|||
zoneId: zone.zoneId
|
||||
}
|
||||
if (visualizationSocket) {
|
||||
visualizationSocket.emit("v2:viz-float:add", updateFloatingWidget)
|
||||
visualizationSocket.emit("v2:viz-float:add", updateFloatingWidget);
|
||||
}
|
||||
|
||||
// if (response.message === "Widget updated successfully") {
|
||||
|
@ -479,7 +483,6 @@ const DroppedObjects: React.FC = () => {
|
|||
// animationRef.current = null;
|
||||
// }
|
||||
} catch (error) {
|
||||
|
||||
} finally {
|
||||
// Clean up regardless of success or failure
|
||||
setDraggingIndex(null);
|
||||
|
@ -565,26 +568,32 @@ const DroppedObjects: React.FC = () => {
|
|||
ref={kebabRef}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
handleKebabClick(obj.id, event)
|
||||
handleKebabClick(obj.id, event);
|
||||
}}
|
||||
>
|
||||
<KebabIcon />
|
||||
</div>
|
||||
{openKebabId === obj.id && (
|
||||
<div className="kebab-options" ref={kebabRef}>
|
||||
<div className="dublicate btn" onClick={(event) => {
|
||||
<div
|
||||
className="dublicate btn"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
handleDuplicate(zoneName, index); // Call the duplicate handler
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<div className="icon">
|
||||
<DublicateIcon />
|
||||
</div>
|
||||
<div className="label">Duplicate</div>
|
||||
</div>
|
||||
<div className="edit btn" onClick={(event) => {
|
||||
<div
|
||||
className="edit btn"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
handleDelete(zoneName, obj.id); // Call the delete handler
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<div className="icon">
|
||||
<DeleteIcon />
|
||||
</div>
|
||||
|
@ -592,7 +601,6 @@ const DroppedObjects: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
))}
|
||||
|
||||
|
@ -630,5 +638,3 @@ const DroppedObjects: React.FC = () => {
|
|||
};
|
||||
|
||||
export default DroppedObjects;
|
||||
|
||||
|
||||
|
|
|
@ -63,6 +63,59 @@ const Panel: React.FC<PanelProps> = ({
|
|||
const { isPlaying } = usePlayButtonStore();
|
||||
const { visualizationSocket } = useSocketStore();
|
||||
|
||||
const [canvasDimensions, setCanvasDimensions] = useState({
|
||||
width: 0,
|
||||
height: 0,
|
||||
});
|
||||
// Track canvas dimensions
|
||||
useEffect(() => {
|
||||
const canvas = document.getElementById("real-time-vis-canvas");
|
||||
if (!canvas) return;
|
||||
|
||||
const updateCanvasDimensions = () => {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
setCanvasDimensions({
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
});
|
||||
};
|
||||
|
||||
// Initial measurement
|
||||
updateCanvasDimensions();
|
||||
|
||||
// Set up ResizeObserver to track changes
|
||||
const resizeObserver = new ResizeObserver(updateCanvasDimensions);
|
||||
resizeObserver.observe(canvas);
|
||||
|
||||
return () => {
|
||||
resizeObserver.unobserve(canvas);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = document.getElementById("real-time-vis-canvas");
|
||||
if (!canvas) return;
|
||||
|
||||
const updateCanvasDimensions = () => {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
setCanvasDimensions({
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
});
|
||||
};
|
||||
|
||||
// Initial measurement
|
||||
updateCanvasDimensions();
|
||||
|
||||
// Set up ResizeObserver to track changes
|
||||
const resizeObserver = new ResizeObserver(updateCanvasDimensions);
|
||||
resizeObserver.observe(canvas);
|
||||
|
||||
return () => {
|
||||
resizeObserver.unobserve(canvas);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const getPanelStyle = useMemo(
|
||||
() => (side: Side) => {
|
||||
const currentIndex = selectedZone.panelOrder.indexOf(side);
|
||||
|
@ -71,36 +124,52 @@ const Panel: React.FC<PanelProps> = ({
|
|||
const rightActive = previousPanels.includes("right");
|
||||
const topActive = previousPanels.includes("top");
|
||||
const bottomActive = previousPanels.includes("bottom");
|
||||
const panelSize = isPlaying ? 300 : 210;
|
||||
|
||||
// Dynamic panel sizes based on canvas width
|
||||
const panelSizeWidth = Math.max(canvasDimensions.width * 0.165, 200); // Ensure minimum width of 200px
|
||||
const panelSizeHeight = Math.max(canvasDimensions.width * 0.13, 200); // Ensure minimum height of 200px
|
||||
|
||||
switch (side) {
|
||||
case "top":
|
||||
case "bottom":
|
||||
return {
|
||||
// minWidth: "200px", // Minimum width constraint
|
||||
width: `calc(100% - ${
|
||||
(leftActive ? panelSize : 0) + (rightActive ? panelSize : 0)
|
||||
(leftActive ? panelSizeWidth : 0) +
|
||||
(rightActive ? panelSizeWidth : 0)
|
||||
}px)`,
|
||||
height: `${panelSize - 2}px`,
|
||||
left: leftActive ? `${panelSize}px` : "0",
|
||||
right: rightActive ? `${panelSize}px` : "0",
|
||||
minHeight: "200px", // Minimum height constraint
|
||||
height: `${panelSizeHeight - 2}px`, // Subtracting for border or margin
|
||||
left: leftActive ? `${panelSizeWidth}px` : "0",
|
||||
right: rightActive ? `${panelSizeWidth}px` : "0",
|
||||
[side]: "0",
|
||||
};
|
||||
|
||||
case "left":
|
||||
case "right":
|
||||
return {
|
||||
width: `${panelSize - 2}px`,
|
||||
minWidth: "200px", // Minimum width constraint
|
||||
width: `${panelSizeWidth - 2}px`, // Subtracting for border or margin
|
||||
// minHeight: "200px", // Minimum height constraint
|
||||
height: `calc(100% - ${
|
||||
(topActive ? panelSize : 0) + (bottomActive ? panelSize : 0)
|
||||
(topActive ? panelSizeHeight : 0) +
|
||||
(bottomActive ? panelSizeHeight : 0)
|
||||
}px)`,
|
||||
top: topActive ? `${panelSize}px` : "0",
|
||||
bottom: bottomActive ? `${panelSize}px` : "0",
|
||||
top: topActive ? `${panelSizeHeight}px` : "0",
|
||||
bottom: bottomActive ? `${panelSizeHeight}px` : "0",
|
||||
[side]: "0",
|
||||
};
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
},
|
||||
[selectedZone.panelOrder, isPlaying]
|
||||
[
|
||||
selectedZone.panelOrder,
|
||||
isPlaying,
|
||||
canvasDimensions.width,
|
||||
canvasDimensions.height,
|
||||
]
|
||||
);
|
||||
|
||||
const handleDrop = (e: React.DragEvent, panel: Side) => {
|
||||
|
@ -152,10 +221,10 @@ const Panel: React.FC<PanelProps> = ({
|
|||
let addWidget = {
|
||||
organization: organization,
|
||||
zoneId: selectedZone.zoneId,
|
||||
widget: newWidget
|
||||
}
|
||||
widget: newWidget,
|
||||
};
|
||||
if (visualizationSocket) {
|
||||
visualizationSocket.emit("v2:viz-widget:add", addWidget)
|
||||
visualizationSocket.emit("v2:viz-widget:add", addWidget);
|
||||
}
|
||||
setSelectedZone((prev) => ({
|
||||
...prev,
|
||||
|
@ -164,7 +233,6 @@ const Panel: React.FC<PanelProps> = ({
|
|||
|
||||
try {
|
||||
// let response = await addingWidgets(selectedZone.zoneId, organization, newWidget);
|
||||
|
||||
// if (response.message === "Widget created successfully") {
|
||||
// setSelectedZone((prev) => ({
|
||||
// ...prev,
|
||||
|
@ -174,7 +242,6 @@ const Panel: React.FC<PanelProps> = ({
|
|||
} catch (error) {
|
||||
console.error("Error adding widget:", error);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -280,3 +347,5 @@ const Panel: React.FC<PanelProps> = ({
|
|||
};
|
||||
|
||||
export default Panel;
|
||||
|
||||
// canvasDimensions.width as percent
|
||||
|
|
|
@ -23,8 +23,11 @@ import RenderOverlay from "../../templates/Overlay";
|
|||
import ConfirmationPopup from "../../layout/confirmationPopup/ConfirmationPopup";
|
||||
import DroppedObjects from "./DroppedFloatingWidgets";
|
||||
import EditWidgetOption from "../menu/EditWidgetOption";
|
||||
import { useEditWidgetOptionsStore, useRightClickSelected, useRightSelected } from "../../../store/useZone3DWidgetStore";
|
||||
|
||||
import {
|
||||
useEditWidgetOptionsStore,
|
||||
useRightClickSelected,
|
||||
useRightSelected,
|
||||
} from "../../../store/useZone3DWidgetStore";
|
||||
|
||||
type Side = "top" | "bottom" | "left" | "right";
|
||||
|
||||
|
@ -58,10 +61,10 @@ const RealTimeVisulization: React.FC = () => {
|
|||
const [zonesData, setZonesData] = useState<FormattedZoneData>({});
|
||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||
|
||||
|
||||
const { rightSelect, setRightSelect } = useRightSelected()
|
||||
const { editWidgetOptions, setEditWidgetOptions } = useEditWidgetOptionsStore()
|
||||
const { rightClickSelected, setRightClickSelected } = useRightClickSelected()
|
||||
const { rightSelect, setRightSelect } = useRightSelected();
|
||||
const { editWidgetOptions, setEditWidgetOptions } =
|
||||
useEditWidgetOptionsStore();
|
||||
const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
|
||||
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
|
||||
|
||||
const [floatingWidgets, setFloatingWidgets] = useState<Record<string, { zoneName: string; zoneId: string; objects: any[] }>>({});
|
||||
|
@ -96,7 +99,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||
{}
|
||||
);
|
||||
setZonesData(formattedData);
|
||||
} catch (error) { }
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
GetZoneData();
|
||||
|
@ -194,7 +197,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||
],
|
||||
},
|
||||
}));
|
||||
} catch (error) { }
|
||||
} catch (error) {}
|
||||
};
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
|
@ -238,6 +241,9 @@ const RealTimeVisulization: React.FC = () => {
|
|||
}, [setRightClickSelected]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
|
||||
<div
|
||||
ref={containerRef}
|
||||
id="real-time-vis-canvas"
|
||||
|
@ -248,6 +254,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||
left: isPlaying || activeModule !== "visualization" ? "0%" : "",
|
||||
}}
|
||||
>
|
||||
<div className="realTime-viz-wrapper">
|
||||
{openConfirmationPopup && (
|
||||
<RenderOverlay>
|
||||
<ConfirmationPopup
|
||||
|
@ -257,7 +264,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||
/>
|
||||
</RenderOverlay>
|
||||
)}
|
||||
<div
|
||||
{/* <div
|
||||
className="scene-container"
|
||||
style={{
|
||||
height: "100%",
|
||||
|
@ -269,7 +276,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||
onDragOver={(event) => event.preventDefault()}
|
||||
>
|
||||
<Scene />
|
||||
</div>
|
||||
</div> */}
|
||||
{activeModule === "visualization" && selectedZone.zoneName !== "" && (
|
||||
<DroppedObjects />
|
||||
)}
|
||||
|
@ -316,6 +323,8 @@ const RealTimeVisulization: React.FC = () => {
|
|||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ const Project: React.FC = () => {
|
|||
|
||||
return (
|
||||
<div className="project-main">
|
||||
{loadingProgress && <LoadingPage progress={loadingProgress} />}
|
||||
{/* {loadingProgress && <LoadingPage progress={loadingProgress} />} */}
|
||||
{!isPlaying && (
|
||||
<>
|
||||
{toggleThreeD && <ModuleToggle />}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
.tools-container {
|
||||
@include flex-center;
|
||||
position: fixed;
|
||||
bottom: 50px;
|
||||
bottom: 32px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
padding: 8px;
|
||||
|
|
|
@ -472,6 +472,15 @@
|
|||
font-size: var(--font-weight-regular);
|
||||
color: #4a4a4a;
|
||||
|
||||
.reviewChart {
|
||||
width: 100%;
|
||||
|
||||
.floating {
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.selectedWidget {
|
||||
padding: 6px 12px;
|
||||
border-top: 1px solid var(--border-color);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
border-radius: 20px;
|
||||
box-shadow: $box-shadow-medium;
|
||||
width: calc(100% - (320px + 270px + 90px));
|
||||
height: calc(100% - (200px + 80px));
|
||||
height: calc(100% - (250px));
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: calc(270px + 45px);
|
||||
|
@ -16,6 +16,13 @@
|
|||
transition: all 0.2s;
|
||||
z-index: #{$z-index-default};
|
||||
|
||||
.realTime-viz-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.floating {
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
|
@ -62,6 +69,7 @@
|
|||
max-width: 80%;
|
||||
overflow: auto;
|
||||
max-width: calc(100% - 500px);
|
||||
z-index: 3;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
|
@ -108,7 +116,7 @@
|
|||
}
|
||||
|
||||
.zone-wrapper.bottom {
|
||||
bottom: 210px;
|
||||
bottom: calc(var(--realTimeViz-container-height) * 0.27);
|
||||
}
|
||||
|
||||
.content-container {
|
||||
|
@ -173,12 +181,15 @@
|
|||
overflow: auto;
|
||||
z-index: $z-index-tools;
|
||||
overflow: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel-content {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -191,7 +202,6 @@
|
|||
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 25% !important;
|
||||
min-height: 150px;
|
||||
max-height: 100%;
|
||||
// border: 1px dashed var(--background-color-gray);
|
||||
|
@ -200,6 +210,7 @@
|
|||
padding: 6px 0;
|
||||
background-color: var(--background-color);
|
||||
position: relative;
|
||||
padding: 0 10px;
|
||||
|
||||
.kebab {
|
||||
width: 30px;
|
||||
|
@ -284,15 +295,17 @@
|
|||
&.bottom-panel {
|
||||
left: 0;
|
||||
right: 0;
|
||||
min-height: 150px;
|
||||
|
||||
.panel-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
min-height: 150px;
|
||||
|
||||
.chart-container {
|
||||
height: 100% !important;
|
||||
width: 20%;
|
||||
|
||||
min-width: 150px;
|
||||
}
|
||||
}
|
||||
|
@ -311,28 +324,53 @@
|
|||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 180px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.right-panel {
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
bottom: 0
|
||||
}
|
||||
|
||||
&.left-panel,
|
||||
&.right-panel {
|
||||
min-width: 150px;
|
||||
|
||||
.panel-content {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
|
||||
|
||||
gap: 6px;
|
||||
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
|
||||
|
||||
min-height: 150px;
|
||||
max-height: 100%;
|
||||
// border: 1px dashed var(--background-color-gray);
|
||||
border-radius: 8px;
|
||||
box-shadow: var(--box-shadow-medium);
|
||||
padding: 6px 0;
|
||||
background-color: var(--background-color);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.panel.hidePanel {
|
||||
opacity: 0;
|
||||
opacity: 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
.playingFlase {
|
||||
.zone-wrapper.bottom {
|
||||
bottom: 300px;
|
||||
bottom: calc(var(--realTimeViz-container-height) * 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -739,7 +777,8 @@
|
|||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
|
||||
min-width: 150px;
|
||||
min-width: 150px;
|
||||
|
||||
.option {
|
||||
padding: 8px 10px;
|
||||
color: var(--text-color);
|
||||
|
|
Loading…
Reference in New Issue