54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
import { useAppStore } from "@/components/state-provider";
|
|
import { fetchTaskEnvironment } from "@/lib/api/domains/task-environment-api";
|
|
import type { ExecutorProfile } from "@/lib/types/http";
|
|
|
|
/** Resolves the executor profile bound to a task's environment. */
|
|
export function useTaskExecutorProfile(taskId: string, enabled = true): ExecutorProfile | null {
|
|
const executors = useAppStore((state) => state.executors.items);
|
|
const executorsFingerprint = useMemo(
|
|
() =>
|
|
executors
|
|
.map(
|
|
(executor) =>
|
|
`${executor.id}|${executor.type}|${(executor.profiles ?? []).map((profile) => profile.id).join(",")}`,
|
|
)
|
|
.join(";"),
|
|
[executors],
|
|
);
|
|
const executorsRef = useRef(executors);
|
|
const [profile, setProfile] = useState<ExecutorProfile | null>(null);
|
|
useLayoutEffect(() => {
|
|
executorsRef.current = executors;
|
|
}, [executors]);
|
|
|
|
useEffect(() => {
|
|
if (!enabled || !taskId) return;
|
|
let active = true;
|
|
void fetchTaskEnvironment(taskId)
|
|
.then((env) => {
|
|
if (!active || !env) return;
|
|
let foundProfile: ExecutorProfile | undefined;
|
|
for (const executor of executorsRef.current) {
|
|
const match = (executor.profiles ?? []).find((p) => p.id === env.executor_profile_id);
|
|
if (match) {
|
|
foundProfile = {
|
|
...match,
|
|
executor_type: match.executor_type ?? executor.type,
|
|
executor_name: match.executor_name ?? executor.name,
|
|
};
|
|
break;
|
|
}
|
|
}
|
|
setProfile(foundProfile ?? null);
|
|
})
|
|
.catch(() => {});
|
|
return () => {
|
|
active = false;
|
|
};
|
|
}, [enabled, taskId, executorsFingerprint]);
|
|
|
|
if (!enabled || !taskId) return null;
|
|
return profile;
|
|
}
|