diff --git a/invokeai/frontend/web/index.d.ts b/invokeai/frontend/web/index.d.ts index 9821091370..4be14302cb 100644 --- a/invokeai/frontend/web/index.d.ts +++ b/invokeai/frontend/web/index.d.ts @@ -1,6 +1,7 @@ import React, { PropsWithChildren } from 'react'; import { IAIPopoverProps } from '../web/src/common/components/IAIPopover'; import { IAIIconButtonProps } from '../web/src/common/components/IAIIconButton'; +import { InvokeTabName } from 'features/ui/store/tabMap'; export {}; @@ -69,6 +70,7 @@ declare module '@invoke-ai/invoke-ai-ui' { interface InvokeProps extends PropsWithChildren { apiUrl?: string; disabledPanels?: string[]; + disabledTabs?: InvokeTabName[]; } declare function Invoke(props: InvokeProps): JSX.Element; diff --git a/invokeai/frontend/web/src/app/App.tsx b/invokeai/frontend/web/src/app/App.tsx index c9b1ed249c..ef843b047e 100644 --- a/invokeai/frontend/web/src/app/App.tsx +++ b/invokeai/frontend/web/src/app/App.tsx @@ -15,13 +15,15 @@ import ImageGalleryPanel from 'features/gallery/components/ImageGalleryPanel'; import Lightbox from 'features/lightbox/components/Lightbox'; import { useAppDispatch, useAppSelector } from './storeHooks'; import { PropsWithChildren, useEffect } from 'react'; -import { setDisabledPanels } from 'features/ui/store/uiSlice'; +import { setDisabledPanels, setDisabledTabs } from 'features/ui/store/uiSlice'; +import { InvokeTabName } from 'features/ui/store/tabMap'; keepGUIAlive(); interface Props extends PropsWithChildren { options: { disabledPanels: string[]; + disabledTabs: InvokeTabName[]; }; } @@ -36,6 +38,10 @@ const App = (props: Props) => { dispatch(setDisabledPanels(props.options.disabledPanels)); }, [dispatch, props.options.disabledPanels]); + useEffect(() => { + dispatch(setDisabledTabs(props.options.disabledTabs)); + }, [dispatch, props.options.disabledTabs]); + useEffect(() => { setColorMode(['light'].includes(currentTheme) ? 'light' : 'dark'); }, [setColorMode, currentTheme]); diff --git a/invokeai/frontend/web/src/component.tsx b/invokeai/frontend/web/src/component.tsx index 9d952c6434..e83b8ff8d5 100644 --- a/invokeai/frontend/web/src/component.tsx +++ b/invokeai/frontend/web/src/component.tsx @@ -4,6 +4,7 @@ import { PersistGate } from 'redux-persist/integration/react'; import { store } from './app/store'; import { persistor } from './persistor'; import { OpenAPI } from 'services/api'; +import { InvokeTabName } from 'features/ui/store/tabMap'; import '@fontsource/inter/100.css'; import '@fontsource/inter/200.css'; import '@fontsource/inter/300.css'; @@ -25,11 +26,13 @@ const ThemeLocaleProvider = lazy(() => import('./app/ThemeLocaleProvider')); interface Props extends PropsWithChildren { apiUrl?: string; disabledPanels?: string[]; + disabledTabs?: InvokeTabName[]; } export default function Component({ apiUrl, disabledPanels = [], + disabledTabs = [], children, }: Props) { useEffect(() => { @@ -42,7 +45,7 @@ export default function Component({ } persistor={persistor}> }> - {children} + {children} diff --git a/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx b/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx index 18db74791b..d7736eb9ea 100644 --- a/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx +++ b/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx @@ -45,38 +45,41 @@ const tabIconStyles: ChakraProps['sx'] = { boxSize: 6, }; -const tabInfo: InvokeTabInfo[] = [ - { - id: 'txt2img', - icon: , - workarea: , - }, - { - id: 'img2img', - icon: , - workarea: , - }, - { - id: 'unifiedCanvas', - icon: , - workarea: , - }, - { - id: 'nodes', - icon: , - workarea: , - }, - { - id: 'postprocessing', - icon: , - workarea: , - }, - { - id: 'training', - icon: , - workarea: , - }, -]; +const buildTabs = (disabledTabs: InvokeTabName[]): InvokeTabInfo[] => { + const tabs: InvokeTabInfo[] = [ + { + id: 'txt2img', + icon: , + workarea: , + }, + { + id: 'img2img', + icon: , + workarea: , + }, + { + id: 'unifiedCanvas', + icon: , + workarea: , + }, + { + id: 'nodes', + icon: , + workarea: , + }, + { + id: 'postprocessing', + icon: , + workarea: , + }, + { + id: 'training', + icon: , + workarea: , + }, + ]; + return tabs.filter((tab) => !disabledTabs.includes(tab.id)); +}; export default function InvokeTabs() { const activeTab = useAppSelector(activeTabIndexSelector); @@ -85,13 +88,10 @@ export default function InvokeTabs() { (state: RootState) => state.lightbox.isLightboxOpen ); - const shouldPinGallery = useAppSelector( - (state: RootState) => state.ui.shouldPinGallery - ); + const { shouldPinGallery, disabledTabs, shouldPinParametersPanel } = + useAppSelector((state: RootState) => state.ui); - const shouldPinParametersPanel = useAppSelector( - (state: RootState) => state.ui.shouldPinParametersPanel - ); + const activeTabs = buildTabs(disabledTabs); const { t } = useTranslation(); @@ -142,7 +142,7 @@ export default function InvokeTabs() { const tabs = useMemo( () => - tabInfo.map((tab) => ( + activeTabs.map((tab) => ( )), - [t] + [t, activeTabs] ); const tabPanels = useMemo( () => - tabInfo.map((tab) => {tab.workarea}), - [] + activeTabs.map((tab) => {tab.workarea}), + [activeTabs] ); return ( diff --git a/invokeai/frontend/web/src/features/ui/store/uiSlice.ts b/invokeai/frontend/web/src/features/ui/store/uiSlice.ts index 7fb36bf9b2..8ab2db57e3 100644 --- a/invokeai/frontend/web/src/features/ui/store/uiSlice.ts +++ b/invokeai/frontend/web/src/features/ui/store/uiSlice.ts @@ -17,6 +17,7 @@ const initialtabsState: UIState = { shouldPinGallery: true, shouldShowGallery: true, disabledParameterPanels: [], + disabledTabs: [], }; const initialState: UIState = initialtabsState; @@ -96,6 +97,9 @@ export const uiSlice = createSlice({ setDisabledPanels: (state, action: PayloadAction) => { state.disabledParameterPanels = action.payload; }, + setDisabledTabs: (state, action: PayloadAction) => { + state.disabledTabs = action.payload; + }, }, }); @@ -118,6 +122,7 @@ export const { toggleParametersPanel, toggleGalleryPanel, setDisabledPanels, + setDisabledTabs, } = uiSlice.actions; export default uiSlice.reducer; diff --git a/invokeai/frontend/web/src/features/ui/store/uiTypes.ts b/invokeai/frontend/web/src/features/ui/store/uiTypes.ts index c188c5690b..d4d8cfdcfe 100644 --- a/invokeai/frontend/web/src/features/ui/store/uiTypes.ts +++ b/invokeai/frontend/web/src/features/ui/store/uiTypes.ts @@ -1,3 +1,5 @@ +import { InvokeTabName } from './tabMap'; + export type AddNewModelType = 'ckpt' | 'diffusers' | null; export interface UIState { @@ -14,4 +16,5 @@ export interface UIState { shouldPinGallery: boolean; shouldShowGallery: boolean; disabledParameterPanels: string[]; + disabledTabs: InvokeTabName[]; }