feat: HUB-21 — réglages généraux du Hub consommés par ObsiGate (bannière + drapeau recherche_partout) #229
CI / lint (pull_request) Successful in 1m16s
CI / security (pull_request) Successful in 19s
CI / test (pull_request) Successful in 3m41s
CI / build (pull_request) Successful in 13s
CI / e2e (pull_request) Failing after 14m58s

This commit is contained in:
Spark
2026-11-06 17:02:04 +00:00
parent 15d015e59b
commit b88191ffcb
17 changed files with 647 additions and 15 deletions
+74 -2
View File
@@ -246,6 +246,21 @@
return [tab];
}
/* HUB-21 (propagation des réglages généraux du Hub) : le drapeau
* « Rechercher partout », rendu par l'hôte dans l'attribut
* data-recherche-partout de #recherche (« true »/« false », lu
* côté serveur depuis GET {hub}/api/reglages/effectifs, cache
* 60 s, patron du pilote TikTak 0.61.22). Seules les valeurs
* explicitement négatives désactivent la fédération ; attribut
* absent ou illisible = fédération active — le comportement
* actuel, qui est aussi le repli quand le Hub est muet.
* Fonction pure, exposée aux tests. */
function federationAutorisee(valeur) {
if (valeur == null) return true;
var v = String(valeur).trim().toLowerCase();
return v !== "false" && v !== "0" && v !== "non";
}
/* Troncature d'affichage : liste complète dans l'onglet propre à
* l'application, PER_APP_LIMIT partout ailleurs (vue « Tout »). */
function pageItems(items, full) {
@@ -514,6 +529,7 @@
visibleKeys: visibleKeys,
pageItems: pageItems,
buildSearchUrl: buildSearchUrl,
federationAutorisee: federationAutorisee,
tabCounts: tabCounts,
searchPath: searchPath,
normalize: normalize,
@@ -609,6 +625,14 @@
".</p>";
return;
}
if (state.status === "desactivee") {
count.textContent = "";
body.innerHTML =
'<p class="rp-state">Recherche fédérée désactivée dans les ' +
"réglages généraux de la suite (Hub) : cette application " +
"n'est pas interrogée.</p>";
return;
}
if (state.status === "idle") {
count.textContent = "";
body.innerHTML =
@@ -651,6 +675,8 @@
var input = document.getElementById("rp-q");
if (!input) return;
var hostApp = root.getAttribute("data-host") || "";
var federation = federationAutorisee(
root.getAttribute("data-recherche-partout"));
var explicit = {};
APPS.forEach(function (app) {
var v = root.getAttribute("data-base-" + app.key);
@@ -772,7 +798,23 @@
applyTab(tab, opts);
/* La console n'est interrogée qu'une fois affichée. */
if (parseTab(tab) === "console" && currentQ && consoleFetchedQ !== currentQ) {
fetchConsole(currentQ, runId);
if (!federation) {
var secConsOnglet = sections.console;
if (secConsOnglet) {
states.console = {
status: "desactivee",
items: [],
message: "",
q: currentQ,
base: consoleBase,
app: "console",
};
renderSection(secConsOnglet, states.console, true);
renderTabs();
}
} else {
fetchConsole(currentQ, runId);
}
}
}
@@ -865,6 +907,22 @@
APPS.forEach(function (app) {
var sec = sections[app.key];
if (!sec) return;
if (!federation && app.key !== hostApp) {
/* HUB-21 : fédération désactivée par le Hub — la section
* sœur n'est pas interrogée, la recherche locale
* (app.key === hostApp, même origine) continue. */
states[app.key] = {
status: "desactivee",
items: [],
message: "",
q: q,
base: bases[app.key],
app: app.key,
};
renderSection(sec, states[app.key], activeTab === app.key);
renderTabs();
return;
}
states[app.key] = {
status: "loading",
items: [],
@@ -915,7 +973,21 @@
});
/* Console : seulement si son onglet est affiché ; sinon son
* compteur reste vide (pas de faux 0) jusqu'à son activation. */
if (activeTab === "console") {
if (activeTab === "console" && !federation) {
var secConsRecherche = sections.console;
if (secConsRecherche) {
states.console = {
status: "desactivee",
items: [],
message: "",
q: q,
base: consoleBase,
app: "console",
};
renderSection(secConsRecherche, states.console, true);
renderTabs();
}
} else if (activeTab === "console") {
fetchConsole(q, myRun);
} else {
states.console = {
+1
View File
@@ -129,6 +129,7 @@
<div class="content-wrapper">
<div class="content-area">
<main class="rp-page" id="recherche" data-host="obsigate"
data-recherche-partout="{{RECHERCHE_PARTOUT}}"
data-base-obsigate="{{URL_OBSIGATE}}"
data-base-flowdeck="{{URL_FLOWDECK}}"
data-base-tiktak="{{URL_TIKTAK}}"
+9
View File
@@ -14378,3 +14378,12 @@ body.has-draco-bar .app-container { height: calc(100vh - 60px); }
.coffres-context-menu { position: fixed; z-index: 1000; min-width: 220px; background: var(--bg-secondary, #161b22); border: 1px solid var(--border, #21262d); border-radius: 8px; padding: 4px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); }
.coffres-context-item { display: block; width: 100%; text-align: left; padding: 8px 12px; background: transparent; border: none; color: var(--text-primary, #e6edf3); cursor: pointer; border-radius: 6px; }
.coffres-context-item:hover { background: var(--bg-hover, #1f2430); }
/* Bannière d'annonce des réglages généraux du Hub (HUB-21) :
bandeau injecté côté serveur sous la barre commune, fermable
(masquage mémorisé pour la session du navigateur). */
.banniere-hub { display: flex; align-items: center; gap: 12px; padding: 8px 16px; background: var(--accent, #7c5cd6); color: #fff; font-size: 14px; }
.banniere-hub[hidden] { display: none; }
.banniere-hub-texte { flex: 1; overflow-wrap: anywhere; }
.banniere-hub-fermer { flex: none; background: transparent; border: none; color: inherit; font-size: 15px; line-height: 1; padding: 4px 6px; cursor: pointer; border-radius: 6px; }
.banniere-hub-fermer:hover { background: rgba(255, 255, 255, 0.18); }