Merge pull request 'Header & Routing' (#9) from feature/header into trunk
All checks were successful
Quality Check / Linting (push) Successful in 22s

Reviewed-on: #9
Reviewed-by: SZUT-Ole <ole.kueck@hmmh.de>
This commit is contained in:
Dominik Säume 2024-12-18 13:03:01 +00:00 committed by Git Euph
commit 1dca4a1f4f
Signed by: Euph Forge
GPG key ID: 85A06461FB6BDBB7
11 changed files with 119 additions and 41 deletions

View file

@ -1,23 +1,3 @@
@if ($employees | async; as employees) { <app-header></app-header>
<mat-tree #tree [dataSource]="employees" [childrenAccessor]="childrenAccessor">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
{{ node.firstName }}
@if (tree.isExpanded(node)) {
<button mat-icon-button matTreeNodeToggle [attr.aria-label]="'Toggle ' + node.id">
<mat-icon>expand_more</mat-icon>
</button>
<ul>
@for (entry of node | keyvalue; track entry) {
<li>{{ entry.key }}: <code>{{ entry.value }}</code></li>
}
</ul>
} @else {
<button mat-icon-button matTreeNodeToggle [attr.aria-label]="'Toggle ' + node.id">
<mat-icon>chevron_right</mat-icon>
</button>
}
</mat-tree-node>
</mat-tree>
}
<router-outlet/> <router-outlet/>

View file

@ -1,23 +1,12 @@
import {AsyncPipe, KeyValuePipe} from '@angular/common';
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {MatIconButton} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
import {MatTree, MatTreeModule} from '@angular/material/tree';
import { RouterOutlet } from '@angular/router'; import { RouterOutlet } from '@angular/router';
import { EmployeeControllerService, FindAll1Response } from '@core/ems'; import {HeaderComponent} from '@app/header/header.component';
import { Observable } from 'rxjs';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
imports: [RouterOutlet, AsyncPipe, MatIconModule, MatTree, MatTreeModule, KeyValuePipe, MatIconButton], imports: [RouterOutlet, HeaderComponent],
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrl: './app.component.scss' styleUrl: './app.component.scss'
}) })
export class AppComponent{ export class AppComponent{
readonly $employees: Observable<FindAll1Response>;
childrenAccessor = () => [];
constructor(private apiClient: EmployeeControllerService) {
this.$employees = this.apiClient.findAll1();
}
} }

View file

@ -1,3 +1,4 @@
import {Routes} from '@angular/router'; import {Routes} from '@angular/router';
import {DashboardComponent} from '@app/views/dashboard/dashboard.component';
export const routes: Routes = []; export const routes: Routes = [{path: '', component: DashboardComponent, title: 'Home'}];

View file

@ -0,0 +1,12 @@
<mat-toolbar class="header">
<nav>
<a routerLink="'/'" mat-button><mat-icon>badge</mat-icon>EMS</a>
@for (route of routes; track route){
<a mat-button href="{{ route.path }}" class="{{ route.class }}">{{ route.title }}</a>
}
</nav>
<button mat-button class="header__login">
<mat-icon>login</mat-icon>
Login
</button>
</mat-toolbar>

View file

@ -0,0 +1,33 @@
@use '@angular/material' as mat;
.header{
position: sticky;
top: 0;
margin: 0;
padding: 0.5rem 1rem;
z-index: 100;
height: fit-content;
background-color: var(--mat-sys-primary-fixed);
nav {
display: flex;
height: fit-content;
width: 100%;
margin: 0;
box-sizing: border-box;
list-style: none;
gap: 0.25rem;
}
a, button {
color: var(--mat-sys-on-primary-fixed-variant);
&:hover, &.active {
background-color: color-mix(in srgb, var(--mat-sys-primary) 50%, transparent)
}
}
&__login {
min-width: fit-content;
}
}

View file

@ -0,0 +1,40 @@
import {Component, OnInit} from '@angular/core';
import {MatAnchor, MatButton} from '@angular/material/button';
import {MatIcon} from '@angular/material/icon';
import {MatToolbar} from '@angular/material/toolbar';
import {Router, RouterLink} from '@angular/router';
@Component({
selector: 'app-header',
imports: [
MatToolbar,
MatAnchor,
RouterLink,
MatIcon,
MatButton,
],
templateUrl: './header.component.html',
styleUrl: './header.component.scss'
})
export class HeaderComponent implements OnInit {
routes: Array<{ path: string, title: string, class: string }> = [];
constructor(
private router: Router
) {
}
ngOnInit(): void {
this.routes = this.router.config
.filter(route => !route.path?.includes(':'))
.filter(route => !route.path?.includes('/'))
.map(route => ({
path: `/${route.path}`,
title: route.title as string,
class: `/${route.path}` == this.router.url ? 'active' : ''
}));
}
}

View file

@ -0,0 +1 @@
<p>dashboard works!</p>

View file

@ -0,0 +1,11 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-dashboard',
imports: [],
templateUrl: './dashboard.component.html',
styleUrl: './dashboard.component.scss'
})
export class DashboardComponent {
}

View file

@ -1,7 +1,6 @@
import { bootstrapApplication } from '@angular/platform-browser'; import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from '@app/app.component';
import { AppComponent } from './app/app.component'; import { appConfig } from '@app/app.config';
import { appConfig } from './app/app.config';
bootstrapApplication(AppComponent, appConfig) bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err)); .catch((err) => console.error(err));

View file

@ -1,4 +1,15 @@
/* You can add global styles to this file, and also import other style files */ @use '@angular/material' as mat;
html {
color-scheme: light dark;
@include mat.theme((
color: mat.$azure-palette,
typography: Roboto,
density: 0
));
}
html, body { html, body {
height: 100%; height: 100%;
@ -6,5 +17,6 @@ html, body {
body { body {
margin: 0; margin: 0;
font-family: Roboto, "Helvetica Neue", sans-serif; background: var(--mat-sys-surface);
color: var(--mat-sys-on-surface);
} }