TASK BACKLOG REFINEMENT fix for closing reason
This commit is contained in:
@@ -46,23 +46,27 @@ type Model struct {
|
||||
deleteConfirmID string
|
||||
deleteConfirmIndex int
|
||||
|
||||
choosingStatus bool // true while choosing a status
|
||||
statusIssueID string
|
||||
choosingPriority bool // true while choosing a priority
|
||||
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
|
||||
feedbackChan chan models.ValidationFeedback
|
||||
quitChan chan bool
|
||||
currentFeedback models.ValidationFeedback
|
||||
showComplete bool
|
||||
submitChan chan<- struct{}
|
||||
choosingStatus bool
|
||||
statusIssueID string
|
||||
choosingPriority bool
|
||||
priorityIssueID string
|
||||
choosingType bool
|
||||
typeIssueID string
|
||||
editingAssignee bool
|
||||
assigneeInput textinput.Model
|
||||
assigneeIssueID string
|
||||
addingComment bool
|
||||
commentInput textarea.Model
|
||||
commentIssueID string
|
||||
choosingCloseReason bool
|
||||
closeReasonIssueID string
|
||||
closingOtherReason bool
|
||||
closeReasonInput textarea.Model
|
||||
feedbackChan chan models.ValidationFeedback
|
||||
quitChan chan bool
|
||||
currentFeedback models.ValidationFeedback
|
||||
showComplete bool
|
||||
submitChan chan<- struct{}
|
||||
}
|
||||
|
||||
func NewDashboard(app *app.App, feedbackChan chan models.ValidationFeedback, quitChan chan bool, submitChan chan<- struct{}) *Model {
|
||||
@@ -92,6 +96,12 @@ func NewDashboard(app *app.App, feedbackChan chan models.ValidationFeedback, qui
|
||||
m.descriptionInput = inputs.Description
|
||||
m.assigneeInput = inputs.Assignee
|
||||
|
||||
closeReasonTa := textarea.New()
|
||||
closeReasonTa.Placeholder = "Enter closing reason..."
|
||||
closeReasonTa.SetWidth(56)
|
||||
closeReasonTa.SetHeight(4)
|
||||
m.closeReasonInput = closeReasonTa
|
||||
|
||||
commentTa := textarea.New()
|
||||
commentTa.Placeholder = "Write your comment..."
|
||||
commentTa.SetWidth(56)
|
||||
@@ -189,7 +199,9 @@ 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.editingAssignee
|
||||
m.choosingStatus || m.choosingPriority || m.confirmingDelete ||
|
||||
m.choosingType || m.editingAssignee ||
|
||||
m.choosingCloseReason || m.closingOtherReason
|
||||
}
|
||||
|
||||
func (m *Model) IsFocusedOnList() bool {
|
||||
|
||||
@@ -361,11 +361,13 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.statusIssueID = ""
|
||||
return m, issues.UpdateIssueStatusCmd(m.app, issueID, string(models.StatusReadyToSprint))
|
||||
case "c":
|
||||
m.logAction("tui selected issue status closed")
|
||||
m.logAction("tui selected issue status closing")
|
||||
issueID := m.statusIssueID
|
||||
m.choosingStatus = false
|
||||
m.statusIssueID = ""
|
||||
return m, issues.UpdateIssueStatusCmd(m.app, issueID, string(models.StatusClosed))
|
||||
m.choosingCloseReason = true
|
||||
m.closeReasonIssueID = issueID
|
||||
return m, nil
|
||||
case "esc":
|
||||
m.logAction("tui canceled status picker")
|
||||
m.choosingStatus = false
|
||||
@@ -374,6 +376,64 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
if m.choosingCloseReason {
|
||||
var reason string
|
||||
switch msg.String() {
|
||||
case "d":
|
||||
m.logAction("tui selected close reason done")
|
||||
reason = "Done"
|
||||
case "u":
|
||||
m.logAction("tui selected close reason duplicate issue")
|
||||
reason = "Duplicate issue"
|
||||
case "w":
|
||||
m.logAction("tui selected close reason won't fix")
|
||||
reason = "Won't fix"
|
||||
case "o":
|
||||
m.logAction("tui selected close reason obsolete")
|
||||
reason = "Obsolete"
|
||||
case "h":
|
||||
m.logAction("tui selected close reason other")
|
||||
m.choosingCloseReason = false
|
||||
m.closingOtherReason = true
|
||||
m.closeReasonInput.SetValue("")
|
||||
return m, nil
|
||||
case "esc":
|
||||
m.logAction("tui canceled close reason picker")
|
||||
m.choosingCloseReason = false
|
||||
m.closeReasonIssueID = ""
|
||||
return m, nil
|
||||
}
|
||||
|
||||
if reason != "" {
|
||||
issueID := m.closeReasonIssueID
|
||||
m.choosingCloseReason = false
|
||||
m.closeReasonIssueID = ""
|
||||
return m, issues.CloseIssueCmd(m.app, issueID, reason)
|
||||
}
|
||||
}
|
||||
|
||||
if m.closingOtherReason {
|
||||
switch msg.String() {
|
||||
case "enter":
|
||||
reason := m.closeReasonInput.Value()
|
||||
if reason != "" {
|
||||
m.logAction("tui submitted custom close reason")
|
||||
issueID := m.closeReasonIssueID
|
||||
m.closingOtherReason = false
|
||||
m.closeReasonIssueID = ""
|
||||
return m, issues.CloseIssueCmd(m.app, issueID, reason)
|
||||
}
|
||||
case "esc":
|
||||
m.logAction("tui canceled custom close reason")
|
||||
m.closingOtherReason = false
|
||||
m.closeReasonIssueID = ""
|
||||
return m, nil
|
||||
}
|
||||
var cmd tea.Cmd
|
||||
m.closeReasonInput, cmd = m.closeReasonInput.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
if m.choosingPriority {
|
||||
switch msg.String() {
|
||||
case "0", "1", "2", "3", "4":
|
||||
|
||||
@@ -149,7 +149,7 @@ func (m *Model) View() string {
|
||||
if m.choosingStatus {
|
||||
statusContent := lipgloss.JoinVertical(lipgloss.Left,
|
||||
styles.LabelStyle.Render("Change status for "+m.statusIssueID+":"),
|
||||
lipgloss.NewStyle().Foreground(styles.FaintText).Render("o = open i = in_progress c = closed ready_to_sprint = r"),
|
||||
lipgloss.NewStyle().Foreground(styles.FaintText).Render("o = open i = in_progress r = ready_to_sprint c = closing (choose reason)"),
|
||||
lipgloss.NewStyle().Foreground(styles.FaintText).Render("Esc = cancel"),
|
||||
)
|
||||
statusBoxWidth := min(50, m.width-4)
|
||||
@@ -174,6 +174,35 @@ func (m *Model) View() string {
|
||||
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, priorityBox)
|
||||
}
|
||||
|
||||
if m.choosingCloseReason {
|
||||
reasonContent := lipgloss.JoinVertical(lipgloss.Left,
|
||||
styles.LabelStyle.Render("Choose closing reason for "+m.closeReasonIssueID+":"),
|
||||
lipgloss.NewStyle().Foreground(styles.FaintText).Render("d = Done u = Duplicate issue w = Won't fix o = Obsolete h = Other"),
|
||||
lipgloss.NewStyle().Foreground(styles.FaintText).Render("Esc = cancel"),
|
||||
)
|
||||
reasonBoxWidth := min(70, m.width-4)
|
||||
reasonBox := styles.ContainerStyle.
|
||||
Width(reasonBoxWidth).
|
||||
BorderForeground(styles.PrimaryBorder).
|
||||
Render(reasonContent)
|
||||
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, reasonBox)
|
||||
}
|
||||
|
||||
if m.closingOtherReason {
|
||||
editBoxWidth := min(60, m.width-4)
|
||||
m.closeReasonInput.SetWidth(editBoxWidth - 2)
|
||||
m.closeReasonInput.SetHeight(4)
|
||||
editContent := lipgloss.JoinVertical(lipgloss.Left,
|
||||
styles.LabelStyle.Render("Enter closing reason for "+m.closeReasonIssueID+" (Enter to save, Esc to cancel):"),
|
||||
m.closeReasonInput.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.choosingType {
|
||||
typeContent := lipgloss.JoinVertical(lipgloss.Left,
|
||||
styles.LabelStyle.Render("Change type for "+m.typeIssueID+":"),
|
||||
|
||||
@@ -56,11 +56,15 @@ type Model struct {
|
||||
editingAssignee bool // true while editing assignee
|
||||
assigneeInput textinput.Model
|
||||
assigneeIssueID string
|
||||
feedbackChan chan models.ValidationFeedback
|
||||
quitChan chan bool
|
||||
submitChan chan<- struct{}
|
||||
currentFeedback models.ValidationFeedback
|
||||
showComplete bool
|
||||
choosingCloseReason bool // true while choosing a close reason
|
||||
closeReasonIssueID string
|
||||
closingOtherReason bool // true while entering a custom close reason
|
||||
closeReasonInput textarea.Model
|
||||
feedbackChan chan models.ValidationFeedback
|
||||
quitChan chan bool
|
||||
submitChan chan<- struct{}
|
||||
currentFeedback models.ValidationFeedback
|
||||
showComplete bool
|
||||
}
|
||||
|
||||
func NewDashboard(app *app.App, feedbackChan chan models.ValidationFeedback, quitChan chan bool, submitChan chan<- struct{}) *Model {
|
||||
@@ -94,6 +98,12 @@ func NewDashboard(app *app.App, feedbackChan chan models.ValidationFeedback, qui
|
||||
m.descriptionInput = inputs.Description
|
||||
m.assigneeInput = inputs.Assignee
|
||||
|
||||
closeReasonTa := textarea.New()
|
||||
closeReasonTa.Placeholder = "Enter closing reason..."
|
||||
closeReasonTa.SetWidth(56)
|
||||
closeReasonTa.SetHeight(4)
|
||||
m.closeReasonInput = closeReasonTa
|
||||
|
||||
if selected := m.todoList.SelectedItem(); selected.ID != "" {
|
||||
m.issueDetail.SetIssue(selected.Issue)
|
||||
} else if selected := m.inProgList.SelectedItem(); selected.ID != "" {
|
||||
@@ -160,7 +170,9 @@ 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.editingAssignee
|
||||
m.choosingStatus || m.choosingPriority || m.confirmingDelete ||
|
||||
m.choosingType || m.editingAssignee ||
|
||||
m.choosingCloseReason || m.closingOtherReason
|
||||
}
|
||||
|
||||
func (m *Model) IsFocusedOnList() bool {
|
||||
|
||||
@@ -262,7 +262,9 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
issueID := m.statusIssueID
|
||||
m.choosingStatus = false
|
||||
m.statusIssueID = ""
|
||||
return m, issues.UpdateIssueStatusCmd(m.app, issueID, string(models.StatusClosed))
|
||||
m.choosingCloseReason = true
|
||||
m.closeReasonIssueID = issueID
|
||||
return m, nil
|
||||
case "esc":
|
||||
m.choosingStatus = false
|
||||
m.statusIssueID = ""
|
||||
@@ -270,6 +272,56 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
if m.choosingCloseReason {
|
||||
var reason string
|
||||
switch msg.String() {
|
||||
case "d":
|
||||
reason = "Done"
|
||||
case "u":
|
||||
reason = "Duplicate issue"
|
||||
case "w":
|
||||
reason = "Won't fix"
|
||||
case "o":
|
||||
reason = "Obsolete"
|
||||
case "h":
|
||||
m.choosingCloseReason = false
|
||||
m.closingOtherReason = true
|
||||
m.closeReasonInput.SetValue("")
|
||||
return m, nil
|
||||
case "esc":
|
||||
m.choosingCloseReason = false
|
||||
m.closeReasonIssueID = ""
|
||||
return m, nil
|
||||
}
|
||||
|
||||
if reason != "" {
|
||||
issueID := m.closeReasonIssueID
|
||||
m.choosingCloseReason = false
|
||||
m.closeReasonIssueID = ""
|
||||
return m, issues.CloseIssueCmd(m.app, issueID, reason)
|
||||
}
|
||||
}
|
||||
|
||||
if m.closingOtherReason {
|
||||
switch msg.String() {
|
||||
case "enter":
|
||||
reason := m.closeReasonInput.Value()
|
||||
if reason != "" {
|
||||
issueID := m.closeReasonIssueID
|
||||
m.closingOtherReason = false
|
||||
m.closeReasonIssueID = ""
|
||||
return m, issues.CloseIssueCmd(m.app, issueID, reason)
|
||||
}
|
||||
case "esc":
|
||||
m.closingOtherReason = false
|
||||
m.closeReasonIssueID = ""
|
||||
return m, nil
|
||||
}
|
||||
var cmd tea.Cmd
|
||||
m.closeReasonInput, cmd = m.closeReasonInput.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
if m.choosingPriority {
|
||||
switch msg.String() {
|
||||
case "0", "1", "2", "3", "4":
|
||||
|
||||
@@ -76,6 +76,35 @@ func (m *Model) View() string {
|
||||
mainView = lipgloss.JoinVertical(lipgloss.Left, header, content, spacer, footer)
|
||||
}
|
||||
|
||||
if m.choosingCloseReason {
|
||||
reasonContent := lipgloss.JoinVertical(lipgloss.Left,
|
||||
styles.LabelStyle.Render("Choose closing reason for "+m.closeReasonIssueID+":"),
|
||||
lipgloss.NewStyle().Foreground(styles.FaintText).Render("d = Done u = Duplicate issue w = Won't fix o = Obsolete h = Other"),
|
||||
lipgloss.NewStyle().Foreground(styles.FaintText).Render("Esc = cancel"),
|
||||
)
|
||||
reasonBoxWidth := min(70, m.width-4)
|
||||
reasonBox := styles.ContainerStyle.
|
||||
Width(reasonBoxWidth).
|
||||
BorderForeground(styles.PrimaryBorder).
|
||||
Render(reasonContent)
|
||||
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, reasonBox)
|
||||
}
|
||||
|
||||
if m.closingOtherReason {
|
||||
editBoxWidth := min(60, m.width-4)
|
||||
m.closeReasonInput.SetWidth(editBoxWidth - 2)
|
||||
m.closeReasonInput.SetHeight(4)
|
||||
editContent := lipgloss.JoinVertical(lipgloss.Left,
|
||||
styles.LabelStyle.Render("Enter closing reason for "+m.closeReasonIssueID+" (Enter to save, Esc to cancel):"),
|
||||
m.closeReasonInput.View(),
|
||||
)
|
||||
editBox := styles.ContainerStyle.
|
||||
Width(editBoxWidth).
|
||||
BorderForeground(styles.PrimaryBorder).
|
||||
Render(editContent)
|
||||
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, editBox)
|
||||
}
|
||||
|
||||
return components.RenderModals(
|
||||
m.width,
|
||||
m.height,
|
||||
|
||||
Reference in New Issue
Block a user