fix: hover foncé + /api/ai/status + cache toolbar si pas de clé API
This commit is contained in:
parent
e013ddc539
commit
6c7d7b4506
@ -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")
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user