Skip to content

Commit

Permalink
[RHOAIENG-12866] entire project context refreshed when individual res…
Browse files Browse the repository at this point in the history
…ources are deleted
  • Loading branch information
jpuzz0 committed Nov 7, 2024
1 parent 0e4420f commit 9adb82d
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 152 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,6 @@ describe('Data connections', () => {
.findSelectOption('Test Notebook')
.click();
editDataConnectionModal.findNotebookRestartAlert().should('exist');
cy.interceptK8sList(
NotebookModel,
mockK8sResourceList([
mockNotebookK8sResource({ envFrom: [{ secretRef: { name: 'test-secret' } }] }),
]),
).as('addConnectedWorkbench');
cy.interceptK8s('PUT', SecretModel, mockSecretK8sResource({})).as('editDataConnection');

editDataConnectionModal.findSubmitButton().click();
Expand Down Expand Up @@ -212,13 +206,6 @@ describe('Data connections', () => {
cy.get('@editDataConnection.all').then((interceptions) => {
expect(interceptions).to.have.length(2); //1 dry run request and 1 actual request
});

cy.wait('@addConnectedWorkbench').then(() => {
projectDetails
.getDataConnectionRow('Test Secret')
.findWorkbenchConnection()
.should('have.text', 'Test Notebook');
});
});
it('Delete connection', () => {
initIntercepts({});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ const ServingRuntimeTableExpandedSection: React.FC<ServingRuntimeTableExpandedSe
obj,
}) => {
const {
inferenceServices: { data: inferenceServices },
refreshAllProjectData,
inferenceServices: { data: inferenceServices, refresh: refreshInferenceServices },
} = React.useContext(ProjectDetailsContext);

const modelInferenceServices = getInferenceServiceFromServingRuntime(inferenceServices, obj);
Expand All @@ -55,7 +54,7 @@ const ServingRuntimeTableExpandedSection: React.FC<ServingRuntimeTableExpandedSe
inferenceServices={modelInferenceServices}
servingRuntimes={[obj]}
refresh={() => {
refreshAllProjectData();
refreshInferenceServices();
onClose();
}}
/>
Expand Down
41 changes: 1 addition & 40 deletions frontend/src/pages/projects/ProjectDetailsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import useConnections from './screens/detail/connections/useConnections';

type ProjectDetailsContextType = {
currentProject: ProjectKind;
refreshAllProjectData: () => void;
filterTokens: (servingRuntime?: string) => SecretKind[];
notebooks: ContextResourceData<NotebookState>;
pvcs: ContextResourceData<PersistentVolumeClaimKind>;
Expand All @@ -54,10 +53,7 @@ type ProjectDetailsContextType = {
};

export const ProjectDetailsContext = React.createContext<ProjectDetailsContextType>({
// We never will get into a case without a project, so fudge the default value
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
currentProject: null as unknown as ProjectKind,
refreshAllProjectData: () => undefined,
currentProject: { apiVersion: '', kind: '', metadata: { name: '' } },
filterTokens: () => [],
notebooks: DEFAULT_CONTEXT_DATA,
pvcs: DEFAULT_CONTEXT_DATA,
Expand Down Expand Up @@ -99,39 +95,6 @@ const ProjectDetailsContextProvider: React.FC = () => {
const projectSharingRB = useContextResourceData<RoleBindingKind>(useProjectSharing(namespace));
const groups = useGroups();

const notebookRefresh = notebooks.refresh;
const pvcRefresh = pvcs.refresh;
const dataConnectionRefresh = dataConnections.refresh;
const connectionRefresh = connections.refresh;
const servingRuntimeRefresh = servingRuntimes.refresh;
const servingRuntimeTemplateOrderRefresh = servingRuntimeTemplateOrder.refresh;
const servingRuntimeTemplateDisablementRefresh = servingRuntimeTemplateDisablement.refresh;
const inferenceServiceRefresh = inferenceServices.refresh;
const projectSharingRefresh = projectSharingRB.refresh;
const refreshAllProjectData = React.useCallback(() => {
notebookRefresh();
setTimeout(notebookRefresh, 2000);
pvcRefresh();
dataConnectionRefresh();
connectionRefresh();
servingRuntimeRefresh();
inferenceServiceRefresh();
projectSharingRefresh();

servingRuntimeTemplateOrderRefresh();
servingRuntimeTemplateDisablementRefresh();
}, [
notebookRefresh,
pvcRefresh,
dataConnectionRefresh,
connectionRefresh,
servingRuntimeRefresh,
servingRuntimeTemplateOrderRefresh,
servingRuntimeTemplateDisablementRefresh,
inferenceServiceRefresh,
projectSharingRefresh,
]);

const filterTokens = React.useCallback(
(servingRuntimeName?: string): SecretKind[] => {
if (!namespace || !servingRuntimeName) {
Expand Down Expand Up @@ -167,7 +130,6 @@ const ProjectDetailsContextProvider: React.FC = () => {
servingRuntimeTemplateOrder,
servingRuntimeTemplateDisablement,
inferenceServices,
refreshAllProjectData,
filterTokens,
serverSecrets,
projectSharingRB,
Expand All @@ -185,7 +147,6 @@ const ProjectDetailsContextProvider: React.FC = () => {
servingRuntimeTemplateOrder,
servingRuntimeTemplateDisablement,
inferenceServices,
refreshAllProjectData,
filterTokens,
serverSecrets,
projectSharingRB,
Expand Down
130 changes: 63 additions & 67 deletions frontend/src/pages/projects/screens/detail/ProjectDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,72 +53,6 @@ const ProjectDetails: React.FC = () => {

useCheckLogoutParams();

const content = () => (
<GenericHorizontalBar
activeKey={state}
sections={[
{ id: ProjectSectionID.OVERVIEW, title: 'Overview', component: <ProjectOverview /> },
{ id: ProjectSectionID.WORKBENCHES, title: 'Workbenches', component: <NotebookList /> },
...(pipelinesEnabled
? [
{
id: ProjectSectionID.PIPELINES,
title: 'Pipelines',
component: <PipelinesSection />,
},
]
: []),
...(modelServingEnabled
? [
{
id: ProjectSectionID.MODEL_SERVER,
title: 'Models',
component: <ModelServingPlatform />,
},
]
: []),
{
id: ProjectSectionID.CLUSTER_STORAGES,
title: 'Cluster storage',
component: <StorageList />,
},
...(connectionTypesEnabled
? [
{
id: ProjectSectionID.CONNECTIONS,
title: 'Connections',
component: <ConnectionsList />,
},
]
: [
{
id: ProjectSectionID.DATA_CONNECTIONS,
title: 'Data connections',
component: <DataConnectionsList />,
},
]),
...(projectSharingEnabled && allowCreate
? [
{
id: ProjectSectionID.PERMISSIONS,
title: 'Permissions',
component: <ProjectSharing />,
},
]
: []),
...(biasMetricsAreaAvailable && allowCreate
? [
{
id: ProjectSectionID.SETTINGS,
title: 'Settings',
component: <ProjectSettingsPage />,
},
]
: []),
]}
/>
);

return (
<ApplicationsPage
title={
Expand All @@ -142,7 +76,69 @@ const ProjectDetails: React.FC = () => {
empty={false}
headerAction={<ProjectActions project={currentProject} />}
>
{content()}
<GenericHorizontalBar
activeKey={state}
sections={[
{ id: ProjectSectionID.OVERVIEW, title: 'Overview', component: <ProjectOverview /> },
{ id: ProjectSectionID.WORKBENCHES, title: 'Workbenches', component: <NotebookList /> },
...(pipelinesEnabled
? [
{
id: ProjectSectionID.PIPELINES,
title: 'Pipelines',
component: <PipelinesSection />,
},
]
: []),
...(modelServingEnabled
? [
{
id: ProjectSectionID.MODEL_SERVER,
title: 'Models',
component: <ModelServingPlatform />,
},
]
: []),
{
id: ProjectSectionID.CLUSTER_STORAGES,
title: 'Cluster storage',
component: <StorageList />,
},
...(connectionTypesEnabled
? [
{
id: ProjectSectionID.CONNECTIONS,
title: 'Connections',
component: <ConnectionsList />,
},
]
: [
{
id: ProjectSectionID.DATA_CONNECTIONS,
title: 'Data connections',
component: <DataConnectionsList />,
},
]),
...(projectSharingEnabled && allowCreate
? [
{
id: ProjectSectionID.PERMISSIONS,
title: 'Permissions',
component: <ProjectSharing />,
},
]
: []),
...(biasMetricsAreaAvailable && allowCreate
? [
{
id: ProjectSectionID.SETTINGS,
title: 'Settings',
component: <ProjectSettingsPage />,
},
]
: []),
]}
/>
</ApplicationsPage>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@ import DataConnectionsTable from './DataConnectionsTable';

const DataConnectionsList: React.FC = () => {
const {
dataConnections: { data: connections, loaded, error },
refreshAllProjectData,
notebooks: { refresh: refreshNotebooks },
dataConnections: {
data: dataConnections,
loaded: dataConnectionsLoaded,
error: dataConnectionsError,
refresh: refreshDataConnections,
},
} = React.useContext(ProjectDetailsContext);
const [open, setOpen] = React.useState(false);

const isDataConnectionsEmpty = connections.length === 0;
const isDataConnectionsEmpty = dataConnections.length === 0;

return (
<>
Expand Down Expand Up @@ -55,9 +60,9 @@ const DataConnectionsList: React.FC = () => {
]
: undefined
}
isLoading={!loaded}
isLoading={!dataConnectionsLoaded}
isEmpty={isDataConnectionsEmpty}
loadError={error}
loadError={dataConnectionsError}
emptyState={
<EmptyDetailsView
title="Start by adding a data connection"
Expand All @@ -77,15 +82,19 @@ const DataConnectionsList: React.FC = () => {
/>
}
>
{!isDataConnectionsEmpty ? (
<DataConnectionsTable connections={connections} refreshData={refreshAllProjectData} />
) : null}
{!isDataConnectionsEmpty && (
<DataConnectionsTable
connections={dataConnections}
refreshData={refreshDataConnections}
/>
)}
</DetailsSection>
{open ? (
<ManageDataConnectionModal
onClose={(submitted) => {
if (submitted) {
refreshAllProjectData();
refreshDataConnections();
refreshNotebooks();
}
setOpen(false);
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,25 @@ import NotebookTable from './NotebookTable';
const NotebookList: React.FC = () => {
const {
currentProject,
notebooks: { data: notebookStates, loaded, error: loadError },
refreshAllProjectData: refresh,
notebooks: {
data: notebooks,
loaded: notebooksLoaded,
error: notebooksError,
refresh: refreshNotebooks,
},
} = React.useContext(ProjectDetailsContext);
const navigate = useNavigate();
const projectName = currentProject.metadata.name;
const isNotebooksEmpty = notebookStates.length === 0;
const isNotebooksEmpty = notebooks.length === 0;

useRefreshInterval(FAST_POLL_INTERVAL, () =>
notebookStates
notebooks
.filter((notebookState) => notebookState.isStarting || notebookState.isStopping)
.forEach((notebookState) => notebookState.refresh()),
);

useRefreshInterval(POLL_INTERVAL, () =>
notebookStates
notebooks
.filter((notebookState) => !notebookState.isStarting && !notebookState.isStopping)
.forEach((notebookState) => notebookState.refresh()),
);
Expand Down Expand Up @@ -63,8 +67,8 @@ const NotebookList: React.FC = () => {
Create workbench
</Button>,
]}
isLoading={!loaded}
loadError={loadError}
isLoading={!notebooksLoaded}
loadError={notebooksError}
isEmpty={isNotebooksEmpty}
emptyState={
<EmptyDetailsView
Expand All @@ -86,7 +90,7 @@ const NotebookList: React.FC = () => {
}
>
{!isNotebooksEmpty ? (
<NotebookTable notebookStates={notebookStates} refresh={refresh} />
<NotebookTable notebookStates={notebooks} refresh={refreshNotebooks} />
) : null}
</DetailsSection>
);
Expand Down
Loading

0 comments on commit 9adb82d

Please sign in to comment.