140 lines
5.2 KiB
TypeScript
140 lines
5.2 KiB
TypeScript
import { DateTime, DateTimeAccurate } from "~/components/primitives/DateTime";
|
||
import { Paragraph } from "~/components/primitives/Paragraph";
|
||
import * as Property from "~/components/primitives/PropertyTable";
|
||
import { TextLink } from "~/components/primitives/TextLink";
|
||
import { useEnvironment } from "~/hooks/useEnvironment";
|
||
import { useOrganization } from "~/hooks/useOrganizations";
|
||
import { useProject } from "~/hooks/useProject";
|
||
import { type WaitpointDetail } from "~/presenters/v3/WaitpointPresenter.server";
|
||
import { ForceTimeout } from "~/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.$waitpointFriendlyId.complete/route";
|
||
import { v3WaitpointTokenPath, v3WaitpointTokensPath } from "~/utils/pathBuilder";
|
||
import { PacketDisplay } from "./PacketDisplay";
|
||
import { WaitpointStatusCombo } from "./WaitpointStatus";
|
||
import { RunTag } from "./RunTag";
|
||
import { ClipboardField } from "~/components/primitives/ClipboardField";
|
||
|
||
export function WaitpointDetailTable({
|
||
waitpoint,
|
||
linkToList = false,
|
||
}: {
|
||
waitpoint: WaitpointDetail;
|
||
linkToList?: boolean;
|
||
}) {
|
||
const organization = useOrganization();
|
||
const project = useProject();
|
||
const environment = useEnvironment();
|
||
|
||
const hasExpired =
|
||
waitpoint.idempotencyKeyExpiresAt && waitpoint.idempotencyKeyExpiresAt < new Date();
|
||
|
||
return (
|
||
<Property.Table>
|
||
<Property.Item>
|
||
<Property.Label>Status</Property.Label>
|
||
<Property.Value>
|
||
<WaitpointStatusCombo status={waitpoint.status} className="text-sm" />
|
||
</Property.Value>
|
||
</Property.Item>
|
||
<Property.Item>
|
||
<Property.Label>ID</Property.Label>
|
||
<Property.Value className="whitespace-pre-wrap">
|
||
{linkToList ? (
|
||
<TextLink
|
||
to={v3WaitpointTokenPath(organization, project, environment, waitpoint, {
|
||
id: waitpoint.id,
|
||
})}
|
||
>
|
||
{waitpoint.id}
|
||
</TextLink>
|
||
) : (
|
||
waitpoint.id
|
||
)}
|
||
</Property.Value>
|
||
</Property.Item>
|
||
{waitpoint.type === "MANUAL" && (
|
||
<Property.Item>
|
||
<Property.Label>Callback URL</Property.Label>
|
||
<Property.Value className="my-1">
|
||
<ClipboardField value={waitpoint.url} variant={"secondary/small"} />
|
||
</Property.Value>
|
||
</Property.Item>
|
||
)}
|
||
<Property.Item>
|
||
<Property.Label>Idempotency key</Property.Label>
|
||
<Property.Value>
|
||
<div>
|
||
<div>
|
||
{waitpoint.userProvidedIdempotencyKey
|
||
? (waitpoint.inactiveIdempotencyKey ?? waitpoint.idempotencyKey)
|
||
: "–"}
|
||
</div>
|
||
<div>
|
||
{waitpoint.idempotencyKeyExpiresAt ? (
|
||
<>
|
||
{hasExpired ? "Expired" : "Expires at"}:{" "}
|
||
<DateTime date={waitpoint.idempotencyKeyExpiresAt} />
|
||
</>
|
||
) : null}
|
||
</div>
|
||
</div>
|
||
</Property.Value>
|
||
</Property.Item>
|
||
{waitpoint.type === "MANUAL" && (
|
||
<>
|
||
<Property.Item>
|
||
<Property.Label>Timeout</Property.Label>
|
||
<Property.Value>
|
||
<div>
|
||
<div className="flex w-full flex-wrap items-center justify-between gap-1">
|
||
{waitpoint.completedAfter ? (
|
||
<>
|
||
<DateTimeAccurate date={waitpoint.completedAfter} />
|
||
</>
|
||
) : (
|
||
"–"
|
||
)}
|
||
{waitpoint.status === "WAITING" && <ForceTimeout waitpoint={waitpoint} />}
|
||
</div>
|
||
<Paragraph variant="extra-small" className="text-text-dimmed/70">
|
||
{waitpoint.status === "TIMED_OUT"
|
||
? "The waitpoint timed out"
|
||
: waitpoint.status === "COMPLETED"
|
||
? "The waitpoint completed before this timeout was reached"
|
||
: "The waitpoint is still waiting"}
|
||
</Paragraph>
|
||
</div>
|
||
</Property.Value>
|
||
</Property.Item>
|
||
<Property.Item>
|
||
<Property.Label>Tags</Property.Label>
|
||
<Property.Value>
|
||
<div className="flex flex-wrap gap-1 pt-1 text-xs">
|
||
{waitpoint.tags.map((tag) => (
|
||
<RunTag
|
||
key={tag}
|
||
tag={tag}
|
||
to={v3WaitpointTokensPath(organization, project, environment, { tags: [tag] })}
|
||
/>
|
||
))}
|
||
</div>
|
||
</Property.Value>
|
||
</Property.Item>
|
||
</>
|
||
)}
|
||
<Property.Item>
|
||
<Property.Label>Completed</Property.Label>
|
||
<Property.Value>
|
||
{waitpoint.completedAt ? <DateTimeAccurate date={waitpoint.completedAt} /> : "–"}
|
||
</Property.Value>
|
||
</Property.Item>
|
||
{waitpoint.status === "WAITING" ? null : waitpoint.status === "TIMED_OUT" ? (
|
||
<></>
|
||
) : waitpoint.output ? (
|
||
<PacketDisplay title="Output" data={waitpoint.output} dataType={waitpoint.outputType} />
|
||
) : waitpoint.completedAfter ? null : (
|
||
"Completed with no output"
|
||
)}
|
||
</Property.Table>
|
||
);
|
||
}
|