---
title: "Recherche avancée"
module: search
type: functional
status: active
updated: 2026-06-30
---

# Recherche avancée

Page dédiée permettant de rechercher dans l'ensemble des données ISI-App via Meilisearch, avec navigation par **onglets de rubriques** (toutes les rubriques accessibles, compteur de résultats par rubrique) et tableaux de résultats riches triés par ordre alphabétique. Complémentaire de la recherche rapide (autocomplete `Ctrl+K`) qui reste mono-input et globale.

URL : `/advanced-search`

---

## À quoi ça sert

L'utilisateur peut :
- Saisir un **terme de recherche** (minimum 2 caractères)
- Voir, pour **chaque rubrique** (utilisateurs, entités, tickets, projets…), le **nombre de résultats** correspondant au terme, affiché dans le badge de son onglet et mis à jour pendant la frappe
- Naviguer entre les rubriques via des **onglets** : toutes les rubriques accessibles sont affichées en permanence (y compris celles à 0 résultat), triées par ordre alphabétique
- Consulter les résultats par **onglet** : chaque rubrique a son propre tableau avec ses colonnes, **triés par ordre alphabétique** (A→Z) sur le libellé principal
- Repérer en un coup d'œil le terme recherché, **surligné** dans les résultats
- Cliquer sur une ligne → redirection vers la page de visualisation de l'entité

Différence avec la recherche rapide (`Ctrl+K`) : la recherche avancée offre un tableau riche, paginé et trié par rubrique, alors que `Ctrl+K` donne un aperçu rapide tous types confondus.

---

## Rubriques disponibles

Les rubriques sont filtrées selon les **droits modules** de l'utilisateur. Une rubrique est cachée si :
- Elle est désactivée dans la config (`enabled => false`)
- L'utilisateur n'a pas le module requis (clé `module_tag`)

| Rubrique | Module requis |
|---|---|
| Utilisateurs, Entités, Adresses, Fournisseurs, Documents, Contrats, Wikis, Actualités | aucun |
| Tickets | `ticket` |
| Projets, Backlogs | `projet` |
| Applications, Matériel, Machines virtuelles | `informatique` |
| Bâtiments, Lots, Pièces, Équipements | aucun (GMAO ouvert) |

**Booklets** et **Missions** sont actuellement désactivés (pas de page de visualisation dédiée trouvée).

---

## Comportement

1. À l'ouverture, la page propose une barre de recherche.
2. La saisie déclenche une recherche **debouncée à 500 ms** (évite les appels Meilisearch à chaque touche).
3. Sous **2 caractères**, un état "Continuez à taper..." s'affiche.
4. À partir de **2 caractères**, une rangée d'**onglets** apparaît : un par rubrique accessible, triés par ordre alphabétique, chacun avec son **compteur de résultats** (badge) pour le terme tapé. Tous les onglets restent affichés, **y compris ceux à 0 résultat**.
5. L'onglet actif (par défaut la première rubrique) affiche son tableau de résultats avec :
   - Les colonnes définies dans la config de la rubrique
   - Les résultats triés par **ordre alphabétique** (A→Z) sur le libellé principal de la rubrique (1re colonne)
   - Le terme recherché **surligné** dans les cellules texte
   - Une pagination 10 résultats par page (indépendante par onglet)
   - Un bouton "Voir" sur chaque ligne pour ouvrir la fiche de l'entité
6. Si la rubrique active n'a aucun résultat, son tableau affiche "Aucun résultat".
7. Si Meilisearch est indisponible, un message d'erreur s'affiche à la place de la barre de recherche.

Les paramètres `q` (terme) et `tab` (onglet actif) sont **bookmarkables** via l'URL (ex: `/advanced-search?q=imprimante&tab=tickets`). Une rubrique non autorisée passée dans `tab` retombe sur la première rubrique accessible (sécurité).

---

## Fichiers concernés

| Fichier | Rôle |
|---|---|
| `routes/web.php` | Déclaration de la route `advanced-search` (middleware `auth, sub, pswd`) |
| `app/Http/Controllers/SearchController.php` | Contrôleur (méthode `index`) |
| `resources/views/search/index.blade.php` | Vue layout |
| `app/Livewire/Search/AdvancedSearchTable.php` | Composant unique : barre + onglets de rubriques + tableau (extends GenericTable) |
| `resources/views/livewire/search/advanced-search-table/wrapper.blade.php` | Vue principale (header + barre + onglets compteurs + zone résultats) |
| `resources/views/livewire/search/advanced-search-table/view.blade.php` | Rendu du tableau (headers + cellules avec rendu inline + surlignage) |
| `resources/views/livewire/search/advanced-search-table/filters.blade.php` | Vue filtres (vide en V1) |
| `app/Services/MeilisearchSearchService.php` | `searchIds()` (pagination + surlignage) + `countByIndex()` (compteurs par rubrique) |
| `app/Services/MeilisearchService.php` | `multiSearch()` (compteurs ; honore la stratégie de matching) |
| `config/meilisearch.php` | Config `advanced_search` par index |

---

## Configuration d'une rubrique

Pour activer/configurer la recherche avancée sur un index existant, éditer `config/meilisearch.php` et ajouter une clé `advanced_search` à l'index :

```php
'advanced_search' => [
    'enabled' => true,
    'label' => 'Tickets',
    'icon' => 'fa-solid fa-ticket',
    'group' => 'Général',
    'module_tag' => 'ticket',
    'view_url' => '/mod/13200101/see/{id}',
    'pk_field' => 'idask',
    'columns' => [
        ['key' => 'idask', 'label' => '#', 'type' => 'text', 'sortable' => true],
        ['key' => 'lbask', 'label' => 'Sujet', 'type' => 'text', 'sortable' => true],
        // ...
    ],
],
```

Pour désactiver une rubrique : `'advanced_search' => ['enabled' => false]`.

---

## Limites actuelles (V1)

- **Tri alphabétique fixe (A→Z) sur le libellé principal** : pas encore de tri par colonne cliquable ni de choix du sens. Le tri est appliqué côté Meilisearch (option `sort`, `sort` placé en tête des `ranking_rules`) et conservé côté Eloquent via `ORDER BY FIELD()`.
- **Pas de filtres additionnels par champ** : seul le terme de recherche global est utilisé. Les filtres config-driven via `filterable_attributes` viendront en V2.
- **Export limité à 1000 résultats** : pour des volumes plus importants, il faudra utiliser le module export-import classique.
- **Booklets** et **Missions** : URLs de visualisation non identifiées, donc rubriques désactivées.
- **Documents et Contrats** : le `view_url` simple `/mod/.../see/{id}` est insuffisant car ces entités nécessitent `idmod`, `idmodmaster`, `idmaster` (cf. herobar Ctrl+K). À raffiner en V2.
