wired-tools: hoist inline editor state (variables + managed holder) to the store

Move the four inline-editor useStates out of WiredCreatorToolsView and
into useWiredCreatorToolsUiStore:

- editingVariable / editingValue — Inspection-tab variables-table
  inline edit (current key being edited + in-flight input text).
- editingManagedHolderVariableId / editingManagedHolderValue — same
  pair for the Variable Manage panel's holder rows (id 0 = none).

WiredInspectionTabView drops three more props (editingVariable,
editingValue, onEditingValueChange) and consumes the store directly
for the read sides + the per-keystroke setEditingValue. The cancel /
keydown / begin handlers stay in the parent because they wrap
shouldPauseVariableSnapshotRefresh-aware logic plus selection
bookkeeping that doesn't belong to a pure tab body.

The shouldPauseVariableSnapshotRefresh derived flag still reads from
the same store now-backed values; no behaviour change on the polling
suppression path.

Tests: three new cases (set+read pair, null-clear, managed-holder
0-as-sentinel reset). 193/193 passing.
This commit is contained in:
simoleo89
2026-05-16 12:37:29 +02:00
parent c1aafffd09
commit 181ca096d0
4 changed files with 97 additions and 17 deletions
@@ -50,8 +50,10 @@ export const WiredCreatorToolsView: FC<{}> = () =>
const setMonitorHistorySeverityFilter = useWiredCreatorToolsUiStore(s => s.setMonitorHistorySeverityFilter);
const monitorHistoryTypeFilter = useWiredCreatorToolsUiStore(s => s.monitorHistoryTypeFilter);
const setMonitorHistoryTypeFilter = useWiredCreatorToolsUiStore(s => s.setMonitorHistoryTypeFilter);
const [ editingVariable, setEditingVariable ] = useState<string>(null);
const [ editingValue, setEditingValue ] = useState('');
const editingVariable = useWiredCreatorToolsUiStore(s => s.editingVariable);
const setEditingVariable = useWiredCreatorToolsUiStore(s => s.setEditingVariable);
const editingValue = useWiredCreatorToolsUiStore(s => s.editingValue);
const setEditingValue = useWiredCreatorToolsUiStore(s => s.setEditingValue);
const [ selectedInspectionVariableKeys, setSelectedInspectionVariableKeys ] = useState<Record<InspectionElementType, string>>({
furni: '',
user: '',
@@ -71,8 +73,10 @@ export const WiredCreatorToolsView: FC<{}> = () =>
const setVariableManagePage = useWiredCreatorToolsUiStore(s => s.setVariableManagePage);
const [ selectedManagedVariableEntry, setSelectedManagedVariableEntry ] = useState<VariableManageEntry>(null);
const [ selectedManagedHolderVariableId, setSelectedManagedHolderVariableId ] = useState(0);
const [ editingManagedHolderVariableId, setEditingManagedHolderVariableId ] = useState(0);
const [ editingManagedHolderValue, setEditingManagedHolderValue ] = useState('');
const editingManagedHolderVariableId = useWiredCreatorToolsUiStore(s => s.editingManagedHolderVariableId);
const setEditingManagedHolderVariableId = useWiredCreatorToolsUiStore(s => s.setEditingManagedHolderVariableId);
const editingManagedHolderValue = useWiredCreatorToolsUiStore(s => s.editingManagedHolderValue);
const setEditingManagedHolderValue = useWiredCreatorToolsUiStore(s => s.setEditingManagedHolderValue);
const isManagedGiveOpen = useWiredCreatorToolsUiStore(s => s.isManagedGiveOpen);
const setIsManagedGiveOpen = useWiredCreatorToolsUiStore(s => s.setIsManagedGiveOpen);
const [ managedGiveVariableItemId, setManagedGiveVariableItemId ] = useState(0);
@@ -3121,9 +3125,6 @@ export const WiredCreatorToolsView: FC<{}> = () =>
setSelectedInspectionVariableKeys(prev => ({ ...prev, [inspectionType]: variable.key }));
beginVariableEdit(variable);
} }
editingVariable={ editingVariable }
editingValue={ editingValue }
onEditingValueChange={ setEditingValue }
onCancelVariableEdit={ cancelVariableEdit }
onVariableInputKeyDown={ onVariableInputKeyDown }
onBeginVariableEdit={ variable =>
@@ -34,10 +34,10 @@ export interface WiredInspectionTabViewProps
selectedInspectionVariableKey: string;
onSelectInspectionVariable: (variable: InspectionVariable) => void;
// inline editor
editingVariable: string;
editingValue: string;
onEditingValueChange: (value: string) => void;
// inline editor — `editingVariable` / `editingValue` come from the
// store; this tab only needs the cancel / keydown / begin handlers
// since each tab consumer wraps `onBeginVariableEdit` with its own
// bookkeeping (variable-key tracking).
onCancelVariableEdit: () => void;
onVariableInputKeyDown: (event: KeyboardEvent<HTMLInputElement>) => void;
onBeginVariableEdit: (variable: InspectionVariable) => void;
@@ -73,9 +73,6 @@ export const WiredInspectionTabView = (props: WiredInspectionTabViewProps) =>
displayedVariables,
selectedInspectionVariableKey,
onSelectInspectionVariable,
editingVariable,
editingValue,
onEditingValueChange,
onCancelVariableEdit,
onVariableInputKeyDown,
onBeginVariableEdit,
@@ -94,6 +91,9 @@ export const WiredInspectionTabView = (props: WiredInspectionTabViewProps) =>
const setInspectionType = useWiredCreatorToolsUiStore(s => s.setInspectionType);
const isInspectionGiveOpen = useWiredCreatorToolsUiStore(s => s.isInspectionGiveOpen);
const setIsInspectionGiveOpen = useWiredCreatorToolsUiStore(s => s.setIsInspectionGiveOpen);
const editingVariable = useWiredCreatorToolsUiStore(s => s.editingVariable);
const editingValue = useWiredCreatorToolsUiStore(s => s.editingValue);
const setEditingValue = useWiredCreatorToolsUiStore(s => s.setEditingValue);
return (
<div className="p-3 min-h-[360px] flex gap-4">
@@ -173,7 +173,7 @@ export const WiredInspectionTabView = (props: WiredInspectionTabViewProps) =>
value={ editingValue }
onClick={ event => event.stopPropagation() }
onBlur={ onCancelVariableEdit }
onChange={ event => onEditingValueChange(event.target.value) }
onChange={ event => setEditingValue(event.target.value) }
onKeyDownCapture={ onVariableInputKeyDown } /> }
{ (editingVariable !== variable.key) && !variable.editable && <span className={ variable.valueClassName }>{ variable.value }</span> }
{ (editingVariable !== variable.key) && variable.editable &&
@@ -24,7 +24,11 @@ const INITIAL = {
selectedUserLiveState: null,
selectedUserActionVersion: 0,
isVariableHighlightActive: false,
variableHighlightOverlays: []
variableHighlightOverlays: [],
editingVariable: null,
editingValue: '',
editingManagedHolderVariableId: 0,
editingManagedHolderValue: ''
};
describe('useWiredCreatorToolsUiStore', () =>
@@ -60,6 +64,10 @@ describe('useWiredCreatorToolsUiStore', () =>
expect(state.selectedUserActionVersion).toBe(0);
expect(state.isVariableHighlightActive).toBe(false);
expect(state.variableHighlightOverlays).toEqual([]);
expect(state.editingVariable).toBeNull();
expect(state.editingValue).toBe('');
expect(state.editingManagedHolderVariableId).toBe(0);
expect(state.editingManagedHolderValue).toBe('');
});
describe('setIsVisible', () =>
@@ -356,4 +364,44 @@ describe('useWiredCreatorToolsUiStore', () =>
expect(useWiredCreatorToolsUiStore.getState().variableHighlightOverlays).toEqual([ overlay ]);
});
});
describe('inline editor', () =>
{
it('setEditingVariable + setEditingValue track the in-flight edit', () =>
{
useWiredCreatorToolsUiStore.getState().setEditingVariable('@state');
useWiredCreatorToolsUiStore.getState().setEditingValue('3');
expect(useWiredCreatorToolsUiStore.getState().editingVariable).toBe('@state');
expect(useWiredCreatorToolsUiStore.getState().editingValue).toBe('3');
});
it('setEditingVariable(null) clears the edit (commit / cancel path)', () =>
{
useWiredCreatorToolsUiStore.getState().setEditingVariable('@state');
useWiredCreatorToolsUiStore.getState().setEditingValue('3');
useWiredCreatorToolsUiStore.getState().setEditingVariable(null);
useWiredCreatorToolsUiStore.getState().setEditingValue('');
expect(useWiredCreatorToolsUiStore.getState().editingVariable).toBeNull();
expect(useWiredCreatorToolsUiStore.getState().editingValue).toBe('');
});
it('managed-holder editor pair uses 0 as "no row being edited"', () =>
{
useWiredCreatorToolsUiStore.getState().setEditingManagedHolderVariableId(42);
useWiredCreatorToolsUiStore.getState().setEditingManagedHolderValue('15');
expect(useWiredCreatorToolsUiStore.getState().editingManagedHolderVariableId).toBe(42);
expect(useWiredCreatorToolsUiStore.getState().editingManagedHolderValue).toBe('15');
// Reset path used after commit / on blur.
useWiredCreatorToolsUiStore.getState().setEditingManagedHolderVariableId(0);
useWiredCreatorToolsUiStore.getState().setEditingManagedHolderValue('');
expect(useWiredCreatorToolsUiStore.getState().editingManagedHolderVariableId).toBe(0);
expect(useWiredCreatorToolsUiStore.getState().editingManagedHolderValue).toBe('');
});
});
});
@@ -65,6 +65,22 @@ interface WiredCreatorToolsUiState
isVariableHighlightActive: boolean;
variableHighlightOverlays: VariableHighlightOverlay[];
/**
* Inline-editor state for the Inspection-tab variables table.
* `editingVariable` is the key of the variable whose value is being
* edited (null = none); `editingValue` is the in-flight text input.
* The "managed holder" pair plays the same role for the Variable
* Manage panel's holder rows (id 0 = none).
*
* The component uses these together with `shouldPauseVariableSnapshotRefresh`
* to suppress the periodic variables poll while an edit is open
* (so typing isn't clobbered by an incoming snapshot).
*/
editingVariable: string | null;
editingValue: string;
editingManagedHolderVariableId: number;
editingManagedHolderValue: string;
setIsVisible: (next: Updater<boolean>) => void;
setActiveTab: (next: WiredToolsTab) => void;
setInspectionType: (next: InspectionElementType) => void;
@@ -94,6 +110,11 @@ interface WiredCreatorToolsUiState
setIsVariableHighlightActive: (next: Updater<boolean>) => void;
setVariableHighlightOverlays: (next: VariableHighlightOverlay[]) => void;
setEditingVariable: (next: string | null) => void;
setEditingValue: (next: string) => void;
setEditingManagedHolderVariableId: (next: number) => void;
setEditingManagedHolderValue: (next: string) => void;
}
export const useWiredCreatorToolsUiStore = createNitroStore<WiredCreatorToolsUiState>()((set) => ({
@@ -126,6 +147,11 @@ export const useWiredCreatorToolsUiStore = createNitroStore<WiredCreatorToolsUiS
isVariableHighlightActive: false,
variableHighlightOverlays: [],
editingVariable: null,
editingValue: '',
editingManagedHolderVariableId: 0,
editingManagedHolderValue: '',
setIsVisible: (next) => set(state => ({ isVisible: apply(state.isVisible, next) })),
setActiveTab: (next) => set({ activeTab: next }),
setInspectionType: (next) => set({ inspectionType: next }),
@@ -154,5 +180,10 @@ export const useWiredCreatorToolsUiStore = createNitroStore<WiredCreatorToolsUiS
setSelectedUserActionVersion: (next) => set(state => ({ selectedUserActionVersion: apply(state.selectedUserActionVersion, next) })),
setIsVariableHighlightActive: (next) => set(state => ({ isVariableHighlightActive: apply(state.isVariableHighlightActive, next) })),
setVariableHighlightOverlays: (next) => set({ variableHighlightOverlays: next })
setVariableHighlightOverlays: (next) => set({ variableHighlightOverlays: next }),
setEditingVariable: (next) => set({ editingVariable: next }),
setEditingValue: (next) => set({ editingValue: next }),
setEditingManagedHolderVariableId: (next) => set({ editingManagedHolderVariableId: next }),
setEditingManagedHolderValue: (next) => set({ editingManagedHolderValue: next })
}));