11import { ArrowPathIcon , ArrowUturnLeftIcon , BookOpenIcon } from "@heroicons/react/20/solid" ;
2- import { type MetaFunction , Outlet , useLocation , useParams } from "@remix-run/react" ;
2+ import { type MetaFunction , Outlet , useLocation , useParams , useNavigate } from "@remix-run/react" ;
33import { type LoaderFunctionArgs } from "@remix-run/server-runtime" ;
44import { typedjson , useTypedLoaderData } from "remix-typedjson" ;
55import { z } from "zod" ;
66import { PromoteIcon } from "~/assets/icons/PromoteIcon" ;
77import { DeploymentsNone , DeploymentsNoneDev } from "~/components/BlankStatePanels" ;
88import { UserAvatar } from "~/components/UserProfilePhoto" ;
9- import { EnvironmentCombo } from "~/components/environments/EnvironmentLabel" ;
109import { MainCenteredContainer , PageBody , PageContainer } from "~/components/layout/AppLayout" ;
1110import { Badge } from "~/components/primitives/Badge" ;
1211import { Button , LinkButton } from "~/components/primitives/Buttons" ;
@@ -53,6 +52,7 @@ import { EnvironmentParamSchema, docsPath, v3DeploymentPath } from "~/utils/path
5352import { createSearchParams } from "~/utils/searchParams" ;
5453import { deploymentIndexingIsRetryable } from "~/v3/deploymentStatus" ;
5554import { compareDeploymentVersions } from "~/v3/utils/deploymentVersions" ;
55+ import { useEffect } from "react" ;
5656
5757export const meta : MetaFunction = ( ) => {
5858 return [
@@ -64,17 +64,37 @@ export const meta: MetaFunction = () => {
6464
6565const SearchParams = z . object ( {
6666 page : z . coerce . number ( ) . optional ( ) ,
67+ version : z . string ( ) . optional ( ) ,
6768} ) ;
6869
6970export const loader = async ( { request, params } : LoaderFunctionArgs ) => {
7071 const userId = await requireUserId ( request ) ;
7172 const { organizationSlug, projectParam, envParam } = EnvironmentParamSchema . parse ( params ) ;
7273
7374 const searchParams = createSearchParams ( request . url , SearchParams ) ;
74- const page = searchParams . success ? searchParams . params . get ( "page" ) ?? 1 : 1 ;
75+
76+ let page = searchParams . success ? Number ( searchParams . params . get ( "page" ) ?? 1 ) : 1 ;
77+ const version = searchParams . success ? searchParams . params . get ( "version" ) ?. toString ( ) : undefined ;
78+
79+ const presenter = new DeploymentListPresenter ( ) ;
80+
81+ // If we have a version, find its page
82+ if ( version ) {
83+ try {
84+ page = await presenter . findPageForVersion ( {
85+ userId,
86+ organizationSlug,
87+ projectSlug : projectParam ,
88+ environmentSlug : envParam ,
89+ version,
90+ } ) ;
91+ } catch ( error ) {
92+ console . error ( "Error finding page for version" , error ) ;
93+ // Carry on, we'll just show the selected page
94+ }
95+ }
7596
7697 try {
77- const presenter = new DeploymentListPresenter ( ) ;
7898 const result = await presenter . call ( {
7999 userId,
80100 organizationSlug,
@@ -83,7 +103,12 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
83103 page,
84104 } ) ;
85105
86- return typedjson ( result ) ;
106+ // If we have a version, find the deployment
107+ const selectedDeployment = version
108+ ? result . deployments . find ( ( d ) => d . version === version )
109+ : undefined ;
110+
111+ return typedjson ( { ...result , selectedDeployment } ) ;
87112 } catch ( error ) {
88113 console . error ( error ) ;
89114 throw new Response ( undefined , {
@@ -97,10 +122,23 @@ export default function Page() {
97122 const organization = useOrganization ( ) ;
98123 const project = useProject ( ) ;
99124 const environment = useEnvironment ( ) ;
100- const { deployments, currentPage, totalPages } = useTypedLoaderData < typeof loader > ( ) ;
125+ const { deployments, currentPage, totalPages, selectedDeployment } =
126+ useTypedLoaderData < typeof loader > ( ) ;
101127 const hasDeployments = totalPages > 0 ;
102128
103129 const { deploymentParam } = useParams ( ) ;
130+ const location = useLocation ( ) ;
131+ const navigate = useNavigate ( ) ;
132+
133+ // If we have a selected deployment from the version param, show it
134+ useEffect ( ( ) => {
135+ if ( selectedDeployment && ! deploymentParam ) {
136+ const searchParams = new URLSearchParams ( location . search ) ;
137+ searchParams . delete ( "version" ) ;
138+ searchParams . set ( "page" , currentPage . toString ( ) ) ;
139+ navigate ( `${ location . pathname } /${ selectedDeployment . shortCode } ?${ searchParams . toString ( ) } ` ) ;
140+ }
141+ } , [ selectedDeployment , deploymentParam , location . search ] ) ;
104142
105143 const currentDeployment = deployments . find ( ( d ) => d . isCurrent ) ;
106144
0 commit comments