Schließanlagen können gelöscht werden
This commit is contained in:
7
client/src/app/model/interface/keysystem.interface.ts
Normal file
7
client/src/app/model/interface/keysystem.interface.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface ISystem {
|
||||
id: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
deletedAt?: string;
|
||||
name: string;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<h2 mat-dialog-title>Gelöschte Schließanlagen</h2>
|
||||
<mat-dialog-content>
|
||||
@if(myTheme) {
|
||||
<ag-grid-angular
|
||||
style="width: 100%; height: 100%;"
|
||||
(gridReady)="onGridReady($event)"
|
||||
[gridOptions]="gridOptions!"
|
||||
[theme]="myTheme"
|
||||
/>
|
||||
}
|
||||
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button matButton mat-dialog-close>Schließen</button>
|
||||
</mat-dialog-actions>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SystemArchiveComponent } from './system-archive.component';
|
||||
|
||||
describe('SystemArchiveComponent', () => {
|
||||
let component: SystemArchiveComponent;
|
||||
let fixture: ComponentFixture<SystemArchiveComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SystemArchiveComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SystemArchiveComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import { Component, inject, LOCALE_ID } from '@angular/core';
|
||||
import { AgGridContainerComponent } from '../../../../shared/ag-grid/components/ag-grid-container/ag-grid-container.component';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { AgGridAngular } from 'ag-grid-angular';
|
||||
import { GridApi, GridOptions, GridReadyEvent } from 'ag-grid-community';
|
||||
import { ApiService } from '../../../../shared/api.service';
|
||||
import { HELPER } from '../../../../shared/helper.service';
|
||||
import { ISystem } from '../../../../model/interface/keysystem.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-system-archive',
|
||||
imports: [MatDialogModule, AgGridAngular, MatButtonModule, MatIconModule],
|
||||
templateUrl: './system-archive.component.html',
|
||||
styleUrl: './system-archive.component.scss',
|
||||
providers: [DatePipe, { provide: LOCALE_ID, useValue: 'de-DE' }]
|
||||
})
|
||||
export class SystemArchiveComponent extends AgGridContainerComponent {
|
||||
private api: ApiService = inject(ApiService);
|
||||
private datePipe = inject(DatePipe);
|
||||
|
||||
gridApi!: GridApi;
|
||||
|
||||
gridOptions: GridOptions = HELPER.getGridOptions();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.gridOptions.columnDefs = [
|
||||
{ colId: 'name', field: 'name' , headerName: 'Name', flex: 1, editable: true, sort: 'asc', filter: true },
|
||||
// { colId: 'nr', field: 'nr' , headerName: 'Schlüsselnummer', flex: 1, editable: true, filter: true },
|
||||
{
|
||||
field: 'deletedAt'
|
||||
, headerName: 'Gelöscht'
|
||||
, width: 160
|
||||
// , type: 'date'
|
||||
, cellRenderer: (data: any) => this.datePipe.transform(new Date(data.value), 'short')
|
||||
},
|
||||
{
|
||||
width: 40,
|
||||
cellRenderer: () => '<div class="icon-btn-sm restore icon-btn-xs" ></div>',
|
||||
onCellClicked: (event) => { this.restoreSystem(event.data);},
|
||||
tooltipValueGetter: () => 'Wiederherstellen',
|
||||
sortable: false
|
||||
}
|
||||
];
|
||||
this.gridOptions.rowHeight = 36;
|
||||
this.gridOptions.overlayNoRowsTemplate = 'Bisher wurden keine Schließanlagen gelöscht. Sobald dies der Fall ist, werden sie hier angezeigt.';
|
||||
}
|
||||
|
||||
onGridReady(params: GridReadyEvent) {
|
||||
this.gridApi = params.api;
|
||||
this.loadSystems();
|
||||
}
|
||||
|
||||
async loadSystems() {
|
||||
this.gridApi.setGridOption("loading", true);
|
||||
const systems = await this.api.getSystemArchive()
|
||||
this.gridApi.setGridOption("rowData", systems);
|
||||
this.gridApi.setGridOption("loading", false);
|
||||
}
|
||||
|
||||
async restoreSystem(system: ISystem) {
|
||||
await this.api.restoreSystem(system);
|
||||
this.loadSystems();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,4 +8,5 @@
|
||||
}
|
||||
<div class="floating-btn-container">
|
||||
<button mat-flat-button class="btn-create mat-elevation-z8" (click)="openCreateSystem()" >Schließanlage anlegen</button>
|
||||
<button mat-mini-fab (click)="openArchive()" matTooltip="Archiv"><mat-icon>inventory_2</mat-icon></button>
|
||||
</div>
|
||||
@@ -9,10 +9,12 @@ import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
||||
import { CreateSystemComponent } from './create/create.component';
|
||||
import { AgGridContainerComponent } from '../../shared/ag-grid/components/ag-grid-container/ag-grid-container.component';
|
||||
import { AgSystemManagerComponent } from '../../shared/ag-grid/components/ag-system-manager/ag-system-manager.component';
|
||||
import { SystemArchiveComponent } from './components/system-archive/system-archive.component';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
|
||||
@Component({
|
||||
selector: 'app-system',
|
||||
imports: [AgGridAngular, MatButtonModule, MatDialogModule],
|
||||
imports: [AgGridAngular, MatButtonModule, MatDialogModule, MatIconModule],
|
||||
providers: [DatePipe, { provide: LOCALE_ID, useValue: 'de-DE' }],
|
||||
templateUrl: './system.component.html',
|
||||
styleUrl: './system.component.scss'
|
||||
@@ -41,12 +43,15 @@ export class SystemComponent extends AgGridContainerComponent {
|
||||
// , onCellClicked: (event) => { this.deleteKey(event.data.id)}
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
async loadSystems() {
|
||||
this.gridApi.setGridOption("loading", true);
|
||||
await this.api.refreshSystems();
|
||||
this.gridApi.setGridOption("loading", false);
|
||||
const a = await this.api.getSystemArchive();
|
||||
console.log(a)
|
||||
}
|
||||
|
||||
onGridReady(params: GridReadyEvent) {
|
||||
@@ -81,4 +86,15 @@ export class SystemComponent extends AgGridContainerComponent {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
openArchive() {
|
||||
this.dialog.open(SystemArchiveComponent, {
|
||||
maxHeight: "calc(100vh - 24px)",
|
||||
maxWidth: "calc(100vw - 24px)",
|
||||
width: "50vw",
|
||||
minWidth: "300px",
|
||||
height: "70vh",
|
||||
disableClose: true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<h2 mat-dialog-title>Schließanlage <u>{{key.name}}</u> löschen?</h2>
|
||||
<mat-dialog-content>
|
||||
<div class="warning-message">
|
||||
<mat-icon>warning</mat-icon>
|
||||
<p>
|
||||
<b>{{key.name}}</b> wirklich entfernen?
|
||||
</p>
|
||||
<p class="additional-info">
|
||||
<!-- Additional information -->
|
||||
<small>Gelöschte Schließanlagen können über das Archiv wiederhergestellt werden.</small>
|
||||
</p>
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions align="end">
|
||||
<button matButton [mat-dialog-close]="false">Abbrechen</button>
|
||||
<button matButton="elevated" [mat-dialog-close]="true" class="btn-warning">
|
||||
<mat-icon>delete</mat-icon>
|
||||
Entfernen
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AgDeleteSystemComponent } from './ag-delete-system.component';
|
||||
|
||||
describe('AgDeleteSystemComponent', () => {
|
||||
let component: AgDeleteSystemComponent;
|
||||
let fixture: ComponentFixture<AgDeleteSystemComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [AgDeleteSystemComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(AgDeleteSystemComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { IKey } from '../../../../model/interface/key.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-ag-delete-system',
|
||||
imports: [MatDialogModule, MatButtonModule, MatIconModule],
|
||||
templateUrl: './ag-delete-system.component.html',
|
||||
styleUrl: './ag-delete-system.component.scss',
|
||||
})
|
||||
export class AgDeleteSystemComponent {
|
||||
readonly dialogRef = inject(MatDialogRef<AgDeleteSystemComponent>);
|
||||
readonly key = inject<any>(MAT_DIALOG_DATA);
|
||||
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
<div class="manage icon-btn-sm" (click)="openManager()" matTooltip="Manager bearbeiten" [matTooltipShowDelay]="600"></div>
|
||||
<div class="manage icon-btn-sm" (click)="openManager()" matTooltip="Manager bearbeiten" [matTooltipShowDelay]="600"></div>
|
||||
<div class="delete icon-btn-sm" (click)="delete()" matTooltip="Löschen" [matTooltipShowDelay]="400"></div>
|
||||
@@ -6,6 +6,7 @@ import { ICellRendererAngularComp } from 'ag-grid-angular';
|
||||
import { ICellRendererParams } from 'ag-grid-community';
|
||||
import { ApiService } from '../../../api.service';
|
||||
import { SystemManagerComponent } from '../../../../modules/system/components/system-manager/system-manager.component';
|
||||
import { AgDeleteSystemComponent } from '../ag-delete-system/ag-delete-system.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-ag-system-manager',
|
||||
@@ -32,15 +33,39 @@ export class AgSystemManagerComponent implements ICellRendererAngularComp {
|
||||
|
||||
|
||||
openManager() {
|
||||
const ref = this.dialog.open(SystemManagerComponent, {
|
||||
data: this.system,
|
||||
autoFocus: false,
|
||||
maxHeight: "calc(100vh - 24px)",
|
||||
maxWidth: "calc(100vw - 24px)",
|
||||
width: "50vw",
|
||||
minWidth: "300px",
|
||||
height: "70vh",
|
||||
disableClose: false
|
||||
})
|
||||
}
|
||||
const ref = this.dialog.open(SystemManagerComponent, {
|
||||
data: this.system,
|
||||
autoFocus: false,
|
||||
maxHeight: "calc(100vh - 24px)",
|
||||
maxWidth: "calc(100vw - 24px)",
|
||||
width: "50vw",
|
||||
minWidth: "300px",
|
||||
height: "70vh",
|
||||
disableClose: false
|
||||
})
|
||||
}
|
||||
|
||||
delete() {
|
||||
const ref = this.dialog.open(AgDeleteSystemComponent, {
|
||||
data: this.system,
|
||||
autoFocus: false,
|
||||
width: '500px',
|
||||
maxWidth: 'calc(100vw - 24px)',
|
||||
})
|
||||
|
||||
ref.afterClosed().subscribe({
|
||||
next: n => {
|
||||
if (n) {
|
||||
this.deleteThisKey();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async deleteThisKey() {
|
||||
this.params.api.setGridOption("loading", true);
|
||||
await this.api.deleteSystem(this.system);
|
||||
this.params.api.setGridOption("loading", false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { IKey } from '../model/interface/key.interface';
|
||||
import { ICylinder } from '../model/interface/cylinder.interface';
|
||||
import { HotToastService } from '@ngxpert/hot-toast';
|
||||
import { ICustomer } from '../model/interface/customer.interface';
|
||||
import { ISystem } from '../model/interface/keysystem.interface';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -198,7 +199,7 @@ export class ApiService {
|
||||
*/
|
||||
deleteSystem(system: any): Promise<boolean> {
|
||||
return new Promise<boolean>(resolve => {
|
||||
this.http.delete(`api/system${system.id}`).pipe(
|
||||
this.http.delete(`api/system/${system.id}`).pipe(
|
||||
this.toast.observe({
|
||||
loading: `Lösche Schließanlage ${system.name}...`,
|
||||
success: `Schließanlage ${system.name} wurde gelöscht.`,
|
||||
@@ -222,6 +223,21 @@ export class ApiService {
|
||||
return this.http.put(`api/key/${id}/restore`, null);
|
||||
}
|
||||
|
||||
restoreSystem(system: ISystem): Promise<boolean> {
|
||||
return new Promise(resolve => {
|
||||
this.http.put(`api/system/${system.id}/restore`, null).subscribe({
|
||||
next: () => {
|
||||
this.refreshSystems();
|
||||
resolve(true);
|
||||
},
|
||||
error: () => {
|
||||
this.toast.error('Schließanlage konnte nicht wiederhergestellt werden');
|
||||
resolve(false)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private getCylinders(): Observable<ICylinder[]> {
|
||||
return this.http.get<ICylinder[]>('api/cylinder');
|
||||
}
|
||||
@@ -240,6 +256,20 @@ export class ApiService {
|
||||
})
|
||||
}
|
||||
|
||||
getSystemArchive(): Promise<any[]> {
|
||||
return new Promise<any[]>(resolve => {
|
||||
this.http.get<any[]>('api/system/archive').subscribe({
|
||||
next: val => {
|
||||
return resolve(val);
|
||||
},
|
||||
error: () => {
|
||||
this.toast.error('Gelöschte Schließanlagen konnten nicht geladen werden');
|
||||
return resolve([])
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualisiert die Zylinder im Behaviour Subject
|
||||
* cylinders
|
||||
|
||||
Reference in New Issue
Block a user