Skip to content

Commit 0e5680d

Browse files
committed
feat(import) : reuse export format for import (WIP)
WIP
1 parent 43ab7a0 commit 0e5680d

File tree

2 files changed

+87
-20
lines changed

2 files changed

+87
-20
lines changed

components/Gestion/ImportForm.vue

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import {AxiosError} from "axios";
4343
import Icon from "~/components/Symbols/Icon.vue";
4444
import FileInput from "~/components/Input/FileInput.vue";
45+
import {ImportExportFormat} from "~/types/exercise";
4546
4647
@Component({
4748
components: {FileInput, ValidationObserver, Icon}
@@ -56,7 +57,7 @@
5657
5758
@Prop({type: String, required: true}) title!: string;
5859
59-
form: {file: File | null} = {
60+
form: { file: File | null } = {
6061
file: null
6162
};
6263
@@ -84,34 +85,87 @@
8485
const buffer = reader.result as ArrayBuffer;
8586
const string: string = new TextDecoder().decode(buffer);
8687
88+
this.$nuxt.$loading.start();
89+
let jsonInput: ImportExportFormat | any[];
90+
8791
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+
}
91139
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.");
92144
this.$nextTick(() => {
93145
this.form.file;
94146
// @ts-ignore
95147
this.fileObserver.deleteFile();
96148
this.observer.reset();
97149
})
98150
} 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.");
113154
} 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+
}
115169
}
116170
} finally {
117171
this.$nuxt.$loading.finish();

types/exercise.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,17 @@ export interface VoteRequest {
155155
score: number
156156
}
157157

158-
158+
// For import feature that used export ( simplest version )
159+
export interface ImportExportFormat {
160+
categories: { [key: string]: string; },
161+
exercises: {
162+
title: string,
163+
description: string,
164+
state: ExerciseState,
165+
url: null | string,
166+
tags: {
167+
text: string,
168+
category: number
169+
}[]
170+
}[]
171+
}

0 commit comments

Comments
 (0)