Add support for viewing pipeline run output
This commit is contained in:
+10
-10
@@ -42,16 +42,16 @@ func (m pipelineWidgetList) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
|
||||
case "enter":
|
||||
if m.list.Index() < len(m.list.Items())-1 {
|
||||
//item := m.list.SelectedItem()
|
||||
//if item, ok := item.(pipelineListItem); ok {
|
||||
// return m, func() tea.Cmd {
|
||||
// view, err := createPipelineEditForm(client, item.id)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return pipelineWidgetScreenSwitch(view)
|
||||
// }
|
||||
//}
|
||||
item := m.list.SelectedItem()
|
||||
if item, ok := item.(pipelineListItem); ok {
|
||||
return m, func() tea.Msg {
|
||||
view, err := createPipelineWidgetView(m.client, item.id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return pipelineWidgetScreenSwitch(view)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return m, func() tea.Msg {
|
||||
view, err := createPipelineCreateForm(m.client, m.list.Width(), m.list.Height())
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
package widget
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"git.ohea.xyz/cursorius/tui/queries"
|
||||
|
||||
"github.com/Khan/genqlient/graphql"
|
||||
"github.com/charmbracelet/bubbles/list"
|
||||
"github.com/charmbracelet/bubbles/viewport"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
type pipelineWidgetViewPage int
|
||||
|
||||
const (
|
||||
topLevel pipelineWidgetViewPage = 0
|
||||
viewRun = 1
|
||||
viewRunBuildOutput = 2
|
||||
viewRunStdout = 3
|
||||
viewRunStderr = 4
|
||||
)
|
||||
|
||||
type pipelineWidgetView struct {
|
||||
client graphql.Client
|
||||
page pipelineWidgetViewPage
|
||||
pipeline queries.GetPipelinePipeline
|
||||
runsList list.Model
|
||||
viewRunSelector list.Model
|
||||
viewRunBuildOutputPager viewport.Model
|
||||
viewRunStdoutPager viewport.Model
|
||||
viewRunStderrPager viewport.Model
|
||||
}
|
||||
|
||||
func (m pipelineWidgetView) Init() tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m pipelineWidgetView) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case tea.WindowSizeMsg:
|
||||
m.runsList.SetWidth(msg.Width - 20)
|
||||
m.runsList.SetHeight(msg.Height - 20)
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "r":
|
||||
return m, func() tea.Msg {
|
||||
view, err := createPipelineWidgetView(m.client, m.pipeline.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return pipelineWidgetScreenSwitch(view)
|
||||
}
|
||||
case "backspace":
|
||||
switch m.page {
|
||||
case topLevel:
|
||||
return m, func() tea.Msg {
|
||||
view, err := createPipelineWidgetList(m.client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return pipelineWidgetScreenSwitch(view)
|
||||
}
|
||||
case viewRun:
|
||||
m.page = topLevel
|
||||
case viewRunBuildOutput:
|
||||
m.page = viewRun
|
||||
case viewRunStderr:
|
||||
m.page = viewRun
|
||||
case viewRunStdout:
|
||||
m.page = viewRun
|
||||
}
|
||||
case "enter":
|
||||
switch m.page {
|
||||
case topLevel:
|
||||
run := m.pipeline.Runs[m.runsList.Index()]
|
||||
|
||||
content := []list.Item{
|
||||
pipelineWidgetViewRunsSelectorItem(fmt.Sprintf("ID: %v", run.Id)),
|
||||
}
|
||||
|
||||
if run.InProgress != nil {
|
||||
content = append(content, pipelineWidgetViewRunsSelectorItem(fmt.Sprintf("In Progress: %v", *run.InProgress)))
|
||||
} else {
|
||||
content = append(content, pipelineWidgetViewRunsSelectorItem("In Progress: null"))
|
||||
}
|
||||
if run.Result != nil {
|
||||
content = append(content, pipelineWidgetViewRunsSelectorItem(fmt.Sprintf("Result: %v", *run.Result)))
|
||||
} else {
|
||||
content = append(content, pipelineWidgetViewRunsSelectorItem("Result: null"))
|
||||
}
|
||||
content = append(content, pipelineWidgetViewRunsSelectorItem("View Build Output"))
|
||||
content = append(content, pipelineWidgetViewRunsSelectorItem("View Stdout"))
|
||||
content = append(content, pipelineWidgetViewRunsSelectorItem("View Stderr"))
|
||||
|
||||
runOutputList := list.New(content, pipelineWigetViewRunsSelectorItemDelegate{}, m.runsList.Width(), m.runsList.Height())
|
||||
runOutputList.SetShowStatusBar(false)
|
||||
runOutputList.Title = "View Run"
|
||||
runOutputList.DisableQuitKeybindings()
|
||||
|
||||
m.viewRunSelector = runOutputList
|
||||
|
||||
m.page = viewRun
|
||||
case viewRun:
|
||||
run := m.pipeline.Runs[m.runsList.Index()]
|
||||
switch m.viewRunSelector.Index() {
|
||||
case 3:
|
||||
if run.BuildOutput == nil {
|
||||
break
|
||||
}
|
||||
m.viewRunBuildOutputPager = viewport.New(m.runsList.Width(), m.runsList.Height())
|
||||
m.viewRunBuildOutputPager.SetContent(*run.BuildOutput)
|
||||
m.page = viewRunBuildOutput
|
||||
case 4:
|
||||
if run.Stdout == nil {
|
||||
break
|
||||
}
|
||||
m.viewRunStdoutPager = viewport.New(m.runsList.Width(), m.runsList.Height())
|
||||
m.viewRunStdoutPager.SetContent(*run.Stdout)
|
||||
|
||||
m.page = viewRunStdout
|
||||
case 5:
|
||||
if run.Stderr == nil {
|
||||
break
|
||||
}
|
||||
m.viewRunStderrPager = viewport.New(m.runsList.Width(), m.runsList.Height())
|
||||
m.viewRunStderrPager.SetContent(*run.Stderr)
|
||||
|
||||
m.page = viewRunStderr
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var cmd tea.Cmd
|
||||
switch m.page {
|
||||
case topLevel:
|
||||
m.runsList, cmd = m.runsList.Update(msg)
|
||||
case viewRun:
|
||||
m.viewRunSelector, cmd = m.viewRunSelector.Update(msg)
|
||||
case viewRunBuildOutput:
|
||||
m.viewRunBuildOutputPager, cmd = m.viewRunBuildOutputPager.Update(msg)
|
||||
case viewRunStdout:
|
||||
m.viewRunStdoutPager, cmd = m.viewRunStdoutPager.Update(msg)
|
||||
case viewRunStderr:
|
||||
m.viewRunStderrPager, cmd = m.viewRunStderrPager.Update(msg)
|
||||
}
|
||||
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
func (m pipelineWidgetView) View() string {
|
||||
s := ""
|
||||
switch m.page {
|
||||
case topLevel:
|
||||
s += fmt.Sprintf("Pipeline: %v\n\n", m.pipeline.Name)
|
||||
s += fmt.Sprintf("Id: %v\n", m.pipeline.Id)
|
||||
s += fmt.Sprintf("Url: %v\n", m.pipeline.Url)
|
||||
s += fmt.Sprintf("Poll Interval: %v\n", m.pipeline.PollInterval)
|
||||
if m.pipeline.CloneCredential != nil {
|
||||
s += fmt.Sprintf("Clone Credential: %v (%v)\n\n", m.pipeline.CloneCredential.Name, m.pipeline.CloneCredential.Type)
|
||||
} else {
|
||||
s += fmt.Sprintf("Clone Credential: None\n\n")
|
||||
}
|
||||
s += m.runsList.View()
|
||||
case viewRun:
|
||||
s += m.viewRunSelector.View()
|
||||
case viewRunBuildOutput:
|
||||
s += m.viewRunBuildOutputPager.View()
|
||||
case viewRunStdout:
|
||||
s += m.viewRunStdoutPager.View()
|
||||
case viewRunStderr:
|
||||
s += m.viewRunStderrPager.View()
|
||||
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func createPipelineWidgetView(client graphql.Client, id string) (tea.Model, error) {
|
||||
|
||||
getPipelineResp, err := queries.GetPipeline(context.Background(), client, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if getPipelineResp.Pipeline == nil {
|
||||
return nil, fmt.Errorf("Server did not give us a pipeline")
|
||||
}
|
||||
|
||||
var content []list.Item
|
||||
|
||||
for _, run := range getPipelineResp.Pipeline.Runs {
|
||||
content = append(content, pipelineWidgetViewRunsItem{
|
||||
id: run.Id,
|
||||
})
|
||||
}
|
||||
|
||||
runsList := list.New(content, pipelineWigetViewRunsItemDelegate{}, 0, 0)
|
||||
runsList.SetShowStatusBar(false)
|
||||
runsList.Title = "Runs"
|
||||
|
||||
return pipelineWidgetView{
|
||||
client: client,
|
||||
page: topLevel,
|
||||
pipeline: *getPipelineResp.Pipeline,
|
||||
runsList: runsList,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type pipelineWidgetViewRunsItem struct {
|
||||
id string
|
||||
}
|
||||
|
||||
func (i pipelineWidgetViewRunsItem) FilterValue() string { return "" }
|
||||
|
||||
type pipelineWigetViewRunsItemDelegate struct{}
|
||||
|
||||
func (d pipelineWigetViewRunsItemDelegate) Height() int { return 1 }
|
||||
func (d pipelineWigetViewRunsItemDelegate) Spacing() int { return 0 }
|
||||
func (d pipelineWigetViewRunsItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { return nil }
|
||||
func (d pipelineWigetViewRunsItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
|
||||
switch i := listItem.(type) {
|
||||
case pipelineWidgetViewRunsItem:
|
||||
fn := itemStyle.Render
|
||||
if index == m.Index() {
|
||||
fn = func(s string) string {
|
||||
return selectedItemStyle.Render("> " + s)
|
||||
}
|
||||
}
|
||||
|
||||
str := fn(i.id)
|
||||
fmt.Fprint(w, str)
|
||||
}
|
||||
}
|
||||
|
||||
type pipelineWidgetViewRunsSelectorItem string
|
||||
|
||||
func (i pipelineWidgetViewRunsSelectorItem) FilterValue() string { return "" }
|
||||
|
||||
type pipelineWigetViewRunsSelectorItemDelegate struct{}
|
||||
|
||||
func (d pipelineWigetViewRunsSelectorItemDelegate) Height() int { return 1 }
|
||||
func (d pipelineWigetViewRunsSelectorItemDelegate) Spacing() int { return 0 }
|
||||
func (d pipelineWigetViewRunsSelectorItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
func (d pipelineWigetViewRunsSelectorItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
|
||||
switch i := listItem.(type) {
|
||||
case pipelineWidgetViewRunsSelectorItem:
|
||||
fn := itemStyle.Render
|
||||
if index == m.Index() {
|
||||
fn = func(s string) string {
|
||||
return selectedItemStyle.Render("> " + s)
|
||||
}
|
||||
}
|
||||
|
||||
str := fn(string(i))
|
||||
fmt.Fprint(w, str)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user