Skip to content

Commit

Permalink
v3 live run reloading and minor style improvements (#925)
Browse files Browse the repository at this point in the history
* Initial work creating the Redis publishing and subscribing

* Live view is working

* Show the live reloading status on the page

* Fixed some style issues on the run page with James

* Fix for invalid JSX attributes in the ExitIcon svg

* Some sexy shit

* The end line is now correctly coloured

* millisecondsToNanoseconds exported from core/v3 and imported correctly

* Fix for e2e tests, we changed the h1 to an h2

* Tidied imports

* Removed unused hook
  • Loading branch information
matt-aitken authored Mar 6, 2024
1 parent 2a1273b commit 44d443a
Show file tree
Hide file tree
Showing 17 changed files with 453 additions and 247 deletions.
8 changes: 4 additions & 4 deletions apps/webapp/app/assets/icons/ExitIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
export function ExitIcon({ className }: { className?: string }) {
return (
<svg className={className} viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<line x1="3.5" y1="8" x2="11.5" y2="8" stroke="currentColor" stroke-linecap="round" />
<line x1="15.5" y1="1.5" x2="15.5" y2="14.5" stroke="currentColor" stroke-linecap="round" />
<line x1="3.5" y1="8" x2="11.5" y2="8" stroke="currentColor" strokeLinecap="round" />
<line x1="15.5" y1="1.5" x2="15.5" y2="14.5" stroke="currentColor" strokeLinecap="round" />
<path
d="M8.5 4.5L12 8L8.5 11.5"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
Expand Down
31 changes: 0 additions & 31 deletions apps/webapp/app/components/VersionLabel.tsx

This file was deleted.

5 changes: 2 additions & 3 deletions apps/webapp/app/components/primitives/Icon.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { FunctionComponent, ReactElement, createElement } from "react";
import { IconNamesOrString, NamedIcon } from "./NamedIcon";
import React, { FunctionComponent, createElement } from "react";
import { cn } from "~/utils/cn";
import { render } from "react-dom";
import { IconNamesOrString, NamedIcon } from "./NamedIcon";

export type RenderIcon =
| IconNamesOrString
Expand Down
17 changes: 1 addition & 16 deletions apps/webapp/app/components/primitives/Timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
useRef,
useState,
} from "react";
import { inverseLerp, lerp } from "~/utils/lerp";

interface MousePosition {
x: number;
Expand Down Expand Up @@ -225,19 +226,3 @@ export function FollowCursor({ children }: FollowCursorProps) {
function calculatePixelWidth(minWidth: number, maxWidth: number, scale: number) {
return lerp(minWidth, maxWidth, scale);
}

/** Linearly interpolates between the min/max values, using t.
* It can't go outside the range */
function lerp(min: number, max: number, t: number) {
return min + (max - min) * clamp(t, 0, 1);
}

/** Inverse lerp */
function inverseLerp(min: number, max: number, value: number) {
return (value - min) / (max - min);
}

/** Clamps a value between a min and max */
function clamp(value: number, min: number, max: number) {
return Math.min(max, Math.max(min, value));
}
31 changes: 31 additions & 0 deletions apps/webapp/app/components/runs/v3/LiveTimer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,34 @@ export function LiveTimer({
</Paragraph>
);
}

export function LiveCountUp({
lastUpdated,
updateInterval = 250,
className,
}: {
lastUpdated: Date;
updateInterval?: number;
className?: string;
}) {
const [now, setNow] = useState<Date>();

useEffect(() => {
const interval = setInterval(() => {
const date = new Date();
setNow(date);
}, updateInterval);

return () => clearInterval(interval);
}, [lastUpdated]);

return (
<>
{formatDuration(lastUpdated, now, {
style: "short",
maxDecimalPoints: 0,
units: ["m", "s"],
})}
</>
);
}
26 changes: 13 additions & 13 deletions apps/webapp/app/components/runs/v3/SpanTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type SpanTitleProps = {
isError: boolean;
style: TaskEventStyle;
level: TaskEventLevel;
isPartial: boolean;
size: "small" | "large";
};

Expand Down Expand Up @@ -90,10 +91,6 @@ export function SpanCodePathAccessory({
}

function eventTextClassName(event: Pick<SpanTitleProps, "isError" | "style" | "level">) {
if (event.isError) {
return "text-rose-500";
}

switch (event.level) {
case "TRACE": {
return textClassNameForVariant(event.style.variant);
Expand All @@ -107,7 +104,7 @@ function eventTextClassName(event: Pick<SpanTitleProps, "isError" | "style" | "l
return "text-amber-400";
}
case "ERROR": {
return "text-rose-500";
return "text-error";
}
default: {
return textClassNameForVariant(event.style.variant);
Expand All @@ -116,29 +113,29 @@ function eventTextClassName(event: Pick<SpanTitleProps, "isError" | "style" | "l
}

export function eventBackgroundClassName(
event: Pick<SpanTitleProps, "isError" | "style" | "level">
event: Pick<SpanTitleProps, "isError" | "style" | "level" | "isPartial">
) {
if (event.isError) {
return "bg-rose-500";
return "bg-error";
}

switch (event.level) {
case "TRACE": {
return backgroundClassNameForVariant(event.style.variant);
return backgroundClassNameForVariant(event.style.variant, event.isPartial);
}
case "LOG":
case "INFO":
case "DEBUG": {
return backgroundClassNameForVariant(event.style.variant);
return backgroundClassNameForVariant(event.style.variant, event.isPartial);
}
case "WARN": {
return "bg-amber-400";
}
case "ERROR": {
return "bg-rose-500";
return "bg-error";
}
default: {
return backgroundClassNameForVariant(event.style.variant);
return backgroundClassNameForVariant(event.style.variant, event.isPartial);
}
}
}
Expand All @@ -154,10 +151,13 @@ function textClassNameForVariant(variant: TaskEventStyle["variant"]) {
}
}

function backgroundClassNameForVariant(variant: TaskEventStyle["variant"]) {
function backgroundClassNameForVariant(variant: TaskEventStyle["variant"], isPartial: boolean) {
switch (variant) {
case "primary": {
return "bg-blue-500";
if (isPartial) {
return "bg-blue-500";
}
return "bg-success";
}
default: {
return "bg-charcoal-500";
Expand Down
6 changes: 3 additions & 3 deletions apps/webapp/app/components/runs/v3/TaskRunStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ export function runStatusClassNameColor(status: ExtendedTaskAttemptStatus | null
case "PENDING":
return "text-charcoal-500";
case "EXECUTING":
return "text-blue-500";
return "text-pending";
case "PAUSED":
return "text-amber-300";
case "FAILED":
return "text-rose-500";
return "text-error";
case "CANCELED":
return "text-charcoal-500";
case "COMPLETED":
return "text-green-500";
return "text-success";
default: {
const _exhaustiveCheck: never = status;
throw new Error(`Non-exhaustive match for value: ${status}`);
Expand Down
13 changes: 13 additions & 0 deletions apps/webapp/app/hooks/useInitialDimensions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useEffect, useLayoutEffect, useState } from "react";

export function useInitialDimensions(ref: React.RefObject<HTMLElement>) {
const [dimensions, setDimensions] = useState<DOMRectReadOnly | null>(null);

useEffect(() => {
if (ref.current) {
setDimensions(ref.current.getBoundingClientRect());
}
}, [ref]);

return dimensions;
}
11 changes: 0 additions & 11 deletions apps/webapp/app/hooks/useIsOrgChildPage.ts

This file was deleted.

12 changes: 11 additions & 1 deletion apps/webapp/app/presenters/v3/RunPresenter.server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { millisecondsToNanoseconds } from "@trigger.dev/core/v3/utils/durations";
import { millisecondsToNanoseconds } from "@trigger.dev/core/v3";
import { createTreeFromFlatItems, flattenTree } from "~/components/primitives/TreeView/TreeView";
import { PrismaClient, prisma } from "~/db.server";
import { getUsername } from "~/utils/username";
Expand Down Expand Up @@ -98,6 +98,15 @@ export class RunPresenter {
}
}

let rootSpanStatus: "executing" | "completed" | "failed" = "executing";
if (events[0]) {
if (events[0].data.isError) {
rootSpanStatus = "failed";
} else if (!events[0].data.isPartial) {
rootSpanStatus = "completed";
}
}

return {
run: {
number: run.number,
Expand All @@ -109,6 +118,7 @@ export class RunPresenter {
userName: getUsername(run.runtimeEnvironment.orgMember?.user),
},
},
rootSpanStatus,
events: events,
parentRunFriendlyId:
tree?.id === traceSummary.rootSpan.id ? undefined : traceSummary.rootSpan.runId,
Expand Down
Loading

0 comments on commit 44d443a

Please sign in to comment.