Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6a23f97
New side menu icons
samejr Mar 23, 2026
179f066
Adds Prompt docs link to top bar
samejr Mar 23, 2026
48ffef9
Table text color update
samejr Mar 23, 2026
01d6c07
Use the CodeBlock component instead
samejr Mar 23, 2026
3a0be5e
Fixes z-index issues with resizable panels handles
samejr Mar 23, 2026
96868f8
Icon update
samejr Mar 23, 2026
a0c598a
Fixes hover behaviour and z-index issues of Resizable
samejr Mar 24, 2026
fd54575
Improves the title bar copy behaviour
samejr Mar 24, 2026
839323c
Fixes shortcuts conflict
samejr Mar 24, 2026
97844ad
Date picker supports shortcut key
samejr Mar 24, 2026
1d2534d
Adds shortcut keys to missing filters
samejr Mar 24, 2026
24b5e51
Simplified templates viewer
samejr Mar 24, 2026
934307c
Details panel imrprovements
samejr Mar 24, 2026
872a4e5
Adds focus-custom class
samejr Mar 24, 2026
1b2a447
Improvements to the Preview tab
samejr Mar 24, 2026
a24a139
Nicer display of versions
samejr Mar 24, 2026
70488ac
Allow className override
samejr Mar 24, 2026
fe2d7b7
Imrproved the Versions and override feature
samejr Mar 24, 2026
e72e5c8
Unified the version UI in the nav bar and version tab
samejr Mar 24, 2026
e62347c
Improvements to the Create Override modal
samejr Mar 24, 2026
00ac152
Metrics layout improvements
samejr Mar 24, 2026
13df095
Modal padding tweak
samejr Mar 24, 2026
98bbf09
Improves scroll behaviour for the code block
samejr Mar 24, 2026
d1686f2
Fixes scrolling for the template section
samejr Mar 24, 2026
cd7eca5
Fix for resizeable handle z-index
samejr Mar 24, 2026
1bff1d0
improvements to the generations table list
samejr Mar 24, 2026
e35167b
Create a new compact horizontal span time UI
samejr Mar 24, 2026
839cb20
Nicer table behaviour at small size
samejr Mar 24, 2026
8968a84
Make span titles bright
samejr Mar 24, 2026
939e6cc
Merge remote-tracking branch 'origin/main' into feat(webapp)-ai-scree…
samejr Mar 25, 2026
a5de1e6
Converts the Generations view into a proper table
samejr Mar 25, 2026
dc72104
Fixes a bunch of shortcut key clashes
samejr Mar 25, 2026
2b14601
Background color tweak
samejr Mar 25, 2026
571eccb
Adds cursor pointer to table row
samejr Mar 25, 2026
a08ffac
fix: review feedback - docsPath, typecheck error, duration rounding
ericallam Mar 25, 2026
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
16 changes: 16 additions & 0 deletions apps/webapp/app/assets/icons/AIMetricsIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export function AIMetricsIcon({ className }: { className?: string }) {
return (
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5.5 2C5.8013 2 6.0688 2.1928 6.16408 2.47864L6.53204 3.58252C6.67139 4.00057 6.99943 4.32861 7.41748 4.46796L8.52136 4.83592C8.8072 4.9312 9 5.1987 9 5.5C9 5.8013 8.8072 6.0688 8.52136 6.16408L7.41748 6.53204C6.99943 6.67139 6.67139 6.99943 6.53204 7.41748L6.16408 8.52136C6.0688 8.8072 5.8013 9 5.5 9C5.1987 9 4.9312 8.8072 4.83592 8.52136L4.46796 7.41748C4.32861 6.99943 4.00057 6.67139 3.58252 6.53204L2.47864 6.16408C2.1928 6.0688 2 5.8013 2 5.5C2 5.1987 2.1928 4.9312 2.47864 4.83592L3.58252 4.46796C4.00057 4.32861 4.32861 4.00057 4.46796 3.58252L4.83592 2.47864C4.9312 2.1928 5.1987 2 5.5 2Z"
fill="currentColor"
/>
<path
d="M18.6 2.40002C18.1226 2.40002 17.6648 2.58967 17.3272 2.92723C16.9896 3.2648 16.8 3.72263 16.8 4.20002V19.8C16.8 20.2774 16.9896 20.7353 17.3272 21.0728C17.6648 21.4104 18.1226 21.6 18.6 21.6H19.8C20.2774 21.6 20.7352 21.4104 21.0728 21.0728C21.4104 20.7353 21.6 20.2774 21.6 19.8V4.20002C21.6 3.72263 21.4104 3.2648 21.0728 2.92723C20.7352 2.58967 20.2774 2.40002 19.8 2.40002H18.6ZM11.4 7.20002C10.9226 7.20002 10.4648 7.38967 10.1272 7.72723C9.78964 8.0648 9.6 8.52263 9.6 9.00002V19.8C9.6 20.2774 9.78964 20.7353 10.1272 21.0728C10.4648 21.4104 10.9226 21.6 11.4 21.6H12.6C13.0774 21.6 13.5352 21.4104 13.8728 21.0728C14.2104 20.7353 14.4 20.2774 14.4 19.8V9.00002C14.4 8.52263 14.2104 8.0648 13.8728 7.72723C13.5352 7.38967 13.0774 7.20002 12.6 7.20002H11.4ZM4.2 12C3.72261 12 3.26477 12.1897 2.92721 12.5272C2.58964 12.8648 2.4 13.3226 2.4 13.8V19.8C2.4 20.2774 2.58964 20.7353 2.92721 21.0728C3.26477 21.4104 3.72261 21.6 4.2 21.6H5.4C5.87739 21.6 6.33523 21.4104 6.67279 21.0728C7.01036 20.7353 7.2 20.2774 7.2 19.8V13.8C7.2 13.3226 7.01036 12.8648 6.67279 12.5272C6.33523 12.1897 5.87739 12 5.4 12H4.2Z"
fill="currentColor"
/>
</svg>
);
}
10 changes: 10 additions & 0 deletions apps/webapp/app/assets/icons/AIPromptsIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export function AIPromptsIcon({ className }: { className?: string }) {
return (
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M12 3C14.5154 3 16.9845 3.20109 19.3916 3.58887C21.0075 3.8492 22.125 5.2653 22.125 6.85449V12.6455C22.125 14.2347 21.0075 15.6508 19.3916 15.9111C17.4843 16.2184 15.5379 16.4079 13.5605 16.4736C13.3313 16.4813 13.1196 16.5737 12.9668 16.7266L8.94043 20.7529C8.69912 20.9942 8.33578 21.0661 8.02051 20.9355C7.70544 20.8049 7.50001 20.4974 7.5 20.1562V16.2832C6.52707 16.189 5.56281 16.0649 4.6084 15.9111C2.99251 15.6508 1.875 14.2347 1.875 12.6455V6.85449C1.875 5.2653 2.99251 3.8492 4.6084 3.58887C7.01552 3.20109 9.48459 3 12 3ZM12 5.25C11.6127 5.25 11.2691 5.49785 11.1465 5.86523L10.6729 7.28418C10.4937 7.8215 10.0724 8.24359 9.53516 8.42285L8.11523 8.89648C7.74786 9.01906 7.5 9.3627 7.5 9.75C7.50001 10.1373 7.74786 10.4809 8.11523 10.6035L9.53516 11.0771C10.0722 11.2564 10.4937 11.6778 10.6729 12.2148L11.1465 13.6348C11.2691 14.0021 11.6127 14.25 12 14.25C12.3873 14.25 12.7309 14.0021 12.8535 13.6348L13.3271 12.2148C13.5063 11.6778 13.9278 11.2564 14.4648 11.0771L15.8848 10.6035C16.2521 10.4809 16.5 10.1373 16.5 9.75C16.5 9.3627 16.2521 9.01906 15.8848 8.89648L14.4648 8.42285C13.9276 8.24359 13.5063 7.8215 13.3271 7.28418L12.8535 5.86523C12.7309 5.49785 12.3873 5.25 12 5.25Z"
fill="currentColor"
/>
</svg>
);
}
79 changes: 37 additions & 42 deletions apps/webapp/app/components/BlankStatePanels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import {
BookOpenIcon,
ChatBubbleLeftRightIcon,
ClockIcon,
DocumentTextIcon,
PlusIcon,
QuestionMarkCircleIcon,
RectangleGroupIcon,
RectangleStackIcon,
ServerStackIcon,
SparklesIcon,
Squares2X2Icon,
} from "@heroicons/react/20/solid";
import { useLocation } from "react-use";
import { AIPromptsIcon } from "~/assets/icons/AIPromptsIcon";
import { BranchEnvironmentIconSmall } from "~/assets/icons/EnvironmentIcons";
import { WaitpointTokenIcon } from "~/assets/icons/WaitpointTokenIcon";
import openBulkActionsPanel from "~/assets/images/open-bulk-actions-panel.png";
Expand All @@ -25,21 +23,28 @@ import { useOrganization } from "~/hooks/useOrganizations";
import { useProject } from "~/hooks/useProject";
import { type MinimumEnvironment } from "~/presenters/SelectBestEnvironmentPresenter.server";
import { NewBranchPanel } from "~/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route";
import { GitHubSettingsPanel } from "~/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github";
import {
docsPath,
v3BillingPath,
v3CreateBulkActionPath,
v3EnvironmentPath,
v3EnvironmentVariablesPath,
v3NewProjectAlertPath,
v3NewSchedulePath,
} from "~/utils/pathBuilder";
import { AskAI } from "./AskAI";
import { CodeBlock } from "./code/CodeBlock";
import { InlineCode } from "./code/InlineCode";
import { environmentFullTitle, EnvironmentIcon } from "./environments/EnvironmentLabel";
import { Feedback } from "./Feedback";
import { EnvironmentSelector } from "./navigation/EnvironmentSelector";
import { Button, LinkButton } from "./primitives/Buttons";
import {
ClientTabs,
ClientTabsContent,
ClientTabsList,
ClientTabsTrigger,
} from "./primitives/ClientTabs";
import { Header1 } from "./primitives/Headers";
import { InfoPanel } from "./primitives/InfoPanel";
import { Paragraph } from "./primitives/Paragraph";
Expand All @@ -54,13 +59,6 @@ import {
} from "./SetupCommands";
import { StepContentContainer } from "./StepContentContainer";
import { V4Badge } from "./V4Badge";
import {
ClientTabs,
ClientTabsContent,
ClientTabsList,
ClientTabsTrigger,
} from "./primitives/ClientTabs";
import { GitHubSettingsPanel } from "~/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.github";

export function HasNoTasksDev() {
return (
Expand Down Expand Up @@ -603,7 +601,9 @@ function DeploymentOnboardingSteps() {
<div className="mb-2 flex items-center justify-between border-b">
<div className="mb-2 flex min-w-0 items-center gap-2">
<EnvironmentIcon environment={environment} className="-ml-1 size-8 shrink-0" />
<Header1 className="truncate">Deploy your tasks to {environmentFullTitle(environment)}</Header1>
<Header1 className="truncate">
Deploy your tasks to {environmentFullTitle(environment)}
</Header1>
</div>
<div className="flex items-center">
<SimpleTooltip
Expand Down Expand Up @@ -655,7 +655,7 @@ function DeploymentOnboardingSteps() {
organizationSlug={organization.slug}
projectSlug={project.slug}
environmentSlug={environment.slug}
billingPath={v3BillingPath({ slug: organization.slug })}
billingPath={v3BillingPath({ slug: organization.slug })}
/>
</div>
</StepContentContainer>
Expand Down Expand Up @@ -693,12 +693,16 @@ export function PromptsNone() {
return (
<InfoPanel
title="Define your first prompt"
icon={SparklesIcon}
iconClassName="text-purple-500"
icon={AIPromptsIcon}
iconClassName="text-aiPrompts"
panelClassName="max-w-lg"
accessory={
<LinkButton to={docsPath("prompt-management")} variant="docs/small" LeadingIcon={BookOpenIcon}>
Prompt docs
<LinkButton
to={docsPath("prompt-management")}
variant="docs/small"
LeadingIcon={BookOpenIcon}
>
Prompts docs
</LinkButton>
}
>
Expand All @@ -707,32 +711,23 @@ export function PromptsNone() {
version them from the dashboard without redeploying.
</Paragraph>
<Paragraph spacing variant="small">
Add a prompt to your project using <InlineCode variant="small">prompts.define()</InlineCode>:
Add a prompt to your project using <InlineCode variant="small">prompts.define()</InlineCode>
:
</Paragraph>
<div className="rounded border border-grid-dimmed bg-charcoal-900 p-3">
<pre className="text-xs leading-relaxed text-text-dimmed">
<span className="text-purple-400">import</span>
{" { prompts } "}
<span className="text-purple-400">from</span>
{' "@trigger.dev/sdk";\n'}
<span className="text-purple-400">import</span>
{" { z } "}
<span className="text-purple-400">from</span>
{' "zod";\n\n'}
<span className="text-purple-400">export const</span>
{" myPrompt = "}
<span className="text-blue-400">prompts.define</span>
{"({\n"}
{" id: "}
<span className="text-green-400">"my-prompt"</span>
{",\n"}
{" variables: z.object({\n"}
{" name: z.string(),\n"}
{" }),\n"}
{" content: "}
<span className="text-green-400">{"`Hello {{name}}!`"}</span>
{",\n"});</pre>
</div>
<CodeBlock
code={`import { prompts } from "@trigger.dev/sdk";
import { z } from "zod";

export const myPrompt = prompts.define({
id: "my-prompt",
variables: z.object({
name: z.string(),
}),
content: \`Hello {{name}}!\`,
});`}
showLineNumbers={false}
showOpenInModal={false}
/>
<Paragraph variant="small" className="mt-2">
Deploy your project and your prompts will appear here with version history and a live
editor.
Expand Down
16 changes: 9 additions & 7 deletions apps/webapp/app/components/code/CodeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,10 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
return (
<>
<div
className={cn("relative overflow-hidden rounded-md border border-grid-bright", className)}
className={cn(
"relative flex flex-col overflow-hidden rounded-md border border-grid-bright",
className
)}
style={{
backgroundColor: theme.plain.backgroundColor,
}}
Expand Down Expand Up @@ -355,9 +358,8 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
<div
dir="ltr"
className={cn(
"px-2 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600",
!isWrapped && "overflow-x-auto",
isWrapped && "overflow-y-auto"
"min-h-0 flex-1 px-2 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600",
"overflow-auto"
)}
style={{
maxHeight,
Expand Down Expand Up @@ -490,9 +492,9 @@ function HighlightCode({
}, []);

const containerClasses = cn(
"px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600",
!isWrapped && "overflow-x-auto",
isWrapped && "overflow-y-auto",
"min-h-0 flex-1 px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600",
!isWrapped && "overflow-auto",
isWrapped && "overflow-auto",
className
);

Expand Down
14 changes: 12 additions & 2 deletions apps/webapp/app/components/layout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,18 @@ export function MainBody({ children }: { children: React.ReactNode }) {
}

/** This container should be placed around the content on a page */
export function PageContainer({ children }: { children: React.ReactNode }) {
return <div className="grid h-full grid-rows-[auto_1fr] overflow-hidden">{children}</div>;
export function PageContainer({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return (
<div className={cn("grid h-full grid-rows-[auto_1fr] overflow-hidden", className)}>
{children}
</div>
);
}

export function PageBody({
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/metrics/ModelsFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { tablerIcons } from "~/utils/tablerIcons";
import tablerSpritePath from "~/components/primitives/tabler-sprite.svg";
import { AnthropicLogoIcon } from "~/assets/icons/AnthropicLogoIcon";

const shortcut = { key: "m" };
const shortcut = { key: "l" };

export type ModelOption = {
model: string;
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/metrics/ProvidersFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { useSearchParams } from "~/hooks/useSearchParam";
import { appliedSummary, FilterMenuProvider } from "~/components/runs/v3/SharedFilters";

const shortcut = { key: "v" };
const shortcut = { key: "r" };

interface ProvidersFilterProps {
possibleProviders: string[];
Expand Down
32 changes: 15 additions & 17 deletions apps/webapp/app/components/navigation/SideMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,27 @@ import {
Cog8ToothIcon,
CogIcon,
ExclamationTriangleIcon,
PuzzlePieceIcon,
FolderIcon,
FolderOpenIcon,
GlobeAmericasIcon,
IdentificationIcon,
KeyIcon,
PencilSquareIcon,
PlusIcon,
PuzzlePieceIcon,
RectangleStackIcon,
DocumentTextIcon,
ServerStackIcon,
SparklesIcon,
Squares2X2Icon,
TableCellsIcon,
UsersIcon,
BugAntIcon,
} from "@heroicons/react/20/solid";
import { Link, useFetcher, useNavigation } from "@remix-run/react";
import { IconBugFilled } from "@tabler/icons-react";
import { LayoutGroup, motion } from "framer-motion";
import { type ReactNode, useCallback, useEffect, useRef, useState } from "react";
import simplur from "simplur";
import { AIMetricsIcon } from "~/assets/icons/AIMetricsIcon";
import { AIPromptsIcon } from "~/assets/icons/AIPromptsIcon";
import { ConcurrencyIcon } from "~/assets/icons/ConcurrencyIcon";
import { DropdownIcon } from "~/assets/icons/DropdownIcon";
import { BranchEnvironmentIconSmall } from "~/assets/icons/EnvironmentIcons";
Expand Down Expand Up @@ -75,13 +75,13 @@ import {
v3DeploymentsPath,
v3EnvironmentPath,
v3EnvironmentVariablesPath,
v3LogsPath,
v3ErrorsPath,
v3PromptsPath,
v3LogsPath,
v3ProjectAlertsPath,
v3ProjectPath,
v3ProjectSettingsGeneralPath,
v3ProjectSettingsIntegrationsPath,
v3PromptsPath,
v3QueuesPath,
v3RunsPath,
v3SchedulesPath,
Expand Down Expand Up @@ -117,7 +117,6 @@ import { SideMenuHeader } from "./SideMenuHeader";
import { SideMenuItem } from "./SideMenuItem";
import { SideMenuSection } from "./SideMenuSection";
import { type SideMenuSectionId } from "./sideMenuTypes";
import { IconBugFilled } from "@tabler/icons-react";

/** Get the collapsed state for a specific side menu section from user preferences */
function getSectionCollapsed(
Expand Down Expand Up @@ -461,26 +460,25 @@ export function SideMenu({
title="AI"
isSideMenuCollapsed={isCollapsed}
itemSpacingClassName="space-y-0"
initialCollapsed={getSectionCollapsed(
user.dashboardPreferences.sideMenu,
"ai"
)}
initialCollapsed={getSectionCollapsed(user.dashboardPreferences.sideMenu, "ai")}
onCollapseToggle={handleSectionToggle("ai")}
>
<SideMenuItem
name="Prompts"
icon={DocumentTextIcon}
activeIconColor="text-purple-500"
inactiveIconColor="text-purple-500"
icon={AIPromptsIcon}
trailingIconClassName="size-6"
activeIconColor="text-aiPrompts"
inactiveIconColor="text-aiPrompts"
to={v3PromptsPath(organization, project, environment)}
data-action="prompts"
isCollapsed={isCollapsed}
/>
<SideMenuItem
name="AI Metrics"
icon={SparklesIcon}
activeIconColor="text-purple-500"
inactiveIconColor="text-purple-500"
icon={AIMetricsIcon}
trailingIconClassName="size-5"
activeIconColor="text-aiMetrics"
inactiveIconColor="text-aiMetrics"
to={v3BuiltInDashboardPath(organization, project, environment, "llm")}
data-action="ai-metrics"
isCollapsed={isCollapsed}
Expand Down
Loading
Loading