@@ -1102,31 +1102,39 @@ export const DevboxCreatePage = ({
11021102 return `Custom (${ egress . allowed_hostnames ?. length || 0 } )` ;
11031103 } ;
11041104
1105- const networkPolicyColumns : Column < NetworkPolicy > [ ] = [
1106- createTextColumn < NetworkPolicy > ( "id" , "ID" , ( policy ) => policy . id , {
1107- width : 25 ,
1108- color : colors . idColor ,
1109- } ) ,
1110- createTextColumn < NetworkPolicy > (
1111- "name" ,
1112- "Name" ,
1113- ( policy ) => policy . name || "" ,
1114- { width : 25 } ,
1115- ) ,
1116- createTextColumn < NetworkPolicy > (
1117- "egress" ,
1118- "Egress" ,
1119- ( policy ) => getEgressLabel ( policy . egress ) ,
1120- { width : 15 } ,
1121- ) ,
1122- createTextColumn < NetworkPolicy > (
1123- "created" ,
1124- "Created" ,
1125- ( policy ) =>
1126- policy . create_time_ms ? formatTimeAgo ( policy . create_time_ms ) : "" ,
1127- { width : 18 , color : colors . textDim } ,
1128- ) ,
1129- ] ;
1105+ const buildNetworkPolicyColumns = ( tw : number ) : Column < NetworkPolicy > [ ] => {
1106+ const fixedWidth = 6 ;
1107+ const idWidth = 25 ;
1108+ const egressWidth = 15 ;
1109+ const timeWidth = 18 ;
1110+ const baseWidth = fixedWidth + idWidth + egressWidth + timeWidth ;
1111+ const nameWidth = Math . min ( 80 , Math . max ( 15 , tw - baseWidth ) ) ;
1112+ return [
1113+ createTextColumn < NetworkPolicy > ( "id" , "ID" , ( policy ) => policy . id , {
1114+ width : idWidth + 1 ,
1115+ color : colors . idColor ,
1116+ } ) ,
1117+ createTextColumn < NetworkPolicy > (
1118+ "name" ,
1119+ "Name" ,
1120+ ( policy ) => policy . name || "" ,
1121+ { width : nameWidth } ,
1122+ ) ,
1123+ createTextColumn < NetworkPolicy > (
1124+ "egress" ,
1125+ "Egress" ,
1126+ ( policy ) => getEgressLabel ( policy . egress ) ,
1127+ { width : egressWidth } ,
1128+ ) ,
1129+ createTextColumn < NetworkPolicy > (
1130+ "created" ,
1131+ "Created" ,
1132+ ( policy ) =>
1133+ policy . create_time_ms ? formatTimeAgo ( policy . create_time_ms ) : "" ,
1134+ { width : timeWidth , color : colors . textDim } ,
1135+ ) ,
1136+ ] ;
1137+ } ;
11301138
11311139 return (
11321140 < ResourcePicker < NetworkPolicy >
@@ -1146,7 +1154,7 @@ export const DevboxCreatePage = ({
11461154 } ,
11471155 getItemId : ( policy ) => policy . id ,
11481156 getItemLabel : ( policy ) => policy . name || policy . id ,
1149- columns : networkPolicyColumns ,
1157+ columns : buildNetworkPolicyColumns ,
11501158 mode : "single" ,
11511159 emptyMessage : "No network policies found" ,
11521160 searchPlaceholder : "Search network policies..." ,
@@ -1167,31 +1175,45 @@ export const DevboxCreatePage = ({
11671175
11681176 // Gateway config picker screen
11691177 if ( showGatewayPicker ) {
1170- const gatewayColumns : Column < GatewayConfig > [ ] = [
1171- createTextColumn < GatewayConfig > ( "id" , "ID" , ( config ) => config . id , {
1172- width : 25 ,
1173- color : colors . idColor ,
1174- } ) ,
1175- createTextColumn < GatewayConfig > (
1176- "name" ,
1177- "Name" ,
1178- ( config ) => config . name || "" ,
1179- { width : 25 } ,
1180- ) ,
1181- createTextColumn < GatewayConfig > (
1182- "endpoint" ,
1183- "Endpoint" ,
1184- ( config ) => config . endpoint || "" ,
1185- { width : 30 , color : colors . textDim } ,
1186- ) ,
1187- createTextColumn < GatewayConfig > (
1188- "created" ,
1189- "Created" ,
1190- ( config ) =>
1191- config . create_time_ms ? formatTimeAgo ( config . create_time_ms ) : "" ,
1192- { width : 18 , color : colors . textDim } ,
1193- ) ,
1194- ] ;
1178+ const buildGatewayColumns = ( tw : number ) : Column < GatewayConfig > [ ] => {
1179+ const fixedWidth = 6 ;
1180+ const idWidth = 25 ;
1181+ const timeWidth = 20 ;
1182+ const showEndpoint = tw >= 100 ;
1183+ const endpointWidth = Math . max ( 20 , tw >= 140 ? 40 : 25 ) ;
1184+ const baseWidth = fixedWidth + idWidth + timeWidth ;
1185+ const optionalWidth = showEndpoint ? endpointWidth : 0 ;
1186+ const nameWidth = Math . min ( 80 , Math . max ( 15 , tw - baseWidth - optionalWidth ) ) ;
1187+ return [
1188+ createTextColumn < GatewayConfig > ( "id" , "ID" , ( config ) => config . id , {
1189+ width : idWidth + 1 ,
1190+ color : colors . idColor ,
1191+ } ) ,
1192+ createTextColumn < GatewayConfig > (
1193+ "name" ,
1194+ "Name" ,
1195+ ( config ) => config . name || "" ,
1196+ { width : nameWidth } ,
1197+ ) ,
1198+ ...( showEndpoint
1199+ ? [
1200+ createTextColumn < GatewayConfig > (
1201+ "endpoint" ,
1202+ "Endpoint" ,
1203+ ( config ) => config . endpoint || "" ,
1204+ { width : endpointWidth , color : colors . textDim } ,
1205+ ) ,
1206+ ]
1207+ : [ ] ) ,
1208+ createTextColumn < GatewayConfig > (
1209+ "created" ,
1210+ "Created" ,
1211+ ( config ) =>
1212+ config . create_time_ms ? formatTimeAgo ( config . create_time_ms ) : "" ,
1213+ { width : timeWidth , color : colors . textDim } ,
1214+ ) ,
1215+ ] ;
1216+ } ;
11951217
11961218 return (
11971219 < ResourcePicker < GatewayConfig >
@@ -1212,7 +1234,7 @@ export const DevboxCreatePage = ({
12121234 } ,
12131235 getItemId : ( config ) => config . id ,
12141236 getItemLabel : ( config ) => config . name || config . id ,
1215- columns : gatewayColumns ,
1237+ columns : buildGatewayColumns ,
12161238 mode : "single" ,
12171239 emptyMessage : "No gateway configs found" ,
12181240 searchPlaceholder : "Search gateway configs..." ,
@@ -1259,25 +1281,32 @@ export const DevboxCreatePage = ({
12591281
12601282 // Secret picker screen (for gateway)
12611283 if ( showSecretPicker ) {
1262- const secretColumns : Column < SecretListItem > [ ] = [
1263- createTextColumn < SecretListItem > ( "id" , "ID" , ( secret ) => secret . id , {
1264- width : 25 ,
1265- color : colors . idColor ,
1266- } ) ,
1267- createTextColumn < SecretListItem > (
1268- "name" ,
1269- "Name" ,
1270- ( secret ) => secret . name || "" ,
1271- { width : 30 } ,
1272- ) ,
1273- createTextColumn < SecretListItem > (
1274- "created" ,
1275- "Created" ,
1276- ( secret ) =>
1277- secret . create_time_ms ? formatTimeAgo ( secret . create_time_ms ) : "" ,
1278- { width : 18 , color : colors . textDim } ,
1279- ) ,
1280- ] ;
1284+ const buildSecretColumns = ( tw : number ) : Column < SecretListItem > [ ] => {
1285+ const fixedWidth = 6 ;
1286+ const idWidth = 30 ;
1287+ const timeWidth = 20 ;
1288+ const baseWidth = fixedWidth + idWidth + timeWidth ;
1289+ const nameWidth = Math . min ( 80 , Math . max ( 15 , tw - baseWidth ) ) ;
1290+ return [
1291+ createTextColumn < SecretListItem > ( "id" , "ID" , ( secret ) => secret . id , {
1292+ width : idWidth + 1 ,
1293+ color : colors . idColor ,
1294+ } ) ,
1295+ createTextColumn < SecretListItem > (
1296+ "name" ,
1297+ "Name" ,
1298+ ( secret ) => secret . name || "" ,
1299+ { width : nameWidth } ,
1300+ ) ,
1301+ createTextColumn < SecretListItem > (
1302+ "created" ,
1303+ "Created" ,
1304+ ( secret ) =>
1305+ secret . create_time_ms ? formatTimeAgo ( secret . create_time_ms ) : "" ,
1306+ { width : timeWidth , color : colors . textDim } ,
1307+ ) ,
1308+ ] ;
1309+ } ;
12811310
12821311 return (
12831312 < ResourcePicker < SecretListItem >
@@ -1286,25 +1315,38 @@ export const DevboxCreatePage = ({
12861315 title : "Select Secret for Gateway" ,
12871316 fetchPage : async ( params ) => {
12881317 const client = getClient ( ) ;
1289- // Secrets API doesn't support cursor pagination, just limit
1318+ // Secrets API doesn't support cursor pagination, so we fetch all
1319+ // and do client-side pagination by slicing to the requested page
12901320 const page = await client . secrets . list ( {
1291- limit : params . limit ,
1321+ limit : 1000 ,
12921322 } ) ;
1323+ const allSecrets = ( page . secrets || [ ] ) . map (
1324+ ( s : { id : string ; name : string ; create_time_ms ?: number } ) => ( {
1325+ id : s . id ,
1326+ name : s . name ,
1327+ create_time_ms : s . create_time_ms ,
1328+ } ) ,
1329+ ) ;
1330+ // Client-side cursor pagination
1331+ let startIdx = 0 ;
1332+ if ( params . startingAt ) {
1333+ const cursorIdx = allSecrets . findIndex (
1334+ ( s ) => s . id === params . startingAt ,
1335+ ) ;
1336+ if ( cursorIdx >= 0 ) {
1337+ startIdx = cursorIdx + 1 ;
1338+ }
1339+ }
1340+ const sliced = allSecrets . slice ( startIdx , startIdx + params . limit ) ;
12931341 return {
1294- items : ( page . secrets || [ ] ) . map (
1295- ( s : { id : string ; name : string ; create_time_ms ?: number } ) => ( {
1296- id : s . id ,
1297- name : s . name ,
1298- create_time_ms : s . create_time_ms ,
1299- } ) ,
1300- ) ,
1301- hasMore : false , // Secrets API doesn't support pagination
1302- totalCount : page . total_count || 0 ,
1342+ items : sliced ,
1343+ hasMore : startIdx + params . limit < allSecrets . length ,
1344+ totalCount : allSecrets . length ,
13031345 } ;
13041346 } ,
13051347 getItemId : ( secret ) => secret . id ,
13061348 getItemLabel : ( secret ) => secret . name || secret . id ,
1307- columns : secretColumns ,
1349+ columns : buildSecretColumns ,
13081350 mode : "single" ,
13091351 emptyMessage : "No secrets found" ,
13101352 searchPlaceholder : "Search secrets..." ,
0 commit comments