Skip to content

Commit 3354b2d

Browse files
committed
Add support for persisting last Coder session
- remembers last opened Coder URL - resolves #72
1 parent 44a8635 commit 3354b2d

File tree

2 files changed

+42
-13
lines changed

2 files changed

+42
-13
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
## [Unreleased]
66

7+
### Added
8+
9+
- support for remembering last opened Coder session
10+
711
### Changed
812

913
- minimum supported Gateway build is now 222.3739.54

src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ import com.intellij.icons.AllIcons
2828
import com.intellij.ide.ActivityTracker
2929
import com.intellij.ide.BrowserUtil
3030
import com.intellij.ide.IdeBundle
31+
import com.intellij.ide.util.PropertiesComponent
3132
import com.intellij.openapi.Disposable
3233
import com.intellij.openapi.actionSystem.AnActionEvent
33-
import com.intellij.openapi.application.ApplicationManager
3434
import com.intellij.openapi.application.ModalityState
3535
import com.intellij.openapi.application.invokeAndWaitIfNeeded
36+
import com.intellij.openapi.components.service
3637
import com.intellij.openapi.diagnostic.Logger
3738
import com.intellij.openapi.progress.ProgressIndicator
3839
import com.intellij.openapi.progress.ProgressManager
@@ -72,16 +73,23 @@ import java.awt.Dimension
7273
import javax.swing.Icon
7374
import javax.swing.JLabel
7475
import javax.swing.JTable
76+
import javax.swing.JTextField
7577
import javax.swing.ListSelectionModel
7678
import javax.swing.table.DefaultTableCellRenderer
7779
import javax.swing.table.TableCellRenderer
7880

7981

82+
private const val CODER_URL_KEY = "coder-url"
83+
84+
private const val SESSION_TOKEN = "session-token"
85+
8086
class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : CoderWorkspacesWizardStep, Disposable {
8187
private val cs = CoroutineScope(Dispatchers.Main)
8288
private var localWizardModel = CoderWorkspacesWizardModel()
83-
private val coderClient: CoderRestClientService = ApplicationManager.getApplication().getService(CoderRestClientService::class.java)
89+
private val coderClient: CoderRestClientService = service()
90+
private val appPropertiesService: PropertiesComponent = service()
8491

92+
private var tfUrl: JTextField? = null
8593
private var listTableModelOfWorkspaces = ListTableModel<WorkspaceAgentModel>(
8694
WorkspaceIconColumnInfo(""),
8795
WorkspaceNameColumnInfo("Name"),
@@ -148,15 +156,15 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
148156
browserLink(CoderGatewayBundle.message("gateway.connector.view.login.documentation.action"), "https://coder.com/docs/coder-oss/latest/workspaces")
149157
}.bottomGap(BottomGap.MEDIUM)
150158
row(CoderGatewayBundle.message("gateway.connector.view.login.url.label")) {
151-
textField().resizableColumn().horizontalAlign(HorizontalAlign.FILL).gap(RightGap.SMALL).bindText(localWizardModel::coderURL).applyToComponent {
159+
tfUrl = textField().resizableColumn().horizontalAlign(HorizontalAlign.FILL).gap(RightGap.SMALL).bindText(localWizardModel::coderURL).applyToComponent {
152160
addActionListener {
153161
poller?.cancel()
154-
loginAndLoadWorkspace()
162+
askTokenAndOpenSession()
155163
}
156-
}
164+
}.component
157165
button(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.connect.text")) {
158166
poller?.cancel()
159-
loginAndLoadWorkspace()
167+
askTokenAndOpenSession()
160168
}.applyToComponent {
161169
background = WelcomeScreenUIManager.getMainAssociatedComponentBackground()
162170
}
@@ -238,6 +246,17 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
238246
enableNextButtonCallback(false)
239247
if (localWizardModel.coderURL.isNotBlank() && localWizardModel.token.isNotBlank()) {
240248
triggerWorkspacePolling()
249+
} else {
250+
val url = appPropertiesService.getValue(CODER_URL_KEY)
251+
val token = appPropertiesService.getValue(SESSION_TOKEN)
252+
if (!url.isNullOrBlank() && !token.isNullOrBlank()) {
253+
localWizardModel.coderURL = url
254+
localWizardModel.token = token
255+
tfUrl?.text = url
256+
257+
poller?.cancel()
258+
loginAndLoadWorkspace(token)
259+
}
241260
}
242261
updateWorkspaceActions()
243262
}
@@ -272,28 +291,31 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
272291
ActivityTracker.getInstance().inc()
273292
}
274293

275-
private fun loginAndLoadWorkspace() {
294+
private fun askTokenAndOpenSession() {
276295
// force bindings to be filled
277296
component.apply()
278297

279-
BrowserUtil.browse(localWizardModel.coderURL.toURL().withPath("/login?redirect=%2Fcli-auth"))
280298
val pastedToken = askToken()
281-
282299
if (pastedToken.isNullOrBlank()) {
283300
return
284301
}
302+
loginAndLoadWorkspace(pastedToken)
303+
}
304+
305+
private fun loginAndLoadWorkspace(token: String) {
285306
try {
286-
coderClient.initClientSession(localWizardModel.coderURL.toURL(), pastedToken)
307+
coderClient.initClientSession(localWizardModel.coderURL.toURL(), token)
287308
} catch (e: AuthenticationResponseException) {
288309
logger.error("Could not authenticate on ${localWizardModel.coderURL}. Reason $e")
289310
return
290311
}
291-
312+
appPropertiesService.setValue(CODER_URL_KEY, localWizardModel.coderURL)
313+
appPropertiesService.setValue(SESSION_TOKEN, token)
292314
val cliManager = CoderCLIManager(localWizardModel.coderURL.toURL(), coderClient.buildVersion)
293315

294316

295317
localWizardModel.apply {
296-
token = pastedToken
318+
this.token = token
297319
buildVersion = coderClient.buildVersion
298320
localCliPath = cliManager.localCliPath.toAbsolutePath().toString()
299321
}
@@ -327,11 +349,14 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
327349
}
328350
}
329351

330-
ProgressManager.getInstance().run(authTask)
352+
cs.launch {
353+
ProgressManager.getInstance().run(authTask)
354+
}
331355
triggerWorkspacePolling()
332356
}
333357

334358
private fun askToken(): String? {
359+
BrowserUtil.browse(localWizardModel.coderURL.toURL().withPath("/login?redirect=%2Fcli-auth"))
335360
return invokeAndWaitIfNeeded(ModalityState.any()) {
336361
lateinit var sessionTokenTextField: JBTextField
337362

0 commit comments

Comments
 (0)