1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
import { useState, useCallback, useEffect } from "react";
import {
getDirective,
getDirectiveGraph,
startDirective,
pauseDirective,
resumeDirective,
stopDirective,
type DirectiveWithProgress,
type DirectiveGraphResponse,
type StartDirectiveResponse,
} from "../lib/api";
interface UseDirectiveDetailResult {
directive: DirectiveWithProgress | null;
graph: DirectiveGraphResponse | null;
loading: boolean;
error: string | null;
refresh: () => Promise<void>;
start: () => Promise<StartDirectiveResponse | null>;
pause: () => Promise<boolean>;
resume: () => Promise<boolean>;
stop: () => Promise<boolean>;
}
export function useDirectiveDetail(directiveId: string | undefined): UseDirectiveDetailResult {
const [directive, setDirective] = useState<DirectiveWithProgress | null>(null);
const [graph, setGraph] = useState<DirectiveGraphResponse | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const fetchDetail = useCallback(async () => {
if (!directiveId) {
setDirective(null);
setGraph(null);
return;
}
setLoading(true);
setError(null);
try {
const [d, g] = await Promise.all([
getDirective(directiveId),
getDirectiveGraph(directiveId).catch(() => null),
]);
setDirective(d);
setGraph(g);
} catch (err) {
console.error("Failed to fetch directive detail:", err);
setError(err instanceof Error ? err.message : "Failed to fetch directive");
setDirective(null);
setGraph(null);
} finally {
setLoading(false);
}
}, [directiveId]);
useEffect(() => {
fetchDetail();
}, [fetchDetail]);
const start = useCallback(async (): Promise<StartDirectiveResponse | null> => {
if (!directiveId) return null;
try {
const response = await startDirective(directiveId);
await fetchDetail();
return response;
} catch (err) {
console.error("Failed to start directive:", err);
setError(err instanceof Error ? err.message : "Failed to start directive");
return null;
}
}, [directiveId, fetchDetail]);
const pause = useCallback(async (): Promise<boolean> => {
if (!directiveId) return false;
try {
await pauseDirective(directiveId);
await fetchDetail();
return true;
} catch (err) {
console.error("Failed to pause directive:", err);
setError(err instanceof Error ? err.message : "Failed to pause directive");
return false;
}
}, [directiveId, fetchDetail]);
const resume = useCallback(async (): Promise<boolean> => {
if (!directiveId) return false;
try {
await resumeDirective(directiveId);
await fetchDetail();
return true;
} catch (err) {
console.error("Failed to resume directive:", err);
setError(err instanceof Error ? err.message : "Failed to resume directive");
return false;
}
}, [directiveId, fetchDetail]);
const stop = useCallback(async (): Promise<boolean> => {
if (!directiveId) return false;
try {
await stopDirective(directiveId);
await fetchDetail();
return true;
} catch (err) {
console.error("Failed to stop directive:", err);
setError(err instanceof Error ? err.message : "Failed to stop directive");
return false;
}
}, [directiveId, fetchDetail]);
return {
directive,
graph,
loading,
error,
refresh: fetchDetail,
start,
pause,
resume,
stop,
};
}
|