Skip to content

Commit 01660ae

Browse files
authored
Support Toolbox 3.5 provider header rendering (#316)
Toolbox 3.5 removes the provider top section when `canCreateNewEnvironments` is false. Coder used that section to render the deployment URL and account dropdown, so the URL header stayed stuck on Coder and the dropdown never appeared. Because we changed `canCreateNewEnvironments` to true, Toolbox 3.5 renders that top/header area again. But `getAccountDropDown()` always returns `accountDropdownField`, and its initial label is "". So I hid it until a real Coder session exists, then made it visible after login when we set the username. As an extra I changed all calls to `showPluginEnvironmentsPage(false)` when returning to the provider page. There is no reason to expand the header bar right now because Coder only renders the URL and account button there. Original Toolbox issue that was fixed in 3.5: https://youtrack.jetbrains.com/issue/TBX-17235
1 parent a76724d commit 01660ae

6 files changed

Lines changed: 40 additions & 13 deletions

File tree

CHANGELOG.md

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

33
## Unreleased
44

5+
### Added
6+
7+
- support Toolbox 3.5 provider header behavior
8+
59
### Fixed
610

711
- snackbar dismissal no longer cancels the calling coroutine, so error popups during URI handling don't leave the page

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ class CoderRemoteEnvironment(
339339
while (context.cs.isActive && workspaceStillExists) {
340340
if (environmentStatus is WorkspaceAndAgentStatus.Deleting || environmentStatus is WorkspaceAndAgentStatus.Deleted) {
341341
workspaceStillExists = false
342-
context.envPageManager.showPluginEnvironmentsPage()
342+
context.envPageManager.showPluginEnvironmentsPage(false)
343343
} else {
344344
delay(1.seconds)
345345
}

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

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ class CoderRemoteProvider(
100100
)
101101
private val accountDropdownField = dropDownFactory(context.i18n.pnotr("")) {
102102
logout()
103-
context.envPageManager.showPluginEnvironmentsPage()
103+
context.envPageManager.showPluginEnvironmentsPage(false)
104+
}.apply {
105+
visibility.update { false }
104106
}
105107

106108
private val router = PageRouter()
@@ -152,7 +154,7 @@ class CoderRemoteProvider(
152154
} else {
153155
if ((ex is APIResponseException && ex.isTokenExpired) || ex is OAuthTokenResponseException) {
154156
close()
155-
context.envPageManager.showPluginEnvironmentsPage()
157+
context.envPageManager.showPluginEnvironmentsPage(false)
156158
context.logAndShowError(
157159
"Error encountered while setting up Coder",
158160
"Your Coder session has expired. Please re-authenticate and try again.",
@@ -265,6 +267,7 @@ class CoderRemoteProvider(
265267
lastEnvironments.clear()
266268
environments.value = LoadableState.Value(emptyList())
267269
isInitialized.update { false }
270+
accountDropdownField.visibility.update { false }
268271
router.clear()
269272
context.logger.info("Coder plugin is now closed")
270273
}
@@ -299,15 +302,12 @@ class CoderRemoteProvider(
299302
*/
300303
override val noEnvironmentsDescription: String? = "No workspaces yet"
301304

302-
303305
/**
304-
* TODO@JB: Supposedly, setting this to false causes the new environment
305-
* page to not show but it shows anyway. For now we have it
306-
* displaying the deployment URL, which is actually useful, so if
307-
* this changes it would be nice to have a new spot to show the
308-
* URL.
306+
* Toolbox 3.5 removes the entire top section when this is false. Coder uses
307+
* the new-environment page as a provider header so the deployment URL and
308+
* account dropdown remain visible above the workspace list.
309309
*/
310-
override val canCreateNewEnvironments: Boolean = false
310+
override val canCreateNewEnvironments: Boolean = true
311311

312312
/**
313313
* Just displays the deployment URL at the moment, but we could use this as
@@ -459,7 +459,7 @@ class CoderRemoteProvider(
459459
)
460460
router.navigate(wizard)
461461

462-
context.envPageManager.showPluginEnvironmentsPage(true)
462+
context.envPageManager.showPluginEnvironmentsPage(false)
463463
context.ui.showUiPage(wizard)
464464
} catch (e: Exception) {
465465
context.logAndShowError("OAuth Error", "Exception during token exchange: ${e.message}", e)
@@ -626,6 +626,7 @@ class CoderRemoteProvider(
626626
accountDropdownField.labelState.update {
627627
context.i18n.pnotr(client.me.username)
628628
}
629+
accountDropdownField.visibility.update { true }
629630
pollJob = poll(client, cli)
630631
context.logger.info("Workspace poll job with name ${pollJob.toString()} was created")
631632
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,6 @@ data class CoderToolboxContext(
104104

105105
fun popupPluginMainPage() {
106106
this.ui.showWindow()
107-
this.envPageManager.showPluginEnvironmentsPage(true)
107+
this.envPageManager.showPluginEnvironmentsPage(false)
108108
}
109109
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class ConnectStep(
138138
}
139139
// The provider's onConnect ran close() which clears the router; combined
140140
// with client now being non-null this drops the wizard from getOverrideUiPage.
141-
context.envPageManager.showPluginEnvironmentsPage()
141+
context.envPageManager.showPluginEnvironmentsPage(false)
142142
} catch (ex: CancellationException) {
143143
// Back-button cancellation already navigates in onBack(), while
144144
// dispose() must cancel without navigating. Treat these control-flow

src/test/kotlin/com/coder/toolbox/CoderRemoteProviderTest.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import kotlin.test.AfterTest
2727
import kotlin.test.BeforeTest
2828
import kotlin.test.Test
2929
import kotlin.test.assertEquals
30+
import kotlin.test.assertFalse
3031
import kotlin.test.assertNotNull
3132
import kotlin.test.assertNull
3233
import kotlin.test.assertSame
@@ -259,6 +260,27 @@ class CoderRemoteProviderTest {
259260
verify { mockContext.popupPluginMainPage() }
260261
}
261262

263+
@Test
264+
fun `given Toolbox 3_5 provider page then header surface is available and account dropdown starts hidden`() {
265+
// Toolbox 3.5 hides the whole top section when this flag is false.
266+
// The Coder header page keeps the deployment URL and account dropdown renderable.
267+
assertTrue(remoteProvider.canCreateNewEnvironments)
268+
assertNotNull(remoteProvider.getNewEnvironmentUiPage())
269+
270+
val accountDropdown = assertNotNull(remoteProvider.getAccountDropDown())
271+
assertFalse(accountDropdown.visibility.value)
272+
}
273+
274+
@Test
275+
fun `given visible account dropdown when provider closes then dropdown is hidden`() {
276+
val accountDropdown = assertNotNull(remoteProvider.getAccountDropDown())
277+
accountDropdown.visibility.value = true
278+
279+
remoteProvider.close()
280+
281+
assertFalse(accountDropdown.visibility.value)
282+
}
283+
262284
@Test
263285
fun `given mTLS is required when auto setup has stored credentials then mTLS takes precedence`() {
264286
// given

0 commit comments

Comments
 (0)