join/src/app/services/drag-drop.service.ts

69 lines
2.2 KiB
TypeScript

import { Injectable, EventEmitter } from '@angular/core';
import { Task } from '../interfaces/task.interface';
import { TaskStatus } from '../constants/task-status.constants';
@Injectable({
providedIn: 'root',
})
export class DragDropService {
itemDropped = new EventEmitter<{ task: Task; status: TaskStatus }>();
itemMovedFrom = new EventEmitter<{ status: string }>();
itemMovedTo = new EventEmitter<{ status: string }>();
private draggedTask: Task | null = null;
constructor() {}
/**
* Start a drag/drop operation. Called on the dragstart event.
* @param event The dragstart event.
* @param task The task being dragged.
* @remarks
* - Sets the dragged task to the given task.
* - Emits the `itemMovedFrom` event with the status of the task.
*/
startDragging(event: DragEvent, task: Task) {
if (task.id) {
event.dataTransfer?.setData('text/plain', task.id);
this.draggedTask = task;
this.itemMovedFrom.emit({ status: task.status });
}
}
/**
* Called on the dragover event.
* @param event The dragover event.
* @param status The status of the column being dropped on.
* @remarks
* - Prevents the default browser behavior.
* - Emits the `itemMovedTo` event with the status of the column.
*/
allowDrop(event: DragEvent, status: TaskStatus) {
event.preventDefault();
this.itemMovedTo.emit({ status });
}
/**
* Complete the drag/drop operation. Called on the drop event.
* @param event The drop event.
* @param newStatus The status of the column being dropped on.
* @remarks
* - Prevents the default browser behavior.
* - If the dragged task is not null and the new status is different from its current status,
* emits the `itemDropped` event with the task and the new status.
* - Sets the dragged task to null.
* - Emits the `itemMovedTo` event with an empty status, to reset the highlight.
*/
drop(event: DragEvent, newStatus: TaskStatus) {
event.preventDefault();
if (this.draggedTask) {
if (this.draggedTask.status !== newStatus) {
this.itemDropped.emit({ task: this.draggedTask, status: newStatus });
}
this.draggedTask = null;
}
this.itemMovedTo.emit({ status: '' });
}
}