Compare commits
10 Commits
9efc26b904
...
d3c7ab3da3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3c7ab3da3 | ||
|
|
6947db1c4e | ||
|
|
a024cf5409 | ||
|
|
d26fd87367 | ||
|
|
4644407ca3 | ||
|
|
45dac8a554 | ||
|
|
42f082996b | ||
|
|
ef99c674e7 | ||
|
|
d6f909a81b | ||
|
|
be1bc2889f |
@@ -48,12 +48,12 @@
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "1mb",
|
||||
"maximumError": "2mb"
|
||||
"maximumError": "3mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
"maximumError": "2.5mb"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all",
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, HostListener, inject } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import {NavMenuComponent} from './components/nav-menu/nav-menu.component'
|
||||
import { TransferService } from './services/button/transfer.service';
|
||||
import { UpdateService } from './services/button/update.service';
|
||||
import { RefreshService } from './services/button/refresh.service';
|
||||
import { DeletionService } from './services/button/deletion.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -11,4 +15,38 @@ import {NavMenuComponent} from './components/nav-menu/nav-menu.component'
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'app';
|
||||
protected transferService: TransferService = inject(TransferService)
|
||||
protected updateService: UpdateService = inject(UpdateService)
|
||||
protected refreshService: RefreshService = inject(RefreshService)
|
||||
protected deletionService: DeletionService = inject(DeletionService)
|
||||
|
||||
@HostListener('window:keydown.control.s', ['$event'])
|
||||
protected handleCtrlS(event: KeyboardEvent) {
|
||||
event.preventDefault();
|
||||
this.updateService.executeAll();
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.control.r', ['$event'])
|
||||
protected handleCtrlR(event: KeyboardEvent) {
|
||||
event.preventDefault();
|
||||
this.refreshService.executeAll();
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.delete', ['$event'])
|
||||
protected handleDelete(event: KeyboardEvent) {
|
||||
event.preventDefault();
|
||||
this.deletionService.executeAll();
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.control.space', ['$event'])
|
||||
protected handleCtrlSpace(event: KeyboardEvent) {
|
||||
event.preventDefault();
|
||||
this.transferService.executeAll();
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.control.l', ['$event'])
|
||||
protected handleCtrlL(event: KeyboardEvent) {
|
||||
event.preventDefault();
|
||||
this.updateService.toggleEditability()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,11 +55,10 @@ export class GroupDirImportComponent implements OnInit {
|
||||
forkJoin(requests).pipe(
|
||||
// finalize is executed after all requests are completed or when an error occurs
|
||||
finalize(() => {
|
||||
// Show Swal notification after all requests are completed
|
||||
Swal.fire({
|
||||
icon: "success",
|
||||
title: "Completed",
|
||||
text: `${numAdded} new groups added`,
|
||||
title: "Abgeschlossen",
|
||||
text: `${numAdded} neue Gruppen hinzugefügt`,
|
||||
position: "center",
|
||||
showConfirmButton: false,
|
||||
timer: 3000
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<p>info works!</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { InfoComponent } from './info.component';
|
||||
|
||||
describe('InfoComponent', () => {
|
||||
let component: InfoComponent;
|
||||
let fixture: ComponentFixture<InfoComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [InfoComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(InfoComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-info',
|
||||
standalone: true,
|
||||
imports: [],
|
||||
templateUrl: './info.component.html',
|
||||
styleUrl: './info.component.scss'
|
||||
})
|
||||
export class InfoComponent {
|
||||
|
||||
}
|
||||
@@ -36,8 +36,8 @@ export class LoginComponent {
|
||||
this.waitRes = false;
|
||||
Swal.fire({
|
||||
icon: "error",
|
||||
title: "Oops...",
|
||||
text: err.error.messages.join("\n"),
|
||||
title: "Ungültiger Benutzername oder Passwort",
|
||||
text: "Bitte überprüfen Sie Ihre Anmeldedaten und versuchen Sie es erneut.",
|
||||
});
|
||||
},
|
||||
complete: () => this.waitRes = false
|
||||
|
||||
@@ -30,19 +30,24 @@
|
||||
<!-- Right menu -->
|
||||
<div class="navbar-collapse justify-content-end me-5">
|
||||
<a class="navbar-brand" [routerLink]="['/']">User Manager Portal</a>
|
||||
<mat-slide-toggle *ngIf="isLogedIn()" [(ngModel)]="updateService.isEditable" [ngStyle]="{ 'visibility': creationService.isVisible ? 'visible' : 'hidden' }"></mat-slide-toggle>
|
||||
<button *ngIf="isLogedIn()" class="btn" (click)="updateService.executeAll()" [ngStyle]="{ 'visibility': updateService.isVisible ? 'visible' : 'hidden' }">
|
||||
<button *ngIf="isLogedIn()" class="btn" (click)="this.updateService.toggleEditability()" [ngStyle]="{ 'visibility': updateService.isVisible ? 'visible' : 'hidden' }" matTooltip="strg + L" matTooltipPosition="below" [matTooltipClass]="tooltipClass" [matTooltipDisabled]="!updateService.isVisible">
|
||||
<mat-icon class="scale-pulse">{{ updateService.isEditable ? 'lock_open' : 'lock' }}</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="isLogedIn()" class="btn" (click)="updateService.executeAll()" [ngStyle]="{ 'visibility': updateService.isVisible ? 'visible' : 'hidden' }" matTooltip="strg + S" matTooltipPosition="below" [matTooltipClass]="tooltipClass" [matTooltipDisabled]="!updateService.isVisible">
|
||||
<mat-icon class="scale-pulse" [matBadge]="updateActCount === 0 ? '' : updateActCount">save</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="isLogedIn()" class="btn" (click)="creationService.openDialog()" [ngStyle]="{ 'visibility': creationService.isVisible ? 'visible' : 'hidden' }">
|
||||
<button *ngIf="isLogedIn()" class="btn" (click)="creationService.openDialog()" [ngStyle]="{ 'visibility': creationService.isVisible ? 'visible' : 'hidden' }" matTooltip="strg + C" matTooltipPosition="below" [matTooltipClass]="tooltipClass" [matTooltipDisabled]="!creationService.isVisible">
|
||||
<mat-icon class="scale-pulse">add_to_photos</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="isLogedIn()" class="btn" (click)="transferService.executeAll()" [ngStyle]="{ 'visibility': transferService.isVisible ? 'visible' : 'hidden' }">
|
||||
<button *ngIf="isLogedIn()" class="btn" (click)="transferService.executeAll()" [ngStyle]="{ 'visibility': transferService.isVisible ? 'visible' : 'hidden' }" matTooltip="strg + ␣" matTooltipPosition="below" [matTooltipClass]="tooltipClass" [matTooltipDisabled]="!transferService.isVisible">
|
||||
<mat-icon class="move-left-right">swap_horiz</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="isLogedIn()" class="btn" (click)="refreshService.executeAll()" [ngStyle]="{ 'visibility': refreshService.isVisible ? 'visible' : 'hidden' }">
|
||||
<button *ngIf="isLogedIn()" class="btn" (click)="refreshService.executeAll()" [ngStyle]="{ 'visibility': refreshService.isVisible ? 'visible' : 'hidden' }" matTooltip="strg + R" matTooltipPosition="below" [matTooltipClass]="tooltipClass" [matTooltipDisabled]="!refreshService.isVisible">
|
||||
<mat-icon class="turn-360">sync</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="isLogedIn()" class="btn" (click)="showInfo()">
|
||||
<mat-icon class="scale-pulse">contact_support</mat-icon>
|
||||
</button>
|
||||
<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>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, QueryList, ViewChildren } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { AuthenticationService, IsLogedIn } from '../../services/api/authentication.service';
|
||||
import { LoginComponent } from '../login/login.component';
|
||||
@@ -11,14 +11,15 @@ import { CreationService } from '../../services/button/creation.service';
|
||||
import { UpdateService, UpdateEvent } from '../../services/button/update.service';
|
||||
import { TransferService } from '../../services/button/transfer.service';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
import {
|
||||
MatSlideToggleModule,
|
||||
} from '@angular/material/slide-toggle';
|
||||
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';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [RouterModule, CommonModule, ColorModeBttnComponent, MatIconModule, MatBadgeModule, MatSlideToggleModule, FormsModule],
|
||||
imports: [RouterModule, CommonModule, ColorModeBttnComponent, MatIconModule, MatBadgeModule, MatSlideToggleModule, FormsModule, MatButtonModule, MatTooltipModule],
|
||||
selector: 'app-nav-menu',
|
||||
templateUrl: './nav-menu.component.html',
|
||||
styleUrls: ['./nav-menu.component.css']
|
||||
@@ -68,4 +69,29 @@ export class NavMenuComponent {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ViewChildren(MatTooltip) tooltips: QueryList<MatTooltip> | undefined;
|
||||
|
||||
private __tooltip_timeout_set = false;
|
||||
private __shift_tooltip: boolean = true;
|
||||
get tooltipClass() {
|
||||
this.__shift_tooltip = !this.__shift_tooltip;
|
||||
return this.__shift_tooltip ? "pt-3" : "";
|
||||
}
|
||||
|
||||
showInfo() {
|
||||
this.tooltips?.forEach(t => {
|
||||
t.show();
|
||||
});
|
||||
|
||||
if(!this.__tooltip_timeout_set){
|
||||
this.__tooltip_timeout_set = true;
|
||||
setTimeout(() => {
|
||||
this.__tooltip_timeout_set = false;
|
||||
this.tooltips?.forEach(t => {
|
||||
t.hide();
|
||||
});
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,8 +71,8 @@ export class UserGroupDirImportComponent implements OnInit, AfterViewInit {
|
||||
// Show Swal notification after all requests are completed
|
||||
Swal.fire({
|
||||
icon: "success",
|
||||
title: "Completed",
|
||||
text: `${numAdded} new users added`,
|
||||
title: "Abgeschlossen",
|
||||
text: `${numAdded} neue Benutzer hinzugefügt`,
|
||||
position: "center",
|
||||
showConfirmButton: false,
|
||||
timer: 3000
|
||||
|
||||
@@ -3,6 +3,7 @@ import { RefreshService } from '../../services/button/refresh.service';
|
||||
import { CreationService } from '../../services/button/creation.service';
|
||||
import { UpdateService } from '../../services/button/update.service';
|
||||
import { TransferService } from '../../services/button/transfer.service';
|
||||
import { DeletionService } from '../../services/button/deletion.service';
|
||||
import { ButtonVisibilityService } from '../../services/button/button-visibility.service';
|
||||
|
||||
@Component({
|
||||
@@ -18,6 +19,7 @@ export class BasePageComponent {
|
||||
protected creationService: CreationService = inject(CreationService)
|
||||
protected updateService: UpdateService = inject(UpdateService)
|
||||
protected transferService: TransferService = inject(TransferService)
|
||||
protected deletionService: DeletionService = inject(DeletionService)
|
||||
protected buttonVisibilityService: ButtonVisibilityService = inject(ButtonVisibilityService)
|
||||
|
||||
constructor() {
|
||||
@@ -28,30 +30,7 @@ export class BasePageComponent {
|
||||
}
|
||||
if(this.transferService.any)
|
||||
this.transferService.removeAll()
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.control.s', ['$event'])
|
||||
protected handleCtrlS(event: KeyboardEvent) {
|
||||
event.preventDefault();
|
||||
this.updateService.executeAll();
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.control.r', ['$event'])
|
||||
protected handleCtrlR(event: KeyboardEvent) {
|
||||
event.preventDefault();
|
||||
this.refreshService.executeAll();
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.delete', ['$event'])
|
||||
protected handleDelete(event: KeyboardEvent) {
|
||||
this.handleDeleteRequest();
|
||||
}
|
||||
|
||||
handleDeleteRequest() { }
|
||||
|
||||
@HostListener('window:keydown.control.t', ['$event'])
|
||||
protected handleCtrlT(event: KeyboardEvent) {
|
||||
event.preventDefault();
|
||||
this.transferService.executeAll();
|
||||
if(this.deletionService.any)
|
||||
this.deletionService.removeAll()
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,8 @@ export class GroupComponent extends BasePageComponent implements AfterViewInit {
|
||||
this.userTable.fetchDataByGroupId(this.sGroupId);
|
||||
});
|
||||
this.creationService.component = GroupFormComponent
|
||||
|
||||
this.deletionService.add(() => this.handleDeleteRequest());
|
||||
}
|
||||
|
||||
@ViewChild("groupTable") groupTable!: GroupTableComponent;
|
||||
@@ -56,7 +58,7 @@ export class GroupComponent extends BasePageComponent implements AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
override handleDeleteRequest() {
|
||||
handleDeleteRequest() {
|
||||
const sRows = this.groupTable.selectedRows;
|
||||
if (sRows.length > 0)
|
||||
Swal.fire({
|
||||
@@ -81,7 +83,7 @@ export class GroupComponent extends BasePageComponent implements AfterViewInit {
|
||||
},
|
||||
error: err => Swal.fire({
|
||||
title: "Fehler",
|
||||
text: `${err.message}`,
|
||||
text: `Dieser Vorgang ist nicht möglich.`,
|
||||
icon: "error"
|
||||
})
|
||||
});
|
||||
|
||||
@@ -37,7 +37,7 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.buttonVisibilityService.setVisibleOnly(this.refreshService)
|
||||
this.buttonVisibilityService.setVisibleOnly(this.refreshService, this.transferService)
|
||||
this.refreshService.removeAll();
|
||||
this.refreshService.add(() => {
|
||||
this.users.fetchData();
|
||||
@@ -45,6 +45,11 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
|
||||
this.repGroups.fetchData();
|
||||
this.rightGroups.fetchData();
|
||||
})
|
||||
this.transferService.add(() => {
|
||||
this.repUsers.safelyUnselectAll();
|
||||
this.repGroups.safelyUnselectAll();
|
||||
this.userReps.safelyUnselectAll();
|
||||
})
|
||||
}
|
||||
|
||||
@ViewChild("users") users!: UserTableComponent;
|
||||
|
||||
@@ -47,6 +47,8 @@ export class UserComponent extends BasePageComponent implements AfterViewInit {
|
||||
});
|
||||
|
||||
this.creationService.component = UserFormComponent;
|
||||
|
||||
this.deletionService.add(() => this.handleDeleteRequest());
|
||||
}
|
||||
|
||||
@ViewChild("userTable") userTable!: UserTableComponent
|
||||
@@ -64,7 +66,7 @@ export class UserComponent extends BasePageComponent implements AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
override handleDeleteRequest() {
|
||||
handleDeleteRequest() {
|
||||
const sRows = this.userTable.selectedRows;
|
||||
if (sRows.length > 0)
|
||||
Swal.fire({
|
||||
@@ -88,7 +90,7 @@ export class UserComponent extends BasePageComponent implements AfterViewInit {
|
||||
},
|
||||
error: err => Swal.fire({
|
||||
title: "Fehler",
|
||||
text: `${err.message}`,
|
||||
text: `Dieser Vorgang ist nicht möglich.`,
|
||||
icon: "error"
|
||||
})
|
||||
});
|
||||
|
||||
@@ -75,7 +75,7 @@ export class AuthenticationService {
|
||||
Swal.fire({
|
||||
icon: "error",
|
||||
title: "Oops...",
|
||||
text: "The backend application is not responding.",
|
||||
text: "Der Server antwortet nicht.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DeletionService } from './deletion.service';
|
||||
|
||||
describe('DeletionService', () => {
|
||||
let service: DeletionService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(DeletionService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BaseButtonService } from './base-button.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DeletionService extends BaseButtonService {
|
||||
|
||||
private actions: Array<() => void> = [];
|
||||
|
||||
public get count(): number {
|
||||
return this.actions.length;
|
||||
}
|
||||
|
||||
public get any(): boolean {
|
||||
return this.count > 0;
|
||||
}
|
||||
|
||||
add(action: () => void): void {
|
||||
this.actions.push(action);
|
||||
}
|
||||
|
||||
removeAll(): void {
|
||||
this.actions = [];
|
||||
}
|
||||
|
||||
executeAll(): void {
|
||||
this.actions.forEach(action => action());
|
||||
}
|
||||
}
|
||||
@@ -84,6 +84,10 @@ export class UpdateService extends BaseButtonService {
|
||||
localStorage.setItem('editable', value ? "T" : "F")
|
||||
this._isEditable = value;
|
||||
}
|
||||
|
||||
toggleEditability() {
|
||||
this.isEditable = !this.isEditable;
|
||||
}
|
||||
}
|
||||
|
||||
export enum UpdateEvent {
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 1.6 KiB |
Reference in New Issue
Block a user