134 lines
4.0 KiB
TypeScript
134 lines
4.0 KiB
TypeScript
import { Component, OnInit } from '@angular/core';
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
|
|
import { Api } from '../../services/api';
|
|
import { Item } from '../../models/item';
|
|
import { MaterialModule } from '../../material.module';
|
|
import { CommonModule } from '@angular/common';
|
|
import { IconService, MaterialIcon } from '../../services/icon.service';
|
|
import { Observable } from 'rxjs';
|
|
import { map, startWith } from 'rxjs/operators';
|
|
|
|
@Component({
|
|
selector: 'app-item-form',
|
|
templateUrl: './item-form.html',
|
|
styleUrls: ['./item-form.scss'],
|
|
standalone: true,
|
|
imports: [MaterialModule, CommonModule, ReactiveFormsModule, FormsModule],
|
|
})
|
|
export class ItemFormComponent implements OnInit {
|
|
itemForm: FormGroup;
|
|
isEditMode = false;
|
|
itemId: number | null = null;
|
|
|
|
// Icon-Auswahl Eigenschaften
|
|
filteredIcons$!: Observable<MaterialIcon[]>;
|
|
allIcons: MaterialIcon[] = [];
|
|
useCustomUrl = false;
|
|
|
|
constructor(
|
|
private fb: FormBuilder,
|
|
private apiService: Api,
|
|
private router: Router,
|
|
private route: ActivatedRoute,
|
|
private iconService: IconService
|
|
) {
|
|
this.itemForm = this.fb.group({
|
|
name: ['', Validators.required],
|
|
displayName: ['', Validators.required],
|
|
target: ['', Validators.required],
|
|
iconUrl: [''],
|
|
iconName: ['']
|
|
});
|
|
}
|
|
|
|
ngOnInit(): void {
|
|
// Icons laden
|
|
this.allIcons = this.iconService.getAllIcons();
|
|
|
|
// Autocomplete für Icons einrichten
|
|
this.filteredIcons$ = this.itemForm.get('iconName')!.valueChanges.pipe(
|
|
startWith(''),
|
|
map(value => this._filterIcons(value || ''))
|
|
);
|
|
|
|
const idParam = this.route.snapshot.params['id'];
|
|
if (idParam) {
|
|
this.isEditMode = true;
|
|
this.itemId = +idParam; // Convert string to number
|
|
this.apiService.getItem(this.itemId).subscribe(item => {
|
|
this.itemForm.patchValue(item);
|
|
|
|
// Prüfen ob Custom URL oder Material Icon verwendet wird
|
|
if (item.iconUrl) {
|
|
if (this.iconService.isValidIcon(item.iconUrl)) {
|
|
// Es ist ein Material Icon Name
|
|
this.itemForm.patchValue({ iconName: item.iconUrl, iconUrl: '' });
|
|
this.useCustomUrl = false;
|
|
} else {
|
|
// Es ist eine Custom URL
|
|
this.useCustomUrl = true;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
private _filterIcons(value: string): MaterialIcon[] {
|
|
const filterValue = value.toLowerCase();
|
|
return this.allIcons.filter(icon =>
|
|
icon.name.toLowerCase().includes(filterValue) ||
|
|
icon.category.toLowerCase().includes(filterValue)
|
|
);
|
|
}
|
|
|
|
onToggleChange(event: any): void {
|
|
this.useCustomUrl = event.checked;
|
|
if (this.useCustomUrl) {
|
|
this.itemForm.patchValue({ iconName: '' });
|
|
} else {
|
|
this.itemForm.patchValue({ iconUrl: '' });
|
|
}
|
|
}
|
|
|
|
getSelectedIconName(): string {
|
|
return this.itemForm.get('iconName')?.value || 'dashboard';
|
|
}
|
|
|
|
displayFn(iconName: string): string {
|
|
return iconName;
|
|
}
|
|
|
|
onSubmit(): void {
|
|
if (this.itemForm.valid) {
|
|
// Bestimme welches Icon-Feld verwendet werden soll
|
|
let finalIconUrl = this.itemForm.value.iconUrl;
|
|
if (!this.useCustomUrl && this.itemForm.value.iconName) {
|
|
// Verwende Material Icon Namen als iconUrl
|
|
finalIconUrl = this.itemForm.value.iconName;
|
|
}
|
|
|
|
const itemData: Item = {
|
|
id: this.itemId ?? 0,
|
|
name: this.itemForm.value.name,
|
|
displayName: this.itemForm.value.displayName,
|
|
target: this.itemForm.value.target,
|
|
iconUrl: finalIconUrl
|
|
};
|
|
|
|
if (this.isEditMode) {
|
|
this.apiService.updateItem(this.itemId!, itemData).subscribe(() => {
|
|
this.router.navigate(['/']);
|
|
});
|
|
} else {
|
|
this.apiService.createItem(itemData).subscribe(() => {
|
|
this.router.navigate(['/admin']);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
cancel(): void {
|
|
this.router.navigate(['/']);
|
|
}
|
|
} |