Correctif Bug activation IA
This commit is contained in:
1 parent
b3f5f80d2d
commit
8d104f2058
3 files changed
+55
-5
No files matched your search
@@ -428,6 +428,11 @@ export default function UsersSection({ currentUserId }) {
|
||||
const [openMenu, setOpenMenu] = useState(null);
|
||||
const [page, setPage] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
// null tant que non charge (voir l'effet ci-dessous) : l'interrupteur
|
||||
// individuel de chaque utilisateur n'a d'effet que si l'IA est activee
|
||||
// globalement ET qu'un fournisseur actif est configure (seule source de
|
||||
// verite : aiAccess.js cote backend).
|
||||
const [aiConfig, setAiConfig] = useState(null);
|
||||
|
||||
const load = useCallback(async (initial = false) => {
|
||||
if (initial) setInitialLoading(true);
|
||||
@@ -437,6 +442,16 @@ export default function UsersSection({ currentUserId }) {
|
||||
}, []);
|
||||
|
||||
useEffect(() => { load(true); }, [load]);
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
Promise.all([api.get('/admin/ai/config'), api.get('/admin/ai/providers')])
|
||||
.then(([cfg, provs]) => {
|
||||
if (cancelled) return;
|
||||
setAiConfig({ actif: !!cfg.actif, hasActiveProvider: provs.some(p => p.actif) });
|
||||
})
|
||||
.catch(() => { if (!cancelled) setAiConfig({ actif: false, hasActiveProvider: false }); });
|
||||
return () => { cancelled = true; };
|
||||
}, []);
|
||||
useEffect(() => { setPage(1); }, [search, filterStatus, filterRole]);
|
||||
useEffect(() => {
|
||||
if (!openMenu) return;
|
||||
@@ -458,6 +473,17 @@ export default function UsersSection({ currentUserId }) {
|
||||
const safePage = Math.min(page, totalPages);
|
||||
const paged = filtered.slice((safePage - 1) * pageSize, safePage * pageSize);
|
||||
|
||||
// true tant que aiConfig n'est pas encore charge : le vrai garde-fou reste
|
||||
// cote serveur (getAiAccessStatus), ceci n'est qu'une aide visuelle.
|
||||
const aiAvailable = !aiConfig || (aiConfig.actif && aiConfig.hasActiveProvider);
|
||||
const aiUnavailableReason = !aiConfig
|
||||
? ''
|
||||
: !aiConfig.actif
|
||||
? "L'Assistant IA est desactive globalement. Activez-le dans Assistant IA > Configuration avant d'accorder l'acces a un utilisateur."
|
||||
: !aiConfig.hasActiveProvider
|
||||
? "Aucun fournisseur IA actif n'est configure. Configurez-en un dans Assistant IA > Fournisseurs avant d'accorder l'acces a un utilisateur."
|
||||
: '';
|
||||
|
||||
// ── Actions ───────────────────────────────────────────────────────────
|
||||
const confirm = (title, message, onConfirm, confirmLabel) =>
|
||||
setConfirmAction({ title, message, onConfirm, confirmLabel });
|
||||
@@ -639,6 +665,17 @@ export default function UsersSection({ currentUserId }) {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{aiConfig && !aiAvailable && (
|
||||
<div style={{
|
||||
display: 'flex', alignItems: 'center', gap: 8, margin: '0 20px 12px',
|
||||
padding: '8px 14px', borderRadius: 8, fontSize: 12.5,
|
||||
background: 'var(--surface-2)', color: 'var(--text-muted)', border: '1px solid var(--border)',
|
||||
}}>
|
||||
<IcoSparkle />
|
||||
{aiUnavailableReason}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Tableau */}
|
||||
{filtered.length === 0 ? (
|
||||
<p style={{ color: 'var(--text-muted)', textAlign: 'center', padding: '40px 20px' }}>
|
||||
@@ -692,7 +729,8 @@ export default function UsersSection({ currentUserId }) {
|
||||
<AiToggle
|
||||
checked={!!u.ai_enabled}
|
||||
onClick={() => toggleAiAccess(u)}
|
||||
title={u.ai_enabled ? "Désactiver l'accès à l'Assistant IA" : "Activer l'accès à l'Assistant IA"}
|
||||
disabled={!aiAvailable}
|
||||
title={!aiAvailable ? aiUnavailableReason : (u.ai_enabled ? "Désactiver l'accès à l'Assistant IA" : "Activer l'accès à l'Assistant IA")}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Reference in new issue
Block a user