Skip to content

Commit 82bb955

Browse files
committed
simplified import and export
1 parent 5f1e301 commit 82bb955

File tree

4 files changed

+53
-74
lines changed

4 files changed

+53
-74
lines changed

src/components/planner/sidebar/sessionController/CsvExport.tsx

+17-26
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import CourseContext from '../../../../contexts/CourseContext'
44
import MultipleOptionsContext from '../../../../contexts/MultipleOptionsContext'
55
import { AnalyticsTracker, Feature } from '../../../../utils/AnalyticsTracker'
66
import { csvEncode } from '../../../../utils/io'
7+
import api from '../../../../api/backend'
78

89

910
/**
@@ -13,43 +14,33 @@ const CsvExport = () => {
1314
const { pickedCourses } = useContext(CourseContext);
1415
const { multipleOptions } = useContext(MultipleOptionsContext);
1516

16-
enum GetOptionsBy {NAME, ID}
17+
const getOptions = async (): Promise<string[]> => {
18+
const lines = [];
19+
20+
for(const course of pickedCourses) {
21+
const baseInfo = [course.course_id, course.course_unit_year, csvEncode(course.name), course.acronym]
1722

18-
const getOptions = (getByName: GetOptionsBy): string[] =>
19-
pickedCourses.map(course => {
20-
const baseInfo = getByName === GetOptionsBy.NAME ?
21-
[course.course_unit_year, csvEncode(course.name), course.acronym] :
22-
[course.id];
23-
2423
const classValues = multipleOptions.map(option => {
2524
const courseOption = option.course_options.find(co => co.course_id === course.id);
2625
const pickedClass = courseOption ?
2726
course.classes.find(c => c.id === courseOption.picked_class_id) :
2827
undefined;
29-
30-
return csvEncode(getByName === GetOptionsBy.NAME ? pickedClass?.name : pickedClass?.id?.toString() || '');
28+
29+
return csvEncode(pickedClass?.name);
3130
});
32-
33-
return [...baseInfo, ...classValues].join(',');
31+
lines.push([...baseInfo, ...classValues].join(','));
3432
}
35-
);
36-
3733

38-
const exportCSV = () => {
39-
const header = ['Ano', 'Nome', 'Sigla']
40-
multipleOptions.forEach((option) => header.push(option.name))
41-
header.push(pickedCourses.length.toString())
42-
43-
const lines = getOptions(GetOptionsBy.NAME);
44-
45-
lines.push("////----////----////----////----////----////----////")
46-
47-
const header_ids = ['UC_ID']
48-
multipleOptions.forEach((option) => header_ids.push(option.name + "_ID"))
34+
return lines;
35+
}
36+
37+
const exportCSV = async () => {
38+
const header = ['ID_Curso', 'Ano', 'Nome', 'Sigla']
39+
multipleOptions.forEach((option) => header.push(option.name));
4940

50-
const lines_id = getOptions(GetOptionsBy.ID);
41+
const lines = await getOptions();
5142

52-
const csv = [header.join(','), lines.flat().join('\n'), header_ids.join(','), lines_id.flat().join('\n')].join('\n')
43+
const csv = [header.join(','), lines.flat().join('\n')].join('\n')
5344
const blob = new Blob([csv], { type: 'text/csv' })
5445
const url = URL.createObjectURL(blob)
5546
const a = document.createElement('a')

src/components/planner/sidebar/sessionController/CsvImport.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const CsvImport = ({handleClick}) => {
77
<div>
88
<button
99
onClick={handleClick}
10-
className="group flex w-full items-center gap-2 dark:text-white rounded-md p-1 text-gray text-sm disabled:cursor-not-allowed disabled:opacity-50"
10+
className="group flex w-full items-center gap-2n dark:text-white rounded-md p-1 text-gray text-sm disabled:cursor-not-allowed disabled:opacity-50"
1111
>
1212
<ArrowDownOnSquareIcon className="h-5 w-5 text-secondary hover:brightness-200" />
1313
<span className="pl-1">Importar Opções (CSV)</span>

src/components/planner/sidebar/sessionController/Export.tsx

+33-34
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { toast } from '../../../ui/use-toast'
1818
const Export = () => {
1919

2020
const fileInputRef = useRef(null);
21-
const { setPickedCourses, setCheckboxedCourses } = useContext(CourseContext);
21+
const { pickedCourses, setPickedCourses, setCheckboxedCourses } = useContext(CourseContext);
2222
const { multipleOptions, setMultipleOptions } = useContext(MultipleOptionsContext);
2323

2424
const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
@@ -29,11 +29,13 @@ const Export = () => {
2929

3030
try {
3131
const content = csvDecode(await file.text());
32+
console.log("input content",content);
3233
const courses = await getSelectedCourses(content);
34+
console.log("selected courses",courses);
3335

3436
setCheckboxedCourses(courses);
3537
setPickedCourses(courses);
36-
setCourseOptions(content);
38+
setCourseOptions(content, courses);
3739
} catch (error) {
3840
toast({
3941
title: 'Não foi possível importar os horários!',
@@ -43,35 +45,41 @@ const Export = () => {
4345
}
4446
};
4547

46-
const getSelectedCourses = async (content: any): Promise<CourseInfo[]> => {
48+
const getSelectedCourses = async (content: string[][]): Promise<CourseInfo[]> => {
4749
if (!Array.isArray(content) || content.length === 0) return [];
48-
49-
const selected_courses = await Promise.all(content.map(row => api.getCourseUnit(row[0])));
50-
51-
const majorsPromises = selected_courses.map(course => api.getCoursesByMajorId(course.course));
52-
const majorsResults = await Promise.all(majorsPromises);
5350

54-
selected_courses.forEach((course, index) => {
55-
const full_courses = majorsResults[index];
56-
const matching_course = full_courses.find(indiv_course => indiv_course.course_unit_id === course.id);
57-
if (matching_course) {
58-
course.ects = matching_course.ects;
59-
}
51+
const courses: CourseInfo[] = [];
52+
53+
const promises = content.map(async (row) => {
54+
const res = await api.getCoursesByMajorId(parseInt(row[0]));
55+
const matchedCourses = res.filter(course => course.acronym === row[3]);
56+
courses.push(...matchedCourses);
6057
});
58+
59+
await Promise.all(promises);
6160

62-
return selected_courses;
61+
for(const course of courses){
62+
if(typeof(course.ects) === "string")
63+
course.ects = parseFloat(course.ects.replace(",", "."));
64+
}
65+
66+
return courses;
6367
};
6468

65-
const setCourseOptions = (courses: number[][]) => {
66-
const transposedCourses = courses[0].map((_, colIndex) => courses.map(row => row[colIndex]));
67-
68-
const newOptions = transposedCourses.slice(1, 11).map((column, i) =>
69-
createOption(multipleOptions[i], column.map((value, j) =>
70-
createCourseOption(transposedCourses[0][j], value)
71-
))
72-
);
73-
74-
setMultipleOptions(newOptions);
69+
const setCourseOptions = async (content: string[][], courses: CourseInfo[]) => {
70+
const updatedOptions = [...multipleOptions];
71+
72+
for (let i = 0; i < courses.length; i++) {
73+
const courseOptions = await api.getCourseClass(courses[i]);
74+
content[i].slice(4).forEach((courseOption, j) => {
75+
const matchedClassOption = courseOptions.find(classOption => classOption.name === courseOption);
76+
if (matchedClassOption) {
77+
updatedOptions[j].course_options.push(createCourseOption(courses[i].id, matchedClassOption.id));
78+
}
79+
});
80+
}
81+
82+
setMultipleOptions(updatedOptions);
7583
};
7684

7785
const createCourseOption = (course_id: number, picked_class_id: number): CourseOption => {
@@ -84,15 +92,6 @@ const Export = () => {
8492
}
8593
}
8694

87-
const createOption = (option : Option, new_course_options : Array<CourseOption>) => {
88-
return {
89-
id: option.id,
90-
icon: option.icon,
91-
name: option.name,
92-
course_options: new_course_options
93-
}
94-
}
95-
9695
const handleClick = () => {
9796
fileInputRef.current.click();
9897
};

src/utils/io.ts

+2-13
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,8 @@ const csvEncode = (text: string | null | undefined) => {
77
}
88

99
const csvDecode = (text: string | null | undefined) => {
10-
const lines = text.split('\n');
11-
12-
const first_line = lines[0].split(',');
13-
const nr_of_courses = first_line[first_line.length - 1];
14-
15-
const id_start = parseInt(nr_of_courses) + 3
16-
17-
const id_lines = lines.slice(id_start, lines.length);
18-
19-
return id_lines.map(line =>{
20-
return line.split(',').map(option_number => {
21-
return parseInt(option_number);
22-
});
10+
return text.split('\n').slice(1).map(line =>{
11+
return line.split(',')
2312
});
2413
};
2514

0 commit comments

Comments
 (0)