Recover survey changes

This commit is contained in:
Ramon Wenger 2023-02-02 14:10:21 +01:00
parent 300cb8681f
commit ad999391f7
1 changed files with 225 additions and 195 deletions

View File

@ -5,38 +5,39 @@
</h1> </h1>
<div id="survey" /> <div id="survey" />
<solution <solution :value="solution" v-if="showSolution" />
:value="solution"
v-if="showSolution"
/>
<div v-if="surveyComplete"> <div v-if="surveyComplete">
<a <a class="button button--primary" @click="reopen">Übung bearbeiten</a>
class="button button--primary"
@click="reopen"
>Übung bearbeiten</a>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import {css} from '@/survey.config'; import '@/styles/survey.modern.css';
import gql from 'graphql-tag'; import '@/styles/survey.reset.css';
import {Model} from 'survey-core'; import { css } from '@/survey.config';
// we are switching to the knockout version because the Vue version only works with Vue 2 (as of July 2022) import gql from 'graphql-tag';
import 'survey-knockout-ui'; import { Model, StylesManager } from 'survey-knockout';
// we are switching to the knockout version because the Vue version only works with Vue 2 (as of July 2022)
import SURVEY_QUERY from '@/graphql/gql/queries/surveyQuery.gql'; import SURVEY_QUERY from '@/graphql/gql/queries/surveyQuery.gql';
import UPDATE_ANSWER from '@/graphql/gql/mutations/updateAnswer.gql'; import UPDATE_ANSWER from '@/graphql/gql/mutations/updateAnswer.gql';
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';
import {defineAsyncComponent} from 'vue'; import { defineAsyncComponent } from 'vue';
const Solution = defineAsyncComponent(() => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/Solution')); const Solution = defineAsyncComponent(() =>
import(
/* webpackChunkName: "content-components"
*/ '@/components/content-blocks/Solution'
)
);
StylesManager.applyTheme('modern');
const MODULE_QUERY = gql` const MODULE_QUERY = gql`
query ModuleSolutions($slug: String) { query ModuleSolutions($slug: String) {
module(slug: $slug) { module(slug: $slug) {
solutionsEnabled solutionsEnabled
@ -45,7 +46,7 @@
} }
`; `;
export default { export default {
props: ['id'], props: ['id'],
components: { components: {
Solution, Solution,
@ -54,6 +55,8 @@
data() { data() {
return { return {
survey: this.initSurvey(), survey: this.initSurvey(),
currentPage: null,
surveyData: null,
title: '', title: '',
module: {}, module: {},
completed: false, completed: false,
@ -80,7 +83,7 @@
} }
if (answer.type === 'matrix' || answer.type === 'checkbox') { if (answer.type === 'matrix' || answer.type === 'checkbox') {
// wrap all the answers inside li tags and convert to a single string // 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(''); const answerText = answer.answer.map((a) => `<li class="solution-text__list-item">${a}</li>`).join('');
return ` return `
${previous} ${previous}
<h2 class="solution-text__heading">${answer.title}</h2> <h2 class="solution-text__heading">${answer.title}</h2>
@ -97,8 +100,8 @@
}; };
}, },
answers() { answers() {
return this.survey.currentPage && this.survey.currentPage.elements return this.currentPage && this.currentPage.elements
? this.survey.currentPage.elements.reduce(extractSurveySolutions, []) ? this.currentPage.elements.reduce(extractSurveySolutions, [])
: []; : [];
}, },
isTeacher() { isTeacher() {
@ -106,6 +109,14 @@
}, },
}, },
mounted() {
if (this.surveyData) {
this.loadSurveyFromServer(this.surveyData);
}
},
destroyed() {},
methods: { methods: {
initSurvey(data, answers) { initSurvey(data, answers) {
let survey = new Model(data); let survey = new Model(data);
@ -113,15 +124,19 @@
for (let k in answers) { for (let k in answers) {
flatAnswers[k] = answers[k].answer; flatAnswers[k] = answers[k].answer;
} }
this.$log.debug('flatAnswers', flatAnswers);
this.$log.debug('data', survey.data);
if (Object.keys(flatAnswers).length > 0) { if (Object.keys(flatAnswers).length > 0) {
// answers are not empty // answers are not empty
survey.data = flatAnswers; survey.data = flatAnswers;
} }
const saveSurvey = (sender, {exit}) => { this.currentPage = survey.currentPage;
this.$log.debug('saving survey', sender);
const updatePage = (sender, { oldCurrentPage, newCurrentPage }) => {
console.log(oldCurrentPage, newCurrentPage);
this.currentPage = newCurrentPage;
};
const saveSurvey = (sender, { exit }) => {
if (this.saveDisabled) { if (this.saveDisabled) {
return; return;
} }
@ -149,28 +164,38 @@
data: JSON.stringify(data), data: JSON.stringify(data),
}; };
this.$apollo.mutate({ this.$apollo
.mutate({
mutation: UPDATE_ANSWER, mutation: UPDATE_ANSWER,
variables: { variables: {
input: { input: {
answer, answer,
}, },
}, },
update: (store, {data: {updateAnswer: {answer}}}) => { update: (
store,
{
data: {
updateAnswer: { answer },
},
}
) => {
const query = SURVEY_QUERY; const query = SURVEY_QUERY;
const variables = {id: this.id}; const variables = { id: this.id };
const {survey} = store.readQuery({query, variables}); const { survey } = store.readQuery({ query, variables });
if (survey) { if (survey) {
const newData = { // data is already in use in parent scope const newData = {
// data is already in use in parent scope
survey: { survey: {
...survey, ...survey,
answer answer,
} },
}; };
store.writeQuery({query, variables, data: newData}); store.writeQuery({ query, variables, data: newData });
} }
}, },
}).then(() => { })
.then(() => {
if (exit) { if (exit) {
this.$router.go(-1); this.$router.go(-1);
} }
@ -180,16 +205,16 @@
survey.onComplete.add((sender, options) => { survey.onComplete.add((sender, options) => {
saveSurvey(sender, { saveSurvey(sender, {
...options, ...options,
exit: true exit: true,
}); });
}); });
survey.onCurrentPageChanged.add(saveSurvey); survey.onCurrentPageChanged.add(saveSurvey);
survey.onCurrentPageChanged.add(updatePage);
survey.css = css; survey.css = css;
survey.locale = 'de'; survey.locale = 'de';
survey.showProgressBar = 'bottom'; survey.showProgressBar = 'bottom';
survey.pageNextText = 'Speichern & Weiter'; survey.pageNextText = 'Speichern & Weiter';
this.$log.debug(survey.data);
survey.render('survey'); survey.render('survey');
return survey; return survey;
}, },
@ -201,6 +226,20 @@
this.survey.data = data; // reapply it this.survey.data = data; // reapply it
this.saveDisabled = false; this.saveDisabled = false;
}, },
loadSurveyFromServer(survey) {
let json = JSON.parse(survey.data);
json.showTitle = false;
json.showProgressBar = 'bottom';
let answer = {};
if (survey.answer && survey.answer.data) {
answer = JSON.parse(survey.answer.data);
}
if (!this.completed) {
this.survey = this.initSurvey(json, answer);
}
this.title = json.title;
},
}, },
apollo: { apollo: {
@ -212,25 +251,16 @@
}; };
}, },
manual: true, manual: true,
result({data, loading }) { result({ data, loading }) {
if (!loading) { if (!loading) {
let json = JSON.parse(data.survey.data); this.surveyData = data.survey;
json.showTitle = false; this.loadSurveyFromServer(data.survey);
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; const module = data.survey.module;
this.$apollo.addSmartQuery('module', { this.$apollo.addSmartQuery('module', {
query: MODULE_QUERY, query: MODULE_QUERY,
variables: { variables: {
slug: module.slug slug: module.slug,
}, },
}); });
} }
@ -238,13 +268,13 @@
}, },
me: meQuery, me: meQuery,
}, },
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import "~styles/helpers"; @import '~styles/helpers';
.survey-page { .survey-page {
max-width: 800px; max-width: 800px;
display: grid; display: grid;
grid-template-rows: auto 1fr; grid-template-rows: auto 1fr;
@ -258,5 +288,5 @@
@include meta-title; @include meta-title;
margin: 0; margin: 0;
} }
} }
</style> </style>