Refactor submission form

This commit is contained in:
Christian Cueni 2019-11-19 10:25:24 +01:00
parent a732074a9b
commit 066f5259ce
7 changed files with 216 additions and 207 deletions

View File

@ -7,44 +7,20 @@
<solution :value="solution" v-if="assignment.solution"></solution> <solution :value="solution" v-if="assignment.solution"></solution>
<template v-if="isStudent"> <template v-if="isStudent">
<div class="assignment__submission submissionform-container"> <submission-form
v-if="isStudent"
@turnIn="turnIn"
@saveInput="saveInput"
@reopen="reopen"
@changeDocumentUrl="changeDocumentUrl"
:user-input="submission"
:placholder="'Ergebnis erfassen'"
:action="'Ergebnis mit Lehrperson teilen'"
:shared-msg="'Das Ergebnis wurde mit der Lehrperson geteilt.'"
:saved="!unsaved"
>
</submission-form>
<div class="submissionform-container__inputs">
<submission-form
@input="saveInput"
:input-text="submission.text"
:saved="!unsaved"
:final="final"
></submission-form>
</div>
<div class="submissionform-container__actions" v-if="!final">
<button
class="submissionform-container__submit button button--primary button--white-bg"
@click="turnIn"
>Ergebnis mit Lehrperson teilen
</button>
<div v-if="assignment.submission.document">
<document-block
:value="{url: assignment.submission.document}"
show-trash-icon
v-on:trash="changeDocumentUrl('')"
></document-block>
</div>
<simple-file-upload
v-on:link-change-url="changeDocumentUrl"
:value="assignment.submission.document"
></simple-file-upload>
</div>
<final-submission
v-if="final"
:user-input="assignment.submission.text"
:shared-msg="'Das Ergebnis wurde mit der Lehrperson geteilt'"
@reopen="reopen"></final-submission>
</div>
<div v-if="this.assignment.submission.submissionfeedback" class="submissionform-container__feedback"> <div v-if="this.assignment.submission.submissionfeedback" class="submissionform-container__feedback">
<p>{{feedbackText}}</p> <p>{{feedbackText}}</p>
</div> </div>
@ -66,6 +42,7 @@
import cloneDeep from 'lodash/cloneDeep' import cloneDeep from 'lodash/cloneDeep'
import FinalSubmission from '@/components/content-blocks/assignment/FinalSubmission'; import FinalSubmission from '@/components/content-blocks/assignment/FinalSubmission';
import SubmissionInput from '@/components/content-blocks/assignment/SubmissionInput';
import SubmissionForm from '@/components/content-blocks/assignment/SubmissionForm'; import SubmissionForm from '@/components/content-blocks/assignment/SubmissionForm';
import DocumentForm from '@/components/content-forms/DocumentForm'; import DocumentForm from '@/components/content-forms/DocumentForm';
import DocumentBlock from '@/components/content-blocks/DocumentBlock'; import DocumentBlock from '@/components/content-blocks/DocumentBlock';
@ -78,10 +55,11 @@
components: { components: {
DocumentBlock, DocumentBlock,
DocumentForm, DocumentForm,
SubmissionForm, SubmissionInput,
FinalSubmission, FinalSubmission,
Solution, Solution,
SimpleFileUpload SimpleFileUpload,
SubmissionForm
}, },
computed: { computed: {

View File

@ -1,61 +0,0 @@
<template>
<div class="feedback__submission submissionform-container">
<div class="submissionform-container__inputs">
<submission-form
@input="saveInput"
:input-text="userInput.text"
:saved="saved"
:final="final"
:placeholder="placeholder"
:reopen="reopenSubmission"
></submission-form>
</div>
<div class="submissionform-container__actions" v-if="!final">
<button class="submissionform-container__submit button button--primary button--white-bg"
@click="$emit('turnIn')"
>{{action}}
</button>
<slot></slot>
</div>
<final-submission
v-if="final"
:user-input="userInput"
:shared-msg="sharedMsg"
@reopen="$emit('reopen')"></final-submission>
</div>
</template>
<script>
import SubmissionForm from '@/components/content-blocks/assignment/SubmissionForm';
import FinalSubmission from '@/components/content-blocks/assignment/FinalSubmission';
export default {
components: {
SubmissionForm,
FinalSubmission
},
props: ['userInput', 'saved', 'placeholder', 'action', 'reopen', 'document', 'sharedMsg'],
computed: {
final() {
return !!this.userInput && this.userInput.final
}
},
methods: {
reopenSubmission() {
this.$emit('reopen');
},
saveInput(input) {
this.$emit('saveInput', input);
}
},
}
</script>
<style scoped lang="scss">
</style>

View File

@ -1,84 +1,119 @@
<template> <template>
<div class="submission-form__text-answer submission-form"> <div class="feedback__submission submissionform-container">
<textarea <div class="submissionform-container__inputs">
v-auto-grow <submission-input
rows="1" @input="saveInput"
class="submission-form__textarea" :input-text="userInput.text"
:placeholder="placeholder" :saved="saved"
:readonly="final" :final="final"
:value="inputText" :placeholder="placeholder"
@input="$emit('input', $event.target.value)" :reopen="reopenSubmission"
></textarea> ></submission-input>
<div class="submission-form__save-status submission-form__save-status--saved" v-if="saved"> </div>
<tick-circle-icon class="submission-form__save-status-icon"></tick-circle-icon>
<div class="submissionform-container__actions" v-if="!final">
<button class="submissionform-container__submit button button--primary button--white-bg"
@click="$emit('turnIn')"
>{{action}}
</button>
<div v-if="userInput.document">
<document-block
:value="{url: userInput.document}"
show-trash-icon
v-on:trash="changeDocumentUrl('')"
></document-block>
</div>
<simple-file-upload
v-if="allowsDocuments"
v-on:link-change-url="changeDocumentUrl"
:value="userInput.document"
class="submissionform-container__document"
></simple-file-upload>
<slot></slot>
</div>
<final-submission
v-if="final"
:user-input="userInput"
:shared-msg="sharedMsg"
@reopen="$emit('reopen')"></final-submission>
</div> </div>
<div class="submission-form__save-status submission-form__save-status--unsaved" v-if="!saved">
<loading-icon class="submission-form__save-status-icon submission-form__saving-icon"></loading-icon>
</div>
</div>
</template> </template>
<script> <script>
import TickCircleIcon from '@/components/icons/TickCircleIcon'; import SubmissionInput from '@/components/content-blocks/assignment/SubmissionInput';
import LoadingIcon from '@/components/icons/LoadingIcon'; import FinalSubmission from '@/components/content-blocks/assignment/FinalSubmission';
import SimpleFileUpload from '@/components/SimpleFileUpload';
import DocumentBlock from '@/components/content-blocks/DocumentBlock';
export default { export default {
props: { components: {
inputText: String, SubmissionInput,
saved: Boolean, FinalSubmission,
final: Boolean, SimpleFileUpload,
placeholder: { DocumentBlock
type: String, },
default: 'Ergebnis erfassen'
props: ['userInput', 'saved', 'placeholder', 'action', 'reopen', 'document', 'sharedMsg'],
computed: {
final() {
return !!this.userInput && this.userInput.final
},
allowsDocuments() {
return 'document' in this.userInput;
} }
}, },
components: {
TickCircleIcon, methods: {
LoadingIcon reopenSubmission() {
} this.$emit('reopen');
},
saveInput(input) {
this.$emit('saveInput', input);
},
changeDocumentUrl(documentUrl) {
this.$emit('changeDocumentUrl', documentUrl);
}
},
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import "@/styles/_variables.scss"; @import '@/styles/_mixins.scss';
@import "@/styles/_mixins.scss";
.submission-form { .submissionform-container {
@include input-box-shadow;
background-color: $color-white;
border-radius: $input-border-radius;
border: 1px solid $color-silver;
padding: $medium-spacing;
&__inputs {
margin-bottom: 12px;
}
&__submit {
margin-right: $medium-spacing;
}
&__actions {
display: flex; display: flex;
flex-direction: row; align-items: center;
justify-content: space-between; }
&__textarea { &__feedback {
display: flex; margin-top: $medium-spacing;
width: 95%; }
padding: 0;
box-sizing: border-box;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
line-height: 1.5;
border: 0;
min-height: 110px;
}
&__save-status { &__document {
position: relative; &:hover {
align-items: center; cursor: pointer;
}
&__save-status-icon {
width: 22px;
height: 22px;
fill: $color-silver-dark;
}
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
&__saving-icon {
animation: spin 2.5s linear infinite;
} }
} }
}
</style> </style>

View File

@ -0,0 +1,84 @@
<template>
<div class="submission-form__text-answer submission-form">
<textarea
v-auto-grow
rows="1"
class="submission-form__textarea"
:placeholder="placeholder"
:readonly="final"
:value="inputText"
@input="$emit('input', $event.target.value)"
></textarea>
<div class="submission-form__save-status submission-form__save-status--saved" v-if="saved">
<tick-circle-icon class="submission-form__save-status-icon"></tick-circle-icon>
</div>
<div class="submission-form__save-status submission-form__save-status--unsaved" v-if="!saved">
<loading-icon class="submission-form__save-status-icon submission-form__saving-icon"></loading-icon>
</div>
</div>
</template>
<script>
import TickCircleIcon from '@/components/icons/TickCircleIcon';
import LoadingIcon from '@/components/icons/LoadingIcon';
export default {
props: {
inputText: String,
saved: Boolean,
final: Boolean,
placeholder: {
type: String,
default: 'Ergebnis erfassen'
}
},
components: {
TickCircleIcon,
LoadingIcon
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.submission-form {
display: flex;
flex-direction: row;
justify-content: space-between;
&__textarea {
display: flex;
width: 95%;
padding: 0;
box-sizing: border-box;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
line-height: 1.5;
border: 0;
min-height: 110px;
}
&__save-status {
position: relative;
align-items: center;
}
&__save-status-icon {
width: 22px;
height: 22px;
fill: $color-silver-dark;
}
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
&__saving-icon {
animation: spin 2.5s linear infinite;
}
}
</style>

View File

@ -6,15 +6,15 @@
</div> </div>
<div class="submission-page__content submission-content"> <div class="submission-page__content submission-content">
<h2>Ergebnis von {{fullName}}</h2> <h2>Ergebnis von {{fullName}}</h2>
<p v-if="studentSubmission.document && studentSubmission.document.length > 0" class="article-content__document"> <p v-html="text"></p>
<p v-if="studentSubmission.document && studentSubmission.document.length > 0" class="article-content__document">
<a :href="studentSubmission.document" class="entry-document__link link" target="_blank"> <a :href="studentSubmission.document" class="entry-document__link link" target="_blank">
<student-submission-document :document="studentSubmission.document"></student-submission-document> <student-submission-document :document="studentSubmission.document"></student-submission-document>
</a> </a>
</p> </p>
<p v-html="text"></p>
</div> </div>
<div class="submission-page__feedback feedback"> <div class="submission-page__feedback feedback">
<feedback-form <submission-form
v-if="studentSubmission" v-if="studentSubmission"
@turnIn="turnIn" @turnIn="turnIn"
@saveInput="saveInput" @saveInput="saveInput"
@ -25,16 +25,16 @@
:shared-msg="'Dieses Feedback wurde geteilt.'" :shared-msg="'Dieses Feedback wurde geteilt.'"
:saved="!unsaved" :saved="!unsaved"
> >
<div v-if="!final" class="feedback-submission__emojis emojis"> <div v-if="!final" class="feedback-submission__emojis emojis">
<span @click="addEmoji('😀')">😀</span> <span @click="addEmoji('😀')">😀</span>
<span @click="addEmoji('🤮')">🤮</span> <span @click="addEmoji('🤮')">🤮</span>
<span @click="addEmoji('🤩')">🤩</span> <span @click="addEmoji('🤩')">🤩</span>
<span @click="addEmoji('😎')">😎</span> <span @click="addEmoji('😎')">😎</span>
<span @click="addEmoji('🤔')">🤔</span> <span @click="addEmoji('🤔')">🤔</span>
<span @click="addEmoji('👍🏻')">👍🏻</span> <span @click="addEmoji('👍🏻')">👍🏻</span>
<span @click="addEmoji('👎🏻')">👎🏻</span> <span @click="addEmoji('👎🏻')">👎🏻</span>
</div> </div>
</feedback-form> </submission-form>
</div> </div>
</div> </div>
</template> </template>
@ -46,12 +46,12 @@
import StudentSubmissionDocument from '@/components/StudentSubmissionDocument'; import StudentSubmissionDocument from '@/components/StudentSubmissionDocument';
import STUDENT_SUBMISSIONS_QUERY from '@/graphql/gql/studentSubmissionQuery.gql'; import STUDENT_SUBMISSIONS_QUERY from '@/graphql/gql/studentSubmissionQuery.gql';
import UPDATE_FEEDBACK_MUTATION from '@/graphql/gql/mutations/updateFeedback.gql'; import UPDATE_FEEDBACK_MUTATION from '@/graphql/gql/mutations/updateFeedback.gql';
import FeedbackForm from '@/components/content-blocks/assignment/FeedbackForm'; import SubmissionForm from '@/components/content-blocks/assignment/SubmissionForm';
export default { export default {
components: { components: {
StudentSubmissionDocument, StudentSubmissionDocument,
FeedbackForm SubmissionForm
}, },
computed: { computed: {

View File

@ -1,27 +0,0 @@
@import '@/styles/_mixins.scss';
.submissionform-container {
@include input-box-shadow;
background-color: $color-white;
border-radius: $input-border-radius;
border: 1px solid $color-silver;
padding: $medium-spacing;
&__inputs {
margin-bottom: 12px;
}
&__submit {
margin-right: $medium-spacing;
}
&__actions {
display: flex;
align-items: center;
}
&__feedback {
margin-top: $medium-spacing;
}
}

View File

@ -42,7 +42,7 @@ class StudentSubmissionNode(DjangoObjectType):
return self.submissionfeedback return self.submissionfeedback
return None return None
class AssignmentNode(DjangoObjectType): class AssignmentNode(DjangoObjectType):
submission = graphene.Field(StudentSubmissionNode) submission = graphene.Field(StudentSubmissionNode)