diff --git a/changelog.d/19.fixed.md b/changelog.d/19.fixed.md new file mode 100644 index 00000000..eeb7c766 --- /dev/null +++ b/changelog.d/19.fixed.md @@ -0,0 +1 @@ +Target selection dialog is now responsive. \ No newline at end of file diff --git a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordApi.kt b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordApi.kt index 3a7d266e..949861c7 100644 --- a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordApi.kt +++ b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordApi.kt @@ -51,10 +51,13 @@ data class MirrordExecution( * Interact with mirrord CLI using this API. */ object MirrordApi { - const val targetlessTargetName = "No Target (\"targetless\")" private val logger = MirrordLogger.logger - /** run mirrord ls, return list of pods + targetless target. */ + /** + * Runs `mirrord ls` to get the list of available targets. + * + * @return list of pods + */ fun listPods( cli: String, configFile: String?, @@ -118,7 +121,6 @@ object MirrordApi { ) } - pods.add(targetlessTargetName) return pods } diff --git a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecDialog.kt b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecDialog.kt index cde7a208..783987d1 100644 --- a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecDialog.kt +++ b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecDialog.kt @@ -4,11 +4,11 @@ import com.intellij.openapi.ui.DialogBuilder import com.intellij.openapi.ui.DialogWrapper import com.intellij.ui.components.JBList import com.intellij.ui.components.JBScrollPane -import java.awt.* +import com.intellij.util.ui.JBUI +import java.awt.Dimension import java.awt.event.KeyEvent import java.awt.event.KeyListener import javax.swing.* -import javax.swing.border.EmptyBorder import javax.swing.event.DocumentEvent import javax.swing.event.DocumentListener @@ -17,9 +17,18 @@ object MirrordExecDialog { private const val dialogHeading: String = "mirrord" private const val targetLabel = "Select Target" - /** returns null if dialog cancelled or closed */ - fun selectTargetDialog(targets: List): String? { - var targets = targets.sorted().toMutableList() + /** + * Label that's used to select targetless mode + */ + const val targetlessTargetName = "No Target (\"targetless\")" + + /** + * Shows a target selection dialog. + * + * @return a target selected from the given list, targetlessTargetName constant if user selected targetless, null if the user cancelled + */ + fun selectTargetDialog(podTargets: List): String? { + val targets = podTargets.sorted().toMutableList() MirrordSettingsState.instance.mirrordState.lastChosenTarget?.let { val idx = targets.indexOf(it) if (idx != -1) { @@ -27,6 +36,7 @@ object MirrordExecDialog { targets.add(0, it) } } + targets.add(targetlessTargetName) val jbTargets = targets.asJBList() val searchField = JTextField() @@ -37,7 +47,10 @@ object MirrordExecDialog { private fun updateList() { val searchTerm = searchField.text - val filteredTargets = targets.filter { it.contains(searchTerm, true) }.sorted() + val filteredTargets = targets + .dropLast(1) // targetless is always last + .filter { it.contains(searchTerm, true) } + .sorted() + targetlessTargetName jbTargets.setListData(filteredTargets.toTypedArray()) } @@ -46,11 +59,11 @@ object MirrordExecDialog { // Add focus logic then we can change back and forth from search field // to target selection using tab/shift+tab searchField.addKeyListener(object : KeyListener { - override fun keyTyped(p0: KeyEvent?) { + override fun keyTyped(p0: KeyEvent) { } - override fun keyPressed(e: KeyEvent?) { - if (e?.keyCode === KeyEvent.VK_TAB) { + override fun keyPressed(e: KeyEvent) { + if (e.keyCode == KeyEvent.VK_TAB) { if (e.modifiersEx > 0) { searchField.transferFocusBackward() } else { @@ -60,19 +73,17 @@ object MirrordExecDialog { } } - override fun keyReleased(p0: KeyEvent?) { + override fun keyReleased(p0: KeyEvent) { } }) val result = DialogBuilder().apply { - setCenterPanel(JPanel(BorderLayout()).apply { - add(createSelectionDialog(targetLabel, jbTargets, searchField), BorderLayout.WEST) - }) + setCenterPanel(createSelectionDialog(jbTargets, searchField)) setTitle(dialogHeading) }.show() if (result == DialogWrapper.OK_EXIT_CODE) { if (jbTargets.isSelectionEmpty) { // The user did not select any target, and clicked ok. - return MirrordApi.targetlessTargetName + return targetlessTargetName } val selectedValue = jbTargets.selectedValue MirrordSettingsState.instance.mirrordState.lastChosenTarget = selectedValue @@ -86,25 +97,24 @@ object MirrordExecDialog { selectionMode = ListSelectionModel.SINGLE_SELECTION } - private fun createSelectionDialog(label: String, items: JBList, searchField: JTextField): JPanel = - JPanel().apply { - layout = BoxLayout(this, BoxLayout.Y_AXIS) - border = EmptyBorder(10, 5, 10, 5) - add(JLabel(label).apply { - alignmentX = JLabel.LEFT_ALIGNMENT - }) - add(Box.createRigidArea(Dimension(0, 5))) - add(searchField.apply { - alignmentX = JBScrollPane.LEFT_ALIGNMENT - preferredSize = Dimension(250, 30) - size = Dimension(250, 30) - }) - add(JBScrollPane(items).apply { - alignmentX = JBScrollPane.LEFT_ALIGNMENT - preferredSize = Dimension(250, 350) - size = Dimension(250, 350) - }) - } - - + private fun createSelectionDialog(items: JBList, searchField: JTextField): JPanel = + JPanel().apply { + layout = BoxLayout(this, BoxLayout.Y_AXIS) + border = JBUI.Borders.empty(10, 5) + add(JLabel(targetLabel).apply { + alignmentX = JLabel.LEFT_ALIGNMENT + }) + add(Box.createRigidArea(Dimension(0, 10))) + add(searchField.apply { + alignmentX = JBScrollPane.LEFT_ALIGNMENT + preferredSize = Dimension(250, 30) + size = Dimension(250, 30) + }) + add(Box.createRigidArea(Dimension(0, 10))) + add(JBScrollPane(items.apply { + minimumSize = Dimension(250, 350) + }).apply { + alignmentX = JBScrollPane.LEFT_ALIGNMENT + }) + } } diff --git a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecManager.kt b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecManager.kt index 7f1e8d51..ce67288c 100644 --- a/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecManager.kt +++ b/modules/core/src/main/kotlin/com/metalbear/mirrord/MirrordExecManager.kt @@ -27,7 +27,6 @@ object MirrordExecManager { false -> null } - // includes targetless target. val pods = MirrordApi.listPods( cli, configPath, @@ -110,8 +109,8 @@ object MirrordExecManager { MirrordNotifier.notify("mirrord loading canceled.", NotificationType.WARNING, project) return null } - if (target == MirrordApi.targetlessTargetName) { - MirrordLogger.logger.warn("No target specified - running targetless") + if (target == MirrordExecDialog.targetlessTargetName) { + MirrordLogger.logger.info("No target specified - running targetless") MirrordNotifier.notify("No target specified, mirrord running targetless.", NotificationType.INFORMATION, project) target = null }