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

[CDS Updates] - Handle cds sticky sidebar #11479

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
183 changes: 101 additions & 82 deletions packages/manager/src/MainContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ import { makeStyles } from 'tss-react/mui';
import Logo from 'src/assets/logo/akamai-logo.svg';
import { MainContentBanner } from 'src/components/MainContentBanner';
import { MaintenanceScreen } from 'src/components/MaintenanceScreen';
import { SIDEBAR_WIDTH } from 'src/components/PrimaryNav/constants';
import { SideMenu } from 'src/components/PrimaryNav/SideMenu';
import { SIDEBAR_WIDTH } from 'src/components/PrimaryNav/SideMenu';
import { useIsPageScrollable } from 'src/components/PrimaryNav/utils';
import { SuspenseLoader } from 'src/components/SuspenseLoader';
import { useDialogContext } from 'src/context/useDialogContext';
import { Footer } from 'src/features/Footer';
import { FOOTER_HEIGHT, Footer } from 'src/features/Footer';
import { GlobalNotifications } from 'src/features/GlobalNotifications/GlobalNotifications';
import {
notificationCenterContext,
useNotificationContext,
} from 'src/features/NotificationCenter/NotificationCenterContext';
import { TopMenu } from 'src/features/TopMenu/TopMenu';
import { TOPMENU_HEIGHT, TopMenu } from 'src/features/TopMenu/TopMenu';
import {
useMutatePreferences,
usePreferences,
Expand Down Expand Up @@ -199,6 +200,7 @@ const IAM = React.lazy(() =>
);

export const MainContent = () => {
const contentRef = React.useRef<HTMLDivElement>(null);
const { classes, cx } = useStyles();
const { data: isDesktopSidebarOpenPreference } = usePreferences(
(preferences) => preferences?.desktop_sidebar_open
Expand Down Expand Up @@ -239,6 +241,8 @@ export const MainContent = () => {

const { isIAMEnabled } = useIsIAMEnabled();

const { isPageScrollable } = useIsPageScrollable(contentRef);

/**
* this is the case where the user has successfully completed signup
* but needs a manual review from Customer Support. In this case,
Expand Down Expand Up @@ -292,6 +296,11 @@ export const MainContent = () => {
});
};

const sideMenuContainerHeight =
isPageScrollable === true
? '100vh'
: `calc(100vh - ${FOOTER_HEIGHT + TOPMENU_HEIGHT}px)`;

return (
<div className={classes.appFrame}>
<SessionExpirationProvider value={sessionExpirationContextValue}>
Expand All @@ -303,90 +312,100 @@ export const MainContent = () => {
openSideMenu={() => toggleMenu(true)}
username={username}
/>
<SideMenu
closeMenu={() => toggleMenu(false)}
collapse={desktopMenuIsOpen || false}
desktopMenuToggle={desktopMenuToggle}
open={menuIsOpen}
/>
<div
className={cx(classes.content, {
[classes.fullWidthContent]:
desktopMenuIsOpen ||
(desktopMenuIsOpen && desktopMenuIsOpen === true),
})}
>
<MainContentBanner />
<main
className={classes.cmrWrapper}
id="main-content"
role="main"
<Box display="flex" flex={1} position="relative">
<Box
alignSelf="flex-start"
height={sideMenuContainerHeight}
position="sticky"
top={0}
zIndex={10000}
>
<SideMenu
closeMenu={() => toggleMenu(false)}
collapse={desktopMenuIsOpen || false}
desktopMenuToggle={desktopMenuToggle}
isPageScrollable={isPageScrollable}
open={menuIsOpen}
/>
</Box>
<div
className={cx(classes.content, {
[classes.fullWidthContent]: desktopMenuIsOpen === true,
})}
ref={contentRef}
>
<Grid className={classes.grid} container spacing={0}>
<Grid className={cx(classes.switchWrapper, 'p0')}>
<GlobalNotifications />
<React.Suspense fallback={<SuspenseLoader />}>
<Switch>
<Route component={LinodesRoutes} path="/linodes" />
{isPlacementGroupsEnabled && (
<MainContentBanner />
<main
className={classes.cmrWrapper}
id="main-content"
role="main"
>
<Grid className={classes.grid} container spacing={0}>
<Grid className={cx(classes.switchWrapper, 'p0')}>
<GlobalNotifications />
<React.Suspense fallback={<SuspenseLoader />}>
<Switch>
<Route component={LinodesRoutes} path="/linodes" />
{isPlacementGroupsEnabled && (
<Route
component={PlacementGroups}
path="/placement-groups"
/>
)}
<Route
component={PlacementGroups}
path="/placement-groups"
component={NodeBalancers}
path="/nodebalancers"
/>
)}
<Route
component={NodeBalancers}
path="/nodebalancers"
/>
<Route component={Managed} path="/managed" />
<Route component={Longview} path="/longview" />
<Route component={Images} path="/images" />
<Route
component={StackScripts}
path="/stackscripts"
/>
<Route
component={ObjectStorage}
path="/object-storage"
/>
<Route component={Kubernetes} path="/kubernetes" />
{isIAMEnabled && (
<Route component={IAM} path="/iam" />
)}
<Route component={Account} path="/account" />
<Route component={Profile} path="/profile" />
<Route component={Help} path="/support" />
<Route component={SearchLanding} path="/search" />
<Route component={EventsLanding} path="/events" />
<Route component={Firewalls} path="/firewalls" />
{isDatabasesEnabled && (
<Route component={Databases} path="/databases" />
)}
<Route component={VPC} path="/vpcs" />
{isACLPEnabled && (
<Route component={CloudPulse} path="/monitor" />
)}
<Redirect exact from="/" to={defaultRoot} />
{/** We don't want to break any bookmarks. This can probably be removed eventually. */}
<Redirect from="/dashboard" to={defaultRoot} />
{/**
* This is the catch all routes that allows TanStack Router to take over.
* When a route is not found here, it will be handled by the migration router, which in turns handles the NotFound component.
* It is currently set to the migration router in order to incrementally migrate the app to the new routing.
* This is a temporary solution until we are ready to fully migrate to TanStack Router.
*/}
<Route path="*">
<RouterProvider
context={{ queryClient }}
router={migrationRouter as AnyRouter}
<Route component={Managed} path="/managed" />
<Route component={Longview} path="/longview" />
<Route component={Images} path="/images" />
<Route
component={StackScripts}
path="/stackscripts"
/>
<Route
component={ObjectStorage}
path="/object-storage"
/>
</Route>
</Switch>
</React.Suspense>
<Route component={Kubernetes} path="/kubernetes" />
{isIAMEnabled && (
<Route component={IAM} path="/iam" />
)}
<Route component={Account} path="/account" />
<Route component={Profile} path="/profile" />
<Route component={Help} path="/support" />
<Route component={SearchLanding} path="/search" />
<Route component={EventsLanding} path="/events" />
<Route component={Firewalls} path="/firewalls" />
{isDatabasesEnabled && (
<Route component={Databases} path="/databases" />
)}
<Route component={VPC} path="/vpcs" />
{isACLPEnabled && (
<Route component={CloudPulse} path="/monitor" />
)}
<Redirect exact from="/" to={defaultRoot} />
{/** We don't want to break any bookmarks. This can probably be removed eventually. */}
<Redirect from="/dashboard" to={defaultRoot} />
{/**
* This is the catch all routes that allows TanStack Router to take over.
* When a route is not found here, it will be handled by the migration router, which in turns handles the NotFound component.
* It is currently set to the migration router in order to incrementally migrate the app to the new routing.
* This is a temporary solution until we are ready to fully migrate to TanStack Router.
*/}
<Route path="*">
<RouterProvider
context={{ queryClient }}
router={migrationRouter as AnyRouter}
/>
</Route>
</Switch>
</React.Suspense>
</Grid>
</Grid>
</Grid>
</main>
</div>
</main>
</div>
</Box>
</NotificationProvider>
<Footer />
</ComplianceUpdateProvider>
Expand Down
2 changes: 1 addition & 1 deletion packages/manager/src/Root.styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { makeStyles } from 'tss-react/mui';

import { SIDEBAR_WIDTH } from 'src/components/PrimaryNav/SideMenu';
import { SIDEBAR_WIDTH } from 'src/components/PrimaryNav/constants';

import type { Theme } from '@mui/material/styles';

Expand Down
32 changes: 14 additions & 18 deletions packages/manager/src/components/PrimaryNav/PrimaryNav.styles.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Accordion, Box, Divider, IconButton, omittedProps } from '@linode/ui';
import { Accordion, Box, Divider, omittedProps } from '@linode/ui';
import { Chip } from '@mui/material';
import { styled } from '@mui/material/styles';
import Grid from '@mui/material/Unstable_Grid2';
import { Link } from 'react-router-dom';

import AkamaiLogo from 'src/assets/logo/akamai-logo.svg';
import { SIDEBAR_WIDTH } from 'src/components/PrimaryNav/SideMenu';
import { SIDEBAR_WIDTH } from 'src/components/PrimaryNav/constants';

export const StyledGrid = styled(Grid, {
label: 'StyledGrid',
Expand All @@ -15,10 +15,11 @@ export const StyledGrid = styled(Grid, {
minHeight: 64,
padding: 0,
[theme.breakpoints.up('md')]: {
minHeight: 80,
},
[theme.breakpoints.up('sm')]: {
minHeight: 72,
'&:hover': {
'.primary-nav-toggle': {
left: SIDEBAR_WIDTH - 52,
},
},
},
width: '100%',
}));
Expand Down Expand Up @@ -98,7 +99,9 @@ export const StyledPrimaryLinkBox = styled(Box, {
? theme.tokens.sideNavigation.SelectedMenuItem.Text
: theme.tokens.sideNavigation.DefaultMenuItem.Text,
display: 'flex',
font: theme.tokens.typography.Label.Semibold.S,
// TODO: Enable token once we have imported Nunito
// font: theme.tokens.typography.Label.Semibold.S,
fontFamily: 'LatoWeb',
justifyContent: 'space-between',
transition: theme.transitions.create(['color', 'opacity']),
width: '100%',
Expand All @@ -110,7 +113,7 @@ export const StyledPrimaryLinkBox = styled(Box, {
export const StyledMenuGrid = styled(Grid, {
label: 'StyledMenuGrid',
})(({ theme }) => ({
flex: '1 1 0%',
flexGrow: 1,
overflowX: 'hidden',
overflowY: 'auto',
scrollbarColor: `${theme.color.grey4} transparent `,
Expand Down Expand Up @@ -147,7 +150,9 @@ export const StyledAccordion = styled(Accordion, {
},
alignItems: 'center',
display: 'flex',
font: theme.tokens.typography.Label.Bold.S,
// TODO: Enable token once we have imported Nunito
// font: theme.tokens.typography.Label.Bold.S,
fontFamily: 'LatoWebBold',
padding: '0 10px',
},
'.MuiAccordionDetails-root': {
Expand Down Expand Up @@ -182,15 +187,6 @@ export const StyledAccordion = styled(Accordion, {
})
);

export const StyledIconButton = styled(IconButton, {
label: 'styledIconButton',
})(({ theme }) => ({
'& svg': {
color: theme.tokens.sideNavigation.Icon,
transition: theme.transitions.create(['color']),
},
}));

export const StyledChip = styled(Chip, {
label: 'styledChip',
shouldForwardProp: omittedProps(['isActiveLink']),
Expand Down
Loading
Loading