|
42 | 42 | import {AxiosError} from "axios"; |
43 | 43 | import Icon from "~/components/Symbols/Icon.vue"; |
44 | 44 | import FileInput from "~/components/Input/FileInput.vue"; |
| 45 | + import {ImportExportFormat} from "~/types/exercise"; |
45 | 46 |
|
46 | 47 | @Component({ |
47 | 48 | components: {FileInput, ValidationObserver, Icon} |
|
56 | 57 |
|
57 | 58 | @Prop({type: String, required: true}) title!: string; |
58 | 59 |
|
59 | | - form: {file: File | null} = { |
| 60 | + form: { file: File | null } = { |
60 | 61 | file: null |
61 | 62 | }; |
62 | 63 |
|
|
84 | 85 | const buffer = reader.result as ArrayBuffer; |
85 | 86 | const string: string = new TextDecoder().decode(buffer); |
86 | 87 |
|
| 88 | + this.$nuxt.$loading.start(); |
| 89 | + let jsonInput: ImportExportFormat | any[]; |
| 90 | +
|
87 | 91 | try { |
88 | | - this.$nuxt.$loading.start(); |
89 | | - await this.$axios.$post("/api/bulk/create_exercises", JSON.parse(string)); |
90 | | - this.$displaySuccess("L'importation s'est correctement déroulée."); |
| 92 | + // first validate the json before anything else |
| 93 | + jsonInput = JSON.parse(string); |
| 94 | + // at the end, both import type use the same endpoint |
| 95 | + let exercises; |
| 96 | +
|
| 97 | + // Type Guards to distinct the two types |
| 98 | + if ((jsonInput as ImportExportFormat).categories) { |
| 99 | +
|
| 100 | + const exportFormat = jsonInput as ImportExportFormat; |
| 101 | +
|
| 102 | + // need that function in the next lines |
| 103 | + // Credits to https://gist.github.com/JamieMason/0566f8412af9fe6a1d470aa1e089a752 |
| 104 | + const groupBy = (key: string) => (array: any[]) => |
| 105 | + array.reduce((objectsByKeyValue, obj) => { |
| 106 | + const value = obj[key]; |
| 107 | + objectsByKeyValue[value] = (objectsByKeyValue[value] || []).concat(obj); |
| 108 | + return objectsByKeyValue; |
| 109 | + }, {}); |
| 110 | +
|
| 111 | + // creates or find the category/ies |
| 112 | + const tags_categories = Object.values(exportFormat.categories); |
| 113 | + const tags_categories_ids: { |
| 114 | + id: number, |
| 115 | + category: string |
| 116 | + }[] = await this.$axios.$post("/api/bulk/create_or_find_tag_categories", tags_categories); |
| 117 | + const tags_dictionary = groupBy("category")(tags_categories_ids); |
| 118 | +
|
| 119 | + // prepare json |
| 120 | + exercises = exportFormat.exercises.map( |
| 121 | + ex => ({ |
| 122 | + title: ex.title, |
| 123 | + description: ex.description, |
| 124 | + url: ex.url, |
| 125 | + state: ex.state, |
| 126 | + tags: ex.tags.map(tag => ( |
| 127 | + { |
| 128 | + // TODO : tag state ??? |
| 129 | + text: tag.text, |
| 130 | + category_id: tags_dictionary[exportFormat.categories[tag.category]][0].id |
| 131 | + } |
| 132 | + )) |
| 133 | + }) |
| 134 | + ); |
| 135 | +
|
| 136 | + } else { |
| 137 | + exercises = jsonInput; |
| 138 | + } |
91 | 139 |
|
| 140 | + // Trial time : execute query |
| 141 | + await this.$axios.$post("/api/bulk/create_exercises", exercises); |
| 142 | +
|
| 143 | + this.$displaySuccess("L'importation s'est correctement déroulée."); |
92 | 144 | this.$nextTick(() => { |
93 | 145 | this.form.file; |
94 | 146 | // @ts-ignore |
95 | 147 | this.fileObserver.deleteFile(); |
96 | 148 | this.observer.reset(); |
97 | 149 | }) |
98 | 150 | } catch (e) { |
99 | | - const error = e as AxiosError; |
100 | | -
|
101 | | - if (error.response) { |
102 | | - const status = error.response.status; |
103 | | -
|
104 | | - if (status === 400) { |
105 | | - this.$displayWarning("Votre fichier ne possède pas le bon format.") |
106 | | - } else if (status === 401) { |
107 | | - this.$displayWarning("Vous n'êtes pas autorisé à effectuer cette action.") |
108 | | - } else if (status === 500) { |
109 | | - this.$displayError("Une erreur est survenue depuis nos serveurs.") |
110 | | - } else { |
111 | | - this.$displayError("Une erreur est survenue.") |
112 | | - } |
| 151 | +
|
| 152 | + if (e instanceof SyntaxError) { |
| 153 | + this.$displayError("Le contenu de votre fichier n'est pas correct."); |
113 | 154 | } else { |
114 | | - this.$displayError("Le contenu de votre fichier n'est pas correct.") |
| 155 | + const error = e as AxiosError; |
| 156 | + if (error.response) { |
| 157 | + const status = error.response.status; |
| 158 | +
|
| 159 | + if (status === 400) { |
| 160 | + this.$displayWarning("Votre fichier ne possède pas le bon format.") |
| 161 | + } else if (status === 401) { |
| 162 | + this.$displayWarning("Vous n'êtes pas autorisé à effectuer cette action.") |
| 163 | + } else if (status === 500) { |
| 164 | + this.$displayError("Une erreur est survenue depuis nos serveurs.") |
| 165 | + } else { |
| 166 | + this.$displayError("Une erreur est survenue.") |
| 167 | + } |
| 168 | + } |
115 | 169 | } |
116 | 170 | } finally { |
117 | 171 | this.$nuxt.$loading.finish(); |
|
0 commit comments