Commit 2dad56d0 authored by Thomas Hamel's avatar Thomas Hamel
Browse files

Liste utilisateurs (listerAction) : passage de DataTables en mode serverSide

parent 7d316fc9
Loading
Loading
Loading
Loading
Loading
+12 −0
Changes for config/merged/utilisateur.config.php: 12 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ return [
                    'action' => [
                        'index',
                        'lister',
                        'lister-data',
                        'exporter'
                    ],
                    'privileges' => [
@@ -149,6 +150,17 @@ return [
                            ],
                        ],
                    ],
                    'lister-data' => [
                        'type'    => Literal::class,
                        'options' => [
                            'route'    => '/lister-data',
                            'defaults' => [
                                'controller' => UtilisateurController::class,
                                /** @see UtilisateurController::listerDataAction() */
                                'action' => 'lister-data',
                            ],
                        ],
                    ],
                    'ajouter' => [
                        'type' => Literal::class,
                        'options' => [
+71 −0
Changes for src/UnicaenUtilisateur/Controller/UtilisateurController.php: 71 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -375,6 +375,77 @@ class UtilisateurController extends AbstractActionController
        ]);
    }

    /**
     * fourni au tableau DataTables une page d'utilisateurs au format JSON
     */
    public function listerDataAction(): JsonModel
    {
        $parametres = $this->params()->fromQuery();

        // --- 1 pagination et recherche --------------------------------------
        $debut        = (int)($parametres['start'] ?? 0);
        $nombreLignes = (int)($parametres['length'] ?? 10);
        $recherche    = $parametres['search']['value'] ?? null;

        // --- 2 tri ------------------------------------------------------------
        $colonnesTriables = [
            0 => 'username',
            1 => 'displayName',
            2 => 'email',
            3 => 'state',
        ];

        $indexColonne = (int)($parametres['order'][0]['column'] ?? 1);
        $champTri = 'displayName';
        if (isset($colonnesTriables[$indexColonne])) $champTri = $colonnesTriables[$indexColonne];
        $sensTri = 'ASC';
        if (strtolower($parametres['order'][0]['dir'] ?? '') === 'desc') $sensTri = 'DESC';

        // --- 3 récup de la page d'utilisateurs -----------------------
        [$utilisateurs, $nombreTotal, $nombreFiltre] = $this->userService->findForDatatable(
            $debut,
            $nombreLignes,
            $recherche,
            $champTri,
            $sensTri
        );

        // --- 4 construction des lignes du tab ---------------------------
        $lignes = [];
        foreach ($utilisateurs as $utilisateur) {
            $url = $this->url()->fromRoute('utilisateur', [], ['query' => ['id' => $utilisateur->getId()]], true);
            $lien = '<a href="'.$url.'">'.$utilisateur->getUsername().'</a>';

            if ($utilisateur->getState()) {
                $statut = '<span class="temoin actif"></span>';
            } else {
                $statut = '<span class="temoin suspendu"></span>';
            }

            $roles = '<ul class="list-unstyled">';
            foreach ($this->identityService->getUserRoles($utilisateur) as $role) {
                $roles .= '<li>' . $role->getLibelle();
                if ($role->isAuto()) {
                    $roles .= ' <i title="Rôle automatique" class="fas fa-user-cog"></i>';
                }
                $roles .= '</li>';
            }
            $roles .= '</ul>';

            $nom   = $utilisateur->getDisplayName();
            $email = $utilisateur->getEmail();
            $lignes[] = [$lien, $nom, $email, $statut, $roles];
        }

        // --- 5 réponse au format attendu par DataTables ---------------------
        return new JsonModel([
            'draw'            => (int) ($parametres['draw'] ?? 0),
            'recordsTotal'    => $nombreTotal,
            'recordsFiltered' => $nombreFiltre,
            'data'            => $lignes,
        ]);
    }

    public function listerRoleAction()
    {
        $utilisateur = $this->userService->getRequestedUser($this);
+21 −0
Changes for src/UnicaenUtilisateur/Service/User/UserService.php: 21 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -235,6 +235,27 @@ class UserService extends CommonService implements RechercheIndividuServiceInter
        return $qb->getQuery()->getResult();
    }

    public function findForDatatable(int $start, int $length, ?string $search, string $orderField, string $orderDir): array
    {
        $qb = $this->getRepo()->createQueryBuilder('u');
        $total = (int) (clone $qb)->select('COUNT(u.id)')->getQuery()->getSingleScalarResult();

        if ($search !== null && $search !== '') {
            $qb->andWhere('LOWER(u.username) LIKE :s OR LOWER(u.displayName) LIKE :s OR LOWER(u.email) LIKE :s')
                ->setParameter('s', '%' . mb_strtolower($search) . '%');
        }

        $filtered = (int) (clone $qb)->select('COUNT(u.id)')->getQuery()->getSingleScalarResult();

        $qb->orderBy('u.' . $orderField, $orderDir)
            ->setFirstResult($start);
        if ($length > 0) {
            $qb->setMaxResults($length);
        }

        return [$qb->getQuery()->getResult(), $total, $filtered];
    }

    /**
     * Recherche un token d'initialisation du mot de passe
     *
+10 −35
Changes for view/unicaen-utilisateur/utilisateur/lister.phtml: 10 added lines, 35 removed lines.
Original line number Diff line number Diff line
@@ -48,34 +48,7 @@ use UnicaenUtilisateur\Entity\Db\UserInterface;
            </tr>
        </thead>
        <tbody>
            <?php foreach ($users as $user) : ?>
                <tr>
                    <td>
                        <a href="<?php echo $this->url('utilisateur', [], ['query' => ['id' => $user->getId()]], true); ?>">
                            <?php echo $user->getUsername(); ?>
                        </a>
                    </td>
                    <td> <?php echo $user->getDisplayName(); ?> </td>
                    <td> <?php echo $user->getEmail(); ?> </td>
                    <td data-order="<?php echo $user->getState(); ?>">
                        <?php
                        echo ($user->getState())
                            ? '<span class="temoin actif"></span>'
                            : '<span class="temoin suspendu"></span>';
                        ?>
                    </td>
                    <td>
                        <ul class="list-unstyled">
                            <?php foreach ($roles[$user->getId()] as $role) : ?>
                                <li>
                                    <?php echo $role->getLibelle(); ?>
                                    <?php echo $role->isAuto() ? '<i title="Rôle automatique" class="fas fa-user-cog"></i>' : ''; ?>
                                </li>
                            <?php endforeach; ?>
                        </ul>
                    </td>
                </tr>
            <?php endforeach; ?>
            <!-- données reçues par datatables -->
        </tbody>
    </table>

@@ -85,8 +58,14 @@ use UnicaenUtilisateur\Entity\Db\UserInterface;
        $(function () {
            if(jQuery().dataTable) {
                $('#utilisateur-liste').DataTable({
                "lengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "Tous"]],
                "language": {
                    serverSide: true,
                    processing: true,
                    searchDelay: 400,
                    ajax: "<?php echo $this->url('unicaen-utilisateur/lister-data'); ?>",
                    order: [[1, 'asc']],
                    columnDefs: [{ targets: 4, orderable: false }],
                    lengthMenu: [[10, 25, 50, 100, -1], [10, 25, 50, 100, "Tous"]],
                    language: {
                        'lengthMenu': "Afficher _MENU_ &eacute;l&eacute;ments",
                        "search": "Filtre de recherche : _INPUT_",
                        "loadingRecords": "Chargement en cours...",
@@ -95,12 +74,8 @@ use UnicaenUtilisateur\Entity\Db\UserInterface;
                        'infoFiltered': "<small class=\"text-highlight\">(_MAX_ &eacute;l&eacute;ments au total)</small>",
                        'emptyTable': "Aucune donnée disponible.",
                        'zeroRecords': "Aucun enregistrement trouvé.",
                    "paginate": {
                        "previous": "<i class=\"fas fa-chevron-left\"></i>",
                        "next": "<i class=\"fas fa-chevron-right\"></i>"
                    }
                    },
                "createdRow": function (row) {
                    createdRow: function (row) {
                        $('.pop-ajax', row).popAjax();
                    },
                });