<template> <div class="dialog-box"> <div v-if="commentDisplayable" class="body elevation-1" :style="{borderColor: borderColor, backgroundColor}"> <span class="tip tip-up" :style="{borderBottomColor: borderColor}"></span> <span v-if="ofTutor" class="of-tutor">Of tutor: {{ofTutor}}</span> <span class="comment-created">{{parsedCreated}}</span> <div class="visibility-icon" v-if="showVisibilityIcon"> <v-tooltip top v-if="visibleToStudent" size="20px"> <v-icon slot="activator" size="20px" >visibility</v-icon> <span>Will be visible to student</span> </v-tooltip> <v-tooltip top v-else> <v-icon slot="activator" size="20px">visibility_off</v-icon> <span>Won't be visible to student</span> </v-tooltip> </div> <div class="message">{{text}}</div> <v-btn flat icon absolute class="delete-button" v-if="deletable" @click.stop="toggleDeleteComment" > <v-icon v-if="!markedForDeletion.hasOwnProperty(this.pk)" color="grey darken-1" size="20px">delete_forever</v-icon> <v-icon v-else size="20px">restore</v-icon> </v-btn> </div> <v-layout v-if="showLabels" ml-2> <v-flex sm4> <v-flex sm12> UNCHANGED </v-flex> <feedback-label removable v-for="label in unchangedLabels" v-bind="label" :key="label.pk" @remove-clicked="deleteAction" /> </v-flex> <v-flex sm4> <v-flex sm12> WILL BE REMOVED </v-flex> <feedback-label removable v-for="label in removedLabels" v-bind="label" :key="label.pk" @remove-clicked="deleteAction" /> </v-flex> <v-flex sm4> <v-flex sm12> WILL BE ADDED </v-flex> <feedback-label removable v-for="label in addedLabels" v-bind="label" :key="label.pk" @remove-clicked="deleteAction" /> </v-flex> </v-layout> </div> </template> <script> import { mapState } from 'vuex' import { UI } from '@/store/modules/ui' import { SubmissionNotes } from '@/store/modules/submission-notes' import FeedbackLabel from "@/components/feedback_labels/FeedbackLabel.vue" import { FeedbackLabels as Labels } from '@/store/modules/feedback-labels' import commentLabelSelector from "@/components/mixins/commentLabelSelector" export default { name: 'feedback-comment', components: { FeedbackLabel, }, mixins: [ commentLabelSelector, ], props: { pk: { type: String, required: false }, text: { type: String, required: true }, modified: { type: String, required: false }, ofTutor: { type: String, required: false }, lineNo: { type: String, required: true }, deletable: { type: Boolean, default: false }, visibleToStudent: { type: Boolean, default: true }, showVisibilityIcon: { type: Boolean, default: true } }, computed: { commentDisplayable () { return this.text !== "" }, showLabels () { return this.visibleToStudent && (this.getUnchangedLabels().length > 0 || this.getAddedLabels().length > 0 || this.getRemovedLabels().length > 0) }, markedForDeletion () { return SubmissionNotes.state.commentsMarkedForDeletion }, parsedCreated () { if (this.modified) { return new Date(this.modified).toLocaleString() } else { return 'Just now' } }, borderColor () { if (this.pk) { return this.markedForDeletion.hasOwnProperty(this.pk) ? '#B5B5B5' : '#3D8FC1' } return 'orange' }, backgroundColor () { return UI.state.darkMode ? 'grey' : '#F3F3F3' }, unchangedLabels() { return this.mapPksToLabelObj(this.getUnchangedLabels()) }, addedLabels() { return this.mapPksToLabelObj(this.getAddedLabels()) }, removedLabels() { return this.mapPksToLabelObj(this.getRemovedLabels()) } }, methods: { deleteAction (pk) { let labels const concated = this.getUnchangedLabels().concat(this.getAddedLabels()) if (this.getUnchangedLabels().includes(pk)) { labels = concated.filter((val) => { return val !== pk }) } else if (this.getAddedLabels().includes(pk)) { labels = concated.filter((val) => { return val !== pk }) } else if (this.getRemovedLabels().includes(pk)) { concated.push(pk) labels = concated } if (labels.length > 0 || SubmissionNotes.state.hasOrigFeedback || this.commentDisplayable) { SubmissionNotes.UPDATE_FEEDBACK_LINE({ lineNo: Number(this.lineNo), comment: { text: this.text || "", labels: labels, } }) } else { SubmissionNotes.DELETE_FEEDBACK_LINE(Number(this.lineNo)) } }, toggleDeleteComment () { if (this.pk) { if (!this.markedForDeletion.hasOwnProperty(this.pk)) { SubmissionNotes.MARK_COMMENT_FOR_DELETION({ pk: this.pk }) } else { SubmissionNotes.UN_MARK_COMMENT_FOR_DELETION({ pk: this.pk }) } } SubmissionNotes.DELETE_FEEDBACK_LINE(this.lineNo) } } } </script> <style scoped> .tip { width: 0px; height: 0px; position: absolute; background: transparent; border: 10px solid; } .tip-up { top: -22px; /* Same as body margin top + border */ left: 10px; border-right-color: transparent; border-left-color: transparent; border-top-color: transparent; } .dialog-box .body { cursor: pointer; position: relative; height: auto; margin: 20px 10px 10px 10px; padding: 5px; border-radius: 0px; border: 2px solid; } .body .message { min-height: 30px; border-radius: 3px; font-size: 14px; line-height: 1.5; white-space: pre-wrap; } .delete-button { bottom: -12px; left: -42px; } .comment-created { position: absolute; font-size: 10px; right: 4px; top: -20px; } .of-tutor { position: absolute; font-size: 13px; top: -20px; left: 50px; } .visibility-icon { position: absolute; top: -4px; left: -34px; } </style>