-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ws): Notebooks 2.0 // Frontend // Namespace selector
Signed-off-by: yelias <[email protected]>
- Loading branch information
yelias
committed
Dec 17, 2024
1 parent
68a0060
commit fee7584
Showing
6 changed files
with
187 additions
and
11 deletions.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
workspaces/frontend/src/__tests__/cypress/cypress/tests/e2e/NamespaceSelector.cy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
const namespaces = ['default', 'kubeflow', 'custom-namespace']; | ||
const mockNamespaces = { | ||
data: [{ name: 'default' }, { name: 'kubeflow' }, { name: 'custom-namespace' }], | ||
}; | ||
|
||
describe('Namespace Selector Dropdown', () => { | ||
beforeEach(() => { | ||
// Mock the namespaces and selected namespace | ||
cy.intercept('GET', '/api/v1/namespaces', { | ||
body: mockNamespaces, | ||
}); | ||
cy.visit('/'); | ||
}); | ||
|
||
it('should open the namespace dropdown and select a namespace', () => { | ||
cy.get('[data-testid="namespace-toggle"]').click(); | ||
cy.get('[data-testid="namespace-dropdown"]').should('be.visible'); | ||
namespaces.forEach((ns) => { | ||
cy.get(`[data-testid="dropdown-item-${ns}"]`).should('exist').and('contain', ns); | ||
}); | ||
|
||
cy.get('[data-testid="dropdown-item-kubeflow"]').click(); | ||
|
||
// Assert the selected namespace is updated | ||
cy.get('[data-testid="namespace-toggle"]').should('contain', 'kubeflow'); | ||
}); | ||
|
||
it('should display the default namespace initially', () => { | ||
cy.get('[data-testid="namespace-toggle"]').should('contain', 'default'); | ||
}); | ||
|
||
it('should navigate to notebook settings and retain the namespace', () => { | ||
cy.get('[data-testid="namespace-toggle"]').click(); | ||
cy.get('[data-testid="dropdown-item-custom-namespace"]').click(); | ||
cy.get('[data-testid="namespace-toggle"]').should('contain', 'custom-namespace'); | ||
// Click on navigation button | ||
cy.get('#Settings').click(); | ||
cy.get('[data-testid="nav-link-/notebookSettings"]').click(); | ||
cy.get('[data-testid="namespace-toggle"]').should('contain', 'custom-namespace'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
workspaces/frontend/src/app/context/NamespaceContextProvider.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import React, { | ||
Check failure on line 1 in workspaces/frontend/src/app/context/NamespaceContextProvider.tsx GitHub Actions / test-and-build
|
||
useState, | ||
useContext, | ||
ReactNode, | ||
useMemo, | ||
useCallback, | ||
} from 'react'; | ||
import useMount from '../hooks/useMount'; | ||
|
||
interface NamespaceContextState { | ||
namespaces: string[]; | ||
selectedNamespace: string; | ||
setSelectedNamespace: (namespace: string) => void; | ||
} | ||
|
||
const NamespaceContext = React.createContext<NamespaceContextState | undefined>( | ||
undefined | ||
); | ||
|
||
export const useNamespaceContext = () => { | ||
const context = useContext(NamespaceContext); | ||
if (!context) { | ||
throw new Error( | ||
Check failure on line 23 in workspaces/frontend/src/app/context/NamespaceContextProvider.tsx GitHub Actions / test-and-build
|
||
"useNamespaceContext must be used within a NamespaceProvider" | ||
); | ||
} | ||
return context; | ||
}; | ||
|
||
interface NamespaceProviderProps { | ||
children: ReactNode; | ||
} | ||
|
||
export const NamespaceProvider: React.FC<NamespaceProviderProps> = ({ | ||
children, | ||
}) => { | ||
const [namespaces, setNamespaces] = useState<string[]>([]); | ||
const [selectedNamespace, setSelectedNamespace] = useState<string>(""); | ||
|
||
// Todo: Need to replace with actual API call | ||
const fetchNamespaces = useCallback(async () => { | ||
const mockNamespaces = { | ||
data: [{ name: 'default' }, { name: 'kubeflow' }, { name: 'custom-namespace' }], | ||
}; | ||
const namespaceNames = mockNamespaces.data.map((ns) => ns.name); | ||
setNamespaces(namespaceNames); | ||
setSelectedNamespace(namespaceNames.length > 0 ? namespaceNames[0] : ""); | ||
}, []); | ||
useMount(fetchNamespaces); | ||
const namespacesContextValues = useMemo( | ||
() => ({ namespaces, selectedNamespace, setSelectedNamespace }), | ||
[namespaces, selectedNamespace] | ||
); | ||
return ( | ||
<NamespaceContext.Provider value={namespacesContextValues}> | ||
{children} | ||
</NamespaceContext.Provider> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { useEffect } from "react" | ||
|
||
const useMount = (callback:()=>void): void => { | ||
useEffect(() => { | ||
callback(); | ||
}, []); | ||
} | ||
|
||
export default useMount; |
57 changes: 57 additions & 0 deletions
57
workspaces/frontend/src/shared/components/NamespaceSelector.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import React, { FC, useMemo, useState } from 'react'; | ||
import { | ||
Dropdown, | ||
DropdownItem, | ||
MenuToggle, | ||
DropdownList, | ||
DropdownProps, | ||
} from '@patternfly/react-core'; | ||
import { useNamespaceContext } from '../../app/context/NamespaceContextProvider'; | ||
|
||
const NamespaceSelector: FC = () => { | ||
const { namespaces, selectedNamespace, setSelectedNamespace } = useNamespaceContext(); | ||
const [isOpen, setIsOpen] = useState<boolean>(false); | ||
|
||
const onSelect: DropdownProps['onSelect'] = (_event, value) => { | ||
setSelectedNamespace(value as string); | ||
setIsOpen(false); | ||
}; | ||
|
||
const dropdownItems = useMemo( | ||
() => | ||
namespaces.map((ns) => ( | ||
<DropdownItem | ||
key={ns} | ||
itemId={ns} | ||
className="namespace-list-items" | ||
data-testid={`dropdown-item-${ns}`} | ||
> | ||
{ns} | ||
</DropdownItem> | ||
)), | ||
[namespaces], | ||
); | ||
|
||
return ( | ||
<Dropdown | ||
onSelect={onSelect} | ||
toggle={(toggleRef) => ( | ||
<MenuToggle | ||
ref={toggleRef} | ||
onClick={() => setIsOpen(!isOpen)} | ||
isExpanded={isOpen} | ||
className="namespace-select-toggle" | ||
data-testid="namespace-toggle" | ||
> | ||
{selectedNamespace} | ||
</MenuToggle> | ||
)} | ||
isOpen={isOpen} | ||
data-testid="namespace-dropdown" | ||
> | ||
<DropdownList>{dropdownItems}</DropdownList> | ||
</Dropdown> | ||
); | ||
}; | ||
|
||
export default NamespaceSelector; |