This commit is contained in:
Bastian Wagner
2026-02-13 13:45:18 +01:00
parent 21b04c5354
commit b83107094f
6 changed files with 84 additions and 13 deletions

View File

@@ -1,7 +1,7 @@
import { Component, inject } from '@angular/core'; import { Component, inject } from '@angular/core';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { ApiService } from '../../../shared/api.service'; import { ApiService } from '../../../shared/api.service';
import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatFormFieldModule } from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field';
@@ -12,6 +12,8 @@ import { HotToastService } from '@ngxpert/hot-toast';
import { SelectKeyCylinderComponent } from './select-key-cylinder/select-key-cylinder.component'; import { SelectKeyCylinderComponent } from './select-key-cylinder/select-key-cylinder.component';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import {MatCheckboxModule} from '@angular/material/checkbox'; import {MatCheckboxModule} from '@angular/material/checkbox';
import { IKey } from '../../../model/interface/key.interface';
import { ICylinder } from '../../../model/interface/cylinder.interface';
@Component({ @Component({
selector: 'app-create', selector: 'app-create',
@@ -26,24 +28,33 @@ export class CreateKeyComponent {
private toast: HotToastService = inject(HotToastService); private toast: HotToastService = inject(HotToastService);
readonly dialogRef = inject(MatDialogRef<CreateKeyComponent>); readonly dialogRef = inject(MatDialogRef<CreateKeyComponent>);
private readonly dialog = inject(MatDialog); private readonly dialog = inject(MatDialog);
readonly key = inject<IKey>(MAT_DIALOG_DATA);
createForm = new FormGroup({ createForm = new FormGroup({
name: new FormControl(null, Validators.required), name: new FormControl<string | null>(null, Validators.required),
nr: new FormControl(null, Validators.required), nr: new FormControl<number | null>(null, Validators.required),
digital: new FormControl(false, Validators.required), digital: new FormControl(false, Validators.required),
cylinder: new FormControl(null, Validators.required), cylinder: new FormControl<any>(null, Validators.required),
}) })
cylinders: any[] = []; cylinders: any[] = [];
filteredCylinders!: Observable<any[]>; filteredCylinders!: Observable<any[]>;
ngOnInit(): void { ngOnInit(): void {
this.loadCylinders(); this.doSetup();
}
async doSetup() {
await this.loadCylinders();
this.filteredCylinders = this.createForm.controls.cylinder.valueChanges.pipe( this.filteredCylinders = this.createForm.controls.cylinder.valueChanges.pipe(
startWith(''), startWith(''),
map(value => this._filter(value || '')), map(value => this._filter(value || '')),
); );
if (this.key) {
this.setEditKey(this.key)
}
} }
private _filter(value: string): string[] { private _filter(value: string): string[] {
@@ -53,16 +64,19 @@ export class CreateKeyComponent {
} }
loadCylinders() { loadCylinders() {
this.api.getCylinders().subscribe({ return new Promise(resolve => {
this.api.getCylinders().subscribe({
next: n => { next: n => {
this.cylinders = n; this.cylinders = n;
this.createForm.controls.cylinder.patchValue(null); this.createForm.controls.cylinder.patchValue(null);
resolve(null)
} }
});
}) })
} }
save() { save() {
this.api.createKey(this.createForm.value as any) this.api.createKey(this.createForm.value as any)
.pipe( .pipe(
this.toast.observe({ this.toast.observe({
@@ -96,4 +110,10 @@ export class CreateKeyComponent {
} }
}) })
} }
async setEditKey(key: IKey) {
this.createForm.patchValue(key as any);
this.createForm.controls.cylinder.patchValue(this.cylinders.filter(c => key.cylinder.some(v => v.id == c.id)));
console.log(this.createForm.value)
}
} }

View File

@@ -17,6 +17,7 @@ import { map, of } from 'rxjs';
import { ICylinder } from '../../model/interface/cylinder.interface'; import { ICylinder } from '../../model/interface/cylinder.interface';
import { LostKeysComponent } from './components/lost-keys/lost-keys.component'; import { LostKeysComponent } from './components/lost-keys/lost-keys.component';
import { MatTooltipModule } from '@angular/material/tooltip'; import { MatTooltipModule } from '@angular/material/tooltip';
import { SelectKeyCylinderComponent } from './create/select-key-cylinder/select-key-cylinder.component';
@Component({ @Component({
selector: 'app-keys', selector: 'app-keys',
@@ -44,10 +45,13 @@ export class KeysComponent {
{ colId: 'name', field: 'name' , headerName: 'Name', flex: 1, editable: true, sort: 'asc', filter: true }, { 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: 'nr', field: 'nr' , headerName: 'Schlüsselnummer', flex: 1, editable: true, filter: true },
{ colId: 'cylinder', field: 'cylinder' , headerName: 'Zylinder', flex: 1, editable: false, filter: true, { colId: 'cylinder', field: 'cylinder' , headerName: 'Zylinder', flex: 1, editable: false, filter: true,
valueFormatter: (data: any) => { return data; },
cellRenderer: (data: any) => {return data.value?.map((m: ICylinder) => m.name).join(', ')}, cellRenderer: (data: any) => {return data.value?.map((m: ICylinder) => m.name).join(', ')},
tooltipValueGetter: (data: any) => data.value?.map((m: ICylinder) => m.name).join(', '), tooltipValueGetter: (data: any) => data.value?.map((m: ICylinder) => m.name).join(','),
cellEditor: 'agSelectCellEditor', onCellDoubleClicked(event) {
cellEditorPopup: false,
},
cellEditorPopup: true,
filterValueGetter: (params: any) => {return params.data.cylinder?.map((m: ICylinder) => m.name).join(', ')}, filterValueGetter: (params: any) => {return params.data.cylinder?.map((m: ICylinder) => m.name).join(', ')},
}, },
{ colId: 'system', field: 'cylinder' , headerName: 'Schließanlage', flex: 1, editable: false, filter: true, cellRenderer: (data: any) => { { colId: 'system', field: 'cylinder' , headerName: 'Schließanlage', flex: 1, editable: false, filter: true, cellRenderer: (data: any) => {
@@ -57,11 +61,13 @@ export class KeysComponent {
filterValueGetter: (params: any) => { filterValueGetter: (params: any) => {
const s = new Set<string>(params.data.cylinder?.map((m: ICylinder) => m.system?.name)); const s = new Set<string>(params.data.cylinder?.map((m: ICylinder) => m.system?.name));
return [...s].join(', ') return [...s].join(', ')
} },
valueFormatter: (data: any) => { return data; },
}, },
{ colId: 'customer', field: 'customer' , headerName: 'Kunde', flex: 1, editable: false, filter: true, { colId: 'customer', field: 'customer' , headerName: 'Kunde', flex: 1, editable: false, filter: true,
cellRenderer: (data: any) => {return data.value?.name}, cellRenderer: (data: any) => {return data.value?.name},
filterValueGetter: (params: any) => {return params.data.customer?.name}, filterValueGetter: (params: any) => {return params.data.customer?.name},
valueFormatter: (data: any) => { return data; },
}, },
{ {
field: 'createdAt' field: 'createdAt'
@@ -69,7 +75,8 @@ export class KeysComponent {
, width: 120 , width: 120
// , type: 'date' // , type: 'date'
, cellRenderer: (data: any) => this.datePipe.transform(new Date(data.value)) , cellRenderer: (data: any) => this.datePipe.transform(new Date(data.value))
, tooltipValueGetter: (data: any) => this.datePipe.transform(new Date(data.value), 'medium') , tooltipValueGetter: (data: any) => this.datePipe.transform(new Date(data.value), 'medium'),
valueFormatter: (data: any) => { return data; },
},{ },{
colId: 'updatedAt', colId: 'updatedAt',
field: 'updatedAt' field: 'updatedAt'
@@ -86,6 +93,7 @@ export class KeysComponent {
, width: 140 , width: 140
, cellRenderer: AgDeleteKeyComponent , cellRenderer: AgDeleteKeyComponent
// , onCellClicked: (event) => { this.deleteKey(event.data.id)} // , onCellClicked: (event) => { this.deleteKey(event.data.id)}
,valueFormatter: (data: any) => { return data; },
} }
], ],
loading: true, loading: true,
@@ -98,6 +106,10 @@ export class KeysComponent {
this.api.deleteKey(id).subscribe() this.api.deleteKey(id).subscribe()
} }
editKey(id: string) {
}
ngOnInit(): void { ngOnInit(): void {
this.api.getCylinders().subscribe({ this.api.getCylinders().subscribe({
next: n => { next: n => {
@@ -168,6 +180,19 @@ export class KeysComponent {
}) })
} }
openSelectCylinder(params: any) {
this.dialog.open(SelectKeyCylinderComponent, {
maxWidth: "calc(100vw - 24px)",
width: "30vw",
minWidth: "200px",
disableClose: true
}).afterClosed().subscribe({
next: key => {
console.log(key)
}
})
}
openArchive() { openArchive() {
this.dialog.open(ArchiveComponent, { this.dialog.open(ArchiveComponent, {
maxHeight: "calc(100vh - 24px)", maxHeight: "calc(100vh - 24px)",

View File

@@ -1,3 +1,4 @@
<div class="handover icon-btn-sm" (click)="openHandoutDialog()" matTooltip="Schlüsselübergaben" [matTooltipShowDelay]="400"></div> <div class="handover icon-btn-sm" (click)="openHandoutDialog()" matTooltip="Schlüsselübergaben" [matTooltipShowDelay]="400"></div>
<div class="magnifying-glass icon-btn-sm" (click)="openLostKeyDialog()" matTooltip="Verloren melden" [matTooltipShowDelay]="400"></div> <div class="magnifying-glass icon-btn-sm" (click)="openLostKeyDialog()" matTooltip="Verloren melden" [matTooltipShowDelay]="400"></div>
<div class="delete icon-btn-sm" (click)="delete()" matTooltip="Löschen" [matTooltipShowDelay]="400"></div> <div class="delete icon-btn-sm" (click)="delete()" matTooltip="Löschen" [matTooltipShowDelay]="400"></div>
<!-- <div class="edit icon-btn-sm" (click)="edit()" matTooltip="Bearbeiten" [matTooltipShowDelay]="400"></div> -->

View File

@@ -9,6 +9,7 @@ import { HotToastService } from '@ngxpert/hot-toast';
import { HandoverDialogComponent } from '../../../../modules/keys/components/handover-dialog/handover-dialog.component'; import { HandoverDialogComponent } from '../../../../modules/keys/components/handover-dialog/handover-dialog.component';
import { MatTooltipModule } from '@angular/material/tooltip'; import { MatTooltipModule } from '@angular/material/tooltip';
import { LostKeyComponent } from '../../../../modules/keys/components/lost-key/lost-key.component'; import { LostKeyComponent } from '../../../../modules/keys/components/lost-key/lost-key.component';
import { CreateKeyComponent } from '../../../../modules/keys/create/create.component';
@Component({ @Component({
selector: 'app-ag-delete-key', selector: 'app-ag-delete-key',
@@ -50,6 +51,25 @@ export class AgDeleteKeyComponent implements ICellRendererAngularComp {
}) })
} }
edit() {
const ref = this.dialog.open(CreateKeyComponent, {
data: this.key,
autoFocus: false,
maxWidth: '100vw',
maxHeight: '100vh'
})
ref.afterClosed().subscribe({
next: n => {
if (n != null) {
this.key.handedOut = n;
this.params.api.refreshCells();
}
}
});
// ref.componentInstance.editKey(this.key)
}
deleteThisKey() { deleteThisKey() {
this.params.api.setGridOption("loading", true); this.params.api.setGridOption("loading", true);
this.api.deleteKey(this.key.id).pipe( this.api.deleteKey(this.key.id).pipe(

View File

@@ -0,0 +1 @@
<svg height="401pt" viewBox="0 -1 401.52289 401" width="401pt" xmlns="http://www.w3.org/2000/svg"><path d="m370.589844 250.972656c-5.523438 0-10 4.476563-10 10v88.789063c-.019532 16.5625-13.4375 29.984375-30 30h-280.589844c-16.5625-.015625-29.980469-13.4375-30-30v-260.589844c.019531-16.558594 13.4375-29.980469 30-30h88.789062c5.523438 0 10-4.476563 10-10 0-5.519531-4.476562-10-10-10h-88.789062c-27.601562.03125-49.96875 22.398437-50 50v260.59375c.03125 27.601563 22.398438 49.96875 50 50h280.589844c27.601562-.03125 49.96875-22.398437 50-50v-88.792969c0-5.523437-4.476563-10-10-10zm0 0"/><path d="m376.628906 13.441406c-17.574218-17.574218-46.066406-17.574218-63.640625 0l-178.40625 178.40625c-1.222656 1.222656-2.105469 2.738282-2.566406 4.402344l-23.460937 84.699219c-.964844 3.472656.015624 7.191406 2.5625 9.742187 2.550781 2.546875 6.269531 3.527344 9.742187 2.566406l84.699219-23.464843c1.664062-.460938 3.179687-1.34375 4.402344-2.566407l178.402343-178.410156c17.546875-17.585937 17.546875-46.054687 0-63.640625zm-220.257812 184.90625 146.011718-146.015625 47.089844 47.089844-146.015625 146.015625zm-9.40625 18.875 37.621094 37.625-52.039063 14.417969zm227.257812-142.546875-10.605468 10.605469-47.09375-47.09375 10.609374-10.605469c9.761719-9.761719 25.589844-9.761719 35.351563 0l11.738281 11.734375c9.746094 9.773438 9.746094 25.589844 0 35.359375zm0 0"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -88,6 +88,10 @@ html, body {
background-image: url("./assets/img/delete.svg"); background-image: url("./assets/img/delete.svg");
} }
.edit {
background-image: url("./assets/img/edit.svg");
}
.restore { .restore {
background-image: url("./assets/img/restore.svg"); background-image: url("./assets/img/restore.svg");
} }