making improvements based on copilot's suggestions from previous merge with main: subtracting the label heights from available heights before calculating the list height, to avoid potential layer overflow, in pkg/tui/views/view.go; creating a handler function for refreshing issue list and updating detail view, to avoid duplicate logic in pkg/tui/views/operations.go

This commit is contained in:
viljarb
2026-02-23 13:50:23 +01:00
parent d8d2994c8a
commit 7674ae3690
2 changed files with 29 additions and 42 deletions

View File

@@ -82,6 +82,25 @@ func deleteIssueCmd(svc *service.Services, issueID string, currentIndex int) tea
} }
} }
func (m *Model) refreshIssueListsAndSelectIssue(issueID string) tea.Cmd {
/* update handler for issueTitleUpdatedMsg, issueDescriptionUpdatedMsg, and issueStatusUpdatedMsg to avoid using nearly identical code for refreshing the issue lists and updating the detail view
Fetch all issues, update both lists, set the detail view for the given issue, and return a command to select that issue. Returns nil if fetch fails.
*/
issues, err := m.svc.Beads.AllIssues(context.Background())
if err != nil {
return nil
}
setItemsCmd := m.issueList.SetIssues(OpenAndInProgressOnly(issues))
closedSetCmd := m.closedIssueList.SetIssues(ClosedOnly(issues))
for _, issue := range issues {
if issue.ID == issueID {
m.issueDetail.SetIssue(issue)
break
}
}
return tea.Sequence(setItemsCmd, closedSetCmd, func() tea.Msg { return selectIssueMsg{IssueID: issueID} })
}
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case issueTitleUpdatedMsg: case issueTitleUpdatedMsg:
@@ -91,19 +110,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if msg.Err != nil { if msg.Err != nil {
return m, nil return m, nil
} }
issues, err := m.svc.Beads.AllIssues(context.Background()) return m, m.refreshIssueListsAndSelectIssue(msg.IssueID)
if err != nil {
return m, nil
}
setItemsCmd := m.issueList.SetIssues(OpenAndInProgressOnly(issues))
closedSetCmd := m.closedIssueList.SetIssues(ClosedOnly(issues))
for _, issue := range issues {
if issue.ID == msg.IssueID {
m.issueDetail.SetIssue(issue)
break
}
}
return m, tea.Sequence(setItemsCmd, closedSetCmd, func() tea.Msg { return selectIssueMsg{IssueID: msg.IssueID} })
case issueDescriptionUpdatedMsg: case issueDescriptionUpdatedMsg:
m.editingDescription = false m.editingDescription = false
@@ -112,19 +119,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if msg.Err != nil { if msg.Err != nil {
return m, nil return m, nil
} }
issues, err := m.svc.Beads.AllIssues(context.Background()) return m, m.refreshIssueListsAndSelectIssue(msg.IssueID)
if err != nil {
return m, nil
}
setItemsCmd := m.issueList.SetIssues(OpenAndInProgressOnly(issues))
closedSetCmd := m.closedIssueList.SetIssues(ClosedOnly(issues))
for _, issue := range issues {
if issue.ID == msg.IssueID {
m.issueDetail.SetIssue(issue)
break
}
}
return m, tea.Sequence(setItemsCmd, closedSetCmd, func() tea.Msg { return selectIssueMsg{IssueID: msg.IssueID} })
case issueStatusUpdatedMsg: case issueStatusUpdatedMsg:
m.choosingStatus = false m.choosingStatus = false
@@ -132,19 +127,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if msg.Err != nil { if msg.Err != nil {
return m, nil return m, nil
} }
issues, err := m.svc.Beads.AllIssues(context.Background()) return m, m.refreshIssueListsAndSelectIssue(msg.IssueID)
if err != nil {
return m, nil
}
setItemsCmd := m.issueList.SetIssues(OpenAndInProgressOnly(issues))
closedSetCmd := m.closedIssueList.SetIssues(ClosedOnly(issues))
for _, issue := range issues {
if issue.ID == msg.IssueID {
m.issueDetail.SetIssue(issue)
break
}
}
return m, tea.Sequence(setItemsCmd, closedSetCmd, func() tea.Msg { return selectIssueMsg{IssueID: msg.IssueID} })
case selectIssueMsg: case selectIssueMsg:
m.issueList.SelectIssueID(msg.IssueID) m.issueList.SelectIssueID(msg.IssueID)

View File

@@ -18,8 +18,14 @@ func (m *Model) View() string {
footer := m.footer() footer := m.footer()
footerHeight := lipgloss.Height(footer) footerHeight := lipgloss.Height(footer)
// To avoid layer overflow or clipping, the label heights are calculated and subtracted from the available height before calculating the list heights to avoid layout overflow or clipping.
contentHeight := m.height - headerHeight - footerHeight contentHeight := m.height - headerHeight - footerHeight
halfHeight := contentHeight / 2
mainLabel := styles.LabelStyle.Render("Display issues")
closedLabel := styles.LabelStyle.Render("Closed issues")
labelHeight := lipgloss.Height(mainLabel) + lipgloss.Height(closedLabel)
availableForLists := contentHeight - labelHeight
halfHeight := availableForLists / 2
if halfHeight < 1 { if halfHeight < 1 {
halfHeight = 1 halfHeight = 1
} }
@@ -36,8 +42,6 @@ func (m *Model) View() string {
closedListView := m.closedIssueList.View() closedListView := m.closedIssueList.View()
detailView := m.issueDetail.View() detailView := m.issueDetail.View()
mainLabel := styles.LabelStyle.Render("Display issues")
closedLabel := styles.LabelStyle.Render("Closed issues")
if m.focusedWindow == 0 { if m.focusedWindow == 0 {
mainLabel = lipgloss.NewStyle().Foreground(styles.Primary).Bold(true).Render("Display issues ▶") mainLabel = lipgloss.NewStyle().Foreground(styles.Primary).Bold(true).Render("Display issues ▶")
} else { } else {