Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f389ead
Change the color to indigo
samejr May 16, 2025
5e2aa4d
Pro tier pricing information now matches the marketing site
samejr May 16, 2025
05a0f4f
Update the button styles to secondary
samejr May 16, 2025
a22e189
WIP adding separate links to Parent and Root runs
samejr May 16, 2025
ec9131b
TextLink now supports optional shortcuts
samejr May 16, 2025
fe0055f
Adds shortcut keys to the root and parent links + the shortcut help p…
samejr May 16, 2025
6f4d713
Adds new icons for root and parent
samejr May 16, 2025
cf41072
root friendlyId works
samejr May 16, 2025
35a9e41
Updates icons for jump to root and parent
samejr May 17, 2025
0e0b8d7
Copy tweak
samejr May 19, 2025
b5c1df7
Merge branch 'main' into update-pricing-page-style
samejr May 19, 2025
be5ca8b
Merge remote-tracking branch 'origin/main' into update-pricing-page-s…
samejr May 28, 2025
fb91c87
Improve how the Free tier shows no preview branches
samejr May 28, 2025
19e8673
Improve the wording in the tooltip
samejr May 28, 2025
9626eb6
Align the x icon better
samejr May 28, 2025
d588031
Show price for additional preview branches
samejr May 28, 2025
6e99c58
Change the shortcut key
samejr May 28, 2025
de5fc66
Merge branch 'main' into update-pricing-page-style
samejr Aug 29, 2025
93954ce
Fixes button alignment
samejr Aug 29, 2025
6e78f23
Adds nested dependencies task hello-world
samejr Aug 29, 2025
ef3699c
Fixes typo “Cancelled”
samejr Aug 29, 2025
93e68e4
Removes taskIdentifier, not needed
samejr Aug 29, 2025
5b9497d
Merge remote-tracking branch 'origin/main' into update-pricing-page-s…
samejr Aug 29, 2025
e0706e8
Merge branch 'main' into update-pricing-page-style
samejr Aug 29, 2025
e436368
Removes unused taskIdentifier
samejr Aug 29, 2025
300641f
Merge remote-tracking branch 'origin/main' into update-pricing-page-s…
samejr Aug 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions apps/webapp/app/assets/icons/MoveToTopIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export function MoveToTopIcon({ className }: { className?: string }) {
return (
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clipPath="url(#clip0_17186_103975)">
<path
d="M12 21L12 9"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M3 3L21 3"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M16.5 11.5L12 7L7.5 11.5"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
<defs>
<clipPath id="clip0_17186_103975">
<rect width="24" height="24" fill="currentColor" />
</clipPath>
</defs>
</svg>
);
}
41 changes: 41 additions & 0 deletions apps/webapp/app/assets/icons/MoveUpIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
export function MoveUpIcon({ className }: { className?: string }) {
return (
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clipPath="url(#clip0_17177_110851)">
<path
d="M12 21L12 13"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M3 3L21 3"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M3 7L21 7"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M16.5 15.5L12 11L7.5 15.5"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
<defs>
<clipPath id="clip0_17177_110851">
<rect width="24" height="24" fill="currentColor" />
</clipPath>
</defs>
</svg>
);
}
6 changes: 6 additions & 0 deletions apps/webapp/app/components/Shortcuts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ function ShortcutContent() {
</Paragraph>
<ShortcutKey shortcut={{ key: "9" }} variant="medium/bright" />
</Shortcut>
<Shortcut name="Jump to root run">
<ShortcutKey shortcut={{ key: "t" }} variant="medium/bright" />
</Shortcut>
<Shortcut name="Jump to parent run">
<ShortcutKey shortcut={{ key: "p" }} variant="medium/bright" />
</Shortcut>
</div>
<div className="space-y-3">
<Header3>Schedules page</Header3>
Expand Down
58 changes: 53 additions & 5 deletions apps/webapp/app/components/primitives/TextLink.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Link } from "@remix-run/react";
import { cn } from "~/utils/cn";
import { Icon, type RenderIcon } from "./Icon";
import { useRef } from "react";
import { type ShortcutDefinition, useShortcutKeys } from "~/hooks/useShortcutKeys";
import { ShortcutKey } from "./ShortcutKey";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./Tooltip";

const variations = {
primary:
Expand All @@ -17,6 +21,9 @@ type TextLinkProps = {
trailingIconClassName?: string;
variant?: keyof typeof variations;
children: React.ReactNode;
shortcut?: ShortcutDefinition;
hideShortcutKey?: boolean;
tooltip?: React.ReactNode;
} & React.AnchorHTMLAttributes<HTMLAnchorElement>;

export function TextLink({
Expand All @@ -27,20 +34,61 @@ export function TextLink({
trailingIcon,
trailingIconClassName,
variant = "primary",
shortcut,
hideShortcutKey,
tooltip,
...props
}: TextLinkProps) {
const innerRef = useRef<HTMLAnchorElement>(null);
const classes = variations[variant];
return to ? (
<Link to={to} className={cn(classes, className)} {...props}>

if (shortcut) {
useShortcutKeys({
shortcut: shortcut,
action: () => {
if (innerRef.current) {
innerRef.current.click();
}
},
});
}
Comment on lines +45 to +54
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid conditional hook calls – they break the Rules of Hooks

useShortcutKeys is invoked only when shortcut is truthy.
If the component first renders with shortcut={undefined} and later re-renders with a shortcut the hook order will change, throwing Invariant Violation: Rendered fewer hooks than expected.

Unconditionally call the hook and gate the feature inside the hook’s own options instead:

- if (shortcut) {
-   useShortcutKeys({
-     shortcut: shortcut,
-     action: () => {
-       if (innerRef.current) {
-         innerRef.current.click();
-       }
-     },
-   });
- }
+ useShortcutKeys(
+   shortcut
+     ? {
+         shortcut,
+         action: () => innerRef.current?.click(),
+       }
+     : undefined // hook still called, but no-op when undefined
+ );
🤖 Prompt for AI Agents
In apps/webapp/app/components/primitives/TextLink.tsx around lines 45 to 54, the
hook useShortcutKeys is called conditionally based on the shortcut prop, which
violates the Rules of Hooks and can cause runtime errors. To fix this, call
useShortcutKeys unconditionally every render and move the conditional logic
inside the hook's options or implementation so that the shortcut feature is
enabled or disabled internally without changing the hook call order.


const renderShortcutKey = () =>
shortcut &&
!hideShortcutKey && <ShortcutKey className="ml-1.5" shortcut={shortcut} variant="small" />;

const linkContent = (
<>
{children}{" "}
{trailingIcon && <Icon icon={trailingIcon} className={cn("size-4", trailingIconClassName)} />}
{shortcut && !tooltip && renderShortcutKey()}
</>
);

const linkElement = to ? (
<Link ref={innerRef} to={to} className={cn(classes, className)} {...props}>
{linkContent}
</Link>
) : href ? (
<a href={href} className={cn(classes, className)} {...props}>
{children}{" "}
{trailingIcon && <Icon icon={trailingIcon} className={cn("size-4", trailingIconClassName)} />}
<a ref={innerRef} href={href} className={cn(classes, className)} {...props}>
{linkContent}
</a>
) : (
<span>Need to define a path or href</span>
);

if (tooltip) {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{linkElement}</TooltipTrigger>
<TooltipContent className="text-dimmed flex items-center gap-3 py-1.5 pl-2.5 pr-3 text-xs">
{tooltip} {shortcut && renderShortcutKey()}
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}

return linkElement;
}
13 changes: 9 additions & 4 deletions apps/webapp/app/presenters/v3/RunPresenter.server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { millisecondsToNanoseconds } from "@trigger.dev/core/v3";
import { createTreeFromFlatItems, flattenTree } from "~/components/primitives/TreeView/TreeView";
import { prisma, PrismaClient } from "~/db.server";
import { prisma, type PrismaClient } from "~/db.server";
import { createTimelineSpanEventsFromSpanEvents } from "~/utils/timelineSpanEvents";
import { getUsername } from "~/utils/username";
import { eventRepository } from "~/v3/eventRepository.server";
Expand Down Expand Up @@ -58,7 +58,13 @@ export class RunPresenter {
rootTaskRun: {
select: {
friendlyId: true,
taskIdentifier: true,
spanId: true,
createdAt: true,
},
},
parentTaskRun: {
Comment on lines +61 to +65
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Root/parent selections updated; confirm no lingering uses of removed taskIdentifier/parentRunFriendlyId

Selections and returned shape look correct for new consumers. Please verify no remaining code paths still read rootTaskRun.taskIdentifier or parentRunFriendlyId.

Run from repo root:

Also applies to: 66-71, 120-121


🏁 Script executed:

#!/bin/bash
# Check for removed fields usage
rg -nP -C2 '\b(rootTaskRun|parentTaskRun)\.taskIdentifier\b|parentRunFriendlyId\b'

Length of output: 460


Remove lingering parentRunFriendlyId usage
apps/webapp/app/utils/taskEvent.ts:143 remove or replace the parentRunFriendlyId reference to match the updated parentTaskRun shape.

🤖 Prompt for AI Agents
In apps/webapp/app/presenters/v3/RunPresenter.server.ts around lines 61-65, the
presenter still expects a legacy parentRunFriendlyId; update the data shape so
callers no longer use parentRunFriendlyId — remove that reference in
apps/webapp/app/utils/taskEvent.ts line 143 and instead access the new
parentTaskRun field (use parentTaskRun.friendlyId if the parentTaskRun now
exposes a friendly identifier, otherwise use parentTaskRun.id). Ensure the
presenter either includes friendlyId on parentTaskRun or change the consumer to
read the canonical id field so no legacy parentRunFriendlyId is referenced.

select: {
friendlyId: true,
spanId: true,
createdAt: true,
},
Expand Down Expand Up @@ -111,6 +117,7 @@ export class RunPresenter {
completedAt: run.completedAt,
logsDeletedAt: showDeletedLogs ? null : run.logsDeletedAt,
rootTaskRun: run.rootTaskRun,
parentTaskRun: run.parentTaskRun,
environment: {
id: run.runtimeEnvironment.id,
organizationId: run.runtimeEnvironment.organizationId,
Expand Down Expand Up @@ -202,8 +209,6 @@ export class RunPresenter {
trace: {
rootSpanStatus,
events: events,
parentRunFriendlyId:
tree?.id === traceSummary.rootSpan.id ? undefined : traceSummary.rootSpan.runId,
duration: totalDuration,
rootStartedAt: tree?.data.startTime,
startedAt: run.startedAt,
Expand Down
Loading
Loading