feat: complete Epic 1 — team management & permission system
- Story 1.1: Permission enum, config, AuthorizesPermissions & HasWorkspaceScope traits, member→worker migration - Story 1.2: Team page with member list, invitation system with queued email - Story 1.3: Role assignment (Manager/Worker) and member removal with activity logging - Story 1.4: Owner-only permission toggle matrix for Managers (manage team, view logs, configure portal) - Story 1.5: Role-based access enforcement — Workers see only assigned declarations/clients, sidebar scoping - Story 1.6: Workspace switcher dropdown for multi-workspace users with session-based switching - 83 new/modified files, 182 tests passing with zero regressions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
HelpCircle,
|
||||
LayoutGrid,
|
||||
Users,
|
||||
UsersRound,
|
||||
} from 'lucide-vue-next';
|
||||
import { computed } from 'vue';
|
||||
import NavFooter from '@/components/NavFooter.vue';
|
||||
@@ -23,11 +24,17 @@ import {
|
||||
SidebarMenuItem,
|
||||
} from '@/components/ui/sidebar';
|
||||
import { dashboard } from '@/routes';
|
||||
import { index as clientsIndex } from '@/routes/clients';
|
||||
import { index as declarationsIndex } from '@/routes/declarations';
|
||||
import { index as teamIndex } from '@/routes/team';
|
||||
import type { NavItem } from '@/types';
|
||||
import AppLogo from './AppLogo.vue';
|
||||
import WorkspaceSwitcher from './WorkspaceSwitcher.vue';
|
||||
|
||||
const page = usePage();
|
||||
const workspaceRole = computed(() => page.props.auth?.workspaceRole);
|
||||
const isWorker = computed(() => workspaceRole.value === 'worker');
|
||||
|
||||
const mainNavItems = computed<NavItem[]>(() => {
|
||||
const items: NavItem[] = [
|
||||
{
|
||||
@@ -37,18 +44,31 @@ const mainNavItems = computed<NavItem[]>(() => {
|
||||
},
|
||||
];
|
||||
if (page.props.auth?.currentWorkspace) {
|
||||
items.push(
|
||||
{
|
||||
title: 'Clients',
|
||||
href: '/clients',
|
||||
icon: Briefcase,
|
||||
},
|
||||
{
|
||||
title: 'Déclarations',
|
||||
href: '/declarations',
|
||||
if (isWorker.value) {
|
||||
items.push({
|
||||
title: 'Mes déclarations',
|
||||
href: declarationsIndex.url(),
|
||||
icon: FileStack,
|
||||
},
|
||||
);
|
||||
});
|
||||
} else {
|
||||
items.push(
|
||||
{
|
||||
title: 'Clients',
|
||||
href: clientsIndex.url(),
|
||||
icon: Briefcase,
|
||||
},
|
||||
{
|
||||
title: 'Déclarations',
|
||||
href: declarationsIndex.url(),
|
||||
icon: FileStack,
|
||||
},
|
||||
{
|
||||
title: 'Équipe',
|
||||
href: teamIndex.url(),
|
||||
icon: UsersRound,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user