From e16e299a65814289e4dd730667d45dca73a2a963 Mon Sep 17 00:00:00 2001 From: Engin Date: Sat, 29 Jun 2024 14:14:34 +0300 Subject: [PATCH] Minor enhancements --- internal/terminal/handler/error/error.go | 52 +++---- .../handler/ghrepository/ghrepository.go | 142 +++++++++--------- .../terminal/handler/ghtrigger/ghtrigger.go | 72 +++++---- .../terminal/handler/ghworkflow/ghworkflow.go | 14 +- .../ghworkflowhistory/ghworkflowhistory.go | 66 ++++---- internal/terminal/handler/handler.go | 15 +- .../handler/information/information.go | 5 +- .../terminal/handler/taboptions/taboptions.go | 142 +++++++++--------- pkg/workflow/workflow.go | 2 - 9 files changed, 250 insertions(+), 260 deletions(-) diff --git a/internal/terminal/handler/error/error.go b/internal/terminal/handler/error/error.go index fdecb07..79a69a5 100644 --- a/internal/terminal/handler/error/error.go +++ b/internal/terminal/handler/error/error.go @@ -43,6 +43,32 @@ func SetupModelError() ModelError { } } +func (m *ModelError) View() string { + var windowStyle = lipgloss.NewStyle().BorderStyle(lipgloss.RoundedBorder()) + + doc := strings.Builder{} + if m.HaveError() { + windowStyle = ts.WindowStyleError.Width(*hdltypes.ScreenWidth) + doc.WriteString(windowStyle.Render(m.ViewError())) + return doc.String() + } + + switch m.messageType { + case MessageTypeDefault: + windowStyle = ts.WindowStyleDefault.Width(*hdltypes.ScreenWidth) + case MessageTypeProgress: + windowStyle = ts.WindowStyleProgress.Width(*hdltypes.ScreenWidth) + case MessageTypeSuccess: + windowStyle = ts.WindowStyleSuccess.Width(*hdltypes.ScreenWidth) + default: + windowStyle = ts.WindowStyleDefault.Width(*hdltypes.ScreenWidth) + } + + doc.WriteString(windowStyle.Render(m.ViewMessage())) + + return doc.String() +} + func (m *ModelError) SetError(err error) { m.err = err } @@ -107,29 +133,3 @@ func (m *ModelError) ViewMessage() string { doc.WriteString(m.message) return doc.String() } - -func (m *ModelError) View() string { - var windowStyle = lipgloss.NewStyle().BorderStyle(lipgloss.RoundedBorder()) - - doc := strings.Builder{} - if m.HaveError() { - windowStyle = ts.WindowStyleError.Width(*hdltypes.ScreenWidth) - doc.WriteString(windowStyle.Render(m.ViewError())) - return doc.String() - } - - switch m.messageType { - case MessageTypeDefault: - windowStyle = ts.WindowStyleDefault.Width(*hdltypes.ScreenWidth) - case MessageTypeProgress: - windowStyle = ts.WindowStyleProgress.Width(*hdltypes.ScreenWidth) - case MessageTypeSuccess: - windowStyle = ts.WindowStyleSuccess.Width(*hdltypes.ScreenWidth) - default: - windowStyle = ts.WindowStyleDefault.Width(*hdltypes.ScreenWidth) - } - - doc.WriteString(windowStyle.Render(m.ViewMessage())) - - return doc.String() -} diff --git a/internal/terminal/handler/ghrepository/ghrepository.go b/internal/terminal/handler/ghrepository/ghrepository.go index 30204b1..d33c20e 100644 --- a/internal/terminal/handler/ghrepository/ghrepository.go +++ b/internal/terminal/handler/ghrepository/ghrepository.go @@ -44,8 +44,7 @@ type ModelGithubRepository struct { searchTableGithubRepository table.Model modelError *hdlerror.ModelError - modelTabOptions tea.Model - actualModelTabOptions *taboptions.Options + modelTabOptions *taboptions.Options textInput textinput.Model } @@ -122,7 +121,6 @@ func SetupModelGithubRepository(viewport *viewport.Model, githubUseCase gu.UseCa modelError: &modelError, SelectedRepository: selectedRepository, modelTabOptions: tabOptions, - actualModelTabOptions: tabOptions, textInput: ti, syncRepositoriesContext: context.Background(), cancelSyncRepositories: func() {}, @@ -145,75 +143,9 @@ func (m *ModelGithubRepository) Init() tea.Cmd { m.modelError.SetSuccessMessage("Opened in browser") } - m.actualModelTabOptions.AddOption("Open in browser", openInBrowser) + m.modelTabOptions.AddOption("Open in browser", openInBrowser) - return nil -} - -func (m *ModelGithubRepository) syncRepositories(ctx context.Context) { - m.modelError.ResetError() // reset previous errors - m.actualModelTabOptions.SetStatus(taboptions.OptionWait) - m.modelError.SetProgressMessage("Fetching repositories...") - - // delete all rows - m.tableGithubRepository.SetRows([]table.Row{}) - m.searchTableGithubRepository.SetRows([]table.Row{}) - - repositories, err := m.github.ListRepositories(ctx, gu.ListRepositoriesInput{ - Limit: 100, // limit to 100 repositories - Page: 5, // page 1 to page 5, at summary we fetch 500 repositories - Sort: domain.SortByUpdated, - }) - if errors.Is(err, context.Canceled) { - return - } else if err != nil { - m.modelError.SetError(err) - m.modelError.SetErrorMessage("Repositories cannot be listed") - return - } - - if len(repositories.Repositories) == 0 { - m.actualModelTabOptions.SetStatus(taboptions.OptionNone) - m.modelError.SetDefaultMessage("No repositories found") - m.textInput.Blur() - return - } - - tableRowsGithubRepository := make([]table.Row, 0, len(repositories.Repositories)) - for _, repository := range repositories.Repositories { - tableRowsGithubRepository = append(tableRowsGithubRepository, - table.Row{repository.Name, repository.DefaultBranch, strconv.Itoa(repository.Stars), strconv.Itoa(len(repository.Workflows))}) - } - - m.tableGithubRepository.SetRows(tableRowsGithubRepository) - m.searchTableGithubRepository.SetRows(tableRowsGithubRepository) - - // set cursor to 0 - m.tableGithubRepository.SetCursor(0) - m.searchTableGithubRepository.SetCursor(0) - - m.tableReady = true - //m.updateSearchBarSuggestions() - m.textInput.Focus() - m.modelError.SetSuccessMessage("Repositories fetched") - go m.Update(m) // update model -} - -func (m *ModelGithubRepository) handleTableInputs(_ context.Context) { - if !m.tableReady { - return - } - - // To avoid go routine leak - selectedRow := m.tableGithubRepository.SelectedRow() - - // Synchronize selected repository name with parent model - if len(selectedRow) > 0 && selectedRow[0] != "" { - m.SelectedRepository.RepositoryName = selectedRow[0] - m.SelectedRepository.BranchName = selectedRow[1] - } - - m.actualModelTabOptions.SetStatus(taboptions.OptionIdle) + return tea.Batch(m.modelTabOptions.Init()) } func (m *ModelGithubRepository) Update(msg tea.Msg) (*ModelGithubRepository, tea.Cmd) { @@ -278,7 +210,73 @@ func (m *ModelGithubRepository) View() string { doc := strings.Builder{} doc.WriteString(baseStyle.Render(m.tableGithubRepository.View())) - return lipgloss.JoinVertical(lipgloss.Top, doc.String(), m.viewSearchBar(), m.actualModelTabOptions.View()) + return lipgloss.JoinVertical(lipgloss.Top, doc.String(), m.viewSearchBar(), m.modelTabOptions.View()) +} + +func (m *ModelGithubRepository) syncRepositories(ctx context.Context) { + m.modelError.ResetError() // reset previous errors + m.modelTabOptions.SetStatus(taboptions.OptionWait) + m.modelError.SetProgressMessage("Fetching repositories...") + + // delete all rows + m.tableGithubRepository.SetRows([]table.Row{}) + m.searchTableGithubRepository.SetRows([]table.Row{}) + + repositories, err := m.github.ListRepositories(ctx, gu.ListRepositoriesInput{ + Limit: 100, // limit to 100 repositories + Page: 5, // page 1 to page 5, at summary we fetch 500 repositories + Sort: domain.SortByUpdated, + }) + if errors.Is(err, context.Canceled) { + return + } else if err != nil { + m.modelError.SetError(err) + m.modelError.SetErrorMessage("Repositories cannot be listed") + return + } + + if len(repositories.Repositories) == 0 { + m.modelTabOptions.SetStatus(taboptions.OptionNone) + m.modelError.SetDefaultMessage("No repositories found") + m.textInput.Blur() + return + } + + tableRowsGithubRepository := make([]table.Row, 0, len(repositories.Repositories)) + for _, repository := range repositories.Repositories { + tableRowsGithubRepository = append(tableRowsGithubRepository, + table.Row{repository.Name, repository.DefaultBranch, strconv.Itoa(repository.Stars), strconv.Itoa(len(repository.Workflows))}) + } + + m.tableGithubRepository.SetRows(tableRowsGithubRepository) + m.searchTableGithubRepository.SetRows(tableRowsGithubRepository) + + // set cursor to 0 + m.tableGithubRepository.SetCursor(0) + m.searchTableGithubRepository.SetCursor(0) + + m.tableReady = true + //m.updateSearchBarSuggestions() + m.textInput.Focus() + m.modelError.SetSuccessMessage("Repositories fetched") + go m.Update(m) // update model +} + +func (m *ModelGithubRepository) handleTableInputs(_ context.Context) { + if !m.tableReady { + return + } + + // To avoid go routine leak + selectedRow := m.tableGithubRepository.SelectedRow() + + // Synchronize selected repository name with parent model + if len(selectedRow) > 0 && selectedRow[0] != "" { + m.SelectedRepository.RepositoryName = selectedRow[0] + m.SelectedRepository.BranchName = selectedRow[1] + } + + m.modelTabOptions.SetStatus(taboptions.OptionIdle) } func (m *ModelGithubRepository) viewSearchBar() string { diff --git a/internal/terminal/handler/ghtrigger/ghtrigger.go b/internal/terminal/handler/ghtrigger/ghtrigger.go index 24e4177..5241ac4 100644 --- a/internal/terminal/handler/ghtrigger/ghtrigger.go +++ b/internal/terminal/handler/ghtrigger/ghtrigger.go @@ -4,11 +4,6 @@ import ( "context" "errors" "fmt" - "github.com/termkit/gama/internal/terminal/handler/header" - "slices" - "strings" - "time" - "github.com/charmbracelet/bubbles/help" "github.com/charmbracelet/bubbles/table" "github.com/charmbracelet/bubbles/textinput" @@ -17,25 +12,29 @@ import ( "github.com/charmbracelet/lipgloss" gu "github.com/termkit/gama/internal/github/usecase" hdlerror "github.com/termkit/gama/internal/terminal/handler/error" + "github.com/termkit/gama/internal/terminal/handler/ghworkflowhistory" + "github.com/termkit/gama/internal/terminal/handler/header" hdltypes "github.com/termkit/gama/internal/terminal/handler/types" "github.com/termkit/gama/pkg/workflow" + "slices" + "strings" + "time" ) type ModelGithubTrigger struct { // current handler's properties - syncWorkflowContext context.Context - cancelSyncWorkflow context.CancelFunc - workflowContent *workflow.Pretty - tableReady bool - isTriggerable bool - forceUpdateWorkflowHistory *bool - optionInit bool - optionCursor int - optionValues []string - currentOption string - selectedWorkflow string - selectedRepositoryName string - triggerFocused bool + syncWorkflowContext context.Context + cancelSyncWorkflow context.CancelFunc + workflowContent *workflow.Pretty + tableReady bool + isTriggerable bool + optionInit bool + optionCursor int + optionValues []string + currentOption string + selectedWorkflow string + selectedRepositoryName string + triggerFocused bool // shared properties SelectedRepository *hdltypes.SelectedRepository @@ -56,7 +55,7 @@ type ModelGithubTrigger struct { tableTrigger table.Model } -func SetupModelGithubTrigger(viewport *viewport.Model, githubUseCase gu.UseCase, selectedRepository *hdltypes.SelectedRepository, forceUpdateWorkflowHistory *bool) *ModelGithubTrigger { +func SetupModelGithubTrigger(viewport *viewport.Model, githubUseCase gu.UseCase, selectedRepository *hdltypes.SelectedRepository) *ModelGithubTrigger { var tableRowsTrigger []table.Row tableTrigger := table.New( @@ -83,24 +82,23 @@ func SetupModelGithubTrigger(viewport *viewport.Model, githubUseCase gu.UseCase, ti.CharLimit = 72 return &ModelGithubTrigger{ - Viewport: viewport, - header: header.NewHeader(viewport), - forceUpdateWorkflowHistory: forceUpdateWorkflowHistory, - Help: help.New(), - Keys: keys, - github: githubUseCase, - SelectedRepository: selectedRepository, - modelError: hdlerror.SetupModelError(), - tableTrigger: tableTrigger, - textInput: ti, - syncWorkflowContext: context.Background(), - cancelSyncWorkflow: func() {}, + Viewport: viewport, + header: header.NewHeader(viewport), + Help: help.New(), + Keys: keys, + github: githubUseCase, + SelectedRepository: selectedRepository, + modelError: hdlerror.SetupModelError(), + tableTrigger: tableTrigger, + textInput: ti, + syncWorkflowContext: context.Background(), + cancelSyncWorkflow: func() {}, } } func (m *ModelGithubTrigger) Init() tea.Cmd { m.modelError.SetDefaultMessage("No workflow contents found.") - return textinput.Blink + return tea.Batch(textinput.Blink) } func (m *ModelGithubTrigger) Update(msg tea.Msg) (*ModelGithubTrigger, tea.Cmd) { @@ -172,6 +170,9 @@ func (m *ModelGithubTrigger) Update(msg tea.Msg) (*ModelGithubTrigger, tea.Cmd) case "enter", tea.KeyEnter.String(): if m.triggerFocused && m.isTriggerable { go m.triggerWorkflow() + return m, func() tea.Msg { + return ghworkflowhistory.UpdateWorkflowHistoryMsg{UpdateAfter: time.Second * 5} + } } } } @@ -601,7 +602,7 @@ func (m *ModelGithubTrigger) triggerWorkflow() { time.Sleep(1 * time.Second) m.modelError.SetProgressMessage("Switching to workflow history tab...") - time.Sleep(1 * time.Second) + time.Sleep(1500 * time.Millisecond) // move these operations under new function named "resetTabSettings" m.workflowContent = nil // reset workflow content @@ -610,11 +611,6 @@ func (m *ModelGithubTrigger) triggerWorkflow() { m.optionValues = nil // reset option values m.selectedRepositoryName = "" // reset selected repository name - go func() { - time.Sleep(1 * time.Second) - *m.forceUpdateWorkflowHistory = true // force update workflow history - }() - m.header.SetCurrentTab(2) // switch tab to workflow history } diff --git a/internal/terminal/handler/ghworkflow/ghworkflow.go b/internal/terminal/handler/ghworkflow/ghworkflow.go index 9b351ff..b80d91f 100644 --- a/internal/terminal/handler/ghworkflow/ghworkflow.go +++ b/internal/terminal/handler/ghworkflow/ghworkflow.go @@ -11,7 +11,6 @@ import ( "github.com/charmbracelet/bubbles/table" hdlerror "github.com/termkit/gama/internal/terminal/handler/error" "github.com/termkit/gama/internal/terminal/handler/ghtrigger" - "github.com/termkit/gama/internal/terminal/handler/taboptions" hdltypes "github.com/termkit/gama/internal/terminal/handler/types" "github.com/charmbracelet/bubbles/list" @@ -44,11 +43,7 @@ type ModelGithubWorkflow struct { tableTriggerableWorkflow table.Model modelError *hdlerror.ModelError - modelTabOptions tea.Model - actualModelTabOptions *taboptions.Options - - modelGithubTrigger tea.Model - actualModelGithubTrigger *ghtrigger.ModelGithubTrigger + modelGithubTrigger *ghtrigger.ModelGithubTrigger } func SetupModelGithubWorkflow(viewport *viewport.Model, githubUseCase gu.UseCase, selectedRepository *hdltypes.SelectedRepository) *ModelGithubWorkflow { @@ -74,7 +69,6 @@ func SetupModelGithubWorkflow(viewport *viewport.Model, githubUseCase gu.UseCase tableTriggerableWorkflow.SetStyles(s) modelError := hdlerror.SetupModelError() - tabOptions := taboptions.NewOptions(&modelError) return &ModelGithubWorkflow{ Viewport: viewport, @@ -84,8 +78,6 @@ func SetupModelGithubWorkflow(viewport *viewport.Model, githubUseCase gu.UseCase modelError: &modelError, tableTriggerableWorkflow: tableTriggerableWorkflow, SelectedRepository: selectedRepository, - modelTabOptions: tabOptions, - actualModelTabOptions: tabOptions, syncTriggerableWorkflowsContext: context.Background(), cancelSyncTriggerableWorkflows: func() {}, } @@ -147,7 +139,6 @@ func (m *ModelGithubWorkflow) syncTriggerableWorkflows(ctx context.Context) { m.modelError.Reset() m.modelError.SetProgressMessage( fmt.Sprintf("[%s@%s] Fetching triggerable workflows...", m.SelectedRepository.RepositoryName, m.SelectedRepository.BranchName)) - m.actualModelTabOptions.SetStatus(taboptions.OptionWait) // delete all rows m.tableTriggerableWorkflow.SetRows([]table.Row{}) @@ -165,7 +156,6 @@ func (m *ModelGithubWorkflow) syncTriggerableWorkflows(ctx context.Context) { } if len(triggerableWorkflows.TriggerableWorkflows) == 0 { - m.actualModelTabOptions.SetStatus(taboptions.OptionNone) m.modelError.SetDefaultMessage(fmt.Sprintf("[%s@%s] No triggerable workflow found.", m.SelectedRepository.RepositoryName, m.SelectedRepository.BranchName)) return } @@ -202,8 +192,6 @@ func (m *ModelGithubWorkflow) handleTableInputs(_ context.Context) { if len(rows) > 0 && len(selectedRow) > 0 { m.SelectedRepository.WorkflowName = selectedRow[1] } - - m.actualModelTabOptions.SetStatus(taboptions.OptionIdle) } func (m *ModelGithubWorkflow) ViewStatus() string { diff --git a/internal/terminal/handler/ghworkflowhistory/ghworkflowhistory.go b/internal/terminal/handler/ghworkflowhistory/ghworkflowhistory.go index dad05bb..393944e 100644 --- a/internal/terminal/handler/ghworkflowhistory/ghworkflowhistory.go +++ b/internal/terminal/handler/ghworkflowhistory/ghworkflowhistory.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "strings" + "time" "github.com/charmbracelet/bubbles/help" "github.com/charmbracelet/bubbles/key" @@ -26,7 +27,6 @@ type ModelGithubWorkflowHistory struct { selectedWorkflowID int64 isTableFocused bool lastRepository string - forceUpdate *bool syncWorkflowHistoryContext context.Context cancelSyncWorkflowHistory context.CancelFunc Workflows []gu.Workflow @@ -46,15 +46,10 @@ type ModelGithubWorkflowHistory struct { tableWorkflowHistory table.Model modelError *hdlerror.ModelError - modelTabOptions tea.Model - actualModelTabOptions *taboptions.Options + modelTabOptions *taboptions.Options } -var baseStyle = lipgloss.NewStyle(). - BorderStyle(lipgloss.NormalBorder()). - BorderForeground(lipgloss.Color("240")) - -func SetupModelGithubWorkflowHistory(viewport *viewport.Model, githubUseCase gu.UseCase, selectedRepository *hdltypes.SelectedRepository, forceUpdate *bool) *ModelGithubWorkflowHistory { +func SetupModelGithubWorkflowHistory(viewport *viewport.Model, githubUseCase gu.UseCase, selectedRepository *hdltypes.SelectedRepository) *ModelGithubWorkflowHistory { var tableRowsWorkflowHistory []table.Row tableWorkflowHistory := table.New( @@ -88,14 +83,26 @@ func SetupModelGithubWorkflowHistory(viewport *viewport.Model, githubUseCase gu. modelError: &modelError, SelectedRepository: selectedRepository, modelTabOptions: tabOptions, - actualModelTabOptions: tabOptions, - forceUpdate: forceUpdate, syncWorkflowHistoryContext: context.Background(), cancelSyncWorkflowHistory: func() {}, } } +type UpdateWorkflowHistoryMsg struct { + UpdateAfter time.Duration +} + func (m *ModelGithubWorkflowHistory) Init() tea.Cmd { + m.setupOptions() + return tea.Batch( + m.modelTabOptions.Init(), + func() tea.Msg { + return UpdateWorkflowHistoryMsg{UpdateAfter: time.Second * 1} + }, + ) +} + +func (m *ModelGithubWorkflowHistory) setupOptions() { openInBrowser := func() { m.modelError.SetProgressMessage("Opening in browser...") @@ -160,23 +167,10 @@ func (m *ModelGithubWorkflowHistory) Init() tea.Cmd { m.modelError.SetSuccessMessage("Canceled workflow") } - m.actualModelTabOptions.AddOption("Open in browser", openInBrowser) - m.actualModelTabOptions.AddOption("Rerun failed jobs", reRunFailedJobs) - m.actualModelTabOptions.AddOption("Rerun workflow", reRunWorkflow) - m.actualModelTabOptions.AddOption("Cancel workflow", cancelWorkflow) - - go func() { - // Make it works with to channels - for { - if *m.forceUpdate { - m.tableReady = false - go m.syncWorkflowHistory(m.syncWorkflowHistoryContext) - *m.forceUpdate = false - } - } - }() - - return tea.Batch(m.modelTabOptions.Init()) + m.modelTabOptions.AddOption("Open in browser", openInBrowser) + m.modelTabOptions.AddOption("Rerun failed jobs", reRunFailedJobs) + m.modelTabOptions.AddOption("Rerun workflow", reRunWorkflow) + m.modelTabOptions.AddOption("Cancel workflow", cancelWorkflow) } func (m *ModelGithubWorkflowHistory) Update(msg tea.Msg) (*ModelGithubWorkflowHistory, tea.Cmd) { @@ -203,6 +197,12 @@ func (m *ModelGithubWorkflowHistory) Update(msg tea.Msg) (*ModelGithubWorkflowHi m.tableReady = false go m.syncWorkflowHistory(m.syncWorkflowHistoryContext) } + case UpdateWorkflowHistoryMsg: + go func() { + time.Sleep(msg.UpdateAfter) + m.tableReady = false + m.syncWorkflowHistory(m.syncWorkflowHistoryContext) // TODO : may you use go routine here? + }() } m.modelTabOptions, cmd = m.modelTabOptions.Update(msg) @@ -218,7 +218,7 @@ func (m *ModelGithubWorkflowHistory) syncWorkflowHistory(ctx context.Context) { m.modelError.Reset() m.modelError.SetProgressMessage( fmt.Sprintf("[%s@%s] Fetching workflow history...", m.SelectedRepository.RepositoryName, m.SelectedRepository.BranchName)) - m.actualModelTabOptions.SetStatus(taboptions.OptionWait) + m.modelTabOptions.SetStatus(taboptions.OptionWait) // delete all rows m.tableWorkflowHistory.SetRows([]table.Row{}) @@ -239,7 +239,7 @@ func (m *ModelGithubWorkflowHistory) syncWorkflowHistory(ctx context.Context) { } if len(workflowHistory.Workflows) == 0 { - m.actualModelTabOptions.SetStatus(taboptions.OptionNone) + m.modelTabOptions.SetStatus(taboptions.OptionNone) m.modelError.SetDefaultMessage(fmt.Sprintf("[%s@%s] No workflows found.", m.SelectedRepository.RepositoryName, m.SelectedRepository.BranchName)) return } @@ -261,12 +261,16 @@ func (m *ModelGithubWorkflowHistory) syncWorkflowHistory(ctx context.Context) { m.tableReady = true m.tableWorkflowHistory.SetRows(tableRowsWorkflowHistory) m.tableWorkflowHistory.SetCursor(0) - m.actualModelTabOptions.SetStatus(taboptions.OptionIdle) + m.modelTabOptions.SetStatus(taboptions.OptionIdle) m.modelError.SetSuccessMessage(fmt.Sprintf("[%s@%s] Workflow history fetched.", m.SelectedRepository.RepositoryName, m.SelectedRepository.BranchName)) go m.Update(m) // update model } func (m *ModelGithubWorkflowHistory) View() string { + var baseStyle = lipgloss.NewStyle(). + BorderStyle(lipgloss.NormalBorder()). + BorderForeground(lipgloss.Color("240")) + termWidth := m.Viewport.Width termHeight := m.Viewport.Height @@ -293,7 +297,7 @@ func (m *ModelGithubWorkflowHistory) View() string { doc := strings.Builder{} doc.WriteString(baseStyle.Render(m.tableWorkflowHistory.View())) - return lipgloss.JoinVertical(lipgloss.Top, doc.String(), m.actualModelTabOptions.View()) + return lipgloss.JoinVertical(lipgloss.Top, doc.String(), m.modelTabOptions.View()) } func (m *ModelGithubWorkflowHistory) ViewStatus() string { diff --git a/internal/terminal/handler/handler.go b/internal/terminal/handler/handler.go index dcd2167..4eaa14f 100644 --- a/internal/terminal/handler/handler.go +++ b/internal/terminal/handler/handler.go @@ -7,6 +7,7 @@ import ( tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" gu "github.com/termkit/gama/internal/github/usecase" + hdlerror "github.com/termkit/gama/internal/terminal/handler/error" hdlgithubrepo "github.com/termkit/gama/internal/terminal/handler/ghrepository" hdltrigger "github.com/termkit/gama/internal/terminal/handler/ghtrigger" hdlWorkflow "github.com/termkit/gama/internal/terminal/handler/ghworkflow" @@ -26,6 +27,7 @@ type model struct { // models viewport *viewport.Model + modelError *hdlerror.ModelError modelHeader *header.Header modelInfo *hdlinfo.ModelInfo modelGithubRepository *hdlgithubrepo.ModelGithubRepository @@ -43,17 +45,17 @@ const ( ) func SetupTerminal(githubUseCase gu.UseCase, version pkgversion.Version) tea.Model { - forceUpdateWorkflowHistory := new(bool) vp := &viewport.Model{Width: minTerminalWidth, Height: minTerminalHeight} selectedRepository := &hdltypes.SelectedRepository{} // setup models + hdlModelError := hdlerror.SetupModelError() hdlModelHeader := header.NewHeader(vp) hdlModelInfo := hdlinfo.SetupModelInfo(vp, githubUseCase, version) hdlModelGithubRepository := hdlgithubrepo.SetupModelGithubRepository(vp, githubUseCase, selectedRepository) - hdlModelWorkflowHistory := hdlworkflowhistory.SetupModelGithubWorkflowHistory(vp, githubUseCase, selectedRepository, forceUpdateWorkflowHistory) + hdlModelWorkflowHistory := hdlworkflowhistory.SetupModelGithubWorkflowHistory(vp, githubUseCase, selectedRepository) hdlModelWorkflow := hdlWorkflow.SetupModelGithubWorkflow(vp, githubUseCase, selectedRepository) - hdlModelTrigger := hdltrigger.SetupModelGithubTrigger(vp, githubUseCase, selectedRepository, forceUpdateWorkflowHistory) + hdlModelTrigger := hdltrigger.SetupModelGithubTrigger(vp, githubUseCase, selectedRepository) hdlModelHeader.AddCommonHeader("Info", ts.TitleStyleInactive, ts.TitleStyleActive) hdlModelHeader.AddCommonHeader("Repository", ts.TitleStyleInactive, ts.TitleStyleActive) @@ -64,6 +66,7 @@ func SetupTerminal(githubUseCase gu.UseCase, version pkgversion.Version) tea.Mod m := model{ viewport: vp, + modelError: &hdlModelError, modelHeader: hdlModelHeader, modelInfo: hdlModelInfo, SelectedRepository: selectedRepository, @@ -106,14 +109,16 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.modelHeader, cmd = m.modelHeader.Update(msg) cmds = append(cmds, cmd) + cmds = append(cmds, m.handleTabContent(cmd, msg)) case hdlinfo.UpdateSpinnerMsg: m.modelInfo, cmd = m.modelInfo.Update(msg) cmds = append(cmds, cmd) case header.UpdateMsg: m.modelHeader, cmd = m.modelHeader.Update(msg) cmds = append(cmds, cmd) - default: - cmds = append(cmds, m.handleTabContent(cmd, msg)) + case hdlworkflowhistory.UpdateWorkflowHistoryMsg: + m.modelWorkflowHistory, cmd = m.modelWorkflowHistory.Update(msg) + cmds = append(cmds, cmd) } return m, tea.Batch(cmds...) diff --git a/internal/terminal/handler/information/information.go b/internal/terminal/handler/information/information.go index 56af815..5cf9f4d 100644 --- a/internal/terminal/handler/information/information.go +++ b/internal/terminal/handler/information/information.go @@ -29,7 +29,7 @@ type ModelInfo struct { Help help.Model Viewport *viewport.Model - modelError hdlerror.ModelError + modelError *hdlerror.ModelError spinner spinner.Model // keymap @@ -71,7 +71,7 @@ func SetupModelInfo(viewport *viewport.Model, githubUseCase gu.UseCase, version version: version, Help: help.New(), Keys: keys, - modelError: modelError, + modelError: &modelError, spinner: s, } } @@ -149,7 +149,6 @@ func (m *ModelInfo) View() string { } func (m *ModelInfo) testConnection(ctx context.Context) { - time.Sleep(time.Second * 5) // TODO : remove, just for testing spinner _, err := m.github.GetAuthUser(ctx) if err != nil { m.modelError.SetError(err) diff --git a/internal/terminal/handler/taboptions/taboptions.go b/internal/terminal/handler/taboptions/taboptions.go index ce9f29d..b37c6e7 100644 --- a/internal/terminal/handler/taboptions/taboptions.go +++ b/internal/terminal/handler/taboptions/taboptions.go @@ -78,72 +78,13 @@ func NewOptions(modelError *hdlerror.ModelError) *Options { } } -func (o *Options) SetStatus(status OptionStatus) { - o.status = status - o.options[0] = status.String() - o.optionsAction[0] = status.String() -} - -func (o *Options) AddOption(option string, action func()) { - var optionWithNumber string - var optionNumber = len(o.options) - optionWithNumber = fmt.Sprintf("%d) %s", optionNumber, option) - o.options = append(o.options, optionWithNumber) - o.optionsAction = append(o.optionsAction, optionWithNumber) - o.optionsWithFunc[optionNumber] = action -} - -func (o *Options) getOptionMessage() string { - option := o.options[o.cursor] - option = strings.TrimPrefix(option, fmt.Sprintf("%d) ", o.cursor)) - return option -} - -func (o *Options) showAreYouSure() { - if !o.modelLock { - o.previousModelError = *o.modelError - o.modelLock = true - } - o.modelError.Reset() - o.modelError.SetProgressMessage(fmt.Sprintf("Are you sure you want to %s?", o.getOptionMessage())) -} - -func (o *Options) switchToPreviousError() { - if o.modelLock { - return - } - *o.modelError = o.previousModelError -} - -func (o *Options) executeOption() { - go o.optionsWithFunc[o.cursor]() - o.cursor = 0 - o.timer = -1 -} - func (o *Options) Init() tea.Cmd { - return nil -} - -func (o *Options) resetOptionsWithOriginal() { - if o.isTabSelected { - return - } - o.isTabSelected = true - o.timer = 3 - for o.timer >= 0 { - o.optionsAction[0] = fmt.Sprintf("> %ds", o.timer) - time.Sleep(1 * time.Second) - o.timer-- + return func() tea.Msg { + return tea.KeyMsg{} } - o.modelLock = false - o.switchToPreviousError() - o.optionsAction[0] = string(OptionIdle) - o.cursor = 0 - o.isTabSelected = false } -func (o *Options) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (o *Options) Update(msg tea.Msg) (*Options, tea.Cmd) { var cmd tea.Cmd if o.status == OptionWait || o.status == OptionNone { @@ -169,14 +110,6 @@ func (o *Options) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return o, cmd } -func (o *Options) updateCursor(cursor int) { - if cursor < len(o.options) { - o.cursor = cursor - o.showAreYouSure() - go o.resetOptionsWithOriginal() - } -} - func (o *Options) View() string { var style = o.Style.Foreground(lipgloss.Color("15")) @@ -202,3 +135,72 @@ func (o *Options) View() string { return lipgloss.JoinHorizontal(lipgloss.Top, opts...) } + +func (o *Options) resetOptionsWithOriginal() { + if o.isTabSelected { + return + } + o.isTabSelected = true + o.timer = 3 + for o.timer >= 0 { + o.optionsAction[0] = fmt.Sprintf("> %ds", o.timer) + time.Sleep(1 * time.Second) + o.timer-- + } + o.modelLock = false + o.switchToPreviousError() + o.optionsAction[0] = string(OptionIdle) + o.cursor = 0 + o.isTabSelected = false +} + +func (o *Options) updateCursor(cursor int) { + if cursor < len(o.options) { + o.cursor = cursor + o.showAreYouSure() + go o.resetOptionsWithOriginal() + } +} + +func (o *Options) SetStatus(status OptionStatus) { + o.status = status + o.options[0] = status.String() + o.optionsAction[0] = status.String() +} + +func (o *Options) AddOption(option string, action func()) { + var optionWithNumber string + var optionNumber = len(o.options) + optionWithNumber = fmt.Sprintf("%d) %s", optionNumber, option) + o.options = append(o.options, optionWithNumber) + o.optionsAction = append(o.optionsAction, optionWithNumber) + o.optionsWithFunc[optionNumber] = action +} + +func (o *Options) getOptionMessage() string { + option := o.options[o.cursor] + option = strings.TrimPrefix(option, fmt.Sprintf("%d) ", o.cursor)) + return option +} + +func (o *Options) showAreYouSure() { + if !o.modelLock { + o.previousModelError = *o.modelError + o.modelLock = true + } + o.modelError.Reset() + o.modelError.SetProgressMessage(fmt.Sprintf("Are you sure you want to %s?", o.getOptionMessage())) +} + +func (o *Options) switchToPreviousError() { + if o.modelLock { + return + } + *o.modelError = o.previousModelError +} + +func (o *Options) executeOption() { + go o.optionsWithFunc[o.cursor]() + o.cursor = 0 + o.timer = -1 +} diff --git a/pkg/workflow/workflow.go b/pkg/workflow/workflow.go index bce1a0e..8eed977 100644 --- a/pkg/workflow/workflow.go +++ b/pkg/workflow/workflow.go @@ -49,8 +49,6 @@ type Choice struct { Value string } -// TODO: Add support for boolean - func ParseWorkflow(content py.WorkflowContent) (*Workflow, error) { var w = &Workflow{ Content: make(map[string]Content),