refactor: improve task database communication and enhance data flow in components

This commit is contained in:
Chneemann 2025-03-29 15:45:24 +01:00
parent 6e0429255b
commit 72ca03086d
12 changed files with 189 additions and 172 deletions

View file

@ -24,7 +24,7 @@
"tsConfig": "tsconfig.app.json", "tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss", "inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"], "assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.css", "node_modules/ngx-toastr/toastr.css"], "styles": ["src/styles.scss", "node_modules/ngx-toastr/toastr.css"],
"scripts": [] "scripts": []
}, },
"configurations": { "configurations": {
@ -76,7 +76,7 @@
"tsConfig": "tsconfig.spec.json", "tsConfig": "tsconfig.spec.json",
"inlineStyleLanguage": "scss", "inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"], "assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.css", "node_modules/ngx-toastr/toastr.css"], "styles": ["src/styles.scss", "node_modules/ngx-toastr/toastr.css"],
"scripts": [] "scripts": []
} }
} }

View file

@ -324,7 +324,7 @@
? 'block' ? 'block'
: 'none' : 'none'
}" }"
(click)="deleteTaskData(overlayData)" (click)="deleteTask(overlayData)"
></app-form-btn> ></app-form-btn>
<app-form-btn <app-form-btn
[class]="'btn-submit'" [class]="'btn-submit'"

View file

@ -10,6 +10,10 @@ import { FormBtnComponent } from '../../shared/components/buttons/form-btn/form-
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { SharedService } from '../../services/shared.service'; import { SharedService } from '../../services/shared.service';
import { AuthService } from '../../services/auth.service';
import { firstValueFrom, map } from 'rxjs';
import { TaskService } from '../../services/task.service';
import { ApiService } from '../../services/api.service';
@Component({ @Component({
selector: 'app-add-task', selector: 'app-add-task',
@ -44,6 +48,9 @@ export class AddTaskComponent implements OnInit {
public firebaseService: FirebaseService, public firebaseService: FirebaseService,
private overlayService: OverlayService, private overlayService: OverlayService,
private sharedService: SharedService, private sharedService: SharedService,
private taskService: TaskService,
private apiService: ApiService,
private authService: AuthService,
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router private router: Router
) {} ) {}
@ -52,15 +59,15 @@ export class AddTaskComponent implements OnInit {
title: '', title: '',
description: '', description: '',
category: '', category: '',
status: 'todo', status: this.taskService.getStatuses()[0],
priority: 'medium', priority: this.taskService.getPriorities()[0],
subtasks: [], subtasks: [],
subtasksTitle: [], subtasksTitle: [],
subtasksDone: [], subtasksDone: [],
assigned: [], assigned: [],
assignees: [], assignees: [],
userData: [], userData: [],
creator: this.firebaseService.getCurrentUserId(), creator: '',
date: this.currentDate, date: this.currentDate,
}; };
@ -72,21 +79,30 @@ export class AddTaskComponent implements OnInit {
* - Loads any existing task data from local storage. * - Loads any existing task data from local storage.
*/ */
ngOnInit() { ngOnInit() {
this.setCurrentUserId();
this.loadEditTaskData(); this.loadEditTaskData();
this.routeParams(); this.routeParams();
this.loadLocalStorageData(); this.loadLocalStorageData();
} }
setCurrentUserId() {
this.authService
.getCurrentUserId()
.pipe(map((userId) => userId ?? ''))
.subscribe((userId) => {
this.taskData.creator = userId;
});
}
/** /**
* Loads task data for editing if applicable, or sets the task status if this is a new task overlay. * Loads task data for editing if applicable, or sets the task status if this is a new task overlay.
* @param {string} overlayData The task id or status of the task to be loaded. * @param {string} overlayData The task id or status of the task to be loaded.
* @param {string} overlayType The type of overlay to be opened. * @param {string} overlayType The type of overlay to be opened.
* @returns {void} * @returns {void}
*/ */
loadEditTaskData() { async loadEditTaskData() {
const excludedValues = ['', 'todo', 'inprogress', 'awaitfeedback', 'done']; if (this.overlayData) {
if (!excludedValues.includes(this.overlayData)) { const taskData = await firstValueFrom(this.getTaskData(this.overlayData));
const taskData = this.getTaskData(this.overlayData)[0];
Object.assign(this.taskData, taskData); Object.assign(this.taskData, taskData);
} else if (this.overlayType === 'newTaskOverlay') { } else if (this.overlayType === 'newTaskOverlay') {
this.taskData.status = this.overlayData; this.taskData.status = this.overlayData;
@ -156,9 +172,7 @@ export class AddTaskComponent implements OnInit {
* @returns {Task[]} an array of tasks with the given id * @returns {Task[]} an array of tasks with the given id
*/ */
getTaskData(taskId: string) { getTaskData(taskId: string) {
return this.firebaseService return this.apiService.getTaskById(taskId);
.getAllTasks()
.filter((task) => task.id === taskId);
} }
/** /**
@ -357,43 +371,20 @@ export class AddTaskComponent implements OnInit {
} }
} }
/**
* Submits the task form and saves the task data to the Firebase Realtime Database.
*
* If the form is valid and the overlay data is one of the allowed values, this
* function adds a new task to the 'tasks' node in the Firebase Realtime Database.
* If the overlay data is not one of the allowed values, this function updates the
* task with the given overlay data in the 'tasks' node.
*
* After submitting the form, this function resets the form and closes the overlay.
* It then navigates to the '/board' route.
* @param ngForm the form to submit
* @param overlayData the overlay data corresponding to the task to be submitted
* @returns {void}
*/
onSubmit(ngForm: NgForm, overlayData: string) { onSubmit(ngForm: NgForm, overlayData: string) {
const allowedValues = [
'',
'none',
'todo',
'inprogress',
'awaitfeedback',
'done',
];
if (ngForm.submitted && ngForm.form.valid) { if (ngForm.submitted && ngForm.form.valid) {
if (allowedValues.includes(overlayData)) { const { id, ...taskWithoutId } = this.taskData;
const { id, ...taskWithoutId } = this.taskData;
this.firebaseService.addNewTask(taskWithoutId); this.apiService.saveNewTask(taskWithoutId).subscribe({
this.removeTaskData(ngForm); next: (response) => {
this.closeOverlay(); this.removeTaskData(ngForm);
} else {
if (this.getTaskData(overlayData).length > 0) {
const { id, ...taskWithoutId } = this.taskData;
this.firebaseService.replaceTaskData(overlayData, taskWithoutId);
this.closeOverlay(); this.closeOverlay();
} this.router.navigate(['/board']);
} },
this.router.navigate(['/board']); error: (error) => {
console.error('Fehler beim Speichern:', error);
},
});
} }
} }
@ -419,9 +410,9 @@ export class AddTaskComponent implements OnInit {
* @param overlayData the overlay data of the task to be deleted * @param overlayData the overlay data of the task to be deleted
* @returns {void} * @returns {void}
*/ */
deleteTaskData(overlayData: string) { deleteTask(overlayData: string) {
this.firebaseService.deleteTask(overlayData); this.apiService.deleteTaskById(overlayData);
this.closeOverlay(); this.closeDialog();
} }
@HostListener('document:click', ['$event']) @HostListener('document:click', ['$event'])

View file

@ -13,6 +13,7 @@ import { ApiService } from '../../services/api.service';
import { Task } from '../../interfaces/task.interface'; import { Task } from '../../interfaces/task.interface';
import { TaskService } from '../../services/task.service'; import { TaskService } from '../../services/task.service';
import { LoadingSpinnerComponent } from '../../shared/components/loading-spinner/loading-spinner.component'; import { LoadingSpinnerComponent } from '../../shared/components/loading-spinner/loading-spinner.component';
import { finalize, Subject, takeUntil } from 'rxjs';
@Component({ @Component({
selector: 'app-board', selector: 'app-board',
@ -30,6 +31,8 @@ import { LoadingSpinnerComponent } from '../../shared/components/loading-spinner
styleUrl: './board.component.scss', styleUrl: './board.component.scss',
}) })
export class BoardComponent { export class BoardComponent {
private destroy$ = new Subject<void>();
readonly TODO = 'todo'; readonly TODO = 'todo';
readonly IN_PROGRESS = 'inprogress'; readonly IN_PROGRESS = 'inprogress';
readonly AWAIT_FEEDBACK = 'awaitfeedback'; readonly AWAIT_FEEDBACK = 'awaitfeedback';
@ -53,33 +56,37 @@ export class BoardComponent {
taskMovedFrom: string = ''; taskMovedFrom: string = '';
isLoading = false; isLoading = false;
/**
* Is called when the component is initialized.
* Calls the `loadTasks` method to load tasks and subscribes to drag-and-drop events via `subscribeToDragDropEvents`.
*/
ngOnInit() { ngOnInit() {
this.loadTasks(); this.loadAllTasks();
this.subscribeToDragDropEvents(); this.subscribeToDragDropEvents();
} }
/** loadAllTasks(): void {
* Retrieves all tasks from the API and initializes the `allTasks` and `filteredTasks` properties.
*/
loadTasks(): void {
this.isLoading = true; this.isLoading = true;
this.taskService.loadAllTasks().subscribe({ this.taskService
next: (result) => { .getTasksWithUsers()
this.allTasks = result.allTasks; .pipe(finalize(() => (this.isLoading = false)))
this.filteredTasks = result.filteredTasks; .subscribe({
this.isLoading = false; next: (response) => {
}, this.allTasks = response.allTasks;
error: (err) => { this.filteredTasks = this.groupTasksByStatus(response.allTasks);
console.error('Error loading the tasks:', err); },
this.isLoading = false; error: (err) => {
}, console.error('Error loading the tasks:', err);
}); },
});
}
groupTasksByStatus(tasks: Task[]): { [key: string]: Task[] } {
return tasks.reduce((acc, task) => {
const status = task.status;
if (!acc[status]) {
acc[status] = [];
}
acc[status].push(task);
return acc;
}, {} as { [key: string]: Task[] });
} }
/** /**
@ -178,4 +185,9 @@ export class BoardComponent {
]) ])
); );
} }
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
} }

View file

@ -5,6 +5,7 @@ import { FirebaseService } from '../../services/firebase.service';
import { Task } from '../../interfaces/task.interface'; import { Task } from '../../interfaces/task.interface';
import { TaskService } from '../../services/task.service'; import { TaskService } from '../../services/task.service';
import { LoadingSpinnerComponent } from '../../shared/components/loading-spinner/loading-spinner.component'; import { LoadingSpinnerComponent } from '../../shared/components/loading-spinner/loading-spinner.component';
import { finalize } from 'rxjs';
@Component({ @Component({
selector: 'app-summary', selector: 'app-summary',
@ -29,25 +30,26 @@ export class SummaryComponent {
* This method loads all tasks from the TaskService. * This method loads all tasks from the TaskService.
*/ */
ngOnInit() { ngOnInit() {
this.loadTasks(); this.loadAllTasks();
} }
/** /**
* Loads all tasks from the TaskService. * Loads all tasks from the TaskService.
*/ */
loadTasks(): void { loadAllTasks(): void {
this.isLoading = true; this.isLoading = true;
this.taskService.loadAllTasks().subscribe({ this.taskService
next: (result) => { .getTasks()
this.allTasks = result.allTasks; .pipe(finalize(() => (this.isLoading = false)))
this.isLoading = false; .subscribe({
}, next: (response) => {
error: (err) => { this.allTasks = response;
console.error('Error loading the tasks:', err); },
this.isLoading = false; error: (err) => {
}, console.error('Error loading the tasks:', err);
}); },
});
} }
/** /**

View file

@ -36,20 +36,28 @@ export class ApiService {
// ------------- TASKS ------------- // // ------------- TASKS ------------- //
getTasks(): Observable<Task[]> {
return this.request<Task[]>('GET', `/api/tasks/`);
}
getTaskById(taskId: string): Observable<Task> { getTaskById(taskId: string): Observable<Task> {
return this.request<Task>('GET', `/api/tasks/${taskId}/`); return this.request<Task>('GET', `/api/tasks/${taskId}/`);
} }
getTasksByStatus(status: string): Observable<Task[]> {
return this.request<Task[]>('GET', '/api/tasks/', undefined, { status });
}
updateTaskStatus(taskId: string, status: string): Observable<Task> { updateTaskStatus(taskId: string, status: string): Observable<Task> {
return this.request<Task>('PUT', `/api/tasks/${taskId}/update_status/`, { return this.request<Task>('PATCH', `/api/tasks/${taskId}/update_status/`, {
status, status,
}); });
} }
saveNewTask(task: Task): Observable<Task> {
return this.request<Task>('POST', '/api/tasks/', task);
}
deleteTaskById(taskId: string): Observable<Task> {
return this.request<Task>('DELETE', `/api/tasks/${taskId}/`);
}
// ------------- USERS ------------- // // ------------- USERS ------------- //
getUserById(userId: string): Observable<User> { getUserById(userId: string): Observable<User> {

View file

@ -10,7 +10,6 @@ import {
import { ApiService } from './api.service'; import { ApiService } from './api.service';
import { TokenService } from './token.service'; import { TokenService } from './token.service';
import { ErrorHandlingService } from './error-handling.service'; import { ErrorHandlingService } from './error-handling.service';
import { ToastrService } from 'ngx-toastr';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
@Injectable({ @Injectable({

View file

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, forkJoin, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { ApiService } from './api.service'; import { ApiService } from './api.service';
import { Task } from '../interfaces/task.interface'; import { Task } from '../interfaces/task.interface';
import { catchError, map, switchMap } from 'rxjs/operators'; import { catchError, map, switchMap } from 'rxjs/operators';
@ -8,55 +8,67 @@ import { UserSummary } from '../interfaces/user.interface';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class TaskService { export class TaskService {
private readonly statuses = ['todo', 'inprogress', 'awaitfeedback', 'done']; private readonly statuses = ['todo', 'inprogress', 'awaitfeedback', 'done'];
private readonly priorities = ['low', 'medium', 'high'];
constructor(private apiService: ApiService) {} constructor(private apiService: ApiService) {}
loadAllTasks(): Observable<{ getStatuses(): string[] {
allTasks: Task[]; return this.statuses;
filteredTasks: Record<string, Task[]>; }
}> {
return forkJoin(
this.statuses.map((status) => this.fetchTasksByStatus(status))
).pipe(
switchMap((results) => {
const allTasks = results.flat();
const filteredTasks = this.statuses.reduce((acc, status, index) => {
acc[status] = results[index] || [];
return acc;
}, {} as Record<string, Task[]>);
return this.loadUsersForTasks(allTasks).pipe( getPriorities(): string[] {
map((tasksWithUsers) => { return this.priorities;
const updatedFilteredTasks = this.statuses.reduce((acc, status) => { }
acc[status] = tasksWithUsers.filter(
(task) => task.status === status
);
return acc;
}, {} as Record<string, Task[]>);
return { getTasks(): Observable<Task[]> {
allTasks: tasksWithUsers, return this.fetchTasks();
filteredTasks: updatedFilteredTasks, }
};
}) getTasksWithUsers(): Observable<{ allTasks: Task[] }> {
); return this.fetchTasks().pipe(
}) switchMap((tasks) =>
this.attachUsersToTasks(tasks).pipe(
map((tasksWithUsers) => ({ allTasks: tasksWithUsers }))
)
)
); );
} }
private fetchTasksByStatus(status: string): Observable<Task[]> { getTaskById(taskId: string): Observable<Task | null> {
return this.apiService.getTasksByStatus(status).pipe( return this.apiService.getTaskById(taskId).pipe(
catchError((error) => { catchError((error) => {
console.error( console.error('Error loading the task:', error);
`Fehler beim Abrufen von Tasks für Status ${status}:`, return of(null);
error }),
); switchMap((task) => (task ? this.attachUsersToTask(task) : of(null)))
);
}
private fetchTasks(): Observable<Task[]> {
return this.apiService.getTasks().pipe(
catchError((error) => {
console.error('Error when retrieving the tasks:', error);
return of([]); return of([]);
}) })
); );
} }
private loadUsersForTasks(tasks: Task[]): Observable<Task[]> { private attachUsersToTask(task: Task): Observable<Task> {
const userIds = [task.creator, ...task.assignees.map((a) => a.userId)];
return this.apiService.getUsersByIds(userIds).pipe(
catchError((error) => {
console.error('Error when retrieving user data:', error);
return of([]);
}),
map((users) => ({
...task,
userData: this.mapTaskUsers(task, this.createUserMap(users)),
}))
);
}
private attachUsersToTasks(tasks: Task[]): Observable<Task[]> {
const userIds = new Set( const userIds = new Set(
tasks.flatMap((task) => [ tasks.flatMap((task) => [
task.creator, task.creator,
@ -66,62 +78,32 @@ export class TaskService {
return this.apiService.getUsersByIds([...userIds]).pipe( return this.apiService.getUsersByIds([...userIds]).pipe(
catchError((error) => { catchError((error) => {
console.error('Fehler beim Abrufen der Benutzer:', error); console.error('Error when retrieving users:', error);
return of([]); return of([]);
}), }),
map((users) => { map((users) => {
const userMap = this.createUserMap(users); const userMap = this.createUserMap(users);
return tasks.map((task) => ({ return tasks.map((task) => ({
...task, ...task,
userData: [ userData: this.mapTaskUsers(task, userMap),
...task.assignees.map((a) => userMap[a.userId] || null),
userMap[task.creator] || null,
].filter(Boolean),
})); }));
}) })
); );
} }
loadSingleTask(taskId: string): Observable<Task | null> {
return this.apiService.getTaskById(taskId).pipe(
switchMap((task) => {
if (!task) return of(null);
const userIds = [task.creator, ...task.assignees.map((a) => a.userId)];
return this.apiService.getUsersByIds(userIds).pipe(
map((users) => ({
...task,
userData: this.mapTaskUsers(task, users),
})),
catchError((error) => {
console.error('Fehler beim Abrufen der Benutzerdaten:', error);
return of(task);
})
);
}),
catchError((error) => {
console.error('Fehler beim Laden des Tasks:', error);
return of(null);
})
);
}
private createUserMap(users: UserSummary[]): Record<string, UserSummary> { private createUserMap(users: UserSummary[]): Record<string, UserSummary> {
return users.reduce((acc, user) => { return users.reduce((acc, user) => {
if (user?.id) if (user?.id) {
acc[user.id] = { acc[user.id] = user;
id: user.id, }
firstName: user.firstName,
lastName: user.lastName,
initials: user.initials,
color: user.color,
};
return acc; return acc;
}, {} as Record<string, UserSummary>); }, {} as Record<string, UserSummary>);
} }
private mapTaskUsers(task: Task, users: UserSummary[]): UserSummary[] { private mapTaskUsers(
const userMap = this.createUserMap(users); task: Task,
userMap: Record<string, UserSummary>
): UserSummary[] {
return [ return [
...task.assignees.map((a) => userMap[a.userId] || null), ...task.assignees.map((a) => userMap[a.userId] || null),
userMap[task.creator] || null, userMap[task.creator] || null,

View file

@ -5,7 +5,7 @@
}" }"
> >
@if (overlayType === 'newTaskOverlay' || (overlayData !== '' && @if (overlayType === 'newTaskOverlay' || (overlayData !== '' &&
getTaskData(overlayData).length > 0)) { getTaskData(overlayData) !== undefined)) {
<div class="header"> <div class="header">
<app-btn-close (click)="closeDialog()"></app-btn-close> <app-btn-close (click)="closeDialog()"></app-btn-close>
</div> </div>

View file

@ -7,6 +7,7 @@ import { AssignedComponent } from '../../../../components/add-task/assigned/assi
import { AddTaskComponent } from '../../../../components/add-task/add-task.component'; import { AddTaskComponent } from '../../../../components/add-task/add-task.component';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { BtnBackComponent } from '../../buttons/btn-back/btn-back.component'; import { BtnBackComponent } from '../../buttons/btn-back/btn-back.component';
import { ApiService } from '../../../../services/api.service';
@Component({ @Component({
selector: 'app-task-edit-overlay', selector: 'app-task-edit-overlay',
@ -24,6 +25,7 @@ export class TaskEditOverlayComponent {
constructor( constructor(
public firebaseService: FirebaseService, public firebaseService: FirebaseService,
private apiService: ApiService,
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router private router: Router
) {} ) {}
@ -53,9 +55,7 @@ export class TaskEditOverlayComponent {
* @returns {Task[]} an array of tasks with the given id * @returns {Task[]} an array of tasks with the given id
*/ */
getTaskData(taskId: string) { getTaskData(taskId: string) {
return this.firebaseService return this.apiService.getTaskById(taskId);
.getAllTasks()
.filter((task) => task.id === taskId);
} }
/** /**

View file

@ -121,7 +121,7 @@
</div> </div>
} }
</div> </div>
@if(task.creator === firebaseService.getCurrentUserId()) { @if(task.creator === currentUserId) {
<div class="btns"> <div class="btns">
<div class="btn btn-delete" (click)="deleteTask(overlayData)"> <div class="btn btn-delete" (click)="deleteTask(overlayData)">
<img src="./../../../../../assets/img/contact/delete.svg" alt="" /> <img src="./../../../../../assets/img/contact/delete.svg" alt="" />

View file

@ -8,6 +8,9 @@ import { BtnBackComponent } from '../../buttons/btn-back/btn-back.component';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { Task } from '../../../../interfaces/task.interface'; import { Task } from '../../../../interfaces/task.interface';
import { TaskService } from '../../../../services/task.service'; import { TaskService } from '../../../../services/task.service';
import { AuthService } from '../../../../services/auth.service';
import { map } from 'rxjs';
import { ApiService } from '../../../../services/api.service';
@Component({ @Component({
selector: 'app-task-overlay', selector: 'app-task-overlay',
@ -22,11 +25,14 @@ export class TaskOverlayComponent implements OnInit {
task: Task | null = null; task: Task | null = null;
overlayMobile: boolean = false; overlayMobile: boolean = false;
currentUserId: string = '';
constructor( constructor(
public firebaseService: FirebaseService, public firebaseService: FirebaseService,
private overlayService: OverlayService, private overlayService: OverlayService,
private taskService: TaskService, private taskService: TaskService,
private authService: AuthService,
private apiService: ApiService,
private router: Router, private router: Router,
private route: ActivatedRoute private route: ActivatedRoute
) {} ) {}
@ -44,10 +50,20 @@ export class TaskOverlayComponent implements OnInit {
* Also sets `overlayMobile` to `true` if parameters are successfully retrieved. * Also sets `overlayMobile` to `true` if parameters are successfully retrieved.
*/ */
ngOnInit() { ngOnInit() {
this.setCurrentUserId();
this.setOverlayDataFromRoute(); this.setOverlayDataFromRoute();
this.loadTask(this.overlayData); this.loadTask(this.overlayData);
} }
setCurrentUserId() {
this.authService
.getCurrentUserId()
.pipe(map((userId) => userId ?? ''))
.subscribe((userId) => {
this.currentUserId = userId;
});
}
setOverlayDataFromRoute() { setOverlayDataFromRoute() {
if (this.overlayData === '') { if (this.overlayData === '') {
this.route.params.subscribe((params) => { this.route.params.subscribe((params) => {
@ -58,7 +74,7 @@ export class TaskOverlayComponent implements OnInit {
} }
loadTask(taskId: string) { loadTask(taskId: string) {
this.taskService.loadSingleTask(taskId).subscribe({ this.taskService.getTaskById(taskId).subscribe({
next: (task) => { next: (task) => {
this.task = task; this.task = task;
}, },
@ -102,8 +118,15 @@ export class TaskOverlayComponent implements OnInit {
* @param overlayData the overlay data of the task to be deleted * @param overlayData the overlay data of the task to be deleted
* @returns {void} * @returns {void}
*/ */
deleteTask(overlayData: string) { deleteTask(taskId: string) {
this.firebaseService.deleteTask(overlayData); this.apiService.deleteTaskById(taskId).subscribe({
next: (task) => {
console.log('Task deleted successfully:', task);
},
error: (err) => {
console.error('Error deleting task', err);
},
});
this.closeDialog(); this.closeDialog();
} }