@@ -8,42 +8,85 @@ import { Remote } from "./remote"
88import { Storage } from "./storage"
99import { OpenableTreeItem } from "./workspacesProvider"
1010
11- // maybeAskUrl asks the user for the URL if it was not provided and normalizes
12- // the returned URL.
13- export async function maybeAskUrl (
14- providedUrl : string | undefined | null ,
15- lastUsedUrl ?: string ,
16- ) : Promise < string | undefined > {
17- let url =
18- providedUrl ||
19- ( await vscode . window . showInputBox ( {
20- title : "Coder URL" ,
21- prompt : "Enter the URL of your Coder deployment." ,
22- placeHolder : "https://example.coder.com" ,
23- value : lastUsedUrl ,
24- } ) )
25- if ( ! url ) {
26- return undefined
27- }
28- if ( ! url . startsWith ( "http://" ) && ! url . startsWith ( "https://" ) ) {
29- // Default to HTTPS if not provided!
30- // https://github.com/coder/vscode-coder/issues/44
31- url = "https://" + url
32- }
33- while ( url . endsWith ( "/" ) ) {
34- url = url . substring ( 0 , url . length - 1 )
35- }
36- return url
37- }
38-
3911export class Commands {
4012 public constructor (
4113 private readonly vscodeProposed : typeof vscode ,
4214 private readonly storage : Storage ,
4315 ) { }
4416
17+ /**
18+ * Ask the user for the URL, letting them choose from a list of recent URLs or
19+ * CODER_URL or enter a new one. Undefined means the user aborted.
20+ */
21+ private askURL ( selection ?: string ) : Promise < string | undefined > {
22+ const quickPick = vscode . window . createQuickPick ( )
23+ quickPick . value = selection || process . env . CODER_URL || ""
24+ quickPick . placeholder = "https://example.coder.com" ,
25+ quickPick . title = "Enter the URL of your Coder deployment." ,
26+
27+ // Initial items.
28+ quickPick . items = this . storage . withUrlHistory ( process . env . CODER_URL )
29+ . map ( ( url ) => ( {
30+ alwaysShow : true ,
31+ label : url
32+ } ) )
33+
34+ // Quick picks do not allow arbitrary values, so we add the value itself as
35+ // an option in case the user wants to connect to something that is not in
36+ // the list.
37+ quickPick . onDidChangeValue ( ( value ) => {
38+ quickPick . items = this . storage . withUrlHistory ( process . env . CODER_URL , value )
39+ . map ( ( url ) => ( {
40+ alwaysShow : true ,
41+ label : url ,
42+ } ) )
43+ } )
44+
45+ quickPick . show ( )
46+
47+ return new Promise < string | undefined > ( ( resolve ) => {
48+ quickPick . onDidHide ( ( ) => resolve ( undefined ) )
49+ quickPick . onDidChangeSelection ( ( selected ) => resolve ( selected [ 0 ] ?. label ) )
50+ } )
51+ }
52+
53+ /**
54+ * Ask the user for the URL if it was not provided, letting them choose from a
55+ * list of recent URLs or CODER_URL or enter a new one, and normalizes the
56+ * returned URL. Undefined means the user aborted.
57+ */
58+ public async maybeAskUrl (
59+ providedUrl : string | undefined | null ,
60+ lastUsedUrl ?: string ,
61+ ) : Promise < string | undefined > {
62+ let url = providedUrl || await askURL ( lastUsedUrl )
63+ if ( ! url ) { // User aborted.
64+ return undefined
65+ }
66+
67+ // Normalize URL.
68+ if ( ! url . startsWith ( "http://" ) && ! url . startsWith ( "https://" ) ) {
69+ // Default to HTTPS if not provided!
70+ // https://github.com/coder/vscode-coder/issues/44
71+ url = "https://" + url
72+ }
73+ while ( url . endsWith ( "/" ) ) {
74+ url = url . substring ( 0 , url . length - 1 )
75+ }
76+ return url
77+ }
78+
79+ /**
80+ * Log into the provided deployment. If the deployment URL is not specified,
81+ * ask for it first with a menu showing recent URLs and CODER_URL, if set.
82+ */
4583 public async login ( ...args : string [ ] ) : Promise < void > {
46- const url = await maybeAskUrl ( args [ 0 ] )
84+ const url = await this . maybeAskUrl ( args [ 0 ] )
85+ if ( ! url ) {
86+ vscode . window . showWarningMessage ( "Aborting login because no URL was provided." )
87+ return
88+ }
89+
4790 let token : string | undefined = args . length >= 2 ? args [ 1 ] : undefined
4891 if ( ! token ) {
4992 const opened = await vscode . env . openExternal ( vscode . Uri . parse ( `${ url } /cli-auth` ) )
@@ -91,6 +134,7 @@ export class Commands {
91134 } )
92135 }
93136 if ( ! token ) {
137+ vscode . window . showWarningMessage ( "Aborting login because no token was provided." )
94138 return
95139 }
96140
0 commit comments