diff --git a/CLAUDE.md b/CLAUDE.md index 4b7448f1..c9cd3505 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -149,15 +149,22 @@ GetEvents() - Streaming (socket) or polling (libpod) - Custom commands configurable via YAML - Command templates use Go template syntax +### GUI Features +- **Pod expand/collapse**: Pods can be expanded/collapsed in the containers panel. State tracked in `gui.State.ExpandedPods` map +- **Container sorting**: Controlled by `LegacySortContainers` config option: + - `false` (default): Sort by state (running → exited → created), then alphabetically + - `true`: Sort alphabetically by name only +- **Container list items**: `ContainerListItem` wraps both pods and containers for unified list display + ## Testing ```bash # Run all tests with coverage ./test.sh -# Run specific package tests -go test -mod=vendor ./pkg/commands/... -go test -mod=vendor ./pkg/gui/... +# Run specific package tests (requires build tags to avoid CGO dependencies) +go test -tags=containers_image_openpgp,exclude_graphdriver_btrfs -mod=vendor ./pkg/gui/... +go test -tags=containers_image_openpgp,exclude_graphdriver_btrfs -mod=vendor ./pkg/commands/... ``` ## Module Info diff --git a/pkg/gui/containers_panel.go b/pkg/gui/containers_panel.go index fff66416..00afbc63 100644 --- a/pkg/gui/containers_panel.go +++ b/pkg/gui/containers_panel.go @@ -138,7 +138,7 @@ func sortContainers(a *commands.Container, b *commands.Container, legacySort boo // sortContainerListItems sorts items to group pods with their containers. // Order: pods first (sorted alphabetically), then their containers indented (sorted alphabetically), // then standalone containers (sorted alphabetically). -func sortContainerListItems(a *commands.ContainerListItem, b *commands.ContainerListItem, _ bool) bool { +func sortContainerListItems(a *commands.ContainerListItem, b *commands.ContainerListItem, legacySort bool) bool { // Pods and their containers sort before standalone containers aInPod := a.IsPod || a.PodID() != "" bInPod := b.IsPod || b.PodID() != "" @@ -181,8 +181,17 @@ func sortContainerListItems(a *commands.ContainerListItem, b *commands.Container return a.Name() < b.Name() } - // Both are standalone containers: sort alphabetically - return a.Name() < b.Name() + // Both are standalone containers + if legacySort { + return a.Name() < b.Name() + } + // Sort by state, then by name + stateA := containerStates[a.State()] + stateB := containerStates[b.State()] + if stateA == stateB { + return a.Name() < b.Name() + } + return stateA < stateB } // Wrapper functions that delegate to container or pod rendering diff --git a/pkg/gui/sort_container_test.go b/pkg/gui/sort_container_test.go index 813da1d6..794292b8 100644 --- a/pkg/gui/sort_container_test.go +++ b/pkg/gui/sort_container_test.go @@ -250,17 +250,17 @@ func TestSortContainerListItems(t *testing.T) { return sortContainerListItems(items[i], items[j], false) }) - // Expected order: + // Expected order (with legacySort=false, sorts by state then name): // 1. pod alpha (alphabetically first pod) // 2. ant (container in alpha, alphabetically first) // 3. bear (container in alpha) // 4. pod beta (alphabetically second pod) // 5. xray (container in beta, alphabetically first) // 6. yak (container in beta) - // 7. apple (standalone, alphabetically first) - // 8. zebra (standalone) + // 7. zebra (standalone, running - state 1) + // 8. apple (standalone, exited - state 2) - expectedOrder := []string{"alpha", "ant", "bear", "beta", "xray", "yak", "apple", "zebra"} + expectedOrder := []string{"alpha", "ant", "bear", "beta", "xray", "yak", "zebra", "apple"} assert.Equal(t, len(expectedOrder), len(items)) for i, item := range items {