@@ -15,6 +15,94 @@ struct ListResponse {
1515 workspaces : Vec < Workspace > ,
1616}
1717
18+ fn load_client ( ) -> ( reqwest:: blocking:: Client , String , String ) {
19+ let profile_config = match config:: load ( "default" ) {
20+ Ok ( c) => c,
21+ Err ( e) => {
22+ eprintln ! ( "{e}" ) ;
23+ std:: process:: exit ( 1 ) ;
24+ }
25+ } ;
26+ let api_key = match & profile_config. api_key {
27+ Some ( key) if key != "PLACEHOLDER" => key. clone ( ) ,
28+ _ => {
29+ eprintln ! ( "error: not authenticated. Run 'hotdata auth login' to log in." ) ;
30+ std:: process:: exit ( 1 ) ;
31+ }
32+ } ;
33+ let api_url = profile_config. api_url . to_string ( ) ;
34+ ( reqwest:: blocking:: Client :: new ( ) , api_key, api_url)
35+ }
36+
37+ fn fetch_all_workspaces ( client : & reqwest:: blocking:: Client , api_key : & str , api_url : & str ) -> Vec < Workspace > {
38+ let url = format ! ( "{api_url}/workspaces" ) ;
39+ let resp = match client
40+ . get ( & url)
41+ . header ( "Authorization" , format ! ( "Bearer {api_key}" ) )
42+ . send ( )
43+ {
44+ Ok ( r) => r,
45+ Err ( e) => {
46+ eprintln ! ( "error connecting to API: {e}" ) ;
47+ std:: process:: exit ( 1 ) ;
48+ }
49+ } ;
50+ if !resp. status ( ) . is_success ( ) {
51+ eprintln ! ( "error: {}" , crate :: util:: api_error( resp. text( ) . unwrap_or_default( ) ) ) ;
52+ std:: process:: exit ( 1 ) ;
53+ }
54+ match resp. json :: < ListResponse > ( ) {
55+ Ok ( b) => b. workspaces ,
56+ Err ( e) => {
57+ eprintln ! ( "error parsing response: {e}" ) ;
58+ std:: process:: exit ( 1 ) ;
59+ }
60+ }
61+ }
62+
63+ pub fn set ( workspace_id : Option < & str > ) {
64+ let ( client, api_key, api_url) = load_client ( ) ;
65+ let workspaces = fetch_all_workspaces ( & client, & api_key, & api_url) ;
66+
67+ let chosen = match workspace_id {
68+ Some ( id) => {
69+ match workspaces. iter ( ) . find ( |w| w. public_id == id) {
70+ Some ( w) => config:: WorkspaceEntry { public_id : w. public_id . clone ( ) , name : w. name . clone ( ) } ,
71+ None => {
72+ eprintln ! ( "error: workspace '{id}' not found or you don't have access to it." ) ;
73+ std:: process:: exit ( 1 ) ;
74+ }
75+ }
76+ }
77+ None => {
78+ if workspaces. is_empty ( ) {
79+ eprintln ! ( "error: no workspaces available." ) ;
80+ std:: process:: exit ( 1 ) ;
81+ }
82+ let options: Vec < String > = workspaces. iter ( )
83+ . map ( |w| format ! ( "{} ({})" , w. name, w. public_id) )
84+ . collect ( ) ;
85+ let selection = match inquire:: Select :: new ( "Select default workspace:" , options. clone ( ) ) . prompt ( ) {
86+ Ok ( s) => s,
87+ Err ( _) => std:: process:: exit ( 1 ) ,
88+ } ;
89+ let idx = options. iter ( ) . position ( |o| o == & selection) . unwrap ( ) ;
90+ let w = & workspaces[ idx] ;
91+ config:: WorkspaceEntry { public_id : w. public_id . clone ( ) , name : w. name . clone ( ) }
92+ }
93+ } ;
94+
95+ if let Err ( e) = config:: save_default_workspace ( "default" , chosen. clone ( ) ) {
96+ eprintln ! ( "error saving config: {e}" ) ;
97+ std:: process:: exit ( 1 ) ;
98+ }
99+
100+ use crossterm:: style:: Stylize ;
101+ println ! ( "{}" , "Default workspace updated" . green( ) ) ;
102+ println ! ( "id: {}" , chosen. public_id) ;
103+ println ! ( "name: {}" , chosen. name) ;
104+ }
105+
18106pub fn list ( format : & str ) {
19107 let profile_config = match config:: load ( "default" ) {
20108 Ok ( c) => c,
@@ -32,6 +120,8 @@ pub fn list(format: &str) {
32120 }
33121 } ;
34122
123+ let default_id = profile_config. workspaces . first ( ) . map ( |w| w. public_id . as_str ( ) ) . unwrap_or ( "" ) . to_string ( ) ;
124+
35125 let url = format ! ( "{}/workspaces" , profile_config. api_url) ;
36126 let client = reqwest:: blocking:: Client :: new ( ) ;
37127
@@ -48,7 +138,7 @@ pub fn list(format: &str) {
48138 } ;
49139
50140 if !resp. status ( ) . is_success ( ) {
51- eprintln ! ( "error: HTTP {}" , resp. status ( ) ) ;
141+ eprintln ! ( "error: {}" , crate :: util :: api_error ( resp. text ( ) . unwrap_or_default ( ) ) ) ;
52142 std:: process:: exit ( 1 ) ;
53143 }
54144
@@ -69,9 +159,10 @@ pub fn list(format: &str) {
69159 }
70160 "table" => {
71161 let mut table = crate :: util:: make_table ( ) ;
72- table. set_header ( [ "PUBLIC_ID " , "NAME " , "ACTIVE" , "FAVORITE ", "PROVISION_STATUS" ] ) ;
162+ table. set_header ( [ "DEFAULT " , "PUBLIC_ID " , "NAME " , "PROVISION_STATUS" ] ) ;
73163 for w in & body. workspaces {
74- table. add_row ( [ & w. public_id , & w. name , & w. active . to_string ( ) , & w. favorite . to_string ( ) , & w. provision_status ] ) ;
164+ let marker = if w. public_id == default_id { "*" } else { "" } ;
165+ table. add_row ( [ marker, & w. public_id , & w. name , & w. provision_status ] ) ;
75166 }
76167 println ! ( "{table}" ) ;
77168 }
0 commit comments