@@ -4,12 +4,17 @@ import {
44 addProjectRemoteSourceProvider ,
55 buildAddProjectRemoteSourceReadiness ,
66 buildProjectCreateCommand ,
7+ canCreateProjectInEnvironment ,
78 findExistingAddProject ,
89 getAddProjectInitialQuery ,
910 resolveAddProjectPath ,
1011 sortAddProjectProviderSources ,
1112 type AddProjectRemoteSource ,
1213} from "@t3tools/client-runtime/operations/projects" ;
14+ import {
15+ connectionStatusText ,
16+ type EnvironmentConnectionPhase ,
17+ } from "@t3tools/client-runtime/connection" ;
1318import {
1419 canPreloadBrowsePath ,
1520 createBrowseNavigationCoordinator ,
@@ -46,6 +51,7 @@ import { uuidv4 } from "../../lib/uuid";
4651import { useAtomCommand } from "../../state/use-atom-command" ;
4752import { useAtomQueryRunner } from "../../state/use-atom-query-runner" ;
4853import {
54+ useRemoteConnectionStatus ,
4955 useRemoteEnvironmentRuntime ,
5056 useSavedRemoteConnections ,
5157} from "../../state/use-remote-environment-registry" ;
@@ -55,6 +61,9 @@ interface EnvironmentOption {
5561 readonly label : string ;
5662 readonly platform : string ;
5763 readonly baseDirectory : string | null ;
64+ readonly connectionState : EnvironmentConnectionPhase ;
65+ readonly connectionError : string | null ;
66+ readonly connectionErrorTraceId : string | null ;
5867}
5968
6069const environmentOptionOrder = Order . mapInput (
@@ -286,19 +295,27 @@ function useBrowsePathInput(environment: EnvironmentOption | null) {
286295function useEnvironmentOptions ( ) : ReadonlyArray < EnvironmentOption > {
287296 const serverConfigByEnvironmentId = useServerConfigs ( ) ;
288297 const { savedConnectionsById } = useSavedRemoteConnections ( ) ;
298+ const { connectedEnvironments } = useRemoteConnectionStatus ( ) ;
289299
290300 return useMemo < ReadonlyArray < EnvironmentOption > > ( ( ) => {
301+ const runtimeByEnvironmentId = new Map (
302+ connectedEnvironments . map ( ( environment ) => [ environment . environmentId , environment ] as const ) ,
303+ ) ;
291304 const options = Object . values ( savedConnectionsById ) . map ( ( connection ) => {
292305 const config = serverConfigByEnvironmentId . get ( connection . environmentId ) ;
306+ const runtime = runtimeByEnvironmentId . get ( connection . environmentId ) ;
293307 return {
294308 environmentId : connection . environmentId ,
295309 label : connection . environmentLabel ,
296310 platform : platformFromOs ( config ?. environment . platform . os ?? null ) ,
297311 baseDirectory : config ?. settings . addProjectBaseDirectory ?? null ,
312+ connectionState : runtime ?. connectionState ?? "available" ,
313+ connectionError : runtime ?. connectionError ?? null ,
314+ connectionErrorTraceId : runtime ?. connectionErrorTraceId ?? null ,
298315 } ;
299316 } ) ;
300317 return Arr . sort ( options , environmentOptionOrder ) ;
301- } , [ savedConnectionsById , serverConfigByEnvironmentId ] ) ;
318+ } , [ connectedEnvironments , savedConnectionsById , serverConfigByEnvironmentId ] ) ;
302319}
303320
304321function useSelectedEnvironment ( ) : {
@@ -309,8 +326,14 @@ function useSelectedEnvironment(): {
309326 const [ selectedEnvironmentId , setSelectedEnvironmentId ] = useState < EnvironmentId | null > ( null ) ;
310327 const environmentOptions = useEnvironmentOptions ( ) ;
311328 const selectedEnvironment =
312- environmentOptions . find ( ( environment ) => environment . environmentId === selectedEnvironmentId ) ??
313- environmentOptions [ 0 ] ??
329+ environmentOptions . find (
330+ ( environment ) =>
331+ environment . environmentId === selectedEnvironmentId &&
332+ canCreateProjectInEnvironment ( environment . connectionState ) ,
333+ ) ??
334+ environmentOptions . find ( ( environment ) =>
335+ canCreateProjectInEnvironment ( environment . connectionState ) ,
336+ ) ??
314337 null ;
315338
316339 return {
@@ -325,9 +348,9 @@ function EmptyEnvironmentState() {
325348
326349 return (
327350 < View className = "items-center gap-3 rounded-2xl bg-card px-5 py-8" >
328- < Text className = "text-center text-lg font-t3-bold" > No environments connected </ Text >
351+ < Text className = "text-center text-lg font-t3-bold" > Environment unavailable </ Text >
329352 < Text className = "text-center text-sm leading-normal text-foreground-muted" >
330- Add an environment before adding a project.
353+ Start or reconnect an environment before adding a project.
331354 </ Text >
332355 < Pressable
333356 onPress = { ( ) => navigation . dispatch ( StackActions . replace ( "ConnectionsNew" ) ) }
@@ -407,17 +430,25 @@ export function AddProjectSourceScreen() {
407430
408431 return (
409432 < AddProjectShell >
410- { environmentOptions . length === 0 ? < EmptyEnvironmentState /> : null }
433+ { selectedEnvironment === null ? < EmptyEnvironmentState /> : null }
411434
412435 { environmentOptions . length > 1 ? (
413436 < >
414- < SectionTitle > Connected environments </ SectionTitle >
437+ < SectionTitle > Environments </ SectionTitle >
415438 < ListSection >
416439 { environmentOptions . map ( ( environment , index ) => (
417440 < ListRow
418441 key = { environment . environmentId }
419442 title = { environment . label }
420- subtitle = { environment . environmentId }
443+ subtitle = {
444+ canCreateProjectInEnvironment ( environment . connectionState )
445+ ? environment . environmentId
446+ : connectionStatusText ( {
447+ phase : environment . connectionState ,
448+ error : environment . connectionError ,
449+ traceId : environment . connectionErrorTraceId ,
450+ } )
451+ }
421452 icon = {
422453 < SymbolView
423454 name = "server.rack"
@@ -427,6 +458,7 @@ export function AddProjectSourceScreen() {
427458 />
428459 }
429460 selected = { environment . environmentId === selectedEnvironment ?. environmentId }
461+ disabled = { ! canCreateProjectInEnvironment ( environment . connectionState ) }
430462 isFirst = { index === 0 }
431463 right = {
432464 environment . environmentId === selectedEnvironment ?. environmentId ? (
@@ -500,7 +532,7 @@ function useCreateProject(environment: EnvironmentOption | null) {
500532
501533 return useCallback (
502534 async ( workspaceRoot : string ) => {
503- if ( ! environment ) return ;
535+ if ( ! environment || ! canCreateProjectInEnvironment ( environment . connectionState ) ) return ;
504536
505537 const existing = findExistingAddProject ( {
506538 projects,
@@ -552,8 +584,14 @@ function useEnvironmentFromParam(
552584 const environmentOptions = useEnvironmentOptions ( ) ;
553585 const environmentId = stringParam ( environmentIdParam ) as EnvironmentId | null ;
554586 return (
555- environmentOptions . find ( ( environment ) => environment . environmentId === environmentId ) ??
556- environmentOptions [ 0 ] ??
587+ environmentOptions . find (
588+ ( environment ) =>
589+ environment . environmentId === environmentId &&
590+ canCreateProjectInEnvironment ( environment . connectionState ) ,
591+ ) ??
592+ environmentOptions . find ( ( environment ) =>
593+ canCreateProjectInEnvironment ( environment . connectionState ) ,
594+ ) ??
557595 null
558596 ) ;
559597}
0 commit comments