diff --git a/invokeai/frontend/web/src/app/components/GlobalHookIsolator.tsx b/invokeai/frontend/web/src/app/components/GlobalHookIsolator.tsx index 35e6862fdf..77d7eb2b9e 100644 --- a/invokeai/frontend/web/src/app/components/GlobalHookIsolator.tsx +++ b/invokeai/frontend/web/src/app/components/GlobalHookIsolator.tsx @@ -10,7 +10,6 @@ import type { PartialAppConfig } from 'app/types/invokeai'; import { useFocusRegionWatcher } from 'common/hooks/focus'; import { useCloseChakraTooltipsOnDragFix } from 'common/hooks/useCloseChakraTooltipsOnDragFix'; import { useGlobalHotkeys } from 'common/hooks/useGlobalHotkeys'; -import { size } from 'es-toolkit/compat'; import { useDynamicPromptsWatcher } from 'features/dynamicPrompts/hooks/useDynamicPromptsWatcher'; import { useStarterModelsToast } from 'features/modelManagerV2/hooks/useStarterModelsToast'; import { useWorkflowBuilderWatcher } from 'features/nodes/components/sidePanel/workflow/IsolatedWorkflowBuilderWatcher'; @@ -55,10 +54,8 @@ export const GlobalHookIsolator = memo( }, [language]); useEffect(() => { - if (size(config)) { - logger.info({ config }, 'Received config'); - dispatch(configChanged(config)); - } + logger.info({ config }, 'Received config'); + dispatch(configChanged(config)); }, [dispatch, config, logger]); useEffect(() => { diff --git a/invokeai/frontend/web/src/features/system/store/configSlice.ts b/invokeai/frontend/web/src/features/system/store/configSlice.ts index 5b4d219c5c..71f17d14c2 100644 --- a/invokeai/frontend/web/src/features/system/store/configSlice.ts +++ b/invokeai/frontend/web/src/features/system/store/configSlice.ts @@ -16,7 +16,8 @@ const baseDimensionConfig: NumericalParameterConfig = { coarseStep: 64, }; -const initialConfigState: AppConfig = { +const initialConfigState: AppConfig & { didLoad: boolean } = { + didLoad: false, isLocal: true, shouldUpdateImagesOnConnect: false, shouldFetchMetadataFromApi: false, @@ -191,6 +192,7 @@ export const configSlice = createSlice({ reducers: { configChanged: (state, action: PayloadAction) => { merge(state, action.payload); + state.didLoad = true; }, }, }); @@ -198,7 +200,8 @@ export const configSlice = createSlice({ export const { configChanged } = configSlice.actions; export const selectConfigSlice = (state: RootState) => state.config; -const createConfigSelector = (selector: Selector) => createSelector(selectConfigSlice, selector); +const createConfigSelector = (selector: Selector) => + createSelector(selectConfigSlice, selector); export const selectWidthConfig = createConfigSelector((config) => config.sd.width); export const selectHeightConfig = createConfigSelector((config) => config.sd.height); @@ -236,3 +239,23 @@ export const selectEnabledTabs = createConfigSelector((config) => { } return enabledTabs; }); +const selectDisabledTabs = createConfigSelector((config) => config.disabledTabs); +const selectDidLoad = createConfigSelector((config) => config.didLoad); +export const selectWithGenerateTab = createSelector(selectDidLoad, selectDisabledTabs, (didLoad, disabledTabs) => + didLoad ? !disabledTabs.includes('generate') : false +); +export const selectWithCanvasTab = createSelector(selectDidLoad, selectDisabledTabs, (didLoad, disabledTabs) => + didLoad ? !disabledTabs.includes('canvas') : false +); +export const selectWithUpscalingTab = createSelector(selectDidLoad, selectDisabledTabs, (didLoad, disabledTabs) => + didLoad ? !disabledTabs.includes('upscaling') : false +); +export const selectWithWorkflowsTab = createSelector(selectDidLoad, selectDisabledTabs, (didLoad, disabledTabs) => + didLoad ? !disabledTabs.includes('workflows') : false +); +export const selectWithModelsTab = createSelector(selectDidLoad, selectDisabledTabs, (didLoad, disabledTabs) => + didLoad ? !disabledTabs.includes('models') : false +); +export const selectWithQueueTab = createSelector(selectDidLoad, selectDisabledTabs, (didLoad, disabledTabs) => + didLoad ? !disabledTabs.includes('queue') : false +); diff --git a/invokeai/frontend/web/src/features/ui/components/AppContent.tsx b/invokeai/frontend/web/src/features/ui/components/AppContent.tsx index 7952177192..618877f578 100644 --- a/invokeai/frontend/web/src/features/ui/components/AppContent.tsx +++ b/invokeai/frontend/web/src/features/ui/components/AppContent.tsx @@ -4,6 +4,14 @@ import 'features/ui/styles/dockview-theme-invoke.css'; import { TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { useDndMonitor } from 'features/dnd/useDndMonitor'; +import { + selectWithCanvasTab, + selectWithGenerateTab, + selectWithModelsTab, + selectWithQueueTab, + selectWithUpscalingTab, + selectWithWorkflowsTab, +} from 'features/system/store/configSlice'; import { VerticalNavBar } from 'features/ui/components/VerticalNavBar'; import { CanvasTabAutoLayout } from 'features/ui/layouts/canvas-tab-auto-layout'; import { GenerateTabAutoLayout } from 'features/ui/layouts/generate-tab-auto-layout'; @@ -12,48 +20,53 @@ import { WorkflowsTabAutoLayout } from 'features/ui/layouts/workflows-tab-auto-l import { selectActiveTabIndex } from 'features/ui/store/uiSelectors'; import { memo } from 'react'; -import { TabMountGate } from './TabMountGate'; import ModelManagerTab from './tabs/ModelManagerTab'; import QueueTab from './tabs/QueueTab'; export const AppContent = memo(() => { - const tabIndex = useAppSelector(selectActiveTabIndex); useDndMonitor(); + const tabIndex = useAppSelector(selectActiveTabIndex); + const withGenerateTab = useAppSelector(selectWithGenerateTab); + const withCanvasTab = useAppSelector(selectWithCanvasTab); + const withUpscalingTab = useAppSelector(selectWithUpscalingTab); + const withWorkflowsTab = useAppSelector(selectWithWorkflowsTab); + const withModelsTab = useAppSelector(selectWithModelsTab); + const withQueueTab = useAppSelector(selectWithQueueTab); return ( - + {withGenerateTab && ( - - + )} + {withCanvasTab && ( - - + )} + {withUpscalingTab && ( - - + )} + {withWorkflowsTab && ( - - + )} + {withModelsTab && ( - - + )} + {withQueueTab && ( - + )} ); diff --git a/invokeai/frontend/web/src/features/ui/components/VerticalNavBar.tsx b/invokeai/frontend/web/src/features/ui/components/VerticalNavBar.tsx index 3a91f96664..3dee456ab6 100644 --- a/invokeai/frontend/web/src/features/ui/components/VerticalNavBar.tsx +++ b/invokeai/frontend/web/src/features/ui/components/VerticalNavBar.tsx @@ -1,11 +1,19 @@ import { Flex, Spacer } from '@invoke-ai/ui-library'; import { useStore } from '@nanostores/react'; import { $customNavComponent } from 'app/store/nanostores/customNavComponent'; +import { useAppSelector } from 'app/store/storeHooks'; import InvokeAILogoComponent from 'features/system/components/InvokeAILogoComponent'; import SettingsMenu from 'features/system/components/SettingsModal/SettingsMenu'; import StatusIndicator from 'features/system/components/StatusIndicator'; import { VideosModalButton } from 'features/system/components/VideosModal/VideosModalButton'; -import { TabMountGate } from 'features/ui/components/TabMountGate'; +import { + selectWithCanvasTab, + selectWithGenerateTab, + selectWithModelsTab, + selectWithQueueTab, + selectWithUpscalingTab, + selectWithWorkflowsTab, +} from 'features/system/store/configSlice'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { @@ -23,29 +31,23 @@ import { TabButton } from './TabButton'; export const VerticalNavBar = memo(() => { const { t } = useTranslation(); const customNavComponent = useStore($customNavComponent); + const withGenerateTab = useAppSelector(selectWithGenerateTab); + const withCanvasTab = useAppSelector(selectWithCanvasTab); + const withUpscalingTab = useAppSelector(selectWithUpscalingTab); + const withWorkflowsTab = useAppSelector(selectWithWorkflowsTab); + const withModelsTab = useAppSelector(selectWithModelsTab); + const withQueueTab = useAppSelector(selectWithQueueTab); return ( - - } label="Generate" /> - - - } label={t('ui.tabs.canvas')} /> - - - } label={t('ui.tabs.upscaling')} /> - - - } label={t('ui.tabs.workflows')} /> - - - } label={t('ui.tabs.models')} /> - - - } label={t('ui.tabs.queue')} /> - + {withGenerateTab && } label="Generate" />} + {withCanvasTab && } label={t('ui.tabs.canvas')} />} + {withUpscalingTab && } label={t('ui.tabs.upscaling')} />} + {withWorkflowsTab && } label={t('ui.tabs.workflows')} />} + {withModelsTab && } label={t('ui.tabs.models')} />} + {withQueueTab && } label={t('ui.tabs.queue')} />}