Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Courts organization #24

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
41811fe
feat: add Court Model
cmglezpdev Nov 18, 2022
9725703
feat: add frist view of create a court
cmglezpdev Nov 18, 2022
00a30c0
feat: add basic check
cmglezpdev Nov 18, 2022
3f33cbb
feat: add select number
cmglezpdev Nov 18, 2022
59076e5
feat: add default values in date and time selectors
cmglezpdev Nov 18, 2022
fa5eab3
feat: add complete check of tribunal disponibility
cmglezpdev Nov 18, 2022
a2fef43
feat: change inputs of time and date
cmglezpdev Nov 18, 2022
d2d1b18
feat: add custom encode to the Court model
cmglezpdev Nov 19, 2022
3ff89c6
feat: show all courts
cmglezpdev Nov 19, 2022
aa518bd
feat: add filter to show the courts
cmglezpdev Nov 19, 2022
9ace556
feat: add place filter
cmglezpdev Nov 19, 2022
5765199
feat: modify a court but no save it
cmglezpdev Nov 19, 2022
aae0160
chore: change name of encode method by print
cmglezpdev Nov 19, 2022
911e06e
feat: save a court that is changed
cmglezpdev Nov 19, 2022
0647b6c
feat: modif the check of Court to save a court changed
cmglezpdev Nov 19, 2022
b2151e2
feat: add Place model
cmglezpdev Nov 19, 2022
58ba4b7
feat: add a new place from form
cmglezpdev Nov 19, 2022
2dd7327
feat: show edit court button only when exist courts
cmglezpdev Nov 19, 2022
d369014
feat: show create tribunal tab when you have access
cmglezpdev Nov 19, 2022
0007b5b
feat: show message when you dont have access
cmglezpdev Nov 19, 2022
0ef299d
fix: values to print
cmglezpdev Nov 20, 2022
f5fadc0
fix: exclude the modification of thesis inside a tribunal
cmglezpdev Nov 20, 2022
e87e35e
feat: show warning icon when a court is in conflicting with other court
cmglezpdev Nov 22, 2022
2b5aa1a
feat: show waring error when a court is in conflicting
cmglezpdev Nov 22, 2022
4c46229
fix: can add a court in the last minute that ended the prev
cmglezpdev Nov 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion dashboard/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
from pathlib import Path
from typing import List
from uuid import UUID, uuid4
from datetime import timedelta, datetime as Datetime

import yaml
import streamlit as st
from datetime import date
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel, Field, HttpUrl, EmailStr
from typing_extensions import Self
Expand Down Expand Up @@ -551,3 +551,54 @@ def create(cls, key, obj=None):
awarded=awarded,
date=date,
)

class Place(CustomModel):
description: str

class Court(CustomModel):
thesis: Thesis = None
members: List[Person]
date: Datetime = None
minutes_duration: int
place: Place = None

def check(self):
if len(self.members) < 1:
raise ValueError("Se debe agregar los miembros del tribunal")

if len(self.place.description) < 1:
raise ValueError("Se debe agregar un lugar")

for court in Court.all():
if court.uuid == self.uuid:
continue

if court.thesis == self.thesis:
raise ValueError("Ya existe un tribual para esta tesis")

end_time = court.date + timedelta(minutes=court.minutes_duration)
self_end_time = self.date + timedelta(minutes=self.minutes_duration)

if court.date.date() == self.date.date():
if court.date.time() <= self.date.time() <= end_time.time() or self.date.time() <= court.date.time() <= self_end_time.time():

# two theses in the same place and the same hour
if self.place == court.place:
raise ValueError(f"Ya existe una discusión de una tesis en __{court.place.description}__ a esa hora")

# a peron in two places in the same moment
for member in self.members:
if member in court.members:
raise ValueError(f"__{member.name}__ ya está en otro tribunal en ese momento")

return True

def print(self) -> dict:
return {
"Tesis": f"{self.thesis.title} - {self.thesis.authors[0]}",
"Miembros del tribunal": ", ".join([member.name for member in self.members]),
"Fecha": self.date.strftime("%Y-%m-%d"),
"Hora Inicio": self.date.strftime("%H:%M"),
"Hora Termina": (self.date + timedelta(minutes=self.minutes_duration)).strftime("%H:%M"),
"Lugar": self.place.description,
}
141 changes: 137 additions & 4 deletions dashboard/pages/04_🎓_tesis.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import collections
import json
import datetime
from pathlib import Path
from typing import List

import pandas as pd
import streamlit as st
from models import Thesis
from models import Thesis, Court, Person, Place
from modules.utils import generate_widget_key
from modules.graph import build_advisors_graph

st.set_page_config(page_title="MatCom Dashboard - Tesis", page_icon="🎓", layout="wide")

listing, create,details = st.tabs(["📃 Listado", "➕ Crear nueva Tesis", "📄 Detalles"])
listing, create, thesis_details, courts, court_details = st.tabs(["📃 Listado", "➕ Crear nueva Tesis", "📄 Detalles - Tesis", "🤵 Tribunales", "📜 Detalles - Tribunales"])

theses: List[Thesis] = []

Expand Down Expand Up @@ -124,8 +125,10 @@
st.error(e)

st.code(thesis.yaml(), "yaml")

with details:
else:
st.error("Acceso de solo lectura. Vaya a la página principal para loguearse.")

with thesis_details:
thesis = st.selectbox(
"Seleccione una tesis",
sorted(theses, key=lambda t: t.title),
Expand Down Expand Up @@ -153,3 +156,133 @@
)
else:
st.write(f"#### No existe el pdf de la tesis")

with courts:
if st.session_state.get('write_access', False):
selected = st.radio(
"Tipo de entrada",
["⭐ Nuevo Tribunal"] + (["📝 Editar Tribunal"] if len(Court.all()) > 0 else []),
horizontal=True,
label_visibility="collapsed"
)

if selected == "📝 Editar Tribunal":
court = st.selectbox(
"Seleccione un tribunal a modificar",
sorted(Court.all(), key=lambda c: c.thesis.title),
format_func=lambda c: f"{c.thesis.title}",
)
else:
court = Court(thesis=None, members=[], date=None, minutes_duration=60, place=None)

left, right = st.columns([2, 1])

with left:

if selected == "⭐ Nuevo Tribunal":
theses = sorted(theses, key=lambda t: t.title)
court.thesis = st.selectbox(
"Seleccione una tesis",
theses,
format_func=lambda t: f"{t.title} - {t.authors[0]}",
index=theses.index(court.thesis if court.thesis else theses[0]),
key='courts_select_thesis',
)

court.members = st.multiselect(
'Seleccione los miembros de la tesis',
Person.all(),
[p for p in Person.all() if p.name in court.thesis.advisors] # selected advisors
)

places = sorted(Place.all(), key=lambda p: p.description) + [ Place(description="➕ Nueva entrada") ]
court.place = st.selectbox(
'Seleccione un local',
places,
format_func=lambda p: p.description,
index=places.index(court.place if court.place else places[0]),
key='courts_select_places',
)
if court.place.description == "➕ Nueva entrada":
court.place.description = st.text_input(
"Descripción del lugar",
key="court_place_description",
)

date = st.date_input(
'Seleccione una fecha',
value=court.date.date() if court.date else datetime.date.today(),
)
time = st.time_input(
'Seleccione una hora',
value=court.date.time() if court.date else datetime.time(9, 0),
)
court.date = datetime.datetime(
year=date.year,
month=date.month,
day=date.day,
hour=time.hour,
minute=time.minute
)

court.minutes_duration = st.number_input(
'Introduce los minutos de duración',
step=5,
min_value=20,
value = court.minutes_duration
)

with right:
try:
court.check()

if st.button("💾 Guardar Tribunal"):
court.save()
court.place.save()
if selected == "⭐ Nuevo Tribunal":
st.success(f"¡Tribunal de la tesis _{court.thesis.title}_ creada con éxito!")
elif selected == "📝 Editar Tribunal":
st.success(f"¡Tribunal de la tesis _{court.thesis.title}_ editada con éxito!")

except ValueError as e:
st.error(e)
else:
st.error("Acceso de solo lectura. Vaya a la página principal para loguearse.")


with court_details:
st.write("##### 🏷️ Filtros")

places = sorted(Place.all(), key=lambda p: p.description)
member_selected = st.selectbox(
"Filtrar por un miembro de tribunal",
["Todos"] + [ p.name for p in Person.all() ],
key='court_details_select_member',
)

place_selected = st.selectbox(
"Filtrar por un lugar",
["Todos"] + [ p for p in places ],
key='court_details_select_place',
)

data = []
for court in Court.all():
include = True
if member_selected != "Todos":
if member_selected not in [p.name for p in court.members]:
include = False

if place_selected != "Todos":
if place_selected != court.place:
include = False

if include:
data.append(court.print())


if len(data) > 0:
df = pd.DataFrame(data)
st.dataframe(df)
else:
st.error("No hay datos para mostrar")