edit hinter button
This commit is contained in:
@@ -36,32 +36,44 @@
|
||||
<mat-card class="editor-card" appearance="outlined">
|
||||
<mat-card-header>
|
||||
<mat-card-title>Details</mat-card-title>
|
||||
@if (!isCreateMode()) {
|
||||
<button mat-stroked-button type="button" (click)="showEditor() ? cancelEditing() : startEditing()">
|
||||
<mat-icon aria-hidden="true">{{ showEditor() ? 'close' : 'edit' }}</mat-icon>
|
||||
{{ showEditor() ? 'Abbrechen' : 'Bearbeiten' }}
|
||||
</button>
|
||||
}
|
||||
</mat-card-header>
|
||||
|
||||
<mat-card-content>
|
||||
<form [formGroup]="listForm" class="list-form" (ngSubmit)="saveList()">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Titel</mat-label>
|
||||
<input matInput formControlName="name" autocomplete="off" />
|
||||
@if (listForm.controls.name.hasError('required')) {
|
||||
<mat-error>Titel ist erforderlich.</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
@if (showEditor()) {
|
||||
<form [formGroup]="listForm" class="list-form" (ngSubmit)="saveList()">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Titel</mat-label>
|
||||
<input matInput formControlName="name" autocomplete="off" />
|
||||
@if (listForm.controls.name.hasError('required')) {
|
||||
<mat-error>Titel ist erforderlich.</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Beschreibung</mat-label>
|
||||
<textarea matInput formControlName="description" rows="4"></textarea>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Beschreibung</mat-label>
|
||||
<textarea matInput formControlName="description" rows="4"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<button mat-flat-button type="submit" [disabled]="saving()">
|
||||
@if (saving()) {
|
||||
<mat-progress-spinner mode="indeterminate" diameter="18" />
|
||||
} @else {
|
||||
<mat-icon aria-hidden="true">save</mat-icon>
|
||||
}
|
||||
{{ isCreateMode() ? 'Liste anlegen' : 'Speichern' }}
|
||||
</button>
|
||||
</form>
|
||||
<button mat-flat-button type="submit" [disabled]="saving()">
|
||||
@if (saving()) {
|
||||
<mat-progress-spinner mode="indeterminate" diameter="18" />
|
||||
} @else {
|
||||
<mat-icon aria-hidden="true">save</mat-icon>
|
||||
}
|
||||
{{ isCreateMode() ? 'Liste anlegen' : 'Speichern' }}
|
||||
</button>
|
||||
</form>
|
||||
} @else {
|
||||
<div class="list-summary">
|
||||
<p>{{ list()?.description || 'Keine Beschreibung hinterlegt.' }}</p>
|
||||
</div>
|
||||
}
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
@@ -78,26 +90,28 @@
|
||||
</mat-card-header>
|
||||
|
||||
<mat-card-content>
|
||||
<form [formGroup]="itemForm" class="item-form" (ngSubmit)="addItem()">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Neues Item</mat-label>
|
||||
<input matInput formControlName="title" autocomplete="off" [disabled]="!canEditItems()" />
|
||||
@if (itemForm.controls.title.hasError('required')) {
|
||||
<mat-error>Item-Titel ist erforderlich.</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
@if (showEditor()) {
|
||||
<form [formGroup]="itemForm" class="item-form" (ngSubmit)="addItem()">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Neues Item</mat-label>
|
||||
<input matInput formControlName="title" autocomplete="off" [disabled]="!canEditItems()" />
|
||||
@if (itemForm.controls.title.hasError('required')) {
|
||||
<mat-error>Item-Titel ist erforderlich.</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox formControlName="required">Pflicht</mat-checkbox>
|
||||
<mat-checkbox formControlName="required">Pflicht</mat-checkbox>
|
||||
|
||||
<button mat-flat-button type="submit" [disabled]="addingItem() || !canEditItems()">
|
||||
@if (addingItem()) {
|
||||
<mat-progress-spinner mode="indeterminate" diameter="18" />
|
||||
} @else {
|
||||
<mat-icon aria-hidden="true">add</mat-icon>
|
||||
}
|
||||
Hinzufügen
|
||||
</button>
|
||||
</form>
|
||||
<button mat-flat-button type="submit" [disabled]="addingItem() || !canEditItems()">
|
||||
@if (addingItem()) {
|
||||
<mat-progress-spinner mode="indeterminate" diameter="18" />
|
||||
} @else {
|
||||
<mat-icon aria-hidden="true">add</mat-icon>
|
||||
}
|
||||
Hinzufügen
|
||||
</button>
|
||||
</form>
|
||||
}
|
||||
|
||||
@if (!canEditItems()) {
|
||||
<div class="inline-empty">
|
||||
@@ -143,7 +157,7 @@
|
||||
|
||||
<a mat-button routerLink="/lists" class="secondary-back">
|
||||
<mat-icon aria-hidden="true">arrow_back</mat-icon>
|
||||
Zur Listenuebersicht
|
||||
Zur Listenübersicht
|
||||
</a>
|
||||
}
|
||||
</section>
|
||||
|
||||
@@ -34,6 +34,16 @@
|
||||
background: color-mix(in srgb, var(--mat-sys-surface-container-low) 94%, white);
|
||||
}
|
||||
|
||||
.editor-card mat-card-header {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.editor-card mat-card-header button {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.list-form,
|
||||
.item-form {
|
||||
display: grid;
|
||||
@@ -72,6 +82,17 @@
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.list-summary {
|
||||
padding-top: 0.75rem;
|
||||
}
|
||||
|
||||
.list-summary p {
|
||||
margin: 0;
|
||||
color: var(--mat-sys-on-surface-variant);
|
||||
overflow-wrap: anywhere;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.error-state mat-icon {
|
||||
color: var(--mat-sys-error);
|
||||
}
|
||||
|
||||
@@ -46,10 +46,12 @@ export class ListDetailComponent implements OnInit {
|
||||
protected readonly isCreateMode = signal(false);
|
||||
protected readonly loading = signal(true);
|
||||
protected readonly saving = signal(false);
|
||||
protected readonly editing = signal(false);
|
||||
protected readonly addingItem = signal(false);
|
||||
protected readonly errorMessage = signal<string | null>(null);
|
||||
protected readonly updatingItemId = signal<string | null>(null);
|
||||
protected readonly canEditItems = computed(() => Boolean(this.list()?.id));
|
||||
protected readonly showEditor = computed(() => this.isCreateMode() || this.editing());
|
||||
|
||||
protected readonly listForm = this.formBuilder.group({
|
||||
name: ['', [Validators.required]],
|
||||
@@ -66,6 +68,7 @@ export class ListDetailComponent implements OnInit {
|
||||
|
||||
if (this.isCreateMode()) {
|
||||
this.loading.set(false);
|
||||
this.editing.set(true);
|
||||
this.listForm.reset({ name: '', description: '' });
|
||||
return;
|
||||
}
|
||||
@@ -128,7 +131,10 @@ export class ListDetailComponent implements OnInit {
|
||||
this.setList(list);
|
||||
if (this.isCreateMode()) {
|
||||
this.isCreateMode.set(false);
|
||||
this.editing.set(false);
|
||||
void this.router.navigate(['/lists', list.id], { replaceUrl: true });
|
||||
} else {
|
||||
this.editing.set(false);
|
||||
}
|
||||
this.snackBar.open('Liste gespeichert.', 'OK', { duration: 2500 });
|
||||
},
|
||||
@@ -196,6 +202,29 @@ export class ListDetailComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
protected startEditing(): void {
|
||||
this.editing.set(true);
|
||||
}
|
||||
|
||||
protected cancelEditing(): void {
|
||||
const list = this.list();
|
||||
|
||||
if (this.isCreateMode()) {
|
||||
void this.router.navigateByUrl('/lists');
|
||||
return;
|
||||
}
|
||||
|
||||
if (list) {
|
||||
this.listForm.reset({
|
||||
name: list.name,
|
||||
description: list.description ?? '',
|
||||
});
|
||||
}
|
||||
|
||||
this.itemForm.reset({ title: '', required: true });
|
||||
this.editing.set(false);
|
||||
}
|
||||
|
||||
protected checkedCount(list: UserList): number {
|
||||
return list.items.filter((item) => item.checked).length;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user