Compare commits

...

22 Commits

Author SHA1 Message Date
Developer 02
9efc26b904 fix: Ctrl+R Tastenkombination funktioniert jetzt korrekt mit dem Refresh-Service 2024-08-08 13:19:58 +02:00
Developer 02
e2d479d9a8 feat: ButtonVisibilityService in der Startseite implementiert 2024-08-08 13:17:37 +02:00
Developer 02
c8bcc2820b feat: ButtonVisibilityService in mehreren Schaltflächen-Komponenten implementiert
- `ButtonVisibilityService` zur Verwaltung der Sichtbarkeit in verschiedenen Schaltflächen-Komponenten integriert.
- Schaltflächen-Komponenten aktualisiert, um den Dienst für dynamische Sichtbarkeitskontrolle zu verwenden.
- Tests refaktoriert, um sicherzustellen, dass der Dienst korrekt in den Komponenten angewendet wird.
2024-08-08 13:10:31 +02:00
Developer 02
06197876e7 feat: Added conditional visibility for buttons based on service visibility state using ngStyle. 2024-08-08 11:22:38 +02:00
Developer 02
0c54a21df5 chore: Das Log-Verzeichnis wurde auf "E:\\LogFiles\\Digital Data\\WebUserManager" festgelegt, um den Speicherort der Protokolle zu standardisieren. 2024-08-08 11:10:41 +02:00
Developer 02
384c843f82 refactor; Typisierung der isVisible Eigenschaft als boolean in BaseButtonService 2024-08-08 10:58:40 +02:00
Developer 02
4a8b65a8d6 Refaktorierung der Services in separate Dateien und Aktualisierung der Referenzen
- Aufteilung des `service` in `service/button` und `service/api` Dateien
- Aktualisierung aller Referenzen auf die neue Service-Dateistruktur
- Erstellung einer `BaseButtonService` Klasse und Verschiebung der gemeinsamen Button-Funktionalität
- Sicherstellung, dass Button-Services `BaseButtonService` erweitern, um gemeinsame Eigenschaften zu erben
2024-08-08 10:52:41 +02:00
Developer 02
fbfe1f774c Refaktorierung der Methoden zur Benutzerzuweisung und Verbesserung der Code-Lesbarkeit
- Umbenennung der Methoden `dropToAssigned` und `dropToUnassigned` in `assign` und `unassign` zur besseren Verständlichkeit
- Vereinfachung der Methoden `assign` und `unassign` durch Verwendung von `map` zur Erstellung von Benutzerarrays
2024-08-08 10:20:00 +02:00
Developer 02
255c6cb138 refactor: Moved click event handlers from mat-icon to button elements 2024-08-08 10:07:29 +02:00
Developer 02
321a4c83bb Refaktorierung der Benutzerzuweisungskomponente: Vereinfachung der Drag-and-Drop-Logik
- Entfernte Drag-and-Drop-Event-Handler aus der HTML-Vorlage
- Vereinfachte Drag-and-Drop-Logik in der Komponentenklasse
- Hinzufügen von transferService zur Verwaltung von Benutzerzuweisungen und -zuweisungen
- Gewährleistung einer nahtlosen Aktualisierung der Benutzertabellen nach der Datenübertragung
- Verbesserung der Code-Lesbarkeit und Wartbarkeit
- Behebung von Problemen mit der Synchronisation der Zeilenauswahl zwischen zugewiesenen und nicht zugewiesenen Benutzertabellen
2024-08-08 09:59:55 +02:00
Developer 02
7eabbd4b99 feat: Ein Tastenkürzel (Strg+T) implementiert, um den Transferdienst auszulösen. 2024-08-07 17:17:36 +02:00
Developer 02
454570b729 feat: Transferdienst hinzugefügt und in BasePage integriert
- Einen neuen Transferdienst erstellt und in die BasePage-Komponente injiziert.
- Einen neuen Button zur NavBar für die Transferfunktionalität hinzugefügt.
- CSS-Animationen für den Button angewendet, um die Benutzerinteraktion zu verbessern.
2024-08-07 16:56:51 +02:00
Developer 02
ced8d30952 Fehlerbehebung: Exklusive Zeilenauswahl in den Benutzerzuweisungstabellen sicherstellen
- Logik hinzugefügt, um automatisch Zeilen in der Tabelle für nicht zugewiesene Benutzer abzuwählen, wenn Zeilen in der Tabelle für zugewiesene Benutzer ausgewählt werden.
- Logik hinzugefügt, um automatisch Zeilen in der Tabelle für zugewiesene Benutzer abzuwählen, wenn Zeilen in der Tabelle für nicht zugewiesene Benutzer ausgewählt werden.
2024-08-07 15:58:43 +02:00
Developer 02
6cf3ee5565 fix: Korrektur der Großschreibung im Label für nicht zugeordnete Benutzer 2024-08-07 15:06:50 +02:00
Developer 02
a19134f487 refactor: Unbenutzten RefreshService-Import entfernen und Fehlermeldungen verbessern
- Unbenutzten Import von RefreshService aus UserRepresentationComponent entfernt.
- Konsistenz und Klarheit der Fehlermeldungen in Swal.fire-Aufrufen verbessert.
- Deutsche Übersetzungen der Fehlermeldungen korrigiert, um Genauigkeit zu gewährleisten.
2024-08-07 15:00:41 +02:00
Developer 02
5645bf7244 refactor: Tab-Bezeichnungen und Spaltenzuweisungen aktualisieren
- Tab-Bezeichnungen und Spaltenzuweisungen zur besseren Klarheit geändert:
- "Rich. Gruppen" in "Rechte Gruppe" umbenannt
- Spaltenzuweisungen für `app-group-table` angepasst
- UI-Bezeichnungen und Komponentenbindungen aktualisiert
2024-08-07 14:16:46 +02:00
Developer 02
d3b804f965 refactor: Methode BasePageComponent in handleDeleteRequest umbenannt 2024-08-07 13:58:19 +02:00
Developer 02
9cef878380 refactor: Gemeinsame Löschbehandlung in die Basisklasse verschieben und in Unterklassen überschreiben
- Methoden `handleCtrlS`, `handleDelete` und `deleteItem` in die `BasePageComponent` verschoben, um gemeinsame Funktionalität zu nutzen.
- Methode `deleteItem` in `GroupComponent` und `UserComponent` überschrieben, um spezifische Löschlogik und Bestätigungsdialoge bereitzustellen.
- Methode `deleteItem` aktualisiert, um SweetAlert2 für Bestätigung sowie Erfolg-/Fehlermeldungen zu integrieren.
- Sicherstellt, dass `BasePageComponent` gemeinsame Shortcut-Aktionen behandelt, während Unterklassen das Löschverhalten anpassen.
2024-08-07 13:53:57 +02:00
Developer 02
0b31b78544 feat: add delete functionality with confirmation dialog and Ctrl+S shortcut
- Added `@HostListener` for `window:keydown.control.s` to trigger the update service using the Ctrl+S shortcut.
- Added `@HostListener` for `window:keydown.delete` to handle item deletion via keyboard.
- Implemented `deleteItem` method with SweetAlert2 confirmation dialog before deleting selected items.
- Integrated `forkJoin` for simultaneous handling of multiple delete requests and appropriate success/error notifications.
2024-08-07 13:20:27 +02:00
Developer 02
7bbd9aacd6 feat: Ctrl+S-Shortcut zum Ausführen des Update-Dienstes hinzufügen 2024-08-07 12:52:01 +02:00
Developer 02
7de506d390 feat: Löschfunktionalität mit Bestätigungsdialog hinzufügen und Tastatur-Delete-Ereignis verarbeiten
- `@HostListener` für das `window:keydown.delete`-Ereignis hinzugefügt, um die Löschung von Elementen über die Tastatur zu verarbeiten.
- `deleteItem`-Methode implementiert, um den Benutzer vor dem Löschen ausgewählter Elemente mit SweetAlert2 zur Bestätigung aufzufordern.
- `forkJoin` integriert, um mehrere Löschanfragen gleichzeitig zu bearbeiten und Erfolg- oder Fehlermeldungen je nach Ergebnis anzuzeigen.
2024-08-07 12:51:17 +02:00
Developer 02
754c9bd5db feat: Aktualisierbarkeitsschalter vor dem Einloggen verbergen 2024-08-07 09:24:23 +02:00
58 changed files with 425 additions and 176 deletions

View File

@@ -5,7 +5,7 @@ import { provideClientHydration } from '@angular/platform-browser';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { provideHttpClient, withFetch } from '@angular/common/http';
import { APP_BASE_HREF } from '@angular/common';
import { UrlService } from './services/url.service';
import { UrlService } from './services/api/url.service';
import { API_URL } from './tokens';
export const appConfig: ApplicationConfig = {

View File

@@ -1,7 +1,6 @@
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { AuthenticationService } from '../services/authentication.service'; // Adjust the path as necessary
import { AuthenticationService } from '../services/api/authentication.service'; // Adjust the path as necessary
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { LoginComponent } from '../components/login/login.component';

View File

@@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { ColorModeService, GetLocalTheme, Theme } from '../../../services/color-mode.service';
import { ColorModeService, GetLocalTheme, Theme } from '../../../services/button/color-mode.service';
import { CommonModule } from '@angular/common'
@Component({

View File

@@ -10,10 +10,10 @@ import { MatCheckboxModule } from '@angular/material/checkbox';
import { CommonModule } from '@angular/common';
import { MatTabsModule } from '@angular/material/tabs';
import { UserGroupDirImportComponent } from "../../user-group-dir-import/user-group-dir-import.component";
import { UserService } from '../../../services/user.service';
import { RefreshService } from '../../../services/refresh.service';
import { UserService } from '../../../services/api/user.service';
import { RefreshService } from '../../../services/button/refresh.service';
import { GroupDirImportComponent } from "../../group-dir-import/group-dir-import.component";
import { GroupService } from '../../../services/group.service';
import { GroupService } from '../../../services/api/group.service';
import Swal from 'sweetalert2';
@Component({

View File

@@ -9,8 +9,8 @@ import { MatButtonModule } from '@angular/material/button';
import { CommonModule } from '@angular/common';
import { MatTabsModule } from '@angular/material/tabs';
import { UserGroupDirImportComponent } from "../../user-group-dir-import/user-group-dir-import.component";
import { UserService } from '../../../services/user.service';
import { RefreshService } from '../../../services/refresh.service';
import { UserService } from '../../../services/api/user.service';
import { RefreshService } from '../../../services/button/refresh.service';
import Swal from 'sweetalert2';
@Component({

View File

@@ -1,7 +1,7 @@
import { AfterViewInit, Component, Inject, OnInit, ViewChild } from '@angular/core';
import { Component, Inject, OnInit, ViewChild } from '@angular/core';
import { GuiRowSelection, GuiRowSelectionMode, GuiRowSelectionType } from '@generic-ui/ngx-grid';
import Swal from 'sweetalert2';
import { GroupService } from '../../services/group.service';
import { GroupService } from '../../services/api/group.service';
import { Observable, forkJoin, of } from 'rxjs';
import { catchError, finalize } from 'rxjs/operators';
import { DirGroupTableComponent } from '../tables/dir-group-table/dir-group-table.component';

View File

@@ -1,5 +1,5 @@
import { Component, Inject, Input } from '@angular/core';
import { AuthenticationService } from '../../services/authentication.service';
import { AuthenticationService } from '../../services/api/authentication.service';
import Swal from 'sweetalert2';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { CommonModule } from '@angular/common';

View File

@@ -107,11 +107,6 @@ html {
}
}
.scale-pulse {
display: inline-block;
transition: transform 1s ease;
}
.scale-pulse:hover {
animation: pulse 1s ease forwards;
}
@@ -126,4 +121,23 @@ html {
100% {
transform: scale(1);
}
}
.move-left-right:hover {
animation: move 0.8s ease forwards;
}
@keyframes move {
0% {
transform: translateX(0);
}
25% {
transform: translateX(-10px);
}
75% {
transform: translateX(10px);
}
100% {
transform: translateX(0);
}
}

View File

@@ -30,14 +30,17 @@
<!-- Right menu -->
<div class="navbar-collapse justify-content-end me-5">
<a class="navbar-brand" [routerLink]="['/']">User Manager Portal</a>
<mat-slide-toggle [(ngModel)]="updateService.isEditable"></mat-slide-toggle>
<button *ngIf="isLogedIn()" class="btn">
<mat-icon class="scale-pulse" [matBadge]="updateActCount === 0 ? '' : updateActCount" (click)="updateService.executeAll()">save</mat-icon>
<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' }">
<mat-icon class="scale-pulse" [matBadge]="updateActCount === 0 ? '' : updateActCount">save</mat-icon>
</button>
<button *ngIf="isLogedIn()" class="btn">
<mat-icon class="scale-pulse" (click)="creationService.openDialog()">add_to_photos</mat-icon>
<button *ngIf="isLogedIn()" class="btn" (click)="creationService.openDialog()" [ngStyle]="{ 'visibility': creationService.isVisible ? 'visible' : 'hidden' }">
<mat-icon class="scale-pulse">add_to_photos</mat-icon>
</button>
<button *ngIf="isLogedIn()" class="btn" (click)="refreshService.executeAll()">
<button *ngIf="isLogedIn()" class="btn" (click)="transferService.executeAll()" [ngStyle]="{ 'visibility': transferService.isVisible ? 'visible' : 'hidden' }">
<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' }">
<mat-icon class="turn-360">sync</mat-icon>
</button>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse"

View File

@@ -1,14 +1,15 @@
import { Component } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AuthenticationService, IsLogedIn } from '../../services/authentication.service';
import { AuthenticationService, IsLogedIn } from '../../services/api/authentication.service';
import { LoginComponent } from '../login/login.component';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { ColorModeBttnComponent } from '../common/color-mode-bttn/color-mode-bttn.component';
import { MatIconModule } from '@angular/material/icon';
import { RefreshService } from '../../services/refresh.service';
import { CreationService } from '../../services/creation.service';
import { UpdateService, UpdateEvent } from '../../services/update.service';
import { RefreshService } from '../../services/button/refresh.service';
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,
@@ -32,7 +33,7 @@ export class NavMenuComponent {
isChecked = true;
constructor(private dialog: MatDialog, private authService: AuthenticationService, public refreshService: RefreshService, public creationService: CreationService, public updateService: UpdateService) {
constructor(private dialog: MatDialog, private authService: AuthenticationService, public refreshService: RefreshService, public creationService: CreationService, public updateService: UpdateService, public transferService: TransferService) {
this.authService.isAuthenticated().then().catch()
this.updateActCount = this.updateService.totalCount;
this.updateService.addChangeListener(UpdateEvent.CountChange, () => {

View File

@@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BaseTableComponent } from './base-table.component';
import { ApiService } from '../../../services/user-management.api.service';
import { ApiService } from '../../../services/api/user-management.api.service';
import { NO_ERRORS_SCHEMA } from '@angular/core';
describe('BaseTableComponent', () => {

View File

@@ -1,8 +1,8 @@
import { Component, Inject, Input, OnDestroy, OnInit, ViewChild, input } from '@angular/core';
import { ApiService } from '../../../services/user-management.api.service';
import { ApiService } from '../../../services/api/user-management.api.service';
import { GuiGridModule, GuiColumn, GuiColumnMenu, GuiSorting, GuiRowDetail, GuiPaging, GuiPagingDisplay, GuiSearching, GuiCellEdit, GuiInfoPanel, GuiTitlePanel, GuiRowSelection, GuiSelectedRow, GuiGridComponent, GuiGridApi, GuiTheme } from '@generic-ui/ngx-grid';
import { Subscription } from 'rxjs/internal/Subscription';
import { ColorModeService, Theme } from '../../../services/color-mode.service';
import { ColorModeService, Theme } from '../../../services/button/color-mode.service';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

View File

@@ -1,13 +1,13 @@
import { Component, Inject } from '@angular/core';
import { BaseTableComponent } from '../base-table/base-table.component';
import { DirGroupService } from '../../../services/dir-group.service';
import { DirGroupService } from '../../../services/api/dir-group.service';
import { DirGroup } from '../../../models/user-management.api.models';
import { GuiGridModule } from '@generic-ui/ngx-grid';
import { ColorModeService } from '../../../services/color-mode.service';
import { ColorModeService } from '../../../services/button/color-mode.service';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { env } from '../../../../environments/environment';
import { GroupService } from '../../../services/group.service';
import { GroupService } from '../../../services/api/group.service';
import { firstValueFrom } from 'rxjs';
@Component({

View File

@@ -1,13 +1,13 @@
import { Component, Inject } from '@angular/core';
import { DirUser } from '../../../models/user-management.api.models';
import { DirUserService } from '../../../services/dir-user.service';
import { DirUserService } from '../../../services/api/dir-user.service';
import { BaseTableComponent } from '../base-table/base-table.component';
import { GuiGridModule, GuiColumn } from '@generic-ui/ngx-grid';
import { ColorModeService } from '../../../services/color-mode.service';
import { ColorModeService } from '../../../services/button/color-mode.service';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { env } from '../../../../environments/environment';
import { UserService } from '../../../services/user.service';
import { UserService } from '../../../services/api/user.service';
import { firstValueFrom } from 'rxjs/internal/firstValueFrom';
@Component({

View File

@@ -1,13 +1,13 @@
import { Component, Inject } from '@angular/core';
import { GroupService } from '../../../services/group.service';
import { GroupService } from '../../../services/api/group.service';
import { Group } from '../../../models/user-management.api.models';
import { GuiGridModule, GuiColumn } from '@generic-ui/ngx-grid';
import { BaseTableComponent } from '../base-table/base-table.component';
import { ColorModeService } from '../../../services/color-mode.service';
import { ColorModeService } from '../../../services/button/color-mode.service';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { env } from '../../../../environments/environment';
import { GroupOfUserService } from '../../../services/group-of-user.service';
import { GroupOfUserService } from '../../../services/api/group-of-user.service';
@Component({
standalone: true,

View File

@@ -2,12 +2,12 @@ import { Component } from '@angular/core';
import { Module } from '../../../models/user-management.api.models';
import { GuiGridModule } from '@generic-ui/ngx-grid';
import { BaseTableComponent } from '../base-table/base-table.component';
import { ModuleService } from '../../../services/module.service'
import { ColorModeService } from '../../../services/color-mode.service';
import { ModuleService } from '../../../services/api/module.service'
import { ColorModeService } from '../../../services/button/color-mode.service';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { env } from '../../../../environments/environment';
import { ModuleOfUserService } from '../../../services/module-of-user.service';
import { ModuleOfUserService } from '../../../services/api/module-of-user.service';
@Component({
standalone: true,

View File

@@ -1,9 +1,9 @@
import { Component, Inject } from '@angular/core';
import { UserRep } from '../../../models/user-management.api.models';
import { UserRepService } from '../../../services/user-representation.service';
import { UserRepService } from '../../../services/api/user-representation.service';
import { BaseTableComponent } from '../base-table/base-table.component';
import { GuiGridModule, GuiColumn } from '@generic-ui/ngx-grid';
import { ColorModeService } from '../../../services/color-mode.service';
import { ColorModeService } from '../../../services/button/color-mode.service';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { env } from '../../../../environments/environment';

View File

@@ -1,11 +1,11 @@
import { Component, Inject, Input } from '@angular/core';
import { UserService } from '../../../services/user.service';
import { ModuleOfUserService } from '../../../services/module-of-user.service';
import { GroupOfUserService } from '../../../services/group-of-user.service';
import { Component } from '@angular/core';
import { UserService } from '../../../services/api/user.service';
import { ModuleOfUserService } from '../../../services/api/module-of-user.service';
import { GroupOfUserService } from '../../../services/api/group-of-user.service';
import { User } from '../../../models/user-management.api.models';
import { GuiGridModule, GuiColumn } from '@generic-ui/ngx-grid';
import { GuiGridModule } from '@generic-ui/ngx-grid';
import { BaseTableComponent } from '../base-table/base-table.component';
import { ColorModeService } from '../../../services/color-mode.service'
import { ColorModeService } from '../../../services/button/color-mode.service'
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { env } from '../../../../environments/environment';

View File

@@ -1,14 +1,14 @@
import { AfterViewInit, Component, Inject, OnInit, ViewChild } from '@angular/core';
import { GuiRowSelection, GuiRowSelectionMode, GuiRowSelectionType, GuiSelectedRow } from '@generic-ui/ngx-grid';
import Swal from 'sweetalert2';
import { GroupService } from '../../services/group.service';
import { GroupService } from '../../services/api/group.service';
import { Observable, forkJoin, of } from 'rxjs';
import { catchError, finalize } from 'rxjs/operators';
import { DirGroupTableComponent } from '../tables/dir-group-table/dir-group-table.component';
import { DirUserTableComponent } from '../tables/dir-user-table/dir-user-table.component';
import { UserService } from '../../services/user.service';
import { UserService } from '../../services/api/user.service';
import { User } from '../../models/user-management.api.models'
import { RefreshService } from '../../services/refresh.service';
import { RefreshService } from '../../services/button/refresh.service';
@Component({
standalone: true,

View File

@@ -1,7 +1,9 @@
import { Component, inject } from '@angular/core';
import { RefreshService } from '../../services/refresh.service';
import { CreationService } from '../../services/creation.service';
import { UpdateService } from '../../services/update.service';
import { Component, HostListener, inject } from '@angular/core';
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 { ButtonVisibilityService } from '../../services/button/button-visibility.service';
@Component({
selector: 'app-base-page',
@@ -15,6 +17,8 @@ export class BasePageComponent {
protected refreshService: RefreshService = inject(RefreshService)
protected creationService: CreationService = inject(CreationService)
protected updateService: UpdateService = inject(UpdateService)
protected transferService: TransferService = inject(TransferService)
protected buttonVisibilityService: ButtonVisibilityService = inject(ButtonVisibilityService)
constructor() {
this.refreshService.removeAll()
@@ -22,5 +26,32 @@ export class BasePageComponent {
if (this.updateService.any) {
this.updateService.executeAll().then()
}
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();
}
}

View File

@@ -6,7 +6,8 @@ import { GuiCellEdit, GuiSelectedRow } from '@generic-ui/ngx-grid';
import { GroupFormComponent } from '../../components/forms/group-form/group-form.component';
import { BasePageComponent } from '../base-page/base-page.component';
import { Group } from '../../models/user-management.api.models';
import { firstValueFrom } from 'rxjs';
import { firstValueFrom, forkJoin } from 'rxjs';
import Swal from 'sweetalert2';
@Component({
standalone: true,
@@ -34,6 +35,7 @@ export class GroupComponent extends BasePageComponent implements AfterViewInit {
private sGroupId = null;
ngAfterViewInit(): void {
this.buttonVisibilityService.setVisibleOnly(this.refreshService, this.creationService, this.updateService)
this.refreshService.removeAll()
this.refreshService.add(() => {
this.groupTable.fetchData();
@@ -53,4 +55,37 @@ export class GroupComponent extends BasePageComponent implements AfterViewInit {
this.userTable.fetchDataByGroupId(this.sGroupId);
}
}
override handleDeleteRequest() {
const sRows = this.groupTable.selectedRows;
if (sRows.length > 0)
Swal.fire({
title: "Löschen besttigen",
html: `<p class="text-start">Dieser Vorgang ist unwiderruflich. Möchten Sie fortfahren?<br><br>Anzahl der zu löschenden Einträge: ${sRows.length}</p>`,
showDenyButton: true,
confirmButtonText: "Ja",
denyButtonText: `Nein`
}).then((result) => {
if (result.isConfirmed) {
const deleteRequests = sRows.map(sRow => this.groupTable.service.delete(sRow.source.id!));
forkJoin(deleteRequests).subscribe({
next: () => {
this.updateService.executeAll().then(() => {
this.refreshService.executeAll();
})
Swal.fire({
text: `${sRows.length} Einträge wurden erfolgreich gelöscht.`,
icon: "success"
})
},
error: err => Swal.fire({
title: "Fehler",
text: `${err.message}`,
icon: "error"
})
});
}
});
}
}

View File

@@ -1,4 +1,4 @@
import { Component } from '@angular/core';
import { AfterViewInit, Component } from '@angular/core';
import { BasePageComponent } from '../base-page/base-page.component';
@Component({
@@ -6,5 +6,8 @@ import { BasePageComponent } from '../base-page/base-page.component';
selector: 'app-home',
templateUrl: './home.component.html'
})
export class HomeComponent extends BasePageComponent {
export class HomeComponent extends BasePageComponent implements AfterViewInit {
ngAfterViewInit(): void {
this.buttonVisibilityService.setVisibleOnly()
}
}

View File

@@ -1,6 +1,5 @@
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { ModuleTableComponent } from '../../components/tables/module-table/module-table.component';
import { RefreshService } from '../../services/refresh.service';
import { MatTabsModule } from '@angular/material/tabs';
import { UserTableComponent } from '../../components/tables/user-table/user-table.component';
import { GuiSelectedRow } from '@generic-ui/ngx-grid';
@@ -19,6 +18,7 @@ export class ModuleComponent extends BasePageComponent implements AfterViewInit
initWithoutData = () => { }
ngAfterViewInit(): void {
this.buttonVisibilityService.setVisibleOnly()
this.refreshService.removeAll()
this.refreshService.add(() => {
this.moduleTable.fetchData();

View File

@@ -15,11 +15,9 @@
<!-- (1, 2): unassigned users -->
<div class="col-5 mt-0 pt-0">
<mat-tab-group>
<mat-tab label="Nicht zugeordnete benutzer">
<mat-tab label="Nicht zugeordnete Benutzer">
<app-user-table #unassignedUsers class="body-content" [onSelectedRows]="unassignedUsersOnSelectedRows"
[rowSelection]="userRowSelection" (drop)="dropToUnassigned($event)"
(dragover)="allowDropOnUnassigned($event)" (dragstart)="dragUnassigned($event)"
[draggable]="true" [initData]="initWithoutData"></app-user-table>
[rowSelection]="userRowSelection" [initData]="initWithoutData"></app-user-table>
<!-- <mt-table></mt-table> -->
</mat-tab>
</mat-tab-group>
@@ -29,11 +27,9 @@
<mat-tab-group>
<mat-tab label="{{userInLabel}}">
<app-user-table #assignedUsers class="body-content" [onSelectedRows]="assignedUsersOnSelectedRows"
[rowSelection]="userRowSelection" (drop)="dropToAssigned($event)" (dragover)="allowDropOnAssigned($event)"
(dragstart)="dragAssigned($event)" [draggable]="true" [initData]="initWithoutData"></app-user-table>
[rowSelection]="userRowSelection" [initData]="initWithoutData"></app-user-table>
</mat-tab>
</mat-tab-group>
</div>
</div>
</div>

View File

@@ -50,85 +50,63 @@ export class UserAssignmentComponent extends BasePageComponent implements OnInit
ngOnInit(): void { }
ngAfterViewInit(): void {
this.buttonVisibilityService.setVisibleOnly(this.refreshService, this.transferService)
this.refreshService.removeAll()
this.refreshService.add(() => {
this.modules.fetchData();
this.groups.fetchData();
if(this.anySelected)
if (this.anySelected)
this.updateUserTables();
});
}
createAssignDragMethod(target: string): (event: DragEvent) => void {
return (event: DragEvent) => {
this.dragging = target;
event.dataTransfer?.setData("text", target);
}
this.transferService.add(() => {
if (this.isAssignment) {
this.assign();
this.refreshService.executeAll();
}
else if (this.isUnassignment) {
this.unassign();
this.refreshService.executeAll();
}
});
}
target: Target = Target.Module;
targetId = 0;
dragging: string = "";
assign() {
var users: User[] = this.unassignedUsers.selectedRows.map(row => row.source)
dragAssigned = this.createAssignDragMethod("assigned")
dragUnassigned = this.createAssignDragMethod("unassigned")
console.log(users)
allowDropOnAssigned(event: DragEvent) {
if (this.dragging == "unassigned")
event.preventDefault();
}
allowDropOnUnassigned(event: DragEvent) {
if (this.dragging == "assigned")
event.preventDefault();
}
dropToAssigned(event: DragEvent) {
if (event.dataTransfer?.getData("text") == "unassigned") {
var rows = this.unassignedUsers.selectedRows;
var users: User[] = new Array<User>();
if (!rows)
return
for (var row of rows)
users.push(row.source);
this.unselectUserTables()
switch (this.target) {
case Target.Module:
this.unassignedUsers.createModuleOfUsers(this.targetId, users)
.then(() => this.updateUserTables())
break;
case Target.Group:
this.unassignedUsers.createGroupOfUsers(this.targetId, users)
.then(() => this.updateUserTables())
break;
}
this.unselectUserTables()
switch (this.target) {
case Target.Module:
this.unassignedUsers.createModuleOfUsers(this.targetId, users)
.then(() => this.updateUserTables())
break;
case Target.Group:
this.unassignedUsers.createGroupOfUsers(this.targetId, users)
.then(() => this.updateUserTables())
break;
}
}
dropToUnassigned(event: DragEvent) {
if (event.dataTransfer?.getData("text") == "assigned") {
var rows = this.assignedUsers.selectedRows;
var users: User[] = new Array<User>();
if (!rows)
return
for (var row of rows)
users.push(row.source);
this.unselectUserTables()
switch (this.target) {
case Target.Module:
this.unassignedUsers.deleteModuleOfUsers(this.targetId, users)
.then(() => this.updateUserTables())
break;
case Target.Group:
this.unassignedUsers.deleteGroupOfUsers(this.targetId, users)
.then(() => this.updateUserTables())
break;
}
unassign() {
var users: User[] = this.assignedUsers.selectedRows.map(row => row.source)
this.unselectUserTables()
switch (this.target) {
case Target.Module:
this.unassignedUsers.deleteModuleOfUsers(this.targetId, users)
.then(() => this.updateUserTables())
break;
case Target.Group:
this.unassignedUsers.deleteGroupOfUsers(this.targetId, users)
.then(() => this.updateUserTables())
break;
}
}
@@ -172,10 +150,32 @@ export class UserAssignmentComponent extends BasePageComponent implements OnInit
}
}
//unselection case
private sUnassgnCount: number = 0;
private sAssgnCount: number = 0;
private get isAssignment(): boolean {
return this.sUnassgnCount > 0;
}
private get isUnassignment(): boolean {
return this.sAssgnCount > 0;
}
unassignedUsersOnSelectedRows = (rows: GuiSelectedRow[]) => {
if (rows.length > this.sUnassgnCount && this.unassignedUsers.selectedRows.length > 0) {
this.assignedUsers.safelyUnselectAll()
}
this.sUnassgnCount = rows.length;
}
assignedUsersOnSelectedRows = (rows: GuiSelectedRow[]) => {
if (rows.length > this.sAssgnCount && this.assignedUsers.selectedRows.length > 0) {
this.unassignedUsers.safelyUnselectAll()
}
this.sAssgnCount = rows.length;
}
}

View File

@@ -9,15 +9,7 @@
</mat-tab>
</mat-tab-group>
</div>
<!-- (1, 2): right groups -->
<div class="col-2">
<mat-tab-group>
<mat-tab label="Rich. Gruppen">
<app-group-table #rightGroups] [columns]="groupRightColumns" [onSelectedRows]="rightGroupOnSelectedRows"></app-group-table>
</mat-tab>
</mat-tab-group>
</div>
<!-- (1, 3): representations -->
<!-- (1, 2): representations -->
<div class="col-2">
<mat-tab-group>
<mat-tab label="Rep. Benutzer">
@@ -28,6 +20,14 @@
</mat-tab>
</mat-tab-group>
</div>
<!-- (1, 3): right groups -->
<div class="col-2">
<mat-tab-group>
<mat-tab label="Rechte Gruppe">
<app-group-table #rightGroups] [columns]="groupRightColumns" [onSelectedRows]="rightGroupOnSelectedRows"></app-group-table>
</mat-tab>
</mat-tab-group>1
</div>
<!-- (1, 4): assigned users -->
<div class="col-3">
<mat-tab-group>

View File

@@ -3,11 +3,10 @@ import { GuiColumn, GuiSelectedRow } from '@generic-ui/ngx-grid/gui/grid/src/cor
import { UserTableComponent } from '../../components/tables/user-table/user-table.component';
import { UserRepTableComponent } from '../../components/tables/user-rep-table/user-rep-table.component';
import { GroupTableComponent } from '../../components/tables/group-table/group-table.component';
import { UserRepService } from '../../services/user-representation.service';
import { UserRepService } from '../../services/api/user-representation.service';
import Swal from 'sweetalert2';
import { MatTabsModule, MatTabGroup } from '@angular/material/tabs';
import { env } from '../../../environments/environment';
import { RefreshService } from '../../services/refresh.service';
import { BasePageComponent } from '../base-page/base-page.component';
@Component({
@@ -38,6 +37,7 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
}
ngAfterViewInit(): void {
this.buttonVisibilityService.setVisibleOnly(this.refreshService)
this.refreshService.removeAll();
this.refreshService.add(() => {
this.users.fetchData();
@@ -56,7 +56,7 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
userOnSelectedRows = (rows: GuiSelectedRow[]) => {
if (rows.length > 0) {
this.users.safelyUnselectAll();
this.useRepLabel = `Repräsentationen von ${rows[0].source?.username}`
this.useRepLabel = `Vertretungen von ${rows[0].source?.username}`
this.userReps.fetchData(rows[0].source?.id)
this.slUserId = rows[0].source?.id
}
@@ -83,14 +83,14 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
Swal.fire({
icon: "error",
title: "Oops...",
text: "Bitte wählen Sie die repräsentative Benutzer!",
text: "Bitte wählen Sie die Vertretungen Benutzer!",
});
}
else if (!this.slRightGroupId) {
Swal.fire({
icon: "error",
title: "Oops...",
text: "Bitte wählen Sie die richtige Gruppe!",
text: "Bitte wählen Sie die Rechte Gruppe!",
});
}
else {
@@ -111,7 +111,7 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
Swal.fire({
icon: "error",
title: "Oops...",
text: `Bitte versuchen Sie es später noch einmal.`,
text: `Dieser Vorgang ist nicht möglich.`,
});
}
});
@@ -137,14 +137,14 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
Swal.fire({
icon: "error",
title: "Oops...",
text: "Bitte wählen Sie die repräsentative Gruppe!",
text: "Bitte wählen Sie die Vertretungen Gruppe!",
});
}
else if (!this.slRightGroupId) {
Swal.fire({
icon: "error",
title: "Oops...",
text: "Bitte wählen Sie die richtige Gruppe!",
text: "Bitte wählen Sie die rechte Gruppe!",
});
}
else {
@@ -162,11 +162,10 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
this.userReps.fetchData(this.slUserId)
},
error: (error) => {
const errorMessage = error?.error || "Es ist ein unerwarteter Fehler aufgetreten.";
Swal.fire({
icon: "error",
title: "Oops...",
text: `${errorMessage}\nBitte versuchen Sie es später noch einmal.`,
text: `Dieser Vorgang ist nicht möglich.`,
});
}
});
@@ -191,11 +190,10 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
error: (err) => {
this.slUserRepId = null;
this.repUsers.safelyUnselectAll()
const errorMessage = err?.error || "Es ist ein unerwarteter Fehler aufgetreten.";
Swal.fire({
icon: "error",
title: "Oops...",
text: `${errorMessage}\nBitte versuchen Sie es später noch einmal.`,
text: `Dieser Vorgang ist nicht möglich.`,
});
}
})

View File

@@ -1,15 +1,14 @@
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { GuiCellEdit, GuiSelectedRow } from '@generic-ui/ngx-grid';
import { UserTableComponent } from '../../components/tables/user-table/user-table.component';
import { RefreshService } from '../../services/refresh.service';
import { MatTabsModule } from '@angular/material/tabs';
import { GroupTableComponent } from '../../components/tables/group-table/group-table.component';
import { ModuleTableComponent } from '../../components/tables/module-table/module-table.component';
import { CreationService } from '../../services/creation.service';
import { UserFormComponent } from '../../components/forms/user-form/user-form.component';
import { BasePageComponent } from '../base-page/base-page.component';
import { User } from '../../models/user-management.api.models';
import { firstValueFrom } from 'rxjs';
import { firstValueFrom, forkJoin } from 'rxjs';
import Swal from 'sweetalert2';
@Component({
standalone: true,
@@ -37,6 +36,7 @@ export class UserComponent extends BasePageComponent implements AfterViewInit {
private sUsername = null;
ngAfterViewInit(): void {
this.buttonVisibilityService.setVisibleOnly(this.refreshService, this.creationService, this.updateService)
this.refreshService.removeAll()
this.refreshService.add(() => {
this.userTable.fetchData();
@@ -63,4 +63,36 @@ export class UserComponent extends BasePageComponent implements AfterViewInit {
}
}
}
override handleDeleteRequest() {
const sRows = this.userTable.selectedRows;
if (sRows.length > 0)
Swal.fire({
title: "Löschen bestätigen",
html: `<p class="text-start">Dieser Vorgang ist unwiderruflich. Möchten Sie fortfahren?<br><br>Anzahl der zu löschenden Einträge: ${sRows.length}</p>`,
showDenyButton: true,
confirmButtonText: "Ja",
denyButtonText: `Nein`
}).then((result) => {
if (result.isConfirmed) {
const deleteRequests = sRows.map(sRow => this.userTable.service.delete(sRow.source.id!));
forkJoin(deleteRequests).subscribe({
next: () => {
this.updateService.executeAll().then(() => {
this.refreshService.executeAll();
})
Swal.fire({
text: `${sRows.length} Einträge wurden erfolgreich gelöscht.`,
icon: "success"
})
},
error: err => Swal.fire({
title: "Fehler",
text: `${err.message}`,
icon: "error"
})
});
}
});
}
}

View File

@@ -1,7 +1,7 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { firstValueFrom } from 'rxjs/internal/firstValueFrom';
import { env } from '../../environments/environment';
import { env } from '../../../environments/environment';
@Injectable({
providedIn: 'root'

View File

@@ -1,6 +1,6 @@
import { Injectable, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DirGroup, } from '../models/user-management.api.models';
import { DirGroup, } from '../../models/user-management.api.models';
import { ApiService } from './user-management.api.service';
import { Observable } from 'rxjs/internal/Observable';
import Swal from 'sweetalert2';

View File

@@ -1,6 +1,6 @@
import { Injectable, Inject } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { DirUser } from '../models/user-management.api.models';
import { DirUser } from '../../models/user-management.api.models';
import { ApiService } from './user-management.api.service';
import { Observable } from 'rxjs/internal/Observable';
import { UrlService } from './url.service';

View File

@@ -1,7 +1,7 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Inject, Injectable } from '@angular/core';
import { DirUser } from '../models/user-management.api.models';
import { DirUser } from '../../models/user-management.api.models';
import { UrlService } from './url.service';
@Injectable({

View File

@@ -1,6 +1,6 @@
import { Injectable, Inject } from '@angular/core';
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { GroupOfUser } from '../models/user-management.api.models';
import { GroupOfUser } from '../../models/user-management.api.models';
import { ApiService } from './user-management.api.service';
import { Observable, firstValueFrom } from 'rxjs';
import { UrlService } from './url.service';

View File

@@ -1,6 +1,6 @@
import { Injectable, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DirGroup, Group, } from '../models/user-management.api.models';
import { DirGroup, Group, } from '../../models/user-management.api.models';
import { ApiService } from './user-management.api.service';
import { Observable } from 'rxjs/internal/Observable';
import { UrlService } from './url.service';

View File

@@ -1,6 +1,6 @@
import { Injectable, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ModuleOfUser } from '../models/user-management.api.models';
import { ModuleOfUser } from '../../models/user-management.api.models';
import { ApiService } from './user-management.api.service';
import { Observable, firstValueFrom } from 'rxjs';
import { UrlService } from './url.service';

View File

@@ -1,7 +1,7 @@
import { Injectable, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ApiService } from './user-management.api.service';
import { Module } from '../models/user-management.api.models';
import { Module } from '../../models/user-management.api.models';
import { UrlService } from './url.service';
@Injectable({

View File

@@ -1,7 +1,7 @@
import { Injectable, Inject, inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { Meta } from '@angular/platform-browser';
import { env } from '../../environments/environment';
import { env } from '../../../environments/environment';
@Injectable({
providedIn: 'root'

View File

@@ -1,5 +1,5 @@
import { Inject, Injectable } from "@angular/core";
import { UserRep } from "../models/user-management.api.models";
import { UserRep } from "../../models/user-management.api.models";
import { ApiService } from "./user-management.api.service";
import { HttpClient, HttpParams } from "@angular/common/http";
import { Observable } from "rxjs";

View File

@@ -1,6 +1,6 @@
import { Injectable, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DirUser, User } from '../models/user-management.api.models';
import { DirUser, User } from '../../models/user-management.api.models';
import { ApiService } from './user-management.api.service';
import { Observable } from 'rxjs';
import { UrlService } from './url.service';

View File

@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { BaseButtonService } from './base-button.service';
describe('BaseButtonService', () => {
let service: BaseButtonService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(BaseButtonService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -0,0 +1,16 @@
import { Injectable, inject } from "@angular/core";
import { ButtonVisibilityService } from "./button-visibility.service";
export class BaseButtonService {
constructor() {
const bvService = inject(ButtonVisibilityService);
bvService.buttons[this.constructorName] = this;
}
public isVisible: boolean = true;
public get constructorName() {
return this.constructor.name;
}
}

View File

@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { ButtonVisibilityService } from './button-visibility.service';
describe('ButtonVisibilityService', () => {
let service: ButtonVisibilityService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ButtonVisibilityService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -0,0 +1,37 @@
import { Injectable } from '@angular/core';
import { BaseButtonService } from './base-button.service';
@Injectable({
providedIn: 'root'
})
export class ButtonVisibilityService {
_buttons: { [key: string]: BaseButtonService } = {};
public get buttons() {
return this._buttons;
}
setVisibility(key: string, show: boolean) {
const bttn = this._buttons[key];
if (show && !bttn.isVisible) {
bttn.isVisible = true
return
}
if (!show && bttn.isVisible) {
bttn.isVisible = false
}
}
setVisibleOnly(...buttons: BaseButtonService[]) {
const keys = buttons.map(b => b.constructorName)
for (const key in this._buttons) {
if (keys.includes(key)) {
this.setVisibility(key, true)
}
else {
this.setVisibility(key, false)
}
}
}
}

View File

@@ -1,11 +1,12 @@
import { Injectable, Inject, Renderer2, RendererFactory2, PLATFORM_ID } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
import { BaseButtonService } from './base-button.service';
@Injectable({
providedIn: 'root'
})
export class ColorModeService {
export class ColorModeService extends BaseButtonService {
private readonly renderer: Renderer2;
@@ -13,6 +14,7 @@ export class ColorModeService {
public themeChanges$ = this.themeSubject.asObservable();
constructor(@Inject(PLATFORM_ID) private platformId: object, private rendererFactory: RendererFactory2, @Inject(DOCUMENT) public document: Document) {
super()
this.renderer = rendererFactory.createRenderer(null, null);
}

View File

@@ -1,16 +1,18 @@
import { Injectable } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { ComponentType } from '@angular/cdk/portal';
import { BaseButtonService } from './base-button.service';
@Injectable({
providedIn: 'root'
})
export class CreationService {
export class CreationService extends BaseButtonService {
public component: ComponentType<unknown> | undefined
public width: string = "50vw";
constructor(private readonly dialog: MatDialog) {
super()
}
openDialog(): MatDialogRef<unknown, any> | undefined {

View File

@@ -1,12 +1,15 @@
import { Injectable } from '@angular/core';
import { UpdateService } from './update.service';
import { BaseButtonService } from './base-button.service';
@Injectable({
providedIn: 'root'
})
export class RefreshService {
export class RefreshService extends BaseButtonService {
constructor(private updateService: UpdateService) { }
constructor(private updateService: UpdateService) {
super()
}
private actions: Array<() => void> = [];

View File

@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { TransferService } from './transfer.service';
describe('TransferService', () => {
let service: TransferService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(TransferService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -0,0 +1,30 @@
import { Injectable } from '@angular/core';
import { BaseButtonService } from './base-button.service';
@Injectable({
providedIn: 'root'
})
export class TransferService 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());
}
}

View File

@@ -1,11 +1,10 @@
import { Injectable } from '@angular/core';
import { BaseButtonService } from './base-button.service';
@Injectable({
providedIn: 'root'
})
export class UpdateService {
constructor() { }
export class UpdateService extends BaseButtonService {
private async_actions: { [key: string]: () => Promise<void> } = {};
private actions: { [key: string]: () => void } = {};

View File

@@ -28,7 +28,7 @@
"NLog": {
"throwConfigExceptions": true,
"variables": {
"logDirectory": "E:\\WebUserManager\\logs",
"logDirectory": "E:\\LogFiles\\Digital Data\\WebUserManager",
"logFileNamePrefix": "${shortdate}-ECM.WebUserManager.Web"
},
"targets": {