From 8db1f18f39bd93a92900cf66078216680a907522 Mon Sep 17 00:00:00 2001 From: Dominik Seeger <dominik.seeger@gmx.net> Date: Wed, 2 Oct 2019 15:00:55 +0200 Subject: [PATCH] setup eslint to also lint vue templates --- frontend/.eslintrc.js | 2 +- frontend/src/App.vue | 8 +- frontend/src/components/AutoLogout.vue | 30 ++- frontend/src/components/BaseLayout.vue | 84 +++++-- .../src/components/CorrectionStatistics.vue | 25 ++- frontend/src/components/GDPRNotice.vue | 206 ++++++++++-------- frontend/src/components/LabelStatistics.vue | 48 ++-- .../src/components/PasswordChangeDialog.vue | 95 ++++---- frontend/src/components/RegisterDialog.vue | 28 ++- frontend/src/components/SubmissionTests.vue | 69 +++--- frontend/src/components/UserOptions.vue | 10 +- frontend/src/components/export/DataExport.vue | 56 +++-- .../src/components/export/ExportDialog.vue | 36 ++- .../src/components/export/InstanceExport.vue | 44 +++- .../feedback_labels/FeedbackLabel.vue | 14 +- .../feedback_labels/FeedbackLabelForm.vue | 61 +++++- .../feedback_labels/FeedbackLabelUpdater.vue | 10 +- .../feedback_labels/FeedbackLabelsList.vue | 40 +++- .../feedback_labels/LabelSelector.vue | 24 +- .../feedback_list/FeedbackListHelpCard.vue | 11 +- .../feedback_list/FeedbackSearchOptions.vue | 67 ++++-- .../feedback_list/FeedbackTable.vue | 30 ++- .../student/NonFinalFeedbackAlert.vue | 12 +- .../src/components/student/SubmissionList.vue | 37 +++- .../components/student_list/StudentList.vue | 98 ++++++--- .../student_list/StudentListHelpCard.vue | 2 +- .../student_list/StudentListMenu.vue | 19 +- .../student_list/StudentListReverseMapper.vue | 15 +- .../submission_notes/CorrectionHelpCard.vue | 49 ++--- .../RouteChangeConfirmation.vue | 61 ++++-- .../submission_notes/SubmissionCorrection.vue | 77 ++++--- .../base/BaseAnnotatedSubmission.vue | 10 +- .../submission_notes/base/CommentForm.vue | 52 +++-- .../submission_notes/base/FeedbackComment.vue | 109 ++++++--- .../submission_notes/base/SubmissionLine.vue | 10 +- .../AnnotatedSubmissionBottomToolbar.vue | 150 ++++++++----- .../AnnotatedSubmissionTopToolbar.vue | 24 +- .../ToggleFeedbackVisibilityButton.vue | 15 +- .../submission_type/SubmissionType.vue | 33 +-- .../SubmissionTypesOverview.vue | 55 +++-- .../submission_type/solution/Solution.vue | 55 +++-- .../solution/SolutionComment.vue | 89 ++++++-- .../subscriptions/SubscriptionCreation.vue | 31 +-- .../subscriptions/SubscriptionEnded.vue | 7 +- .../subscriptions/SubscriptionForList.vue | 7 +- .../subscriptions/SubscriptionList.vue | 47 +++- .../subscriptions/SubscriptionsForStage.vue | 11 +- .../src/components/tutor_list/TutorList.vue | 66 ++++-- frontend/src/components/util/FileSelect.vue | 9 +- frontend/src/pages/LayoutSelector.vue | 6 +- frontend/src/pages/Login.vue | 69 ++++-- frontend/src/pages/PageNotFound.vue | 27 ++- frontend/src/pages/StartPageSelector.vue | 5 +- frontend/src/pages/Statistics.vue | 14 +- .../src/pages/StudentSubmissionSideView.vue | 10 +- frontend/src/pages/SubscriptionWorkPage.vue | 18 +- .../src/pages/base/FeedbackHistoryPage.vue | 12 +- .../pages/base/TutorReviewerBaseLayout.vue | 23 +- .../src/pages/reviewer/ReviewerLayout.vue | 15 +- .../src/pages/reviewer/ReviewerStartPage.vue | 27 ++- .../pages/reviewer/StudentOverviewPage.vue | 78 ++++--- .../src/pages/reviewer/TutorOverviewPage.vue | 4 +- frontend/src/pages/student/StudentLayout.vue | 37 +++- frontend/src/pages/student/StudentPage.vue | 37 ++-- .../pages/student/StudentSubmissionPage.vue | 90 +++++--- frontend/src/pages/tutor/TutorLayout.vue | 6 +- frontend/src/pages/tutor/TutorStartPage.vue | 27 ++- 67 files changed, 1781 insertions(+), 872 deletions(-) diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 6e46f9f8..d2fb930e 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -4,7 +4,7 @@ module.exports = { node: true, }, extends: [ - 'plugin:vue/essential', + 'plugin:vue/recommended', '@vue/typescript', ], rules: { diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 61d97b5b..c8171566 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,9 +1,9 @@ <template> <div id="app"> <v-app :dark="darkMode"> - <notifications/> - <router-view/> - <auto-logout/> + <notifications /> + <router-view /> + <auto-logout /> </v-app> </div> </template> @@ -17,8 +17,8 @@ import { UI } from '@/store/modules/ui' import AutoLogout from '@/components/AutoLogout' export default { + name: 'App', components: { AutoLogout }, - name: 'app', computed: { darkMode () { return UI.state.darkMode diff --git a/frontend/src/components/AutoLogout.vue b/frontend/src/components/AutoLogout.vue index a9c4a64e..8aa2bdf4 100644 --- a/frontend/src/components/AutoLogout.vue +++ b/frontend/src/components/AutoLogout.vue @@ -1,28 +1,36 @@ <template> <v-dialog + v-model="logoutDialog" persistent max-width="30%" - v-model="logoutDialog" > <v-card id="logout-dialog"> <v-card-title class="headline"> You'll be logged out! </v-card-title> <v-card-text> - Due to inactivity you'll be logged out in a couple of moments.<br/> + Due to inactivity you'll be logged out in a couple of moments.<br> Any unsaved work will be lost. Click Continue to stay logged in. </v-card-text> <v-card-actions> - <v-btn flat color="grey lighten-0" - id="logout-btn" - @click="logout" - >Logout now</v-btn> - <v-spacer/> - <v-btn flat color="blue darken-2" - id="continue-btn" - @click="continueWork" - >Continue</v-btn> + <v-btn + id="logout-btn" + flat + color="grey lighten-0" + @click="logout" + > + Logout now + </v-btn> + <v-spacer /> + <v-btn + id="continue-btn" + flat + color="blue darken-2" + @click="continueWork" + > + Continue + </v-btn> </v-card-actions> </v-card> </v-dialog> diff --git a/frontend/src/components/BaseLayout.vue b/frontend/src/components/BaseLayout.vue index ae32a6af..5ee9e221 100644 --- a/frontend/src/components/BaseLayout.vue +++ b/frontend/src/components/BaseLayout.vue @@ -11,42 +11,56 @@ <v-list> <v-list-tile> <v-list-tile-action v-if="mini"> - <v-btn icon @click.native.stop="mini = !mini"> + <v-btn + icon + @click.native.stop="mini = !mini" + > <v-icon>chevron_right</v-icon> </v-btn> </v-list-tile-action> <v-list-tile-content class="title" > - <slot name="header"></slot> + <slot name="header" /> </v-list-tile-content> <v-list-tile-action v-if="!mini"> - <v-btn icon @click.native.stop="mini = !mini"> + <v-btn + icon + @click.native.stop="mini = !mini" + > <v-icon>chevron_left</v-icon> </v-btn> </v-list-tile-action> </v-list-tile> </v-list> </v-toolbar> - <slot name="sidebar-content"></slot> + <slot name="sidebar-content" /> <div class="sidebar-footer"> - <v-tooltip top style="min-width: 150px"> + <v-tooltip + top + style="min-width: 150px" + > <v-switch - class="ml-3" slot="activator" + v-model="darkMode" + class="ml-3" :disabled="!darkModeUnlocked" - v-model="darkMode" label="dark mode"/> + label="dark mode" + /> <span v-if="darkModeUnlocked">Experimental: styling issues may occur!</span> <span v-else>You need to visit the feedback site below first!</span> </v-tooltip> - <v-footer v-if="!mini" @click.native="logFeedbackClick"> - <v-spacer/> + <v-footer + v-if="!mini" + @click.native="logFeedbackClick" + > + <v-spacer /> <a href="https://gitlab.gwdg.de/j.michal/grady/issues" target="_blank" class="feedback-link" >Give us Feedback!</a> - <v-spacer/> + <v-spacer /> </v-footer> </div> </v-navigation-drawer> @@ -61,27 +75,53 @@ <v-toolbar-title> <router-link to="/home"> <v-avatar> - <img v-if="production" :src="productionBrandUrl"/> - <img v-else src="../assets/brand.png"/> + <img + v-if="production" + :src="productionBrandUrl" + > + <img + v-else + src="../assets/brand.png" + > </v-avatar> </router-link> </v-toolbar-title> <span class="pl-2 grady-speak">{{ gradySpeak }}</span> - <v-spacer/> - <slot name="toolbar-center"/> + <v-spacer /> + <slot name="toolbar-center" /> <div class="toolbar-content"> - <v-menu bottom offset-y v-if="!isStudent"> - <v-btn slot="activator" color="cyan" style="text-transform: none"> + <v-menu + v-if="!isStudent" + bottom + offset-y + > + <v-btn + slot="activator" + color="cyan" + style="text-transform: none" + > {{ userRole }} | {{ username }} <v-icon>arrow_drop_down</v-icon> </v-btn> - <user-options class="mt-1" v-if="!isStudent"/> + <user-options + v-if="!isStudent" + class="mt-1" + /> </v-menu> - <span v-else style="color:#595959"> - {{username}} + <span + v-else + style="color:#595959" + > + {{ username }} </span> </div> - <slot name="toolbar-right"></slot> - <v-btn color="blue darken-1" id="logout" @click.native="logout">Logout</v-btn> + <slot name="toolbar-right" /> + <v-btn + id="logout" + color="blue darken-1" + @click.native="logout" + > + Logout + </v-btn> </v-toolbar> </div> </template> @@ -95,7 +135,7 @@ import { Authentication } from '@/store/modules/authentication' import { actions } from '@/store/actions' export default { - name: 'base-layout', + name: 'BaseLayout', components: { UserOptions }, computed: { username () { return Authentication.state.user.username }, diff --git a/frontend/src/components/CorrectionStatistics.vue b/frontend/src/components/CorrectionStatistics.vue index fe55e9fa..bf827c0a 100644 --- a/frontend/src/components/CorrectionStatistics.vue +++ b/frontend/src/components/CorrectionStatistics.vue @@ -1,22 +1,29 @@ <template> - <v-card class="py-2" id="correction-statistics"> + <v-card + id="correction-statistics" + class="py-2" + > <v-card-title> <span class="title">Statistics</span> </v-card-title> <div v-if="loaded"> <ul class="inline-list mx-3"> - <li>Submissions per participant: <span>{{statistics.submissionsPerStudent}}</span></li> - <li>Submissions per type: <span>{{statistics.submissionsPerType}}</span></li> - <li>Curr. mean score: + <li>Submissions per participant: <span>{{ statistics.submissionsPerStudent }}</span></li> + <li>Submissions per type: <span>{{ statistics.submissionsPerType }}</span></li> + <li> + Curr. mean score: <span> - {{statistics.currentMeanScore === null ? 'N.A.' : statistics.currentMeanScore.toFixed(2)}} + {{ statistics.currentMeanScore === null ? 'N.A.' : statistics.currentMeanScore.toFixed(2) }} </span> </li> </ul> - <v-divider class="mx-2 my-2"></v-divider> - <div v-for="(progress, index) in statistics.submissionTypeProgress" :key="index"> + <v-divider class="mx-2 my-2" /> + <div + v-for="(progress, index) in statistics.submissionTypeProgress" + :key="index" + > <v-card-title class="py-0"> - {{progress.name}} + {{ progress.name }} </v-card-title> <div class="mx-3"> <v-progress-linear @@ -35,7 +42,7 @@ import { actions } from '@/store/actions' export default { - name: 'correction-statistics', + name: 'CorrectionStatistics', data () { return { loaded: false diff --git a/frontend/src/components/GDPRNotice.vue b/frontend/src/components/GDPRNotice.vue index d82c479f..46677c70 100644 --- a/frontend/src/components/GDPRNotice.vue +++ b/frontend/src/components/GDPRNotice.vue @@ -1,99 +1,133 @@ <template> - <div> - <p><strong>Allgemeiner Hinweis und Pflichtinformationen</strong></p> - <p><strong>Benennung der verantwortlichen Stelle</strong></p> - <p>Die verantwortliche Stelle für die Datenverarbeitung auf dieser Website ist:</p> - <p><span id="s3-t-firma">Institut für Informatik - Georg-August-Universität Göttingen</span><br> - <span id="s3-t-ansprechpartner">Dr. Henrik Brosenne</span><br><span id="s3-t-strasse">Goldschmidtstraße 7</span><br> - <span id="s3-t-plz">37077</span> <span id="s3-t-ort">Göttingen</span></p><p></p> - <p>Die verantwortliche Stelle entscheidet allein oder gemeinsam mit anderen über die Zwecke und Mittel der - Verarbeitung von personenbezogenen Daten (z.B. Namen, Kontaktdaten o. Ä.).</p> + <div> + <p><strong>Allgemeiner Hinweis und Pflichtinformationen</strong></p> + <p><strong>Benennung der verantwortlichen Stelle</strong></p> + <p>Die verantwortliche Stelle für die Datenverarbeitung auf dieser Website ist:</p> + <p> + <span id="s3-t-firma">Institut für Informatik - Georg-August-Universität Göttingen</span><br> + <span id="s3-t-ansprechpartner">Dr. Henrik Brosenne</span><br><span id="s3-t-strasse">Goldschmidtstraße 7</span><br> + <span id="s3-t-plz">37077</span> <span id="s3-t-ort">Göttingen</span> + </p><p /> + <p> + Die verantwortliche Stelle entscheidet allein oder gemeinsam mit anderen über die Zwecke und Mittel der + Verarbeitung von personenbezogenen Daten (z.B. Namen, Kontaktdaten o. Ä.). + </p> - <p><strong>Recht auf Beschwerde bei der zuständigen Aufsichtsbehörde</strong></p> - <p>Als Betroffener steht Ihnen im Falle eines datenschutzrechtlichen Verstoßes ein Beschwerderecht bei der zuständigen - Aufsichtsbehörde zu. Zuständige Aufsichtsbehörde bezüglich datenschutzrechtlicher Fragen ist:<br> - Die Landesbeauftragte für den Datenschutz Niedersachsen<br> - Prinzenstraße 5<br> - 30159 Hannover<br> - <p><strong>Recht auf Datenübertragbarkeit</strong></p> - <p>Ihnen steht das Recht zu, Daten, die wir auf Grundlage der Erfüllung eines Vertrags - automatisiert verarbeiten, an sich oder an Dritte aushändigen zu lassen. Die Bereitstellung erfolgt in einem - maschinenlesbaren Format. Sofern Sie die direkte Übertragung der Daten an einen anderen Verantwortlichen verlangen, erfolgt dies nur, soweit es technisch machbar ist.</p> + <p><strong>Recht auf Beschwerde bei der zuständigen Aufsichtsbehörde</strong></p> + <p> + Als Betroffener steht Ihnen im Falle eines datenschutzrechtlichen Verstoßes ein Beschwerderecht bei der zuständigen + Aufsichtsbehörde zu. Zuständige Aufsichtsbehörde bezüglich datenschutzrechtlicher Fragen ist:<br> + Die Landesbeauftragte für den Datenschutz Niedersachsen<br> + Prinzenstraße 5<br> + 30159 Hannover<br> + </p><p><strong>Recht auf Datenübertragbarkeit</strong></p> + <p> + Ihnen steht das Recht zu, Daten, die wir auf Grundlage der Erfüllung eines Vertrags + automatisiert verarbeiten, an sich oder an Dritte aushändigen zu lassen. Die Bereitstellung erfolgt in einem + maschinenlesbaren Format. Sofern Sie die direkte Übertragung der Daten an einen anderen Verantwortlichen verlangen, erfolgt dies nur, soweit es technisch machbar ist. + </p> - <p><strong>Recht auf Auskunft, Berichtigung, Sperrung, Löschung</strong></p> - <p>Sie haben jederzeit im Rahmen der geltenden gesetzlichen Bestimmungen das Recht auf unentgeltliche Auskunft über - Ihre gespeicherten personenbezogenen Daten, Herkunft der Daten, deren Empfänger und den Zweck der - Datenverarbeitung und ggf. ein Recht auf Berichtigung, Sperrung oder Löschung dieser Daten. Diesbezüglich und - auch zu weiteren Fragen zum Thema personenbezogene Daten können Sie sich jederzeit über die im Impressum aufgeführten Kontaktmöglichkeiten an uns wenden.</p> + <p><strong>Recht auf Auskunft, Berichtigung, Sperrung, Löschung</strong></p> + <p> + Sie haben jederzeit im Rahmen der geltenden gesetzlichen Bestimmungen das Recht auf unentgeltliche Auskunft über + Ihre gespeicherten personenbezogenen Daten, Herkunft der Daten, deren Empfänger und den Zweck der + Datenverarbeitung und ggf. ein Recht auf Berichtigung, Sperrung oder Löschung dieser Daten. Diesbezüglich und + auch zu weiteren Fragen zum Thema personenbezogene Daten können Sie sich jederzeit über die im Impressum aufgeführten Kontaktmöglichkeiten an uns wenden. + </p> - <p><strong>SSL- bzw. TLS-Verschlüsselung</strong></p> - <p>Aus Sicherheitsgründen und zum Schutz der Übertragung vertraulicher Inhalte, die Sie an uns als Seitenbetreiber - senden, nutzt unsere Website eine SSL-bzw. TLS-Verschlüsselung. Damit sind Daten, die Sie über diese Website - übermitteln, für Dritte nicht mitlesbar. Sie erkennen eine verschlüsselte Verbindung an der „https://“ - Adresszeile Ihres Browsers und am Schloss-Symbol in der Browserzeile.</p> + <p><strong>SSL- bzw. TLS-Verschlüsselung</strong></p> + <p> + Aus Sicherheitsgründen und zum Schutz der Übertragung vertraulicher Inhalte, die Sie an uns als Seitenbetreiber + senden, nutzt unsere Website eine SSL-bzw. TLS-Verschlüsselung. Damit sind Daten, die Sie über diese Website + übermitteln, für Dritte nicht mitlesbar. Sie erkennen eine verschlüsselte Verbindung an der „https://“ + Adresszeile Ihres Browsers und am Schloss-Symbol in der Browserzeile. + </p> - <p><strong>Datenschutzbeauftragter</strong></p> - <p>Wir haben einen Datenschutzbeauftragten bestellt.</p> - Datenschutzbeauftragter der Universität<br> - Prof. Dr. Andreas Wiebe<br> - Lehrstuhl für Bürgerliches Recht, Wettbewerbs- und Immaterialgüterrecht, Medien- und Informationsrecht<br> - Platz der Göttinger Sieben 6<br> - 37073 Göttingen<br> - Tel.: 0551 39 - 7381<br> - Fax: 0551 39 - 4437<br> - E-Mail: lehrstuhl.wiebe@jura.uni-goettingen.de<br> + <p><strong>Datenschutzbeauftragter</strong></p> + <p>Wir haben einen Datenschutzbeauftragten bestellt.</p> + Datenschutzbeauftragter der Universität<br> + Prof. Dr. Andreas Wiebe<br> + Lehrstuhl für Bürgerliches Recht, Wettbewerbs- und Immaterialgüterrecht, Medien- und Informationsrecht<br> + Platz der Göttinger Sieben 6<br> + 37073 Göttingen<br> + Tel.: 0551 39 - 7381<br> + Fax: 0551 39 - 4437<br> + E-Mail: lehrstuhl.wiebe@jura.uni-goettingen.de<br> - <p><strong>Server-Log-Dateien</strong></p> - <p>Der Provider der Website erhebt automatisch Informationen, die Ihr Browser automatisch an uns übermittelt. Dies sind:</p> - <ul> - <li>Besuchte Seite auf unserer Domain</li> - <li>Datum und Uhrzeit der Serveranfrage</li> - <li>Browsertyp und Browserversion</li> - <li>Verwendetes Betriebssystem</li> - <li>Referrer URL</li> - <li>Hostname des zugreifenden Rechners</li> - <li>IP-Adresse</li> - </ul> - <p>Es findet keine Zusammenführung dieser Daten mit anderen Datenquellen statt. Grundlage der Datenverarbeitung - bildet Art. 6 Abs. 1 lit. b DSGVO, der die Verarbeitung von Daten zur Erfüllung eines Vertrags oder - vorvertraglicher Maßnahmen gestattet.</p> + <p><strong>Server-Log-Dateien</strong></p> + <p>Der Provider der Website erhebt automatisch Informationen, die Ihr Browser automatisch an uns übermittelt. Dies sind:</p> + <ul> + <li>Besuchte Seite auf unserer Domain</li> + <li>Datum und Uhrzeit der Serveranfrage</li> + <li>Browsertyp und Browserversion</li> + <li>Verwendetes Betriebssystem</li> + <li>Referrer URL</li> + <li>Hostname des zugreifenden Rechners</li> + <li>IP-Adresse</li> + </ul> + <p> + Es findet keine Zusammenführung dieser Daten mit anderen Datenquellen statt. Grundlage der Datenverarbeitung + bildet Art. 6 Abs. 1 lit. b DSGVO, der die Verarbeitung von Daten zur Erfüllung eines Vertrags oder + vorvertraglicher Maßnahmen gestattet. + </p> - <p><strong>Registrierung auf dieser Website</strong></p> - <p>Zur Nutzung bestimmter Funktionen müssen Sie sich auf unserer Website registrieren. Die übermittelten Daten - dienen ausschließlich zum Zwecke der Nutzung des jeweiligen Angebotes oder Dienstes. Bei der Registrierung - abgefragte Pflichtangaben sind vollständig anzugeben. Andernfalls werden wir die Registrierung ablehnen.</p> - <p>Im Falle wichtiger Änderungen, etwa aus technischen Gründen, informieren wir Sie</p> - <p>Wir speichern die bei der Registrierung erfassten Daten während des Zeitraums, den Sie auf unserer Website - registriert sind. - Gesetzliche Aufbewahrungsfristen bleiben unberührt.</p> + <p><strong>Registrierung auf dieser Website</strong></p> + <p> + Zur Nutzung bestimmter Funktionen müssen Sie sich auf unserer Website registrieren. Die übermittelten Daten + dienen ausschließlich zum Zwecke der Nutzung des jeweiligen Angebotes oder Dienstes. Bei der Registrierung + abgefragte Pflichtangaben sind vollständig anzugeben. Andernfalls werden wir die Registrierung ablehnen. + </p> + <p>Im Falle wichtiger Änderungen, etwa aus technischen Gründen, informieren wir Sie</p> + <p> + Wir speichern die bei der Registrierung erfassten Daten während des Zeitraums, den Sie auf unserer Website + registriert sind. + Gesetzliche Aufbewahrungsfristen bleiben unberührt. + </p> - <p><strong>Speicherdauer von Beiträgen und Kommentaren</strong></p> - <p>Beiträge und Kommentare sowie damit in Verbindung stehende Daten, wie beispielsweise der Benutzername, - werden gespeichert. Der Inhalt verbleibt auf unserer Website, bis er vollständig gelöscht wurde oder aus - rechtlichen Gründen gelöscht werden musste.</p> - <p>Die Speicherung der Beiträge und Kommentare erfolgt auf Grundlage Art. 6 Abs. 1 lit. b DSGVO zur Erfüllung des - Arbeitsvertrages.</p> + <p><strong>Speicherdauer von Beiträgen und Kommentaren</strong></p> + <p> + Beiträge und Kommentare sowie damit in Verbindung stehende Daten, wie beispielsweise der Benutzername, + werden gespeichert. Der Inhalt verbleibt auf unserer Website, bis er vollständig gelöscht wurde oder aus + rechtlichen Gründen gelöscht werden musste. + </p> + <p> + Die Speicherung der Beiträge und Kommentare erfolgt auf Grundlage Art. 6 Abs. 1 lit. b DSGVO zur Erfüllung des + Arbeitsvertrages. + </p> - <p><strong>Session storage</strong></p> - <p>Unsere Website verwendet den Session storage des Browsers. In diesem werden für die Dauer einer Sitzun (Session) - Daten auf Ihrem Endgerät gespeichert.</p> + <p><strong>Session storage</strong></p> + <p> + Unsere Website verwendet den Session storage des Browsers. In diesem werden für die Dauer einer Sitzun (Session) + Daten auf Ihrem Endgerät gespeichert. + </p> - <p><strong>Google Web Fonts</strong></p> - <p>Unsere Website verwendet Web Fonts von Google. Anbieter ist die Google Inc., 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA.</p> - <p>Durch den Einsatz dieser Web Fonts wird es möglich Ihnen die von uns gewünschte Darstellung unserer Website - zu präsentieren, unabhängig davon welche Schriften Ihnen lokal zur Verfügung stehen. Dies erfolgt über - den Abruf der Google Web Fonts von einem Server von Google in den USA und der damit verbundenen Weitergabe - Ihrer Daten an Google. Dabei handelt es sich um Ihre IP-Adresse und welche Seite Sie bei uns besucht haben. - Der Einsatz von Google Web Fonts erfolgt auf Grundlage von Art. 6 Abs. 1 lit. f DSGVO. Als Betreiber dieser - Website haben wir ein berechtigtes Interesse an der optimalen Darstellung und Übertragung unseres Webauftritts.</p> - <p>Das Unternehmen Google ist für das us-europäische Datenschutzübereinkommen "Privacy Shield" zertifiziert. - Dieses Datenschutzübereinkommen soll die Einhaltung des in der EU geltenden Datenschutzniveaus gewährleisten.</p> - <p>Einzelheiten über Google Web Fonts finden Sie unter: - <a href="https://www.google.com/fonts#AboutPlace:about">https://www.google.com/fonts#AboutPlace:about</a> - und weitere Informationen in den Datenschutzbestimmungen von Google: - <a href="https://policies.google.com/privacy/partners?hl=de">https://policies.google.com/privacy/partners?hl=de</a></p> - <p><small>Quelle: Datenschutz-Konfigurator von <a href="http://www.mein-datenschutzbeauftragter.de" target="_blank">mein-datenschutzbeauftragter.de</a></small></p> - </div> + <p><strong>Google Web Fonts</strong></p> + <p>Unsere Website verwendet Web Fonts von Google. Anbieter ist die Google Inc., 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA.</p> + <p> + Durch den Einsatz dieser Web Fonts wird es möglich Ihnen die von uns gewünschte Darstellung unserer Website + zu präsentieren, unabhängig davon welche Schriften Ihnen lokal zur Verfügung stehen. Dies erfolgt über + den Abruf der Google Web Fonts von einem Server von Google in den USA und der damit verbundenen Weitergabe + Ihrer Daten an Google. Dabei handelt es sich um Ihre IP-Adresse und welche Seite Sie bei uns besucht haben. + Der Einsatz von Google Web Fonts erfolgt auf Grundlage von Art. 6 Abs. 1 lit. f DSGVO. Als Betreiber dieser + Website haben wir ein berechtigtes Interesse an der optimalen Darstellung und Übertragung unseres Webauftritts. + </p> + <p> + Das Unternehmen Google ist für das us-europäische Datenschutzübereinkommen "Privacy Shield" zertifiziert. + Dieses Datenschutzübereinkommen soll die Einhaltung des in der EU geltenden Datenschutzniveaus gewährleisten. + </p> + <p> + Einzelheiten über Google Web Fonts finden Sie unter: + <a href="https://www.google.com/fonts#AboutPlace:about">https://www.google.com/fonts#AboutPlace:about</a> + und weitere Informationen in den Datenschutzbestimmungen von Google: + <a href="https://policies.google.com/privacy/partners?hl=de">https://policies.google.com/privacy/partners?hl=de</a> + </p> + <p> + <small>Quelle: Datenschutz-Konfigurator von <a + href="http://www.mein-datenschutzbeauftragter.de" + target="_blank" + >mein-datenschutzbeauftragter.de</a></small> + </p> + </div> </template> <script> diff --git a/frontend/src/components/LabelStatistics.vue b/frontend/src/components/LabelStatistics.vue index 087a8846..446218aa 100644 --- a/frontend/src/components/LabelStatistics.vue +++ b/frontend/src/components/LabelStatistics.vue @@ -1,36 +1,50 @@ <template> <v-card> - <v-card-title class="title">Accumulated Label Statistics</v-card-title> + <v-card-title class="title"> + Accumulated Label Statistics + </v-card-title> <v-data-table - :headers=headers + :headers="headers" :pagination="pagination" :loading="loading" :items="summedLabelCounts" hide-actions > - <template slot="items" slot-scope="props"> + <template + slot="items" + slot-scope="props" + > <td>{{ props.item.name }}</td> - <td class="text-xs-center">{{ props.item.count }}</td> + <td class="text-xs-center"> + {{ props.item.count }} + </td> </template> </v-data-table> - <div v-for="([subType, labelCounts]) in mappedLabelCounts" :key="subType"> + <div + v-for="([subType, labelCounts]) in mappedLabelCounts" + :key="subType" + > <v-card-title class="title"> Statistics for: {{ subType }} </v-card-title> <v-data-table - :headers=headers - :pagination.sync="pagination" - :loading="loading" - :items="labelCounts" - hide-actions - > - <template slot="items" slot-scope="props"> - <td>{{ props.item.name }}</td> - <td class="text-xs-center">{{ props.item.count }}</td> - </template> - </v-data-table> - + :headers="headers" + :pagination.sync="pagination" + :loading="loading" + :items="labelCounts" + hide-actions + > + <template + slot="items" + slot-scope="props" + > + <td>{{ props.item.name }}</td> + <td class="text-xs-center"> + {{ props.item.count }} + </td> + </template> + </v-data-table> </div> </v-card> </template> diff --git a/frontend/src/components/PasswordChangeDialog.vue b/frontend/src/components/PasswordChangeDialog.vue index 71b888d1..bc3763a8 100644 --- a/frontend/src/components/PasswordChangeDialog.vue +++ b/frontend/src/components/PasswordChangeDialog.vue @@ -1,37 +1,52 @@ <template> - <v-dialog v-model="show" width="30%"> - <v-card> - <v-card-title class="title">Change your password</v-card-title> - <v-card-text> - <v-form class="mx-4"> - <v-text-field - label="Current password" - type="password" - v-model="currentPassword" - autofocus - required - /> - <v-text-field - label="New password" - type="password" - v-model="newPassword" - required - /> - <v-text-field - label="Repeat new password" - type="password" - v-model="newPasswordRepeated" - :error-messages="errorMessageRepeat" - required - /> - </v-form> - </v-card-text> - <v-card-actions> - <v-btn @click="submitChange" :disabled="!allowChange">Change password</v-btn> - <v-btn @click="$emit('hide')" color="red">Cancel</v-btn> - </v-card-actions> - </v-card> - </v-dialog> + <v-dialog + v-model="show" + width="30%" + > + <v-card> + <v-card-title class="title"> + Change your password + </v-card-title> + <v-card-text> + <v-form class="mx-4"> + <v-text-field + v-model="currentPassword" + label="Current password" + type="password" + autofocus + required + /> + <v-text-field + v-model="newPassword" + label="New password" + type="password" + required + /> + <v-text-field + v-model="newPasswordRepeated" + label="Repeat new password" + type="password" + :error-messages="errorMessageRepeat" + required + /> + </v-form> + </v-card-text> + <v-card-actions> + <v-btn + :disabled="!allowChange" + @click="submitChange" + > + Change password + </v-btn> + <v-btn + color="red" + @click="$emit('hide')" + > + Cancel + </v-btn> + </v-card-actions> + </v-card> + </v-dialog> </template> <script> @@ -65,6 +80,13 @@ export default { return '' } }, + watch: { + show (val) { + if (!val) { + this.$emit('hide') + } + } + }, methods: { submitChange () { const data = { @@ -91,13 +113,6 @@ export default { }) }) } - }, - watch: { - show (val) { - if (!val) { - this.$emit('hide') - } - } } } </script> diff --git a/frontend/src/components/RegisterDialog.vue b/frontend/src/components/RegisterDialog.vue index b5c1f760..2206d095 100644 --- a/frontend/src/components/RegisterDialog.vue +++ b/frontend/src/components/RegisterDialog.vue @@ -4,10 +4,15 @@ Datenschutzerklärung </v-card-title> <v-card-text> - <GDPRNotice id="gdpr-notice"/> + <GDPRNotice id="gdpr-notice" /> </v-card-text> <v-card-actions> - <v-btn @click="acceptedGDPR = true" id="accept-gdpr-notice">Einwilligen</v-btn> + <v-btn + id="accept-gdpr-notice" + @click="acceptedGDPR = true" + > + Einwilligen + </v-btn> </v-card-actions> </v-card> <v-card v-else> @@ -16,22 +21,29 @@ </v-card-title> <v-card-text> <v-text-field + id="input-register-username" + v-model="credentials.username" label="Username" required autofocus - v-model="credentials.username" - id="input-register-username" /> <v-text-field + id="input-register-password" + v-model="credentials.password" label="Password" required type="password" - v-model="credentials.password" - id="input-register-password" /> </v-card-text> <v-card-actions class="justify-center"> - <v-btn flat :loading="loading" @click="register" id="register-submit">submit</v-btn> + <v-btn + id="register-submit" + flat + :loading="loading" + @click="register" + > + submit + </v-btn> </v-card-actions> </v-card> </template> @@ -41,7 +53,7 @@ import { registerTutor } from '@/api' import GDPRNotice from '@/components/GDPRNotice' export default { - name: 'register-dialog', + name: 'RegisterDialog', components: { GDPRNotice }, data () { return { diff --git a/frontend/src/components/SubmissionTests.vue b/frontend/src/components/SubmissionTests.vue index 65c6882b..daa9a95c 100644 --- a/frontend/src/components/SubmissionTests.vue +++ b/frontend/src/components/SubmissionTests.vue @@ -1,34 +1,51 @@ <template> - <v-card id="submission-tests"> - <v-card-title class="title py-0" v-if="tests.length > 0"> - Tests - <v-spacer/> - <v-btn icon @click="expanded = !expanded"> - <v-icon v-if="expanded">keyboard_arrow_up</v-icon> - <v-icon v-else>keyboard_arrow_down</v-icon> - </v-btn> - </v-card-title> - <v-card-title v-else> - No Tests available - </v-card-title> - <v-card-text v-if="expanded"> - <v-flex sm12 v-for="item in tests" :key="item.pk"> - <div name="test-name-label"> - <v-layout row class="pr-4"> - <h3>{{item.name}}</h3> - <v-spacer/> - <h3>{{item.label}}</h3> - </v-layout> - </div> - <span class="test-output">{{item.annotation}}</span> - </v-flex> - </v-card-text> - </v-card> + <v-card id="submission-tests"> + <v-card-title + v-if="tests.length > 0" + class="title py-0" + > + Tests + <v-spacer /> + <v-btn + icon + @click="expanded = !expanded" + > + <v-icon v-if="expanded"> + keyboard_arrow_up + </v-icon> + <v-icon v-else> + keyboard_arrow_down + </v-icon> + </v-btn> + </v-card-title> + <v-card-title v-else> + No Tests available + </v-card-title> + <v-card-text v-if="expanded"> + <v-flex + v-for="item in tests" + :key="item.pk" + sm12 + > + <div name="test-name-label"> + <v-layout + row + class="pr-4" + > + <h3>{{ item.name }}</h3> + <v-spacer /> + <h3>{{ item.label }}</h3> + </v-layout> + </div> + <span class="test-output">{{ item.annotation }}</span> + </v-flex> + </v-card-text> + </v-card> </template> <script> export default { - name: 'submission-tests', + name: 'SubmissionTests', props: { tests: { type: Array, diff --git a/frontend/src/components/UserOptions.vue b/frontend/src/components/UserOptions.vue index 465288e3..04695831 100644 --- a/frontend/src/components/UserOptions.vue +++ b/frontend/src/components/UserOptions.vue @@ -4,14 +4,18 @@ <template v-for="(opt, i) in userOptions"> <v-list-tile v-if="opt.condition()" - @click="opt.action" :key="i" + @click="opt.action" > - {{opt.display}} + {{ opt.display }} </v-list-tile> </template> </v-list> - <component v-if="displayComponent" :is="displayComponent" @hide="hideComponent"/> + <component + :is="displayComponent" + v-if="displayComponent" + @hide="hideComponent" + /> </div> </template> diff --git a/frontend/src/components/export/DataExport.vue b/frontend/src/components/export/DataExport.vue index 4b4be7cd..ec734f82 100644 --- a/frontend/src/components/export/DataExport.vue +++ b/frontend/src/components/export/DataExport.vue @@ -1,5 +1,9 @@ <template> - <v-dialog v-model="exportDialog" max-width="31vw" @update:returnValue="hide"> + <v-dialog + v-model="exportDialog" + max-width="31vw" + @update:returnValue="hide" + > <v-card id="data-export-modal"> <v-card-title class="title"> Student Data Export @@ -8,10 +12,17 @@ <div v-if="!mapFileLoaded"> If you select a mapping file, the anonymized data will be mapped back automatically and locally on your machine. - <v-layout row align-center> - <file-select v-model="mapFile" display-text="Select map file" class="ma-3"/> + <v-layout + row + align-center + > + <file-select + v-model="mapFile" + display-text="Select map file" + class="ma-3" + /> <span>Without the mapping, the data will still be obfuscated.</span> - </v-layout> + </v-layout> </div> <span> <b>NOTE:</b> Mapping / setting passwords can take some time depending on course size. @@ -20,9 +31,9 @@ <v-flex xs4> <v-tooltip top> <v-checkbox - label="Set passwords" - v-model="setPasswords" slot="activator" + v-model="setPasswords" + label="Set passwords" /> <span>Setting this will cause all student passwords to be reset upon export. The new passwords will be contained in the @@ -30,23 +41,40 @@ </span> </v-tooltip> </v-flex> - <v-flex xs3 offset-xs1 id="type-select"> + <v-flex + id="type-select" + xs3 + offset-xs1 + > <v-select + v-model="exportType" label="Export file format" :items="availableExportTypes" - v-model="exportType" /> </v-flex> </v-layout> <v-card-actions> <v-btn - flat color="blue lighten-2" + flat + color="blue lighten-2" @click="exportDialog = false" - >close</v-btn> - <v-spacer/> - <v-progress-circular v-if="loading" indeterminate/> - <v-btn v-else id="export-data-download-btn" flat outline @click="getExportFile('data')" - >{{mapFile || mapFileLoaded ? 'Download and apply mapping' : 'Download without mapping'}}</v-btn> + > + close + </v-btn> + <v-spacer /> + <v-progress-circular + v-if="loading" + indeterminate + /> + <v-btn + v-else + id="export-data-download-btn" + flat + outline + @click="getExportFile('data')" + > + {{ mapFile || mapFileLoaded ? 'Download and apply mapping' : 'Download without mapping' }} + </v-btn> </v-card-actions> </v-card-text> </v-card> diff --git a/frontend/src/components/export/ExportDialog.vue b/frontend/src/components/export/ExportDialog.vue index a62a099e..86bb10b3 100644 --- a/frontend/src/components/export/ExportDialog.vue +++ b/frontend/src/components/export/ExportDialog.vue @@ -1,19 +1,43 @@ <template> <div> <v-menu offset-y> - <v-tooltip bottom slot="activator"> - <v-btn id="export-btn" :color="exportColor" slot="activator"> + <v-tooltip + slot="activator" + bottom + > + <v-btn + id="export-btn" + slot="activator" + :color="exportColor" + > export <v-icon>file_download</v-icon> </v-btn> - <span id="corrected-tooltip" v-if="corrected">All submissions have been corrected!</span> - <span id="uncorrected-tooltip" v-else>UNCORRECTED submissions left! Export will be incomplete.</span> + <span + v-if="corrected" + id="corrected-tooltip" + >All submissions have been corrected!</span> + <span + v-else + id="uncorrected-tooltip" + >UNCORRECTED submissions left! Export will be incomplete.</span> </v-tooltip> <v-list> - <v-list-tile :id="'export-list' + i" v-for="(item, i) in menuItems" :key="i" @click="item.action">{{item.display}}</v-list-tile> + <v-list-tile + v-for="(item, i) in menuItems" + :id="'export-list' + i" + :key="i" + @click="item.action" + > + {{ item.display }} + </v-list-tile> </v-list> </v-menu> - <component v-if="displayComponent" :is="displayComponent" @hide="displayComponent = null"/> + <component + :is="displayComponent" + v-if="displayComponent" + @hide="displayComponent = null" + /> </div> </template> diff --git a/frontend/src/components/export/InstanceExport.vue b/frontend/src/components/export/InstanceExport.vue index 4cd0378a..c6b0f92f 100644 --- a/frontend/src/components/export/InstanceExport.vue +++ b/frontend/src/components/export/InstanceExport.vue @@ -1,5 +1,9 @@ <template> - <v-dialog v-model="exportDialog" max-width="31vw" @update:returnValue="hide"> + <v-dialog + v-model="exportDialog" + max-width="31vw" + @update:returnValue="hide" + > <v-card id="instance-export-modal"> <v-card-title class="title"> Instance Data Export @@ -8,23 +12,43 @@ <div v-if="!mapFileLoaded"> If you select a mapping file, the anonymized data will be mapped back automatically and locally on your machine. - <v-layout row align-center> - <file-select v-model="mapFile" display-text="Select map file" class="ma-3"/> + <v-layout + row + align-center + > + <file-select + v-model="mapFile" + display-text="Select map file" + class="ma-3" + /> <span>Without the mapping, the data will still be obfuscated.</span> - </v-layout> + </v-layout> </div> <span> <b>NOTE:</b> Mapping can take some time depending on course size. </span> <v-card-actions> <v-btn - flat color="blue lighten-2" + flat + color="blue lighten-2" @click="exportDialog = false" - >close</v-btn> - <v-spacer/> - <v-progress-circular v-if="loading" indeterminate/> - <v-btn v-else id="instance-export-dl" flat outline @click="getExportFile('instance')" - >{{mapFile || mapFileLoaded ? 'Download and apply mapping' : 'Download without mapping'}}</v-btn> + > + close + </v-btn> + <v-spacer /> + <v-progress-circular + v-if="loading" + indeterminate + /> + <v-btn + v-else + id="instance-export-dl" + flat + outline + @click="getExportFile('instance')" + > + {{ mapFile || mapFileLoaded ? 'Download and apply mapping' : 'Download without mapping' }} + </v-btn> </v-card-actions> </v-card-text> </v-card> diff --git a/frontend/src/components/feedback_labels/FeedbackLabel.vue b/frontend/src/components/feedback_labels/FeedbackLabel.vue index 78c17f22..3b16edb6 100644 --- a/frontend/src/components/feedback_labels/FeedbackLabel.vue +++ b/frontend/src/components/feedback_labels/FeedbackLabel.vue @@ -1,11 +1,13 @@ <template> <v-tooltip top> - <v-chip - :close=removable - :color="colour" - slot="activator" - @input="onClose" - > {{ name }} </v-chip> + <v-chip + slot="activator" + :close="removable" + :color="colour" + @input="onClose" + > + {{ name }} + </v-chip> <span> {{ description }} </span> </v-tooltip> </template> diff --git a/frontend/src/components/feedback_labels/FeedbackLabelForm.vue b/frontend/src/components/feedback_labels/FeedbackLabelForm.vue index 5f85acf6..af7acf72 100644 --- a/frontend/src/components/feedback_labels/FeedbackLabelForm.vue +++ b/frontend/src/components/feedback_labels/FeedbackLabelForm.vue @@ -1,25 +1,62 @@ <template> - <v-layout wrap justify-start> - <v-flex ml-3 xs9> - <v-text-field id="label-name" - label="Name" + <v-layout + wrap + justify-start + > + <v-flex + ml-3 + xs9 + > + <v-text-field + id="label-name" v-model="mutableName" + label="Name" /> </v-flex> - <v-flex ml-3 xs9> - <v-textarea id="label-description" - label="Description" + <v-flex + ml-3 + xs9 + > + <v-textarea + id="label-description" v-model="mutableDescription" + label="Description" placeholder="The description can be seen when hovering above the label" auto-grow /> </v-flex> - <v-flex ml-2 xs12> - <compact-picker style="width:85%;box-shadow:none;" v-model="mutableColour"/> + <v-flex + ml-2 + xs12 + > + <compact-picker + v-model="mutableColour" + style="width:85%;box-shadow:none;" + /> </v-flex> - <v-flex ml-1 mb-3 xs4> - <v-btn id="create-label-btn" v-if="!is_update" :loading="loading" color="teal" @click="createLabel">Create</v-btn> - <v-btn id="update-label-btn" v-else color="teal" :loading="loading" @click="updateLabel">Update</v-btn> + <v-flex + ml-1 + mb-3 + xs4 + > + <v-btn + v-if="!is_update" + id="create-label-btn" + :loading="loading" + color="teal" + @click="createLabel" + > + Create + </v-btn> + <v-btn + v-else + id="update-label-btn" + color="teal" + :loading="loading" + @click="updateLabel" + > + Update + </v-btn> </v-flex> </v-layout> </template> diff --git a/frontend/src/components/feedback_labels/FeedbackLabelUpdater.vue b/frontend/src/components/feedback_labels/FeedbackLabelUpdater.vue index 2854b39b..e53c4572 100644 --- a/frontend/src/components/feedback_labels/FeedbackLabelUpdater.vue +++ b/frontend/src/components/feedback_labels/FeedbackLabelUpdater.vue @@ -1,6 +1,9 @@ <template> <v-layout wrap> - <v-flex mx-2 xs12> + <v-flex + mx-2 + xs12 + > <v-autocomplete id="label-update-autocomplete" :items="feedbackLabels" @@ -11,7 +14,10 @@ @input="setLabel" /> </v-flex> - <v-flex xs12 v-if="label.pk !== -1"> + <v-flex + v-if="label.pk !== -1" + xs12 + > <feedback-label-form is_update v-bind="currentLabel" diff --git a/frontend/src/components/feedback_labels/FeedbackLabelsList.vue b/frontend/src/components/feedback_labels/FeedbackLabelsList.vue index 1ec81a02..f2b45b55 100644 --- a/frontend/src/components/feedback_labels/FeedbackLabelsList.vue +++ b/frontend/src/components/feedback_labels/FeedbackLabelsList.vue @@ -1,26 +1,48 @@ <template> <v-card> - <v-toolbar color="teal" :dense="sidebar"> + <v-toolbar + color="teal" + :dense="sidebar" + > <v-toolbar-side-icon> <v-icon>label</v-icon> </v-toolbar-side-icon> - <v-toolbar-title v-if="showDetail" style="min-width: fit-content;"> + <v-toolbar-title + v-if="showDetail" + style="min-width: fit-content;" + > Labels </v-toolbar-title> <v-spacer /> - <v-btn icon @click="refreshLabels"> - <v-icon v-if="!updating">refresh</v-icon> - <v-progress-circular v-else indeterminate color="black" size="20" /> + <v-btn + icon + @click="refreshLabels" + > + <v-icon v-if="!updating"> + refresh + </v-icon> + <v-progress-circular + v-else + indeterminate + color="black" + size="20" + /> </v-btn> </v-toolbar> - <v-tabs grow color="teal lighten-1" v-if="showDetail"> + <v-tabs + v-if="showDetail" + grow + color="teal lighten-1" + > <v-tab>Create</v-tab> - <v-tab id="update-label-section">Update</v-tab> + <v-tab id="update-label-section"> + Update + </v-tab> <v-tab-item> - <feedback-label-form/> + <feedback-label-form /> </v-tab-item> <v-tab-item> - <feedback-label-updater/> + <feedback-label-updater /> </v-tab-item> </v-tabs> </v-card> diff --git a/frontend/src/components/feedback_labels/LabelSelector.vue b/frontend/src/components/feedback_labels/LabelSelector.vue index 63c6549c..c738a7b8 100644 --- a/frontend/src/components/feedback_labels/LabelSelector.vue +++ b/frontend/src/components/feedback_labels/LabelSelector.vue @@ -1,9 +1,12 @@ <template> <v-card> <v-card-title>Assign labels</v-card-title> - <v-divider/> + <v-divider /> <v-layout wrap> - <v-flex ml-2 sm10> + <v-flex + ml-2 + sm10 + > <v-autocomplete id="label-add-autocomplete" :items="feedbackLabels" @@ -15,16 +18,19 @@ @input="addLabel" /> </v-flex> - <v-layout ml-2 mb-3> + <v-layout + ml-2 + mb-3 + > <v-flex sm4> <v-flex sm12> UNCHANGED </v-flex> <feedback-label - removable v-for="label in unchangedMapped" - v-bind="label" :key="label.pk" + removable + v-bind="label" @remove-clicked="removeLabel" /> </v-flex> @@ -33,10 +39,10 @@ WILL BE REMOVED </v-flex> <feedback-label - removable v-for="label in removedMapped" - v-bind="label" :key="label.pk" + removable + v-bind="label" @remove-clicked="addLabel" /> </v-flex> @@ -45,10 +51,10 @@ WILL BE ADDED </v-flex> <feedback-label - removable v-for="label in addedMapped" - v-bind="label" :key="label.pk" + removable + v-bind="label" @remove-clicked="removeLabel" /> </v-flex> diff --git a/frontend/src/components/feedback_list/FeedbackListHelpCard.vue b/frontend/src/components/feedback_list/FeedbackListHelpCard.vue index 9f5ed64e..745d7d75 100644 --- a/frontend/src/components/feedback_list/FeedbackListHelpCard.vue +++ b/frontend/src/components/feedback_list/FeedbackListHelpCard.vue @@ -1,6 +1,9 @@ <template> <v-layout justify-center> - <v-card class="mt-5" v-if="isReviewer"> + <v-card + v-if="isReviewer" + class="mt-5" + > <v-card-title class="title"> This is the history of all the feedback! </v-card-title> @@ -9,7 +12,8 @@ <ol style="padding-left: 30px;"> <li>click on one of the rows to see the submission, including the feedback.</li> <li>sort the table via clicking on the table headers</li> - <li>search the type names and also the <b>content</b> of the feedback that was written<br/> + <li> + search the type names and also the <b>content</b> of the feedback that was written<br> (e.g. you're looking for a feedback where someone mentioned a segmentation fault, just type it into the search!) </li> <li>filter by assigned labels</li> @@ -26,7 +30,8 @@ <ol style="padding-left: 30px;"> <li>click on one of the rows tp see the submission, including your feedback and potentially a second tutor's feedback.</li> <li>sort the table via clicking on the table headers</li> - <li>search the type names and also the <b>content</b> of the feedback that you wrote<br/> + <li> + search the type names and also the <b>content</b> of the feedback that you wrote<br> (e.g. you're looking for a feedback where you mentioned a segmentation fault, just type it into the search!) </li> </ol> diff --git a/frontend/src/components/feedback_list/FeedbackSearchOptions.vue b/frontend/src/components/feedback_list/FeedbackSearchOptions.vue index 3bde9e6f..19601ccc 100644 --- a/frontend/src/components/feedback_list/FeedbackSearchOptions.vue +++ b/frontend/src/components/feedback_list/FeedbackSearchOptions.vue @@ -1,34 +1,51 @@ <template> - <v-layout row wrap> - <v-flex md6 lg3> + <v-layout + row + wrap + > + <v-flex + md6 + lg3 + > <v-checkbox - label="show final" v-model="showFinal" + label="show final" /> </v-flex> - <v-flex md6 lg3> + <v-flex + md6 + lg3 + > <v-checkbox - label="search all comments" v-model="searchOtherUserComments" + label="search all comments" /> </v-flex> - <v-flex md6 lg3> + <v-flex + md6 + lg3 + > <v-checkbox - label="case sensitive" v-model="caseSensitive" + label="case sensitive" /> </v-flex> - <v-flex md6 lg3> + <v-flex + md6 + lg3 + > <v-layout row> <v-checkbox - label="use RegEx" v-model="useRegex" + label="use RegEx" style="max-width: 60%" /> <v-tooltip top> - <a slot="activator" - href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#character-classes" - target="_blank"> + <a + slot="activator" + href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#character-classes" + target="_blank" + > <v-icon>help</v-icon> </a> <span>Go to RegEx documentation</span> @@ -39,20 +56,23 @@ <v-layout row> <v-flex md5> <v-select + v-model="filterByLabels" label="Label" :items="labels" - v-model="filterByLabels" multiple hint="Filter by label" persistent-hint clearable /> </v-flex> - <v-flex md5 offset-md1> + <v-flex + md5 + offset-md1 + > <v-select + v-model="filterByExcludingLabels" label="Exclude label" :items="labels" - v-model="filterByExcludingLabels" multiple hint="Filter by excluding labels" persistent-hint @@ -63,22 +83,31 @@ </v-container> <v-container pa-0> <v-layout row> - <v-flex md12 lg5 v-if="isReviewer"> + <v-flex + v-if="isReviewer" + md12 + lg5 + > <v-select + v-model="filterByTutors" label="Tutors" :items="tutorNames" - v-model="filterByTutors" multiple hint="Filter by tutors" persistent-hint clearable /> </v-flex> - <v-flex md12 lg5 offset-lg1 v-if="filterByTutors.length > 0"> + <v-flex + v-if="filterByTutors.length > 0" + md12 + lg5 + offset-lg1 + > <v-select + v-model="filterByStage" label="Stage" :items="feedbackStages" - v-model="filterByStage" placeholder="All" hint="Filter after initial feedback or validated" persistent-hint diff --git a/frontend/src/components/feedback_list/FeedbackTable.vue b/frontend/src/components/feedback_list/FeedbackTable.vue index 91eebcfa..e3030c81 100644 --- a/frontend/src/components/feedback_list/FeedbackTable.vue +++ b/frontend/src/components/feedback_list/FeedbackTable.vue @@ -2,16 +2,16 @@ <v-card> <v-card-title class="title"> <span v-if="isTutor">Your</span><span>All</span> feedback history - <v-spacer/> + <v-spacer /> <v-text-field + v-model="search" append-icon="search" label="Search" single-line hide-details - v-model="search" /> </v-card-title> - <feedback-search-options class="mx-3"/> + <feedback-search-options class="mx-3" /> <v-data-table :headers="headers" :items="feedback" @@ -20,16 +20,24 @@ :filter="containsSearch" hide-actions > - <template slot="items" slot-scope="props"> - <tr @click="showSubmission(props.item.ofSubmission)" - class="feedback-row" + <template + slot="items" + slot-scope="props" + > + <tr + class="feedback-row" + @click="showSubmission(props.item.ofSubmission)" > - <td>{{props.item.ofSubmissionType}}</td> - <td>{{props.item.score}}</td> - <td>{{new Date(props.item.created).toLocaleString()}}</td> + <td>{{ props.item.ofSubmissionType }}</td> + <td>{{ props.item.score }}</td> + <td>{{ new Date(props.item.created).toLocaleString() }}</td> <td> - <v-icon v-if="props.item.isFinal">check</v-icon> - <v-icon v-else>clear</v-icon> + <v-icon v-if="props.item.isFinal"> + check + </v-icon> + <v-icon v-else> + clear + </v-icon> </td> </tr> </template> diff --git a/frontend/src/components/student/NonFinalFeedbackAlert.vue b/frontend/src/components/student/NonFinalFeedbackAlert.vue index fc58ae20..76c55311 100644 --- a/frontend/src/components/student/NonFinalFeedbackAlert.vue +++ b/frontend/src/components/student/NonFinalFeedbackAlert.vue @@ -1,12 +1,16 @@ <template> - <v-alert type="warning" :value="value" class="non-final-alert "> - This feedback is not final! Changes will likely occur! - </v-alert> + <v-alert + type="warning" + :value="value" + class="non-final-alert " + > + This feedback is not final! Changes will likely occur! + </v-alert> </template> <script> export default { - name: 'non-final-feedback-alert', + name: 'NonFinalFeedbackAlert', props: { value: { type: Boolean, diff --git a/frontend/src/components/student/SubmissionList.vue b/frontend/src/components/student/SubmissionList.vue index bd927b48..61a6a7e4 100644 --- a/frontend/src/components/student/SubmissionList.vue +++ b/frontend/src/components/student/SubmissionList.vue @@ -6,18 +6,31 @@ :items="submissions" item-key="type.pk" > - <template slot="items" slot-scope="props"> + <template + slot="items" + slot-scope="props" + > <td>{{ props.item.type.name }}</td> - <td class="text-xs-right">{{ props.item.feedback ? props.item.feedback.score : 'N/A'}}</td> - <td class="text-xs-right">{{ props.item.type.fullScore }}</td> <td class="text-xs-right"> - <v-btn :to="`/submission/${props.item.type.pk}`" color="orange lighten-2"> + {{ props.item.feedback ? props.item.feedback.score : 'N/A' }} + </td> + <td class="text-xs-right"> + {{ props.item.type.fullScore }} + </td> + <td class="text-xs-right"> + <v-btn + :to="`/submission/${props.item.type.pk}`" + color="orange lighten-2" + > <v-icon>chevron_right</v-icon> </v-btn> </td> </template> </v-data-table> - <v-alert color="info" value="true"> + <v-alert + color="info" + value="true" + > You reached <b>{{ sumScore }}</b> of <b>{{ sumFullScore }}</b> possible points ( {{ pointRatio }}% ). </v-alert> </div> @@ -25,7 +38,13 @@ <script> export default { - name: 'submission-list', + name: 'SubmissionList', + props: { + submissions: { + type: Array, + required: true + } + }, data () { return { headers: [ @@ -53,12 +72,6 @@ export default { ] } }, - props: { - submissions: { - type: Array, - required: true - } - }, computed: { sumScore () { return this.submissions.map(a => a.feedback && a.feedback.score).reduce((a, b) => a + b) diff --git a/frontend/src/components/student_list/StudentList.vue b/frontend/src/components/student_list/StudentList.vue index 626dd494..c55cca60 100644 --- a/frontend/src/components/student_list/StudentList.vue +++ b/frontend/src/components/student_list/StudentList.vue @@ -4,18 +4,23 @@ <span class="title"> Participants </span> - <student-list-reverse-mapper class="ml-4"/> - <v-spacer/> + <student-list-reverse-mapper class="ml-4" /> + <v-spacer /> <v-text-field + v-model="search" append-icon="search" label="Search" single-line hide-details - v-model="search" - ></v-text-field> + /> <v-card-actions> - <v-btn icon @click="refresh"><v-icon>refresh</v-icon></v-btn> - <student-list-menu/> + <v-btn + icon + @click="refresh" + > + <v-icon>refresh</v-icon> + </v-btn> + <student-list-menu /> </v-card-actions> </v-card-title> <v-data-table @@ -27,10 +32,14 @@ item-key="name" hide-actions > - <template slot="headers" slot-scope="props"> + <template + slot="headers" + slot-scope="props" + > <tr> <th - v-for="(header, i) in props.headers" :key="i" + v-for="(header, i) in props.headers" + :key="i" :class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']" style="padding: 0;" @click="changeSort(header.value)" @@ -40,18 +49,39 @@ </th> </tr> </template> - <template slot="items" slot-scope="props"> + <template + slot="items" + slot-scope="props" + > <tr> <td> - <v-btn small icon @click="props.expanded = !props.expanded"> - <v-icon v-if="props.expanded">keyboard_arrow_up</v-icon> - <v-icon v-else>keyboard_arrow_down</v-icon> + <v-btn + small + icon + @click="props.expanded = !props.expanded" + > + <v-icon v-if="props.expanded"> + keyboard_arrow_up + </v-icon> + <v-icon v-else> + keyboard_arrow_down + </v-icon> </v-btn> - {{props.item.name}} + {{ props.item.name }} <v-tooltip top> <template slot="activator"> - <v-icon small v-if="!props.item.isActive">lock</v-icon> - <v-icon small v-else>lock_open</v-icon> + <v-icon + v-if="!props.item.isActive" + small + > + lock + </v-icon> + <v-icon + v-else + small + > + lock_open + </v-icon> </template> <span v-if="!props.item.isActive">Participant doesn't have access.</span> <span v-else>Participant has access.</span> @@ -59,43 +89,51 @@ </td> <td v-for="type in submissionTypeHeaders" - style="padding: 0" :key="type.pk" + style="padding: 0" class="text-xs-right" > <v-btn - small round outline class="submission-button" - exact v-if="props.item[type.pk]" - v-on:click="showSubmissionDetails" + small + round + outline + class="submission-button" + exact :to="{name: 'submission-side-view', params: { studentPk: props.item.pk, submissionPk: props.item[type.pk].pk - }}" + }}" :color="props.item[type.pk].final ? 'green darken-2' : 'grey'" + @click="showSubmissionDetails" > - {{props.item[type.pk].score}} + {{ props.item[type.pk].score }} </v-btn> <span v-else>N.A</span> </td> <td style="padding: 0 15px;" class="text-xs-right" - >{{props.item.total}}</td> + > + {{ props.item.total }} + </td> </tr> </template> - <template slot="expand" slot-scope="props"> + <template + slot="expand" + slot-scope="props" + > <v-card flat> <v-card-text> <v-btn @click="changeActiveStatus(props.item)"> - {{props.item.isActive ? 'Revoke access' : 'Grant access'}} + {{ props.item.isActive ? 'Revoke access' : 'Grant access' }} </v-btn> <ul class="student-info-list"> <li> - <b>Modul:</b> {{props.item.exam}} + <b>Modul:</b> {{ props.item.exam }} </li> <li> - <b>MatrikelNr:</b> {{props.item.matrikelNo}} + <b>MatrikelNr:</b> {{ props.item.matrikelNo }} </li> </ul> </v-card-text> @@ -113,10 +151,10 @@ import { changeActiveForUser } from '@/api' import { getters } from '@/store/getters' export default { + name: 'StudentList', components: { StudentListReverseMapper, StudentListMenu }, - name: 'student-list', data () { return { loading: true, @@ -181,6 +219,9 @@ export default { return {} } }, + created () { + this.getStudents().then(() => { this.loading = false }) + }, methods: { ...mapActions([ 'getStudents' @@ -229,9 +270,6 @@ export default { this.$emit('detail-click') } }, - created () { - this.getStudents().then(() => { this.loading = false }) - } } </script> diff --git a/frontend/src/components/student_list/StudentListHelpCard.vue b/frontend/src/components/student_list/StudentListHelpCard.vue index 79f156cd..9ff4de2c 100644 --- a/frontend/src/components/student_list/StudentListHelpCard.vue +++ b/frontend/src/components/student_list/StudentListHelpCard.vue @@ -20,7 +20,7 @@ <script> export default { - name: 'student-list-help-card' + name: 'StudentListHelpCard' } </script> diff --git a/frontend/src/components/student_list/StudentListMenu.vue b/frontend/src/components/student_list/StudentListMenu.vue index 85905bce..4b60c8f1 100644 --- a/frontend/src/components/student_list/StudentListMenu.vue +++ b/frontend/src/components/student_list/StudentListMenu.vue @@ -1,10 +1,21 @@ <template> - <v-menu open-on-hover bottom offset-y> - <v-btn icon slot="activator"> + <v-menu + open-on-hover + bottom + offset-y + > + <v-btn + slot="activator" + icon + > <v-icon>menu</v-icon> </v-btn> <v-list> - <v-list-tile v-for="item in items" :key="item.title" @click="item.action"> + <v-list-tile + v-for="item in items" + :key="item.title" + @click="item.action" + > <v-list-tile-title>{{ item.title }}</v-list-tile-title> </v-list-tile> </v-list> @@ -17,7 +28,7 @@ import { activateAllStudentAccess, import { actions } from '@/store/actions' export default { - name: 'student-list-menu', + name: 'StudentListMenu', computed: { studentsActive () { const firstStudent = Object.values(this.$store.state.students)[0] diff --git a/frontend/src/components/student_list/StudentListReverseMapper.vue b/frontend/src/components/student_list/StudentListReverseMapper.vue index c0119eff..0f647636 100644 --- a/frontend/src/components/student_list/StudentListReverseMapper.vue +++ b/frontend/src/components/student_list/StudentListReverseMapper.vue @@ -1,9 +1,16 @@ <template> - <v-layout row align-center> - <file-select v-model="file" display-text="Select map file"/> + <v-layout + row + align-center + > + <file-select + v-model="file" + display-text="Select map file" + /> <v-tooltip top> <v-btn - icon slot="activator" + slot="activator" + icon @click="readMapFileAndApply" > <v-icon>vpn_key</v-icon> @@ -18,8 +25,8 @@ import FileSelect from '@/components/util/FileSelect' import parseCSVMapMixin from '@/components/mixins/parseCSVMapMixin' export default { + name: 'StudentListReverseMapper', components: { FileSelect }, - name: 'student-list-reverse-mapper', mixins: [parseCSVMapMixin], data () { return { diff --git a/frontend/src/components/submission_notes/CorrectionHelpCard.vue b/frontend/src/components/submission_notes/CorrectionHelpCard.vue index 93d74c6e..0be45efe 100644 --- a/frontend/src/components/submission_notes/CorrectionHelpCard.vue +++ b/frontend/src/components/submission_notes/CorrectionHelpCard.vue @@ -1,33 +1,32 @@ <template> - <v-card class="help-card"> - <v-card-title> - <v-icon>help_outline</v-icon> - <h3>Tips on using the correction interface</h3> - </v-card-title> - <v-card-text> - Never trade an ale. - The sea-dog leads with yellow fever, crush the captain's quarters until it waves.<br> - Ho-ho-ho! malaria of life.<br> - Halitosis, adventure, and yellow fever.<br> - The girl drinks with halitosis, pull the galley before it laughs.<br> - The moon fires with life, vandalize the bikini atoll before it travels.<br> - The tuna blows with fight, haul the freighter before it whines.<br> - The cannibal robs with hunger, fire the lighthouse until it whines.<br> - The captain loves with death, vandalize the lighthouse before it whines.<br> - The anchor loots with treasure, raid the freighter before it grows.<br> - The reef commands with endurance, view the quarter-deck until it whines.<br> - The scallywag loots with passion, crush the bikini atoll before it falls.<br> - The sea leads with treasure, ransack the brig until it dies.<br> - The parrot robs with desolation, view the seychelles before it screams.<br> - The warm anchor quirky blows the landlubber.<br> - - </v-card-text> - </v-card> + <v-card class="help-card"> + <v-card-title> + <v-icon>help_outline</v-icon> + <h3>Tips on using the correction interface</h3> + </v-card-title> + <v-card-text> + Never trade an ale. + The sea-dog leads with yellow fever, crush the captain's quarters until it waves.<br> + Ho-ho-ho! malaria of life.<br> + Halitosis, adventure, and yellow fever.<br> + The girl drinks with halitosis, pull the galley before it laughs.<br> + The moon fires with life, vandalize the bikini atoll before it travels.<br> + The tuna blows with fight, haul the freighter before it whines.<br> + The cannibal robs with hunger, fire the lighthouse until it whines.<br> + The captain loves with death, vandalize the lighthouse before it whines.<br> + The anchor loots with treasure, raid the freighter before it grows.<br> + The reef commands with endurance, view the quarter-deck until it whines.<br> + The scallywag loots with passion, crush the bikini atoll before it falls.<br> + The sea leads with treasure, ransack the brig until it dies.<br> + The parrot robs with desolation, view the seychelles before it screams.<br> + The warm anchor quirky blows the landlubber.<br> + </v-card-text> + </v-card> </template> <script> export default { - name: 'correction-help-card' + name: 'CorrectionHelpCard' } </script> diff --git a/frontend/src/components/submission_notes/RouteChangeConfirmation.vue b/frontend/src/components/submission_notes/RouteChangeConfirmation.vue index 9abcee3b..098f72f7 100644 --- a/frontend/src/components/submission_notes/RouteChangeConfirmation.vue +++ b/frontend/src/components/submission_notes/RouteChangeConfirmation.vue @@ -1,28 +1,41 @@ <template> - <v-dialog - v-model="dialog" - max-width="30%" - > - <v-card class="text-xs-center"> - <v-card-title class="title"> - Are you sure? - </v-card-title> - <v-card-text> - Not submitted feedback will be lost! - </v-card-text> - <v-card-actions> - <v-btn flat outline color="red lighten-1" @click="changeRoute">Change page</v-btn> - <v-btn flat outline @click="dialog = false">Stay here</v-btn> - </v-card-actions> - </v-card> - </v-dialog> + <v-dialog + v-model="dialog" + max-width="30%" + > + <v-card class="text-xs-center"> + <v-card-title class="title"> + Are you sure? + </v-card-title> + <v-card-text> + Not submitted feedback will be lost! + </v-card-text> + <v-card-actions> + <v-btn + flat + outline + color="red lighten-1" + @click="changeRoute" + > + Change page + </v-btn> + <v-btn + flat + outline + @click="dialog = false" + > + Stay here + </v-btn> + </v-card-actions> + </v-card> + </v-dialog> </template> <script> import { SubmissionNotes } from '@/store/modules/submission-notes' export default { - name: 'route-change-confirmation', + name: 'RouteChangeConfirmation', props: { nextRoute: { type: Function, @@ -34,12 +47,6 @@ export default { dialog: false } }, - methods: { - changeRoute () { - this.nextRoute() - this.dialog = false - } - }, watch: { nextRoute (newVal, oldVal) { if (newVal !== oldVal && SubmissionNotes.workInProgress) { @@ -48,6 +55,12 @@ export default { this.nextRoute() } } + }, + methods: { + changeRoute () { + this.nextRoute() + this.dialog = false + } } } </script> diff --git a/frontend/src/components/submission_notes/SubmissionCorrection.vue b/frontend/src/components/submission_notes/SubmissionCorrection.vue index b18d3df9..aae712a2 100644 --- a/frontend/src/components/submission_notes/SubmissionCorrection.vue +++ b/frontend/src/components/submission_notes/SubmissionCorrection.vue @@ -2,11 +2,18 @@ <div> <base-annotated-submission> <annotated-submission-top-toolbar - class="mb-1 elevation-1" slot="header" + class="mb-1 elevation-1" /> - <template slot="table-content" id='sub-lines'> - <tr v-for="(code, lineNo) in submission" :key="`${submissionObj.pk}${lineNo}`" :id="`sub-line-${lineNo}`"> + <template + id="sub-lines" + slot="table-content" + > + <tr + v-for="(code, lineNo) in submission" + :id="`sub-line-${lineNo}`" + :key="`${submissionObj.pk}${lineNo}`" + > <submission-line :hint="hasHiddenComment(lineNo)" :code="code" @@ -17,10 +24,10 @@ <div v-if="origFeedback[lineNo]"> <feedback-comment v-for="(comment, index) in getSortedComments(lineNo)" + :key="index" v-bind="comment" - :visibleToStudent="updatedFeedback[lineNo] ? false : comment.visibleToStudent" + :visible-to-student="updatedFeedback[lineNo] ? false : comment.visibleToStudent" :line-no="lineNo" - :key="index" :deletable="comment.ofTutor === user || isReviewer" @click.native="toggleEditorOnLine(lineNo, comment)" /> @@ -36,24 +43,23 @@ <comment-form v-if="showEditorOnLine[lineNo]" :feedback="selectedComment[lineNo].text" - :lineNo="lineNo" + :line-no="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" + :assigned-to-feedback="true" + class="mt-1 elevation-1" /> <annotated-submission-bottom-toolbar - class="mt-1 elevation-1" slot="footer" + class="mt-1 elevation-1" :loading="loading" - :fullScore="submissionObj['fullScore']" + :full-score="submissionObj['fullScore']" :skippable="assignment !== undefined" :feedback="feedbackObj ? feedbackObj : {}" @submitFeedback="submitFeedback" @@ -79,6 +85,7 @@ import { actions } from '@/store/actions' import { fetchFeedback } from '@/api' export default { + name: 'SubmissionCorrection', components: { SubmissionLine, BaseAnnotatedSubmission, @@ -87,22 +94,18 @@ export default { FeedbackComment, LabelSelector, CommentForm }, - name: 'submission-correction', - data () { - return { - loading: false, - feedbackShortPollInterval: null - } - }, props: { assignment: { + default: () => {}, type: Object }, // either pass in an assignment or a submission and feedback submissionWithoutAssignment: { + default: () => {}, type: Object }, feedback: { + default: () => {}, type: Object }, ignoreHiddenState: { @@ -110,6 +113,12 @@ export default { default: false, } }, + data () { + return { + loading: false, + feedbackShortPollInterval: null + } + }, computed: { showEditorOnLine () { return SubmissionNotes.state.ui.showEditorOnLine }, selectedComment () { return SubmissionNotes.state.ui.selectedCommentOnLine }, @@ -133,6 +142,21 @@ export default { return this.assignment ? this.assignment.feedback : this.feedback } }, + watch: { + assignment: function (newVar, oldVar) { + this.init() + }, + submissionWithoutAssignment: function () { + this.init() + } + }, + created () { + this.init() + this.shortPollOrigFeedback() + }, + beforeDestroy () { + clearInterval(this.feedbackShortPollInterval) + }, methods: { toggleEditorOnLine (lineNo, comment = '') { SubmissionNotes.TOGGLE_EDITOR_ON_LINE({ lineNo, comment }) @@ -194,21 +218,6 @@ export default { 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> diff --git a/frontend/src/components/submission_notes/base/BaseAnnotatedSubmission.vue b/frontend/src/components/submission_notes/base/BaseAnnotatedSubmission.vue index 267fe57b..9cb5de21 100644 --- a/frontend/src/components/submission_notes/base/BaseAnnotatedSubmission.vue +++ b/frontend/src/components/submission_notes/base/BaseAnnotatedSubmission.vue @@ -1,17 +1,17 @@ <template> <div> - <slot name="header"/> + <slot name="header" /> <table class="submission-table elevation-1"> - <slot name="table-content"/> + <slot name="table-content" /> </table> - <slot name="labels"/> - <slot name="footer"/> + <slot name="labels" /> + <slot name="footer" /> </div> </template> <script> export default { - name: 'base-annotated-submission' + name: 'BaseAnnotatedSubmission' } </script> diff --git a/frontend/src/components/submission_notes/base/CommentForm.vue b/frontend/src/components/submission_notes/base/CommentForm.vue index 58d17f69..57dac519 100644 --- a/frontend/src/components/submission_notes/base/CommentForm.vue +++ b/frontend/src/components/submission_notes/base/CommentForm.vue @@ -1,36 +1,60 @@ <template> <v-layout wrap> - <v-flex lg12 md12 sm12 mr-1> + <v-flex + lg12 + md12 + sm12 + mr-1 + > <v-textarea + v-model="currentFeedback" name="feedback-input" label="Please provide your feedback here" - v-model="currentFeedback" - @keyup.enter.ctrl.exact="submitFeedback" - @keyup.esc="collapseTextField" - @focus="selectInput($event)" rows="2" outline autofocus auto-grow hide-details + @keyup.enter.ctrl.exact="submitFeedback" + @keyup.esc="collapseTextField" + @focus="selectInput($event)" /> </v-flex> - <v-flex lg10 md8 sm8 my-2> + <v-flex + lg10 + md8 + sm8 + my-2 + > <label-selector id="comment-label-selector" - :assignedToFeedback="false" - :lineNo="this.lineNo" - :labelsUnchanged="labelsUnchanged" - :labelsAdded="labelsAdded" - :labelsRemoved="labelsRemoved" + :assigned-to-feedback="false" + :line-no="lineNo" + :labels-unchanged="labelsUnchanged" + :labels-added="labelsAdded" + :labels-removed="labelsRemoved" @label-added="labelAdded" @label-removed="labelRemoved" @submit-shortcut="submitFeedback" /> </v-flex> - <v-flex lg2 ma-0> - <v-btn id="submit-comment" color="success" @click="submitFeedback"><v-icon>check</v-icon>Submit</v-btn> - <v-btn id="cancel-comment" @click="collapseTextField"><v-icon>cancel</v-icon>cancel</v-btn> + <v-flex + lg2 + ma-0 + > + <v-btn + id="submit-comment" + color="success" + @click="submitFeedback" + > + <v-icon>check</v-icon>Submit + </v-btn> + <v-btn + id="cancel-comment" + @click="collapseTextField" + > + <v-icon>cancel</v-icon>cancel + </v-btn> </v-flex> </v-layout> </template> diff --git a/frontend/src/components/submission_notes/base/FeedbackComment.vue b/frontend/src/components/submission_notes/base/FeedbackComment.vue index 9991220c..26c63771 100644 --- a/frontend/src/components/submission_notes/base/FeedbackComment.vue +++ b/frontend/src/components/submission_notes/base/FeedbackComment.vue @@ -1,47 +1,88 @@ <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"> + <div + v-if="commentDisplayable" + class="body elevation-1" + :style="{borderColor: borderColor, backgroundColor}" + > + <span + class="tip tip-up" + :style="{borderBottomColor: borderColor}" + /> + <span + v-if="ofTutor" + class="of-tutor" + >Of tutor: {{ ofTutor }}</span> + <span class="comment-created">{{ parsedCreated }}</span> + <div + v-if="showVisibilityIcon" + class="visibility-icon" + > + <v-tooltip + v-if="visibleToStudent" + top + size="20px" + > <v-icon slot="activator" size="20px" - >visibility</v-icon> + > + visibility + </v-icon> <span>Will be visible to student</span> </v-tooltip> - <v-tooltip top v-else> + <v-tooltip + v-else + top + > <v-icon slot="activator" - size="20px">visibility_off</v-icon> + size="20px" + > + visibility_off + </v-icon> <span>Won't be visible to student</span> </v-tooltip> </div> - <div class="message">{{text}}</div> + <div class="message"> + {{ text }} + </div> <v-btn - flat icon absolute - class="delete-button" v-if="deletable" + flat + icon + absolute + class="delete-button" @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-if="!markedForDeletion.hasOwnProperty(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 && correctorView" ml-2> + <v-layout + v-if="showLabels && correctorView" + 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" + removable + v-bind="label" @remove-clicked="deleteAction" /> </v-flex> @@ -50,10 +91,10 @@ WILL BE REMOVED </v-flex> <feedback-label - removable v-for="label in removedLabels" - v-bind="label" :key="label.pk" + removable + v-bind="label" @remove-clicked="deleteAction" /> </v-flex> @@ -62,23 +103,34 @@ WILL BE ADDED </v-flex> <feedback-label - removable v-for="label in addedLabels" - v-bind="label" :key="label.pk" + removable + v-bind="label" @remove-clicked="deleteAction" /> </v-flex> </v-layout> - <template row wrap v-if="!correctorView" align-center> - <v-layout row wrap align-center v-for="label in unchangedLabels" :key="label.pk"> + <template + v-if="!correctorView" + row + wrap + align-center + > + <v-layout + v-for="label in unchangedLabels" + :key="label.pk" + row + wrap + align-center + > <v-flex sm6> - <feedback-label + <feedback-label v-bind="label" /> </v-flex> <v-flex sm6> - <span><b>Description: </b>{{label.description}}</span> + <span><b>Description: </b>{{ label.description }}</span> </v-flex> </v-layout> </template> @@ -94,7 +146,7 @@ import { FeedbackLabels as Labels } from '@/store/modules/feedback-labels' import commentLabelSelector from '@/components/mixins/commentLabelSelector' export default { - name: 'feedback-comment', + name: 'FeedbackComment', components: { FeedbackLabel, }, @@ -103,6 +155,7 @@ export default { ], props: { pk: { + default: '', type: String, required: false }, @@ -111,10 +164,12 @@ export default { required: true }, modified: { + default: '', type: String, required: false }, ofTutor: { + default: '', type: String, required: false }, diff --git a/frontend/src/components/submission_notes/base/SubmissionLine.vue b/frontend/src/components/submission_notes/base/SubmissionLine.vue index 3bad6a50..7cf21589 100644 --- a/frontend/src/components/submission_notes/base/SubmissionLine.vue +++ b/frontend/src/components/submission_notes/base/SubmissionLine.vue @@ -2,7 +2,8 @@ <div> <td :style="backgroundColor" - class="line-number-cell"> + class="line-number-cell" + > <v-btn flat block @@ -14,15 +15,16 @@ </v-btn> </td> <td class="code-cell-content pl-2"> - <span v-html="code" class="code-line"></span> - <slot/> + <!-- eslint-disable-next-line --> + <span class="code-line" v-html="code"/> + <slot /> </td> </div> </template> <script> export default { - name: 'submission-line', + name: 'SubmissionLine', props: { lineNo: { type: String, diff --git a/frontend/src/components/submission_notes/toolbars/AnnotatedSubmissionBottomToolbar.vue b/frontend/src/components/submission_notes/toolbars/AnnotatedSubmissionBottomToolbar.vue index 87508460..3e9e3c96 100644 --- a/frontend/src/components/submission_notes/toolbars/AnnotatedSubmissionBottomToolbar.vue +++ b/frontend/src/components/submission_notes/toolbars/AnnotatedSubmissionBottomToolbar.vue @@ -3,63 +3,109 @@ <template> <v-container class="bottom-container"> <v-layout wrap> - <v-flex sm4 md4 lg2> - <v-tooltip top v-if="skippable"> - <v-btn slot="activator" outline round - id="skip-submission" - color="grey darken-2" - @click="skipSubmission">Skip</v-btn> + <v-flex + sm4 + md4 + lg2 + > + <v-tooltip + v-if="skippable" + top + > + <v-btn + id="skip-submission" + slot="activator" + outline + round + color="grey darken-2" + @click="skipSubmission" + > + Skip + </v-btn> <span>Skip this submission</span> </v-tooltip> <v-spacer /> </v-flex> <v-flex> - <v-layout wrap class="score-submit-container"> - <v-flex xs5 class="score-flex"> + <v-layout + wrap + class="score-submit-container" + > + <v-flex + xs5 + class="score-flex" + > <span class="mr-2">Score:</span> - <input class="score-text-field" - v-shortkey="'numeric'" @shortkey="handleKeypress" - id="score-input" - type="number" - step="0.5" - v-model="score" - @input="validateScore" - @change="validateScore" /> - <span> / {{fullScore}}</span> - <v-btn outline round flat - id="score-zero" - class="score-button" - @click="score=0" - color="red lighten-1">0 + <input + id="score-input" + v-model="score" + v-shortkey="'numeric'" + class="score-text-field" + type="number" + step="0.5" + @shortkey="handleKeypress" + @input="validateScore" + @change="validateScore" + > + <span> / {{ fullScore }}</span> + <v-btn + id="score-zero" + outline + round + flat + class="score-button" + color="red lighten-1" + @click="score=0" + > + 0 </v-btn> - <v-btn outline round flat - id="score-full" - @click="score=fullScore" - color="blue darken-3" - class="score-button">{{fullScore}} + <v-btn + id="score-full" + outline + round + flat + color="blue darken-3" + class="score-button" + @click="score=fullScore" + > + {{ fullScore }} </v-btn> </v-flex> - <v-flex class="submit-flex" xs3 sm3> + <v-flex + class="submit-flex" + xs3 + sm3 + > <v-layout> <v-flex xs4> - <v-tooltip top v-if="showFinalCheckbox"> - <v-toolbar-items class="final-container" - slot="activator"> + <v-tooltip + v-if="showFinalCheckbox" + top + > + <v-toolbar-items + slot="activator" + class="final-container" + > <label>Final</label> - <v-checkbox slot="activator" - v-model="isFinal" - class="final-checkbox" /> + <v-checkbox + slot="activator" + v-model="isFinal" + class="final-checkbox" + /> </v-toolbar-items> <span>If unchecked this submission will be marked for review by the lecturer</span> </v-tooltip> </v-flex> <v-flex xs> <v-tooltip top> - <v-btn color="success" - id="submit-feedback" - slot="activator" - :loading="loading" - @click="submit">Submit + <v-btn + id="submit-feedback" + slot="activator" + color="success" + :loading="loading" + @click="submit" + > + Submit <v-icon>chevron_right</v-icon> </v-btn> <span>Submit and continue</span> @@ -70,10 +116,14 @@ </v-layout> </v-flex> <v-flex v-if="scoreError"> - <v-alert class="score-alert ma-3" - color="error" - icon="warning" - :value="scoreError">{{ scoreError }}</v-alert> + <v-alert + class="score-alert ma-3" + color="error" + icon="warning" + :value="scoreError" + > + {{ scoreError }} + </v-alert> </v-flex> </v-layout> </v-container> @@ -85,13 +135,7 @@ import { Authentication } from '@/store/modules/authentication' import { Subscriptions } from '@/store/modules/subscriptions' export default { - name: 'annotated-submission-bottom-toolbar', - data () { - return { - scoreError: '', - isFinal: this.initialFinalStatus() - } - }, + name: 'AnnotatedSubmissionBottomToolbar', props: { fullScore: { type: Number, @@ -110,6 +154,12 @@ export default { default: () => {} } }, + data () { + return { + scoreError: '', + isFinal: this.initialFinalStatus() + } + }, computed: { score: { get: function () { diff --git a/frontend/src/components/submission_notes/toolbars/AnnotatedSubmissionTopToolbar.vue b/frontend/src/components/submission_notes/toolbars/AnnotatedSubmissionTopToolbar.vue index e9f103d5..050eab90 100644 --- a/frontend/src/components/submission_notes/toolbars/AnnotatedSubmissionTopToolbar.vue +++ b/frontend/src/components/submission_notes/toolbars/AnnotatedSubmissionTopToolbar.vue @@ -1,25 +1,29 @@ <template> <v-toolbar - dense> + dense + > <v-toolbar-side-icon @click.stop="helpDialog=true"> - <v-icon>help_outline</v-icon> + <v-icon>help_outline</v-icon> </v-toolbar-side-icon> <v-dialog + v-model="helpDialog" scrollable max-width="fit-content" - v-model="helpDialog" > - <correction-help-card/> + <correction-help-card /> </v-dialog> <span class="title">Participant submission</span> - <toggle-feedback-visibility-button/> - <v-spacer/> + <toggle-feedback-visibility-button /> + <v-spacer /> <v-tooltip top> <v-btn - icon slot="activator" + slot="activator" + icon @click="copyToClipboard" - ><v-icon>content_copy</v-icon></v-btn> - <span>{{copyMessage}}</span> + > + <v-icon>content_copy</v-icon> + </v-btn> + <span>{{ copyMessage }}</span> </v-tooltip> </v-toolbar> </template> @@ -31,10 +35,10 @@ import ToggleFeedbackVisibilityButton from '@/components/submission_notes/toolba import { SubmissionNotes } from '@/store/modules/submission-notes' export default { + name: 'AnnotatedSubmissionTopToolbar', components: { ToggleFeedbackVisibilityButton, CorrectionHelpCard }, - name: 'annotated-submission-top-toolbar', data () { return { helpDialog: false, diff --git a/frontend/src/components/submission_notes/toolbars/ToggleFeedbackVisibilityButton.vue b/frontend/src/components/submission_notes/toolbars/ToggleFeedbackVisibilityButton.vue index a74985a2..c06f3d3e 100644 --- a/frontend/src/components/submission_notes/toolbars/ToggleFeedbackVisibilityButton.vue +++ b/frontend/src/components/submission_notes/toolbars/ToggleFeedbackVisibilityButton.vue @@ -1,7 +1,16 @@ <template> - <v-btn id="feedback-visibility-toggle" flat color="info" @click="showFeedback = !showFeedback"> - <div v-if="showFeedback"> Hide Feedback</div> - <div v-else> Show Feedback</div> + <v-btn + id="feedback-visibility-toggle" + flat + color="info" + @click="showFeedback = !showFeedback" + > + <div v-if="showFeedback"> + Hide Feedback + </div> + <div v-else> + Show Feedback + </div> </v-btn> </template> diff --git a/frontend/src/components/submission_type/SubmissionType.vue b/frontend/src/components/submission_type/SubmissionType.vue index 1ee5177e..b42450f5 100644 --- a/frontend/src/components/submission_type/SubmissionType.vue +++ b/frontend/src/components/submission_type/SubmissionType.vue @@ -1,8 +1,13 @@ <template> <v-layout column> <v-card id="submission-type"> - <v-card-title class="title mb-2">{{ name }} - Full score: {{ fullScore }}</v-card-title> - <v-expansion-panel expand v-model="expanded"> + <v-card-title class="title mb-2"> + {{ name }} - Full score: {{ fullScore }} + </v-card-title> + <v-expansion-panel + v-model="expanded" + expand + > <v-expansion-panel-content v-for="(item, i) in typeItems" :key="i" @@ -10,32 +15,32 @@ <div slot="header"> <b>{{ item.title }}</b> <v-btn + v-if="item.title == 'Solution'" class="ml-5" color="info" flat - v-if="item.title == 'Solution'" @click.stop="showSolutionComments = !showSolutionComments" - >Toggle Comments</v-btn> + > + Toggle Comments + </v-btn> </div> <v-card v-if="item.title === 'Description'" class="type-description" > <v-card-text class="ml-2"> - <span - v-html="item.text" - ></span> + <!-- eslint-disable-next-line --> + <span v-html="item.text"/> </v-card-text> </v-card> <div v-else-if="item.title === 'Solution'"> <solution - :pk=pk - :solution=solution - :programmingLanguage=programmingLanguage - :solutionComments=solutionComments - :showSolutionComments=showSolutionComments - > - </solution> + :pk="pk" + :solution="solution" + :programming-language="programmingLanguage" + :solution-comments="solutionComments" + :show-solution-comments="showSolutionComments" + /> </div> </v-expansion-panel-content> </v-expansion-panel> diff --git a/frontend/src/components/submission_type/SubmissionTypesOverview.vue b/frontend/src/components/submission_type/SubmissionTypesOverview.vue index 4280ca90..4c1730b6 100644 --- a/frontend/src/components/submission_type/SubmissionTypesOverview.vue +++ b/frontend/src/components/submission_type/SubmissionTypesOverview.vue @@ -1,26 +1,39 @@ <template> <v-card> - <v-card-title class="title">Task types</v-card-title> - <v-layout row wrap> - <v-flex xs3> - <v-list id="submission-types-list"> - <v-list-tile - v-for="submissionType in sortedSubmissionTypes" :key="submissionType.pk" - @click="selectedSubmissionType = submissionType" - > - <v-list-tile-content> - {{submissionType.name}} - </v-list-tile-content> - </v-list-tile> - </v-list> - </v-flex> - <v-flex xs9> - <v-layout v-if="!selectedSubmissionType" justify-center> - <strong>Select a task type on the left to see the description and solution.</strong> - </v-layout> - <submission-type class="mr-2 mb-2" v-else v-bind="selectedSubmissionType"/> - </v-flex> - </v-layout> + <v-card-title class="title"> + Task types + </v-card-title> + <v-layout + row + wrap + > + <v-flex xs3> + <v-list id="submission-types-list"> + <v-list-tile + v-for="submissionType in sortedSubmissionTypes" + :key="submissionType.pk" + @click="selectedSubmissionType = submissionType" + > + <v-list-tile-content> + {{ submissionType.name }} + </v-list-tile-content> + </v-list-tile> + </v-list> + </v-flex> + <v-flex xs9> + <v-layout + v-if="!selectedSubmissionType" + justify-center + > + <strong>Select a task type on the left to see the description and solution.</strong> + </v-layout> + <submission-type + v-else + class="mr-2 mb-2" + v-bind="selectedSubmissionType" + /> + </v-flex> + </v-layout> </v-card> </template> diff --git a/frontend/src/components/submission_type/solution/Solution.vue b/frontend/src/components/submission_type/solution/Solution.vue index 38ba45bf..457cc53b 100644 --- a/frontend/src/components/submission_type/solution/Solution.vue +++ b/frontend/src/components/submission_type/solution/Solution.vue @@ -1,22 +1,34 @@ <template> <table class="solution-table"> - <tr v-for="(code, lineNo) in highlightedSolution" :key="`${pk}:${lineNo}`" :id="`solution-line-${lineNo}`"> - <td class="line-number-cell" :style="backgroundColor(lineNo)"> + <tr + v-for="(code, lineNo) in highlightedSolution" + :id="`solution-line-${lineNo}`" + :key="`${pk}:${lineNo}`" + > + <td + class="line-number-cell" + :style="backgroundColor(lineNo)" + > <v-btn - flat - block - depressed - class="line-number-btn" - @click="toggleEditor(lineNo)">{{lineNo}}</v-btn> + flat + block + depressed + class="line-number-btn" + @click="toggleEditor(lineNo)" + > + {{ lineNo }} + </v-btn> </td> <td class="code-cell-content pl-2"> - <span v-html="code" class="code-line"></span> + <!-- eslint-disable-next-line --> + <span class="code-line" v-html="code"/> <template - v-if="solutionComments[lineNo] && solutionComments[lineNo].length && showSolutionComments"> + v-if="solutionComments[lineNo] && solutionComments[lineNo].length && showSolutionComments" + > <solution-comment v-for="comment in solutionComments[lineNo]" - v-bind="comment" :key="comment.pk" + v-bind="comment" @update-submission-type="updateSubmissionType" @toggle-editor="toggleEditor(lineNo)" @toggle-eidt-editor="toggleEditor(lineNo)" @@ -24,21 +36,32 @@ </template> <template v-if="showEditorOnline[lineNo]"> <v-textarea + v-model="editedSolutionComments[lineNo]" name="solution-comment-input" label="Here you can comment the solution. Other tutors will see those comments." - v-model="editedSolutionComments[lineNo]" - @keyup.enter.ctrl.exact="submitSolutionComment(lineNo)" - @keyup.esc="collapseTextField(lineNo)" - @focus="selectInput($event)" rows="2" outline autofocus auto-grow hide-details class="mx-2" + @keyup.enter.ctrl.exact="submitSolutionComment(lineNo)" + @keyup.esc="collapseTextField(lineNo)" + @focus="selectInput($event)" /> - <v-btn id="submit-comment" color="success" @click="submitSolutionComment(lineNo)"><v-icon>check</v-icon>Submit</v-btn> - <v-btn id="cancel-comment" @click="toggleEditor(lineNo)"><v-icon>cancel</v-icon>cancel</v-btn> + <v-btn + id="submit-comment" + color="success" + @click="submitSolutionComment(lineNo)" + > + <v-icon>check</v-icon>Submit + </v-btn> + <v-btn + id="cancel-comment" + @click="toggleEditor(lineNo)" + > + <v-icon>cancel</v-icon>cancel + </v-btn> </template> </td> </tr> diff --git a/frontend/src/components/submission_type/solution/SolutionComment.vue b/frontend/src/components/submission_type/solution/SolutionComment.vue index 9684e001..3835846d 100644 --- a/frontend/src/components/submission_type/solution/SolutionComment.vue +++ b/frontend/src/components/submission_type/solution/SolutionComment.vue @@ -1,46 +1,85 @@ <template> <div> - <div class="dialog-box" @click="$emit('toggle-editor')"> - <div class="body elevation-1" :style="{borderColor: '#3D8FC1', backgroundColor}"> - <span class="tip tip-up" :style="{borderBottomColor: '#3D8FC1'}"></span> - <span v-if="ofUser" class="of-user">Of user: {{ofUser}}</span> - <span class="comment-created">{{parsedCreated}}</span> - <div class="message">{{text}}</div> + <div + class="dialog-box" + @click="$emit('toggle-editor')" + > + <div + class="body elevation-1" + :style="{borderColor: '#3D8FC1', backgroundColor}" + > + <span + class="tip tip-up" + :style="{borderBottomColor: '#3D8FC1'}" + /> + <span + v-if="ofUser" + class="of-user" + >Of user: {{ ofUser }}</span> + <span class="comment-created">{{ parsedCreated }}</span> + <div class="message"> + {{ text }} + </div> <v-btn - flat icon absolute - class="delete-button" v-if="deletable" + flat + icon + absolute + class="delete-button" @click.stop="deleteConfirmation = true" > - <v-icon color="grey darken-1" size="20px">delete_forever</v-icon> + <v-icon + color="grey darken-1" + size="20px" + > + delete_forever + </v-icon> </v-btn> <v-btn - flat icon absolute - class="edit-button" v-if="editable" + flat + icon + absolute + class="edit-button" @click.stop="toggleEditing()" > - <v-icon color="grey darken-1" size="20px">edit</v-icon> + <v-icon + color="grey darken-1" + size="20px" + > + edit + </v-icon> </v-btn> </div> </div> <template v-if="editing"> <v-textarea + v-model="editedText" name="solution-comment-edit" label="Here you can edit your comment" - v-model="editedText" - @keyup.enter.ctrl.exact="submitEdit" - @keyup.esc="editing = false" - @focus="selectInput($event)" rows="2" outline autofocus auto-grow hide-details class="mx-2" + @keyup.enter.ctrl.exact="submitEdit" + @keyup.esc="editing = false" + @focus="selectInput($event)" /> - <v-btn id="submit-comment" color="success" @click="submitEdit"><v-icon>check</v-icon>Submit</v-btn> - <v-btn id="cancel-comment" @click="editing = false"><v-icon>cancel</v-icon>cancel</v-btn> + <v-btn + id="submit-comment" + color="success" + @click="submitEdit" + > + <v-icon>check</v-icon>Submit + </v-btn> + <v-btn + id="cancel-comment" + @click="editing = false" + > + <v-icon>cancel</v-icon>cancel + </v-btn> </template> <v-dialog @@ -48,14 +87,22 @@ max-width="max-content" > <v-card - class="text-xs-center pa-2" + class="text-xs-center pa-2" > <v-card-title class="title"> Delete permanently? </v-card-title> <v-card-actions> - <v-btn :id="`confirm-delete-comment`" color="red lighten-1" @click="deleteComment">delete</v-btn> - <v-btn @click="deleteConfirmation = false">cancel</v-btn> + <v-btn + :id="`confirm-delete-comment`" + color="red lighten-1" + @click="deleteComment" + > + delete + </v-btn> + <v-btn @click="deleteConfirmation = false"> + cancel + </v-btn> </v-card-actions> </v-card> </v-dialog> diff --git a/frontend/src/components/subscriptions/SubscriptionCreation.vue b/frontend/src/components/subscriptions/SubscriptionCreation.vue index fe0d76d8..7e039d0e 100644 --- a/frontend/src/components/subscriptions/SubscriptionCreation.vue +++ b/frontend/src/components/subscriptions/SubscriptionCreation.vue @@ -17,12 +17,14 @@ label="Select your desired feedback stage" /> <v-card-actions> - <v-spacer/> + <v-spacer /> <v-btn flat - @click="subscribe" :loading="loading" - >Subscribe</v-btn> + @click="subscribe" + > + Subscribe + </v-btn> </v-card-actions> </v-card-text> </v-card> @@ -44,17 +46,7 @@ const stages = [ ] export default { - name: 'subscription-creation', - data () { - return { - key: { - text: '', - key: '' - }, - stage: stages[0], - loading: false - } - }, + name: 'SubscriptionCreation', props: { title: { type: String, @@ -65,9 +57,20 @@ export default { required: true }, keyItems: { + default: () => [], type: Array } }, + data () { + return { + key: { + text: '', + key: '' + }, + stage: stages[0], + loading: false + } + }, computed: { possibleStages () { let possibleStages = [...stages] diff --git a/frontend/src/components/subscriptions/SubscriptionEnded.vue b/frontend/src/components/subscriptions/SubscriptionEnded.vue index d5c6815e..7890a5dc 100644 --- a/frontend/src/components/subscriptions/SubscriptionEnded.vue +++ b/frontend/src/components/subscriptions/SubscriptionEnded.vue @@ -1,11 +1,14 @@ <template> - <v-card class="mx-auto center-page" id="subscription-ended"> + <v-card + id="subscription-ended" + class="mx-auto center-page" + > <v-card-title class="title"> No submissions left </v-card-title> <v-card-text> All submissions for <b> {{ submissionTypeName() }} </b> in the current stage have been corrected. If you've - been validating feedback or <br/> + been validating feedback or <br> resolving conflicts some submissions may become active again. If that is the case they will appear clickable in the sidebar again. </v-card-text> diff --git a/frontend/src/components/subscriptions/SubscriptionForList.vue b/frontend/src/components/subscriptions/SubscriptionForList.vue index d88fa9cf..c38a974f 100644 --- a/frontend/src/components/subscriptions/SubscriptionForList.vue +++ b/frontend/src/components/subscriptions/SubscriptionForList.vue @@ -8,11 +8,12 @@ <!-- dynamically set css class depending on active --> <v-list-tile-content :class="{'inactive-subscription': !active}" - class="mr-3 subscription"> - {{name}} + class="mr-3 subscription" + > + {{ name }} </v-list-tile-content> <v-list-tile-action-text> - left: {{available}} + left: {{ available }} </v-list-tile-action-text> </v-list-tile> </v-layout> diff --git a/frontend/src/components/subscriptions/SubscriptionList.vue b/frontend/src/components/subscriptions/SubscriptionList.vue index 07dc0dae..bb7e561c 100644 --- a/frontend/src/components/subscriptions/SubscriptionList.vue +++ b/frontend/src/components/subscriptions/SubscriptionList.vue @@ -1,13 +1,24 @@ <template> - <v-card name='subscription-list'> - <v-toolbar color="teal" :dense="sidebar"> + <v-card name="subscription-list"> + <v-toolbar + color="teal" + :dense="sidebar" + > <v-toolbar-side-icon><v-icon>assignment</v-icon></v-toolbar-side-icon> - <v-toolbar-title v-if="showDetail" style="min-width: fit-content;"> + <v-toolbar-title + v-if="showDetail" + style="min-width: fit-content;" + > Tasks </v-toolbar-title> - <v-spacer/> - <v-btn icon @click="getSubscriptions(false)"> - <v-icon v-if="!updating">refresh</v-icon> + <v-spacer /> + <v-btn + icon + @click="getSubscriptions(false)" + > + <v-icon v-if="!updating"> + refresh + </v-icon> <v-progress-circular v-else indeterminate @@ -16,12 +27,26 @@ /> </v-btn> </v-toolbar> - <v-tabs grow color="teal lighten-1" v-model="selectedStage" v-if="showDetail"> - <v-tab v-for="(item, i) in stagesReadable" :key="i"> - {{item}} + <v-tabs + v-if="showDetail" + v-model="selectedStage" + grow + color="teal lighten-1" + > + <v-tab + v-for="(item, i) in stagesReadable" + :key="i" + > + {{ item }} </v-tab> - <v-tab-item v-for="(stage, i) in stages" :key="i"> - <subscriptions-for-stage :stage="stage" :id="`stage-${i}`"/> + <v-tab-item + v-for="(stage, i) in stages" + :key="i" + > + <subscriptions-for-stage + :id="`stage-${i}`" + :stage="stage" + /> </v-tab-item> </v-tabs> </v-card> diff --git a/frontend/src/components/subscriptions/SubscriptionsForStage.vue b/frontend/src/components/subscriptions/SubscriptionsForStage.vue index 1e961cbd..49587104 100644 --- a/frontend/src/components/subscriptions/SubscriptionsForStage.vue +++ b/frontend/src/components/subscriptions/SubscriptionsForStage.vue @@ -1,12 +1,13 @@ <template> <v-list :dense="dense"> <div> - <div v-for="subscription in subscriptions['submission_type']" - :key="subscription.pk"> + <div + v-for="subscription in subscriptions['submission_type']" + :key="subscription.pk" + > <subscription-for-list v-bind="subscription" - > - </subscription-for-list> + /> </div> </div> </v-list> @@ -16,10 +17,10 @@ import SubscriptionForList from '@/components/subscriptions/SubscriptionForList' import { Subscriptions } from '@/store/modules/subscriptions' export default { + name: 'SubscriptionsForStage', components: { SubscriptionForList }, - name: 'subscriptions-for-stage', props: { stage: { type: String, diff --git a/frontend/src/components/tutor_list/TutorList.vue b/frontend/src/components/tutor_list/TutorList.vue index 0aa8ecf7..ec0c1b8f 100644 --- a/frontend/src/components/tutor_list/TutorList.vue +++ b/frontend/src/components/tutor_list/TutorList.vue @@ -1,10 +1,18 @@ <template> - <v-flex lg7 xl5> + <v-flex + lg7 + xl5 + > <v-card> <v-card-title class="title"> Tutors - <v-spacer/> - <v-btn icon @click="refresh"><v-icon>refresh</v-icon></v-btn> + <v-spacer /> + <v-btn + icon + @click="refresh" + > + <v-icon>refresh</v-icon> + </v-btn> </v-card-title> <v-data-table :headers="headers" @@ -13,28 +21,54 @@ item-key="pk" hide-actions > - <template slot="items" slot-scope="props"> - <td>{{props.item.username}}</td> - <td class="text-xs-right">{{props.item.feedbackCreated}}</td> - <td class="text-xs-right">{{props.item.feedbackValidated}}</td> + <template + slot="items" + slot-scope="props" + > + <td>{{ props.item.username }}</td> <td class="text-xs-right"> - {{props.item.reservedSubmissions}} - <v-tooltip top v-if="props.item.reservedSubmissions"> - <template slot="activator"> - <v-icon small @click="deleteAssignmentsOfTutor(props.item)">clear</v-icon> - </template> - <span>Free reserved submissions</span> + {{ props.item.feedbackCreated }} + </td> + <td class="text-xs-right"> + {{ props.item.feedbackValidated }} + </td> + <td class="text-xs-right"> + {{ props.item.reservedSubmissions }} + <v-tooltip + v-if="props.item.reservedSubmissions" + top + > + <template slot="activator"> + <v-icon + small + @click="deleteAssignmentsOfTutor(props.item)" + > + clear + </v-icon> + </template> + <span>Free reserved submissions</span> </v-tooltip> </td> <td class="text-xs-right"> <v-btn v-if="canRevokeAccess(props.item.username)" - icon @click="changeActiveStatus(props.item)" + icon + @click="changeActiveStatus(props.item)" > <v-tooltip top> <template slot="activator"> - <v-icon small v-if="!props.item.isActive">lock</v-icon> - <v-icon small v-else>lock_open</v-icon> + <v-icon + v-if="!props.item.isActive" + small + > + lock + </v-icon> + <v-icon + v-else + small + > + lock_open + </v-icon> </template> <span v-if="!props.item.isActive">Grant access</span> <span v-else>Revoke access</span> diff --git a/frontend/src/components/util/FileSelect.vue b/frontend/src/components/util/FileSelect.vue index 1bf8b055..58ba0306 100644 --- a/frontend/src/components/util/FileSelect.vue +++ b/frontend/src/components/util/FileSelect.vue @@ -1,10 +1,13 @@ <template> <label class="file-select"> <div class="select-button"> - <span v-if="value">Selected: {{value.name}}</span> - <span v-else>{{displayText}}</span> + <span v-if="value">Selected: {{ value.name }}</span> + <span v-else>{{ displayText }}</span> </div> - <input type="file" @change="handleFileChange"/> + <input + type="file" + @change="handleFileChange" + > </label> </template> diff --git a/frontend/src/pages/LayoutSelector.vue b/frontend/src/pages/LayoutSelector.vue index 4032be08..a2e85b2b 100644 --- a/frontend/src/pages/LayoutSelector.vue +++ b/frontend/src/pages/LayoutSelector.vue @@ -1,8 +1,8 @@ <template> <div> - <component :is="layout"></component> + <component :is="layout" /> <v-content> - <router-view></router-view> + <router-view /> </v-content> </div> </template> @@ -15,11 +15,11 @@ import ReviewerLayout from '@/pages/reviewer/ReviewerLayout' import { Authentication } from '@/store/modules/authentication' export default { + name: 'LayoutSelector', components: { ReviewerLayout, StudentLayout, TutorLayout }, - name: 'layout-selector', computed: { isStudent () { return Authentication.isStudent }, isTutor () { return Authentication.isTutor }, diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index ccccdc23..1f497dcd 100644 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -1,38 +1,75 @@ <template> <v-container fill-height> - <v-layout align-center justify-center> - <v-dialog v-model="registerDialog" class="pa-4" max-width="30%"> - <register-dialog @registered="registered($event)"/> + <v-layout + align-center + justify-center + > + <v-dialog + v-model="registerDialog" + class="pa-4" + max-width="30%" + > + <register-dialog @registered="registered($event)" /> </v-dialog> - <v-flex text-xs-center xs8 sm6 md4 lg2> - <img v-if="production" :src="productionBrandUrl"/> - <img v-else src="../assets/brand.png"/> - <h3 class="pt-3">Log in</h3> + <v-flex + text-xs-center + xs8 + sm6 + md4 + lg2 + > + <img + v-if="production" + :src="productionBrandUrl" + > + <img + v-else + src="../assets/brand.png" + > + <h3 class="pt-3"> + Log in + </h3> <v-alert - outline v-if="msg" + outline color="error" :value="true" transition="fade-transition" - >{{ msg }}</v-alert> - <p v-else>But I corrected them, sir.</p> + > + {{ msg }} + </v-alert> + <p v-else> + But I corrected them, sir. + </p> <v-form - @submit.prevent="submit"> + @submit.prevent="submit" + > <v-text-field - label="Username" v-model="credentials.username" + label="Username" required autofocus /> <v-text-field - label="Password" v-model="credentials.password" + label="Password" type="password" required /> <v-layout class="btn-container"> - <v-btn @click="registerDialog = true" id="register">Register</v-btn> - <v-btn :loading="loading" type="submit" color="primary">Access</v-btn> + <v-btn + id="register" + @click="registerDialog = true" + > + Register + </v-btn> + <v-btn + :loading="loading" + type="submit" + color="primary" + > + Access + </v-btn> </v-layout> </v-form> </v-flex> @@ -46,8 +83,8 @@ import RegisterDialog from '@/components/RegisterDialog' import { Authentication as Auth } from '@/store/modules/authentication' export default { + name: 'GradyLogin', components: { RegisterDialog }, - name: 'grady-login', data () { return { credentials: { diff --git a/frontend/src/pages/PageNotFound.vue b/frontend/src/pages/PageNotFound.vue index d84f88ac..64a3ecb0 100644 --- a/frontend/src/pages/PageNotFound.vue +++ b/frontend/src/pages/PageNotFound.vue @@ -1,14 +1,29 @@ <template> <v-container fill-height> - <v-layout align-center justify-center> - <v-card dark width="80%" height="80%"> + <v-layout + align-center + justify-center + > + <v-card + dark + width="80%" + height="80%" + > <v-card-title style="font-size: 350%"> The content you're requesting is not available in your country. </v-card-title> - <v-divider class="px-5"/> - <v-flex xs10 offset-xs2> + <v-divider class="px-5" /> + <v-flex + xs10 + offset-xs2 + > <v-card-text class="no-content-text"> - <v-icon size="200px" color="deep-orange accent-4">play_circle_outline</v-icon> + <v-icon + size="200px" + color="deep-orange accent-4" + > + play_circle_outline + </v-icon> <span style="font-size: xx-large">We're sorry about that ¯\_(ツ)_/¯</span> </v-card-text> </v-flex> @@ -19,7 +34,7 @@ <script> export default { - name: 'page-not-found' + name: 'PageNotFound' } </script> diff --git a/frontend/src/pages/StartPageSelector.vue b/frontend/src/pages/StartPageSelector.vue index fe8bde54..85edbc66 100644 --- a/frontend/src/pages/StartPageSelector.vue +++ b/frontend/src/pages/StartPageSelector.vue @@ -1,6 +1,5 @@ <template> - <component :is="startPage"> - </component> + <component :is="startPage" /> </template> <script> @@ -10,7 +9,7 @@ import StudentPage from '@/pages/student/StudentPage' import ReviewerStartPage from '@/pages/reviewer/ReviewerStartPage' import { Authentication } from '@/store/modules/authentication' export default { - name: 'start-page-selector', + name: 'StartPageSelector', components: { ReviewerStartPage, StudentPage, diff --git a/frontend/src/pages/Statistics.vue b/frontend/src/pages/Statistics.vue index 92a69ce1..51b8f9fa 100644 --- a/frontend/src/pages/Statistics.vue +++ b/frontend/src/pages/Statistics.vue @@ -1,11 +1,17 @@ <template> <div> - <v-layout row class="ma-2"> + <v-layout + row + class="ma-2" + > <v-flex xs5> - <label-statistics/> + <label-statistics /> </v-flex> - <v-flex offset-xs1 xs5> - <correction-statistics/> + <v-flex + offset-xs1 + xs5 + > + <correction-statistics /> </v-flex> </v-layout> </div> diff --git a/frontend/src/pages/StudentSubmissionSideView.vue b/frontend/src/pages/StudentSubmissionSideView.vue index 6f1ee7b8..ef863ba4 100644 --- a/frontend/src/pages/StudentSubmissionSideView.vue +++ b/frontend/src/pages/StudentSubmissionSideView.vue @@ -1,22 +1,22 @@ <template> <div> - <route-change-confirmation :next-route="nextRoute"/> + <route-change-confirmation :next-route="nextRoute" /> <submission-correction :submission-without-assignment="submission" :feedback="submission.feedback" + :ignore-hidden-state="true" @feedbackCreated="refresh" @feedbackChanged="refresh" - :ignoreHiddenState="true" /> <submission-tests :tests="submission.tests" class="mt-4" /> <submission-type - v-bind="submissionType" :key="submissionType.pk" + v-bind="submissionType" :reverse="true" - :expandedByDefault="{ Description: true, Solution: true }" + :expanded-by-default="{ Description: true, Solution: true }" class="mt-1" /> </div> @@ -57,12 +57,12 @@ function onRouteEnterOrUpdate (to, from, next) { } export default { + name: 'StudentSubmissionSideView', components: { RouteChangeConfirmation, SubmissionType, SubmissionTests, SubmissionCorrection }, - name: 'student-submission-side-view', data () { return { nextRoute: null diff --git a/frontend/src/pages/SubscriptionWorkPage.vue b/frontend/src/pages/SubscriptionWorkPage.vue index 15e0935f..2ba14b0b 100644 --- a/frontend/src/pages/SubscriptionWorkPage.vue +++ b/frontend/src/pages/SubscriptionWorkPage.vue @@ -1,14 +1,18 @@ <template> <v-layout - row wrap + row + wrap > - <route-change-confirmation :next-route="nextRoute"/> - <v-flex xs12 md6> + <route-change-confirmation :next-route="nextRoute" /> + <v-flex + xs12 + md6 + > <submission-correction - :assignment="currentAssignment" :key="subscription.pk" - @feedbackCreated="startWorkOnNextAssignment" + :assignment="currentAssignment" class="ma-4 autofocus" + @feedbackCreated="startWorkOnNextAssignment" /> <submission-tests :tests="submission.tests" @@ -20,10 +24,10 @@ <v-flex md6> <div class="sub-correction"> <submission-type - v-bind="submissionType" :key="submissionType.pk" + v-bind="submissionType" :reverse="true" - :expandedByDefault="{ Description: true, Solution: true }" + :expanded-by-default="{ Description: true, Solution: true }" class="mt-4 mr-4" /> </div> diff --git a/frontend/src/pages/base/FeedbackHistoryPage.vue b/frontend/src/pages/base/FeedbackHistoryPage.vue index 5147ed1e..4a5fa6f0 100644 --- a/frontend/src/pages/base/FeedbackHistoryPage.vue +++ b/frontend/src/pages/base/FeedbackHistoryPage.vue @@ -1,11 +1,17 @@ <template> <v-layout row> <v-flex xs6> - <router-view name="left"></router-view> + <router-view name="left" /> </v-flex> - <v-flex xs6 class="ml-3"> + <v-flex + xs6 + class="ml-3" + > <div class="right-view"> - <router-view name="right" @refresh="refresh"></router-view> + <router-view + name="right" + @refresh="refresh" + /> </div> </v-flex> </v-layout> diff --git a/frontend/src/pages/base/TutorReviewerBaseLayout.vue b/frontend/src/pages/base/TutorReviewerBaseLayout.vue index beed5790..4a798aa4 100644 --- a/frontend/src/pages/base/TutorReviewerBaseLayout.vue +++ b/frontend/src/pages/base/TutorReviewerBaseLayout.vue @@ -1,13 +1,16 @@ <template> <base-layout> - <template slot="header"> Grady </template> <template slot="sidebar-content"> <v-list dense> - <v-list-tile v-for="(item, i) in generalNavItems" :key="i" :to="item.route"> + <v-list-tile + v-for="(item, i) in generalNavItems" + :key="i" + :to="item.route" + > <v-list-tile-action> <v-icon>{{ item.icon }}</v-icon> </v-list-tile-action> @@ -18,13 +21,15 @@ </v-list-tile-content> </v-list-tile> </v-list> - <v-divider></v-divider> - <slot name="above-subscriptions"></slot> - <subscription-list :sidebar="true"/> - <feedback-labels-list/> - <slot name="below-subscriptions"></slot> + <v-divider /> + <slot name="above-subscriptions" /> + <subscription-list :sidebar="true" /> + <feedback-labels-list /> + <slot name="below-subscriptions" /> + </template> + <template slot="toolbar-right"> + <slot name="toolbar-right" /> </template> - <template slot="toolbar-right"><slot name="toolbar-right"></slot></template> </base-layout> </template> @@ -34,11 +39,11 @@ import SubscriptionList from '@/components/subscriptions/SubscriptionList' import FeedbackLabelsList from '@/components/feedback_labels/FeedbackLabelsList.vue' export default { + name: 'TutorReviewerBaseLayout', components: { SubscriptionList, FeedbackLabelsList, BaseLayout }, - name: 'tutor-reviewer-base-layout', data () { return { generalNavItems: [ diff --git a/frontend/src/pages/reviewer/ReviewerLayout.vue b/frontend/src/pages/reviewer/ReviewerLayout.vue index 57989a39..e16033eb 100644 --- a/frontend/src/pages/reviewer/ReviewerLayout.vue +++ b/frontend/src/pages/reviewer/ReviewerLayout.vue @@ -1,7 +1,14 @@ <template> <tutor-reviewer-base-layout> - <v-list dense slot="above-subscriptions"> - <v-list-tile v-for="(item, i) in subGeneralNavItems" :key="i" :to="item.route"> + <v-list + slot="above-subscriptions" + dense + > + <v-list-tile + v-for="(item, i) in subGeneralNavItems" + :key="i" + :to="item.route" + > <v-list-tile-action> <v-icon>{{ item.icon }}</v-icon> </v-list-tile-action> @@ -13,7 +20,7 @@ </v-list-tile> </v-list> <template slot="toolbar-right"> - <export-dialog/> + <export-dialog /> </template> </tutor-reviewer-base-layout> </template> @@ -23,10 +30,10 @@ import TutorReviewerBaseLayout from '@/pages/base/TutorReviewerBaseLayout' import ExportDialog from '@/components/export/ExportDialog' export default { + name: 'ReviewerLayout', components: { ExportDialog, TutorReviewerBaseLayout }, - name: 'reviewer-layout', data () { return { subGeneralNavItems: [ diff --git a/frontend/src/pages/reviewer/ReviewerStartPage.vue b/frontend/src/pages/reviewer/ReviewerStartPage.vue index 860c602f..c6a200f2 100644 --- a/frontend/src/pages/reviewer/ReviewerStartPage.vue +++ b/frontend/src/pages/reviewer/ReviewerStartPage.vue @@ -1,14 +1,25 @@ <template> <div> - <v-layout row wrap> - <v-flex lg5 md9 xs12> - <correction-statistics class="ma-4"></correction-statistics> + <v-layout + row + wrap + > + <v-flex + lg5 + md9 + xs12 + > + <correction-statistics class="ma-4" /> </v-flex> - <v-flex lg5 md9 xs12> - <subscription-list class="ma-4"></subscription-list> + <v-flex + lg5 + md9 + xs12 + > + <subscription-list class="ma-4" /> </v-flex> </v-layout> - <SubmissionTypesOverview class="ma-4"/> + <SubmissionTypesOverview class="ma-4" /> </div> </template> @@ -18,11 +29,11 @@ import SubscriptionList from '@/components/subscriptions/SubscriptionList' import SubmissionTypesOverview from '@/components/submission_type/SubmissionTypesOverview' export default { + name: 'ReviewerStartPage', components: { SubmissionTypesOverview, SubscriptionList, - CorrectionStatistics }, - name: 'reviewer-start-page' + CorrectionStatistics } } </script> diff --git a/frontend/src/pages/reviewer/StudentOverviewPage.vue b/frontend/src/pages/reviewer/StudentOverviewPage.vue index 8345dc59..53a246bd 100644 --- a/frontend/src/pages/reviewer/StudentOverviewPage.vue +++ b/frontend/src/pages/reviewer/StudentOverviewPage.vue @@ -1,33 +1,51 @@ <template> - <v-layout v-if="this.$vuetify.breakpoint.xl" wrap> - <v-flex xs6> - <student-list class="ma-1"></student-list> - </v-flex> - <v-flex xs6 class="right-view"> - <router-view></router-view> - </v-flex> - </v-layout> - <v-layout v-else> - <v-flex xs12> - <student-list class="ma-1" - v-on:detail-click="openDialog" - ></student-list> - </v-flex> - <v-dialog v-model="dialog" fullscreen hide-overlay> - <v-card> - <v-toolbar dark color="#1a237e"> - <v-btn icon dark @click="dialog = false"> - <v-icon>close</v-icon> - </v-btn> - <v-toolbar-title>Submission details</v-toolbar-title> - <v-spacer></v-spacer> - </v-toolbar> - <v-card-text> - <router-view @refresh="dialog = false"></router-view> - </v-card-text> - </v-card> - </v-dialog> - </v-layout> + <v-layout + v-if="this.$vuetify.breakpoint.xl" + wrap + > + <v-flex xs6> + <student-list class="ma-1" /> + </v-flex> + <v-flex + xs6 + class="right-view" + > + <router-view /> + </v-flex> + </v-layout> + <v-layout v-else> + <v-flex xs12> + <student-list + class="ma-1" + @detail-click="openDialog" + /> + </v-flex> + <v-dialog + v-model="dialog" + fullscreen + hide-overlay + > + <v-card> + <v-toolbar + dark + color="#1a237e" + > + <v-btn + icon + dark + @click="dialog = false" + > + <v-icon>close</v-icon> + </v-btn> + <v-toolbar-title>Submission details</v-toolbar-title> + <v-spacer /> + </v-toolbar> + <v-card-text> + <router-view @refresh="dialog = false" /> + </v-card-text> + </v-card> + </v-dialog> + </v-layout> </template> <script> @@ -35,8 +53,8 @@ import StudentList from '@/components/student_list/StudentList' import StudentListHelpCard from '@/components/student_list/StudentListHelpCard' export default { + name: 'StudentOverviewPage', components: { StudentList }, - name: 'student-overview-page', data: () => { return { dialog: false diff --git a/frontend/src/pages/reviewer/TutorOverviewPage.vue b/frontend/src/pages/reviewer/TutorOverviewPage.vue index 7b6039cb..b0b98e30 100644 --- a/frontend/src/pages/reviewer/TutorOverviewPage.vue +++ b/frontend/src/pages/reviewer/TutorOverviewPage.vue @@ -1,5 +1,5 @@ <template> - <tutor-list class="ma-2 elevation-1"></tutor-list> + <tutor-list class="ma-2 elevation-1" /> </template> <script> @@ -9,8 +9,8 @@ import { actions } from '@/store/actions' import { TutorOverview } from '@/store/modules/tutor-overview' export default { + name: 'TutorOverviewPage', components: { TutorList }, - name: 'tutor-overview-page', beforeRouteEnter (to, from, next) { TutorOverview.getTutors() TutorOverview.getActiveAssignments() diff --git a/frontend/src/pages/student/StudentLayout.vue b/frontend/src/pages/student/StudentLayout.vue index 377bc64d..5f2988c3 100644 --- a/frontend/src/pages/student/StudentLayout.vue +++ b/frontend/src/pages/student/StudentLayout.vue @@ -1,13 +1,19 @@ <template> <base-layout> - - <template slot="header"> + <template slot="header"> {{ moduleReference }} </template> - <v-list dense slot="sidebar-content"> - - <v-list-tile exact v-for="(item, i) in generalNavItems" :key="i" :to="item.route"> + <v-list + slot="sidebar-content" + dense + > + <v-list-tile + v-for="(item, i) in generalNavItems" + :key="i" + exact + :to="item.route" + > <v-list-tile-action> <v-icon>{{ item.icon }}</v-icon> </v-list-tile-action> @@ -18,17 +24,26 @@ </v-list-tile-content> </v-list-tile> - <v-divider></v-divider> + <v-divider /> <exam-information - :exam="exam" v-if="!mini" + :exam="exam" class="elevation-1 exam-info ma-1" /> - <v-list-tile exact v-for="item in submissionNavItems" :key="item.route" :to="item.route"> + <v-list-tile + v-for="item in submissionNavItems" + :key="item.route" + exact + :to="item.route" + > <v-list-tile-action> - <v-icon v-if="!visited[item.id]">assignment</v-icon> - <v-icon v-else>check</v-icon> + <v-icon v-if="!visited[item.id]"> + assignment + </v-icon> + <v-icon v-else> + check + </v-icon> </v-list-tile-action> <v-list-tile-content> <v-list-tile-title> @@ -46,8 +61,8 @@ import BaseLayout from '@/components/BaseLayout' import ExamInformation from '@/components/student/ExamInformation' import { StudentPage } from '@/store/modules/student-page' export default { + name: 'StudentLayout', components: { BaseLayout, ExamInformation }, - name: 'student-layout', data () { return { generalNavItems: [ diff --git a/frontend/src/pages/student/StudentPage.vue b/frontend/src/pages/student/StudentPage.vue index 029a21ce..81dd41a0 100644 --- a/frontend/src/pages/student/StudentPage.vue +++ b/frontend/src/pages/student/StudentPage.vue @@ -1,14 +1,21 @@ <template> - <v-container fluid> - <v-layout justify center> - <template v-if="loaded"> - <v-flex md10 mt-5 offset-xs1> - <h2>Your submissions:</h2> - <submission-list :submissions="submissions"/> - </v-flex> - </template> - </v-layout> - </v-container> + <v-container fluid> + <v-layout + justify + center + > + <template v-if="loaded"> + <v-flex + md10 + mt-5 + offset-xs1 + > + <h2>Your submissions:</h2> + <submission-list :submissions="submissions" /> + </v-flex> + </template> + </v-layout> + </v-container> </template> <script> @@ -17,10 +24,14 @@ import { StudentPage } from '@/store/modules/student-page' import { FeedbackLabels } from '@/store/modules/feedback-labels' export default { + name: 'StudentPage', components: { SubmissionList }, - name: 'student-page', + computed: { + submissions () { return StudentPage.state.submissionsForList }, + loaded () { return StudentPage.state.loaded } + }, created: function () { if (!this.loaded) { StudentPage.getStudentData().then(() => { @@ -28,10 +39,6 @@ export default { StudentPage.getStudentSubmissions() }) } - }, - computed: { - submissions () { return StudentPage.state.submissionsForList }, - loaded () { return StudentPage.state.loaded } } } </script> diff --git a/frontend/src/pages/student/StudentSubmissionPage.vue b/frontend/src/pages/student/StudentSubmissionPage.vue index c2024e54..bfca6ff0 100644 --- a/frontend/src/pages/student/StudentSubmissionPage.vue +++ b/frontend/src/pages/student/StudentSubmissionPage.vue @@ -1,36 +1,55 @@ <template> <v-container flex> - <v-layout row wrap> - <v-flex xs6 offset-xs3> - <v-alert :value="!feedback" type="info"> + <v-layout + row + wrap + > + <v-flex + xs6 + offset-xs3 + > + <v-alert + :value="!feedback" + type="info" + > This submission hasn't been corrected due to this being a pass only exam. </v-alert> </v-flex> - <v-flex lg6 md12 mt-5> + <v-flex + lg6 + md12 + mt-5 + > <base-annotated-submission> <v-toolbar - dense slot="header" + dense class="mb-1 elevation-1" > - <toggle-feedback-visibility-button/> + <toggle-feedback-visibility-button /> - <v-spacer/> + <v-spacer /> - <h2>Score: {{feedback ? feedback.score : 'N/A'}} / {{submissionType.fullScore}}</h2> + <h2>Score: {{ feedback ? feedback.score : 'N/A' }} / {{ submissionType.fullScore }}</h2> </v-toolbar> <template slot="table-content"> - <tr v-for="(code, lineNo) in submissionText" :key="lineNo"> - <submission-line :code="code" :lineNo="lineNo"> + <tr + v-for="(code, lineNo) in submissionText" + :key="lineNo" + > + <submission-line + :code="code" + :line-no="lineNo" + > <template v-if="feedback"> <template v-for="(comment, index) in feedback.feedbackLines[lineNo]"> <feedback-comment v-if="showFeedback" + :key="comment.pk + index" v-bind="comment" :line-no="lineNo" - :key="comment.pk + index" - :showVisibilityIcon="false" - :correctorView="false" + :show-visibility-icon="false" + :corrector-view="false" /> </template> </template> @@ -41,16 +60,22 @@ <v-card> <v-card-title>Labels:</v-card-title> <v-card-text> - <v-layout row wrap align-center v-for="label in mappedLabels" :key="'global' + label.pk"> - <v-flex sm6> - <feedback-label - v-bind="label" - /> - </v-flex> - <v-flex sm6> - <span><b>Description: </b>{{label.description}}</span> - </v-flex> - </v-layout> + <v-layout + v-for="label in mappedLabels" + :key="'global' + label.pk" + row + wrap + align-center + > + <v-flex sm6> + <feedback-label + v-bind="label" + /> + </v-flex> + <v-flex sm6> + <span><b>Description: </b>{{ label.description }}</span> + </v-flex> + </v-layout> </v-card-text> </v-card> <submission-tests @@ -59,10 +84,15 @@ class="mt-3" /> </v-flex> - <v-flex lg6 md12 mt-5 pl-3> + <v-flex + lg6 + md12 + mt-5 + pl-3 + > <submission-type - v-bind="submissionType"> - </submission-type> + v-bind="submissionType" + /> </v-flex> </v-layout> </v-container> @@ -85,7 +115,7 @@ import FeedbackLabel from '@/components/feedback_labels/FeedbackLabel.vue' export default { - name: 'student-submission-page', + name: 'StudentSubmissionPage', components: { ToggleFeedbackVisibilityButton, SubmissionTests, @@ -111,15 +141,15 @@ export default { }) } }, + mounted () { + this.onRouteMountOrUpdate(this.id) + }, methods: { onRouteMountOrUpdate (routeId) { StudentPage.SET_VISITED({ index: routeId, visited: true }) SubmissionNotes.SET_SUBMISSION(StudentPage.state.submissionData[routeId]) } }, - mounted () { - this.onRouteMountOrUpdate(this.id) - }, beforeRouteUpdate (to, from, next) { this.onRouteMountOrUpdate(to.params.id) next() diff --git a/frontend/src/pages/tutor/TutorLayout.vue b/frontend/src/pages/tutor/TutorLayout.vue index ec4f01b7..4e6f16b4 100644 --- a/frontend/src/pages/tutor/TutorLayout.vue +++ b/frontend/src/pages/tutor/TutorLayout.vue @@ -1,14 +1,14 @@ <template> - <tutor-reviewer-base-layout></tutor-reviewer-base-layout> + <tutor-reviewer-base-layout /> </template> <script> import TutorReviewerBaseLayout from '@/pages/base/TutorReviewerBaseLayout' export default { + name: 'TutorLayout', components: { TutorReviewerBaseLayout - }, - name: 'tutor-layout' + } } </script> diff --git a/frontend/src/pages/tutor/TutorStartPage.vue b/frontend/src/pages/tutor/TutorStartPage.vue index ad127cf2..87387bb2 100644 --- a/frontend/src/pages/tutor/TutorStartPage.vue +++ b/frontend/src/pages/tutor/TutorStartPage.vue @@ -1,14 +1,25 @@ <template> <div> - <v-layout row wrap> - <v-flex lg5 md9 xs12> - <correction-statistics class="ma-4"></correction-statistics> + <v-layout + row + wrap + > + <v-flex + lg5 + md9 + xs12 + > + <correction-statistics class="ma-4" /> </v-flex> - <v-flex lg5 md9 xs12> - <subscription-list class="ma-4"></subscription-list> + <v-flex + lg5 + md9 + xs12 + > + <subscription-list class="ma-4" /> </v-flex> </v-layout> - <SubmissionTypesOverview class="ma-4"/> + <SubmissionTypesOverview class="ma-4" /> </div> </template> @@ -18,11 +29,11 @@ import CorrectionStatistics from '@/components/CorrectionStatistics' import SubmissionTypesOverview from '@/components/submission_type/SubmissionTypesOverview' export default { + name: 'TutorStartPage', components: { SubmissionTypesOverview, CorrectionStatistics, - SubscriptionList }, - name: 'tutor-start-page' + SubscriptionList } } </script> -- GitLab