diff --git a/frontend/src/pages/projects/screens/detail/ProjectDetailsComponents.tsx b/frontend/src/pages/projects/screens/detail/ProjectDetailsComponents.tsx index 6f0126e7b8..819130f635 100644 --- a/frontend/src/pages/projects/screens/detail/ProjectDetailsComponents.tsx +++ b/frontend/src/pages/projects/screens/detail/ProjectDetailsComponents.tsx @@ -1,12 +1,10 @@ import * as React from 'react'; -import { Divider, PageSection, Stack, StackItem } from '@patternfly/react-core'; +import { PageSection, Stack, StackItem } from '@patternfly/react-core'; import GenericSidebar from '~/components/GenericSidebar'; import { useAppContext } from '~/app/AppContext'; import ServingRuntimeList from '~/pages/modelServing/screens/projects/ServingRuntimeList'; -import { ProjectDetailsContext } from '~/pages/projects/ProjectDetailsContext'; import { featureFlagEnabled } from '~/utilities/utils'; import PipelinesSection from '~/pages/projects/screens/detail/pipelines/PipelinesSection'; -import { usePipelinesAPI } from '~/concepts/pipelines/context'; import NotebooksList from './notebooks/NotebookList'; import { ProjectSectionID } from './types'; import StorageList from './storage/StorageList'; @@ -17,19 +15,10 @@ import useCheckLogoutParams from './useCheckLogoutParams'; type SectionType = { id: ProjectSectionID; component: React.ReactNode; - isEmpty: boolean; }; const ProjectDetailsComponents: React.FC = () => { const { dashboardConfig } = useAppContext(); - const { - notebooks: { data: notebookStates, loaded: notebookStatesLoaded }, - pvcs: { data: pvcs, loaded: pvcsLoaded }, - dataConnections: { data: connections, loaded: connectionsLoaded }, - servingRuntimes: { data: modelServers, loaded: modelServersLoaded }, - } = React.useContext(ProjectDetailsContext); - const { pipelinesServer } = usePipelinesAPI(); - const modelServingEnabled = featureFlagEnabled( dashboardConfig.spec.dashboardConfig.disableModelServing, ); @@ -42,24 +31,20 @@ const ProjectDetailsComponents: React.FC = () => { { id: ProjectSectionID.WORKBENCHES, component: , - isEmpty: notebookStatesLoaded && notebookStates.length === 0, }, { id: ProjectSectionID.CLUSTER_STORAGES, component: , - isEmpty: pvcsLoaded && pvcs.length === 0, }, { id: ProjectSectionID.DATA_CONNECTIONS, component: , - isEmpty: connectionsLoaded && connections.length === 0, }, ...(pipelinesEnabled ? [ { id: ProjectSectionID.PIPELINES, component: , - isEmpty: !pipelinesServer.installed, }, ] : []), @@ -68,7 +53,6 @@ const ProjectDetailsComponents: React.FC = () => { { id: ProjectSectionID.MODEL_SERVER, component: , - isEmpty: modelServersLoaded && modelServers.length === 0, }, ] : []), @@ -82,7 +66,7 @@ const ProjectDetailsComponents: React.FC = () => { maxWidth={175} > - {sections.map(({ id, component, isEmpty }, index) => ( + {sections.map(({ id, component }) => ( { > {component} - {index !== sections.length - 1 && isEmpty && ( - - )} ))} diff --git a/frontend/src/pages/projects/screens/detail/data-connections/DataConnectionsList.tsx b/frontend/src/pages/projects/screens/detail/data-connections/DataConnectionsList.tsx index 18d23c0fe7..66145c3ca6 100644 --- a/frontend/src/pages/projects/screens/detail/data-connections/DataConnectionsList.tsx +++ b/frontend/src/pages/projects/screens/detail/data-connections/DataConnectionsList.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Button } from '@patternfly/react-core'; +import { Button, Divider } from '@patternfly/react-core'; import EmptyDetailsList from '~/pages/projects/screens/detail/EmptyDetailsList'; import { ProjectSectionID } from '~/pages/projects/screens/detail/types'; import DetailsSection from '~/pages/projects/screens/detail/DetailsSection'; @@ -15,6 +15,8 @@ const DataConnectionsList: React.FC = () => { } = React.useContext(ProjectDetailsContext); const [open, setOpen] = React.useState(false); + const emptyDataConnections = connections.length === 0; + return ( <> { , ]} isLoading={!loaded} - isEmpty={connections.length === 0} + isEmpty={emptyDataConnections} loadError={error} emptyState={ { > + {emptyDataConnections && } { diff --git a/frontend/src/pages/projects/screens/detail/notebooks/NotebookList.tsx b/frontend/src/pages/projects/screens/detail/notebooks/NotebookList.tsx index 0396239c96..95da057a2b 100644 --- a/frontend/src/pages/projects/screens/detail/notebooks/NotebookList.tsx +++ b/frontend/src/pages/projects/screens/detail/notebooks/NotebookList.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Button } from '@patternfly/react-core'; +import { Button, Divider } from '@patternfly/react-core'; import { useNavigate } from 'react-router-dom'; import EmptyDetailsList from '~/pages/projects/screens/detail/EmptyDetailsList'; import { ProjectSectionID } from '~/pages/projects/screens/detail/types'; @@ -17,6 +17,7 @@ const NotebookList: React.FC = () => { } = React.useContext(ProjectDetailsContext); const navigate = useNavigate(); const projectName = currentProject.metadata.name; + const emptyNotebooks = notebookStates.length === 0; React.useEffect(() => { let interval: ReturnType; @@ -27,30 +28,33 @@ const NotebookList: React.FC = () => { }, [notebookStates, refreshNotebooks]); return ( - navigate(`/projects/${projectName}/spawner`)} - variant="secondary" - > - Create workbench - , - ]} - isLoading={!loaded} - loadError={loadError} - isEmpty={notebookStates.length === 0} - emptyState={ - - } - > - - + <> + navigate(`/projects/${projectName}/spawner`)} + variant="secondary" + > + Create workbench + , + ]} + isLoading={!loaded} + loadError={loadError} + isEmpty={emptyNotebooks} + emptyState={ + + } + > + + + {emptyNotebooks && } + ); }; diff --git a/frontend/src/pages/projects/screens/detail/pipelines/PipelinesList.tsx b/frontend/src/pages/projects/screens/detail/pipelines/PipelinesList.tsx index f038c0d882..f87403be93 100644 --- a/frontend/src/pages/projects/screens/detail/pipelines/PipelinesList.tsx +++ b/frontend/src/pages/projects/screens/detail/pipelines/PipelinesList.tsx @@ -9,11 +9,19 @@ import { usePipelinesAPI } from '~/concepts/pipelines/context'; import EmptyStateErrorMessage from '~/components/EmptyStateErrorMessage'; import { TABLE_CONTENT_LIMIT, LIMIT_MAX_ITEM_COUNT } from '~/concepts/pipelines/const'; -const PipelinesList: React.FC = () => { +interface PipelinesListProps { + setPipelinesIsEmpty: (arg0: boolean) => void; +} + +const PipelinesList: React.FC = ({ setPipelinesIsEmpty }) => { const { namespace } = usePipelinesAPI(); const [pipelines, loaded, loadError, refresh] = usePipelines(LIMIT_MAX_ITEM_COUNT); const navigate = useNavigate(); + React.useEffect(() => { + pipelines.length === 0 ? setPipelinesIsEmpty(true) : setPipelinesIsEmpty(false); + }, [pipelines, setPipelinesIsEmpty]); + if (loadError) { return ( diff --git a/frontend/src/pages/projects/screens/detail/pipelines/PipelinesSection.tsx b/frontend/src/pages/projects/screens/detail/pipelines/PipelinesSection.tsx index ed36a91cd9..5cf3d2d896 100644 --- a/frontend/src/pages/projects/screens/detail/pipelines/PipelinesSection.tsx +++ b/frontend/src/pages/projects/screens/detail/pipelines/PipelinesSection.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { Divider } from '@patternfly/react-core'; import { ProjectSectionID } from '~/pages/projects/screens/detail/types'; import { ProjectSectionTitles } from '~/pages/projects/screens/detail/const'; import DetailsSection from '~/pages/projects/screens/detail/DetailsSection'; @@ -13,29 +14,34 @@ const PipelinesSection: React.FC = () => { pipelinesServer: { initializing, installed, timedOut }, } = usePipelinesAPI(); + const [isPipelinesEmpty, setPipelinesIsEmpty] = React.useState(false); + return ( - , - ]} - isLoading={initializing} - isEmpty={!installed} - emptyState={} - > - {timedOut ? ( - - ) : ( - - - - )} - + <> + , + ]} + isLoading={initializing} + isEmpty={!installed} + emptyState={} + > + {timedOut ? ( + + ) : ( + + + + )} + + {(isPipelinesEmpty || !installed) && } + ); }; diff --git a/frontend/src/pages/projects/screens/detail/storage/StorageList.tsx b/frontend/src/pages/projects/screens/detail/storage/StorageList.tsx index 439f8f86b8..594bb77660 100644 --- a/frontend/src/pages/projects/screens/detail/storage/StorageList.tsx +++ b/frontend/src/pages/projects/screens/detail/storage/StorageList.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Button } from '@patternfly/react-core'; +import { Button, Divider } from '@patternfly/react-core'; import EmptyDetailsList from '~/pages/projects/screens/detail/EmptyDetailsList'; import DetailsSection from '~/pages/projects/screens/detail/DetailsSection'; import { ProjectSectionID } from '~/pages/projects/screens/detail/types'; @@ -15,6 +15,8 @@ const StorageList: React.FC = () => { refreshAllProjectData: refresh, } = React.useContext(ProjectDetailsContext); + const emptyPvsc = pvcs.length === 0; + return ( <> { , ]} isLoading={!loaded} - isEmpty={pvcs.length === 0} + isEmpty={emptyPvsc} loadError={loadError} emptyState={ { > setOpen(true)} /> + {emptyPvsc && } {