skillbox/client/src/components/content-blocks/assignment/Assignment.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>