AI Implementation feature(896): Admin Area General Settings and Categories 1.14 (#36)
This commit was merged in pull request #36.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, DestroyRef, effect, inject, input, output, signal } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, effect, inject, input, output, signal } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { AdminCategory } from '../../../core/services/admin.service';
|
||||
|
||||
@@ -15,6 +15,41 @@ export interface CategoryFormSubmit {
|
||||
iconFile?: File;
|
||||
}
|
||||
|
||||
export type CategoryFormGroup = FormGroup<{
|
||||
name: FormControl<string>;
|
||||
abbreviation: FormControl<string>;
|
||||
description: FormControl<string>;
|
||||
}>;
|
||||
|
||||
export function syncCategoryForm(
|
||||
form: CategoryFormGroup,
|
||||
mode: CategoryFormMode,
|
||||
category: AdminCategory | null,
|
||||
): { abbreviationReadonly: boolean; iconPreview: string | null } {
|
||||
if (mode === 'edit' && category) {
|
||||
form.controls.name.setValue(category.name ?? '', { emitEvent: false });
|
||||
form.controls.abbreviation.setValue(category.abbreviation ?? '', { emitEvent: false });
|
||||
form.controls.description.setValue(category.description ?? '', { emitEvent: false });
|
||||
form.controls.name.markAsUntouched();
|
||||
form.controls.name.markAsPristine();
|
||||
form.controls.abbreviation.markAsUntouched();
|
||||
form.controls.abbreviation.markAsPristine();
|
||||
form.controls.description.markAsUntouched();
|
||||
form.controls.description.markAsPristine();
|
||||
return { abbreviationReadonly: !!category.isSystem, iconPreview: category.iconPath || null };
|
||||
}
|
||||
form.controls.name.setValue('', { emitEvent: false });
|
||||
form.controls.abbreviation.setValue('', { emitEvent: false });
|
||||
form.controls.description.setValue('', { emitEvent: false });
|
||||
form.controls.name.markAsUntouched();
|
||||
form.controls.name.markAsPristine();
|
||||
form.controls.abbreviation.markAsUntouched();
|
||||
form.controls.abbreviation.markAsPristine();
|
||||
form.controls.description.markAsUntouched();
|
||||
form.controls.description.markAsPristine();
|
||||
return { abbreviationReadonly: false, iconPreview: null };
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-category-form-modal',
|
||||
standalone: true,
|
||||
@@ -69,6 +104,7 @@ export interface CategoryFormSubmit {
|
||||
export class CategoryFormModalComponent {
|
||||
private readonly fb = inject(FormBuilder);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly cdr = inject(ChangeDetectorRef);
|
||||
|
||||
readonly open = input(false);
|
||||
readonly mode = input<CategoryFormMode>('create');
|
||||
@@ -82,31 +118,23 @@ export class CategoryFormModalComponent {
|
||||
readonly submitting = signal(false);
|
||||
readonly abbreviationReadonly = signal(false);
|
||||
|
||||
readonly form = this.fb.nonNullable.group({
|
||||
readonly form: CategoryFormGroup = this.fb.nonNullable.group({
|
||||
name: this.fb.nonNullable.control('', [Validators.required, Validators.maxLength(120)]),
|
||||
abbreviation: this.fb.nonNullable.control('', [Validators.required, Validators.minLength(2), Validators.maxLength(6)]),
|
||||
description: this.fb.nonNullable.control(''),
|
||||
});
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
const c = this.category();
|
||||
const m = this.mode();
|
||||
if (m === 'edit' && c) {
|
||||
this.form.patchValue({
|
||||
name: c.name,
|
||||
abbreviation: c.abbreviation,
|
||||
description: c.description,
|
||||
});
|
||||
this.abbreviationReadonly.set(c.isSystem);
|
||||
this.iconPreview.set(c.iconPath || null);
|
||||
} else {
|
||||
this.form.patchValue({ name: '', abbreviation: '', description: '' });
|
||||
this.abbreviationReadonly.set(false);
|
||||
this.iconPreview.set(null);
|
||||
}
|
||||
this.iconFile.set(null);
|
||||
});
|
||||
effect(
|
||||
() => {
|
||||
const result = syncCategoryForm(this.form, this.mode(), this.category());
|
||||
this.abbreviationReadonly.set(result.abbreviationReadonly);
|
||||
this.iconPreview.set(result.iconPreview);
|
||||
this.iconFile.set(null);
|
||||
this.cdr.markForCheck();
|
||||
},
|
||||
{ allowSignalWrites: true },
|
||||
);
|
||||
}
|
||||
|
||||
onFile(ev: Event): void {
|
||||
|
||||
Reference in New Issue
Block a user