schlüssel neuen zylindern zuordnen geht
This commit is contained in:
@@ -122,5 +122,8 @@
|
||||
"@schematics/angular:resolver": {
|
||||
"typeSeparator": "."
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
|
||||
1293
client/package-lock.json
generated
1293
client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -78,16 +78,11 @@ export class LostKeysComponent extends AgGridContainerComponent {
|
||||
|
||||
markAsFound(key: IKey) {
|
||||
this.dialog.open(LostKeyComponent, { data: key, autoFocus: false }).afterClosed().subscribe({
|
||||
next: (result) => {
|
||||
next: async (result) => {
|
||||
if (result == "") {
|
||||
key.keyLost = null;
|
||||
this.api.updateKey(key).subscribe({
|
||||
next: () => {
|
||||
this.toast.success('Schlüssel als gefunden markiert');
|
||||
this.loadLostKeys();
|
||||
this.api.refreshKeys();
|
||||
}
|
||||
});
|
||||
await this.api.updateKey(key);
|
||||
this.loadLostKeys();
|
||||
this.dataChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<h2 mat-dialog-title>Mehrere Schließanlagen gewählt!</h2>
|
||||
<mat-dialog-content>
|
||||
<div class="warning-message">
|
||||
<mat-icon>warning</mat-icon>
|
||||
<p>
|
||||
Der Schlüssel ist Zylindern in mehreren Schließanlagen zugeordnet!
|
||||
</p>
|
||||
<p class="additional-info">
|
||||
<!-- Additional information -->
|
||||
<small>Zum Korrigieren abbrechen, ansonsten speichern</small>
|
||||
</p>
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions align="end">
|
||||
<button matButton [mat-dialog-close]="false">
|
||||
<mat-icon>close</mat-icon>
|
||||
Vorgang abbrechen
|
||||
</button>
|
||||
<button matButton="elevated" [mat-dialog-close]="true" class="btn-warning">
|
||||
<mat-icon>check</mat-icon>
|
||||
Schlüssel speichern
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MultipleCylinderSystemsDialogComponent } from './multiple-cylinder-systems-dialog.component';
|
||||
|
||||
describe('MultipleCylinderSystemsDialogComponent', () => {
|
||||
let component: MultipleCylinderSystemsDialogComponent;
|
||||
let fixture: ComponentFixture<MultipleCylinderSystemsDialogComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [MultipleCylinderSystemsDialogComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(MultipleCylinderSystemsDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
|
||||
@Component({
|
||||
selector: 'app-multiple-cylinder-systems-dialog',
|
||||
imports: [MatDialogModule, MatButtonModule, MatIconModule],
|
||||
templateUrl: './multiple-cylinder-systems-dialog.component.html',
|
||||
styleUrl: './multiple-cylinder-systems-dialog.component.scss',
|
||||
})
|
||||
export class MultipleCylinderSystemsDialogComponent {
|
||||
|
||||
}
|
||||
@@ -11,6 +11,6 @@
|
||||
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button matButton [mat-dialog-close]="null">Abbrechen</button>
|
||||
<button matButton [mat-dialog-close]="selectedCylinders">Übernehmen</button>
|
||||
<button matButton (click)="close(false)">Abbrechen</button>
|
||||
<button matButton="elevated" (click)="close(true)" class="btn-primary" [disabled]="selectedCylinders.length < 1" >Übernehmen</button>
|
||||
</mat-dialog-actions>
|
||||
@@ -3,11 +3,12 @@ import { ApiService } from '../../../../shared/api.service';
|
||||
import { ICylinder } from '../../../../model/interface/cylinder.interface';
|
||||
import { HotToastService } from '@ngxpert/hot-toast';
|
||||
import { AgGridAngular } from 'ag-grid-angular';
|
||||
import { GridApi, GridOptions, GridReadyEvent } from 'ag-grid-community';
|
||||
import { GridApi, GridOptions, GridReadyEvent, IRowNode } from 'ag-grid-community';
|
||||
import { AG_GRID_LOCALE_DE } from '@ag-grid-community/locale';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||
import { MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { AgGridContainerComponent } from '../../../../shared/ag-grid/components/ag-grid-container/ag-grid-container.component';
|
||||
import { MultipleCylinderSystemsDialogComponent } from './multiple-cylinder-systems-dialog/multiple-cylinder-systems-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-select-key-cylinder',
|
||||
@@ -20,6 +21,8 @@ export class SelectKeyCylinderComponent extends AgGridContainerComponent {
|
||||
readonly dialogRef = inject(MatDialogRef<SelectKeyCylinderComponent>);
|
||||
readonly cylinders = inject<ICylinder[]>(MAT_DIALOG_DATA);
|
||||
|
||||
private dialog = inject(MatDialog);
|
||||
|
||||
gridApi!: GridApi;
|
||||
|
||||
gridOptions: GridOptions = {
|
||||
@@ -48,6 +51,46 @@ export class SelectKeyCylinderComponent extends AgGridContainerComponent {
|
||||
}
|
||||
|
||||
selectionChanged(): void {
|
||||
this.selectedCylinders =this.gridApi?.getSelectedRows();
|
||||
this.selectedCylinders = this.gridApi?.getSelectedRows();
|
||||
if (this.selectedCylinders.length == 0 ) {
|
||||
this.toast.info('Jeder Schlüssel muss mindestens einem Zylinder zugeordnet sein. Bitte Zylinder wählen.')
|
||||
}
|
||||
}
|
||||
|
||||
preselectCylinders(cylinders: ICylinder[]) {
|
||||
this.gridApi.setGridOption('loading', true)
|
||||
|
||||
const nodesToSelect: IRowNode<ICylinder>[] = [];
|
||||
this.gridApi.forEachNode(node => {
|
||||
if (cylinders.some(c => c.id == node.data.id )) {
|
||||
nodesToSelect.push(node);
|
||||
}
|
||||
})
|
||||
this.gridApi.setNodesSelected({
|
||||
nodes: nodesToSelect,
|
||||
newValue: true
|
||||
})
|
||||
this.gridApi.setGridOption('loading', false)
|
||||
}
|
||||
|
||||
async close(data = false) {
|
||||
if (!data) { return this.dialogRef.close() }
|
||||
|
||||
|
||||
const amountOfSystems = Array.from(new Set(this.selectedCylinders.map( c => c.system.id )));
|
||||
if (amountOfSystems.length == 1) {
|
||||
return this.dialogRef.close(this.selectedCylinders);
|
||||
}
|
||||
|
||||
this.dialog.open(MultipleCylinderSystemsDialogComponent, {}).afterClosed().subscribe({
|
||||
next: val => {
|
||||
if (val) {
|
||||
return this.dialogRef.close(this.selectedCylinders);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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, FilterActionParams, FilterAction, themeQuartz, Theme, ThemeDefaultParams } from 'ag-grid-community';
|
||||
import { GridOptions,GridApi, GridReadyEvent, CellEditingStoppedEvent, ICellEditorParams, FilterActionParams, FilterAction, themeQuartz, Theme, ThemeDefaultParams, AgGridEvent, CellClickedEvent, CellDoubleClickedEvent } from 'ag-grid-community';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { ApiService } from '../../shared/api.service';
|
||||
import { IKey } from '../../model/interface/key.interface';
|
||||
@@ -54,7 +54,9 @@ export class KeysComponent extends AgGridContainerComponent {
|
||||
valueFormatter: (data: any) => { return data; },
|
||||
cellRenderer: (data: any) => {return data.value?.map((m: ICylinder) => m.name).join(', ')},
|
||||
tooltipValueGetter: (data: any) => data.value?.map((m: ICylinder) => m.name).join(','),
|
||||
onCellDoubleClicked(event) {},
|
||||
onCellDoubleClicked: (event) => {
|
||||
this.openSelectCylinder(event)
|
||||
},
|
||||
cellEditorPopup: true,
|
||||
filterValueGetter: (params: any) => {return params.data.cylinder?.map((m: ICylinder) => m.name).join(', ')},
|
||||
},
|
||||
@@ -157,24 +159,13 @@ export class KeysComponent extends AgGridContainerComponent {
|
||||
this.setFilterToParams();
|
||||
}
|
||||
|
||||
cellEditEnd(event: CellEditingStoppedEvent) {
|
||||
async 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();
|
||||
}
|
||||
})
|
||||
await this.api.updateKey(key)
|
||||
this.gridApi.setGridOption("loading", false);
|
||||
}
|
||||
|
||||
openCreateKey() {
|
||||
@@ -195,17 +186,33 @@ export class KeysComponent extends AgGridContainerComponent {
|
||||
})
|
||||
}
|
||||
|
||||
openSelectCylinder(params: any) {
|
||||
this.dialog.open(SelectKeyCylinderComponent, {
|
||||
async openSelectCylinder(event: CellDoubleClickedEvent) {
|
||||
const key: IKey = event.data;
|
||||
this.gridApi.setGridOption("loading", true);
|
||||
const cylinders = await this.api.refreshCylinders()
|
||||
this.gridApi.setGridOption('loading', false)
|
||||
const ref = this.dialog.open(SelectKeyCylinderComponent, {
|
||||
data: cylinders,
|
||||
maxHeight: "calc(100vh - 24px)",
|
||||
maxWidth: "calc(100vw - 24px)",
|
||||
width: "30vw",
|
||||
minWidth: "200px",
|
||||
disableClose: true
|
||||
}).afterClosed().subscribe({
|
||||
next: key => {
|
||||
console.log(key)
|
||||
width: "50vw",
|
||||
minWidth: "300px",
|
||||
height: "70vh",
|
||||
disableClose: true,
|
||||
});
|
||||
|
||||
ref.afterOpened().subscribe({
|
||||
next: () => {
|
||||
ref.componentInstance.preselectCylinders(event.data.cylinder);
|
||||
}
|
||||
})
|
||||
ref.afterClosed().subscribe({
|
||||
next: (cylinders: ICylinder[]) => {
|
||||
if (cylinders == null) { return; }
|
||||
key.cylinder = cylinders;
|
||||
this.api.updateKey(key)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
openArchive() {
|
||||
|
||||
@@ -105,8 +105,7 @@ export class AgKeyActionsComponent implements ICellRendererAngularComp {
|
||||
}
|
||||
this.key.keyLost = n;
|
||||
this.params.api.refreshCells();
|
||||
await this.api.updateKey(this.key).subscribe();
|
||||
this.api.refreshKeys();
|
||||
await this.api.updateKey(this.key)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -76,8 +76,20 @@ export class ApiService {
|
||||
return this.http.get<IKey[]>('api/key/lost')
|
||||
}
|
||||
|
||||
updateKey(key: IKey): Observable<IKey> {
|
||||
return this.http.put<IKey>('api/key', key);
|
||||
updateKey(key: IKey): Promise<IKey | null> {
|
||||
return new Promise<IKey | null>(resolve => {
|
||||
this.http.put<IKey>('api/key', key).pipe(
|
||||
this.toast.observe({
|
||||
loading: `Speichere Schlüssel ${key.name}....`,
|
||||
success: `Schlüssel ${key.name} gespeichert.`,
|
||||
error: `Es ist ein Fehler aufgetreten!`
|
||||
})
|
||||
).subscribe({
|
||||
next: (key: IKey) => resolve(key),
|
||||
error: () => resolve(null),
|
||||
complete: () => { this.refreshKeys(); }
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
updateCylinder(cylinder: ICylinder): Promise<boolean> {
|
||||
@@ -275,8 +287,8 @@ export class ApiService {
|
||||
* cylinders
|
||||
* @returns Promise wenn geladen
|
||||
*/
|
||||
refreshCylinders(): Promise<void> {
|
||||
return new Promise<void>(resolve => {
|
||||
refreshCylinders(): Promise<ICylinder[]> {
|
||||
return new Promise<ICylinder[]>(resolve => {
|
||||
this.getCylinders().subscribe({
|
||||
next: data => {
|
||||
this.cylinders.next(data);
|
||||
@@ -284,7 +296,7 @@ export class ApiService {
|
||||
error: () => {
|
||||
this.toast.error('Fehler beim Laden der Zylinder')
|
||||
},
|
||||
complete: () => resolve()
|
||||
complete: () => resolve(this.cylinders.value)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user