diff --git a/frontend/src/__mocks__/index.ts b/frontend/src/__mocks__/index.ts index 372231f23d..374e375d54 100644 --- a/frontend/src/__mocks__/index.ts +++ b/frontend/src/__mocks__/index.ts @@ -11,6 +11,7 @@ export * from './mockPipelineVersionsProxy'; export * from './mockPipelinesProxy'; export * from './mockDscStatus'; export * from './mockNotebookK8sResource'; +export * from './mockNotebookState'; export * from './mockPipelineKF'; export * from './mockSecretK8sResource'; export * from './mockGoogleRpcStatusKF'; diff --git a/frontend/src/__mocks__/mockNotebookState.ts b/frontend/src/__mocks__/mockNotebookState.ts new file mode 100644 index 0000000000..bff959705d --- /dev/null +++ b/frontend/src/__mocks__/mockNotebookState.ts @@ -0,0 +1,30 @@ +import _ from 'lodash-es'; +import { NotebookKind } from '~/k8sTypes'; +import { NotebookState, NotebookRefresh } from '~/pages/projects/notebook/types'; + +type MockConfigType = { + isStarting?: boolean; + isRunning?: boolean; + isStopping?: boolean; + isStopped?: boolean; + runningPodUid?: string; + refresh?: NotebookRefresh; +}; + +export const mockNotebookState = ( + notebook: NotebookKind, + mockConfig?: MockConfigType, +): NotebookState => ({ + notebook, + ..._.merge( + { + isStarting: false, + isRunning: false, + isStopping: false, + isStopped: false, + runningPodUid: '', + refresh: () => Promise.resolve(), + }, + mockConfig, + ), +}); diff --git a/frontend/src/concepts/design/TypedObjectIcon.tsx b/frontend/src/concepts/design/TypedObjectIcon.tsx new file mode 100644 index 0000000000..ae497a0eb0 --- /dev/null +++ b/frontend/src/concepts/design/TypedObjectIcon.tsx @@ -0,0 +1,44 @@ +import * as React from 'react'; +import { SVGIconProps } from '@patternfly/react-icons/dist/esm/createIcon'; +import { ProjectObjectType, typedColor } from '~/concepts/design/utils'; +import NotebookIcon from '~/images/icons/NotebookIcon'; +import ModelIcon from '~/images/icons/ModelsIcon'; + +type TypedObjectIconProps = SVGIconProps & { + resourceType: ProjectObjectType; + useTypedColor?: boolean; + size?: number; +}; +const TypedObjectIcon: React.FC = ({ + resourceType, + useTypedColor, + style, + ...rest +}) => { + switch (resourceType) { + case ProjectObjectType.notebook: + return ( + + ); + case ProjectObjectType.deployedModels: + return ( + + ); + default: + return null; + } +}; + +export default TypedObjectIcon; diff --git a/frontend/src/concepts/design/utils.ts b/frontend/src/concepts/design/utils.ts index 4ded3d8436..aab8805065 100644 --- a/frontend/src/concepts/design/utils.ts +++ b/frontend/src/concepts/design/utils.ts @@ -78,6 +78,36 @@ export const typedBackgroundColor = (objectType: ProjectObjectType): string => { } }; +export const typedColor = (objectType: ProjectObjectType): string => { + switch (objectType) { + case ProjectObjectType.project: + return 'var(--ai-project--Color)'; + case ProjectObjectType.notebook: + return 'var(--ai-notebook--Color)'; + case ProjectObjectType.pipeline: + case ProjectObjectType.pipelineRun: + return 'var(--ai-pipeline--Color)'; + case ProjectObjectType.pipelineSetup: + return 'var(--ai-set-up--Color)'; + case ProjectObjectType.clusterStorage: + return 'var(--ai-cluster-storage--Color)'; + case ProjectObjectType.modelServer: + case ProjectObjectType.registeredModels: + case ProjectObjectType.deployedModels: + case ProjectObjectType.deployingModels: + return 'var(--ai-model-server--Color)'; + case ProjectObjectType.dataConnection: + case ProjectObjectType.connections: + return 'var(--ai-data-connection--Color)'; + case ProjectObjectType.user: + return 'var(--ai-user--Color)'; + case ProjectObjectType.group: + return 'var(--ai-group--Color)'; + default: + return ''; + } +}; + export const typedObjectImage = (objectType: ProjectObjectType): string => { switch (objectType) { case ProjectObjectType.project: diff --git a/frontend/src/concepts/design/vars.scss b/frontend/src/concepts/design/vars.scss index bfff386084..911552ee80 100644 --- a/frontend/src/concepts/design/vars.scss +++ b/frontend/src/concepts/design/vars.scss @@ -9,23 +9,40 @@ --ai-training--BorderColor: #9ad8d8; --ai-serving--BorderColor: #92c5f9; + --ai-project--BackgroundColor: var(--ai-organize--BackgroundColor); --ai-project--BorderColor: var(--ai-organize--BorderColor); + --ai-project--Color: var(--ai-organize--BorderColor); + --ai-data-connection--BackgroundColor: var(--ai-organize--BackgroundColor); --ai-data-connection--BorderColor: var(--ai-organize--BorderColor); + --ai-data-connection--Color: var(--ai-organize--BorderColor); + --ai-cluster-storage--BackgroundColor: var(--ai-organize--BackgroundColor); --ai-cluster-storage--BorderColor: var(--ai-organize--BorderColor); + --ai-cluster-storage--Color: var(--ai-organize--BorderColor); --ai-notebook--BackgroundColor: var(--ai-training--BackgroundColor); --ai-notebook--BorderColor: var(--ai-training--BorderColor); + --ai-notebook--Color: #37a3a3; + + --ai-model--BackgroundColor: var(--ai-serving--BackgroundColor); + --ai-model--BorderColor: var(--ai-serviing--BorderColor); + --ai-model--Color: var(--ai-serviing--BorderColor); + --ai-pipeline--BackgroundColor: var(--ai-training--BackgroundColor); --ai-pipeline--BorderColor: var(--ai-training--BorderColor); + --ai-pipeline--Color: var(--ai-training--BorderColor); --ai-model-server--BackgroundColor: var(--ai-serving--BackgroundColor); --ai-model-server--BorderColor: var(--ai-serving--BorderColor); + --ai-model-server--Color: #5E40BE; --ai-user--BackgroundColor: var(--ai-set-up--BackgroundColor); --ai-user--BorderColor: var(--ai-set-up--BorderColor); + --ai-user--Color: var(--ai-set-up--BorderColor); + --ai-group--BackgroundColor: var(--ai-set-up--BackgroundColor); --ai-group--BorderColor: var(--ai-set-up--BorderColor); + --ai-group--Color: var(--ai-set-up--BorderColor); } diff --git a/frontend/src/images/icons/ModelsIcon.ts b/frontend/src/images/icons/ModelsIcon.ts new file mode 100644 index 0000000000..990167d337 --- /dev/null +++ b/frontend/src/images/icons/ModelsIcon.ts @@ -0,0 +1,13 @@ +import { createIcon } from '@patternfly/react-icons/dist/esm/createIcon'; + +const ModelIcon = createIcon({ + name: 'ModelIcon', + width: 32, + height: 32, + svgPath: + 'M19.5 11H12.5C11.6729 11 11 10.3271 11 9.5V2.5C11 1.6729 11.6729 1 12.5 1H19.5C20.3271 1 21 1.6729 21 2.5V9.5C21 10.3271 20.3271 11 19.5 11ZM19 3H13V9H19V3ZM12.5 25H5.5C4.6729 25 4 24.3271 4 23.5V16.5C4 15.6729 4.6729 15 5.5 15H12.5C13.3271 15 14 15.6729 14 16.5V23.5C14 24.3271 13.3271 25 12.5 25ZM12 17H6V23H12V17ZM2 29H30C30.5527 29 31 29.4478 31 30C31 30.5522 30.5527 31 30 31H2C1.4473 31 1 30.5522 1 30C1 29.4478 1.4473 29 2 29ZM18 16.5V23.5C18 24.3271 18.6729 25 19.5 25H26.5C27.3271 25 28 24.3271 28 23.5V16.5C28 15.6729 27.3271 15 26.5 15H19.5C18.6729 15 18 15.6729 18 16.5ZM20 17H26V23H20V17Z', + xOffset: 0, + yOffset: 0, +}); + +export default ModelIcon; diff --git a/frontend/src/pages/projects/notebook/ConnectedNotebookNames.tsx b/frontend/src/pages/projects/notebook/ConnectedNotebookNames.tsx index f84d4dddb4..a2d0ae158b 100644 --- a/frontend/src/pages/projects/notebook/ConnectedNotebookNames.tsx +++ b/frontend/src/pages/projects/notebook/ConnectedNotebookNames.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { Label, LabelGroup, Spinner } from '@patternfly/react-core'; import { getDisplayNameFromK8sResource } from '~/concepts/k8s/utils'; -import useRelatedNotebooks, { ConnectedNotebookContext } from './useRelatedNotebooks'; +import { useRelatedNotebooks, ConnectedNotebookContext } from './useRelatedNotebooks'; type ConnectedNotebookNamesProps = { context: ConnectedNotebookContext; diff --git a/frontend/src/pages/projects/notebook/useNotebooksStates.ts b/frontend/src/pages/projects/notebook/useNotebooksStates.ts index d465d12a10..00ab80044c 100644 --- a/frontend/src/pages/projects/notebook/useNotebooksStates.ts +++ b/frontend/src/pages/projects/notebook/useNotebooksStates.ts @@ -5,7 +5,7 @@ import { POLL_INTERVAL } from '~/utilities/const'; import { getNotebooksStates } from '~/pages/projects/notebook/useProjectNotebookStates'; import { NotebookState } from './types'; -const useNotebooksStates = ( +export const useNotebooksStates = ( notebooks: NotebookKind[], namespace: string, ): FetchState => { @@ -18,5 +18,3 @@ const useNotebooksStates = ( refreshRate: POLL_INTERVAL, }); }; - -export default useNotebooksStates; diff --git a/frontend/src/pages/projects/notebook/useRelatedNotebooks.ts b/frontend/src/pages/projects/notebook/useRelatedNotebooks.ts index cf30a47a82..b3e98e0618 100644 --- a/frontend/src/pages/projects/notebook/useRelatedNotebooks.ts +++ b/frontend/src/pages/projects/notebook/useRelatedNotebooks.ts @@ -16,7 +16,7 @@ export enum ConnectedNotebookContext { POSSIBLE_DATA_CONNECTION = 'data-connection-possible', } -const useRelatedNotebooks = ( +export const useRelatedNotebooks = ( context: ConnectedNotebookContext, resourceName?: string, ): { notebooks: NotebookKind[]; loaded: boolean; error: Error | undefined } => { @@ -88,5 +88,3 @@ const useRelatedNotebooks = ( error, }; }; - -export default useRelatedNotebooks; diff --git a/frontend/src/pages/projects/pvc/DeletePVCModal.tsx b/frontend/src/pages/projects/pvc/DeletePVCModal.tsx index 2778104cda..c010502867 100644 --- a/frontend/src/pages/projects/pvc/DeletePVCModal.tsx +++ b/frontend/src/pages/projects/pvc/DeletePVCModal.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; import { PersistentVolumeClaimKind } from '~/k8sTypes'; import { deletePvc, removeNotebookPVC } from '~/api'; -import useRelatedNotebooks, { +import { + useRelatedNotebooks, ConnectedNotebookContext, } from '~/pages/projects/notebook/useRelatedNotebooks'; import DeleteModal from '~/pages/projects/components/DeleteModal'; diff --git a/frontend/src/pages/projects/screens/detail/connections/ConnectedResources.tsx b/frontend/src/pages/projects/screens/detail/connections/ConnectedResources.tsx new file mode 100644 index 0000000000..b0a44e60e4 --- /dev/null +++ b/frontend/src/pages/projects/screens/detail/connections/ConnectedResources.tsx @@ -0,0 +1,43 @@ +import * as React from 'react'; +import { LabelGroup, Spinner } from '@patternfly/react-core'; +import { + useRelatedNotebooks, + ConnectedNotebookContext, +} from '~/pages/projects/notebook/useRelatedNotebooks'; +import { Connection } from '~/concepts/connectionTypes/types'; +import { ProjectObjectType } from '~/concepts/design/utils'; +import ResourceLabel from '~/pages/projects/screens/detail/connections/ResourceLabel'; +import { getDisplayNameFromK8sResource } from '~/concepts/k8s/utils'; + +type Props = { + connection: Connection; +}; + +const ConnectedResources: React.FC = ({ connection }) => { + const { notebooks: connectedNotebooks, loaded: notebooksLoaded } = useRelatedNotebooks( + ConnectedNotebookContext.EXISTING_DATA_CONNECTION, + connection.metadata.name, + ); + + if (!notebooksLoaded) { + return ; + } + + if (!connectedNotebooks.length) { + return '-'; + } + + return ( + + {connectedNotebooks.map((notebook) => ( + + ))} + + ); +}; + +export default ConnectedResources; diff --git a/frontend/src/pages/projects/screens/detail/connections/ConnectionsDeleteModal.tsx b/frontend/src/pages/projects/screens/detail/connections/ConnectionsDeleteModal.tsx index 939a11c768..6697614bbe 100644 --- a/frontend/src/pages/projects/screens/detail/connections/ConnectionsDeleteModal.tsx +++ b/frontend/src/pages/projects/screens/detail/connections/ConnectionsDeleteModal.tsx @@ -1,22 +1,54 @@ import React from 'react'; import { K8sStatus } from '@openshift/dynamic-plugin-sdk-utils'; +import { + Badge, + Bullseye, + ExpandableSection, + ExpandableSectionToggle, + Spinner, + TextContent, + TextList, + TextListItem, +} from '@patternfly/react-core'; import { getDisplayNameFromK8sResource } from '~/concepts/k8s/utils'; import { Connection } from '~/concepts/connectionTypes/types'; import DeleteModal from '~/pages/projects/components/DeleteModal'; +import { + useRelatedNotebooks, + ConnectedNotebookContext, +} from '~/pages/projects/notebook/useRelatedNotebooks'; +import { useNotebooksStates } from '~/pages/projects/notebook/useNotebooksStates'; +import { NotebookKind } from '~/k8sTypes'; type Props = { + namespace: string; deleteConnection: Connection; onClose: (deleted?: boolean) => void; onDelete: () => Promise; }; export const ConnectionsDeleteModal: React.FC = ({ + namespace, deleteConnection, onClose, onDelete, }) => { const [isDeleting, setIsDeleting] = React.useState(false); const [error, setError] = React.useState(); + const { notebooks: connectedNotebooks, loaded: notebooksLoaded } = useRelatedNotebooks( + ConnectedNotebookContext.EXISTING_DATA_CONNECTION, + deleteConnection.metadata.name, + ); + const [notebookStates] = useNotebooksStates(connectedNotebooks, namespace); + const [notebooksExpanded, setNotebooksExpanded] = React.useState(false); + + const getNotebookStatusText = React.useCallback( + (notebook: NotebookKind) => + notebookStates.find((n) => n.notebook.metadata.name === notebook.metadata.name)?.isRunning + ? ' (Running)' + : '', + [notebookStates], + ); return ( = ({ > The {getDisplayNameFromK8sResource(deleteConnection)} connection will be deleted, and its dependent resources will stop working. + {notebooksLoaded && !connectedNotebooks.length ? null : ( +
+ {!notebooksLoaded ? ( + + + + ) : ( + <> + + Workbenches + + {connectedNotebooks.length} + + + + + + {connectedNotebooks.map((notebook) => ( + + {getDisplayNameFromK8sResource(notebook)} + {getNotebookStatusText(notebook)} + + ))} + + + + + )} +
+ )}
); }; diff --git a/frontend/src/pages/projects/screens/detail/connections/ConnectionsList.tsx b/frontend/src/pages/projects/screens/detail/connections/ConnectionsList.tsx index 646f1e75df..3ea827c639 100644 --- a/frontend/src/pages/projects/screens/detail/connections/ConnectionsList.tsx +++ b/frontend/src/pages/projects/screens/detail/connections/ConnectionsList.tsx @@ -73,6 +73,7 @@ const ConnectionsList: React.FC = () => { } > void; @@ -14,6 +15,7 @@ type ConnectionsTableProps = { }; const ConnectionsTable: React.FC = ({ + namespace, connections, connectionTypes, refreshConnections, @@ -40,6 +42,7 @@ const ConnectionsTable: React.FC = ({ /> {deleteConnection && ( { setDeleteConnection(undefined); diff --git a/frontend/src/pages/projects/screens/detail/connections/ConnectionsTableRow.tsx b/frontend/src/pages/projects/screens/detail/connections/ConnectionsTableRow.tsx index 9442bf4bac..95d5d9749d 100644 --- a/frontend/src/pages/projects/screens/detail/connections/ConnectionsTableRow.tsx +++ b/frontend/src/pages/projects/screens/detail/connections/ConnectionsTableRow.tsx @@ -6,6 +6,7 @@ import { TableRowTitleDescription } from '~/components/table'; import { getDescriptionFromK8sResource, getDisplayNameFromK8sResource } from '~/concepts/k8s/utils'; import { getCompatibleTypes } from '~/concepts/connectionTypes/utils'; import CompatibilityLabel from '~/concepts/connectionTypes/CompatibilityLabel'; +import ConnectedResources from '~/pages/projects/screens/detail/connections/ConnectedResources'; type ConnectionsTableRowProps = { obj: Connection; @@ -62,7 +63,9 @@ const ConnectionsTableRow: React.FC = ({ '-' )} - - + + + = ({ title, resourceType }) => ( + +); + +export default ResourceLabel; diff --git a/frontend/src/pages/projects/screens/detail/connections/__tests__/ConnectionsDeleteModal.spec.tsx b/frontend/src/pages/projects/screens/detail/connections/__tests__/ConnectionsDeleteModal.spec.tsx new file mode 100644 index 0000000000..f1d7fc5975 --- /dev/null +++ b/frontend/src/pages/projects/screens/detail/connections/__tests__/ConnectionsDeleteModal.spec.tsx @@ -0,0 +1,64 @@ +import React, { act } from 'react'; +import '@testing-library/jest-dom'; +import { fireEvent, render, screen } from '@testing-library/react'; +import { ConnectionsDeleteModal } from '~/pages/projects/screens/detail/connections/ConnectionsDeleteModal'; +import { mockConnection } from '~/__mocks__/mockConnection'; +import { useRelatedNotebooks } from '~/pages/projects/notebook/useRelatedNotebooks'; +import { mockNotebookK8sResource, mockNotebookState } from '~/__mocks__'; +import { useNotebooksStates } from '~/pages/projects/notebook/useNotebooksStates'; + +jest.mock('~/pages/projects/notebook/useRelatedNotebooks', () => ({ + ...jest.requireActual('~/pages/projects/notebook/useRelatedNotebooks'), + useRelatedNotebooks: jest.fn(), +})); + +jest.mock('~/pages/projects/notebook/useNotebooksStates', () => ({ + useNotebooksStates: jest.fn(), +})); + +const useRelatedNotebooksMock = useRelatedNotebooks as jest.Mock; +const useNotebooksStatesMock = useNotebooksStates as jest.Mock; + +const mockNotebooks = [ + mockNotebookK8sResource({ name: 'connected-notebook', displayName: 'Connected notebook' }), + mockNotebookK8sResource({ name: 'another-notebook', displayName: 'Another notebook' }), +]; +describe('Delete connection modal', () => { + const onDelete = jest.fn(); + const onClose = jest.fn(); + + beforeEach(() => { + useRelatedNotebooksMock.mockReturnValue({ + notebooks: mockNotebooks, + loaded: true, + }); + useNotebooksStatesMock.mockReturnValue([ + [ + mockNotebookState(mockNotebooks[0], { isRunning: true }), + mockNotebookState(mockNotebooks[1], { isStopped: true }), + ], + ]); + }); + + it('should show related resources', async () => { + const deleteConnection = mockConnection({ displayName: 'connection1', description: 'desc1' }); + + render( + , + ); + + const notebooksCountBadge = screen.getByTestId('connections-delete-notebooks-count'); + expect(notebooksCountBadge).toHaveTextContent('2'); + await act(() => fireEvent.click(notebooksCountBadge)); + + const notebookItems = screen.getAllByTestId('connections-delete-notebooks-item'); + expect(notebookItems).toHaveLength(2); + expect(notebookItems[0]).toHaveTextContent('Connected notebook (Running)'); + expect(notebookItems[1]).toHaveTextContent('Another notebook'); + }); +}); diff --git a/frontend/src/pages/projects/screens/detail/connections/__tests__/ConnectionsTable.spec.tsx b/frontend/src/pages/projects/screens/detail/connections/__tests__/ConnectionsTable.spec.tsx index 736de605af..89b52b7515 100644 --- a/frontend/src/pages/projects/screens/detail/connections/__tests__/ConnectionsTable.spec.tsx +++ b/frontend/src/pages/projects/screens/detail/connections/__tests__/ConnectionsTable.spec.tsx @@ -3,12 +3,27 @@ import { render, screen } from '@testing-library/react'; import ConnectionsTable from '~/pages/projects/screens/detail/connections/ConnectionsTable'; import { mockConnectionTypeConfigMapObj } from '~/__mocks__/mockConnectionType'; import { mockConnection } from '~/__mocks__/mockConnection'; +import { mockNotebookK8sResource } from '~/__mocks__/mockNotebookK8sResource'; +import { useRelatedNotebooks } from '~/pages/projects/notebook/useRelatedNotebooks'; + +jest.mock('~/pages/projects/notebook/useRelatedNotebooks', () => ({ + ...jest.requireActual('~/pages/projects/notebook/useRelatedNotebooks'), + useRelatedNotebooks: jest.fn(), +})); + +const useRelatedNotebooksMock = useRelatedNotebooks as jest.Mock; describe('ConnectionsTable', () => { + beforeEach(() => { + useRelatedNotebooksMock.mockReturnValue({ notebooks: [], loaded: true }); + }); + it('should render table', () => { + const connection = mockConnection({ displayName: 'connection1', description: 'desc1' }); render( undefined} setManageConnectionModal={() => undefined} />, @@ -21,9 +36,37 @@ describe('ConnectionsTable', () => { }); it('should show display name of connection type if available', () => { + const connection = mockConnection({ displayName: 'connection1', description: 'desc1' }); + render( + undefined} + setManageConnectionModal={() => undefined} + />, + ); + + expect(screen.getByTestId('connection-table')).toBeTruthy(); + expect(screen.getByText('connection1')).toBeTruthy(); + expect(screen.getByText('desc1')).toBeTruthy(); + expect(screen.queryByText('s3')).toBeFalsy(); + expect(screen.getByText('S3 Buckets')).toBeTruthy(); + }); + + it('should show connected resources', () => { + useRelatedNotebooksMock.mockReturnValue({ + notebooks: [mockNotebookK8sResource({ displayName: 'Connected notebook' })], + loaded: true, + }); + + const connection = mockConnection({ displayName: 'connection1', description: 'desc1' }); render( { expect(screen.getByText('desc1')).toBeTruthy(); expect(screen.queryByText('s3')).toBeFalsy(); expect(screen.getByText('S3 Buckets')).toBeTruthy(); + expect(screen.getByText('Connected notebook')).toBeTruthy(); }); }); diff --git a/frontend/src/pages/projects/screens/detail/data-connections/DeleteDataConnectionModal.tsx b/frontend/src/pages/projects/screens/detail/data-connections/DeleteDataConnectionModal.tsx index a4d942f822..debc3f6360 100644 --- a/frontend/src/pages/projects/screens/detail/data-connections/DeleteDataConnectionModal.tsx +++ b/frontend/src/pages/projects/screens/detail/data-connections/DeleteDataConnectionModal.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; import { DataConnection, DataConnectionType } from '~/pages/projects/types'; import DeleteModal from '~/pages/projects/components/DeleteModal'; -import useRelatedNotebooks, { +import { + useRelatedNotebooks, ConnectedNotebookContext, } from '~/pages/projects/notebook/useRelatedNotebooks'; import { removeNotebookSecret } from '~/api'; diff --git a/frontend/src/pages/projects/screens/detail/data-connections/useSelectedNotebooks.ts b/frontend/src/pages/projects/screens/detail/data-connections/useSelectedNotebooks.ts index 336d92cb4e..2f21ceec6c 100644 --- a/frontend/src/pages/projects/screens/detail/data-connections/useSelectedNotebooks.ts +++ b/frontend/src/pages/projects/screens/detail/data-connections/useSelectedNotebooks.ts @@ -1,7 +1,8 @@ import * as React from 'react'; import { NotebookKind } from '~/k8sTypes'; import { useDeepCompareMemoize } from '~/utilities/useDeepCompareMemoize'; -import useRelatedNotebooks, { +import { + useRelatedNotebooks, ConnectedNotebookContext, } from '~/pages/projects/notebook/useRelatedNotebooks'; import { DataConnection } from '~/pages/projects/types'; diff --git a/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx b/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx index edd5474d39..cb5d4ccd67 100644 --- a/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx +++ b/frontend/src/pages/projects/screens/detail/storage/ManageStorageModal.tsx @@ -6,7 +6,8 @@ import { ProjectDetailsContext } from '~/pages/projects/ProjectDetailsContext'; import { useCreateStorageObjectForNotebook } from '~/pages/projects/screens/spawner/storage/utils'; import CreateNewStorageSection from '~/pages/projects/screens/spawner/storage/CreateNewStorageSection'; import StorageNotebookConnections from '~/pages/projects/notebook/StorageNotebookConnections'; -import useRelatedNotebooks, { +import { + useRelatedNotebooks, ConnectedNotebookContext, } from '~/pages/projects/notebook/useRelatedNotebooks'; import NotebookRestartAlert from '~/pages/projects/components/NotebookRestartAlert'; diff --git a/frontend/src/pages/projects/screens/detail/storage/useIsRootVolume.ts b/frontend/src/pages/projects/screens/detail/storage/useIsRootVolume.ts index 16b1796fb6..de7d5f7f41 100644 --- a/frontend/src/pages/projects/screens/detail/storage/useIsRootVolume.ts +++ b/frontend/src/pages/projects/screens/detail/storage/useIsRootVolume.ts @@ -1,5 +1,6 @@ import { PersistentVolumeClaimKind } from '~/k8sTypes'; -import useRelatedNotebooks, { +import { + useRelatedNotebooks, ConnectedNotebookContext, } from '~/pages/projects/notebook/useRelatedNotebooks'; import { getNotebookPVCMountPathMap } from '~/pages/projects/notebook/utils'; diff --git a/frontend/src/pages/projects/screens/projects/ProjectTableRowNotebookTable.tsx b/frontend/src/pages/projects/screens/projects/ProjectTableRowNotebookTable.tsx index 4f1503cb4a..64851e559f 100644 --- a/frontend/src/pages/projects/screens/projects/ProjectTableRowNotebookTable.tsx +++ b/frontend/src/pages/projects/screens/projects/ProjectTableRowNotebookTable.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { Table } from '~/components/table'; import { NotebookKind, ProjectKind } from '~/k8sTypes'; -import useNotebooksStates from '~/pages/projects/notebook/useNotebooksStates'; +import { useNotebooksStates } from '~/pages/projects/notebook/useNotebooksStates'; import CanEnableElyraPipelinesCheck from '~/concepts/pipelines/elyra/CanEnableElyraPipelinesCheck'; import ProjectTableRowNotebookTableRow from '~/pages/projects/screens/projects/ProjectTableRowNotebookTableRow'; import DeleteNotebookModal from '~/pages/projects/notebook/DeleteNotebookModal'; diff --git a/frontend/src/pages/projects/screens/spawner/storage/utils.ts b/frontend/src/pages/projects/screens/spawner/storage/utils.ts index 0a2bedf3bd..871d80338c 100644 --- a/frontend/src/pages/projects/screens/spawner/storage/utils.ts +++ b/frontend/src/pages/projects/screens/spawner/storage/utils.ts @@ -7,7 +7,8 @@ import { UpdateObjectAtPropAndValue, } from '~/pages/projects/types'; import { NotebookKind, PersistentVolumeClaimKind } from '~/k8sTypes'; -import useRelatedNotebooks, { +import { + useRelatedNotebooks, ConnectedNotebookContext, } from '~/pages/projects/notebook/useRelatedNotebooks'; import useGenericObjectState from '~/utilities/useGenericObjectState';