@procaaso/alphinity-ui-components 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -750,6 +750,50 @@ interface ThemeToggleProps extends react__default.HTMLAttributes<HTMLDivElement>
750
750
  }
751
751
  declare const ThemeToggle: react__default.FC<ThemeToggleProps>;
752
752
 
753
+ /**
754
+ * ISA-101 High Performance HMI — Unified Status Color System
755
+ *
756
+ * Single source of truth for mapping device status to visual colors.
757
+ * Used by NodeRenderer (SVG fill/stroke), DeviceControlPanel (status indicator),
758
+ * and DataOverlay (telemetry badge).
759
+ */
760
+ /** Canonical device status vocabulary */
761
+ type DeviceStatus = 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'starting' | 'stopping';
762
+ /** Color entry covering both SVG node and overlay/panel needs */
763
+ interface StatusColorEntry {
764
+ /** Fill color for SVG node symbols */
765
+ fill: string;
766
+ /** Stroke color for SVG node symbols */
767
+ stroke: string;
768
+ /** Background color for overlays and panel indicators */
769
+ bg: string;
770
+ /** Text color for overlays */
771
+ text: string;
772
+ /** Border color for overlays */
773
+ border: string;
774
+ }
775
+ /** Partial map for consumer overrides — only specify statuses you want to change */
776
+ type StatusColorMap = Partial<Record<DeviceStatus, Partial<StatusColorEntry>>>;
777
+ /**
778
+ * ISA-101 defaults.
779
+ *
780
+ * - normal: muted grey (ISA-101: no color for normal operation)
781
+ * - warning: amber/yellow
782
+ * - alarm: red
783
+ * - fault: dark red
784
+ * - off: light grey (matches canvas default #edeeef)
785
+ * - starting: light green (transitional)
786
+ * - stopping: amber (transitional)
787
+ */
788
+ declare const DEFAULT_STATUS_COLORS: Record<DeviceStatus, StatusColorEntry>;
789
+ /**
790
+ * Resolve a status string to a full color entry.
791
+ *
792
+ * Priority: customMap[status] (merged) > DEFAULT_STATUS_COLORS[status] > off fallback.
793
+ * Supports aliases ('running' -> 'normal', 'stopped' -> 'off').
794
+ */
795
+ declare function resolveStatusColor(status: string | undefined, customMap?: StatusColorMap): StatusColorEntry;
796
+
753
797
  interface NodeInstance {
754
798
  id: string;
755
799
  symbolId: string;
@@ -762,7 +806,7 @@ interface NodeInstance {
762
806
  y: number;
763
807
  };
764
808
  labelFontSize?: number;
765
- status?: 'stopped' | 'running' | 'alarm' | 'warning' | string;
809
+ status?: 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'starting' | 'stopping' | string;
766
810
  customColors?: {
767
811
  fill?: string;
768
812
  stroke?: string;
@@ -1296,6 +1340,8 @@ interface PIDCanvasProps extends react__default.HTMLAttributes<HTMLDivElement> {
1296
1340
  onMounted?: (controls: PIDCanvasControls) => void;
1297
1341
  /** Telemetry data bindings for live values */
1298
1342
  telemetry?: TelemetryMap;
1343
+ /** Custom status-to-color map for node rendering (overrides ISA-101 defaults) */
1344
+ statusColorMap?: StatusColorMap;
1299
1345
  }
1300
1346
  interface PIDCanvasControls {
1301
1347
  /** Fit view to show all diagram content */
@@ -1314,7 +1360,7 @@ interface PIDCanvasControls {
1314
1360
  *
1315
1361
  * Future: Editing tools, symbol library UI
1316
1362
  */
1317
- declare function PIDCanvas({ diagram, className, style, features, onSelectionChange, onNodeClick, onPipeClick, onNodeMove, onDiagramChange, onDelete, onItemsCopied, onPaste, onSymbolDrop, onPipeCreated, onMounted, telemetry, ...props }: PIDCanvasProps): react__default.ReactElement;
1363
+ declare function PIDCanvas({ diagram, className, style, features, onSelectionChange, onNodeClick, onPipeClick, onNodeMove, onDiagramChange, onDelete, onItemsCopied, onPaste, onSymbolDrop, onPipeCreated, onMounted, telemetry, statusColorMap, ...props }: PIDCanvasProps): react__default.ReactElement;
1318
1364
 
1319
1365
  interface SymbolLibraryProps {
1320
1366
  /** Optional className for styling */
@@ -1810,4 +1856,4 @@ interface SimulationOptions {
1810
1856
  */
1811
1857
  declare function useSimulation(telemetry: TelemetryMap, updateTelemetryBatch: (updates: Array<any>) => void, options?: SimulationOptions): void;
1812
1858
 
1813
- export { type AnchorType, Button, type ButtonProps, CardHeader, CardUnit, CardValue, CircularGauge, type CircularGaugeProps, type ConfigActions, type ConfigDisplay, type ConfigParameter, type ConfigSection, type ConfigState, type ConfigTheme, type ControlCapabilities, type ControlMode, ControlPanel, type ControlPanelProps, type ControlParameter, type ControlState, DEFAULT_THRESHOLDS, DashboardCard, type DataBinding, type DeviceConfigBinding, type DeviceConfigMap, DeviceConfigPanel, type DeviceConfigPanelProps, type DeviceControlBinding, type DeviceControlMap, DeviceControlPanel, type DeviceControlPanelProps, type Diagram, type DiagramMetadata, type DisplayMode, DisplayModeToggle, type DragPoint, type DragState, EquipmentIndicator, type EquipmentIndicatorProps, EquipmentIndicatorWithSparkline, type EquipmentIndicatorWithSparklineProps, FixedSVGContainer, FooterPanel, FullscreenContainer, FullscreenWorkspace, type FullscreenWorkspaceProps, type FullscreenWorkspaceTab, type KeyboardShortcutsOptions, LeftPanel, LeftToggleButton, LegacyValueEntry, type LegacyValueEntryProps, type ModeConfig, NodeConfigPanel, type NodeConfigPanelProps, type NodeControlConfig, NodeControlsPanel, type NodeControlsPanelProps, type NodeInstance, type Overlay, type OverlayContent, type OverlayTheme, type OverlayType, PIDCanvas, type PIDCanvasControls, type PIDCanvasFeatures, type PIDCanvasProps, PanelContent, PanelTabs, type PipeEdge, type PipeStyle, type Point, type PortDefinition, type PortInstance, type PortType, RightPanel, RightToggleButton, SVGArea, SVGLockedOverlay, type SVGLockedOverlayProps, ScrollableSVGWrapper, type SelectionState, Selector, type SelectorOption, type SelectorProps, type SimulationOptions, Sparkline, type SparklineProps, StatusIndicator, type StatusIndicatorProps, type SymbolCategory, type SymbolDefinition, SymbolLibrary, type SymbolLibraryProps, type SymbolMetadata, type TelemetryBinding, type TelemetryMap, type TelemetryStatus$1 as TelemetryStatus, type TelemetryValue, ThemeProvider, ThemeToggle, type ThemeToggleProps, type Thresholds, type Transform, TrendLine, type TrendLineProps, type UseDragOptions, type UseDragResult, type UseSelectionOptions, type UseSelectionResult, type UseTelemetryOptions, type UseTelemetryResult, type UseTelemetryStatusOptions, type UseViewBoxOptions, type UseViewBoxResult, ValueEntry, type ValueEntryProps, type ViewBox, ZoomButton, ZoomControls, calculateThresholdStatus, createConfigBinding, createControlBinding, exampleDiagram, exportDiagram, generateRoutePoints, getAvailableSymbols, getPortWorldPosition, getSymbolDefinition, importDiagram, mockSymbolLibrary, nodeHasPort, overlayStyles, registerSymbol, registerSymbols, useDeviceConfigs, useDeviceControls, useDrag, useKeyboardShortcuts, useSelection, useSimulation, useTelemetry, useTelemetryStatus, useTheme, useViewBox, validateDiagram };
1859
+ export { type AnchorType, Button, type ButtonProps, CardHeader, CardUnit, CardValue, CircularGauge, type CircularGaugeProps, type ConfigActions, type ConfigDisplay, type ConfigParameter, type ConfigSection, type ConfigState, type ConfigTheme, type ControlCapabilities, type ControlMode, ControlPanel, type ControlPanelProps, type ControlParameter, type ControlState, DEFAULT_STATUS_COLORS, DEFAULT_THRESHOLDS, DashboardCard, type DataBinding, type DeviceConfigBinding, type DeviceConfigMap, DeviceConfigPanel, type DeviceConfigPanelProps, type DeviceControlBinding, type DeviceControlMap, DeviceControlPanel, type DeviceControlPanelProps, type DeviceStatus, type Diagram, type DiagramMetadata, type DisplayMode, DisplayModeToggle, type DragPoint, type DragState, EquipmentIndicator, type EquipmentIndicatorProps, EquipmentIndicatorWithSparkline, type EquipmentIndicatorWithSparklineProps, FixedSVGContainer, FooterPanel, FullscreenContainer, FullscreenWorkspace, type FullscreenWorkspaceProps, type FullscreenWorkspaceTab, type KeyboardShortcutsOptions, LeftPanel, LeftToggleButton, LegacyValueEntry, type LegacyValueEntryProps, type ModeConfig, NodeConfigPanel, type NodeConfigPanelProps, type NodeControlConfig, NodeControlsPanel, type NodeControlsPanelProps, type NodeInstance, type Overlay, type OverlayContent, type OverlayTheme, type OverlayType, PIDCanvas, type PIDCanvasControls, type PIDCanvasFeatures, type PIDCanvasProps, PanelContent, PanelTabs, type PipeEdge, type PipeStyle, type Point, type PortDefinition, type PortInstance, type PortType, RightPanel, RightToggleButton, SVGArea, SVGLockedOverlay, type SVGLockedOverlayProps, ScrollableSVGWrapper, type SelectionState, Selector, type SelectorOption, type SelectorProps, type SimulationOptions, Sparkline, type SparklineProps, type StatusColorEntry, type StatusColorMap, StatusIndicator, type StatusIndicatorProps, type SymbolCategory, type SymbolDefinition, SymbolLibrary, type SymbolLibraryProps, type SymbolMetadata, type TelemetryBinding, type TelemetryMap, type TelemetryStatus$1 as TelemetryStatus, type TelemetryValue, ThemeProvider, ThemeToggle, type ThemeToggleProps, type Thresholds, type Transform, TrendLine, type TrendLineProps, type UseDragOptions, type UseDragResult, type UseSelectionOptions, type UseSelectionResult, type UseTelemetryOptions, type UseTelemetryResult, type UseTelemetryStatusOptions, type UseViewBoxOptions, type UseViewBoxResult, ValueEntry, type ValueEntryProps, type ViewBox, ZoomButton, ZoomControls, calculateThresholdStatus, createConfigBinding, createControlBinding, exampleDiagram, exportDiagram, generateRoutePoints, getAvailableSymbols, getPortWorldPosition, getSymbolDefinition, importDiagram, mockSymbolLibrary, nodeHasPort, overlayStyles, registerSymbol, registerSymbols, resolveStatusColor, useDeviceConfigs, useDeviceControls, useDrag, useKeyboardShortcuts, useSelection, useSimulation, useTelemetry, useTelemetryStatus, useTheme, useViewBox, validateDiagram };
package/dist/index.d.ts CHANGED
@@ -750,6 +750,50 @@ interface ThemeToggleProps extends react__default.HTMLAttributes<HTMLDivElement>
750
750
  }
751
751
  declare const ThemeToggle: react__default.FC<ThemeToggleProps>;
752
752
 
753
+ /**
754
+ * ISA-101 High Performance HMI — Unified Status Color System
755
+ *
756
+ * Single source of truth for mapping device status to visual colors.
757
+ * Used by NodeRenderer (SVG fill/stroke), DeviceControlPanel (status indicator),
758
+ * and DataOverlay (telemetry badge).
759
+ */
760
+ /** Canonical device status vocabulary */
761
+ type DeviceStatus = 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'starting' | 'stopping';
762
+ /** Color entry covering both SVG node and overlay/panel needs */
763
+ interface StatusColorEntry {
764
+ /** Fill color for SVG node symbols */
765
+ fill: string;
766
+ /** Stroke color for SVG node symbols */
767
+ stroke: string;
768
+ /** Background color for overlays and panel indicators */
769
+ bg: string;
770
+ /** Text color for overlays */
771
+ text: string;
772
+ /** Border color for overlays */
773
+ border: string;
774
+ }
775
+ /** Partial map for consumer overrides — only specify statuses you want to change */
776
+ type StatusColorMap = Partial<Record<DeviceStatus, Partial<StatusColorEntry>>>;
777
+ /**
778
+ * ISA-101 defaults.
779
+ *
780
+ * - normal: muted grey (ISA-101: no color for normal operation)
781
+ * - warning: amber/yellow
782
+ * - alarm: red
783
+ * - fault: dark red
784
+ * - off: light grey (matches canvas default #edeeef)
785
+ * - starting: light green (transitional)
786
+ * - stopping: amber (transitional)
787
+ */
788
+ declare const DEFAULT_STATUS_COLORS: Record<DeviceStatus, StatusColorEntry>;
789
+ /**
790
+ * Resolve a status string to a full color entry.
791
+ *
792
+ * Priority: customMap[status] (merged) > DEFAULT_STATUS_COLORS[status] > off fallback.
793
+ * Supports aliases ('running' -> 'normal', 'stopped' -> 'off').
794
+ */
795
+ declare function resolveStatusColor(status: string | undefined, customMap?: StatusColorMap): StatusColorEntry;
796
+
753
797
  interface NodeInstance {
754
798
  id: string;
755
799
  symbolId: string;
@@ -762,7 +806,7 @@ interface NodeInstance {
762
806
  y: number;
763
807
  };
764
808
  labelFontSize?: number;
765
- status?: 'stopped' | 'running' | 'alarm' | 'warning' | string;
809
+ status?: 'normal' | 'warning' | 'alarm' | 'fault' | 'off' | 'starting' | 'stopping' | string;
766
810
  customColors?: {
767
811
  fill?: string;
768
812
  stroke?: string;
@@ -1296,6 +1340,8 @@ interface PIDCanvasProps extends react__default.HTMLAttributes<HTMLDivElement> {
1296
1340
  onMounted?: (controls: PIDCanvasControls) => void;
1297
1341
  /** Telemetry data bindings for live values */
1298
1342
  telemetry?: TelemetryMap;
1343
+ /** Custom status-to-color map for node rendering (overrides ISA-101 defaults) */
1344
+ statusColorMap?: StatusColorMap;
1299
1345
  }
1300
1346
  interface PIDCanvasControls {
1301
1347
  /** Fit view to show all diagram content */
@@ -1314,7 +1360,7 @@ interface PIDCanvasControls {
1314
1360
  *
1315
1361
  * Future: Editing tools, symbol library UI
1316
1362
  */
1317
- declare function PIDCanvas({ diagram, className, style, features, onSelectionChange, onNodeClick, onPipeClick, onNodeMove, onDiagramChange, onDelete, onItemsCopied, onPaste, onSymbolDrop, onPipeCreated, onMounted, telemetry, ...props }: PIDCanvasProps): react__default.ReactElement;
1363
+ declare function PIDCanvas({ diagram, className, style, features, onSelectionChange, onNodeClick, onPipeClick, onNodeMove, onDiagramChange, onDelete, onItemsCopied, onPaste, onSymbolDrop, onPipeCreated, onMounted, telemetry, statusColorMap, ...props }: PIDCanvasProps): react__default.ReactElement;
1318
1364
 
1319
1365
  interface SymbolLibraryProps {
1320
1366
  /** Optional className for styling */
@@ -1810,4 +1856,4 @@ interface SimulationOptions {
1810
1856
  */
1811
1857
  declare function useSimulation(telemetry: TelemetryMap, updateTelemetryBatch: (updates: Array<any>) => void, options?: SimulationOptions): void;
1812
1858
 
1813
- export { type AnchorType, Button, type ButtonProps, CardHeader, CardUnit, CardValue, CircularGauge, type CircularGaugeProps, type ConfigActions, type ConfigDisplay, type ConfigParameter, type ConfigSection, type ConfigState, type ConfigTheme, type ControlCapabilities, type ControlMode, ControlPanel, type ControlPanelProps, type ControlParameter, type ControlState, DEFAULT_THRESHOLDS, DashboardCard, type DataBinding, type DeviceConfigBinding, type DeviceConfigMap, DeviceConfigPanel, type DeviceConfigPanelProps, type DeviceControlBinding, type DeviceControlMap, DeviceControlPanel, type DeviceControlPanelProps, type Diagram, type DiagramMetadata, type DisplayMode, DisplayModeToggle, type DragPoint, type DragState, EquipmentIndicator, type EquipmentIndicatorProps, EquipmentIndicatorWithSparkline, type EquipmentIndicatorWithSparklineProps, FixedSVGContainer, FooterPanel, FullscreenContainer, FullscreenWorkspace, type FullscreenWorkspaceProps, type FullscreenWorkspaceTab, type KeyboardShortcutsOptions, LeftPanel, LeftToggleButton, LegacyValueEntry, type LegacyValueEntryProps, type ModeConfig, NodeConfigPanel, type NodeConfigPanelProps, type NodeControlConfig, NodeControlsPanel, type NodeControlsPanelProps, type NodeInstance, type Overlay, type OverlayContent, type OverlayTheme, type OverlayType, PIDCanvas, type PIDCanvasControls, type PIDCanvasFeatures, type PIDCanvasProps, PanelContent, PanelTabs, type PipeEdge, type PipeStyle, type Point, type PortDefinition, type PortInstance, type PortType, RightPanel, RightToggleButton, SVGArea, SVGLockedOverlay, type SVGLockedOverlayProps, ScrollableSVGWrapper, type SelectionState, Selector, type SelectorOption, type SelectorProps, type SimulationOptions, Sparkline, type SparklineProps, StatusIndicator, type StatusIndicatorProps, type SymbolCategory, type SymbolDefinition, SymbolLibrary, type SymbolLibraryProps, type SymbolMetadata, type TelemetryBinding, type TelemetryMap, type TelemetryStatus$1 as TelemetryStatus, type TelemetryValue, ThemeProvider, ThemeToggle, type ThemeToggleProps, type Thresholds, type Transform, TrendLine, type TrendLineProps, type UseDragOptions, type UseDragResult, type UseSelectionOptions, type UseSelectionResult, type UseTelemetryOptions, type UseTelemetryResult, type UseTelemetryStatusOptions, type UseViewBoxOptions, type UseViewBoxResult, ValueEntry, type ValueEntryProps, type ViewBox, ZoomButton, ZoomControls, calculateThresholdStatus, createConfigBinding, createControlBinding, exampleDiagram, exportDiagram, generateRoutePoints, getAvailableSymbols, getPortWorldPosition, getSymbolDefinition, importDiagram, mockSymbolLibrary, nodeHasPort, overlayStyles, registerSymbol, registerSymbols, useDeviceConfigs, useDeviceControls, useDrag, useKeyboardShortcuts, useSelection, useSimulation, useTelemetry, useTelemetryStatus, useTheme, useViewBox, validateDiagram };
1859
+ export { type AnchorType, Button, type ButtonProps, CardHeader, CardUnit, CardValue, CircularGauge, type CircularGaugeProps, type ConfigActions, type ConfigDisplay, type ConfigParameter, type ConfigSection, type ConfigState, type ConfigTheme, type ControlCapabilities, type ControlMode, ControlPanel, type ControlPanelProps, type ControlParameter, type ControlState, DEFAULT_STATUS_COLORS, DEFAULT_THRESHOLDS, DashboardCard, type DataBinding, type DeviceConfigBinding, type DeviceConfigMap, DeviceConfigPanel, type DeviceConfigPanelProps, type DeviceControlBinding, type DeviceControlMap, DeviceControlPanel, type DeviceControlPanelProps, type DeviceStatus, type Diagram, type DiagramMetadata, type DisplayMode, DisplayModeToggle, type DragPoint, type DragState, EquipmentIndicator, type EquipmentIndicatorProps, EquipmentIndicatorWithSparkline, type EquipmentIndicatorWithSparklineProps, FixedSVGContainer, FooterPanel, FullscreenContainer, FullscreenWorkspace, type FullscreenWorkspaceProps, type FullscreenWorkspaceTab, type KeyboardShortcutsOptions, LeftPanel, LeftToggleButton, LegacyValueEntry, type LegacyValueEntryProps, type ModeConfig, NodeConfigPanel, type NodeConfigPanelProps, type NodeControlConfig, NodeControlsPanel, type NodeControlsPanelProps, type NodeInstance, type Overlay, type OverlayContent, type OverlayTheme, type OverlayType, PIDCanvas, type PIDCanvasControls, type PIDCanvasFeatures, type PIDCanvasProps, PanelContent, PanelTabs, type PipeEdge, type PipeStyle, type Point, type PortDefinition, type PortInstance, type PortType, RightPanel, RightToggleButton, SVGArea, SVGLockedOverlay, type SVGLockedOverlayProps, ScrollableSVGWrapper, type SelectionState, Selector, type SelectorOption, type SelectorProps, type SimulationOptions, Sparkline, type SparklineProps, type StatusColorEntry, type StatusColorMap, StatusIndicator, type StatusIndicatorProps, type SymbolCategory, type SymbolDefinition, SymbolLibrary, type SymbolLibraryProps, type SymbolMetadata, type TelemetryBinding, type TelemetryMap, type TelemetryStatus$1 as TelemetryStatus, type TelemetryValue, ThemeProvider, ThemeToggle, type ThemeToggleProps, type Thresholds, type Transform, TrendLine, type TrendLineProps, type UseDragOptions, type UseDragResult, type UseSelectionOptions, type UseSelectionResult, type UseTelemetryOptions, type UseTelemetryResult, type UseTelemetryStatusOptions, type UseViewBoxOptions, type UseViewBoxResult, ValueEntry, type ValueEntryProps, type ViewBox, ZoomButton, ZoomControls, calculateThresholdStatus, createConfigBinding, createControlBinding, exampleDiagram, exportDiagram, generateRoutePoints, getAvailableSymbols, getPortWorldPosition, getSymbolDefinition, importDiagram, mockSymbolLibrary, nodeHasPort, overlayStyles, registerSymbol, registerSymbols, resolveStatusColor, useDeviceConfigs, useDeviceControls, useDrag, useKeyboardShortcuts, useSelection, useSimulation, useTelemetry, useTelemetryStatus, useTheme, useViewBox, validateDiagram };
package/dist/index.js CHANGED
@@ -895,6 +895,31 @@ var NodeControlsPanel = ({
895
895
 
896
896
  // src/components/DeviceControlPanel/DeviceControlPanel.tsx
897
897
  import { useState as useState5, useEffect as useEffect2 } from "react";
898
+
899
+ // src/theme/statusColors.ts
900
+ var DEFAULT_STATUS_COLORS = {
901
+ normal: { fill: "#888888", stroke: "#6b6b6b", bg: "#888888", text: "#ffffff", border: "#6b6b6b" },
902
+ warning: { fill: "#f59e0b", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" },
903
+ alarm: { fill: "#ef4444", stroke: "#dc2626", bg: "#FF0000", text: "#ffffff", border: "#dc2626" },
904
+ fault: { fill: "#dc2626", stroke: "#b91c1c", bg: "#FF0000", text: "#ffffff", border: "#b91c1c" },
905
+ off: { fill: "#edeeef", stroke: "#000000", bg: "#666666", text: "#ffffff", border: "#4b5563" },
906
+ starting: { fill: "#90EE90", stroke: "#22c55e", bg: "#90EE90", text: "#000000", border: "#22c55e" },
907
+ stopping: { fill: "#FFD700", stroke: "#d97706", bg: "#FFD700", text: "#000000", border: "#d97706" }
908
+ };
909
+ var STATUS_ALIASES = {
910
+ running: "normal",
911
+ stopped: "off"
912
+ };
913
+ function resolveStatusColor(status, customMap) {
914
+ const raw = (status || "off").toLowerCase();
915
+ const key = STATUS_ALIASES[raw] ?? raw;
916
+ const defaults = DEFAULT_STATUS_COLORS[key] ?? DEFAULT_STATUS_COLORS.off;
917
+ const overrides = customMap?.[key];
918
+ if (!overrides) return defaults;
919
+ return { ...defaults, ...overrides };
920
+ }
921
+
922
+ // src/components/DeviceControlPanel/DeviceControlPanel.tsx
898
923
  import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
899
924
  function DeviceControlPanel({
900
925
  binding,
@@ -969,23 +994,8 @@ function DeviceControlPanel({
969
994
  const textColor = binding.theme?.textColor || "#000000";
970
995
  const mutedTextColor = "#666666";
971
996
  const selectedColor = "#b4d0fe";
972
- const statusColors = {
973
- normal: binding.theme?.statusColors?.normal || "#888888",
974
- // Gray (no alarm)
975
- warning: binding.theme?.statusColors?.warning || "#FFD700",
976
- // Yellow
977
- alarm: binding.theme?.statusColors?.alarm || "#FF0000",
978
- // Red
979
- fault: binding.theme?.statusColors?.fault || "#FF0000",
980
- // Red
981
- off: binding.theme?.statusColors?.off || "#666666",
982
- // Dark gray
983
- starting: binding.theme?.statusColors?.starting || "#90EE90",
984
- // Light green
985
- stopping: binding.theme?.statusColors?.stopping || "#FFD700"
986
- // Yellow
987
- };
988
- const statusColor = statusColors[binding.state.status || "normal"];
997
+ const statusEntry = resolveStatusColor(binding.state.status, binding.theme?.statusColors);
998
+ const statusColor = statusEntry.bg;
989
999
  const handleModeChange = (mode) => {
990
1000
  onModeChange?.(mode);
991
1001
  };
@@ -1272,7 +1282,10 @@ function DeviceControlPanel({
1272
1282
  /* @__PURE__ */ jsxs7(
1273
1283
  "div",
1274
1284
  {
1275
- onClick: () => setShowModeModal(true),
1285
+ onClick: () => {
1286
+ setPendingMode(currentMode);
1287
+ setShowModeModal(true);
1288
+ },
1276
1289
  style: {
1277
1290
  padding: "12px",
1278
1291
  backgroundColor: surfaceColor,
@@ -4012,7 +4025,8 @@ function NodeRenderer({
4012
4025
  onNodeDragStart,
4013
4026
  draggingNodeId,
4014
4027
  dragOffset = { x: 0, y: 0 },
4015
- enableDrag = false
4028
+ enableDrag = false,
4029
+ statusColorMap
4016
4030
  }) {
4017
4031
  return /* @__PURE__ */ jsx15("g", { id: "layer-nodes", children: nodes2.filter((node) => node.visible !== false).map((node) => {
4018
4032
  const symbol = getSymbolDefinition(node.symbolId);
@@ -4071,24 +4085,9 @@ function NodeRenderer({
4071
4085
  `translate(${centerX}, ${centerY}) scale(${scaleX}, ${scaleY}) translate(${-centerX}, ${-centerY})`
4072
4086
  );
4073
4087
  }
4074
- const getStatusColor = (status) => {
4075
- switch (status) {
4076
- case "running":
4077
- return "#22c55e";
4078
- // Green
4079
- case "alarm":
4080
- return "#ef4444";
4081
- // Red
4082
- case "warning":
4083
- return "#f59e0b";
4084
- // Orange
4085
- case "stopped":
4086
- default:
4087
- return "#edeeef";
4088
- }
4089
- };
4090
- const fillColor = node.customColors?.fill ?? getStatusColor(node.status);
4091
- const strokeColor = node.customColors?.stroke ?? "rgb(0, 0, 0)";
4088
+ const statusEntry = resolveStatusColor(node.status, statusColorMap);
4089
+ const fillColor = node.customColors?.fill ?? statusEntry.fill;
4090
+ const strokeColor = node.customColors?.stroke ?? statusEntry.stroke;
4092
4091
  return /* @__PURE__ */ jsxs11(
4093
4092
  "g",
4094
4093
  {
@@ -4352,7 +4351,8 @@ function DataOverlay({
4352
4351
  x,
4353
4352
  y,
4354
4353
  telemetry,
4355
- scale = 1
4354
+ scale = 1,
4355
+ statusColorMap
4356
4356
  }) {
4357
4357
  const { value, display, history } = telemetry;
4358
4358
  const showValue = display?.showValue ?? true;
@@ -4377,21 +4377,9 @@ function DataOverlay({
4377
4377
  }
4378
4378
  return val.toString();
4379
4379
  };
4380
- const defaultStatusColors = {
4381
- normal: { bg: "#10b981", text: "#ffffff", border: "#059669" },
4382
- warning: { bg: "#f59e0b", text: "#ffffff", border: "#d97706" },
4383
- alarm: { bg: "#ef4444", text: "#ffffff", border: "#dc2626" },
4384
- fault: { bg: "#dc2626", text: "#ffffff", border: "#b91c1c" },
4385
- off: { bg: "#6b7280", text: "#ffffff", border: "#4b5563" }
4386
- };
4387
- const getStatusColors = () => {
4388
- const customColor = telemetry.statusColors?.[value.status];
4389
- if (customColor) {
4390
- return { bg: customColor, text: "#ffffff", border: customColor };
4391
- }
4392
- return defaultStatusColors[value.status] || defaultStatusColors.normal;
4393
- };
4394
- const statusColors = getStatusColors();
4380
+ const resolvedEntry = resolveStatusColor(value.status, statusColorMap);
4381
+ const customColor = telemetry.statusColors?.[value.status];
4382
+ const statusColors = customColor ? { bg: customColor, text: "#ffffff", border: customColor } : { bg: resolvedEntry.bg, text: resolvedEntry.text, border: resolvedEntry.border };
4395
4383
  const colors = backgroundColor && backgroundColor !== "status" ? { bg: backgroundColor, text: textColor || "#ffffff", border: backgroundColor } : statusColors;
4396
4384
  const finalTextColor = textColor || colors.text;
4397
4385
  const formattedValue = formatValue(value.value);
@@ -5662,6 +5650,7 @@ function PIDCanvas({
5662
5650
  onPipeCreated,
5663
5651
  onMounted,
5664
5652
  telemetry,
5653
+ statusColorMap,
5665
5654
  ...props
5666
5655
  }) {
5667
5656
  const [localDiagram, setLocalDiagram] = useState13(diagram);
@@ -6315,7 +6304,8 @@ function PIDCanvas({
6315
6304
  enableDrag: dragEnabled && !isConnecting,
6316
6305
  onNodeDragStart: dragEnabled && !isConnecting ? handleNodeDragStart : void 0,
6317
6306
  draggingNodeId: dragState.draggedId,
6318
- dragOffset: dragState.offset
6307
+ dragOffset: dragState.offset,
6308
+ statusColorMap
6319
6309
  }
6320
6310
  ),
6321
6311
  (features.editPipeRoutes ?? false) && /* @__PURE__ */ jsx19(
@@ -6349,7 +6339,8 @@ function PIDCanvas({
6349
6339
  x: overlayX,
6350
6340
  y: overlayY,
6351
6341
  telemetry: binding,
6352
- scale: features.telemetryScale ?? 1
6342
+ scale: features.telemetryScale ?? 1,
6343
+ statusColorMap
6353
6344
  },
6354
6345
  `telemetry-${node.id}`
6355
6346
  );
@@ -8844,6 +8835,7 @@ export {
8844
8835
  CardValue,
8845
8836
  CircularGauge,
8846
8837
  ControlPanel,
8838
+ DEFAULT_STATUS_COLORS,
8847
8839
  DEFAULT_THRESHOLDS,
8848
8840
  DashboardCard,
8849
8841
  DeviceConfigPanel,
@@ -8893,6 +8885,7 @@ export {
8893
8885
  overlayStyles,
8894
8886
  registerSymbol,
8895
8887
  registerSymbols,
8888
+ resolveStatusColor,
8896
8889
  useDeviceConfigs,
8897
8890
  useDeviceControls,
8898
8891
  useDrag,