From cfeace1a4bfcd1e6463adfe262cd7e1564fcd811 Mon Sep 17 00:00:00 2001 From: Ioan Faur Date: Tue, 2 Aug 2022 23:59:56 +0300 Subject: [PATCH 1/6] Fix overlaping components in the `Connections` view - `Recent Coder Workspaces` overlaps with the search bar. - reworked the first row to workaround the DSL limitations. - resolves #44 --- CHANGELOG.md | 24 ++++---- ...erGatewayRecentWorkspaceConnectionsView.kt | 61 +++++++++++-------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4b82464..3168ad48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,20 +1,22 @@ -# coder-gateway Changelog - -## [Unreleased] - -## [2.0.0] +# coder-gateway Changelog + +## [Unreleased] +### Fixed +- `Recent Coder Workspaces` label overlaps with the search bar in the `Connections` view + +## [2.0.0] ### Added - support for Gateway 2022.2 - - + + ### Changed - Java 17 is now required to run the plugin -- adapted the code to the new SSH API provided by Gateway - -## [1.0.0] -### Added +- adapted the code to the new SSH API provided by Gateway + +## [1.0.0] +### Added - initial scaffold for Gateway plugin - browser based authentication on Coder environments - REST client for Coder V2 public API diff --git a/src/main/kotlin/com/coder/gateway/views/CoderGatewayRecentWorkspaceConnectionsView.kt b/src/main/kotlin/com/coder/gateway/views/CoderGatewayRecentWorkspaceConnectionsView.kt index 6c2f9e59..ae99b38c 100644 --- a/src/main/kotlin/com/coder/gateway/views/CoderGatewayRecentWorkspaceConnectionsView.kt +++ b/src/main/kotlin/com/coder/gateway/views/CoderGatewayRecentWorkspaceConnectionsView.kt @@ -39,6 +39,7 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import java.awt.Dimension import javax.swing.JComponent +import javax.swing.JLabel import javax.swing.event.DocumentEvent class CoderGatewayRecentWorkspaceConnectionsView : GatewayRecentConnections, Disposable { @@ -62,36 +63,42 @@ class CoderGatewayRecentWorkspaceConnectionsView : GatewayRecentConnections, Dis label(CoderGatewayBundle.message("gateway.connector.recentconnections.title")).applyToComponent { font = JBFont.h3().asBold() } - label("").resizableColumn().horizontalAlign(HorizontalAlign.FILL) - searchBar = cell(SearchTextField(false)).applyToComponent { - minimumSize = Dimension(350, -1) - textEditor.border = JBUI.Borders.empty(2, 5, 2, 0) - addDocumentListener(object : DocumentAdapter() { - override fun textChanged(e: DocumentEvent) { - val toSearchFor = this@applyToComponent.text - val filteredConnections = recentConnectionsService.getAllRecentConnections().filter { it.coderWorkspaceHostname?.toLowerCase()?.contains(toSearchFor) ?: false || it.projectPath?.toLowerCase()?.contains(toSearchFor) ?: false } - updateContentView(filteredConnections.groupBy { it.coderWorkspaceHostname }) - } - }) - }.component + panel { + indent { + row { + cell(JLabel()).resizableColumn().horizontalAlign(HorizontalAlign.FILL) + searchBar = cell(SearchTextField(false)).resizableColumn().horizontalAlign(HorizontalAlign.FILL).applyToComponent { + minimumSize = Dimension(350, -1) + textEditor.border = JBUI.Borders.empty(2, 5, 2, 0) + addDocumentListener(object : DocumentAdapter() { + override fun textChanged(e: DocumentEvent) { + val toSearchFor = this@applyToComponent.text + val filteredConnections = recentConnectionsService.getAllRecentConnections().filter { it.coderWorkspaceHostname?.toLowerCase()?.contains(toSearchFor) ?: false || it.projectPath?.toLowerCase()?.contains(toSearchFor) ?: false } + updateContentView(filteredConnections.groupBy { it.coderWorkspaceHostname }) + } + }) + }.component - actionButton( - object : DumbAwareAction(CoderGatewayBundle.message("gateway.connector.recentconnections.new.wizard.button.tooltip"), null, AllIcons.General.Add) { - override fun actionPerformed(e: AnActionEvent) { - rootPanel.apply { - removeAll() - addToCenter(CoderGatewayConnectorWizardWrapperView { - rootPanel.apply { - removeAll() - addToCenter(contentPanel) - updateUI() + actionButton( + object : DumbAwareAction(CoderGatewayBundle.message("gateway.connector.recentconnections.new.wizard.button.tooltip"), null, AllIcons.General.Add) { + override fun actionPerformed(e: AnActionEvent) { + rootPanel.apply { + removeAll() + addToCenter(CoderGatewayConnectorWizardWrapperView { + rootPanel.apply { + removeAll() + addToCenter(contentPanel) + updateUI() + } + }.component) + updateUI() + } } - }.component) - updateUI() - } + }, + ).gap(RightGap.SMALL) } - }, - ).gap(RightGap.SMALL) + } + } }.bottomGap(BottomGap.MEDIUM) separator(background = WelcomeScreenUIManager.getSeparatorColor()) row { From 6253bcbc5d390cc5a204359ef5437653ba5d4d92 Mon Sep 17 00:00:00 2001 From: Ioan Faur Date: Wed, 3 Aug 2022 00:13:19 +0300 Subject: [PATCH 2/6] Change links to documentation - to point at latest Coder OSS instead of V1 - resolves #48 --- CHANGELOG.md | 3 +++ README.md | 2 +- src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt | 2 +- .../kotlin/com/coder/gateway/views/steps/CoderAuthStepView.kt | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3168ad48..756e8a97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ ### Fixed - `Recent Coder Workspaces` label overlaps with the search bar in the `Connections` view +### Changed +- links to documentation now point to latest Coder OSS + ## [2.0.0] ### Added - support for Gateway 2022.2 diff --git a/README.md b/README.md index 1415ddaa..dd0582bb 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Follow](https://img.shields.io/twitter/follow/CoderHQ?label=%40CoderHQ&style=soc [![Coder Gateway Plugin Build](https://github.com/coder/coder-jetbrains/actions/workflows/build.yml/badge.svg)](https://github.com/coder/coder-jetbrains/actions/workflows/build.yml) -**Coder Gateway** connects your Jetbrains IDE to your [Coder Workspaces](https://coder.com/docs/coder/latest/workspaces) so that you can develop from anywhere. +**Coder Gateway** connects your Jetbrains IDE to your [Coder Workspaces](https://coder.com/docs/coder-oss/latest/workspaces) so that you can develop from anywhere. **Manage less** diff --git a/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt b/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt index 7c90cc4b..895de9bc 100644 --- a/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt +++ b/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt @@ -32,7 +32,7 @@ class CoderGatewayMainView : GatewayConnector { } override fun getDocumentationLink(): ActionLink { - return BrowserLink("Learn more about Coder Workspaces", "https://coder.com/docs/coder/latest/workspaces") + return BrowserLink("Learn more about Coder Workspaces", "https://coder.com/docs/coder-oss/latest/workspaces") } override fun getRecentConnections(setContentCallback: (Component) -> Unit): GatewayRecentConnections { diff --git a/src/main/kotlin/com/coder/gateway/views/steps/CoderAuthStepView.kt b/src/main/kotlin/com/coder/gateway/views/steps/CoderAuthStepView.kt index 012a8978..0b45c0b5 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderAuthStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderAuthStepView.kt @@ -57,7 +57,7 @@ class CoderAuthStepView(private val nextAction: () -> Unit) : CoderWorkspacesWiz cell(ComponentPanelBuilder.createCommentComponent(CoderGatewayBundle.message("gateway.connector.view.login.comment.text"), false, -1, true)) } row { - browserLink(CoderGatewayBundle.message("gateway.connector.view.login.documentation.action"), "https://coder.com/docs/coder/latest/workspaces") + browserLink(CoderGatewayBundle.message("gateway.connector.view.login.documentation.action"), "https://coder.com/docs/coder-oss/latest/workspaces") }.bottomGap(BottomGap.MEDIUM) row(CoderGatewayBundle.message("gateway.connector.view.login.url.label")) { textField().resizableColumn().horizontalAlign(HorizontalAlign.FILL).gap(RightGap.SMALL).bindText(model::coderURL).applyToComponent { From fd0686a5d57f09ba7abfcfba02f7a9e39ed699ed Mon Sep 17 00:00:00 2001 From: Ioan Faur Date: Wed, 3 Aug 2022 00:23:07 +0300 Subject: [PATCH 3/6] Change main action link - from `Connect to Coder Workspaces` to `Connect to Coder` - the wording was too long, and a bit confusing. - main documentation link now points to the general documentation about Coder, not only specifics for Workspaces - resolves #49 --- CHANGELOG.md | 1 + src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt | 2 +- src/main/resources/messages/CoderGatewayBundle.properties | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 756e8a97..c24d174a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Changed - links to documentation now point to latest Coder OSS +- simplified main action link text from `Connect to Coder Workspaces` to `Connect to Coder` ## [2.0.0] ### Added diff --git a/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt b/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt index 895de9bc..9c4c7985 100644 --- a/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt +++ b/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt @@ -32,7 +32,7 @@ class CoderGatewayMainView : GatewayConnector { } override fun getDocumentationLink(): ActionLink { - return BrowserLink("Learn more about Coder Workspaces", "https://coder.com/docs/coder-oss/latest/workspaces") + return BrowserLink("Learn more", "https://coder.com/docs/coder-oss/latest") } override fun getRecentConnections(setContentCallback: (Component) -> Unit): GatewayRecentConnections { diff --git a/src/main/resources/messages/CoderGatewayBundle.properties b/src/main/resources/messages/CoderGatewayBundle.properties index cff561cb..78b1ed11 100644 --- a/src/main/resources/messages/CoderGatewayBundle.properties +++ b/src/main/resources/messages/CoderGatewayBundle.properties @@ -1,6 +1,6 @@ gateway.connector.title=Coder gateway.connector.description=Connects to a Coder Workspace dev environment so that you can develop from anywhere -gateway.connector.action.text=Connect to Coder Workspaces +gateway.connector.action.text=Connect to Coder gateway.connector.view.login.header.text=Coder Workspaces gateway.connector.view.login.comment.text=Self-hosted developer workspaces in the cloud or on premise. Coder Workspaces empower developers with secure, consistent, and fast developer workspaces. gateway.connector.view.login.documentation.action=Explore Coder Workspaces From ea13402af938b4eddc4a0607f756f423f136166e Mon Sep 17 00:00:00 2001 From: Ioan Faur Date: Wed, 3 Aug 2022 00:27:39 +0300 Subject: [PATCH 4/6] Fix typo in ChangeLogwq --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c24d174a..19162e8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ - `Recent Coder Workspaces` label overlaps with the search bar in the `Connections` view ### Changed -- links to documentation now point to latest Coder OSS +- links to documentation now point to the latest Coder OSS - simplified main action link text from `Connect to Coder Workspaces` to `Connect to Coder` ## [2.0.0] From 582b789e03ebdf3a5676c78d5124ef0ce53ef400 Mon Sep 17 00:00:00 2001 From: Ioan Faur Date: Thu, 4 Aug 2022 00:21:26 +0300 Subject: [PATCH 5/6] Fix: show working workspaces - finer grained error handling when resolving agents - resolves #51 --- CHANGELOG.md | 1 + .../views/steps/CoderWorkspacesStepView.kt | 43 +++++++++++-------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19162e8e..0fd77929 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ## [Unreleased] ### Fixed - `Recent Coder Workspaces` label overlaps with the search bar in the `Connections` view +- working Workspaces are now listed when there are issues with resolving agents ### Changed - links to documentation now point to the latest Coder OSS diff --git a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt index f4fa0521..7ddaec78 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt @@ -8,6 +8,7 @@ import com.coder.gateway.sdk.Arch import com.coder.gateway.sdk.CoderRestClientService import com.coder.gateway.sdk.OS import com.coder.gateway.sdk.v2.models.ProvisionerJobStatus +import com.coder.gateway.sdk.v2.models.Workspace import com.coder.gateway.sdk.v2.models.WorkspaceBuildTransition import com.intellij.ide.IdeBundle import com.intellij.openapi.Disposable @@ -87,23 +88,7 @@ class CoderWorkspacesStepView : CoderWorkspacesWizardStep, Disposable { cs.launch { val workspaceList = withContext(Dispatchers.IO) { try { - val workspaces = coderClient.workspaces() - return@withContext workspaces.flatMap { workspace -> - val agents = coderClient.workspaceAgents(workspace) - val shouldContainAgentName = agents.size > 1 - agents.map { agent -> - val workspaceName = if (shouldContainAgentName) "${workspace.name}.${agent.name}" else workspace.name - WorkspaceAgentModel( - workspaceName, - workspace.templateName, - workspace.latestBuild.job.status, - workspace.latestBuild.workspaceTransition, - OS.from(agent.operatingSystem), - Arch.from(agent.architecture), - agent.directory - ) - } - } + return@withContext coderClient.workspaces().collectAgents() } catch (e: Exception) { logger.error("Could not retrieve workspaces for ${coderClient.me.username} on ${coderClient.coderURL}. Reason: $e") emptyList() @@ -115,6 +100,30 @@ class CoderWorkspacesStepView : CoderWorkspacesWizardStep, Disposable { } } + private fun List.collectAgents(): List { + return this.flatMap { workspace -> + try { + val agents = coderClient.workspaceAgents(workspace) + val shouldContainAgentName = agents.size > 1 + return@flatMap agents.map { agent -> + val workspaceName = if (shouldContainAgentName) "${workspace.name}.${agent.name}" else workspace.name + WorkspaceAgentModel( + workspaceName, + workspace.templateName, + workspace.latestBuild.job.status, + workspace.latestBuild.workspaceTransition, + OS.from(agent.operatingSystem), + Arch.from(agent.architecture), + agent.directory + ) + } + } catch (e: Exception) { + logger.error("Skipping workspace ${workspace.name} because we could not retrieve the agent(s). Reason: $e") + emptyList() + } + } + } + override fun onNext(wizardModel: CoderWorkspacesWizardModel): Boolean { val workspace = tableOfWorkspaces.selectedObject if (workspace != null) { From 382f363845fb4a4ec7e8305b7497ced838525a89 Mon Sep 17 00:00:00 2001 From: Ioan Faur Date: Thu, 4 Aug 2022 23:08:49 +0300 Subject: [PATCH 6/6] Fix: list only workspaces owned by the logged user - right now all workspaces are listed to which a user has access to. Which means the user can open a project on a workspace he does not own. - resolves #53 --- CHANGELOG.md | 3 ++- .../kotlin/com/coder/gateway/sdk/CoderRestClientService.kt | 2 +- src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fd77929..f87d503b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ ## [Unreleased] ### Fixed - `Recent Coder Workspaces` label overlaps with the search bar in the `Connections` view -- working Workspaces are now listed when there are issues with resolving agents +- working Workspaces are now listed when there are issues with resolving agents +- list only workspaces owned by the logged user ### Changed - links to documentation now point to the latest Coder OSS diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderRestClientService.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderRestClientService.kt index 786a1512..0e37889c 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/CoderRestClientService.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/CoderRestClientService.kt @@ -80,7 +80,7 @@ class CoderRestClientService { * @throws WorkspaceResponseException if workspaces could not be retrieved. */ fun workspaces(): List { - val workspacesResponse = retroRestClient.workspaces().execute() + val workspacesResponse = retroRestClient.workspaces("owner:me").execute() if (!workspacesResponse.isSuccessful) { throw WorkspaceResponseException("Could not retrieve Coder Workspaces:${workspacesResponse.code()}, reason: ${workspacesResponse.message()}") } diff --git a/src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt b/src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt index 9ef91d52..0fcaa20e 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt @@ -7,6 +7,7 @@ import com.coder.gateway.sdk.v2.models.WorkspaceResource import retrofit2.Call import retrofit2.http.GET import retrofit2.http.Path +import retrofit2.http.Query import java.util.UUID interface CoderV2RestFacade { @@ -21,7 +22,7 @@ interface CoderV2RestFacade { * Retrieves all workspaces the authenticated user has access to. */ @GET("api/v2/workspaces") - fun workspaces(): Call> + fun workspaces(@Query("q") searchParams: String): Call> @GET("api/v2/buildinfo") fun buildInfo(): Call