feat: badge published events with their direct mairie link
Additive enrichment after the list renders: never blocks the list, and a scraping failure leaves it intact without badge. The 'Créer' button is removed for published events (anti-duplicate). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6c4f4219f1
commit
9c7099f224
@@ -59,6 +59,28 @@ h1 {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.evenement-publication {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.evenement-publie {
|
||||
align-self: flex-end;
|
||||
padding: 0.15rem 0.5rem;
|
||||
border-radius: 0.75rem;
|
||||
background: #1a7f37;
|
||||
color: #fff;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.evenement-lien-mairie {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
#etat {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
+58
-1
@@ -2,6 +2,8 @@ import { recupererFluxCalendrier } from "./nextcloud.js";
|
||||
import { parserEvenements } from "./evenements.js";
|
||||
import { formaterDate, formaterLieu, trierParDebut } from "./presentation.js";
|
||||
import { deposerEvenement } from "./transfert.js";
|
||||
import { calculerPeriode, extraireCartes, recupererAgendaPublie } from "./agenda-mairie.js";
|
||||
import { indexerCartes, trouverPublication } from "./publication.js";
|
||||
|
||||
const URL_NEXTCLOUD = "https://atelier-huit.frama.space/";
|
||||
|
||||
@@ -49,6 +51,8 @@ function rendreEvenements(evenements) {
|
||||
function rendreEvenement(evenement) {
|
||||
const item = document.createElement("li");
|
||||
item.className = "evenement";
|
||||
// Ancre pour retrouver le <li> lors de l'annotation « publié » (phase 2).
|
||||
item.dataset.uid = evenement.uid;
|
||||
|
||||
const infos = document.createElement("div");
|
||||
infos.className = "evenement-infos";
|
||||
@@ -135,10 +139,63 @@ async function charger() {
|
||||
// « Illegal invocation » dans le navigateur.
|
||||
const res = await recupererFluxCalendrier((u, o) => fetch(u, o));
|
||||
if (res.ok) {
|
||||
rendreEvenements(trierParDebut(parserEvenements(res.flux, new Date())));
|
||||
const evenements = trierParDebut(parserEvenements(res.flux, new Date()));
|
||||
rendreEvenements(evenements);
|
||||
// Enrichissement additif : la liste est déjà rendue, l'agenda ne la
|
||||
// bloque jamais. Un échec de scraping laisse la liste intacte, sans badge.
|
||||
// Fire-and-forget : le `.catch` garantit qu'aucune erreur imprévue
|
||||
// (indexation, annotation) ne devienne une rejection non gérée.
|
||||
annoterPublications(evenements).catch((erreur) =>
|
||||
console.error("Écho du Huit : annotation des publications interrompue.", erreur),
|
||||
);
|
||||
} else {
|
||||
rendreErreur(res.erreur);
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 2 : marque « publié » les événements retrouvés sur l'agenda mairie et y
|
||||
// pose leur lien direct. Dégradation gracieuse : agenda injoignable ou structure
|
||||
// changée → on ne touche à rien (aucun faux positif, biais précision v1).
|
||||
async function annoterPublications(evenements) {
|
||||
if (evenements.length === 0) return;
|
||||
|
||||
const periode = calculerPeriode(evenements, new Date());
|
||||
// Agenda public : fetch SANS credentials.
|
||||
const res = await recupererAgendaPublie((u, o) => fetch(u, o), extraireCartes, periode);
|
||||
if (!res.ok) return;
|
||||
|
||||
const index = indexerCartes(res.cartes);
|
||||
for (const evenement of evenements) {
|
||||
const publication = trouverPublication(evenement, index);
|
||||
if (!publication.publie) continue;
|
||||
|
||||
const item = liste.querySelector(`[data-uid="${CSS.escape(evenement.uid)}"]`);
|
||||
if (item) annoterItem(item, publication.lien);
|
||||
}
|
||||
}
|
||||
|
||||
// Badge « Publié » + lien direct ; le bouton « Créer » est retiré (anti-doublon :
|
||||
// un événement déjà publié n'a pas à être re-soumis). textContent uniquement,
|
||||
// le lien vient d'une source externe.
|
||||
function annoterItem(item, lien) {
|
||||
item.querySelector(".evenement-creer")?.remove();
|
||||
|
||||
const publication = document.createElement("div");
|
||||
publication.className = "evenement-publication";
|
||||
|
||||
const badge = document.createElement("span");
|
||||
badge.className = "evenement-publie";
|
||||
badge.textContent = "Publié";
|
||||
|
||||
const voir = document.createElement("a");
|
||||
voir.className = "evenement-lien-mairie";
|
||||
voir.href = lien;
|
||||
voir.target = "_blank";
|
||||
voir.rel = "noopener";
|
||||
voir.textContent = "Voir sur le site mairie";
|
||||
|
||||
publication.append(badge, voir);
|
||||
item.append(publication);
|
||||
}
|
||||
|
||||
charger();
|
||||
|
||||
Reference in New Issue
Block a user