import { useState, useEffect, useCallback } from 'react'; import workflowService, { type WorkflowTransition, type WorkflowInfo, getWorkflowStateStyle, getActionButtonStyle, getActionIcon } from '../services/workflowService'; interface UseWorkflowOptions { doctype: string; docname: string | null; workflowState?: string; enabled?: boolean; docData?: Record; // Added: Document data for condition evaluation } interface UseWorkflowReturn { // State transitions: WorkflowTransition[]; workflowInfo: WorkflowInfo | null; userRoles: string[]; currentUser: string; isSystemManager: boolean; loading: boolean; actionLoading: boolean; error: string | null; canEdit: boolean; // Actions applyAction: (action: string, nextState?: string) => Promise; refreshTransitions: () => Promise; // Helpers getStateStyle: (state: string) => { bg: string; text: string; border: string }; getButtonStyle: (action: string) => string; getIcon: (action: string) => string; } export const useWorkflow = ({ doctype, docname, workflowState, enabled = true, docData, // Added: Document data for condition evaluation }: UseWorkflowOptions): UseWorkflowReturn => { const [transitions, setTransitions] = useState([]); const [workflowInfo, setWorkflowInfo] = useState(null); const [userRoles, setUserRoles] = useState([]); const [currentUser, setCurrentUser] = useState(''); const [isSystemManagerUser, setIsSystemManagerUser] = useState(false); const [loading, setLoading] = useState(false); const [actionLoading, setActionLoading] = useState(false); const [error, setError] = useState(null); const [canEdit, setCanEdit] = useState(true); // Fetch workflow info on mount useEffect(() => { if (!enabled) return; const fetchWorkflowInfo = async () => { try { const info = await workflowService.getWorkflowInfo(doctype); setWorkflowInfo(info); } catch (err) { console.error('Error fetching workflow info:', err); } }; fetchWorkflowInfo(); }, [doctype, enabled]); // Fetch user roles, current user, and check System Manager useEffect(() => { if (!enabled) return; const fetchUserInfo = async () => { try { const [roles, user, isSysManager] = await Promise.all([ workflowService.getCurrentUserRoles(), workflowService.getCurrentUser(), workflowService.isSystemManager(), ]); setUserRoles(roles); setCurrentUser(user); setIsSystemManagerUser(isSysManager); // System Manager can always edit if (isSysManager) { setCanEdit(true); } } catch (err) { console.error('Error fetching user info:', err); } }; fetchUserInfo(); }, [enabled]); // Fetch available transitions when docname, workflowState, or docData changes const refreshTransitions = useCallback(async () => { if (!docname || !enabled) { setTransitions([]); return; } setLoading(true); setError(null); try { // Pass document data for condition evaluation const availableTransitions = await workflowService.getWorkflowTransitions( doctype, docname, workflowState, docData // Pass document data ); console.log('[useWorkflow] Available transitions:', availableTransitions); setTransitions(availableTransitions); // Check if user can edit (System Manager always can) if (workflowState) { const canUserEdit = await workflowService.canUserEditDocument(doctype, docname, workflowState); setCanEdit(canUserEdit); } } catch (err) { console.error('Error fetching transitions:', err); setError('Failed to load workflow actions'); setTransitions([]); } finally { setLoading(false); } }, [doctype, docname, workflowState, enabled, docData]); useEffect(() => { refreshTransitions(); }, [refreshTransitions]); // Apply workflow action const applyAction = useCallback(async (action: string, nextState?: string): Promise => { if (!docname) { setError('Document not saved yet'); return false; } setActionLoading(true); setError(null); try { // Pass nextState for System Manager force update if needed await workflowService.applyWorkflowAction(doctype, docname, action, nextState); // Refresh transitions after action await refreshTransitions(); return true; } catch (err: any) { console.error('Error applying workflow action:', err); // Extract error message let errorMessage = 'Failed to apply action'; if (err.message) { errorMessage = err.message; } else if (err._server_messages) { try { const serverMessages = JSON.parse(err._server_messages); errorMessage = serverMessages.map((m: string) => { try { return JSON.parse(m).message; } catch { return m; } }).join('\n'); } catch { errorMessage = err._server_messages; } } setError(errorMessage); return false; } finally { setActionLoading(false); } }, [doctype, docname, refreshTransitions]); return { transitions, workflowInfo, userRoles, currentUser, isSystemManager: isSystemManagerUser, loading, actionLoading, error, canEdit, applyAction, refreshTransitions, getStateStyle: getWorkflowStateStyle, getButtonStyle: getActionButtonStyle, getIcon: getActionIcon, }; }; export default useWorkflow;