Created initial menu structure
This commit is contained in:
parent
fbd602e18a
commit
30cc326168
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Debug" type="JavascriptDebugType" uri="http://localhost:4200"
|
||||||
|
useFirstLineBreakpoints="true">
|
||||||
|
<method v="2"/>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
|
@ -1,8 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "tsw-timetable-frontend",
|
"name": "tsw-timetable-frontend",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"author": "Ionic Framework",
|
"author": "Jim Martens",
|
||||||
"homepage": "https://ionicframework.com/",
|
"homepage": "https://2martens.de/",
|
||||||
|
"description": "Frontend for timetable application",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
|
@ -76,6 +77,5 @@
|
||||||
"ts-node": "^8.3.0",
|
"ts-node": "^8.3.0",
|
||||||
"typescript": "~5.0.2",
|
"typescript": "~5.0.2",
|
||||||
"webpack-bundle-analyzer": "^4.9.0"
|
"webpack-bundle-analyzer": "^4.9.0"
|
||||||
},
|
}
|
||||||
"description": "An Ionic project"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,36 @@
|
||||||
<ion-app>
|
<ion-app>
|
||||||
<ion-split-pane contentId="main-content">
|
<ion-split-pane when="md" contentId="main-content">
|
||||||
<ion-menu contentId="main-content" type="overlay">
|
<ion-menu contentId="main-content" type="overlay">
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<ion-list id="inbox-list">
|
<ion-list id="menu-list">
|
||||||
<ion-list-header>Inbox</ion-list-header>
|
<ion-list-header i18n>Timetable</ion-list-header>
|
||||||
<ion-note>hi@ionicframework.com</ion-note>
|
<ion-note *ngIf="isLoggedIn$ | async">{{ username$ | async }}</ion-note>
|
||||||
|
|
||||||
<ion-menu-toggle auto-hide="false" *ngFor="let p of appPages; let i = index">
|
<ng-container *ngIf="isLoggedIn$ | async; else loggedOut">
|
||||||
<ion-item routerDirection="root" [routerLink]="[p.url]" lines="none" detail="false"
|
<ion-item *ngFor="let p of accountPages; let i = index"
|
||||||
routerLinkActive="selected">
|
[routerDirection]="'root'" [routerLink]="[p.url]" [routerLinkActiveOptions]="{exact: true}"
|
||||||
|
lines="none" [detail]="false"
|
||||||
|
[routerLinkActive]="'selected'" [ariaCurrentWhenActive]="'page'" [button]="true">
|
||||||
|
<ion-icon aria-hidden="true" [slot]="'start'" [ios]="p.icon + '-outline'"
|
||||||
|
[md]="p.icon + '-sharp'"></ion-icon>
|
||||||
|
<ion-label>{{ p.title }}</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
</ng-container>
|
||||||
|
<ion-item-divider></ion-item-divider>
|
||||||
|
<ng-template #loggedOut>
|
||||||
|
<ion-item *ngFor="let p of loggedOutPages; let i = index"
|
||||||
|
routerDirection="root" [routerLink]="[p.url]" lines="none" detail="false"
|
||||||
|
routerLinkActive="selected" [routerLinkActiveOptions]="{exact: true}" [button]="true">
|
||||||
<ion-icon aria-hidden="true" slot="start" [ios]="p.icon + '-outline'" [md]="p.icon + '-sharp'"></ion-icon>
|
<ion-icon aria-hidden="true" slot="start" [ios]="p.icon + '-outline'" [md]="p.icon + '-sharp'"></ion-icon>
|
||||||
<ion-label>{{ p.title }}</ion-label>
|
<ion-label>{{ p.title }}</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-menu-toggle>
|
</ng-template>
|
||||||
</ion-list>
|
|
||||||
|
|
||||||
<ion-list id="labels-list" *ngIf="labels.length > 0">
|
<ion-item *ngFor="let p of appPages; let i = index"
|
||||||
<ion-list-header>Labels</ion-list-header>
|
routerDirection="root" [routerLink]="[p.url]" lines="none" detail="false"
|
||||||
|
routerLinkActive="selected" [routerLinkActiveOptions]="{exact: true}" [button]="true">
|
||||||
<ion-item *ngFor="let label of labels" lines="none">
|
<ion-icon aria-hidden="true" slot="start" [ios]="p.icon + '-outline'" [md]="p.icon + '-sharp'"></ion-icon>
|
||||||
<ion-icon aria-hidden="true" slot="start" ios="bookmark-outline" md="bookmark-sharp"></ion-icon>
|
<ion-label>{{ p.title }}</ion-label>
|
||||||
<ion-label>{{ label }}</ion-label>
|
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import {CommonModule} from '@angular/common';
|
import {AsyncPipe, NgFor, NgIf} from '@angular/common';
|
||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {RouterLink, RouterLinkActive} from '@angular/router';
|
import {RouterLink, RouterLinkActive} from '@angular/router';
|
||||||
import {
|
import {
|
||||||
IonApp,
|
IonApp,
|
||||||
IonContent,
|
IonContent,
|
||||||
|
IonHeader,
|
||||||
IonIcon,
|
IonIcon,
|
||||||
IonItem,
|
IonItem,
|
||||||
|
IonItemDivider,
|
||||||
IonLabel,
|
IonLabel,
|
||||||
IonList,
|
IonList,
|
||||||
IonListHeader,
|
IonListHeader,
|
||||||
|
@ -13,61 +15,74 @@ import {
|
||||||
IonMenuToggle,
|
IonMenuToggle,
|
||||||
IonNote,
|
IonNote,
|
||||||
IonRouterOutlet,
|
IonRouterOutlet,
|
||||||
IonSplitPane
|
IonSplitPane,
|
||||||
|
IonTitle,
|
||||||
|
IonToolbar
|
||||||
} from '@ionic/angular/standalone';
|
} from '@ionic/angular/standalone';
|
||||||
import {addIcons} from 'ionicons';
|
import {addIcons} from 'ionicons';
|
||||||
import {
|
import {
|
||||||
archiveOutline,
|
homeOutline,
|
||||||
archiveSharp,
|
homeSharp,
|
||||||
bookmarkOutline,
|
logInOutline,
|
||||||
bookmarkSharp,
|
logInSharp,
|
||||||
heartOutline,
|
logOutOutline,
|
||||||
heartSharp,
|
logOutSharp,
|
||||||
mailOutline,
|
readerOutline,
|
||||||
mailSharp,
|
readerSharp,
|
||||||
paperPlaneOutline,
|
shieldOutline,
|
||||||
paperPlaneSharp,
|
shieldSharp
|
||||||
trashOutline,
|
|
||||||
trashSharp,
|
|
||||||
warningOutline,
|
|
||||||
warningSharp
|
|
||||||
} from 'ionicons/icons';
|
} from 'ionicons/icons';
|
||||||
|
import {KeycloakService} from "keycloak-angular";
|
||||||
|
import {from, Observable, of, switchMap} from "rxjs";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
templateUrl: 'app.component.html',
|
templateUrl: 'app.component.html',
|
||||||
styleUrls: ['app.component.scss'],
|
styleUrls: ['app.component.scss'],
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [RouterLink, RouterLinkActive, CommonModule, IonApp, IonSplitPane, IonMenu, IonContent, IonList,
|
imports: [RouterLink, RouterLinkActive, IonApp, IonSplitPane, IonMenu, IonContent, IonList,
|
||||||
IonListHeader, IonNote, IonMenuToggle, IonItem, IonIcon, IonLabel, IonRouterOutlet],
|
IonListHeader, IonNote, IonMenuToggle, IonItem, IonIcon, IonLabel, IonRouterOutlet, NgIf, NgFor, AsyncPipe, IonItemDivider, IonHeader, IonToolbar, IonTitle],
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
public appPages = [
|
public appPages = [
|
||||||
{title: 'Inbox', url: '/folder/inbox', icon: 'mail'},
|
{title: $localize`Dashboard`, url: '', icon: 'home'},
|
||||||
{title: 'Outbox', url: '/folder/outbox', icon: 'paper-plane'},
|
{title: $localize`Privacy Policy`, url: '/privacy-policy', icon: 'shield'},
|
||||||
{title: 'Favorites', url: '/folder/favorites', icon: 'heart'},
|
{title: $localize`Legal Notice`, url: '/legal-notice', icon: 'reader'},
|
||||||
{title: 'Archived', url: '/folder/archived', icon: 'archive'},
|
|
||||||
{title: 'Trash', url: '/folder/trash', icon: 'trash'},
|
|
||||||
{title: 'Spam', url: '/folder/spam', icon: 'warning'},
|
|
||||||
];
|
];
|
||||||
public labels = [];
|
public accountPages = [
|
||||||
|
{title: $localize`Logout`, url: '/logout', icon: 'log-out'},
|
||||||
|
];
|
||||||
|
public loggedOutPages = [
|
||||||
|
{title: $localize`Logout`, url: '/login', icon: 'log-in'},
|
||||||
|
]
|
||||||
|
public isLoggedIn$: Observable<boolean>;
|
||||||
|
public username$: Observable<string>;
|
||||||
|
|
||||||
constructor() {
|
constructor(
|
||||||
|
private keycloakService: KeycloakService
|
||||||
|
) {
|
||||||
|
this.isLoggedIn$ = from(this.keycloakService.isLoggedIn());
|
||||||
|
this.username$ = this.isLoggedIn$.pipe(
|
||||||
|
switchMap(loggedIn => {
|
||||||
|
if (loggedIn) {
|
||||||
|
return of(this.keycloakService.getUsername());
|
||||||
|
} else {
|
||||||
|
return of('');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
addIcons({
|
addIcons({
|
||||||
mailOutline,
|
homeOutline,
|
||||||
mailSharp,
|
homeSharp,
|
||||||
paperPlaneOutline,
|
logInOutline,
|
||||||
paperPlaneSharp,
|
logInSharp,
|
||||||
heartOutline,
|
logOutOutline,
|
||||||
heartSharp,
|
logOutSharp,
|
||||||
archiveOutline,
|
shieldOutline,
|
||||||
archiveSharp,
|
shieldSharp,
|
||||||
trashOutline,
|
readerOutline,
|
||||||
trashSharp,
|
readerSharp,
|
||||||
warningOutline,
|
|
||||||
warningSharp,
|
|
||||||
bookmarkOutline,
|
|
||||||
bookmarkSharp
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
import {Routes} from '@angular/router';
|
import {Routes} from '@angular/router';
|
||||||
|
import {AppAuthGuard} from "./auth/auth.guard";
|
||||||
|
|
||||||
export const ROOT_ROUTES: Routes = [
|
export const ROOT_ROUTES: Routes = [
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
loadComponent: () => import("./dashboard/dashboard.component").then(mod => mod.DashboardComponent),
|
|
||||||
pathMatch: 'full',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'permission-denied',
|
path: 'permission-denied',
|
||||||
loadComponent: () => import("./permission-denied/permission-denied.component")
|
loadComponent: () => import("./permission-denied/permission-denied.component")
|
||||||
.then(mod => mod.PermissionDeniedComponent)
|
.then(mod => mod.PermissionDeniedComponent),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'legal-notice',
|
path: 'legal-notice',
|
||||||
|
@ -19,4 +15,18 @@ export const ROOT_ROUTES: Routes = [
|
||||||
path: 'privacy-policy',
|
path: 'privacy-policy',
|
||||||
loadComponent: () => import("./privacy-policy/privacy-policy.component").then(mod => mod.PrivacyPolicyComponent)
|
loadComponent: () => import("./privacy-policy/privacy-policy.component").then(mod => mod.PrivacyPolicyComponent)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'login',
|
||||||
|
loadComponent: () => import("./login/login.component").then(mod => mod.LoginComponent)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'logout',
|
||||||
|
loadComponent: () => import("./logout/logout.component").then(mod => mod.LogoutComponent),
|
||||||
|
canActivate: [AppAuthGuard]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
loadComponent: () => import("./dashboard/dashboard.component").then(mod => mod.DashboardComponent),
|
||||||
|
pathMatch: 'full',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {IonButtons, IonContent, IonHeader, IonMenuButton, IonTitle, IonToolbar} from "@ionic/angular/standalone";
|
import {
|
||||||
|
IonButtons,
|
||||||
|
IonContent,
|
||||||
|
IonHeader,
|
||||||
|
IonMenuButton,
|
||||||
|
IonMenuToggle,
|
||||||
|
IonTitle,
|
||||||
|
IonToolbar
|
||||||
|
} from "@ionic/angular/standalone";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-dashboard',
|
selector: 'app-dashboard',
|
||||||
|
@ -12,7 +20,8 @@ import {IonButtons, IonContent, IonHeader, IonMenuButton, IonTitle, IonToolbar}
|
||||||
IonMenuButton,
|
IonMenuButton,
|
||||||
IonTitle,
|
IonTitle,
|
||||||
IonToolbar,
|
IonToolbar,
|
||||||
IonContent
|
IonContent,
|
||||||
|
IonMenuToggle
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class DashboardComponent {
|
export class DashboardComponent {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<ion-header [translucent]="true">
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-buttons slot="start">
|
||||||
|
<ion-menu-button></ion-menu-button>
|
||||||
|
</ion-buttons>
|
||||||
|
<ion-title i18n="page title">Timetable</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content [fullscreen]="true">
|
||||||
|
<ion-header collapse="condense">
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title size="large" i18n="page title">Timetable</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<p i18n="welcome text|A welcome to users">
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</ion-content>
|
|
@ -0,0 +1,24 @@
|
||||||
|
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
|
||||||
|
import {IonicModule} from '@ionic/angular';
|
||||||
|
|
||||||
|
import {LoginComponent} from './login.component';
|
||||||
|
|
||||||
|
describe('LoginComponent', () => {
|
||||||
|
let component: LoginComponent;
|
||||||
|
let fixture: ComponentFixture<LoginComponent>;
|
||||||
|
|
||||||
|
beforeEach(waitForAsync(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [LoginComponent],
|
||||||
|
imports: [IonicModule.forRoot()]
|
||||||
|
}).compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(LoginComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
import {Component, OnInit} from '@angular/core';
|
||||||
|
import {IonButtons, IonContent, IonHeader, IonMenuButton, IonTitle, IonToolbar} from "@ionic/angular/standalone";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-login',
|
||||||
|
templateUrl: './login.component.html',
|
||||||
|
styleUrls: ['./login.component.scss'],
|
||||||
|
imports: [
|
||||||
|
IonButtons,
|
||||||
|
IonContent,
|
||||||
|
IonHeader,
|
||||||
|
IonMenuButton,
|
||||||
|
IonTitle,
|
||||||
|
IonToolbar
|
||||||
|
],
|
||||||
|
standalone: true
|
||||||
|
})
|
||||||
|
export class LoginComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<ion-header [translucent]="true">
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-buttons slot="start">
|
||||||
|
<ion-menu-button></ion-menu-button>
|
||||||
|
</ion-buttons>
|
||||||
|
<ion-title i18n="page title">Timetable</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content [fullscreen]="true">
|
||||||
|
<ion-header collapse="condense">
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title size="large" i18n="page title">Timetable</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<p i18n="welcome text|A welcome to users">
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</ion-content>
|
|
@ -0,0 +1,24 @@
|
||||||
|
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
|
||||||
|
import {IonicModule} from '@ionic/angular';
|
||||||
|
|
||||||
|
import {LogoutComponent} from './logout.component';
|
||||||
|
|
||||||
|
describe('LogoutComponent', () => {
|
||||||
|
let component: LogoutComponent;
|
||||||
|
let fixture: ComponentFixture<LogoutComponent>;
|
||||||
|
|
||||||
|
beforeEach(waitForAsync(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [LogoutComponent],
|
||||||
|
imports: [IonicModule.forRoot()]
|
||||||
|
}).compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(LogoutComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
import {Component, OnInit} from '@angular/core';
|
||||||
|
import {IonButtons, IonContent, IonHeader, IonMenuButton, IonTitle, IonToolbar} from "@ionic/angular/standalone";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-logout',
|
||||||
|
templateUrl: './logout.component.html',
|
||||||
|
styleUrls: ['./logout.component.scss'],
|
||||||
|
imports: [
|
||||||
|
IonButtons,
|
||||||
|
IonContent,
|
||||||
|
IonHeader,
|
||||||
|
IonMenuButton,
|
||||||
|
IonTitle,
|
||||||
|
IonToolbar
|
||||||
|
],
|
||||||
|
standalone: true
|
||||||
|
})
|
||||||
|
export class LogoutComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue