Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 41 additions & 13 deletions src/app/administration/layout/nav-bar/menu-builder.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,47 @@
import { faCalendarDays, faClock, faTicket } from '@fortawesome/free-solid-svg-icons';
import { faCalendarDay, faCalendarDays, faClock, faTicket } from '@fortawesome/free-solid-svg-icons';
import { MenuItem, MenuSubItem } from './menu-items';
import { IconDefinition } from '@fortawesome/angular-fontawesome';
import { inject } from '@angular/core';
import { AuthService } from 'src/app/services/auth.service';

export class MenuBuilder {
constructor() { }
readonly #auth = inject(AuthService);
#defaultMenu: MenuItem[] = [
this.#getMenuItem('My events', 'my-events', faCalendarDay, () => this.getSubItemsByPath('my-events')),
].filter(o => o);

build(): MenuItem[] {
ticketsMenuItem: MenuItem = this.#getMenuItem('Tickets', 'tickets', faTicket, () => this.getSubItemsByPath('tickets'));
ticketGroupsMenuItem: MenuItem = this.#getMenuItem('Ticket groups', 'ticket_groups', faClock, () => this.getSubItemsByPath('ticket_groups'));
eventsMenuItem: MenuItem = this.#getMenuItem('Events', 'events', faCalendarDays, () => this.getSubItemsByPath('events'));
#adminMenu: MenuItem[] = [
this.ticketsMenuItem,
this.ticketGroupsMenuItem,
this.eventsMenuItem,
];

build(currentUrl: string = ''): MenuItem[] {
let scopes = this.#auth.getScopes();
let username = this.#auth.getUsername();

// TODO: Add admin mode to condition
if (scopes.includes('admin') || username.includes('admin')) {
// user is admin and should have access to all things
return this.#adminMenu.filter(o => o);
}

// user has restricted access
let menu: MenuItem[] = [];

for (let i = 0; i < this.#adminMenu.length; i++) {
const menuItem = this.#adminMenu[i];
if (currentUrl.startsWith(`/${menuItem.link}`)) {
menu.push(menuItem);
}
}

return [
this.#getMenuItem('Tickets', 'tickets', faTicket, () => this.getTicketsSubItems()),
this.#getMenuItem('Ticket groups', 'ticket_groups', faClock, () => this.getSubItemsByPath('ticket_groups')),
this.#getMenuItem('Events', 'events', faCalendarDays, () => this.getSubItemsByPath('events')),
...menu,
...this.#defaultMenu,
].filter(o => o);
}

Expand All @@ -19,14 +50,11 @@ export class MenuBuilder {
): MenuSubItem[] {
const result: MenuSubItem[] = [];
result.push(new MenuSubItem('List', `/${path}/list`));
result.push(new MenuSubItem('New', `/${path}/add`));
return result;
}

getTicketsSubItems(): MenuSubItem[] {
const result: MenuSubItem[] = [];
result.push(new MenuSubItem('List', '/tickets/list'));
result.push(new MenuSubItem('New', '/tickets/add'));
// TODO: Add admin mode to condition
if (this.#auth.getScopes().includes(`${path}:edit`)) {
result.push(new MenuSubItem('New', `/${path}/add`));
}
return result;
}

Expand Down
25 changes: 19 additions & 6 deletions src/app/administration/layout/nav-bar/nav-bar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { MenuItem } from './menu-items';
import { MenuBuilder } from './menu-builder';
import { AuthService } from 'src/app/services/auth.service';
import { faBars, faChartLine, faSignOutAlt, faTimes, faUser } from '@fortawesome/free-solid-svg-icons';
import { NavigationEnd, Router } from '@angular/router';
import { filter } from 'rxjs';

@Component({
selector: 'app-nav-bar',
Expand All @@ -12,6 +14,7 @@ import { faBars, faChartLine, faSignOutAlt, faTimes, faUser } from '@fortawesome
})
export class NavBarComponent implements OnInit {
readonly #authService = inject(AuthService);
readonly #router = inject(Router);

dashboardItem = new MenuItem('Dashboard', 'dashboard', faChartLine);
userProfileItem = new MenuItem('My profile', 'profile', faUser);
Expand All @@ -26,12 +29,13 @@ export class NavBarComponent implements OnInit {

ngOnInit(): void {
this.menuOpen = history.state.navBarVisible ?? false;
this.availableItems = this.builder.build()
this.availableItems.unshift(this.dashboardItem);
this.availableItems.push(
this.userProfileItem,
this.logoutItem
);
this.#rebuildMenu(this.#router.url);

this.#router.events.pipe(
filter((event): event is NavigationEnd => event instanceof NavigationEnd),
).subscribe(event => {
this.#rebuildMenu(event.urlAfterRedirects);
});
}

toggle(): void {
Expand All @@ -45,4 +49,13 @@ export class NavBarComponent implements OnInit {
logout(): void {
this.#authService.logout();
}

#rebuildMenu(currentUrl: string): void {
this.availableItems = this.builder.build(currentUrl);
this.availableItems.unshift(this.dashboardItem);
this.availableItems.push(
this.userProfileItem,
this.logoutItem
);
}
}
52 changes: 29 additions & 23 deletions src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,30 @@ import { EventsFormComponent } from './administration/events/form/events-form.co
import { authGuard } from './guards/auth.guard';
import { logoutGuard } from './guards/logout.guard';

let eventsChildren: Routes = [
{
path: '',
pathMatch: 'full',
redirectTo: 'list',
},
{
path: 'list',
component: EventsListComponent
},
{
path: 'add',
component: EventsFormComponent
},
{
path: 'edit/:id',
component: EventsFormComponent
},
{
path: 'detail/:id',
component: EventsFormComponent
},
];

export let APP_ROUTES: Routes = [
{
path: '',
Expand Down Expand Up @@ -96,31 +120,13 @@ export let APP_ROUTES: Routes = [
}
]
},
{
path: 'my-events',
children: eventsChildren,
},
{
path: 'events',
children: [
{
path: '',
pathMatch: 'full',
redirectTo: 'list',
},
{
path: 'list',
component: EventsListComponent
},
{
path: 'add',
component: EventsFormComponent
},
{
path: 'edit/:id',
component: EventsFormComponent
},
{
path: 'detail/:id',
component: EventsFormComponent
},
]
children: eventsChildren,
},
{
path: '**',
Expand Down