fix(jetbrains): collapse expandable session views

This commit is contained in:
kirillk
2026-05-21 12:54:18 -04:00
parent 46b0ea1a17
commit 525bfc9b32
5 changed files with 43 additions and 45 deletions
@@ -0,0 +1,5 @@
---
"@kilocode/kilo-jetbrains": patch
---
Start expandable session sections collapsed by default.
@@ -391,7 +391,7 @@ class SessionHeaderPanel(
expand.accessibleContext.accessibleName = KiloBundle.message(key)
}
private fun expanded() = PropertiesComponent.getInstance().getBoolean(EXPANDED_KEY, true)
private fun expanded() = PropertiesComponent.getInstance().getBoolean(EXPANDED_KEY, false)
private fun sizeTimeline() {
val size = timeline.preferredSize
@@ -109,7 +109,6 @@ class ReasoningView(reasoning: Reasoning) : PartView() {
body.add(md.component, BorderLayout.CENTER)
add(header, BorderLayout.NORTH)
if (canExpand()) add(scroll, BorderLayout.CENTER)
sync()
}
@@ -122,7 +121,6 @@ class ReasoningView(reasoning: Reasoning) : PartView() {
md.set(source)
changed = true
}
changed = syncBody() || changed
changed = sync() || changed
if (changed) refresh()
}
@@ -131,8 +129,7 @@ class ReasoningView(reasoning: Reasoning) : PartView() {
if (delta.isEmpty()) return
source += delta
md.append(delta)
var changed = syncBody()
changed = sync() || changed
val changed = sync()
if (changed || bodyVisible()) refresh()
}
@@ -209,12 +206,6 @@ class ReasoningView(reasoning: Reasoning) : PartView() {
return changed
}
private fun syncBody(): Boolean {
if (!canExpand()) return collapse()
if (bodyVisible()) return false
return expand()
}
private fun setVisible(component: JBLabel, visible: Boolean): Boolean {
if (component.isVisible == visible) return false
component.isVisible = visible
@@ -54,7 +54,7 @@ class SessionHeaderPanelTest : SessionControllerTestBase() {
val style = SessionEditorStyle.current()
assertTrue(panel.isVisible)
assertTrue(panel.isExpanded())
assertFalse(panel.isExpanded())
assertEquals("Generated title", panel.titleText())
assertEquals("$0.07", panel.costText())
assertEquals("1%", panel.contextText())
@@ -135,6 +135,9 @@ class SessionHeaderPanelTest : SessionControllerTestBase() {
val timeline = panel.timelinePanel()
val bar = panel.contextBar()
assertFalse(panel.isExpanded())
panel.expandButton().doClick()
assertTrue(panel.isExpanded())
assertSame(body, panel.bodyPanel())
assertSame(timeline, panel.timelinePanel())
@@ -244,26 +247,27 @@ class SessionHeaderPanelTest : SessionControllerTestBase() {
val c = promptedHeader()
val panel = SessionHeaderPanel(c, parent)
assertTrue(panel.isExpanded())
assertEquals("Hide session metrics", panel.expandTip())
panel.expandButton().doClick()
emit(ChatEventDto.SessionUpdated("ses_test", session("ses_test", title = "New title")))
assertFalse(panel.isExpanded())
assertEquals("Show session metrics", panel.expandTip())
panel.expandButton().doClick()
emit(ChatEventDto.MessageUpdated("ses_test", assistant(cost = 0.2)))
emit(ChatEventDto.SessionUpdated("ses_test", session("ses_test", title = "New title")))
assertTrue(panel.isExpanded())
assertEquals("Hide session metrics", panel.expandTip())
panel.expandButton().doClick()
emit(ChatEventDto.MessageUpdated("ses_test", assistant(cost = 0.2)))
assertFalse(panel.isExpanded())
assertEquals("Show session metrics", panel.expandTip())
}
fun `test collapse persists and new header starts collapsed`() {
val c = promptedHeader()
val panel = SessionHeaderPanel(c, parent)
panel.expandButton().doClick()
panel.expandButton().doClick()
assertFalse(panel.isExpanded())
@@ -294,6 +298,7 @@ class SessionHeaderPanelTest : SessionControllerTestBase() {
}
fun `test hidden empty header collapse keeps saved expansion preference`() {
PropertiesComponent.getInstance().setValue(SessionHeaderPanel.EXPANDED_KEY, "true")
appRpc.state.value = ai.kilocode.rpc.dto.KiloAppStateDto(ai.kilocode.rpc.dto.KiloAppStatusDto.READY)
projectRpc.state.value = workspaceReady()
val c = controller()
@@ -8,61 +8,58 @@ import javax.swing.ScrollPaneConstants
@Suppress("UnstableApiUsage")
class ReasoningViewTest : BasePlatformTestCase() {
fun `test completed reasoning is expanded by default`() {
fun `test completed reasoning is collapsed by default`() {
val view = ReasoningView(reasoning("p1", done = true, text = "one\ntwo\nthree\nfour"))
assertTrue(view.isExpanded())
assertFalse(view.isExpanded())
assertEquals("Reasoning", view.headerText())
assertEquals("one\ntwo\nthree\nfour", view.markdown())
assertTrue(view.hasToggle())
assertTrue(view.bodyVisible())
assertFalse(view.bodyVisible())
assertTrue(view.bodyCreated())
}
fun `test short completed reasoning is collapsible`() {
val view = ReasoningView(reasoning("p1", done = true, text = "one\ntwo\nthree"))
assertTrue(view.isExpanded())
assertFalse(view.isExpanded())
assertTrue(view.hasToggle())
view.toggle()
assertFalse(view.isExpanded())
assertFalse(view.bodyVisible())
assertTrue(view.isExpanded())
assertTrue(view.bodyVisible())
assertTrue(view.bodyCreated())
}
fun `test streaming reasoning is expanded by default`() {
fun `test streaming reasoning is collapsed by default`() {
val view = ReasoningView(reasoning("p1", done = false, text = "one\ntwo\nthree\nfour"))
assertTrue(view.isExpanded())
assertFalse(view.isExpanded())
assertTrue(view.hasToggle())
}
fun `test update to done preserves visible reasoning`() {
fun `test update to done preserves collapsed reasoning`() {
val view = ReasoningView(reasoning("p1", done = false, text = "one\ntwo\nthree\nfour"))
view.update(reasoning("p1", done = true, text = "one\ntwo\nthree\nfour"))
assertTrue(view.isExpanded())
assertFalse(view.isExpanded())
assertEquals("one\ntwo\nthree\nfour", view.markdown())
}
fun `test toggle opens and closes reasoning`() {
val view = ReasoningView(reasoning("p1", done = true, text = "one\ntwo\nthree\nfour"))
view.toggle()
assertTrue(view.isExpanded())
view.toggle()
assertFalse(view.isExpanded())
view.toggle()
assertTrue(view.isExpanded())
}
fun `test collapsed reasoning expands on update`() {
fun `test collapsed reasoning stays collapsed on update`() {
val view = ReasoningView(reasoning("p1", done = false, text = "one\ntwo"))
view.toggle()
view.update(reasoning("p1", done = true, text = "one\ntwo\nthree"))
assertTrue(view.isExpanded())
assertFalse(view.isExpanded())
assertEquals("one\ntwo\nthree", view.markdown())
}
@@ -72,39 +69,38 @@ class ReasoningViewTest : BasePlatformTestCase() {
view.appendDelta("b")
assertEquals("ab", view.markdown())
assertTrue(view.isExpanded())
assertFalse(view.isExpanded())
}
fun `test blank reasoning expands when delta arrives`() {
fun `test blank reasoning stays collapsed when delta arrives`() {
val view = ReasoningView(reasoning("p1", done = false, text = ""))
view.appendDelta("b")
assertEquals("b", view.markdown())
assertTrue(view.bodyCreated())
assertTrue(view.bodyVisible())
assertFalse(view.bodyVisible())
assertTrue(view.hasToggle())
}
fun `test collapsed append reattaches eager reasoning body`() {
fun `test collapsed append keeps eager reasoning body detached`() {
val view = ReasoningView(reasoning("p1", done = false, text = "a"))
view.toggle()
view.appendDelta("b")
assertEquals("ab", view.markdown())
assertTrue(view.bodyCreated())
assertTrue(view.bodyVisible())
assertFalse(view.bodyVisible())
}
fun `test collapsed update reattaches eager reasoning body`() {
fun `test collapsed update keeps eager reasoning body detached`() {
val view = ReasoningView(reasoning("p1", done = false, text = "a"))
view.toggle()
view.update(reasoning("p1", done = false, text = "abc"))
assertEquals("abc", view.markdown())
assertTrue(view.bodyCreated())
assertTrue(view.bodyVisible())
assertFalse(view.bodyVisible())
}
fun `test reasoning reuses eager markdown body`() {
@@ -116,7 +112,7 @@ class ReasoningViewTest : BasePlatformTestCase() {
view.toggle()
assertSame(component, view.md.component)
assertFalse(view.bodyVisible())
assertTrue(view.bodyVisible())
}
fun `test blank reasoning has no toggle`() {
@@ -158,6 +154,7 @@ class ReasoningViewTest : BasePlatformTestCase() {
fun `test expanded reasoning body is capped to five rows`() {
val view = ReasoningView(reasoning("p1", done = false, text = (1..20).joinToString("\n") { "line $it" }))
view.toggle()
assertEquals(5, view.bodyMaxRows())
assertTrue(view.preferredSize.height > 0)