Format matrix solutions in a more readable way

This commit is contained in:
Ramon Wenger 2020-10-07 11:22:15 +02:00
parent 4193af9ef6
commit e94573cd09
6 changed files with 186 additions and 168 deletions

View File

@ -50,7 +50,7 @@
import CurrentClass from '@/components/school-class/CurrentClass'; import CurrentClass from '@/components/school-class/CurrentClass';
import AddIcon from '@/components/icons/AddIcon'; import AddIcon from '@/components/icons/AddIcon';
import updateSelectedClassMixin from '@/mixins/updateSelectedClass'; import updateSelectedClassMixin from '@/mixins/update-selected-class';
import sidebarMixin from '@/mixins/sidebar'; import sidebarMixin from '@/mixins/sidebar';
import meMixin from '@/mixins/me'; import meMixin from '@/mixins/me';

View File

@ -11,11 +11,9 @@ const extractAnswerFromQuestion = (previous, question) => {
return text; return text;
}); // get the keys as they appear in the question, without punctuation at the end }); // get the keys as they appear in the question, without punctuation at the end
const answers = keys.map(key => `${key}: ${correctAnswer[key]}`); answer = keys.map(key => `${key}: ${correctAnswer[key]}`); // return an array, it gets converted to a string further up
answer = answers.join('\n');
} }
return [...previous, {title: question.title, answer}]; return [...previous, {title: question.title, answer, type: question.getType()}];
}; };
export const extractSurveySolutions = (prev, element) => { export const extractSurveySolutions = (prev, element) => {

View File

@ -18,7 +18,7 @@
<script> <script>
import OLD_CLASSES_QUERY from '@/graphql/gql/oldClasses.gql'; import OLD_CLASSES_QUERY from '@/graphql/gql/oldClasses.gql';
import updateSelectedClassMixin from '@/mixins/updateSelectedClass'; import updateSelectedClassMixin from '@/mixins/update-selected-class';
export default { export default {
mixins: [updateSelectedClassMixin], mixins: [updateSelectedClassMixin],

View File

@ -15,196 +15,206 @@
</template> </template>
<script> <script>
import * as SurveyVue from 'survey-vue'; import * as SurveyVue from 'survey-vue';
import {css} from '@/survey.config'; import {css} from '@/survey.config';
import SURVEY_QUERY from '@/graphql/gql/surveyQuery.gql'; import SURVEY_QUERY from '@/graphql/gql/surveyQuery.gql';
import MODULE_QUERY from '@/graphql/gql/moduleByIdQuery.gql'; import MODULE_QUERY from '@/graphql/gql/moduleByIdQuery.gql';
import UPDATE_ANSWER from '@/graphql/gql/mutations/updateAnswer.gql'; import UPDATE_ANSWER from '@/graphql/gql/mutations/updateAnswer.gql';
import Solution from '@/components/content-blocks/Solution'; import Solution from '@/components/content-blocks/Solution';
import {extractSurveySolutions} from '@/helpers/survey-solutions'; import {extractSurveySolutions} from '@/helpers/survey-solutions';
import {isTeacher} from '@/helpers/is-teacher'; import {isTeacher} from '@/helpers/is-teacher';
import {meQuery} from '@/graphql/queries'; import {meQuery} from '@/graphql/queries';
const Survey = SurveyVue.Survey; const Survey = SurveyVue.Survey;
export default { export default {
props: ['id'], props: ['id'],
components: { components: {
Solution, Solution,
Survey Survey
},
data() {
return {
survey: this.initSurvey(),
title: '',
module: {},
completed: false,
me: {
permissions: []
},
};
},
computed: {
surveyComplete() {
return this.survey && this.survey.isCompleted;
}, },
showSolution() {
data() { return (module.solutionsEnabled || isTeacher) && !this.survey.isCompleted;
},
solution() {
// todo: should this be done inside of Solution.vue?
return { return {
survey: this.initSurvey(), text: this.answers.reduce((previous, answer) => {
title: '', if (!answer.answer) {
module: {}, return previous;
completed: false, }
me: { if (answer.type === 'matrix') {
permissions: [] // wrap all the answers inside li tags and convert to a single string
}, const answerText = answer.answer.map(a => `<li class="solution-text__list-item">${a}</li>`).join('');
}; return `
}, ${previous}
<h2 class="solution-text__heading">${answer.title}</h2>
computed: { <ul class="solution-text__answer solution-text__list">${answerText}</ul>
surveyComplete() { `;
return this.survey && this.survey.isCompleted; } else {
},
showSolution() {
return (module.solutionsEnabled || isTeacher) && !this.survey.isCompleted;
},
solution() {
return {
text: this.answers.reduce((previous, answer) => {
if (!answer.answer) {
return previous;
}
const answerText = answer.answer.replace(/\n/g, '<br>'); // replace all newlines with line breaks
return ` return `
${previous} ${previous}
<h2 class="solution-text__heading">${answer.title}</h2> <h2 class="solution-text__heading">${answer.title}</h2>
<p class="solution-text__answer">${answerText}</p> <p class="solution-text__answer">${answer.answer}</p>
`; `;
}, '') }
}; }, '')
}, };
answers() {
return this.survey.currentPage && this.survey.currentPage.elements
? this.survey.currentPage.elements.reduce(extractSurveySolutions, [])
: [];
},
isTeacher() {
return isTeacher(this);
}
}, },
answers() {
return this.survey.currentPage && this.survey.currentPage.elements
? this.survey.currentPage.elements.reduce(extractSurveySolutions, [])
: [];
},
isTeacher() {
return isTeacher(this);
}
},
methods: { methods: {
initSurvey(data, answers) { initSurvey(data, answers) {
let survey = new SurveyVue.Model(data); let survey = new SurveyVue.Model(data);
const flatAnswers = {}; const flatAnswers = {};
for (let k in answers) { for (let k in answers) {
flatAnswers[k] = answers[k].answer; flatAnswers[k] = answers[k].answer;
}
survey.data = flatAnswers;
const saveSurvey = (sender, options) => {
// sender.clear(false);
//
// sender.mode = 'display';
this.completed = true;
const data = {};
for (let k in survey.data) {
if (survey.data.hasOwnProperty(k)) {
let question = sender.getQuestionByName(k);
data[k] = {
answer: survey.data[k],
correct: question && question.correctAnswer ? question.correctAnswer : ''
};
}
} }
survey.data = flatAnswers;
const saveSurvey = (sender, options) => { this.$apollo.mutate({
// sender.clear(false); mutation: UPDATE_ANSWER,
// variables: {
// sender.mode = 'display'; input: {
answer: {
this.completed = true; surveyId: this.id,
data: JSON.stringify(data)
const data = {}; }
}
for (let k in survey.data) { },
if (survey.data.hasOwnProperty(k)) { // fixme: make the update work instead of refetching
let question = sender.getQuestionByName(k); update: (store, {data: {updateAnswer: {answer}}}) => {
data[k] = { const query = SURVEY_QUERY;
answer: survey.data[k], const variables = {id: this.id};
correct: question && question.correctAnswer ? question.correctAnswer : '' const queryData = store.readQuery({query, variables});
}; if (queryData.survey) {
queryData.survey.answer = answer;
store.writeQuery({query, variables, data: queryData});
} }
} }
});
};
this.$apollo.mutate({ survey.onComplete.add(saveSurvey);
mutation: UPDATE_ANSWER, survey.onCurrentPageChanged.add(saveSurvey);
survey.css = css;
survey.locale = 'de';
survey.showProgressBar = 'bottom';
survey.pageNextText = 'Speichern & Weiter';
return survey;
},
reopen() {
this.completed = false;
let data = this.survey.data; // save the data
this.survey.clear();
this.survey.data = data; // reapply it
}
},
apollo: {
survey: {
query: SURVEY_QUERY,
variables() {
return {
id: this.id
};
},
manual: true,
result({data, loading, networkStatus}) {
if (!loading) {
let json = JSON.parse(data.survey.data);
json.showTitle = false;
let answer = {};
if (data.survey.answer && data.survey.answer.data) {
answer = JSON.parse(data.survey.answer.data);
}
if (!this.completed) {
this.survey = this.initSurvey(json, answer);
}
this.title = json.title;
const module = data.survey.module;
this.$apollo.addSmartQuery('module', {
query: MODULE_QUERY,
variables: { variables: {
input: { id: module.id
answer: {
surveyId: this.id,
data: JSON.stringify(data)
}
}
},
// fixme: make the update work instead of refetching
update: (store, {data: {updateAnswer: {answer}}}) => {
const query = SURVEY_QUERY;
const variables = {id: this.id};
const queryData = store.readQuery({query, variables});
if (queryData.survey) {
queryData.survey.answer = answer;
store.writeQuery({query, variables, data: queryData});
}
} }
}); });
}; }
survey.onComplete.add(saveSurvey);
survey.onCurrentPageChanged.add(saveSurvey);
survey.css = css;
survey.locale = 'de';
survey.showProgressBar = 'bottom';
survey.pageNextText = 'Speichern & Weiter';
return survey;
}, },
reopen() {
this.completed = false;
let data = this.survey.data; // save the data
this.survey.clear();
this.survey.data = data; // reapply it
}
}, },
me: meQuery
apollo: { }
survey: { };
query: SURVEY_QUERY,
variables() {
return {
id: this.id
};
},
manual: true,
result({data, loading, networkStatus}) {
if (!loading) {
let json = JSON.parse(data.survey.data);
json.showTitle = false;
let answer = {};
if (data.survey.answer && data.survey.answer.data) {
answer = JSON.parse(data.survey.answer.data);
}
if (!this.completed) {
this.survey = this.initSurvey(json, answer);
}
this.title = json.title;
const module = data.survey.module;
this.$apollo.addSmartQuery('module', {
query: MODULE_QUERY,
variables: {
id: module.id
}
});
}
},
},
me: meQuery
}
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import "@/styles/_variables.scss"; @import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss"; @import "@/styles/_mixins.scss";
.survey-page { .survey-page {
max-width: 800px; max-width: 800px;
display: grid; display: grid;
grid-template-rows: auto 1fr; grid-template-rows: auto 1fr;
grid-auto-rows: auto; grid-auto-rows: auto;
grid-row-gap: $large-spacing; grid-row-gap: $large-spacing;
justify-self: center; justify-self: center;
padding: 100px 0; padding: 100px 0;
width: 100%; width: 100%;
&__title { &__title {
@include meta-title; @include meta-title;
margin: 0; margin: 0;
}
} }
}
</style> </style>

View File

@ -8,4 +8,14 @@
@include regular-text; @include regular-text;
margin-bottom: $medium-spacing; margin-bottom: $medium-spacing;
} }
&__list {
list-style: disc;
padding-left: $medium-spacing;
}
&__list-item {
@include inline-title;
margin-bottom: $medium-spacing;
}
} }