mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): use stickyscrollable for models list
This commit is contained in:
parent
ed4e8624dd
commit
b0add805c5
@ -0,0 +1,32 @@
|
|||||||
|
import type { ButtonProps } from '@invoke-ai/ui-library';
|
||||||
|
import { Button } from '@invoke-ai/ui-library';
|
||||||
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { PiArrowsClockwiseBold } from 'react-icons/pi';
|
||||||
|
|
||||||
|
import { useSyncModels } from './useSyncModels';
|
||||||
|
|
||||||
|
export const SyncModelsButton = memo((props: Omit<ButtonProps, 'aria-label'>) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { syncModels, isLoading } = useSyncModels();
|
||||||
|
const isSyncModelEnabled = useFeatureStatus('syncModels').isFeatureEnabled;
|
||||||
|
|
||||||
|
if (!isSyncModelEnabled) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
leftIcon={<PiArrowsClockwiseBold />}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onClick={syncModels}
|
||||||
|
variant="ghost"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{t('modelManager.syncModels')}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
SyncModelsButton.displayName = 'SyncModelsButton';
|
@ -1,9 +1,10 @@
|
|||||||
import { Box, Button, Flex, Heading } from '@invoke-ai/ui-library';
|
import { Button, Flex, Heading, Spacer } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
import { SyncModelsIconButton } from 'features/modelManagerV2/components/SyncModels/SyncModelsIconButton';
|
import { SyncModelsButton } from 'features/modelManagerV2/components/SyncModels/SyncModelsButton';
|
||||||
import { setSelectedModelKey } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
import { setSelectedModelKey } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { PiPlusBold } from 'react-icons/pi';
|
||||||
|
|
||||||
import ModelList from './ModelManagerPanel/ModelList';
|
import ModelList from './ModelManagerPanel/ModelList';
|
||||||
import { ModelListNavigation } from './ModelManagerPanel/ModelListNavigation';
|
import { ModelListNavigation } from './ModelManagerPanel/ModelListNavigation';
|
||||||
@ -16,20 +17,19 @@ export const ModelManager = () => {
|
|||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box layerStyle="first" p={3} borderRadius="base" w="50%" h="full">
|
<Flex flexDir="column" layerStyle="first" p={4} gap={4} borderRadius="base" w="50%" h="full">
|
||||||
<Flex w="full" p={3} justifyContent="space-between" alignItems="center">
|
<Flex w="full" gap={4} justifyContent="space-between" alignItems="center">
|
||||||
<Flex gap={2}>
|
|
||||||
<Heading fontSize="xl">{t('common.modelManager')}</Heading>
|
<Heading fontSize="xl">{t('common.modelManager')}</Heading>
|
||||||
<SyncModelsIconButton />
|
<Spacer />
|
||||||
</Flex>
|
<SyncModelsButton />
|
||||||
<Button colorScheme="invokeYellow" onClick={handleClickAddModel}>
|
<Button colorScheme="invokeYellow" leftIcon={<PiPlusBold />} onClick={handleClickAddModel}>
|
||||||
{t('modelManager.addModels')}
|
{t('modelManager.addModels')}
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Box layerStyle="second" p={3} borderRadius="base" w="full" h="full">
|
<Flex flexDir="column" layerStyle="second" p={4} gap={4} borderRadius="base" w="full" h="full">
|
||||||
<ModelListNavigation />
|
<ModelListNavigation />
|
||||||
<ModelList />
|
<ModelList />
|
||||||
</Box>
|
</Flex>
|
||||||
</Box>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Flex, Spinner, Text } from '@invoke-ai/ui-library';
|
import { Flex, Spinner, Text } from '@invoke-ai/ui-library';
|
||||||
import type { EntityState } from '@reduxjs/toolkit';
|
import type { EntityState } from '@reduxjs/toolkit';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
||||||
import { forEach } from 'lodash-es';
|
import { forEach } from 'lodash-es';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { ALL_BASE_MODELS } from 'services/api/constants';
|
import { ALL_BASE_MODELS } from 'services/api/constants';
|
||||||
@ -73,8 +74,8 @@ const ModelList = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex flexDirection="column" p={4}>
|
<ScrollableContent>
|
||||||
<Flex flexDirection="column" maxHeight={window.innerHeight - 130} overflow="scroll">
|
<Flex flexDirection="column" w="full" h="full" gap={4}>
|
||||||
{/* Main Model List */}
|
{/* Main Model List */}
|
||||||
{isLoadingMainModels && <FetchingModelsLoader loadingMessage="Loading Main..." />}
|
{isLoadingMainModels && <FetchingModelsLoader loadingMessage="Loading Main..." />}
|
||||||
{!isLoadingMainModels && filteredMainModels.length > 0 && (
|
{!isLoadingMainModels && filteredMainModels.length > 0 && (
|
||||||
@ -118,7 +119,7 @@ const ModelList = () => {
|
|||||||
<ModelListWrapper title="T2I Adapters" modelList={filteredT2iAdapterModels} key="t2i-adapters" />
|
<ModelListWrapper title="T2I Adapters" modelList={filteredT2iAdapterModels} key="t2i-adapters" />
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</ScrollableContent>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -148,7 +149,7 @@ const modelsFilter = <T extends AnyModelConfig>(
|
|||||||
|
|
||||||
const FetchingModelsLoader = memo(({ loadingMessage }: { loadingMessage?: string }) => {
|
const FetchingModelsLoader = memo(({ loadingMessage }: { loadingMessage?: string }) => {
|
||||||
return (
|
return (
|
||||||
<Flex flexDirection="column" gap={4} borderRadius={4} p={4} bg="base.800">
|
<Flex flexDirection="column" gap={4} borderRadius="base" p={4} bg="base.800">
|
||||||
<Flex justifyContent="center" alignItems="center" flexDirection="column" p={4} gap={8}>
|
<Flex justifyContent="center" alignItems="center" flexDirection="column" p={4} gap={8}>
|
||||||
<Spinner />
|
<Spinner />
|
||||||
<Text variant="subtext">{loadingMessage ? loadingMessage : 'Fetching...'}</Text>
|
<Text variant="subtext">{loadingMessage ? loadingMessage : 'Fetching...'}</Text>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Flex } from '@invoke-ai/ui-library';
|
import { StickyScrollable } from 'features/system/components/StickyScrollable';
|
||||||
import type { AnyModelConfig } from 'services/api/types';
|
import type { AnyModelConfig } from 'services/api/types';
|
||||||
|
|
||||||
import { ModelListHeader } from './ModelListHeader';
|
|
||||||
import ModelListItem from './ModelListItem';
|
import ModelListItem from './ModelListItem';
|
||||||
|
|
||||||
type ModelListWrapperProps = {
|
type ModelListWrapperProps = {
|
||||||
@ -12,14 +11,10 @@ type ModelListWrapperProps = {
|
|||||||
export const ModelListWrapper = (props: ModelListWrapperProps) => {
|
export const ModelListWrapper = (props: ModelListWrapperProps) => {
|
||||||
const { title, modelList } = props;
|
const { title, modelList } = props;
|
||||||
return (
|
return (
|
||||||
<Flex flexDirection="column" p="10px 0">
|
<StickyScrollable title={title}>
|
||||||
<Flex gap={2} flexDir="column">
|
|
||||||
<ModelListHeader title={title} />
|
|
||||||
|
|
||||||
{modelList.map((model) => (
|
{modelList.map((model) => (
|
||||||
<ModelListItem key={model.key} model={model} />
|
<ModelListItem key={model.key} model={model} />
|
||||||
))}
|
))}
|
||||||
</Flex>
|
</StickyScrollable>
|
||||||
</Flex>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user