feat: Task 16 — SSH Session Tab (multi-session)
- pkg/tui/session.go — SessionTab with live SSH terminal in a tab - pkg/tui/messages.go — quitMsg, openSessionMsg, sessionOutputMsg - pkg/tui/tabs.go — Tab.Close() interface, Add() returns tea.Cmd - pkg/tui/host_list_tab.go — Enter opens session tab, q quits - pkg/tui/tui.go — handle openSessionMsg/quitMsg, SetDataDir - cmd/hostkeeper/tui.go — pass dataDir to model
This commit is contained in:
+23
-2
@@ -23,6 +23,7 @@ type Model struct {
|
||||
SelectedIndex int // deprecated
|
||||
Error error
|
||||
Quit bool
|
||||
dataDir string
|
||||
}
|
||||
|
||||
// New creates a new TUI model
|
||||
@@ -47,11 +48,26 @@ func (m *Model) Init() tea.Cmd {
|
||||
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "ctrl+c", "q":
|
||||
// Only hard quit on ctrl+c (let tabs handle q)
|
||||
if msg.String() == "ctrl+c" {
|
||||
m.Quit = true
|
||||
return m, tea.Quit
|
||||
}
|
||||
|
||||
case quitMsg:
|
||||
m.Quit = true
|
||||
return m, tea.Quit
|
||||
|
||||
case openSessionMsg:
|
||||
tab := NewSessionTab(msg.host, m.dataDir)
|
||||
cmd := m.tabs.Add(tab)
|
||||
return m, cmd
|
||||
|
||||
case sessionDoneMsg:
|
||||
if msg.err != nil {
|
||||
m.Error = msg.err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
cmd, err := m.tabs.Update(msg)
|
||||
@@ -94,6 +110,11 @@ func (m *Model) LoadHosts(hosts []*models.Host) {
|
||||
}
|
||||
}
|
||||
|
||||
// SetDataDir sets the data directory for SSH connections
|
||||
func (m *Model) SetDataDir(dir string) {
|
||||
m.dataDir = dir
|
||||
}
|
||||
|
||||
// TabManager returns the underlying tab manager
|
||||
func (m *Model) TabManager() *TabManager {
|
||||
return m.tabs
|
||||
|
||||
Reference in New Issue
Block a user