Skip to content

Commit

Permalink
Global Nav: Add collapsed global sidebar (#88865)
Browse files Browse the repository at this point in the history
* Global Nav: Add collapsed global sidebar

* Fix positioning of tooltips in collapsed sidebar

* fix padding on me icon

* Update to use feature flag

* revert changes that hides the global site sidebar

* Update sites dashboard to setSelectedSiteId when clicking on a site thumbnail/name

* Add onClick handler

* disable feature flag by default

* Undo removal of href prop
  • Loading branch information
eoigal authored Mar 28, 2024
1 parent 0264199 commit 995ce9c
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 12 deletions.
21 changes: 19 additions & 2 deletions client/layout/global-sidebar/menu-items/notifications/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import { Component, createRef } from 'react';
import { connect } from 'react-redux';
import store from 'store';
import AsyncLoad from 'calypso/components/async-load';
import { withCurrentRoute } from 'calypso/components/route';
import TranslatableString from 'calypso/components/translatable/proptype';
import SidebarMenuItem from 'calypso/layout/global-sidebar/menu-items/menu-item';
import { recordTracksEvent } from 'calypso/state/analytics/actions';
import { getShouldShowCollapsedGlobalSidebar } from 'calypso/state/global-sidebar/selectors';
import hasUnseenNotifications from 'calypso/state/selectors/has-unseen-notifications';
import isNotificationsOpen from 'calypso/state/selectors/is-notifications-open';
import { toggleNotificationsPanel } from 'calypso/state/ui/actions';
import { getSelectedSiteId } from 'calypso/state/ui/selectors';
import { BellIcon } from './icon';

import './style.scss';
Expand All @@ -24,6 +27,7 @@ class SidebarNotifications extends Component {
isNotificationsOpen: PropTypes.bool,
hasUnseenNotifications: PropTypes.bool,
tooltip: TranslatableString,
shouldShowCollapsedGlobalSidebar: PropTypes.bool,
};

notificationLink = createRef();
Expand Down Expand Up @@ -133,6 +137,9 @@ class SidebarNotifications extends Component {
className={ classes }
ref={ this.notificationLink }
key={ this.state.animationState }
tooltipPlacement={
this.props.shouldShowCollapsedGlobalSidebar ? 'bottom-left' : 'bottom'
}
/>
<div className="sidebar-notifications__panel" ref={ this.notificationPanel }>
<AsyncLoad
Expand All @@ -149,15 +156,25 @@ class SidebarNotifications extends Component {
}
}

const mapStateToProps = ( state ) => {
const mapStateToProps = ( state, { currentSection } ) => {
const sectionGroup = currentSection?.group ?? null;
const siteId = getSelectedSiteId( state );
const shouldShowCollapsedGlobalSidebar = getShouldShowCollapsedGlobalSidebar(
state,
siteId,
sectionGroup
);
return {
isNotificationsOpen: isNotificationsOpen( state ),
hasUnseenNotifications: hasUnseenNotifications( state ),
shouldShowCollapsedGlobalSidebar,
};
};
const mapDispatchToProps = {
toggleNotificationsPanel,
recordTracksEvent,
};

export default connect( mapStateToProps, mapDispatchToProps )( SidebarNotifications );
export default withCurrentRoute(
connect( mapStateToProps, mapDispatchToProps )( SidebarNotifications )
);
10 changes: 10 additions & 0 deletions client/layout/global-sidebar/menu-items/search/index.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { Icon, search } from '@wordpress/icons';
import classnames from 'classnames';
import { useSelector } from 'react-redux';
import { useCurrentRoute } from 'calypso/components/route';
import { useDispatch } from 'calypso/state';
import { openCommandPalette } from 'calypso/state/command-palette/actions';
import { getShouldShowCollapsedGlobalSidebar } from 'calypso/state/global-sidebar/selectors';
import { getSelectedSiteId } from 'calypso/state/ui/selectors';
import SidebarMenuItem from '../menu-item';

export const SidebarSearch = ( { tooltip, onClick } ) => {
Expand All @@ -10,6 +14,11 @@ export const SidebarSearch = ( { tooltip, onClick } ) => {
dispatch( openCommandPalette() );
onClick();
};
const selectedSiteId = useSelector( getSelectedSiteId );
const { currentSection } = useCurrentRoute();
const shouldShowCollapsedGlobalSidebar = useSelector( ( state ) => {
return getShouldShowCollapsedGlobalSidebar( state, selectedSiteId, currentSection?.group );
} );
return (
<>
<SidebarMenuItem
Expand All @@ -19,6 +28,7 @@ export const SidebarSearch = ( { tooltip, onClick } ) => {
} ) }
tooltip={ tooltip }
icon={ <Icon icon={ search } size={ 28 } /> }
tooltipPlacement={ shouldShowCollapsedGlobalSidebar ? 'bottom-left' : 'bottom' }
/>
</>
);
Expand Down
39 changes: 39 additions & 0 deletions client/layout/global-sidebar/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ $brand-text: "SF Pro Text", $sans;
li.sidebar-streams__search {
margin: 0;
}

.sidebar__menu-link {
&.svg_all-sites {
margin: -2px 6px -2px -2px;
}
}
}

.sidebar__footer {
Expand Down Expand Up @@ -399,3 +405,36 @@ $brand-text: "SF Pro Text", $sans;
}
}
}

.is-global-sidebar-collapsed {
.global-sidebar {
.sidebar__header,
.sidebar__footer {
flex-direction: column;

.sidebar__footer-profile {
padding: 0;
}
}

.sidebar__header {
span.dotcom {
background-position: left;
width: 24px;
margin-left: 6px;
}
}

.sidebar__body {
.sidebar__menu-link-text {
display: none;
}
.sidebar__menu-icon {
margin-left: 4px;
&.svg_all-sites {
margin-left: 2px;
}
}
}
}
}
12 changes: 11 additions & 1 deletion client/layout/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { closeCommandPalette } from 'calypso/state/command-palette/actions';
import { isCommandPaletteOpen as getIsCommandPaletteOpen } from 'calypso/state/command-palette/selectors';
import { isUserLoggedIn } from 'calypso/state/current-user/selectors';
import {
getShouldShowCollapsedGlobalSidebar,
getShouldShowGlobalSidebar,
getShouldShowGlobalSiteSidebar,
} from 'calypso/state/global-sidebar/selectors';
Expand Down Expand Up @@ -313,6 +314,7 @@ class Layout extends Component {
'is-woocommerce-core-profiler-flow': this.props.isWooCoreProfilerFlow,
woo: this.props.isWooCoreProfilerFlow,
'is-global-sidebar-visible': this.props.isGlobalSidebarVisible,
'is-global-sidebar-collapsed': this.props.isGlobalSidebarCollapsed,
'is-global-site-sidebar-visible': this.props.isGlobalSiteSidebarVisible,
} );

Expand All @@ -335,7 +337,9 @@ class Layout extends Component {
this.props.userAllowedToHelpCenter;

const shouldDisableSidebarScrollSynchronizer =
this.props.isGlobalSidebarVisible || this.props.isGlobalSiteSidebarVisible;
this.props.isGlobalSidebarVisible ||
this.props.isGlobalSidebarCollapsed ||
this.props.isGlobalSiteSidebarVisible;

return (
<div className={ sectionClass }>
Expand Down Expand Up @@ -457,6 +461,11 @@ export default withCurrentRoute(
[ 'jetpack-connect', 'login' ].includes( sectionName ) &&
isWooCommerceCoreProfilerFlow( state );
const shouldShowGlobalSidebar = getShouldShowGlobalSidebar( state, siteId, sectionGroup );
const shouldShowCollapsedGlobalSidebar = getShouldShowCollapsedGlobalSidebar(
state,
siteId,
sectionGroup
);
const shouldShowGlobalSiteSidebar = getShouldShowGlobalSiteSidebar(
state,
siteId,
Expand Down Expand Up @@ -531,6 +540,7 @@ export default withCurrentRoute(
userAllowedToHelpCenter,
currentRoute,
isGlobalSidebarVisible: shouldShowGlobalSidebar && ! sidebarIsHidden,
isGlobalSidebarCollapsed: shouldShowCollapsedGlobalSidebar && ! sidebarIsHidden,
isGlobalSiteSidebarVisible: shouldShowGlobalSiteSidebar && ! sidebarIsHidden,
currentRoutePattern: getCurrentRoutePattern( state ),
userCapabilities: state.currentUser.capabilities,
Expand Down
11 changes: 7 additions & 4 deletions client/my-sites/sidebar/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,17 @@ $brand-text: "SF Pro Text", $sans;
--color-global-masterbar-hover-background: var(--studio-gray-80);
}

.is-global-sidebar-collapsed {
--sidebar-width-max: 69px;
--sidebar-width-min: 69px;

}

.layout__secondary {
overflow: initial;

.global-sidebar {
overflow: hidden;
overflow: unset;
}
}
}
Expand Down Expand Up @@ -394,9 +400,6 @@ $font-size: rem(14px);
&::before {
transition: none;
}
&.svg_all-sites {
margin: -2px 6px -2px -2px;
}
}

&:hover,
Expand Down
8 changes: 6 additions & 2 deletions client/my-sites/sidebar/use-site-menu-items.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useCurrentRoute } from 'calypso/components/route';
import domainOnlyFallbackMenu from 'calypso/my-sites/sidebar/static-data/domain-only-fallback-menu';
import { getAdminMenu } from 'calypso/state/admin-menu/selectors';
import {
getShouldShowCollapsedGlobalSidebar,
getShouldShowGlobalSidebar,
getShouldShowGlobalSiteSidebar,
} from 'calypso/state/global-sidebar/selectors';
Expand Down Expand Up @@ -45,11 +46,13 @@ const useSiteMenuItems = () => {
const shouldShowGlobalSidebar = useSelector( ( state ) => {
return getShouldShowGlobalSidebar( state, selectedSiteId, currentSection?.group );
} );
const shouldShowCollapsedGlobalSidebar = useSelector( ( state ) => {
return getShouldShowCollapsedGlobalSidebar( state, selectedSiteId, currentSection?.group );
} );
const shouldShowGlobalSiteSidebar = useSelector( ( state ) => {
return getShouldShowGlobalSiteSidebar( state, selectedSiteId, currentSection?.group );
} );
const isDesktop = useBreakpoint( '>782px' );

useEffect( () => {
if ( selectedSiteId && siteDomain ) {
dispatch( requestAdminMenu( selectedSiteId ) );
Expand Down Expand Up @@ -117,9 +120,10 @@ const useSiteMenuItems = () => {
} );
}, [ isJetpack, menuItems, siteDomain, translate ] );

if ( shouldShowGlobalSidebar ) {
if ( shouldShowGlobalSidebar || shouldShowCollapsedGlobalSidebar ) {
return globalSidebarMenu();
}

if ( shouldShowGlobalSiteSidebar ) {
return globalSiteSidebarMenu( {
siteDomain,
Expand Down
23 changes: 20 additions & 3 deletions client/sites-dashboard/components/sites-table-row.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { isEnabled } from '@automattic/calypso-config';
import { ListTile, Popover } from '@automattic/components';
import { useSiteLaunchStatusLabel } from '@automattic/sites';
import { css } from '@emotion/css';
import styled from '@emotion/styled';
import { useI18n } from '@wordpress/react-i18n';
import { useTranslate } from 'i18n-calypso';
import { memo, useRef, useState } from 'react';
import * as React from 'react';
import { useInView } from 'react-intersection-observer';
import StatsSparkline from 'calypso/blocks/stats-sparkline';
import TimeSince from 'calypso/components/time-since';
import SitesMigrationTrialBadge from 'calypso/sites-dashboard/components/sites-migration-trial-badge';
import { useSelector } from 'calypso/state';
import { useDispatch, useSelector } from 'calypso/state';
import { getCurrentUserId } from 'calypso/state/current-user/selectors';
import isDIFMLiteInProgress from 'calypso/state/selectors/is-difm-lite-in-progress';
import { isTrialSite } from 'calypso/state/sites/plans/selectors';
import { hasSiteStatsQueryFailed } from 'calypso/state/stats/lists/selectors';
import { setSelectedSiteId } from 'calypso/state/ui/actions';
import {
displaySiteUrl,
getDashboardUrl,
Expand Down Expand Up @@ -185,6 +188,20 @@ export default memo( function SitesTableRow( { site }: SiteTableRowProps ) {
siteUrl = site.options?.unmapped_url;
}

const dispatch = useDispatch();
const onSiteClick = ( event: React.MouseEvent< HTMLAnchorElement, MouseEvent > ) => {
if ( isEnabled( 'layout/dotcom-nav-redesign-v2' ) ) {
event.stopPropagation();
event.preventDefault();
dispatch( setSelectedSiteId( site.ID ) );
}
};

let title = __( 'Visit Dashboard' );
if ( isEnabled( 'layout/dotcom-nav-redesign-v2' ) ) {
title = __( 'View Site Details' );
}

return (
<Row ref={ ref }>
<Column>
Expand All @@ -193,13 +210,13 @@ export default memo( function SitesTableRow( { site }: SiteTableRowProps ) {
min-width: 0;
` }
leading={
<ListTileLeading href={ dashboardUrl } title={ __( 'Visit Dashboard' ) }>
<ListTileLeading href={ dashboardUrl } title={ title } onClick={ onSiteClick }>
<SiteItemThumbnail displayMode="list" showPlaceholder={ ! inView } site={ site } />
</ListTileLeading>
}
title={
<ListTileTitle>
<SiteName href={ dashboardUrl } title={ __( 'Visit Dashboard' ) }>
<SiteName href={ dashboardUrl } title={ title } onClick={ onSiteClick }>
{ site.title }
</SiteName>
{ isP2Site && <SitesP2Badge>P2</SitesP2Badge> }
Expand Down
7 changes: 7 additions & 0 deletions client/sites-dashboard/controller.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isEnabled } from '@automattic/calypso-config';
import {
DEFAULT_SITE_LAUNCH_STATUS_GROUP_VALUE,
siteLaunchStatusGroupValues,
Expand All @@ -8,6 +9,7 @@ import AsyncLoad from 'calypso/components/async-load';
import PageViewTracker from 'calypso/lib/analytics/page-view-tracker';
import MySitesNavigation from 'calypso/my-sites/navigation';
import { removeNotice } from 'calypso/state/notices/actions';
import { setAllSitesSelected } from 'calypso/state/ui/actions';
import { SitesDashboard } from './components/sites-dashboard';
import type { Context as PageJSContext } from '@automattic/calypso-router';

Expand Down Expand Up @@ -97,6 +99,11 @@ export function sitesDashboard( context: PageJSContext, next: () => void ) {
/>
</>
);

if ( isEnabled( 'layout/dotcom-nav-redesign-v2' ) ) {
// By definition, Sites Management does not select any one specific site
context.store.dispatch( setAllSitesSelected() );
}
next();
}

Expand Down
12 changes: 12 additions & 0 deletions client/state/global-sidebar/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isEnabled } from '@automattic/calypso-config';
import { isGlobalSiteViewEnabled } from '../sites/selectors';
import type { AppState } from 'calypso/types';

Expand All @@ -10,6 +11,17 @@ export const getShouldShowGlobalSidebar = ( _: AppState, siteId: number, section
);
};

export const getShouldShowCollapsedGlobalSidebar = (
state: AppState,
siteId: number,
sectionGroup: string
) => {
// Global sidebar should be collapsed when in sites dashboard and a site is selected.
return (
isEnabled( 'layout/dotcom-nav-redesign-v2' ) && sectionGroup === 'sites-dashboard' && siteId
);
};

export const getShouldShowGlobalSiteSidebar = (
state: AppState,
siteId: number,
Expand Down

0 comments on commit 995ce9c

Please sign in to comment.