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