+
diff --git a/app/src/components/SimulationDashboard/components/element/ElementEditor.tsx b/app/src/components/SimulationDashboard/components/element/ElementEditor.tsx
index 28991e3..1492cd8 100644
--- a/app/src/components/SimulationDashboard/components/element/ElementEditor.tsx
+++ b/app/src/components/SimulationDashboard/components/element/ElementEditor.tsx
@@ -9,6 +9,7 @@ import { AddIcon, DeviceIcon, ParametersIcon, ResizeHeightIcon } from "../../../
import DataDetailedDropdown from "../../../ui/inputs/DataDetailedDropdown";
import { useSceneContext } from "../../../../modules/scene/sceneContext";
import ElementDesign from "./ElementDesign";
+import { useVisualizationStore } from "../../../../store/visualization/useVisualizationStore";
interface ElementEditorProps {
elementEditorRef: RefObject
;
@@ -64,27 +65,30 @@ const ElementEditor: React.FC = ({
const [selectType, setSelectType] = useState("design");
const [selectDataMapping, setSelectDataMapping] = useState(element?.type === "graph" && element.dataBinding?.dataType === "multiple-machine" ? "multipleMachine" : "singleMachine");
- // Dragging state for the panel
+ // Use shared position from VisualizationStore
+ const { editorPosition, setEditorPosition } = useVisualizationStore();
const panelRef = useRef(null);
- const [position, setPosition] = useState<{ x: number; y: number }>(() => {
- if (typeof window !== "undefined") {
- // approximate initial left using a default panel width of 300
- return { x: Math.max(0, window.innerWidth - 300 - 40), y: 80 };
- }
- return { x: 100, y: 80 };
- });
const initialPositionRef = useRef<{ x: number; y: number } | null>(null);
+ // Compute position from store or initialize
+ const position = editorPosition || { x: 100, y: 80 };
+ const setPosition = (newPosition: { x: number; y: number }) => {
+ setEditorPosition(newPosition);
+ };
+
// On mount, compute exact initial position based on panel width and store it
useEffect(() => {
- const panelEl = panelRef.current || (elementEditorRef && (elementEditorRef as any).current);
- const width = panelEl?.offsetWidth || 300;
- const nx = Math.max(0, window.innerWidth - width - 40);
- const ny = 80;
- initialPositionRef.current = { x: nx, y: ny };
- setPosition({ x: nx, y: ny });
+ if (!editorPosition) {
+ const panelEl = panelRef.current || (elementEditorRef && (elementEditorRef as any).current);
+ const width = panelEl?.offsetWidth || 300;
+ const nx = Math.max(0, window.innerWidth - width - 40);
+ const ny = 80;
+ initialPositionRef.current = { x: nx, y: ny };
+ setPosition({ x: nx, y: ny });
+ }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
+
const draggingRef = useRef(false);
const startXRef = useRef(0);
const startYRef = useRef(0);
@@ -157,7 +161,7 @@ const ElementEditor: React.FC = ({
window.removeEventListener("pointerup", onPointerUp);
try {
(panel as Element).releasePointerCapture?.((e as any).pointerId);
- } catch (err) { }
+ } catch (err) {}
};
window.addEventListener("pointermove", onPointerMove);
diff --git a/app/src/modules/simulation/analyzer/analyzer.tsx b/app/src/modules/simulation/analyzer/analyzer.tsx
index f9d6334..b5c6544 100644
--- a/app/src/modules/simulation/analyzer/analyzer.tsx
+++ b/app/src/modules/simulation/analyzer/analyzer.tsx
@@ -1376,17 +1376,18 @@ function Analyzer() {
// Occupancy trends
const timestamp = new Date().toISOString();
- if (!historicalDataRef.current[storage.modelUuid]) {
- historicalDataRef.current[storage.modelUuid] = [];
- }
- historicalDataRef.current[storage.modelUuid].push({
- timestamp,
- currentLoad,
- utilizationRate,
- operation: storeOps > retrieveOps ? "store" : "retrieve",
- totalOps,
- state: storage.state,
- });
+ const currentData = historicalDataRef.current[storage.modelUuid] || [];
+ historicalDataRef.current[storage.modelUuid] = [
+ ...currentData,
+ {
+ timestamp,
+ currentLoad,
+ utilizationRate,
+ operation: storeOps > retrieveOps ? "store" : "retrieve",
+ totalOps,
+ state: storage.state,
+ },
+ ].slice(-100);
// Calculate peak occupancy from historical data
const occupancyData = historicalDataRef.current[storage.modelUuid] || [];
diff --git a/app/src/store/visualization/useVisualizationStore.ts b/app/src/store/visualization/useVisualizationStore.ts
index 4b18f49..0ccdc85 100644
--- a/app/src/store/visualization/useVisualizationStore.ts
+++ b/app/src/store/visualization/useVisualizationStore.ts
@@ -1,13 +1,22 @@
import { create } from "zustand";
import { immer } from "zustand/middleware/immer";
+interface PanelPosition {
+ x: number;
+ y: number;
+}
+
interface VisualizationState {
- // blocks: Block[]
+ editorPosition: PanelPosition | null;
+ setEditorPosition: (position: PanelPosition) => void;
}
export const useVisualizationStore = create()(
immer((set) => ({
- // blocks: [],
-
+ editorPosition: null,
+ setEditorPosition: (position) =>
+ set((state) => {
+ state.editorPosition = position;
+ }),
}))
);
diff --git a/app/src/styles/components/simulationDashboard/_simulationDashBoard.scss b/app/src/styles/components/simulationDashboard/_simulationDashBoard.scss
index af2a618..1f171fd 100644
--- a/app/src/styles/components/simulationDashboard/_simulationDashBoard.scss
+++ b/app/src/styles/components/simulationDashboard/_simulationDashBoard.scss
@@ -12,7 +12,7 @@
left: 0;
pointer-events: none;
- *> {
+ * > {
pointer-events: auto;
}
@@ -256,8 +256,12 @@
width: 100%;
display: flex;
justify-content: space-between;
+ width: fit-content !important;
+ pointer-events: none;
+ }
- pointer-events: auto;
+ .block-grid-container.editable {
+ pointer-events: all;
}
.panel {
@@ -272,7 +276,6 @@
box-shadow: 0px 4px 8px rgba(60, 60, 67, 0.1019607843);
z-index: 3;
-
display: flex;
flex-direction: column;
gap: 11px;
@@ -321,7 +324,6 @@
}
.design-section {
-
padding: 4px;
outline: 1px solid var(--border-color);
outline-offset: -1px;
@@ -356,7 +358,7 @@
}
.position-canvas {
- background: #8D70AD33;
+ background: #8d70ad33;
height: 110px;
border-radius: 17px;
@@ -369,7 +371,7 @@
.canvas {
width: 60%;
height: 27px;
- background: #E0DFFF80;
+ background: #e0dfff80;
// position: relative;
.value {
@@ -420,7 +422,6 @@
display: flex;
gap: 10px;
width: fit-content;
-
}
.icon {
@@ -511,11 +512,9 @@
.datas__label,
.datas__class {
flex: 1;
-
}
}
-
.type-switch {
display: flex;
padding: 6px 12px;
@@ -548,22 +547,16 @@
}
}
-
&.block-editor-panel {
// h4 {
// color: #4caf50;
// }
-
-
.design-section-wrapper {
display: flex;
flex-direction: column;
gap: 6px;
-
-
}
-
}
.data-details {
@@ -620,7 +613,8 @@
text-align: center;
}
- .type-switch {}
+ .type-switch {
+ }
.fields-wrapper {
display: flex;
@@ -653,7 +647,6 @@
border-radius: 2px;
&.active {
-
background: var(--background-color-button);
}
}
@@ -673,11 +666,11 @@
cursor: pointer;
svg path {
- stroke: #CCACFF !important;
+ stroke: #ccacff !important;
}
.label {
- color: #CCACFF;
+ color: #ccacff;
}
}
}
@@ -698,7 +691,6 @@
right: 40px;
.appearance {
.design-datas-wrapper {
-
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px 16px;
@@ -708,14 +700,13 @@
width: 80%;
text-wrap: nowrap;
}
-
}
}
}
.footer {
text-align: center;
- color: #CCACFF;
+ color: #ccacff;
}
}
}
@@ -926,12 +917,6 @@
}
}
-
-
-
-
-
-
// DataDetailedDropdown
.data-detailed-dropdown {
display: flex;
@@ -973,7 +958,6 @@
}
.input-wrapper {
-
outline: 1px solid var(--input-border-color);
outline-offset: -1px;
border: none;
@@ -1011,7 +995,6 @@
gap: 8px;
.search {
-
outline: 1px solid var(--border-color);
outline-offset: -1px;
border-radius: 12px;
@@ -1063,11 +1046,11 @@
&.active {
span {
- color: #CCACFF;
+ color: #ccacff;
}
}
}
}
}
}
-}
\ No newline at end of file
+}