diff --git a/frontend/src/components/Sidebar/Sidebar.tsx b/frontend/src/components/Sidebar/Sidebar.tsx index 529db8ab55..afd0239509 100644 --- a/frontend/src/components/Sidebar/Sidebar.tsx +++ b/frontend/src/components/Sidebar/Sidebar.tsx @@ -17,13 +17,8 @@ import { ActionButton } from '../common'; import CreateButton from '../common/Resource/CreateButton'; import NavigationTabs from './NavigationTabs'; import prepareRoutes from './prepareRoutes'; -import SidebarItem from './SidebarItem'; -import { - DefaultSidebars, - setSidebarSelected, - setWhetherSidebarOpen, - SidebarEntry, -} from './sidebarSlice'; +import SidebarItem, { SidebarItemProps } from './SidebarItem'; +import { DefaultSidebars, setSidebarSelected, setWhetherSidebarOpen } from './sidebarSlice'; import VersionButton from './VersionButton'; export const drawerWidth = 240; @@ -153,6 +148,34 @@ const DefaultLinkArea = memo((props: { sidebarName: string; isOpen: boolean }) = ); }); +/** + * Checks if item or any sub items are selected + */ +function getIsSelected(item: SidebarItemProps, selectedName?: string | null): boolean { + if (!selectedName) return false; + return ( + item.name === selectedName || Boolean(item.subList?.find(it => getIsSelected(it, selectedName))) + ); +} + +/** + * Updates the isSelected field of an item + */ +function updateItemSelected( + item: SidebarItemProps, + selectedName?: string | null +): SidebarItemProps { + const isSelected = getIsSelected(item, selectedName); + if (isSelected === false) return item; + return { + ...item, + isSelected: isSelected, + subList: item.subList + ? item.subList.map(it => updateItemSelected(it, selectedName)) + : item.subList, + }; +} + export default function Sidebar() { const { t, i18n } = useTranslation(['glossary', 'translation']); @@ -177,7 +200,7 @@ export default function Sidebar() { return prepareRoutes(t, sidebar.selected.sidebar || ''); }, [ cluster, - sidebar.selected, + sidebar.selected.sidebar, sidebar.entries, sidebar.filters, i18n.language, @@ -195,13 +218,18 @@ export default function Sidebar() { [sidebar.selected.sidebar, isOpen] ); + const processedItems = useMemo( + () => items.map(item => updateItemSelected(item, sidebar.selected.item)), + [items, sidebar.selected.item] + ); + if (sidebar.selected.sidebar === null || !sidebar?.isVisible) { return null; } return ( ( { search, useClusterURL = false, subList = [], - selectedName, + isSelected, hasParent = false, icon, fullWidth = true, @@ -61,31 +61,6 @@ const SidebarItem = memo((props: SidebarItemProps) => { fullURL = createRouteURL(routeName); } - const isSelected = React.useMemo(() => { - if (name === selectedName) { - return true; - } - - let subListToCheck = [...subList]; - for (let i = 0; i < subListToCheck.length; i++) { - const subItem = subListToCheck[i]; - if (subItem.name === selectedName) { - return true; - } - - if (!!subItem.subList) { - subListToCheck = subListToCheck.concat(subItem.subList); - } - } - return false; - }, [subList, name, selectedName]); - - function shouldExpand() { - return isSelected || !!subList.find(item => item.name === selectedName); - } - - const expanded = subList.length > 0 && shouldExpand(); - return hide ? null : ( { padding: 0, }} > - + { {subList.map((item: SidebarItemProps) => ( = args => { export const Selected = Template.bind({}); Selected.args = { - selectedName: 'cluster', + isSelected: true, name: 'cluster', label: 'Cluster', icon: 'mdi:hexagon-multiple-outline', @@ -43,7 +43,7 @@ Selected.args = { export const Unselected = Template.bind({}); Unselected.args = { - selectedName: 'meow', + isSelected: false, name: 'cluster', label: 'Cluster', icon: 'mdi:hexagon-multiple-outline', @@ -52,14 +52,14 @@ Unselected.args = { export const SublistExpanded = Template.bind({}); SublistExpanded.args = { - selectedName: 'cluster', + isSelected: true, name: 'cluster', label: 'Cluster', fullWidth: true, icon: 'mdi:hexagon-multiple-outline', subList: [ { - selectedName: 'cluster', + isSelected: true, name: 'namespaces', label: 'Namespaces', hasParent: true, @@ -69,14 +69,14 @@ SublistExpanded.args = { export const Sublist = Template.bind({}); Sublist.args = { - selectedName: 'meow', + isSelected: false, name: 'cluster', label: 'Cluster', fullWidth: true, icon: 'mdi:hexagon-multiple-outline', subList: [ { - selectedName: 'cluster', + isSelected: false, name: 'namespaces', label: 'Namespaces', hasParent: true, diff --git a/frontend/src/components/Sidebar/__snapshots__/Sidebaritem.SublistExpanded.stories.storyshot b/frontend/src/components/Sidebar/__snapshots__/Sidebaritem.SublistExpanded.stories.storyshot index 49701e12dd..16bdb81545 100644 --- a/frontend/src/components/Sidebar/__snapshots__/Sidebaritem.SublistExpanded.stories.storyshot +++ b/frontend/src/components/Sidebar/__snapshots__/Sidebaritem.SublistExpanded.stories.storyshot @@ -50,10 +50,10 @@ class="MuiList-root css-2l483y-MuiList-root" >