SubmissionCorrection.vue 7.01 KiB
<template>
<div>
<base-annotated-submission>
<annotated-submission-top-toolbar
class="mb-1 elevation-1"
slot="header"
/>
<template slot="table-content" id='sub-lines'>
<tr v-for="(code, lineNo) in submission" :key="`${submissionObj.pk}${lineNo}`" :id="`sub-line-${lineNo}`">
<submission-line
:code="code"
:line-no="lineNo"
@toggleEditor="toggleEditorOnLine(lineNo)"
>
<template v-if="showFeedback">
<div v-if="origFeedback[lineNo]">
<feedback-comment
v-for="(comment, index) in getSortedComments(lineNo)"
v-bind="comment"
:visibleToStudent="updatedFeedback[lineNo] ? false : comment.visibleToStudent"
:line-no="lineNo"
:key="index"
:deletable="comment.ofTutor === user || isReviewer"
@click.native="toggleEditorOnLine(lineNo, comment)"
/>
</div>
<feedback-comment
v-if="updatedFeedback[lineNo]"
v-bind="updatedFeedback[lineNo]"
:line-no="lineNo"
:deletable="true"
@click.native="toggleEditorOnLine(lineNo, updatedFeedback[lineNo])"
/>
</template>
<comment-form
v-if="showEditorOnLine[lineNo]"
:feedback="selectedComment[lineNo].text"
:lineNo="lineNo"
@collapseFeedbackForm="toggleEditorOnLine(lineNo)"
>
</comment-form>
</submission-line>
</tr>
</template>
<label-selector
id="feedback-label-selector"
:assignedToFeedback="true"
class="mt-1 elevation-1"
slot="labels"
/>
<annotated-submission-bottom-toolbar
class="mt-1 elevation-1"
slot="footer"
:loading="loading"
:fullScore="submissionObj['fullScore']"
:skippable="assignment !== undefined"
:feedback="feedbackObj ? feedbackObj : {}"
@submitFeedback="submitFeedback"
/>
</base-annotated-submission>
</div>
</template>
<script>
import { mapState, mapGetters } from 'vuex'
import CommentForm from '@/components/submission_notes/base/CommentForm.vue'
import FeedbackComment from '@/components/submission_notes/base/FeedbackComment.vue'
import AnnotatedSubmissionTopToolbar from '@/components/submission_notes/toolbars/AnnotatedSubmissionTopToolbar'
import AnnotatedSubmissionBottomToolbar from '@/components/submission_notes/toolbars/AnnotatedSubmissionBottomToolbar'
import BaseAnnotatedSubmission from '@/components/submission_notes/base/BaseAnnotatedSubmission'
import FeedbackLabel from "@/components/feedback_labels/FeedbackLabel.vue"
import { FeedbackLabels as Labels } from '@/store/modules/feedback-labels'
import LabelSelector from '@/components/feedback_labels/LabelSelector.vue'
import SubmissionLine from '@/components/submission_notes/base/SubmissionLine'
import { SubmissionNotes } from '@/store/modules/submission-notes'
import { Authentication } from '@/store/modules/authentication'
import { actions } from '@/store/actions'
import { fetchFeedback } from '@/api'
export default {
components: {
SubmissionLine,
BaseAnnotatedSubmission,
AnnotatedSubmissionBottomToolbar,
AnnotatedSubmissionTopToolbar,
FeedbackComment,
LabelSelector,
CommentForm },
name: 'submission-correction',
data () {
return {
loading: false,
feedbackShortPollInterval: null
}
},
props: {
assignment: {
type: Object
},
// either pass in an assignment or a submission and feedback
submissionWithoutAssignment: {
type: Object
},
feedback: {
type: Object
},
ignoreHiddenState: {
type: Boolean,
default: false,
}
},
computed: {
showEditorOnLine () { return SubmissionNotes.state.ui.showEditorOnLine },
selectedComment () { return SubmissionNotes.state.ui.selectedCommentOnLine },
origFeedback () { return SubmissionNotes.state.origFeedback.feedbackLines },
updatedFeedback () { return SubmissionNotes.state.updatedFeedback.feedbackLines },
showFeedback () { return SubmissionNotes.state.ui.showFeedback },
workInProgress () { return SubmissionNotes.workInProgress },
isStudent () { return Authentication.isStudent },
isTutor () { return Authentication.isTutor },
isReviewer () { return Authentication.isReviewer },
user () { return Authentication.state.user.username },
submission () {
return SubmissionNotes.submission
},
submissionObj () {
return this.assignment ? this.assignment.submission : this.submissionWithoutAssignment
},
feedbackObj () {
return this.assignment ? this.assignment.feedback : this.feedback
}
},
methods: {
toggleEditorOnLine (lineNo, comment = '') {
SubmissionNotes.TOGGLE_EDITOR_ON_LINE({ lineNo, comment })
},
submitFeedback ({ isFinal }) {
this.loading = true
SubmissionNotes.submitFeedback({
isFinal: isFinal
}).then(feedback => {
SubmissionNotes.RESET_UPDATED_FEEDBACK()
SubmissionNotes.SET_ORIG_FEEDBACK(feedback)
this.$emit('feedbackCreated')
}).catch(err => {
// ignore trivial errors as those are handled
// by an interceptor
if (err.message.includes("Request failed")) return
this.$notify({
title: 'Feedback creation Error!',
text: err.message,
type: 'error',
duration: -1
})
}).finally(() => {
this.$emit('feedbackChanged')
SubmissionNotes.RESET_MARKED_COMMENTS_FOR_DELETE()
this.loading = false
})
},
shortPollOrigFeedback () {
this.feedbackShortPollInterval = setInterval(() => {
if (this.feedbackObj && this.feedbackObj.ofSubmission) {
fetchFeedback({ ofSubmission: this.feedbackObj.ofSubmission }).then(feedback => {
SubmissionNotes.SET_ORIG_FEEDBACK(feedback)
})
}
}, 5e3)
},
getSortedComments (lineNo) {
if (!this.origFeedback || (!this.origFeedback && !this.origFeedback[lineNo])) return new Array()
let feedback = [...this.origFeedback[lineNo]]
return feedback.sort((a, b) => {
const da = new Date(a.modified)
const db = new Date(b.modified)
return da.getTime() - db.getTime()
})
},
init () {
SubmissionNotes.RESET_STATE()
SubmissionNotes.SET_SUBMISSION(this.submissionObj)
SubmissionNotes.SET_ORIG_FEEDBACK(this.feedbackObj)
SubmissionNotes.SET_SHOW_FEEDBACK(this.ignoreHiddenState ? true : !SubmissionNotes.state.hasOrigFeedback)
}
},
watch: {
assignment: function (newVar, oldVar) {
this.init()
},
submissionWithoutAssignment: function () {
this.init()
}
},
created () {
this.init()
this.shortPollOrigFeedback()
},
beforeDestroy () {
clearInterval(this.feedbackShortPollInterval)
}
}
</script>
<style scoped>
</style>