From 9820829edb64334a98fe070e762bbbd77c7378a9 Mon Sep 17 00:00:00 2001 From: Mary Hipp Date: Tue, 4 Apr 2023 14:12:19 -0400 Subject: [PATCH] feat(ui): disable panels based on app props --- invokeai/frontend/web/index.d.ts | 1 + invokeai/frontend/web/src/app/store.ts | 106 +++++++++++++----- invokeai/frontend/web/src/component.tsx | 7 +- .../components/ParametersAccordion.tsx | 29 +++-- .../ImageToImage/ImageToImageParameters.tsx | 2 +- .../TextToImage/TextToImageParameters.tsx | 2 +- .../web/src/features/ui/store/uiSlice.ts | 10 ++ .../web/src/features/ui/store/uiTypes.ts | 1 + invokeai/frontend/web/src/persistor.ts | 4 +- 9 files changed, 112 insertions(+), 50 deletions(-) diff --git a/invokeai/frontend/web/index.d.ts b/invokeai/frontend/web/index.d.ts index 06a362d3a2..9821091370 100644 --- a/invokeai/frontend/web/index.d.ts +++ b/invokeai/frontend/web/index.d.ts @@ -68,6 +68,7 @@ declare module '@invoke-ai/invoke-ai-ui' { interface InvokeProps extends PropsWithChildren { apiUrl?: string; + disabledPanels?: string[]; } declare function Invoke(props: InvokeProps): JSX.Element; diff --git a/invokeai/frontend/web/src/app/store.ts b/invokeai/frontend/web/src/app/store.ts index 1fc09a2c99..762607d64d 100644 --- a/invokeai/frontend/web/src/app/store.ts +++ b/invokeai/frontend/web/src/app/store.ts @@ -5,16 +5,28 @@ import storage from 'redux-persist/lib/storage'; // defaults to localStorage for import { getPersistConfig } from 'redux-deep-persist'; -import canvasReducer from 'features/canvas/store/canvasSlice'; -import galleryReducer from 'features/gallery/store/gallerySlice'; -import resultsReducer from 'features/gallery/store/resultsSlice'; -import uploadsReducer from 'features/gallery/store/uploadsSlice'; -import lightboxReducer from 'features/lightbox/store/lightboxSlice'; -import generationReducer from 'features/parameters/store/generationSlice'; -import postprocessingReducer from 'features/parameters/store/postprocessingSlice'; -import systemReducer from 'features/system/store/systemSlice'; -import uiReducer from 'features/ui/store/uiSlice'; -import apiReducer from 'services/apiSlice'; +import canvasReducer, { canvasSlice } from 'features/canvas/store/canvasSlice'; +import galleryReducer, { + gallerySlice, +} from 'features/gallery/store/gallerySlice'; +import resultsReducer, { + resultsSlice, +} from 'features/gallery/store/resultsSlice'; +import uploadsReducer, { + uploadsSlice, +} from 'features/gallery/store/uploadsSlice'; +import lightboxReducer, { + lightboxSlice, +} from 'features/lightbox/store/lightboxSlice'; +import generationReducer, { + generationSlice, +} from 'features/parameters/store/generationSlice'; +import postprocessingReducer, { + postprocessingSlice, +} from 'features/parameters/store/postprocessingSlice'; +import systemReducer, { systemSlice } from 'features/system/store/systemSlice'; +import uiReducer, { uiSlice } from 'features/ui/store/uiSlice'; +import apiReducer, { apiSlice } from 'services/apiSlice'; import { socketioMiddleware } from './socketio/middleware'; import { socketioMiddleware as nodesSocketioMiddleware } from './nodesSocketio/middleware'; @@ -113,28 +125,60 @@ function buildMiddleware() { } } +interface InitializeStore { + disabledPanels?: string[]; +} + +const disablePanels = ({ + disabledPanels, + enabledParameterPanels, +}: { + disabledPanels: string[]; + enabledParameterPanels: { [key: string]: boolean }; +}) => { + const updatedParameterPanels: { [key: string]: boolean } = {}; + Object.keys(enabledParameterPanels).forEach(function (key, index) { + updatedParameterPanels[key] = + disabledPanels.indexOf(key) >= 0 ? false : true; + }); + return updatedParameterPanels; +}; + // Continue with store setup -export const store = configureStore({ - reducer: persistedReducer, - middleware: (getDefaultMiddleware) => - getDefaultMiddleware({ - immutableCheck: false, - serializableCheck: false, - }).concat(buildMiddleware()), - devTools: { - // Uncommenting these very rapidly called actions makes the redux dev tools output much more readable - actionsDenylist: [ - 'canvas/setCursorPosition', - 'canvas/setStageCoordinates', - 'canvas/setStageScale', - 'canvas/setIsDrawing', - 'canvas/setBoundingBoxCoordinates', - 'canvas/setBoundingBoxDimensions', - 'canvas/setIsDrawing', - 'canvas/addPointToCurrentLine', - ], - }, -}); +export const initializeStore = ({ disabledPanels = [] }: InitializeStore) => + configureStore({ + reducer: persistedReducer, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware({ + immutableCheck: false, + serializableCheck: false, + }).concat(buildMiddleware()), + preloadedState: { + ui: { + ...uiSlice.getInitialState(), + enabledParameterPanels: disablePanels({ + disabledPanels, + enabledParameterPanels: + uiSlice.getInitialState().enabledParameterPanels, + }), + }, + }, + devTools: { + // Uncommenting these very rapidly called actions makes the redux dev tools output much more readable + actionsDenylist: [ + 'canvas/setCursorPosition', + 'canvas/setStageCoordinates', + 'canvas/setStageScale', + 'canvas/setIsDrawing', + 'canvas/setBoundingBoxCoordinates', + 'canvas/setBoundingBoxDimensions', + 'canvas/setIsDrawing', + 'canvas/addPointToCurrentLine', + ], + }, + }); + +const store = initializeStore({}); export type AppGetState = typeof store.getState; export type RootState = ReturnType; diff --git a/invokeai/frontend/web/src/component.tsx b/invokeai/frontend/web/src/component.tsx index a642516417..a20b38774d 100644 --- a/invokeai/frontend/web/src/component.tsx +++ b/invokeai/frontend/web/src/component.tsx @@ -1,7 +1,7 @@ import React, { lazy, PropsWithChildren, useEffect } from 'react'; import { Provider } from 'react-redux'; import { PersistGate } from 'redux-persist/integration/react'; -import { store } from './app/store'; +import { initializeStore } from './app/store'; import { persistor } from './persistor'; import { OpenAPI } from 'services/api'; import '@fontsource/inter/100.css'; @@ -24,16 +24,17 @@ const ThemeLocaleProvider = lazy(() => import('./app/ThemeLocaleProvider')); interface Props extends PropsWithChildren { apiUrl?: string; + disabledPanels?: string[]; } -export default function Component({ apiUrl, children }: Props) { +export default function Component({ apiUrl, disabledPanels, children }: Props) { useEffect(() => { if (apiUrl) OpenAPI.BASE = apiUrl; }, [apiUrl]); return ( - + } persistor={persistor}> }> diff --git a/invokeai/frontend/web/src/features/parameters/components/ParametersAccordion.tsx b/invokeai/frontend/web/src/features/parameters/components/ParametersAccordion.tsx index 76277867de..e0f2e7ce98 100644 --- a/invokeai/frontend/web/src/features/parameters/components/ParametersAccordion.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/ParametersAccordion.tsx @@ -21,9 +21,10 @@ type ParametersAccordionsType = { const ParametersAccordion = (props: ParametersAccordionsType) => { const { accordionInfo } = props; - const openAccordions = useAppSelector( - (state: RootState) => state.system.openAccordions - ); + const { system, ui } = useAppSelector((state: RootState) => state); + + const { openAccordions } = system; + const { enabledParameterPanels } = ui; const dispatch = useAppDispatch(); @@ -39,15 +40,19 @@ const ParametersAccordion = (props: ParametersAccordionsType) => { Object.keys(accordionInfo).forEach((key) => { const { header, feature, content, additionalHeaderComponents } = accordionInfo[key]; - accordionsToRender.push( - - ); + + // do not render if panel is disabled in global state + if (enabledParameterPanels[key] !== false) { + accordionsToRender.push( + + ); + } }); } return accordionsToRender; diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageParameters.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageParameters.tsx index 4989ef034b..fe638bf180 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageParameters.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageParameters.tsx @@ -44,7 +44,7 @@ const ImageToImageParameters = () => { content: , additionalHeaderComponents: , }, - face_restore: { + faceRestore: { header: `${t('parameters.faceRestoration')}`, feature: Feature.FACE_CORRECTION, content: , diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageParameters.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageParameters.tsx index 126dd10228..df84ad2fe5 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageParameters.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageParameters.tsx @@ -38,7 +38,7 @@ const TextToImageParameters = () => { content: , additionalHeaderComponents: , }, - face_restore: { + faceRestore: { header: `${t('parameters.faceRestoration')}`, feature: Feature.FACE_CORRECTION, content: , diff --git a/invokeai/frontend/web/src/features/ui/store/uiSlice.ts b/invokeai/frontend/web/src/features/ui/store/uiSlice.ts index a0eaf46096..530f6ddf7b 100644 --- a/invokeai/frontend/web/src/features/ui/store/uiSlice.ts +++ b/invokeai/frontend/web/src/features/ui/store/uiSlice.ts @@ -16,6 +16,16 @@ const initialtabsState: UIState = { addNewModelUIOption: null, shouldPinGallery: true, shouldShowGallery: true, + enabledParameterPanels: { + general: true, + seed: true, + variations: true, + faceRestore: true, + upscale: true, + symmetry: true, + other: true, + imageToImage: true, + }, }; const initialState: UIState = initialtabsState; diff --git a/invokeai/frontend/web/src/features/ui/store/uiTypes.ts b/invokeai/frontend/web/src/features/ui/store/uiTypes.ts index 900ea703b4..bd3ef33577 100644 --- a/invokeai/frontend/web/src/features/ui/store/uiTypes.ts +++ b/invokeai/frontend/web/src/features/ui/store/uiTypes.ts @@ -13,4 +13,5 @@ export interface UIState { addNewModelUIOption: AddNewModelType; shouldPinGallery: boolean; shouldShowGallery: boolean; + enabledParameterPanels: { [key: string]: boolean }; } diff --git a/invokeai/frontend/web/src/persistor.ts b/invokeai/frontend/web/src/persistor.ts index ee860da3f3..9c76ca8771 100644 --- a/invokeai/frontend/web/src/persistor.ts +++ b/invokeai/frontend/web/src/persistor.ts @@ -1,4 +1,4 @@ -import { store } from 'app/store'; +import { initializeStore } from 'app/store'; import { persistStore } from 'redux-persist'; -export const persistor = persistStore(store); +export const persistor = persistStore(initializeStore({}));