mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
Merged nav menus.
This commit is contained in:
parent
2f5e69229c
commit
554054d3a1
12 changed files with 164 additions and 47 deletions
|
|
@ -1,14 +1,14 @@
|
|||
export * from 'lucide-react';
|
||||
export {
|
||||
Logo as LogoSvg,
|
||||
Compare as CompareSvg,
|
||||
Funnel as FunnelSvg,
|
||||
Lightning as LightningSvg,
|
||||
Location as LocationSvg,
|
||||
Logo as LogoSvg,
|
||||
Magnet as MagnetSvg,
|
||||
Money as MoneySvg,
|
||||
Network as NetworkSvg,
|
||||
Path as PathSvg,
|
||||
Switch as SwitchSvg,
|
||||
Target as TargetSvg,
|
||||
AddUser as AddUserSvg,
|
||||
} from '@/components/svg';
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@ import {
|
|||
Settings,
|
||||
User,
|
||||
Users,
|
||||
SwitchSvg,
|
||||
} from '@/components/icons';
|
||||
import { DOCS_URL } from '@/lib/constants';
|
||||
import * as url from 'node:url';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
|
||||
export interface TeamsButtonProps {
|
||||
showText?: boolean;
|
||||
|
|
@ -43,7 +44,7 @@ export function NavButton({ showText = true }: TeamsButtonProps) {
|
|||
const label = teamId ? team?.name : user.username;
|
||||
|
||||
const getUrl = (url: string) => {
|
||||
return cloudMode ? `${process.env.cloudUrl}/${url}` : url;
|
||||
return cloudMode ? `${process.env.cloudUrl}${url}` : url;
|
||||
};
|
||||
|
||||
const handleAction = async () => {};
|
||||
|
|
@ -75,42 +76,52 @@ export function NavButton({ showText = true }: TeamsButtonProps) {
|
|||
</Pressable>
|
||||
<Popover placement="bottom start">
|
||||
<Column minWidth="300px">
|
||||
<Menu
|
||||
selectionMode="single"
|
||||
selectedKeys={selectedKeys}
|
||||
autoFocus="last"
|
||||
onAction={handleAction}
|
||||
>
|
||||
<MenuSection title={formatMessage(labels.myAccount)}>
|
||||
<MenuItem id="user">
|
||||
<IconLabel icon={<User />} label={user.username} />
|
||||
</MenuItem>
|
||||
</MenuSection>
|
||||
<MenuSeparator />
|
||||
<Menu autoFocus="last" onAction={handleAction}>
|
||||
<SubmenuTrigger>
|
||||
<MenuItem id="teams" showChecked={false} showSubMenuIcon>
|
||||
<IconLabel icon={<Users />} label={formatMessage(labels.teams)} />
|
||||
<IconLabel icon={<SwitchSvg />} label={formatMessage(labels.switchAccount)} />
|
||||
</MenuItem>
|
||||
<Popover placement="right top">
|
||||
<Column minWidth="300px">
|
||||
<Menu>
|
||||
<Menu selectionMode="single" selectedKeys={selectedKeys}>
|
||||
<MenuSection title={formatMessage(labels.myAccount)}>
|
||||
<MenuItem id="user" href={getUrl('/')}>
|
||||
<IconLabel icon={<User />} label={user.username} />
|
||||
</MenuItem>
|
||||
</MenuSection>
|
||||
<MenuSeparator />
|
||||
<MenuSection title={formatMessage(labels.teams)}>
|
||||
{user?.teams?.map(({ id, name }) => (
|
||||
<MenuItem key={id} id={id}>
|
||||
<Row alignItems="center" gap>
|
||||
<Icon size="sm">
|
||||
<Users />
|
||||
</Icon>
|
||||
<MenuItem key={id} id={id} href={getUrl(`/teams/${id}`)}>
|
||||
<IconLabel icon={<Users />}>
|
||||
<Text wrap="nowrap">{name}</Text>
|
||||
</Row>
|
||||
</IconLabel>
|
||||
</MenuItem>
|
||||
))}
|
||||
{user?.teams?.length === 0 && (
|
||||
<MenuItem id="manage-teams">
|
||||
<a href="/settings/teams" style={{ width: '100%' }}>
|
||||
<Row alignItems="center" justifyContent="space-between" gap>
|
||||
<Text align="center">Manage teams</Text>
|
||||
<Icon>
|
||||
<ArrowRight />
|
||||
</Icon>
|
||||
</Row>
|
||||
</a>
|
||||
</MenuItem>
|
||||
)}
|
||||
</MenuSection>
|
||||
</Menu>
|
||||
</Column>
|
||||
</Popover>
|
||||
</SubmenuTrigger>
|
||||
<MenuItem id="settings" icon={<Settings />} label={formatMessage(labels.settings)} />
|
||||
<MenuSeparator />
|
||||
<MenuItem
|
||||
id="settings"
|
||||
href={getUrl('/settings')}
|
||||
icon={<Settings />}
|
||||
label={formatMessage(labels.settings)}
|
||||
/>
|
||||
{cloudMode && (
|
||||
<>
|
||||
<MenuItem
|
||||
|
|
@ -132,14 +143,24 @@ export function NavButton({ showText = true }: TeamsButtonProps) {
|
|||
/>
|
||||
</>
|
||||
)}
|
||||
{user.isAdmin && (
|
||||
{!cloudMode && user.isAdmin && (
|
||||
<>
|
||||
<MenuSeparator />
|
||||
<MenuItem id="/admin" icon={<LockKeyhole />} label={formatMessage(labels.admin)} />
|
||||
<MenuItem
|
||||
id="/admin"
|
||||
href="/admin"
|
||||
icon={<LockKeyhole />}
|
||||
label={formatMessage(labels.admin)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<MenuSeparator />
|
||||
<MenuItem id="/logout" icon={<LogOut />} label={formatMessage(labels.logout)} />
|
||||
<MenuItem
|
||||
id="logout"
|
||||
href={getUrl('/logout')}
|
||||
icon={<LogOut />}
|
||||
label={formatMessage(labels.logout)}
|
||||
/>
|
||||
</Menu>
|
||||
</Column>
|
||||
</Popover>
|
||||
|
|
|
|||
|
|
@ -362,6 +362,7 @@ export const labels = defineMessages({
|
|||
share: { id: 'label.share', defaultMessage: 'Share' },
|
||||
support: { id: 'label.support', defaultMessage: 'Support' },
|
||||
documentation: { id: 'label.documentation', defaultMessage: 'Documentation' },
|
||||
switchAccount: { id: 'label.switch-account', defaultMessage: 'Switch account' },
|
||||
});
|
||||
|
||||
export const messages = defineMessages({
|
||||
|
|
|
|||
9
src/components/svg/Download.tsx
Normal file
9
src/components/svg/Download.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import * as React from 'react';
|
||||
import type { SVGProps } from 'react';
|
||||
const SvgDownload = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}>
|
||||
<path d="M97.5 82.656V71.357a3.545 3.545 0 0 0-3.545-3.544H89.17a3.545 3.545 0 0 0-3.545 3.544v11.3c0 1.639-1.33 2.968-2.969 2.968H17.344a2.97 2.97 0 0 1-2.969-2.969V71.357a3.545 3.545 0 0 0-3.545-3.545H6.045A3.545 3.545 0 0 0 2.5 71.357v11.3C2.5 90.853 9.146 97.5 17.344 97.5h65.312c8.198 0 14.844-6.646 14.844-14.844" />
|
||||
<path d="m29.68 44.105-3.387 3.388a3.545 3.545 0 0 0 0 5.014l19.506 19.506a5.94 5.94 0 0 0 8.397.005l.005-.005 19.506-19.506a3.545 3.545 0 0 0 0-5.014l-3.388-3.388a3.545 3.545 0 0 0-5.013 0l-9.368 9.368V6.045A3.545 3.545 0 0 0 52.393 2.5h-4.786a3.545 3.545 0 0 0-3.544 3.545v47.428l-9.369-9.368a3.545 3.545 0 0 0-5.013 0" />
|
||||
</svg>
|
||||
);
|
||||
export default SvgDownload;
|
||||
12
src/components/svg/Export.tsx
Normal file
12
src/components/svg/Export.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import * as React from 'react';
|
||||
import type { SVGProps } from 'react';
|
||||
const SvgExport = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width={512} height={512} viewBox="0 0 24 24" {...props}>
|
||||
<switch>
|
||||
<g>
|
||||
<path d="M8.7 7.7 11 5.4V15c0 .6.4 1 1 1s1-.4 1-1V5.4l2.3 2.3c.4.4 1 .4 1.4 0s.4-1 0-1.4l-4-4c-.1-.1-.2-.2-.3-.2-.2-.1-.5-.1-.8 0-.1 0-.2.1-.3.2l-4 4c-.4.4-.4 1 0 1.4s1 .4 1.4 0M21 14c-.6 0-1 .4-1 1v4c0 .6-.4 1-1 1H5c-.6 0-1-.4-1-1v-4c0-.6-.4-1-1-1s-1 .4-1 1v4c0 1.7 1.3 3 3 3h14c1.7 0 3-1.3 3-3v-4c0-.6-.4-1-1-1" />
|
||||
</g>
|
||||
</switch>
|
||||
</svg>
|
||||
);
|
||||
export default SvgExport;
|
||||
19
src/components/svg/Switch.tsx
Normal file
19
src/components/svg/Switch.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import * as React from 'react';
|
||||
import type { SVGProps } from 'react';
|
||||
const SvgSwitch = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={200}
|
||||
height={200}
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
viewBox="0 0 24 24"
|
||||
{...props}
|
||||
>
|
||||
<path d="m16 3 4 4-4 4M10 7h10M8 13l-4 4 4 4M4 17h9" />
|
||||
</svg>
|
||||
);
|
||||
export default SvgSwitch;
|
||||
|
|
@ -6,7 +6,9 @@ export { default as Bookmark } from './Bookmark';
|
|||
export { default as Change } from './Change';
|
||||
export { default as Compare } from './Compare';
|
||||
export { default as Dashboard } from './Dashboard';
|
||||
export { default as Download } from './Download';
|
||||
export { default as Expand } from './Expand';
|
||||
export { default as Export } from './Export';
|
||||
export { default as Flag } from './Flag';
|
||||
export { default as Funnel } from './Funnel';
|
||||
export { default as Gear } from './Gear';
|
||||
|
|
@ -28,6 +30,7 @@ export { default as Redo } from './Redo';
|
|||
export { default as Reports } from './Reports';
|
||||
export { default as Security } from './Security';
|
||||
export { default as Speaker } from './Speaker';
|
||||
export { default as Switch } from './Switch';
|
||||
export { default as Tag } from './Tag';
|
||||
export { default as Target } from './Target';
|
||||
export { default as Visitor } from './Visitor';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue