mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-23 15:08:16 +02:00
Modale preset : ouverture en haut et bloc moteur stabilise, pastilles redondantes retirees
This commit is contained in:
1 parent
f3769299b9
commit
d15d40eb7c
4 files changed
+36
-22
No files matched your search
@@ -2215,10 +2215,11 @@ function renderInternet(s){
|
|||||||
if(cf) cf.style.display = (webEngine==='crawl4ai') ? '' : 'none';
|
if(cf) cf.style.display = (webEngine==='crawl4ai') ? '' : 'none';
|
||||||
if(document.activeElement !== document.getElementById('crawl-url'))
|
if(document.activeElement !== document.getElementById('crawl-url'))
|
||||||
document.getElementById('crawl-url').value = s.url || '';
|
document.getElementById('crawl-url').value = s.url || '';
|
||||||
// Actif mais serveur injoignable : la pastille le dit (sinon l'UI ment — les
|
// La pastille ne redit PAS ce que l'interrupteur montre déjà (actif/inactif) :
|
||||||
// outils web ne sont pas proposés au modèle dans ce cas).
|
// elle ne sert qu'à signaler l'anomalie — actif mais serveur injoignable, cas
|
||||||
|
// où les outils web ne sont pas proposés au modèle.
|
||||||
if(internetOn && !s.reachable) setBadge('internet-badge','warn','injoignable');
|
if(internetOn && !s.reachable) setBadge('internet-badge','warn','injoignable');
|
||||||
else setBadge('internet-badge', internetOn, internetOn?'actif':'inactif');
|
else setBadge('internet-badge', null);
|
||||||
// Clé du serveur Crawl4AI : le champ reste vide (la clé n'est jamais renvoyée),
|
// Clé du serveur Crawl4AI : le champ reste vide (la clé n'est jamais renvoyée),
|
||||||
// on indique seulement si une clé est enregistrée.
|
// on indique seulement si une clé est enregistrée.
|
||||||
const ks=document.getElementById('crawl-key-state'), kc=document.getElementById('crawl-key-clear');
|
const ks=document.getElementById('crawl-key-state'), kc=document.getElementById('crawl-key-clear');
|
||||||
@@ -2397,9 +2398,9 @@ const KINDS = {
|
|||||||
// si le bouton était mort. On affiche la coquille tout de suite, puis on la
|
// si le bouton était mort. On affiche la coquille tout de suite, puis on la
|
||||||
// remplit. `openSeq` protège du cas « deux ouvertures coup sur coup » : une
|
// remplit. `openSeq` protège du cas « deux ouvertures coup sur coup » : une
|
||||||
// réponse en retard ne doit jamais écraser la modale ouverte après elle.
|
// réponse en retard ne doit jamais écraser la modale ouverte après elle.
|
||||||
// Pendant ce remplissage la modale est en `.loading` : son corps est estompé et
|
// Pendant ce remplissage la modale est en `.loading` : un rond tourne à la place
|
||||||
// inerte, puis révélé d'un coup une fois TOUT en place — sinon on voyait les
|
// du formulaire, qui n'est révélé qu'une fois TOUT en place (contenu, réglages,
|
||||||
// champs se peupler un par un, ce qui donnait une impression de bricolage.
|
// backends, GPU) — sinon on voyait les champs se peupler un par un.
|
||||||
let openSeq = 0;
|
let openSeq = 0;
|
||||||
async function openItem(kind, key){
|
async function openItem(kind, key){
|
||||||
const K = KINDS[kind];
|
const K = KINDS[kind];
|
||||||
@@ -2438,6 +2439,10 @@ async function openItem(kind, key){
|
|||||||
rawBody.style.display = '';
|
rawBody.style.display = '';
|
||||||
}
|
}
|
||||||
document.getElementById('modal').classList.add('loading');
|
document.getElementById('modal').classList.add('loading');
|
||||||
|
// Le corps de la modale est un conteneur défilant RÉUTILISÉ d'une ouverture à
|
||||||
|
// l'autre : sans cette remise à zéro, ouvrir un preset après en avoir fait
|
||||||
|
// défiler un autre rouvrait la fiche au milieu.
|
||||||
|
const peBody=document.querySelector('#modal .pe-body'); if(peBody) peBody.scrollTop=0;
|
||||||
showModal('modal');
|
showModal('modal');
|
||||||
// --- Remplissage, une fois la modale à l'écran -----------------------------
|
// --- Remplissage, une fois la modale à l'écran -----------------------------
|
||||||
const r = await jfetch(K.getUrl + '?' + K.param + '=' + encodeURIComponent(key||''));
|
const r = await jfetch(K.getUrl + '?' + K.param + '=' + encodeURIComponent(key||''));
|
||||||
@@ -2640,7 +2645,10 @@ async function populateBackend(){
|
|||||||
if(radio) radio.checked = true;
|
if(radio) radio.checked = true;
|
||||||
toggleBackendCustom(mode);
|
toggleBackendCustom(mode);
|
||||||
if(mode === 'custom') document.getElementById('m-backend-path').value = cur;
|
if(mode === 'custom') document.getElementById('m-backend-path').value = cur;
|
||||||
loadGpuDevices();
|
// Attendu (et non lancé dans le vide) : la liste des GPU change la hauteur du
|
||||||
|
// bloc « moteur ». Sans ce await, elle arrivait APRÈS la levée du voile de
|
||||||
|
// chargement et on voyait le bloc bouger tout seul.
|
||||||
|
await loadGpuDevices();
|
||||||
}
|
}
|
||||||
function toggleBackendCustom(mode){
|
function toggleBackendCustom(mode){
|
||||||
document.getElementById('m-backend-custom').style.display = (mode==='custom') ? 'block' : 'none';
|
document.getElementById('m-backend-custom').style.display = (mode==='custom') ? 'block' : 'none';
|
||||||
@@ -4051,10 +4059,9 @@ async function loadMCP(){ renderMCP(await jget('/api/mcp')); }
|
|||||||
|
|
||||||
function renderMCP(r){
|
function renderMCP(r){
|
||||||
mcpServers = (r && r.servers) || [];
|
mcpServers = (r && r.servers) || [];
|
||||||
const enabled = mcpServers.filter(s=>s.enabled).length;
|
// Pas de pastille de comptage : chaque serveur affiche déjà son propre état
|
||||||
if(enabled) setBadge('mcp-badge', true, enabled+(enabled>1?' actifs':' actif'));
|
// dans la liste juste en dessous.
|
||||||
else if(mcpServers.length) setBadge('mcp-badge', false, 'aucun actif');
|
setBadge('mcp-badge', null);
|
||||||
else setBadge('mcp-badge', null);
|
|
||||||
const list = document.getElementById('mcp-list');
|
const list = document.getElementById('mcp-list');
|
||||||
list.textContent = '';
|
list.textContent = '';
|
||||||
if(!mcpServers.length){
|
if(!mcpServers.length){
|
||||||
|
|||||||
@@ -147,10 +147,11 @@ function renderInternet(s){
|
|||||||
if(cf) cf.style.display = (webEngine==='crawl4ai') ? '' : 'none';
|
if(cf) cf.style.display = (webEngine==='crawl4ai') ? '' : 'none';
|
||||||
if(document.activeElement !== document.getElementById('crawl-url'))
|
if(document.activeElement !== document.getElementById('crawl-url'))
|
||||||
document.getElementById('crawl-url').value = s.url || '';
|
document.getElementById('crawl-url').value = s.url || '';
|
||||||
// Actif mais serveur injoignable : la pastille le dit (sinon l'UI ment — les
|
// La pastille ne redit PAS ce que l'interrupteur montre déjà (actif/inactif) :
|
||||||
// outils web ne sont pas proposés au modèle dans ce cas).
|
// elle ne sert qu'à signaler l'anomalie — actif mais serveur injoignable, cas
|
||||||
|
// où les outils web ne sont pas proposés au modèle.
|
||||||
if(internetOn && !s.reachable) setBadge('internet-badge','warn','injoignable');
|
if(internetOn && !s.reachable) setBadge('internet-badge','warn','injoignable');
|
||||||
else setBadge('internet-badge', internetOn, internetOn?'actif':'inactif');
|
else setBadge('internet-badge', null);
|
||||||
// Clé du serveur Crawl4AI : le champ reste vide (la clé n'est jamais renvoyée),
|
// Clé du serveur Crawl4AI : le champ reste vide (la clé n'est jamais renvoyée),
|
||||||
// on indique seulement si une clé est enregistrée.
|
// on indique seulement si une clé est enregistrée.
|
||||||
const ks=document.getElementById('crawl-key-state'), kc=document.getElementById('crawl-key-clear');
|
const ks=document.getElementById('crawl-key-state'), kc=document.getElementById('crawl-key-clear');
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ const KINDS = {
|
|||||||
// si le bouton était mort. On affiche la coquille tout de suite, puis on la
|
// si le bouton était mort. On affiche la coquille tout de suite, puis on la
|
||||||
// remplit. `openSeq` protège du cas « deux ouvertures coup sur coup » : une
|
// remplit. `openSeq` protège du cas « deux ouvertures coup sur coup » : une
|
||||||
// réponse en retard ne doit jamais écraser la modale ouverte après elle.
|
// réponse en retard ne doit jamais écraser la modale ouverte après elle.
|
||||||
// Pendant ce remplissage la modale est en `.loading` : son corps est estompé et
|
// Pendant ce remplissage la modale est en `.loading` : un rond tourne à la place
|
||||||
// inerte, puis révélé d'un coup une fois TOUT en place — sinon on voyait les
|
// du formulaire, qui n'est révélé qu'une fois TOUT en place (contenu, réglages,
|
||||||
// champs se peupler un par un, ce qui donnait une impression de bricolage.
|
// backends, GPU) — sinon on voyait les champs se peupler un par un.
|
||||||
let openSeq = 0;
|
let openSeq = 0;
|
||||||
async function openItem(kind, key){
|
async function openItem(kind, key){
|
||||||
const K = KINDS[kind];
|
const K = KINDS[kind];
|
||||||
@@ -103,6 +103,10 @@ async function openItem(kind, key){
|
|||||||
rawBody.style.display = '';
|
rawBody.style.display = '';
|
||||||
}
|
}
|
||||||
document.getElementById('modal').classList.add('loading');
|
document.getElementById('modal').classList.add('loading');
|
||||||
|
// Le corps de la modale est un conteneur défilant RÉUTILISÉ d'une ouverture à
|
||||||
|
// l'autre : sans cette remise à zéro, ouvrir un preset après en avoir fait
|
||||||
|
// défiler un autre rouvrait la fiche au milieu.
|
||||||
|
const peBody=document.querySelector('#modal .pe-body'); if(peBody) peBody.scrollTop=0;
|
||||||
showModal('modal');
|
showModal('modal');
|
||||||
// --- Remplissage, une fois la modale à l'écran -----------------------------
|
// --- Remplissage, une fois la modale à l'écran -----------------------------
|
||||||
const r = await jfetch(K.getUrl + '?' + K.param + '=' + encodeURIComponent(key||''));
|
const r = await jfetch(K.getUrl + '?' + K.param + '=' + encodeURIComponent(key||''));
|
||||||
@@ -305,7 +309,10 @@ async function populateBackend(){
|
|||||||
if(radio) radio.checked = true;
|
if(radio) radio.checked = true;
|
||||||
toggleBackendCustom(mode);
|
toggleBackendCustom(mode);
|
||||||
if(mode === 'custom') document.getElementById('m-backend-path').value = cur;
|
if(mode === 'custom') document.getElementById('m-backend-path').value = cur;
|
||||||
loadGpuDevices();
|
// Attendu (et non lancé dans le vide) : la liste des GPU change la hauteur du
|
||||||
|
// bloc « moteur ». Sans ce await, elle arrivait APRÈS la levée du voile de
|
||||||
|
// chargement et on voyait le bloc bouger tout seul.
|
||||||
|
await loadGpuDevices();
|
||||||
}
|
}
|
||||||
function toggleBackendCustom(mode){
|
function toggleBackendCustom(mode){
|
||||||
document.getElementById('m-backend-custom').style.display = (mode==='custom') ? 'block' : 'none';
|
document.getElementById('m-backend-custom').style.display = (mode==='custom') ? 'block' : 'none';
|
||||||
|
|||||||
@@ -9,10 +9,9 @@ async function loadMCP(){ renderMCP(await jget('/api/mcp')); }
|
|||||||
|
|
||||||
function renderMCP(r){
|
function renderMCP(r){
|
||||||
mcpServers = (r && r.servers) || [];
|
mcpServers = (r && r.servers) || [];
|
||||||
const enabled = mcpServers.filter(s=>s.enabled).length;
|
// Pas de pastille de comptage : chaque serveur affiche déjà son propre état
|
||||||
if(enabled) setBadge('mcp-badge', true, enabled+(enabled>1?' actifs':' actif'));
|
// dans la liste juste en dessous.
|
||||||
else if(mcpServers.length) setBadge('mcp-badge', false, 'aucun actif');
|
setBadge('mcp-badge', null);
|
||||||
else setBadge('mcp-badge', null);
|
|
||||||
const list = document.getElementById('mcp-list');
|
const list = document.getElementById('mcp-list');
|
||||||
list.textContent = '';
|
list.textContent = '';
|
||||||
if(!mcpServers.length){
|
if(!mcpServers.length){
|
||||||
|
|||||||
Reference in new issue
Block a user