74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
import { useQuery } from "@tanstack/react-query";
|
|
import type { components } from "../../api/schema";
|
|
import { apiClient } from "../lib/api-client";
|
|
import { mockWorkspaces } from "../lib/mock-data";
|
|
import {
|
|
type PRState,
|
|
type PullRequestFacts,
|
|
toAgentProvider,
|
|
toSessionStatus,
|
|
type WorkspaceSummary,
|
|
} from "../types/workspace";
|
|
|
|
function toPullRequestFacts(pr: components["schemas"]["SessionPRFacts"]): PullRequestFacts {
|
|
return {
|
|
url: pr.url,
|
|
number: pr.number,
|
|
state: pr.state as PRState,
|
|
ci: pr.ci,
|
|
review: pr.review,
|
|
mergeability: pr.mergeability,
|
|
reviewComments: pr.reviewComments,
|
|
updatedAt: pr.updatedAt,
|
|
};
|
|
}
|
|
|
|
export const workspaceQueryKey = ["workspaces"] as const;
|
|
const usePreviewData = import.meta.env.VITE_NO_ELECTRON === "1";
|
|
|
|
async function fetchWorkspaces(): Promise<WorkspaceSummary[]> {
|
|
if (usePreviewData) {
|
|
return mockWorkspaces;
|
|
}
|
|
|
|
const [{ data: projectsData, error: projectsError }, { data: sessionsData, error: sessionsError }] =
|
|
await Promise.all([apiClient.GET("/api/v1/projects"), apiClient.GET("/api/v1/sessions")]);
|
|
|
|
if (projectsError || sessionsError) throw projectsError ?? sessionsError;
|
|
|
|
return (projectsData?.projects ?? []).map((project) => ({
|
|
id: project.id,
|
|
name: project.name,
|
|
path: project.path,
|
|
sessions: (sessionsData?.sessions ?? [])
|
|
.filter((session) => session.projectId === project.id)
|
|
.map((session) => ({
|
|
id: session.id,
|
|
terminalHandleId: session.terminalHandleId,
|
|
workspaceId: project.id,
|
|
workspaceName: project.name,
|
|
title: session.displayName ?? session.issueId ?? session.id,
|
|
provider: toAgentProvider(session.harness),
|
|
kind: session.kind === "orchestrator" ? "orchestrator" : session.kind === "worker" ? "worker" : undefined,
|
|
branch: `session/${session.id}`,
|
|
status: toSessionStatus(session.status, session.isTerminated),
|
|
createdAt: session.createdAt,
|
|
updatedAt: session.updatedAt,
|
|
prs: (session.prs ?? []).map(toPullRequestFacts),
|
|
})),
|
|
}));
|
|
}
|
|
|
|
// Shared so route loaders can prefetch via queryClient.ensureQueryData (paired
|
|
// with the router's defaultPreload: "intent") and the hook reads the same cache.
|
|
export const workspaceQueryOptions = {
|
|
queryKey: workspaceQueryKey,
|
|
queryFn: fetchWorkspaces,
|
|
retry: 1,
|
|
refetchInterval: 15_000,
|
|
};
|
|
|
|
export function useWorkspaceQuery() {
|
|
return useQuery(workspaceQueryOptions);
|
|
}
|