Skip to content

Commit 25e6c44

Browse files
committed
fix: mark the deployment as busy
During URI handling we can wait for workspaces to start up. The existing implementation had no visual feedback that we are waiting/doing anything. With this PR the header bar shows a nice work in progress visual. Additionally, the deployment URL was not properly refreshed when switching between different urls via URI handling. This is also fixed by forcing TBX to render a blank page for a very short period of time and then going back to the main page.
1 parent e53595b commit 25e6c44

File tree

6 files changed

+48
-13
lines changed

6 files changed

+48
-13
lines changed

src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import com.coder.toolbox.util.DialogUi
99
import com.coder.toolbox.util.withPath
1010
import com.coder.toolbox.views.Action
1111
import com.coder.toolbox.views.AuthWizardPage
12-
import com.coder.toolbox.views.CoderPage
1312
import com.coder.toolbox.views.CoderSettingsPage
1413
import com.coder.toolbox.views.NewEnvironmentPage
1514
import com.coder.toolbox.views.state.AuthWizardState
@@ -269,12 +268,25 @@ class CoderRemoteProvider(
269268
* Handle incoming links (like from the dashboard).
270269
*/
271270
override suspend fun handleUri(uri: URI) {
272-
linkHandler.handle(uri, shouldDoAutoLogin()) { restClient, cli ->
271+
linkHandler.handle(
272+
uri, shouldDoAutoLogin(),
273+
{
274+
coderHeaderPage.isBusyCreatingNewEnvironment.update {
275+
true
276+
}
277+
},
278+
{
279+
coderHeaderPage.isBusyCreatingNewEnvironment.update {
280+
false
281+
}
282+
}
283+
) { restClient, cli ->
273284
// stop polling and de-initialize resources
274285
close()
275286
// start initialization with the new settings
276287
this@CoderRemoteProvider.client = restClient
277288
coderHeaderPage = NewEnvironmentPage(context, context.i18n.pnotr(restClient.url.toString()))
289+
278290
environments.showLoadingMessage()
279291
pollJob = poll(restClient, cli)
280292
}
@@ -332,7 +344,7 @@ class CoderRemoteProvider(
332344

333345
private fun shouldDoAutoLogin(): Boolean = firstRun && context.secrets.rememberMe == true
334346

335-
private fun onConnect(client: CoderRestClient, cli: CoderCLIManager) {
347+
private suspend fun onConnect(client: CoderRestClient, cli: CoderCLIManager) {
336348
// Store the URL and token for use next time.
337349
context.secrets.lastDeploymentURL = client.url.toString()
338350
context.secrets.lastToken = client.token ?: ""
@@ -344,8 +356,7 @@ class CoderRemoteProvider(
344356
environments.showLoadingMessage()
345357
coderHeaderPage = NewEnvironmentPage(context, context.i18n.pnotr(client.url.toString()))
346358
pollJob = poll(client, cli)
347-
context.ui.showUiPage(CoderPage.emptyPage(context))
348-
goToEnvironmentsPage()
359+
context.refreshMainPage()
349360
}
350361

351362
private fun MutableStateFlow<LoadableState<List<RemoteProviderEnvironment>>>.showLoadingMessage() {

src/main/kotlin/com/coder/toolbox/CoderToolboxContext.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.coder.toolbox
33
import com.coder.toolbox.store.CoderSecretsStore
44
import com.coder.toolbox.store.CoderSettingsStore
55
import com.coder.toolbox.util.toURL
6+
import com.coder.toolbox.views.CoderPage
67
import com.jetbrains.toolbox.api.core.diagnostics.Logger
78
import com.jetbrains.toolbox.api.core.os.LocalDesktopManager
89
import com.jetbrains.toolbox.api.localization.LocalizableStringFactory
@@ -13,8 +14,10 @@ import com.jetbrains.toolbox.api.remoteDev.states.EnvironmentStateColorPalette
1314
import com.jetbrains.toolbox.api.remoteDev.ui.EnvironmentUiPageManager
1415
import com.jetbrains.toolbox.api.ui.ToolboxUi
1516
import kotlinx.coroutines.CoroutineScope
17+
import kotlinx.coroutines.delay
1618
import java.net.URL
1719
import java.util.UUID
20+
import kotlin.time.Duration.Companion.milliseconds
1821

1922
@Suppress("UnstableApiUsage")
2023
data class CoderToolboxContext(
@@ -88,4 +91,13 @@ data class CoderToolboxContext(
8891
i18n.ptrl("OK")
8992
)
9093
}
94+
95+
/**
96+
* Forces the title bar on the main page to be refreshed
97+
*/
98+
suspend fun refreshMainPage() {
99+
ui.showUiPage(CoderPage.emptyPage(this))
100+
delay(10.milliseconds)
101+
envPageManager.showPluginEnvironmentsPage()
102+
}
91103
}

src/main/kotlin/com/coder/toolbox/util/CoderProtocolHandler.kt

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ open class CoderProtocolHandler(
4343
suspend fun handle(
4444
uri: URI,
4545
shouldWaitForAutoLogin: Boolean,
46+
markAsBusy: () -> Unit,
47+
unmarkAsBusy: () -> Unit,
4648
reInitialize: suspend (CoderRestClient, CoderCLIManager) -> Unit
4749
) {
4850
val params = uri.toQueryParameters()
@@ -62,16 +64,22 @@ open class CoderProtocolHandler(
6264
val workspaceName = resolveWorkspaceName(params) ?: return
6365
val restClient = buildRestClient(deploymentURL, token) ?: return
6466
val workspace = restClient.workspaces().matchName(workspaceName, deploymentURL) ?: return
65-
if (!prepareWorkspace(workspace, restClient, workspaceName, deploymentURL)) return
66-
67-
// we resolve the agent after the workspace is started otherwise we can get misleading
68-
// errors like: no agent available while workspace is starting or stopping
69-
val agent = resolveAgent(params, workspace) ?: return
70-
if (!ensureAgentIsReady(workspace, agent)) return
7167

7268
val cli = configureCli(deploymentURL, restClient)
7369
reInitialize(restClient, cli)
7470

71+
var agent: WorkspaceAgent
72+
try {
73+
markAsBusy()
74+
context.refreshMainPage()
75+
if (!prepareWorkspace(workspace, restClient, workspaceName, deploymentURL)) return
76+
// we resolve the agent after the workspace is started otherwise we can get misleading
77+
// errors like: no agent available while workspace is starting or stopping
78+
agent = resolveAgent(params, workspace) ?: return
79+
if (!ensureAgentIsReady(workspace, agent)) return
80+
} finally {
81+
unmarkAsBusy()
82+
}
7583
val environmentId = "${workspace.name}.${agent.name}"
7684
context.showEnvironmentPage(environmentId)
7785

@@ -432,6 +440,7 @@ open class CoderProtocolHandler(
432440
}
433441
}
434442

443+
435444
private fun CoderToolboxContext.popupPluginMainPage() {
436445
this.ui.showWindow()
437446
this.envPageManager.showPluginEnvironmentsPage(true)

src/main/kotlin/com/coder/toolbox/views/AuthWizardPage.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class AuthWizardPage(
1616
private val context: CoderToolboxContext,
1717
private val settingsPage: CoderSettingsPage,
1818
initialAutoLogin: Boolean = false,
19-
onConnect: (
19+
onConnect: suspend (
2020
client: CoderRestClient,
2121
cli: CoderCLIManager,
2222
) -> Unit,

src/main/kotlin/com/coder/toolbox/views/CoderPage.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.jetbrains.toolbox.api.core.ui.icons.SvgIcon.IconType
66
import com.jetbrains.toolbox.api.localization.LocalizableString
77
import com.jetbrains.toolbox.api.ui.actions.RunnableActionDescription
88
import com.jetbrains.toolbox.api.ui.components.UiPage
9+
import kotlinx.coroutines.flow.MutableStateFlow
910
import kotlinx.coroutines.launch
1011
import java.util.UUID
1112

@@ -39,6 +40,8 @@ abstract class CoderPage(
3940
SvgIcon(byteArrayOf(), type = IconType.Masked)
4041
}
4142

43+
override val isBusyCreatingNewEnvironment: MutableStateFlow<Boolean> = MutableStateFlow(false)
44+
4245
/**
4346
* Show an error as a popup on this page.
4447
*/

src/main/kotlin/com/coder/toolbox/views/ConnectStep.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ConnectStep(
2828
private val shouldAutoLogin: StateFlow<Boolean>,
2929
private val notify: (String, Throwable) -> Unit,
3030
private val refreshWizard: () -> Unit,
31-
private val onConnect: (
31+
private val onConnect: suspend (
3232
client: CoderRestClient,
3333
cli: CoderCLIManager,
3434
) -> Unit,

0 commit comments

Comments
 (0)