From ebc369deace937fa9d4e9cffe6e95c573a91f11f Mon Sep 17 00:00:00 2001 From: Matthias Van Parijs Date: Sat, 31 Aug 2024 16:00:37 +0200 Subject: [PATCH] chore: Added stretch loader to dashboard UI --- packages/api/src/contract.ts | 4 ++- packages/dashboard/package.json | 1 + packages/dashboard/src/components/JobLogs.tsx | 7 ++++- .../src/components/OpenApiReference.tsx | 21 +++++++++++++-- .../src/components/StretchLoader.tsx | 17 ++++++++++++ packages/dashboard/src/hooks/useJob.ts | 22 +++++++++++----- packages/dashboard/src/pages/ApiEmbedPage.tsx | 8 +++++- packages/dashboard/src/pages/ApiPage.tsx | 26 ++++++++++++++++++- packages/dashboard/src/pages/JobPage.tsx | 9 ++++++- packages/dashboard/src/pages/JobsPage.tsx | 11 +++++--- pnpm-lock.yaml | 7 +++++ 11 files changed, 117 insertions(+), 16 deletions(-) create mode 100644 packages/dashboard/src/components/StretchLoader.tsx diff --git a/packages/api/src/contract.ts b/packages/api/src/contract.ts index 18c8b4d8..a1446450 100644 --- a/packages/api/src/contract.ts +++ b/packages/api/src/contract.ts @@ -66,6 +66,8 @@ export const contract = c.router({ getSpec: { method: "GET", path: "/spec.json", - responses: {}, + responses: { + 200: c.type>(), + }, }, }); diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json index 24a9cc95..5fa8ddbc 100644 --- a/packages/dashboard/package.json +++ b/packages/dashboard/package.json @@ -29,6 +29,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "date-fns": "^3.6.0", + "ldrs": "^1.0.2", "lucide-react": "^0.424.0", "pretty-ms": "^9.1.0", "react": "^18.3.1", diff --git a/packages/dashboard/src/components/JobLogs.tsx b/packages/dashboard/src/components/JobLogs.tsx index fdd4eb49..9ba9f18d 100644 --- a/packages/dashboard/src/components/JobLogs.tsx +++ b/packages/dashboard/src/components/JobLogs.tsx @@ -5,11 +5,16 @@ type JobLogsProps = { }; export function JobLogs({ id }: JobLogsProps) { - const { data } = tsr.getJobLogs.useSuspenseQuery({ + const { data } = tsr.getJobLogs.useQuery({ queryKey: ["jobs", id, "logs"], queryData: { params: { id } }, refetchInterval: 2000, }); + + if (!data) { + return null; + } + const logs = data.body; return ( diff --git a/packages/dashboard/src/components/OpenApiReference.tsx b/packages/dashboard/src/components/OpenApiReference.tsx index 092c87d6..a42c5f12 100644 --- a/packages/dashboard/src/components/OpenApiReference.tsx +++ b/packages/dashboard/src/components/OpenApiReference.tsx @@ -1,18 +1,35 @@ import { ApiReferenceReact } from "@scalar/api-reference-react"; +import { tsr } from "@/tsr"; import "@scalar/api-reference-react/style.css"; +import { useEffect } from "react"; type OpenApiReferenceProps = { url: string; + onLoad(): void; }; -export function OpenApiReference({ url }: OpenApiReferenceProps) { +export function OpenApiReference({ url, onLoad }: OpenApiReferenceProps) { + const { data } = tsr.getSpec.useQuery({ + queryKey: ["spec"], + }); + + useEffect(() => { + if (data) { + onLoad(); + } + }, [data]); + + if (!data) { + return null; + } + return ( + {/* @ts-expect-error */} + + + ); +} diff --git a/packages/dashboard/src/hooks/useJob.ts b/packages/dashboard/src/hooks/useJob.ts index 931770bd..1a492fc1 100644 --- a/packages/dashboard/src/hooks/useJob.ts +++ b/packages/dashboard/src/hooks/useJob.ts @@ -1,20 +1,30 @@ import { tsr } from "@/tsr"; +import { useEffect, useRef } from "react"; import type { JobDto } from "@/tsr"; export function useJob(id: string) { - const { data: jobData } = tsr.getJob.useSuspenseQuery({ + const lastResultRef = useRef(); + + const { data } = tsr.getJob.useQuery({ queryKey: ["jobsFromRoot", id], queryData: { params: { id }, query: { fromRoot: true } }, refetchInterval: 2000, }); - const rootJob = jobData.body; - const job = findJob(rootJob, id); - if (!job) { - throw new Error("Job not found in tree."); + useEffect(() => { + if (data) { + lastResultRef.current = data.body; + } + }, [data]); + + const rootJob = data?.body ?? lastResultRef.current; + if (!rootJob) { + return null; } - return [job, rootJob] as const; + const job = findJob(rootJob, id); + + return { job, rootJob }; } function findJob(job: JobDto, id: string): JobDto | null { diff --git a/packages/dashboard/src/pages/ApiEmbedPage.tsx b/packages/dashboard/src/pages/ApiEmbedPage.tsx index 6bf6f012..4d58d85f 100644 --- a/packages/dashboard/src/pages/ApiEmbedPage.tsx +++ b/packages/dashboard/src/pages/ApiEmbedPage.tsx @@ -7,5 +7,11 @@ const LazyOpenApiReference = lazy(() => ); export function ApiEmbedPage() { - return ; + const onLoad = () => { + window.parent.postMessage("mixwave_openapi_loaded", "*"); + }; + + return ( + + ); } diff --git a/packages/dashboard/src/pages/ApiPage.tsx b/packages/dashboard/src/pages/ApiPage.tsx index 07456420..6ebd758c 100644 --- a/packages/dashboard/src/pages/ApiPage.tsx +++ b/packages/dashboard/src/pages/ApiPage.tsx @@ -1,3 +1,27 @@ +import { StretchLoader } from "@/components/StretchLoader"; +import { useEffect, useState } from "react"; + export function ApiPage() { - return