From 64e1a5c12ff9f860f1a737790ea3281180256e15 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 20 Dec 2023 09:41:31 +0100 Subject: [PATCH 1/3] Fix Status Color of Task in TaskDetailOverview --- .../task-detail-overview/task-detail-overview.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.ts b/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.ts index 3309a1a..fa2d09d 100644 --- a/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.ts +++ b/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.ts @@ -41,6 +41,7 @@ export class TaskDetailOverviewComponent implements OnInit { task: TaskEntityInfo | undefined schedules: ScheduleInfo[] = [] + schedulesLoaded: boolean = false; taskStatus: string = "🟢" @@ -88,6 +89,7 @@ export class TaskDetailOverviewComponent implements OnInit { this.scheduleService.schedulesTaskIDGet(Number(params.get('taskID'))).subscribe({ next: resp => { this.schedules = resp; + this.schedulesLoaded = true; } }) } @@ -97,7 +99,7 @@ export class TaskDetailOverviewComponent implements OnInit { getStatusOfTask(task: TaskEntityInfo ) { if(moment(task.deadline, 'YYYY-MM-DDTHH:mm:ss.SSSZ').isBefore(moment())) { return "🔴"; - } else if(this.schedules.length == 0){ + } else if(this.schedules.length == 0 && this.schedulesLoaded){ return "🟠"; } else { return "🟢"; From be5af2bfe397f3a60cc311b7b049a3cbc41228a9 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 20 Dec 2023 10:28:35 +0100 Subject: [PATCH 2/3] Fix not working progress bar in task-detail-overview --- .../task-detail-overview.component.html | 9 ++++++- .../task-detail-overview.component.ts | 27 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.html b/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.html index 43cae92..d745f2b 100644 --- a/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.html +++ b/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.html @@ -14,7 +14,14 @@

ETA: {{task!.eta}} Minuten - Deadline: {{task!.deadline}}

- +
+
+
{{currentProgress}}
+
+
+
{{futureProgress}}
+
+
diff --git a/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.ts b/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.ts index fa2d09d..ef2179b 100644 --- a/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.ts +++ b/frontend/src/app/tasks/task-detail-overview/task-detail-overview.component.ts @@ -2,6 +2,7 @@ import {Component, OnInit, ViewChild} from '@angular/core'; import {NavigationLink, NavigationLinkListComponent} from "../../navigation-link-list/navigation-link-list.component"; import {ActivatedRoute, Router} from "@angular/router"; import { + AdvancedScheduleInfo, ScheduleInfo, ScheduleService, TaskEntityInfo, @@ -44,6 +45,8 @@ export class TaskDetailOverviewComponent implements OnInit { schedulesLoaded: boolean = false; taskStatus: string = "🟢" + currentProgress: string = "0"; + futureProgress: string = "0"; constructor(private activatedRoute: ActivatedRoute, private taskgroupService: TaskgroupService, @@ -84,12 +87,14 @@ export class TaskDetailOverviewComponent implements OnInit { next: resp => { this.task = resp; this.taskStatus = this.getStatusOfTask(resp) + this.calcProgress(); } }); this.scheduleService.schedulesTaskIDGet(Number(params.get('taskID'))).subscribe({ next: resp => { this.schedules = resp; this.schedulesLoaded = true; + this.calcProgress(); } }) } @@ -106,6 +111,28 @@ export class TaskDetailOverviewComponent implements OnInit { } } + calcProgress() { + if(this.task != undefined && this.task!.eta > 0) { + const currentProgress = this.task!.workTime / this.task!.eta * 100; + + let futureProgress = 0; + this.schedules.forEach(schedule => { + if(schedule.scheduleType == "ADVANCED" && schedule.startTime == null) { + let advancedSchedule: AdvancedScheduleInfo = schedule as AdvancedScheduleInfo; + if(moment(advancedSchedule.scheduleStartTime).isBefore(moment())) { + const duration = moment.duration(moment(advancedSchedule.scheduleStopTime).diff(moment(advancedSchedule.scheduleStartTime))); + const plannedMinutes = duration.asMinutes(); + futureProgress += plannedMinutes; + } + } + }) + + this.futureProgress = (futureProgress) / this.task!.eta *100 + "%"; + this.currentProgress = currentProgress + "%"; + } + + } + openTaskEditor() { if(this.task != undefined) { const taskEditorInfo: TaskEditorData = { From 1337bbb6abace21672808276ae8139b71d929a7e Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 20 Dec 2023 10:50:41 +0100 Subject: [PATCH 3/3] Only display unstarted schedules --- .../core/api/controller/ScheduleController.java | 14 +++++++++----- .../main/java/core/entities/timemanager/Task.java | 4 ++++ .../java/core/services/TaskScheduleService.java | 4 ++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/core/api/controller/ScheduleController.java b/backend/src/main/java/core/api/controller/ScheduleController.java index 3949347..0828926 100644 --- a/backend/src/main/java/core/api/controller/ScheduleController.java +++ b/backend/src/main/java/core/api/controller/ScheduleController.java @@ -3,10 +3,7 @@ package core.api.controller; import core.api.models.auth.SimpleStatusResponse; import core.api.models.timemanager.taskSchedule.*; -import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleFieldInfo; -import core.api.models.timemanager.taskSchedule.scheduleInfos.AdvancedScheduleInfo; -import core.api.models.timemanager.taskSchedule.scheduleInfos.BasicScheduleFieldInfo; -import core.api.models.timemanager.taskSchedule.scheduleInfos.ScheduleFieldInfo; +import core.api.models.timemanager.taskSchedule.scheduleInfos.*; import core.entities.timemanager.AbstractSchedule; import core.entities.timemanager.AdvancedTaskSchedule; import core.entities.timemanager.BasicTaskSchedule; @@ -50,7 +47,14 @@ public class ScheduleController { } List taskSchedules = permissionResult.getResult().getBasicTaskSchedules(); - return ResponseEntity.ok(taskSchedules.stream().map(AbstractSchedule::toScheduleInfo).toList()); + List scheduleInfos = new ArrayList<>(); + for(AbstractSchedule schedule : taskSchedules) { + //Filter completed schedules out + if(!schedule.isCompleted()) { + scheduleInfos.add(schedule.toScheduleInfo()); + } + } + return ResponseEntity.ok(scheduleInfos); } @PutMapping("/schedules/{taskID}/basic") diff --git a/backend/src/main/java/core/entities/timemanager/Task.java b/backend/src/main/java/core/entities/timemanager/Task.java index 940478f..89562c6 100644 --- a/backend/src/main/java/core/entities/timemanager/Task.java +++ b/backend/src/main/java/core/entities/timemanager/Task.java @@ -207,4 +207,8 @@ public class Task { } return false; } + + public void increaseWorkTime(long minutes) { + this.workTime += (int) minutes; + } } diff --git a/backend/src/main/java/core/services/TaskScheduleService.java b/backend/src/main/java/core/services/TaskScheduleService.java index 8265759..2df2e3f 100644 --- a/backend/src/main/java/core/services/TaskScheduleService.java +++ b/backend/src/main/java/core/services/TaskScheduleService.java @@ -14,6 +14,7 @@ import core.repositories.timemanager.TaskRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; @@ -164,6 +165,9 @@ public class TaskScheduleService { if(schedule.getStartTime() != null && schedule.getStopTime() == null) { schedule.setStopTime(LocalDateTime.now()); scheduleRepository.save(schedule); + Duration scheduleDuration = Duration.between(schedule.getStartTime(), schedule.getStopTime()); + schedule.getTask().increaseWorkTime(scheduleDuration.toMinutes()); + taskRepository.save(schedule.getTask()); } if(finish) {