Refactor simulation dashboard styles and types
- Updated SCSS styles for the simulation dashboard, adjusting z-index and reintroducing the element dropdown styles. - Simplified type definitions in simulationDashboard.d.ts by removing unnecessary exports and consolidating types. - Modified shortcut key handling to import from the correct path for useSelectedZoneStore. - Created a new Zustand store for managing simulation dashboard state, including blocks and elements. - Introduced old visualization stores for chart and dropped objects, refactoring to use Zustand for state management. - Added a new store for managing 3D widget data and zone widget data. - Implemented a store for managing selected zones and their properties. - Initialized a visualization store with a basic structure for future enhancements. - Updated exported types to include ExtendedCSSProperties and refined Block and UIElement definitions.
This commit is contained in:
439
app/src/store/simulation/useSimulationDashBoardStore.ts
Normal file
439
app/src/store/simulation/useSimulationDashBoardStore.ts
Normal file
@@ -0,0 +1,439 @@
|
||||
import { MathUtils } from "three";
|
||||
import { create } from "zustand";
|
||||
import { immer } from "zustand/middleware/immer";
|
||||
import { defaultGraphData } from "../../SimulationDashboard/data/defaultGraphData";
|
||||
import { Block, UIElement, ExtendedCSSProperties } from "../../types/exportedTypes";
|
||||
|
||||
interface SimulationDashboardStore {
|
||||
blocks: Block[];
|
||||
selectedBlockId: string | null;
|
||||
selectedElementId: string | null;
|
||||
hoveredBlockId: string | null;
|
||||
hoveredElementId: string | null;
|
||||
|
||||
// Block operations
|
||||
addBlock: () => void;
|
||||
removeBlock: (blockId: string) => void;
|
||||
updateBlock: (blockId: string, updates: Partial<Block>) => void;
|
||||
clearBlocks: () => void;
|
||||
setBlocks: (blocks: Block[]) => void;
|
||||
|
||||
// Block styling and positioning
|
||||
updateBlockStyle: (blockId: string, newStyle: React.CSSProperties) => void;
|
||||
updateBlockSize: (blockId: string, size: Size) => void;
|
||||
updateBlockPosition: (blockId: string, position: Position) => void;
|
||||
updateBlockPositionType: (blockId: string, positionType: "relative" | "absolute" | "fixed") => void;
|
||||
updateBlockZIndex: (blockId: string, zIndex: number) => void;
|
||||
|
||||
// Element operations
|
||||
addElement: (blockId: string, type: UIType, graphType?: GraphTypes) => void;
|
||||
removeElement: (blockId: string, elementId: string) => void;
|
||||
updateElement: (blockId: string, elementId: string, updates: Partial<UIElement>) => void;
|
||||
|
||||
// Element styling and positioning
|
||||
updateElementStyle: (blockId: string, elementId: string, newStyle: ExtendedCSSProperties) => void;
|
||||
updateElementSize: (blockId: string, elementId: string, size: Size) => void;
|
||||
updateElementPosition: (blockId: string, elementId: string, position: Position) => void;
|
||||
updateElementPositionType: (blockId: string, elementId: string, positionType: "relative" | "absolute" | "fixed") => void;
|
||||
updateElementZIndex: (blockId: string, elementId: string, zIndex: number) => void;
|
||||
|
||||
// Element data operations
|
||||
updateElementData: (blockId: string, elementId: string, updates: Partial<DataBinding>) => void;
|
||||
updateGraphData: (blockId: string, elementId: string, newData: GraphDataPoint[]) => void;
|
||||
updateGraphTitle: (blockId: string, elementId: string, title: string) => void;
|
||||
|
||||
// Selection and hover management
|
||||
setSelectedBlock: (blockId: string | null) => void;
|
||||
setSelectedElement: (elementId: string | null) => void;
|
||||
setHoveredBlock: (blockId: string | null) => void;
|
||||
setHoveredElement: (elementId: string | null) => void;
|
||||
|
||||
// Element swapping
|
||||
swapElements: (blockId: string, elementId1: string, elementId2: string) => void;
|
||||
|
||||
// Helper functions
|
||||
getBlockById: (blockId: string) => Block | undefined;
|
||||
getElementById: (blockId: string, elementId: string) => UIElement | undefined;
|
||||
getSelectedBlock: () => Block | undefined;
|
||||
getSelectedElement: () => UIElement | undefined;
|
||||
hasBlock: (blockId: string) => boolean;
|
||||
hasElement: (blockId: string, elementId: string) => boolean;
|
||||
}
|
||||
|
||||
export const createSimulationDashboardStore = () => {
|
||||
return create<SimulationDashboardStore>()(
|
||||
immer((set, get) => ({
|
||||
blocks: [],
|
||||
selectedBlockId: null,
|
||||
selectedElementId: null,
|
||||
hoveredBlockId: null,
|
||||
hoveredElementId: null,
|
||||
|
||||
// Block operations
|
||||
addBlock: () => {
|
||||
set((state) => {
|
||||
const newBlock: Block = {
|
||||
id: MathUtils.generateUUID(),
|
||||
style: {
|
||||
backgroundColor: "rgba(50, 50, 50, 0.8)",
|
||||
backdropFilter: "blur(10px)",
|
||||
padding: 10,
|
||||
borderRadius: 8,
|
||||
border: "1px solid rgba(255, 255, 255, 0.1)",
|
||||
position: "relative",
|
||||
minHeight: "200px",
|
||||
minWidth: "300px",
|
||||
},
|
||||
elements: [],
|
||||
zIndex: 1,
|
||||
size: { width: 400, height: 300 },
|
||||
position: { x: 0, y: 0 },
|
||||
positionType: "relative",
|
||||
};
|
||||
state.blocks.push(newBlock);
|
||||
});
|
||||
},
|
||||
|
||||
removeBlock: (blockId) => {
|
||||
set((state) => {
|
||||
state.blocks = state.blocks.filter((block) => block.id !== blockId);
|
||||
if (state.selectedBlockId === blockId) {
|
||||
state.selectedBlockId = null;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateBlock: (blockId, updates) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
Object.assign(block, updates);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
clearBlocks: () => {
|
||||
set((state) => {
|
||||
state.blocks = [];
|
||||
state.selectedBlockId = null;
|
||||
state.selectedElementId = null;
|
||||
});
|
||||
},
|
||||
|
||||
setBlocks: (blocks) => {
|
||||
set((state) => {
|
||||
state.blocks = blocks;
|
||||
});
|
||||
},
|
||||
|
||||
// Block styling and positioning
|
||||
updateBlockStyle: (blockId, newStyle) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
block.style = { ...block.style, ...newStyle };
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateBlockSize: (blockId, size) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
block.size = size;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateBlockPosition: (blockId, position) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
block.position = position;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateBlockPositionType: (blockId, positionType) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
block.positionType = positionType;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateBlockZIndex: (blockId, zIndex) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
block.zIndex = zIndex;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Element operations
|
||||
addElement: (blockId, type, graphType) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
const newElement: UIElement = {
|
||||
id: MathUtils.generateUUID(),
|
||||
type: type,
|
||||
graphType,
|
||||
graphTitle: graphType ? `${graphType.charAt(0).toUpperCase() + graphType.slice(1)} Chart` : undefined,
|
||||
style:
|
||||
type === "graph"
|
||||
? {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
minHeight: "120px",
|
||||
color: "#fff",
|
||||
fontSize: 14,
|
||||
textAlign: "left" as const,
|
||||
backgroundColor: "rgba(0, 0, 0, 0.2)",
|
||||
borderRadius: "4px",
|
||||
padding: "8px",
|
||||
}
|
||||
: type === "label-value"
|
||||
? {
|
||||
color: "#fff",
|
||||
fontSize: 14,
|
||||
textAlign: "left" as const,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "4px",
|
||||
alignItems: "flex-start",
|
||||
justifyContent: "center",
|
||||
labelColor: "#ffffff",
|
||||
valueColor: "#ffffff",
|
||||
}
|
||||
: {
|
||||
color: "#fff",
|
||||
fontSize: 14,
|
||||
textAlign: "left" as const,
|
||||
},
|
||||
positionType: "relative",
|
||||
position: { x: 0, y: 0 },
|
||||
zIndex: 1,
|
||||
data: {
|
||||
key: MathUtils.generateUUID(),
|
||||
dataSource: "static",
|
||||
staticValue: type === "label-value" ? "Value" : type === "text" ? "Text" : "",
|
||||
label: type === "label-value" ? "Label" : undefined,
|
||||
},
|
||||
graphData: type === "graph" ? defaultGraphData : undefined,
|
||||
size: type === "graph" ? { width: 400, height: 200 } : { width: 200, height: 60 },
|
||||
};
|
||||
block.elements.push(newElement);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
removeElement: (blockId, elementId) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
block.elements = block.elements.filter((el) => el.id !== elementId);
|
||||
if (state.selectedElementId === elementId) {
|
||||
state.selectedElementId = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateElement: (blockId, elementId, updates) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
const element = block.elements.find((el) => el.id === elementId);
|
||||
if (element) {
|
||||
Object.assign(element, updates);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Element styling and positioning
|
||||
updateElementStyle: (blockId, elementId, newStyle) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
const element = block.elements.find((el) => el.id === elementId);
|
||||
if (element) {
|
||||
element.style = { ...element.style, ...newStyle };
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateElementSize: (blockId, elementId, size) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
const element = block.elements.find((el) => el.id === elementId);
|
||||
if (element) {
|
||||
element.size = size;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateElementPosition: (blockId, elementId, position) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
const element = block.elements.find((el) => el.id === elementId);
|
||||
if (element) {
|
||||
element.position = position;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateElementPositionType: (blockId, elementId, positionType) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
const element = block.elements.find((el) => el.id === elementId);
|
||||
if (element) {
|
||||
element.positionType = positionType;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateElementZIndex: (blockId, elementId, zIndex) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
const element = block.elements.find((el) => el.id === elementId);
|
||||
if (element) {
|
||||
element.zIndex = zIndex;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Element data operations
|
||||
updateElementData: (blockId, elementId, updates) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
const element = block.elements.find((el) => el.id === elementId);
|
||||
if (element?.data) {
|
||||
element.data = { ...element.data, ...updates };
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateGraphData: (blockId, elementId, newData) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
const element = block.elements.find((el) => el.id === elementId);
|
||||
if (element) {
|
||||
element.graphData = newData;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateGraphTitle: (blockId, elementId, title) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
const element = block.elements.find((el) => el.id === elementId);
|
||||
if (element) {
|
||||
element.graphTitle = title;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Selection and hover management
|
||||
setSelectedBlock: (blockId) => {
|
||||
set((state) => {
|
||||
state.selectedBlockId = blockId;
|
||||
// Clear element selection when selecting a block
|
||||
if (blockId) {
|
||||
state.selectedElementId = null;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setSelectedElement: (elementId) => {
|
||||
set((state) => {
|
||||
state.selectedElementId = elementId;
|
||||
});
|
||||
},
|
||||
|
||||
setHoveredBlock: (blockId) => {
|
||||
set((state) => {
|
||||
state.hoveredBlockId = blockId;
|
||||
});
|
||||
},
|
||||
|
||||
setHoveredElement: (elementId) => {
|
||||
set((state) => {
|
||||
state.hoveredElementId = elementId;
|
||||
});
|
||||
},
|
||||
|
||||
// Element swapping
|
||||
swapElements: (blockId, elementId1, elementId2) => {
|
||||
set((state) => {
|
||||
const block = state.blocks.find((b) => b.id === blockId);
|
||||
if (block) {
|
||||
block.elements = block.elements.map((el) => {
|
||||
if (el.id === elementId1) {
|
||||
const targetElement = block.elements.find((e) => e.id === elementId2);
|
||||
return targetElement ? { ...targetElement, id: elementId1 } : el;
|
||||
}
|
||||
if (el.id === elementId2) {
|
||||
const sourceElement = block.elements.find((e) => e.id === elementId1);
|
||||
return sourceElement ? { ...sourceElement, id: elementId2 } : el;
|
||||
}
|
||||
return el;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Helper functions
|
||||
getBlockById: (blockId) => {
|
||||
return get().blocks.find((b) => b.id === blockId);
|
||||
},
|
||||
|
||||
getElementById: (blockId, elementId) => {
|
||||
const block = get().blocks.find((b) => b.id === blockId);
|
||||
return block?.elements.find((el) => el.id === elementId);
|
||||
},
|
||||
|
||||
getSelectedBlock: () => {
|
||||
const { selectedBlockId, blocks } = get();
|
||||
return selectedBlockId ? blocks.find((b) => b.id === selectedBlockId) : undefined;
|
||||
},
|
||||
|
||||
getSelectedElement: () => {
|
||||
const { selectedElementId, selectedBlockId, blocks } = get();
|
||||
if (!selectedElementId || !selectedBlockId) return undefined;
|
||||
|
||||
const block = blocks.find((b) => b.id === selectedBlockId);
|
||||
return block?.elements.find((el) => el.id === selectedElementId);
|
||||
},
|
||||
|
||||
hasBlock: (blockId) => {
|
||||
return get().blocks.some((b) => b.id === blockId);
|
||||
},
|
||||
|
||||
hasElement: (blockId, elementId) => {
|
||||
const block = get().blocks.find((b) => b.id === blockId);
|
||||
return block?.elements.some((el) => el.id === elementId) || false;
|
||||
},
|
||||
}))
|
||||
);
|
||||
};
|
||||
|
||||
export type SimulationDashboardStoreType = ReturnType<typeof createSimulationDashboardStore>;
|
||||
Reference in New Issue
Block a user