feat(front) : tags multiselect — couleur des sites + limite d'affichage
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Failing after 11s
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Failing after 1m6s

- Sites : les tags du multiselect prennent la couleur de fond du site
  (champ color, groupe site:read) avec texte blanc, en saisie comme en
  consultation (clients, fournisseurs, prestataires, produits).
- Autres multiselects : 3 tags affichés au maximum (surplus condensé en « +N »).
- Bump @malio/layer-ui 1.7.15 → 1.7.17 (support color/textColor et maxTags
  sur les options).
This commit is contained in:
2026-06-28 14:15:50 +02:00
parent c9645caabd
commit 7cd0a90c8e
28 changed files with 130 additions and 47 deletions
@@ -16,6 +16,13 @@ import { ref } from 'vue'
export interface RefOption {
value: string
label: string
// Couleur de fond optionnelle de l'option (hex #RRGGBB). Alimentee par le
// referentiel sites (couleur d'identification du site, affichee sur les tags
// selectionnes du multiselect).
color?: string
// Couleur de texte optionnelle (hex). Sites : blanc, pour rester lisible
// sur le fond colore du tag.
textColor?: string
}
/** Membre Hydra minimal commun aux referentiels consommes ici. */
@@ -23,6 +30,7 @@ interface HydraMember {
'@id': string
name?: string
label?: string
color?: string
}
const LD_JSON_HEADERS = { Accept: 'application/ld+json' }
@@ -35,13 +43,19 @@ async function fetchOptions(
url: string,
query: Record<string, string | string[]>,
toLabel: (member: HydraMember) => string,
toColor?: (member: HydraMember) => string | undefined,
): Promise<RefOption[]> {
const res = await useApi().get<{ member?: HydraMember[] }>(
url,
{ pagination: 'false', ...query },
{ headers: LD_JSON_HEADERS, toast: false },
)
return (res.member ?? []).map(m => ({ value: m['@id'], label: toLabel(m) }))
return (res.member ?? []).map(m => ({
value: m['@id'],
label: toLabel(m),
// Couleur reportee uniquement si un extracteur est fourni (ex: sites).
...(toColor ? { color: toColor(m) } : {}),
}))
}
/** Sites de disponibilite (libelle = nom du site). */
@@ -49,7 +63,9 @@ export function useSiteOptions() {
const options = ref<RefOption[]>([])
async function load(): Promise<void> {
options.value = await fetchOptions('/sites', {}, s => s.name ?? '')
// Sites : couleur de fond depuis l'embed + texte blanc pour rester lisible.
const sites = await fetchOptions('/sites', {}, s => s.name ?? '', s => s.color)
options.value = sites.map(o => ({ ...o, textColor: '#FFFFFF' }))
}
return { options, load }