From f966bb4e2f88e77b9f123ccd66ec0c332339e7f9 Mon Sep 17 00:00:00 2001 From: Jeff Puzzo Date: Tue, 6 Aug 2024 12:01:09 -0400 Subject: [PATCH] [RHOAIENG-7572] Registered Models - Empty View Redesign --- frontend/src/concepts/design/utils.ts | 4 +- .../images/empty-state-model-registries.svg | 9 +++ .../RegisteredModelListView.tsx | 60 ++++++++++++------- .../components/EmptyModelRegistryState.tsx | 31 ++++++---- 4 files changed, 72 insertions(+), 32 deletions(-) create mode 100644 frontend/src/images/empty-state-model-registries.svg diff --git a/frontend/src/concepts/design/utils.ts b/frontend/src/concepts/design/utils.ts index 5fcf9ed8d5..60c4f68aed 100644 --- a/frontend/src/concepts/design/utils.ts +++ b/frontend/src/concepts/design/utils.ts @@ -15,6 +15,7 @@ import pipelineEmptyStateImg from '~/images/empty-state-pipelines.svg'; import clusterStorageEmptyStateImg from '~/images/empty-state-cluster-storage.svg'; import modelServerEmptyStateImg from '~/images/empty-state-model-serving.svg'; import dataConnectionEmptyStateImg from '~/images/empty-state-data-connections.svg'; +import modelRegistryEmptyStateImg from '~/images/empty-state-model-registries.svg'; import './vars.scss'; @@ -114,8 +115,9 @@ export const typedEmptyImage = (objectType: ProjectObjectType): string => { case ProjectObjectType.clusterStorage: return clusterStorageEmptyStateImg; case ProjectObjectType.modelServer: - case ProjectObjectType.registeredModels: return modelServerEmptyStateImg; + case ProjectObjectType.registeredModels: + return modelRegistryEmptyStateImg; case ProjectObjectType.dataConnection: return dataConnectionEmptyStateImg; default: diff --git a/frontend/src/images/empty-state-model-registries.svg b/frontend/src/images/empty-state-model-registries.svg new file mode 100644 index 0000000000..87b06da4eb --- /dev/null +++ b/frontend/src/images/empty-state-model-registries.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/frontend/src/pages/modelRegistry/screens/RegisteredModels/RegisteredModelListView.tsx b/frontend/src/pages/modelRegistry/screens/RegisteredModels/RegisteredModelListView.tsx index 139cb36e66..bbb84258c2 100644 --- a/frontend/src/pages/modelRegistry/screens/RegisteredModels/RegisteredModelListView.tsx +++ b/frontend/src/pages/modelRegistry/screens/RegisteredModels/RegisteredModelListView.tsx @@ -1,18 +1,24 @@ -import * as React from 'react'; -import { SearchInput, ToolbarFilter, ToolbarGroup, ToolbarItem } from '@patternfly/react-core'; -import { FilterIcon } from '@patternfly/react-icons'; -import { useNavigate } from 'react-router'; +import React from 'react'; + +import { + Button, + List, + ListItem, + Popover, + SearchInput, + ToolbarFilter, + ToolbarGroup, + ToolbarItem, +} from '@patternfly/react-core'; +import { FilterIcon, OutlinedQuestionCircleIcon } from '@patternfly/react-icons'; + import { SearchType } from '~/concepts/dashboard/DashboardSearchField'; import { RegisteredModel } from '~/concepts/modelRegistry/types'; import SimpleDropdownSelect from '~/components/SimpleDropdownSelect'; import { filterRegisteredModels } from '~/pages/modelRegistry/screens/utils'; -import { ModelRegistrySelectorContext } from '~/concepts/modelRegistry/context/ModelRegistrySelectorContext'; import EmptyModelRegistryState from '~/pages/modelRegistry/screens/components/EmptyModelRegistryState'; -import { - registerModelUrl, - registeredModelArchiveUrl, -} from '~/pages/modelRegistry/screens/routeUtils'; import { asEnumMember } from '~/utilities/utils'; +import { ProjectObjectType, typedEmptyImage } from '~/concepts/design/utils'; import RegisteredModelTable from './RegisteredModelTable'; import RegisteredModelsTableToolbar from './RegisteredModelsTableToolbar'; @@ -25,8 +31,6 @@ const RegisteredModelListView: React.FC = ({ registeredModels: unfilteredRegisteredModels, refresh, }) => { - const navigate = useNavigate(); - const { preferredModelRegistry } = React.useContext(ModelRegistrySelectorContext); const [searchType, setSearchType] = React.useState(SearchType.KEYWORD); const [search, setSearch] = React.useState(''); @@ -36,16 +40,30 @@ const RegisteredModelListView: React.FC = ({ return ( { - navigate(registerModelUrl(preferredModelRegistry?.metadata.name)); - }} - secondaryActionOnClick={() => { - navigate(registeredModelArchiveUrl(preferredModelRegistry?.metadata.name)); - }} + title="Request access to model registries" + description="To request a new model registry, or to request permission to access an existing model registry, contact your administrator." + headerIcon={() => } + customAction={ + + + The person who gave you your username, or who helped you to log in for the first + time + + Someone in your IT department or help desk + A project manager or developer + + } + > + + + } /> ); } diff --git a/frontend/src/pages/modelRegistry/screens/components/EmptyModelRegistryState.tsx b/frontend/src/pages/modelRegistry/screens/components/EmptyModelRegistryState.tsx index 65d239019c..e223096ff5 100644 --- a/frontend/src/pages/modelRegistry/screens/components/EmptyModelRegistryState.tsx +++ b/frontend/src/pages/modelRegistry/screens/components/EmptyModelRegistryState.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { Button, ButtonVariant, @@ -7,10 +8,10 @@ import { EmptyStateFooter, EmptyStateHeader, EmptyStateIcon, + EmptyStateIconProps, EmptyStateVariant, } from '@patternfly/react-core'; import { PlusCircleIcon } from '@patternfly/react-icons'; -import * as React from 'react'; type EmptyModelRegistryStateType = { testid?: string; @@ -20,6 +21,8 @@ type EmptyModelRegistryStateType = { primaryActionOnClick?: () => void; secondaryActionText?: string; secondaryActionOnClick?: () => void; + headerIcon?: EmptyStateIconProps['icon']; + customAction?: React.ReactNode; }; const EmptyModelRegistryState: React.FC = ({ @@ -30,13 +33,18 @@ const EmptyModelRegistryState: React.FC = ({ secondaryActionText, primaryActionOnClick, secondaryActionOnClick, + headerIcon, + customAction, }) => ( - } /> + } + /> {description} - - {primaryActionText && ( + {primaryActionText && ( + - )} - - - {secondaryActionText && ( + + )} + + {secondaryActionText && ( + - )} - + + )} + + {customAction && {customAction}} );