chore: remove obsolete v3/v4 version copy from the dashboard (#4589)
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
area: webapp
|
||||
type: improvement
|
||||
---
|
||||
|
||||
Out-of-date upgrade prompts no longer appear in the dashboard: the "V4" badges and the notices saying preview branches and the queues table need V4 have been removed. The side menu still warns you when a project is on v3, with updated wording and a link to the v4 upgrade guide.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 185 KiB |
@@ -7,7 +7,6 @@ import {
|
||||
PlusIcon,
|
||||
QuestionMarkCircleIcon,
|
||||
RectangleGroupIcon,
|
||||
RectangleStackIcon,
|
||||
SparklesIcon,
|
||||
Squares2X2Icon,
|
||||
} from "@heroicons/react/20/solid";
|
||||
@@ -63,7 +62,6 @@ import {
|
||||
TriggerDevStepV3,
|
||||
} from "./SetupCommands";
|
||||
import { StepContentContainer } from "./StepContentContainer";
|
||||
import { V4Badge } from "./V4Badge";
|
||||
|
||||
/**
|
||||
* What the agent is asked when it's opened from a deployment setup panel. The panel is the docs
|
||||
@@ -475,36 +473,6 @@ export function AlertsNoneDeployed() {
|
||||
);
|
||||
}
|
||||
|
||||
export function QueuesHasNoTasks() {
|
||||
const organization = useOrganization();
|
||||
const project = useProject();
|
||||
const environment = useEnvironment();
|
||||
|
||||
return (
|
||||
<InfoPanel
|
||||
title="You don't have any queues"
|
||||
icon={RectangleStackIcon}
|
||||
iconClassName="text-queues"
|
||||
panelClassName="max-w-md"
|
||||
accessory={
|
||||
<LinkButton
|
||||
to={v3EnvironmentPath(organization, project, environment)}
|
||||
variant="primary/small"
|
||||
>
|
||||
Create a task
|
||||
</LinkButton>
|
||||
}
|
||||
>
|
||||
<Paragraph spacing variant="small">
|
||||
Queues will appear here when you have created a task in this environment. Follow the
|
||||
instructions on the{" "}
|
||||
<TextLink to={v3EnvironmentPath(organization, project, environment)}>Tasks page</TextLink>{" "}
|
||||
to create a task, then return here to see its queue.
|
||||
</Paragraph>
|
||||
</InfoPanel>
|
||||
);
|
||||
}
|
||||
|
||||
export function NoWaitpointTokens() {
|
||||
return (
|
||||
<InfoPanel
|
||||
@@ -567,14 +535,10 @@ export function BranchesNoBranchableEnvironment({ showSelfServe }: { showSelfSer
|
||||
)
|
||||
}
|
||||
>
|
||||
<Paragraph spacing variant="small">
|
||||
<Paragraph variant="small">
|
||||
Preview branches in Trigger.dev create isolated environments for testing new features before
|
||||
production.
|
||||
</Paragraph>
|
||||
<Paragraph variant="small">
|
||||
You must be on <V4Badge inline /> to access preview branches. Read our{" "}
|
||||
<TextLink to={docsPath("upgrade-to-v4")}>upgrade to v4 guide</TextLink> to learn more.
|
||||
</Paragraph>
|
||||
</InfoPanel>
|
||||
);
|
||||
}
|
||||
@@ -648,14 +612,10 @@ export function BranchesNoBranches({
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Paragraph spacing variant="small">
|
||||
<Paragraph variant="small">
|
||||
Branches are a way to test new features in isolation before merging them into the main
|
||||
environment.
|
||||
</Paragraph>
|
||||
<Paragraph spacing variant="small">
|
||||
Branches are only available when using <V4Badge inline /> or above. Read our{" "}
|
||||
<TextLink to={docsPath("upgrade-to-v4")}>v4 upgrade guide</TextLink> to learn more.
|
||||
</Paragraph>
|
||||
</InfoPanel>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { cn } from "~/utils/cn";
|
||||
import { Badge } from "./primitives/Badge";
|
||||
import { SimpleTooltip } from "./primitives/Tooltip";
|
||||
|
||||
export function V4Badge({ inline = false, className }: { inline?: boolean; className?: string }) {
|
||||
return (
|
||||
<SimpleTooltip
|
||||
button={
|
||||
<Badge variant="extra-small" className={cn(inline ? "inline-grid" : "", className)}>
|
||||
V4
|
||||
</Badge>
|
||||
}
|
||||
content="This feature is only available in V4 and above."
|
||||
disableHoverableContent
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function V4Title({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<>
|
||||
<span>{children}</span>
|
||||
<V4Badge />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import { useFeatures } from "~/hooks/useFeatures";
|
||||
import { useOrganization, type MatchedOrganization } from "~/hooks/useOrganizations";
|
||||
import { useProject } from "~/hooks/useProject";
|
||||
import { cn } from "~/utils/cn";
|
||||
import { branchesPath, branchesDevPath, docsPath, v3BillingPath } from "~/utils/pathBuilder";
|
||||
import { branchesPath, branchesDevPath, v3BillingPath } from "~/utils/pathBuilder";
|
||||
import {
|
||||
EnvironmentCombo,
|
||||
EnvironmentIcon,
|
||||
@@ -29,9 +29,7 @@ import {
|
||||
PopoverSectionHeader,
|
||||
PopoverTrigger,
|
||||
} from "../primitives/Popover";
|
||||
import { TextLink } from "../primitives/TextLink";
|
||||
import { SimpleTooltip } from "../primitives/Tooltip";
|
||||
import { V4Badge } from "../V4Badge";
|
||||
import { type SideMenuEnvironment, type SideMenuProject } from "./SideMenu";
|
||||
import { Badge } from "../primitives/Badge";
|
||||
|
||||
@@ -411,14 +409,10 @@ export function BranchesPopoverContent({
|
||||
<BranchEnvironmentIconSmall className={cn("size-4", envTextClassName)} />
|
||||
<Header2>Create your first branch</Header2>
|
||||
</div>
|
||||
<Paragraph spacing variant="small">
|
||||
<Paragraph variant="small">
|
||||
Branches are a way to test new features in isolation before merging them into the main
|
||||
environment.
|
||||
</Paragraph>
|
||||
<Paragraph variant="small">
|
||||
Branches are only available when using <V4Badge inline /> or above. Read our{" "}
|
||||
<TextLink to={docsPath("upgrade-to-v4")}>v4 upgrade guide</TextLink> to learn more.
|
||||
</Paragraph>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex max-w-sm flex-col gap-1 p-2">
|
||||
|
||||
@@ -96,6 +96,7 @@ import {
|
||||
adminPath,
|
||||
branchesPath,
|
||||
concurrencyPath,
|
||||
docsPath,
|
||||
limitsPath,
|
||||
logoutPath,
|
||||
newOrganizationPath,
|
||||
@@ -1111,7 +1112,7 @@ export function SideMenu({
|
||||
isDragging={isDragging}
|
||||
className="min-w-0 flex-1"
|
||||
/>
|
||||
{environment.type === "DEVELOPMENT" && project.engine === "V2" && (
|
||||
{environment.type === "DEVELOPMENT" && (
|
||||
<CollapsibleElement isDragging={isDragging} className="shrink-0">
|
||||
<Dialog>
|
||||
<TooltipProvider disableHoverableContent={true}>
|
||||
@@ -1604,7 +1605,7 @@ function V3DeprecationPanel({
|
||||
<ExclamationTriangleIcon className="size-5 text-amber-400" />
|
||||
</PopoverTrigger>
|
||||
}
|
||||
content="V3 deprecation warning"
|
||||
content="v3 is now deprecated"
|
||||
side="right"
|
||||
sideOffset={8}
|
||||
disableHoverableContent
|
||||
@@ -1625,23 +1626,23 @@ function V3DeprecationContent() {
|
||||
<div className="flex items-center gap-1 border-b border-amber-500/30 pb-1">
|
||||
<ExclamationTriangleIcon className="size-4 text-amber-400" />
|
||||
<Paragraph variant="small/bright" className="text-amber-300">
|
||||
V3 deprecation warning
|
||||
v3 is now deprecated
|
||||
</Paragraph>
|
||||
</div>
|
||||
<Paragraph variant="extra-small/bright" className="text-amber-300">
|
||||
This is a v3 project. V3 deploys will stop working on 1 April 2026. Full shutdown is 1 July
|
||||
2026 where all v3 runs will stop executing. Migrate to v4 to avoid downtime.
|
||||
This is a v3 project which is now deprecated so no runs are executing. Upgrade to v4 to
|
||||
resume executing runs in this project.
|
||||
</Paragraph>
|
||||
<LinkButton
|
||||
variant="secondary/small"
|
||||
to="https://trigger.dev/docs/migrating-from-v3"
|
||||
to={docsPath("/upgrade-to-v4")}
|
||||
target="_blank"
|
||||
fullWidth
|
||||
TrailingIcon={ArrowTopRightOnSquareIcon}
|
||||
trailingIconClassName="text-amber-300"
|
||||
className="border-amber-500/30 bg-amber-500/15 hover:border-amber-500/50! hover:bg-amber-500/25!"
|
||||
>
|
||||
<span className="text-amber-300">View migration guide</span>
|
||||
<span className="text-amber-300">Upgrade to v4</span>
|
||||
</LinkButton>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,6 @@ import { type PrismaClientOrTransaction } from "~/db.server";
|
||||
import { type AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
||||
import { clickhouseFactory } from "~/services/clickhouse/clickhouseFactoryInstance.server";
|
||||
import { logger } from "~/services/logger.server";
|
||||
import { determineEngineVersion } from "~/v3/engineVersion.server";
|
||||
import { engine } from "~/v3/runEngine.server";
|
||||
import { BasePresenter } from "./basePresenter.server";
|
||||
import { toQueueItem } from "./QueueRetrievePresenter.server";
|
||||
@@ -51,25 +50,12 @@ type QueueListPagination =
|
||||
| { mode: "filtered"; currentPage: number; hasMore: boolean }
|
||||
| { mode: "unfiltered"; currentPage: number; totalPages: number; count: number };
|
||||
|
||||
// The `?: undefined` markers keep every key reachable across the union, so consumers
|
||||
// can destructure before narrowing on `success`.
|
||||
export type QueueListResult =
|
||||
| {
|
||||
success: false;
|
||||
code: string;
|
||||
totalQueues: number;
|
||||
hasFilters: boolean;
|
||||
queues?: undefined;
|
||||
pagination?: undefined;
|
||||
}
|
||||
| {
|
||||
success: true;
|
||||
queues: QueueListItem[];
|
||||
pagination: QueueListPagination;
|
||||
totalQueues?: number;
|
||||
hasFilters: boolean;
|
||||
code?: undefined;
|
||||
};
|
||||
export type QueueListResult = {
|
||||
queues: QueueListItem[];
|
||||
pagination: QueueListPagination;
|
||||
totalQueues?: number;
|
||||
hasFilters: boolean;
|
||||
};
|
||||
|
||||
function formatClickhouseDateTime(date: Date): string {
|
||||
return date.toISOString().slice(0, 19).replace("T", " ");
|
||||
@@ -126,37 +112,6 @@ export class QueueListPresenter extends BasePresenter {
|
||||
}): Promise<QueueListResult> {
|
||||
const hasFilters = Boolean(query?.trim()) || type !== undefined;
|
||||
|
||||
const engineVersion = await determineEngineVersion({ environment });
|
||||
if (engineVersion === "V1") {
|
||||
const totalQueues = await this._replica.taskQueue.count({
|
||||
where: buildQueueListWhere(environment.id, query, type),
|
||||
});
|
||||
|
||||
if (totalQueues === 0) {
|
||||
const oldQueue = await this._replica.taskQueue.findFirst({
|
||||
where: {
|
||||
runtimeEnvironmentId: environment.id,
|
||||
version: "V1",
|
||||
},
|
||||
});
|
||||
if (oldQueue) {
|
||||
return {
|
||||
success: false as const,
|
||||
code: "engine-version",
|
||||
totalQueues: 1,
|
||||
hasFilters,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: false as const,
|
||||
code: "engine-version",
|
||||
totalQueues,
|
||||
hasFilters,
|
||||
};
|
||||
}
|
||||
|
||||
if (sort !== "name") {
|
||||
// Ranking is additive: any failure or unsupported input falls back to name order.
|
||||
try {
|
||||
@@ -173,7 +128,6 @@ export class QueueListPresenter extends BasePresenter {
|
||||
const { queues, hasMore } = await this.getFilteredQueues(environment, query, page, type);
|
||||
|
||||
return {
|
||||
success: true as const,
|
||||
queues,
|
||||
pagination: {
|
||||
mode: "filtered" as const,
|
||||
@@ -189,7 +143,6 @@ export class QueueListPresenter extends BasePresenter {
|
||||
});
|
||||
|
||||
return {
|
||||
success: true as const,
|
||||
queues: await this.getUnfilteredQueues(environment, page, type),
|
||||
pagination: {
|
||||
mode: "unfiltered" as const,
|
||||
@@ -300,7 +253,6 @@ export class QueueListPresenter extends BasePresenter {
|
||||
}
|
||||
|
||||
return {
|
||||
success: true as const,
|
||||
queues: await this.enrichQueues(environment, [...rankedPageQueues, ...tailQueues]),
|
||||
pagination: {
|
||||
mode: "unfiltered" as const,
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
type TaskQueueType,
|
||||
} from "@trigger.dev/database";
|
||||
import { type AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
||||
import { determineEngineVersion } from "~/v3/engineVersion.server";
|
||||
import { engine } from "~/v3/runEngine.server";
|
||||
import { BasePresenter } from "./basePresenter.server";
|
||||
|
||||
@@ -80,16 +79,6 @@ export class QueueRetrievePresenter extends BasePresenter {
|
||||
environment: AuthenticatedEnvironment;
|
||||
queueInput: RetrieveQueueParam;
|
||||
}) {
|
||||
//check the engine is the correct version
|
||||
const engineVersion = await determineEngineVersion({ environment });
|
||||
|
||||
if (engineVersion === "V1") {
|
||||
return {
|
||||
success: false as const,
|
||||
code: "engine-version",
|
||||
};
|
||||
}
|
||||
|
||||
const queue = await getQueue(this._replica, environment, queueInput);
|
||||
if (!queue) {
|
||||
return {
|
||||
|
||||
+2
-3
@@ -14,7 +14,6 @@ import { BranchEnvironmentIconSmall } from "~/assets/icons/EnvironmentIcons";
|
||||
import { BranchesNoBranchableEnvironment, BranchesNoBranches } from "~/components/BlankStatePanels";
|
||||
import { Feedback } from "~/components/Feedback";
|
||||
import { GitMetadata } from "~/components/GitMetadata";
|
||||
import { V4Title } from "~/components/V4Badge";
|
||||
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
|
||||
import { MainCenteredContainer, PageBody, PageContainer } from "~/components/layout/AppLayout";
|
||||
import { Badge } from "~/components/primitives/Badge";
|
||||
@@ -231,7 +230,7 @@ export default function Page() {
|
||||
return (
|
||||
<PageContainer>
|
||||
<NavBar>
|
||||
<PageTitle title={<V4Title>Preview branches</V4Title>} />
|
||||
<PageTitle title="Preview branches" />
|
||||
</NavBar>
|
||||
<PageBody>
|
||||
<MainCenteredContainer className="max-w-md">
|
||||
@@ -245,7 +244,7 @@ export default function Page() {
|
||||
return (
|
||||
<PageContainer>
|
||||
<NavBar>
|
||||
<PageTitle title={<V4Title>Preview branches</V4Title>} />
|
||||
<PageTitle title="Preview branches" />
|
||||
<PageAccessories>
|
||||
<AdminDebugTooltip>
|
||||
<Property.Table>
|
||||
|
||||
+1
-2
@@ -6,7 +6,6 @@ import { useCallback } from "react";
|
||||
import { SearchInput } from "~/components/primitives/SearchInput";
|
||||
import { typedjson, useTypedLoaderData } from "remix-typedjson";
|
||||
import { BranchEnvironmentIconSmall } from "~/assets/icons/EnvironmentIcons";
|
||||
import { V4Title } from "~/components/V4Badge";
|
||||
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
|
||||
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
|
||||
import { Badge } from "~/components/primitives/Badge";
|
||||
@@ -98,7 +97,7 @@ export default function Page() {
|
||||
return (
|
||||
<PageContainer>
|
||||
<NavBar>
|
||||
<PageTitle title={<V4Title>Dev branches</V4Title>} />
|
||||
<PageTitle title="Dev branches" />
|
||||
<PageAccessories>
|
||||
<AdminDebugTooltip>
|
||||
<Property.Table>
|
||||
|
||||
+695
-777
File diff suppressed because it is too large
Load Diff
+1
-4
@@ -166,16 +166,13 @@ export default function Page() {
|
||||
const { data, rootOnlyDefault, filters, canCancelRuns, canReplayRuns } =
|
||||
useTypedLoaderData<typeof loader>();
|
||||
const { isConnected } = useDevPresence();
|
||||
const project = useProject();
|
||||
const environment = useEnvironment();
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavBar>
|
||||
<PageTitle title="Runs" accessory={<RunsHelpTooltip />} />
|
||||
{environment.type === "DEVELOPMENT" && project.engine === "V2" && (
|
||||
<DevDisconnectedBanner isConnected={isConnected} />
|
||||
)}
|
||||
{environment.type === "DEVELOPMENT" && <DevDisconnectedBanner isConnected={isConnected} />}
|
||||
<PageAccessories>
|
||||
<AdminDebugTooltip />
|
||||
<WhenAgentUnavailable>
|
||||
|
||||
+1
-2
@@ -35,7 +35,6 @@ import {
|
||||
WaitpointSearchParamsSchema,
|
||||
WaitpointTokenFilters,
|
||||
} from "~/components/runs/v3/WaitpointTokenFilters";
|
||||
import { V4Title } from "~/components/V4Badge";
|
||||
import { useEnvironment } from "~/hooks/useEnvironment";
|
||||
import { useOrganization } from "~/hooks/useOrganizations";
|
||||
import { useProject } from "~/hooks/useProject";
|
||||
@@ -138,7 +137,7 @@ export default function Page() {
|
||||
return (
|
||||
<PageContainer>
|
||||
<NavBar>
|
||||
<PageTitle title={<V4Title>Waitpoint Tokens</V4Title>} />
|
||||
<PageTitle title="Waitpoint Tokens" />
|
||||
<PageAccessories>
|
||||
<AdminDebugTooltip />
|
||||
<WhenAgentUnavailable>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { type QueueItem, type RetrieveQueueParam, RetrieveQueueType } from "@tri
|
||||
import { z } from "zod";
|
||||
import { QueueRetrievePresenter } from "~/presenters/v3/QueueRetrievePresenter.server";
|
||||
import { createLoaderApiRoute } from "~/services/routeBuilders/apiBuilder.server";
|
||||
import { determineEngineVersion } from "~/v3/engineVersion.server";
|
||||
|
||||
const SearchParamsSchema = z.object({
|
||||
type: RetrieveQueueType.default("id"),
|
||||
@@ -24,6 +25,15 @@ export const loader = createLoaderApiRoute(
|
||||
},
|
||||
},
|
||||
async ({ params, searchParams, authentication }) => {
|
||||
// v3 (engine V1) has no V2 queues to retrieve, so old clients get a clean 400.
|
||||
const engineVersion = await determineEngineVersion({
|
||||
environment: authentication.environment,
|
||||
});
|
||||
|
||||
if (engineVersion === "V1") {
|
||||
return json({ error: "engine-version" }, { status: 400 });
|
||||
}
|
||||
|
||||
const input: RetrieveQueueParam =
|
||||
searchParams.type === "id"
|
||||
? params.queueParam
|
||||
@@ -39,11 +49,7 @@ export const loader = createLoaderApiRoute(
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
if (result.code === "queue-not-found") {
|
||||
return json({ error: result.code }, { status: 404 });
|
||||
}
|
||||
|
||||
return json({ error: result.code }, { status: 400 });
|
||||
return json({ error: result.code }, { status: 404 });
|
||||
}
|
||||
|
||||
const q: QueueItem = result.queue;
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
import { toOffsetLimitQueueListPagination } from "~/presenters/v3/queueListPagination.server";
|
||||
import { logger } from "~/services/logger.server";
|
||||
import { createLoaderApiRoute } from "~/services/routeBuilders/apiBuilder.server";
|
||||
import { determineEngineVersion } from "~/v3/engineVersion.server";
|
||||
import { ServiceValidationError } from "~/v3/services/baseService.server";
|
||||
|
||||
const SearchParamsSchema = z.object({
|
||||
@@ -30,15 +31,20 @@ export const loader = createLoaderApiRoute(
|
||||
const service = new QueueListPresenter(searchParams.perPage);
|
||||
|
||||
try {
|
||||
// v3 (engine V1) has no V2 queues to list, so old clients get a clean 400.
|
||||
const engineVersion = await determineEngineVersion({
|
||||
environment: authentication.environment,
|
||||
});
|
||||
|
||||
if (engineVersion === "V1") {
|
||||
return json({ error: "engine-version" }, { status: 400 });
|
||||
}
|
||||
|
||||
const result = await service.call({
|
||||
environment: authentication.environment,
|
||||
page: searchParams.page ?? 1,
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
return json({ error: result.code }, { status: 400 });
|
||||
}
|
||||
|
||||
const queues: QueueItem[] = result.queues;
|
||||
return json(
|
||||
{
|
||||
|
||||
-9
@@ -51,15 +51,6 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
|
||||
type,
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
return {
|
||||
queues: [],
|
||||
currentPage: 1,
|
||||
hasMore: false,
|
||||
hasFilters: Boolean(query?.trim()) || Boolean(type),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
queues: result.queues.map((queue) => ({
|
||||
id: queue.id,
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ export async function action({ request, params }: ActionFunctionArgs) {
|
||||
type,
|
||||
});
|
||||
return {
|
||||
queues: queues.success ? queues.queues.map((q) => q.name) : [],
|
||||
queues: queues.queues.map((q) => q.name),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user