Explorar o código

gestion formulaires en modales

garthh hai 2 días
pai
achega
b951a8f4b3

+ 44 - 0
assets/controllers/bulma_modal_controller.js

@@ -0,0 +1,44 @@
+
+import { Controller } from "@hotwired/stimulus"
+
+export default class extends Controller {
+    connect() {
+        this._closeListener = () => this.close()
+        window.addEventListener('modal:close', this._closeListener)
+
+        // Écoute tous les clics sur .open-modal
+        document.querySelectorAll('.open-modal').forEach(element => {
+            element.addEventListener('click', this.handleClick.bind(this))
+        })
+    }
+
+    disconnect() {
+        window.removeEventListener('modal:close', this._closeListener)
+
+        // Nettoie les événements attachés
+        document.querySelectorAll('.open-modal').forEach(element => {
+            element.removeEventListener('click', this.handleClick.bind(this))
+        })
+    }
+
+    handleClick(event) {
+        event.preventDefault()
+        const url = event.currentTarget.getAttribute('href') || event.currentTarget.dataset.url
+
+        if (!url) return
+
+        fetch(url, {
+            headers: { "Turbo-Frame": "modal-content" }
+        })
+        .then(response => response.text())
+        .then(html => {
+            document.getElementById('modal-content').innerHTML = html
+            document.getElementById('modal').classList.add('is-active')
+        })
+    }
+
+    close() {
+        document.getElementById('modal').classList.remove('is-active')
+        document.getElementById('modal-content').innerHTML = ''
+    }
+}

+ 18 - 9
src/Controller/PartyController.php

@@ -33,7 +33,7 @@ final class PartyController extends AbstractController
 
     // supprimer une partie
     #[Route('/party/delete/{id}', name: 'app_party_delete', requirements: ['id' => Requirement::UUID_V7], methods: ['GET'])]
-    public function delete(?Party $party, EntityManagerInterface $manager, SlotRepository $slotRepository): Response
+    public function delete(?Party $party, Request $request, EntityManagerInterface $manager, SlotRepository $slotRepository): Response
     {
         // Seuls admin (ADMIN)
         $user = $this->getUser();
@@ -50,12 +50,14 @@ final class PartyController extends AbstractController
         } else {
             $this->addFlash('danger', 'Seuls les admins peuvent supprimer une partie.');
         }
-        return $this->redirectToRoute('app_main'); // @todo: à changer   
+            //return $this->redirectToRoute('app_main'); // @todo: à modifier !
+            $referer = $request->headers->get('referer'); 
+            return $this->redirect($referer);  
     }
 
     // valider une partie proposée par un MJ
     #[Route('/party/validate/{id}', name: 'app_party_validate', requirements: ['id' => Requirement::UUID_V7], methods: ['GET'])]
-    public function validate(?Party $party, EntityManagerInterface $manager, SlotRepository $slotRepository): Response
+    public function validate(?Party $party, Request $request, EntityManagerInterface $manager, SlotRepository $slotRepository): Response
     {
         // Seuls gestionnaires (MANAGER), admin (ADMIN)
         $user = $this->getUser();
@@ -72,7 +74,9 @@ final class PartyController extends AbstractController
         } else {
             $this->addFlash('danger', 'Seuls les rôles Gestionnaires et Admin peuvent valider une partie');
         }
-        return $this->redirectToRoute('app_main'); // @todo: à changer    
+            //return $this->redirectToRoute('app_main'); // @todo: à modifier !
+            $referer = $request->headers->get('referer'); 
+            return $this->redirect($referer); 
     }
 
     // modifier une partie
@@ -147,8 +151,9 @@ final class PartyController extends AbstractController
             } else {
                 $this->addFlash('danger', 'Pas de MJ ou de jeu sélectionné.');
             }
-            return $this->redirectToRoute('app_main'); // @todo: à modifier !
-
+            //return $this->redirectToRoute('app_main'); // @todo: à modifier !
+            $referer = $request->headers->get('referer'); 
+            return $this->redirect($referer);
         }
 
         return $this->render('party/edit.html.twig', [
@@ -158,7 +163,8 @@ final class PartyController extends AbstractController
             'games' => $games,
             'slotStart' => $slotStart,
             'slotsAvailables' => $slotsAvailables,
-            'mod' => true
+            'mod' => true,
+            'pathController' => 'app_party_modify'
         ]);
     }
 
@@ -247,7 +253,9 @@ final class PartyController extends AbstractController
             } else {
                 $this->addFlash('danger', 'Pas de MJ ou de jeu sélectionné.');
             }
-            return $this->redirectToRoute('app_main'); // @todo: à modifier !
+            //return $this->redirectToRoute('app_main'); // @todo: à modifier !
+            $referer = $request->headers->get('referer'); 
+            return $this->redirect($referer);
 
         }
 
@@ -258,7 +266,8 @@ final class PartyController extends AbstractController
             'games' => $games,
             'slotStart' => $slotStart,
             'slotsAvailables' => $slotsAvailables,
-            'mod' => false
+            'mod' => false,
+            'pathController' => 'app_party_add'
         ]);
     }
 

+ 6 - 0
templates/admin/event/config/party.html.twig

@@ -13,6 +13,12 @@
       </ul>
     </nav>
 
+    <div id="modal" class="modal" {{ stimulus_controller('bulma_modal')}}>
+      <div class="modal-background" data-action="click->modal#close"></div>
+      <div class="modal-content" id="modal-content"></div>
+      <button class="modal-close is-large" aria-label="close" data-action="click->modal#close"></button>
+    </div>
+
     <div class="box has-text-centered">
       <strong class="has-text-primary">{{ event.name }}</strong> du {{ event.startOn|date('d/m/Y H:i', app_timezone) }} au {{ event.endOn|date('d/m/Y H:i', app_timezone) }}
     </div>

+ 3 - 3
templates/components/Planning.html.twig

@@ -58,7 +58,7 @@
                                                     <div class="media">
                                                         <div class="media-left">
                                                             <figure class="image is-48x48">
-                                                                {% if pathFullSlot %}<a href="{{ path(pathFullSlot, {id: thisSlot.id}) }}">{% endif %}
+                                                                {% if pathFullSlot %}<a href="{{ path(pathFullSlot, {id: thisSlot.id}) }}" class="open-modal">{% endif %}
                                                                 {% if thisSlot.party.gamemaster.picture %}
                                                                 <img class="is-rounded" src="/images/gamemasters/{{ thisSlot.party.gamemaster.picture }}"  />
                                                                 {% else %}
@@ -69,7 +69,7 @@
                                                         </div>
                                                     </div>
                                                         <div class="media-content">
-                                                            {% if pathFullSlot %}<a href="{{ path(pathFullSlot, {id: thisSlot.id}) }}">{% endif %}<span class="title is-6">{{ thisSlot.party.game.name }}</span>{% if pathFullSlot %}</a>{% endif %}<br/>
+                                                            {% if pathFullSlot %}<a href="{{ path(pathFullSlot, {id: thisSlot.id}) }}" class="open-modal">{% endif %}<span class="title is-6">{{ thisSlot.party.game.name }}</span>{% if pathFullSlot %}</a>{% endif %}<br/>
                                                             <small class="hax-text-grey-light">@{{ thisSlot.party.gamemaster.preferedName }}{% if thisSlot.party.gamemasterIsAuthor %}<br/><span class="tag is-info">animée par l'auteur</span>{% endif %}</small>
                                                         </div>
 
@@ -97,7 +97,7 @@
                         {# si le slot est disponible et sans partie #}
                         {% if not thisSlot.unavailable and not thisSlot.party %}
                             {% if pathEmptySlot %}
-                            <a href="{{ path(pathEmptySlot, {id: thisSlot.id}) }}">
+                            <a href="{{ path(pathEmptySlot, {id: thisSlot.id}) }}"  class="open-modal">
                             <div class="cell planning-cell planning-cell-free" data-id="{{ thisSlot.id }}">
                                 <div class="icon"><twig:ux:icon name="bi:plus-circle" /></div>
                             </div>

+ 9 - 0
templates/modal.html.twig

@@ -0,0 +1,9 @@
+<div class="modal-card">
+    <div class="modal-card-head">
+        <h1 class="title is-3">{% block title %}{% endblock %}</h1>
+    </div>
+    <section class="modal-card-body">
+{% block content %}
+{% endblock %}
+</section>
+</div>

+ 3 - 3
templates/party/edit.html.twig

@@ -1,6 +1,6 @@
-{% extends 'bulma.html.twig' %}
+{% extends 'modal.html.twig' %}
 
-{% block title %}Ajouter une partie{% endblock %}
+{% block title %}{% if mod %}Modifier{%else%}Ajouter{% endif %} une partie{% endblock %}
 
 {% block content %}
 
@@ -16,7 +16,7 @@
     {% endif %}
 
     {{ form_errors(form) }}
-    {{ form_start(form) }}
+    {{ form_start(form, {action: path(pathController, {id: slotStart.getId}), attr: {'data-turbo-frame': 'modal-content'}}) }}
 
     <div id="gamemaster-controller" class="field" {{ stimulus_controller('party_selector') }}>
         <label class="label">Meneur(euse) de jeu</label>