From dbc14fa7e9db18345b67fa55368721a9847869ae Mon Sep 17 00:00:00 2001 From: Mateusz Kwasniewski Date: Tue, 28 May 2024 15:47:26 +0200 Subject: [PATCH] feat: last viewed project (#7191) --- .../NavigationSidebar/IconRenderer.tsx | 4 +- .../NavigationSidebar/ListItems.tsx | 13 ++++- .../NavigationSidebar/NavigationList.tsx | 46 +++++++++++++++++- .../NavigationSidebar/NavigationSidebar.tsx | 48 +++++++++++++------ .../MainLayout/NavigationSidebar/ShowHide.tsx | 14 ++++-- frontend/src/hooks/useLastViewedProject.ts | 2 +- 6 files changed, 103 insertions(+), 24 deletions(-) diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/IconRenderer.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/IconRenderer.tsx index e7d26c1dbc..7aac47429c 100644 --- a/frontend/src/component/layout/MainLayout/NavigationSidebar/IconRenderer.tsx +++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/IconRenderer.tsx @@ -9,14 +9,14 @@ import CustomStrategiesIcon from '@mui/icons-material/ExtensionOutlined'; import TagTypesIcon from '@mui/icons-material/LabelImportantOutlined'; import EnvironmentsIcon from '@mui/icons-material/CloudOutlined'; import UsersIcon from '@mui/icons-material/GroupOutlined'; -import ServiceAccountIcon from '@mui/icons-material/SmartToyOutlined'; +import ServiceAccountIcon from '@mui/icons-material/Computer'; import GroupsIcon from '@mui/icons-material/GroupsOutlined'; import RoleIcon from '@mui/icons-material/AdminPanelSettingsOutlined'; import ApiAccessIcon from '@mui/icons-material/KeyOutlined'; import SingleSignOnIcon from '@mui/icons-material/AssignmentOutlined'; import NetworkIcon from '@mui/icons-material/HubOutlined'; import MaintenanceIcon from '@mui/icons-material/BuildOutlined'; -import BannersIcon from '@mui/icons-material/PhotoOutlined'; +import BannersIcon from '@mui/icons-material/ViewCarousel'; import InstanceStatsIcon from '@mui/icons-material/QueryStatsOutlined'; import LicenseIcon from '@mui/icons-material/ReceiptLongOutlined'; import InstancePrivacyIcon from '@mui/icons-material/ShieldOutlined'; diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/ListItems.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/ListItems.tsx index 5375b7219e..22f86d8db0 100644 --- a/frontend/src/component/layout/MainLayout/NavigationSidebar/ListItems.tsx +++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/ListItems.tsx @@ -4,7 +4,9 @@ import { ListItemButton, ListItemIcon, ListItemText, + styled, Tooltip, + Typography, } from '@mui/material'; import { Link } from 'react-router-dom'; import { basePath } from 'utils/formatPath'; @@ -19,6 +21,13 @@ const listItemButtonStyle = (theme: Theme) => ({ }, }); +const CappedText = styled(Typography)({ + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + maxWidth: '160px', +}); + export const FullListItem: FC<{ href: string; text: string; @@ -38,7 +47,9 @@ export const FullListItem: FC<{ ({ minWidth: theme.spacing(4) })}> {children} - + + {text} + {badge} diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationList.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationList.tsx index f205caca72..ac10cdb769 100644 --- a/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationList.tsx +++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationList.tsx @@ -7,7 +7,7 @@ import { MiniListItem, SignOutItem, } from './ListItems'; -import { List, styled, Tooltip, Typography } from '@mui/material'; +import { Box, List, styled, Tooltip, Typography } from '@mui/material'; import { IconRenderer, StyledProjectIcon } from './IconRenderer'; import { EnterpriseBadge } from 'component/common/EnterpriseBadge/EnterpriseBadge'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; @@ -98,6 +98,27 @@ export const OtherLinksList = () => { ); }; +export const RecentProjectsList: FC<{ + projectId: string; + mode: NavigationMode; + onClick: () => void; +}> = ({ projectId, mode, onClick }) => { + const DynamicListItem = mode === 'mini' ? MiniListItem : FullListItem; + + return ( + + + + + + ); +}; + export const PrimaryNavigationList: FC<{ mode: NavigationMode; onClick: (activeItem: string) => void; @@ -177,3 +198,26 @@ export const SecondaryNavigation: FC<{ ); }; + +export const RecentProjectsNavigation: FC<{ + mode: NavigationMode; + projectId: string; + onClick: () => void; +}> = ({ mode, onClick, projectId }) => { + return ( + + {mode === 'full' && ( + + Recent project + + )} + + + ); +}; diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx index 218cefdc93..25a1c2b960 100644 --- a/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx +++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NavigationSidebar.tsx @@ -7,10 +7,12 @@ import { useExpanded } from './useExpanded'; import { OtherLinksList, PrimaryNavigationList, + RecentProjectsNavigation, SecondaryNavigation, SecondaryNavigationList, } from './NavigationList'; import { useInitialPathname } from './useInitialPathname'; +import { useLastViewedProject } from 'hooks/useLastViewedProject'; export const MobileNavigationSidebar: FC<{ onClick: () => void }> = ({ onClick, @@ -37,7 +39,11 @@ export const MobileNavigationSidebar: FC<{ onClick: () => void }> = ({ export const StyledBox = styled(Box)(({ theme }) => ({ backgroundColor: theme.palette.background.paper, - padding: theme.spacing(2, 2, 6, 2), + padding: theme.spacing(2, 2, 2, 2), + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(3), + zIndex: theme.zIndex.tooltip, })); export const NavigationSidebar = () => { @@ -49,6 +55,9 @@ export const NavigationSidebar = () => { const [activeItem, setActiveItem] = useState(initialPathname); + const { lastViewed } = useLastViewedProject(); + const showRecentProject = mode === 'full' && lastViewed; + return ( { activeItem={activeItem} /> - { - changeExpanded('admin', expand); - }} - mode={mode} - title='Admin' - > - { + changeExpanded('admin', expand); + }} mode={mode} - onClick={setActiveItem} - activeItem={activeItem} + title='Admin' + > + + + )} + + {showRecentProject && ( + setActiveItem('/projects')} /> - + )} + { diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/ShowHide.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/ShowHide.tsx index ad6f79cea4..64d455e468 100644 --- a/frontend/src/component/layout/MainLayout/NavigationSidebar/ShowHide.tsx +++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/ShowHide.tsx @@ -1,8 +1,8 @@ import { Box, IconButton, styled, Tooltip } from '@mui/material'; import type { NavigationMode } from './NavigationMode'; import type { FC } from 'react'; -import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; -import ChevronRightIcon from '@mui/icons-material/ChevronRight'; +import HideIcon from '@mui/icons-material/KeyboardDoubleArrowLeft'; +import ExpandIcon from '@mui/icons-material/KeyboardDoubleArrowRight'; const ShowHideWrapper = styled(Box, { shouldForwardProp: (prop) => prop !== 'mode', @@ -10,7 +10,8 @@ const ShowHideWrapper = styled(Box, { display: 'flex', justifyContent: 'space-between', alignItems: 'center', - margin: theme.spacing(2, 1, 0, mode === 'mini' ? 1.5 : 2), + padding: theme.spacing(2, 1, 0, mode === 'mini' ? 1.5 : 2), + marginTop: 'auto', cursor: 'pointer', })); @@ -32,10 +33,13 @@ export const ShowHide: FC<{ mode: NavigationMode; onChange: () => void }> = ({ )} {mode === 'full' ? ( - + ) : ( - + )} diff --git a/frontend/src/hooks/useLastViewedProject.ts b/frontend/src/hooks/useLastViewedProject.ts index 3abd74ee94..83747a3663 100644 --- a/frontend/src/hooks/useLastViewedProject.ts +++ b/frontend/src/hooks/useLastViewedProject.ts @@ -5,7 +5,7 @@ import { basePath } from 'utils/formatPath'; export const useLastViewedProject = () => { const key = `${basePath}:unleash-lastViewedProject`; - const [lastViewed, setLastViewed] = useState(() => { + const [lastViewed, setLastViewed] = useState(() => { return getLocalStorageItem(key); });