167 lines
4.1 KiB
TypeScript
167 lines
4.1 KiB
TypeScript
import {
|
|
Bell,
|
|
Columns3,
|
|
Folder,
|
|
FolderGit2,
|
|
House,
|
|
KeyRound,
|
|
Layers3,
|
|
LayoutGrid,
|
|
ListTodo,
|
|
Settings2,
|
|
Shield,
|
|
Tags,
|
|
Users,
|
|
} from 'lucide-vue-next';
|
|
import { dashboard } from '@/routes';
|
|
import { index as adminUsers } from '@/routes/admin/users';
|
|
import { index as templates } from '@/routes/project-templates';
|
|
import { access, index as projects, show } from '@/routes/projects';
|
|
import { index as backlog } from '@/routes/projects/backlog';
|
|
import { index as board } from '@/routes/projects/board';
|
|
import {
|
|
board as boardSettings,
|
|
general,
|
|
metadata,
|
|
notifications,
|
|
repositories,
|
|
} from '@/routes/projects/settings';
|
|
import { index as teams } from '@/routes/teams';
|
|
import type { Localization } from '@/lib/localization';
|
|
import type { AuthPermissions, NavItem, NavigationProject } from '@/types';
|
|
|
|
export function workspaceNavigation(
|
|
permissions: AuthPermissions,
|
|
t: Localization['t'],
|
|
): NavItem[] {
|
|
const items: NavItem[] = [
|
|
{
|
|
title: t('navigation.dashboard'),
|
|
href: dashboard(),
|
|
icon: LayoutGrid,
|
|
},
|
|
{
|
|
title: t('navigation.projects'),
|
|
href: projects(),
|
|
icon: Folder,
|
|
match: 'section',
|
|
},
|
|
];
|
|
if (permissions.projectCreate) {
|
|
items.push({
|
|
title: t('navigation.templates'),
|
|
href: templates(),
|
|
icon: Layers3,
|
|
match: 'section',
|
|
});
|
|
}
|
|
if (permissions.canManageTeams) {
|
|
items.push({
|
|
title: t('navigation.teams'),
|
|
href: teams(),
|
|
icon: Users,
|
|
match: 'section',
|
|
});
|
|
}
|
|
if (permissions.globalAdmin) {
|
|
items.push({
|
|
title: t('navigation.users'),
|
|
href: adminUsers(),
|
|
icon: Shield,
|
|
match: 'section',
|
|
});
|
|
}
|
|
return items;
|
|
}
|
|
|
|
export function projectNavigation(
|
|
project: NavigationProject | null,
|
|
t: Localization['t'],
|
|
): NavItem[] {
|
|
if (!project) {
|
|
return [];
|
|
}
|
|
return [
|
|
{
|
|
title: t('navigation.overview'),
|
|
href: show(project.id),
|
|
icon: House,
|
|
},
|
|
{
|
|
title: t('navigation.board'),
|
|
href: board(project.id),
|
|
icon: Columns3,
|
|
match: 'section',
|
|
},
|
|
{
|
|
title: t('navigation.backlog'),
|
|
href: backlog(project.id),
|
|
icon: ListTodo,
|
|
match: 'section',
|
|
},
|
|
];
|
|
}
|
|
|
|
export function projectSettingsNavigation(
|
|
project: NavigationProject | null,
|
|
t: Localization['t'],
|
|
): NavItem[] {
|
|
if (!project?.canManage) {
|
|
return [];
|
|
}
|
|
return [
|
|
{
|
|
title: t('navigation.general'),
|
|
href: general(project.id),
|
|
icon: Settings2,
|
|
},
|
|
{
|
|
title: t('navigation.boardSettings'),
|
|
href: boardSettings(project.id),
|
|
icon: Columns3,
|
|
},
|
|
{
|
|
title: t('navigation.ticketSettings'),
|
|
href: metadata(project.id),
|
|
icon: Tags,
|
|
},
|
|
{
|
|
title: t('navigation.repositories'),
|
|
href: repositories(project.id),
|
|
icon: FolderGit2,
|
|
},
|
|
{
|
|
title: t('navigation.notifications'),
|
|
href: notifications(project.id),
|
|
icon: Bell,
|
|
},
|
|
{
|
|
title: t('navigation.access'),
|
|
href: access(project.id),
|
|
icon: KeyRound,
|
|
},
|
|
];
|
|
}
|
|
|
|
export function matchesNavigationUrl(
|
|
target: string,
|
|
current: string,
|
|
section = false,
|
|
): boolean {
|
|
try {
|
|
const base = 'http://localhost';
|
|
const targetPath =
|
|
new URL(target, base).pathname.replace(/\/+$/, '') || '/';
|
|
const currentPath =
|
|
new URL(current, base).pathname.replace(/\/+$/, '') || '/';
|
|
return (
|
|
currentPath === targetPath ||
|
|
(section &&
|
|
targetPath !== '/' &&
|
|
currentPath.startsWith(`${targetPath}/`))
|
|
);
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|