adding assignee for tui

This commit is contained in:
viljarb
2026-03-11 21:23:07 +01:00
parent 7ceb0929c5
commit 0b4e33b28f
15 changed files with 184 additions and 16 deletions

View File

@@ -21,6 +21,7 @@ type DashboardKeyMap struct {
ChangeStatus key.Binding
ChangePriority key.Binding
ChangeType key.Binding
ChangeAssignee key.Binding
AddComment key.Binding
AddIssue key.Binding
DeleteIssue key.Binding
@@ -56,6 +57,10 @@ var defaultDashboardKeyMap = DashboardKeyMap{
key.WithKeys("t"),
key.WithHelp("t", "change type"),
),
ChangeAssignee: key.NewBinding(
key.WithKeys("A"),
key.WithHelp("A", "change assignee"),
),
AddComment: key.NewBinding(
key.WithKeys("c"),
key.WithHelp("c", "add comment"),
@@ -127,12 +132,18 @@ func (d *Model) handleKeyMsg(msg tea.KeyMsg) tea.Cmd {
d.startChooseType(selected)
d.logAction("tui opened type picker")
}
case !d.IsInModal() && !d.addingComment && key.Matches(msg, d.keyMap.ChangeAssignee):
if selected := d.FocusedIssueList().SelectedItem(); selected.ID != "" {
d.startEditAssignee(selected)
cmd = d.assigneeInput.Focus()
d.logAction("tui started editing assignee")
}
case !d.IsInModal() && !d.addingComment && key.Matches(msg, d.keyMap.AddComment):
if selected := d.FocusedIssueList().SelectedItem(); selected.ID != "" {
d.startAddComment(selected)
cmd = d.commentInput.Focus()
}
case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && !d.addingComment && key.Matches(msg, d.keyMap.AddIssue):
case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && !d.editingAssignee && !d.addingComment && key.Matches(msg, d.keyMap.AddIssue):
d.startCreateIssue()
cmd = d.createTitleInput.Focus()
d.logAction("tui started creating issue")

View File

@@ -52,6 +52,9 @@ type Model struct {
priorityIssueID string
choosingType bool // true while choosing a type
typeIssueID string
editingAssignee bool // true while editing assignee
assigneeInput textinput.Model
assigneeIssueID string
addingComment bool // true while adding a comment
commentInput textarea.Model
commentIssueID string
@@ -87,6 +90,7 @@ func NewDashboard(app *app.App, feedbackChan chan models.ValidationFeedback, qui
m.titleInput = inputs.Title
m.createTitleInput = inputs.CreateTitle
m.descriptionInput = inputs.Description
m.assigneeInput = inputs.Assignee
commentTa := textarea.New()
commentTa.Placeholder = "Write your comment..."
@@ -171,6 +175,13 @@ func (m *Model) startChooseType(selected ListIssue) {
m.typeIssueID = selected.ID
}
func (m *Model) startEditAssignee(selected ListIssue) {
m.editingAssignee = true
m.assigneeIssueID = selected.ID
m.assigneeInput.SetValue(selected.Assignee)
m.assigneeInput.CursorEnd()
}
func (m *Model) Init() tea.Cmd {
return components.ListenForValidation(m.feedbackChan)
}
@@ -178,7 +189,7 @@ func (m *Model) Init() tea.Cmd {
// IsInModal returns true when a modal (edit, create, delete confirm, choose status/priority/type) is active.
func (m *Model) IsInModal() bool {
return m.editingTitle || m.creatingIssue || m.editingDescription ||
m.choosingStatus || m.choosingPriority || m.confirmingDelete || m.choosingType
m.choosingStatus || m.choosingPriority || m.confirmingDelete || m.choosingType || m.editingAssignee
}
func (m *Model) IsFocusedOnList() bool {

View File

@@ -211,6 +211,17 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.logAction("tui updated issue type")
return m, m.refreshIssueListsAndSelectIssue(msg.IssueID)
case issues.AssigneeUpdatedMsg:
m.editingAssignee = false
m.assigneeIssueID = ""
m.assigneeInput.Blur()
if msg.Err != nil {
m.logAction("tui failed to update issue assignee")
return m, nil
}
m.logAction("tui updated issue assignee")
return m, m.refreshIssueListsAndSelectIssue(msg.IssueID)
case issues.SelectIssueMsg:
m.issueList.SelectIssueID(msg.IssueID)
m.closedIssueList.SelectIssueID(msg.IssueID)
@@ -444,6 +455,24 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, cmd
}
if m.editingAssignee {
if msg.String() == "enter" {
assignee := m.assigneeInput.Value()
m.logAction("tui submitted assignee edit")
return m, issues.UpdateIssueAssigneeCmd(m.app, m.assigneeIssueID, assignee)
}
if msg.String() == "esc" {
m.logAction("tui canceled assignee edit")
m.editingAssignee = false
m.assigneeIssueID = ""
m.assigneeInput.Blur()
return m, nil
}
var cmd tea.Cmd
m.assigneeInput, cmd = m.assigneeInput.Update(msg)
return m, cmd
}
if m.editingTitle {
if msg.String() == "enter" {
newTitle := m.titleInput.Value()

View File

@@ -61,6 +61,20 @@ func (m *Model) View() string {
mainView := lipgloss.JoinVertical(lipgloss.Left, header, content, footer)
if m.editingAssignee {
editBoxWidth := min(60, m.width-4)
m.assigneeInput.Width = editBoxWidth - 2
editContent := lipgloss.JoinVertical(lipgloss.Left,
styles.LabelStyle.Render("Edit assignee (Enter to save, Esc to cancel):"),
m.assigneeInput.View(),
)
editBox := styles.ContainerStyle.
Width(editBoxWidth).
BorderForeground(styles.PrimaryBorder).
Render(editContent)
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, editBox)
}
if m.editingTitle {
editBoxWidth := min(60, m.width-4)
m.titleInput.Width = editBoxWidth - 2