add delete group button, fix delete leader button, add filter to students and leaders in addGroup

This commit is contained in:
Patryk Drzewiński 2022-06-14 00:44:12 +02:00
parent f6b53a84a3
commit f642d62ff0
5 changed files with 119 additions and 16 deletions

View File

@ -65,9 +65,9 @@ def create_group(data: dict) -> dict:
db.session.commit() db.session.commit()
students = db.session.query(Student).filter(Student.index.in_(students_indexes)).all() students = db.session.query(Student).filter(Student.index.in_(students_indexes)).all()
project_supervisor.count_groups += 1
for student in students: for student in students:
student.group_id = group.id student.group_id = group.id
project_supervisor.count_groups += 1
db.session.commit() db.session.commit()
@ -89,6 +89,14 @@ def delete_group(id: int) -> dict:
group = Group.query.filter_by(id=id).first() group = Group.query.filter_by(id=id).first()
if group is None: if group is None:
abort(400, f"Group with id {id} doesn't exist!") abort(400, f"Group with id {id} doesn't exist!")
project_supervisor = ProjectSupervisor.query.filter_by(id=group.project_supervisor_id).first()
project_supervisor.count_groups -= 1
students = db.session.query(Student).filter_by(group_id=id).all()
for student in students:
student.group_id = None
db.session.delete(group) db.session.delete(group)
db.session.commit() db.session.commit()
return {"message": "Group was deleted!"} return {"message": "Group was deleted!"}

View File

@ -69,8 +69,9 @@ def delete_project_supervisor(id: int) -> dict:
abort(400, f"Project Supervisor with id {id} doesn't exist!") abort(400, f"Project Supervisor with id {id} doesn't exist!")
count_groups = db.session.query(db.func.count(ProjectSupervisor.id)).join(Group).\ count_groups = db.session.query(db.func.count(ProjectSupervisor.id)).join(Group).\
filter(ProjectSupervisor.id == id).group_by(ProjectSupervisor.id).scalar() filter(ProjectSupervisor.id == id).group_by(ProjectSupervisor.id)
if count_groups > 0:
if count_groups is not None:
abort(400, f"Project Supervisor with id {id} has gropus!") abort(400, f"Project Supervisor with id {id} has gropus!")
db.session.delete(project_supervisor) db.session.delete(project_supervisor)

View File

@ -34,3 +34,8 @@ export const getGroups = (
export const createGroup = (payload: CreateGroup) => export const createGroup = (payload: CreateGroup) =>
axiosInstance.post('http://127.0.0.1:5000/api/coordinator/groups/', payload) axiosInstance.post('http://127.0.0.1:5000/api/coordinator/groups/', payload)
export const deleteGroup = (id: number) =>
axiosInstance.delete(
`http://127.0.0.1:5000/api/coordinator/groups/${id}/`,
)

View File

@ -29,7 +29,8 @@ const AddGroup = () => {
{ {
onSuccess: (data) => { onSuccess: (data) => {
setStudentOptions( setStudentOptions(
data?.data.students.map(({ first_name, last_name, index }) => { data?.data.students.filter(st => st.group === null)
.map(({ first_name, last_name, index }) => {
return { return {
value: index, value: index,
label: `${first_name} ${last_name} (${index})`, label: `${first_name} ${last_name} (${index})`,
@ -45,7 +46,7 @@ const AddGroup = () => {
{ {
onSuccess: (data) => { onSuccess: (data) => {
setSupervisorOptions( setSupervisorOptions(
data?.data.project_supervisors.map( data?.data.project_supervisors.filter(ld => ld.count_groups < ld.limit_group).map(
({ id, first_name, last_name }) => ({ ({ id, first_name, last_name }) => ({
value: id, value: id,
label: `${first_name} ${last_name}`, label: `${first_name} ${last_name}`,

View File

@ -1,26 +1,75 @@
import { useQuery } from 'react-query' import classNames from 'classnames'
import { useEffect, useState } from 'react'
import { useMutation, useQuery } from 'react-query'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { getGroups } from '../../api/groups' import { deleteGroup, getGroups } from '../../api/groups'
const Groups = () => { const Groups = () => {
let navigate = useNavigate() let navigate = useNavigate()
const [page, setPage] = useState(1)
const [perPage, setPerPage] = useState(10)
const { isLoading: areGroupsLoading, data: groups } = useQuery( const perPageOptions = [
['groups'], {
() => getGroups({ per_page: 1000 }), value: 10,
label: '10 rekordów',
},
{
value: 20,
label: '20 rekordów',
},
{
value: 50,
label: '50 rekordów',
},
{
value: 1000,
label: 'Pokaż wszystkie',
},
]
const {
isLoading: areGroupsLoading,
data: groups,
refetch: refetchGroups,
} = useQuery(['groups', page, perPage], () =>
getGroups({ page, per_page: perPage }),
) )
const { mutate: mutateDelete } = useMutation(
'deleteGroup',
(index: number) => deleteGroup(index),
{
onSuccess: () => refetchGroups(),
},
)
useEffect(() => {
setPage(1)
}, [perPage])
if (areGroupsLoading) { if (areGroupsLoading) {
return <div>Ładowanie</div> return <div>Ładowanie</div>
} }
return ( return (
<div> <div>
<button <div className="flex items-center justify-between flex-col gap-3 md:flex-row md:gap-0">
className="btn btn-success" <button
onClick={() => navigate('/coordinator/add-group')} className="btn btn-success"
> onClick={() => navigate('/coordinator/add-group')}
Dodaj nową grupę >
</button> Dodaj nową grupę
</button>
<div className="flex">
<select className="select select-xs md:select-md select-bordered mr-3">
{perPageOptions.map(({ value, label }) => (
<option key={value} onClick={() => setPerPage(value)}>
{label}
</option>
))}
</select>
</div>
</div>
<div className="flex mx-auto mt-5 overflow-hidden overflow-x-auto border border-gray-100 rounded"> <div className="flex mx-auto mt-5 overflow-hidden overflow-x-auto border border-gray-100 rounded">
<table className="min-w-full table table-compact"> <table className="min-w-full table table-compact">
<thead> <thead>
@ -29,6 +78,7 @@ const Groups = () => {
<th>Opiekun</th> <th>Opiekun</th>
<th>Semestr 1</th> <th>Semestr 1</th>
<th>Semestr 2</th> <th>Semestr 2</th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-gray-100"> <tbody className="divide-y divide-gray-100">
@ -47,12 +97,50 @@ const Groups = () => {
</td> </td>
<td>{points_for_first_term}</td> <td>{points_for_first_term}</td>
<td>{points_for_second_term}</td> <td>{points_for_second_term}</td>
<td>
<button onClick={() => mutateDelete(id)}>X</button>
</td>
</tr> </tr>
), ),
)} )}
</tbody> </tbody>
</table> </table>
</div> </div>
<div className="w-full flex items-center justify-center mt-2">
<div className="btn-group">
<button
className="btn btn-outline"
onClick={() => setPage(page - 1)}
disabled={page === 1}
>
«
</button>
{[
...Array(
groups?.data?.max_pages && groups?.data?.max_pages + 1,
).keys(),
]
.slice(1)
.map((p) => (
<button
key={p}
className={classNames('btn btn-outline', {
'bg-success': p === page,
})}
onClick={() => setPage(p)}
>
{p}
</button>
))}
<button
className="btn btn-outline"
onClick={() => setPage(page + 1)}
disabled={page === groups?.data?.max_pages}
>
»
</button>
</div>
</div>
</div> </div>
) )
} }