@@ -0,0 +1,109 @@
|
||||
import { Component, inject, signal } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { StatusEntity, StatusesStore } from './statuses.store';
|
||||
|
||||
type FormMode = 'create' | 'edit';
|
||||
type StatusForm = { id: string; label: string; bg: string; color: string };
|
||||
|
||||
@Component({
|
||||
selector: 'app-statuses',
|
||||
imports: [FormsModule],
|
||||
templateUrl: './statuses.html',
|
||||
styleUrl: './statuses.css',
|
||||
})
|
||||
export class Statuses {
|
||||
protected readonly statusesStore = inject(StatusesStore);
|
||||
protected readonly statuses = this.statusesStore.statuses;
|
||||
|
||||
protected dragIndex: number | null = null;
|
||||
protected dragOverIndex: number | null = null;
|
||||
|
||||
protected formMode = signal<FormMode | null>(null);
|
||||
protected editingId = signal<string | null>(null);
|
||||
protected form: StatusForm = this.emptyForm();
|
||||
protected idError = signal<string | null>(null);
|
||||
|
||||
protected openCreate(): void {
|
||||
this.form = this.emptyForm();
|
||||
this.idError.set(null);
|
||||
this.editingId.set(null);
|
||||
this.formMode.set('create');
|
||||
}
|
||||
|
||||
protected openEdit(status: StatusEntity): void {
|
||||
this.form = { id: status.id, label: status.label, bg: status.bg, color: status.color };
|
||||
this.idError.set(null);
|
||||
this.editingId.set(status.id);
|
||||
this.formMode.set('edit');
|
||||
}
|
||||
|
||||
protected cancel(): void {
|
||||
this.formMode.set(null);
|
||||
this.editingId.set(null);
|
||||
}
|
||||
|
||||
protected save(): void {
|
||||
if (this.formMode() === 'create') {
|
||||
const id = this.slugify(this.form.id || this.form.label);
|
||||
if (!id) return;
|
||||
if (this.statusesStore.getById(id)) {
|
||||
this.idError.set('Un statut avec cet identifiant existe déjà.');
|
||||
return;
|
||||
}
|
||||
this.statusesStore.create({ id, label: this.form.label.trim(), bg: this.form.bg, color: this.form.color });
|
||||
} else {
|
||||
const id = this.editingId();
|
||||
if (!id) return;
|
||||
this.statusesStore.update(id, { label: this.form.label.trim(), bg: this.form.bg, color: this.form.color });
|
||||
}
|
||||
this.formMode.set(null);
|
||||
this.editingId.set(null);
|
||||
}
|
||||
|
||||
protected isFormValid(): boolean {
|
||||
return this.form.label.trim().length > 0;
|
||||
}
|
||||
|
||||
protected onDragStart(index: number): void {
|
||||
this.dragIndex = index;
|
||||
}
|
||||
|
||||
protected onDragOver(event: DragEvent, index: number): void {
|
||||
event.preventDefault();
|
||||
this.dragOverIndex = index;
|
||||
}
|
||||
|
||||
protected onDrop(event: DragEvent, dropIndex: number): void {
|
||||
event.preventDefault();
|
||||
if (this.dragIndex === null || this.dragIndex === dropIndex) {
|
||||
this.dragIndex = null;
|
||||
this.dragOverIndex = null;
|
||||
return;
|
||||
}
|
||||
const newOrder = [...this.statuses()];
|
||||
const [dragged] = newOrder.splice(this.dragIndex, 1);
|
||||
newOrder.splice(dropIndex, 0, dragged);
|
||||
this.statusesStore.setOrder(newOrder);
|
||||
this.dragIndex = null;
|
||||
this.dragOverIndex = null;
|
||||
}
|
||||
|
||||
protected onDragEnd(): void {
|
||||
this.dragIndex = null;
|
||||
this.dragOverIndex = null;
|
||||
}
|
||||
|
||||
private slugify(value: string): string {
|
||||
return value
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.normalize('NFD')
|
||||
.replace(/[̀-ͯ]/g, '')
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '');
|
||||
}
|
||||
|
||||
private emptyForm(): StatusForm {
|
||||
return { id: '', label: '', bg: '#e2e8f0', color: '#475569' };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user