Skip to content

Room reservation - #1092

Open
imperosol wants to merge 13 commits into
taistefrom
room-reservation
Open

Room reservation#1092
imperosol wants to merge 13 commits into
taistefrom
room-reservation

Conversation

@imperosol

@imperosol imperosol commented Apr 21, 2025

Copy link
Copy Markdown
Member

Fonctionnalité pour permettre aux clubs de gérer des salles que les gens peuvent réserver.

  • Créer les modèles
  • Ecrire les tests
    • Deux créneaux ne doivent pas pouvoir être créés en même temps sur la même pièce
    • Un créneau ne doit pas pouvoir être créé dans le futur
    • Une salle ne doit être créée que par quelqu'un qui en a les droits
    • Une salle ne doit être réservable que par quelqu'un qui en a les droits
  • Générer des données pour l'environnement de dev
  • Afficher la timeline réservation des salles dans un calendrier
  • Permettre de créer une réservation directement depuis ce calendrier
  • Permettre la création de nouvelles salles depuis un formulaire

Aperçu

Le coeur de la fonctionnalité est le planning de réservation :

image

Ce planning est accessible depuis les liens sur la page d'accueil :

image

Chaque salle est liée à un site (Belfort, Sev ou Montbé) et gérée par un club.

Un club peut gérer ses salles depuis ses outils

image

Les salles sont réservables. Une réservation possède un auteur (la personne qui a fait la réservation), une salle, une heure de début et une heure de fin. Comme on peut le voir plus haut, il y a marqué en-dessous du planning qu'on peut créer une réservation en sélectionnant une plage horaire. Lorsqu'on le fait, un formulaire apparait avec les champs appropriés pré-remplis.

Si on a les permissions requises, on peut également déplacer les réservations directement par glisser-déposer sur le planning.

Modération et permission

Il n'y a pas (encore) de système de modération des événements. La PR est déjà assez grosse comme ça, je préfère passer une gestion plus fine des permissions dans une autre mise-à-jour plus tard.

Pour le moment, les réservations sont créables avec la permission globale reservation.add_reservationslot, qui sera attribuée aux respos sites (et éventuellement au bureau AE dans son ensemble aussi).
Les réservations sont modifiables avec la permission reservation.change_reservationslot, attribuée aux respos site.

Même avec les permissions requises, les réservations passées ne sont ni créables, ni modifiables. Une réservation dont l'heure de début se trouve avant le moment présent est donc gelée.

@imperosol
imperosol force-pushed the room-reservation branch 2 times, most recently from 926122e to 3ebd4b1 Compare April 23, 2025 12:23
@imperosol
imperosol force-pushed the room-reservation branch 2 times, most recently from b99fbc0 to ddf3382 Compare June 5, 2025 10:52
@imperosol
imperosol force-pushed the room-reservation branch 5 times, most recently from be1f35b to 03a04fc Compare June 18, 2025 14:14
@imperosol
imperosol force-pushed the room-reservation branch 2 times, most recently from 438b632 to cc5ab90 Compare June 21, 2025 21:40
@imperosol
imperosol marked this pull request as ready for review June 28, 2025 11:25
Comment thread core/static/core/style.scss Outdated
Comment thread package.json Outdated
@imperosol
imperosol force-pushed the room-reservation branch 4 times, most recently from 04e2e00 to 0baaf69 Compare June 30, 2025 14:16

@klmp200 klmp200 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Petit début de review parce que j'ai un peu de temps, je m'y remet plus tard

*/
async fetchResources() {
const res = await reservableroomFetchRooms();
return res.data.map((i) => Object.assign(i, { title: i.name, group: i.location }));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vu que la majorité des gens vont pas avoir le droit de voir cette page, ce serait bien de faire qu'il n'y ai pas le lien de la page pour tous les gens connectés, sinon les gens voient un truc pété comme ça quand l'api renvoi une 403
image

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est déjà le cas. Tu ne vois le lien et tu n'as le droit d'accéder à la vue que si tu a la permission de voir des réservations. Tu as peut-être oublié de générer les données de test.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Du coup, tu peux avoir le droit de voir la page mais pas forcément le droit de voir les salles, c'est étrange

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est même pire que ça. J'ai pris krophil qui est président troll (qui possède la jolly), il a la permission de réservation et pourtant on voit aucune salle dans le tableau.

Il y a un truc que je comprend pas

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je vais regarder ça

Comment thread core/management/commands/populate.py Outdated
<i class="fa-solid fa-magnifying-glass fa-xl"></i>
<a href="{{ url("matmat:search_clear") }}">{% trans %}Matmatronch{% endtrans %}</a>
</li>
{% if user.has_perm("reservation.view_reservationslot") %}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhh, ça a pas vraiment l'air de fonctionner cette histoire
J'ai connecté plusieurs users et on arrive juste sur une page pétée parce que l'api renvoie une 403 dessus

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perso, j'ai bien ça
image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, j'ai trouvé, d'après le populate, tous les cotisants ont cette perm.
En prod ce sera le cas ou pas ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui
Après, c'est comme toutes les autres perms de django, on peut choisir directement dans l'interface admin quels groupes ont quelles perms

@imperosol
imperosol force-pushed the room-reservation branch 3 times, most recently from b8bf684 to 03cdad5 Compare September 26, 2025 21:31
@imperosol
imperosol requested review from Aonfu and ken-soares October 8, 2025 13:34
<i class="fa-solid fa-magnifying-glass fa-xl"></i>
<a href="{{ url("matmat:search_clear") }}">{% trans %}Matmatronch{% endtrans %}</a>
</li>
{% if user.has_perm("reservation.view_reservationslot") %}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, j'ai trouvé, d'après le populate, tous les cotisants ont cette perm.
En prod ce sera le cas ou pas ?

Comment thread reservation/models.py
)
if self.id is not None:
overlapping = overlapping.exclude(id=self.id)
if overlapping.exists():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image Alors, j'ai pas spécialement try hard mais j'ai l'impression qu'il y a un petit soucis là. Si tu met EXACTEMENT les mêmes heures, il ne voit pas ça comme overlapping

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est un problème de lt/gt au lieu de lte/gte

*/
async fetchResources() {
const res = await reservableroomFetchRooms();
return res.data.map((i) => Object.assign(i, { title: i.name, group: i.location }));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Du coup, tu peux avoir le droit de voir la page mais pas forcément le droit de voir les salles, c'est étrange

resources: this.fetchResources,
events: this.fetchEvents,
select: this.selectFreeSlot,
selectOverlap: false,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On peut pas déplacer entre les salles la réservation, il y a une option pour ça ?

{% endfor %}
</div>
{% endif %}
<form

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Utilisation intéressante du formulaire.
Par contre, si le but c'était juste d'ajouter des attributs, on peut le faire directement dans un formulaire django https://www.geeksforgeeks.org/python/how-to-add-html-attributes-to-input-fields-in-django-forms/#methods-to-add-html-attributes

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Les attributs Alpine, je préfère les mettre dans le template. C'est pas juste un placeholder ou un autre attribut qui marche bien tout seul. L'attribut Alpine, s'il est là, c'est pour interagir avec autre chose. Si on définit les variables Alpine à plusieurs endroits différents, ça devient difficile à suivre.

Comment thread reservation/models.py
verbose_name=_("reserved room"),
)
author = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_("author"))
comment = models.TextField(_("comment"), blank=True, default="")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Le commentaire, j'ai trouvé aucun moyen de le voir, même pas un petit tooltip, rien :/

href="{{ url("reservation:room_create") }}?club={{ object.id }}"
class="btn btn-blue"
>
{% trans %}Add a room{% endtrans %}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avec l'utilisateur krophil, président club.

Ptet un ptit check pour retirer le bouton si t'as pas les droits pour ajouter une salle

Image Image

Comment thread reservation/models.py
_("site"),
blank=True,
choices=[
("BELFORT", "Belfort"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ptet un peu hardcodé quand même :/
Ça devrais pas changer mais ptet au moins mettre ça dans les settings, non ?

Comment thread reservation/urls.py
path("room/<int:room_id>/delete", RoomDeleteView.as_view(), name="room_delete"),
path(
"fragment/reservation", ReservationFragment.as_view(), name="make_reservation"
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Une page qui liste toutes les salles ce serait pas de refus, c'est vraiment difficile de s'y retrouver.
Mais ça peut être fait plus tard

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

La page qui liste toutes les salles, c'est la page des réservations

private locale = "en";
private canEditSlot = false;
private canBookSlot = false;
private canDeleteSlot = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'ai toujours pas trouvé comment delete un slot :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants