fixes
This commit is contained in:
@@ -6,7 +6,6 @@ import {
|
|||||||
Entity,
|
Entity,
|
||||||
ManyToMany,
|
ManyToMany,
|
||||||
ManyToOne,
|
ManyToOne,
|
||||||
OneToMany,
|
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
@@ -18,9 +17,12 @@ export class Cylinder {
|
|||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
@Column({ nullable: false, unique: true })
|
@Column({ nullable: false })
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
|
@Column({ name:'description', type: 'text', nullable: true })
|
||||||
|
description: string;
|
||||||
|
|
||||||
@ManyToMany(() => Key, (key) => key.cylinder, { onDelete: 'NO ACTION'})
|
@ManyToMany(() => Key, (key) => key.cylinder, { onDelete: 'NO ACTION'})
|
||||||
keys: Key[];
|
keys: Key[];
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ export class CylinderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createCylinder(user: User, cylinder: Partial<Cylinder>) {
|
async createCylinder(user: User, cylinder: Partial<Cylinder>) {
|
||||||
|
try {
|
||||||
const c = await this.cylinderRepo.save(this.cylinderRepo.create(cylinder));
|
const c = await this.cylinderRepo.save(this.cylinderRepo.create(cylinder));
|
||||||
|
|
||||||
this.systemActivityRepo.save({
|
this.systemActivityRepo.save({
|
||||||
@@ -68,6 +69,10 @@ export class CylinderService {
|
|||||||
system: (c as any).system
|
system: (c as any).system
|
||||||
});
|
});
|
||||||
return c
|
return c
|
||||||
|
} catch (e) {
|
||||||
|
// this.log.log()
|
||||||
|
throw new HttpException('Zylinder konnte nicht angelegt werden', HttpStatus.BAD_REQUEST)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getDeletedCylinders(user: User) {
|
getDeletedCylinders(user: User) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
Delete,
|
Delete,
|
||||||
Req,
|
Req,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
|
Put,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { SystemService } from './system.service';
|
import { SystemService } from './system.service';
|
||||||
import { CreateSystemDto } from './dto/create-system.dto';
|
import { CreateSystemDto } from './dto/create-system.dto';
|
||||||
@@ -47,7 +48,7 @@ export class SystemController {
|
|||||||
return this.systemService.findOne(id);
|
return this.systemService.findOne(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(':id')
|
@Put(':id')
|
||||||
update(@Param('id') id: string, @Body() updateSystemDto: UpdateSystemDto) {
|
update(@Param('id') id: string, @Body() updateSystemDto: UpdateSystemDto) {
|
||||||
return this.systemService.update(id, updateSystemDto);
|
return this.systemService.update(id, updateSystemDto);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { IKey } from "./key.interface";
|
|||||||
export interface ICylinder {
|
export interface ICylinder {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
description: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
deletedAt: string;
|
deletedAt: string;
|
||||||
|
|||||||
@@ -12,6 +12,12 @@
|
|||||||
}
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Beschreibung</mat-label>
|
||||||
|
<input type="text" matInput formControlName="description" maxlength="255">
|
||||||
|
<mat-hint>Zylinderlänge und co.</mat-hint>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Schließanlage</mat-label>
|
<mat-label>Schließanlage</mat-label>
|
||||||
<mat-select formControlName="system">
|
<mat-select formControlName="system">
|
||||||
|
|||||||
@@ -25,11 +25,12 @@ export class CreateCylinderComponent {
|
|||||||
|
|
||||||
createForm = new FormGroup({
|
createForm = new FormGroup({
|
||||||
name: new FormControl<string | null>(null, Validators.required),
|
name: new FormControl<string | null>(null, Validators.required),
|
||||||
system: new FormControl<any>(null, Validators.required)
|
system: new FormControl<any>(null, Validators.required),
|
||||||
|
description: new FormControl<string | null>(null)
|
||||||
});
|
});
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.api.getSystems().subscribe({
|
this.api.systems.asObservable().subscribe({
|
||||||
next: systems => {
|
next: systems => {
|
||||||
this.systems = systems;
|
this.systems = systems;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { HELPER } from '../../shared/helper.service';
|
import { HELPER } from '../../shared/helper.service';
|
||||||
import { GridApi, GridOptions, GridReadyEvent } from 'ag-grid-community';
|
import { CellEditingStoppedEvent, GridApi, GridOptions, GridReadyEvent } from 'ag-grid-community';
|
||||||
import { AgGridAngular } from 'ag-grid-angular';
|
import { AgGridAngular } from 'ag-grid-angular';
|
||||||
import { ApiService } from '../../shared/api.service';
|
import { ApiService } from '../../shared/api.service';
|
||||||
import { DatePipe } from '@angular/common';
|
import { DatePipe } from '@angular/common';
|
||||||
@@ -11,6 +11,7 @@ import { MatIconModule } from '@angular/material/icon';
|
|||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { AgGridContainerComponent } from '../../shared/ag-grid/components/ag-grid-container/ag-grid-container.component';
|
import { AgGridContainerComponent } from '../../shared/ag-grid/components/ag-grid-container/ag-grid-container.component';
|
||||||
import { CylinderArchiveComponent } from './components/cylinder-archive/cylinder-archive.component';
|
import { CylinderArchiveComponent } from './components/cylinder-archive/cylinder-archive.component';
|
||||||
|
import { ICylinder } from '../../model/interface/cylinder.interface';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-cylinder',
|
selector: 'app-cylinder',
|
||||||
@@ -33,7 +34,8 @@ export class CylinderComponent extends AgGridContainerComponent {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.gridOptions.columnDefs = [
|
this.gridOptions.columnDefs = [
|
||||||
{ field: 'name', headerName: 'Name', sort: 'asc', flex: 1, filter: true },
|
{ field: 'name', headerName: 'Name', sort: 'asc', flex: 1, filter: true, editable: true },
|
||||||
|
{ field: 'description', headerName: 'Beschreibung', flex: 1, filter: true, editable: true },
|
||||||
{ field: 'system.name', headerName: 'System', flex: 1, filter: true },
|
{ field: 'system.name', headerName: 'System', flex: 1, filter: true },
|
||||||
{ field: 'keyCount', headerName: 'Anzahl Schlüssel', flex: 0, type: 'number' },
|
{ field: 'keyCount', headerName: 'Anzahl Schlüssel', flex: 0, type: 'number' },
|
||||||
{ field: 'createdAt', headerName: 'Angelegt', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
{ field: 'createdAt', headerName: 'Angelegt', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
||||||
@@ -54,6 +56,7 @@ export class CylinderComponent extends AgGridContainerComponent {
|
|||||||
|
|
||||||
onGridReady(params: GridReadyEvent) {
|
onGridReady(params: GridReadyEvent) {
|
||||||
this.gridApi = params.api;
|
this.gridApi = params.api;
|
||||||
|
this.gridApi.addEventListener("cellEditingStopped", evt => this.cellEditEnd(evt));
|
||||||
this.loadCylinders();
|
this.loadCylinders();
|
||||||
this.api.cylinders.asObservable().subscribe({
|
this.api.cylinders.asObservable().subscribe({
|
||||||
next: (data) => {
|
next: (data) => {
|
||||||
@@ -63,6 +66,15 @@ export class CylinderComponent extends AgGridContainerComponent {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async cellEditEnd(event: CellEditingStoppedEvent) {
|
||||||
|
const cylinder: ICylinder = event.data;
|
||||||
|
|
||||||
|
if (!event.valueChanged || event.newValue == event.oldValue) { return; }
|
||||||
|
|
||||||
|
await this.api.updateCylinder(cylinder)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
openCreateCylinder() {
|
openCreateCylinder() {
|
||||||
this.dialog.open(CreateCylinderComponent, {
|
this.dialog.open(CreateCylinderComponent, {
|
||||||
maxWidth: "calc(100vw - 24px)",
|
maxWidth: "calc(100vw - 24px)",
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
style="width: 100%; height: 100%;"
|
style="width: 100%; height: 100%;"
|
||||||
(gridReady)="onGridReady($event)"
|
(gridReady)="onGridReady($event)"
|
||||||
[gridOptions]="gridOptions!"
|
[gridOptions]="gridOptions!"
|
||||||
|
[theme]="myTheme"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { GridApi, GridOptions, GridReadyEvent } from 'ag-grid-community';
|
|||||||
import { AG_GRID_LOCALE_DE } from '@ag-grid-community/locale';
|
import { AG_GRID_LOCALE_DE } from '@ag-grid-community/locale';
|
||||||
import { AgGridAngular } from 'ag-grid-angular';
|
import { AgGridAngular } from 'ag-grid-angular';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { AgGridContainerComponent } from '../../../../shared/ag-grid/components/ag-grid-container/ag-grid-container.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-handover-dialog',
|
selector: 'app-handover-dialog',
|
||||||
@@ -38,7 +39,7 @@ import { MatIconModule } from '@angular/material/icon';
|
|||||||
templateUrl: './handover-dialog.component.html',
|
templateUrl: './handover-dialog.component.html',
|
||||||
styleUrl: './handover-dialog.component.scss'
|
styleUrl: './handover-dialog.component.scss'
|
||||||
})
|
})
|
||||||
export class HandoverDialogComponent {
|
export class HandoverDialogComponent extends AgGridContainerComponent {
|
||||||
|
|
||||||
private api: ApiService = inject(ApiService);
|
private api: ApiService = inject(ApiService);
|
||||||
readonly dialogRef = inject(MatDialogRef<HandoverDialogComponent>);
|
readonly dialogRef = inject(MatDialogRef<HandoverDialogComponent>);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
style="width: 100%; height: 100%;"
|
style="width: 100%; height: 100%;"
|
||||||
(gridReady)="onGridReady($event)"
|
(gridReady)="onGridReady($event)"
|
||||||
[gridOptions]="gridOptions!"
|
[gridOptions]="gridOptions!"
|
||||||
|
[theme]="myTheme"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { GridApi, GridOptions, GridReadyEvent } from 'ag-grid-community';
|
|||||||
import { AG_GRID_LOCALE_DE } from '@ag-grid-community/locale';
|
import { AG_GRID_LOCALE_DE } from '@ag-grid-community/locale';
|
||||||
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { AgGridContainerComponent } from '../../../../shared/ag-grid/components/ag-grid-container/ag-grid-container.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-select-key-cylinder',
|
selector: 'app-select-key-cylinder',
|
||||||
@@ -14,7 +15,7 @@ import { MatButtonModule } from '@angular/material/button';
|
|||||||
templateUrl: './select-key-cylinder.component.html',
|
templateUrl: './select-key-cylinder.component.html',
|
||||||
styleUrl: './select-key-cylinder.component.scss'
|
styleUrl: './select-key-cylinder.component.scss'
|
||||||
})
|
})
|
||||||
export class SelectKeyCylinderComponent {
|
export class SelectKeyCylinderComponent extends AgGridContainerComponent {
|
||||||
private toast: HotToastService = inject(HotToastService);
|
private toast: HotToastService = inject(HotToastService);
|
||||||
readonly dialogRef = inject(MatDialogRef<SelectKeyCylinderComponent>);
|
readonly dialogRef = inject(MatDialogRef<SelectKeyCylinderComponent>);
|
||||||
readonly cylinders = inject<ICylinder[]>(MAT_DIALOG_DATA);
|
readonly cylinders = inject<ICylinder[]>(MAT_DIALOG_DATA);
|
||||||
|
|||||||
@@ -149,7 +149,6 @@ export class KeysComponent extends AgGridContainerComponent {
|
|||||||
this.gridApi.addEventListener("cellEditingStopped", evt => this.cellEditEnd(evt));
|
this.gridApi.addEventListener("cellEditingStopped", evt => this.cellEditEnd(evt));
|
||||||
this.api.keys.asObservable().subscribe({
|
this.api.keys.asObservable().subscribe({
|
||||||
next: keys => {
|
next: keys => {
|
||||||
console.log(keys)
|
|
||||||
this.gridApi.setGridOption("rowData", keys);
|
this.gridApi.setGridOption("rowData", keys);
|
||||||
this.gridApi.setGridOption("loading", false);
|
this.gridApi.setGridOption("loading", false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export class SystemComponent extends AgGridContainerComponent {
|
|||||||
super();
|
super();
|
||||||
this.gridOptions.columnDefs = [
|
this.gridOptions.columnDefs = [
|
||||||
{ colId: 'name', field: 'name', headerName: 'Name', sort: 'asc', flex: 1},
|
{ colId: 'name', field: 'name', headerName: 'Name', sort: 'asc', flex: 1},
|
||||||
{ colId: 'cylinderCount', field: 'cylinders', headerName: 'Zylinderanzahl', flex: 0, cellRenderer: (data: any) => data.value.length},
|
{ colId: 'cylinderCount', field: 'cylinders', headerName: 'Zylinderanzahl', flex: 0, cellRenderer: (data: any) => data.value?.length || 0},
|
||||||
{ field: 'createdAt', headerName: 'Angelegt', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
{ field: 'createdAt', headerName: 'Angelegt', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
||||||
{ field: 'updatedAt', headerName: 'Upgedated', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
{ field: 'updatedAt', headerName: 'Upgedated', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
||||||
{
|
{
|
||||||
@@ -43,17 +43,20 @@ export class SystemComponent extends AgGridContainerComponent {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
loadSystems() {
|
async loadSystems() {
|
||||||
this.api.getSystems().subscribe({
|
this.gridApi.setGridOption("loading", true);
|
||||||
next: n => {
|
await this.api.refreshSystems();
|
||||||
this.gridApi.setGridOption("rowData", n);
|
|
||||||
this.gridApi.setGridOption("loading", false);
|
this.gridApi.setGridOption("loading", false);
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onGridReady(params: GridReadyEvent) {
|
onGridReady(params: GridReadyEvent) {
|
||||||
this.gridApi = params.api;
|
this.gridApi = params.api;
|
||||||
|
this.api.systems.asObservable().subscribe({
|
||||||
|
next: systems => {
|
||||||
|
this.gridApi.setGridOption("rowData", systems);
|
||||||
|
this.gridApi.setGridOption("loading", false);
|
||||||
|
}
|
||||||
|
})
|
||||||
this.loadSystems();
|
this.loadSystems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export class ApiService {
|
|||||||
|
|
||||||
public keys: BehaviorSubject<IKey[]> = new BehaviorSubject<IKey[]>([]);
|
public keys: BehaviorSubject<IKey[]> = new BehaviorSubject<IKey[]>([]);
|
||||||
public cylinders: BehaviorSubject<ICylinder[]> = new BehaviorSubject<ICylinder[]>([]);
|
public cylinders: BehaviorSubject<ICylinder[]> = new BehaviorSubject<ICylinder[]>([]);
|
||||||
|
public systems: BehaviorSubject<any[]> = new BehaviorSubject<any[]>([]);
|
||||||
|
|
||||||
|
|
||||||
public user: BehaviorSubject<IUser> = new BehaviorSubject<IUser>(null!);
|
public user: BehaviorSubject<IUser> = new BehaviorSubject<IUser>(null!);
|
||||||
@@ -73,6 +74,24 @@ export class ApiService {
|
|||||||
return this.http.put<IKey>('api/key', key);
|
return this.http.put<IKey>('api/key', key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateCylinder(cylinder: ICylinder): Promise<boolean> {
|
||||||
|
return new Promise<boolean>(resolve => {
|
||||||
|
this.http.put('api/cylinder', cylinder).pipe(
|
||||||
|
this.toast.observe({
|
||||||
|
loading: `Zylinder ${cylinder} wird gespeichert...`,
|
||||||
|
success: `Zylinder ${cylinder.name} gespeichert.`,
|
||||||
|
error: 'Es ist ein Fehler aufgetreten'
|
||||||
|
})
|
||||||
|
).subscribe({
|
||||||
|
next: () => resolve(true),
|
||||||
|
error: () => resolve(false),
|
||||||
|
complete: () => {
|
||||||
|
this.refreshCylinders()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
createKey(key: any) {
|
createKey(key: any) {
|
||||||
return this.http.post<IKey>('api/key', key);
|
return this.http.post<IKey>('api/key', key);
|
||||||
}
|
}
|
||||||
@@ -81,7 +100,7 @@ export class ApiService {
|
|||||||
return this.http.post('api/system', keySystem);
|
return this.http.post('api/system', keySystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
getSystems(): Observable<any[]> {
|
private getSystems(): Observable<any[]> {
|
||||||
return this.http.get<any[]>('api/system');
|
return this.http.get<any[]>('api/system');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,6 +158,24 @@ export class ApiService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteSystem(system: any): Promise<boolean> {
|
||||||
|
return new Promise<boolean>(resolve => {
|
||||||
|
this.http.delete(`api/system${system.id}`).pipe(
|
||||||
|
this.toast.observe({
|
||||||
|
loading: `Lösche Schließsystem ${system.name}...`,
|
||||||
|
success: `Schließsystem ${system.name} wurde gelöscht.`,
|
||||||
|
error: 'Es ist ein Fehler aufgetreten'
|
||||||
|
})
|
||||||
|
).subscribe({
|
||||||
|
next: () => resolve(true),
|
||||||
|
error: () => resolve(false),
|
||||||
|
complete: () => {
|
||||||
|
this.refreshSystems();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
getKeyArchive(): Observable<IKey[]> {
|
getKeyArchive(): Observable<IKey[]> {
|
||||||
return this.http.get<IKey[]>('api/key/archive');
|
return this.http.get<IKey[]>('api/key/archive');
|
||||||
}
|
}
|
||||||
@@ -184,6 +221,21 @@ export class ApiService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshSystems(): Promise<void> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.getSystems().subscribe({
|
||||||
|
next: data => {
|
||||||
|
this.systems.next(data);
|
||||||
|
resolve()
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
this.toast.error('Fehler beim Laden der Schließsysteme')
|
||||||
|
},
|
||||||
|
complete: () => resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
deleteCylinder(cylinder: ICylinder): Promise<boolean> {
|
deleteCylinder(cylinder: ICylinder): Promise<boolean> {
|
||||||
return new Promise<boolean>(resolve => {
|
return new Promise<boolean>(resolve => {
|
||||||
this.http.delete(`api/cylinder/${cylinder.id}`).pipe(
|
this.http.delete(`api/cylinder/${cylinder.id}`).pipe(
|
||||||
|
|||||||
@@ -216,6 +216,6 @@ div.ag-row {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ag-filter-body-wrapper {
|
.ag-filter-body-wrapper {
|
||||||
padding: 8px;
|
padding: 8px 12px;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user