Select top taskgroups by default in Activity Statistic
All checks were successful
Java CI with Maven / build-and-push-frontend (push) Successful in 13s
Java CI with Maven / build-and-push-backend (push) Successful in 13s

This commit is contained in:
Sebastian Böckelmann 2024-03-18 14:45:25 +01:00
parent e1f69b340d
commit 183030611b
12 changed files with 93 additions and 119 deletions

View File

@ -39,7 +39,7 @@ public class StatisticController {
return ResponseEntity.ok(new WorkingStatus(missedSchedules, activeTime));
}
@GetMapping("/statistics/{startingDate}/{endingDate}/{includeSubTaskgroups}")
@GetMapping("/statistics/{startingDate}/{endingDate}")
public ResponseEntity<?> getTaskgroupActivity(@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"));

View File

@ -5,11 +5,11 @@ import java.time.LocalDate;
public class ActivityInfo {
private LocalDate scheduleDate;
private int workedMinutes;
private int activeMinutes;
public ActivityInfo(LocalDate scheduleDate, int workedMinutes) {
this.scheduleDate = scheduleDate;
this.workedMinutes = workedMinutes;
this.activeMinutes = workedMinutes;
}
public LocalDate getScheduleDate() {
@ -20,11 +20,11 @@ public class ActivityInfo {
this.scheduleDate = scheduleDate;
}
public int getWorkedMinutes() {
return workedMinutes;
public int getActiveMinutes() {
return activeMinutes;
}
public void setWorkedMinutes(int workedMinutes) {
this.workedMinutes = workedMinutes;
public void setActiveMinutes(int activeMinutes) {
this.activeMinutes = activeMinutes;
}
}

View File

@ -17,6 +17,7 @@ encoder.ts
git_push.sh
index.ts
model/accountDeleteRequest.ts
model/activityInfo.ts
model/advancedScheduleFieldInfo.ts
model/advancedScheduleInfo.ts
model/advancedScheduleInfoAllOf.ts

View File

@ -203,28 +203,20 @@ export class HistoryService {
}
/**
* @param taskgroupID internal id of taskgroup
* @param startingDate 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 reportProgress flag to report request and response progress.
*/
public statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(taskgroupID: number, startingDate: string, endingDate: string, includeSubTaskgroups: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<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 statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(taskgroupID: number, startingDate: string, endingDate: string, includeSubTaskgroups: boolean, 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: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
if (taskgroupID === null || taskgroupID === undefined) {
throw new Error('Required parameter taskgroupID was null or undefined when calling statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet.');
}
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 statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet.');
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 statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet.');
}
if (includeSubTaskgroups === null || includeSubTaskgroups === undefined) {
throw new Error('Required parameter includeSubTaskgroups was null or undefined when calling statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet.');
throw new Error('Required parameter endingDate was null or undefined when calling statisticsStartingDateEndingDateGet.');
}
let localVarHeaders = this.defaultHeaders;
@ -259,7 +251,7 @@ export class HistoryService {
responseType_ = 'text';
}
return this.httpClient.get<Array<TaskgroupActivityInfo>>(`${this.configuration.basePath}/statistics/taskgroup-activity/${encodeURIComponent(String(taskgroupID))}/${encodeURIComponent(String(startingDate))}/${encodeURIComponent(String(endingDate))}/${encodeURIComponent(String(includeSubTaskgroups))}`,
return this.httpClient.get<Array<TaskgroupActivityInfo>>(`${this.configuration.basePath}/statistics/${encodeURIComponent(String(startingDate))}/${encodeURIComponent(String(endingDate))}`,
{
context: localVarHttpContext,
responseType: <any>responseType_,

View File

@ -0,0 +1,21 @@
/**
* 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;
}

View File

@ -1,4 +1,5 @@
export * from './accountDeleteRequest';
export * from './activityInfo';
export * from './advancedScheduleFieldInfo';
export * from './advancedScheduleInfo';
export * from './advancedScheduleInfoAllOf';

View File

@ -9,13 +9,12 @@
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { ActivityInfo } from './activityInfo';
import { TaskgroupEntityInfo } from './taskgroupEntityInfo';
export interface TaskgroupActivityInfo {
date: string;
/**
* Number of minutes the task was active
*/
activeMinutes: number;
taskgroup: TaskgroupEntityInfo;
activityInfos: Array<ActivityInfo>;
}

View File

@ -40,7 +40,7 @@ export class HeatmapActivityComponent implements OnChanges{
ngOnChanges() {
if(this.selectedTaskgroupPath != undefined) {
this.historyService.statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(
/*this.historyService.statisticsTaskgroupActivityTaskgroupIDStartingDateEndingDateIncludeSubTaskgroupsGet(
this.selectedTaskgroupPath!.rootTasktroup.taskgroupID,
moment().startOf('year').format("YYYY-MM-DD"),
moment().endOf("year").format("YYYY-MM-DD"),
@ -149,7 +149,7 @@ export class HeatmapActivityComponent implements OnChanges{
}
};
}
})
})*/
}
}
@ -175,6 +175,6 @@ export class HeatmapActivityComponent implements OnChanges{
}
private findTaskgroupActivityInfoByDate(date: moment.Moment, data: TaskgroupActivityInfo[]) {
return data.find(taskActivity => moment(taskActivity.date).isSame(date))
//return data.find(taskActivity => moment(taskActivity.date).isSame(date))
}
}

View File

@ -1,5 +1,5 @@
<div style="text-align:center">
<apx-chart
<apx-chart #chart *ngIf="chartOptions != undefined"
[series]="chartOptions.series!"
[chart]="chartOptions.chart!"
[xaxis]="chartOptions.xaxis!"

View File

@ -1,4 +1,4 @@
import {Component, Input, ViewChild} from '@angular/core';
import {Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
import {FormControl} from "@angular/forms";
import {ChangeContext, LabelType, Options} from "ngx-slider-v2";
import {ApexAxisChartSeries, ChartComponent, ChartType} from "ng-apexcharts";
@ -11,8 +11,8 @@ import {ChartOptions} from "../taskgroup-activity.component";
templateUrl: './simple-activity-diagram.component.html',
styleUrls: ['./simple-activity-diagram.component.css']
})
export class SimpleActivityDiagramComponent {
@Input('selectedChartype') selectedChartype: string = "bar";
export class SimpleActivityDiagramComponent implements OnChanges {
@Input('selectedChartype') selectedChartype: string | undefined
@Input() selectedTaskgroupPath: TaskgroupPathInfo | undefined;
sliderControl: FormControl = new FormControl()
@ -31,11 +31,53 @@ export class SimpleActivityDiagramComponent {
};
@ViewChild("chart") chart?: ChartComponent;
public chartOptions: Partial<ChartOptions> = this.generateChartOptions()
series: ApexAxisChartSeries = []
chartOptions: Partial<ChartOptions> | undefined;
constructor(private taskgroupService: TaskgroupService,
private historyService: HistoryService) {
}
ngOnChanges() {
this.series = [];
const startingDate = moment(this.dateRange[0]).format("yyyy-MM-DD");
const endingDate = moment(this.dateRange[this.dateRange.length-1]).format("yyyy-MM-DD");
this.historyService.statisticsStartingDateEndingDateGet(startingDate, endingDate).subscribe({
next: resp => {
resp.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)
}
})
this.series.push({
name: taskgroupActivityInfo.taskgroup.taskgroupName,
data: data
})
})
this.chartOptions = {
series: this.series,
chart: {
height: 350,
type: this.selectedChartype as ChartType,
stacked: true
},
title: {
text: ""
},
xaxis: {
categories: this.selectedDateRange.map(date => date.toDateString())
}
}
}
})
}
createDateRange(): Date[] {
const dates: Date[] = [];
@ -63,84 +105,10 @@ export class SimpleActivityDiagramComponent {
console.log("min " + moment(changeContext.value).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.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) {
this.selectedChartype = selectedChartype;
this.updateSerieSelection();
}
//this.selectedChartype = selectedChartype;
setSelectedTaskgroupPath(selectedTaskgroupPath: TaskgroupPathInfo) {
this.selectedTaskgroupPath = selectedTaskgroupPath;
this.updateSerieSelection();
}
}

View File

@ -2,7 +2,7 @@
<app-navigation-link-list #navLinkList [navigationLinks]="defaultNavigationLinkPath"></app-navigation-link-list>
<mat-form-field style="width: 90%">
<mat-label>Taskgroup</mat-label>
<mat-select [(ngModel)]="selectedTaskgroupPath" (ngModelChange)="onSelectTaskgroupPath()">
<mat-select [(ngModel)]="selectedTaskgroupPath">
<mat-option *ngFor="let topping of taskgroupPaths" [value]="topping">{{topping.taskgroupPath}}</mat-option>
</mat-select>
</mat-form-field>

View File

@ -65,14 +65,6 @@ export class TaskgroupActivityComponent implements OnInit{
}
onSelectTaskgroupPath() {
if(this.simpleActivityDiagram != undefined) {
this.simpleActivityDiagram.setSelectedTaskgroupPath(this.selectedTaskgroupPath!);
}
//this.heatMap?.setSelectedTaskgroupPath(this.selectedTaskgroupPath!);
}
onSelectChartType() {
if(this.simpleActivityDiagram != undefined) {
this.simpleActivityDiagram.setSelectedChartType(this.selectedChartype);