Unfinish task and allow unfinishable tasks
Some checks failed
Java CI with Maven / build-and-push-frontend (push) Successful in 8s
Java CI with Maven / build-and-push-backend (push) Successful in 7s
Java CI with Maven / test (push) Failing after 35s

This commit is contained in:
Sebastian Böckelmann 2023-11-18 09:36:26 +01:00
parent eb3dba0830
commit de01f5a100
20 changed files with 138 additions and 17 deletions

View File

@ -22,6 +22,8 @@ public class TaskEntityInfo {
private int workTime; private int workTime;
private boolean finishable;
public TaskEntityInfo(Task task) { public TaskEntityInfo(Task task) {
this.taskID = task.getTaskID(); this.taskID = task.getTaskID();
this.taskName = task.getTaskName(); this.taskName = task.getTaskName();
@ -33,6 +35,7 @@ public class TaskEntityInfo {
} }
this.finished = task.isFinished(); this.finished = task.isFinished();
this.workTime = task.getWorkTime(); this.workTime = task.getWorkTime();
this.finishable = task.isFinishable();
} }
public long getTaskID() { public long getTaskID() {
@ -98,4 +101,12 @@ public class TaskEntityInfo {
public void setWorkTime(int workTime) { public void setWorkTime(int workTime) {
this.workTime = workTime; this.workTime = workTime;
} }
public boolean isFinishable() {
return finishable;
}
public void setFinishable(boolean finishable) {
this.finishable = finishable;
}
} }

View File

@ -20,6 +20,8 @@ public class TaskFieldInfo {
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
private LocalDate deadline; private LocalDate deadline;
private boolean finishable;
public TaskFieldInfo() { public TaskFieldInfo() {
} }
@ -61,4 +63,12 @@ public class TaskFieldInfo {
public void setDeadline(LocalDate deadline) { public void setDeadline(LocalDate deadline) {
this.deadline = deadline; this.deadline = deadline;
} }
public boolean isFinishable() {
return finishable;
}
public void setFinishable(boolean finishable) {
this.finishable = finishable;
}
} }

View File

@ -16,6 +16,7 @@ public class TaskOverviewInfo {
private LocalDate limit; private LocalDate limit;
private boolean overdue; private boolean overdue;
private boolean finishable;
public TaskOverviewInfo(Task task) { public TaskOverviewInfo(Task task) {
this.taskID = task.getTaskID(); this.taskID = task.getTaskID();
@ -26,6 +27,7 @@ public class TaskOverviewInfo {
if(task.getDeadline() != null) { if(task.getDeadline() != null) {
this.overdue = LocalDate.now().isAfter(task.getDeadline()); this.overdue = LocalDate.now().isAfter(task.getDeadline());
} }
this.finishable = task.isFinishable();
} }
public long getTaskID() { public long getTaskID() {
@ -75,4 +77,12 @@ public class TaskOverviewInfo {
public void setOverdue(boolean overdue) { public void setOverdue(boolean overdue) {
this.overdue = overdue; this.overdue = overdue;
} }
public boolean isFinishable() {
return finishable;
}
public void setFinishable(boolean finishable) {
this.finishable = finishable;
}
} }

View File

@ -7,9 +7,12 @@ public class TaskShortInfo {
private long taskID; private long taskID;
private String taskName; private String taskName;
private boolean finishable;
public TaskShortInfo(Task task) { public TaskShortInfo(Task task) {
this.taskID = task.getTaskID(); this.taskID = task.getTaskID();
this.taskName = task.getTaskName(); this.taskName = task.getTaskName();
this.finishable = task.isFinishable();
} }
public TaskShortInfo(long taskID, String taskName) { public TaskShortInfo(long taskID, String taskName) {
@ -32,4 +35,12 @@ public class TaskShortInfo {
public void setTaskName(String taskName) { public void setTaskName(String taskName) {
this.taskName = taskName; this.taskName = taskName;
} }
public boolean isFinishable() {
return finishable;
}
public void setFinishable(boolean finishable) {
this.finishable = finishable;
}
} }

View File

@ -27,6 +27,8 @@ public class TaskTaskgroupInfo {
private List<TaskgroupEntityInfo> taskgroups; private List<TaskgroupEntityInfo> taskgroups;
private boolean finishable;
public TaskTaskgroupInfo(Task task) { public TaskTaskgroupInfo(Task task) {
this.taskID = task.getTaskID(); this.taskID = task.getTaskID();
this.taskName = task.getTaskName(); this.taskName = task.getTaskName();
@ -42,6 +44,7 @@ public class TaskTaskgroupInfo {
List<Taskgroup> taskgroupList = Taskgroup.getAncestorList(task.getTaskgroup()); List<Taskgroup> taskgroupList = Taskgroup.getAncestorList(task.getTaskgroup());
taskgroupList.add(task.getTaskgroup()); taskgroupList.add(task.getTaskgroup());
this.taskgroups = taskgroupList.stream().map(TaskgroupEntityInfo::new).toList(); this.taskgroups = taskgroupList.stream().map(TaskgroupEntityInfo::new).toList();
this.finishable = task.isFinishable();
} }
public long getTaskID() { public long getTaskID() {
@ -115,4 +118,12 @@ public class TaskTaskgroupInfo {
public void setTaskgroups(List<TaskgroupEntityInfo> taskgroups) { public void setTaskgroups(List<TaskgroupEntityInfo> taskgroups) {
this.taskgroups = taskgroups; this.taskgroups = taskgroups;
} }
public boolean isFinishable() {
return finishable;
}
public void setFinishable(boolean finishable) {
this.finishable = finishable;
}
} }

View File

@ -1,5 +1,7 @@
package core.entities.timemanager; package core.entities.timemanager;
import core.api.models.timemanager.tasks.TaskFieldInfo;
import javax.persistence.*; import javax.persistence.*;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -29,21 +31,25 @@ public class Task {
private boolean finished; private boolean finished;
private boolean finishable;
@OneToMany(mappedBy = "task", cascade = CascadeType.ALL, fetch = FetchType.EAGER) @OneToMany(mappedBy = "task", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<AbstractSchedule> basicTaskSchedules; private List<AbstractSchedule> basicTaskSchedules;
private int workTime; private int workTime;
public Task(Taskgroup taskgroup, String taskName, LocalDate startDate, LocalDate deadline, int eta) { public Task() {
this.taskgroup = taskgroup;
this.taskName = taskName;
this.startDate = startDate;
this.deadline = deadline;
this.eta = eta;
this.finished = false;
} }
public Task() { public Task(Taskgroup taskgroup, TaskFieldInfo taskFieldInfo) {
this.taskgroup = taskgroup;
this.taskName = taskFieldInfo.getTaskName();
this.startDate = taskFieldInfo.getStartDate();
this.deadline = taskFieldInfo.getDeadline();
this.eta = taskFieldInfo.getEta();
this.finished = false;
this.finishable = taskFieldInfo.isFinishable();
System.err.println(this.finishable);
} }
public long getTaskID() { public long getTaskID() {
@ -91,7 +97,7 @@ public class Task {
} }
public void finish() { public void finish() {
this.finished = true; this.finished = !this.finished;
} }
public boolean isFinished() { public boolean isFinished() {
@ -171,4 +177,12 @@ public class Task {
} }
return abstractSchedules; return abstractSchedules;
} }
public boolean isFinishable() {
return finishable;
}
public void setFinishable(boolean finishable) {
this.finishable = finishable;
}
} }

View File

@ -40,7 +40,7 @@ public class TaskService {
return new ServiceResult<>(ServiceExitCode.INVALID_PARAMETER); return new ServiceResult<>(ServiceExitCode.INVALID_PARAMETER);
} }
Task task = new Task(taskgroup, taskFieldInfo.getTaskName(), taskFieldInfo.getStartDate(), taskFieldInfo.getDeadline(), taskFieldInfo.getEta()); Task task = new Task(taskgroup, taskFieldInfo);
taskgroup.getTasks().add(task); taskgroup.getTasks().add(task);
taskRepository.save(task); taskRepository.save(task);

View File

@ -44,5 +44,9 @@ export interface TaskEntityInfo {
* number in minutes that was already worked on this task * number in minutes that was already worked on this task
*/ */
workTime: number; workTime: number;
/**
* determines whether the task can be finished
*/
finishable: boolean;
} }

View File

@ -28,5 +28,9 @@ export interface TaskFieldInfo {
* date until the task has to be finished * date until the task has to be finished
*/ */
deadline?: string; deadline?: string;
/**
* determines whether the task can be finished
*/
finishable: boolean;
} }

View File

@ -38,5 +38,9 @@ export interface TaskOverviewInfo {
*/ */
activeTime?: number; activeTime?: number;
taskgroupPath: Array<TaskgroupEntityInfo>; taskgroupPath: Array<TaskgroupEntityInfo>;
/**
* determines whether the task can be finished
*/
finishable: boolean;
} }

View File

@ -20,5 +20,9 @@ export interface TaskShortInfo {
* name of task * name of task
*/ */
taskName: string; taskName: string;
/**
* determines whether the task can be finished
*/
finishable: boolean;
} }

View File

@ -46,5 +46,9 @@ export interface TaskTaskgroupInfo {
*/ */
workTime: number; workTime: number;
taskgroups: Array<TaskgroupEntityInfo>; taskgroups: Array<TaskgroupEntityInfo>;
/**
* determines whether the task can be finished
*/
finishable: boolean;
} }

View File

@ -14,6 +14,6 @@
</mat-card-content> </mat-card-content>
<mat-card-actions> <mat-card-actions>
<button mat-raised-button class="grayBtn" (click)="stopTask(false)">Stop</button> <button mat-raised-button class="grayBtn" (click)="stopTask(false)">Stop</button>
<button mat-raised-button class="greenBtn" (click)="stopTask(true)">Finish</button> <button mat-raised-button class="greenBtn" *ngIf="activeSchedule!.task.finishable" (click)="stopTask(true)">Finish</button>
</mat-card-actions> </mat-card-actions>
</mat-card> </mat-card>

View File

@ -10,7 +10,7 @@
<mat-card-actions> <mat-card-actions>
<button mat-raised-button color="primary" class="btn-without-radius" (click)="startTaskNow(task)">Start now</button> <button mat-raised-button color="primary" class="btn-without-radius" (click)="startTaskNow(task)">Start now</button>
<button *ngIf="taskgroupID != undefined" mat-raised-button class="yellowBtn btn-without-radius" [routerLink]="['/taskgroups', taskgroupID!, 'tasks', task.taskID, 'schedule']">Schedule</button> <button *ngIf="taskgroupID != undefined" mat-raised-button class="yellowBtn btn-without-radius" [routerLink]="['/taskgroups', taskgroupID!, 'tasks', task.taskID, 'schedule']">Schedule</button>
<button mat-raised-button class="greenBtn btn-without-radius" (click)="finishTask(task)">Finish</button> <button *ngIf="task.finishable" mat-raised-button class="greenBtn btn-without-radius" (click)="finishTask(task)">Finish</button>
</mat-card-actions> </mat-card-actions>
</mat-card> </mat-card>

View File

@ -87,7 +87,8 @@ export class TaskOverviewComponent {
taskName: res.taskName, taskName: res.taskName,
activeTime: 0, activeTime: 0,
overdue: res.overdue, overdue: res.overdue,
taskgroupPath: [] taskgroupPath: [],
finishable: res.finishable
} }
this.creationEmitter.emit({ this.creationEmitter.emit({
task: taskOverviewInfo, task: taskOverviewInfo,

View File

@ -23,7 +23,7 @@
<button mat-flat-button class="yellowBtn" (click)="startTaskNow()">Start now</button> <button mat-flat-button class="yellowBtn" (click)="startTaskNow()">Start now</button>
<button mat-flat-button class="grayBtn" (click)="openTaskEditor()">Edit</button> <button mat-flat-button class="grayBtn" (click)="openTaskEditor()">Edit</button>
<!--<button mat-raised-button>Copy</button>--> <!--<button mat-raised-button>Copy</button>-->
<button mat-flat-button class="greenBtn" >Finished</button> <button mat-flat-button class="greenBtn" *ngIf="task!.finishable" (click)="finishTask()">{{task!.finished ? 'Reopen':'Finish'}}</button>
</div> </div>
<div style="float:right;"> <div style="float:right;">

View File

@ -101,4 +101,12 @@ export class TaskDetailOverviewComponent implements OnInit {
}); });
} }
} }
finishTask() {
this.taskService.tasksTaskIDFinishPost(this.task!.taskID).subscribe({
next: resp => {
this.task!.finished = !this.task!.finished;
}
})
}
} }

View File

@ -24,6 +24,8 @@
<mat-datepicker-toggle matIconSuffix [for]="deadlinepicker"></mat-datepicker-toggle> <mat-datepicker-toggle matIconSuffix [for]="deadlinepicker"></mat-datepicker-toggle>
<mat-datepicker #deadlinepicker></mat-datepicker> <mat-datepicker #deadlinepicker></mat-datepicker>
</mat-form-field> </mat-form-field>
<mat-slide-toggle [(ngModel)]="finishable">Finishable</mat-slide-toggle>
</div> </div>
<div mat-dialog-actions align="end"> <div mat-dialog-actions align="end">

View File

@ -20,6 +20,8 @@ export class TaskEditorComponent implements OnInit {
nameCtrl: FormControl = new FormControl('', [Validators.required, Validators.maxLength(255)]) nameCtrl: FormControl = new FormControl('', [Validators.required, Validators.maxLength(255)])
etaCtrl: FormControl = new FormControl(0, [Validators.required, Validators.min(0)]) etaCtrl: FormControl = new FormControl(0, [Validators.required, Validators.min(0)])
startDate: FormControl = new FormControl(Date.now(), [Validators.required]) startDate: FormControl = new FormControl(Date.now(), [Validators.required])
finishable: boolean = true;
endDate: FormControl = new FormControl(''); endDate: FormControl = new FormControl('');
constructor(private dialog: MatDialogRef<TaskEditorComponent>, constructor(private dialog: MatDialogRef<TaskEditorComponent>,
private taskService: TaskService, private taskService: TaskService,
@ -58,12 +60,12 @@ export class TaskEditorComponent implements OnInit {
if(this.startDate.value.length > 0) { if(this.startDate.value.length > 0) {
startDate_formatted = moment(this.startDate.value).format('YYYY-MM-DDTHH:mm:ss.SSSZ'); startDate_formatted = moment(this.startDate.value).format('YYYY-MM-DDTHH:mm:ss.SSSZ');
} }
this.taskService.tasksTaskgroupIDPut(this.editorData.taskgroupID, { this.taskService.tasksTaskgroupIDPut(this.editorData.taskgroupID, {
taskName: this.nameCtrl.value, taskName: this.nameCtrl.value,
eta: this.etaCtrl.value, eta: this.etaCtrl.value,
startDate: startDate_formatted, startDate: startDate_formatted,
deadline: endDate_formatted deadline: endDate_formatted,
finishable: this.finishable
}).subscribe({ }).subscribe({
next: resp => { next: resp => {
this.dialog.close(resp); this.dialog.close(resp);
@ -89,7 +91,8 @@ export class TaskEditorComponent implements OnInit {
taskName: this.nameCtrl.value, taskName: this.nameCtrl.value,
eta: this.etaCtrl.value, eta: this.etaCtrl.value,
startDate: startingDate, startDate: startingDate,
deadline: deadline deadline: deadline,
finishable: this.finishable
}).subscribe({ }).subscribe({
next: resp => { next: resp => {
this.editorData.task!.taskName = this.nameCtrl.value; this.editorData.task!.taskName = this.nameCtrl.value;

View File

@ -2147,6 +2147,7 @@ components:
- overdue - overdue
- finished - finished
- workTime - workTime
- finishable
additionalProperties: false additionalProperties: false
properties: properties:
taskID: taskID:
@ -2182,6 +2183,9 @@ components:
type: number type: number
description: number in minutes that was already worked on this task description: number in minutes that was already worked on this task
example: 10 example: 10
finishable:
type: boolean
description: determines whether the task can be finished
TaskTaskgroupInfo: TaskTaskgroupInfo:
required: required:
- taskID - taskID
@ -2193,6 +2197,7 @@ components:
- finished - finished
- workTime - workTime
- taskgroups - taskgroups
- finishable
additionalProperties: false additionalProperties: false
properties: properties:
taskID: taskID:
@ -2232,10 +2237,14 @@ components:
type: array type: array
items: items:
$ref: '#/components/schemas/TaskgroupEntityInfo' $ref: '#/components/schemas/TaskgroupEntityInfo'
finishable:
type: boolean
description: determines whether the task can be finished
TaskFieldInfo: TaskFieldInfo:
required: required:
- taskName - taskName
- eta - eta
- finishable
additionalProperties: false additionalProperties: false
properties: properties:
taskName: taskName:
@ -2255,6 +2264,9 @@ components:
type: string type: string
format: date format: date
description: date until the task has to be finished description: date until the task has to be finished
finishable:
type: boolean
description: determines whether the task can be finished
BasicScheduleEntityInfo: BasicScheduleEntityInfo:
required: required:
- scheduleID - scheduleID
@ -2347,6 +2359,7 @@ components:
required: required:
- taskID - taskID
- taskName - taskName
- finishable
additionalProperties: false additionalProperties: false
properties: properties:
taskID: taskID:
@ -2357,6 +2370,9 @@ components:
type: string type: string
description: name of task description: name of task
example: "Vorlesung zusammenfassen" example: "Vorlesung zusammenfassen"
finishable:
type: boolean
description: determines whether the task can be finished
ScheduleActivateInfo: ScheduleActivateInfo:
required: required:
- startTime - startTime
@ -2420,6 +2436,7 @@ components:
- limit - limit
- overdue - overdue
- taskgroupPath - taskgroupPath
- finishable
additionalProperties: false additionalProperties: false
properties: properties:
taskID: taskID:
@ -2451,6 +2468,9 @@ components:
type: array type: array
items: items:
$ref: '#/components/schemas/TaskgroupEntityInfo' $ref: '#/components/schemas/TaskgroupEntityInfo'
finishable:
type: boolean
description: determines whether the task can be finished
ScheduleStatus: ScheduleStatus:
required: required:
- activeMinutes - activeMinutes