add delete group button, fix delete leader button, add filter to students and leaders in addGroup
This commit is contained in:
parent
f6b53a84a3
commit
f642d62ff0
@ -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!"}
|
||||||
|
@ -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)
|
||||||
|
@ -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}/`,
|
||||||
|
)
|
@ -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}`,
|
||||||
|
@ -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>
|
||||||
|
<div className="flex items-center justify-between flex-col gap-3 md:flex-row md:gap-0">
|
||||||
<button
|
<button
|
||||||
className="btn btn-success"
|
className="btn btn-success"
|
||||||
onClick={() => navigate('/coordinator/add-group')}
|
onClick={() => navigate('/coordinator/add-group')}
|
||||||
>
|
>
|
||||||
Dodaj nową grupę
|
Dodaj nową grupę
|
||||||
</button>
|
</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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user