Register Forgotten Activities
This commit is contained in:
parent
836247ff73
commit
2324976bd6
@ -5,8 +5,23 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="3a869f59-290a-4ab2-b036-a878ce801bc4" name="Changes" comment="Load worked minutes when reloading dashboard">
|
<list default="true" id="3a869f59-290a-4ab2-b036-a878ce801bc4" name="Changes" comment="Load worked minutes when reloading dashboard">
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/core/api/models/timemanager/taskSchedule/ForgottenActivity.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/core/api/models/timemanager/taskSchedule/ForgottenActivityMode.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/api/controller/ScheduleController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/api/controller/ScheduleController.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/api/controller/TaskController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/api/controller/TaskController.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/api/models/timemanager/tasks/TaskShortInfo.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/api/models/timemanager/tasks/TaskShortInfo.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/entities/timemanager/Task.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/entities/timemanager/Task.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/entities/timemanager/Taskgroup.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/entities/timemanager/Taskgroup.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/repositories/timemanager/BasicTaskScheduleRepository.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/repositories/timemanager/BasicTaskScheduleRepository.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/repositories/timemanager/TaskRepository.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/repositories/timemanager/TaskRepository.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/core/services/TaskScheduleService.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/services/TaskScheduleService.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/services/TaskScheduleService.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/services/TaskScheduleService.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/services/TaskService.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/services/TaskService.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../frontend/src/api/api/task.service.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/api/api/task.service.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../frontend/src/app/app.module.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/app/app.module.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../frontend/src/app/dashboard/active-schedule/active-schedule.component.html" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/app/dashboard/active-schedule/active-schedule.component.html" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../frontend/src/app/dashboard/active-schedule/active-schedule.component.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/app/dashboard/active-schedule/active-schedule.component.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../openapi.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/../openapi.yaml" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@ -16,16 +31,16 @@
|
|||||||
<component name="FileTemplateManagerImpl">
|
<component name="FileTemplateManagerImpl">
|
||||||
<option name="RECENT_TEMPLATES">
|
<option name="RECENT_TEMPLATES">
|
||||||
<list>
|
<list>
|
||||||
<option value="Enum" />
|
|
||||||
<option value="Interface" />
|
<option value="Interface" />
|
||||||
<option value="Class" />
|
<option value="Class" />
|
||||||
|
<option value="Enum" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="Git.Settings">
|
<component name="Git.Settings">
|
||||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
||||||
<map>
|
<map>
|
||||||
<entry key="$PROJECT_DIR$/.." value="issue-23" />
|
<entry key="$PROJECT_DIR$/.." value="issue-29" />
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
|
||||||
@ -259,7 +274,8 @@
|
|||||||
<MESSAGE value="Remove update spamming in console" />
|
<MESSAGE value="Remove update spamming in console" />
|
||||||
<MESSAGE value="Start task now from Taskoverview in Dashboard" />
|
<MESSAGE value="Start task now from Taskoverview in Dashboard" />
|
||||||
<MESSAGE value="Load worked minutes when reloading dashboard" />
|
<MESSAGE value="Load worked minutes when reloading dashboard" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="Load worked minutes when reloading dashboard" />
|
<MESSAGE value="Check if there is another active schedule when starting task now" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="Check if there is another active schedule when starting task now" />
|
||||||
</component>
|
</component>
|
||||||
<component name="XDebuggerManager">
|
<component name="XDebuggerManager">
|
||||||
<breakpoint-manager>
|
<breakpoint-manager>
|
||||||
@ -271,12 +287,12 @@
|
|||||||
</line-breakpoint>
|
</line-breakpoint>
|
||||||
<line-breakpoint enabled="true" type="java-line">
|
<line-breakpoint enabled="true" type="java-line">
|
||||||
<url>file://$PROJECT_DIR$/src/main/java/core/services/TaskScheduleService.java</url>
|
<url>file://$PROJECT_DIR$/src/main/java/core/services/TaskScheduleService.java</url>
|
||||||
<line>86</line>
|
<line>87</line>
|
||||||
<option name="timeStamp" value="5" />
|
<option name="timeStamp" value="5" />
|
||||||
</line-breakpoint>
|
</line-breakpoint>
|
||||||
<line-breakpoint enabled="true" type="java-line">
|
<line-breakpoint enabled="true" type="java-line">
|
||||||
<url>file://$PROJECT_DIR$/src/main/java/core/services/TaskScheduleService.java</url>
|
<url>file://$PROJECT_DIR$/src/main/java/core/services/TaskScheduleService.java</url>
|
||||||
<line>93</line>
|
<line>94</line>
|
||||||
<option name="timeStamp" value="6" />
|
<option name="timeStamp" value="6" />
|
||||||
</line-breakpoint>
|
</line-breakpoint>
|
||||||
</breakpoints>
|
</breakpoints>
|
||||||
|
@ -201,4 +201,23 @@ public class ScheduleController {
|
|||||||
int workedMinutes = taskScheduleService.getWorkedMinutes(user.get());
|
int workedMinutes = taskScheduleService.getWorkedMinutes(user.get());
|
||||||
return ResponseEntity.ok(new ScheduleStatus(workedMinutes, taskScheduleService.isAnyScheduleMissed(user.get())));
|
return ResponseEntity.ok(new ScheduleStatus(workedMinutes, taskScheduleService.isAnyScheduleMissed(user.get())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/schedules/{taskID}/forgotten")
|
||||||
|
public ResponseEntity<?> registerForgottenActivity(@PathVariable long taskID, @Valid @RequestBody ForgottenActivity forgottenActivity) {
|
||||||
|
PermissionResult<Task> permissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
if(!permissionResult.isHasPermissions()) {
|
||||||
|
return ResponseEntity.status(403).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(permissionResult.getExitCode() == ServiceExitCode.MISSING_ENTITY) {
|
||||||
|
return ResponseEntity.status(404).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceResult<Integer> serviceResult = taskScheduleService.registerForgottenActivity(permissionResult.getResult(), forgottenActivity);
|
||||||
|
if(serviceResult.getExitCode() == ServiceExitCode.INVALID_OPERATION) {
|
||||||
|
return ResponseEntity.status(400).body(new SimpleStatusResponse("failed"));
|
||||||
|
} else {
|
||||||
|
return ResponseEntity.ok(new TaskScheduleStopResponse(serviceResult.getResult()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import core.api.models.auth.SimpleStatusResponse;
|
|||||||
import core.api.models.timemanager.taskSchedule.ScheduleInfo;
|
import core.api.models.timemanager.taskSchedule.ScheduleInfo;
|
||||||
import core.api.models.timemanager.tasks.TaskEntityInfo;
|
import core.api.models.timemanager.tasks.TaskEntityInfo;
|
||||||
import core.api.models.timemanager.tasks.TaskFieldInfo;
|
import core.api.models.timemanager.tasks.TaskFieldInfo;
|
||||||
|
import core.api.models.timemanager.tasks.TaskShortInfo;
|
||||||
import core.entities.timemanager.Task;
|
import core.entities.timemanager.Task;
|
||||||
import core.entities.timemanager.Taskgroup;
|
import core.entities.timemanager.Taskgroup;
|
||||||
import core.services.*;
|
import core.services.*;
|
||||||
@ -13,6 +14,9 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
@CrossOrigin(origins = "*", maxAge = 3600)
|
||||||
@RestController
|
@RestController
|
||||||
@ -27,6 +31,24 @@ public class TaskController {
|
|||||||
this.taskgroupService = taskgroupService;
|
this.taskgroupService = taskgroupService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tasks/all/{finished}")
|
||||||
|
public ResponseEntity<List<TaskShortInfo>> loadAllTasks(@PathVariable boolean finished) {
|
||||||
|
List<Task> taskList = taskService.loadAllTasks(SecurityContextHolder.getContext().getAuthentication().getName(), finished);
|
||||||
|
List<TaskShortInfo> taskShortInfos = new ArrayList<>();
|
||||||
|
for(Task task : taskList) {
|
||||||
|
List<Taskgroup> ancestors = Taskgroup.getAncestorList(task.getTaskgroup());
|
||||||
|
ancestors.add(task.getTaskgroup());
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for(Taskgroup taskgroup : ancestors) {
|
||||||
|
builder.append(taskgroup.getTaskgroupName()).append("/");
|
||||||
|
}
|
||||||
|
builder.append(task.getTaskName());
|
||||||
|
taskShortInfos.add(new TaskShortInfo(task.getTaskID(), builder.toString()));
|
||||||
|
|
||||||
|
}
|
||||||
|
return ResponseEntity.ok(taskShortInfos);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/tasks/{taskgroupID}/{status}")
|
@GetMapping("/tasks/{taskgroupID}/{status}")
|
||||||
public ResponseEntity<?> listTasksOfTaskgroup(@PathVariable long taskgroupID, @PathVariable String status) {
|
public ResponseEntity<?> listTasksOfTaskgroup(@PathVariable long taskgroupID, @PathVariable String status) {
|
||||||
PermissionResult<Taskgroup> taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName());
|
PermissionResult<Taskgroup> taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package core.api.models.timemanager.taskSchedule;
|
||||||
|
|
||||||
|
public class ForgottenActivity {
|
||||||
|
private ForgottenActivityMode mode;
|
||||||
|
private int minutesSpent;
|
||||||
|
|
||||||
|
public ForgottenActivityMode getMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMode(ForgottenActivityMode mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinutesSpent() {
|
||||||
|
return minutesSpent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinutesSpent(int minutesSpent) {
|
||||||
|
this.minutesSpent = minutesSpent;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package core.api.models.timemanager.taskSchedule;
|
||||||
|
|
||||||
|
public enum ForgottenActivityMode {
|
||||||
|
|
||||||
|
MANUAL,
|
||||||
|
LAST,
|
||||||
|
PLANNED
|
||||||
|
}
|
@ -12,6 +12,11 @@ public class TaskShortInfo {
|
|||||||
this.taskName = task.getTaskName();
|
this.taskName = task.getTaskName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TaskShortInfo(long taskID, String taskName) {
|
||||||
|
this.taskID = taskID;
|
||||||
|
this.taskName = taskName;
|
||||||
|
}
|
||||||
|
|
||||||
public long getTaskID() {
|
public long getTaskID() {
|
||||||
return taskID;
|
return taskID;
|
||||||
}
|
}
|
||||||
|
@ -146,4 +146,8 @@ public class Task {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void increaseActiveTime(int minutesSpent) {
|
||||||
|
this.workTime += minutesSpent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,7 @@ public class Taskgroup {
|
|||||||
ancestors.add(currentTaskgroup.parent);
|
ancestors.add(currentTaskgroup.parent);
|
||||||
currentTaskgroup = currentTaskgroup.parent;
|
currentTaskgroup = currentTaskgroup.parent;
|
||||||
}
|
}
|
||||||
|
//ancestors.add(taskgroup);
|
||||||
return ancestors;
|
return ancestors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,4 +36,7 @@ public interface BasicTaskScheduleRepository extends CrudRepository<BasicTaskSch
|
|||||||
Optional<BasicTaskSchedule> findActiveTaskSchedule(String username);
|
Optional<BasicTaskSchedule> findActiveTaskSchedule(String username);
|
||||||
|
|
||||||
List<BasicTaskSchedule> findAllByStartTimeIsNull();
|
List<BasicTaskSchedule> findAllByStartTimeIsNull();
|
||||||
|
|
||||||
|
@Query(value = "SELECT bts FROM BasicTaskSchedule bts WHERE bts.task.taskgroup.user = ?1 AND bts.scheduleDate = ?2 AND bts.finishedTime IS NOT NULL")
|
||||||
|
List<BasicTaskSchedule> findAllFinishedByUserAndDate(User user, LocalDate now);
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,14 @@ import org.springframework.data.repository.CrudRepository;
|
|||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface TaskRepository extends CrudRepository<Task, Long> {
|
public interface TaskRepository extends CrudRepository<Task, Long> {
|
||||||
|
|
||||||
|
@Query(value = "SELECT t FROM Task t WHERE t.taskgroup.user.username = ?1 AND t.finished = ?2")
|
||||||
|
List<Task> findAllByUser(String username, boolean finished);
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query(value = "DELETE FROM Task t WHERE t.taskgroup = ?1")
|
@Query(value = "DELETE FROM Task t WHERE t.taskgroup = ?1")
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package core.services;
|
package core.services;
|
||||||
|
|
||||||
import core.api.models.timemanager.taskSchedule.BasicTaskScheduleFieldInfo;
|
import core.api.models.timemanager.taskSchedule.BasicTaskScheduleFieldInfo;
|
||||||
|
import core.api.models.timemanager.taskSchedule.ForgottenActivity;
|
||||||
import core.entities.User;
|
import core.entities.User;
|
||||||
import core.entities.timemanager.BasicTaskSchedule;
|
import core.entities.timemanager.BasicTaskSchedule;
|
||||||
import core.entities.timemanager.Task;
|
import core.entities.timemanager.Task;
|
||||||
@ -157,4 +158,56 @@ public class TaskScheduleService {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServiceResult<Integer> registerForgottenActivity(Task task, ForgottenActivity forgottenActivity) {
|
||||||
|
switch (forgottenActivity.getMode()) {
|
||||||
|
case MANUAL -> {
|
||||||
|
task.increaseActiveTime(forgottenActivity.getMinutesSpent());
|
||||||
|
BasicTaskSchedule basicTaskSchedule = new BasicTaskSchedule(task, LocalDate.now());
|
||||||
|
LocalDateTime timeReference = LocalDateTime.now();
|
||||||
|
basicTaskSchedule.setStartTime(timeReference.minusMinutes(forgottenActivity.getMinutesSpent()));
|
||||||
|
basicTaskSchedule.setFinishedTime(timeReference);
|
||||||
|
task.getBasicTaskSchedules().add(basicTaskSchedule);
|
||||||
|
basicTaskScheduleRepository.save(basicTaskSchedule);
|
||||||
|
taskRepository.save(task);
|
||||||
|
return new ServiceResult<>(forgottenActivity.getMinutesSpent());
|
||||||
|
}
|
||||||
|
case LAST -> {
|
||||||
|
List<BasicTaskSchedule> schedules = basicTaskScheduleRepository.findAllFinishedByUserAndDate(task.getTaskgroup().getUser(), LocalDate.now());
|
||||||
|
if(schedules.isEmpty()) {
|
||||||
|
return new ServiceResult<>(ServiceExitCode.INVALID_OPERATION);
|
||||||
|
} else {
|
||||||
|
LocalDateTime timeReference = LocalDateTime.now();
|
||||||
|
BasicTaskSchedule nearestSchedule = null;
|
||||||
|
long nearestDuration = Long.MAX_VALUE;
|
||||||
|
for(BasicTaskSchedule schedule : schedules) {
|
||||||
|
if(nearestSchedule == null) {
|
||||||
|
nearestSchedule = schedule;
|
||||||
|
nearestDuration = Duration.between(nearestSchedule.getFinishedTime(), timeReference).getSeconds();
|
||||||
|
} else {
|
||||||
|
long currentDuration = Duration.between(schedule.getFinishedTime(), timeReference).getSeconds();
|
||||||
|
if(currentDuration < nearestDuration) {
|
||||||
|
nearestSchedule = schedule;
|
||||||
|
nearestDuration = currentDuration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int minutesSpent = (int) Duration.between(nearestSchedule.getFinishedTime(), timeReference).toMinutes();
|
||||||
|
task.increaseActiveTime(minutesSpent);
|
||||||
|
BasicTaskSchedule basicTaskSchedule = new BasicTaskSchedule(task, timeReference.toLocalDate());
|
||||||
|
basicTaskSchedule.setStartTime(nearestSchedule.getFinishedTime());
|
||||||
|
basicTaskSchedule.setFinishedTime(timeReference);
|
||||||
|
basicTaskScheduleRepository.save(basicTaskSchedule);
|
||||||
|
taskRepository.save(task);
|
||||||
|
new ServiceResult<>(minutesSpent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case PLANNED -> {
|
||||||
|
//Does not make sense until advanced schedule/moderate schedule is implemented
|
||||||
|
return new ServiceResult<>(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException("INVALID MODE");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,4 +98,8 @@ public class TaskService {
|
|||||||
taskScheduleService.deleteBasicSchedule(deletedTaskSchedule);
|
taskScheduleService.deleteBasicSchedule(deletedTaskSchedule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Task> loadAllTasks(String username, boolean finished) {
|
||||||
|
return taskRepository.findAllByUser(username, finished);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ model/accountDeleteRequest.ts
|
|||||||
model/basicScheduleEntityInfo.ts
|
model/basicScheduleEntityInfo.ts
|
||||||
model/basicScheduleFieldInfo.ts
|
model/basicScheduleFieldInfo.ts
|
||||||
model/eMailChangeRequest.ts
|
model/eMailChangeRequest.ts
|
||||||
|
model/forgottenActivityRequest.ts
|
||||||
model/inlineResponse200.ts
|
model/inlineResponse200.ts
|
||||||
model/inlineResponse401.ts
|
model/inlineResponse401.ts
|
||||||
model/inlineResponse403.ts
|
model/inlineResponse403.ts
|
||||||
|
@ -20,6 +20,7 @@ import { Observable } from 'rxjs';
|
|||||||
|
|
||||||
import { BasicScheduleEntityInfo } from '../model/models';
|
import { BasicScheduleEntityInfo } from '../model/models';
|
||||||
import { BasicScheduleFieldInfo } from '../model/models';
|
import { BasicScheduleFieldInfo } from '../model/models';
|
||||||
|
import { ForgottenActivityRequest } from '../model/models';
|
||||||
import { ScheduleActivateInfo } from '../model/models';
|
import { ScheduleActivateInfo } from '../model/models';
|
||||||
import { ScheduleInfo } from '../model/models';
|
import { ScheduleInfo } from '../model/models';
|
||||||
import { ScheduleStatus } from '../model/models';
|
import { ScheduleStatus } from '../model/models';
|
||||||
@ -581,6 +582,76 @@ export class ScheduleService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* registers forgotten schedule
|
||||||
|
* Registers forgotten schedule
|
||||||
|
* @param taskID internal id of task
|
||||||
|
* @param forgottenActivityRequest
|
||||||
|
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||||
|
* @param reportProgress flag to report request and response progress.
|
||||||
|
*/
|
||||||
|
public schedulesTaskIDForgottenPost(taskID: number, forgottenActivityRequest?: ForgottenActivityRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<TaskScheduleStopResponse>;
|
||||||
|
public schedulesTaskIDForgottenPost(taskID: number, forgottenActivityRequest?: ForgottenActivityRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<TaskScheduleStopResponse>>;
|
||||||
|
public schedulesTaskIDForgottenPost(taskID: number, forgottenActivityRequest?: ForgottenActivityRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<TaskScheduleStopResponse>>;
|
||||||
|
public schedulesTaskIDForgottenPost(taskID: number, forgottenActivityRequest?: ForgottenActivityRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||||
|
if (taskID === null || taskID === undefined) {
|
||||||
|
throw new Error('Required parameter taskID was null or undefined when calling schedulesTaskIDForgottenPost.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHeaders = this.defaultHeaders;
|
||||||
|
|
||||||
|
let localVarCredential: string | undefined;
|
||||||
|
// authentication (API_TOKEN) required
|
||||||
|
localVarCredential = this.configuration.lookupCredential('API_TOKEN');
|
||||||
|
if (localVarCredential) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
|
||||||
|
if (localVarHttpHeaderAcceptSelected === undefined) {
|
||||||
|
// to determine the Accept header
|
||||||
|
const httpHeaderAccepts: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||||
|
}
|
||||||
|
if (localVarHttpHeaderAcceptSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpContext: HttpContext | undefined = options && options.context;
|
||||||
|
if (localVarHttpContext === undefined) {
|
||||||
|
localVarHttpContext = new HttpContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// to determine the Content-Type header
|
||||||
|
const consumes: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||||
|
if (httpContentTypeSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let responseType_: 'text' | 'json' = 'json';
|
||||||
|
if(localVarHttpHeaderAcceptSelected && localVarHttpHeaderAcceptSelected.startsWith('text')) {
|
||||||
|
responseType_ = 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.httpClient.post<TaskScheduleStopResponse>(`${this.configuration.basePath}/schedules/${encodeURIComponent(String(taskID))}/forgotten`,
|
||||||
|
forgottenActivityRequest,
|
||||||
|
{
|
||||||
|
context: localVarHttpContext,
|
||||||
|
responseType: <any>responseType_,
|
||||||
|
withCredentials: this.configuration.withCredentials,
|
||||||
|
headers: localVarHeaders,
|
||||||
|
observe: observe,
|
||||||
|
reportProgress: reportProgress
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* schedule task now
|
* schedule task now
|
||||||
* schedule task now
|
* schedule task now
|
||||||
|
@ -22,6 +22,7 @@ import { InlineResponse403 } from '../model/models';
|
|||||||
import { SimpleStatusResponse } from '../model/models';
|
import { SimpleStatusResponse } from '../model/models';
|
||||||
import { TaskEntityInfo } from '../model/models';
|
import { TaskEntityInfo } from '../model/models';
|
||||||
import { TaskFieldInfo } from '../model/models';
|
import { TaskFieldInfo } from '../model/models';
|
||||||
|
import { TaskShortInfo } from '../model/models';
|
||||||
|
|
||||||
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
|
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
|
||||||
import { Configuration } from '../configuration';
|
import { Configuration } from '../configuration';
|
||||||
@ -88,6 +89,65 @@ export class TaskService {
|
|||||||
return httpParams;
|
return httpParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* edits an existing task
|
||||||
|
* edits an existing task
|
||||||
|
* @param finished fetches either finished or unfinished tasks
|
||||||
|
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||||
|
* @param reportProgress flag to report request and response progress.
|
||||||
|
*/
|
||||||
|
public tasksAllFinishedGet(finished: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<Array<TaskShortInfo>>;
|
||||||
|
public tasksAllFinishedGet(finished: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<Array<TaskShortInfo>>>;
|
||||||
|
public tasksAllFinishedGet(finished: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<Array<TaskShortInfo>>>;
|
||||||
|
public tasksAllFinishedGet(finished: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||||
|
if (finished === null || finished === undefined) {
|
||||||
|
throw new Error('Required parameter finished was null or undefined when calling tasksAllFinishedGet.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHeaders = this.defaultHeaders;
|
||||||
|
|
||||||
|
let localVarCredential: string | undefined;
|
||||||
|
// authentication (API_TOKEN) required
|
||||||
|
localVarCredential = this.configuration.lookupCredential('API_TOKEN');
|
||||||
|
if (localVarCredential) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
|
||||||
|
if (localVarHttpHeaderAcceptSelected === undefined) {
|
||||||
|
// to determine the Accept header
|
||||||
|
const httpHeaderAccepts: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||||
|
}
|
||||||
|
if (localVarHttpHeaderAcceptSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpContext: HttpContext | undefined = options && options.context;
|
||||||
|
if (localVarHttpContext === undefined) {
|
||||||
|
localVarHttpContext = new HttpContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let responseType_: 'text' | 'json' = 'json';
|
||||||
|
if(localVarHttpHeaderAcceptSelected && localVarHttpHeaderAcceptSelected.startsWith('text')) {
|
||||||
|
responseType_ = 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.httpClient.get<Array<TaskShortInfo>>(`${this.configuration.basePath}/tasks/all/${encodeURIComponent(String(finished))}`,
|
||||||
|
{
|
||||||
|
context: localVarHttpContext,
|
||||||
|
responseType: <any>responseType_,
|
||||||
|
withCredentials: this.configuration.withCredentials,
|
||||||
|
headers: localVarHeaders,
|
||||||
|
observe: observe,
|
||||||
|
reportProgress: reportProgress
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* edits an existing task
|
* edits an existing task
|
||||||
* edits an existing task
|
* edits an existing task
|
||||||
|
33
frontend/src/api/model/forgottenActivityRequest.ts
Normal file
33
frontend/src/api/model/forgottenActivityRequest.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* API Title
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export interface ForgottenActivityRequest {
|
||||||
|
/**
|
||||||
|
* mode of register forgotten activity
|
||||||
|
*/
|
||||||
|
mode: ForgottenActivityRequest.ModeEnum;
|
||||||
|
/**
|
||||||
|
* number of minutes spent on task
|
||||||
|
*/
|
||||||
|
minutesSpent?: number;
|
||||||
|
}
|
||||||
|
export namespace ForgottenActivityRequest {
|
||||||
|
export type ModeEnum = 'MANUAL' | 'LAST' | 'PLANNED';
|
||||||
|
export const ModeEnum = {
|
||||||
|
Manual: 'MANUAL' as ModeEnum,
|
||||||
|
Last: 'LAST' as ModeEnum,
|
||||||
|
Planned: 'PLANNED' as ModeEnum
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -2,6 +2,7 @@ export * from './accountDeleteRequest';
|
|||||||
export * from './basicScheduleEntityInfo';
|
export * from './basicScheduleEntityInfo';
|
||||||
export * from './basicScheduleFieldInfo';
|
export * from './basicScheduleFieldInfo';
|
||||||
export * from './eMailChangeRequest';
|
export * from './eMailChangeRequest';
|
||||||
|
export * from './forgottenActivityRequest';
|
||||||
export * from './inlineResponse200';
|
export * from './inlineResponse200';
|
||||||
export * from './inlineResponse401';
|
export * from './inlineResponse401';
|
||||||
export * from './inlineResponse403';
|
export * from './inlineResponse403';
|
||||||
|
@ -67,6 +67,8 @@ import { ActiveScheduleComponent } from './dashboard/active-schedule/active-sche
|
|||||||
import {MatTreeModule} from "@angular/material/tree";
|
import {MatTreeModule} from "@angular/material/tree";
|
||||||
import { TaskgroupOverviewComponent } from './dashboard/taskgroup-overview/taskgroup-overview.component';
|
import { TaskgroupOverviewComponent } from './dashboard/taskgroup-overview/taskgroup-overview.component';
|
||||||
import { TaskOverviewComponent } from './dashboard/task-overview/task-overview.component';
|
import { TaskOverviewComponent } from './dashboard/task-overview/task-overview.component';
|
||||||
|
import { ForgottenTaskStartDialogComponent } from './dashboard/forgotten-task-start-dialog/forgotten-task-start-dialog.component';
|
||||||
|
import {MatAutocompleteModule} from "@angular/material/autocomplete";
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
@ -97,44 +99,46 @@ import { TaskOverviewComponent } from './dashboard/task-overview/task-overview.c
|
|||||||
DashboardComponent,
|
DashboardComponent,
|
||||||
ActiveScheduleComponent,
|
ActiveScheduleComponent,
|
||||||
TaskgroupOverviewComponent,
|
TaskgroupOverviewComponent,
|
||||||
TaskOverviewComponent
|
TaskOverviewComponent,
|
||||||
|
ForgottenTaskStartDialogComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
AppRoutingModule,
|
||||||
|
FormsModule,
|
||||||
|
ApiModule,
|
||||||
|
HttpClientModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
MatToolbarModule,
|
||||||
|
MatButtonModule,
|
||||||
|
MatIconModule,
|
||||||
|
MatDialogModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatProgressSpinnerModule,
|
||||||
|
MatSnackBarModule,
|
||||||
|
MatMenuModule,
|
||||||
|
MatTabsModule,
|
||||||
|
MatTableModule,
|
||||||
|
MatCheckboxModule,
|
||||||
|
MatCardModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
MatListModule,
|
||||||
|
MatDatepickerModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatDatepickerModule,
|
||||||
|
MatMomentDateModule,
|
||||||
|
FormsModule,
|
||||||
|
MatSlideToggleModule,
|
||||||
|
MatSortModule,
|
||||||
|
MatPaginatorModule,
|
||||||
|
MatProgressBarModule,
|
||||||
|
MatExpansionModule,
|
||||||
|
CalendarModule.forRoot({provide: DateAdapter, useFactory: adapterFactory}),
|
||||||
|
MatSelectModule,
|
||||||
|
MatTreeModule,
|
||||||
|
MatAutocompleteModule
|
||||||
],
|
],
|
||||||
imports: [
|
|
||||||
BrowserModule,
|
|
||||||
AppRoutingModule,
|
|
||||||
FormsModule,
|
|
||||||
ApiModule,
|
|
||||||
HttpClientModule,
|
|
||||||
BrowserAnimationsModule,
|
|
||||||
MatToolbarModule,
|
|
||||||
MatButtonModule,
|
|
||||||
MatIconModule,
|
|
||||||
MatDialogModule,
|
|
||||||
MatFormFieldModule,
|
|
||||||
MatInputModule,
|
|
||||||
MatProgressSpinnerModule,
|
|
||||||
MatSnackBarModule,
|
|
||||||
MatMenuModule,
|
|
||||||
MatTabsModule,
|
|
||||||
MatTableModule,
|
|
||||||
MatCheckboxModule,
|
|
||||||
MatCardModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
MatListModule,
|
|
||||||
MatDatepickerModule,
|
|
||||||
MatInputModule,
|
|
||||||
MatDatepickerModule,
|
|
||||||
MatMomentDateModule,
|
|
||||||
FormsModule,
|
|
||||||
MatSlideToggleModule,
|
|
||||||
MatSortModule,
|
|
||||||
MatPaginatorModule,
|
|
||||||
MatProgressBarModule,
|
|
||||||
MatExpansionModule,
|
|
||||||
CalendarModule.forRoot({provide: DateAdapter, useFactory: adapterFactory}),
|
|
||||||
MatSelectModule,
|
|
||||||
MatTreeModule
|
|
||||||
],
|
|
||||||
providers: [
|
providers: [
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
/*
|
/*
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<mat-card class="green-card" *ngIf="activeSchedule == undefined">
|
<mat-card class="green-card" *ngIf="activeSchedule == undefined">
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<p>Currently there is no task in progress.</p>
|
<p>Currently there is no task in progress.</p>
|
||||||
<a class="btn-link" routerLink="/">Did you forget to start an activity?</a>
|
<a class="btn-link" (click)="openForgettedActivityDialog()">Did you forget to start an activity?</a>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
<mat-card *ngIf="activeSchedule != undefined">
|
<mat-card *ngIf="activeSchedule != undefined">
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
||||||
import {ScheduleInfo, ScheduleService, TaskOverviewInfo} from "../../../api";
|
import {ScheduleInfo, ScheduleService, TaskOverviewInfo, TaskScheduleStopResponse} from "../../../api";
|
||||||
import {StopActiveScheduleInfo} from "./StopActiveScheduleInfo";
|
import {StopActiveScheduleInfo} from "./StopActiveScheduleInfo";
|
||||||
import {TaskOverviewComponent} from "../task-overview/task-overview.component";
|
import {TaskOverviewComponent} from "../task-overview/task-overview.component";
|
||||||
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
|
import {ForgottenTaskStartDialogComponent} from "../forgotten-task-start-dialog/forgotten-task-start-dialog.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-active-schedule',
|
selector: 'app-active-schedule',
|
||||||
@ -16,8 +18,10 @@ export class ActiveScheduleComponent implements OnInit{
|
|||||||
displayTime: string = "00:00:00"
|
displayTime: string = "00:00:00"
|
||||||
|
|
||||||
@Output('onStopTask') scheduleStopEmitter = new EventEmitter<StopActiveScheduleInfo>;
|
@Output('onStopTask') scheduleStopEmitter = new EventEmitter<StopActiveScheduleInfo>;
|
||||||
|
@Output('registerForgotten') registerForgottenEmitter = new EventEmitter<TaskScheduleStopResponse>
|
||||||
|
|
||||||
constructor(private scheduleService: ScheduleService) {
|
constructor(private scheduleService: ScheduleService,
|
||||||
|
private dialog: MatDialog) {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -74,4 +78,12 @@ export class ActiveScheduleComponent implements OnInit{
|
|||||||
this.activeSchedule = undefined
|
this.activeSchedule = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openForgettedActivityDialog() {
|
||||||
|
const dialogRef = this.dialog.open(ForgottenTaskStartDialogComponent, {width: "400px"})
|
||||||
|
dialogRef.afterClosed().subscribe(res => {
|
||||||
|
if(res != undefined) {
|
||||||
|
this.registerForgottenEmitter.emit(res);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</mat-card>
|
</mat-card>
|
||||||
<h1 class="dashboard-heading">Now<b class="today-worked-info">Today: {{workedMinutesToday}} min</b></h1>
|
<h1 class="dashboard-heading">Now<b class="today-worked-info">Today: {{workedMinutesToday}} min</b></h1>
|
||||||
|
|
||||||
<app-active-schedule #activeSchedule (onStopTask)="stopedTask($event)"></app-active-schedule>
|
<app-active-schedule #activeSchedule (onStopTask)="stopedTask($event)" (registerForgotten)="registerForgotten($event)"></app-active-schedule>
|
||||||
|
|
||||||
<h1 class="dashboard-heading">Scheduled for today</h1>
|
<h1 class="dashboard-heading">Scheduled for today</h1>
|
||||||
<mat-card class="green-card" *ngIf="schedules.length == 0">
|
<mat-card class="green-card" *ngIf="schedules.length == 0">
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
import {Component, OnInit, ViewChild} from '@angular/core';
|
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||||
import {BasicScheduleEntityInfo, ScheduleInfo, ScheduleService, TaskOverviewInfo} from "../../api";
|
import {
|
||||||
|
BasicScheduleEntityInfo,
|
||||||
|
ScheduleInfo,
|
||||||
|
ScheduleService,
|
||||||
|
TaskOverviewInfo,
|
||||||
|
TaskScheduleStopResponse
|
||||||
|
} from "../../api";
|
||||||
import {ActiveScheduleComponent} from "./active-schedule/active-schedule.component";
|
import {ActiveScheduleComponent} from "./active-schedule/active-schedule.component";
|
||||||
import {StopActiveScheduleInfo} from "./active-schedule/StopActiveScheduleInfo";
|
import {StopActiveScheduleInfo} from "./active-schedule/StopActiveScheduleInfo";
|
||||||
import {TaskOverviewComponent} from "./task-overview/task-overview.component";
|
import {TaskOverviewComponent} from "./task-overview/task-overview.component";
|
||||||
@ -72,4 +78,8 @@ export class DashboardComponent implements OnInit{
|
|||||||
|
|
||||||
this.schedules = this.schedules.filter(schedule => schedule.task.taskID !== task.taskID)
|
this.schedules = this.schedules.filter(schedule => schedule.task.taskID !== task.taskID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerForgotten(taskScheduleStopResponse: TaskScheduleStopResponse) {
|
||||||
|
this.workedMinutesToday += taskScheduleStopResponse.workTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
.example-full-width {
|
||||||
|
width: 100%;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
<h1 mat-dialog-title>Register forgotten activity</h1>
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<mat-form-field class="example-full-width">
|
||||||
|
<mat-label>Number</mat-label>
|
||||||
|
<input type="text"
|
||||||
|
placeholder="Pick one"
|
||||||
|
matInput
|
||||||
|
[formControl]="myControl"
|
||||||
|
[matAutocomplete]="auto">
|
||||||
|
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
|
||||||
|
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
|
||||||
|
{{option}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-autocomplete>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-checkbox *ngIf="!plannedSchedule" [(ngModel)]="lastSchedule">Automatic starttime based on <b>last</b> schedule</mat-checkbox>
|
||||||
|
<mat-checkbox *ngIf="!lastSchedule" [(ngModel)]="plannedSchedule">Automatic starttime based on <b>planned</b> schedule</mat-checkbox>
|
||||||
|
|
||||||
|
<mat-form-field class="example-full-width" *ngIf="!lastSchedule && !plannedSchedule">
|
||||||
|
<mat-label>Minutes spent</mat-label>
|
||||||
|
<input matInput type="number" [formControl]="minutesSpentControl">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div mat-dialog-actions align="end">
|
||||||
|
<button mat-raised-button>Cancel</button>
|
||||||
|
<button mat-raised-button color="primary" (click)="registerActivity()">Register</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ForgottenTaskStartDialogComponent } from './forgotten-task-start-dialog.component';
|
||||||
|
|
||||||
|
describe('ForgottenTaskStartDialogComponent', () => {
|
||||||
|
let component: ForgottenTaskStartDialogComponent;
|
||||||
|
let fixture: ComponentFixture<ForgottenTaskStartDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ForgottenTaskStartDialogComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(ForgottenTaskStartDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,80 @@
|
|||||||
|
import {Component, OnInit} from '@angular/core';
|
||||||
|
import {ScheduleService, TaskService, TaskShortInfo} from "../../../api";
|
||||||
|
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||||
|
import {DialogRef} from "@angular/cdk/dialog";
|
||||||
|
import {MatDialogRef} from "@angular/material/dialog";
|
||||||
|
import {filter, map, Observable, startWith} from "rxjs";
|
||||||
|
import {FormControl} from "@angular/forms";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-forgotten-task-start-dialog',
|
||||||
|
templateUrl: './forgotten-task-start-dialog.component.html',
|
||||||
|
styleUrls: ['./forgotten-task-start-dialog.component.css']
|
||||||
|
})
|
||||||
|
export class ForgottenTaskStartDialogComponent implements OnInit{
|
||||||
|
|
||||||
|
tasks: TaskShortInfo[] = []
|
||||||
|
myControl: FormControl = new FormControl('');
|
||||||
|
filteredOptions: Observable<string[]> | undefined;
|
||||||
|
|
||||||
|
lastSchedule: boolean = false
|
||||||
|
plannedSchedule: boolean = false
|
||||||
|
minutesSpentControl: FormControl = new FormControl();
|
||||||
|
|
||||||
|
|
||||||
|
constructor(private taskService: TaskService,
|
||||||
|
private snackbar: MatSnackBar,
|
||||||
|
private dialogRef: MatDialogRef<ForgottenTaskStartDialogComponent>,
|
||||||
|
private scheduleService: ScheduleService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.taskService.tasksAllFinishedGet(false).subscribe({
|
||||||
|
next: resp => {
|
||||||
|
this.tasks = resp;
|
||||||
|
this.filteredOptions = this.myControl.valueChanges.pipe(
|
||||||
|
startWith(''),
|
||||||
|
map(value => this._filter(value || '')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
error: err => {
|
||||||
|
this.snackbar.open("Unexpected error", "", {duration: 2000});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private _filter(value: string): string[] {
|
||||||
|
const filterValue = value.toLowerCase();
|
||||||
|
|
||||||
|
return this.tasks.map(x => x.taskName).filter(option => option.toLowerCase().includes(filterValue))
|
||||||
|
}
|
||||||
|
|
||||||
|
registerActivity() {
|
||||||
|
const task = this.tasks.find(task => task.taskName === this.myControl.value);
|
||||||
|
if(task != undefined) {
|
||||||
|
this.scheduleService.schedulesTaskIDForgottenPost(task.taskID, {
|
||||||
|
mode: "MANUAL",
|
||||||
|
minutesSpent: this.minutesSpentControl.value
|
||||||
|
}).subscribe({
|
||||||
|
next: resp => {
|
||||||
|
this.dialogRef.close(resp);
|
||||||
|
},
|
||||||
|
error: err => {
|
||||||
|
if(err.status == 400) {
|
||||||
|
this.snackbar.open("Invalid Operation", "", {duration: 2000});
|
||||||
|
} else if(err.status == 403) {
|
||||||
|
this.snackbar.open("No permission", "", {duration: 2000});
|
||||||
|
} else if(err.status == 404) {
|
||||||
|
this.snackbar.open("Task not found", "", {duration: 2000});
|
||||||
|
} else {
|
||||||
|
this.snackbar.open("Unexpected error", "", {duration: 2000});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private determineRegisterMode(): string {
|
||||||
|
return "MANUAL";
|
||||||
|
}
|
||||||
|
}
|
95
openapi.yaml
95
openapi.yaml
@ -883,6 +883,32 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
$ref: "#/components/schemas/SimpleStatusResponse"
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
/tasks/all/{finished}:
|
||||||
|
get:
|
||||||
|
security:
|
||||||
|
- API_TOKEN: []
|
||||||
|
tags:
|
||||||
|
- task
|
||||||
|
summary: edits an existing task
|
||||||
|
description: edits an existing task
|
||||||
|
parameters:
|
||||||
|
- name: finished
|
||||||
|
in: path
|
||||||
|
description: fetches either finished or unfinished tasks
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
example: true
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Operation successfull
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/TaskShortInfo'
|
||||||
|
|
||||||
/tasks/{taskgroupID}/{status}:
|
/tasks/{taskgroupID}/{status}:
|
||||||
get:
|
get:
|
||||||
security:
|
security:
|
||||||
@ -1619,7 +1645,55 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
$ref: "#/components/schemas/SimpleStatusResponse"
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
/schedules/{taskID}/forgotten:
|
||||||
|
post:
|
||||||
|
security:
|
||||||
|
- API_TOKEN: []
|
||||||
|
tags:
|
||||||
|
- schedule
|
||||||
|
description: Registers forgotten schedule
|
||||||
|
summary: registers forgotten schedule
|
||||||
|
parameters:
|
||||||
|
- name: taskID
|
||||||
|
in: path
|
||||||
|
description: internal id of task
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: number
|
||||||
|
example: 1
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ForgottenActivityRequest'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Operation successfull
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TaskScheduleStopResponse'
|
||||||
|
403:
|
||||||
|
description: No permission
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
404:
|
||||||
|
description: Schedule does not exist
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
400:
|
||||||
|
description: Operation not valid
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2140,4 +2214,21 @@ components:
|
|||||||
missedSchedules:
|
missedSchedules:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: states whether a schedule was missed or not
|
description: states whether a schedule was missed or not
|
||||||
example: true
|
example: true
|
||||||
|
ForgottenActivityRequest:
|
||||||
|
required:
|
||||||
|
- mode
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
mode:
|
||||||
|
type: string
|
||||||
|
description: mode of register forgotten activity
|
||||||
|
example: MANUAL
|
||||||
|
enum:
|
||||||
|
- MANUAL
|
||||||
|
- LAST
|
||||||
|
- PLANNED
|
||||||
|
minutesSpent:
|
||||||
|
type: number
|
||||||
|
description: number of minutes spent on task
|
||||||
|
example: 10
|
Loading…
Reference in New Issue
Block a user