Skip to content

Commit cb4f62b

Browse files
committed
chore(webapp): retain v3 deprecation panel with updated wording
Restore the V3DeprecationPanel in the side menu for old v3 projects and reword it: "v3 is now deprecated" plus a note that no runs are executing and a link to the v4 upgrade guide. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 42d6b54 commit cb4f62b

2 files changed

Lines changed: 112 additions & 4 deletions

File tree

.server-changes/remove-obsolete-v4-version-copy.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ area: webapp
33
type: improvement
44
---
55

6-
Out-of-date upgrade prompts no longer appear in the dashboard: the "V4" badges, the notices saying preview branches and the queues table need V4, and the v3 deprecation warning in the side menu have all been removed.
6+
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.

apps/webapp/app/components/navigation/SideMenu.tsx

Lines changed: 111 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { ChevronRightIcon } from "@heroicons/react/24/outline";
1+
import {
2+
ArrowTopRightOnSquareIcon,
3+
ChevronRightIcon,
4+
ExclamationTriangleIcon,
5+
} from "@heroicons/react/24/outline";
26
import { EllipsisHorizontalIcon } from "@heroicons/react/20/solid";
37
import {
48
Form,
@@ -92,6 +96,7 @@ import {
9296
adminPath,
9397
branchesPath,
9498
concurrencyPath,
99+
docsPath,
95100
limitsPath,
96101
logoutPath,
97102
newOrganizationPath,
@@ -130,9 +135,10 @@ import {
130135
import { FreePlanUsage } from "../billing/FreePlanUsage";
131136
import { ConnectionIcon, DevPresencePanel, useDevPresence } from "../DevPresence";
132137
import { AlphaBadge, NewBadge } from "../FeatureBadges";
133-
import { Button, ButtonContent } from "../primitives/Buttons";
138+
import { Button, ButtonContent, LinkButton } from "../primitives/Buttons";
134139
import { Dialog, DialogTrigger } from "../primitives/Dialog";
135140
import { type RenderIcon } from "../primitives/Icon";
141+
import { Paragraph } from "../primitives/Paragraph";
136142
import { Badge } from "../primitives/Badge";
137143
import {
138144
Popover,
@@ -320,7 +326,7 @@ type SideMenuUser = Pick<
320326
};
321327
export type SideMenuProject = Pick<
322328
MatchedProject,
323-
"id" | "name" | "slug" | "version" | "environments"
329+
"id" | "name" | "slug" | "version" | "environments" | "engine" | "createdAt"
324330
>;
325331
export type SideMenuEnvironment = MatchedEnvironment;
326332

@@ -396,6 +402,7 @@ export function SideMenu({
396402
const { isManagedCloud } = useFeatures();
397403
const featureFlags = useFeatureFlags();
398404
const incidentStatus = useIncidentStatus();
405+
const isV3Project = project.engine === "V1";
399406
const favorites = useFavorites();
400407
const [isCustomizeOpen, setCustomizeOpen] = useState(false);
401408
// Lives here (not in the dialog): the dialog unmounts on close, which would abort a fetcher it
@@ -1247,6 +1254,13 @@ export function SideMenu({
12471254
hasIncident={incidentStatus.hasIncident}
12481255
isManagedCloud={incidentStatus.isManagedCloud}
12491256
/>
1257+
<V3DeprecationPanel
1258+
isCollapsed={isCollapsed}
1259+
isV3={isV3Project}
1260+
projectCreatedAt={project.createdAt}
1261+
hasIncident={incidentStatus.hasIncident}
1262+
isManagedCloud={incidentStatus.isManagedCloud}
1263+
/>
12501264
<motion.div
12511265
layout
12521266
transition={{ duration: 0.2, ease: "easeInOut" }}
@@ -1540,6 +1554,100 @@ function SectionHeaderMenu({ onCustomize }: { onCustomize: () => void }) {
15401554
);
15411555
}
15421556

1557+
function V3DeprecationPanel({
1558+
isCollapsed,
1559+
isV3,
1560+
projectCreatedAt,
1561+
hasIncident,
1562+
isManagedCloud,
1563+
}: {
1564+
isCollapsed: boolean;
1565+
isV3: boolean;
1566+
projectCreatedAt: Date;
1567+
hasIncident: boolean;
1568+
isManagedCloud: boolean;
1569+
}) {
1570+
// Only show for projects created before v4 was released
1571+
const V4_RELEASE_DATE = new Date("2025-09-01");
1572+
const isLikelyV3 = isV3 && new Date(projectCreatedAt) < V4_RELEASE_DATE;
1573+
1574+
if (!isManagedCloud || !isLikelyV3 || hasIncident) {
1575+
return null;
1576+
}
1577+
1578+
return (
1579+
<Popover>
1580+
<div className="p-1">
1581+
<motion.div
1582+
initial={false}
1583+
animate={{
1584+
height: isCollapsed ? 0 : "auto",
1585+
opacity: isCollapsed ? 0 : 1,
1586+
}}
1587+
transition={{ duration: 0.15 }}
1588+
className="overflow-hidden"
1589+
>
1590+
<V3DeprecationContent />
1591+
</motion.div>
1592+
1593+
<motion.div
1594+
initial={false}
1595+
animate={{
1596+
height: isCollapsed ? "auto" : 0,
1597+
opacity: isCollapsed ? 1 : 0,
1598+
}}
1599+
transition={{ duration: 0.15 }}
1600+
className="overflow-hidden"
1601+
>
1602+
<SimpleTooltip
1603+
button={
1604+
<PopoverTrigger className="flex h-8! w-full items-center justify-center rounded border border-amber-500/30 bg-amber-500/15 transition-colors hover:border-amber-500/50 hover:bg-amber-500/25">
1605+
<ExclamationTriangleIcon className="size-5 text-amber-400" />
1606+
</PopoverTrigger>
1607+
}
1608+
content="v3 is now deprecated"
1609+
side="right"
1610+
sideOffset={8}
1611+
disableHoverableContent
1612+
asChild
1613+
/>
1614+
</motion.div>
1615+
</div>
1616+
<PopoverContent side="right" sideOffset={8} align="start" className="w-52 min-w-0! p-0">
1617+
<V3DeprecationContent />
1618+
</PopoverContent>
1619+
</Popover>
1620+
);
1621+
}
1622+
1623+
function V3DeprecationContent() {
1624+
return (
1625+
<div className="flex flex-col gap-2 rounded border border-amber-500/30 bg-amber-500/10 p-2 pt-1.5">
1626+
<div className="flex items-center gap-1 border-b border-amber-500/30 pb-1">
1627+
<ExclamationTriangleIcon className="size-4 text-amber-400" />
1628+
<Paragraph variant="small/bright" className="text-amber-300">
1629+
v3 is now deprecated
1630+
</Paragraph>
1631+
</div>
1632+
<Paragraph variant="extra-small/bright" className="text-amber-300">
1633+
This is a v3 project which is now deprecated so no runs are executing. Upgrade to v4 to
1634+
resume executing runs in this project.
1635+
</Paragraph>
1636+
<LinkButton
1637+
variant="secondary/small"
1638+
to={docsPath("/upgrade-to-v4")}
1639+
target="_blank"
1640+
fullWidth
1641+
TrailingIcon={ArrowTopRightOnSquareIcon}
1642+
trailingIconClassName="text-amber-300"
1643+
className="border-amber-500/30 bg-amber-500/15 hover:border-amber-500/50! hover:bg-amber-500/25!"
1644+
>
1645+
<span className="text-amber-300">Upgrade to v4</span>
1646+
</LinkButton>
1647+
</div>
1648+
);
1649+
}
1650+
15431651
function OrgSelector({
15441652
organization,
15451653
organizations,

0 commit comments

Comments
 (0)