Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Added

- support Toolbox 3.5 provider header behavior

### Fixed

- snackbar dismissal no longer cancels the calling coroutine, so error popups during URI handling don't leave the page
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ class CoderRemoteEnvironment(
while (context.cs.isActive && workspaceStillExists) {
if (environmentStatus is WorkspaceAndAgentStatus.Deleting || environmentStatus is WorkspaceAndAgentStatus.Deleted) {
workspaceStillExists = false
context.envPageManager.showPluginEnvironmentsPage()
context.envPageManager.showPluginEnvironmentsPage(false)
} else {
delay(1.seconds)
}
Expand Down
21 changes: 11 additions & 10 deletions src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ class CoderRemoteProvider(
)
private val accountDropdownField = dropDownFactory(context.i18n.pnotr("")) {
logout()
context.envPageManager.showPluginEnvironmentsPage()
context.envPageManager.showPluginEnvironmentsPage(false)
}.apply {
visibility.update { false }
}

private val router = PageRouter()
Expand Down Expand Up @@ -152,7 +154,7 @@ class CoderRemoteProvider(
} else {
if ((ex is APIResponseException && ex.isTokenExpired) || ex is OAuthTokenResponseException) {
close()
context.envPageManager.showPluginEnvironmentsPage()
context.envPageManager.showPluginEnvironmentsPage(false)
context.logAndShowError(
"Error encountered while setting up Coder",
"Your Coder session has expired. Please re-authenticate and try again.",
Expand Down Expand Up @@ -265,6 +267,7 @@ class CoderRemoteProvider(
lastEnvironments.clear()
environments.value = LoadableState.Value(emptyList())
isInitialized.update { false }
accountDropdownField.visibility.update { false }
router.clear()
context.logger.info("Coder plugin is now closed")
}
Expand Down Expand Up @@ -299,15 +302,12 @@ class CoderRemoteProvider(
*/
override val noEnvironmentsDescription: String? = "No workspaces yet"


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

/**
* Just displays the deployment URL at the moment, but we could use this as
Expand Down Expand Up @@ -459,7 +459,7 @@ class CoderRemoteProvider(
)
router.navigate(wizard)

context.envPageManager.showPluginEnvironmentsPage(true)
context.envPageManager.showPluginEnvironmentsPage(false)
context.ui.showUiPage(wizard)
} catch (e: Exception) {
context.logAndShowError("OAuth Error", "Exception during token exchange: ${e.message}", e)
Expand Down Expand Up @@ -626,6 +626,7 @@ class CoderRemoteProvider(
accountDropdownField.labelState.update {
context.i18n.pnotr(client.me.username)
}
accountDropdownField.visibility.update { true }
pollJob = poll(client, cli)
context.logger.info("Workspace poll job with name ${pollJob.toString()} was created")
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/com/coder/toolbox/CoderToolboxContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,6 @@ data class CoderToolboxContext(

fun popupPluginMainPage() {
this.ui.showWindow()
this.envPageManager.showPluginEnvironmentsPage(true)
this.envPageManager.showPluginEnvironmentsPage(false)
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/com/coder/toolbox/views/ConnectStep.kt
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class ConnectStep(
}
// The provider's onConnect ran close() which clears the router; combined
// with client now being non-null this drops the wizard from getOverrideUiPage.
context.envPageManager.showPluginEnvironmentsPage()
context.envPageManager.showPluginEnvironmentsPage(false)
} catch (ex: CancellationException) {
// Back-button cancellation already navigates in onBack(), while
// dispose() must cancel without navigating. Treat these control-flow
Expand Down
22 changes: 22 additions & 0 deletions src/test/kotlin/com/coder/toolbox/CoderRemoteProviderTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertSame
Expand Down Expand Up @@ -259,6 +260,27 @@ class CoderRemoteProviderTest {
verify { mockContext.popupPluginMainPage() }
}

@Test
fun `given Toolbox 3_5 provider page then header surface is available and account dropdown starts hidden`() {
// Toolbox 3.5 hides the whole top section when this flag is false.
// The Coder header page keeps the deployment URL and account dropdown renderable.
assertTrue(remoteProvider.canCreateNewEnvironments)
assertNotNull(remoteProvider.getNewEnvironmentUiPage())

val accountDropdown = assertNotNull(remoteProvider.getAccountDropDown())
assertFalse(accountDropdown.visibility.value)
}

@Test
fun `given visible account dropdown when provider closes then dropdown is hidden`() {
val accountDropdown = assertNotNull(remoteProvider.getAccountDropDown())
accountDropdown.visibility.value = true

remoteProvider.close()

assertFalse(accountDropdown.visibility.value)
}

@Test
fun `given mTLS is required when auto setup has stored credentials then mTLS takes precedence`() {
// given
Expand Down
Loading