feat(fiches): / et /agences ouvrent la fiche dans le panneau ; FicheReseauContenu extrait, FicheModal et FicheModalV2 retirées ; Voir sur la carte (B12-M4)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AGNSEFZdoKvbdsGyfSnu5S
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1bb55538a4
commit
5e0027b861
+23
-17
@@ -11,7 +11,6 @@
|
||||
libelle-recherche="Rechercher une structure…"
|
||||
:pending="pending"
|
||||
:selected-id="selectedId"
|
||||
@select="(f) => onSelectStructure(String(f.id))"
|
||||
>
|
||||
<template #carte>
|
||||
<!-- Métropole -->
|
||||
@@ -21,6 +20,7 @@
|
||||
:structures="metropoleStructures"
|
||||
:selectedId="selectedId"
|
||||
:survolId="vf.survolId == null ? null : String(vf.survolId)"
|
||||
:centrage="centrageCarte"
|
||||
@select-structure="onSelectStructure"
|
||||
@survol="(id) => (vf.survolId = id)"
|
||||
/>
|
||||
@@ -63,15 +63,18 @@
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</VueFiches>
|
||||
|
||||
<!-- ═══════════════════════════════════════ MODAL FICHE V2 -->
|
||||
<FicheModalV2
|
||||
v-model="ficheModalOpen"
|
||||
:structureId="ficheModalId"
|
||||
:data="bifurcationData"
|
||||
@update:structureId="ficheModalId = $event"
|
||||
/>
|
||||
<!-- Détail (B12) : le corps de l'ancienne FicheModalV2 ; une structure liée s'ouvre dans le même panneau -->
|
||||
<template #detail="{ fiche, filtrer }">
|
||||
<FicheReseauContenu
|
||||
:structure-id="String(fiche.id)"
|
||||
:data="bifurcationData"
|
||||
:etiquettes-actives="(vf.etat.filtres.tags ?? []).map((t) => `#${t}`)"
|
||||
@etiquette="(tag) => filtrer('tags', sansDiese(tag))"
|
||||
@voisin="(id) => vf.ouvrirFiche(id)"
|
||||
/>
|
||||
</template>
|
||||
</VueFiches>
|
||||
|
||||
<!-- ═══════════════════════════════════════ BOUTON CHATBOT FLOTTANT (mobile) -->
|
||||
<button
|
||||
@@ -221,18 +224,21 @@ const vf = useVueFiches(fichesMini, config)
|
||||
// La carte ne montre que le résultat courant (recherche + filtres)
|
||||
const metropoleStructures = computed<StructureV2[]>(() => structures.value.filter((s) => vf.idsResultat.has(s.id)))
|
||||
|
||||
// ── Sélection : FicheModalV2 à toutes les largeurs (comportement d'avant B11) ──
|
||||
const selectedId = ref<string | null>(null)
|
||||
const ficheModalOpen = ref(false)
|
||||
const ficheModalId = ref<string | null>(null)
|
||||
// ── Sélection (B12) : la fiche ouverte vit dans l'URL (`fiche=`), détail en panneau ──
|
||||
const selectedId = computed<string | null>(() => vf.ficheId)
|
||||
|
||||
function onSelectStructure(id: string) {
|
||||
const ordinateur = typeof window !== 'undefined' && window.innerWidth >= 1024
|
||||
selectedId.value = ordinateur && selectedId.value === id ? null : id
|
||||
ficheModalId.value = id
|
||||
ficheModalOpen.value = true
|
||||
vf.ouvrirFiche(id)
|
||||
}
|
||||
|
||||
// « Voir sur la carte » : l'épingle est sur la carte Métropole (pas dans le graphe)
|
||||
const centrageCarte = ref<{ id: string; n: number } | null>(null)
|
||||
watch(() => vf.centrage, (c) => {
|
||||
if (!c) return
|
||||
if (vf.etat.sousVue !== 'metropole') vf.setSousVue('metropole')
|
||||
centrageCarte.value = { id: c.id, n: c.n }
|
||||
})
|
||||
|
||||
// ── Boutons flottants (téléphone) : au-dessus du pied « Voir les N fiches » en état Carte ──
|
||||
const chatbotOpen = ref(false)
|
||||
const missionOpen = ref(false)
|
||||
|
||||
+47
-29
@@ -17,7 +17,7 @@
|
||||
libelle-recherche="Rechercher une structure…"
|
||||
:pending="pending"
|
||||
:selected-id="selectedId"
|
||||
@select="(f) => onSelectOrg(Number(f.id))"
|
||||
:lien-page="(f) => `/fiche/${f.id}`"
|
||||
>
|
||||
<template #carte>
|
||||
<!-- Métropole -->
|
||||
@@ -27,6 +27,7 @@
|
||||
:orgs="metropoleOrgs"
|
||||
:selectedId="selectedId"
|
||||
:survolId="survolNum"
|
||||
:centrage="centrageMetropole"
|
||||
@select-org="onSelectOrg"
|
||||
@survol="(id) => (vf.survolId = id)"
|
||||
/>
|
||||
@@ -55,13 +56,22 @@
|
||||
<ChatbotPlaceholder @highlightOrgs="onHighlightOrgs" />
|
||||
</div>
|
||||
</template>
|
||||
</VueFiches>
|
||||
|
||||
<!-- ═══════════════════════════════════════ MODAL FICHE (ordinateur) -->
|
||||
<FicheModal
|
||||
v-model="ficheModalOpen"
|
||||
:orgId="ficheModalId"
|
||||
/>
|
||||
<!-- Détail (B12) : la fiche complète vient de la liste (même enregistrement NocoDB que /api/fiche/:id) -->
|
||||
<template #detail="{ fiche, filtrer }">
|
||||
<template v-if="orgParId.get(String(fiche.id))">
|
||||
<FicheDetail
|
||||
:key="fiche.id"
|
||||
:org="orgParId.get(String(fiche.id))!"
|
||||
compact
|
||||
etiquettes-cliquables
|
||||
@etiquette="(t) => filtrer('fonctions', t)"
|
||||
/>
|
||||
<CommentSection :key="`c-${fiche.id}`" :org-id="Number(fiche.id)" :refresh="commentaires" />
|
||||
<CommentForm :key="`f-${fiche.id}`" :org-id="Number(fiche.id)" @submitted="commentaires++" />
|
||||
</template>
|
||||
</template>
|
||||
</VueFiches>
|
||||
|
||||
<!-- ═══════════════════════════════════════ BOUTON CHATBOT FLOTTANT (mobile) -->
|
||||
<button
|
||||
@@ -171,41 +181,49 @@ const metropoleOrgs = computed<Org[]>(() => orgsFiltres.value.filter((o) => !o.t
|
||||
const outremerOrgs = computed<Org[]>(() => orgsFiltres.value.filter((o) => o.territoire && DOM_TOM.includes(o.territoire)))
|
||||
const survolNum = computed(() => (vf.survolId == null ? null : Number(vf.survolId)))
|
||||
|
||||
// ── Sélection ─────────────────────────────────────────────────────────────
|
||||
const selectedId = ref<number | null>(null)
|
||||
const ficheModalOpen = ref(false)
|
||||
const ficheModalId = ref<number | null>(null)
|
||||
// ── Sélection (B12) : la fiche ouverte vit dans l'URL (`fiche=`), détail en panneau ──
|
||||
const orgParId = computed(() => new Map(orgs.value.map((o) => [String(o.Id), o])))
|
||||
|
||||
// Épingle et carte-fiche allumées : la fiche ouverte, ou 5 s celle que le chatbot désigne
|
||||
const surligneId = ref<number | null>(null)
|
||||
const selectedId = computed<number | null>(() => surligneId.value ?? (vf.ficheId != null ? Number(vf.ficheId) : null))
|
||||
|
||||
const commentaires = ref(0)
|
||||
|
||||
// Ordinateur : FicheModal ; téléphone et tablette : page /fiche/:id (comportement d'avant B11)
|
||||
function onSelectOrg(id: number) {
|
||||
if (typeof window !== 'undefined' && window.innerWidth >= 1024) {
|
||||
selectedId.value = selectedId.value === id ? null : id
|
||||
ficheModalId.value = id
|
||||
ficheModalOpen.value = true
|
||||
return
|
||||
}
|
||||
selectedId.value = id
|
||||
try {
|
||||
// Le bouton retour de /fiche/:id revient à la même vue, filtres compris
|
||||
sessionStorage.setItem('nav_back_filters', new URLSearchParams(route.query as Record<string, string>).toString())
|
||||
} catch {}
|
||||
router.push(`/fiche/${id}`)
|
||||
vf.ouvrirFiche(id)
|
||||
}
|
||||
|
||||
// « Voir sur la carte » : la bonne sous-vue (Métropole ou Outre-mer), puis l'épingle
|
||||
const centrageMetropole = ref<{ id: number; n: number } | null>(null)
|
||||
watch(() => vf.centrage, (c) => {
|
||||
if (!c) return
|
||||
const o = orgParId.value.get(c.id)
|
||||
const dom = !!o?.territoire && DOM_TOM.includes(o.territoire)
|
||||
if (vf.etat.sousVue !== (dom ? 'outremer' : 'metropole')) vf.setSousVue(dom ? 'outremer' : 'metropole')
|
||||
if (!dom) centrageMetropole.value = { id: Number(c.id), n: c.n }
|
||||
})
|
||||
|
||||
// Le bouton retour de /fiche/:id (« Ouvrir la page de la fiche ») revient à la même vue
|
||||
if (import.meta.client) {
|
||||
watch(() => route.fullPath, () => {
|
||||
try {
|
||||
sessionStorage.setItem('nav_back_filters', new URLSearchParams(route.query as Record<string, string>).toString())
|
||||
} catch {}
|
||||
}, { immediate: true })
|
||||
}
|
||||
|
||||
// Surlignage temporaire (5 s) suite à une réponse chatbot
|
||||
let highlightTimer: ReturnType<typeof setTimeout> | null = null
|
||||
const prevSelectedId = ref<number | null>(null)
|
||||
|
||||
function onHighlightOrgs(ids: (number | string)[]) {
|
||||
if (!ids.length) return
|
||||
const firstId = typeof ids[0] === 'string' ? parseInt(ids[0], 10) : ids[0]
|
||||
if (isNaN(firstId)) return
|
||||
prevSelectedId.value = selectedId.value
|
||||
selectedId.value = firstId
|
||||
surligneId.value = firstId
|
||||
if (highlightTimer) clearTimeout(highlightTimer)
|
||||
highlightTimer = setTimeout(() => {
|
||||
selectedId.value = prevSelectedId.value
|
||||
prevSelectedId.value = null
|
||||
surligneId.value = null
|
||||
highlightTimer = null
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user