1- import { AlertCircle , Check , CheckCircle , Shield , XCircle } from "lucide-react " ;
1+ import type { RouterOutputs } from "@ctrlplane/trpc " ;
22
3- import type { DeploymentVersion , Environment , ReleaseTarget } from "./types" ;
4- import { Badge } from "~/components/ui/badge" ;
3+ import type { Environment } from "./types" ;
54import {
65 Dialog ,
76 DialogContent ,
87 DialogDescription ,
98 DialogHeader ,
109 DialogTitle ,
1110} from "~/components/ui/dialog" ;
12- import {
13- Tooltip ,
14- TooltipContent ,
15- TooltipTrigger ,
16- } from "~/components/ui/tooltip" ;
1711
1812type VersionActionsPanelProps = {
19- version : DeploymentVersion ;
13+ version : NonNullable <
14+ NonNullable < RouterOutputs [ "deployment" ] [ "versions" ] > [ "items" ]
15+ > [ number ] ;
2016 environments : Environment [ ] ;
21- releaseTargets : ReleaseTarget [ ] ;
2217 open : boolean ;
2318 onOpenChange : ( open : boolean ) => void ;
2419} ;
2520
26- type EnvironmentDeploymentStatus = {
27- env : Environment ;
28- onVersion : number ; // Number of release targets currently on this version
29- total : number ; // Total release targets in environment
30- cannotDeployReasons : Array < { reason : string ; count : number } > ; // Reasons why some can't deploy
31- } ;
32-
33- const EnvironmentRow : React . FC < EnvironmentDeploymentStatus > = ( {
34- env,
35- onVersion,
36- total,
37- cannotDeployReasons,
38- } ) => {
39- const isFullyDeployed = onVersion === total && total > 0 ;
40- const isPartiallyDeployed = onVersion > 0 && onVersion < total ;
41- const isNotDeployed = onVersion === 0 ;
42- const hasBlockedResources = cannotDeployReasons . length > 0 ;
43-
44- return (
45- < div className = "rounded border p-2.5" >
46- < div className = "flex items-start justify-between" >
47- < div className = "flex-1" >
48- < div className = "mb-1 flex items-center gap-2" >
49- < span className = "text-sm font-medium" > { env . name } </ span >
50- { isFullyDeployed && (
51- < Badge className = "border-green-500/20 bg-green-500/10 py-0 text-[10px] text-green-600" >
52- < CheckCircle className = "mr-0.5 h-2.5 w-2.5" />
53- Fully Deployed
54- </ Badge >
55- ) }
56- </ div >
57-
58- < div className = "mb-2 flex items-baseline gap-1.5" >
59- < span className = "text-lg font-semibold" >
60- { onVersion }
61- < span className = "text-muted-foreground" > /{ total } </ span >
62- </ span >
63- < span className = "text-xs text-muted-foreground" >
64- resource{ total !== 1 ? "s" : "" } on this version
65- </ span >
66- </ div >
67-
68- { /* Status Messages */ }
69- < div className = "space-y-1" >
70- { isFullyDeployed && (
71- < div className = "flex items-center gap-1.5 text-xs text-green-600" >
72- < Check className = "h-3 w-3" />
73- All resources deployed successfully
74- </ div >
75- ) }
76-
77- { isPartiallyDeployed && ! hasBlockedResources && (
78- < div className = "flex items-center gap-1.5 text-xs text-blue-600" >
79- < AlertCircle className = "h-3 w-3" />
80- Can deploy to { total - onVersion } more resource
81- { total - onVersion !== 1 ? "s" : "" }
82- </ div >
83- ) }
84-
85- { isNotDeployed && ! hasBlockedResources && (
86- < div className = "flex items-center gap-1.5 text-xs text-muted-foreground" >
87- < AlertCircle className = "h-3 w-3" />
88- Not yet deployed to this environment
89- </ div >
90- ) }
91-
92- { hasBlockedResources && (
93- < div className = "space-y-1" >
94- { cannotDeployReasons . map ( ( reason , idx ) => (
95- < Tooltip key = { idx } >
96- < TooltipTrigger asChild >
97- < div className = "flex items-center gap-1.5 text-xs text-amber-600" >
98- < Shield className = "h-3 w-3" />
99- < span >
100- { reason . count } resource{ reason . count !== 1 ? "s" : "" } { " " }
101- blocked: { reason . reason }
102- </ span >
103- </ div >
104- </ TooltipTrigger >
105- < TooltipContent side = "left" className = "max-w-sm" >
106- < div className = "text-[11px]" >
107- { reason . reason } - preventing deployment to{ " " }
108- { reason . count } resource{ reason . count !== 1 ? "s" : "" }
109- </ div >
110- </ TooltipContent >
111- </ Tooltip >
112- ) ) }
113- </ div >
114- ) }
115- </ div >
116- </ div >
117-
118- { /* Status Icon */ }
119- < div className = "ml-2 flex items-center" >
120- { isFullyDeployed ? (
121- < CheckCircle className = "h-5 w-5 text-green-600" />
122- ) : hasBlockedResources && onVersion === 0 ? (
123- < XCircle className = "h-5 w-5 text-amber-600" />
124- ) : (
125- < AlertCircle className = "h-5 w-5 text-blue-600" />
126- ) }
127- </ div >
128- </ div >
129- </ div >
130- ) ;
131- } ;
21+ // type EnvironmentDeploymentStatus = {
22+ // env: Environment;
23+ // onVersion: number; // Number of release targets currently on this version
24+ // total: number; // Total release targets in environment
25+ // cannotDeployReasons: Array<{ reason: string; count: number }>; // Reasons why some can't deploy
26+ // };
27+
28+ // const EnvironmentRow: React.FC<EnvironmentDeploymentStatus> = ({
29+ // env,
30+ // onVersion,
31+ // total,
32+ // cannotDeployReasons,
33+ // }) => {
34+ // const isFullyDeployed = onVersion === total && total > 0;
35+ // const isPartiallyDeployed = onVersion > 0 && onVersion < total;
36+ // const isNotDeployed = onVersion === 0;
37+ // const hasBlockedResources = cannotDeployReasons.length > 0;
38+
39+ // return (
40+ // <div className="rounded border p-2.5">
41+ // <div className="flex items-start justify-between">
42+ // <div className="flex-1">
43+ // <div className="mb-1 flex items-center gap-2">
44+ // <span className="text-sm font-medium">{env.name}</span>
45+ // {isFullyDeployed && (
46+ // <Badge className="border-green-500/20 bg-green-500/10 py-0 text-[10px] text-green-600">
47+ // <CheckCircle className="mr-0.5 h-2.5 w-2.5" />
48+ // Fully Deployed
49+ // </Badge>
50+ // )}
51+ // </div>
52+
53+ // <div className="mb-2 flex items-baseline gap-1.5">
54+ // <span className="text-lg font-semibold">
55+ // {onVersion}
56+ // <span className="text-muted-foreground">/{total}</span>
57+ // </span>
58+ // <span className="text-xs text-muted-foreground">
59+ // resource{total !== 1 ? "s" : ""} on this version
60+ // </span>
61+ // </div>
62+
63+ // {/* Status Messages */}
64+ // <div className="space-y-1">
65+ // {isFullyDeployed && (
66+ // <div className="flex items-center gap-1.5 text-xs text-green-600">
67+ // <Check className="h-3 w-3" />
68+ // All resources deployed successfully
69+ // </div>
70+ // )}
71+
72+ // {isPartiallyDeployed && !hasBlockedResources && (
73+ // <div className="flex items-center gap-1.5 text-xs text-blue-600">
74+ // <AlertCircle className="h-3 w-3" />
75+ // Can deploy to {total - onVersion} more resource
76+ // {total - onVersion !== 1 ? "s" : ""}
77+ // </div>
78+ // )}
79+
80+ // {isNotDeployed && !hasBlockedResources && (
81+ // <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
82+ // <AlertCircle className="h-3 w-3" />
83+ // Not yet deployed to this environment
84+ // </div>
85+ // )}
86+
87+ // {hasBlockedResources && (
88+ // <div className="space-y-1">
89+ // {cannotDeployReasons.map((reason, idx) => (
90+ // <Tooltip key={idx}>
91+ // <TooltipTrigger asChild>
92+ // <div className="flex items-center gap-1.5 text-xs text-amber-600">
93+ // <Shield className="h-3 w-3" />
94+ // <span>
95+ // {reason.count} resource{reason.count !== 1 ? "s" : ""}{" "}
96+ // blocked: {reason.reason}
97+ // </span>
98+ // </div>
99+ // </TooltipTrigger>
100+ // <TooltipContent side="left" className="max-w-sm">
101+ // <div className="text-[11px]">
102+ // {reason.reason} - preventing deployment to{" "}
103+ // {reason.count} resource{reason.count !== 1 ? "s" : ""}
104+ // </div>
105+ // </TooltipContent>
106+ // </Tooltip>
107+ // ))}
108+ // </div>
109+ // )}
110+ // </div>
111+ // </div>
112+
113+ // {/* Status Icon */}
114+ // <div className="ml-2 flex items-center">
115+ // {isFullyDeployed ? (
116+ // <CheckCircle className="h-5 w-5 text-green-600" />
117+ // ) : hasBlockedResources && onVersion === 0 ? (
118+ // <XCircle className="h-5 w-5 text-amber-600" />
119+ // ) : (
120+ // <AlertCircle className="h-5 w-5 text-blue-600" />
121+ // )}
122+ // </div>
123+ // </div>
124+ // </div>
125+ // );
126+ // };
132127
133128export const VersionActionsPanel : React . FC < VersionActionsPanelProps > = ( {
134129 version,
135- environments,
136- releaseTargets,
137130 open,
138131 onOpenChange,
139132} ) => {
140- // Calculate deployment status for each environment
141- const environmentStatuses : EnvironmentDeploymentStatus [ ] = environments . map (
142- ( env ) => {
143- const envReleaseTargets = releaseTargets . filter (
144- ( rt ) => rt . environment . id === env . id ,
145- ) ;
146- const total = envReleaseTargets . length ;
147-
148- // Count how many are currently on this version
149- const onVersion = envReleaseTargets . filter (
150- ( rt ) => rt . version . currentId === version . id ,
151- ) . length ;
152-
153- // Find resources that cannot deploy this version and why
154- const blockReasonsMap = new Map < string , number > ( ) ;
155- envReleaseTargets . forEach ( ( rt ) => {
156- const blockForVersion = rt . version . blockedVersions ?. find (
157- ( bv ) => bv . versionId === version . id ,
158- ) ;
159- if ( blockForVersion ) {
160- const currentCount = blockReasonsMap . get ( blockForVersion . reason ) ?? 0 ;
161- blockReasonsMap . set ( blockForVersion . reason , currentCount + 1 ) ;
162- }
163- } ) ;
164-
165- const cannotDeployReasons = Array . from ( blockReasonsMap . entries ( ) ) . map (
166- ( [ reason , count ] ) => ( {
167- reason,
168- count,
169- } ) ,
170- ) ;
171-
172- return {
173- env,
174- onVersion,
175- total,
176- cannotDeployReasons,
177- } ;
178- } ,
179- ) ;
180-
181- // Calculate summary stats
182- const totalResources = environmentStatuses . reduce (
183- ( sum , e ) => sum + e . total ,
184- 0 ,
185- ) ;
186- const totalOnVersion = environmentStatuses . reduce (
187- ( sum , e ) => sum + e . onVersion ,
188- 0 ,
189- ) ;
133+ // // Calculate deployment status for each environment
134+ // const environmentStatuses: EnvironmentDeploymentStatus[] = environments.map(
135+ // (env) => {
136+ // const envReleaseTargets = releaseTargets.filter(
137+ // (rt) => rt.environment.id === env.id,
138+ // );
139+ // const total = envReleaseTargets.length;
140+
141+ // // Count how many are currently on this version
142+ // const onVersion = envReleaseTargets.filter(
143+ // (rt) => rt.state.currentRelease. version.id === version.id,
144+ // ).length;
145+
146+ // // Find resources that cannot deploy this version and why
147+ // const blockReasonsMap = new Map<string, number>();
148+ // // envReleaseTargets.forEach((rt) => {
149+ // // const blockForVersion = rt.state.desiredRelease .blockedVersions?.find(
150+ // // (bv) => bv.versionId === version.id,
151+ // // );
152+ // // if (blockForVersion) {
153+ // // const currentCount = blockReasonsMap.get(blockForVersion.reason) ?? 0;
154+ // // blockReasonsMap.set(blockForVersion.reason, currentCount + 1);
155+ // / / }
156+ // / / });
157+
158+ // const cannotDeployReasons = Array.from(blockReasonsMap.entries()).map(
159+ // ([reason, count]) => ({
160+ // reason,
161+ // count,
162+ // }),
163+ // );
164+
165+ // return {
166+ // env,
167+ // onVersion,
168+ // total,
169+ // cannotDeployReasons,
170+ // };
171+ // },
172+ // );
173+
174+ // // Calculate summary stats
175+ // const totalResources = environmentStatuses.reduce(
176+ // (sum, e) => sum + e.total,
177+ // 0,
178+ // );
179+ // const totalOnVersion = environmentStatuses.reduce(
180+ // (sum, e) => sum + e.onVersion,
181+ // 0,
182+ // );
190183
191184 return (
192185 < Dialog open = { open } onOpenChange = { onOpenChange } >
@@ -196,17 +189,17 @@ export const VersionActionsPanel: React.FC<VersionActionsPanelProps> = ({
196189 { version . tag }
197190 </ DialogTitle >
198191 < DialogDescription className = "text-[10px]" >
199- Deployed to { totalOnVersion } of { totalResources } total resources
200- across all environments
192+ { /* Deployed to {totalOnVersion} of {totalResources} total resources
193+ across all environments */ }
201194 </ DialogDescription >
202195 </ DialogHeader >
203196
204197 { /* Scrollable Content */ }
205198 < div className = "max-h-[calc(85vh-120px)] overflow-y-auto px-4 pb-4" >
206199 < div className = "space-y-2.5 pt-4" >
207- { environmentStatuses . map ( ( status ) => (
200+ { /* { environmentStatuses.map((status) => (
208201 <EnvironmentRow key={status.env.id} {...status} />
209- ) ) }
202+ ))} */ }
210203 </ div >
211204 </ div >
212205 </ DialogContent >
0 commit comments