From 23fc302b24c217157a8679973eee94776916ec55 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Mon, 11 May 2026 16:46:48 +0000 Subject: [PATCH] Extract Variables tab JSX into WiredVariablesTabView component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Proposal #5 from docs/ARCHITECTURE.md, first slice: split one of the three remaining inline tab bodies of WiredCreatorToolsView out into its own file. Same approach the Settings tab has had for a while (see WiredToolsSettingsTabView). What moved - 113 lines of inline JSX (the `{ activeTab === 'variables' &&
...
}` block) → src/components/wired-tools/WiredVariablesTabView.tsx - The new component is a pure presentation function: 12 typed props, no useState, no useEffect, no event subscriptions. It receives: * state to render: variablesType, variablePickerDefinitions, selectedVariableDefinition, canVariableHighlight, isVariableHighlightActive, variableManageCanOpen, selectedVariableProperties, selectedVariableTextValues * actions to call: onVariablesTypeChange, onPickVariable, onToggleVariableHighlight, onOpenManagePanel - The parent supplies all of them inline at the call site. The manage-panel open sequence (request fresh user vars + reset page + clear selection + show modal) is closed over into a single onOpenManagePanel callback, so the sub-component doesn't need to know about its three internal setters. Impact - WiredCreatorToolsView.tsx: 3901 → 3809 lines (−92 net). The file is still large, but one of the three big inline blocks is gone. Monitor (~176 lines) and Inspection (~138 lines) remain inline as follow-up PRs. - The React Compiler now has a smaller file boundary for the Variables panel; once the other two blocks come out the parent module should stop being skipped for memoization. Conscious non-goals - No state was moved. The shared state (selectedVariableKeys, isVariableHighlightActive, variableManagePage, etc.) still lives in the parent's useState. Hoisting them to a Zustand slice would be a separate PR — premature here. - No behavior change. Same renders, same handlers, same DOM. Verification - yarn eslint on the two touched files: 34 problems baseline, 34 problems after the split (identical: same FC<{}>, same pre-existing set-state-in-effect, same react-compiler skip warnings on the parent module). - yarn test: 49/49 passing. - yarn tsc on the two files: clean. --- .../wired-tools/WiredCreatorToolsView.tsx | 133 +++------------- .../wired-tools/WiredVariablesTabView.tsx | 150 ++++++++++++++++++ 2 files changed, 171 insertions(+), 112 deletions(-) create mode 100644 src/components/wired-tools/WiredVariablesTabView.tsx diff --git a/src/components/wired-tools/WiredCreatorToolsView.tsx b/src/components/wired-tools/WiredCreatorToolsView.tsx index 798d3ad..64ff67c 100644 --- a/src/components/wired-tools/WiredCreatorToolsView.tsx +++ b/src/components/wired-tools/WiredCreatorToolsView.tsx @@ -10,6 +10,7 @@ import { DIRECTION_NAMES, EDITABLE_FURNI_VARIABLES, EDITABLE_USER_VARIABLES, INS import { createEmptyMonitorSnapshot, formatMonitorHistoryOccurrence, formatMonitorLatestOccurrence, formatMonitorSource, formatVariableTimestamp, getHotelDateTimeParts, getHotelTimeFormatter, normalizeMonitorReason } from './WiredCreatorTools.helpers'; import { HotelDateTimeParts, InspectionElementButton, InspectionElementType, InspectionFurniLiveState, InspectionFurniSelection, InspectionUserLiveState, InspectionUserSelection, InspectionUserTeamData, InspectionVariable, ManagedHolderVariableEntry, MonitorLog, MonitorLogDetails, MonitorSnapshot, MonitorStat, ParsedWallLocation, TeamEffectData, VariableDefinition, VariableHighlightOverlay, VariableHighlightTarget, VariableManageEntry, VariableTextValue, VariablesElementButton, VariablesElementType, WiredToolsTab } from './WiredCreatorTools.types'; import { WiredToolsSettingsTabView } from './WiredToolsSettingsTabView'; +import { WiredVariablesTabView } from './WiredVariablesTabView'; export const WiredCreatorToolsView: FC<{}> = () => { @@ -3387,118 +3388,26 @@ export const WiredCreatorToolsView: FC<{}> = () => } { (activeTab === 'variables') && -
-
-
- Variable type: -
- { VARIABLES_ELEMENTS.map(element => ( - - )) } -
-
-
- Variable picker: -
-
- - - { variablePickerDefinitions.map((variable, index) => ( - setSelectedVariableKeys(prev => ({ ...prev, [variablesType]: variable.key })) }> - - - )) } - -
{ variable.key }
-
-
-
-
- - -
-
-
- { (variablesType === 'context') && -
- Context variables live only during the current wired execution. This tab shows their definitions, text mappings and execution-scoped capabilities, but not live values from a running stack. -
} -
- Properties: -
-
- Property - Value -
-
- - - { selectedVariableProperties.map((property, index) => ( - - - - - )) } - -
{ property.key }{ property.value }
-
-
-
-
- Text values: -
-
- Value - Text -
- { !selectedVariableTextValues.length && -
- Nothing to display -
} - { !!selectedVariableTextValues.length && -
- - - { selectedVariableTextValues.map((entry, index) => ( - - - - - )) } - -
{ entry.value }{ entry.text }
-
} -
-
-
-
} + setSelectedVariableKeys(prev => ({ ...prev, [variablesType]: key })) } + canVariableHighlight={ canVariableHighlight } + isVariableHighlightActive={ isVariableHighlightActive } + onToggleVariableHighlight={ () => setIsVariableHighlightActive(value => !value) } + variableManageCanOpen={ variableManageCanOpen } + onOpenManagePanel={ () => + { + requestUserVariables(); + setVariableManagePage(1); + setSelectedManagedVariableEntry(null); + setIsVariableManageOpen(true); + } } + selectedVariableProperties={ selectedVariableProperties } + selectedVariableTextValues={ selectedVariableTextValues } + /> } { (activeTab === 'settings') && } { (activeTab !== 'monitor') && (activeTab !== 'inspection') && diff --git a/src/components/wired-tools/WiredVariablesTabView.tsx b/src/components/wired-tools/WiredVariablesTabView.tsx new file mode 100644 index 0000000..44fcd1b --- /dev/null +++ b/src/components/wired-tools/WiredVariablesTabView.tsx @@ -0,0 +1,150 @@ +import { FC } from 'react'; +import { Button, Text } from '../../common'; +import { VARIABLES_ELEMENTS } from './WiredCreatorTools.constants'; +import { VariableDefinition, VariablesElementType, VariableTextValue } from './WiredCreatorTools.types'; + +export interface WiredVariablesTabViewProps +{ + variablesType: VariablesElementType; + onVariablesTypeChange: (next: VariablesElementType) => void; + variablePickerDefinitions: VariableDefinition[]; + selectedVariableDefinition: VariableDefinition | null; + onPickVariable: (key: string) => void; + canVariableHighlight: boolean; + isVariableHighlightActive: boolean; + onToggleVariableHighlight: () => void; + variableManageCanOpen: boolean; + onOpenManagePanel: () => void; + selectedVariableProperties: { key: string; value: string; }[]; + selectedVariableTextValues: VariableTextValue[]; +} + +/** + * The "Variables" tab body of WiredCreatorToolsView. Extracted so the + * parent module no longer carries 110 lines of inline JSX. Pure + * presentation: every piece of state and every callback is supplied as + * a prop, so this component is trivially memoizable and (eventually) + * testable in isolation. + */ +export const WiredVariablesTabView: FC = ({ + variablesType, + onVariablesTypeChange, + variablePickerDefinitions, + selectedVariableDefinition, + onPickVariable, + canVariableHighlight, + isVariableHighlightActive, + onToggleVariableHighlight, + variableManageCanOpen, + onOpenManagePanel, + selectedVariableProperties, + selectedVariableTextValues +}) => + ( +
+
+
+ Variable type: +
+ { VARIABLES_ELEMENTS.map(element => ( + + )) } +
+
+
+ Variable picker: +
+
+ + + { variablePickerDefinitions.map((variable, index) => ( + onPickVariable(variable.key) }> + + + )) } + +
{ variable.key }
+
+
+
+
+ + +
+
+
+ { (variablesType === 'context') && +
+ Context variables live only during the current wired execution. This tab shows their definitions, text mappings and execution-scoped capabilities, but not live values from a running stack. +
} +
+ Properties: +
+
+ Property + Value +
+
+ + + { selectedVariableProperties.map((property, index) => ( + + + + + )) } + +
{ property.key }{ property.value }
+
+
+
+
+ Text values: +
+
+ Value + Text +
+ { !selectedVariableTextValues.length && +
+ Nothing to display +
} + { !!selectedVariableTextValues.length && +
+ + + { selectedVariableTextValues.map((entry, index) => ( + + + + + )) } + +
{ entry.value }{ entry.text }
+
} +
+
+
+
+ );