diff --git a/core/tests/test_import_views.py b/core/tests/test_import_views.py index dd5c99341256c032cb6edf8d965c829a1b352bd7..e5d4888194aa405f315fdc98946dc7fda7be262a 100644 --- a/core/tests/test_import_views.py +++ b/core/tests/test_import_views.py @@ -126,7 +126,10 @@ class ImportStudentsApiViewSetTest(APITestCase): self.url = '/api/import-students/' self.client = APIClient() self.client.force_login(user=self.factory.make_reviewer()) - ExamType.objects.get_or_create(module_reference='john and jane does exam', total_score=10, pass_score=5) + ExamType.objects.get_or_create( + module_reference='john and jane does exam', + total_score=10, pass_score=5 + ) def test_can_not_submit_nothing(self): res = self.client.post(self.url) diff --git a/frontend/src/components/import/HektorImportDialog.vue b/frontend/src/components/import/HektorImportDialog.vue new file mode 100644 index 0000000000000000000000000000000000000000..e81ac8ad3c61aa5a423e079331230cb3fe6555d8 --- /dev/null +++ b/frontend/src/components/import/HektorImportDialog.vue @@ -0,0 +1,71 @@ +<template> + <v-dialog + v-model="show" + width="30%" + > + <v-card> + <v-card-title class="title"> + Import data + </v-card-title> + <v-card-text> + <p> + You can use this component to import data into Grady. + You can use + <a + href="https://gitlab.gwdg.de/grady-corp/rusty-hektor" + target="_blank" + >rusty-hektor</a> to convert + and pseudonomize ILIAS output. + </p> + <file-select + v-model="importFile" + display-text="Select json file" + /> + </v-card-text> + <v-card-actions> + <v-btn + id="submit-import" + :loading="loading" + @click="submitData" + > + Import + </v-btn> + <v-btn + color="red" + @click="$emit('hide')" + > + Cancel + </v-btn> + </v-card-actions> + </v-card> + </v-dialog> +</template> + +<script> + import FileSelect from '@/components/util/FileSelect.vue' + import { importHektorData } from '@/api' + import importJSONMixin from '@/components/mixins/importJSONMixin' + + export default { + name: 'HektorImportDialog', + components: { + FileSelect + }, + mixins: [importJSONMixin], + data: () => { + return { + show: true, + loading: false, + importFile: null, + importAction: importHektorData + } + }, + watch: { + show(val) { + if (!val) { + this.$emit('hide') + } + } + }, + } +</script> diff --git a/frontend/src/components/mixins/importJSONMixin.ts b/frontend/src/components/mixins/importJSONMixin.ts new file mode 100644 index 0000000000000000000000000000000000000000..4d6c4b0ee8e89e465b2809025e6e2ef0572782b5 --- /dev/null +++ b/frontend/src/components/mixins/importJSONMixin.ts @@ -0,0 +1,54 @@ +import Vue from 'vue' + +export default Vue.extend({ + data: () => { + return { + show: true, + loading: false, + importFile: new Blob(), + importAction: async (data: string) => {} + } + }, + methods: { + async submitData() { + this.loading = true + let data + try { + data = await this.readFile() + data = JSON.parse(data) + } catch (error) { + this.$notify({ + type: 'error', + title: 'Error reading import file', + text: error.message + }) + this.loading = false + } + + try { + await this.importAction(data) + this.$emit('imported') + this.$notify({ + title: 'Successfully imported data. Please log out and in again.', + type: 'success' + }) + } finally { + this.loading = false + } + }, + readFile(): Promise<string> { + const fileReader = new FileReader() + return new Promise((resolve, reject) => { + fileReader.onload = event => { + const target = event.target as FileReader + resolve(target.result as string) + } + fileReader.onerror = () => { + fileReader.abort() + reject(new Error('Problem parsing input file.')) + } + fileReader.readAsText(this.importFile) + }) + } + } +}) \ No newline at end of file