@@ -6,6 +6,7 @@ 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
9
10
import com.coder.gateway.sdk.CoderRestClient
10
11
import com.coder.gateway.sdk.ex.AuthenticationResponseException
11
12
import com.coder.gateway.sdk.v2.models.Workspace
@@ -20,11 +21,18 @@ import com.intellij.openapi.application.ApplicationManager
20
21
import com.intellij.openapi.components.service
21
22
import com.intellij.openapi.diagnostic.Logger
22
23
import com.intellij.openapi.ui.DialogWrapper
24
+ import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeScreenUIManager
25
+ import com.intellij.ui.dsl.builder.panel
26
+ import com.intellij.util.ui.JBUI
23
27
import com.jetbrains.gateway.api.ConnectionRequestor
24
28
import com.jetbrains.gateway.api.GatewayConnectionHandle
25
29
import com.jetbrains.gateway.api.GatewayConnectionProvider
26
30
import java.net.URL
31
+ import javax.swing.Action
32
+ import javax.swing.JButton
27
33
import javax.swing.JComponent
34
+ import javax.swing.JPanel
35
+ import javax.swing.border.Border
28
36
29
37
// In addition to `type`, these are the keys that we support in our Gateway
30
38
// links.
@@ -38,16 +46,50 @@ private const val IDE_DOWNLOAD_LINK = "ide_download_link"
38
46
private const val IDE_PRODUCT_CODE = " ide_product_code"
39
47
private const val IDE_BUILD_NUMBER = " ide_build_number"
40
48
private const val IDE_PATH_ON_HOST = " ide_path_on_host"
41
- private const val PROJECT_PATH = " project_path"
42
49
43
- class SelectWorkspaceIDEDialog (private val comp : JComponent ) : DialogWrapper(true ) {
50
+ /* *
51
+ * A dialog wrapper around CoderWorkspaceStepView.
52
+ */
53
+ class CoderWorkspaceStepDialog (
54
+ name : String ,
55
+ private val state : CoderWorkspacesStepSelection ,
56
+ ) : DialogWrapper(true ) {
57
+ private val view = CoderWorkspaceStepView (showTitle = false )
58
+
44
59
init {
45
60
init ()
46
- title = " Select workspace IDE"
61
+ title = CoderGatewayBundle .message(" gateway.connector.view.coder.remoteproject.choose.text" , name)
62
+ }
63
+
64
+ override fun show () {
65
+ view.init (state)
66
+ view.onPrevious = { close(1 ) }
67
+ view.onNext = { close(0 ) }
68
+ super .show()
69
+ view.dispose()
47
70
}
48
71
49
- override fun createCenterPanel (): JComponent ? {
50
- return comp
72
+ fun showAndGetData (): Map <String , String >? {
73
+ if (showAndGet()) {
74
+ return view.data()
75
+ }
76
+ return null
77
+ }
78
+
79
+ override fun createContentPaneBorder (): Border {
80
+ return JBUI .Borders .empty()
81
+ }
82
+
83
+ override fun createCenterPanel (): JComponent {
84
+ return view
85
+ }
86
+
87
+ override fun createSouthPanel (): JComponent {
88
+ // The plugin provides its own buttons.
89
+ // TODO: Is it more idiomatic to handle buttons out here?
90
+ return panel{}.apply {
91
+ border = JBUI .Borders .empty()
92
+ }
51
93
}
52
94
}
53
95
@@ -109,41 +151,34 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
109
151
cli.login(client.token)
110
152
111
153
indicator.text = " Configuring Coder CLI..."
112
- cli.configSsh(client.agentNames(workspaces).toSet())
113
-
154
+ cli.configSsh(client.agentNames(workspaces))
114
155
156
+ val name = " ${workspace.name} .${agent.name} "
115
157
val openDialog = parameters[IDE_PRODUCT_CODE ].isNullOrBlank() ||
116
158
parameters[IDE_BUILD_NUMBER ].isNullOrBlank() ||
117
159
(parameters[IDE_PATH_ON_HOST ].isNullOrBlank() && parameters[IDE_DOWNLOAD_LINK ].isNullOrBlank()) ||
118
160
parameters[FOLDER ].isNullOrBlank()
119
161
120
- val params = if (openDialog) {
121
- val view = CoderWorkspaceStepView {}
162
+ if (openDialog) {
163
+ var data : Map < String , String > ? = null
122
164
ApplicationManager .getApplication().invokeAndWait {
123
- view.init (
124
- CoderWorkspacesStepSelection (agent, workspace, cli, client, workspaces)
125
- )
126
- val dialog = SelectWorkspaceIDEDialog (view.component)
127
- dialog.show()
165
+ val dialog = CoderWorkspaceStepDialog (name,
166
+ CoderWorkspacesStepSelection (agent, workspace, cli, client, workspaces))
167
+ data = dialog.showAndGetData()
128
168
}
129
- val p = parameters.toMutableMap()
130
-
131
-
132
- listOf (IDE_PRODUCT_CODE , IDE_BUILD_NUMBER , PROJECT_PATH , IDE_PATH_ON_HOST , IDE_DOWNLOAD_LINK ).forEach { prop ->
133
- view.data()[prop]?.let { value -> p[prop] = value }
134
- }
135
- p
136
- } else
137
- parameters.withProjectPath(parameters[FOLDER ]!! )
138
-
139
- // Check that both the domain and the redirected domain are
140
- // allowlisted. If not, check with the user whether to proceed.
141
- verifyDownloadLink(parameters)
142
-
143
- params.withWorkspaceHostname(CoderCLIManager .getHostName(deploymentURL.toURL(), " ${workspace.name} .${agent.name} " ))
144
- .withWebTerminalLink(client.url.withPath(" /@$username /$workspace .name/terminal" ).toString())
145
- .withConfigDirectory(cli.coderConfigPath.toString())
146
- .withName(workspaceName)
169
+ data ? : throw Exception (" IDE selection aborted; unable to connect" )
170
+ } else {
171
+ // Check that both the domain and the redirected domain are
172
+ // allowlisted. If not, check with the user whether to proceed.
173
+ verifyDownloadLink(parameters)
174
+
175
+ parameters
176
+ .withWorkspaceHostname(CoderCLIManager .getHostName(deploymentURL.toURL(), name))
177
+ .withProjectPath(parameters[FOLDER ]!! )
178
+ .withWebTerminalLink(client.url.withPath(" /@$username /$workspace .name/terminal" ).toString())
179
+ .withConfigDirectory(cli.coderConfigPath.toString())
180
+ .withName(name)
181
+ }
147
182
}
148
183
return null
149
184
}
@@ -152,7 +187,7 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
152
187
* Return an authenticated Coder CLI and the user's name, asking for the
153
188
* token as long as it continues to result in an authentication failure.
154
189
*/
155
- private fun authenticate (deploymentURL : URL , queryToken : String? , lastToken : Pair <String , TokenSource >? = null): Pair <CoderRestClient , String > {
190
+ private fun authenticate (deploymentURL : URL , queryToken : String? , lastToken : Pair <String , TokenSource >? = null): Pair <BaseCoderRestClient , String > {
156
191
// Use the token from the query, unless we already tried that.
157
192
val isRetry = lastToken != null
158
193
val token = if (! queryToken.isNullOrBlank() && ! isRetry)
0 commit comments