<template> <div> <base-annotated-submission> <annotated-submission-top-toolbar class="mb-1 elevation-1" slot="header" /> <template slot="table-content"> <tr v-for="(code, lineNo) in submission" :key="`${submissionObj.pk}${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 origFeedback[lineNo]" v-bind="comment" :visible_to_student="updatedFeedback[lineNo] ? false : comment.visible_to_student" :line-no="lineNo" :key="index" :deletable="comment.of_tutor === 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)" @submitFeedback="" > </comment-form> </submission-line> </tr> </template> <annotated-submission-bottom-toolbar class="mt-1 elevation-1" slot="footer" :loading="loading" :fullScore="submissionObj['full_score']" :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 SubmissionLine from '@/components/submission_notes/base/SubmissionLine' import {subNotesMut, subNotesNamespace} from '@/store/modules/submission-notes' import RouteChangeConfirmation from '@/components/submission_notes/RouteChangeConfirmation' export default { components: { RouteChangeConfirmation, SubmissionLine, BaseAnnotatedSubmission, AnnotatedSubmissionBottomToolbar, AnnotatedSubmissionTopToolbar, FeedbackComment, 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 } }, computed: { ...mapState({ user: state => state.authentication.username, showEditorOnLine: state => state.submissionNotes.ui.showEditorOnLine, selectedComment: state => state.submissionNotes.ui.selectedCommentOnLine, origFeedback: state => state.submissionNotes.origFeedback.feedback_lines, updatedFeedback: state => state.submissionNotes.updatedFeedback.feedback_lines, showFeedback: state => state.submissionNotes.ui.showFeedback }), ...mapGetters([ 'isStudent', 'isTutor', 'isReviewer', 'getSubmission', 'getFeedback', 'getSubmissionType', 'workInProgress' ]), submission () { return this.$store.getters['submissionNotes/submission'] }, submissionObj () { return this.assignment ? this.assignment.submission : this.submissionWithoutAssignment }, feedbackObj () { return this.assignment ? this.assignment.feedback : this.feedback } }, methods: { toggleEditorOnLine (lineNo, comment = '') { this.$store.commit(subNotesNamespace(subNotesMut.TOGGLE_EDITOR_ON_LINE), {lineNo, comment}) }, submitFeedback ({isFinal}) { this.loading = true this.$store.dispatch(subNotesNamespace('submitFeedback'), { isFinal: isFinal }).then(feedback => { this.$store.commit(subNotesNamespace(subNotesMut.RESET_UPDATED_FEEDBACK)) this.$store.commit(subNotesNamespace(subNotesMut.SET_ORIG_FEEDBACK), feedback) this.$emit('feedbackCreated') }).catch(err => { this.$notify({ title: 'Feedback creation Error!', text: err.message, type: 'error' }) }).finally(() => { this.loading = false }) }, shortPollOrigFeedback () { this.feedbackShortPollInterval = setInterval(() => { if (this.feedbackObj && this.feedbackObj.of_submission) { this.$store.dispatch('getFeedback', {ofSubmission: this.feedbackObj.of_submission}).then(feedback => { this.$store.commit(subNotesNamespace(subNotesMut.SET_ORIG_FEEDBACK), feedback) }) } }, 5e3) }, init () { this.$store.commit(subNotesNamespace(subNotesMut.RESET_STATE)) this.$store.commit(subNotesNamespace(subNotesMut.SET_SUBMISSION), this.submissionObj) this.$store.commit(subNotesNamespace(subNotesMut.SET_ORIG_FEEDBACK), this.feedbackObj) } }, watch: { assignment: function (newVar, oldVar) { this.init() }, submissionWithoutAssignment: function () { this.init() } }, created () { this.init() this.shortPollOrigFeedback() }, beforeDestroy () { clearInterval(this.feedbackShortPollInterval) } } </script> <style scoped> </style>