Commit 38ca87c3 authored by Julien BOUYER's avatar Julien BOUYER
Browse files

UNOTOPLYS-237 feat : conditions d'affichage des items

parent 07eb417e
import { mixins } from 'vue-class-component';
import { Component } from 'vue-property-decorator';
import QuestionConditionMixin from '@/components/screen-item/conditions/question-condition.mixin';
@Component
export default class AnswerCondition extends mixins(QuestionConditionMixin) {
public answers: [];
constructor() {
super();
this.answers = [];
}
public selectQuestion(selection: any) {
this.selectedQuestion = selection;
this.answers = this.questions.filter(q => q === this.selectedQuestion).flatMap(q => q.value.choices);
}
}
import { mixins } from 'vue-class-component';
import { Component, Watch } from 'vue-property-decorator';
import { uuid } from 'vue-uuid';
import QuestionConditionMixin from '@/components/screen-item/conditions/question-condition.mixin';
@Component
export default class AnswersCondition extends mixins(QuestionConditionMixin) {
public answers: any[];
public values: string[];
public uuid: string;
public loadingCompleted: boolean;
constructor() {
super();
this.answers = [];
this.uuid = uuid.v1();
this.loadingCompleted = false;
}
public selectQuestion(selection: any) {
this.selectedQuestion = selection;
this.answers = this.questions.filter(q => q === this.selectedQuestion).flatMap(q => q.value.choices);
this.values = [];
}
public getChoiceId({ value }) {
return `${this.selectedQuestionReference}_${value}_${this.uuid}`;
}
public updateAnswer() {
if (this.selectedQuestion && this.values.length > 0) {
const validCondition = {
questionReference: this.selectedQuestion.id,
answers: this.values,
};
this.updateCondition(validCondition);
}
}
@Watch('questions')
public onQuestionsLoad() {
if (!this.loadingCompleted) {
const questionReference = this.condition.reference;
const selection = this.questions.filter(q => q.id === questionReference);
if (selection && selection.length === 1) {
this.selectQuestion(selection[0]);
}
}
}
@Watch('answers')
public onAnswersLoad() {
if (!this.loadingCompleted) {
if (this.condition.answers && this.condition.answers.length > 0) {
this.values = this.condition.answers;
}
this.loadingCompleted = true;
}
}
}
......@@ -2,27 +2,29 @@
<div>
<autocomplete
:items="questions"
:label="$t('screen.item.conditions.answer.question.label')"
:label="$t('screen.item.conditions.answers.question.label')"
:value="selectedQuestionLabel"
@selected="selectQuestion"
/>
<div v-if="answers && answers.length > 0">
<label class="block mb-2 font-bold">{{ $t('screen.item.conditions.answer.answers.label') }}</label>
<label class="block mb-2 font-bold">{{ $t('screen.item.conditions.answers.answers.label') }}</label>
<ul>
<li class="flex space-x-2 items-center" v-for="(answer, key) in answers" :key="key">
<input
class="checked:border-blue-700 checked:bg-blue-500 appearance-none border border-gray-400 w-5 h-5 rounded-sm ring-inset ring-4 ring-white cursor-pointer"
type="checkbox"
v-model="values"
:name="selectedQuestionReference"
:value="answer.value"
:id="`${answer.value}_${key}`"
:id="getChoiceId(answer)"
@change="updateAnswer"
/>
<label class="cursor-pointer" :for="`${answer.value}_${key}`">{{ answer.label }}</label>
<label class="cursor-pointer" :for="getChoiceId(answer)">{{ answer.label }}</label>
</li>
</ul>
<p class="mt-1 text-sm italic text-gray-500">{{ $t('screen.item.conditions.answer.answers.helpText') }}</p>
<p class="mt-1 text-sm italic text-gray-500">{{ $t('screen.item.conditions.answers.answers.helpText') }}</p>
</div>
</div>
</template>
<script lang="ts" src="./answer-condition.component.ts" />
<script lang="ts" src="./answers-condition.component.ts" />
......@@ -4,4 +4,4 @@ import { Component } from 'vue-property-decorator';
import AnswerConditionMixin from '@/components/screen-item/conditions/answer-condition.mixin';
@Component
export default class NotHasAnswerCondition extends mixins(AnswerConditionMixin) {}
export default class HasNoAnswerCondition extends mixins(AnswerConditionMixin) {}
......@@ -8,4 +8,4 @@
/>
</template>
<script lang="ts" src="./nothasanswer-condition.component.ts" />
<script lang="ts" src="./hasnoanswer-condition.component.ts" />
......@@ -21,7 +21,7 @@ export default class QuestionConditionMixin extends mixins(ConditionMixin) {
public get questions(): any {
return this.$store.getters.questions.map((item: any) => {
return {
id: item.reference,
id: `${item.screenReference}_${item.reference}`,
label: `${item.idxScreen}. ${item.question}`,
value: item,
};
......@@ -34,6 +34,7 @@ export default class QuestionConditionMixin extends mixins(ConditionMixin) {
}
return this.selectedQuestion.label;
}
public get selectedQuestionReference() {
if (!this.selectedQuestion) {
return null;
......
import Component from 'vue-class-component';
import { mixins } from 'vue-class-component';
import OperatorConditionMixin from '@/components/screen-item/conditions/operator-condition.mixin';
@Component
export default class ScoreCondition extends mixins(OperatorConditionMixin) {}
<template>
<div>
<autocomplete
:items="questions"
:label="$t('screen.item.conditions.score.question.label')"
:value="selectedQuestionLabel"
@selected="selectQuestion"
/>
<div class="px-6 mb-6">
<div class="grid grid-cols-10 gap-x-2 items-center">
<div class="col-span-3">
<div class="font-bold py-4" v-html="$t('screen.item.conditions.score.range.label')"></div>
</div>
<div class="col-span-1">
<select
class="focus:ring w-full px-6 py-4 text-lg transition bg-white border rounded-md outline-none appearance-none ring-inset"
:id="id"
:name="name"
:aria-describedby="helpTextId"
required="true"
v-model="leftOperatorValue"
>
<option v-for="(option, index) in leftOptions" :key="index" :value="option.value">{{ option.label }}</option>
</select>
</div>
<div class="col-span-2">
<input
class="w-full px-6 py-4 text-lg transition bg-white border rounded-md outline-none ring-inset focus:ring"
type="text"
value=""
aria-describedby="h0"
id="f0"
placeholder="1"
/>
</div>
<!-- TODO : afficher les 3 colonnes suivantes que si l'opérateur > ou ⩾ est sélectionné-->
<div class="col-span-1 justify-self-end flex items-center">
<div class="font-bold p-4">et</div>
</div>
<div class="col-span-1">
<select
class="focus:ring w-full px-6 py-4 text-lg transition bg-white border rounded-md outline-none appearance-none ring-inset"
:id="id"
:name="name"
:aria-describedby="helpTextId"
required="true"
v-model="rightOperatorValue"
>
<option v-for="(option, index) in rightOptions" :key="index" :value="option.value">{{ option.label }}</option>
</select>
</div>
<div class="col-span-2">
<input
class="w-full px-6 py-4 text-lg transition bg-white border rounded-md outline-none ring-inset focus:ring"
type="text"
value=""
aria-describedby="h0"
id="f0"
placeholder="2"
/>
</div>
</div>
<p class="mt-1 text-sm italic text-gray-500" id="hundefined">
{{ $t('screen.item.conditions.score.range.helpText') }}
</p>
</div>
</div>
</template>
<script lang="ts" src="./score-condition.component.ts" />
import Vue from 'vue';
import Component from 'vue-class-component';
import { Inject, Prop } from 'vue-property-decorator';
import { Prop } from 'vue-property-decorator';
import { ConditionTypes } from '@/services/conditions.service';
......@@ -9,10 +9,9 @@ import Icon from '@/components/icon/icon.vue';
import OaTextarea from '@/components/forms/textarea/oa-textarea.vue';
import AdvancedCondition from '@/components/screen-item/conditions/advanced-condition/advanced-condition.vue';
import AnswerCondition from '@/components/screen-item/conditions/answer-condition/answer-condition.vue';
import AnswersCondition from '@/components/screen-item/conditions/answers-condition/answers-condition.vue';
import HasAnswerCondition from '@/components/screen-item/conditions/hasanswer-condition/hasanswer-condition.vue';
import NotHasAnswerCondition from '@/components/screen-item/conditions/nothasanswer-condition/nothasanswer-condition.vue';
import ScoreCondition from '@/components/screen-item/conditions/score-condition/score-condition.vue';
import HasNoAnswerCondition from '@/components/screen-item/conditions/hasnoanswer-condition/hasnoanswer-condition.vue';
import ValueCondition from '@/components/screen-item/conditions/value-condition/value-condition.vue';
@Component({
......@@ -55,17 +54,15 @@ export default class ItemConditions extends Vue {
}
public defineConditionComponent(type: string) {
if (type === 'advanced') {
if (type === ConditionTypes.ADVANCED) {
return AdvancedCondition;
} else if (type === 'answer') {
return AnswerCondition;
} else if (type === 'hasAnswer') {
} else if (type === ConditionTypes.ANSWERS) {
return AnswersCondition;
} else if (type === ConditionTypes.HAS_ANSWER) {
return HasAnswerCondition;
} else if (type === 'notHasAnswer') {
return NotHasAnswerCondition;
} else if (type === 'score') {
return ScoreCondition;
} else if (type === 'value') {
} else if (type === ConditionTypes.HAS_NO_ANSWER) {
return HasNoAnswerCondition;
} else if (type === ConditionTypes.VALUE) {
return ValueCondition;
} else {
return null;
......
......@@ -3,8 +3,8 @@ import axios from 'axios';
export const ConditionTypes = {
HAS_ANSWER: 'hasAnswer',
ANSWER: 'answer',
SCORE: 'score',
HAS_NO_ANSWER: 'hasNoAnswer',
ANSWERS: 'answers',
VALUE: 'value',
ADVANCED: 'advanced',
};
......@@ -23,22 +23,43 @@ export default class ConditionsService {
});
}
public loadScreensQuestions(screens) {
public loadScreensQuestions(screens: any) {
return screens.flatMap((screen: IScreen) => {
const itemsList = [];
screen.itemsList.forEach(item => {
Object.assign(item, { idxScreen: screen.index });
Object.assign(item, { idxScreen: screen.index, screenReference: screen.reference });
itemsList.push(item);
});
return itemsList;
});
}
public parseItemConditions(item) {
const displayConditions = item.displayConditionSimple.displayConditions;
if (displayConditions.length === 0) {
public parseItemConditions(item: any) {
if (item.displayConditionSimple.displayConditions.length === 0) {
return [];
}
const displayConditions = [];
try {
item.displayConditionSimple.displayConditions.forEach((condition: any) => {
// TODO tester les types de conditions restants
// à voir si ceux qui sont à push dans l'Array directement
// et ceux qui sont à traiter à part, comme c'est fait pour l'advanced condition
if (condition.type === ConditionTypes.ANSWERS && condition.reference) {
displayConditions.push(condition);
} else {
// Si une des conditions n'est pas gérée, on sort de la boucle en erreur
throw 'Unknown condition : ' + JSON.stringify(condition);
}
});
} catch (e) {
console.error(e);
// Lorsqu'on est sorti en erreur, on retourne une condition en mode avancée
return this.defineAvancedCondition(item);
}
return displayConditions;
}
private defineAvancedCondition(item) {
return [
{
type: ConditionTypes.ADVANCED,
......
......@@ -66,18 +66,16 @@
"title": {
"undefined": "Condition {{ index }}",
"advanced": "Condition {{ index }} : Validation d'une condition complexe",
"answer": "Condition {{ index }} : Contrôle des réponses à une question",
"answers": "Condition {{ index }} : Contrôle des réponses à une question",
"hasAnswer": "Condition {{ index }} : Contrôle si question répondue",
"notHasAnswer": "Condition {{ index }} : Contrôle si question non répondue",
"score": "Condition {{ index }} : Contrôle du score associé à une question",
"value": "Condition {{ index }} : Contrôle de la valeur d'une variable"
},
"types": {
"advanced": "Autre cas (saisie manuelle)",
"answer": "Réponses sélectionnées",
"answers": "Réponses sélectionnées",
"hasAnswer": "Question répondue",
"notHasAnswer": "Question non répondue",
"score": "Score d’une question",
"value": "Valeur d’une variable"
},
"advanced": {
......@@ -86,7 +84,7 @@
"helpText": "L'élément s'affiche si la condition ci-dessus est vérifiée (cf. documentation pour la syntaxe Spring Expression Language)"
}
},
"answer": {
"answers": {
"question": {
"label": "Sélectionnez la question à contrôler",
"helpText": "L'élément ne s'affiche que si la question a reçu une réponse de l’utilisateur"
......@@ -96,15 +94,6 @@
"helpText": "L'élément ne s'affiche que si l'une des réponses cochées ci-dessus est sélectionnée par l’utilisateur"
}
},
"score": {
"question": {
"label": "Sélectionnez la question à contrôler et définissez les seuils à partir desquels l'élément doit s'afficher"
},
"range": {
"label": "Le score de la question est&mldr;",
"helpText": "L'élément ne s'affiche que si le score de la réponse sélectionnée par l’utilisateur correspond au test ci-dessus"
}
},
"value": {
"question": {
"label": "Sélectionnez la variable à contrôler et définissez les seuils à partir desquels l'élément doit s'afficher"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment