feat: gate live and task actions when modules are disabled
This commit is contained in:
parent
5662f34415
commit
1952a139ae
3 changed files with 62 additions and 6 deletions
|
|
@ -1,6 +1,7 @@
|
|||
use crate::error::AppError;
|
||||
use crate::models::agent::Agent;
|
||||
use crate::models::agent_task::AgentTask;
|
||||
use crate::models::module::{ProjectModule, MODULE_AGENT_TASK_RUNNER};
|
||||
use crate::models::project::Project;
|
||||
use crate::AppState;
|
||||
use tauri::State;
|
||||
|
|
@ -24,6 +25,13 @@ pub fn create_agent_task(
|
|||
.lock()
|
||||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
let enabled = ProjectModule::is_enabled(&db, &project_id, MODULE_AGENT_TASK_RUNNER)?;
|
||||
if !enabled {
|
||||
return Err(AppError::from(
|
||||
"Le module Agent task runner est désactivé pour ce projet".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
Project::get_by_id(&db, &project_id)?;
|
||||
Agent::get_by_id(&db, &agent_id)?;
|
||||
|
||||
|
|
@ -59,6 +67,13 @@ pub fn retry_agent_task(state: State<'_, AppState>, task_id: String) -> Result<(
|
|||
.map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;
|
||||
|
||||
let task = AgentTask::get_by_id(&db, &task_id)?;
|
||||
let enabled = ProjectModule::is_enabled(&db, &task.project_id, MODULE_AGENT_TASK_RUNNER)?;
|
||||
if !enabled {
|
||||
return Err(AppError::from(
|
||||
"Le module Agent task runner est désactivé pour ce projet".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
if task.status != "error" && task.status != "cancelled" && task.status != "done" {
|
||||
return Err(AppError::from(format!(
|
||||
"Impossible de relancer une tâche avec le statut '{}'",
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import {
|
|||
createLiveSession,
|
||||
listAgents,
|
||||
listLiveMessages,
|
||||
listProjectModules,
|
||||
listLiveSessions,
|
||||
sendLiveMessage,
|
||||
} from "../../lib/api";
|
||||
|
|
@ -28,6 +29,7 @@ export default function ProjectLiveAgent() {
|
|||
const [draft, setDraft] = useState("");
|
||||
const [sending, setSending] = useState(false);
|
||||
const [creatingSession, setCreatingSession] = useState(false);
|
||||
const [moduleEnabled, setModuleEnabled] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const usableAgents = useMemo(
|
||||
|
|
@ -68,8 +70,14 @@ export default function ProjectLiveAgent() {
|
|||
|
||||
setError(null);
|
||||
try {
|
||||
const [availableAgents] = await Promise.all([listAgents()]);
|
||||
const [availableAgents, modules] = await Promise.all([
|
||||
listAgents(),
|
||||
listProjectModules(projectId),
|
||||
]);
|
||||
setAgents(availableAgents);
|
||||
setModuleEnabled(
|
||||
modules.find((mod) => mod.module_key === "ai_live_chat")?.enabled ?? true
|
||||
);
|
||||
|
||||
const firstAgentId = availableAgents[0]?.id ?? "";
|
||||
setSelectedAgentId((current) => current || firstAgentId);
|
||||
|
|
@ -113,6 +121,10 @@ export default function ProjectLiveAgent() {
|
|||
async function handleCreateSession(event: FormEvent) {
|
||||
event.preventDefault();
|
||||
if (!projectId || !selectedAgentId) return;
|
||||
if (!moduleEnabled) {
|
||||
setError("Le module Live chat agent est désactivé pour ce projet.");
|
||||
return;
|
||||
}
|
||||
|
||||
setCreatingSession(true);
|
||||
setError(null);
|
||||
|
|
@ -130,6 +142,10 @@ export default function ProjectLiveAgent() {
|
|||
async function handleSendMessage(event: FormEvent) {
|
||||
event.preventDefault();
|
||||
if (!selectedSessionId || !draft.trim()) return;
|
||||
if (!moduleEnabled) {
|
||||
setError("Le module Live chat agent est désactivé pour ce projet.");
|
||||
return;
|
||||
}
|
||||
|
||||
const content = draft.trim();
|
||||
setDraft("");
|
||||
|
|
@ -172,6 +188,11 @@ export default function ProjectLiveAgent() {
|
|||
{error}
|
||||
</div>
|
||||
)}
|
||||
{!moduleEnabled && (
|
||||
<div className="rounded border border-amber-200 bg-amber-50 p-2 text-sm text-amber-700">
|
||||
Le module est désactivé. La lecture reste possible, mais la création de session et l'envoi de message sont bloqués.
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={handleCreateSession} className="rounded-lg border border-gray-200 bg-white p-4">
|
||||
<h3 className="mb-3 text-sm font-semibold text-gray-800">Nouvelle session</h3>
|
||||
|
|
@ -196,7 +217,7 @@ export default function ProjectLiveAgent() {
|
|||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={creatingSession || !selectedAgentId}
|
||||
disabled={creatingSession || !selectedAgentId || !moduleEnabled}
|
||||
className="rounded bg-blue-600 px-4 py-2 text-sm text-white hover:bg-blue-700 disabled:opacity-50"
|
||||
>
|
||||
{creatingSession ? "Création..." : "Créer la session"}
|
||||
|
|
@ -270,7 +291,7 @@ export default function ProjectLiveAgent() {
|
|||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!selectedSessionId || sending || !draft.trim()}
|
||||
disabled={!selectedSessionId || sending || !draft.trim() || !moduleEnabled}
|
||||
className="rounded bg-gray-900 px-4 py-2 text-sm text-white hover:bg-black disabled:opacity-50"
|
||||
>
|
||||
{sending ? "Envoi..." : "Envoyer"}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {
|
|||
createAgentTask,
|
||||
listAgentTasks,
|
||||
listAgents,
|
||||
listProjectModules,
|
||||
retryAgentTask,
|
||||
} from "../../lib/api";
|
||||
import { getErrorMessage } from "../../lib/errors";
|
||||
|
|
@ -26,6 +27,7 @@ export default function ProjectTasks() {
|
|||
const [agentId, setAgentId] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [moduleEnabled, setModuleEnabled] = useState(true);
|
||||
const [creating, setCreating] = useState(false);
|
||||
const [workingTaskId, setWorkingTaskId] = useState<string | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
|
@ -40,12 +42,16 @@ export default function ProjectTasks() {
|
|||
|
||||
setError(null);
|
||||
try {
|
||||
const [availableAgents, projectTasks] = await Promise.all([
|
||||
const [availableAgents, projectTasks, modules] = await Promise.all([
|
||||
listAgents(),
|
||||
listAgentTasks(projectId),
|
||||
listProjectModules(projectId),
|
||||
]);
|
||||
setAgents(availableAgents);
|
||||
setTasks(projectTasks);
|
||||
setModuleEnabled(
|
||||
modules.find((mod) => mod.module_key === "agent_task_runner")?.enabled ?? true
|
||||
);
|
||||
if (!agentId && availableAgents.length > 0) {
|
||||
setAgentId(availableAgents[0].id);
|
||||
}
|
||||
|
|
@ -95,6 +101,10 @@ export default function ProjectTasks() {
|
|||
async function handleCreateTask(event: FormEvent) {
|
||||
event.preventDefault();
|
||||
if (!projectId || !agentId || !title.trim()) return;
|
||||
if (!moduleEnabled) {
|
||||
setError("Le module Agent task runner est désactivé pour ce projet.");
|
||||
return;
|
||||
}
|
||||
|
||||
setCreating(true);
|
||||
setError(null);
|
||||
|
|
@ -111,6 +121,11 @@ export default function ProjectTasks() {
|
|||
}
|
||||
|
||||
async function handleRetry(taskId: string) {
|
||||
if (!moduleEnabled) {
|
||||
setError("Le module Agent task runner est désactivé pour ce projet.");
|
||||
return;
|
||||
}
|
||||
|
||||
setWorkingTaskId(taskId);
|
||||
setError(null);
|
||||
try {
|
||||
|
|
@ -145,6 +160,11 @@ export default function ProjectTasks() {
|
|||
{error}
|
||||
</div>
|
||||
)}
|
||||
{!moduleEnabled && (
|
||||
<div className="rounded border border-amber-200 bg-amber-50 p-2 text-sm text-amber-700">
|
||||
Le module est désactivé. Les tâches existantes restent visibles, mais la création et la relance sont bloquées.
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={handleCreateTask} className="rounded-lg border border-gray-200 bg-white p-4">
|
||||
<h3 className="mb-3 text-sm font-semibold text-gray-800">Créer une tâche</h3>
|
||||
|
|
@ -171,7 +191,7 @@ export default function ProjectTasks() {
|
|||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={creating || !agentId || !title.trim()}
|
||||
disabled={creating || !agentId || !title.trim() || !moduleEnabled}
|
||||
className="rounded bg-blue-600 px-4 py-2 text-sm text-white hover:bg-blue-700 disabled:opacity-50"
|
||||
>
|
||||
{creating ? "Création..." : "Créer"}
|
||||
|
|
@ -223,7 +243,7 @@ export default function ProjectTasks() {
|
|||
<button
|
||||
type="button"
|
||||
onClick={() => void handleRetry(task.id)}
|
||||
disabled={workingTaskId === task.id}
|
||||
disabled={workingTaskId === task.id || !moduleEnabled}
|
||||
className="rounded bg-gray-900 px-3 py-1 text-xs text-white hover:bg-black disabled:opacity-50"
|
||||
>
|
||||
Relancer
|
||||
|
|
|
|||
Loading…
Reference in a new issue