diff --git a/src/components/wired-tools/WiredCreatorToolsView.tsx b/src/components/wired-tools/WiredCreatorToolsView.tsx index 063364d..97c5389 100644 --- a/src/components/wired-tools/WiredCreatorToolsView.tsx +++ b/src/components/wired-tools/WiredCreatorToolsView.tsx @@ -54,11 +54,8 @@ export const WiredCreatorToolsView: FC<{}> = () => const setEditingVariable = useWiredCreatorToolsUiStore(s => s.setEditingVariable); const editingValue = useWiredCreatorToolsUiStore(s => s.editingValue); const setEditingValue = useWiredCreatorToolsUiStore(s => s.setEditingValue); - const [ selectedInspectionVariableKeys, setSelectedInspectionVariableKeys ] = useState>({ - furni: '', - user: '', - global: '' - }); + const selectedInspectionVariableKeys = useWiredCreatorToolsUiStore(s => s.selectedInspectionVariableKeys); + const setSelectedInspectionVariableKeys = useWiredCreatorToolsUiStore(s => s.setSelectedInspectionVariableKeys); const isInspectionGiveOpen = useWiredCreatorToolsUiStore(s => s.isInspectionGiveOpen); const setIsInspectionGiveOpen = useWiredCreatorToolsUiStore(s => s.setIsInspectionGiveOpen); const [ inspectionGiveVariableItemId, setInspectionGiveVariableItemId ] = useState(0); @@ -87,12 +84,8 @@ export const WiredCreatorToolsView: FC<{}> = () => const setVariableHighlightOverlays = useWiredCreatorToolsUiStore(s => s.setVariableHighlightOverlays); const variableHighlightObjectsRef = useRef>([]); const shouldPauseVariableSnapshotRefresh = (!!editingVariable || !!editingManagedHolderVariableId || isInspectionGiveOpen || isManagedGiveOpen); - const [ selectedVariableKeys, setSelectedVariableKeys ] = useState>({ - furni: VARIABLE_DEFINITIONS.furni[0].key, - user: VARIABLE_DEFINITIONS.user[0].key, - global: VARIABLE_DEFINITIONS.global[0].key, - context: VARIABLE_DEFINITIONS.context[0].key - }); + const selectedVariableKeys = useWiredCreatorToolsUiStore(s => s.selectedVariableKeys); + const setSelectedVariableKeys = useWiredCreatorToolsUiStore(s => s.setSelectedVariableKeys); const { roomSession = null } = useRoom(); const { ownUser: tradeOwnUser = null, otherUser: tradeOtherUser = null, isTrading = false } = useInventoryTrade(); const { roomSettings, userVariableDefinitions, userVariableAssignments, furniVariableDefinitions, furniVariableAssignments, roomVariableDefinitions, roomVariableAssignments, contextVariableDefinitions, requestUserVariables, assignUserVariable, removeUserVariable, updateUserVariableValue, assignFurniVariable, removeFurniVariable, updateFurniVariableValue, updateRoomVariableValue } = useWiredTools(); diff --git a/src/components/wired-tools/wiredCreatorToolsUiStore.test.ts b/src/components/wired-tools/wiredCreatorToolsUiStore.test.ts index 49a524e..c128497 100644 --- a/src/components/wired-tools/wiredCreatorToolsUiStore.test.ts +++ b/src/components/wired-tools/wiredCreatorToolsUiStore.test.ts @@ -28,7 +28,9 @@ const INITIAL = { editingVariable: null, editingValue: '', editingManagedHolderVariableId: 0, - editingManagedHolderValue: '' + editingManagedHolderValue: '', + selectedInspectionVariableKeys: { furni: '', user: '', global: '' }, + selectedVariableKeys: { furni: '', user: '', global: '', context: '' } }; describe('useWiredCreatorToolsUiStore', () => @@ -68,6 +70,8 @@ describe('useWiredCreatorToolsUiStore', () => expect(state.editingValue).toBe(''); expect(state.editingManagedHolderVariableId).toBe(0); expect(state.editingManagedHolderValue).toBe(''); + expect(state.selectedInspectionVariableKeys).toEqual({ furni: '', user: '', global: '' }); + expect(state.selectedVariableKeys).toEqual({ furni: '', user: '', global: '', context: '' }); }); describe('setIsVisible', () => @@ -404,4 +408,54 @@ describe('useWiredCreatorToolsUiStore', () => expect(useWiredCreatorToolsUiStore.getState().editingManagedHolderValue).toBe(''); }); }); + + describe('variable-key records', () => + { + it('setSelectedInspectionVariableKeys accepts the updater shape used by give/remove handlers', () => + { + useWiredCreatorToolsUiStore.getState().setSelectedInspectionVariableKeys(prev => ({ ...prev, furni: '@state' })); + expect(useWiredCreatorToolsUiStore.getState().selectedInspectionVariableKeys).toEqual({ furni: '@state', user: '', global: '' }); + + useWiredCreatorToolsUiStore.getState().setSelectedInspectionVariableKeys(prev => ({ ...prev, user: 'username' })); + expect(useWiredCreatorToolsUiStore.getState().selectedInspectionVariableKeys).toEqual({ furni: '@state', user: 'username', global: '' }); + }); + + it('setSelectedVariableKeys preserves untouched keys when patching a single type', () => + { + useWiredCreatorToolsUiStore.getState().setSelectedVariableKeys(prev => ({ ...prev, furni: '@state', user: 'level' })); + useWiredCreatorToolsUiStore.getState().setSelectedVariableKeys(prev => ({ ...prev, context: 'hotel.uptime' })); + + expect(useWiredCreatorToolsUiStore.getState().selectedVariableKeys).toEqual({ + furni: '@state', + user: 'level', + global: '', + context: 'hotel.uptime' + }); + }); + + it('setSelectedVariableKeys accepts a direct record (definition-sync write path)', () => + { + useWiredCreatorToolsUiStore.getState().setSelectedVariableKeys({ + furni: '~teleport.target_id', + user: 'username', + global: 'hotel.uptime', + context: 'event.type' + }); + + expect(useWiredCreatorToolsUiStore.getState().selectedVariableKeys.furni).toBe('~teleport.target_id'); + expect(useWiredCreatorToolsUiStore.getState().selectedVariableKeys.context).toBe('event.type'); + }); + + it('variable-key records persist across the panel close/reopen lifecycle', () => + { + useWiredCreatorToolsUiStore.getState().setSelectedVariableKeys(prev => ({ ...prev, furni: '@state' })); + useWiredCreatorToolsUiStore.getState().setSelectedInspectionVariableKeys(prev => ({ ...prev, user: 'level' })); + + useWiredCreatorToolsUiStore.getState().setIsVisible(false); + useWiredCreatorToolsUiStore.getState().setIsVisible(true); + + expect(useWiredCreatorToolsUiStore.getState().selectedVariableKeys.furni).toBe('@state'); + expect(useWiredCreatorToolsUiStore.getState().selectedInspectionVariableKeys.user).toBe('level'); + }); + }); }); diff --git a/src/components/wired-tools/wiredCreatorToolsUiStore.ts b/src/components/wired-tools/wiredCreatorToolsUiStore.ts index 03c4c0e..3726b6f 100644 --- a/src/components/wired-tools/wiredCreatorToolsUiStore.ts +++ b/src/components/wired-tools/wiredCreatorToolsUiStore.ts @@ -81,6 +81,16 @@ interface WiredCreatorToolsUiState editingManagedHolderVariableId: number; editingManagedHolderValue: string; + /** + * Currently selected variable key per tab/type, used as the "active" + * row in the Inspection and Variables tabs. The sync effects in + * `WiredCreatorToolsView` auto-pick the first available key whenever + * the definitions list for that type changes, so we initialize empty + * — the component's first paint populates them. + */ + selectedInspectionVariableKeys: Record; + selectedVariableKeys: Record; + setIsVisible: (next: Updater) => void; setActiveTab: (next: WiredToolsTab) => void; setInspectionType: (next: InspectionElementType) => void; @@ -115,6 +125,9 @@ interface WiredCreatorToolsUiState setEditingValue: (next: string) => void; setEditingManagedHolderVariableId: (next: number) => void; setEditingManagedHolderValue: (next: string) => void; + + setSelectedInspectionVariableKeys: (next: Updater>) => void; + setSelectedVariableKeys: (next: Updater>) => void; } export const useWiredCreatorToolsUiStore = createNitroStore()((set) => ({ @@ -152,6 +165,9 @@ export const useWiredCreatorToolsUiStore = createNitroStore set(state => ({ isVisible: apply(state.isVisible, next) })), setActiveTab: (next) => set({ activeTab: next }), setInspectionType: (next) => set({ inspectionType: next }), @@ -185,5 +201,8 @@ export const useWiredCreatorToolsUiStore = createNitroStore set({ editingVariable: next }), setEditingValue: (next) => set({ editingValue: next }), setEditingManagedHolderVariableId: (next) => set({ editingManagedHolderVariableId: next }), - setEditingManagedHolderValue: (next) => set({ editingManagedHolderValue: next }) + setEditingManagedHolderValue: (next) => set({ editingManagedHolderValue: next }), + + setSelectedInspectionVariableKeys: (next) => set(state => ({ selectedInspectionVariableKeys: apply(state.selectedInspectionVariableKeys, next) })), + setSelectedVariableKeys: (next) => set(state => ({ selectedVariableKeys: apply(state.selectedVariableKeys, next) })) }));