Files
keyvault/client/src/app/modules/keys/keys.component.ts
Bastian Wagner 92f0c10bd8 Lost Keys
2025-01-03 13:39:47 +01:00

205 lines
6.9 KiB
TypeScript

import { Component, inject } from '@angular/core';
import { AG_GRID_LOCALE_DE } from '@ag-grid-community/locale';
import { AgGridAngular } from 'ag-grid-angular';
import { GridOptions,GridApi, GridReadyEvent, CellEditingStoppedEvent, ICellEditorParams } from 'ag-grid-community';
import { DatePipe } from '@angular/common';
import { ApiService } from '../../shared/api.service';
import { IKey } from '../../model/interface/key.interface';
import { HotToastService } from '@ngxpert/hot-toast';
import { MatButtonModule } from '@angular/material/button';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { CreateKeyComponent } from './create/create.component';
import { AgDeleteKeyComponent } from '../../shared/ag-grid/components/ag-delete-key/ag-delete-key.component';
import { MatIconModule } from '@angular/material/icon';
import { ArchiveComponent } from './components/archive/archive.component';
import { AgLoadingComponent } from '../../shared/ag-grid/components/ag-loading/ag-loading.component';
import { map, of } from 'rxjs';
import { ICylinder } from '../../model/interface/cylinder.interface';
import { LostKeysComponent } from './components/lost-keys/lost-keys.component';
import { MatTooltipModule } from '@angular/material/tooltip';
@Component({
selector: 'app-keys',
standalone: true,
imports: [AgGridAngular, MatButtonModule, MatDialogModule, MatIconModule, MatTooltipModule],
providers: [DatePipe],
templateUrl: './keys.component.html',
styleUrl: './keys.component.scss'
})
export class KeysComponent {
private api: ApiService = inject(ApiService);
private datePipe = inject(DatePipe);
private toast: HotToastService = inject(HotToastService);
private dialog: MatDialog = inject(MatDialog);
cylinders: any[] = [{name: 'dummy'}];
gridApi!: GridApi;
gridOptions: GridOptions = {
localeText: AG_GRID_LOCALE_DE,
rowData: [],
rowClassRules: {
'key-lost': (params) => {console.log(params.data); return params.data.keyLost != null},
},
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 },
{ colId: 'cylinder', field: 'cylinder' , headerName: 'Zylinder', flex: 1, editable: false, filter: true, cellRenderer: (data: any) => {return data.value?.map((m: ICylinder) => m.name).join(', ')}, cellEditor: 'agSelectCellEditor',
// cellEditorParams: () => {
// return {
// values: this.cylinders,
// }
// },
// valueFormatter: (val) => {
// return val.value?.name + ` (${val.value?.system?.name})`;
// },
cellEditorPopup: false
},
{ colId: 'system', field: 'cylinder' , headerName: 'Schließanlage', flex: 1, editable: false, filter: true, cellRenderer: (data: any) => {
const s = new Set<string>(data.value?.map((m: ICylinder) => m.system?.name));
return [...s].join(', ')
} },
{ colId: 'customer', field: 'customer' , headerName: 'Kunde', flex: 1, editable: false, filter: true, cellRenderer: (data: any) => {return data.value?.name} },
{
field: 'createdAt'
, headerName: 'Erstellt'
, width: 120
// , type: 'date'
, cellRenderer: (data: any) => this.datePipe.transform(new Date(data.value))
, tooltipValueGetter: (data: any) => this.datePipe.transform(new Date(data.value), 'medium')
},{
colId: 'updatedAt',
field: 'updatedAt'
, headerName: 'Geändert'
, width: 120
// , type: 'date'
, cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-'
, tooltipValueGetter: (data: any) => this.datePipe.transform(new Date(data.value), 'medium')
},
{ colId: 'handedOut', field: 'handedOut' , headerName: 'Ausgegeben', width: 100, editable: false, filter: false, headerTooltip: 'Ausgegeben' },
{
colId: 'actions'
, headerName: 'Aktionen'
, width: 120
, cellRenderer: AgDeleteKeyComponent
// , onCellClicked: (event) => { this.deleteKey(event.data.id)}
}
],
loading: true,
rowHeight: 54,
loadingOverlayComponent: AgLoadingComponent,
pagination: true,
}
deleteKey(id: string) {
this.api.deleteKey(id).subscribe()
}
ngOnInit(): void {
this.api.getCylinders().subscribe({
next: n => {
this.cylinders = n;
},
error: () => {
this.cylinders = [];
}
})
}
loadKeys() {
this.gridApi.setGridOption("loading", true);
this.api.getKeys().subscribe({
next: n => {
this.gridApi.setGridOption("rowData", n);
this.gridApi.setGridOption("loading", false);
},
error: () => {
this.gridApi.setGridOption("loading", false);
// set error in grid
this.toast.error('Fehler beim Laden der Schlüssel')
}
})
}
onGridReady(params: GridReadyEvent) {
this.gridApi = params.api;
this.gridApi.addEventListener("cellEditingStopped", evt => this.cellEditEnd(evt))
this.loadKeys();
}
cellEditEnd(event: CellEditingStoppedEvent) {
const key: IKey = event.data;
if (!event.valueChanged || event.newValue == event.oldValue) { return; }
this.gridApi.setGridOption("loading", true);
this.api.updateKey(key)
.pipe(
this.toast.observe({
loading: 'speichern...',
success: 'Änderungen gespeichert',
error: 'Änderungen konnten nicht gespeichert werden!'
})
).subscribe({
next: () => {this.gridApi.setGridOption("loading", false);},
error: () => {
this.loadKeys();
}
})
}
openCreateKey() {
this.dialog.open(CreateKeyComponent, {
maxWidth: "calc(100vw - 24px)",
width: "30vw",
minWidth: "200px",
disableClose: true
}).afterClosed().subscribe({
next: key => {
if (key) {
let d = [...this.gridApi.getGridOption("rowData") || [], key];
this.gridApi.setGridOption("rowData", d);
this.loadKeys();
}
}
})
}
openArchive() {
this.dialog.open(ArchiveComponent, {
maxHeight: "calc(100vh - 24px)",
maxWidth: "calc(100vw - 24px)",
width: "50vw",
minWidth: "300px",
height: "70vh",
disableClose: true
}).afterClosed().subscribe({
next: changed => {
if (changed) {
this.loadKeys();
}
}
})
}
openLostKeys() {
this.dialog.open(LostKeysComponent, {
maxHeight: "calc(100vh - 24px)",
maxWidth: "calc(100vw - 24px)",
width: "50vw",
minWidth: "min(700px,calc(100vw - 24px))",
height: "70vh",
disableClose: true
}).afterClosed().subscribe({
next: changed => {
console.log(changed)
if (changed) {
this.loadKeys();
}
}
})
}
}