import { useState, useCallback } from 'react'; import { useAppStore } from '../store/appStore'; import { fetchWorkflows, activateWorkflow, deactivateWorkflow, runWorkflow, Workflow, } from '../api/workflows'; import { usePolling } from './usePolling'; /** Interface des valeurs et actions exposées par le hook */ interface UseWorkflowsResult { workflows: Workflow[]; isLoading: boolean; isRefreshing: boolean; /** * Recharge manuellement la liste des workflows. * Utilisé pour le pull-to-refresh. */ refresh: () => Promise; /** * Bascule le statut actif/inactif d'un workflow. * Met à jour l'état local après confirmation serveur. * * @param workflow - Workflow à basculer */ toggleWorkflow: (workflow: Workflow) => Promise; /** * Déclenche manuellement l'exécution d'un workflow. * * @param id - Identifiant du workflow à déclencher */ triggerWorkflow: (id: string) => Promise; } /** * Hook de gestion des workflows : chargement, polling automatique et actions. * Délègue la gestion des erreurs à l'intercepteur Axios (errorHandler). * Les screens ne font pas d'appels API directs — tout passe par ce hook. */ export const useWorkflows = (): UseWorkflowsResult => { const { preferences, config } = useAppStore(); const [workflows, setWorkflows] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isRefreshing, setIsRefreshing] = useState(false); /** Charge la liste des workflows depuis la couche API */ const loadWorkflows = useCallback(async (): Promise => { try { const data = await fetchWorkflows(); setWorkflows(data); } catch { // Erreur déjà remontée via l'intercepteur Axios → toast affiché } finally { setIsLoading(false); } }, []); /** * Polling automatique déclenché uniquement si l'app est configurée. * L'intervalle est lu depuis les préférences utilisateur (configurable dans Settings). */ usePolling({ callback: loadWorkflows, interval: preferences.pollingInterval, enabled: config.isConfigured, immediate: true, }); /** Pull-to-refresh : indicateur distinct du chargement initial */ const refresh = useCallback(async (): Promise => { setIsRefreshing(true); try { await loadWorkflows(); } finally { setIsRefreshing(false); } }, [loadWorkflows]); /** * Bascule actif/inactif d'un workflow. * Met à jour l'entrée correspondante dans l'état local après retour serveur. */ const toggleWorkflow = useCallback(async (workflow: Workflow): Promise => { try { const updated = workflow.active ? await deactivateWorkflow(workflow.id) : await activateWorkflow(workflow.id); // Mise à jour ciblée sans recharger toute la liste setWorkflows((prev) => prev.map((w) => (w.id === updated.id ? updated : w))); } catch { // Géré par l'intercepteur Axios } }, []); const triggerWorkflow = useCallback(async (id: string): Promise => { try { await runWorkflow(id); } catch { // Géré par l'intercepteur Axios } }, []); return { workflows, isLoading, isRefreshing, refresh, toggleWorkflow, triggerWorkflow, }; };