From 1ada7e321e7cc148ea2a0cc3de5374f0b6c21ad6 Mon Sep 17 00:00:00 2001 From: lakhoune Date: Sat, 11 Jun 2022 15:46:55 +0200 Subject: [PATCH] close #96 --- .../limesurvey-measure.component.html | 41 ++++++++- .../limesurvey-measure.component.scss | 11 +++ .../limesurvey-measure.component.ts | 92 +++++++++++++++++-- .../pick-survey-dialog.component.html | 3 +- .../pick-survey-dialog.component.ts | 4 +- .../surveys/surveys.component.ts | 2 +- src/app/services/store/store.selectors.ts | 12 +++ .../chart-visualization.component.ts | 2 +- 8 files changed, 154 insertions(+), 13 deletions(-) diff --git a/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.html b/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.html index 80e335bc..e1099125 100644 --- a/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.html +++ b/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.html @@ -1 +1,40 @@ -

limesurvey-measure works!

+
+ +
+ + + + + + +

+ {{ measure.name }} +

+
+ + + + +
+
diff --git a/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.scss b/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.scss index e69de29b..f4b93982 100644 --- a/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.scss +++ b/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.scss @@ -0,0 +1,11 @@ +#measure-header { + display: flex; + flex-direction: row; + vertical-align: middle; + + #edit-button, + #delete-button { + margin-top: 5px; + } + +} \ No newline at end of file diff --git a/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.ts b/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.ts index 26a43151..a541e6bb 100644 --- a/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.ts +++ b/src/app/components/success-modeling/success-model/success-dimension/success-factor/limesurvey-measure/limesurvey-measure.component.ts @@ -2,26 +2,38 @@ import { Component, Input, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { TranslateService } from '@ngx-translate/core'; +import { ChartType } from 'angular-google-charts'; import { combineLatest, filter, + firstValueFrom, map, Observable, + Subscription, switchMap, withLatestFrom, } from 'rxjs'; import { + IMeasure, LimeSurveyMeasure, Measure, + SQLQuery, } from 'src/app/models/measure.model'; +import { ServiceInformation } from 'src/app/models/service.model'; import { VisualizationData, Visualization, + ChartVisualization, } from 'src/app/models/visualization.model'; +import { removeMeasureFromModel } from 'src/app/services/store/store.actions'; import { MEASURE, RESPONSES_FOR_LIMESURVEY, + RESPONSES_FOR_LIMESURVEY_QUESTION, + SELECTED_SERVICE, + USER_HAS_EDIT_RIGHTS, } from 'src/app/services/store/store.selectors'; +import { ConfirmationDialogComponent } from 'src/app/shared/dialogs/confirmation-dialog/confirmation-dialog.component'; @Component({ selector: 'app-limesurvey-measure', @@ -34,9 +46,16 @@ export class LimesurveyMeasureComponent implements OnInit { @Input() factorName = ''; @Input() preview = false; - data$: Observable; + data$: Observable; visualzation$: Observable; measure$: Observable; + service$: Observable = + this.ngrxStore.select(SELECTED_SERVICE); + subscriptions$: Subscription[] = []; + canEdit$ = this.ngrxStore.select(USER_HAS_EDIT_RIGHTS); + queries$: Observable; + description$: Observable; + constructor( private translate: TranslateService, private dialog: MatDialog, @@ -51,25 +70,82 @@ export class LimesurveyMeasureComponent implements OnInit { map((measure) => measure as LimeSurveyMeasure), ); - const responses$ = this.measure$.pipe( + const responseData$ = this.measure$.pipe( switchMap((m) => { if (!m.sid) { console.error('No survey id found for measure', m); } return this.ngrxStore.select( - RESPONSES_FOR_LIMESURVEY({ sid: m.sid }), + RESPONSES_FOR_LIMESURVEY_QUESTION({ + sid: m.sid, + statement: m.title, + }), ); }), ); + this.data$ = responseData$.pipe( + map(({ responses }) => { + const table = []; + const columnLabels = ['answer', 'count']; + const firstKey = Object.keys(responses)[0]; + const columnTypes = [ + typeof firstKey, + typeof responses[firstKey], + ]; + table.push(columnLabels); + table.push(columnTypes); + const data = Object.entries(responses) + .map(([key, value]) => + !!key ? [key, value] : ['undetermined', value], + ) + .sort((row_a, row_b) => { + const a = row_a[0]; + const b = row_b[0]; + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + }); + return { + data: table.concat(data), + fetchDate: new Date().toISOString(), + }; + }), + ); - this.data$ = combineLatest([this.measure$, responses$]).pipe( - map(([measure, responses]) => { - let data = []; + this.visualzation$ = responseData$.pipe( + map(({ type }) => { + switch (type) { + case '5': + return new ChartVisualization(ChartType.BarChart); + case 'L': + return new ChartVisualization(ChartType.PieChart); + case 'Y': + return new ChartVisualization(ChartType.PieChart); + } + return null; }), ); + } - this.data$.subscribe((data) => { - console.log(data); + async onDeleteClicked(measure, $event: MouseEvent): Promise { + const message = this.translate.instant( + 'success-factor.remove-measure-prompt', + ); + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + minWidth: 300, + data: message, }); + + const result = await firstValueFrom(dialogRef.afterClosed()); + if (result) { + this.ngrxStore.dispatch( + removeMeasureFromModel({ name: measure.name }), + ); + } + $event.stopPropagation(); } } diff --git a/src/app/components/success-modeling/success-model/surveys/pick-survey-dialog/pick-survey-dialog.component.html b/src/app/components/success-modeling/success-model/surveys/pick-survey-dialog/pick-survey-dialog.component.html index 504ff173..0954cd55 100644 --- a/src/app/components/success-modeling/success-model/surveys/pick-survey-dialog/pick-survey-dialog.component.html +++ b/src/app/components/success-modeling/success-model/surveys/pick-survey-dialog/pick-survey-dialog.component.html @@ -55,6 +55,7 @@ {{ @@ -64,7 +65,7 @@ >
{{ 'success-modeling.questionnaires.pick-questionnaire-dialog.assign-measures' diff --git a/src/app/components/success-modeling/success-model/surveys/pick-survey-dialog/pick-survey-dialog.component.ts b/src/app/components/success-modeling/success-model/surveys/pick-survey-dialog/pick-survey-dialog.component.ts index ff026a3c..cc3eb2ea 100644 --- a/src/app/components/success-modeling/success-model/surveys/pick-survey-dialog/pick-survey-dialog.component.ts +++ b/src/app/components/success-modeling/success-model/surveys/pick-survey-dialog/pick-survey-dialog.component.ts @@ -30,6 +30,7 @@ import { SELECTED_SERVICE, USER, QUESTIONNAIRES, + EXPERT_MODE, } from 'src/app/services/store/store.selectors'; import { environment } from 'src/environments/environment'; import { PickQuestionnaireDialogComponent } from '../pick-questionnaire-dialog/pick-questionnaire-dialog.component'; @@ -50,6 +51,7 @@ export class PickSurveyDialogComponent implements OnInit { @ViewChild('inputRef', { static: true }) inputRef: ElementRef; + expertMode$ = this.ngrxStore.select(EXPERT_MODE); addMeasures = true; assignMeasures = true; mobsosSurveysUrl = environment.mobsosSurveysUrl; @@ -251,7 +253,7 @@ export class PickSurveyDialogComponent implements OnInit { } isMobSOSSurvey(selectedSurvey: ISurvey) { - return selectedSurvey instanceof Survey; + return !!selectedSurvey && 'resource-label' in selectedSurvey; } } diff --git a/src/app/components/success-modeling/success-model/surveys/surveys.component.ts b/src/app/components/success-modeling/success-model/surveys/surveys.component.ts index 39b01917..00b7829e 100644 --- a/src/app/components/success-modeling/success-model/surveys/surveys.component.ts +++ b/src/app/components/success-modeling/success-model/surveys/surveys.component.ts @@ -193,7 +193,7 @@ export class SurveyComponent implements OnInit { ); this.ngrxStore.dispatch( addCatalogToWorkspace({ - xml: catalog.toXml().outerHTML, + xml: MeasureCatalog.fromJSON(catalog).toXml().outerHTML, }), ); } diff --git a/src/app/services/store/store.selectors.ts b/src/app/services/store/store.selectors.ts index 5f0d1c9d..0c7af517 100644 --- a/src/app/services/store/store.selectors.ts +++ b/src/app/services/store/store.selectors.ts @@ -126,6 +126,18 @@ export const RESPONSES_FOR_LIMESURVEY = (props: { sid: string }) => res ? res[props.sid] : undefined, ); +export const RESPONSES_FOR_LIMESURVEY_QUESTION = (props: { + sid: string; + statement: string; +}) => + createSelector( + RESPONSES_FOR_LIMESURVEY({ sid: props.sid }), + (res) => + res + ? res.find((q) => q.question === props.statement) + : undefined, + ); + export const QUESTIONS_FROM_LIMESURVEY = (props: { sid: string }) => createSelector(LIMESURVEY_RESPONSES, (res) => res && props.sid in res diff --git a/src/app/shared/visualizations/chart-visualization/chart-visualization.component.ts b/src/app/shared/visualizations/chart-visualization/chart-visualization.component.ts index 88f9f002..31188a42 100644 --- a/src/app/shared/visualizations/chart-visualization/chart-visualization.component.ts +++ b/src/app/shared/visualizations/chart-visualization/chart-visualization.component.ts @@ -100,7 +100,7 @@ export class ChartVisualizerComponent implements OnInit, OnDestroy { ); this.subscriptions$.push(sub); - this.query$ = this.queries$.pipe( + this.query$ = this.queries$?.pipe( filter((queries) => !!queries), map((queries) => queries[0].sql), );