diff --git a/invokeai/frontend/web/package.json b/invokeai/frontend/web/package.json index 4cedfd81e8..5ac1c7f9d3 100644 --- a/invokeai/frontend/web/package.json +++ b/invokeai/frontend/web/package.json @@ -110,6 +110,7 @@ "prettier": "^2.8.4", "rollup-plugin-visualizer": "^5.9.0", "terser": "^5.16.4", + "ts-toolbelt": "^9.6.0", "typescript": "4.9.5", "vite": "^4.1.2", "vite-plugin-eslint": "^1.8.1", diff --git a/invokeai/frontend/web/src/app/App.tsx b/invokeai/frontend/web/src/app/App.tsx index 787821611c..f30bdc0eb3 100644 --- a/invokeai/frontend/web/src/app/App.tsx +++ b/invokeai/frontend/web/src/app/App.tsx @@ -18,7 +18,7 @@ import { PropsWithChildren, useCallback, useEffect, useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import Loading from 'common/components/Loading/Loading'; import { useIsApplicationReady } from 'features/system/hooks/useIsApplicationReady'; -import { AppConfig } from './invokeai'; +import { PartialAppConfig } from './invokeai'; import { useGlobalHotkeys } from 'common/hooks/useGlobalHotkeys'; import { configChanged } from 'features/system/store/configSlice'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; @@ -26,7 +26,7 @@ import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; keepGUIAlive(); interface Props extends PropsWithChildren { - config?: Partial; + config?: PartialAppConfig; } const App = ({ config = {}, children }: Props) => { diff --git a/invokeai/frontend/web/src/app/invokeai.d.ts b/invokeai/frontend/web/src/app/invokeai.d.ts index 9eadda4f99..3ee0d421e2 100644 --- a/invokeai/frontend/web/src/app/invokeai.d.ts +++ b/invokeai/frontend/web/src/app/invokeai.d.ts @@ -17,6 +17,7 @@ import { InvokeTabName } from 'features/ui/store/tabMap'; import { IRect } from 'konva/lib/types'; import { ImageMetadata, ImageType } from 'services/api'; import { AnyInvocation } from 'services/events/types'; +import { O } from 'ts-toolbelt'; /** * TODO: @@ -425,3 +426,5 @@ export declare type AppConfig = { }; }; }; + +export declare type PartialAppConfig = O.Partial; diff --git a/invokeai/frontend/web/src/component.tsx b/invokeai/frontend/web/src/component.tsx index a3a8c82259..ae962b4ba1 100644 --- a/invokeai/frontend/web/src/component.tsx +++ b/invokeai/frontend/web/src/component.tsx @@ -16,7 +16,7 @@ import '@fontsource/inter/900.css'; import Loading from './common/components/Loading/Loading'; import { addMiddleware, resetMiddlewares } from 'redux-dynamic-middlewares'; -import { AppConfig } from 'app/invokeai'; +import { PartialAppConfig } from 'app/invokeai'; import './i18n'; @@ -26,7 +26,7 @@ const ThemeLocaleProvider = lazy(() => import('./app/ThemeLocaleProvider')); interface Props extends PropsWithChildren { apiUrl?: string; token?: string; - config?: Partial; + config?: PartialAppConfig; } export default function Component({ apiUrl, token, config, children }: Props) { diff --git a/invokeai/frontend/web/src/features/system/store/configSlice.ts b/invokeai/frontend/web/src/features/system/store/configSlice.ts index 6e7f145eef..4339307082 100644 --- a/invokeai/frontend/web/src/features/system/store/configSlice.ts +++ b/invokeai/frontend/web/src/features/system/store/configSlice.ts @@ -1,7 +1,7 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; -import { AppConfig } from 'app/invokeai'; -import { cloneDeep, defaultsDeep } from 'lodash'; +import { AppConfig, PartialAppConfig } from 'app/invokeai'; +import { merge } from 'lodash'; const initialConfigState: AppConfig = { shouldTransformUrls: false, @@ -64,8 +64,8 @@ export const configSlice = createSlice({ name: 'config', initialState: initialConfigState, reducers: { - configChanged: (state, action: PayloadAction>) => { - defaultsDeep(state, cloneDeep(action.payload)); + configChanged: (state, action: PayloadAction) => { + merge(state, action.payload); }, }, }); diff --git a/invokeai/frontend/web/src/main.tsx b/invokeai/frontend/web/src/main.tsx index 8b9e581711..e0423d7e4e 100644 --- a/invokeai/frontend/web/src/main.tsx +++ b/invokeai/frontend/web/src/main.tsx @@ -1,13 +1,7 @@ -import { AppConfig } from 'app/invokeai'; import ReactDOM from 'react-dom/client'; import Component from './component'; -const testConfig: Partial = { - disabledTabs: ['nodes'], - disabledFeatures: ['upscaling'], -}; - ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( - + ); diff --git a/invokeai/frontend/web/yarn.lock b/invokeai/frontend/web/yarn.lock index 8688f1fd41..7cc6ab769b 100644 --- a/invokeai/frontend/web/yarn.lock +++ b/invokeai/frontend/web/yarn.lock @@ -5796,6 +5796,11 @@ ts-node@^10.7.0: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +ts-toolbelt@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz#50a25426cfed500d4a09bd1b3afb6f28879edfd5" + integrity sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w== + tsconfck@^2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-2.0.3.tgz#47b79fc6be3c5ec6ec9b3862d1c959e85038b117"