<template> <v-toolbar dense > <v-app-bar-nav-icon v-if="showCorrectionHelp" @click.stop="helpDialog=true" > <v-icon>help_outline</v-icon> </v-app-bar-nav-icon> <v-dialog v-model="helpDialog" scrollable max-width="fit-content" > <correction-help-card /> </v-dialog> <span v-if="score < 0">Submission of {{ ofStudent }}</span> <span v-else class="title" > Score: {{ score }} </span> <v-spacer /> <toggle-feedback-visibility-button /> <div v-if="isMarkdown"> <v-btn v-if="!mathIsRendered" @click="renderAsciiMath" > Render Math </v-btn> <v-btn v-else @click="resetSubmission" > Reset Math </v-btn> </div> <v-spacer /> <v-tooltip v-if="sourceCodeAvailable" top > <template #activator="{ on }"> <v-btn icon v-on="on" @click="downloadSourceCode" > <v-icon> cloud_download </v-icon> </v-btn> </template> <span>Download original source code (.ipynb, etc.)</span> </v-tooltip> <v-btn v-if="notebookAvailable" text class="blue-grey lighten-2" @click="showOriginalSubmission" > VIEW ORIGINAL SUBMISSION </v-btn> <v-tooltip top> <template #activator="{ on }"> <v-btn v-if="showClipboard" icon v-on="on" @click="copyToClipboard" > <v-icon>content_copy</v-icon> </v-btn> </template> <span>{{ copyMessage }}</span> </v-tooltip> <v-tooltip v-if="solutionHidden" top > <template #activator="{ on }"> <v-btn icon v-on="on" @click="showSolution" > <v-icon> keyboard_arrow_left </v-icon> </v-btn> </template> <span>Show Solution</span> </v-tooltip> <v-dialog v-model="originalSubmissionDialog" fullscreen hide-overlay > <v-card> <v-toolbar dark color="#1a237e" > <v-btn icon dark @click="originalSubmissionDialog = false" > <v-icon>close</v-icon> </v-btn> <v-toolbar-title>Original notebook</v-toolbar-title> <v-spacer /> </v-toolbar> <v-card-text> <iframe :srcdoc="originalSubmission" class="origNotebookFrame" /> </v-card-text> </v-card> </v-dialog> </v-toolbar> </template> <script> import CorrectionHelpCard from '@/components/submission_notes/CorrectionHelpCard' import { mapState } from 'vuex' import ToggleFeedbackVisibilityButton from '@/components/submission_notes/toolbars/ToggleFeedbackVisibilityButton' import { SubmissionNotes, subNotesEventBus } from '@/store/modules/submission-notes' import { StudentPage } from '@/store/modules/student-page' import {fetchSubmissionSourceCode} from '@/api.ts' import { fetchNotebookSubmissionAsHtml } from '@/api.ts' import {saveAs} from 'file-saver' import store from '../../../store/store' import { SubmissionType } from '../../../models' import Vue from 'vue' import { UI } from '@/store/modules/ui' export default { name: 'AnnotatedSubmissionTopToolbar', components: { ToggleFeedbackVisibilityButton, CorrectionHelpCard }, props: { ofStudent: { type: String, default: 'Participant' }, showClipboard: { type: Boolean, default: false }, score: { type: Number, default: -1 }, showCorrectionHelp: { type: Boolean, default: false }, sourceCodeAvailable: { type: Boolean, default: false }, isMarkdown: { type: Boolean, default: false }, notebookAvailable: { type: Boolean, default: false }, submission: { type: Object, default: null }, submissionType: { type: Object, default: null }, feedback: { type: Object, default: null }, submissionLanguage: { type: String, default: null } }, data () { return { helpDialog: false, copyMessage: 'Copy to clipboard', originalSubmissionDialog: false, originalSubmission: '', mathIsRendered: false, mathRerender: 0 } }, computed: { solutionHidden () { return UI.state.showSubmissionType === false } }, created () { subNotesEventBus.$on('submissionChanged', () => { if (this.mathIsRendered) { this.$nextTick(() => { this.renderAsciiMath() }) } }) }, mounted () { if (this.isMarkdown) { this.renderAsciiMath() } }, methods: { renderAsciiMath () { window.MathJax.typeset() this.mathIsRendered = true }, resetSubmission () { this.mathIsRendered = false subNotesEventBus.$emit('resetSubmission') }, async showOriginalSubmission () { if (!this.originalSubmission) { const notebook = await fetchNotebookSubmissionAsHtml(this.submission.pk) this.originalSubmission = notebook } this.originalSubmissionDialog = true }, async downloadSourceCode () { const data = await fetchSubmissionSourceCode(SubmissionNotes.state.submission.pk) saveAs(new Blob([data.sourceCode], {type: 'application/json'}), 'notebook.ipynb') }, copyToClipboard () { this.$clipboard(SubmissionNotes.state.submission.text) this.copyMessage = 'Copied!' setTimeout(() => { this.copyMessage = 'Copy to clipboard' }, 2500) }, showSolution () { UI.SET_SHOW_SUBMISSIONTYPE(true) } } } </script> <style scoped> .origNotebookFrame { width: 100%; min-height: 85vh; } </style>