feat: improve mobile display by tab bar and other changes (#2304)
* feat: improve mobile display by tab bar and other changes * fix: remove unused declaration in mobile navigation * fix: update desktop navbar stories title * fix: retrieve old titles for desktop-navbar stories * fix: styles, manage active tabs * fix: styles, manage active tabs * fix: styles, manage active tabs * fix: styles, manage active tabs * fix: styles, manage active tabs * fix: styles, manage active tabs * fix: styles, manage active tabs * fix: styles, manage active tabs * fix: update logic for tab bar menu icons * fix: remove Settings icon for mobile * fix: resolve comments in pl * feat: rework mobile navigation bar * Fix * Fixes --------- Co-authored-by: Thaïs Guigon <guigon.thais@gmail.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useCurrentUserTaskCount } from '@/activities/tasks/hooks/useCurrentUserDueTaskCount';
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { Favorites } from '@/favorites/components/Favorites';
|
||||
import { useIsTasksPage } from '@/navigation/hooks/useIsTasksPage';
|
||||
import { SettingsNavbar } from '@/settings/components/SettingsNavbar';
|
||||
import {
|
||||
IconBell,
|
||||
IconCheckbox,
|
||||
IconSearch,
|
||||
IconSettings,
|
||||
} from '@/ui/display/icon/index';
|
||||
import MainNavbar from '@/ui/navigation/navigation-drawer/components/MainNavbar';
|
||||
import NavItem from '@/ui/navigation/navigation-drawer/components/NavItem';
|
||||
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
||||
|
||||
import { useIsSettingsPage } from '../hooks/useIsSettingsPage';
|
||||
|
||||
import { WorkspaceNavItems } from './WorkspaceNavItems';
|
||||
|
||||
export const DesktopNavigationDrawer = () => {
|
||||
const { toggleCommandMenu } = useCommandMenu();
|
||||
const isSettingsPage = useIsSettingsPage();
|
||||
const isTasksPage = useIsTasksPage();
|
||||
const { currentUserDueTaskCount } = useCurrentUserTaskCount();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const setNavigationMemorizedUrl = useSetRecoilState(
|
||||
navigationMemorizedUrlState,
|
||||
);
|
||||
|
||||
return isSettingsPage ? (
|
||||
<SettingsNavbar />
|
||||
) : (
|
||||
<MainNavbar>
|
||||
<NavItem
|
||||
label="Search"
|
||||
Icon={IconSearch}
|
||||
onClick={toggleCommandMenu}
|
||||
keyboard={['⌘', 'K']}
|
||||
/>
|
||||
<NavItem label="Notifications" to="/inbox" Icon={IconBell} soon />
|
||||
<NavItem
|
||||
label="Settings"
|
||||
onClick={() => {
|
||||
setNavigationMemorizedUrl(location.pathname + location.search);
|
||||
navigate('/settings/profile');
|
||||
}}
|
||||
Icon={IconSettings}
|
||||
/>
|
||||
<NavItem
|
||||
label="Tasks"
|
||||
to="/tasks"
|
||||
active={isTasksPage}
|
||||
Icon={IconCheckbox}
|
||||
count={currentUserDueTaskCount}
|
||||
/>
|
||||
<Favorites />
|
||||
<WorkspaceNavItems />
|
||||
</MainNavbar>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import {
|
||||
IconCheckbox,
|
||||
IconList,
|
||||
IconSearch,
|
||||
IconSettings,
|
||||
} from '@/ui/display/icon';
|
||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
||||
import { NavigationBar } from '@/ui/navigation/navigation-bar/components/NavigationBar';
|
||||
import { navigationDrawerState } from '@/ui/navigation/states/navigationDrawerState';
|
||||
|
||||
import { useIsSettingsPage } from '../hooks/useIsSettingsPage';
|
||||
import { useIsTasksPage } from '../hooks/useIsTasksPage';
|
||||
|
||||
type NavigationBarItemName = 'main' | 'search' | 'tasks' | 'settings';
|
||||
|
||||
export const MobileNavigationBar = () => {
|
||||
const [isCommandMenuOpened] = useRecoilState(isCommandMenuOpenedState);
|
||||
const { closeCommandMenu, toggleCommandMenu } = useCommandMenu();
|
||||
const isTasksPage = useIsTasksPage();
|
||||
const isSettingsPage = useIsSettingsPage();
|
||||
const navigate = useNavigate();
|
||||
const [navigationDrawer, setNavigationDrawer] = useRecoilState(
|
||||
navigationDrawerState,
|
||||
);
|
||||
|
||||
const initialActiveItemName: NavigationBarItemName = isCommandMenuOpened
|
||||
? 'search'
|
||||
: isTasksPage
|
||||
? 'tasks'
|
||||
: isSettingsPage
|
||||
? 'settings'
|
||||
: 'main';
|
||||
|
||||
const items: {
|
||||
name: NavigationBarItemName;
|
||||
Icon: IconComponent;
|
||||
onClick: () => void;
|
||||
}[] = [
|
||||
{
|
||||
name: 'main',
|
||||
Icon: IconList,
|
||||
onClick: () => {
|
||||
closeCommandMenu();
|
||||
setNavigationDrawer(navigationDrawer === 'main' ? '' : 'main');
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'search',
|
||||
Icon: IconSearch,
|
||||
onClick: () => {
|
||||
setNavigationDrawer('');
|
||||
toggleCommandMenu();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'tasks',
|
||||
Icon: IconCheckbox,
|
||||
onClick: () => {
|
||||
closeCommandMenu();
|
||||
setNavigationDrawer('');
|
||||
navigate('/tasks');
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'settings',
|
||||
Icon: IconSettings,
|
||||
onClick: () => {
|
||||
closeCommandMenu();
|
||||
setNavigationDrawer(navigationDrawer === 'settings' ? '' : 'settings');
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<NavigationBar
|
||||
activeItemName={navigationDrawer || initialActiveItemName}
|
||||
items={items}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { Favorites } from '@/favorites/components/Favorites';
|
||||
import { SettingsNavbar } from '@/settings/components/SettingsNavbar';
|
||||
import MainNavbar from '@/ui/navigation/navigation-drawer/components/MainNavbar';
|
||||
import { navigationDrawerState } from '@/ui/navigation/states/navigationDrawerState';
|
||||
|
||||
import { WorkspaceNavItems } from './WorkspaceNavItems';
|
||||
|
||||
export const MobileNavigationDrawer = () => {
|
||||
const [navigationDrawer] = useRecoilState(navigationDrawerState);
|
||||
|
||||
return navigationDrawer === 'settings' ? (
|
||||
<SettingsNavbar />
|
||||
) : (
|
||||
<MainNavbar>
|
||||
<Favorites />
|
||||
<WorkspaceNavItems />
|
||||
</MainNavbar>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { ObjectMetadataNavItems } from '@/object-metadata/components/ObjectMetadataNavItems';
|
||||
import { IconTargetArrow } from '@/ui/display/icon/index';
|
||||
import NavItem from '@/ui/navigation/navigation-drawer/components/NavItem';
|
||||
import NavTitle from '@/ui/navigation/navigation-drawer/components/NavTitle';
|
||||
|
||||
export const WorkspaceNavItems = () => {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavTitle label="Workspace" />
|
||||
<ObjectMetadataNavItems />
|
||||
<NavItem
|
||||
label="Opportunities"
|
||||
to="/objects/opportunities"
|
||||
active={pathname === '/objects/opportunities'}
|
||||
Icon={IconTargetArrow}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
|
||||
|
||||
import { DesktopNavigationDrawer } from '../DesktopNavigationDrawer';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
|
||||
const meta: Meta<typeof DesktopNavigationDrawer> = {
|
||||
title: 'Modules/Navigation/DesktopNavigationDrawer',
|
||||
component: DesktopNavigationDrawer,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof DesktopNavigationDrawer>;
|
||||
|
||||
export const Default: Story = {
|
||||
decorators: [
|
||||
ComponentDecorator,
|
||||
ComponentWithRouterDecorator,
|
||||
SnackBarDecorator,
|
||||
],
|
||||
};
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
|
||||
|
||||
import { MobileNavigationDrawer } from '../MobileNavigationDrawer';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
|
||||
const meta: Meta<typeof MobileNavigationDrawer> = {
|
||||
title: 'Modules/Navigation/MobileNavigationDrawer',
|
||||
component: MobileNavigationDrawer,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof MobileNavigationDrawer>;
|
||||
|
||||
export const Default: Story = {
|
||||
decorators: [
|
||||
ComponentDecorator,
|
||||
ComponentWithRouterDecorator,
|
||||
SnackBarDecorator,
|
||||
],
|
||||
};
|
||||
Reference in New Issue
Block a user