diff --git a/CHANGELOG.md b/CHANGELOG.md index fb5b0090..09c5e1ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,14 @@ ## Unreleased +### Added + +- support for Gateway 2023 + ## 2.1.7 - 2023-02-28 ### Fixed + - terminal link is now correct when host ends in `/` - improved resiliency and error handling when trying to open the last successful connection diff --git a/gradle.properties b/gradle.properties index c1cc0844..71cf26f0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,16 +3,16 @@ pluginGroup=com.coder.gateway pluginName=coder-gateway # SemVer format -> https://semver.org -pluginVersion=2.1.7 +pluginVersion=2.2.0 # See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html # for insight into build numbers and IntelliJ Platform versions. pluginSinceBuild=223.7571.70 -pluginUntilBuild=223.* +pluginUntilBuild=231.* # IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties # Gateway available build versions https://www.jetbrains.com/intellij-repository/snapshots and https://www.jetbrains.com/intellij-repository/releases platformType=GW -platformVersion=223.8617.56-CUSTOM-SNAPSHOT -instrumentationCompiler=223.8617.56-CUSTOM-SNAPSHOT +platformVersion=231.7665.28-CUSTOM-SNAPSHOT +instrumentationCompiler=231.7665.28-CUSTOM-SNAPSHOT platformDownloadSources=true # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html # Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 diff --git a/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt b/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt index bb366459..c1a0a810 100644 --- a/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt +++ b/src/main/kotlin/com/coder/gateway/CoderGatewayMainView.kt @@ -1,17 +1,17 @@ package com.coder.gateway +import com.coder.gateway.help.ABOUT_HELP_TOPIC import com.coder.gateway.icons.CoderIcons import com.coder.gateway.views.CoderGatewayConnectorWizardWrapperView import com.coder.gateway.views.CoderGatewayRecentWorkspaceConnectionsView -import com.intellij.ui.components.ActionLink -import com.intellij.ui.components.BrowserLink +import com.intellij.openapi.help.HelpManager import com.jetbrains.gateway.api.GatewayConnector +import com.jetbrains.gateway.api.GatewayConnectorDocumentation import com.jetbrains.gateway.api.GatewayConnectorView import com.jetbrains.gateway.api.GatewayRecentConnections import com.jetbrains.rd.util.lifetime.Lifetime import java.awt.Component import javax.swing.Icon -import javax.swing.JComponent class CoderGatewayMainView : GatewayConnector { override fun getConnectorId() = CoderGatewayConstants.GATEWAY_CONNECTOR_ID @@ -31,8 +31,10 @@ class CoderGatewayMainView : GatewayConnector { return CoderGatewayBundle.message("gateway.connector.description") } - override fun getDocumentationLink(): ActionLink { - return BrowserLink("Learn more", "https://coder.com/docs/coder-oss/latest") + override fun getDocumentationAction(): GatewayConnectorDocumentation { + return GatewayConnectorDocumentation(true) { + HelpManager.getInstance().invokeHelp(ABOUT_HELP_TOPIC) + } } override fun getRecentConnections(setContentCallback: (Component) -> Unit): GatewayRecentConnections { @@ -43,10 +45,6 @@ class CoderGatewayMainView : GatewayConnector { return CoderGatewayBundle.message("gateway.connector.title") } - override fun getTitleAdornment(): JComponent? { - return null - } - override fun isAvailable(): Boolean { return true } diff --git a/src/main/kotlin/com/coder/gateway/help/CoderWebHelp.kt b/src/main/kotlin/com/coder/gateway/help/CoderWebHelp.kt new file mode 100644 index 00000000..60ae2cce --- /dev/null +++ b/src/main/kotlin/com/coder/gateway/help/CoderWebHelp.kt @@ -0,0 +1,14 @@ +package com.coder.gateway.help + +import com.intellij.openapi.help.WebHelpProvider + +const val ABOUT_HELP_TOPIC = "com.coder.gateway.about" + +class CoderWebHelp : WebHelpProvider() { + override fun getHelpPageUrl(helpTopicId: String): String { + return when (helpTopicId) { + ABOUT_HELP_TOPIC -> "https://coder.com/docs/coder-oss/latest" + else -> "https://coder.com/docs/coder-oss/latest" + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/coder/gateway/sdk/TemplateIconDownloader.kt b/src/main/kotlin/com/coder/gateway/sdk/TemplateIconDownloader.kt index 2cfa1bdf..a8575de8 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/TemplateIconDownloader.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/TemplateIconDownloader.kt @@ -3,10 +3,16 @@ package com.coder.gateway.sdk import com.coder.gateway.icons.CoderIcons import com.intellij.openapi.components.Service import com.intellij.openapi.components.service -import com.intellij.util.IconUtil +import com.intellij.ui.JreHiDpiUtil +import com.intellij.ui.paint.alignToInt +import com.intellij.ui.scale.JBUIScale import com.intellij.util.ImageLoader import com.intellij.util.ui.ImageUtil import org.imgscalr.Scalr +import java.awt.Component +import java.awt.Graphics +import java.awt.Graphics2D +import java.awt.image.BufferedImage import java.net.URL import javax.swing.Icon @@ -30,7 +36,7 @@ class TemplateIconDownloader { } var img = ImageLoader.loadFromUrl(url) if (img != null) { - val icon = IconUtil.toRetinaAwareIcon(Scalr.resize(ImageUtil.toBufferedImage(img), Scalr.Method.ULTRA_QUALITY, 32)) + val icon = toRetinaAwareIcon(Scalr.resize(ImageUtil.toBufferedImage(img), Scalr.Method.ULTRA_QUALITY, 32)) cache[Pair(workspaceName, path)] = icon return icon } @@ -39,6 +45,34 @@ class TemplateIconDownloader { return iconForChar(workspaceName.lowercase().first()) } + private fun toRetinaAwareIcon(image: BufferedImage): Icon { + val sysScale = JBUIScale.sysScale() + return object : Icon { + override fun paintIcon(c: Component?, g: Graphics, x: Int, y: Int) { + if (isJreHiDPI) { + val newG = g.create(x, y, image.width, image.height) as Graphics2D + alignToInt(newG) + newG.scale(1.0 / sysScale, 1.0 / sysScale) + newG.drawImage(image, 0, 0, null) + newG.dispose() + } else { + g.drawImage(image, x, y, null) + } + } + + override fun getIconWidth(): Int = if (isJreHiDPI) (image.width / sysScale).toInt() else image.width + + override fun getIconHeight(): Int = if (isJreHiDPI) (image.height / sysScale).toInt() else image.height + + private val isJreHiDPI: Boolean + get() = JreHiDpiUtil.isJreHiDPI(sysScale) + + override fun toString(): String { + return "TemplateIconDownloader.toRetinaAwareIcon for $image" + } + } + } + private fun iconForChar(c: Char) = when (c) { '0' -> CoderIcons.ZERO '1' -> CoderIcons.ONE diff --git a/src/main/kotlin/com/coder/gateway/views/CoderGatewayConnectorWizardView.kt b/src/main/kotlin/com/coder/gateway/views/CoderGatewayConnectorWizardView.kt index f136d6fb..49673158 100644 --- a/src/main/kotlin/com/coder/gateway/views/CoderGatewayConnectorWizardView.kt +++ b/src/main/kotlin/com/coder/gateway/views/CoderGatewayConnectorWizardView.kt @@ -6,9 +6,9 @@ import com.coder.gateway.views.steps.CoderWorkspacesStepView import com.coder.gateway.views.steps.CoderWorkspacesWizardStep import com.intellij.openapi.Disposable import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeScreenUIManager +import com.intellij.ui.dsl.builder.AlignX import com.intellij.ui.dsl.builder.RightGap import com.intellij.ui.dsl.builder.panel -import com.intellij.ui.dsl.gridLayout.HorizontalAlign import com.intellij.util.ui.components.BorderLayoutPanel import com.jetbrains.gateway.api.GatewayUI import java.awt.Component @@ -109,9 +109,10 @@ class CoderGatewayConnectorWizardView : BorderLayoutPanel(), Disposable { indent { row { - label("").resizableColumn().horizontalAlign(HorizontalAlign.FILL).gap(RightGap.SMALL) - previousButton = button("") { previous() }.horizontalAlign(HorizontalAlign.RIGHT).gap(RightGap.SMALL).applyToComponent { background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() }.component - nextButton = button("") { next() }.horizontalAlign(HorizontalAlign.RIGHT).gap(RightGap.SMALL).applyToComponent { background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() }.component + label("").resizableColumn().align(AlignX.FILL).gap(RightGap.SMALL) + previousButton = button("") { previous() }.align(AlignX.RIGHT).gap(RightGap.SMALL).applyToComponent { background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() }.component + nextButton = button("") { next() }.align(AlignX.RIGHT).gap(RightGap.SMALL).applyToComponent { background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() }.component + cell() } }.apply { background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() diff --git a/src/main/kotlin/com/coder/gateway/views/CoderGatewayRecentWorkspaceConnectionsView.kt b/src/main/kotlin/com/coder/gateway/views/CoderGatewayRecentWorkspaceConnectionsView.kt index cc0e14c9..130d2ea5 100644 --- a/src/main/kotlin/com/coder/gateway/views/CoderGatewayRecentWorkspaceConnectionsView.kt +++ b/src/main/kotlin/com/coder/gateway/views/CoderGatewayRecentWorkspaceConnectionsView.kt @@ -20,12 +20,12 @@ import com.intellij.ui.DocumentAdapter import com.intellij.ui.SearchTextField import com.intellij.ui.components.ActionLink import com.intellij.ui.components.JBScrollPane +import com.intellij.ui.dsl.builder.AlignX +import com.intellij.ui.dsl.builder.AlignY import com.intellij.ui.dsl.builder.BottomGap import com.intellij.ui.dsl.builder.RightGap import com.intellij.ui.dsl.builder.TopGap import com.intellij.ui.dsl.builder.panel -import com.intellij.ui.dsl.gridLayout.HorizontalAlign -import com.intellij.ui.dsl.gridLayout.VerticalAlign import com.intellij.util.ui.JBFont import com.intellij.util.ui.JBUI import com.jetbrains.gateway.api.GatewayRecentConnections @@ -38,7 +38,7 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import java.awt.Component import java.awt.Dimension -import java.util.Locale +import java.util.* import javax.swing.JComponent import javax.swing.JLabel import javax.swing.event.DocumentEvent @@ -65,14 +65,15 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback: panel { indent { row { - cell(JLabel()).resizableColumn().horizontalAlign(HorizontalAlign.FILL) - searchBar = cell(SearchTextField(false)).resizableColumn().horizontalAlign(HorizontalAlign.FILL).applyToComponent { + cell(JLabel()).resizableColumn().align(AlignX.FILL) + searchBar = cell(SearchTextField(false)).resizableColumn().align(AlignX.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?.lowercase(Locale.getDefault())?.contains(toSearchFor) ?: false || it.projectPath?.lowercase(Locale.getDefault())?.contains(toSearchFor) ?: false } + val filteredConnections = recentConnectionsService.getAllRecentConnections() + .filter { it.coderWorkspaceHostname?.lowercase(Locale.getDefault())?.contains(toSearchFor) ?: false || it.projectPath?.lowercase(Locale.getDefault())?.contains(toSearchFor) ?: false } updateContentView(filteredConnections.groupBy { it.coderWorkspaceHostname }) } }) @@ -92,7 +93,7 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback: separator(background = WelcomeScreenUIManager.getSeparatorColor()) row { resizableRow() - cell(recentWorkspacesContentPanel).resizableColumn().horizontalAlign(HorizontalAlign.FILL).verticalAlign(VerticalAlign.FILL).component + cell(recentWorkspacesContentPanel).resizableColumn().align(AlignX.FILL).align(AlignY.FILL).component } } }.apply { @@ -114,7 +115,7 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback: if (hostname != null) { label(hostname).applyToComponent { font = JBFont.h3().asBold() - }.horizontalAlign(HorizontalAlign.LEFT).gap(RightGap.SMALL) + }.align(AlignX.LEFT).gap(RightGap.SMALL) actionButton(object : DumbAwareAction(CoderGatewayBundle.message("gateway.connector.recentconnections.terminal.button.tooltip"), "", CoderIcons.OPEN_TERMINAL) { override fun actionPerformed(e: AnActionEvent) { BrowserUtil.browse(recentConnections[0].webTerminalLink ?: "") @@ -132,7 +133,7 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback: GatewayUI.getInstance().connect(connectionDetails.toWorkspaceParams()) } }) - label("").resizableColumn().horizontalAlign(HorizontalAlign.FILL) + label("").resizableColumn().align(AlignX.FILL) label("Last opened: ${connectionDetails.lastOpened}").applyToComponent { foreground = JBUI.CurrentTheme.ContextHelp.FOREGROUND font = ComponentPanelBuilder.getCommentFont(font) diff --git a/src/main/kotlin/com/coder/gateway/views/steps/CoderLocateRemoteProjectStepView.kt b/src/main/kotlin/com/coder/gateway/views/steps/CoderLocateRemoteProjectStepView.kt index 9beb388c..9172eeea 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderLocateRemoteProjectStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderLocateRemoteProjectStepView.kt @@ -29,11 +29,11 @@ import com.intellij.ui.AnimatedIcon import com.intellij.ui.ColoredListCellRenderer import com.intellij.ui.DocumentAdapter import com.intellij.ui.components.JBTextField +import com.intellij.ui.dsl.builder.AlignX import com.intellij.ui.dsl.builder.BottomGap import com.intellij.ui.dsl.builder.RowLayout import com.intellij.ui.dsl.builder.TopGap import com.intellij.ui.dsl.builder.panel -import com.intellij.ui.dsl.gridLayout.HorizontalAlign import com.intellij.util.ui.JBFont import com.intellij.util.ui.UIUtil import com.intellij.util.ui.update.MergingUpdateQueue @@ -47,6 +47,7 @@ import com.jetbrains.gateway.ssh.HighLevelHostAccessor import com.jetbrains.gateway.ssh.IdeStatus import com.jetbrains.gateway.ssh.IdeWithStatus import com.jetbrains.gateway.ssh.IntelliJPlatformProduct +import com.jetbrains.gateway.ssh.util.validateRemotePath import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -62,7 +63,7 @@ import kotlinx.coroutines.withContext import java.awt.Component import java.awt.FlowLayout import java.time.Duration -import java.util.Locale +import java.util.* import javax.swing.ComboBoxModel import javax.swing.DefaultComboBoxModel import javax.swing.JLabel @@ -99,13 +100,13 @@ class CoderLocateRemoteProjectStepView(private val disableNextAction: () -> Unit label("IDE:") cbIDE = cell(IDEComboBox(ideComboBoxModel).apply { renderer = IDECellRenderer() - }).resizableColumn().horizontalAlign(HorizontalAlign.FILL).comment("The IDE will be downloaded from jetbrains.com").component + }).resizableColumn().align(AlignX.FILL).comment("The IDE will be downloaded from jetbrains.com").component cell() }.topGap(TopGap.NONE).layout(RowLayout.PARENT_GRID) row { label("Project directory:") - cell(tfProject).resizableColumn().horizontalAlign(HorizontalAlign.FILL).component + cell(tfProject).resizableColumn().align(AlignX.FILL).component cell() }.topGap(TopGap.NONE).bottomGap(BottomGap.NONE).layout(RowLayout.PARENT_GRID) row { @@ -190,8 +191,8 @@ class CoderLocateRemoteProjectStepView(private val disableNextAction: () -> Unit pathValidationJobs.queue(Update.create("validate-remote-path") { runBlocking { try { - val isPathPresent = executor.isPathPresentOnRemote(tfProject.text) - if (!isPathPresent) { + val isPathPresent = validateRemotePath(tfProject.text, executor) + if (isPathPresent.pathOrNull == null) { ComponentValidator.getInstance(tfProject).ifPresent { it.updateInfo(ValidationInfo("Can't find directory: ${tfProject.text}", tfProject)) } 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 a962a87f..925d1c28 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt @@ -28,9 +28,10 @@ import com.intellij.ide.BrowserUtil import com.intellij.ide.IdeBundle import com.intellij.ide.util.PropertiesComponent import com.intellij.openapi.Disposable +import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ModalityState -import com.intellij.openapi.application.invokeAndWaitIfNeeded import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.progress.ProgressIndicator @@ -45,13 +46,13 @@ import com.intellij.ui.RelativeFont import com.intellij.ui.ToolbarDecorator import com.intellij.ui.components.JBTextField import com.intellij.ui.components.dialog +import com.intellij.ui.dsl.builder.AlignX +import com.intellij.ui.dsl.builder.AlignY import com.intellij.ui.dsl.builder.BottomGap import com.intellij.ui.dsl.builder.RightGap import com.intellij.ui.dsl.builder.TopGap import com.intellij.ui.dsl.builder.bindText import com.intellij.ui.dsl.builder.panel -import com.intellij.ui.dsl.gridLayout.HorizontalAlign -import com.intellij.ui.dsl.gridLayout.VerticalAlign import com.intellij.ui.table.TableView import com.intellij.util.ui.ColumnInfo import com.intellij.util.ui.JBFont @@ -187,11 +188,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : .disableAddAction() .disableRemoveAction() .disableUpDownActions() - .addExtraAction(goToDashboardAction) - .addExtraAction(startWorkspaceAction) - .addExtraAction(stopWorkspaceAction) - .addExtraAction(updateWorkspaceTemplateAction) - .addExtraAction(createWorkspaceAction) + .addExtraActions(goToDashboardAction, startWorkspaceAction, stopWorkspaceAction, updateWorkspaceTemplateAction, createWorkspaceAction as AnAction) private var poller: Job? = null @@ -211,7 +208,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : 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")) { - tfUrl = textField().resizableColumn().horizontalAlign(HorizontalAlign.FILL).gap(RightGap.SMALL).bindText(localWizardModel::coderURL).applyToComponent { + tfUrl = textField().resizableColumn().align(AlignX.FILL).gap(RightGap.SMALL).bindText(localWizardModel::coderURL).applyToComponent { addActionListener { poller?.cancel() askTokenAndOpenSession() @@ -228,7 +225,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : row { scrollCell(toolbar.createPanel().apply { add(notificationBanner.component.apply { isVisible = false }, "South") - }).resizableColumn().horizontalAlign(HorizontalAlign.FILL).verticalAlign(VerticalAlign.FILL) + }).resizableColumn().align(AlignX.FILL).align(AlignY.FILL) cell() }.topGap(TopGap.NONE).bottomGap(BottomGap.NONE).resizableRow() } @@ -237,13 +234,15 @@ 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) { + 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) { + 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) { val workspace = tableOfWorkspaces.selectedObject as WorkspaceAgentModel @@ -261,7 +260,8 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : } } - private inner class UpdateWorkspaceTemplateAction : AnActionButton(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.update.text"), CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.update.text"), CoderIcons.UPDATE) { + private inner class UpdateWorkspaceTemplateAction : + AnActionButton(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.update.text"), CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.update.text"), CoderIcons.UPDATE) { override fun actionPerformed(p0: AnActionEvent) { if (tableOfWorkspaces.selectedObject != null) { val workspace = tableOfWorkspaces.selectedObject as WorkspaceAgentModel @@ -281,7 +281,8 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : } } - 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) { + 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) { val workspace = tableOfWorkspaces.selectedObject as WorkspaceAgentModel @@ -299,7 +300,8 @@ 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) { + 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")) } @@ -460,7 +462,8 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : private fun askToken(): String? { BrowserUtil.browse(localWizardModel.coderURL.toURL().withPath("/login?redirect=%2Fcli-auth")) - return invokeAndWaitIfNeeded(ModalityState.any()) { + var tokenFromUser: String? = null + ApplicationManager.getApplication().invokeAndWait({ lateinit var sessionTokenTextField: JBTextField val panel = panel { @@ -474,10 +477,11 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : AppIcon.getInstance().requestAttention(null, true) if (!dialog(CoderGatewayBundle.message("gateway.connector.view.login.token.dialog"), panel = panel, focusedComponent = sessionTokenTextField).showAndGet()) { - return@invokeAndWaitIfNeeded null + return@invokeAndWait } - return@invokeAndWaitIfNeeded sessionTokenTextField.text - } + tokenFromUser = sessionTokenTextField.text + }, ModalityState.any()) + return tokenFromUser } private fun triggerWorkspacePolling() { diff --git a/src/main/kotlin/com/coder/gateway/views/steps/NotificationBanner.kt b/src/main/kotlin/com/coder/gateway/views/steps/NotificationBanner.kt index e0cb8b1a..1b38a3c0 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/NotificationBanner.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/NotificationBanner.kt @@ -2,8 +2,8 @@ package com.coder.gateway.views.steps import com.intellij.icons.AllIcons import com.intellij.openapi.ui.DialogPanel +import com.intellij.ui.dsl.builder.AlignX import com.intellij.ui.dsl.builder.panel -import com.intellij.ui.dsl.gridLayout.HorizontalAlign import com.intellij.util.ui.JBUI import javax.swing.JEditorPane import javax.swing.JLabel @@ -19,7 +19,7 @@ class NotificationBanner { icon = icon(AllIcons.General.Warning).applyToComponent { border = JBUI.Borders.empty(0, 5) }.component - txt = text("").resizableColumn().horizontalAlign(HorizontalAlign.FILL).applyToComponent { foreground = JBUI.CurrentTheme.NotificationWarning.foregroundColor() }.component + txt = text("").resizableColumn().align(AlignX.FILL).applyToComponent { foreground = JBUI.CurrentTheme.NotificationWarning.foregroundColor() }.component } }.apply { background = JBUI.CurrentTheme.NotificationWarning.backgroundColor() diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 81bb8158..36750c41 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -18,6 +18,7 @@ +