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
30 changes: 25 additions & 5 deletions src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import com.coder.toolbox.util.DialogUi
import com.coder.toolbox.util.TOKEN
import com.coder.toolbox.util.URL
import com.coder.toolbox.util.WebUrlValidationResult.Invalid
import com.coder.toolbox.util.owner
import com.coder.toolbox.util.toQueryParameters
import com.coder.toolbox.util.toURL
import com.coder.toolbox.util.token
import com.coder.toolbox.util.url
import com.coder.toolbox.util.validateStrictWebUrl
import com.coder.toolbox.util.withPath
import com.coder.toolbox.util.workspace
import com.coder.toolbox.views.Action
import com.coder.toolbox.views.CoderDelimiter
import com.coder.toolbox.views.CoderSettingsPage
Expand Down Expand Up @@ -385,7 +387,7 @@ class CoderRemoteProvider(
} else {
this.client!! to this.cli!!
}
linkHandler.handle(params, newUrl, activeSession.first, activeSession.second)
handleLink(params, newUrl, activeSession.first, activeSession.second)
} finally {
coderHeaderPage.isBusy.update { false }
}
Expand Down Expand Up @@ -662,18 +664,36 @@ class CoderRemoteProvider(
}

/**
* Returns a [SuspendBiConsumer] that handles the given link parameters.
* Runs in a background coroutine so it doesn't block the connect step's
* post-connection flow.
* Applies the appropriate workspace filter for the URI then delegates to [linkHandler].
* Scopes the filter to the target workspace when it is owned by a different user so the poll
* fetches and registers it before the IDE launch runs. For own workspaces, resets to the
* default filter, clearing any leftover non-owned filter from a previous URI.
*/
private suspend fun handleLink(
params: Map<String, String>,
url: URL,
client: CoderRestClient,
cli: CoderCLIManager,
) {
val uriOwner = params.owner()
val uriWorkspace = params.workspace()
if (!uriOwner.isNullOrBlank() && !uriWorkspace.isNullOrBlank() && uriOwner != client.me.username) {
coderHeaderPage.setFilter("owner:$uriOwner name:$uriWorkspace")
} else {
coderHeaderPage.resetFilter()
}
linkHandler.handle(params, url, client, cli)
}

/** Returns a [SuspendBiConsumer] that handles the given link parameters in a background coroutine. */
private fun deferredLinkHandler(
params: Map<String, String>,
deploymentUrl: URL,
): SuspendBiConsumer<CoderRestClient, CoderCLIManager> = SuspendBiConsumer { client, cli ->
context.cs.launch(CoroutineName("Deferred Link Handler")) {
coderHeaderPage.isBusy.update { true }
try {
linkHandler.handle(params, deploymentUrl, client, cli)
handleLink(params, deploymentUrl, client, cli)
} catch (ex: Exception) {
context.logAndShowError(
"Error handling deferred link",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,6 @@ val WORKSPACE_FILTER_PRESETS = listOf(
)

/** The preset name whose query exactly matches this query, or [CUSTOM_WORKSPACE_FILTER_NAME] if none. */
fun String.presetNameForQuery(): String =
WORKSPACE_FILTER_PRESETS.firstOrNull { it.query == trim() }?.name ?: CUSTOM_WORKSPACE_FILTER_NAME
fun String.presetNameForQuery(): String {
return WORKSPACE_FILTER_PRESETS.firstOrNull { it.query == this.trim() }?.name ?: CUSTOM_WORKSPACE_FILTER_NAME
}
11 changes: 11 additions & 0 deletions src/main/kotlin/com/coder/toolbox/views/NewEnvironmentPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,17 @@ class NewEnvironmentPage(
reportFilterError(null)
}

/**
* Sets the filter to an arbitrary query, e.g. when a URI targets a workspace owned by a
* different user. Updates both the visible search field and the backing query so the poll
* immediately uses the new value.
*/
fun setFilter(query: String) {
workspaceSearchField.contentState.value = query
mutableWorkspaceSearchQuery.value = query
reportFilterError(null)
}

/**
* Shows the server's validation [message] under the search bar, or clears it when [message] is
* null. Called by the provider when a workspace query is rejected or succeeds.
Expand Down
Loading