1

I'm facing a visual replication issue when implementing drag and drop functionality to move tasks between columns in an Angular application that uses Firebase as the database. When I drag a task from one column to another, the task is correctly transferred to the destination column, but a visual copy of the task remains in the source column.

Currently, I'm using the @angular/cdk/drag-drop package to handle the drag and drop functionality. Upon dropping the task in the destination column, I'm performing the following steps:

Removing the task from the source column using this.store.collection(event.previousContainer.id).doc(item.id).delete();

Adding the task to the destination column using this.store.collection(event.container.id).add(item);

Updating the view using transferArrayItem(event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex);

Although the data transfer occurs correctly in Firebase, the source column displays a visual copy of the moved task. The issue seems to be related to rendering the previous state of the columns upon the next change detection cycle of Angular.

I have tried different approaches, including using Promise.all and Firestore transactions, but the issue persists. Additionally, I have attempted to debug the code logic and simulate the problem in a separate environment, but I haven't been able to identify the root cause.

I would like to know if anyone has encountered a similar issue when implementing drag and drop functionality with Angular and Firebase. Any suggestions or guidance on how to resolve this visual replication issue would be greatly appreciated.

Here's the relevant code snippet:

export class HomeComponent implements OnInit {
  user$ = this.usersService.currentUserProfile$;
  userId: string | null = null;

  constructor(private usersService: UsersService, private dialog: MatDialog, private store: AngularFirestore, private AuthService: AuthService) {}

  ngOnInit(): void {this.AuthService.currentUser$.subscribe(user => {
    this.userId = user?.uid;
  });}

  filterTasksByUser(tasks: Task[]): Task[] {
    return tasks.filter(task => task.userId === this.userId);
  }

 /* todo: Task[] = [
    {
      title: 'Criar um app em Angular',
      description: 'Primeiro passo: Deitar no chão e chorar'
    },
    {
      title: 'Criar um app Kanban',
      description: 'Mais fácil do que parece... Será?'
    }
  ];
  inProgress: Task[] = [];
  done: Task[] = [];*/

  todo = getObservable(this.store.collection('todo')) as Observable<Task[]>;
  inProgress = getObservable(this.store.collection('inProgress')) as Observable<Task[]>;
  done = getObservable(this.store.collection('done')) as Observable<Task[]>;

  editTask(list: 'done' | 'todo' | 'inProgress', task: Task): void {
    const dialogRef = this.dialog.open(TaskDialogComponent, {
      width: '270px',
      data: {
        task,
        enableDelete: true,
      },
    });


    dialogRef.afterClosed().subscribe((result: TaskDialogResult|undefined) => {
      if (!result) {
        return;
      }
      if (result.delete) {
        this.store.collection(list).doc(task.id).delete();
      } else {
        this.store.collection(list).doc(task.id).update(task);
      }
    });
  }
/* drop(event: CdkDragDrop<Task[]>): void {
    if (event.previousContainer === event.container) {
      return;
    }
    if (!event.container.data || !event.previousContainer.data) {
      return;
    }
    transferArrayItem(
      event.previousContainer.data,
      event.container.data,
      event.previousIndex,
      event.currentIndex
    );
  }*/
  drop(event: CdkDragDrop<Task[] | null>): void {
    if (event.previousContainer === event.container) {
      return;
    }
    const item = event.previousContainer.data[event.previousIndex];
    this.store.firestore.runTransaction(() => {
      const promise = Promise.all([
        this.store.collection(event.previousContainer.id).doc(item.id).delete(),
        this.store.collection(event.container.id).add(item),
      ]);
      return promise;
    });
    transferArrayItem(
      event.previousContainer.data,
      event.container.data,
      event.previousIndex,
      event.currentIndex
    );
  }


  newTask(): void {
    const dialogRef = this.dialog.open(TaskDialogComponent, {
      width: '270px',
      data: {
        task: {},
      },
    });
    dialogRef
      .afterClosed()
      .subscribe((result: TaskDialogResult|undefined) => {
        if (!result) {
          return;
        }
        this.AuthService.currentUser$.pipe(take(1)).subscribe(user => {
          const userId = user?.uid; // Obtém o ID do usuário atual
          if (userId) {
            const taskWithUserId = { ...result.task, userId }; // Adiciona o ID do usuário à tarefa
            this.store.collection('todo').add(taskWithUserId);
          }
        });
      });
  }
}
rphLnrd
  • 11
  • 1

0 Answers0