@@ -6,7 +6,6 @@ import com.coder.gateway.cli.CoderCLIManager
6
6
import com.coder.gateway.cli.ensureCLI
7
7
import com.coder.gateway.models.TokenSource
8
8
import com.coder.gateway.models.WorkspaceAndAgentStatus
9
- import com.coder.gateway.sdk.BaseCoderRestClient
10
9
import com.coder.gateway.sdk.CoderRestClient
11
10
import com.coder.gateway.sdk.ex.AuthenticationResponseException
12
11
import com.coder.gateway.sdk.v2.models.Workspace
@@ -15,12 +14,17 @@ import com.coder.gateway.sdk.v2.models.WorkspaceStatus
15
14
import com.coder.gateway.services.CoderSettingsService
16
15
import com.coder.gateway.util.toURL
17
16
import com.coder.gateway.util.withPath
17
+ import com.coder.gateway.views.steps.CoderWorkspaceStepView
18
+ import com.coder.gateway.views.steps.CoderWorkspacesStepSelection
19
+ import com.intellij.openapi.application.ApplicationManager
18
20
import com.intellij.openapi.components.service
19
21
import com.intellij.openapi.diagnostic.Logger
22
+ import com.intellij.openapi.ui.DialogWrapper
20
23
import com.jetbrains.gateway.api.ConnectionRequestor
21
24
import com.jetbrains.gateway.api.GatewayConnectionHandle
22
25
import com.jetbrains.gateway.api.GatewayConnectionProvider
23
26
import java.net.URL
27
+ import javax.swing.JComponent
24
28
25
29
// In addition to `type`, these are the keys that we support in our Gateway
26
30
// links.
@@ -34,6 +38,18 @@ private const val IDE_DOWNLOAD_LINK = "ide_download_link"
34
38
private const val IDE_PRODUCT_CODE = " ide_product_code"
35
39
private const val IDE_BUILD_NUMBER = " ide_build_number"
36
40
private const val IDE_PATH_ON_HOST = " ide_path_on_host"
41
+ private const val PROJECT_PATH = " project_path"
42
+
43
+ class SelectWorkspaceIDEDialog (private val comp : JComponent ) : DialogWrapper(true ) {
44
+ init {
45
+ init ()
46
+ title = " Select workspace IDE"
47
+ }
48
+
49
+ override fun createCenterPanel (): JComponent ? {
50
+ return comp
51
+ }
52
+ }
37
53
38
54
// CoderGatewayConnectionProvider handles connecting via a Gateway link such as
39
55
// jetbrains-gateway://connect#type=coder.
@@ -93,31 +109,38 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
93
109
cli.login(client.token)
94
110
95
111
indicator.text = " Configuring Coder CLI..."
96
- cli.configSsh(client.agentNames(workspaces))
97
-
98
- // TODO: Ask for these if missing. Maybe we can reuse the second
99
- // step of the wizard? Could also be nice if we automatically used
100
- // the last IDE.
101
- if (parameters[IDE_PRODUCT_CODE ].isNullOrBlank()) {
102
- throw IllegalArgumentException (" Query parameter \" $IDE_PRODUCT_CODE \" is missing" )
103
- }
104
- if (parameters[IDE_BUILD_NUMBER ].isNullOrBlank()) {
105
- throw IllegalArgumentException (" Query parameter \" $IDE_BUILD_NUMBER \" is missing" )
106
- }
107
- if (parameters[IDE_PATH_ON_HOST ].isNullOrBlank() && parameters[IDE_DOWNLOAD_LINK ].isNullOrBlank()) {
108
- throw IllegalArgumentException (" One of \" $IDE_PATH_ON_HOST \" or \" $IDE_DOWNLOAD_LINK \" is required" )
109
- }
110
-
111
- // Check that both the domain and the redirected domain are
112
- // allowlisted. If not, check with the user whether to proceed.
113
- verifyDownloadLink(parameters)
114
-
115
- // TODO: Ask for the project path if missing and validate the path.
116
- val folder = parameters[FOLDER ] ? : throw IllegalArgumentException (" Query parameter \" $FOLDER \" is missing" )
117
-
118
- parameters
119
- .withWorkspaceHostname(CoderCLIManager .getHostName(deploymentURL.toURL(), agent.name))
120
- .withProjectPath(folder)
112
+ cli.configSsh(client.agentNames(workspaces).toSet())
113
+
114
+
115
+ val openDialog = if (parameters[IDE_PRODUCT_CODE ].isNullOrBlank())
116
+ true
117
+ else if (parameters[IDE_BUILD_NUMBER ].isNullOrBlank())
118
+ true
119
+ else if (parameters[IDE_PATH_ON_HOST ].isNullOrBlank() && parameters[IDE_DOWNLOAD_LINK ].isNullOrBlank())
120
+ true
121
+ else if (parameters[FOLDER ].isNullOrBlank())
122
+ true
123
+ else
124
+ false
125
+
126
+ val params = if (openDialog) {
127
+ val view = CoderWorkspaceStepView {}
128
+ ApplicationManager .getApplication().invokeAndWait {
129
+ view.init (
130
+ CoderWorkspacesStepSelection (agent, workspace, cli, client, workspaces)
131
+ )
132
+ val dialog = SelectWorkspaceIDEDialog (view.component)
133
+ dialog.show()
134
+ }
135
+ val p = parameters.toMutableMap()
136
+ listOf (IDE_PRODUCT_CODE , IDE_BUILD_NUMBER , IDE_DOWNLOAD_LINK , IDE_PATH_ON_HOST , PROJECT_PATH ).forEach { prop ->
137
+ view.data()[prop]?.let { value -> p[prop] = value }
138
+ }
139
+ p
140
+ } else
141
+ parameters.withProjectPath(parameters[FOLDER ]!! )
142
+
143
+ params.withWorkspaceHostname(CoderCLIManager .getHostName(deploymentURL.toURL(), " ${workspace.name} .${agent.name} " ))
121
144
.withWebTerminalLink(client.url.withPath(" /@$username /$workspace .name/terminal" ).toString())
122
145
.withConfigDirectory(cli.coderConfigPath.toString())
123
146
.withName(workspaceName)
@@ -129,7 +152,7 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
129
152
* Return an authenticated Coder CLI and the user's name, asking for the
130
153
* token as long as it continues to result in an authentication failure.
131
154
*/
132
- private fun authenticate (deploymentURL : URL , queryToken : String? , lastToken : Pair <String , TokenSource >? = null): Pair <BaseCoderRestClient , String > {
155
+ private fun authenticate (deploymentURL : URL , queryToken : String? , lastToken : Pair <String , TokenSource >? = null): Pair <CoderRestClient , String > {
133
156
// Use the token from the query, unless we already tried that.
134
157
val isRetry = lastToken != null
135
158
val token = if (! queryToken.isNullOrBlank() && ! isRetry)
0 commit comments