wired-tools(store): hoist managed-holder give picker chain (selectedManagedVariableEntry, selectedManagedHolderVariableId, managedGiveVariableItemId, managedGiveValue)

Move the Variable-Manage panel's four-step picker cascade into the
Zustand store. Closes the WiredCreatorTools "fragmented picker state"
roadmap item — every remaining useState in the panel is now either a
store-backed UI flag or a transient component-only value (keepSelected,
globalClock, roomEnteredAt, monitor error/log details).

All writers were already direct assignments (no updater shape), so the
setters are plain typed setters. Sentinels remain `null` / `0` / `0` /
`'0'`; the cascade reset effects at WiredCreatorToolsView.tsx:2265-2307
keep the chain self-consistent. Panel close/reopen now preserves the
managed picker state, matching the lifecycle guarantee already provided
for selection, monitor snapshot, variable highlight, and inline editor.

Tests: 4 new cases (entry select/clear, chain write, post-action reset
to sentinels, panel-lifecycle persistence). Suite: 203/203.
This commit is contained in:
simoleo89
2026-05-18 20:40:19 +02:00
parent 8894fcc959
commit 1c2d8da08d
3 changed files with 104 additions and 7 deletions
@@ -70,16 +70,20 @@ export const WiredCreatorToolsView: FC<{}> = () =>
const setVariableManageSort = useWiredCreatorToolsUiStore(s => s.setVariableManageSort);
const variableManagePage = useWiredCreatorToolsUiStore(s => s.variableManagePage);
const setVariableManagePage = useWiredCreatorToolsUiStore(s => s.setVariableManagePage);
const [ selectedManagedVariableEntry, setSelectedManagedVariableEntry ] = useState<VariableManageEntry>(null);
const [ selectedManagedHolderVariableId, setSelectedManagedHolderVariableId ] = useState(0);
const selectedManagedVariableEntry = useWiredCreatorToolsUiStore(s => s.selectedManagedVariableEntry);
const setSelectedManagedVariableEntry = useWiredCreatorToolsUiStore(s => s.setSelectedManagedVariableEntry);
const selectedManagedHolderVariableId = useWiredCreatorToolsUiStore(s => s.selectedManagedHolderVariableId);
const setSelectedManagedHolderVariableId = useWiredCreatorToolsUiStore(s => s.setSelectedManagedHolderVariableId);
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);
const [ managedGiveValue, setManagedGiveValue ] = useState('0');
const managedGiveVariableItemId = useWiredCreatorToolsUiStore(s => s.managedGiveVariableItemId);
const setManagedGiveVariableItemId = useWiredCreatorToolsUiStore(s => s.setManagedGiveVariableItemId);
const managedGiveValue = useWiredCreatorToolsUiStore(s => s.managedGiveValue);
const setManagedGiveValue = useWiredCreatorToolsUiStore(s => s.setManagedGiveValue);
const isVariableHighlightActive = useWiredCreatorToolsUiStore(s => s.isVariableHighlightActive);
const setIsVariableHighlightActive = useWiredCreatorToolsUiStore(s => s.setIsVariableHighlightActive);
const variableHighlightOverlays = useWiredCreatorToolsUiStore(s => s.variableHighlightOverlays);
@@ -32,7 +32,11 @@ const INITIAL = {
selectedInspectionVariableKeys: { furni: '', user: '', global: '' },
selectedVariableKeys: { furni: '', user: '', global: '', context: '' },
inspectionGiveVariableItemId: 0,
inspectionGiveValue: '0'
inspectionGiveValue: '0',
selectedManagedVariableEntry: null,
selectedManagedHolderVariableId: 0,
managedGiveVariableItemId: 0,
managedGiveValue: '0'
};
describe('useWiredCreatorToolsUiStore', () =>
@@ -76,6 +80,10 @@ describe('useWiredCreatorToolsUiStore', () =>
expect(state.selectedVariableKeys).toEqual({ furni: '', user: '', global: '', context: '' });
expect(state.inspectionGiveVariableItemId).toBe(0);
expect(state.inspectionGiveValue).toBe('0');
expect(state.selectedManagedVariableEntry).toBeNull();
expect(state.selectedManagedHolderVariableId).toBe(0);
expect(state.managedGiveVariableItemId).toBe(0);
expect(state.managedGiveValue).toBe('0');
});
describe('setIsVisible', () =>
@@ -486,4 +494,61 @@ describe('useWiredCreatorToolsUiStore', () =>
expect(useWiredCreatorToolsUiStore.getState().inspectionGiveValue).toBe('0');
});
});
describe('managed holder give pickers', () =>
{
const entry = { entityId: 7, entityName: 'fountain', categoryLabel: 'Furni', value: '12' } as never;
it('setSelectedManagedVariableEntry writes the picked entry; null clears (reset path)', () =>
{
useWiredCreatorToolsUiStore.getState().setSelectedManagedVariableEntry(entry);
expect(useWiredCreatorToolsUiStore.getState().selectedManagedVariableEntry).toEqual(entry);
useWiredCreatorToolsUiStore.getState().setSelectedManagedVariableEntry(null);
expect(useWiredCreatorToolsUiStore.getState().selectedManagedVariableEntry).toBeNull();
});
it('the holder + give picker chain writes through cleanly', () =>
{
useWiredCreatorToolsUiStore.getState().setSelectedManagedHolderVariableId(11);
useWiredCreatorToolsUiStore.getState().setManagedGiveVariableItemId(33);
useWiredCreatorToolsUiStore.getState().setManagedGiveValue('75');
const state = useWiredCreatorToolsUiStore.getState();
expect(state.selectedManagedHolderVariableId).toBe(11);
expect(state.managedGiveVariableItemId).toBe(33);
expect(state.managedGiveValue).toBe('75');
});
it('post-give-action reset returns the give-side back to its 0 / "0" sentinels', () =>
{
useWiredCreatorToolsUiStore.getState().setSelectedManagedHolderVariableId(11);
useWiredCreatorToolsUiStore.getState().setManagedGiveVariableItemId(33);
useWiredCreatorToolsUiStore.getState().setManagedGiveValue('75');
// Matches the post-action path at WiredCreatorToolsView.tsx:2400-2402:
// setSelectedManagedHolderVariableId(newId);
// setManagedGiveValue('0');
useWiredCreatorToolsUiStore.getState().setSelectedManagedHolderVariableId(99);
useWiredCreatorToolsUiStore.getState().setManagedGiveValue('0');
expect(useWiredCreatorToolsUiStore.getState().selectedManagedHolderVariableId).toBe(99);
expect(useWiredCreatorToolsUiStore.getState().managedGiveValue).toBe('0');
});
it('the managed picker chain persists across the panel close/reopen lifecycle', () =>
{
useWiredCreatorToolsUiStore.getState().setSelectedManagedVariableEntry(entry);
useWiredCreatorToolsUiStore.getState().setSelectedManagedHolderVariableId(11);
useWiredCreatorToolsUiStore.getState().setManagedGiveVariableItemId(33);
useWiredCreatorToolsUiStore.getState().setIsVisible(false);
useWiredCreatorToolsUiStore.getState().setIsVisible(true);
const state = useWiredCreatorToolsUiStore.getState();
expect(state.selectedManagedVariableEntry).toEqual(entry);
expect(state.selectedManagedHolderVariableId).toBe(11);
expect(state.managedGiveVariableItemId).toBe(33);
});
});
});
@@ -1,6 +1,6 @@
import { createNitroStore } from '../../state/createNitroStore';
import { createEmptyMonitorSnapshot } from './WiredCreatorTools.helpers';
import { InspectionElementType, InspectionFurniLiveState, InspectionFurniSelection, InspectionUserLiveState, InspectionUserSelection, MonitorSnapshot, VariableHighlightOverlay, VariablesElementType, WiredToolsTab } from './WiredCreatorTools.types';
import { InspectionElementType, InspectionFurniLiveState, InspectionFurniSelection, InspectionUserLiveState, InspectionUserSelection, MonitorSnapshot, VariableHighlightOverlay, VariableManageEntry, VariablesElementType, WiredToolsTab } from './WiredCreatorTools.types';
type MonitorSeverityFilter = 'ALL' | 'ERROR' | 'WARNING';
type Updater<T> = T | ((prev: T) => T);
@@ -100,6 +100,19 @@ interface WiredCreatorToolsUiState
inspectionGiveVariableItemId: number;
inspectionGiveValue: string;
/**
* Variable-Manage panel — "managed holder" picker chain. Selecting
* an entry seeds the holder row, which seeds the give-variable
* picker. Sentinels: `null` entry / `0` holder-id / `0` give-id /
* `'0'` give-value. The cascade reset effects at
* WiredCreatorToolsView.tsx:2265-2307 keep these in sync as the
* upstream selection or available definitions change.
*/
selectedManagedVariableEntry: VariableManageEntry | null;
selectedManagedHolderVariableId: number;
managedGiveVariableItemId: number;
managedGiveValue: string;
setIsVisible: (next: Updater<boolean>) => void;
setActiveTab: (next: WiredToolsTab) => void;
setInspectionType: (next: InspectionElementType) => void;
@@ -140,6 +153,11 @@ interface WiredCreatorToolsUiState
setInspectionGiveVariableItemId: (next: number) => void;
setInspectionGiveValue: (next: string) => void;
setSelectedManagedVariableEntry: (next: VariableManageEntry | null) => void;
setSelectedManagedHolderVariableId: (next: number) => void;
setManagedGiveVariableItemId: (next: number) => void;
setManagedGiveValue: (next: string) => void;
}
export const useWiredCreatorToolsUiStore = createNitroStore<WiredCreatorToolsUiState>()((set) => ({
@@ -183,6 +201,11 @@ export const useWiredCreatorToolsUiStore = createNitroStore<WiredCreatorToolsUiS
inspectionGiveVariableItemId: 0,
inspectionGiveValue: '0',
selectedManagedVariableEntry: null,
selectedManagedHolderVariableId: 0,
managedGiveVariableItemId: 0,
managedGiveValue: '0',
setIsVisible: (next) => set(state => ({ isVisible: apply(state.isVisible, next) })),
setActiveTab: (next) => set({ activeTab: next }),
setInspectionType: (next) => set({ inspectionType: next }),
@@ -222,5 +245,10 @@ export const useWiredCreatorToolsUiStore = createNitroStore<WiredCreatorToolsUiS
setSelectedVariableKeys: (next) => set(state => ({ selectedVariableKeys: apply(state.selectedVariableKeys, next) })),
setInspectionGiveVariableItemId: (next) => set({ inspectionGiveVariableItemId: next }),
setInspectionGiveValue: (next) => set({ inspectionGiveValue: next })
setInspectionGiveValue: (next) => set({ inspectionGiveValue: next }),
setSelectedManagedVariableEntry: (next) => set({ selectedManagedVariableEntry: next }),
setSelectedManagedHolderVariableId: (next) => set({ selectedManagedHolderVariableId: next }),
setManagedGiveVariableItemId: (next) => set({ managedGiveVariableItemId: next }),
setManagedGiveValue: (next) => set({ managedGiveValue: next })
}));