diff --git a/backend/src/main/java/core/api/controller/TaskgroupController.java b/backend/src/main/java/core/api/controller/TaskgroupController.java index 6de2010..e9cdea2 100644 --- a/backend/src/main/java/core/api/controller/TaskgroupController.java +++ b/backend/src/main/java/core/api/controller/TaskgroupController.java @@ -1,10 +1,7 @@ package core.api.controller; import core.api.models.auth.SimpleStatusResponse; -import core.api.models.timemanager.taskgroup.RecursiveTaskgroupInfo; -import core.api.models.timemanager.taskgroup.TaskgroupDetailInfo; -import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo; -import core.api.models.timemanager.taskgroup.TaskgroupFieldInfo; +import core.api.models.timemanager.taskgroup.*; import core.entities.timemanager.Taskgroup; import core.services.*; import org.springframework.beans.factory.annotation.Autowired; @@ -116,4 +113,10 @@ public class TaskgroupController { taskService.clearTasks(taskgroupPermissionResult.getResult()); return ResponseEntity.ok(new SimpleStatusResponse("success")); } + + @GetMapping("/taskgroups/path") + public ResponseEntity getTaskgroupPaths() { + List taskgroups = taskgroupService.getTaskgroupsByUser(SecurityContextHolder.getContext().getAuthentication().getName()); + return ResponseEntity.ok(taskgroups.stream().map(TaskgroupPathInfo::new)); + } } diff --git a/backend/src/main/java/core/api/models/timemanager/taskgroup/TaskgroupPathInfo.java b/backend/src/main/java/core/api/models/timemanager/taskgroup/TaskgroupPathInfo.java new file mode 100644 index 0000000..e37be0a --- /dev/null +++ b/backend/src/main/java/core/api/models/timemanager/taskgroup/TaskgroupPathInfo.java @@ -0,0 +1,21 @@ +package core.api.models.timemanager.taskgroup; + +import com.fasterxml.jackson.annotation.JsonProperty; +import core.entities.timemanager.Taskgroup; + +import java.util.ArrayList; +import java.util.List; + +public class TaskgroupPathInfo { + + @JsonProperty + private List taskgroupPathNames; + + public TaskgroupPathInfo(Taskgroup taskgroup) { + taskgroupPathNames = new ArrayList<>(); + List taskgroupPath = Taskgroup.getAncestorList(taskgroup); + for(Taskgroup cT : taskgroupPath) { + taskgroupPathNames.add(cT.getTaskgroupName()); + } + } +} diff --git a/backend/src/main/java/core/services/TaskgroupService.java b/backend/src/main/java/core/services/TaskgroupService.java index 3e0d725..ebbc078 100644 --- a/backend/src/main/java/core/services/TaskgroupService.java +++ b/backend/src/main/java/core/services/TaskgroupService.java @@ -107,4 +107,8 @@ public class TaskgroupService { public void deleteTaskgroupByUser(User user) { taskgroupRepository.deleteAllByUser(user); } + + public List getTaskgroupsByUser(String name) { + return taskgroupRepository.findAllByUser(name); + } } diff --git a/frontend/src/api/.openapi-generator/FILES b/frontend/src/api/.openapi-generator/FILES index 9ff84f1..aee98ad 100644 --- a/frontend/src/api/.openapi-generator/FILES +++ b/frontend/src/api/.openapi-generator/FILES @@ -50,6 +50,7 @@ model/taskTaskgroupInfo.ts model/taskgroupDetailInfo.ts model/taskgroupEntityInfo.ts model/taskgroupFieldInfo.ts +model/taskgroupPathInfo.ts model/userAddInfo.ts model/userInfo.ts model/userUpdateInfo.ts diff --git a/frontend/src/api/api/taskgroup.service.ts b/frontend/src/api/api/taskgroup.service.ts index 8433f82..41da811 100644 --- a/frontend/src/api/api/taskgroup.service.ts +++ b/frontend/src/api/api/taskgroup.service.ts @@ -25,6 +25,7 @@ import { SimpleStatusResponse } from '../model/models'; import { TaskgroupDetailInfo } from '../model/models'; import { TaskgroupEntityInfo } from '../model/models'; import { TaskgroupFieldInfo } from '../model/models'; +import { TaskgroupPathInfo } from '../model/models'; import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; import { Configuration } from '../configuration'; @@ -201,6 +202,61 @@ export class TaskgroupService { ); } + /** + * lists all taskgrouppaths + * lists all taskgroup-paths + * @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 taskgroupsPathGet(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; + public taskgroupsPathGet(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>>; + public taskgroupsPathGet(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>>; + public taskgroupsPathGet(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + + 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>(`${this.configuration.basePath}/taskgroups/path`, + { + context: localVarHttpContext, + responseType: responseType_, + withCredentials: this.configuration.withCredentials, + headers: localVarHeaders, + observe: observe, + reportProgress: reportProgress + } + ); + } + /** * creates taskgroup * creates taskgroup diff --git a/frontend/src/api/model/models.ts b/frontend/src/api/model/models.ts index e94238f..78779ac 100644 --- a/frontend/src/api/model/models.ts +++ b/frontend/src/api/model/models.ts @@ -33,6 +33,7 @@ export * from './taskTaskgroupInfo'; export * from './taskgroupDetailInfo'; export * from './taskgroupEntityInfo'; export * from './taskgroupFieldInfo'; +export * from './taskgroupPathInfo'; export * from './userAddInfo'; export * from './userInfo'; export * from './userUpdateInfo'; diff --git a/frontend/src/api/model/taskgroupPathInfo.ts b/frontend/src/api/model/taskgroupPathInfo.ts new file mode 100644 index 0000000..2c09be3 --- /dev/null +++ b/frontend/src/api/model/taskgroupPathInfo.ts @@ -0,0 +1,17 @@ +/** + * 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 TaskgroupPathInfo { + taskgroupPathNames: Array; +} + diff --git a/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.html b/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.html index affe899..fa3d545 100644 --- a/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.html +++ b/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.html @@ -1,5 +1,12 @@
+ + Toppings + + {{topping}} + + +
- +
diff --git a/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.ts b/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.ts index bb94ef5..d2424a4 100644 --- a/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.ts +++ b/frontend/src/app/statistics/taskgroup-activity/taskgroup-activity.component.ts @@ -1,7 +1,7 @@ -import {Component, ViewChild} from '@angular/core'; +import {Component, OnInit, ViewChild} from '@angular/core'; import {NavigationLink} from "../../navigation-link-list/navigation-link-list.component"; import * as moment from "moment"; -import {LabelType, Options} from "ngx-slider-v2"; +import {ChangeContext, LabelType, Options} from "ngx-slider-v2"; import { ChartComponent, ApexAxisChartSeries, @@ -9,6 +9,9 @@ import { ApexXAxis, ApexTitleSubtitle } from "ng-apexcharts"; +import {timeInterval} from "rxjs"; +import {FormControl} from "@angular/forms"; +import {TaskgroupService} from "../../../api"; export type ChartOptions = { series: ApexAxisChartSeries; @@ -21,7 +24,7 @@ export type ChartOptions = { templateUrl: './taskgroup-activity.component.html', styleUrls: ['./taskgroup-activity.component.css'] }) -export class TaskgroupActivityComponent { +export class TaskgroupActivityComponent implements OnInit{ defaultNavigationLinkPath: NavigationLink[] = [ { linkText: 'Dashboard', @@ -37,14 +40,13 @@ export class TaskgroupActivityComponent { } ]; - minValue: number = 50; - maxValue: number = 200; - /*options: Options = { - floor: 0, - ceil: 250 - };*/ + toppings = new FormControl(); + toppingList: string[] = []; + selectedSeries: string[] = [] + sliderControl: FormControl = new FormControl() dateRange: Date[] = this.createDateRange(); + selectedDateRange: Date[] = this.dateRange; value: number = this.dateRange[0].getTime(); options: Options = { stepsArray: this.dateRange.map((date: Date) => { @@ -58,24 +60,23 @@ export class TaskgroupActivityComponent { }; @ViewChild("chart") chart?: ChartComponent; - public chartOptions: Partial = { - series: [ - { - name: "My-series", - data: [10, 41, 35, 51, 49, 62, 69, 91, 148] + public chartOptions: Partial = this.generateChartOptions() + + constructor(private taskgroupService: TaskgroupService) { + } + + ngOnInit() { + this.taskgroupService.taskgroupsPathGet().subscribe({ + next: resp => { + resp.forEach(taskgroupPath => { + let taskgroupPathName = ""; + taskgroupPath.taskgroupPathNames.forEach(name => taskgroupPathName += (name + "/")) + this.toppingList.push(taskgroupPathName) + }) } - ], - chart: { - height: 350, - type: "bar" - }, - title: { - text: "My First Angular Chart" - }, - xaxis: { - categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep"] - } - }; + }) + } + createDateRange(): Date[] { const dates: Date[] = []; @@ -83,7 +84,76 @@ export class TaskgroupActivityComponent { dates.push(moment().subtract(30-i, 'd').toDate()); } + this.sliderControl.setValue([dates[0], dates[dates.length-1]]) return dates; } + createDateRangeBetween(minValue: moment.Moment, maxValue: moment.Moment) { + const dates: Date[] = []; + const numberDays = maxValue.diff(minValue, 'days'); + for(let i=0; i<=numberDays; i++) { + dates.push(minValue.add(i, 'd').toDate()); + } + return dates; + } + + onUserChangeStart(changeContext: ChangeContext) { + + //console.log("onUserChangeStart" + new Date(changeContext.value)); + } + + onUserChangeStop(changeContext: ChangeContext) { + //console.log("onUserChangeStop" + new Date(changeContext.highValue!)) + } + + onUserChange(changeContext: ChangeContext) { + const dateRange = this.createDateRangeBetween(moment(changeContext.value), moment(changeContext.highValue!)) + this.chartOptions = this.generateChartOptions() + } + + generateChartOptions(): Partial { + return { + series: this.selectedSeries.map(serie => this.generateSeries(serie)!), + chart: { + height: 350, + type: "bar", + stacked: false + }, + title: { + text: "" + }, + xaxis: { + categories: this.selectedDateRange.map(date => date.toDateString()) + } + }; + } + + generateSeries(serie: string) { + if(serie == "KIT/") { + return { + name: "Marine Sprite", + data: [44, 55, 41, 37, 22, 43, 21] + } + } else if(serie == "Striking Calf") { + return { + name: "Striking Calf", + data: [53, 32, 33, 52, 13, 43, 32] + } + } else if(serie == "Tank Picture") { + return { + name: "Tank Picture", + data: [12, 17, 11, 9, 15, 11, 20] + } + } else { + return { + name: "", + data: [] + } + } + + } + + updateSerieSelection() { + this.chartOptions = this.generateChartOptions() + } } diff --git a/openapi.yaml b/openapi.yaml index 13559c7..25f2353 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -883,6 +883,23 @@ paths: schema: type: object $ref: "#/components/schemas/SimpleStatusResponse" + /taskgroups/path: + get: + security: + - API_TOKEN: [] + tags: + - taskgroup + summary: lists all taskgrouppaths + description: lists all taskgroup-paths + responses: + 200: + description: Operation successfull + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/TaskgroupPathInfo' /tasks/all/{scope}/{detailed}: get: security: @@ -2529,4 +2546,13 @@ components: format: date scheduleStopTime: type: string - format: date \ No newline at end of file + format: date + TaskgroupPathInfo: + required: + - taskgroupPathNames + additionalProperties: false + properties: + taskgroupPathNames: + type: array + items: + type: string \ No newline at end of file