Compare commits
5 Commits
387777972b
...
11e8c46e44
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11e8c46e44 | ||
|
|
a14bd78415 | ||
|
|
609f7d09fc | ||
|
|
4c21cb4ba7 | ||
|
|
00ebf45605 |
@@ -31,9 +31,14 @@
|
||||
],
|
||||
"styles": [
|
||||
"@angular/material/prebuilt-themes/indigo-pink.css",
|
||||
"src/styles.scss"
|
||||
"src/styles.scss",
|
||||
"node_modules/bootstrap/dist/css/bootstrap.min.css"
|
||||
],
|
||||
"scripts": [
|
||||
"node_modules/jquery/dist/jquery.min.js",
|
||||
"node_modules/@popperjs/core/dist/umd/popper.min.js",
|
||||
"node_modules/bootstrap/dist/js/bootstrap.min.js"
|
||||
],
|
||||
"scripts": [],
|
||||
"server": "src/main.server.ts",
|
||||
"prerender": true,
|
||||
"ssr": {
|
||||
@@ -106,7 +111,7 @@
|
||||
],
|
||||
"scripts": [
|
||||
"node_modules/jquery/dist/jquery.min.js",
|
||||
"node_modules/popper.js/dist/umd/popper.min.js",
|
||||
"node_modules/@popperjs/core/dist/umd/popper.min.js",
|
||||
"node_modules/bootstrap/dist/js/bootstrap.min.js"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "envelope-generator-ui",
|
||||
"version": "0.0.0",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "envelope-generator-ui",
|
||||
"version": "0.0.0",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@angular/animations": "^17.3.0",
|
||||
"@angular/cdk": "^17.3.10",
|
||||
@@ -24,9 +24,9 @@
|
||||
"@generic-ui/hermes": "^0.21.0",
|
||||
"@generic-ui/ngx-grid": "^0.21.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "^16.0.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"bootstrap": "^5.3.3",
|
||||
"express": "^4.18.2",
|
||||
"jquery": "^3.7.1",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.14.3"
|
||||
@@ -4259,6 +4259,7 @@
|
||||
"version": "2.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
@@ -8448,6 +8449,11 @@
|
||||
"jiti": "bin/jiti.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jquery": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
|
||||
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg=="
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
"@generic-ui/hermes": "^0.21.0",
|
||||
"@generic-ui/ngx-grid": "^0.21.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "^16.0.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"bootstrap": "^5.3.3",
|
||||
"express": "^4.18.2",
|
||||
"jquery": "^3.7.1",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.14.3"
|
||||
|
||||
@@ -2,9 +2,11 @@ import { Routes } from '@angular/router';
|
||||
import { HomeComponent } from '../app/pages/home/home.component'
|
||||
import { authGuard } from './guards/auth.guard'
|
||||
import { EnvelopeComponent } from './pages/envelope/envelope.component';
|
||||
import { EnvelopeCreationComponent } from './pages/envelope-creation/envelope-creation.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: '', component: HomeComponent },
|
||||
{ path: 'login', component: HomeComponent },
|
||||
{ path: 'envelope', component: EnvelopeComponent, canActivate: [authGuard] }
|
||||
{ path: 'envelope', component: EnvelopeComponent, canActivate: [authGuard] },
|
||||
{ path: 'envelope-creation', component: EnvelopeCreationComponent, canActivate: [authGuard] }
|
||||
];
|
||||
@@ -1,13 +1,48 @@
|
||||
<gui-grid
|
||||
[columns]="columns"
|
||||
[source]="source"
|
||||
[columnMenu]="columnMenu"
|
||||
[paging]="paging"
|
||||
[sorting]="sorting"
|
||||
[searching]="searching"
|
||||
[infoPanel]="infoPanel"
|
||||
[localization]="localization"
|
||||
[theme]="theme"
|
||||
[autoResizeWidth] = "true"
|
||||
>
|
||||
</gui-grid>
|
||||
<table #table mat-table [dataSource]="data" class="mat-elevation-z8">
|
||||
|
||||
@for (colId of displayedColumns; track colId) {
|
||||
<ng-container matColumnDef="{{colId}}">
|
||||
<th mat-header-cell *matHeaderCellDef> {{schema[colId].header}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{schema[colId].field(element)}} </td>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<ng-container matColumnDef="expand">
|
||||
<th mat-header-cell *matHeaderCellDef aria-label="row actions"> </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button mat-icon-button aria-label="expand row"
|
||||
(click)="(expandedElement = expandedElement === element ? null : element); $event.stopPropagation()">
|
||||
@if (expandedElement === element) {
|
||||
<mat-icon>keyboard_arrow_up</mat-icon>
|
||||
} @else {
|
||||
<mat-icon>keyboard_arrow_down</mat-icon>
|
||||
}
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
|
||||
<ng-container matColumnDef="expandedDetail">
|
||||
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplayWithExpand.length">
|
||||
<div class="example-element-detail" [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
|
||||
<div class="example-element-diagram">
|
||||
<div class="example-element-position"> {{"element.position"}} </div>
|
||||
<div class="example-element-symbol"> {{"element.symbol"}} </div>
|
||||
<div class="example-element-name"> {{"element.name"}} </div>
|
||||
<div class="example-element-weight"> {{"element.weight"}} </div>
|
||||
</div>
|
||||
<div class="example-element-description">
|
||||
{{"element.description"}}
|
||||
<span class="example-element-description-attribution"> -- Wikipedia </span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="columnsToDisplayWithExpand"></tr>
|
||||
<tr mat-row *matRowDef="let element; columns: columnsToDisplayWithExpand;" class="example-element-row"
|
||||
[class.example-expanded-row]="expandedElement === element"
|
||||
(click)="expandedElement = expandedElement === element ? null : element">
|
||||
</tr>
|
||||
<!--<tr mat-row *matRowDef="let row; columns: ['expandedDetail']; when: isExpandedRow" class="example-detail-row"></tr>-->
|
||||
</table>
|
||||
@@ -0,0 +1,31 @@
|
||||
.example-element-row td {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
.example-element-detail {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.example-element-diagram {
|
||||
min-width: 80px;
|
||||
border: 2px solid black;
|
||||
padding: 8px;
|
||||
font-weight: lighter;
|
||||
margin: 8px 0;
|
||||
height: 104px;
|
||||
}
|
||||
|
||||
.example-element-symbol {
|
||||
font-weight: bold;
|
||||
font-size: 40px;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.example-element-description {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.example-element-description-attribution {
|
||||
opacity: 0.5;
|
||||
}
|
||||
@@ -1,132 +1,70 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, ViewChild } from '@angular/core';
|
||||
import { EnvelopeReceiverService } from '../../services/envelope-receiver.service';
|
||||
import { GuiColumn, GuiColumnMenu, GuiGridModule, GuiInfoPanel, GuiLocalization, GuiPaging, GuiPagingDisplay, GuiSearching, GuiSorting, GuiSummaries, GuiTheme } from '@generic-ui/ngx-grid';
|
||||
import { MatTable, MatTableModule } from '@angular/material/table';
|
||||
import { CommonModule } from '@angular/common'
|
||||
import {MatIconModule} from '@angular/material/icon';
|
||||
import {MatButtonModule} from '@angular/material/button';
|
||||
import {animate, state, style, transition, trigger} from '@angular/animations';
|
||||
|
||||
@Component({
|
||||
selector: 'app-envelope-table',
|
||||
standalone: true,
|
||||
imports: [GuiGridModule],
|
||||
imports: [MatTableModule, CommonModule, MatTableModule, MatButtonModule, MatIconModule],
|
||||
templateUrl: './envelope-table.component.html',
|
||||
animations: [
|
||||
trigger('detailExpand', [
|
||||
state('collapsed,void', style({height: '0px', minHeight: '0'})),
|
||||
state('expanded', style({height: '*'})),
|
||||
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
|
||||
]),
|
||||
],
|
||||
styleUrl: './envelope-table.component.scss'
|
||||
})
|
||||
export class EnvelopeTableComponent {
|
||||
|
||||
columnMenu: GuiColumnMenu = {
|
||||
enabled: true,
|
||||
sort: true,
|
||||
columnsManager: true
|
||||
};
|
||||
data: Array<any> = []
|
||||
|
||||
sorting: GuiSorting = {
|
||||
enabled: true,
|
||||
multiSorting: true
|
||||
};
|
||||
public displayedColumns: string[] = ['title', 'status', 'type', 'privateMessage', 'addedWhen'];
|
||||
columnsToDisplayWithExpand = [...this.displayedColumns, 'expand'];
|
||||
|
||||
schema: any = {
|
||||
'title': {
|
||||
header: 'Title',
|
||||
field: (element: any) => element.envelope.title
|
||||
},
|
||||
'status': {
|
||||
header: 'Status',
|
||||
field: (element: any) => element.envelope.statusName
|
||||
},
|
||||
'type': {
|
||||
header: 'Type',
|
||||
field: (element: any) => element.envelope.contractType
|
||||
},
|
||||
'privateMessage': {
|
||||
header: 'Private Message',
|
||||
field: (element: any) => element.privateMessage
|
||||
},
|
||||
'addedWhen': {
|
||||
header: 'Added When',
|
||||
field: (element: any) => element.addedWhen
|
||||
},
|
||||
}
|
||||
|
||||
paging: GuiPaging = {
|
||||
enabled: true,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
pageSizes: [10, 25, 50],
|
||||
pagerTop: true,
|
||||
pagerBottom: true,
|
||||
display: GuiPagingDisplay.ADVANCED
|
||||
};
|
||||
expandedElement: any | null;
|
||||
|
||||
searching: GuiSearching = {
|
||||
enabled: true
|
||||
};
|
||||
|
||||
summaries: GuiSummaries = {
|
||||
enabled: true
|
||||
};
|
||||
|
||||
infoPanel: GuiInfoPanel = {
|
||||
enabled: true,
|
||||
infoDialog: false,
|
||||
columnsManager: true,
|
||||
schemaManager: true
|
||||
};
|
||||
|
||||
localization: GuiLocalization = {
|
||||
translationResolver: (key: string, value: string) => EnvelopeTableComponent.Translation[key] ?? value
|
||||
};
|
||||
|
||||
theme: GuiTheme = GuiTheme.FABRIC;
|
||||
|
||||
source: Array<any> = []
|
||||
@ViewChild(MatTable) table!: MatTable<any>;
|
||||
|
||||
constructor(private erService: EnvelopeReceiverService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.source = await this.erService.getEnvelopeReceiver();
|
||||
this.data = await this.erService.getEnvelopeReceiver();
|
||||
}
|
||||
|
||||
columns: Array<GuiColumn> = [
|
||||
{
|
||||
header: 'Title',
|
||||
field: er => er.envelope.title
|
||||
},
|
||||
{
|
||||
header: "Status",
|
||||
field: er => er.envelope.statusName
|
||||
},
|
||||
{
|
||||
header: 'Type',
|
||||
field: er => er.envelope.contractType
|
||||
},
|
||||
{
|
||||
header: 'PrivateMessage',
|
||||
field: 'privateMessage'
|
||||
},
|
||||
{
|
||||
header: 'AddedWhen',
|
||||
field: 'addedWhen'
|
||||
}];
|
||||
|
||||
static readonly Translation: { [key: string]: string } = {
|
||||
"sourceEmpty": "There are no items to show.",
|
||||
"pagingItemsPerPage": "Items per page:",
|
||||
"pagingOf": "of",
|
||||
"pagingNextPage": "Next",
|
||||
"pagingPrevPage": "Prev",
|
||||
"pagingNoItems": "There is no items.",
|
||||
"infoPanelShowing": "Showing",
|
||||
"infoPanelItems": "items",
|
||||
"infoPanelOutOf": "out of",
|
||||
"infoPanelThemeMangerTooltipText": "Theme manager",
|
||||
"infoPanelColumnManagerTooltipText": "Column manager",
|
||||
"infoPanelInfoTooltipText": "info",
|
||||
"themeManagerModalTitle": "Theme manager",
|
||||
"themeManagerModalTheme": "Theme:",
|
||||
"themeManagerModalRowColoring": "Row coloring:",
|
||||
"themeManagerModalVerticalGrid": "Vertical grid",
|
||||
"themeManagerModalHorizontalGrid": "HorizontalGrid",
|
||||
"columnManagerModalTitle": "Manage columns",
|
||||
"headerMenuMainTab": "Menu",
|
||||
"headerMenuMainTabColumnSort": "Column sort",
|
||||
"headerMenuMainTabHideColumn": "Hide column",
|
||||
"headerMenuMainTabHighlightColumn": "Highlight",
|
||||
"headerMenuMainTabMoveLeft": "Move left",
|
||||
"headerMenuMainTabMoveRight": "Move right",
|
||||
"headerMenuMainTabColumnSortAscending": "Ascending",
|
||||
"headerMenuMainTabColumnSortDescending": "Descending",
|
||||
"headerMenuMainTabColumnSortNone": "None",
|
||||
"headerMenuFilterTab": "Filter",
|
||||
"headerMenuColumnsTab": "Columns",
|
||||
"summariesCount": "Count",
|
||||
"summariesDist": "Dist",
|
||||
"summariesSum": "Sum",
|
||||
"summariesAvg": "Avg",
|
||||
"summariesMin": "Min",
|
||||
"summariesMax": "Max",
|
||||
"summariesMed": "Med",
|
||||
"summariesTruthy": "Truthy",
|
||||
"summariesFalsy": "Falsy",
|
||||
"summariesDistinctValuesTooltip": "Distinct values",
|
||||
"summariesAverageTooltip": "Average",
|
||||
"summariesMinTooltip": "Min",
|
||||
"summariesMaxTooltip": "Max",
|
||||
"summariesMedTooltip": "Median",
|
||||
"summariesCountTooltip": "Number of items in the grid"
|
||||
public updateTable() {
|
||||
this.table.renderRows();
|
||||
}
|
||||
|
||||
isExpandedRow(index: number, row: any): boolean {
|
||||
return (row?.envelopeId === this.expandedElement?.envelopeId) && (row?.receiverId === this.expandedElement?.receiverId);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,25 @@
|
||||
<!-- src/app/components/login/login.component.html -->
|
||||
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
|
||||
<div class="mb-3">
|
||||
<mat-form-field>
|
||||
<mat-label>Username</mat-label>
|
||||
<input matInput formControlName="username">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<mat-form-field>
|
||||
<mat-label>Enter your password</mat-label>
|
||||
<input matInput [type]="hide ? 'password' : 'text'" formControlName="password">
|
||||
<button type="button" mat-icon-button matSuffix (click)="togglePWVisibility($event)" [attr.aria-label]="'Hide password'"
|
||||
[attr.aria-pressed]="hide">
|
||||
<mat-icon>{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button mat-flat-button color="primary" type="submit">Log In</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="mb-3">
|
||||
<mat-form-field>
|
||||
<mat-label>Username</mat-label>
|
||||
<input matInput formControlName="username">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<mat-form-field>
|
||||
<mat-label>Enter your password</mat-label>
|
||||
<input matInput [type]="hide ? 'password' : 'text'" formControlName="password">
|
||||
<button type="button" mat-icon-button matSuffix (click)="togglePWVisibility($event)"
|
||||
[attr.aria-label]="'Hide password'" [attr.aria-pressed]="hide">
|
||||
<mat-icon>{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn" mat-flat-button color="primary">
|
||||
<span class="me-2">Anmeldung</span>
|
||||
<span class="p-0 m-0" [class.spinner-border]="wait4waitRes" [class.spinner-border-sm]="wait4waitRes" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -18,6 +18,7 @@ import { ReactiveFormsModule } from '@angular/forms';
|
||||
export class LoginComponent {
|
||||
hide = true;
|
||||
loginForm: FormGroup;
|
||||
wait4waitRes: boolean = false;
|
||||
|
||||
constructor(private fb: FormBuilder, private authService: AuthService, private router: Router) {
|
||||
this.loginForm = this.fb.group({
|
||||
@@ -33,12 +34,14 @@ export class LoginComponent {
|
||||
|
||||
onSubmit() {
|
||||
if (this.loginForm.valid) {
|
||||
this.wait4waitRes = true;
|
||||
this.authService.login(this.loginForm.value).subscribe({
|
||||
next: () => {
|
||||
this.router.navigate(['/envelope']);
|
||||
this.wait4waitRes = false;
|
||||
this.router.navigate(['/envelope']);
|
||||
},
|
||||
error: error => {
|
||||
console.error('Login failed', error);
|
||||
this.wait4waitRes = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,36 @@
|
||||
<mat-toolbar color="primary" class="toolbar">
|
||||
<button mat-icon-button>
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
<span>signFlow</span>
|
||||
</mat-toolbar>
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-lg bg-body-tertiary fs-5">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand fs-2 fw-bold" [routerLink]="['/']">SignFlow</a>
|
||||
<!-- Navbars -->
|
||||
<div *ngIf="isLogedIn()" class="navbar-collapse collapse d-sm-inline-flex justify-content-center"
|
||||
[ngClass]="{ show: isExpanded }">
|
||||
<ul class=" navbar-nav flex-grow">
|
||||
<li class="nav-item" [routerLinkActive]="['link-active']" [routerLinkActiveOptions]="{exact: true}">
|
||||
<button class="btn nav-link d-flex flex-column align-items-center justify-content-center" (click)="router.navigate(['/envelope-creation'])">
|
||||
<mat-icon>mail</mat-icon>
|
||||
<span class="fs-6">Neuer Umschlag</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Right menu -->
|
||||
<div class="navbar-collapse justify-content-end me-5">
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse"
|
||||
aria-label="Toggle navigation" [attr.aria-expanded]="isExpanded" (click)="toggle()">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<button class="fs-5 btn d-flex align-items-center ms-2 me-0 pe-0" type="button" (click)="logInOut()">
|
||||
@if(isLogedIn()){
|
||||
<mat-icon>logout</mat-icon>
|
||||
<span class="fs-6 ms-1">Abmelden</span>
|
||||
}
|
||||
@else {
|
||||
<mat-icon>login</mat-icon>
|
||||
<span class="fs-6 ms-1">Anmelden</span>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
@@ -1,23 +1,55 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { Component, QueryList, ViewChildren } from '@angular/core';
|
||||
import { Router, RouterModule } from '@angular/router';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatTooltip, MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { AuthService } from '../../services/auth.service'
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-navbar',
|
||||
standalone: true,
|
||||
imports: [
|
||||
MatToolbarModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatSidenavModule,
|
||||
MatListModule
|
||||
],
|
||||
imports: [RouterModule, CommonModule, MatIconModule, MatBadgeModule, MatSlideToggleModule, FormsModule, MatButtonModule, MatTooltipModule],
|
||||
selector: 'app-navbar',
|
||||
templateUrl: './navbar.component.html',
|
||||
styleUrl: './navbar.component.scss'
|
||||
styleUrls: ['./navbar.component.scss']
|
||||
})
|
||||
export class NavbarComponent {
|
||||
isLogedIn(): boolean {
|
||||
return this.authService.IsAuthenticated;
|
||||
}
|
||||
|
||||
}
|
||||
async logInOut(): Promise<void> {
|
||||
if (this.isLogedIn())
|
||||
return this.authService.logoutAsync().then(() => {
|
||||
this.router.navigate(['/']);
|
||||
})
|
||||
else
|
||||
this.router.navigate(['/login']);
|
||||
}
|
||||
|
||||
isExpanded = false;
|
||||
|
||||
isChecked = true;
|
||||
|
||||
constructor(public router: Router, public authService: AuthService) {
|
||||
}
|
||||
|
||||
get isDarkTheme(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
collapse() {
|
||||
this.isExpanded = false;
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.isExpanded = !this.isExpanded;
|
||||
}
|
||||
|
||||
@ViewChildren(MatTooltip) tooltips: QueryList<MatTooltip> | undefined;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<mat-stepper orientation="vertical" [linear]="isLinear" #stepper>
|
||||
<mat-step [stepControl]="firstFormGroup">
|
||||
<form [formGroup]="firstFormGroup">
|
||||
<ng-template matStepLabel>Titel & Vertragstyp</ng-template>
|
||||
<mat-form-field>
|
||||
<mat-label>Titel</mat-label>
|
||||
<input matInput placeholder="Arbeitsvertrag" formControlName="firstCtrl" required>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="ms-5">
|
||||
<mat-label>Vertragstyp</mat-label>
|
||||
<mat-select [(value)]="selectedType" [formControl]="typeControl" formControlName="firstCtrl" required>
|
||||
@for (type of types; track type) {
|
||||
<mat-option [value]="type.value">{{type.viewValue}}</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div>
|
||||
<button mat-button matStepperNext>Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
<mat-step [stepControl]="secondFormGroup">
|
||||
<form [formGroup]="secondFormGroup">
|
||||
<ng-template matStepLabel>Fill out your address</ng-template>
|
||||
<mat-form-field>
|
||||
<mat-label>Address</mat-label>
|
||||
<input matInput formControlName="secondCtrl" placeholder="Ex. 1 Main St, New York, NY" required>
|
||||
</mat-form-field>
|
||||
<div>
|
||||
<button mat-button matStepperPrevious>Back</button>
|
||||
<button mat-button matStepperNext>Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
<mat-step>
|
||||
<ng-template matStepLabel>Done</ng-template>
|
||||
<p>You are now done.</p>
|
||||
<div>
|
||||
<button mat-button matStepperPrevious>Back</button>
|
||||
<button mat-button (click)="stepper.reset()">Reset</button>
|
||||
</div>
|
||||
</mat-step>
|
||||
</mat-stepper>
|
||||
@@ -0,0 +1,7 @@
|
||||
.mat-stepper-vertical {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.mat-mdc-form-field {
|
||||
margin-top: 16px;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { EnvelopeCreationComponent } from './envelope-creation.component';
|
||||
|
||||
describe('EnvelopeCreationComponent', () => {
|
||||
let component: EnvelopeCreationComponent;
|
||||
let fixture: ComponentFixture<EnvelopeCreationComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [EnvelopeCreationComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(EnvelopeCreationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { FormBuilder, Validators, FormsModule, ReactiveFormsModule, FormControl } from '@angular/forms';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatStepperModule } from '@angular/material/stepper';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
|
||||
@Component({
|
||||
selector: 'app-envelope-creation',
|
||||
standalone: true,
|
||||
imports: [
|
||||
MatButtonModule,
|
||||
MatStepperModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatSelectModule
|
||||
],
|
||||
templateUrl: './envelope-creation.component.html',
|
||||
styleUrl: './envelope-creation.component.scss'
|
||||
})
|
||||
export class EnvelopeCreationComponent {
|
||||
|
||||
ngOnInit() {
|
||||
this.selectedType = this.types[0].value;
|
||||
}
|
||||
|
||||
private _formBuilder = inject(FormBuilder);
|
||||
|
||||
firstFormGroup = this._formBuilder.group({
|
||||
firstCtrl: ['', Validators.required],
|
||||
});
|
||||
secondFormGroup = this._formBuilder.group({
|
||||
secondCtrl: ['', Validators.required],
|
||||
});
|
||||
isLinear = true;
|
||||
|
||||
selectedType: string = "Mietvertrag"
|
||||
types: any[] = [
|
||||
{value: 0, viewValue: 'Mietvertrag'},
|
||||
{value: 1, viewValue: 'Kaufvertrag'}
|
||||
];
|
||||
typeControl = new FormControl('Mietvertrag', [Validators.required]);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Observable, firstValueFrom, tap } from 'rxjs';
|
||||
import { API_URL } from '../tokens/index';
|
||||
|
||||
@Injectable({
|
||||
@@ -22,7 +22,18 @@ export class AuthService {
|
||||
return this.http.post(`${this.url}/logout`, {});
|
||||
}
|
||||
|
||||
async logoutAsync(): Promise<void> {
|
||||
return await firstValueFrom(this.logout());
|
||||
}
|
||||
|
||||
isAuthenticated(): Observable<boolean> {
|
||||
return this.http.get<boolean>(`${this.url}/check`);
|
||||
return this.http.get<boolean>(`${this.url}/check`).pipe(
|
||||
tap(isAuthenticated => this.#IsAuthenticated = isAuthenticated)
|
||||
);
|
||||
}
|
||||
|
||||
#IsAuthenticated = false;
|
||||
get IsAuthenticated(): boolean {
|
||||
return this.#IsAuthenticated;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="3em" height="2.5em" viewBox="0 0 24 24" style="stroke: #a9a8ad;">
|
||||
<path opacity="0.5" d="M15.9998 2L14.9998 2C12.1714 2 10.7576 2.00023 9.87891 2.87891C9.00023 3.75759 9.00023 5.1718 9.00023 8.00023L9.00023 16.0002C9.00023 18.8287 9.00023 20.2429 9.87891 21.1215C10.7574 22 12.1706 22 14.9976 22L14.9998 22L15.9998 22C18.8282 22 20.2424 22 21.1211 21.1213C21.9998 20.2426 21.9998 18.8284 21.9998 16L21.9998 8L21.9998 7.99998C21.9998 5.17157 21.9998 3.75736 21.1211 2.87868C20.2424 2 18.8282 2 15.9998 2Z" fill="#1C274C"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.25098 11.999C1.25098 11.5848 1.58676 11.249 2.00098 11.249L13.9735 11.249L12.0129 9.56845C11.6984 9.29889 11.662 8.82541 11.9315 8.51092C12.2011 8.19642 12.6746 8.16 12.9891 8.42957L16.4891 11.4296C16.6553 11.5721 16.751 11.7801 16.751 11.999C16.751 12.218 16.6553 12.426 16.4891 12.5685L12.9891 15.5685C12.6746 15.838 12.2011 15.8016 11.9315 15.4871C11.662 15.1726 11.6984 14.6991 12.0129 14.4296L13.9735 12.749L2.00098 12.749C1.58676 12.749 1.25098 12.4132 1.25098 11.999Z" fill="#1C274C"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
Reference in New Issue
Block a user