Skip to content

Commit

Permalink
[fix] force admin confirm reselection & fix toast timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
robinovitch61 committed Jan 31, 2024
1 parent 86fb38c commit a17a716
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 88 deletions.
4 changes: 4 additions & 0 deletions internal/fileio/fileio.go
Expand Up @@ -10,6 +10,10 @@ import (
"time"
)

type SaveCompleteMessage struct {
FullPath, SuccessMessage, Err string
}

func SaveToFile(saveDialogValue string, fileContent []string) (string, error) {
var path, fileName string

Expand Down
68 changes: 39 additions & 29 deletions internal/tui/components/app/app.go
Expand Up @@ -2,6 +2,7 @@ package app

import (
"fmt"
"github.com/robinovitch61/wander/internal/fileio"
"os"
"os/exec"
"path"
Expand All @@ -13,9 +14,9 @@ import (
"github.com/hashicorp/nomad/api"
"github.com/itchyny/gojq"
"github.com/robinovitch61/wander/internal/dev"
"github.com/robinovitch61/wander/internal/tui/components/toast"
"github.com/robinovitch61/wander/internal/tui/components/header"
"github.com/robinovitch61/wander/internal/tui/components/page"
"github.com/robinovitch61/wander/internal/tui/components/toast"
"github.com/robinovitch61/wander/internal/tui/constants"
"github.com/robinovitch61/wander/internal/tui/formatter"
"github.com/robinovitch61/wander/internal/tui/keymap"
Expand Down Expand Up @@ -63,13 +64,13 @@ type Config struct {
}

type Model struct {
config Config
client api.Client
config Config
client api.Client

header header.Model
compact bool
currentPage nomad.Page
pageModels map[nomad.Page]*page.Model
header header.Model
compact bool
currentPage nomad.Page
pageModels map[nomad.Page]*page.Model

inJobsMode bool
jobID string
Expand Down Expand Up @@ -207,6 +208,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
case nomad.ExecPage:
m.getCurrentPageModel().SetInputPrefix("Enter command: ")
case nomad.TaskAdminConfirmPage:
// always make user go down one to confirm
m.getCurrentPageModel().SetViewportSelectionToTop()
}
cmds = append(cmds, nomad.UpdatePageDataWithDelay(m.updateID, m.currentPage, m.config.UpdateSeconds))
}
Expand Down Expand Up @@ -302,27 +306,33 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
})
}

case fileio.SaveCompleteMessage:
toastMsg := msg.SuccessMessage
toastStyle := style.SuccessToast
if msg.Err != "" {
toastStyle = style.ErrorToast
toastMsg = fmt.Sprintf("Error: %s", msg.Err)
}
newToast := toast.New(toastMsg)
m.getCurrentPageModel().SetToast(newToast, toastStyle)
cmds = append(cmds, tea.Tick(newToast.Timeout, func(t time.Time) tea.Msg { return toast.TimeoutMsg{ID: newToast.ID} }))

case nomad.TaskAdminActionCompleteMsg:
m.getCurrentPageModel().SetToast(
toast.New(
fmt.Sprintf(
"%s completed successfully",
nomad.GetTaskAdminText(
m.adminAction, msg.TaskName, msg.AllocName, msg.AllocID))),
style.SuccessToast,
)
newToast := toast.New(fmt.Sprintf(
"%s completed successfully",
nomad.GetTaskAdminText(m.adminAction, msg.TaskName, msg.AllocName, msg.AllocID),
))
m.getCurrentPageModel().SetToast(newToast, style.SuccessToast)
cmds = append(cmds, tea.Tick(newToast.Timeout, func(t time.Time) tea.Msg { return toast.TimeoutMsg{ID: newToast.ID} }))

case nomad.TaskAdminActionFailedMsg:
m.getCurrentPageModel().SetToast(
toast.New(
fmt.Sprintf(
"%s failed with error: %s",
nomad.GetTaskAdminText(
m.adminAction, msg.TaskName, msg.AllocName, msg.AllocID),
msg.Error())),
style.ErrorToast,
)

newToast := toast.New(fmt.Sprintf(
"%s failed with error: %s",
nomad.GetTaskAdminText(m.adminAction, msg.TaskName, msg.AllocName, msg.AllocID),
msg.Error(),
))
m.getCurrentPageModel().SetToast(newToast, style.ErrorToast)
cmds = append(cmds, tea.Tick(newToast.Timeout, func(t time.Time) tea.Msg { return toast.TimeoutMsg{ID: newToast.ID} }))
}

currentPageModel = m.getCurrentPageModel()
Expand Down Expand Up @@ -420,8 +430,10 @@ func (m *Model) handleKeyMsg(msg tea.KeyMsg) tea.Cmd {
m.adminAction = nomad.KeyToAdminAction(selectedPageRow.Key)
case nomad.TaskAdminConfirmPage:
if selectedPageRow.Key == constants.ConfirmationKey {
cmds = append(cmds, nomad.GetCmdForTaskAdminAction(
m.client, m.adminAction, m.taskName, m.alloc.Name, m.alloc.ID))
cmds = append(
cmds,
nomad.GetCmdForTaskAdminAction(m.client, m.adminAction, m.taskName, m.alloc.Name, m.alloc.ID),
)
} else {
backPage := m.currentPage.Backward(m.inJobsMode)
m.setPage(backPage)
Expand Down Expand Up @@ -728,7 +740,6 @@ func (m Model) getCurrentPageCmd() tea.Cmd {
AllPageRows: rows,
}
}

case nomad.TaskAdminConfirmPage:
return func() tea.Msg {
// this does no async work, just constructs the confirmation page
Expand All @@ -743,7 +754,6 @@ func (m Model) getCurrentPageCmd() tea.Cmd {
},
}
}

default:
panic(fmt.Sprintf("Load command for page:%s not found", m.currentPage))
}
Expand Down
10 changes: 7 additions & 3 deletions internal/tui/components/page/page.go
Expand Up @@ -2,6 +2,7 @@ package page

import (
"fmt"
"github.com/robinovitch61/wander/internal/fileio"
"strings"

"github.com/atotto/clipboard"
Expand Down Expand Up @@ -113,7 +114,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
}

switch msg := msg.(type) {
case viewport.SaveStatusMsg:
case fileio.SaveCompleteMessage:
if m.copySavePath {
cmds = append(cmds, func() tea.Msg {
_ = clipboard.WriteAll(msg.FullPath)
Expand All @@ -124,8 +125,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
cmds = append(cmds, cmd)

case toast.TimeoutMsg:
m.viewport, cmd = m.viewport.Update(msg)
cmds = append(cmds, cmd)
m.viewport.HideToast()

case tea.KeyMsg:
switch {
Expand Down Expand Up @@ -234,6 +234,10 @@ func (m *Model) SetFilterPrefix(prefix string) {
m.filter.SetPrefix(prefix)
}

func (m *Model) SetViewportSelectionToTop() {
m.viewport.SetSelectedContentIdx(0)
}

func (m *Model) SetViewportSelectionToBottom() {
m.viewport.SetSelectedContentIdx(len(m.pageData.FilteredRows) - 1)
}
Expand Down
22 changes: 6 additions & 16 deletions internal/tui/components/toast/toast.go
Expand Up @@ -17,40 +17,34 @@ var (
)

type Model struct {
id int
ID int
message string
timeout time.Duration
Timeout time.Duration
initialized bool
Visible bool
MessageStyle lipgloss.Style
}

func New(message string) Model {
return Model{
id: nextID(),
ID: nextID(),
message: message,
timeout: constants.ToastDuration,
Timeout: constants.ToastDuration,
Visible: true,
MessageStyle: style.SuccessToast,
}
}

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
dev.Debug(fmt.Sprintf("toast %T", msg))
if !m.initialized {
m.initialized = true
return m, m.timeoutAfterDuration()
}

switch msg := msg.(type) {
case TimeoutMsg:
if msg.ID > 0 && msg.ID != m.id {
if msg.ID > 0 && msg.ID != m.ID {
return m, nil
}

m.Visible = false
}

return m, nil
}

Expand All @@ -65,18 +59,14 @@ func (m Model) ViewHeight() int {
return lipgloss.Height(m.View())
}

// Msg and Cmds

type TimeoutMsg struct {
ID int
}

func (m Model) timeoutAfterDuration() tea.Cmd {
return tea.Tick(m.timeout, func(t time.Time) tea.Msg { return TimeoutMsg{m.id} })
return tea.Tick(m.Timeout, func(t time.Time) tea.Msg { return TimeoutMsg{m.ID} })
}

// Helpers

func nextID() int {
idMtx.Lock()
defer idMtx.Unlock()
Expand Down
17 changes: 2 additions & 15 deletions internal/tui/components/viewport/viewport.go
Expand Up @@ -18,10 +18,6 @@ const lineContinuationIndicator = "..."

var lenLineContinuationIndicator = stringWidth(lineContinuationIndicator)

type SaveStatusMsg struct {
FullPath, SuccessMessage, Err string
}

type Model struct {
header []string
wrappedHeader []string
Expand Down Expand Up @@ -134,15 +130,6 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
}
} else {
switch msg := msg.(type) {
case SaveStatusMsg:
if msg.Err != "" {
m.toast = toast.New(fmt.Sprintf("Error: %s", msg.Err))
m.toast.MessageStyle = style.ErrorToast.Copy().Width(m.width)
} else {
m.toast = toast.New(msg.SuccessMessage)
m.toast.MessageStyle = style.SuccessToast.Copy().Width(m.width)
}

case tea.KeyMsg:
switch {
case key.Matches(msg, m.keyMap.Up):
Expand Down Expand Up @@ -740,9 +727,9 @@ func (m Model) getSaveCommand() tea.Cmd {

savePathWithFileName, err := fileio.SaveToFile(m.saveDialog.Value(), saveContent)
if err != nil {
return SaveStatusMsg{Err: err.Error()}
return fileio.SaveCompleteMessage{Err: err.Error()}
}
return SaveStatusMsg{FullPath: savePathWithFileName, SuccessMessage: fmt.Sprintf("Success: saved to %s", savePathWithFileName)}
return fileio.SaveCompleteMessage{FullPath: savePathWithFileName, SuccessMessage: fmt.Sprintf("Success: saved to %s", savePathWithFileName)}
}
}

Expand Down
45 changes: 31 additions & 14 deletions internal/tui/nomad/pages.go
Expand Up @@ -158,7 +158,19 @@ func (p Page) DoesLoad() bool {
}

func (p Page) DoesReload() bool {
noReloadPages := []Page{LoglinePage, JobEventsPage, JobEventPage, AllocEventsPage, AllocEventPage, AllEventsPage, AllEventPage, ExecPage, ExecCompletePage}
noReloadPages := []Page{
LoglinePage,
JobEventsPage,
JobEventPage,
AllocEventsPage,
AllocEventPage,
AllEventsPage,
AllEventPage,
ExecPage,
ExecCompletePage,
TaskAdminPage,
TaskAdminConfirmPage,
}
for _, noReloadPage := range noReloadPages {
if noReloadPage == p {
return false
Expand Down Expand Up @@ -193,18 +205,20 @@ func (p Page) CanBeFirstPage() bool {

func (p Page) doesUpdate() bool {
noUpdatePages := []Page{
LoglinePage, // doesn't load
ExecPage, // doesn't reload
ExecCompletePage, // doesn't reload
LogsPage, // currently makes scrolling impossible - solve in https://github.com/robinovitch61/wander/issues/1
JobSpecPage, // would require changes to make scrolling possible
AllocSpecPage, // would require changes to make scrolling possible
JobEventsPage, // constant connection, streams data
JobEventPage, // doesn't load
AllocEventsPage, // constant connection, streams data
AllocEventPage, // doesn't load
AllEventsPage, // constant connection, streams data
AllEventPage, // doesn't load
LoglinePage, // doesn't load
ExecPage, // doesn't reload
ExecCompletePage, // doesn't reload
LogsPage, // currently makes scrolling impossible - solve in https://github.com/robinovitch61/wander/issues/1
JobSpecPage, // would require changes to make scrolling possible
AllocSpecPage, // would require changes to make scrolling possible
JobEventsPage, // constant connection, streams data
JobEventPage, // doesn't load
AllocEventsPage, // constant connection, streams data
AllocEventPage, // doesn't load
AllEventsPage, // constant connection, streams data
AllEventPage, // doesn't load
TaskAdminPage, // doesn't load
TaskAdminConfirmPage, // doesn't load
}
for _, noUpdatePage := range noUpdatePages {
if noUpdatePage == p {
Expand Down Expand Up @@ -251,7 +265,7 @@ func (p Page) String() string {
case TaskAdminPage:
return "task admin menu"
case TaskAdminConfirmPage:
return "confirm"
return "execute"
}
return "unknown"
}
Expand Down Expand Up @@ -476,6 +490,9 @@ func GetPageKeyHelp(
var fourthRow []key.Binding
if nextPage := currentPage.Forward(inJobsMode); nextPage != currentPage {
changeKeyHelp(&keymap.KeyMap.Forward, currentPage.Forward(inJobsMode).String())
if currentPage == TaskAdminConfirmPage {
changeKeyHelp(&keymap.KeyMap.Forward, "choose")
}
fourthRow = append(fourthRow, keymap.KeyMap.Forward)
}

Expand Down

0 comments on commit a17a716

Please sign in to comment.