Compare commits

...

5 Commits

Author SHA1 Message Date
Developer 02
11e8c46e44 feat: Umschlag-Erstellungskomponente erstellt und Angular Material Stepper initialisiert 2024-08-20 09:35:00 +02:00
Developer 02
a14bd78415 feat: Navigationsleiste angepasst, Logout- und Neuen-Umschlag-Button hinzugefügt
- Navigationsleiste überarbeitet und das Layout optimiert.
- Logout-Button hinzugefügt, um den Benutzern das Abmelden zu erleichtern.
- Button für das Erstellen eines neuen Umschlags hinzugefügt, um die Benutzerfreundlichkeit zu verbessern.
2024-08-19 16:43:24 +02:00
Developer 02
609f7d09fc feat: Bootstrap zur Projektstruktur hinzugefügt 2024-08-19 13:32:14 +02:00
Developer 02
4c21cb4ba7 feat: Zeilen-Erweiterungsfunktion zur EnvelopeTableComponent hinzugefügt 2024-08-19 11:48:45 +02:00
Developer 02
00ebf45605 refactor: Aktualisierung von EnvelopeTableComponent zur Verwendung der Angular Material Tabelle
- Ersetzte `@generic-ui/ngx-grid` durch Angular Material Tabellenkomponenten.
- Aktualisierte `EnvelopeTableComponent`, um `mat-table` für die Tabellenanzeige zu verwenden.
- Umorganisierte Daten- und Schema-Definitionen zur Kompatibilität mit Angular Material Tabelle.
- Füge `MatTableModule` und `CommonModule` zu den Komponenten-Imports hinzu.
- Implementierte dynamische Spaltenanzeige basierend auf dem Schema.
- Hinzugefügt `updateTable` Methode zur erneuten Darstellung der Tabelle.
2024-08-19 09:41:01 +02:00
17 changed files with 395 additions and 177 deletions

View File

@@ -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"
]
}

View File

@@ -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",

View File

@@ -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"

View File

@@ -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] }
];

View File

@@ -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">&nbsp;</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>

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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>

View File

@@ -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;
}
});
}

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -0,0 +1,7 @@
.mat-stepper-vertical {
margin-top: 8px;
}
.mat-mdc-form-field {
margin-top: 16px;
}

View File

@@ -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();
});
});

View File

@@ -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]);
}

View File

@@ -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;
}
}

View File

@@ -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