Le filtre fournisseur était une recherche de sous-chaîne : impossible de comparer deux fournisseurs, et « PPR » ramenait ses homonymes au passage. Il devient une sélection multiple exacte, prise dans un menu déroulant filtrable au clavier (SelectionMultiple, générique et réutilisable). La liste vient de /api/fournisseurs, remise en ordre alphabétique — l'API la trie par montant, ce qui se lit bien dans un classement mais rend introuvable un fournisseur qu'on cherche à l'œil. Côté API, `fournisseur` devient répétable et s'entend comme un OU exact. Le filtre tag, lui, ne savait pas demander « ce qui n'est pas encore tagué » — c'est pourtant la question qui amorce le travail de tagging. `tag_id=0` le demande, et l'option « Sans tag » l'ouvre depuis la page. Au passage, les deux endpoints dupliquaient leurs filtres : ils partagent désormais _appliquer_filtres, pour que les totaux du résumé ne puissent plus porter sur d'autres lignes que la table. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
50 lines
1.7 KiB
JavaScript
50 lines
1.7 KiB
JavaScript
// Le declencheur du menu multi-selection est ce qui reste visible une fois le
|
|
// menu referme : il doit dire l'etat du filtre sans qu'on ait a le rouvrir.
|
|
import { describe, expect, it } from 'vitest'
|
|
import { createSSRApp } from 'vue'
|
|
import { renderToString } from 'vue/server-renderer'
|
|
|
|
import SelectionMultiple from '../src/components/SelectionMultiple.vue'
|
|
|
|
const FOURNISSEURS = [
|
|
{ valeur: 'ACME', libelle: 'ACME', complement: '12' },
|
|
{ valeur: 'BOREAL', libelle: 'BOREAL', complement: '3' },
|
|
{ valeur: 'CERES', libelle: 'CERES', complement: '1' },
|
|
]
|
|
|
|
function rendu(proprietes = {}) {
|
|
return renderToString(
|
|
createSSRApp(SelectionMultiple, {
|
|
options: FOURNISSEURS,
|
|
libelleVide: 'Tous',
|
|
nomPluriel: 'fournisseurs',
|
|
...proprietes,
|
|
})
|
|
)
|
|
}
|
|
|
|
describe('SelectionMultiple', () => {
|
|
it('annonce l absence de filtre quand rien n est coche', async () => {
|
|
expect(await rendu({ modelValue: [] })).toContain('Tous')
|
|
})
|
|
|
|
it('nomme le fournisseur quand il n y en a qu un', async () => {
|
|
// Le compte seul (« 1 fournisseur ») cacherait lequel, alors que c'est
|
|
// justement le cas ou la reponse tient dans le bouton.
|
|
const html = await rendu({ modelValue: ['BOREAL'] })
|
|
|
|
expect(html).toContain('BOREAL')
|
|
expect(html).not.toContain('1 fournisseurs')
|
|
})
|
|
|
|
it('compte les fournisseurs des qu il y en a plusieurs', async () => {
|
|
expect(await rendu({ modelValue: ['ACME', 'CERES'] })).toContain('2 fournisseurs')
|
|
})
|
|
|
|
it('garde le menu ferme au premier rendu', async () => {
|
|
// Une liste de dizaines de fournisseurs deployee d'entree recouvrirait la
|
|
// page a chaque chargement.
|
|
expect(await rendu({ modelValue: [] })).not.toContain('Rechercher')
|
|
})
|
|
})
|