Skip to content

Commit 38f9055

Browse files
committed
la meccanica di EditDegreePage sembra funzionare...
issue #177
1 parent 49e4db0 commit 38f9055

3 files changed

Lines changed: 94 additions & 91 deletions

File tree

frontend/package-lock.json

Lines changed: 1 addition & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,13 @@
4141
"npm": "^11.4.1",
4242
"react": "^17.0.2",
4343
"react-bootstrap": "^2.8.0",
44-
"react-bootstrap-multiselect": "^2.4.1",
4544
"react-csv": "^2.2.2",
4645
"react-datepicker": "^4.6.0",
4746
"react-dom": "^17.0.2",
4847
"react-fontawesome": "^1.7.1",
4948
"react-query": "^3.39.2",
5049
"react-router-dom": "^6.3.0",
51-
"react-select": "^5.7.2",
50+
"react-select": "^5.10.1",
5251
"regenerator-runtime": "^0.13.9",
5352
"startbootstrap-sb-admin-2": "^4.1.4"
5453
},

frontend/src/pages/DegreePage.tsx

Lines changed: 92 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import React, {useState} from 'react'
1+
import React, {useState, Dispatch, SetStateAction} from 'react'
22
import { Link, useParams, useNavigate } from "react-router-dom"
33
import { Form, Dropdown } from "react-bootstrap"
4-
import MultiSelect from "react-bootstrap-multiselect"
5-
import 'react-bootstrap-multiselect/css/bootstrap-multiselect.css'
4+
import Select, {MultiValue} from "react-select"
65

7-
import { useEngine, useGetDegree, useIndexExam, usePostDegree, usePatchDegree } from '../modules/engine'
6+
import { useEngine, useGetDegree, useIndexExam, usePostDegree, usePatchDegree, ExamGet } from '../modules/engine'
87
import Card from '../components/Card'
98
import Group from '../components/Group'
109
import LoadingMessage from '../components/LoadingMessage'
@@ -163,74 +162,39 @@ export function EditDegreePage() {
163162
const query = useGetDegree(id || '')
164163
const updater = usePatchDegree(id || '')
165164
const poster = usePostDegree()
166-
const exams = useIndexExam()
165+
const exams_query = useIndexExam()
167166
const mutate = isNew ? poster.mutate : updater.mutate
168167
const degree = query.data
169168
const isEdit = degree?._id !== undefined
170169

171-
if (query.isLoading || exams.isLoading) return <LoadingMessage>caricamento...</LoadingMessage>
170+
if (query.isLoading || exams_query.isLoading) return <LoadingMessage>caricamento...</LoadingMessage>
172171
if (query.isError) return <div>Errore: {query.error.message}</div>
173-
if (exams.isError) return <div>Errore: {`${exams}`}</div>
172+
if (exams_query.isError || !exams_query.data) return <div>Errore: {`${exams_query}`}</div>
173+
174+
const exams = exams_query.data.items
174175

175176
return <>
176177
<h1>{isEdit ? "Modifica" : "Nuovo"} corso di Laurea</h1>
177178
<DegreeForm mutate={mutate} degree={degree} exams={exams} />
178179
</>
179180
}
180181

181-
function DegreeForm({ mutate, degree, exams }) {
182-
const options = [
183-
{ label: 'Mela', value: 'mela' },
184-
{ label: 'Banana', value: 'banana' },
185-
{ label: 'Arancia', value: 'arancia' }
186-
];
187-
188-
const handleChange = (selectedOptions) => {
189-
console.log('Selezionato:', selectedOptions);
190-
};
191-
192-
return (
193-
<div className="container mt-5">
194-
<h3>Frutta preferita</h3>
195-
<MultiSelect
196-
multiple
197-
onChange={handleChange}
198-
enableFiltering
199-
includeSelectAllOption
200-
buttonClass="btn btn-primary"
201-
>
202-
{options.map(option =>
203-
<option key={option.value} value={option.value}>{option.label}</option>)}
204-
</MultiSelect>
205-
</div>
206-
);
207-
}
182+
type ExamGroup = {
183+
name: string,
184+
exam_ids: string[]
185+
}
208186

209-
function DegreeForm_({mutate,degree,exams}) {
187+
function DegreeForm({mutate, degree, exams}) {
210188
const [data, setData] = useState(degree)
189+
const [groups, setGroups] = useState<ExamGroup[]>(Object.entries(degree.groups as Record<string,string[]>)
190+
.map(([name,exam_ids])=>({name, exam_ids}))
191+
.sort((a, b) => a.name.localeCompare(b.name))
192+
)
211193
const [validation, setValidation] = useState<any>({})
212194
const engine = useEngine()
213195
const navigate = useNavigate()
214196
const current_year = new Date().getFullYear()
215-
216-
const [selectedOptions, setSelectedOptions] = useState([]);
217-
const options = [
218-
{ value: 'One', selected: true },
219-
{ value: 'Two' },
220-
{ value: 'Three' }
221-
];
222-
223-
const handleChange = (selected) => {
224-
setSelectedOptions(selected);
225-
};
226-
return (
227-
<MultiSelect
228-
onChange={handleChange}
229-
data={options}
230-
multiple
231-
/>
232-
);
233-
197+
234198
return <Card>
235199
<Group
236200
validationError={validation.name}
@@ -276,37 +240,23 @@ function DegreeForm_({mutate,degree,exams}) {
276240
<option value="admin">amministratori</option>
277241
</Form.Select>
278242
</Group>
243+
279244
<h4>gruppi di esami</h4>
280245

281-
<Dropdown>
282-
<Dropdown.Toggle variant="success" id="dropdown-basic">
283-
Select Options
284-
</Dropdown.Toggle>
285-
<Dropdown.Menu>
286-
{["A","B","C"].map((option, index) => (
287-
<Dropdown.Item
288-
key={index}
289-
onClick={() => {}}
290-
active={["B"].includes(option)}
291-
>
292-
{option}
293-
</Dropdown.Item>
294-
))}
295-
</Dropdown.Menu>
296-
</Dropdown>
246+
<EditGroups groups={groups} setGroups={setGroups} exams={exams} />
297247

298248
<Group
299249
validationError={validation.default_group}
300250
controlId="default_group"
301251
label="gruppo esami a scelta libera">
302252
{} <Form.Select value={data.default_group} onChange={onChange("default_group")}>
303253
<option value="">tutti gli esami</option>
304-
{ Object.keys(data.groups).map(name =>
305-
<option value={name}>{name}</option>
254+
{ groups.map(group =>
255+
<option key={group.name} value={group.name}>{group.name}</option>
306256
) }
307257
</Form.Select>
308258
</Group>
309-
259+
310260
<h4>notifiche email</h4>
311261
<Group
312262
validationError={validation.submission_confirmation}
@@ -387,3 +337,72 @@ function DegreeForm_({mutate,degree,exams}) {
387337
return e => setData(data => ({...data, [field]: e.target.checked}))
388338
}
389339
}
340+
341+
function EditGroups({groups, setGroups, exams}:{
342+
groups: ExamGroup[],
343+
setGroups: Dispatch<ExamGroup[]>,
344+
exams: ExamGet[]
345+
}) {
346+
const examDict = Object.fromEntries(exams.map(exam => [exam._id,exam]))
347+
return <>
348+
{ groups.map((group,i) =>
349+
<EditGroup
350+
key={i}
351+
name={group.name}
352+
setName={name => setGroups(groups.map(g => (g.name===group.name
353+
? {name, exam_ids: g.exam_ids}
354+
: g)))}
355+
group={group.exam_ids}
356+
setGroup={ids => setGroups(groups.map(g => (g.name===group.name
357+
? {name: g.name, exam_ids: ids}
358+
: g)))}
359+
examDict={examDict}
360+
/>)}
361+
</>
362+
}
363+
364+
type Option = {
365+
value: string;
366+
label: string;
367+
};
368+
369+
function EditGroup({name, setName, group, setGroup, examDict}:{
370+
name: string,
371+
setName: Dispatch<string>,
372+
group: string[],
373+
setGroup: Dispatch<string[]>
374+
examDict: Record<string, {_id: string, name: string, code: string}>
375+
}) {
376+
const sort_fun = (a,b) => a.label.localeCompare(b.label)
377+
const options: Option[] = Object.values(examDict).map(option_from_exam).sort(sort_fun)
378+
const selected: Option[] = group.map(option_from_exam_id).sort(sort_fun)
379+
380+
// TODO: l'ordinamento non funziona
381+
// sembra che la select ordini sempre in base al codice
382+
383+
return <Group controlId={`group-${name}`} label="gruppo">
384+
{} <input value={name} onChange={e => setName(e.target.value)} />
385+
<Select isMulti isSearchable
386+
options={options}
387+
value={selected}
388+
onChange={onChange}
389+
/>
390+
</Group>
391+
392+
function option_from_exam(exam) {
393+
return {
394+
value: exam?._id,
395+
label: `${exam.code} ${exam.name}`
396+
}
397+
}
398+
399+
function option_from_exam_id(exam_id) {
400+
const exam = examDict[exam_id]
401+
if (!exam) return {value: exam_id, label: exam_id}
402+
return option_from_exam(exam)
403+
}
404+
405+
function onChange(new_options: readonly Option[]) {
406+
setGroup(new_options.map(option => option.value))
407+
}
408+
}

0 commit comments

Comments
 (0)