Skip to content

Commit 40db4d3

Browse files
committed
add no projects page
1 parent 8b92c62 commit 40db4d3

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

frontend/packages/modelServing/src/GlobalModelsPage.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { ProjectsContext } from '@odh-dashboard/internal/concepts/projects/Proje
33
import { useParams } from 'react-router-dom';
44
import { useExtensions, useResolvedExtensions } from '@odh-dashboard/plugin-core';
55
import { Bullseye, Spinner } from '@patternfly/react-core';
6+
import ApplicationsPage from '@odh-dashboard/internal/pages/ApplicationsPage';
67
import GlobalDeploymentsView from './components/global/GlobalDeploymentsView';
8+
import NoProjectsPage from './components/global/NoProjectsPage';
79
import { ModelDeploymentsProvider } from './concepts/ModelDeploymentsContext';
810
import { ModelServingPlatformProvider } from './concepts/ModelServingPlatformContext';
911
import {
@@ -17,32 +19,48 @@ const GlobalModelsPage: React.FC = () => (
1719
</ModelServingPlatformProvider>
1820
);
1921

22+
type ApplicationPageProps = React.ComponentProps<typeof ApplicationsPage>;
23+
type EmptyStateProps = 'emptyStatePage' | 'empty';
24+
type ApplicationPageRenderState = Pick<ApplicationPageProps, EmptyStateProps>;
25+
2026
const GlobalModelsPageCoreLoader: React.FC = () => {
2127
const availablePlatforms = useExtensions(isModelServingPlatformExtension);
2228
const [deploymentWatchers] = useResolvedExtensions(isModelServingPlatformWatchDeployments);
2329
const { namespace } = useParams();
30+
2431
const { projects, loaded: projectsLoaded } = React.useContext(ProjectsContext);
32+
2533
const selectedProject = namespace
2634
? projects.find((project) => project.metadata.name === namespace)
2735
: null;
2836
const projectsToShow = selectedProject ? [selectedProject] : projects;
37+
38+
let renderStateProps: ApplicationPageRenderState & { children?: React.ReactNode } = {
39+
empty: false,
40+
};
41+
2942
if (!projectsLoaded) {
3043
return (
3144
<Bullseye>
3245
<Spinner />
3346
</Bullseye>
3447
);
3548
}
49+
3650
if (projects.length === 0) {
37-
return <div>No projects found component</div>;
51+
renderStateProps = {
52+
empty: true,
53+
emptyStatePage: <NoProjectsPage />,
54+
};
3855
}
56+
3957
return (
4058
<ModelDeploymentsProvider
4159
modelServingPlatforms={availablePlatforms}
4260
projects={projectsToShow}
4361
deploymentWatchers={deploymentWatchers}
4462
>
45-
<GlobalDeploymentsView />
63+
<GlobalDeploymentsView {...renderStateProps} />
4664
</ModelDeploymentsProvider>
4765
);
4866
};

frontend/packages/modelServing/src/components/global/GlobalDeploymentsView.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,25 @@ import GlobalDeploymentsTable from './GlobalDeploymentsTable';
88
import ModelServingProjectSelection from './ModelServingProjectSelection';
99
import { ModelDeploymentsContext } from '../../concepts/ModelDeploymentsContext';
1010

11-
const GlobalDeploymentsView: React.FC = () => {
11+
type GlobalDeploymentsViewProps = {
12+
empty?: boolean;
13+
emptyStatePage?: React.ReactNode;
14+
};
15+
16+
const GlobalDeploymentsView: React.FC<GlobalDeploymentsViewProps> = ({ empty, emptyStatePage }) => {
1217
const { deployments, loaded: deploymentsLoaded } = React.useContext(ModelDeploymentsContext);
1318
const { preferredProject: currentProject } = React.useContext(ProjectsContext);
1419
const hasDeployments = deployments && deployments.length > 0;
1520
const isLoading = !deploymentsLoaded;
21+
const isEmpty = empty || (!isLoading && !hasDeployments);
1622

1723
return (
1824
<ApplicationsPage
1925
loaded={!isLoading}
20-
empty={!hasDeployments}
21-
emptyStatePage={<GlobalNoModelsView project={currentProject ?? undefined} />}
26+
empty={isEmpty}
27+
emptyStatePage={
28+
emptyStatePage ?? <GlobalNoModelsView project={currentProject ?? undefined} />
29+
}
2230
description="Manage and view the health and performance of your deployed models."
2331
title={
2432
<TitleWithIcon title="Model deployments" objectType={ProjectObjectType.deployedModels} />
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import * as React from 'react';
2+
import { EmptyState, EmptyStateBody, EmptyStateFooter } from '@patternfly/react-core';
3+
import { WrenchIcon } from '@patternfly/react-icons/dist/esm/icons/wrench-icon';
4+
import { useNavigate } from 'react-router-dom';
5+
import NewProjectButton from '@odh-dashboard/internal/pages/projects/screens/projects/NewProjectButton';
6+
7+
const NoProjectsPage: React.FC = () => {
8+
const navigate = useNavigate();
9+
return (
10+
<EmptyState headingLevel="h4" icon={WrenchIcon} titleText="No data science projects">
11+
<EmptyStateBody>To deploy a model, first create a data science project.</EmptyStateBody>
12+
<EmptyStateFooter>
13+
<NewProjectButton
14+
closeOnCreate
15+
onProjectCreated={(projectName) => navigate(`/modelServing/${projectName}`)}
16+
/>
17+
</EmptyStateFooter>
18+
</EmptyState>
19+
);
20+
};
21+
22+
export default NoProjectsPage;

0 commit comments

Comments
 (0)