(ui) handle empty state

This commit is contained in:
Mary Hipp
2024-10-07 21:08:46 -04:00
committed by Mary Hipp Rogers
parent 5832228fea
commit 7c9779b496
5 changed files with 65 additions and 36 deletions

View File

@@ -870,6 +870,7 @@
"nodeType": "Node Type",
"noFieldsLinearview": "No fields added to Linear View",
"noFieldsViewMode": "This workflow has no selected fields to display. View the full workflow to configure values.",
"workflowHelpText": "Need Help? Check out our guide to <LinkComponent>Getting Started with Workflows</LinkComponent>",
"noNodeSelected": "No node selected",
"nodeOpacity": "Node Opacity",
"nodeVersion": "Node Version",

View File

@@ -28,7 +28,7 @@ const overlayScrollbarsStyles: CSSProperties = {
width: '100%',
};
const selectCleanEditor = createMemoizedSelector([selectNodesSlice, selectWorkflowSlice], (nodes, workflow) => {
export const selectCleanEditor = createMemoizedSelector([selectNodesSlice, selectWorkflowSlice], (nodes, workflow) => {
const noNodes = !nodes.nodes.length;
const isTouched = workflow.isTouched;
return noNodes && !isTouched;

View File

@@ -9,7 +9,7 @@ import { useGetAndLoadLibraryWorkflow } from 'features/workflowLibrary/hooks/use
import type { MouseEvent } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { PiDownloadSimpleBold, PiPencilBold, PiShareFatBold, PiTrashBold } from 'react-icons/pi';
import { PiDownloadSimpleBold, PiPencilBold, PiTrashBold } from 'react-icons/pi';
import type { WorkflowRecordListItemDTO } from 'services/api/types';
export const WorkflowListItem = ({ workflow }: { workflow: WorkflowRecordListItemDTO }) => {
@@ -120,15 +120,6 @@ export const WorkflowListItem = ({ workflow }: { workflow: WorkflowRecordListIte
icon={<PiDownloadSimpleBold />}
isDisabled={!isHovered}
/>
<IconButton
size="sm"
variant="outline"
aria-label={t('stylePresets.deleteTemplate')}
onClick={handleClickDelete}
isLoading={deleteWorkflowResult.isLoading}
icon={<PiShareFatBold />}
isDisabled={!isHovered}
/>
{workflow.category !== 'default' && (
<IconButton
size="sm"

View File

@@ -69,7 +69,7 @@ export const WorkflowListMenu = () => {
) : (
<>
{workflowCategories.map((category) => (
<WorkflowList key={category} title={t(`workflows.${category}Workflows`)} data={data[category]} isLoading />
<WorkflowList key={category} title={t(`workflows.${category}Workflows`)} data={data[category]} />
))}
</>
)}

View File

@@ -1,36 +1,40 @@
import { Button, Flex, Image, Text } from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { selectCleanEditor } from 'features/nodes/components/sidePanel/NodeEditorPanelGroup';
import { $isWorkflowListMenuIsOpen } from 'features/nodes/store/workflowListMenu';
import { workflowModeChanged } from 'features/nodes/store/workflowSlice';
import InvokeLogoSVG from 'public/assets/images/invoke-symbol-wht-lrg.svg';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { Trans, useTranslation } from 'react-i18next';
export const EmptyState = () => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const isCleanEditor = useAppSelector(selectCleanEditor);
const onClick = useCallback(() => {
dispatch(workflowModeChanged('edit'));
}, [dispatch]);
const onClickLoadWorkflow = useCallback(() => {
$isWorkflowListMenuIsOpen.set(true);
}, []);
const onClickNewWorkflow = useCallback(() => {
dispatch(workflowModeChanged('edit'));
}, [dispatch]);
return (
<Flex
sx={{
w: 'full',
h: 'full',
userSelect: 'none',
}}
>
<Flex w="full" userSelect="none" justifyContent="center">
<Flex
sx={{
alignItems: 'center',
justifyContent: 'center',
borderRadius: 'base',
flexDir: 'column',
gap: 5,
maxW: '230px',
margin: '0 auto',
}}
alignItems="center"
justifyContent="center"
borderRadius="base"
flexDir="column"
gap={5}
maxW="230px"
pt={24}
>
<Image
src={InvokeLogoSVG}
@@ -43,12 +47,45 @@ export const EmptyState = () => {
minH={16}
userSelect="none"
/>
<Text textAlign="center" fontSize="md">
{t('nodes.noFieldsViewMode')}
</Text>
<Button colorScheme="invokeBlue" onClick={onClick}>
{t('nodes.edit')}
</Button>
{isCleanEditor ? (
<>
<Flex gap={2}>
<Button size="sm" onClick={onClickNewWorkflow}>
{t('nodes.newWorkflow')}
</Button>
<Button size="sm" colorScheme="invokeBlue" onClick={onClickLoadWorkflow}>
{t('nodes.loadWorkflow')}
</Button>
</Flex>
<Text textAlign="center" fontSize="md">
<Trans
i18nKey="nodes.workflowHelpText"
size="sm"
components={{
LinkComponent: (
<Text
as="a"
color="white"
fontSize="md"
fontWeight="semibold"
href="https://support.invoke.ai/support/solutions/articles/151000159663-example-workflows"
target="_blank"
/>
),
}}
/>
</Text>
</>
) : (
<>
<Text textAlign="center" fontSize="md">
{t('nodes.noFieldsViewMode')}
</Text>
<Button size="sm" colorScheme="invokeBlue" onClick={onClick}>
{t('nodes.edit')}
</Button>
</>
)}
</Flex>
</Flex>
);