diff --git a/CHANGELOG.md b/CHANGELOG.md
index adf978a2..690093b1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
- warning system when plugin might not be compatible with Coder REST API
- a `Create workspace` button which links to Coder's templates page
- workspace icons
+- quick toolbar action to open Coder Dashboard in the browser
### Changed
- redesigned the information&warning banner. Messages can now include hyperlinks
diff --git a/src/main/kotlin/com/coder/gateway/icons/CoderIcons.kt b/src/main/kotlin/com/coder/gateway/icons/CoderIcons.kt
index dbf2b4d8..c2199a41 100644
--- a/src/main/kotlin/com/coder/gateway/icons/CoderIcons.kt
+++ b/src/main/kotlin/com/coder/gateway/icons/CoderIcons.kt
@@ -8,6 +8,7 @@ object CoderIcons {
val OPEN_TERMINAL = IconLoader.getIcon("open_terminal.svg", javaClass)
+ val HOME = IconLoader.getIcon("homeFolder.svg", javaClass)
val CREATE = IconLoader.getIcon("create.svg", javaClass)
val RUN = IconLoader.getIcon("run.svg", javaClass)
val STOP = IconLoader.getIcon("stop.svg", javaClass)
diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderRestClientService.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderRestClientService.kt
index c8b2102d..485d3596 100644
--- a/src/main/kotlin/com/coder/gateway/sdk/CoderRestClientService.kt
+++ b/src/main/kotlin/com/coder/gateway/sdk/CoderRestClientService.kt
@@ -28,6 +28,8 @@ import java.util.UUID
@Service(Service.Level.APP)
class CoderRestClientService {
+ var isReady: Boolean = false
+ private set
private lateinit var httpClient: OkHttpClient
private lateinit var retroRestClient: CoderV2RestFacade
private lateinit var sessionToken: String
@@ -40,21 +42,10 @@ class CoderRestClientService {
* @throws [AuthenticationResponseException] if authentication failed.
*/
fun initClientSession(url: URL, token: String): User {
- val gson: Gson = GsonBuilder()
- .registerTypeAdapter(Instant::class.java, InstantConverter())
- .setPrettyPrinting()
- .create()
- httpClient = OkHttpClient.Builder()
- .addInterceptor { it.proceed(it.request().newBuilder().addHeader("Coder-Session-Token", token).build()) }
- .addInterceptor(HttpLoggingInterceptor().apply { setLevel(HttpLoggingInterceptor.Level.BASIC) })
- .build()
-
- retroRestClient = Retrofit.Builder()
- .baseUrl(url.toString())
- .client(httpClient)
- .addConverterFactory(GsonConverterFactory.create(gson))
- .build()
- .create(CoderV2RestFacade::class.java)
+ val gson: Gson = GsonBuilder().registerTypeAdapter(Instant::class.java, InstantConverter()).setPrettyPrinting().create()
+ httpClient = OkHttpClient.Builder().addInterceptor { it.proceed(it.request().newBuilder().addHeader("Coder-Session-Token", token).build()) }.addInterceptor(HttpLoggingInterceptor().apply { setLevel(HttpLoggingInterceptor.Level.BASIC) }).build()
+
+ retroRestClient = Retrofit.Builder().baseUrl(url.toString()).client(httpClient).addConverterFactory(GsonConverterFactory.create(gson)).build().create(CoderV2RestFacade::class.java)
val userResponse = retroRestClient.me().execute()
if (!userResponse.isSuccessful) {
@@ -65,7 +56,7 @@ class CoderRestClientService {
sessionToken = token
me = userResponse.body()!!
buildVersion = buildInfo().version
-
+ isReady = true
return me
}
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 fdb7dc8e..fd6a5874 100644
--- a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt
+++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt
@@ -125,6 +125,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
}
}
+ private val goToDashboardAction = GoToDashboardAction()
private val startWorkspaceAction = StartWorkspaceAction()
private val stopWorkspaceAction = StopWorkspaceAction()
private val updateWorkspaceTemplateAction = UpdateWorkspaceTemplateAction()
@@ -134,6 +135,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
.disableAddAction()
.disableRemoveAction()
.disableUpDownActions()
+ .addExtraAction(goToDashboardAction)
.addExtraAction(startWorkspaceAction)
.addExtraAction(stopWorkspaceAction)
.addExtraAction(updateWorkspaceTemplateAction)
@@ -183,6 +185,12 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
override val previousActionText = IdeBundle.message("button.back")
override val nextActionText = CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.next.text")
+ private inner class GoToDashboardAction : AnActionButton(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.dashboard.text"), CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.dashboard.text"), CoderIcons.HOME) {
+ override fun actionPerformed(p0: AnActionEvent) {
+ BrowserUtil.browse(coderClient.coderURL)
+ }
+ }
+
private inner class StartWorkspaceAction : AnActionButton(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.start.text"), CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.start.text"), CoderIcons.RUN) {
override fun actionPerformed(p0: AnActionEvent) {
if (tableOfWorkspaces.selectedObject != null) {
@@ -221,12 +229,6 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
}
}
- private inner class CreateWorkspaceAction : AnActionButton(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.create.text"), CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.create.text"), CoderIcons.CREATE) {
- override fun actionPerformed(p0: AnActionEvent) {
- BrowserUtil.browse(coderClient.coderURL.toURI().resolve("/templates"))
- }
- }
-
private inner class StopWorkspaceAction : AnActionButton(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.stop.text"), CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.stop.text"), CoderIcons.STOP) {
override fun actionPerformed(p0: AnActionEvent) {
if (tableOfWorkspaces.selectedObject != null) {
@@ -245,6 +247,12 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
}
}
+ private inner class CreateWorkspaceAction : AnActionButton(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.create.text"), CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.create.text"), CoderIcons.CREATE) {
+ override fun actionPerformed(p0: AnActionEvent) {
+ BrowserUtil.browse(coderClient.coderURL.toURI().resolve("/templates"))
+ }
+ }
+
override fun onInit(wizardModel: CoderWorkspacesWizardModel) {
enableNextButtonCallback(false)
if (localWizardModel.coderURL.isNotBlank() && localWizardModel.token.isNotBlank()) {
@@ -265,8 +273,8 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
}
private fun updateWorkspaceActions() {
- createWorkspaceAction.isEnabled = true
-
+ goToDashboardAction.isEnabled = coderClient.isReady
+ createWorkspaceAction.isEnabled = coderClient.isReady
when (tableOfWorkspaces.selectedObject?.agentStatus) {
RUNNING -> {
startWorkspaceAction.isEnabled = false
@@ -380,6 +388,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) :
cs.launch {
ProgressManager.getInstance().run(authTask)
}
+ updateWorkspaceActions()
triggerWorkspacePolling()
}
diff --git a/src/main/resources/homeFolder.svg b/src/main/resources/homeFolder.svg
new file mode 100644
index 00000000..2d482b28
--- /dev/null
+++ b/src/main/resources/homeFolder.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/src/main/resources/homeFolder_dark.svg b/src/main/resources/homeFolder_dark.svg
new file mode 100644
index 00000000..b7ba16ba
--- /dev/null
+++ b/src/main/resources/homeFolder_dark.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/src/main/resources/messages/CoderGatewayBundle.properties b/src/main/resources/messages/CoderGatewayBundle.properties
index 8611e344..784f84cb 100644
--- a/src/main/resources/messages/CoderGatewayBundle.properties
+++ b/src/main/resources/messages/CoderGatewayBundle.properties
@@ -11,6 +11,7 @@ gateway.connector.view.coder.workspaces.connect.text=Connect
gateway.connector.view.coder.workspaces.cli.downloader.dialog.title=Authenticate and setup Coder
gateway.connector.view.coder.workspaces.cli.configssh.dialog.title=Coder Config SSH
gateway.connector.view.coder.workspaces.next.text=Select IDE and Project
+gateway.connector.view.coder.workspaces.dashboard.text=Open Dashboard
gateway.connector.view.coder.workspaces.start.text=Start Workspace
gateway.connector.view.coder.workspaces.stop.text=Stop Workspace
gateway.connector.view.coder.workspaces.update.text=Update Workspace Template