MCPcopy Create free account
hub / github.com/ShipSecAI/studio / WorkflowList

Function WorkflowList

frontend/src/pages/WorkflowList.tsx:76–497  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

74}
75
76export function WorkflowList() {
77 const navigate = useNavigate();
78 const [workflows, setWorkflows] = useState<WorkflowMetadataNormalized[]>([]);
79 const [isLoading, setIsLoading] = useState(true);
80 const [error, setError] = useState<string | null>(null);
81 const [retryCount, setRetryCount] = useState(0);
82 const retryCountRef = useRef(0); // Use ref to track actual count
83 const retryTimeoutRef = useRef<NodeJS.Timeout | null>(null);
84 const roles = useAuthStore((state) => state.roles);
85 const canManageWorkflows = hasAdminRole(roles);
86 const isReadOnly = !canManageWorkflows;
87 const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
88 const [workflowToDelete, setWorkflowToDelete] = useState<WorkflowMetadataNormalized | null>(null);
89 const [deleteError, setDeleteError] = useState<string | null>(null);
90 const [isDeleting, setIsDeleting] = useState(false);
91 const { isAuthenticated, isLoading: authLoading } = useAuth();
92 const token = useAuthStore((state) => state.token);
93 const adminUsername = useAuthStore((state) => state.adminUsername);
94
95 const sensors = useSensors(
96 useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
97 useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
98 );
99
100 const handleDragEnd = useCallback((event: DragEndEvent) => {
101 const { active, over } = event;
102 if (!over || active.id === over.id) return;
103 setWorkflows((prev) => {
104 const oldIndex = prev.findIndex((w) => w.id === active.id);
105 const newIndex = prev.findIndex((w) => w.id === over.id);
106 if (oldIndex !== -1 && newIndex !== -1) {
107 const reordered = arrayMove(prev, oldIndex, newIndex);
108 saveOrder(reordered.map((w) => w.id));
109 return reordered;
110 }
111 return prev;
112 });
113 }, []);
114
115 const MAX_RETRY_ATTEMPTS = 30; // Try for ~60 seconds (30 attempts × 2s)
116 const RETRY_INTERVAL_MS = 2000; // 2 seconds between retries
117
118 useEffect(() => {
119 // Wait for auth to be ready before loading workflows
120 if (authLoading) {
121 return;
122 }
123
124 // Check if we have authentication (either token or admin credentials)
125 const hasAuth = isAuthenticated || token || adminUsername;
126
127 if (hasAuth) {
128 loadWorkflows();
129 } else {
130 setIsLoading(false);
131 setError('Please log in to view workflows');
132 }
133 }, [isAuthenticated, authLoading, token, adminUsername]);

Callers

nothing calls this directly

Calls 12

hasAdminRoleFunction · 0.90
trackFunction · 0.90
useAuthFunction · 0.85
saveOrderFunction · 0.85
loadWorkflowsFunction · 0.85
applyOrderFunction · 0.85
getSavedOrderFunction · 0.85
parseMethod · 0.80
errorMethod · 0.80
fromMethod · 0.80
handleDeleteDialogChangeFunction · 0.70
listMethod · 0.65

Tested by

no test coverage detected