Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions .changeset/list-project-runtime-updates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"trigger.dev": patch
"@trigger.dev/core": patch
---

List the current Production runtime for every accessible project with `trigger projects list`. Add `--needs-update` to identify projects currently running Node.js 21.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ArrowLeftIcon } from "@heroicons/react/24/solid";
import { BellIcon } from "~/assets/icons/BellIcon";
import { ChainLinkIcon } from "~/assets/icons/ChainLinkIcon";
import { CreditCardIcon } from "~/assets/icons/CreditCardIcon";
import { FolderOpenIcon } from "~/assets/icons/FolderOpenIcon";
import { PadlockIcon } from "~/assets/icons/PadlockIcon";
import { UsageIcon } from "~/assets/icons/UsageIcon";
import { RolesIcon } from "~/assets/icons/RolesIcon";
Expand All @@ -16,6 +17,7 @@ import { cn } from "~/utils/cn";
import {
organizationPath,
organizationRolesPath,
organizationRuntimeUpdatesPath,
organizationSettingsPath,
organizationSlackIntegrationPath,
organizationSsoPath,
Expand Down Expand Up @@ -49,11 +51,13 @@ export function OrganizationSettingsSideMenu({
buildInfo,
isUsingPlugin,
isSsoUsingPlugin,
hasProjectRuntimeUpdate,
}: {
organization: MatchedOrganization;
buildInfo: BuildInfo;
isUsingPlugin: boolean;
isSsoUsingPlugin: boolean;
hasProjectRuntimeUpdate: boolean;
}) {
const { isManagedCloud } = useFeatures();
const featureFlags = useFeatureFlags();
Expand Down Expand Up @@ -127,6 +131,22 @@ export function OrganizationSettingsSideMenu({
) : null}
</>
)}
<SideMenuItem
name="Projects"
icon={FolderOpenIcon}
activeIconColor="text-text-bright"
inactiveIconColor="text-text-dimmed"
to={organizationRuntimeUpdatesPath(organization)}
data-action="runtime-updates"
badge={
hasProjectRuntimeUpdate ? (
<>
<span aria-hidden className="size-2 shrink-0 rounded-full bg-warning" />
<span className="sr-only">Runtime update available.</span>
</>
) : undefined
}
/>
<SideMenuItem
name="Team"
icon={UserGroupIcon}
Expand Down
3 changes: 2 additions & 1 deletion apps/webapp/app/components/primitives/ClipboardField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ export function ClipboardField({
readOnly={true}
className={cn(
"shrink grow select-all overflow-x-auto",
fullWidth ? "w-full" : "max-w-fit",
// min-w-0 stops the input's intrinsic min-width pushing the copy button out of the row.
fullWidth ? "w-full min-w-0" : "max-w-fit",
input
)}
onFocus={(e) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/primitives/CopyButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function CopyButton({
onClick={copy}
className={cn(
buttonSize,
"flex items-center justify-center rounded border border-border-bright bg-background-hover",
"flex shrink-0 items-center justify-center rounded border border-border-bright bg-background-hover",
copied
? "text-green-500"
: "text-text-dimmed hover:border-border-bright hover:bg-background-raised hover:text-text-bright",
Expand Down
7 changes: 4 additions & 3 deletions apps/webapp/app/components/primitives/Label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import * as React from "react";
import { cn } from "~/utils/cn";
import { InfoIconTooltip } from "./Tooltip";

const variants = {
// Non-form labels (e.g. settings row titles) share this typography, so it is exported.
export const labelVariants = {
small: {
text: "font-sans text-[0.8125rem] font-normal text-text-bright leading-tight flex items-center gap-1",
},
Expand All @@ -17,7 +18,7 @@ const variants = {
type LabelProps = React.AllHTMLAttributes<HTMLLabelElement> & {
className?: string;
children: React.ReactNode;
variant?: keyof typeof variants;
variant?: keyof typeof labelVariants;
required?: boolean;
tooltip?: React.ReactNode;
};
Expand All @@ -30,7 +31,7 @@ export function Label({
tooltip,
...props
}: LabelProps) {
const variation = variants[variant];
const variation = labelVariants[variant];
return (
<label className={cn(variation.text, className)} {...props}>
{children}
Expand Down
14 changes: 6 additions & 8 deletions apps/webapp/app/components/primitives/SettingsLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type ReactNode } from "react";
import { MainHorizontallyCenteredContainer } from "~/components/layout/AppLayout";
import { cn } from "~/utils/cn";
import { Header2, Header3 } from "./Headers";
import { labelVariants } from "./Label";
import { Paragraph } from "./Paragraph";

// A composable layout system for settings pages: a centered container holds
Expand Down Expand Up @@ -82,7 +83,7 @@ export function SettingsHeader({
className
)}
>
<div className="space-y-1">
<div className="space-y-0.5">
<Heading>{title}</Heading>
{description ? <Paragraph variant="small">{description}</Paragraph> : null}
</div>
Expand All @@ -101,10 +102,7 @@ export function SettingsRowTitle({
htmlFor?: string;
className?: string;
}) {
const classes = cn(
"block font-sans text-sm font-semibold leading-tight text-text-bright",
className
);
const classes = cn(labelVariants.medium.text, className);
return htmlFor ? (
<label htmlFor={htmlFor} className={classes}>
{children}
Expand All @@ -123,7 +121,7 @@ export function SettingsRowDescription({
className?: string;
}) {
return (
<Paragraph variant="small" className={className}>
<Paragraph variant="extra-small" className={className}>
{children}
</Paragraph>
Comment thread
carderne marked this conversation as resolved.
);
Expand Down Expand Up @@ -170,7 +168,7 @@ export function SettingsRow({
)}
>
{children ?? (
<div className="flex-1 space-y-1">
<div className="flex-1 space-y-0.5">
{title ? (
<SettingsRowTitle htmlFor={htmlFor} className={titleClassName}>
{title}
Expand Down Expand Up @@ -229,7 +227,7 @@ export function SettingsAlertRow({

return (
<SettingsRow action={action}>
<div className="flex-1 space-y-1">
<div className="flex-1 space-y-0.5">
<div className="flex items-center gap-1.5">
<Icon className={cn("size-4 shrink-0", color)} />
<SettingsRowTitle className={color}>{title}</SettingsRowTitle>
Expand Down
24 changes: 19 additions & 5 deletions apps/webapp/app/routes/[_].$.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ import { prisma } from "~/db.server";
import { getUsersInvites } from "~/models/member.server";
import { SelectBestEnvironmentPresenter } from "~/presenters/SelectBestEnvironmentPresenter.server";
import { requireUser } from "~/services/session.server";
import { deeplinkSuffix, resolveDeeplinkPage } from "~/utils/deeplinkPages";
import {
deeplinkSuffix,
resolveDeeplinkPage,
resolveOrganizationDeeplinkPage,
} from "~/utils/deeplinkPages";
import {
invitesPath,
newOrganizationPath,
newProjectPath,
organizationRuntimeUpdatesPath,
v3EnvironmentPath,
} from "~/utils/pathBuilder";

Expand All @@ -16,7 +21,9 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await requireUser(request);

const { pathname, search } = new URL(request.url);
const page = resolveDeeplinkPage(deeplinkSuffix(pathname));
const suffix = deeplinkSuffix(pathname);
const page = resolveDeeplinkPage(suffix);
const organizationPage = resolveOrganizationDeeplinkPage(suffix);

const invites = await getUsersInvites({ email: user.email });
if (invites.length > 0) {
Expand All @@ -26,11 +33,14 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
const presenter = new SelectBestEnvironmentPresenter();
try {
const { project, organization, environment } = await presenter.call({ user });
const environmentPath = v3EnvironmentPath(organization, project, environment);
if (organizationPage === "runtime-updates") {
return redirect(`${organizationRuntimeUpdatesPath(organization)}${search}`);
}
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.

const suffix = page ? `/${page}` : "";
const environmentPath = v3EnvironmentPath(organization, project, environment);
const pageSuffix = page ? `/${page}` : "";

return redirect(`${environmentPath}${suffix}${search}`);
return redirect(`${environmentPath}${pageSuffix}${search}`);
} catch (_e) {
const organization = await prisma.organization.findFirst({
where: {
Expand All @@ -47,6 +57,10 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
});

if (organization) {
if (organizationPage === "runtime-updates") {
return redirect(`${organizationRuntimeUpdatesPath(organization)}${search}`);
}

return redirect(newProjectPath(organization));
}

Expand Down
Loading