From 4e1e343858de6ebee3ebdd6b6b555a39333d1460 Mon Sep 17 00:00:00 2001 From: Tomasz Turkowski Date: Fri, 3 Jul 2026 13:25:03 +0200 Subject: [PATCH] Update window title bar based on step or view --- internal/devtui/model_test.go | 34 ++++++++++++++++++++++++++++++++++ internal/devtui/model_view.go | 18 +++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/internal/devtui/model_test.go b/internal/devtui/model_test.go index eb9c91ca..2f316d01 100644 --- a/internal/devtui/model_test.go +++ b/internal/devtui/model_test.go @@ -633,3 +633,37 @@ func TestStartStorefrontWatchRequest_OpensPicker(t *testing.T) { _, ok := m.modal.(*salesChannelPicker) assert.True(t, ok, "parent must open the sales-channel picker on the request") } + +func TestView_WindowTitlePerPhase(t *testing.T) { + cases := []struct { + phase phase + wantTitle string + }{ + {phaseDashboard, "[project] · Overview"}, + {phaseStarting, "[project] · Starting..."}, + {phaseStopping, "[project] · Stopping"}, + {phaseInstallPrompt, "[project] · Install"}, + {phaseInstalling, "[project] · Installing..."}, + {phaseMigrationWizard, "[project] · Setup"}, + } + + for _, tc := range cases { + m := newTestModel() + m.width = 120 + m.height = 40 + m.phase = tc.phase + if tc.phase == phaseMigrationWizard { + m.migrationWizard = newMigrationWizard("") + } + if tc.phase == phaseStarting || tc.phase == phaseStopping { + m.dockerSpinner = newBrandSpinner() + } + if tc.phase == phaseInstalling { + m.installProg.spinner = newBrandSpinner() + m.installProg.progress = newInstallProgress() + } + + v := m.View() + assert.Equal(t, tc.wantTitle, v.WindowTitle, "phase %d", tc.phase) + } +} diff --git a/internal/devtui/model_view.go b/internal/devtui/model_view.go index 0559f359..1844c6c9 100644 --- a/internal/devtui/model_view.go +++ b/internal/devtui/model_view.go @@ -2,6 +2,7 @@ package devtui import ( "fmt" + "path/filepath" "strings" tea "charm.land/bubbletea/v2" @@ -17,12 +18,24 @@ func (m Model) View() tea.View { v := tea.NewView("") v.AltScreen = true + dir := "[" + filepath.Base(m.projectRoot) + "] · " switch m.phase { case phaseDashboard: v.Content = m.renderDashboard() - case phaseStarting, phaseStopping, phaseInstallPrompt, phaseInstalling: + v.WindowTitle = dir + tabNames[m.activeTab] + case phaseStarting: + v.Content = m.renderPhase() + v.WindowTitle = dir + "Starting..." + case phaseStopping: + v.Content = m.renderPhase() + v.WindowTitle = dir + "Stopping" + case phaseInstallPrompt: + v.Content = m.renderPhase() + v.WindowTitle = dir + "Install" + case phaseInstalling: v.Content = m.renderPhase() + v.WindowTitle = dir + "Installing..." case phaseTask: title := m.taskTitle if !m.taskDone { @@ -31,6 +44,9 @@ func (m Model) View() tea.View { v.Content = m.renderDockerLogs(title, "") case phaseMigrationWizard: v.Content = m.renderMigrationWizard() + v.WindowTitle = dir + "Setup" + default: + v.WindowTitle = dir + "shopware-cli" } if m.modal != nil {