29
29
query_app = typer .Typer (help = "Manage query programs" , no_args_is_help = True )
30
30
endpoints_app = typer .Typer (help = "Manage endpoints" , no_args_is_help = True )
31
31
jobs_app = typer .Typer (help = "Manage jobs" , no_args_is_help = True )
32
+ teams_app = typer .Typer (help = "Manage teams" , no_args_is_help = True )
32
33
33
34
# Add sub-apps to main app
34
35
app .add_typer (organizations_app , name = "orgs" )
38
39
app .add_typer (query_app , name = "query" )
39
40
app .add_typer (endpoints_app , name = "endpoints" )
40
41
app .add_typer (jobs_app , name = "jobs" )
42
+ app .add_typer (teams_app , name = "teams" )
41
43
42
44
# Configure logging
43
45
logging .basicConfig (level = logging .INFO , format = "%(levelname)s: %(message)s" )
@@ -214,7 +216,7 @@ def show( # noqa: C901
214
216
return
215
217
216
218
# Create a table for better formatting
217
- table = Table (title = "Current State " , show_header = False )
219
+ table = Table (title = "Infactory CLI " , show_header = False )
218
220
table .add_column ("Setting" )
219
221
table .add_column ("Value" )
220
222
@@ -406,7 +408,8 @@ def organizations_select():
406
408
407
409
@projects_app .command (name = "list" )
408
410
def projects_list (
409
- team_id : str | None = typer .Option (None , help = "Team ID to list projects for" )
411
+ team_id : str | None = typer .Option (None , help = "Team ID to list projects for" ),
412
+ json_output : bool = typer .Option (False , "--json" , help = "Output in JSON format" ),
410
413
):
411
414
"""List projects."""
412
415
client = get_client ()
@@ -427,16 +430,31 @@ def projects_list(
427
430
typer .echo ("No projects found" )
428
431
return
429
432
433
+ if json_output :
434
+ project_data = [
435
+ {
436
+ "id" : project .id ,
437
+ "name" : project .name ,
438
+ "description" : project .description ,
439
+ "is_current" : project .id == client .state .project_id ,
440
+ }
441
+ for project in projects
442
+ ]
443
+ print (json .dumps (project_data , indent = 2 ))
444
+ return
445
+
430
446
table = Table ()
431
447
table .add_column ("ID" )
432
448
table .add_column ("Name" )
433
449
table .add_column ("Description" )
450
+ table .add_column ("Current" , justify = "center" )
434
451
435
452
for project in projects :
436
453
description = project .description or ""
437
454
if len (description ) > 47 :
438
455
description = description [:47 ] + "..."
439
- table .add_row (project .id , project .name , description )
456
+ is_current = "✓" if project .id == client .state .project_id else ""
457
+ table .add_row (project .id , project .name , description , is_current )
440
458
441
459
console .print (table )
442
460
@@ -445,36 +463,59 @@ def projects_list(
445
463
raise typer .Exit (1 )
446
464
447
465
448
- @projects_app .command (name = "create" )
449
- def project_create (
450
- name : str ,
451
- team_id : str | None = typer .Option (None , help = "Team ID to create project in" ),
452
- description : str | None = typer .Option (None , help = "Project description" ),
453
- ):
454
- """Create a new project."""
466
+ @projects_app .command (name = "select" )
467
+ def projects_select ():
468
+ """Interactively select a project to set as current."""
455
469
client = get_client ()
456
470
457
471
try :
458
- if not team_id and not client .state .team_id :
472
+ if not client .state .team_id :
459
473
typer .echo (
460
- "No team ID provided. Please specify --team-id or set a current team." ,
461
- err = True ,
474
+ "No team selected. Please select a team first with 'nf teams select'"
462
475
)
463
- raise typer .Exit (1 )
476
+ return
477
+
478
+ projects = client .projects .list (team_id = client .state .team_id )
479
+
480
+ if not projects :
481
+ typer .echo ("No projects found" )
482
+ return
483
+
484
+ # Create a list of choices
485
+ choices = {str (i ): project for i , project in enumerate (projects , 1 )}
486
+
487
+ # Display projects with numbers
488
+ table = Table ()
489
+ table .add_column ("#" )
490
+ table .add_column ("ID" )
491
+ table .add_column ("Name" )
492
+ table .add_column ("Description" )
493
+ table .add_column ("Current" , justify = "center" )
494
+
495
+ for num , project in choices .items ():
496
+ description = project .description or ""
497
+ if len (description ) > 47 :
498
+ description = description [:47 ] + "..."
499
+ is_current = "✓" if project .id == client .state .project_id else ""
500
+ table .add_row (num , project .id , project .name , description , is_current )
501
+
502
+ console .print (table )
464
503
465
- team_id = team_id or client .state .team_id
466
- project = client .projects .create (
467
- name = name , team_id = team_id , description = description
504
+ # Prompt for selection
505
+ choice = Prompt .ask (
506
+ "\n Select project number" ,
507
+ choices = list (choices .keys ()),
508
+ show_choices = False ,
468
509
)
469
510
470
- typer . echo ( "Project created successfully!" )
471
- typer . echo ( f"ID: { project .id } " )
472
- typer .echo (f"Name: { project . name } " )
473
- if project . description :
474
- typer . echo ( f"Description: { project . description } " )
511
+ selected_project = choices [ choice ]
512
+ client . set_current_project ( selected_project .id )
513
+ typer .echo (
514
+ f" \n Current project set to { selected_project . name } (ID: { selected_project . id } )"
515
+ )
475
516
476
517
except Exception as e :
477
- typer .echo (f"Failed to create project: { e } " , err = True )
518
+ typer .echo (f"Failed to select project: { e } " , err = True )
478
519
raise typer .Exit (1 )
479
520
480
521
@@ -859,6 +900,94 @@ def jobs_subscribe(datasource_id: str):
859
900
raise typer .Exit (1 )
860
901
861
902
903
+ @teams_app .command (name = "list" )
904
+ def teams_list (
905
+ json_output : bool = typer .Option (False , "--json" , help = "Output in JSON format" )
906
+ ):
907
+ """List teams the user has access to."""
908
+ client = get_client ()
909
+
910
+ try :
911
+ teams = client .teams .list ()
912
+
913
+ if not teams :
914
+ typer .echo ("No teams found" )
915
+ return
916
+
917
+ if json_output :
918
+ team_data = [
919
+ {
920
+ "id" : team .id ,
921
+ "name" : team .name ,
922
+ "is_current" : team .id == client .state .team_id ,
923
+ }
924
+ for team in teams
925
+ ]
926
+ print (json .dumps (team_data , indent = 2 ))
927
+ return
928
+
929
+ table = Table ()
930
+ table .add_column ("ID" )
931
+ table .add_column ("Name" )
932
+ table .add_column ("Current" , justify = "center" )
933
+
934
+ for team in teams :
935
+ is_current = "✓" if team .id == client .state .team_id else ""
936
+ table .add_row (team .id , team .name , is_current )
937
+
938
+ console .print (table )
939
+
940
+ except Exception as e :
941
+ typer .echo (f"Failed to list teams: { e } " , err = True )
942
+ raise typer .Exit (1 )
943
+
944
+
945
+ @teams_app .command (name = "select" )
946
+ def teams_select ():
947
+ """Interactively select a team to set as current."""
948
+ client = get_client ()
949
+
950
+ try :
951
+ teams = client .teams .list ()
952
+
953
+ if not teams :
954
+ typer .echo ("No teams found" )
955
+ return
956
+
957
+ # Create a list of choices
958
+ choices = {str (i ): team for i , team in enumerate (teams , 1 )}
959
+
960
+ # Display teams with numbers
961
+ table = Table ()
962
+ table .add_column ("#" )
963
+ table .add_column ("ID" )
964
+ table .add_column ("Name" )
965
+ table .add_column ("Current" , justify = "center" )
966
+
967
+ for num , team in choices .items ():
968
+ is_current = "✓" if team .id == client .state .team_id else ""
969
+ table .add_row (num , team .id , team .name , is_current )
970
+
971
+ console .print (table )
972
+
973
+ # Prompt for selection
974
+ choice = Prompt .ask (
975
+ "\n Select team number" ,
976
+ choices = list (choices .keys ()),
977
+ show_choices = False ,
978
+ )
979
+
980
+ selected_team = choices [choice ]
981
+ client .set_current_team (selected_team .id )
982
+ typer .echo (
983
+ f"\n Current team set to { selected_team .name } (ID: { selected_team .id } )"
984
+ )
985
+
986
+ except Exception as e :
987
+ typer .echo (f"Failed to select team: { e } " , err = True )
988
+ raise typer .Exit (1 )
989
+
990
+
862
991
def main ():
863
992
"""Main entry point for the CLI."""
864
993
try :
0 commit comments