mirror of
https://github.com/Gu1llaum-3/sshm.git
synced 2025-09-07 13:20:40 +02:00
feat: implement dynamic table sizing based on available terminal space
This commit is contained in:
parent
959c084466
commit
8f2837db78
@ -130,4 +130,119 @@ func (m *Model) updateTableRows() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.table.SetRows(rows)
|
m.table.SetRows(rows)
|
||||||
|
|
||||||
|
// Update table height and columns based on current terminal size
|
||||||
|
m.updateTableHeight()
|
||||||
|
m.updateTableColumns()
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateTableHeight dynamically adjusts table height based on terminal size
|
||||||
|
func (m *Model) updateTableHeight() {
|
||||||
|
if !m.ready {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate dynamic table height based on terminal size
|
||||||
|
// Layout breakdown:
|
||||||
|
// - ASCII title: 5 lines (1 empty + 4 text lines)
|
||||||
|
// - Search bar: 1 line
|
||||||
|
// - Sort info: 1 line
|
||||||
|
// - Help text: 2 lines (multi-line text)
|
||||||
|
// - App margins/spacing: 2 lines
|
||||||
|
// Total reserved: 11 lines, mais réduisons à 7 pour forcer plus d'espace
|
||||||
|
reservedHeight := 7 // Réduction agressive pour tester
|
||||||
|
availableHeight := m.height - reservedHeight
|
||||||
|
hostCount := len(m.table.Rows())
|
||||||
|
|
||||||
|
// Minimum height should be at least 5 rows for usability
|
||||||
|
minTableHeight := 6 // 1 header + 5 data rows
|
||||||
|
maxTableHeight := availableHeight
|
||||||
|
if maxTableHeight < minTableHeight {
|
||||||
|
maxTableHeight = minTableHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
tableHeight := 1 // header
|
||||||
|
dataRowsNeeded := hostCount
|
||||||
|
maxDataRows := maxTableHeight - 1 // subtract 1 for header
|
||||||
|
|
||||||
|
if dataRowsNeeded <= maxDataRows {
|
||||||
|
// We have enough space for all hosts
|
||||||
|
tableHeight += dataRowsNeeded
|
||||||
|
} else {
|
||||||
|
// We need to limit to available space
|
||||||
|
tableHeight += maxDataRows
|
||||||
|
}
|
||||||
|
|
||||||
|
// FORCE: Ajoutons une ligne supplémentaire pour résoudre le problème
|
||||||
|
tableHeight += 1
|
||||||
|
|
||||||
|
// Update table height
|
||||||
|
m.table.SetHeight(tableHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateTableColumns dynamically adjusts table column widths based on terminal size
|
||||||
|
func (m *Model) updateTableColumns() {
|
||||||
|
if !m.ready {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hostsToShow := m.filteredHosts
|
||||||
|
if hostsToShow == nil {
|
||||||
|
hostsToShow = m.hosts
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate base column widths
|
||||||
|
nameWidth := calculateNameColumnWidth(hostsToShow)
|
||||||
|
tagsWidth := calculateTagsColumnWidth(hostsToShow)
|
||||||
|
lastLoginWidth := calculateLastLoginColumnWidth(hostsToShow, m.historyManager)
|
||||||
|
|
||||||
|
// Fixed column widths
|
||||||
|
hostnameWidth := 25
|
||||||
|
userWidth := 12
|
||||||
|
portWidth := 6
|
||||||
|
|
||||||
|
// Calculate total width needed for all columns
|
||||||
|
totalFixedWidth := hostnameWidth + userWidth + portWidth
|
||||||
|
totalVariableWidth := nameWidth + tagsWidth + lastLoginWidth
|
||||||
|
totalWidth := totalFixedWidth + totalVariableWidth
|
||||||
|
|
||||||
|
// Available width (accounting for table borders and padding)
|
||||||
|
availableWidth := m.width - 4 // 4 chars for borders and padding
|
||||||
|
|
||||||
|
// If the table is too wide, scale down the variable columns proportionally
|
||||||
|
if totalWidth > availableWidth {
|
||||||
|
excessWidth := totalWidth - availableWidth
|
||||||
|
variableColumnsWidth := totalVariableWidth
|
||||||
|
|
||||||
|
if variableColumnsWidth > 0 {
|
||||||
|
// Reduce variable columns proportionally
|
||||||
|
nameReduction := (excessWidth * nameWidth) / variableColumnsWidth
|
||||||
|
tagsReduction := (excessWidth * tagsWidth) / variableColumnsWidth
|
||||||
|
lastLoginReduction := excessWidth - nameReduction - tagsReduction
|
||||||
|
|
||||||
|
nameWidth = max(8, nameWidth-nameReduction)
|
||||||
|
tagsWidth = max(8, tagsWidth-tagsReduction)
|
||||||
|
lastLoginWidth = max(10, lastLoginWidth-lastLoginReduction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new columns with updated widths
|
||||||
|
columns := []table.Column{
|
||||||
|
{Title: "Name", Width: nameWidth},
|
||||||
|
{Title: "Hostname", Width: hostnameWidth},
|
||||||
|
{Title: "User", Width: userWidth},
|
||||||
|
{Title: "Port", Width: portWidth},
|
||||||
|
{Title: "Tags", Width: tagsWidth},
|
||||||
|
{Title: "Last Login", Width: lastLoginWidth},
|
||||||
|
}
|
||||||
|
|
||||||
|
m.table.SetColumns(columns)
|
||||||
|
}
|
||||||
|
|
||||||
|
// max returns the maximum of two integers
|
||||||
|
func max(a, b int) int {
|
||||||
|
if a > b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
@ -99,21 +99,12 @@ func NewModel(hosts []config.SSHHost, configFile string) Model {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine table height: 1 (header) + number of hosts (max 10)
|
// Create the table with initial height (will be updated on first WindowSizeMsg)
|
||||||
hostCount := len(rows)
|
|
||||||
tableHeight := 1 // header
|
|
||||||
if hostCount < 10 {
|
|
||||||
tableHeight += hostCount
|
|
||||||
} else {
|
|
||||||
tableHeight += 10
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the table
|
|
||||||
t := table.New(
|
t := table.New(
|
||||||
table.WithColumns(columns),
|
table.WithColumns(columns),
|
||||||
table.WithRows(rows),
|
table.WithRows(rows),
|
||||||
table.WithFocused(true),
|
table.WithFocused(true),
|
||||||
table.WithHeight(tableHeight),
|
table.WithHeight(10), // Initial height, will be recalculated dynamically
|
||||||
)
|
)
|
||||||
|
|
||||||
// Style the table
|
// Style the table
|
||||||
@ -135,6 +126,9 @@ func NewModel(hosts []config.SSHHost, configFile string) Model {
|
|||||||
// Initialize table styles based on initial focus state
|
// Initialize table styles based on initial focus state
|
||||||
m.updateTableStyles()
|
m.updateTableStyles()
|
||||||
|
|
||||||
|
// The table height will be properly set on the first WindowSizeMsg
|
||||||
|
// when m.ready becomes true and actual terminal dimensions are known
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,10 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
m.styles = NewStyles(m.width)
|
m.styles = NewStyles(m.width)
|
||||||
m.ready = true
|
m.ready = true
|
||||||
|
|
||||||
|
// Update table height and columns based on new window size
|
||||||
|
m.updateTableHeight()
|
||||||
|
m.updateTableColumns()
|
||||||
|
|
||||||
// Update sub-forms if they exist
|
// Update sub-forms if they exist
|
||||||
if m.addForm != nil {
|
if m.addForm != nil {
|
||||||
m.addForm.width = m.width
|
m.addForm.width = m.width
|
||||||
|
@ -39,7 +39,7 @@ func (m Model) renderListView() string {
|
|||||||
components = append(components, m.styles.Header.Render(asciiTitle))
|
components = append(components, m.styles.Header.Render(asciiTitle))
|
||||||
|
|
||||||
// Add the search bar with the appropriate style based on focus
|
// Add the search bar with the appropriate style based on focus
|
||||||
searchPrompt := "Search (/ to focus, Tab to switch): "
|
searchPrompt := "Search (/ to focus): "
|
||||||
if m.searchMode {
|
if m.searchMode {
|
||||||
components = append(components, m.styles.SearchFocused.Render(searchPrompt+m.searchInput.View()))
|
components = append(components, m.styles.SearchFocused.Render(searchPrompt+m.searchInput.View()))
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user