220 lines
5.8 KiB
Vue
220 lines
5.8 KiB
Vue
<template>
|
|
<div class="assignment">
|
|
<h3 class="assignment__title">{{assignment.title}}</h3>
|
|
<p class="assignment__assignment-text">
|
|
{{assignment.assignment}}
|
|
</p>
|
|
|
|
<final-submission :submission="assignment.submission" v-if="final"></final-submission>
|
|
|
|
<div class="assignment__submission" v-if="!final">
|
|
<div class="assignment__toggle-input-container">
|
|
<button
|
|
class="assignment__toggle-input"
|
|
@click="inputType = 'text'"
|
|
:class="{'assignment__toggle-input--active': inputType === 'text'}"
|
|
>Text
|
|
erfassen
|
|
</button>
|
|
<button
|
|
class="assignment__toggle-input"
|
|
@click="inputType = 'file'"
|
|
:class="{'assignment__toggle-input--active': inputType === 'file'}"
|
|
>Dokument hochladen
|
|
</button>
|
|
</div>
|
|
|
|
<div class="assignment__inputs">
|
|
<submission-form
|
|
@input="saveInput"
|
|
:submission="submission"
|
|
:saved="!unsaved"
|
|
v-if="inputType === 'text'"
|
|
></submission-form>
|
|
<div
|
|
class="assignment__file-upload"
|
|
v-if="inputType === 'file'">
|
|
<div v-if="assignment.submission.document">
|
|
<document-block
|
|
:value="{url: assignment.submission.document}"
|
|
show-trash-icon
|
|
v-on:trash="changeDocumentUrl('')"
|
|
></document-block>
|
|
</div>
|
|
<document-form
|
|
v-if="!assignment.submission.document"
|
|
:value="{url: ''}"
|
|
v-on:link-change-url="changeDocumentUrl"
|
|
></document-form>
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
class="assignment__submit button button--primary button--white-bg"
|
|
@click="turnIn"
|
|
>Ergebnis mit Lehrperson teilen
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import ASSIGNMENT_QUERY from '@/graphql/gql/assignmentQuery.gql';
|
|
import UPDATE_ASSIGNMENT_MUTATION from '@/graphql/gql/mutations/updateAssignmentMutation.gql';
|
|
import UPDATE_ASSIGNMENT_MUTATION_WITH_SUCCESS from '@/graphql/gql/mutations/updateAssignmentMutationWithSuccess.gql';
|
|
import debounce from 'lodash/debounce';
|
|
import cloneDeep from 'lodash/cloneDeep'
|
|
|
|
import FinalSubmission from '@/components/content-blocks/assignment/FinalSubmission';
|
|
import SubmissionForm from '@/components/content-blocks/assignment/SubmissionForm';
|
|
import DocumentForm from '@/components/content-forms/DocumentForm';
|
|
import DocumentBlock from '@/components/content-blocks/DocumentBlock';
|
|
|
|
export default {
|
|
props: ['value'],
|
|
|
|
components: {
|
|
DocumentBlock,
|
|
DocumentForm,
|
|
SubmissionForm,
|
|
FinalSubmission,
|
|
},
|
|
|
|
computed: {
|
|
final() {
|
|
return !!this.submission && this.submission.final
|
|
},
|
|
submission() {
|
|
return this.assignment.submission ? this.assignment.submission : {}
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
_save: debounce(function () {
|
|
this.$apollo.mutate({
|
|
mutation: UPDATE_ASSIGNMENT_MUTATION_WITH_SUCCESS,
|
|
variables: {
|
|
input: {
|
|
assignment: {
|
|
id: this.assignment.id,
|
|
answer: this.assignment.submission.text,
|
|
document: this.assignment.submission.document,
|
|
}
|
|
}
|
|
}
|
|
}).then(() => {
|
|
this.unsaved = false;
|
|
});
|
|
}, 500),
|
|
saveInput: function (answer) {
|
|
this.unsaved = true;
|
|
/*
|
|
We update the assignment on this component, so the changes are reflected on it. The server does not return
|
|
the updated entity, to prevent the UI to update when the user is entering his input
|
|
*/
|
|
this.assignment.submission.text = answer;
|
|
this._save();
|
|
},
|
|
changeDocumentUrl(documentUrl) {
|
|
this.assignment.submission.document = documentUrl;
|
|
this._save();
|
|
},
|
|
turnIn() {
|
|
this.$apollo.mutate({
|
|
mutation: UPDATE_ASSIGNMENT_MUTATION,
|
|
variables: {
|
|
input: {
|
|
assignment: {
|
|
id: this.assignment.id,
|
|
answer: this.assignment.submission.text,
|
|
document: this.assignment.submission.document,
|
|
final: true
|
|
}
|
|
}
|
|
}
|
|
});
|
|
},
|
|
initialSubmission() {
|
|
return {
|
|
text: '',
|
|
document: '',
|
|
final: false,
|
|
}
|
|
},
|
|
},
|
|
|
|
apollo: {
|
|
assignment: {
|
|
query: ASSIGNMENT_QUERY,
|
|
variables() {
|
|
return {
|
|
id: this.value.id
|
|
}
|
|
},
|
|
result ({ data }) {
|
|
this.assignment = cloneDeep(data.assignment);
|
|
this.assignment.submission = Object.assign(this.initialSubmission(), this.assignment.submission);
|
|
}
|
|
},
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
assignment: {
|
|
submission: this.initialSubmission(),
|
|
},
|
|
inputType: 'text',
|
|
unsaved: false
|
|
}
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
@import '@/styles/_variables.scss';
|
|
@import '@/styles/_functions.scss';
|
|
@import '@/styles/_mixins.scss';
|
|
|
|
.assignment {
|
|
margin-bottom: 2em;
|
|
|
|
&__title {
|
|
font-size: toRem(17px);
|
|
}
|
|
|
|
&__toggle-input-container {
|
|
display: flex;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
&__toggle-input {
|
|
border: 0;
|
|
font-family: $sans-serif-font-family;
|
|
background: transparent;
|
|
font-size: toRem(14px);
|
|
padding: 5px 0;
|
|
margin-right: 15px;
|
|
outline: 0;
|
|
color: $color-grey;
|
|
cursor: pointer;
|
|
border-bottom: 2px solid transparent;
|
|
|
|
&--active {
|
|
border-bottom-color: $color-darkgrey-1;
|
|
color: $color-darkgrey-1;
|
|
}
|
|
}
|
|
|
|
&__submission {
|
|
/*margin-bottom: 12px;*/
|
|
}
|
|
|
|
&__inputs {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
&__submit {
|
|
}
|
|
}
|
|
</style>
|