Compare commits
No commits in common. "master" and "issue-113" have entirely different histories.
@ -5,7 +5,10 @@ import core.api.models.timemanager.history.TaskgroupActivityInfo;
|
|||||||
import core.api.models.timemanager.history.WorkingStatus;
|
import core.api.models.timemanager.history.WorkingStatus;
|
||||||
import core.entities.timemanager.AbstractSchedule;
|
import core.entities.timemanager.AbstractSchedule;
|
||||||
import core.entities.timemanager.Taskgroup;
|
import core.entities.timemanager.Taskgroup;
|
||||||
import core.services.*;
|
import core.services.PermissionResult;
|
||||||
|
import core.services.ServiceExitCode;
|
||||||
|
import core.services.TaskScheduleService;
|
||||||
|
import core.services.TaskgroupService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
@ -21,7 +24,6 @@ import java.util.*;
|
|||||||
public class StatisticController {
|
public class StatisticController {
|
||||||
|
|
||||||
@Autowired private TaskScheduleService taskScheduleService;
|
@Autowired private TaskScheduleService taskScheduleService;
|
||||||
@Autowired private StatisticService statisticService;
|
|
||||||
@Autowired private TaskgroupService taskgroupService;
|
@Autowired private TaskgroupService taskgroupService;
|
||||||
|
|
||||||
@GetMapping("/history/workingStatus")
|
@GetMapping("/history/workingStatus")
|
||||||
@ -40,29 +42,24 @@ public class StatisticController {
|
|||||||
return ResponseEntity.ok(new WorkingStatus(missedSchedules, activeTime));
|
return ResponseEntity.ok(new WorkingStatus(missedSchedules, activeTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/statistics/{startingDate}/{endingDate}")
|
@GetMapping("/statistics/taskgroup-activity/{taskgroupID}/{startingDate}/{endingDate}/{includeSubTaskgroups}")
|
||||||
public ResponseEntity<?> getTaskgroupActivity(@PathVariable String startingDate, @PathVariable String endingDate){
|
public ResponseEntity<?> getTaskgroupActivity(@PathVariable long taskgroupID, @PathVariable String startingDate, @PathVariable String endingDate, @PathVariable boolean includeSubTaskgroups){
|
||||||
LocalDate starting = LocalDate.parse(startingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
PermissionResult<Taskgroup> taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
LocalDate ending = LocalDate.parse(endingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
if(taskgroupPermissionResult.isNoPermissions()) {
|
||||||
|
return ResponseEntity.status(403).body(new SimpleStatusResponse("failed"));
|
||||||
var taskgroupActivityInfos = statisticService.calcActivityByUser(null, SecurityContextHolder.getContext().getAuthentication().getName(), starting, ending);
|
} else if(taskgroupPermissionResult.getExitCode() == ServiceExitCode.MISSING_ENTITY) {
|
||||||
List<TaskgroupActivityInfo> outgoingResult = StatisticService.convertInternActivityInfo(taskgroupActivityInfos);
|
return ResponseEntity.status(404).body(new SimpleStatusResponse("failed"));
|
||||||
return ResponseEntity.ok(outgoingResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/statistics/{taskgroupID}/{startingDate}/{endingDate}")
|
|
||||||
public ResponseEntity<?> getTaskgroupActivity(@PathVariable long taskgroupID, @PathVariable String startingDate, @PathVariable String endingDate){
|
|
||||||
LocalDate starting = LocalDate.parse(startingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
||||||
LocalDate ending = LocalDate.parse(endingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
||||||
String username = SecurityContextHolder.getContext().getAuthentication().getName();
|
|
||||||
var permissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, username);
|
|
||||||
if(permissionResult.hasIssue()) {
|
|
||||||
return permissionResult.mapToResponseEntity();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var taskgroupActivityInfos = statisticService.calcActivityByUser(permissionResult.getResult(), username, starting, ending);
|
List<TaskgroupActivityInfo> activityInfos = taskgroupPermissionResult.getResult().calcActivityInfo(includeSubTaskgroups,
|
||||||
List<TaskgroupActivityInfo> outgoingResult = StatisticService.convertInternActivityInfo(taskgroupActivityInfos);
|
LocalDate.parse(startingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")), LocalDate.parse(endingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||||
return ResponseEntity.ok(outgoingResult);
|
activityInfos.sort(new Comparator<TaskgroupActivityInfo>() {
|
||||||
|
@Override
|
||||||
|
public int compare(TaskgroupActivityInfo o1, TaskgroupActivityInfo o2) {
|
||||||
|
return o1.getDate().compareTo(o2.getDate());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ResponseEntity.ok(activityInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/history/schedules/{date}")
|
@GetMapping("/history/schedules/{date}")
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package core.api.models.timemanager.history;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
|
|
||||||
public class ActivityInfo {
|
|
||||||
|
|
||||||
private LocalDate scheduleDate;
|
|
||||||
private int activeMinutes;
|
|
||||||
|
|
||||||
public ActivityInfo(LocalDate scheduleDate, int workedMinutes) {
|
|
||||||
this.scheduleDate = scheduleDate;
|
|
||||||
this.activeMinutes = workedMinutes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getScheduleDate() {
|
|
||||||
return scheduleDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setScheduleDate(LocalDate scheduleDate) {
|
|
||||||
this.scheduleDate = scheduleDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getActiveMinutes() {
|
|
||||||
return activeMinutes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setActiveMinutes(int activeMinutes) {
|
|
||||||
this.activeMinutes = activeMinutes;
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,23 +4,25 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo;
|
import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TaskgroupActivityInfo {
|
public class TaskgroupActivityInfo {
|
||||||
|
|
||||||
private TaskgroupEntityInfo taskgroup;
|
@JsonProperty
|
||||||
private List<ActivityInfo> activityInfos;
|
private LocalDate date;
|
||||||
|
|
||||||
public TaskgroupActivityInfo(TaskgroupEntityInfo taskgroup, List<ActivityInfo> activityInfos) {
|
@JsonProperty
|
||||||
this.taskgroup = taskgroup;
|
private int activeMinutes;
|
||||||
this.activityInfos = activityInfos;
|
|
||||||
|
public TaskgroupActivityInfo(int activeMinutes, LocalDate localDate) {
|
||||||
|
this.date = localDate;
|
||||||
|
this.activeMinutes = activeMinutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskgroupEntityInfo getTaskgroup() {
|
public LocalDate getDate() {
|
||||||
return taskgroup;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ActivityInfo> getActivityInfos() {
|
public int getActiveMinutes() {
|
||||||
return activityInfos;
|
return activeMinutes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,6 @@ public class Task {
|
|||||||
clonedSchedules.add(clonedSchedule);
|
clonedSchedules.add(clonedSchedule);
|
||||||
clonedTask.getBasicTaskSchedules().clear();
|
clonedTask.getBasicTaskSchedules().clear();
|
||||||
clonedTask.getBasicTaskSchedules().add(clonedSchedule);
|
clonedTask.getBasicTaskSchedules().add(clonedSchedule);
|
||||||
|
|
||||||
clonedSchedule.setTask(clonedTask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Task> clonedSubtasks = new HashSet<>();
|
Set<Task> clonedSubtasks = new HashSet<>();
|
||||||
|
@ -136,5 +136,54 @@ public class Taskgroup {
|
|||||||
return Objects.hash(taskgroupID);
|
return Objects.hash(taskgroupID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<TaskgroupActivityInfo> calcActivityInfo(boolean includeChildTasks, LocalDate start, LocalDate end) {
|
||||||
|
HashMap<LocalDate, Integer> activityInfos = new HashMap<>();
|
||||||
|
if(includeChildTasks) {
|
||||||
|
|
||||||
|
Queue<Taskgroup> queue = new LinkedList<>(children);
|
||||||
|
while(!queue.isEmpty()) {
|
||||||
|
Taskgroup childTraskgroup = queue.poll();
|
||||||
|
LocalDate currentDate = start;
|
||||||
|
while(!currentDate.isAfter(end)) {
|
||||||
|
int activeMinutes = 0;
|
||||||
|
for(Task task : childTraskgroup.getTasks()) {
|
||||||
|
activeMinutes += task.calcOverallActivityInfo(currentDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(activityInfos.containsKey(currentDate)) {
|
||||||
|
activityInfos.put(currentDate, activityInfos.get(currentDate) + activeMinutes);
|
||||||
|
} else {
|
||||||
|
activityInfos.put(currentDate, activeMinutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDate = currentDate.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
queue.addAll(childTraskgroup.getChildren());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate currentDate = start;
|
||||||
|
while(!currentDate.isAfter(end)) {
|
||||||
|
int activeMinutes = 0;
|
||||||
|
for(Task task : tasks) {
|
||||||
|
activeMinutes += task.calcOverallActivityInfo(currentDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(activityInfos.containsKey(currentDate)) {
|
||||||
|
activityInfos.put(currentDate, activityInfos.get(currentDate) + activeMinutes);
|
||||||
|
} else {
|
||||||
|
activityInfos.put(currentDate, activeMinutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDate = currentDate.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TaskgroupActivityInfo> taskgroupActivityInfos = new ArrayList<>();
|
||||||
|
for(Map.Entry<LocalDate, Integer> entry : activityInfos.entrySet()) {
|
||||||
|
taskgroupActivityInfos.add(new TaskgroupActivityInfo(entry.getValue(), entry.getKey()));
|
||||||
|
}
|
||||||
|
return taskgroupActivityInfos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,4 @@ public interface ScheduleRepository extends CrudRepository<AbstractSchedule, Lon
|
|||||||
@Transactional
|
@Transactional
|
||||||
@Query(value = "DELETE FROM AbstractSchedule a WHERE a.task IN (SELECT t FROM Task t WHERE t.taskgroup = ?1)")
|
@Query(value = "DELETE FROM AbstractSchedule a WHERE a.task IN (SELECT t FROM Task t WHERE t.taskgroup = ?1)")
|
||||||
void deleteByTaskgroup(Taskgroup taskgroup);
|
void deleteByTaskgroup(Taskgroup taskgroup);
|
||||||
|
|
||||||
@Query(value = "SELECT s FROM AbstractSchedule s WHERE s.task.taskgroup.user.username = ?1 AND s.startTime is NOT NULL AND s.stopTime IS NOT NULL")
|
|
||||||
List<AbstractSchedule> getAllFinishedSchedulesByUser(String username);
|
|
||||||
}
|
}
|
||||||
|
@ -1,113 +0,0 @@
|
|||||||
package core.services;
|
|
||||||
|
|
||||||
import core.api.models.timemanager.history.ActivityInfo;
|
|
||||||
import core.api.models.timemanager.history.TaskgroupActivityInfo;
|
|
||||||
import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo;
|
|
||||||
import core.entities.timemanager.AbstractSchedule;
|
|
||||||
import core.entities.timemanager.Taskgroup;
|
|
||||||
import core.repositories.timemanager.ScheduleRepository;
|
|
||||||
import core.repositories.timemanager.TaskgroupRepository;
|
|
||||||
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.time.LocalTime;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class StatisticService {
|
|
||||||
|
|
||||||
@Autowired private ScheduleRepository scheduleRepository;
|
|
||||||
|
|
||||||
public HashMap<Taskgroup, HashMap<LocalDate, Integer>> calcActivityByUser(Taskgroup taskgroup, String username, LocalDate startinDate, LocalDate endingDate) {
|
|
||||||
HashMap<Taskgroup, HashMap<LocalDate, Integer>> taskgroupActivityInfos = new HashMap<>();
|
|
||||||
List<AbstractSchedule> startedSchedules = scheduleRepository.getAllFinishedSchedulesByUser(username);
|
|
||||||
for(AbstractSchedule schedule : startedSchedules) {
|
|
||||||
if(schedule.getStartTime().toLocalDate().isAfter(endingDate) || schedule.getStopTime().toLocalDate().isBefore(startinDate)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Taskgroup topTaskgroup;
|
|
||||||
if(taskgroup == null) {
|
|
||||||
topTaskgroup = findTopTaskgroup(schedule.getTask().getTaskgroup());
|
|
||||||
} else {
|
|
||||||
topTaskgroup = findTaskgroupOfLayer(taskgroup, schedule.getTask().getTaskgroup());
|
|
||||||
if(topTaskgroup == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap<LocalDate, Integer> taskgroupActivity;
|
|
||||||
if(taskgroupActivityInfos.containsKey(topTaskgroup)) {
|
|
||||||
taskgroupActivity = taskgroupActivityInfos.get(topTaskgroup);
|
|
||||||
} else {
|
|
||||||
taskgroupActivity = new HashMap<>();
|
|
||||||
taskgroupActivityInfos.put(topTaskgroup, taskgroupActivity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(schedule.getStartTime().toLocalDate().isEqual(schedule.getStopTime().toLocalDate())) {
|
|
||||||
insertActivity(taskgroupActivity, schedule.getStartTime().toLocalDate(), schedule.getActiveTime());
|
|
||||||
} else {
|
|
||||||
//Starting Date
|
|
||||||
LocalDateTime startingDayEnd = schedule.getStartTime().toLocalDate().atTime(LocalTime.MAX);
|
|
||||||
Duration startingActivity = Duration.between(schedule.getStartTime(), startingDayEnd);
|
|
||||||
insertActivity(taskgroupActivity, schedule.getStartTime().toLocalDate(), (int) startingActivity.toMinutes());
|
|
||||||
|
|
||||||
//Ending Date
|
|
||||||
LocalDateTime endingDayStart = schedule.getStopTime().toLocalDate().atStartOfDay();
|
|
||||||
Duration endingActivity = Duration.between(endingDayStart, schedule.getStopTime());
|
|
||||||
insertActivity(taskgroupActivity, schedule.getStopTime().toLocalDate(), (int) endingActivity.toMinutes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return taskgroupActivityInfos;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<TaskgroupActivityInfo> convertInternActivityInfo(HashMap<Taskgroup, HashMap<LocalDate, Integer>> taskgroupActivity) {
|
|
||||||
List<TaskgroupActivityInfo> taskgroupActivityInfos = new ArrayList<>();
|
|
||||||
for(Map.Entry<Taskgroup, HashMap<LocalDate, Integer>> entry: taskgroupActivity.entrySet()) {
|
|
||||||
List<ActivityInfo> activityInfos = new ArrayList<>();
|
|
||||||
for(Map.Entry<LocalDate, Integer> dateActivity : entry.getValue().entrySet()) {
|
|
||||||
activityInfos.add(new ActivityInfo(dateActivity.getKey(), dateActivity.getValue()));
|
|
||||||
}
|
|
||||||
taskgroupActivityInfos.add(new TaskgroupActivityInfo(new TaskgroupEntityInfo(entry.getKey()), activityInfos));
|
|
||||||
}
|
|
||||||
return taskgroupActivityInfos;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void insertActivity(HashMap<LocalDate, Integer> activityInfo, LocalDate date, int deltaActivity) {
|
|
||||||
if(activityInfo.containsKey(date)) {
|
|
||||||
int activity = activityInfo.get(date);
|
|
||||||
activity += deltaActivity;
|
|
||||||
activityInfo.put(date, activity);
|
|
||||||
} else {
|
|
||||||
activityInfo.put(date, deltaActivity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Taskgroup findTopTaskgroup(Taskgroup taskgroup) {
|
|
||||||
Taskgroup currentTaskgroup = taskgroup;
|
|
||||||
while(currentTaskgroup.getParent() != null) {
|
|
||||||
currentTaskgroup = currentTaskgroup.getParent();
|
|
||||||
}
|
|
||||||
return currentTaskgroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Taskgroup findTaskgroupOfLayer(Taskgroup targetLayer, Taskgroup childTaskgroup) {
|
|
||||||
if(targetLayer.getTaskgroupID() == childTaskgroup.getTaskgroupID()) {
|
|
||||||
return childTaskgroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
Taskgroup currentTaskgroup = childTaskgroup;
|
|
||||||
while (currentTaskgroup.getParent() != null && currentTaskgroup.getParent().getTaskgroupID() != targetLayer.getTaskgroupID()) {
|
|
||||||
currentTaskgroup = currentTaskgroup.getParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(currentTaskgroup.getParent() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return currentTaskgroup;
|
|
||||||
}
|
|
||||||
}
|
|
@ -62,7 +62,6 @@ public class TaskSeriesService {
|
|||||||
List<AbstractSchedule> clonedSchedules = new ArrayList<>();
|
List<AbstractSchedule> clonedSchedules = new ArrayList<>();
|
||||||
|
|
||||||
LocalDate currentDate = rootTask.getStartDate().plusDays(offsetMap.get(rootTask));
|
LocalDate currentDate = rootTask.getStartDate().plusDays(offsetMap.get(rootTask));
|
||||||
long index = 1;
|
|
||||||
while(currentDate.isBefore(endingDate)) {
|
while(currentDate.isBefore(endingDate)) {
|
||||||
var cloneResult = rootTask.cloneTask();
|
var cloneResult = rootTask.cloneTask();
|
||||||
Task clonedRootTask = cloneResult.getValue00();
|
Task clonedRootTask = cloneResult.getValue00();
|
||||||
@ -74,11 +73,10 @@ public class TaskSeriesService {
|
|||||||
taskSerie.addItem(item);
|
taskSerie.addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
clonedRootTask.shiftTask(index * offsetMap.get(rootTask));
|
clonedRootTask.shiftTask(offsetMap.get(rootTask));
|
||||||
|
|
||||||
currentDate = currentDate.plusDays(offsetMap.get(rootTask));
|
currentDate = currentDate.plusDays(offsetMap.get(rootTask));
|
||||||
itemIndex += offsetMap.size();
|
itemIndex += offsetMap.size();
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Tupel<>(clonedTasks, clonedSchedules);
|
return new Tupel<>(clonedTasks, clonedSchedules);
|
||||||
@ -107,7 +105,7 @@ public class TaskSeriesService {
|
|||||||
HashMap<Task, Integer> offsetMap = new HashMap<>();
|
HashMap<Task, Integer> offsetMap = new HashMap<>();
|
||||||
offsetMap.put(rootTask, taskRepeatInfo.getOffset());
|
offsetMap.put(rootTask, taskRepeatInfo.getOffset());
|
||||||
|
|
||||||
var repeatingResult = repeatTask(rootTask, taskRepeatInfo.getEndingDate(), offsetMap, taskSerie, 1);
|
var repeatingResult = repeatTask(rootTask, taskRepeatInfo.getEndingDate(), offsetMap, taskSerie, 0);
|
||||||
List<Task> clonedTasks = new ArrayList<>(repeatingResult.getValue00());
|
List<Task> clonedTasks = new ArrayList<>(repeatingResult.getValue00());
|
||||||
List<AbstractSchedule> clonedSchedules = new ArrayList<>(repeatingResult.getValue01());
|
List<AbstractSchedule> clonedSchedules = new ArrayList<>(repeatingResult.getValue01());
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ encoder.ts
|
|||||||
git_push.sh
|
git_push.sh
|
||||||
index.ts
|
index.ts
|
||||||
model/accountDeleteRequest.ts
|
model/accountDeleteRequest.ts
|
||||||
model/activityInfo.ts
|
|
||||||
model/advancedScheduleFieldInfo.ts
|
model/advancedScheduleFieldInfo.ts
|
||||||
model/advancedScheduleInfo.ts
|
model/advancedScheduleInfo.ts
|
||||||
model/advancedScheduleInfoAllOf.ts
|
model/advancedScheduleInfoAllOf.ts
|
||||||
|
@ -202,86 +202,29 @@ export class HistoryService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param startingDate starting date
|
|
||||||
* @param endingDate starting date
|
|
||||||
* @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 statisticsStartingDateEndingDateGet(startingDate: string, endingDate: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<Array<TaskgroupActivityInfo>>;
|
|
||||||
public statisticsStartingDateEndingDateGet(startingDate: string, endingDate: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<Array<TaskgroupActivityInfo>>>;
|
|
||||||
public statisticsStartingDateEndingDateGet(startingDate: string, endingDate: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<Array<TaskgroupActivityInfo>>>;
|
|
||||||
public statisticsStartingDateEndingDateGet(startingDate: string, endingDate: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
|
||||||
if (startingDate === null || startingDate === undefined) {
|
|
||||||
throw new Error('Required parameter startingDate was null or undefined when calling statisticsStartingDateEndingDateGet.');
|
|
||||||
}
|
|
||||||
if (endingDate === null || endingDate === undefined) {
|
|
||||||
throw new Error('Required parameter endingDate was null or undefined when calling statisticsStartingDateEndingDateGet.');
|
|
||||||
}
|
|
||||||
|
|
||||||
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<TaskgroupActivityInfo>>(`${this.configuration.basePath}/statistics/${encodeURIComponent(String(startingDate))}/${encodeURIComponent(String(endingDate))}`,
|
|
||||||
{
|
|
||||||
context: localVarHttpContext,
|
|
||||||
responseType: <any>responseType_,
|
|
||||||
withCredentials: this.configuration.withCredentials,
|
|
||||||
headers: localVarHeaders,
|
|
||||||
observe: observe,
|
|
||||||
reportProgress: reportProgress
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param taskgroupID internal id of taskgroup
|
* @param taskgroupID internal id of taskgroup
|
||||||
* @param startingDate starting date
|
* @param startingDate starting date
|
||||||
* @param endingDate starting date
|
* @param endingDate starting date
|
||||||
|
* @param includeSubTaskgroups determines whether to include subtaskgroups or not
|
||||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
* @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.
|
* @param reportProgress flag to report request and response progress.
|
||||||
*/
|
*/
|
||||||
public statisticsTaskgroupIDStartingDateEndingDateGet(taskgroupID: number, startingDate: string, endingDate: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<Array<TaskgroupActivityInfo>>;
|
public statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(taskgroupID: number, startingDate: string, endingDate: string, includeSubTaskgroups: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<Array<TaskgroupActivityInfo>>;
|
||||||
public statisticsTaskgroupIDStartingDateEndingDateGet(taskgroupID: number, startingDate: string, endingDate: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<Array<TaskgroupActivityInfo>>>;
|
public statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(taskgroupID: number, startingDate: string, endingDate: string, includeSubTaskgroups: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<Array<TaskgroupActivityInfo>>>;
|
||||||
public statisticsTaskgroupIDStartingDateEndingDateGet(taskgroupID: number, startingDate: string, endingDate: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<Array<TaskgroupActivityInfo>>>;
|
public statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(taskgroupID: number, startingDate: string, endingDate: string, includeSubTaskgroups: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<Array<TaskgroupActivityInfo>>>;
|
||||||
public statisticsTaskgroupIDStartingDateEndingDateGet(taskgroupID: number, startingDate: string, endingDate: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
public statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(taskgroupID: number, startingDate: string, endingDate: string, includeSubTaskgroups: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||||
if (taskgroupID === null || taskgroupID === undefined) {
|
if (taskgroupID === null || taskgroupID === undefined) {
|
||||||
throw new Error('Required parameter taskgroupID was null or undefined when calling statisticsTaskgroupIDStartingDateEndingDateGet.');
|
throw new Error('Required parameter taskgroupID was null or undefined when calling statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet.');
|
||||||
}
|
}
|
||||||
if (startingDate === null || startingDate === undefined) {
|
if (startingDate === null || startingDate === undefined) {
|
||||||
throw new Error('Required parameter startingDate was null or undefined when calling statisticsTaskgroupIDStartingDateEndingDateGet.');
|
throw new Error('Required parameter startingDate was null or undefined when calling statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet.');
|
||||||
}
|
}
|
||||||
if (endingDate === null || endingDate === undefined) {
|
if (endingDate === null || endingDate === undefined) {
|
||||||
throw new Error('Required parameter endingDate was null or undefined when calling statisticsTaskgroupIDStartingDateEndingDateGet.');
|
throw new Error('Required parameter endingDate was null or undefined when calling statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet.');
|
||||||
|
}
|
||||||
|
if (includeSubTaskgroups === null || includeSubTaskgroups === undefined) {
|
||||||
|
throw new Error('Required parameter includeSubTaskgroups was null or undefined when calling statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet.');
|
||||||
}
|
}
|
||||||
|
|
||||||
let localVarHeaders = this.defaultHeaders;
|
let localVarHeaders = this.defaultHeaders;
|
||||||
@ -316,7 +259,7 @@ export class HistoryService {
|
|||||||
responseType_ = 'text';
|
responseType_ = 'text';
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.httpClient.get<Array<TaskgroupActivityInfo>>(`${this.configuration.basePath}/statistics/${encodeURIComponent(String(taskgroupID))}/${encodeURIComponent(String(startingDate))}/${encodeURIComponent(String(endingDate))}`,
|
return this.httpClient.get<Array<TaskgroupActivityInfo>>(`${this.configuration.basePath}/statistics/taskgroup-activity/${encodeURIComponent(String(taskgroupID))}/${encodeURIComponent(String(startingDate))}/${encodeURIComponent(String(endingDate))}/${encodeURIComponent(String(includeSubTaskgroups))}`,
|
||||||
{
|
{
|
||||||
context: localVarHttpContext,
|
context: localVarHttpContext,
|
||||||
responseType: <any>responseType_,
|
responseType: <any>responseType_,
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 ActivityInfo {
|
|
||||||
date: string;
|
|
||||||
/**
|
|
||||||
* Number of minutes the task was active
|
|
||||||
*/
|
|
||||||
activeMinutes: number;
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
|||||||
export * from './accountDeleteRequest';
|
export * from './accountDeleteRequest';
|
||||||
export * from './activityInfo';
|
|
||||||
export * from './advancedScheduleFieldInfo';
|
export * from './advancedScheduleFieldInfo';
|
||||||
export * from './advancedScheduleInfo';
|
export * from './advancedScheduleInfo';
|
||||||
export * from './advancedScheduleInfoAllOf';
|
export * from './advancedScheduleInfoAllOf';
|
||||||
|
@ -9,12 +9,13 @@
|
|||||||
* https://openapi-generator.tech
|
* https://openapi-generator.tech
|
||||||
* Do not edit the class manually.
|
* Do not edit the class manually.
|
||||||
*/
|
*/
|
||||||
import { ActivityInfo } from './activityInfo';
|
|
||||||
import { TaskgroupEntityInfo } from './taskgroupEntityInfo';
|
|
||||||
|
|
||||||
|
|
||||||
export interface TaskgroupActivityInfo {
|
export interface TaskgroupActivityInfo {
|
||||||
taskgroup: TaskgroupEntityInfo;
|
date: string;
|
||||||
activityInfos: Array<ActivityInfo>;
|
/**
|
||||||
|
* Number of minutes the task was active
|
||||||
|
*/
|
||||||
|
activeMinutes: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,18 +6,16 @@
|
|||||||
</mat-card>
|
</mat-card>
|
||||||
<mat-card *ngIf="activeSchedule != undefined">
|
<mat-card *ngIf="activeSchedule != undefined">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<mat-card-title><a [routerLink]="['/taskgroups', taskgroupID, 'tasks', activeSchedule!.task.taskID]" class="link-no-deco">{{activeSchedule!.task.taskName}}</a></mat-card-title>
|
<mat-card-title><a routerLink="/" class="link-no-deco">{{activeSchedule!.task.taskName}}</a></mat-card-title>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<span *ngFor="let taskgroupPath of activeSchedule!.taskgroupPath">
|
<span *ngFor="let taskgroupPath of activeSchedule!.taskgroupPath">{{taskgroupPath.taskgroupName}} /</span>
|
||||||
<a class="link-no-deco" [routerLink]="['/taskgroups', taskgroupPath.taskgroupID]"> {{taskgroupPath.taskgroupName}} </a>/
|
|
||||||
</span>
|
|
||||||
<p class="gray-text">Running for {{displayTime}}</p>
|
<p class="gray-text">Running for {{displayTime}}</p>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
<mat-card-actions>
|
<mat-card-actions>
|
||||||
<button class="btn btn-secondary" (click)="stopTask(false)">Stop</button>
|
<button class="btn btn-secondary" (click)="stopTask(false)">Stop</button>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-success" (click)="finishSchedule()">Finish</button>
|
<button type="button" class="btn btn-success">Finish</button>
|
||||||
<button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
|
<button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<span class="visually-hidden">Toggle Dropdown</span>
|
<span class="visually-hidden">Toggle Dropdown</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
||||||
import {
|
import {ScheduleInfo, ScheduleService, TaskOverviewInfo, TaskScheduleStopResponse} from "../../../api";
|
||||||
ScheduleInfo,
|
|
||||||
ScheduleService,
|
|
||||||
TaskgroupEntityInfo,
|
|
||||||
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 {MatDialog} from "@angular/material/dialog";
|
||||||
@ -25,7 +19,6 @@ export interface StopActiveScheduleEmitterInfo {
|
|||||||
})
|
})
|
||||||
export class ActiveScheduleComponent implements OnInit{
|
export class ActiveScheduleComponent implements OnInit{
|
||||||
activeSchedule: ScheduleInfo | undefined
|
activeSchedule: ScheduleInfo | undefined
|
||||||
taskgroupID: number | undefined
|
|
||||||
|
|
||||||
startTime: number = 0;
|
startTime: number = 0;
|
||||||
currentTime: number = 0;
|
currentTime: number = 0;
|
||||||
@ -63,15 +56,11 @@ export class ActiveScheduleComponent implements OnInit{
|
|||||||
next: resp => {
|
next: resp => {
|
||||||
if(resp.scheduleID >= 0) {
|
if(resp.scheduleID >= 0) {
|
||||||
this.activateSchedule(resp);
|
this.activateSchedule(resp);
|
||||||
this.taskgroupID = resp.taskgroupPath[resp.taskgroupPath.length-1].taskgroupID
|
|
||||||
console.log(this.taskgroupID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stopTask(finish: boolean) {
|
stopTask(finish: boolean) {
|
||||||
@ -110,14 +99,6 @@ export class ActiveScheduleComponent implements OnInit{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finishSchedule() {
|
|
||||||
this.scheduleService.schedulesScheduleIDStopFinishPost(this.activeSchedule!.scheduleID, true).subscribe({
|
|
||||||
next: resp => {
|
|
||||||
this.activeSchedule = undefined;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
finishManual() {
|
finishManual() {
|
||||||
const dialogRef = this.dialog.open(StopScheduleManuallyComponent, {
|
const dialogRef = this.dialog.open(StopScheduleManuallyComponent, {
|
||||||
data: this.activeSchedule,
|
data: this.activeSchedule,
|
||||||
|
@ -23,18 +23,16 @@
|
|||||||
<mat-card *ngFor="let schedule of schedules">
|
<mat-card *ngFor="let schedule of schedules">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<mat-card-title>
|
<mat-card-title>
|
||||||
<a [routerLink]="['/taskgroups', schedule.taskgroupPath[schedule.taskgroupPath.length-1].taskgroupID, 'tasks', schedule.task.taskID]" class="link-no-deco">{{schedule.task.taskName}}</a>
|
<a routerLink="/" class="link-no-deco">{{schedule.task.taskName}}</a>
|
||||||
</mat-card-title>
|
</mat-card-title>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<span *ngFor="let taskgroupPath of schedule.taskgroupPath">
|
<span *ngFor="let taskgroupPath of schedule.taskgroupPath">{{taskgroupPath.taskgroupName}} /</span>
|
||||||
<a class="link-no-deco" [routerLink]="['/taskgroups', taskgroupPath.taskgroupID]"> {{taskgroupPath.taskgroupName}} /</a>
|
|
||||||
</span>
|
|
||||||
<p class="gray-text" *ngIf="schedule.scheduleType==='BASIC'">To be done sometime today</p>
|
<p class="gray-text" *ngIf="schedule.scheduleType==='BASIC'">To be done sometime today</p>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
<mat-card-actions>
|
<mat-card-actions>
|
||||||
<button mat-raised-button color="primary" class="primaryBtn" (click)="startSchedule(schedule)" [disabled]="activeScheduleComponent!.activeSchedule != undefined">Start now</button>
|
<button mat-raised-button color="primary" class="primaryBtn" (click)="startSchedule(schedule)" [disabled]="activeScheduleComponent!.activeSchedule != undefined">Start now</button>
|
||||||
<button mat-raised-button class="yellowBtn" [routerLink]="['/taskgroups', schedule.taskgroupPath[schedule.taskgroupPath.length-1].taskgroupID, 'tasks', schedule.task.taskID, 'schedule', schedule.scheduleID]">Reschedule</button>
|
<button mat-raised-button class="yellowBtn">Reschedule</button>
|
||||||
</mat-card-actions>
|
</mat-card-actions>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,11 +5,6 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navi-link-container {
|
|
||||||
margin: 20px auto;
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spacer {
|
.spacer {
|
||||||
margin-bottom: 2.5%;
|
margin-bottom: 2.5%;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
<div class="navi-link-container">
|
|
||||||
<app-navigation-link-list [navigationLinks]="defaultNavigationLinks"></app-navigation-link-list>
|
|
||||||
</div>
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<div class="calendar-container">
|
<div class="calendar-container">
|
||||||
<h1 mat-dialog-title>Register forgotten activity</h1>
|
<h1 mat-dialog-title>Register forgotten activity</h1>
|
||||||
<mwl-calendar-day-view
|
<mwl-calendar-day-view
|
||||||
|
@ -17,7 +17,6 @@ import * as moment from "moment/moment";
|
|||||||
import {EventColor} from "calendar-utils";
|
import {EventColor} from "calendar-utils";
|
||||||
import {TaskOverviewData} from "../taskgroup-overview/taskgroup-overview.component";
|
import {TaskOverviewData} from "../taskgroup-overview/taskgroup-overview.component";
|
||||||
import {Router} from "@angular/router";
|
import {Router} from "@angular/router";
|
||||||
import {NavigationLink} from "../../navigation-link-list/navigation-link-list.component";
|
|
||||||
|
|
||||||
|
|
||||||
const colors: Record<string, EventColor> = {
|
const colors: Record<string, EventColor> = {
|
||||||
@ -66,16 +65,6 @@ export class ForgottenTaskStartDialogComponent implements OnInit{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
defaultNavigationLinks: NavigationLink[] = [
|
|
||||||
{
|
|
||||||
linkText: "Dashboard",
|
|
||||||
routerLink: ['/']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
linkText: "Register Forgotten Activity",
|
|
||||||
routerLink: ["/forgotten"]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
constructor(private router: Router,
|
constructor(private router: Router,
|
||||||
@ -135,8 +124,6 @@ export class ForgottenTaskStartDialogComponent implements OnInit{
|
|||||||
event.start = newStart;
|
event.start = newStart;
|
||||||
if (newEnd) {
|
if (newEnd) {
|
||||||
event.end = newEnd;
|
event.end = newEnd;
|
||||||
} else {
|
|
||||||
event.end = moment(event.start).add( 30, "minutes").toDate()
|
|
||||||
}
|
}
|
||||||
this.events = [...this.events];
|
this.events = [...this.events];
|
||||||
}
|
}
|
||||||
@ -182,8 +169,6 @@ export class ForgottenTaskStartDialogComponent implements OnInit{
|
|||||||
}
|
}
|
||||||
|
|
||||||
register() {
|
register() {
|
||||||
console.log(this.events[this.events.length-1].start)
|
|
||||||
console.log(this.events[this.events.length-1].end)
|
|
||||||
this.scheduleService.schedulesTaskIDForgottenPost(this.events[this.events.length-1].meta.taskID, {
|
this.scheduleService.schedulesTaskIDForgottenPost(this.events[this.events.length-1].meta.taskID, {
|
||||||
startTime: moment(this.events[this.events.length-1].start).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),
|
startTime: moment(this.events[this.events.length-1].start).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),
|
||||||
endTime: moment(this.events[this.events.length-1].end).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),
|
endTime: moment(this.events[this.events.length-1].end).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
<div style="text-align:center" *ngIf="selectedTaskgroupPath != undefined">
|
<div style="text-align:center">
|
||||||
<apx-chart
|
<apx-chart
|
||||||
[series]="chartOptions!.series!"
|
[series]="chartOptions.series!"
|
||||||
[chart]="chartOptions!.chart!"
|
[chart]="chartOptions.chart!"
|
||||||
[title]="chartOptions!.title!"
|
[xaxis]="chartOptions.xaxis!"
|
||||||
[plotOptions]="chartOptions!.plotOptions!"
|
[title]="chartOptions.title!"
|
||||||
[xaxis]="chartOptions!.xAxis!"
|
|
||||||
[yaxis]="chartOptions!.yAxis!"
|
|
||||||
[tooltip]="chartOptions!.tooltip!"
|
|
||||||
></apx-chart>
|
></apx-chart>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,180 +1,168 @@
|
|||||||
import {Component, Input, OnChanges, ViewChild} from '@angular/core';
|
import {Component, Input, OnInit, ViewChild} from '@angular/core';
|
||||||
|
import {ApexAxisChartSeries, ChartComponent, ChartType} from "ng-apexcharts";
|
||||||
import {
|
import {ChartOptions} from "../taskgroup-activity.component";
|
||||||
ApexAxisChartSeries,
|
|
||||||
ApexTitleSubtitle,
|
|
||||||
ApexDataLabels,
|
|
||||||
ApexChart,
|
|
||||||
ApexPlotOptions, ChartComponent, ApexXAxis, ApexYAxis, ApexTooltip
|
|
||||||
} from "ng-apexcharts";
|
|
||||||
import {generate} from "rxjs";
|
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
import {HistoryService, TaskgroupActivityInfo, TaskgroupPathInfo} from "../../../../api";
|
import {HistoryService, TaskgroupActivityInfo, TaskgroupPathInfo} from "../../../../api";
|
||||||
|
|
||||||
export type ChartOptions = {
|
|
||||||
series: ApexAxisChartSeries;
|
interface XYData {
|
||||||
chart: ApexChart;
|
x: any,
|
||||||
dataLabels: ApexDataLabels;
|
y: any
|
||||||
title: ApexTitleSubtitle;
|
}
|
||||||
plotOptions: ApexPlotOptions;
|
|
||||||
xAxis: ApexXAxis,
|
|
||||||
yAxis: ApexYAxis,
|
|
||||||
tooltip: ApexTooltip
|
|
||||||
};
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-heatmap-activity',
|
selector: 'app-heatmap-activity',
|
||||||
templateUrl: './heatmap-activity.component.html',
|
templateUrl: './heatmap-activity.component.html',
|
||||||
styleUrls: ['./heatmap-activity.component.css']
|
styleUrls: ['./heatmap-activity.component.css']
|
||||||
})
|
})
|
||||||
export class HeatmapActivityComponent implements OnChanges{
|
export class HeatmapActivityComponent implements OnInit{
|
||||||
|
|
||||||
@ViewChild("chart") chart: ChartComponent | undefined;
|
@ViewChild("chart") chart?: ChartComponent;
|
||||||
@Input() selectedTaskgroupPath: TaskgroupPathInfo | undefined
|
public chartOptions: Partial<ChartOptions> = this.generateChartOptions()
|
||||||
public chartOptions: Partial<ChartOptions> | undefined;
|
|
||||||
|
|
||||||
maxValue = 120
|
@Input() selectedTaskgroupPath?: TaskgroupPathInfo
|
||||||
|
|
||||||
constructor(private historyService: HistoryService) {
|
constructor(private historyService: HistoryService) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnInit() {
|
||||||
|
this.chartOptions = this.generateChartOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
generateChartOptions(): Partial<ChartOptions> {
|
||||||
|
return {
|
||||||
|
series: this.generateSeries(),
|
||||||
|
chart: {
|
||||||
|
height: 350,
|
||||||
|
type: 'heatmap',
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: ""
|
||||||
|
},
|
||||||
|
dataLabels: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
colors: ["#008FFB"],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
generateSeries() : ApexAxisChartSeries {
|
||||||
|
const series: ApexAxisChartSeries = []
|
||||||
|
|
||||||
if(this.selectedTaskgroupPath != undefined) {
|
if(this.selectedTaskgroupPath != undefined) {
|
||||||
/*this.historyService.statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(
|
const startingDate = new Date(2023, 4, 9);
|
||||||
this.selectedTaskgroupPath!.rootTasktroup.taskgroupID,
|
const endDate = new Date(2023, 11, 20);
|
||||||
moment().startOf('year').format("YYYY-MM-DD"),
|
let activityInfos: TaskgroupActivityInfo[];
|
||||||
moment().endOf("year").format("YYYY-MM-DD"),
|
this.historyService.statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(
|
||||||
false
|
this.selectedTaskgroupPath.rootTasktroup.taskgroupID,
|
||||||
|
moment().subtract(6, "months").format("YYYY-MM-DD"),
|
||||||
|
moment().add(2, 'days').format("YYYY-MM-DD"),
|
||||||
|
true
|
||||||
).subscribe({
|
).subscribe({
|
||||||
next: resp => {
|
next: resp => {
|
||||||
const taskgroupActivityInfo = resp;
|
activityInfos = resp;
|
||||||
console.log("Chat Options")
|
const data: XYData[][] = [];
|
||||||
this.chartOptions = {
|
let currentDate: moment.Moment = moment(activityInfos[0].date).subtract(moment(activityInfos[0].date).day(), 'days');
|
||||||
series: [
|
|
||||||
{
|
//Offset until data starts
|
||||||
name: "Monday",
|
let index = currentDate.day();
|
||||||
data: this.generateData(moment().startOf('year'),taskgroupActivityInfo)
|
while(currentDate < moment(activityInfos[0].date)) {
|
||||||
},
|
if(data[currentDate.day()] == undefined) {
|
||||||
{
|
data[currentDate.day()] = [];
|
||||||
name: "Tuesday",
|
|
||||||
data: this.generateData(moment().startOf('year').add(1, "days"),taskgroupActivityInfo)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Wednesday",
|
|
||||||
data: this.generateData(moment().startOf('year').add(2, "days"), taskgroupActivityInfo)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Thursday",
|
|
||||||
data: this.generateData(moment().startOf('year').add(3, "days"), taskgroupActivityInfo)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Friday",
|
|
||||||
data: this.generateData(moment().startOf('year').add(4, "days"), taskgroupActivityInfo)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Saturday",
|
|
||||||
data: this.generateData(moment().startOf('year').add(5, "days"), taskgroupActivityInfo)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Sunday",
|
|
||||||
data: this.generateData(moment().startOf('year').add(6, "days"), taskgroupActivityInfo)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
chart: {
|
|
||||||
height: 350,
|
|
||||||
type: "heatmap"
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
labels: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
labels: {
|
|
||||||
show: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plotOptions: {
|
|
||||||
heatmap: {
|
|
||||||
shadeIntensity: 0.5,
|
|
||||||
colorScale: {
|
|
||||||
ranges: [
|
|
||||||
{
|
|
||||||
from: 0,
|
|
||||||
to: 5,
|
|
||||||
name: "low",
|
|
||||||
color: "#00A100"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: 6,
|
|
||||||
to: 20,
|
|
||||||
name: "medium",
|
|
||||||
color: "#128FD9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: 21,
|
|
||||||
to: 45,
|
|
||||||
name: "high",
|
|
||||||
color: "#FFB200"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
from: 46,
|
|
||||||
to: this.maxValue,
|
|
||||||
name: "extreme",
|
|
||||||
color: "#FF0000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dataLabels: {
|
|
||||||
enabled: true,
|
|
||||||
style: {
|
|
||||||
fontSize: "12px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
text: "HeatMap Chart with Color Range"
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
enabled: true,
|
|
||||||
y: {
|
|
||||||
formatter: function (value, { seriesIndex, dataPointIndex, w }) {
|
|
||||||
return "<span style='font-weight: normal'>Spent </span>" + value + " <span style='font-weight: normal'>Minutes on <br>" + w.config.series[seriesIndex].data[dataPointIndex].extraInfo.format("dddd, MMMM D, YYYY") + "</span>"
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
formatter: seriesName => ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
data[currentDate.day()][index] = {
|
||||||
|
x: moment(currentDate).toDate(),
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
currentDate.add(1, 'days');
|
||||||
|
}
|
||||||
|
|
||||||
|
//inside data
|
||||||
|
activityInfos.forEach(activityInfo => {
|
||||||
|
const momentDate: moment.Moment = moment(activityInfo.date);
|
||||||
|
const seriesIndex = momentDate.day();
|
||||||
|
|
||||||
|
if(data[seriesIndex] == undefined) {
|
||||||
|
data[seriesIndex] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
data[seriesIndex][index] = {
|
||||||
|
x: activityInfo.date,
|
||||||
|
y: activityInfo.activeMinutes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(seriesIndex == 6) {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
currentDate = moment(activityInfos[activityInfos.length-1].date);
|
||||||
|
currentDate = currentDate.add(1, "days");
|
||||||
|
//offset outside data
|
||||||
|
for(let i=moment(activityInfos[activityInfos.length-1].date).day(); i<7; i++) {
|
||||||
|
data[i][index] = {
|
||||||
|
x: moment(currentDate).toDate(),
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
console.log(currentDate)
|
||||||
|
currentDate = currentDate.add(1, "days");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
series.push({
|
||||||
|
name: "Saturday",
|
||||||
|
data: data[6]
|
||||||
|
});
|
||||||
|
series.push({
|
||||||
|
name: "Friday",
|
||||||
|
data: data[5]
|
||||||
|
});
|
||||||
|
series.push({
|
||||||
|
name: "Thursday",
|
||||||
|
data: data[4]
|
||||||
|
});
|
||||||
|
series.push({
|
||||||
|
name: "Wednesday",
|
||||||
|
data: data[3]
|
||||||
|
});
|
||||||
|
series.push({
|
||||||
|
name: "Tuesday",
|
||||||
|
data: data[2]
|
||||||
|
});
|
||||||
|
series.push({
|
||||||
|
name: "Monday",
|
||||||
|
data: data[1]
|
||||||
|
});
|
||||||
|
series.push({
|
||||||
|
name: "Sunday",
|
||||||
|
data: data[0]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private generateData(startingDate: moment.Moment, data: TaskgroupActivityInfo[]) {
|
|
||||||
let currentDate = startingDate;
|
|
||||||
|
|
||||||
let series = []
|
|
||||||
let endingDate = startingDate.clone().endOf('year');
|
|
||||||
|
|
||||||
while(currentDate.isBefore(endingDate)) {
|
|
||||||
let x = "w" + currentDate.isoWeek();
|
|
||||||
let y = this.findTaskgroupActivityInfoByDate(currentDate, data)
|
|
||||||
let extraInfo = currentDate.clone()
|
|
||||||
|
|
||||||
series.push({
|
|
||||||
x: x,
|
|
||||||
y: y,
|
|
||||||
extraInfo: extraInfo
|
|
||||||
})
|
})
|
||||||
currentDate = currentDate.add(7, "days");
|
return series;
|
||||||
|
} else {
|
||||||
|
return series;
|
||||||
}
|
}
|
||||||
return series;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private findTaskgroupActivityInfoByDate(date: moment.Moment, data: TaskgroupActivityInfo[]) {
|
generateData(start: moment.Moment, end: moment.Moment) {
|
||||||
//return data.find(taskActivity => moment(taskActivity.date).isSame(date))
|
const data: TaskgroupActivityInfo[] = [];
|
||||||
|
let currentDate: moment.Moment = moment(start);
|
||||||
|
while(currentDate <= end) {
|
||||||
|
data.push({
|
||||||
|
date: currentDate.format("YYYY-MM-DD"),
|
||||||
|
activeMinutes: Math.floor(Math.random() * (100 + 1))
|
||||||
|
})
|
||||||
|
currentDate = currentDate.add(1, 'days');
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedTaskgroupPath(taskgroupPath: TaskgroupPathInfo) {
|
||||||
|
this.selectedTaskgroupPath = taskgroupPath;
|
||||||
|
this.chartOptions = this.generateChartOptions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div style="text-align:center">
|
<div style="text-align:center">
|
||||||
<apx-chart #chart *ngIf="chartOptions != undefined"
|
<apx-chart
|
||||||
[series]="chartOptions.series!"
|
[series]="chartOptions.series!"
|
||||||
[chart]="chartOptions.chart!"
|
[chart]="chartOptions.chart!"
|
||||||
[xaxis]="chartOptions.xaxis!"
|
[xaxis]="chartOptions.xaxis!"
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
|
import {Component, Input, ViewChild} from '@angular/core';
|
||||||
import {FormControl} from "@angular/forms";
|
import {FormControl} from "@angular/forms";
|
||||||
import {ChangeContext, LabelType, Options} from "ngx-slider-v2";
|
import {ChangeContext, LabelType, Options} from "ngx-slider-v2";
|
||||||
import {ApexAxisChartSeries, ChartComponent, ChartType} from "ng-apexcharts";
|
import {ApexAxisChartSeries, ChartComponent, ChartType} from "ng-apexcharts";
|
||||||
import {HistoryService, TaskgroupActivityInfo, TaskgroupPathInfo, TaskgroupService} from "../../../../api";
|
import {HistoryService, TaskgroupPathInfo, TaskgroupService} from "../../../../api";
|
||||||
import * as moment from "moment/moment";
|
import * as moment from "moment/moment";
|
||||||
import {ChartOptions} from "../taskgroup-activity.component";
|
import {ChartOptions} from "../taskgroup-activity.component";
|
||||||
|
|
||||||
@ -11,8 +11,8 @@ import {ChartOptions} from "../taskgroup-activity.component";
|
|||||||
templateUrl: './simple-activity-diagram.component.html',
|
templateUrl: './simple-activity-diagram.component.html',
|
||||||
styleUrls: ['./simple-activity-diagram.component.css']
|
styleUrls: ['./simple-activity-diagram.component.css']
|
||||||
})
|
})
|
||||||
export class SimpleActivityDiagramComponent implements OnChanges {
|
export class SimpleActivityDiagramComponent {
|
||||||
@Input('selectedChartype') selectedChartype: string | undefined
|
@Input('selectedChartype') selectedChartype: string = "bar";
|
||||||
@Input() selectedTaskgroupPath: TaskgroupPathInfo | undefined;
|
@Input() selectedTaskgroupPath: TaskgroupPathInfo | undefined;
|
||||||
|
|
||||||
sliderControl: FormControl = new FormControl()
|
sliderControl: FormControl = new FormControl()
|
||||||
@ -31,83 +31,15 @@ export class SimpleActivityDiagramComponent implements OnChanges {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@ViewChild("chart") chart?: ChartComponent;
|
@ViewChild("chart") chart?: ChartComponent;
|
||||||
|
public chartOptions: Partial<ChartOptions> = this.generateChartOptions()
|
||||||
chartOptions: Partial<ChartOptions> | undefined;
|
|
||||||
|
|
||||||
constructor(private taskgroupService: TaskgroupService,
|
constructor(private taskgroupService: TaskgroupService,
|
||||||
private historyService: HistoryService) {
|
private historyService: HistoryService) {
|
||||||
}
|
}
|
||||||
ngOnChanges() {
|
|
||||||
this.fetchData()
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchData() {
|
|
||||||
const startingDate = moment(this.dateRange[0]).format("yyyy-MM-DD");
|
|
||||||
const endingDate = moment(this.dateRange[this.dateRange.length-1]).format("yyyy-MM-DD");
|
|
||||||
|
|
||||||
if(this.selectedTaskgroupPath == undefined) {
|
|
||||||
this.historyService.statisticsStartingDateEndingDateGet(startingDate, endingDate).subscribe({
|
|
||||||
next: resp => {
|
|
||||||
const series = this.createChartSeries(resp);
|
|
||||||
this.chartOptions = this.createChartOptions(series);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.historyService.statisticsTaskgroupIDStartingDateEndingDateGet(
|
|
||||||
this.selectedTaskgroupPath.rootTasktroup.taskgroupID,
|
|
||||||
startingDate,
|
|
||||||
endingDate
|
|
||||||
).subscribe({
|
|
||||||
next: resp => {
|
|
||||||
const series = this.createChartSeries(resp);
|
|
||||||
this.chartOptions = this.createChartOptions(series)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createChartSeries(data: TaskgroupActivityInfo[]) {
|
|
||||||
const series: ApexAxisChartSeries = [];
|
|
||||||
data.forEach(taskgroupActivityInfo => {
|
|
||||||
const data: any[] = [];
|
|
||||||
this.dateRange.map(date => {
|
|
||||||
const selectedActivity = taskgroupActivityInfo.activityInfos.find(activity => moment(date).isSame(moment(activity.date), "day"))
|
|
||||||
if(selectedActivity != undefined) {
|
|
||||||
data.push(selectedActivity.activeMinutes)
|
|
||||||
} else {
|
|
||||||
data.push(0)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
series.push({
|
|
||||||
name: taskgroupActivityInfo.taskgroup.taskgroupName,
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return series;
|
|
||||||
}
|
|
||||||
|
|
||||||
createChartOptions(series: any[] = []) {
|
|
||||||
return {
|
|
||||||
series: series,
|
|
||||||
chart: {
|
|
||||||
height: 350,
|
|
||||||
type: this.selectedChartype as ChartType,
|
|
||||||
stacked: true
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
text: ""
|
|
||||||
},
|
|
||||||
xaxis: {
|
|
||||||
categories: this.selectedDateRange.map(date => date.toDateString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createDateRange(): Date[] {
|
createDateRange(): Date[] {
|
||||||
const dates: Date[] = [];
|
const dates: Date[] = [];
|
||||||
for (let i: number = 1; i <= 30; i++) {
|
for (let i: number = 1; i <= 31; i++) {
|
||||||
|
|
||||||
dates.push(moment().subtract(30-i, 'd').toDate());
|
dates.push(moment().subtract(30-i, 'd').toDate());
|
||||||
}
|
}
|
||||||
@ -131,10 +63,84 @@ export class SimpleActivityDiagramComponent implements OnChanges {
|
|||||||
console.log("min " + moment(changeContext.value).format("YYYY-MM-DD"));
|
console.log("min " + moment(changeContext.value).format("YYYY-MM-DD"));
|
||||||
console.log("max " + moment(changeContext.highValue!).format("YYYY-MM-DD"))
|
console.log("max " + moment(changeContext.highValue!).format("YYYY-MM-DD"))
|
||||||
this.selectedDateRange = this.createDateRangeBetween(moment(changeContext.value), moment(changeContext.highValue!))
|
this.selectedDateRange = this.createDateRangeBetween(moment(changeContext.value), moment(changeContext.highValue!))
|
||||||
|
this.chartOptions = this.generateChartOptions()
|
||||||
|
}
|
||||||
|
|
||||||
|
generateChartOptions(): Partial<ChartOptions> {
|
||||||
|
return {
|
||||||
|
series: this.generateSeries(),
|
||||||
|
chart: {
|
||||||
|
height: 350,
|
||||||
|
type: this.selectedChartype as ChartType,
|
||||||
|
stacked: true
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: ""
|
||||||
|
},
|
||||||
|
xaxis: {
|
||||||
|
categories: this.selectedDateRange.map(date => date.toDateString())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
generateSeries() : ApexAxisChartSeries {
|
||||||
|
const series: ApexAxisChartSeries = []
|
||||||
|
|
||||||
|
if(this.selectedTaskgroupPath != undefined) {
|
||||||
|
this.historyService.statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(
|
||||||
|
this.selectedTaskgroupPath!.rootTasktroup.taskgroupID,
|
||||||
|
moment(this.selectedDateRange[0]).format("YYYY-MM-DD"),
|
||||||
|
moment(this.selectedDateRange[this.selectedDateRange.length-1]).format("YYYY-MM-DD"),
|
||||||
|
false
|
||||||
|
).subscribe({
|
||||||
|
next: resp => {
|
||||||
|
series.push(
|
||||||
|
{
|
||||||
|
name: this.selectedTaskgroupPath!.rootTasktroup.taskgroupName,
|
||||||
|
data: resp.map(dailyActivityInfo => dailyActivityInfo.activeMinutes)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.selectedTaskgroupPath?.directChildren.forEach(taskgroup => {
|
||||||
|
|
||||||
|
this.historyService.statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(
|
||||||
|
taskgroup.taskgroupID,
|
||||||
|
moment(this.selectedDateRange[0]).format("YYYY-MM-DD"),
|
||||||
|
moment(this.selectedDateRange[this.selectedDateRange.length-1]).format("YYYY-MM-DD"), true
|
||||||
|
).subscribe({
|
||||||
|
next: resp => {
|
||||||
|
series.push(
|
||||||
|
{
|
||||||
|
name: taskgroup.taskgroupName,
|
||||||
|
data: resp.map(dailyActivityInfo => dailyActivityInfo.activeMinutes)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
console.log(series);
|
||||||
|
return series;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSerieSelection() {
|
||||||
|
this.chartOptions = this.generateChartOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectedChartType(selectedChartype: string) {
|
setSelectedChartType(selectedChartype: string) {
|
||||||
//this.selectedChartype = selectedChartype;
|
this.selectedChartype = selectedChartype;
|
||||||
|
this.updateSerieSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedTaskgroupPath(selectedTaskgroupPath: TaskgroupPathInfo) {
|
||||||
|
this.selectedTaskgroupPath = selectedTaskgroupPath;
|
||||||
|
this.updateSerieSelection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<app-navigation-link-list #navLinkList [navigationLinks]="defaultNavigationLinkPath"></app-navigation-link-list>
|
<app-navigation-link-list #navLinkList [navigationLinks]="defaultNavigationLinkPath"></app-navigation-link-list>
|
||||||
<mat-form-field style="width: 90%">
|
<mat-form-field style="width: 90%">
|
||||||
<mat-label>Taskgroup</mat-label>
|
<mat-label>Taskgroup</mat-label>
|
||||||
<mat-select [(ngModel)]="selectedTaskgroupPath">
|
<mat-select [(ngModel)]="selectedTaskgroupPath" (ngModelChange)="onSelectTaskgroupPath()">
|
||||||
<mat-option *ngFor="let topping of taskgroupPaths" [value]="topping">{{topping.taskgroupPath}}</mat-option>
|
<mat-option *ngFor="let topping of taskgroupPaths" [value]="topping">{{topping.taskgroupPath}}</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@ -14,5 +14,5 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<app-simple-activity-diagram *ngIf="selectedChartype !== 'heatmap'" #simpleActivityDiagram [selectedChartype]="selectedChartype" [selectedTaskgroupPath]="selectedTaskgroupPath"></app-simple-activity-diagram>
|
<app-simple-activity-diagram *ngIf="selectedChartype !== 'heatmap'" #simpleActivityDiagram [selectedChartype]="selectedChartype" [selectedTaskgroupPath]="selectedTaskgroupPath"></app-simple-activity-diagram>
|
||||||
<app-heatmap-activity *ngIf="selectedChartype === 'heatmap'" #heatMap [selectedTaskgroupPath]="selectedTaskgroupPath!"></app-heatmap-activity>
|
<app-heatmap-activity *ngIf="selectedChartype === 'heatmap'" #heatMap></app-heatmap-activity>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,6 +65,14 @@ export class TaskgroupActivityComponent implements OnInit{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSelectTaskgroupPath() {
|
||||||
|
if(this.simpleActivityDiagram != undefined) {
|
||||||
|
this.simpleActivityDiagram.setSelectedTaskgroupPath(this.selectedTaskgroupPath!);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.heatMap?.setSelectedTaskgroupPath(this.selectedTaskgroupPath!);
|
||||||
|
}
|
||||||
|
|
||||||
onSelectChartType() {
|
onSelectChartType() {
|
||||||
if(this.simpleActivityDiagram != undefined) {
|
if(this.simpleActivityDiagram != undefined) {
|
||||||
this.simpleActivityDiagram.setSelectedChartType(this.selectedChartype);
|
this.simpleActivityDiagram.setSelectedChartType(this.selectedChartype);
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="float:right;">
|
<div style="float:right;">
|
||||||
<button mat-raised-button color="warn" (click)="deleteTask()">Delete</button>
|
<button mat-raised-button color="warn">Delete</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -187,12 +187,4 @@ export class TaskDetailOverviewComponent implements OnInit {
|
|||||||
minWidth: "400px"
|
minWidth: "400px"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteTask() {
|
|
||||||
this.taskService.tasksTaskIDDelete(this.task!.taskID).subscribe({
|
|
||||||
next: resp => {
|
|
||||||
this.router.navigateByUrl("/")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
66
openapi.yaml
66
openapi.yaml
@ -2060,49 +2060,7 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
$ref: "#/components/schemas/SimpleStatusResponse"
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
/statistics/{startingDate}/{endingDate}:
|
/statistics/taskgroup-activity/{taskgroupID}/{startingDate}/{endingDate}/{includeSubTaskgroups}:
|
||||||
get:
|
|
||||||
security:
|
|
||||||
- API_TOKEN: []
|
|
||||||
tags:
|
|
||||||
- history
|
|
||||||
parameters:
|
|
||||||
- name: startingDate
|
|
||||||
in: path
|
|
||||||
description: starting date
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: date
|
|
||||||
- name: endingDate
|
|
||||||
in: path
|
|
||||||
description: starting date
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: date
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: Operation successfull
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/TaskgroupActivityInfo'
|
|
||||||
403:
|
|
||||||
description: No permission
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/SimpleStatusResponse'
|
|
||||||
404:
|
|
||||||
description: Schedule not found
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/SimpleStatusResponse'
|
|
||||||
/statistics/{taskgroupID}/{startingDate}/{endingDate}:
|
|
||||||
get:
|
get:
|
||||||
security:
|
security:
|
||||||
- API_TOKEN: []
|
- API_TOKEN: []
|
||||||
@ -2130,6 +2088,13 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: date
|
format: date
|
||||||
|
- name: includeSubTaskgroups
|
||||||
|
in: path
|
||||||
|
description: determines whether to include subtaskgroups or not
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
example: false
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Operation successfull
|
description: Operation successfull
|
||||||
@ -2983,7 +2948,7 @@ components:
|
|||||||
rootTasktroup:
|
rootTasktroup:
|
||||||
type: object
|
type: object
|
||||||
$ref: '#/components/schemas/TaskgroupEntityInfo'
|
$ref: '#/components/schemas/TaskgroupEntityInfo'
|
||||||
ActivityInfo:
|
TaskgroupActivityInfo:
|
||||||
required:
|
required:
|
||||||
- date
|
- date
|
||||||
- activeMinutes
|
- activeMinutes
|
||||||
@ -2996,19 +2961,6 @@ components:
|
|||||||
type: number
|
type: number
|
||||||
description: Number of minutes the task was active
|
description: Number of minutes the task was active
|
||||||
example: 122
|
example: 122
|
||||||
TaskgroupActivityInfo:
|
|
||||||
required:
|
|
||||||
- taskgroup
|
|
||||||
- activityInfos
|
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
|
||||||
taskgroup:
|
|
||||||
type: object
|
|
||||||
$ref: '#/components/schemas/TaskgroupEntityInfo'
|
|
||||||
activityInfos:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/ActivityInfo'
|
|
||||||
ManualScheduleStopInfo:
|
ManualScheduleStopInfo:
|
||||||
required:
|
required:
|
||||||
- duration
|
- duration
|
||||||
|
Loading…
Reference in New Issue
Block a user