Digitale Zylinder eingebaut

This commit is contained in:
Bastian Wagner
2026-02-24 14:55:19 +01:00
parent e5c590165c
commit f7e9ee493b
7 changed files with 42 additions and 27 deletions

View File

@@ -23,6 +23,10 @@ export class Cylinder {
@Column({ name:'description', type: 'text', nullable: true }) @Column({ name:'description', type: 'text', nullable: true })
description: string; description: string;
@Column({name: 'is_digital', type: 'boolean', default: false})
isDigital: boolean;
@ManyToMany(() => Key, (key) => key.cylinder, { onDelete: 'NO ACTION'}) @ManyToMany(() => Key, (key) => key.cylinder, { onDelete: 'NO ACTION'})
keys: Key[]; keys: Key[];

View File

@@ -1,10 +1,11 @@
<h2 mat-dialog-title>Neuen Zylinder anlegen</h2> <h2 mat-dialog-title>Neuen Zylinder anlegen</h2>
<mat-dialog-content> <mat-dialog-content>
<div class="mat-body" style="margin-bottom: 24px;">Hier können Zylinder angelegt werden. Jeder Zylinder muss genau einer Schließanlage zugeordnet werden. Es können mehrere Schlüssel zu einem Zylinder zugeordnet werden.</div>
<form [formGroup]="createForm" class="flex flex-col gap-3"> <form [formGroup]="createForm" class="flex flex-col gap-3">
<mat-form-field> <mat-form-field>
<mat-label>Name</mat-label> <mat-label>Name</mat-label>
<input type="text" matInput formControlName="name" maxlength="100"> <input type="text" matInput formControlName="name" maxlength="100" placeholder="Bsp.: Haustür Ferienhaus">
@if ((createForm.controls.name.value || '').length > 20) { @if ((createForm.controls.name.value || '').length > 20) {
<mat-hint>{{ (createForm.controls.name.value || '').length }} / 100 Zeichen</mat-hint> <mat-hint>{{ (createForm.controls.name.value || '').length }} / 100 Zeichen</mat-hint>
} @else { } @else {
@@ -12,11 +13,16 @@
} }
</mat-form-field> </mat-form-field>
<mat-form-field> <div class="flex items-center gap-6">
<mat-label>Beschreibung</mat-label> <mat-form-field class="flex-auto">
<input type="text" matInput formControlName="description" maxlength="255"> <mat-label>Beschreibung</mat-label>
<mat-hint>Zylinderlänge und co.</mat-hint> <input type="text" matInput formControlName="description" maxlength="255" placeholder="Bsp.: 30/30">
</mat-form-field> <mat-hint>Zylinderlänge und co.</mat-hint>
</mat-form-field>
<mat-checkbox formControlName="isDigital">Digitales Schloss</mat-checkbox>
</div>
<mat-form-field> <mat-form-field>
@@ -27,9 +33,11 @@
} }
</mat-select> </mat-select>
<mat-hint>Zu welcher Schließanlage gehört der Zylinder?</mat-hint> <mat-hint>Zu welcher Schließanlage gehört der Zylinder?</mat-hint>
<mat-progress-bar mode="indeterminate" *ngIf="isLoading"></mat-progress-bar> @if (isLoading) {
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
}
</mat-form-field> </mat-form-field>
</form> </form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions> <mat-dialog-actions>

View File

@@ -11,10 +11,11 @@ import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressBarModule } from '@angular/material/progress-bar';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MatCheckboxModule } from '@angular/material/checkbox';
@Component({ @Component({
selector: 'app-create-cylinder', selector: 'app-create-cylinder',
imports: [MatFormFieldModule, MatInputModule, MatDialogModule, ReactiveFormsModule, FormsModule, MatSelectModule, MatButtonModule, MatIconModule, MatProgressBarModule, CommonModule], imports: [MatFormFieldModule, MatInputModule, MatDialogModule, ReactiveFormsModule, FormsModule, MatSelectModule, MatButtonModule, MatIconModule, MatProgressBarModule, CommonModule, MatCheckboxModule],
templateUrl: './create-cylinder.component.html', templateUrl: './create-cylinder.component.html',
styleUrl: './create-cylinder.component.scss' styleUrl: './create-cylinder.component.scss'
}) })
@@ -29,7 +30,8 @@ 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) description: new FormControl<string | null>(null),
isDigital: new FormControl<boolean>(false)
}); });
ngOnInit() { ngOnInit() {

View File

@@ -12,6 +12,7 @@ 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'; import { ICylinder } from '../../model/interface/cylinder.interface';
import { DialogPosition } from '@angular/material/dialog'
@Component({ @Component({
selector: 'app-cylinder', selector: 'app-cylinder',
@@ -77,10 +78,10 @@ export class CylinderComponent extends AgGridContainerComponent {
openCreateCylinder() { openCreateCylinder() {
this.dialog.open(CreateCylinderComponent, { this.dialog.open(CreateCylinderComponent, {
maxWidth: "calc(100vw - 24px)", maxWidth: "calc(100vw - 48px)",
width: "30vw", width: "800px",
minWidth: "200px", minWidth: "200px",
disableClose: true disableClose: true,
}).afterClosed().subscribe({ }).afterClosed().subscribe({
next: (cylinder) => { next: (cylinder) => {
if (cylinder) { if (cylinder) {
@@ -92,9 +93,9 @@ export class CylinderComponent extends AgGridContainerComponent {
openArchive() { openArchive() {
this.dialog.open(CylinderArchiveComponent, { this.dialog.open(CylinderArchiveComponent, {
maxHeight: "calc(100vh - 24px)", maxHeight: "calc(100vh - 48px)",
maxWidth: "calc(100vw - 24px)", maxWidth: "calc(100vw - 48px)",
width: "50vw", width: "800px",
minWidth: "min(700px,calc(100vw - 24px))", minWidth: "min(700px,calc(100vw - 24px))",
height: "70vh", height: "70vh",
}) })

View File

@@ -4,19 +4,19 @@
<mat-form-field> <mat-form-field>
<mat-label>Name</mat-label> <mat-label>Name</mat-label>
<input type="text" matInput formControlName="name" maxlength="100"> <input type="text" matInput formControlName="name" maxlength="100" placeholder="Bsp.: Kellerschlüssel Ferienhaus">
@if ((createForm.controls.name.value || '').length > 20) { @if ((createForm.controls.name.value || '').length > 20) {
<mat-hint>{{ (createForm.controls.name.value || '').length }} / 100 Zeichen</mat-hint> <mat-hint>{{ (createForm.controls.name.value || '').length }} / 100 Zeichen</mat-hint>
} @else { } @else {
<mat-hint>Wie soll der Schlüssel heißen?</mat-hint> <mat-hint>Wie soll der Schlüssel heißen? Der Name beschreibt den Schlüssel. Er sollte aber nicht einem Mieter zugeordnet werden.</mat-hint>
} }
</mat-form-field> </mat-form-field>
<div class="flex items-center gap-6"> <div class="flex items-center gap-6">
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Schlüsselnummer</mat-label> <mat-label>Schlüsselnummer</mat-label>
<input type="text" matInput formControlName="nr" maxlength="100"> <input type="text" matInput formControlName="nr" maxlength="100" placeholder="12 - R115843">
<mat-hint>Nummer auf dem Schlüssel</mat-hint> <mat-hint>Die Nummer auf dem Schlüssel oder dem Chip.</mat-hint>
</mat-form-field> </mat-form-field>
<div> <div>

View File

@@ -93,9 +93,9 @@ export class CreateKeyComponent {
openSelectMultipleCylinders() { openSelectMultipleCylinders() {
this.dialog.open(SelectKeyCylinderComponent, { this.dialog.open(SelectKeyCylinderComponent, {
maxHeight: "calc(100vh - 24px)", maxHeight: "calc(100vh - 48px)",
maxWidth: "calc(100vw - 24px)", maxWidth: "calc(100vw - 48px)",
width: "50vw", width: "800px",
minWidth: "300px", minWidth: "300px",
height: "70vh", height: "70vh",
disableClose: true, disableClose: true,

View File

@@ -170,8 +170,8 @@ export class KeysComponent extends AgGridContainerComponent {
openCreateKey() { openCreateKey() {
this.dialog.open(CreateKeyComponent, { this.dialog.open(CreateKeyComponent, {
maxWidth: "calc(100vw - 24px)", maxWidth: "calc(100vw - 48px)",
width: "30vw", width: "800px",
minWidth: "200px", minWidth: "200px",
disableClose: true disableClose: true
}).afterClosed().subscribe({ }).afterClosed().subscribe({
@@ -193,8 +193,8 @@ export class KeysComponent extends AgGridContainerComponent {
this.gridApi.setGridOption('loading', false) this.gridApi.setGridOption('loading', false)
const ref = this.dialog.open(SelectKeyCylinderComponent, { const ref = this.dialog.open(SelectKeyCylinderComponent, {
data: cylinders, data: cylinders,
maxHeight: "calc(100vh - 24px)", maxHeight: "calc(100vh - 48px)",
maxWidth: "calc(100vw - 24px)", maxWidth: "calc(100vw - 48px)",
width: "50vw", width: "50vw",
minWidth: "300px", minWidth: "300px",
height: "70vh", height: "70vh",