Skip to content

Commit

Permalink
feat(crux-ui): reorganize the menu structure (#977)
Browse files Browse the repository at this point in the history
  • Loading branch information
m8vago committed May 22, 2024
1 parent d6c5301 commit 07b4e70
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 140 deletions.
3 changes: 2 additions & 1 deletion web/crux-ui/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
"log": "Log",

"home": "Home",
"settings": "Settings",
"components": "Components",
"integrations": "Integrations",
"tools": "Tools",

"logout": "Log out",

Expand Down
29 changes: 17 additions & 12 deletions web/crux-ui/src/components/main/nav-button.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,39 @@
import DyoIcon from '@app/elements/dyo-icon'
import DyoLink from '@app/elements/dyo-link'
import clsx from 'clsx'
import { useRouter } from 'next/router'

interface NavButtonProps {
children: string
type NavButtonProps = {
className?: string
href: string
target?: string
passHref?: boolean
icon?: JSX.Element
icon: string
text: string
activeIndicator?: boolean
}

const NavButton = (props: NavButtonProps) => {
const { children, href, target, passHref, icon } = props
const { className, activeIndicator, href, target, icon, text } = props

const router = useRouter()

const active = router.asPath.startsWith(href)
const active = activeIndicator && router.asPath.startsWith(href)

return (
<>
<div className={clsx('pl-8 py-2', active ? 'bg-dark w-full' : null)}>
<DyoLink href={href} passHref={passHref} target={target} qaLabel={`menu-item-${children}`}>
<div className="flex flex-row">
<div className="flex items-center mr-2 text-bright text-sm font-semibold">{icon}</div>
{children}
<div className={clsx(className ?? 'pl-8 py-1.5', active ? 'bg-dark w-full' : null)}>
<DyoLink href={href} target={target} qaLabel={`menu-item-${text}`}>
<div className="flex flex-row text-bright">
<div className="flex items-center mr-2 text-bright text-sm font-semibold">
<DyoIcon src={icon} alt={text} />
</div>

{text}
</div>
</DyoLink>
</div>

<div className={clsx('w-1 py-2', active ? 'bg-dyo-turquoise opacity-50' : null)}>&nbsp;</div>
<div className={clsx('w-1 py-1.5', active ? 'bg-dyo-turquoise opacity-50' : null)}>&nbsp;</div>
</>
)
}
Expand Down
18 changes: 7 additions & 11 deletions web/crux-ui/src/components/main/nav-section.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import DyoIcon from '@app/elements/dyo-icon'
import useTranslation from 'next-translate/useTranslation'
import NavButton from './nav-button'

Expand All @@ -9,7 +8,7 @@ export type MenuOption = {
icon: string
}

interface NavSectionProps {
type NavSectionProps = {
title: string
options: MenuOption[]
className?: string
Expand All @@ -20,17 +19,14 @@ export const NavSection = (props: NavSectionProps) => {

const { t } = useTranslation('common')

const optionToIcon = (it: MenuOption) => <DyoIcon src={it.icon} alt={t(it.text)} />

return (
<div className={className}>
<p className="text-bright px-6 text-sm tracking-widest">{title.toUpperCase()}</p>
<ul className="list-none flex flex-col text-bright">
{options.map((option, index) => (
<li key={index} className="flex flex-row items-center mt-2">
<NavButton href={option.link} icon={optionToIcon(option)} target={option.target}>
{t(option.text)}
</NavButton>
<p className="text-light px-6 text-sm tracking-widest">{title.toUpperCase()}</p>

<ul className="list-none flex flex-col text-bright pt-2">
{options.map((it, index) => (
<li key={index} className="flex flex-row items-center">
<NavButton activeIndicator href={it.link} icon={it.icon} text={t(it.text)} target={it.target} />
</li>
))}
</ul>
Expand Down
90 changes: 90 additions & 0 deletions web/crux-ui/src/components/main/profile-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { DyoCard } from '@app/elements/dyo-card'
import useTeamRoutes from '@app/hooks/use-team-routes'
import { UserMeta, UserMetaTeam } from '@app/models'
import { ROUTE_DOCS, ROUTE_LOGOUT, ROUTE_PROFILE, ROUTE_TEAMS, TeamRoutes } from '@app/routes'
import clsx from 'clsx'
import useTranslation from 'next-translate/useTranslation'
import Image from 'next/image'
import NavButton from './nav-button'

interface TeamSelectionCardProps {
className?: string
meta: UserMeta
onTeamSelected: (team: UserMetaTeam) => void
}

const menuItemsOf = (routes: TeamRoutes) => [
{
icon: '/audit.svg',
text: 'audit',
link: routes.audit.list(),
},
{
icon: '/team.svg',
text: 'teams',
link: ROUTE_TEAMS,
},
{
icon: '/documentation.svg',
text: 'documentation',
link: ROUTE_DOCS,
target: '_blank',
},
{
icon: '/logout.svg',
text: 'logout',
link: ROUTE_LOGOUT,
},
]

const ProfileCard = (props: TeamSelectionCardProps) => {
const { meta, className, onTeamSelected } = props

const { t } = useTranslation('common')
const routes = useTeamRoutes()

const teamRoutes = useTeamRoutes()
const menuitems = menuItemsOf(teamRoutes)

return (
<DyoCard className={clsx(className, 'px-4 py-2 gap-4 text-bright')}>
<div className="flex flex-row border-b-2 border-light-grey">
<NavButton className="m-2" href={ROUTE_PROFILE} icon="/profile.svg" text={t('profile')} />
</div>

<p className="text-light px-2 text-sm tracking-widest">{t('yourTeams').toUpperCase()}</p>

{meta.teams.map(team => {
const currentTeam = team.slug === routes?.teamSlug

return (
<div
key={`team-${team.slug}`}
className={clsx('flex flex-row items-center mx-6', currentTeam ? null : 'cursor-pointer')}
onClick={currentTeam ? null : () => onTeamSelected(team)}
>
<Image
className={currentTeam ? null : 'opacity-30 bg-blend-darken'}
src="/default_team_avatar.svg"
alt={t('teamAvatar')}
width={32}
height={32}
/>

<div className="ml-4">{team.name}</div>
</div>
)
})}

<div className="flex flex-col border-t-2 border-light-grey">
{menuitems.map(it => (
<div key={it.link} className="flex flex-row">
<NavButton className="m-2" href={it.link} icon={it.icon} text={t(it.text)} />
</div>
))}
</div>
</DyoCard>
)
}

export default ProfileCard
71 changes: 14 additions & 57 deletions web/crux-ui/src/components/main/sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import DyoIcon from '@app/elements/dyo-icon'
import DyoLink from '@app/elements/dyo-link'
import useTeamRoutes from '@app/hooks/use-team-routes'
import {
ROUTE_COMPOSER,
ROUTE_DOCS,
ROUTE_INDEX,
ROUTE_LOGOUT,
ROUTE_PROFILE,
ROUTE_TEAMS,
ROUTE_TEMPLATES,
TeamRoutes,
} from '@app/routes'
import { ROUTE_COMPOSER, ROUTE_INDEX, ROUTE_TEMPLATES, TeamRoutes } from '@app/routes'
import useTranslation from 'next-translate/useTranslation'
import Image from 'next/image'
import NavButton from './nav-button'
Expand All @@ -27,7 +17,7 @@ export interface SidebarProps {

export const sidebarSectionsOf = (routes: TeamRoutes): MenuSection[] => [
{
title: 'project',
title: 'components',
items: [
{
icon: '/projects.svg',
Expand All @@ -39,11 +29,6 @@ export const sidebarSectionsOf = (routes: TeamRoutes): MenuSection[] => [
text: 'deployments',
link: routes.deployment.list(),
},
],
},
{
title: 'components',
items: [
{
icon: '/servers.svg',
text: 'nodes',
Expand All @@ -59,6 +44,11 @@ export const sidebarSectionsOf = (routes: TeamRoutes): MenuSection[] => [
text: 'configBundles',
link: routes.configBundles.list(),
},
],
},
{
title: 'integrations',
items: [
{
icon: '/storage.svg',
text: 'storages',
Expand All @@ -74,6 +64,11 @@ export const sidebarSectionsOf = (routes: TeamRoutes): MenuSection[] => [
text: 'notifications',
link: routes.notification.list(),
},
],
},
{
title: 'tools',
items: [
{
icon: '/template.svg',
text: 'templates',
Expand All @@ -86,37 +81,6 @@ export const sidebarSectionsOf = (routes: TeamRoutes): MenuSection[] => [
},
],
},
{
title: 'settings',
items: [
{
icon: '/audit.svg',
text: 'audit',
link: routes.audit.list(),
},
{
icon: '/team.svg',
text: 'teams',
link: ROUTE_TEAMS,
},
{
icon: '/profile.svg',
text: 'profile',
link: ROUTE_PROFILE,
},
{
icon: '/documentation.svg',
text: 'documentation',
link: ROUTE_DOCS,
target: '_blank',
},
{
icon: '/logout.svg',
text: 'logout',
link: ROUTE_LOGOUT,
},
],
},
]

export const Sidebar = (props: SidebarProps) => {
Expand Down Expand Up @@ -145,18 +109,11 @@ export const Sidebar = (props: SidebarProps) => {
{sidebarSections && (
<div className="flex flex-col grow">
<div className="flex text-bright my-6">
<NavButton href={routes.dashboard.index()} icon={<DyoIcon src="/dashboard.svg" alt={t('dashboard')} />}>
{t('dashboard')}
</NavButton>
<NavButton activeIndicator href={routes.dashboard.index()} icon="/dashboard.svg" text={t('dashboard')} />
</div>

{sidebarSections.map((it, index) => (
<NavSection
key={index}
className={index < sidebarSections.length - 1 ? 'mb-6' : 'mt-auto mb-3'}
title={t(it.title)}
options={it.items}
/>
<NavSection key={index} className="mb-6" title={t(it.title)} options={it.items} />
))}
</div>
)}
Expand Down
56 changes: 0 additions & 56 deletions web/crux-ui/src/components/main/team-selection-card.tsx

This file was deleted.

7 changes: 4 additions & 3 deletions web/crux-ui/src/components/main/top-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import useTranslation from 'next-translate/useTranslation'
import { useRouter } from 'next/router'
import { useState } from 'react'
import UserDefaultAvatar from '../team/user-default-avatar'
import TeamSelectionCard from './team-selection-card'
import ProfileCard from './profile-card'

interface TopbarProps {
className?: string
Expand Down Expand Up @@ -60,12 +60,13 @@ const Topbar = (props: TopbarProps) => {
{!teamSelectionVisible ? null : (
<>
<div className="w-full absolute bottom-0 right-0">
<TeamSelectionCard
className="flex flex-col flex-grow absolute top-0 right-0 mt-2 z-20"
<ProfileCard
className="flex flex-col absolute top-0 right-0 mt-2 z-20"
meta={meta}
onTeamSelected={onTeamSelected}
/>
</div>

<div className="w-full h-full fixed top-0 right-0 z-10" onClick={toggleTeamSelection} />
</>
)}
Expand Down

0 comments on commit 07b4e70

Please sign in to comment.