fix: hover foncé + /api/ai/status + cache toolbar si pas de clé API
Some checks failed
CI / lint (push) Failing after 13s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / security (push) Successful in 8s

This commit is contained in:
Bruno Charest 2026-05-30 19:57:39 -04:00
parent e013ddc539
commit 6c7d7b4506
3 changed files with 38 additions and 7 deletions

View File

@ -10,13 +10,29 @@ from backend.ai import (
ai_simplify, ai_change_tone, ai_translate, ai_explain, ai_summarize,
ai_continue_writing, ai_custom_rewrite, ai_convert_to_list,
ai_convert_to_table, ai_generate_frontmatter, ai_inline_complete,
ai_convert_to_canvas,
ai_convert_to_canvas, DEFAULT_PROVIDER, PROVIDERS,
)
logger = logging.getLogger("obsigate.ai_routes")
router = APIRouter(prefix="/api/ai", tags=["AI"])
@router.get("/status")
async def api_status():
"""Check if AI is configured and which providers are available."""
providers = {}
for name, cfg in PROVIDERS.items():
providers[name] = {
"available": bool(cfg["api_key"]),
"model": cfg["model"] if cfg["api_key"] else None,
}
return {
"configured": any(p["available"] for p in providers.values()),
"default_provider": DEFAULT_PROVIDER,
"providers": providers,
}
class AIRequest(BaseModel):
text: str = Field(..., description="Input text to process", min_length=1)
instruction: Optional[str] = Field(None, description="Custom instruction for rewrite")

View File

@ -111,7 +111,7 @@ function createMenu(items, parentEl) {
el.appendChild(arrow);
}
el.addEventListener('mouseenter', () => {
el.style.background = 'var(--bg-secondary)';
el.style.background = 'rgba(255,255,255,0.06)';
// Show submenu
if (item.children) {
const sub = el.querySelector('.ai-submenu');
@ -171,7 +171,7 @@ function createSubMenu(items, parentEl) {
whiteSpace: 'nowrap',
});
el.innerHTML = item.label;
el.addEventListener('mouseenter', () => { el.style.background = 'var(--bg-secondary)'; });
el.addEventListener('mouseenter', () => { el.style.background = 'rgba(255,255,255,0.06)'; });
el.addEventListener('mouseleave', () => { el.style.background = ''; });
el.addEventListener('click', (e) => {
e.stopPropagation();
@ -186,7 +186,22 @@ function createSubMenu(items, parentEl) {
}
// ── Main AI Toolbar ──
export function createAIToolbar(container, getEditorView) {
export async function createAIToolbar(container, getEditorView) {
// Check if AI is configured
let aiConfigured = false;
try {
const status = await api('/api/ai/status');
aiConfigured = status.configured;
} catch { aiConfigured = false; }
if (!aiConfigured) {
const hint = document.createElement('div');
hint.style.cssText = 'padding:6px 12px;font-size:0.7rem;color:var(--text-muted);border-bottom:1px solid var(--border-color)';
hint.textContent = '⚠️ AI non configuré — ajouter DEEPSEEK_API_KEY, OPENROUTER_API_KEY ou GEMINI_API_KEY dans .env';
container.appendChild(hint);
return;
}
const toolbar = document.createElement('div');
toolbar.className = 'ai-toolbar';
Object.assign(toolbar.style, {
@ -195,7 +210,7 @@ export function createAIToolbar(container, getEditorView) {
gap: '2px',
padding: '4px 8px',
borderBottom: '1px solid var(--border-color)',
background: 'var(--bg-secondary)',
background: '#2a2a2a',
flexWrap: 'wrap',
});
@ -347,7 +362,7 @@ function createDropdownBtn(text, items) {
e.stopPropagation();
createMenu(items, btn);
});
btn.addEventListener('mouseenter', () => { btn.style.background = 'var(--bg-hover)'; });
btn.addEventListener('mouseenter', () => { btn.style.background = 'rgba(255,255,255,0.08)'; });
btn.addEventListener('mouseleave', () => { btn.style.background = ''; });
return btn;
}

View File

@ -379,7 +379,7 @@ async function openEditor(vaultName, filePath) {
// Set up AI toolbar (recreate each time editor opens)
const container = document.getElementById('ai-toolbar-container');
if (container && !container.querySelector('.ai-toolbar')) {
if (container && !container.querySelector('.ai-toolbar') && !container.querySelector('div')) {
createAIToolbar(container, () => state.editorView || null);
}