mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
workflow library UI updates: scrollbar to make obvious its overflowing, move deselecet all tags to be next to browse button
This commit is contained in:
committed by
psychedelicious
parent
9cc2232b6f
commit
05de3b7a84
@@ -20,12 +20,22 @@ export const overlayScrollbarsParams: UseOverlayScrollbarsParams = {
|
||||
},
|
||||
};
|
||||
|
||||
export const getOverlayScrollbarsParams = (
|
||||
overflowX: 'hidden' | 'scroll' = 'hidden',
|
||||
overflowY: 'hidden' | 'scroll' = 'scroll'
|
||||
) => {
|
||||
export const getOverlayScrollbarsParams = ({
|
||||
overflowX = 'hidden',
|
||||
overflowY = 'scroll',
|
||||
visibility = 'auto',
|
||||
}: {
|
||||
overflowX?: 'hidden' | 'scroll';
|
||||
overflowY?: 'hidden' | 'scroll';
|
||||
visibility?: 'auto' | 'hidden' | 'visible';
|
||||
}) => {
|
||||
const params = deepClone(overlayScrollbarsParams);
|
||||
merge(params, { options: { overflow: { y: overflowY, x: overflowX } } });
|
||||
merge(params, {
|
||||
options: {
|
||||
overflow: { y: overflowY, x: overflowX },
|
||||
scrollbars: { visibility, autoHide: visibility === 'visible' ? 'never' : 'scroll' },
|
||||
},
|
||||
});
|
||||
return params;
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import { PiXBold } from 'react-icons/pi';
|
||||
|
||||
import type { FieldComponentProps } from './types';
|
||||
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
|
||||
|
||||
const sx = {
|
||||
borderWidth: 1,
|
||||
|
||||
@@ -24,7 +24,7 @@ import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDebounce } from 'use-debounce';
|
||||
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
|
||||
|
||||
export const FloatGeneratorFieldInputComponent = memo(
|
||||
(props: FieldComponentProps<FloatGeneratorFieldInputInstance, FloatGeneratorFieldInputTemplate>) => {
|
||||
|
||||
@@ -24,7 +24,7 @@ import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
import type { FieldComponentProps } from './types';
|
||||
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
|
||||
|
||||
const sx = {
|
||||
borderWidth: 1,
|
||||
|
||||
@@ -17,7 +17,7 @@ import type { ChangeEvent } from 'react';
|
||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
|
||||
|
||||
export const ImageGeneratorFieldInputComponent = memo(
|
||||
(props: FieldComponentProps<ImageGeneratorFieldInputInstance, ImageGeneratorFieldInputTemplate>) => {
|
||||
|
||||
@@ -27,7 +27,7 @@ import { PiXBold } from 'react-icons/pi';
|
||||
|
||||
import type { FieldComponentProps } from './types';
|
||||
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
|
||||
|
||||
const sx = {
|
||||
borderWidth: 1,
|
||||
|
||||
@@ -27,7 +27,7 @@ import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDebounce } from 'use-debounce';
|
||||
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
|
||||
|
||||
export const IntegerGeneratorFieldInputComponent = memo(
|
||||
(props: FieldComponentProps<IntegerGeneratorFieldInputInstance, IntegerGeneratorFieldInputTemplate>) => {
|
||||
|
||||
@@ -17,7 +17,7 @@ import { PiXBold } from 'react-icons/pi';
|
||||
|
||||
import type { FieldComponentProps } from './types';
|
||||
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
|
||||
|
||||
const sx = {
|
||||
borderWidth: 1,
|
||||
|
||||
@@ -21,7 +21,7 @@ import type { ChangeEvent } from 'react';
|
||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams().options;
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams({}).options;
|
||||
|
||||
export const StringGeneratorFieldInputComponent = memo(
|
||||
(props: FieldComponentProps<StringGeneratorFieldInputInstance, StringGeneratorFieldInputTemplate>) => {
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
import type { ButtonProps, CheckboxProps } from '@invoke-ai/ui-library';
|
||||
import { Button, Checkbox, Collapse, Flex, Spacer, Text } from '@invoke-ai/ui-library';
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Checkbox,
|
||||
Collapse,
|
||||
Flex,
|
||||
IconButton,
|
||||
Spacer,
|
||||
Text,
|
||||
Tooltip,
|
||||
} from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { getOverlayScrollbarsParams, overlayScrollbarsStyles } from 'common/components/OverlayScrollbars/constants';
|
||||
import type { WorkflowLibraryView, WorkflowTagCategory } from 'features/nodes/store/workflowLibrarySlice';
|
||||
import {
|
||||
$workflowLibraryCategoriesOptions,
|
||||
@@ -15,6 +26,7 @@ import {
|
||||
} from 'features/nodes/store/workflowLibrarySlice';
|
||||
import { NewWorkflowButton } from 'features/workflowLibrary/components/NewWorkflowButton';
|
||||
import { UploadWorkflowButton } from 'features/workflowLibrary/components/UploadWorkflowButton';
|
||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiArrowCounterClockwiseBold, PiUsersBold } from 'react-icons/pi';
|
||||
@@ -25,9 +37,14 @@ export const WorkflowLibrarySideNav = () => {
|
||||
const { t } = useTranslation();
|
||||
const categoryOptions = useStore($workflowLibraryCategoriesOptions);
|
||||
const view = useAppSelector(selectWorkflowLibraryView);
|
||||
const dispatch = useAppDispatch();
|
||||
const selectedTags = useAppSelector(selectWorkflowLibrarySelectedTags);
|
||||
const resetTags = useCallback(() => {
|
||||
dispatch(workflowLibraryTagsReset());
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<Flex h="full" minH={0} overflow="hidden" flexDir="column" w={64} gap={1}>
|
||||
<Flex h="full" minH={0} overflow="hidden" flexDir="column" w={64} gap={0}>
|
||||
<Flex flexDir="column" w="full" pb={2}>
|
||||
<WorkflowLibraryViewButton view="recent">{t('workflows.recentlyOpened')}</WorkflowLibraryViewButton>
|
||||
</Flex>
|
||||
@@ -48,7 +65,26 @@ export const WorkflowLibrarySideNav = () => {
|
||||
)}
|
||||
</Flex>
|
||||
<Flex h="full" minH={0} overflow="hidden" flexDir="column">
|
||||
<WorkflowLibraryViewButton view="defaults">{t('workflows.browseWorkflows')}</WorkflowLibraryViewButton>
|
||||
{view === 'defaults' && selectedTags.length > 0 ? (
|
||||
<ButtonGroup>
|
||||
<WorkflowLibraryViewButton view="defaults" w="auto">
|
||||
{t('workflows.browseWorkflows')}
|
||||
</WorkflowLibraryViewButton>
|
||||
<Tooltip label={t('workflows.deselectAll')}>
|
||||
<IconButton
|
||||
onClick={resetTags}
|
||||
size="md"
|
||||
aria-label={t('workflows.deselectAll')}
|
||||
icon={<PiArrowCounterClockwiseBold size={12} />}
|
||||
variant="ghost"
|
||||
bg="base.700"
|
||||
color="base.50"
|
||||
/>
|
||||
</Tooltip>
|
||||
</ButtonGroup>
|
||||
) : (
|
||||
<WorkflowLibraryViewButton view="defaults">{t('workflows.browseWorkflows')}</WorkflowLibraryViewButton>
|
||||
)}
|
||||
<DefaultsViewCheckboxesCollapsible />
|
||||
</Flex>
|
||||
<Spacer />
|
||||
@@ -58,39 +94,22 @@ export const WorkflowLibrarySideNav = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const overlayscrollbarsOptions = getOverlayScrollbarsParams({ visibility: 'visible' }).options;
|
||||
|
||||
const DefaultsViewCheckboxesCollapsible = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
const tags = useAppSelector(selectWorkflowLibrarySelectedTags);
|
||||
const tagCategoryOptions = useStore($workflowLibraryTagCategoriesOptions);
|
||||
const view = useAppSelector(selectWorkflowLibraryView);
|
||||
|
||||
const resetTags = useCallback(() => {
|
||||
dispatch(workflowLibraryTagsReset());
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<Collapse in={view === 'defaults'}>
|
||||
<Flex flexDir="column" gap={2} pl={4} py={2} overflow="hidden" h="100%" minH={0}>
|
||||
<Button
|
||||
isDisabled={tags.length === 0}
|
||||
onClick={resetTags}
|
||||
size="sm"
|
||||
variant="link"
|
||||
fontWeight="bold"
|
||||
justifyContent="flex-start"
|
||||
flexGrow={0}
|
||||
flexShrink={0}
|
||||
leftIcon={<PiArrowCounterClockwiseBold />}
|
||||
h={8}
|
||||
>
|
||||
{t('workflows.deselectAll')}
|
||||
</Button>
|
||||
<Flex flexDir="column" gap={2} overflow="auto">
|
||||
{tagCategoryOptions.map((tagCategory) => (
|
||||
<TagCategory key={tagCategory.categoryTKey} tagCategory={tagCategory} />
|
||||
))}
|
||||
</Flex>
|
||||
<OverlayScrollbarsComponent style={overlayScrollbarsStyles} options={overlayscrollbarsOptions}>
|
||||
<Flex flexDir="column" gap={2} overflow="auto">
|
||||
{tagCategoryOptions.map((tagCategory) => (
|
||||
<TagCategory key={tagCategory.categoryTKey} tagCategory={tagCategory} />
|
||||
))}
|
||||
</Flex>
|
||||
</OverlayScrollbarsComponent>
|
||||
</Flex>
|
||||
</Collapse>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user