From a9df8d98bb9418aa8b0af8266ec8a01f8fc6191f Mon Sep 17 00:00:00 2001 From: Nalvazhuthi Date: Tue, 16 Dec 2025 18:01:17 +0530 Subject: [PATCH] Add new alignment icons and enhance dropdown components - Introduced new alignment icons: AlignRightIcon, AlignJustifyIcon, AlignLeftIcon, FlexRowIcon, FlexColumnIcon, FlexRowReverseIcon, and FlexColumnReverseIcon. - Updated MainScene to ensure loading progress is displayed correctly. - Enhanced DataDetailedDropdown to include click outside functionality for closing the dropdown and improved eye dropper icon interaction. - Created a new DataSourceSelector component for selecting data sources with an optional eye dropper feature. - Cleaned up InputWithDropDown component by removing unnecessary whitespace. - Improved styles in _simulationDashBoard.scss for better layout and responsiveness, including new design sections and alignment options. --- .../components/block/BlockEditor.tsx | 548 +++------ .../components/element/ElementEditor.tsx | 1050 +++++++++-------- .../components/icons/ExportCommonIcons.tsx | 89 ++ .../components/layout/scenes/MainScene.tsx | 4 +- .../ui/inputs/DataDetailedDropdown.tsx | 44 +- .../ui/inputs/DataSourceSelector.tsx | 55 + .../ui/inputs/InputWithDropDown.tsx | 4 + .../_simulationDashBoard.scss | 454 +++++-- 8 files changed, 1252 insertions(+), 996 deletions(-) create mode 100644 app/src/components/ui/inputs/DataSourceSelector.tsx diff --git a/app/src/components/SimulationDashboard/components/block/BlockEditor.tsx b/app/src/components/SimulationDashboard/components/block/BlockEditor.tsx index 40269a0..33e11b5 100644 --- a/app/src/components/SimulationDashboard/components/block/BlockEditor.tsx +++ b/app/src/components/SimulationDashboard/components/block/BlockEditor.tsx @@ -9,8 +9,10 @@ import InputRange from "../../../ui/inputs/InputRange"; import RegularDropDown from "../../../ui/inputs/RegularDropDown"; import { DeleteIcon } from "../../../icons/ContextMenuIcons"; import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; -import { AddIcon, DeviceIcon, EyeDroperIcon, ParametersIcon } from "../../../icons/ExportCommonIcons"; +import { AddIcon, DeviceIcon, ParametersIcon } from "../../../icons/ExportCommonIcons"; import DataDetailedDropdown from "../../../ui/inputs/DataDetailedDropdown"; +import RenameInput from "../../../ui/inputs/RenameInput"; +import DataSourceSelector from "../../../ui/inputs/DataSourceSelector"; interface BlockEditorProps { blockEditorRef: RefObject; @@ -34,439 +36,169 @@ const BlockEditor: React.FC = ({ updateBlockZIndex, }) => { - const [selectType, setSelectType] = useState("data") - const [selectDataMapping, setSelectDataMapping] = useState("singleMachine") + const [color, setColor] = useState("#000000"); + return (

Block Style

- {/*
+
-
*/} -
- -
-
setSelectType("design")}> - Design -
-
setSelectType("data")}> - Data
- {selectType === "design" && ( - <> -
- - +
+
+
Size
+ { + updateBlockSize(selectedBlock, { + ...currentBlock.size!, + width: Number(newValue), // Make sure to convert the string back to a number here + }) + }} + /> + { + updateBlockSize(selectedBlock, { + ...currentBlock.size!, + height: Number(newValue), + }) + }} + /> +
- {/* updateBlockPositionType( - selectedBlock, - option.toLowerCase() as "relative" | "absolute" | "fixed" - )} - search={false} - /> */} -
- - {currentBlock.positionType === "absolute" && ( - <> -
- - - updateBlockPosition(selectedBlock, { - ...currentBlock.position!, - x: Number(e.target.value), - }) - } - className="form-input" - /> +
+
Position
+
+ {["relative", "absolute"].map((position) => ( +
updateBlockPositionType(selectedBlock, position as "relative" | "absolute" | "fixed")} + > + {position.charAt(0).toUpperCase() + position.slice(1)}
-
- - - updateBlockPosition(selectedBlock, { - ...currentBlock.position!, - y: Number(e.target.value), - }) + ))} +
+
+
+
+ +
- - )} +
+ -
- - handleBackgroundColorChange(currentBlock, selectedBlock, updateBlockStyle, e.target.value)} - className="color-input" - /> +
+
+ + +
+
+ + +
+
-
- {/* - - handleBackgroundAlphaChange( - currentBlock, - selectedBlock, - updateBlockStyle, - Number(e.target.value) - ) - } - className="range-input" - /> */} - handleBackgroundAlphaChange(currentBlock, selectedBlock, updateBlockStyle, Number(value))} - // onPointerUp={updatedDist} - key={"6"} - /> -
- -
- {/* - - handleBlurAmountChange( - selectedBlock, - updateBlockStyle, - Number(e.target.value) - ) - } - className="range-input" - /> */} - - handleBlurAmountChange(selectedBlock, updateBlockStyle, Number(value))} - // onPointerUp={updatedDist} - key={"6"} - /> -
- -
- - - updateBlockSize(selectedBlock, { - ...currentBlock.size!, - width: Number(e.target.value), - }) - } - className="form-input" - /> -
- -
- - - updateBlockSize(selectedBlock, { - ...currentBlock.size!, - height: Number(e.target.value), - }) - } - className="form-input" - /> -
- -
- - updateBlockZIndex(selectedBlock, Number(e.target.value))} className="form-input" /> -
- -
- - updateBlockStyle(selectedBlock, { padding: Number(e.target.value) })} - className="form-input" - /> -
- -
- - - updateBlockStyle(selectedBlock, { - borderRadius: Number(e.target.value), - }) - } - className="form-input" - /> -
- - - )} - - - - {selectType === "data" && ( -
- -
+
{ }} + label="Layer" + value={String(currentBlock.zIndex || 1)} + placeholder={"Layer"} + onChange={(newValue) => updateBlockZIndex(selectedBlock, Number(newValue))} /> -
- }, - ], - }, - { - title: "Assets", - items: [ - { id: "cmm-001", label: "CMM-001", icon: }, - { id: "cnc-1", label: "CNC-Lathe-0001", icon: }, - { id: "cnc-2", label: "CNC-drilling-tapping-3Axis", icon: }, - { id: "cnc-3", label: "CNC_0001", icon: }, - ], - }, - ]} - value={null} - onChange={() => { }} - dropDownHeader={"RT-Data"} - eyedroper={true} - /> -
- -
- }, - { id: "measurementDeviation", label: "measurementDeviation", icon: }, - { id: "powerConsumption", label: "powerConsumption", icon: }, - { id: "probeX", label: "probePositionX", icon: }, - { id: "probeY", label: "probePositionY", icon: }, - { id: "probeZ", label: "probePositionZ", icon: }, - ], - }, - ]} - value={null} - onChange={() => { }} - dropDownHeader={"RT-Data-Value"} - - /> - -
- -
- - {/* Data Mapping */} -
-
Data Mapping
- -
-
setSelectDataMapping("singleMachine")} - > - Single Machine -
-
setSelectDataMapping("multipleeMachine")} - > - Multiple Machine -
-
- - {selectDataMapping === "singleMachine" && ( -
-
-
Data Source
-
- { }} - search={false} - /> -
-
-
-
-
Input 1
-
- { }} - search={false} - /> -
-
-
-
Input 2
-
- { }} - search={false} - /> -
-
- -
-
-
Add Field
-
- -
- )} - - {selectDataMapping === "multipleeMachine" && ( -
-
-
Common Value
-
- { }} - search={false} - /> -
-
-
-
Data Source
-
- { }} - search={false} - /> -
- -
-
-
-
Data Source
-
- { }} - search={false} - /> -
- -
-
- - -
-
-
Add Field
-
- -
- )} + { + updateBlockStyle(selectedBlock, { + borderRadius: Number(newValue), + }) + }} + />
- )} + +
+
Background
+
+
Color
+
+ setColor(e.target.value)} + onChange={(e) => handleBackgroundColorChange(currentBlock, selectedBlock, updateBlockStyle, e.target.value)} + + /> + +
{color}
+
+
+ handleBackgroundAlphaChange(currentBlock, selectedBlock, updateBlockStyle, Number(value))} + onChange={(value: number) => handleBlurAmountChange(selectedBlock, updateBlockStyle, Number(value))} + + /> + + +
+
+ + + + +
); }; diff --git a/app/src/components/SimulationDashboard/components/element/ElementEditor.tsx b/app/src/components/SimulationDashboard/components/element/ElementEditor.tsx index 2800288..ed92b8a 100644 --- a/app/src/components/SimulationDashboard/components/element/ElementEditor.tsx +++ b/app/src/components/SimulationDashboard/components/element/ElementEditor.tsx @@ -1,8 +1,15 @@ -import type { RefObject } from "react"; +import { useState, type RefObject } from "react"; import { ExtendedCSSProperties, UIElement } from "../../../../types/exportedTypes"; import { getCurrentElementStyleValue } from "../../functions/helpers/getCurrentElementStyleValue"; import type { DataModelManager } from "../../data/dataModel"; import { DeleteIcon } from "../../../icons/ContextMenuIcons"; +import DataSourceSelector from "../../../ui/inputs/DataSourceSelector"; +import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; +import InputRange from "../../../ui/inputs/InputRange"; +import RenameInput from "../../../ui/inputs/RenameInput"; +import { AddIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, DeviceIcon, FlexColumnIcon, FlexRowIcon, FlexRowReverseIcon, ParametersIcon } from "../../../icons/ExportCommonIcons"; +import { getAlphaFromRgba, rgbaToHex, hexToRgba } from "../../functions/helpers/colorHandlers"; +import DataDetailedDropdown from "../../../ui/inputs/DataDetailedDropdown"; interface ElementEditorProps { elementEditorRef: RefObject; @@ -41,6 +48,9 @@ const ElementEditor: React.FC = ({ setShowSwapUI, dataModelManager, }) => { + const [selectType, setSelectType] = useState("design") + const [selectDataMapping, setSelectDataMapping] = useState("singleMachine") + const defaultGraphData = [ { name: "Jan", value: 400 }, { name: "Feb", value: 300 }, @@ -50,6 +60,40 @@ const ElementEditor: React.FC = ({ { name: "Jun", value: 900 }, ]; + const [singleFields, setSingleFields] = useState>([ + { id: "data-source", label: "Data Source", showEyeDropper: true }, + { id: "input-1", label: "Input 1", showEyeDropper: false }, + { id: "input-2", label: "Input 2", showEyeDropper: false }, + ]); + + const [multipleFields, setMultipleFields] = useState>([ + { id: "common-value", label: "Common Value" }, + { id: "data-source-1", label: "Data Source" }, + { id: "data-source-2", label: "Data Source" }, + ]); + + const addField = () => { + if (selectDataMapping === "singleMachine") { + setSingleFields((prev) => [ + ...prev, + { + id: `input-${Date.now()}`, + label: `Input ${prev.filter((f) => f.label.startsWith("Input")).length + 1}`, + showEyeDropper: false, + }, + ]); + return; + } + + setMultipleFields((prev) => [ + ...prev, + { + id: `data-${Date.now()}`, + label: "Data Source", + }, + ]); + }; + return (
@@ -57,496 +101,542 @@ const ElementEditor: React.FC = ({

Element Style

- {currentElement.type === "label-value" && ( - <> -
- - - updateElementStyle(selectedBlock, selectedElement, { - labelColor: e.target.value, - }) - } - className="color-input" - /> -
-
- - - updateElementStyle(selectedBlock, selectedElement, { - valueColor: e.target.value, - }) - } - className="color-input" - /> -
-
- - -
- -
- - -
- -
- - -
- -
- - - updateElementStyle(selectedBlock, selectedElement, { - gap: `${e.target.value}px`, - }) - } - className="form-input" - /> -
- - )} - - {currentElement.type !== "label-value" && ( -
- - - updateElementStyle(selectedBlock, selectedElement, { - color: e.target.value, - }) - } - className="color-input" - /> +
+
setSelectType("design")}> + Design +
+
setSelectType("data")}> + Data
- )} - -
- -
-
- - - updateElementStyle(selectedBlock, selectedElement, { - fontSize: Number(e.target.value), - }) - } - className="form-input" - /> -
-
- - - updateElementSize(selectedBlock, selectedElement, { - ...currentElement.size!, - width: Number(e.target.value), - }) - } - className="form-input" - /> -
- -
- - - updateElementSize(selectedBlock, selectedElement, { - ...currentElement.size!, - height: Number(e.target.value), - }) - } - className="form-input" - /> -
- -
- - - updateElementStyle(selectedBlock, selectedElement, { - padding: Number(e.target.value), - }) - } - className="form-input" - /> -
- -
- - -
- - {currentElement.positionType === "absolute" && ( + {selectType === "design" && ( <> -
- - - updateElementPosition(selectedBlock, selectedElement, { - ...currentElement.position!, - x: Number(e.target.value), - }) - } - className="form-input" - /> -
-
- - - updateElementPosition(selectedBlock, selectedElement, { - ...currentElement.position!, - y: Number(e.target.value), - }) - } - className="form-input" - /> -
- - )} - - {currentElement.positionType === "fixed" && ( - <> -
- - - updateElementPosition(selectedBlock, selectedElement, { - ...currentElement.position!, - x: Number(e.target.value), - }) - } - className="form-input" - /> -
-
- - - updateElementPosition(selectedBlock, selectedElement, { - ...currentElement.position!, - y: Number(e.target.value), - }) - } - className="form-input" - /> -
- - )} - -
- - updateElementZIndex(selectedBlock, selectedElement, Number(e.target.value))} - className="form-input" - /> -
- - {currentElement.type === "graph" && ( - <> -
- - -
- -
- - updateGraphTitle(selectedBlock, selectedElement, e.target.value)} - className="form-input" - /> -
- - )} - -
- -
- - {/* Data Binding Section */} -
-

Data Binding

-
- -
- - -
- - {currentElement.data?.dataSource === "static" && ( - <> - {currentElement.type === "label-value" && ( -
- - - updateElementData(selectedBlock, selectedElement, { - label: e.target.value, - }) - } - className="form-input" - /> -
- )} -
- - - updateElementData(selectedBlock, selectedElement, { - staticValue: e.target.value, - }) - } - className="form-input" - /> -
- - )} - - {currentElement.data?.dataSource === "dynamic" && ( - <> - {currentElement.type === "label-value" && ( -
- - - updateElementData(selectedBlock, selectedElement, { - label: e.target.value, - }) - } - className="form-input" - /> -
- )} -
- - -
- - )} - - {currentElement.data?.dataSource === "formula" && ( - <> - {currentElement.type === "label-value" && ( -
- - - updateElementData(selectedBlock, selectedElement, { - label: e.target.value, - }) - } - className="form-input" - /> -
- )} -
- - - updateElementData(selectedBlock, selectedElement, { - formula: e.target.value, - }) - } - className="form-input" - /> - - Use {"{key}"} to reference data values. Example: {"{totalUsers} * {growthRate}"} - -
- - )} - - {currentElement.type === "graph" && ( -
- -