+ @for (status of STATUSES; track status) {
-
{{ "board.todo" | translate }}![]()
{{ STATUS_LABELS[status] | translate }}
+
-
-
- @for (task of filteredTasks[TODO]; track task.id) {
-
-
-
- } @empty {
-
- @if (isLoading) {
-
- } @else {
-
{{ "board.noTasks" | translate }}
- } }
-
-
- @if (taskMovedTo === TODO && taskMovedFrom !== TODO) {
-
- }
-
-
-
-
-
{{ "board.inProgress" | translate }}
-
-
-
- @for (task of filteredTasks[IN_PROGRESS]; track task.id) {
-
-
-
- } @empty {
-
- @if (isLoading) {
-
- } @else {
-
{{ "board.noTasks" | translate }}
- } }
-
-
- @if (taskMovedTo === IN_PROGRESS && taskMovedFrom !== IN_PROGRESS) {
-
- }
-
-
-
-
-
{{ "board.awaitFeedback" | translate }}
-
-
-
- @for (task of filteredTasks[AWAIT_FEEDBACK]; track task.id) {
-
-
-
- } @empty {
-
- @if (isLoading) {
-
- } @else {
-
{{ "board.noTasks" | translate }}
- } }
-
-
- @if (taskMovedTo === AWAIT_FEEDBACK && taskMovedFrom !==
- AWAIT_FEEDBACK) {
-
- }
-
-
-
-
-
{{ "board.done" | translate }}
-
-
+
- @for (task of filteredTasks[DONE]; track task.id) {
+ @for (task of filteredTasks[status]; track task.id) {
} @empty {
+
@if (isLoading) {
@@ -181,11 +77,12 @@
} }
- @if (taskMovedTo === DONE && taskMovedFrom !== DONE) {
+ @if (taskMovedTo === status && taskMovedFrom !== status) {
}
+ }
diff --git a/src/app/components/board/board.component.ts b/src/app/components/board/board.component.ts
index 54c854e..04d2810 100644
--- a/src/app/components/board/board.component.ts
+++ b/src/app/components/board/board.component.ts
@@ -9,7 +9,11 @@ import { Router } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { TaskHighlightedComponent } from './task/task-highlighted/task-highlighted.component';
import { ApiService } from '../../services/api.service';
-import { Task, TaskMoveEvent } from '../../interfaces/task.interface';
+import {
+ Task,
+ TaskMoveEvent,
+ TaskStatus,
+} from '../../interfaces/task.interface';
import { TaskService } from '../../services/task.service';
import { LoadingSpinnerComponent } from '../../shared/components/loading-spinner/loading-spinner.component';
import { debounceTime, finalize, Subject, take, takeUntil } from 'rxjs';
@@ -17,6 +21,7 @@ import { UpdateNotifierService } from '../../services/update-notifier.service';
import { ToastNotificationService } from '../../services/toast-notification.service';
import { ResizeService } from '../../services/resize.service';
import { HeadlineComponent } from '../../shared/components/headline/headline.component';
+import { STATUS_LABELS, STATUSES } from '../../constants/task-status.constants';
@Component({
selector: 'app-board',
@@ -35,10 +40,8 @@ import { HeadlineComponent } from '../../shared/components/headline/headline.com
styleUrl: './board.component.scss',
})
export class BoardComponent implements OnInit, OnDestroy {
- readonly TODO = 'todo';
- readonly IN_PROGRESS = 'inprogress';
- readonly AWAIT_FEEDBACK = 'awaitfeedback';
- readonly DONE = 'done';
+ readonly STATUSES = STATUSES;
+ readonly STATUS_LABELS = STATUS_LABELS;
allTasks: Array
= [];
filteredTasks: { [key: string]: Task[] } = {};
@@ -166,7 +169,7 @@ export class BoardComponent implements OnInit, OnDestroy {
* @param taskId The id of the task being moved.
* @param status The status of the column where the task was dropped.
*/
- handleItemDropped(task: Task, status: string): void {
+ handleItemDropped(task: Task, status: TaskStatus): void {
if (!task || task.status === status) return;
this.apiService
@@ -186,7 +189,7 @@ export class BoardComponent implements OnInit, OnDestroy {
* @param taskId The ID of the task to be updated.
* @param status The new status to assign to the task.
*/
- updateTaskStatus(taskId: string, status: string) {
+ updateTaskStatus(taskId: string, status: TaskStatus) {
const updatedTask = this.allTasks.find((task) => task.id === taskId);
if (updatedTask) {
const oldStatus = updatedTask.status;
diff --git a/src/app/components/board/task/task-menu/task-menu.component.html b/src/app/components/board/task/task-menu/task-menu.component.html
index 68e4f62..2ebccbc 100644
--- a/src/app/components/board/task/task-menu/task-menu.component.html
+++ b/src/app/components/board/task/task-menu/task-menu.component.html
@@ -1,11 +1,11 @@
- @if (boardTaskStatus !== TODO) {
- To do
- } @if (boardTaskStatus !== IN_PROGRESS) {
- In progress
- } @if (boardTaskStatus !== AWAIT_FEEDBACK) {
- Await feedback
- } @if (boardTaskStatus !== DONE) {
- Done
- }
+
+ @for (status of STATUSES; track status) {
+
+
+ @if (status !== currentTaskStatus) {
+
+ {{ STATUS_LABELS[status] | translate }}
+
+ } }
diff --git a/src/app/components/board/task/task-menu/task-menu.component.ts b/src/app/components/board/task/task-menu/task-menu.component.ts
index 36519a3..f121c4a 100644
--- a/src/app/components/board/task/task-menu/task-menu.component.ts
+++ b/src/app/components/board/task/task-menu/task-menu.component.ts
@@ -1,27 +1,31 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
-import { Task, TaskMoveEvent } from '../../../../interfaces/task.interface';
+import {
+ Task,
+ TaskMoveEvent,
+ TaskStatus,
+} from '../../../../interfaces/task.interface';
+import {
+ STATUS_LABELS,
+ STATUSES,
+} from '../../../../constants/task-status.constants';
+import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'app-task-menu',
standalone: true,
- imports: [],
+ imports: [TranslateModule],
templateUrl: './task-menu.component.html',
styleUrl: './task-menu.component.scss',
})
export class TaskMenuComponent {
@Input() task!: Task;
- @Input() boardTaskStatus!: string;
+ @Input() currentTaskStatus!: TaskStatus;
@Output() updateStatusEmitter = new EventEmitter();
- readonly TODO = 'todo';
- readonly IN_PROGRESS = 'inprogress';
- readonly AWAIT_FEEDBACK = 'awaitfeedback';
- readonly DONE = 'done';
+ readonly STATUSES = STATUSES;
+ readonly STATUS_LABELS = STATUS_LABELS;
- moveTask(moveTo: string) {
- this.updateStatusEmitter.emit({
- task: this.task,
- moveTo: moveTo,
- });
+ moveTask(moveTo: TaskStatus) {
+ this.updateStatusEmitter.emit({ task: this.task, moveTo });
}
}
diff --git a/src/app/components/board/task/task.component.html b/src/app/components/board/task/task.component.html
index a1fc126..77b3300 100644
--- a/src/app/components/board/task/task.component.html
+++ b/src/app/components/board/task/task.component.html
@@ -91,7 +91,7 @@
@if (mobileMenuOpen){
}
diff --git a/src/app/constants/task-status.constants.ts b/src/app/constants/task-status.constants.ts
new file mode 100644
index 0000000..1448176
--- /dev/null
+++ b/src/app/constants/task-status.constants.ts
@@ -0,0 +1,15 @@
+import { TaskStatus } from '../interfaces/task.interface';
+
+export const STATUSES: TaskStatus[] = [
+ TaskStatus.TODO,
+ TaskStatus.IN_PROGRESS,
+ TaskStatus.AWAIT_FEEDBACK,
+ TaskStatus.DONE,
+];
+
+export const STATUS_LABELS: Record = {
+ [TaskStatus.TODO]: 'taskStatus.todo',
+ [TaskStatus.IN_PROGRESS]: 'taskStatus.inProgress',
+ [TaskStatus.AWAIT_FEEDBACK]: 'taskStatus.awaitFeedback',
+ [TaskStatus.DONE]: 'taskStatus.done',
+};
diff --git a/src/app/interfaces/task.interface.ts b/src/app/interfaces/task.interface.ts
index 93997db..e0a8bae 100644
--- a/src/app/interfaces/task.interface.ts
+++ b/src/app/interfaces/task.interface.ts
@@ -1,11 +1,22 @@
import { UserSummary } from './user.interface';
+// Enums
+
+export enum TaskStatus {
+ TODO = 'todo',
+ IN_PROGRESS = 'inProgress',
+ AWAIT_FEEDBACK = 'awaitFeedback',
+ DONE = 'done',
+}
+
+// Interfaces
+
export interface Task {
id?: string;
title: string;
description: string;
category: string;
- status: string;
+ status: TaskStatus;
priority: string;
subtasks: Subtask[];
assignees: Assignee[];
@@ -27,5 +38,5 @@ export interface Assignee {
export interface TaskMoveEvent {
task: Task;
- moveTo: string;
+ moveTo: TaskStatus;
}
diff --git a/src/app/services/drag-drop.service.ts b/src/app/services/drag-drop.service.ts
index 7fa67e0..01dc91c 100644
--- a/src/app/services/drag-drop.service.ts
+++ b/src/app/services/drag-drop.service.ts
@@ -1,11 +1,11 @@
import { Injectable, EventEmitter } from '@angular/core';
-import { Task } from '../interfaces/task.interface';
+import { Task, TaskStatus } from '../interfaces/task.interface';
@Injectable({
providedIn: 'root',
})
export class DragDropService {
- itemDropped = new EventEmitter<{ task: Task; status: string }>();
+ itemDropped = new EventEmitter<{ task: Task; status: TaskStatus }>();
itemMovedFrom = new EventEmitter<{ status: string }>();
itemMovedTo = new EventEmitter<{ status: string }>();
@@ -37,7 +37,7 @@ export class DragDropService {
* - Prevents the default browser behavior.
* - Emits the `itemMovedTo` event with the status of the column.
*/
- allowDrop(event: DragEvent, status: string) {
+ allowDrop(event: DragEvent, status: TaskStatus) {
event.preventDefault();
this.itemMovedTo.emit({ status });
}
@@ -53,7 +53,7 @@ export class DragDropService {
* - Sets the dragged task to null.
* - Emits the `itemMovedTo` event with an empty status, to reset the highlight.
*/
- drop(event: DragEvent, newStatus: string) {
+ drop(event: DragEvent, newStatus: TaskStatus) {
event.preventDefault();
if (this.draggedTask) {
diff --git a/src/app/services/overlay.service.ts b/src/app/services/overlay.service.ts
index dff8d6b..9fe936f 100644
--- a/src/app/services/overlay.service.ts
+++ b/src/app/services/overlay.service.ts
@@ -1,5 +1,6 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
+import { TaskState } from 'zone.js/lib/zone-impl';
@Injectable({
providedIn: 'root',
@@ -16,7 +17,7 @@ export class OverlayService {
* @param overlay The overlay type.
* @param data The overlay data.
*/
- setOverlayData(overlay: string, data: any) {
+ setOverlayData(overlay: string | TaskState, data: any) {
this.overlayDataSubject.next({ overlay, data });
}
diff --git a/src/app/services/task.service.ts b/src/app/services/task.service.ts
index 41b3eeb..961a599 100644
--- a/src/app/services/task.service.ts
+++ b/src/app/services/task.service.ts
@@ -1,18 +1,23 @@
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { ApiService } from './api.service';
-import { Task } from '../interfaces/task.interface';
+import { Task, TaskStatus } from '../interfaces/task.interface';
import { catchError, map, switchMap } from 'rxjs/operators';
import { UserSummary } from '../interfaces/user.interface';
@Injectable({ providedIn: 'root' })
export class TaskService {
- private readonly statuses = ['todo', 'inprogress', 'awaitfeedback', 'done'];
+ private readonly statuses: TaskStatus[] = [
+ TaskStatus.TODO,
+ TaskStatus.IN_PROGRESS,
+ TaskStatus.AWAIT_FEEDBACK,
+ TaskStatus.DONE,
+ ];
private readonly priorities = ['low', 'medium', 'high'];
constructor(private apiService: ApiService) {}
- getStatuses(): string[] {
+ getStatuses(): TaskStatus[] {
return this.statuses;
}
diff --git a/src/app/shared/components/overlay/overlay.component.ts b/src/app/shared/components/overlay/overlay.component.ts
index 6d03ae3..db7359c 100644
--- a/src/app/shared/components/overlay/overlay.component.ts
+++ b/src/app/shared/components/overlay/overlay.component.ts
@@ -103,6 +103,9 @@ export class OverlayComponent implements OnInit, OnDestroy {
* @param {boolean} close Indicates the close event.
*/
onCloseOverlay() {
+ this.overlayType = null;
+ this.overlayData = null;
+ this.shouldShowOverlay = false;
this.overlayService.clearOverlayData();
}
diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json
index 0f6a5f6..a2bed9d 100644
--- a/src/assets/i18n/de.json
+++ b/src/assets/i18n/de.json
@@ -117,16 +117,18 @@
},
"board": {
"headline": "Tafel",
- "todo": "Zu Erledigen",
- "inProgress": "In Bearbeitung",
- "awaitFeedback": "Warte auf Rückmeldung",
- "done": "Erledigt",
"addTask": "Neue Aufgabe",
"findTask": "Aufgabe suchen",
"noTasks": "Keine Aufgaben",
"dropHere": "Hier ablegen",
"emptyTask": "Keine Aufgaben"
},
+ "taskStatus": {
+ "todo": "Zu Erledigen",
+ "inProgress": "In Bearbeitung",
+ "awaitFeedback": "Warte auf Rückmeldung",
+ "done": "Erledigt"
+ },
"addTask": {
"headline": "Aufgabe",
"title": "Titel",
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index 565b450..7f52719 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -117,16 +117,18 @@
},
"board": {
"headline": "Board",
- "todo": "To-do",
- "inProgress": "In progress",
- "awaitFeedback": "Await feedback",
- "done": "Done",
"addTask": "Add Task",
"findTask": "Find Task",
"noTasks": "No tasks",
"dropHere": "Drop here",
"emptyTask": "No tasks"
},
+ "taskStatus": {
+ "todo": "To-do",
+ "inProgress": "In progress",
+ "awaitFeedback": "Await feedback",
+ "done": "Done"
+ },
"addTask": {
"headline": "Add Task",
"title": "Title",