Skip to content
Permalink
Browse files

Merge branch 'develop' into feature/adaptInteractiveMetricsPersistenc…

…eToWpt
  • Loading branch information...
Johannes Weiß
Johannes Weiß committed Aug 14, 2019
2 parents 2c7fb27 + fedc45a commit 393f88cff41062a92809799f907826ad567eca72
Showing with 189 additions and 85 deletions.
  1. +5 −1 frontend/src/app/models/measurand.model.ts
  2. +1 −0 frontend/src/app/models/perfomance-aspect.model.ts
  3. +3 −0 frontend/src/app/modules/aggregation/models/get-barchart-command.model.ts
  4. +2 −1 frontend/src/app/modules/aggregation/services/barchart-data.service.ts
  5. +2 −0 frontend/src/app/modules/application-dashboard/components/page-metric/page-metric.component.spec.ts
  6. +1 −1 frontend/src/app/modules/application-dashboard/components/page/page.component.spec.ts
  7. +5 −5 ...d/src/app/modules/aspect-configuration/components/aspect-metrics/aspect-metrics.component.spec.ts
  8. +2 −2 .../app/modules/aspect-configuration/components/edit-aspect-metrics/edit-aspect-metrics.component.ts
  9. +7 −7 frontend/src/app/modules/aspect-configuration/services/aspect-configuration.service.spec.ts
  10. +1 −1 ...p/modules/result-selection/components/measurands/measurand-select/measurand-select.component.html
  11. +14 −7 ...app/modules/result-selection/components/measurands/measurand-select/measurand-select.component.ts
  12. +1 −1 frontend/src/app/modules/result-selection/components/measurands/measurands.component.html
  13. +7 −2 frontend/src/app/modules/result-selection/components/measurands/measurands.component.spec.ts
  14. +32 −18 frontend/src/app/modules/result-selection/components/measurands/measurands.component.ts
  15. +6 −6 frontend/src/app/modules/result-selection/components/submit/submit.component.html
  16. +8 −6 frontend/src/app/modules/result-selection/components/submit/submit.component.ts
  17. +1 −2 frontend/src/app/modules/result-selection/components/time-frame/time-frame.component.ts
  18. +4 −0 frontend/src/app/modules/result-selection/models/remaing-result-selection.model.ts
  19. +5 −3 frontend/src/app/modules/result-selection/services/result-selection.service.ts
  20. +2 −1 frontend/src/app/modules/result-selection/services/result-selection.store.ts
  21. +6 −1 frontend/src/app/services/performance-aspect.service.ts
  22. +1 −1 grails-app/assets/javascripts/charts/chartContextUtilities.js
  23. +5 −5 grails-app/controllers/de/iteratec/osm/result/AggregationController.groovy
  24. +3 −0 grails-app/i18n/messages.properties
  25. +3 −0 grails-app/i18n/messages_de.properties
  26. +42 −11 grails-app/services/de/iteratec/osm/barchart/BarchartAggregationService.groovy
  27. +5 −1 src/main/groovy/de/iteratec/osm/barchart/BarchartAggregation.groovy
  28. +5 −0 src/main/groovy/de/iteratec/osm/barchart/GetBarchartCommand.groovy
  29. +10 −2 src/test/groovy/de/iteratec/osm/result/AggregationControllerSpec.groovy
@@ -1,12 +1,16 @@
import {Loading} from "./loading.model";
import {PerformanceAspectType} from "./perfomance-aspect.model";

export interface SelectableMeasurand {
kind: "selectable-measurand"
name: string
id: string
isUserTiming?: boolean
}

export interface MeasurandGroup extends Loading {
export interface MeasurandGroup extends Loading {
name: string,
values: SelectableMeasurand[]
}

export type Measurand = PerformanceAspectType | SelectableMeasurand
@@ -15,6 +15,7 @@ export interface PerformanceAspect {
export type ExtendedPerformanceAspect = PerformanceAspect & BrowserInfoDto

export interface PerformanceAspectType {
kind: "performance-aspect-type"
name: string
icon: string
unit: string
@@ -6,6 +6,7 @@ export interface GetBarchartCommandDTO {
pages?: number[];
jobGroups?: number[];
measurands?: string[];
performanceAspectTypes?: string[];
browsers?: number[];
deviceTypes?: string[];
operatingSystems?: string[];
@@ -20,6 +21,7 @@ export class GetBarchartCommand implements GetBarchartCommandDTO {
pages?: number[];
jobGroups?: number[];
measurands?: string[];
performanceAspectTypes?: string[];
browsers?: number[];
deviceTypes?: string[];
operatingSystems?: string[];
@@ -33,6 +35,7 @@ export class GetBarchartCommand implements GetBarchartCommandDTO {
this.pages = dto.pages;
this.jobGroups = dto.jobGroups;
this.measurands = dto.measurands;
this.performanceAspectTypes = dto.performanceAspectTypes;
this.browsers = dto.browsers;
this.deviceTypes = dto.deviceTypes;
this.operatingSystems = dto.operatingSystems;
@@ -28,6 +28,7 @@ export class BarchartDataService {
pages: resultSelectionCommand.pageIds,
jobGroups: resultSelectionCommand.jobGroupIds,
measurands: remainingResultSelection.measurands,
performanceAspectTypes: remainingResultSelection.performanceAspectTypes,
browsers: resultSelectionCommand.browserIds,
deviceTypes: remainingResultSelection.deviceTypes,
operatingSystems: remainingResultSelection.operatingSystems,
@@ -44,7 +45,7 @@ export class BarchartDataService {
params = params.append(key, getBarchartCommand[key].toISOString());
} else if (key === 'aggregationValue') {
params = params.append(key, getBarchartCommand[key].toString());
} else {
} else if (getBarchartCommand[key].length > 0) {
params = params.append(key, JSON.stringify(getBarchartCommand[key]));
}
}
@@ -39,6 +39,7 @@ describe('PageMetricComponent', () => {
it("should show the value if the value is available", () => {
const value: string = "2.34";
const metric: PerformanceAspectType = {
kind: "performance-aspect-type",
name: 'PAGE_CONSTRUCTION_STARTED',
icon: 'fas fa-eye',
unit: 'ms'
@@ -57,6 +58,7 @@ describe('PageMetricComponent', () => {
it("should be 'n/a' and without unit if the value is empty", () => {
const value: string = "";
const metric: PerformanceAspectType = {
kind: "performance-aspect-type",
name: 'PAGE_CONSTRUCTION_STARTED',
icon: 'fas fa-eye',
unit: 'ms'
@@ -44,7 +44,7 @@ describe('PageComponent', () => {
fixture = TestBed.createComponent(PageComponent);
component = fixture.componentInstance;
component.application = new Application({name: 'app', id: 1});
component.aspectTypes = [{name: 'aspect-type-name', icon: 'aspect-type-icon', unit: 'aspect-type-unit'}];
component.aspectTypes = [{kind: "performance-aspect-type", name: 'aspect-type-name', icon: 'aspect-type-icon', unit: 'aspect-type-unit'}];
component.metricsForPage = {
pageId: 1,
pageName: 'page',
@@ -33,7 +33,7 @@ describe('AspectMetricsComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(AspectMetricsComponent);
component = fixture.componentInstance;
component.actualType = {name: 'aspect-type', icon: 'aspect-type-icon', unit: 'aspect-type-unit'};
component.actualType = {kind: "performance-aspect-type", name: 'aspect-type', icon: 'aspect-type-icon', unit: 'aspect-type-unit'};
fixture.detectChanges();
});

@@ -43,15 +43,15 @@ describe('AspectMetricsComponent', () => {
it('should filter aspects respective asp', inject(
[AspectMetricsComponent, AspectConfigurationService],
(component: AspectMetricsComponent, aspectConfService: AspectConfigurationService) => {
const type1: PerformanceAspectType = {name: 'PAGE_CONSTRUCTION_STARTED', icon: 'hourglass', unit: 'ms'};
const type2: PerformanceAspectType = {name: 'PAGE_SHOWS_USEFUL_CONTENT', icon: 'hourglass', unit: 'ms'};
const type1: PerformanceAspectType = {kind: "performance-aspect-type", name: 'PAGE_CONSTRUCTION_STARTED', icon: 'hourglass', unit: 'ms'};
const type2: PerformanceAspectType = {kind: "performance-aspect-type", name: 'PAGE_SHOWS_USEFUL_CONTENT', icon: 'hourglass', unit: 'ms'};
const aspectsOfTwoDifferentTypes: ExtendedPerformanceAspect[] = [
{
id: 1,
pageId: 1,
applicationId: 1,
browserId: 1,
measurand: {id: 'DOC_COMPLETE', name: 'Document complete'},
measurand: {kind: "selectable-measurand", id: 'DOC_COMPLETE', name: 'Document complete'},
performanceAspectType: type1,
persistent: true,
browserName: 'browser1',
@@ -63,7 +63,7 @@ describe('AspectMetricsComponent', () => {
pageId: 4,
applicationId: 1,
browserId: 1,
measurand: {id: 'DOC_COMPLETE', name: 'Document complete'},
measurand: {kind: "selectable-measurand", id: 'DOC_COMPLETE', name: 'Document complete'},
performanceAspectType: type2,
persistent: true,
browserName: 'browser1',
@@ -100,9 +100,9 @@ export class EditAspectMetricsComponent implements OnInit {
}

persistAspect() {
const perfAspectToCreateOrUpdate = {
const perfAspectToCreateOrUpdate: PerformanceAspect = {
...this.aspectMetricsCmp.getSelectedAspect(),
measurand: {name: this.metricFinderCmp.selectedMetric, id: this.metricFinderCmp.selectedMetric}
measurand: {kind: "selectable-measurand", name: this.metricFinderCmp.selectedMetric, id: this.metricFinderCmp.selectedMetric}
};
this.aspectConfService.createOrUpdatePerformanceAspect(perfAspectToCreateOrUpdate);
}
@@ -86,7 +86,7 @@ describe('AspectConfigurationService', () => {
expect(info2.browserName).toBe("browser2");
expect(info2.operatingSystem).toBe("Android");
expect(info2.deviceType).toEqual({name: 'Galaxy Tab A', icon: 'tablet'});
}))
}));

describe('aspect extension', () => {
it('should not provide any extended aspects if just BrowserInfos and no PerformanceAspects exist', inject(
@@ -109,8 +109,8 @@ describe('AspectConfigurationService', () => {
pageId: 1,
applicationId: 1,
browserId: 1,
measurand: {id: 'DOC_COMPLETE', name: 'Document complete'},
performanceAspectType: {name: 'PAGE_CONSTRUCTION_STARTED', icon: 'hourglass', unit: 'ms'},
measurand: {kind: "selectable-measurand", id: 'DOC_COMPLETE', name: 'Document complete'},
performanceAspectType: {kind: "performance-aspect-type", name: 'PAGE_CONSTRUCTION_STARTED', icon: 'hourglass', unit: 'ms'},
persistent: true,
}];
const extendedAspects: ExtendedPerformanceAspect[] = service.extendAspects(aspects, []);
@@ -127,17 +127,17 @@ describe('AspectConfigurationService', () => {
pageId: 1,
applicationId: 1,
browserId: idOfExtended,
measurand: {id: 'DOC_COMPLETE', name: 'Document complete'},
performanceAspectType: {name: 'PAGE_CONSTRUCTION_STARTED', icon: 'hourglass', unit: 'ms'},
measurand: {kind: "selectable-measurand", id: 'DOC_COMPLETE', name: 'Document complete'},
performanceAspectType: {kind: "performance-aspect-type", name: 'PAGE_CONSTRUCTION_STARTED', icon: 'hourglass', unit: 'ms'},
persistent: true,
},
{
id: 1,
pageId: 1,
applicationId: 1,
browserId: idOfNotExtended,
measurand: {id: 'DOC_COMPLETE', name: 'Document complete'},
performanceAspectType: {name: 'PAGE_CONSTRUCTION_STARTED', icon: 'hourglass', unit: 'ms'},
measurand: {kind: "selectable-measurand", id: 'DOC_COMPLETE', name: 'Document complete'},
performanceAspectType: {kind: "performance-aspect-type", name: 'PAGE_CONSTRUCTION_STARTED', icon: 'hourglass', unit: 'ms'},
persistent: true,
}
];
@@ -1,7 +1,7 @@
<select class="form-control" [(ngModel)]="selectedMeasurand" (ngModelChange)="selectMeasurand()"
[compareWith]="compareMeasurands">
<optgroup label="{{'frontend.de.iteratec.osm.performance-aspects' | translate}}">
<option *ngFor="let type of perfAspectTypes$ |async">
<option *ngFor="let type of perfAspectTypes$ |async" [ngValue]="type">
{{ 'frontend.de.iteratec.osm.performance-aspect.' + type.name + '.user-centric-question' | translate }}
</option>
</optgroup>
@@ -1,6 +1,6 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {BehaviorSubject, ReplaySubject} from "rxjs";
import {MeasurandGroup, SelectableMeasurand} from "../../../../../models/measurand.model";
import {BehaviorSubject} from "rxjs";
import {MeasurandGroup, Measurand} from "../../../../../models/measurand.model";
import {ResponseWithLoadingState} from "../../../../../models/response-with-loading-state.model";
import {PerformanceAspectType} from "../../../../../models/perfomance-aspect.model";

@@ -10,11 +10,11 @@ import {PerformanceAspectType} from "../../../../../models/perfomance-aspect.mod
styleUrls: ['./measurand-select.component.scss']
})
export class MeasurandSelectComponent implements OnInit {
@Input() selectedMeasurand: SelectableMeasurand;
@Output() onSelect: EventEmitter<SelectableMeasurand> = new EventEmitter<SelectableMeasurand>();
@Input() selectedMeasurand: Measurand;
@Output() onSelect: EventEmitter<Measurand> = new EventEmitter<Measurand>();

@Input() selectableMeasurandGroups: BehaviorSubject<ResponseWithLoadingState<BehaviorSubject<MeasurandGroup>[]>>;
@Input() perfAspectTypes$: ReplaySubject<PerformanceAspectType[]>;
@Input() perfAspectTypes$: BehaviorSubject<PerformanceAspectType[]>;


ngOnInit() {
@@ -24,7 +24,14 @@ export class MeasurandSelectComponent implements OnInit {
this.onSelect.emit(this.selectedMeasurand);
}

compareMeasurands(measurand1: SelectableMeasurand, measurand2: SelectableMeasurand): boolean {
return measurand1 && measurand2 ? measurand1.id == measurand2.id : measurand1 == measurand2;
compareMeasurands(measurand1: Measurand, measurand2: Measurand): boolean {
if (measurand1 && measurand2) {
if (measurand1.kind === "performance-aspect-type" && measurand2.kind === "performance-aspect-type") {
return measurand1.name == measurand2.name;
} if (measurand1.kind === "selectable-measurand" && measurand2.kind === "selectable-measurand") {
return measurand1.id == measurand2.id;
}
}
return measurand1 == measurand2;
}
}
@@ -7,7 +7,7 @@ <h2>{{ 'frontend.de.iteratec.osm.resultSelection.measurands.title' | translate }
{{ 'frontend.de.iteratec.osm.resultSelection.measurands.title' | translate }}:
</label>
<div class="col-sm-8" [ngClass]="{'col-sm-offset-3': !isFirst}">
<osm-measurand-select [selectedMeasurand]="metric" [selectableMeasurandGroups]="measurands$" [perfAspectTypes$]="aspectTypes$"
<osm-measurand-select [selectedMeasurand]="metric" [perfAspectTypes$]="aspectTypes$" [selectableMeasurandGroups]="measurands$"
(onSelect)="selectMeasurand(i, $event)"></osm-measurand-select>
</div>
<div class="col-sm-1 remove-measurand" *ngIf="!isFirst">
@@ -6,6 +6,7 @@ import {SharedMocksModule} from "../../../../testing/shared-mocks.module";
import {ResultSelectionStore} from "../../services/result-selection.store";
import {ResultSelectionService} from "../../services/result-selection.service";
import {By} from "@angular/platform-browser";
import {MeasurandGroup} from "../../../../models/measurand.model";

describe('MeasurandsComponent', () => {
let component: MeasurandsComponent;
@@ -30,24 +31,28 @@ describe('MeasurandsComponent', () => {
component = fixture.componentInstance;
component.multipleMeasurands = true;

resultSelectionStore.loadTimes$.next({
const loadTimes: MeasurandGroup = {
isLoading: false,
name: 'frontend.de.iteratec.isr.measurand.group.LOAD_TIMES',
values: [
{
kind: "selectable-measurand",
id: 'DOC_COMPLETE_TIME',
name: 'frontend.de.iteratec.isr.measurand.DOC_COMPLETE_TIME'
},
{
kind: "selectable-measurand",
id: 'DOM_TIME',
name: 'frontend.de.iteratec.isr.measurand.DOM_TIME'
},
{
kind: "selectable-measurand",
id: 'FIRST_BYTE',
name: 'frontend.de.iteratec.isr.measurand.FIRST_BYTE'
}
]
});
};
resultSelectionStore.loadTimes$.next(loadTimes);
fixture.detectChanges();
});

@@ -1,5 +1,5 @@
import {Component, Input, OnInit} from '@angular/core';
import {MeasurandGroup, SelectableMeasurand} from "../../../../models/measurand.model";
import {MeasurandGroup, SelectableMeasurand, Measurand} from "../../../../models/measurand.model";
import {BehaviorSubject, combineLatest, Observable} from "rxjs";
import {ResultSelectionStore} from "../../services/result-selection.store";
import {ResponseWithLoadingState} from "../../../../models/response-with-loading-state.model";
@@ -15,20 +15,21 @@ import {RemainingResultSelectionParameter} from "../../models/remaing-result-sel
styleUrls: ['./measurands.component.scss']
})
export class MeasurandsComponent implements OnInit {
aspectTypes$:BehaviorSubject<PerformanceAspectType[]> = new BehaviorSubject<PerformanceAspectType[]>([]);
measurands$: BehaviorSubject<ResponseWithLoadingState<BehaviorSubject<MeasurandGroup>[]>> = new BehaviorSubject({
isLoading: false,
data: []
});
aspectTypes$:BehaviorSubject<PerformanceAspectType[]> = new BehaviorSubject<PerformanceAspectType[]>([]);

selectedMeasurands: SelectableMeasurand[] = [];
defaultValue: SelectableMeasurand;
selectedMeasurands: (Measurand)[] = [];
defaultValue: PerformanceAspectType;
addingComparativeTimeFrameDisabled$: BehaviorSubject<boolean> = new BehaviorSubject(false);

@Input() multipleMeasurands = false;
@Input() addingMeasurandsDisabled$: BehaviorSubject<boolean> = new BehaviorSubject(false);

constructor(private resultSelectionStore: ResultSelectionStore, private performanceAspectService: PerformanceAspectService) {
this.aspectTypes$ = this.performanceAspectService.aspectTypes$;
this.measurands$.next({
...this.measurands$.getValue(),
data: [
@@ -50,36 +51,35 @@ export class MeasurandsComponent implements OnInit {
});
}

selectMeasurand(index: number, measurand: SelectableMeasurand) {
selectMeasurand(index: number, measurand: Measurand): void {
this.selectedMeasurands[index] = measurand;
this.setMeasurandIds();
this.setResultSelection();
}

addMeasurandField() {
addMeasurandField(): void {
this.selectedMeasurands.push(this.defaultValue);
this.setMeasurandIds();
this.setResultSelection();
this.addingComparativeTimeFrameDisabled$.next(true);
}

removeMeasurandField(index: number) {
removeMeasurandField(index: number): void {
this.selectedMeasurands.splice(index, 1);
this.setMeasurandIds();
this.setResultSelection();
if (this.selectedMeasurands.length == 1) {
this.addingComparativeTimeFrameDisabled$.next(false);
}
}

trackByFn(index: number, item: any) {
trackByFn(index: number, item: any): number {
return index;
}

setDefaultValue() {
this.resultSelectionStore.loadTimes$.subscribe((next: MeasurandGroup) => {
this.defaultValue = next.values[0];
setDefaultValue(): void {
this.performanceAspectService.aspectTypes$.subscribe((next: PerformanceAspectType[]) => {
this.defaultValue = next[0];
this.selectedMeasurands = [this.defaultValue];
this.aspectTypes$ = this.performanceAspectService.aspectTypes$;
if (this.defaultValue) {
this.setMeasurandIds();
this.setResultSelection();
}
});
}
@@ -97,9 +97,23 @@ export class MeasurandsComponent implements OnInit {
)
}

private setMeasurandIds() {
private setResultSelection(): void {
this.resultSelectionStore.setRemainingResultSelectionEnums(
this.selectedMeasurands.filter((item: Measurand) => {
if (item) {
return item.kind === "performance-aspect-type"
}
return false
}).map((performanceAspectType: PerformanceAspectType) => performanceAspectType.name),
RemainingResultSelectionParameter.PERFORMANCE_ASPECT_TYPES
);
this.resultSelectionStore.setRemainingResultSelectionEnums(
this.selectedMeasurands.map((measurand: SelectableMeasurand) => measurand.id),
this.selectedMeasurands.filter((item: Measurand) => {
if (item) {
return item.kind === "selectable-measurand"
}
return false;
}).map((measurand: SelectableMeasurand) => measurand.id),
RemainingResultSelectionParameter.MEASURANDS
);
}

0 comments on commit 393f88c

Please sign in to comment.
You can’t perform that action at this time.