feat(ui): named install models tabs

This commit is contained in:
psychedelicious
2025-06-27 12:04:57 +10:00
parent 3de186061d
commit 7ba6c67049
8 changed files with 40 additions and 27 deletions

View File

@@ -4,7 +4,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import { InvokeLogoIcon } from 'common/components/InvokeLogoIcon';
import { LOADING_SYMBOL, useHasImages } from 'features/gallery/hooks/useHasImages';
import { $installModelsTab } from 'features/modelManagerV2/store/installModelsStore';
import { setInstallModelsTabByName } from 'features/modelManagerV2/store/installModelsStore';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { selectIsLocal } from 'features/system/store/configSlice';
import { selectActiveTab } from 'features/ui/store/uiSelectors';
@@ -133,12 +133,12 @@ const StarterBundlesCallout = () => {
const handleClickDownloadStarterModels = useCallback(() => {
dispatch(setActiveTab('models'));
$installModelsTab.set(3);
setInstallModelsTabByName('starterModels');
}, [dispatch]);
const handleClickImportModels = useCallback(() => {
dispatch(setActiveTab('models'));
$installModelsTab.set(0);
setInstallModelsTabByName('urlOrLocal');
}, [dispatch]);
return (

View File

@@ -1,6 +1,6 @@
import { Button, Text, useToast } from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks';
import { $installModelsTab } from 'features/modelManagerV2/store/installModelsStore';
import { setInstallModelsTabByName } from 'features/modelManagerV2/store/installModelsStore';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { setActiveTab } from 'features/ui/store/uiSlice';
import { useCallback, useEffect, useState } from 'react';
@@ -45,7 +45,7 @@ const ToastDescription = () => {
const onClick = useCallback(() => {
dispatch(setActiveTab('models'));
$installModelsTab.set(3);
setInstallModelsTabByName('launchpad');
toast.close(TOAST_ID);
}, [dispatch, toast]);

View File

@@ -1,7 +1,16 @@
import { atom } from 'nanostores';
/**
* Atom to manage the active tab index for the Install Models panel.
* Moved to separate file to avoid circular dependencies.
*/
export const $installModelsTab = atom(0);
type InstallModelsTabName = 'launchpad' | 'urlOrLocal' | 'huggingface' | 'scanFolder' | 'starterModels';
const TAB_TO_INDEX_MAP: Record<InstallModelsTabName, number> = {
launchpad: 0,
urlOrLocal: 1,
huggingface: 2,
scanFolder: 3,
starterModels: 4,
};
export const setInstallModelsTabByName = (tab: InstallModelsTabName) => {
$installModelsTabIndex.set(TAB_TO_INDEX_MAP[tab]);
};
export const $installModelsTabIndex = atom(0);

View File

@@ -1,7 +1,7 @@
import { Box, Button, Flex, Grid, Heading, Text } from '@invoke-ai/ui-library';
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
import { useStarterBundleInstall } from 'features/modelManagerV2/hooks/useStarterBundleInstall';
import { $installModelsTab } from 'features/modelManagerV2/store/installModelsStore';
import { setInstallModelsTabByName } from 'features/modelManagerV2/store/installModelsStore';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { PiFolderOpenBold, PiLinkBold, PiStarBold } from 'react-icons/pi';
@@ -31,19 +31,19 @@ export const LaunchpadForm = memo(() => {
);
const navigateToUrlTab = useCallback(() => {
$installModelsTab.set(1); // URL/Local Path tab (now index 1)
setInstallModelsTabByName('urlOrLocal');
}, []);
const navigateToHuggingFaceTab = useCallback(() => {
$installModelsTab.set(2); // HuggingFace tab (now index 2)
setInstallModelsTabByName('huggingface');
}, []);
const navigateToScanFolderTab = useCallback(() => {
$installModelsTab.set(3); // Scan Folder tab (now index 3)
setInstallModelsTabByName('scanFolder');
}, []);
const navigateToStarterModelsTab = useCallback(() => {
$installModelsTab.set(4); // Starter Models tab (now index 4)
setInstallModelsTabByName('starterModels');
}, []);
const handleSD15BundleClick = useCallback(() => {

View File

@@ -1,6 +1,6 @@
import { Box, Button, Flex, Heading, Tab, TabList, TabPanel, TabPanels, Tabs, Text } from '@invoke-ai/ui-library';
import { useStore } from '@nanostores/react';
import { $installModelsTab } from 'features/modelManagerV2/store/installModelsStore';
import { $installModelsTabIndex } from 'features/modelManagerV2/store/installModelsStore';
import { StarterModelsForm } from 'features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StarterModelsForm';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
@@ -14,10 +14,7 @@ import { ScanModelsForm } from './AddModelPanel/ScanFolder/ScanFolderForm';
export const InstallModels = memo(() => {
const { t } = useTranslation();
const index = useStore($installModelsTab);
const onChange = useCallback((index: number) => {
$installModelsTab.set(index);
}, []);
const tabIndex = useStore($installModelsTabIndex);
const onClickLearnMore = useCallback(() => {
window.open('https://support.invoke.ai/support/solutions/articles/151000170961-supported-models');
@@ -31,7 +28,14 @@ export const InstallModels = memo(() => {
<Text variant="subtext">{t('modelManager.learnMoreAboutSupportedModels')}</Text>
</Button>
</Flex>
<Tabs variant="collapse" height="50%" display="flex" flexDir="column" index={index} onChange={onChange}>
<Tabs
variant="collapse"
height="50%"
display="flex"
flexDir="column"
index={tabIndex}
onChange={$installModelsTabIndex.set}
>
<TabList>
<Tab>{t('modelManager.launchpadTab')}</Tab>
<Tab>{t('modelManager.urlOrLocalPath')}</Tab>

View File

@@ -18,7 +18,7 @@ import type { Group, PickerContextState } from 'common/components/Picker/Picker'
import { buildGroup, getRegex, Picker, usePickerContext } from 'common/components/Picker/Picker';
import { useDisclosure } from 'common/hooks/useBoolean';
import { typedMemo } from 'common/util/typedMemo';
import { $installModelsTab } from 'features/modelManagerV2/store/installModelsStore';
import { setInstallModelsTabByName } from 'features/modelManagerV2/store/installModelsStore';
import { BASE_COLOR_MAP } from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelBaseBadge';
import ModelImage from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelImage';
import { NavigateToModelManagerButton } from 'features/parameters/components/MainModel/NavigateToModelManagerButton';
@@ -38,7 +38,7 @@ const ModelManagerLink = memo((props: ButtonProps) => {
const dispatch = useAppDispatch();
const onClick = useCallback(() => {
dispatch(setActiveTab('models'));
$installModelsTab.set(3);
setInstallModelsTabByName('launchpad');
}, [dispatch]);
return (

View File

@@ -11,7 +11,7 @@ import {
} from '@invoke-ai/ui-library';
import { adHocPostProcessingRequested } from 'app/store/middleware/listenerMiddleware/listeners/addAdHocPostProcessingRequestedListener';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { $installModelsTab } from 'features/modelManagerV2/store/installModelsStore';
import { setInstallModelsTabByName } from 'features/modelManagerV2/store/installModelsStore';
import ParamPostProcessingModel from 'features/parameters/components/PostProcessing/ParamPostProcessingModel';
import { selectPostProcessingModel } from 'features/parameters/store/upscaleSlice';
import { useIsQueueMutationInProgress } from 'features/queue/hooks/useIsQueueMutationInProgress';
@@ -78,7 +78,7 @@ const MissingModelWarning = () => {
const handleGoToModelManager = useCallback(() => {
dispatch(setActiveTab('models'));
$installModelsTab.set(3);
setInstallModelsTabByName('launchpad');
}, [dispatch]);
return (

View File

@@ -1,7 +1,7 @@
import { Button, Flex, ListItem, Text, UnorderedList } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { selectModel } from 'features/controlLayers/store/paramsSlice';
import { $installModelsTab } from 'features/modelManagerV2/store/installModelsStore';
import { setInstallModelsTabByName } from 'features/modelManagerV2/store/installModelsStore';
import { useIsTooLargeToUpscale } from 'features/parameters/hooks/useIsTooLargeToUpscale';
import {
selectTileControlNetModel,
@@ -69,7 +69,7 @@ export const UpscaleWarning = () => {
const handleGoToModelManager = useCallback(() => {
dispatch(setActiveTab('models'));
$installModelsTab.set(3);
setInstallModelsTabByName('launchpad');
}, [dispatch]);
if (isBaseModelCompatible && modelWarnings.length > 0 && isModelsTabDisabled) {