From c16ac1d2766673602d84bb6a21039137d2af7e67 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sat, 16 May 2026 11:21:10 +0200 Subject: [PATCH] wired-tools: hoist UI-only state flags to Zustand store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move 14 pure UI flags off useState in WiredCreatorToolsView and into a new feature-local Zustand store (useWiredCreatorToolsUiStore): tab navigation (isVisible, activeTab, inspectionType, variablesType), modal open flags (monitor history/info, inspection give, variable manage, managed give), and the variable-manage / monitor-history filter + sort + page selectors. The setters accept either a value or a (prev => next) updater to preserve the toggle/pagination call sites. WiredInspectionTabView and WiredVariablesTabView now consume the store directly for inspectionType / variablesType / isInspectionGiveOpen, dropping six props from their interfaces. Behaviour is unchanged: every listener and memo in the parent still reads the same values through selectors, and the new tests pin the defaults and setter semantics across the 14 flags. Derived selection state (selectedFurni, monitorSnapshot, variable highlight overlays, etc.) intentionally stays in the parent for this pass — moving those requires moving their listener effects too. --- .../wired-tools/WiredCreatorToolsView.tsx | 48 +++-- .../wired-tools/WiredInspectionTabView.tsx | 22 +-- .../wired-tools/WiredVariablesTabView.tsx | 16 +- .../wired-tools/wiredCreatorToolsUiStore.ts | 85 +++++++++ tests/wiredCreatorToolsUiStore.test.ts | 180 ++++++++++++++++++ 5 files changed, 312 insertions(+), 39 deletions(-) create mode 100644 src/components/wired-tools/wiredCreatorToolsUiStore.ts create mode 100644 tests/wiredCreatorToolsUiStore.test.ts diff --git a/src/components/wired-tools/WiredCreatorToolsView.tsx b/src/components/wired-tools/WiredCreatorToolsView.tsx index de5ae3b..dde13ad 100644 --- a/src/components/wired-tools/WiredCreatorToolsView.tsx +++ b/src/components/wired-tools/WiredCreatorToolsView.tsx @@ -9,6 +9,7 @@ import { useInventoryTrade, useMessageEvent, useNotification, useObjectSelectedE import { DIRECTION_NAMES, EDITABLE_FURNI_VARIABLES, EDITABLE_USER_VARIABLES, INSPECTION_ELEMENTS, MONITOR_ERROR_INFO, MONITOR_LOG_ORDER, MONTH_NAMES, TABS, TEAM_COLOR_NAMES, VARIABLES_ELEMENTS, VARIABLE_DEFINITIONS, WEEKDAY_NAMES, WIRED_CLOCK_REFRESH_MS, WIRED_FREEZE_EFFECT_IDS, WIRED_INSPECTION_REFRESH_MS, WIRED_MONITOR_ACTION_CLEAR_LOGS, WIRED_MONITOR_ACTION_FETCH, WIRED_MONITOR_POLL_MS, WIRED_VARIABLES_POLL_MS } from './WiredCreatorTools.constants'; 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 { useWiredCreatorToolsUiStore } from './wiredCreatorToolsUiStore'; import { WiredInspectionTabView } from './WiredInspectionTabView'; import { WiredMonitorTabView } from './WiredMonitorTabView'; import { WiredToolsSettingsTabView } from './WiredToolsSettingsTabView'; @@ -16,10 +17,13 @@ import { WiredVariablesTabView } from './WiredVariablesTabView'; export const WiredCreatorToolsView: FC<{}> = () => { - const [ isVisible, setIsVisible ] = useState(false); - const [ activeTab, setActiveTab ] = useState('monitor'); - const [ inspectionType, setInspectionType ] = useState('furni'); - const [ variablesType, setVariablesType ] = useState('furni'); + const isVisible = useWiredCreatorToolsUiStore(s => s.isVisible); + const setIsVisible = useWiredCreatorToolsUiStore(s => s.setIsVisible); + const activeTab = useWiredCreatorToolsUiStore(s => s.activeTab); + const setActiveTab = useWiredCreatorToolsUiStore(s => s.setActiveTab); + const inspectionType = useWiredCreatorToolsUiStore(s => s.inspectionType); + const setInspectionType = useWiredCreatorToolsUiStore(s => s.setInspectionType); + const variablesType = useWiredCreatorToolsUiStore(s => s.variablesType); const [ keepSelected, setKeepSelected ] = useState(false); const [ selectedFurni, setSelectedFurni ] = useState(null); const [ selectedFurniLiveState, setSelectedFurniLiveState ] = useState(null); @@ -31,10 +35,14 @@ export const WiredCreatorToolsView: FC<{}> = () => const [ monitorSnapshot, setMonitorSnapshot ] = useState(() => createEmptyMonitorSnapshot()); const [ selectedMonitorErrorType, setSelectedMonitorErrorType ] = useState(null); const [ selectedMonitorLogDetails, setSelectedMonitorLogDetails ] = useState(null); - const [ isMonitorHistoryOpen, setIsMonitorHistoryOpen ] = useState(false); - const [ isMonitorInfoOpen, setIsMonitorInfoOpen ] = useState(false); - const [ monitorHistorySeverityFilter, setMonitorHistorySeverityFilter ] = useState<'ALL' | 'ERROR' | 'WARNING'>('ALL'); - const [ monitorHistoryTypeFilter, setMonitorHistoryTypeFilter ] = useState('ALL'); + const isMonitorHistoryOpen = useWiredCreatorToolsUiStore(s => s.isMonitorHistoryOpen); + const setIsMonitorHistoryOpen = useWiredCreatorToolsUiStore(s => s.setIsMonitorHistoryOpen); + const isMonitorInfoOpen = useWiredCreatorToolsUiStore(s => s.isMonitorInfoOpen); + const setIsMonitorInfoOpen = useWiredCreatorToolsUiStore(s => s.setIsMonitorInfoOpen); + const monitorHistorySeverityFilter = useWiredCreatorToolsUiStore(s => s.monitorHistorySeverityFilter); + const setMonitorHistorySeverityFilter = useWiredCreatorToolsUiStore(s => s.setMonitorHistorySeverityFilter); + const monitorHistoryTypeFilter = useWiredCreatorToolsUiStore(s => s.monitorHistoryTypeFilter); + const setMonitorHistoryTypeFilter = useWiredCreatorToolsUiStore(s => s.setMonitorHistoryTypeFilter); const [ editingVariable, setEditingVariable ] = useState(null); const [ editingValue, setEditingValue ] = useState(''); const [ selectedInspectionVariableKeys, setSelectedInspectionVariableKeys ] = useState>({ @@ -42,18 +50,24 @@ export const WiredCreatorToolsView: FC<{}> = () => user: '', global: '' }); - const [ isInspectionGiveOpen, setIsInspectionGiveOpen ] = useState(false); + const isInspectionGiveOpen = useWiredCreatorToolsUiStore(s => s.isInspectionGiveOpen); + const setIsInspectionGiveOpen = useWiredCreatorToolsUiStore(s => s.setIsInspectionGiveOpen); const [ inspectionGiveVariableItemId, setInspectionGiveVariableItemId ] = useState(0); const [ inspectionGiveValue, setInspectionGiveValue ] = useState('0'); - const [ isVariableManageOpen, setIsVariableManageOpen ] = useState(false); - const [ variableManageTypeFilter, setVariableManageTypeFilter ] = useState('ALL'); - const [ variableManageSort, setVariableManageSort ] = useState('highest_value'); - const [ variableManagePage, setVariableManagePage ] = useState(1); + const isVariableManageOpen = useWiredCreatorToolsUiStore(s => s.isVariableManageOpen); + const setIsVariableManageOpen = useWiredCreatorToolsUiStore(s => s.setIsVariableManageOpen); + const variableManageTypeFilter = useWiredCreatorToolsUiStore(s => s.variableManageTypeFilter); + const setVariableManageTypeFilter = useWiredCreatorToolsUiStore(s => s.setVariableManageTypeFilter); + const variableManageSort = useWiredCreatorToolsUiStore(s => s.variableManageSort); + const setVariableManageSort = useWiredCreatorToolsUiStore(s => s.setVariableManageSort); + const variableManagePage = useWiredCreatorToolsUiStore(s => s.variableManagePage); + const setVariableManagePage = useWiredCreatorToolsUiStore(s => s.setVariableManagePage); const [ selectedManagedVariableEntry, setSelectedManagedVariableEntry ] = useState(null); const [ selectedManagedHolderVariableId, setSelectedManagedHolderVariableId ] = useState(0); const [ editingManagedHolderVariableId, setEditingManagedHolderVariableId ] = useState(0); const [ editingManagedHolderValue, setEditingManagedHolderValue ] = useState(''); - const [ isManagedGiveOpen, setIsManagedGiveOpen ] = useState(false); + const isManagedGiveOpen = useWiredCreatorToolsUiStore(s => s.isManagedGiveOpen); + const setIsManagedGiveOpen = useWiredCreatorToolsUiStore(s => s.setIsManagedGiveOpen); const [ managedGiveVariableItemId, setManagedGiveVariableItemId ] = useState(0); const [ managedGiveValue, setManagedGiveValue ] = useState('0'); const [ isVariableHighlightActive, setIsVariableHighlightActive ] = useState(false); @@ -3085,8 +3099,6 @@ export const WiredCreatorToolsView: FC<{}> = () => /> } { (activeTab === 'inspection') && = () => setSelectedInspectionVariableKeys(prev => ({ ...prev, [inspectionType]: variable.key })); beginVariableEdit(variable); } } - isInspectionGiveOpen={ isInspectionGiveOpen } - onToggleInspectionGive={ () => setIsInspectionGiveOpen(value => !value) } selectedInspectionGiveDefinition={ selectedInspectionGiveDefinition } onSelectGiveVariable={ setInspectionGiveVariableItemId } availableInspectionDefinitions={ availableInspectionDefinitions } @@ -3124,8 +3134,6 @@ export const WiredCreatorToolsView: FC<{}> = () => /> } { (activeTab === 'variables') && setSelectedVariableKeys(prev => ({ ...prev, [variablesType]: key })) } diff --git a/src/components/wired-tools/WiredInspectionTabView.tsx b/src/components/wired-tools/WiredInspectionTabView.tsx index c364d05..94c7a9c 100644 --- a/src/components/wired-tools/WiredInspectionTabView.tsx +++ b/src/components/wired-tools/WiredInspectionTabView.tsx @@ -2,7 +2,8 @@ import { KeyboardEvent } from 'react'; import wiredGlobalPlaceholderImage from '../../assets/images/wiredtools/wired_global_placeholder.png'; import { Button, LayoutAvatarImageView, LayoutPetImageView, LayoutRoomObjectImageView, Text } from '../../common'; import { INSPECTION_ELEMENTS } from './WiredCreatorTools.constants'; -import { InspectionElementType, InspectionFurniSelection, InspectionUserSelection, InspectionVariable } from './WiredCreatorTools.types'; +import { InspectionFurniSelection, InspectionUserSelection, InspectionVariable } from './WiredCreatorTools.types'; +import { useWiredCreatorToolsUiStore } from './wiredCreatorToolsUiStore'; /** * Structural shape we need from the renderer's variable-definition @@ -18,9 +19,7 @@ export interface InspectionGiveDefinition export interface WiredInspectionTabViewProps { - // element type + preview - inspectionType: InspectionElementType; - onInspectionTypeChange: (next: InspectionElementType) => void; + // preview selectedFurni: InspectionFurniSelection | null; selectedUser: InspectionUserSelection | null; roomId: number | null; @@ -44,8 +43,6 @@ export interface WiredInspectionTabViewProps onBeginVariableEdit: (variable: InspectionVariable) => void; // give-variable popover - isInspectionGiveOpen: boolean; - onToggleInspectionGive: () => void; selectedInspectionGiveDefinition: InspectionGiveDefinition | null; onSelectGiveVariable: (itemId: number) => void; availableInspectionDefinitions: InspectionGiveDefinition[]; @@ -67,8 +64,6 @@ export interface WiredInspectionTabViewProps export const WiredInspectionTabView = (props: WiredInspectionTabViewProps) => { const { - inspectionType, - onInspectionTypeChange, selectedFurni, selectedUser, roomId, @@ -84,8 +79,6 @@ export const WiredInspectionTabView = (props: WiredInspectionTabViewProps) => onCancelVariableEdit, onVariableInputKeyDown, onBeginVariableEdit, - isInspectionGiveOpen, - onToggleInspectionGive, selectedInspectionGiveDefinition, onSelectGiveVariable, availableInspectionDefinitions, @@ -97,6 +90,11 @@ export const WiredInspectionTabView = (props: WiredInspectionTabViewProps) => onRemoveInspectionVariable } = props; + const inspectionType = useWiredCreatorToolsUiStore(s => s.inspectionType); + const setInspectionType = useWiredCreatorToolsUiStore(s => s.setInspectionType); + const isInspectionGiveOpen = useWiredCreatorToolsUiStore(s => s.isInspectionGiveOpen); + const setIsInspectionGiveOpen = useWiredCreatorToolsUiStore(s => s.setIsInspectionGiveOpen); + return (
@@ -108,7 +106,7 @@ export const WiredInspectionTabView = (props: WiredInspectionTabViewProps) => key={ element.key } type="button" className={ `w-[42px] h-[38px] rounded border flex items-center justify-center shadow-[inset_0_1px_0_rgba(255,255,255,.7)] ${ (inspectionType === element.key) ? 'border-[#222] bg-[#d9d6cf]' : 'border-[#7f7f7f] bg-[#ece9e1]' }` } - onClick={ () => onInspectionTypeChange(element.key) } + onClick={ () => setInspectionType(element.key) } title={ element.label }> { @@ -225,7 +223,7 @@ export const WiredInspectionTabView = (props: WiredInspectionTabViewProps) =>
diff --git a/src/components/wired-tools/WiredVariablesTabView.tsx b/src/components/wired-tools/WiredVariablesTabView.tsx index 44fcd1b..2ca1ed9 100644 --- a/src/components/wired-tools/WiredVariablesTabView.tsx +++ b/src/components/wired-tools/WiredVariablesTabView.tsx @@ -1,12 +1,11 @@ import { FC } from 'react'; import { Button, Text } from '../../common'; import { VARIABLES_ELEMENTS } from './WiredCreatorTools.constants'; -import { VariableDefinition, VariablesElementType, VariableTextValue } from './WiredCreatorTools.types'; +import { VariableDefinition, VariableTextValue } from './WiredCreatorTools.types'; +import { useWiredCreatorToolsUiStore } from './wiredCreatorToolsUiStore'; export interface WiredVariablesTabViewProps { - variablesType: VariablesElementType; - onVariablesTypeChange: (next: VariablesElementType) => void; variablePickerDefinitions: VariableDefinition[]; selectedVariableDefinition: VariableDefinition | null; onPickVariable: (key: string) => void; @@ -27,8 +26,6 @@ export interface WiredVariablesTabViewProps * testable in isolation. */ export const WiredVariablesTabView: FC = ({ - variablesType, - onVariablesTypeChange, variablePickerDefinitions, selectedVariableDefinition, onPickVariable, @@ -40,7 +37,11 @@ export const WiredVariablesTabView: FC = ({ selectedVariableProperties, selectedVariableTextValues }) => - ( +{ + const variablesType = useWiredCreatorToolsUiStore(s => s.variablesType); + const setVariablesType = useWiredCreatorToolsUiStore(s => s.setVariablesType); + + return (
@@ -52,7 +53,7 @@ export const WiredVariablesTabView: FC = ({ type="button" className={ `w-[42px] h-[38px] rounded border flex items-center justify-center shadow-[inset_0_1px_0_rgba(255,255,255,.7)] ${ element.disabled ? 'border-[#b7b7b7] bg-[#e7e3da] opacity-60 cursor-not-allowed' : ((variablesType === element.key) ? 'border-[#222] bg-[#d9d6cf]' : 'border-[#7f7f7f] bg-[#ece9e1]') }` } disabled={ element.disabled } - onClick={ () => !element.disabled && onVariablesTypeChange(element.key) } + onClick={ () => !element.disabled && setVariablesType(element.key) } title={ element.label }> { @@ -148,3 +149,4 @@ export const WiredVariablesTabView: FC = ({
); +}; diff --git a/src/components/wired-tools/wiredCreatorToolsUiStore.ts b/src/components/wired-tools/wiredCreatorToolsUiStore.ts new file mode 100644 index 0000000..34aaf68 --- /dev/null +++ b/src/components/wired-tools/wiredCreatorToolsUiStore.ts @@ -0,0 +1,85 @@ +import { createNitroStore } from '../../state/createNitroStore'; +import { InspectionElementType, VariablesElementType, WiredToolsTab } from './WiredCreatorTools.types'; + +type MonitorSeverityFilter = 'ALL' | 'ERROR' | 'WARNING'; +type Updater = T | ((prev: T) => T); + +const apply = (prev: T, next: Updater): T => + ((typeof next === 'function') ? (next as (p: T) => T)(prev) : next); + +interface WiredCreatorToolsUiState +{ + isVisible: boolean; + activeTab: WiredToolsTab; + inspectionType: InspectionElementType; + variablesType: VariablesElementType; + + isMonitorHistoryOpen: boolean; + isMonitorInfoOpen: boolean; + isInspectionGiveOpen: boolean; + isVariableManageOpen: boolean; + isManagedGiveOpen: boolean; + + monitorHistorySeverityFilter: MonitorSeverityFilter; + monitorHistoryTypeFilter: string; + + variableManageTypeFilter: string; + variableManageSort: string; + variableManagePage: number; + + setIsVisible: (next: Updater) => void; + setActiveTab: (next: WiredToolsTab) => void; + setInspectionType: (next: InspectionElementType) => void; + setVariablesType: (next: VariablesElementType) => void; + + setIsMonitorHistoryOpen: (next: boolean) => void; + setIsMonitorInfoOpen: (next: boolean) => void; + setIsInspectionGiveOpen: (next: Updater) => void; + setIsVariableManageOpen: (next: boolean) => void; + setIsManagedGiveOpen: (next: Updater) => void; + + setMonitorHistorySeverityFilter: (next: MonitorSeverityFilter) => void; + setMonitorHistoryTypeFilter: (next: string) => void; + + setVariableManageTypeFilter: (next: string) => void; + setVariableManageSort: (next: string) => void; + setVariableManagePage: (next: Updater) => void; +} + +export const useWiredCreatorToolsUiStore = createNitroStore()((set) => ({ + isVisible: false, + activeTab: 'monitor', + inspectionType: 'furni', + variablesType: 'furni', + + isMonitorHistoryOpen: false, + isMonitorInfoOpen: false, + isInspectionGiveOpen: false, + isVariableManageOpen: false, + isManagedGiveOpen: false, + + monitorHistorySeverityFilter: 'ALL', + monitorHistoryTypeFilter: 'ALL', + + variableManageTypeFilter: 'ALL', + variableManageSort: 'highest_value', + variableManagePage: 1, + + setIsVisible: (next) => set(state => ({ isVisible: apply(state.isVisible, next) })), + setActiveTab: (next) => set({ activeTab: next }), + setInspectionType: (next) => set({ inspectionType: next }), + setVariablesType: (next) => set({ variablesType: next }), + + setIsMonitorHistoryOpen: (next) => set({ isMonitorHistoryOpen: next }), + setIsMonitorInfoOpen: (next) => set({ isMonitorInfoOpen: next }), + setIsInspectionGiveOpen: (next) => set(state => ({ isInspectionGiveOpen: apply(state.isInspectionGiveOpen, next) })), + setIsVariableManageOpen: (next) => set({ isVariableManageOpen: next }), + setIsManagedGiveOpen: (next) => set(state => ({ isManagedGiveOpen: apply(state.isManagedGiveOpen, next) })), + + setMonitorHistorySeverityFilter: (next) => set({ monitorHistorySeverityFilter: next }), + setMonitorHistoryTypeFilter: (next) => set({ monitorHistoryTypeFilter: next }), + + setVariableManageTypeFilter: (next) => set({ variableManageTypeFilter: next }), + setVariableManageSort: (next) => set({ variableManageSort: next }), + setVariableManagePage: (next) => set(state => ({ variableManagePage: apply(state.variableManagePage, next) })) +})); diff --git a/tests/wiredCreatorToolsUiStore.test.ts b/tests/wiredCreatorToolsUiStore.test.ts new file mode 100644 index 0000000..9618616 --- /dev/null +++ b/tests/wiredCreatorToolsUiStore.test.ts @@ -0,0 +1,180 @@ +import { beforeEach, describe, expect, it } from 'vitest'; +import { useWiredCreatorToolsUiStore } from '../src/components/wired-tools/wiredCreatorToolsUiStore'; + +const INITIAL = { + isVisible: false, + activeTab: 'monitor' as const, + inspectionType: 'furni' as const, + variablesType: 'furni' as const, + isMonitorHistoryOpen: false, + isMonitorInfoOpen: false, + isInspectionGiveOpen: false, + isVariableManageOpen: false, + isManagedGiveOpen: false, + monitorHistorySeverityFilter: 'ALL' as const, + monitorHistoryTypeFilter: 'ALL', + variableManageTypeFilter: 'ALL', + variableManageSort: 'highest_value', + variableManagePage: 1 +}; + +describe('useWiredCreatorToolsUiStore', () => +{ + beforeEach(() => + { + useWiredCreatorToolsUiStore.setState(INITIAL); + }); + + it('exposes the documented defaults', () => + { + const state = useWiredCreatorToolsUiStore.getState(); + + expect(state.isVisible).toBe(false); + expect(state.activeTab).toBe('monitor'); + expect(state.inspectionType).toBe('furni'); + expect(state.variablesType).toBe('furni'); + expect(state.isMonitorHistoryOpen).toBe(false); + expect(state.isMonitorInfoOpen).toBe(false); + expect(state.isInspectionGiveOpen).toBe(false); + expect(state.isVariableManageOpen).toBe(false); + expect(state.isManagedGiveOpen).toBe(false); + expect(state.monitorHistorySeverityFilter).toBe('ALL'); + expect(state.monitorHistoryTypeFilter).toBe('ALL'); + expect(state.variableManageTypeFilter).toBe('ALL'); + expect(state.variableManageSort).toBe('highest_value'); + expect(state.variableManagePage).toBe(1); + }); + + describe('setIsVisible', () => + { + it('accepts a direct boolean', () => + { + useWiredCreatorToolsUiStore.getState().setIsVisible(true); + expect(useWiredCreatorToolsUiStore.getState().isVisible).toBe(true); + }); + + it('accepts a functional updater (toggle pattern)', () => + { + useWiredCreatorToolsUiStore.getState().setIsVisible(prev => !prev); + expect(useWiredCreatorToolsUiStore.getState().isVisible).toBe(true); + + useWiredCreatorToolsUiStore.getState().setIsVisible(prev => !prev); + expect(useWiredCreatorToolsUiStore.getState().isVisible).toBe(false); + }); + }); + + describe('setActiveTab', () => + { + it('switches the active tab', () => + { + useWiredCreatorToolsUiStore.getState().setActiveTab('variables'); + expect(useWiredCreatorToolsUiStore.getState().activeTab).toBe('variables'); + + useWiredCreatorToolsUiStore.getState().setActiveTab('inspection'); + expect(useWiredCreatorToolsUiStore.getState().activeTab).toBe('inspection'); + }); + }); + + describe('setInspectionType / setVariablesType', () => + { + it('updates the inspection element type', () => + { + useWiredCreatorToolsUiStore.getState().setInspectionType('user'); + expect(useWiredCreatorToolsUiStore.getState().inspectionType).toBe('user'); + }); + + it('updates the variables element type (including context)', () => + { + useWiredCreatorToolsUiStore.getState().setVariablesType('context'); + expect(useWiredCreatorToolsUiStore.getState().variablesType).toBe('context'); + }); + }); + + describe('modal/popover flags', () => + { + it('setIsMonitorHistoryOpen toggles the history modal flag', () => + { + useWiredCreatorToolsUiStore.getState().setIsMonitorHistoryOpen(true); + expect(useWiredCreatorToolsUiStore.getState().isMonitorHistoryOpen).toBe(true); + + useWiredCreatorToolsUiStore.getState().setIsMonitorHistoryOpen(false); + expect(useWiredCreatorToolsUiStore.getState().isMonitorHistoryOpen).toBe(false); + }); + + it('setIsMonitorInfoOpen toggles the info modal flag', () => + { + useWiredCreatorToolsUiStore.getState().setIsMonitorInfoOpen(true); + expect(useWiredCreatorToolsUiStore.getState().isMonitorInfoOpen).toBe(true); + }); + + it('setIsInspectionGiveOpen accepts a functional updater', () => + { + useWiredCreatorToolsUiStore.getState().setIsInspectionGiveOpen(prev => !prev); + expect(useWiredCreatorToolsUiStore.getState().isInspectionGiveOpen).toBe(true); + + useWiredCreatorToolsUiStore.getState().setIsInspectionGiveOpen(prev => !prev); + expect(useWiredCreatorToolsUiStore.getState().isInspectionGiveOpen).toBe(false); + }); + + it('setIsVariableManageOpen takes a direct boolean', () => + { + useWiredCreatorToolsUiStore.getState().setIsVariableManageOpen(true); + expect(useWiredCreatorToolsUiStore.getState().isVariableManageOpen).toBe(true); + }); + + it('setIsManagedGiveOpen accepts a functional updater', () => + { + useWiredCreatorToolsUiStore.getState().setIsManagedGiveOpen(prev => !prev); + expect(useWiredCreatorToolsUiStore.getState().isManagedGiveOpen).toBe(true); + }); + }); + + describe('monitor history filters', () => + { + it('setMonitorHistorySeverityFilter narrows to ERROR / WARNING / ALL', () => + { + useWiredCreatorToolsUiStore.getState().setMonitorHistorySeverityFilter('ERROR'); + expect(useWiredCreatorToolsUiStore.getState().monitorHistorySeverityFilter).toBe('ERROR'); + + useWiredCreatorToolsUiStore.getState().setMonitorHistorySeverityFilter('WARNING'); + expect(useWiredCreatorToolsUiStore.getState().monitorHistorySeverityFilter).toBe('WARNING'); + + useWiredCreatorToolsUiStore.getState().setMonitorHistorySeverityFilter('ALL'); + expect(useWiredCreatorToolsUiStore.getState().monitorHistorySeverityFilter).toBe('ALL'); + }); + + it('setMonitorHistoryTypeFilter stores an arbitrary type label', () => + { + useWiredCreatorToolsUiStore.getState().setMonitorHistoryTypeFilter('FurnitureRuntime'); + expect(useWiredCreatorToolsUiStore.getState().monitorHistoryTypeFilter).toBe('FurnitureRuntime'); + }); + }); + + describe('variable manage UI', () => + { + it('setVariableManageTypeFilter / setVariableManageSort store string filters', () => + { + useWiredCreatorToolsUiStore.getState().setVariableManageTypeFilter('Number'); + useWiredCreatorToolsUiStore.getState().setVariableManageSort('lowest_value'); + + expect(useWiredCreatorToolsUiStore.getState().variableManageTypeFilter).toBe('Number'); + expect(useWiredCreatorToolsUiStore.getState().variableManageSort).toBe('lowest_value'); + }); + + it('setVariableManagePage accepts a direct value', () => + { + useWiredCreatorToolsUiStore.getState().setVariableManagePage(4); + expect(useWiredCreatorToolsUiStore.getState().variableManagePage).toBe(4); + }); + + it('setVariableManagePage accepts a functional updater (next/prev pagination)', () => + { + useWiredCreatorToolsUiStore.getState().setVariableManagePage(2); + useWiredCreatorToolsUiStore.getState().setVariableManagePage(prev => prev + 1); + expect(useWiredCreatorToolsUiStore.getState().variableManagePage).toBe(3); + + useWiredCreatorToolsUiStore.getState().setVariableManagePage(prev => Math.max(1, prev - 1)); + expect(useWiredCreatorToolsUiStore.getState().variableManagePage).toBe(2); + }); + }); +});