Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle workbench not enabled #3492

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type HandlersProps = {
pipelineServerInitializing?: boolean;
pipelineServerErrorMessage?: string;
rejectAddSupportServingPlatformProject?: boolean;
disableWorkbenches?: boolean;
};

const initIntercepts = ({
Expand All @@ -79,6 +80,7 @@ const initIntercepts = ({
pipelineServerInitializing,
pipelineServerErrorMessage,
rejectAddSupportServingPlatformProject = false,
disableWorkbenches = false,
}: HandlersProps) => {
cy.interceptK8sList(
{ model: SecretModel, ns: 'test-project' },
Expand All @@ -96,7 +98,7 @@ const initIntercepts = ({
'GET /api/dsc/status',
mockDscStatus({
installedComponents: {
workbenches: true,
workbenches: !disableWorkbenches,
'data-science-pipelines-operator': true,
kserve: true,
'model-mesh': true,
Expand Down Expand Up @@ -830,4 +832,28 @@ describe('Project Details', () => {
);
});
});

describe('Workbench disabled', () => {
beforeEach(() => {
initIntercepts({
disableWorkbenches: true,
});
});

it('should hide workbench tab when workbenches are disabled', () => {
projectDetails.visit('test-project');
projectDetails.findTab('Workbenches').should('not.exist');
});

it('should hide workbench card in overview when workbenches are disabled', () => {
projectDetails.visitSection('test-project', 'overview');
cy.get('h2').contains('Workbench').should('not.exist');
});

it('should hide workbench references in storage table when workbenches are disabled', () => {
projectDetails.visitSection('test-project', 'cluster-storages');

cy.get('th').contains('Connected workbenches').should('not.exist');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
SelfSubjectAccessReviewModel,
} from '~/__tests__/cypress/cypress/utils/models';
import { mock200Status } from '~/__mocks__/mockK8sStatus';
import { mockNotebookK8sResource, mockRouteK8sResource } from '~/__mocks__';
import { mockDscStatus, mockNotebookK8sResource, mockRouteK8sResource } from '~/__mocks__';
import { mockPodK8sResource } from '~/__mocks__/mockPodK8sResource';
import { mockSelfSubjectAccessReview } from '~/__mocks__/mockSelfSubjectAccessReview';
import { asProjectAdminUser } from '~/__tests__/cypress/cypress/utils/mockUsers';
Expand Down Expand Up @@ -358,6 +358,43 @@ describe('Data science projects details', () => {
notebookRow.findNotebookStatusText().should('have.text', 'Stopped');
notebookRow.findNotebookRouteLink().should('have.attr', 'aria-disabled', 'true');
});

describe('Workbench disabled', () => {
beforeEach(() => {
cy.interceptOdh(
'GET /api/dsc/status',
mockDscStatus({
installedComponents: {
workbenches: false,
'data-science-pipelines-operator': true,
kserve: true,
'model-mesh': true,
'model-registry-operator': true,
},
}),
);
initIntercepts();
});

it('should hide workbench column when workbenches are disabled', () => {
projectListPage.visit();

// Verify workbench column is not present
cy.get('th').contains('Workbenches').should('not.exist');

// Verify workbench status indicators are not shown
const projectTableRow = projectListPage.getProjectRow('Test Project');
projectTableRow.findNotebookColumnExpander().should('not.exist');
});

it('should not show workbench count or details', () => {
projectListPage.visit();

// Verify no workbench info is shown
cy.get('[data-label="Workbenches"]').should('not.exist');
cy.get('.pf-v5-c-table__expandable-row-content').should('not.exist');
});
});
});

const deletedMockProjectResource = (resource: ProjectKind): ProjectKind =>
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/components/OdhAppCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { addNotification, forceComponentsUpdate } from '~/redux/actions/actions'
import { ODH_PRODUCT_NAME } from '~/utilities/const';
import { useAppContext } from '~/app/AppContext';
import { useAppDispatch } from '~/redux/hooks';
import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas';
import { useQuickStartCardSelected } from './useQuickStartCardSelected';
import SupportedAppTitle from './SupportedAppTitle';
import BrandImage from './BrandImage';
Expand All @@ -40,6 +41,7 @@ const OdhAppCard: React.FC<OdhAppCardProps> = ({ odhApp }) => {
odhApp.spec.quickStart,
odhApp.metadata.name,
);
const workbenchEnabled = useIsAreaAvailable(SupportedArea.WORKBENCHES).status;
const disabled = !odhApp.spec.isEnabled;
const { dashboardConfig } = useAppContext();
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -97,7 +99,7 @@ const OdhAppCard: React.FC<OdhAppCardProps> = ({ odhApp }) => {

const launchClasses = classNames('odh-card__footer__link', {
'm-hidden': !odhApp.spec.link,
'm-disabled': disabled,
'm-disabled': disabled || !workbenchEnabled,
});

const cardFooter = (
Expand All @@ -107,7 +109,9 @@ const OdhAppCard: React.FC<OdhAppCardProps> = ({ odhApp }) => {
<Link
data-testid="jupyter-app-link"
to="/notebookController"
className="odh-card__footer__link"
className={classNames('odh-card__footer__link', {
'm-disabled': !workbenchEnabled,
})}
>
Launch application
</Link>
Expand Down
11 changes: 10 additions & 1 deletion frontend/src/pages/projects/screens/detail/ProjectDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const ProjectDetails: React.FC = () => {
...accessReviewResource,
namespace: currentProject.metadata.name,
});
const workbenchEnabled = useIsAreaAvailable(SupportedArea.WORKBENCHES).status;

useCheckLogoutParams();

Expand Down Expand Up @@ -80,7 +81,15 @@ const ProjectDetails: React.FC = () => {
activeKey={state}
sections={[
{ id: ProjectSectionID.OVERVIEW, title: 'Overview', component: <ProjectOverview /> },
{ id: ProjectSectionID.WORKBENCHES, title: 'Workbenches', component: <NotebookList /> },
...(workbenchEnabled
? [
{
id: ProjectSectionID.WORKBENCHES,
title: 'Workbenches',
component: <NotebookList />,
},
]
: []),
...(pipelinesEnabled
? [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import NotebooksCard from './NotebooksCard';

const TrainModelsSection: React.FC = () => {
const pipelinesEnabled = useIsAreaAvailable(SupportedArea.DS_PIPELINES).status;
const workbenchEnabled = useIsAreaAvailable(SupportedArea.WORKBENCHES).status;

if (!workbenchEnabled && !pipelinesEnabled) {
return null;
}

return (
<CollapsibleSection title="Train models">
Expand All @@ -15,7 +20,7 @@ const TrainModelsSection: React.FC = () => {
minWidths={{ default: '100%', lg: pipelinesEnabled ? 'calc(50% - 1rem / 2)' : '100%' }}
maxWidths={{ default: '100%', lg: pipelinesEnabled ? 'calc(50% - 1rem / 2)' : '100%' }}
>
<NotebooksCard />
{workbenchEnabled ? <NotebooksCard /> : null}
{pipelinesEnabled ? <PipelinesCard /> : null}
</Gallery>
</CollapsibleSection>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import NotebookRestartAlert from '~/pages/projects/components/NotebookRestartAlert';
import StorageNotebookConnections from '~/pages/projects/notebook/StorageNotebookConnections';
import useWillNotebooksRestart from '~/pages/projects/notebook/useWillNotebooksRestart';
import { useIsAreaAvailable, SupportedArea } from '~/concepts/areas';
import BaseStorageModal from './BaseStorageModal';
import ExistingConnectedNotebooks from './ExistingConnectedNotebooks';
import { isPvcUpdateRequired } from './utils';
Expand All @@ -33,6 +34,8 @@ const ClusterStorageModal: React.FC<ClusterStorageModalProps> = ({ existingPvc,
existingPvc?.metadata.name,
);

const workbenchEnabled = useIsAreaAvailable(SupportedArea.WORKBENCHES).status;

const {
notebooks: removableNotebooks,
loaded: removableNotebookLoaded,
Expand Down Expand Up @@ -127,34 +130,36 @@ const ClusterStorageModal: React.FC<ClusterStorageModalProps> = ({ existingPvc,
onClose={(submitted) => onClose(submitted)}
existingPvc={existingPvc}
>
<>
{hasExistingNotebookConnections && (
{workbenchEnabled && (
<>
{hasExistingNotebookConnections && (
<StackItem>
<ExistingConnectedNotebooks
connectedNotebooks={removableNotebooks}
onNotebookRemove={(notebook: NotebookKind) =>
setRemovedNotebooks([...removedNotebooks, notebook.metadata.name])
}
loaded={removableNotebookLoaded}
error={removableNotebookError}
/>
</StackItem>
)}
<StackItem>
<ExistingConnectedNotebooks
connectedNotebooks={removableNotebooks}
onNotebookRemove={(notebook: NotebookKind) =>
setRemovedNotebooks([...removedNotebooks, notebook.metadata.name])
}
loaded={removableNotebookLoaded}
error={removableNotebookError}
<StorageNotebookConnections
setForNotebookData={(forNotebookData) => {
setNotebookData(forNotebookData);
}}
forNotebookData={notebookData}
connectedNotebooks={connectedNotebooks}
/>
</StackItem>
)}
<StackItem>
<StorageNotebookConnections
setForNotebookData={(forNotebookData) => {
setNotebookData(forNotebookData);
}}
forNotebookData={notebookData}
connectedNotebooks={connectedNotebooks}
/>
</StackItem>
{restartNotebooks.length !== 0 && (
<StackItem>
<NotebookRestartAlert notebooks={restartNotebooks} />
</StackItem>
)}
</>
{restartNotebooks.length !== 0 && (
<StackItem>
<NotebookRestartAlert notebooks={restartNotebooks} />
</StackItem>
)}
</>
)}
</BaseStorageModal>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,19 @@ const StorageTable: React.FC<StorageTableProps> = ({ pvcs, refresh, onAddPVC })
[storageClassesLoaded, storageTableData],
);
const shouldShowAlert = isDeprecatedAlert && !alertDismissed && isStorageClassesAvailable;
const workbenchEnabled = useIsAreaAvailable(SupportedArea.WORKBENCHES).status;

const getStorageColumns = () => {
let storageColumns = columns;

if (!isStorageClassesAvailable) {
storageColumns = columns.filter((column) => column.field !== 'storage');
}

if (!workbenchEnabled) {
storageColumns = storageColumns.filter((column) => column.field !== 'connected');
}

return storageColumns;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const StorageTableRow: React.FC<StorageTableRowProps> = ({
const isRootVolume = useIsRootVolume(obj.pvc);

const isStorageClassesAvailable = useIsAreaAvailable(SupportedArea.STORAGE_CLASSES).status;
const workbenchEnabled = useIsAreaAvailable(SupportedArea.WORKBENCHES).status;
const storageClassConfig = obj.storageClass && getStorageClassConfig(obj.storageClass);

const actions: IAction[] = [
Expand Down Expand Up @@ -165,12 +166,14 @@ const StorageTableRow: React.FC<StorageTableRowProps> = ({
</Flex>
</Text>
</Td>
<Td dataLabel="Connected workbenches">
<ConnectedNotebookNames
context={ConnectedNotebookContext.EXISTING_PVC}
relatedResourceName={obj.pvc.metadata.name}
/>
</Td>
{workbenchEnabled && (
<Td dataLabel="Connected workbenches">
<ConnectedNotebookNames
context={ConnectedNotebookContext.EXISTING_PVC}
relatedResourceName={obj.pvc.metadata.name}
/>
</Td>
)}
<Td isActionCell>
<ActionsColumn items={actions} />
</Td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import * as React from 'react';
import { Button, ButtonVariant, Tooltip } from '@patternfly/react-core';
import { useNavigate } from 'react-router-dom';
import { useCheckJupyterEnabled } from '~/utilities/notebookControllerUtils';
import { useIsAreaAvailable, SupportedArea } from '~/concepts/areas';

const LaunchJupyterButton: React.FC = () => {
const navigate = useNavigate();
const isJupyterEnabled = useCheckJupyterEnabled();
const workbenchEnabled = useIsAreaAvailable(SupportedArea.WORKBENCHES).status;

if (!isJupyterEnabled) {
if (!isJupyterEnabled || !workbenchEnabled) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
initialProjectsFilterData,
ProjectsFilterDataType,
} from '~/pages/projects/screens/projects/const';
import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas';
import { columns } from './tableData';
import DeleteProjectModal from './DeleteProjectModal';
import ManageProjectModal from './ManageProjectModal';
Expand Down Expand Up @@ -60,6 +61,11 @@ const ProjectListView: React.FC<ProjectListViewProps> = ({ allowCreate }) => {
const [deleteData, setDeleteData] = React.useState<ProjectKind | undefined>();
const [editData, setEditData] = React.useState<ProjectKind | undefined>();
const [refreshIds, setRefreshIds] = React.useState<string[]>([]);
const workbenchEnabled = useIsAreaAvailable(SupportedArea.WORKBENCHES).status;

const filteredColumns = workbenchEnabled
? columns
: columns.filter((column) => column.field !== 'Workbenches');

return (
<>
Expand All @@ -69,7 +75,7 @@ const ProjectListView: React.FC<ProjectListViewProps> = ({ allowCreate }) => {
variant="compact"
defaultSortColumn={0}
data={filteredProjects}
columns={columns}
columns={filteredColumns}
emptyTableView={<DashboardEmptyTableView onClearFilters={resetFilters} />}
data-testid="project-view-table"
disableRowRenderSupport
Expand Down
Loading
Loading