diff --git a/frontend/package.json b/frontend/package.json
index f14e1e4..0788022 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -7,7 +7,7 @@
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test",
- "compdoc": "npx compodoc -p tsconfig.app.json -s -w -r 9090"
+ "compodoc": "npx compodoc -p tsconfig.doc.json"
},
"private": true,
"dependencies": {
diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts
index a211689..d49f78d 100644
--- a/frontend/src/app/app.component.ts
+++ b/frontend/src/app/app.component.ts
@@ -8,7 +8,9 @@ import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
})
-
+/**
+* The AppComponent is just a container for the NTTGanttComponent
+*/
export class AppComponent {
constructor() {}
diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts
index 24c7b6a..bf33ddb 100644
--- a/frontend/src/app/app.module.ts
+++ b/frontend/src/app/app.module.ts
@@ -26,7 +26,7 @@ import { ImplementerDialogComponent } from './implementer-dialog/implementer-dia
import {MatExpansionModule} from '@angular/material/expansion';
import {MatInputModule} from '@angular/material/input';
import {MatCheckboxModule} from '@angular/material/checkbox';
-import { FilterComponentComponent } from './filter-component/filter-component.component';
+
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import { MultiselectAutocompleteComponent } from './multiselect-autocomplete/multiselect-autocomplete.component';
import {MatChipsModule} from '@angular/material/chips';
@@ -42,7 +42,6 @@ import { PlanTimeBarComponent } from './plan-time-bar/plan-time-bar.component';
NttGanttComponent,
StateDialogComponent,
ImplementerDialogComponent,
- FilterComponentComponent,
MultiselectAutocompleteComponent,
FilterDialogComponent,
PlanTimeBarComponent
diff --git a/frontend/src/app/data.service.ts b/frontend/src/app/data.service.ts
index 6bb2c3c..44d32e8 100644
--- a/frontend/src/app/data.service.ts
+++ b/frontend/src/app/data.service.ts
@@ -4,16 +4,14 @@ import { Injectable } from '@angular/core';
import { ResourceFields } from '@syncfusion/ej2-angular-gantt';
import { LanguageService } from './language.service';
-
@Injectable({
providedIn: 'root'
})
-
/**
- *The DataService manages the communication between Frontend and Backend, fetches Data from the Backend and maps it to the Frontend Data Structure. Additionally it updates data on the Backend.
- *
- */
+* The DataService manages the communication between Frontend and Backend, fetches Data from the Backend and maps it to the Frontend Data Structure. Additionally it updates data on the Backend.
+*
+*/
export class DataService {
private states: any []; //Array of statuses and possible statuses, which is queried once at the beginning by backend and stored in dataservice
private supportGroups: any [];
@@ -21,11 +19,13 @@ export class DataService {
private paketTypes: any [];
private totalSize: number = null;
public userSupportGroup: string;
- //public selectedLanguage: string = 'DE';
+ //public selectedLanguage: string = 'DE';
+
/**
- * This constructor builds the dataService and fetches the states from the backend
- * @param http
- */
+ * This constructor builds the dataService and fetches the states from the backend
+ * @param languageService injection of the languageService
+ * @param http representation of the HttpClient
+ */
constructor(public languageService: LanguageService, private http: HttpClient) {
this.fetchStates().then((res: any [])=>{
this.states = res;
@@ -46,33 +46,78 @@ export class DataService {
});
}
-/**
- *
- * @returns an array of states and possible states per state
- */
+ /**
+ * the function getStates
+ * @returns an array of states and possible states per state
+ */
public getStates():any[]{
return this.states;
}
+ /**
+ * the function getSupportGroups
+ * @returns an array of all supportGroups
+ */
public getSupportGroups():any[]{
return this.supportGroups;
}
+ /**
+ * the function getContracts
+ * @returns an array of all contracts
+ */
public getContracts():any[]{
return this.contracts;
}
+ /**
+ * the function getPaketTypes
+ * @returns an array of all paketTypes
+ */
public getPaketTypes():any[]{
return this.paketTypes;
}
+ /**
+ * the function getTotalSize
+ * @returns the size of all changes, that are matched by the actual filters
+ * required for totalSize attribute of the paginator
+ */
public getTotalSize():number{
return this.totalSize;
}
+ /**
+ * the function getUserSupportGroup
+ * @returns the supportGroup of the actual user
+ */
public getUserSupportGroup():string{
return this.userSupportGroup;
}
+
+ /**
+ * the function getStateIdByName translates the name of a state into the id
+ * @param stateName name of the state
+ * @returns id of the state
+ */
+ public getStateIdByName(stateName: string): number {
+ for (let state of this.states) {
+ if(stateName == state.stateNameEN){
+ return state.id;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * the function getContractByName searches a contract by its uid and returns the name
+ * @param contractId uid to search the contract
+ * @returns the name of the corresponding contract
+ */
+ public getContractName(contractId: string): string{
+ return this.contracts.find((contract)=> {return contract.id == contractId;}).name;
+ }
+
/**
* The function fetchStates fetches an array from the possible statuses per state
* @returns promise for the fetched Status Array
@@ -91,6 +136,10 @@ export class DataService {
return promise;
}
+ /**
+ * The function fetchSupportGroups fetches an array of all supportGroups
+ * @returns promise for the fetched supportGroups array
+ */
public async fetchSupportGroups(){
const promise = new Promise(resolve=>{
let res : any[] = [];
@@ -105,6 +154,10 @@ export class DataService {
return promise;
}
+ /**
+ * The function fetchContracts fetches an array of all contracts
+ * @returns promise for the fetched contracts array
+ */
public async fetchContracts(){
const promise = new Promise(resolve=>{
let res : any[] = [];
@@ -119,6 +172,10 @@ export class DataService {
return promise;
}
+ /**
+ * The function fetchPaketTypes fetches an array of all paketTypes
+ * @returns promise for the fetched paketTypes array
+ */
public async fetchPaketTypes(){
const promise = new Promise(resolve=>{
let res : any[] = [];
@@ -133,6 +190,10 @@ export class DataService {
return promise;
}
+ /**
+ * The function fetchPaketTypes fetches the supportGroup of the current user
+ * @returns promise for the fetched current user supportGroup
+ */
public async fetchUserSupportGroup(){
const promise = new Promise(resolve=>{
let res : any = {};
@@ -146,76 +207,13 @@ export class DataService {
return promise;
}
-/**
- * The function updateDatePerChange sends the new date to the backend if the date was moved
- * @param change the Change (the Resource) from which the date should be changed
- */
- public async updateDatePerChange(change: any){
- // //console.log(change);
- // let serializableResource = { resourceId: change.resourceId, d2: change.tasks[1].StartDate, changeNr: change.changeNr, state: change.state};
- // let strigifiedResource = JSON.stringify(serializableResource);
- // let resJson = JSON.parse(strigifiedResource) as typeof strigifiedResource;
- // // console.log(resJson);
- // this.http.post('http://localhost:8080/api/updateChange', resJson).toPromise().then((value)=>{
- // console.log(value);
- // });
- const promise = new Promise(resolve=>{
- let serializableResource = { resourceId: change.resourceId, d2: change.tasks[1].StartDate, changeNr: change.changeNr, state: change.state};
- let strigifiedResource = JSON.stringify(serializableResource);
- let resJson = JSON.parse(strigifiedResource) as typeof strigifiedResource;
- // console.log(dataJson);
- this.http.post('http://localhost:8080/api/updateChange', resJson).subscribe((response:any)=>{
- resolve(response);
- },(error:any)=>{
- resolve(error);
- });
- });
-
- return promise;
-
-
-
- }
-
-/**
- * The function updateStatePerChange performs a status transition on the backend
- * @param change The Change for which the status transition is to be performed
- * @returns a Promise
- */
- public async updateStatePerChange(change: any){
- const promise = new Promise(resolve=>{
- let obj = {changeNr : change.changeNr, currentState : change.currentState, nextState : change.nextState};
- let stringyfiedData = JSON.stringify(obj);
- let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData;
- // console.log(dataJson);
- this.http.post('http://localhost:8080/api/updateState', dataJson).subscribe((response:any)=>{
- resolve(response);
- },(error:any)=>{
- resolve(error);
- });
- });
-
- return promise;
- }
-
- public async updateImplementerPerChange(change: any){
- const promise = new Promise(resolve=>{
- // console.log(change);
- let obj = {pkgId : change.resourceId, loginId : change.loginId};
- let stringyfiedData = JSON.stringify(obj);
- let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData;
- // console.log(dataJson);
- this.http.post('http://localhost:8080/api/updateImplementer', dataJson).subscribe((response:any)=>{
- resolve(response);
- },(error:any)=>{
- console.log(error);
- resolve(error);
- });
- })
-
- return promise;
- }
-
+ /**
+ * The function fetchPlanTimes fetches the plan times per week from the backend
+ * @param filters current applied filters for the planTime calculation
+ * @param renderStartDate startDate of the current gantt chart (first week rendered)
+ * @param renderEndtDate startDate of the current gantt chart (last week rendered)
+ * @returns a promise for the response
+ */
public async fetchPlanTimes(filters: any, renderStartDate: Date, renderEndtDate: Date){
const promise = new Promise(resolve=>{
let obj = {filter : filters.filter, renderStartDate : renderStartDate, renderEndDate: renderEndtDate };
@@ -234,6 +232,11 @@ export class DataService {
return promise;
}
+ /**
+ * The function fetchImplementers fetches an array of all implementers of the supportGoup from a specific change
+ * @param change change, for which the possible implementers should be fetched
+ * @returns promise for the fetched implementers array
+ */
public async fetchImplementers(change: any){
const promise = new Promise(resolve=>{
let obj = {entryId : change.resourceId, supportGroup : change.supportGroupId};
@@ -252,6 +255,73 @@ export class DataService {
return promise;
}
+ /**
+ * The function updateDatePerChange sends the new date to the backend if the date was moved
+ * @param change the Change (the Resource) from which the date should be changed
+ */
+ public async updateDatePerChange(change: any){
+ const promise = new Promise(resolve=>{
+ let serializableResource = { resourceId: change.resourceId, d2: change.tasks[1].StartDate, changeNr: change.changeNr, state: change.state};
+ let strigifiedResource = JSON.stringify(serializableResource);
+ let resJson = JSON.parse(strigifiedResource) as typeof strigifiedResource;
+ this.http.post('http://localhost:8080/api/updateChange', resJson).subscribe((response:any)=>{
+ resolve(response);
+ },(error:any)=>{
+ resolve(error);
+ });
+ });
+ return promise;
+ }
+
+ /**
+ * The function updateStatePerChange performs a status transition on the backend
+ * @param change the change for which the status transition is to be performed
+ * @returns a aromise for the response
+ */
+ public async updateStatePerChange(change: any){
+ const promise = new Promise(resolve=>{
+ let obj = {changeNr : change.changeNr, currentState : change.currentState, nextState : change.nextState};
+ let stringyfiedData = JSON.stringify(obj);
+ let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData;
+ // console.log(dataJson);
+ this.http.post('http://localhost:8080/api/updateState', dataJson).subscribe((response:any)=>{
+ resolve(response);
+ },(error:any)=>{
+ resolve(error);
+ });
+ });
+
+ return promise;
+ }
+
+ /**
+ * The function updateImplementerPerChange updates the implementer for a specific change on the backend
+ * @param data the change for which the implementer update is to be performed and the loginId of the implementer
+ * @returns a promise for the response
+ */
+ public async updateImplementerPerChange(data: any){
+ const promise = new Promise(resolve=>{
+ // console.log(change);
+ let obj = {pkgId : data.resourceId, loginId : data.loginId};
+ let stringyfiedData = JSON.stringify(obj);
+ let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData;
+ // console.log(dataJson);
+ this.http.post('http://localhost:8080/api/updateImplementer', dataJson).subscribe((response:any)=>{
+ resolve(response);
+ },(error:any)=>{
+ console.log(error);
+ resolve(error);
+ });
+ })
+
+ return promise;
+ }
+
+ /**
+ * The function updateApproval updates the approvalStatus for a specific change on the backend
+ * @param change concerning change
+ * @returns a promise for the response
+ */
public async updateApproval(change: any, approvalAction){
const promise = new Promise(resolve=>{
let obj = {changeNr : change.changeNr, approvalAction: approvalAction};
@@ -272,12 +342,10 @@ export class DataService {
/**
- * The function fetchChanges fetches the changes from backend and maps them to a structure that the Gannt component can interpret
- * @returns promise for the fetched Changes Array
- */
+ * The function fetchChanges fetches the changes from backend and maps them to a structure that the Gannt component can interpret
+ * @returns promise for the fetched Changes Array
+ */
public async fetchChanges(reqestParams: any = null){
-
- // let filter = {'filterElement': [reqestParams]};
let stringyfiedData = JSON.stringify(reqestParams);
let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData;
const promise = new Promise(resolve=>{
@@ -367,8 +435,12 @@ export class DataService {
return promise;
}
-
- validateImplementerEdit(state):boolean{
+ /**
+ * The function validateImplementerEdit validates if a change is in a state where its implementer can be updated
+ * @param state state of the concerning change
+ * @returns true or false for a boolean flag
+ */
+ private validateImplementerEdit(state):boolean{
if(state == 1 || state == 3 || state == 6){
return true;
}else{
@@ -376,14 +448,25 @@ export class DataService {
}
}
- validateCancel(state):boolean{
+ /**
+ * The function validateCancel validates if a change is in a state where it can be canceld
+ * @param state state of the concerning change
+ * @returns true or false for a boolean flag
+ */
+ private validateCancel(state):boolean{
if(state == 1){
return true
}else{
return false
}
}
- validatePermit(state): boolean{
+
+ /**
+ * The function validatePermit validates if a change is in a state where it can be permited
+ * @param state state of the concerning change
+ * @returns true or false for a boolean flag
+ */
+ private validatePermit(state): boolean{
if(state == 0){
return true
}else{
@@ -391,7 +474,12 @@ export class DataService {
}
}
- validateApproval(approval):boolean{
+ /**
+ * The function validatePermit validates if a change has an active approval
+ * @param state approvalString
+ * @returns true or false for a boolean flag
+ */
+ private validateApproval(approval):boolean{
if(approval!=""){
return true;
}else{
@@ -399,8 +487,12 @@ export class DataService {
}
}
-
- getStateNameById(stateNr): String {
+ /**
+ * The function getStateNameById searches the name of a status by its id, depending on the set language
+ * @param stateNr state number (uid)
+ * @returns string with the stateName
+ */
+ public getStateNameById(stateNr): String {
if(this.languageService.language == 'EN'){
for (let state of this.states) {
if(stateNr == state.actualState){
@@ -417,20 +509,6 @@ export class DataService {
}
return "";
}
-
- getStateIdByName(stateName: string): number {
- for (let state of this.states) {
- if(stateName == state.stateNameEN){
- return state.id;
- }
- }
- return -1;
- }
-
- getContractName(contractId: string): string{
- return this.contracts.find((contract)=> {return contract.id == contractId;}).name;
- }
-
}
diff --git a/frontend/src/app/filter-component/filter-component.component.css b/frontend/src/app/filter-component/filter-component.component.css
deleted file mode 100644
index d514949..0000000
--- a/frontend/src/app/filter-component/filter-component.component.css
+++ /dev/null
@@ -1,7 +0,0 @@
-.full-width {
- width: 100%;
-}
-
-.chip-list-wrapper {
- min-height: 3em;
-}
diff --git a/frontend/src/app/filter-component/filter-component.component.html b/frontend/src/app/filter-component/filter-component.component.html
deleted file mode 100644
index c5f5ad3..0000000
--- a/frontend/src/app/filter-component/filter-component.component.html
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
+
diff --git a/frontend/src/app/filter-dialog/filter-dialog.component.ts b/frontend/src/app/filter-dialog/filter-dialog.component.ts
index 3615265..57d0744 100644
--- a/frontend/src/app/filter-dialog/filter-dialog.component.ts
+++ b/frontend/src/app/filter-dialog/filter-dialog.component.ts
@@ -4,6 +4,7 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { DataService } from '../data.service';
import { MAT_DATE_FORMATS } from '@angular/material/core'
+
export interface FilterAttribute{
name: string,
}
@@ -29,42 +30,44 @@ export const MY_DATE_FORMATS = {
]
})
+/**
+* The ImplementerDialogComponent displays a dialog with all filter options
+*/
export class FilterDialogComponent implements OnInit {
+ public supportGroups: string[] = [];
+ public paketTypes: string[] = [];
+ public states: string[] = [];
+ public contracts: string[] = [];
+ public userSupportGroup: string;
- /**
- * The constructor injects required Dependencies and sets default values for logic and ui
- * @param dialogRef MatDialog Reference from Angular
- * @param data contains an array of Changes which should be sent to the backend for a status transition
- * @param dataService injects the dataService for data management and backend communication
- */
+ public criteria: string;
+ public filterStartDate: Date;
+ public filterEndDate: Date;
- public supportGroups: string[] = [];
- public paketTypes: string[] = [];
- public states: string[] = [];
- public contracts: string[] = [];
- public userSupportGroup: string;
+ public supportGroupsFilter = [];
+ public paketTypesFilter = [];
+ public statesFilter = [];
+ public contractsFilter = [];
+ public textFilter = [];
+ public dateFilter = [];
+ public filterLabels: string[] = [];
+ public filterObj;
- public criteria: string;
- public filterStartDate: Date;
- public filterEndDate: Date;
+ /**
+ * The constructor injects required Dependencies and sets default values for logic and ui
+ * @param languageService representation of the LanguageService
+ * @param dialogRef MatDialog Reference from Angular
+ * @param data contains an array of Changes which should be sent to the backend for a status transition
+ * @param dataService injects the dataService for data management and backend communication
+ */
+ constructor(public languageService: LanguageService, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any, private dataService: DataService, private _snackBar: MatSnackBar) {
+ //dialogRef.beforeClosed().subscribe(() => dialogRef.close(this.dataToReturn));
+ }
- public supportGroupsFilter = [];
- public paketTypesFilter = [];
- public statesFilter = [];
- public contractsFilter = [];
- public textFilter = [];
- public dateFilter = [];
- public filterLabels: string[] = [];
-
- public filterObj;
-
-
-
- constructor(public languageService: LanguageService, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any, private dataService: DataService, private _snackBar: MatSnackBar) {
- //dialogRef.beforeClosed().subscribe(() => dialogRef.close(this.dataToReturn));
- }
-
- ngOnInit(): void {
+ /**
+ * The function ngOnInit initialized the component by fetching all relevant data via the dataService
+ */
+ ngOnInit(): void {
this.dataService.fetchUserSupportGroup().then((res:any)=>{
this.userSupportGroup = res.name;
});
@@ -88,23 +91,20 @@ export class FilterDialogComponent implements OnInit {
for (const paketType of this.dataService.getPaketTypes()) {
this.paketTypes.push(paketType.name);
}
- }
+ }
- onResult(event: any) {
+ /**
+ * The function onResult gets the result (selection) from the multiselect-autocomplete-component,
+ * evaluates, which filter was selected and maps it to a list
+ * @param event selection event from the multiselect-autocomplete-component
+ */
+ onResult(event: any) {
console.log(event);
switch (event.key) {
case 'supportGroup':
this.supportGroupsFilter = event.data;
- // console.log(event.data);
- // for (const sg of event.data) {
- // if(this.dataService.getSupportGroups().find((item)=> {return item.name == sg;})){
- // this.supportGroupsFilter.push(this.dataService.getSupportGroups().find((item)=> {return item.name == sg;}).id);
- // }
- // console.log(this.supportGroupsFilter);
- // }
break;
case 'state':
- // this.statesFilter = event.data;
if(this.languageService.language == 'DE'){
console.log(event.data);
for (const state of event.data) {
@@ -148,9 +148,12 @@ export class FilterDialogComponent implements OnInit {
break;
}
- }
+ }
- applyFilter(){
+ /**
+ * The function mapFilter builds a filterElement out of all the selected filters, delivers it back and closes the dialog
+ */
+ mapFilter(){
let filterElement = []
if(this.paketTypesFilter.length > 0){
filterElement.push({
@@ -160,8 +163,6 @@ export class FilterDialogComponent implements OnInit {
});
}
-
-
if(this.statesFilter.length > 0){
filterElement.push({
"column": "State",
@@ -193,7 +194,6 @@ export class FilterDialogComponent implements OnInit {
});
}
-
if(this.filterStartDate != null && this.filterEndDate != null){
filterElement.push({
"column": "D2",
@@ -209,10 +209,9 @@ export class FilterDialogComponent implements OnInit {
"criteria": [this.criteria]
});
}
+
let filter = {filterElement: filterElement};
console.log(filter);
this.dialogRef.close(filter);
-
-
- }
+ }
}
diff --git a/frontend/src/app/implementer-dialog/implementer-dialog.component.ts b/frontend/src/app/implementer-dialog/implementer-dialog.component.ts
index 84153c2..06c9c7f 100644
--- a/frontend/src/app/implementer-dialog/implementer-dialog.component.ts
+++ b/frontend/src/app/implementer-dialog/implementer-dialog.component.ts
@@ -14,6 +14,10 @@ import { LanguageService } from '../language.service';
templateUrl: './implementer-dialog.component.html',
styleUrls: ['./implementer-dialog.component.css']
})
+
+/**
+* The ImplementerDialogComponent displays a dialog to change the implementer of a change
+*/
export class ImplementerDialogComponent implements OnInit {
@@ -36,114 +40,101 @@ export class ImplementerDialogComponent implements OnInit {
* @param data contains an array of Changes which should be sent to the backend for a status transition
* @param dataService injects the dataService for data management and backend communication
*/
- constructor(public languageService: LanguageService, private dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any,private dataService: DataService, private _snackBar: MatSnackBar) {
- this.progress = 0;
- this.bdiasbled = true;
- this.diasbled = false;
- this.selectedValue = -1;
- this.possibleImplementers = [];
- }
-
-/**
-* The function ngOnInit checks in which actual State the selected changes are, then it provides a list that contains which statuses can be switched to in the current state
-*/
- ngOnInit(): void {
- console.log(this.data.changes[0]);
- this.dataService.fetchImplementers(this.data.changes[0]).then((res: any)=>{
- this.implementers = res;
- console.log(this.implementers);
+ constructor(public languageService: LanguageService, private dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any,private dataService: DataService, private _snackBar: MatSnackBar) {
+ this.progress = 0;
+ this.bdiasbled = true;
+ this.diasbled = false;
+ this.selectedValue = -1;
this.possibleImplementers = [];
- if(this.implementers.length>0){
- for (const implementer of this.implementers) {
- this.possibleImplementers.push({value: implementer.loginId, viewValue: implementer.memberName});
- }
- }else{
- this.dialogRef.close();
- }
- }).catch((error)=>{
-
- });
-
- // MOCK:
-// this.implementers = [{name: "Manuel Tauber", loginId: "MT01"}, {name: "Julius Sula", loginId: "MT02"}, {name: "Said Gedik", loginId: "MT03"}];
-// console.log(this.implementers);
-// this.possibleImplementers = [];
-// if(this.implementers.length>0){
-// for (const implementer of this.implementers) {
-// this.possibleImplementers.push({value: implementer.loginId, viewValue: implementer.name});
-// }
-// }else{
-// this.dialogRef.close();
-// }
}
- /**
+ /**
+ * The function ngOnInit checks in which actual State the selected changes are, then it provides a list that contains which statuses can be switched to in the current state
+ */
+ ngOnInit(): void {
+ console.log(this.data.changes[0]);
+ this.dataService.fetchImplementers(this.data.changes[0]).then((res: any)=>{
+ this.implementers = res;
+ console.log(this.implementers);
+ this.possibleImplementers = [];
+ if(this.implementers.length>0){
+ for (const implementer of this.implementers) {
+ this.possibleImplementers.push({value: implementer.loginId, viewValue: implementer.memberName});
+ }
+ }else{
+ this.dialogRef.close();
+ }
+ }).catch((error)=>{
+
+ });
+ }
+
+ /**
* The function enableButton is triggered by the selction event of a possible state by the user it anebles the execution button
*/
- enableButton():void{
- this.bdiasbled = false;
- }
+ enableButton():void{
+ this.bdiasbled = false;
+ }
- /**
+ /**
* The function updateState uses the dataService to execute a status transition on the backend. It sends the Changes to the backend one-by-one and calculates the percent-progress value for the progress bar.
*/
- updateImplementer(): void{
- let counter : number = 0;
- if(this.selectedValue != -1){
- for (let change of this.data.changes){
- this.dataService.updateImplementerPerChange({resourceId: change.pkgId, loginId: this.selectedValue}).then((res: any)=>{
- this.diasbled = true;
- this.bdiasbled = true;
- console.log(res);
- if(res.status == 200){
- counter++;
- this.progress = (counter/this.data.changes.length)*100;
- }
- if(res.status == 500){
- let msg;
- let action;
- if(this.languageService.language == 'DE'){
- msg = 'Implementer Eintragung fehlgeschlagen';
- action ='Schließen';
- }else{
- msg = 'Implementer Update failed';
- action ='close';
+ updateImplementer(): void{
+ let counter : number = 0;
+ if(this.selectedValue != -1){
+ for (let change of this.data.changes){
+ this.dataService.updateImplementerPerChange({resourceId: change.pkgId, loginId: this.selectedValue}).then((res: any)=>{
+ this.diasbled = true;
+ this.bdiasbled = true;
+ console.log(res);
+ if(res.status == 200){
+ counter++;
+ this.progress = (counter/this.data.changes.length)*100;
}
- this._snackBar.open(msg+" : "+res.error.message, action, {
- horizontalPosition: this.horizontalPosition,
- verticalPosition: this.verticalPosition,
- panelClass: ['mat-primary']
- }).onAction().subscribe(() => {
- console.log('The snackbar action was triggered!');
- });
- this.dialogRef.close();
- //this.dialogRef.close();
- //counter++;
- //this.progress = (counter/this.data.changes.length)*100;
- }
-
- if(this.progress == 100){
- this.diasbled = false;
- this.bdiasbled = true;
- let msg;
- let action;
- if(this.languageService.language == 'DE'){
- msg = 'Implementer Eintragung erfolgreich';
- action ='Schließen';
- }else{
- msg = 'Implementer Update successful';
- action ='close';
+ if(res.status == 500){
+ let msg;
+ let action;
+ if(this.languageService.language == 'DE'){
+ msg = 'Implementer Eintragung fehlgeschlagen';
+ action ='Schließen';
+ }else{
+ msg = 'Implementer Update failed';
+ action ='close';
+ }
+ this._snackBar.open(msg+" : "+res.error.message, action, {
+ horizontalPosition: this.horizontalPosition,
+ verticalPosition: this.verticalPosition,
+ panelClass: ['mat-primary']
+ }).onAction().subscribe(() => {
+ console.log('The snackbar action was triggered!');
+ });
+ this.dialogRef.close();
+ //this.dialogRef.close();
+ //counter++;
+ //this.progress = (counter/this.data.changes.length)*100;
}
- this._snackBar.open(msg, action, {
- horizontalPosition: this.horizontalPosition,
- verticalPosition: this.verticalPosition,
- duration: 5000,
- });
- this.dialogRef.close();
- }
- });
- }
- }
- }
+ if(this.progress == 100){
+ this.diasbled = false;
+ this.bdiasbled = true;
+ let msg;
+ let action;
+ if(this.languageService.language == 'DE'){
+ msg = 'Implementer Eintragung erfolgreich';
+ action ='Schließen';
+ }else{
+ msg = 'Implementer Update successful';
+ action ='close';
+ }
+ this._snackBar.open(msg, action, {
+ horizontalPosition: this.horizontalPosition,
+ verticalPosition: this.verticalPosition,
+ duration: 5000,
+ });
+ this.dialogRef.close();
+ }
+ });
+ }
+ }
+ }
}
diff --git a/frontend/src/app/language.service.ts b/frontend/src/app/language.service.ts
index d4d30a3..497c69d 100644
--- a/frontend/src/app/language.service.ts
+++ b/frontend/src/app/language.service.ts
@@ -3,6 +3,12 @@ import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
+
+/**
+* The LanguageService manages the language (DE or EN) over all Components
+* and returns and returns all textual attributes in the selected language
+* By holding 2 languageMaps for german and english and one languageMap that can be set to the german or english map
+*/
export class LanguageService {
public language: string = 'DE';
@@ -17,6 +23,9 @@ export class LanguageService {
public dePlanTimeResources: any[];
public enPlanTimeResources: any[];
+ /**
+ * The constructor sets all the language values and does the default mapping
+ */
constructor() {
this.deMap.set('detailButton', 'Details anzeigen');
this.enMap.set('detailButton', 'Show Details');
@@ -176,21 +185,31 @@ export class LanguageService {
}
}
- public languageChange(args: any){
+ /**
+ * The function languageChange set the language map to the german or english map depending on the selected language
+ * it is triggered by an language change from the NttGanttComponent
+ * @param args args with the selected language
+ */
+ public languageChange(args: any){
if(this.language == 'DE'){
this.lMap = this.deMap;
}else{
this.language = 'EN';
this.lMap = this.enMap;
}
- }
- public getColumns(){
+ }
+
+ /**
+ * The function getColumns delivers the gannt chart columns for the NttGanttComponent in the selected language
+ * it is triggered by an language change from the NttGanttComponent
+ */
+ public getColumns(){
if(this.language == 'DE'){
return this.deColumns;
}else{
this.language = 'EN';
return this.enColumns;
}
- }
}
+}
diff --git a/frontend/src/app/multiselect-autocomplete/multiselect-autocomplete.component.ts b/frontend/src/app/multiselect-autocomplete/multiselect-autocomplete.component.ts
index f03b76b..52ef499 100644
--- a/frontend/src/app/multiselect-autocomplete/multiselect-autocomplete.component.ts
+++ b/frontend/src/app/multiselect-autocomplete/multiselect-autocomplete.component.ts
@@ -16,23 +16,27 @@ export interface ItemData {
templateUrl: './multiselect-autocomplete.component.html',
styleUrls: ['./multiselect-autocomplete.component.css']
})
+
+/**
+* The MultiselectAutocompleteComponent mixes a angular material multiselect and a angular material autocomplete
+* it builds the base for many filter select option
+*/
export class MultiselectAutocompleteComponent implements OnInit {
@Output() result = new EventEmitter<{ key: string, data: Array }>();
-
@Input() placeholder: string = 'Select Data';
@Input() data: Array = [];
@Input() key: string = '';
-
selectControl = new FormControl();
-
rawData: Array = [];
selectData: Array = [];
-
filteredData: Observable>;
filterString: string = '';
+ /**
+ * The constructor maps the default values
+ */
constructor() {
this.filteredData = this.selectControl.valueChanges.pipe(
startWith(''),
@@ -41,7 +45,9 @@ export class MultiselectAutocompleteComponent implements OnInit {
);
}
-
+ /**
+ * The function ngOnInit imports the data (filter options) and maps it
+ */
ngOnInit(): void {
this.data.forEach((item: string) => {
this.rawData.push({ item, selected: false });
@@ -58,8 +64,10 @@ export class MultiselectAutocompleteComponent implements OnInit {
}
-
-
+ /**
+ * The function filter filters the list with the select options
+ * @param filter text to search for
+ */
filter = (filter: string): Array => {
this.filterString = filter;
if (filter.length > 0) {
@@ -70,27 +78,37 @@ export class MultiselectAutocompleteComponent implements OnInit {
return this.rawData.slice();
}
};
-
- displayFn = (): string => '';
+ displayFn = (): string => '';
+ /**
+ * The funtion optionClicked hanled the selection of a select option (filter option)
+ * @param event selection event
+ * @param data (filter)item data
+ */
optionClicked = (event: Event, data: ItemData): void => {
event.stopPropagation();
this.toggleSelection(data);
};
-
+ /**
+ * The function toggleSelection handles a click on a selection item
+ * if it is already selected it will be removed from the selection, if it is not yet selected it will be selected
+ * it builds the base for many filter select option
+ */
toggleSelection = (data: ItemData): void => {
data.selected = !data.selected;
-
if (data.selected === true) {
this.selectData.push(data);
} else {
const i = this.selectData.findIndex(value => value.item === data.item);
this.selectData.splice(i, 1);
}
-
this.selectControl.setValue(this.selectData);
this.emitAdjustedData();
};
+ /**
+ * The emitAdjustedData emits the selected options the the parent component
+ * its triggered when the selectbox is closed
+ */
emitAdjustedData = (): void => {
const results: Array = []
@@ -100,6 +118,9 @@ export class MultiselectAutocompleteComponent implements OnInit {
this.result.emit({ key: this.key, data: results });
};
+ /**
+ * The removeChip removes a option from the selection list if the user presses the remove button on the chip list
+ */
removeChip = (data: ItemData): void => {
this.toggleSelection(data);
};
diff --git a/frontend/src/app/ntt-gantt/ntt-gantt.component.ts b/frontend/src/app/ntt-gantt/ntt-gantt.component.ts
index b05075b..6a30d7c 100644
--- a/frontend/src/app/ntt-gantt/ntt-gantt.component.ts
+++ b/frontend/src/app/ntt-gantt/ntt-gantt.component.ts
@@ -35,6 +35,9 @@ export const MY_DATE_FORMATS = {
{ provide: MAT_DATE_FORMATS, useValue: MY_DATE_FORMATS }
]
})
+ /**
+ * The NttGanttComponent is the core Component of the application
+ */
export class NttGanttComponent implements OnInit {
/**###################################################################### Variable Declarations and Definitions ######################################################################*/
diff --git a/frontend/src/app/plan-time-bar/plan-time-bar.component.ts b/frontend/src/app/plan-time-bar/plan-time-bar.component.ts
index bd98c9b..e11fa99 100644
--- a/frontend/src/app/plan-time-bar/plan-time-bar.component.ts
+++ b/frontend/src/app/plan-time-bar/plan-time-bar.component.ts
@@ -22,6 +22,12 @@ export const MY_DATE_FORMATS = {
templateUrl: './plan-time-bar.component.html',
styleUrls: ['./plan-time-bar.component.css']
})
+
+/**
+* The PlanTimeBarComponent displays a second gannt chart with the calculated planTime per week
+* and must have the same renderStartDate and renderEndDate as the main gantt chart
+*/
+
export class PlanTimeBarComponent implements OnInit {
@Input() inputData: Array = [];
@Input() splitterSettings: object;
@@ -46,8 +52,16 @@ export class PlanTimeBarComponent implements OnInit {
public renderTimeGantt: boolean = false;
public filterObj: any;
+ /**
+ * The constructor only injects the LanguageService and DataService
+ * @param languageService representation of the LanguageService
+ * @param dataService representation of the DataService
+ */
constructor(public languageService: LanguageService, public dataService: DataService) {}
+ /**
+ * The function ngOnInit initializes all parameters of the planTime gantt chart
+ */
ngOnInit(): void {
this.splitterSettings = this.inputData[0];
this.projectStartDate = this.inputData[1];
@@ -80,6 +94,11 @@ export class PlanTimeBarComponent implements OnInit {
};
}
+ /**
+ * The function fetchPlanTimes fetches the calculated Plantimes from the dataService, depending on applied filters.
+ * and triggers the (re)rendering of the planTime gantt chart
+ * @param filters current applied filters
+ */
public fetchPlanTimes(filter:any = null){
this.renderTimeGantt = false;
this.data = [];
@@ -111,6 +130,11 @@ export class PlanTimeBarComponent implements OnInit {
});
}
+ /**
+ * The queryTaskbarInfo catches the corresponding syncfusion framework event
+ * and manipulates it for a correct representation
+ * @param args args from the syncfusion framework
+ */
public queryTaskbarInfo(args: any) {
args.taskbarBgColor = "transparent";
args.taskbarBorderColor = "transparent";
@@ -126,6 +150,10 @@ export class PlanTimeBarComponent implements OnInit {
}
}
+ /**
+ * The changeLanguage executes a languageChange for the planTime gantt chart
+ * it is triggered by a language change from the NttGanttComponent
+ */
public changeLanguage(){
if(this.languageService.language == 'DE'){
this.resources = [{resourceId: 1, resourceName: 'Planzeit Summen pro Woche'}];
diff --git a/frontend/src/app/state-dialog/state-dialog.component.ts b/frontend/src/app/state-dialog/state-dialog.component.ts
index ce09086..f118a9d 100644
--- a/frontend/src/app/state-dialog/state-dialog.component.ts
+++ b/frontend/src/app/state-dialog/state-dialog.component.ts
@@ -11,8 +11,8 @@ import { LanguageService } from '../language.service';
})
/**
- * The StateDialogComponent enables the user to select an execute a status transition
- */
+* The StateDialogComponent enables the user to select an execute a status transition
+*/
export class StateDialogComponent implements OnInit {
public possibleStates: any[] = [
@@ -27,7 +27,6 @@ export class StateDialogComponent implements OnInit {
public labels: string[] = [];
private states : any[];
-
/**
* The constructor injects required Dependencies and sets default values for logic and ui
* @param dialogRef MatDialog Reference from Angular
@@ -43,7 +42,7 @@ export class StateDialogComponent implements OnInit {
this.possibleStates = [];
}
-/**
+ /**
* The function ngOnInit checks in which actual State the selected changes are, then it provides a list that contains which statuses can be switched to in the current state
*/
ngOnInit(): void {
@@ -73,15 +72,15 @@ export class StateDialogComponent implements OnInit {
}
/**
- * The function enableButton is triggered by the selction event of a possible state by the user it anebles the execution button
- */
+ * The function enableButton is triggered by the selction event of a possible state by the user it anebles the execution button
+ */
enableButton():void{
this.bdiasbled = false;
}
/**
- * The function updateState uses the dataService to execute a status transition on the backend. It sends the Changes to the backend one-by-one and calculates the percent-progress value for the progress bar.
- */
+ * The function updateState uses the dataService to execute a status transition on the backend. It sends the Changes to the backend one-by-one and calculates the percent-progress value for the progress bar.
+ */
updateState(): void{
let counter : number = 0;
if(this.selectedValue != -1){
@@ -121,6 +120,11 @@ export class StateDialogComponent implements OnInit {
}
}
}
+
+ /**
+ * The function findStateName returns a state name by the state number (uid), depending on the selected language
+ * @param stateNr uid of the state
+ */
findStateName(stateNr): String {
for (let state of this.states) {
if(stateNr == state.actualState){
diff --git a/frontend/src/tsconfig.doc.json b/frontend/src/tsconfig.doc.json
new file mode 100644
index 0000000..a2f03b8
--- /dev/null
+++ b/frontend/src/tsconfig.doc.json
@@ -0,0 +1,4 @@
+{
+ "include": ["src/**/*.ts"],
+ "exclude": ["src/test.ts", "src/**/*.spec.ts", "src/app/file-to-exclude.ts"]
+}