Refactor pipeline widget into multiple files

This commit is contained in:
2023-02-24 17:55:50 -07:00
parent 6cf2aefc6d
commit 5c1c1478ee
3 changed files with 255 additions and 241 deletions
-241
View File
@@ -1,16 +1,8 @@
package widget
import (
"context"
"fmt"
"io"
"github.com/Khan/genqlient/graphql"
"github.com/charmbracelet/bubbles/list"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"git.ohea.xyz/cursorius/tui/queries"
)
type pipelineWidgetScreenSwitch tea.Model
@@ -44,239 +36,6 @@ func (m pipelineWidget) View() string {
return m.currentView.View()
}
type pipelineWidgetList struct {
list list.Model
client graphql.Client
}
func (m pipelineWidgetList) Init() tea.Cmd {
return nil
}
func (m pipelineWidgetList) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.list.SetWidth(msg.Width - 10)
m.list.SetHeight(msg.Height - 10)
case tea.KeyMsg:
switch msg.String() {
case "down":
if m.list.Index() < len(m.list.Items()) {
m.list.Select(m.list.Index() + 1)
}
case "up":
if m.list.Index() > 0 {
m.list.Select(m.list.Index() - 1)
}
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)
// }
//}
} else {
return m, func() tea.Msg {
view, err := createPipelineCreateForm(m.client, m.list.Width(), m.list.Height())
if err != nil {
return err
}
return pipelineWidgetScreenSwitch(view)
}
}
}
}
return m, nil
}
func (m pipelineWidgetList) View() string {
return m.list.View()
}
type pipelineListItem struct {
name string
id string
}
func createPipelineWidgetList(client graphql.Client) (tea.Model, error) {
getPipelineResp, err := queries.GetPipelines(context.Background(), client)
if err != nil {
return pipelineWidget{}, fmt.Errorf("Could not connect to server: %w", err)
}
var content []list.Item
if getPipelineResp.Pipelines != nil {
for _, pipeline := range getPipelineResp.Pipelines {
if pipeline != nil {
content = append(content, pipelineListItem{
name: pipeline.Name,
id: pipeline.Id,
})
}
}
}
content = append(content, pipelineCreateListItem("[Create Pipeline]"))
pipelineList := list.New(content, pipelineListItemDelegate{}, 0, 0)
pipelineList.SetShowStatusBar(false)
pipelineList.Title = "Pipelines"
return pipelineWidgetList{
list: pipelineList,
client: client,
}, nil
}
type pipelineCreateForm struct {
list list.Model
}
func (m pipelineCreateForm) Init() tea.Cmd {
return nil
}
func (m pipelineCreateForm) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "enter":
// TODO: enable submitting
}
}
var cmd tea.Cmd
m.list, cmd = m.list.Update(msg)
items := m.list.Items()
for i := 0; i < len(items); i++ {
if e, ok := items[i].(createPipelineItem); ok {
if i == m.list.Index() {
e.field.Focus()
e.field, _ = e.field.Update(msg)
} else {
e.field.Blur()
}
m.list.SetItem(i, e)
}
}
return m, cmd
}
func (m pipelineCreateForm) View() string {
return m.list.View()
}
type pipelineCreateListItem string
func (i pipelineListItem) FilterValue() string { return "" }
func (i pipelineCreateListItem) FilterValue() string { return "" }
type pipelineListItemDelegate struct{}
func (d pipelineListItemDelegate) Height() int { return 1 }
func (d pipelineListItemDelegate) Spacing() int { return 0 }
func (d pipelineListItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { return nil }
func (d pipelineListItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
switch i := listItem.(type) {
case pipelineListItem:
fn := itemStyle.Render
faintFn := faintItemStyle.Render
if index == m.Index() {
fn = func(s string) string {
return selectedItemStyle.Render("> " + s)
}
faintFn = faintSelectedItemStyle.Render
}
str := fn(i.name) + faintFn(" ("+i.id+")")
fmt.Fprint(w, str)
case pipelineCreateListItem:
fn := itemStyle.Render
if index == m.Index() {
fn = func(s string) string {
return selectedItemStyle.Render("> " + s)
}
}
str := string(i)
fmt.Fprint(w, fn(str))
}
}
type createPipelineItem struct {
field textinput.Model
}
type createPipelineSubmitItem string
func (i createPipelineItem) FilterValue() string { return "" }
func (i createPipelineSubmitItem) FilterValue() string { return "" }
type createPipelineDelegate struct{}
func (d createPipelineDelegate) Height() int { return 1 }
func (d createPipelineDelegate) Spacing() int { return 0 }
func (d createPipelineDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { return nil }
func (d createPipelineDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
var str string
switch i := listItem.(type) {
case createPipelineItem:
str = i.field.View()
case createPipelineSubmitItem:
str = string(i)
}
fn := itemStyle.Render
if index == m.Index() {
fn = func(s string) string {
return selectedItemStyle.Render("> " + s)
}
}
fmt.Fprint(w, fn(str))
}
func createPipelineCreateForm(client graphql.Client, width int, height int) (tea.Model, error) {
nameField := textinput.New()
nameField.Focus()
nameField.Width = 20
nameField.Prompt = "Name: "
nameField.Placeholder = "pipeline0"
urlField := textinput.New()
urlField.Prompt = "Url: "
urlField.Placeholder = "https://git.cursorius.ohea/group/repo"
pollIntervalField := textinput.New()
pollIntervalField.Width = 20
pollIntervalField.Prompt = "Poll Interval: "
pollIntervalField.Placeholder = "0 (disable polling)"
items := []list.Item{
createPipelineItem{field: nameField},
createPipelineItem{field: urlField},
createPipelineItem{field: pollIntervalField},
createPipelineSubmitItem("> Submit <"),
}
l := list.New(items, createPipelineDelegate{}, width, height-10)
l.Title = "Create a new pipeline."
l.SetShowStatusBar(false)
l.KeyMap.GoToStart.SetEnabled(false)
l.KeyMap.GoToEnd.SetEnabled(false)
l.KeyMap.Filter.SetEnabled(false)
l.KeyMap.Quit.SetEnabled(false)
return pipelineCreateForm{
list: l,
}, nil
}
func CreatePipelineWidget(client graphql.Client) (tea.Model, error) {
view, err := createPipelineWidgetList(client)
+153
View File
@@ -0,0 +1,153 @@
package widget
import (
"fmt"
"io"
"github.com/Khan/genqlient/graphql"
"github.com/charmbracelet/bubbles/list"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
)
type pipelineCreateForm struct {
list list.Model
}
func (m pipelineCreateForm) Init() tea.Cmd {
return nil
}
func (m pipelineCreateForm) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "enter":
// TODO: enable submitting
}
}
var cmd tea.Cmd
m.list, cmd = m.list.Update(msg)
items := m.list.Items()
for i := 0; i < len(items); i++ {
if e, ok := items[i].(createPipelineItem); ok {
if i == m.list.Index() {
e.field.Focus()
e.field, _ = e.field.Update(msg)
} else {
e.field.Blur()
}
m.list.SetItem(i, e)
}
}
return m, cmd
}
func (m pipelineCreateForm) View() string {
return m.list.View()
}
type pipelineCreateListItem string
func (i pipelineListItem) FilterValue() string { return "" }
func (i pipelineCreateListItem) FilterValue() string { return "" }
type pipelineListItemDelegate struct{}
func (d pipelineListItemDelegate) Height() int { return 1 }
func (d pipelineListItemDelegate) Spacing() int { return 0 }
func (d pipelineListItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { return nil }
func (d pipelineListItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
switch i := listItem.(type) {
case pipelineListItem:
fn := itemStyle.Render
faintFn := faintItemStyle.Render
if index == m.Index() {
fn = func(s string) string {
return selectedItemStyle.Render("> " + s)
}
faintFn = faintSelectedItemStyle.Render
}
str := fn(i.name) + faintFn(" ("+i.id+")")
fmt.Fprint(w, str)
case pipelineCreateListItem:
fn := itemStyle.Render
if index == m.Index() {
fn = func(s string) string {
return selectedItemStyle.Render("> " + s)
}
}
str := string(i)
fmt.Fprint(w, fn(str))
}
}
type createPipelineItem struct {
field textinput.Model
}
type createPipelineSubmitItem string
func (i createPipelineItem) FilterValue() string { return "" }
func (i createPipelineSubmitItem) FilterValue() string { return "" }
type createPipelineDelegate struct{}
func (d createPipelineDelegate) Height() int { return 1 }
func (d createPipelineDelegate) Spacing() int { return 0 }
func (d createPipelineDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { return nil }
func (d createPipelineDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
var str string
switch i := listItem.(type) {
case createPipelineItem:
str = i.field.View()
case createPipelineSubmitItem:
str = string(i)
}
fn := itemStyle.Render
if index == m.Index() {
fn = func(s string) string {
return selectedItemStyle.Render("> " + s)
}
}
fmt.Fprint(w, fn(str))
}
func createPipelineCreateForm(client graphql.Client, width int, height int) (tea.Model, error) {
nameField := textinput.New()
nameField.Focus()
nameField.Width = 20
nameField.Prompt = "Name: "
nameField.Placeholder = "pipeline0"
urlField := textinput.New()
urlField.Prompt = "Url: "
urlField.Placeholder = "https://git.cursorius.ohea/group/repo"
pollIntervalField := textinput.New()
pollIntervalField.Width = 20
pollIntervalField.Prompt = "Poll Interval: "
pollIntervalField.Placeholder = "0 (disable polling)"
items := []list.Item{
createPipelineItem{field: nameField},
createPipelineItem{field: urlField},
createPipelineItem{field: pollIntervalField},
createPipelineSubmitItem("> Submit <"),
}
l := list.New(items, createPipelineDelegate{}, width, height-10)
l.Title = "Create a new pipeline."
l.SetShowStatusBar(false)
l.KeyMap.GoToStart.SetEnabled(false)
l.KeyMap.GoToEnd.SetEnabled(false)
l.KeyMap.Filter.SetEnabled(false)
l.KeyMap.Quit.SetEnabled(false)
return pipelineCreateForm{
list: l,
}, nil
}
+102
View File
@@ -0,0 +1,102 @@
package widget
import (
"context"
"fmt"
"git.ohea.xyz/cursorius/tui/queries"
"github.com/Khan/genqlient/graphql"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
)
type pipelineWidgetList struct {
list list.Model
client graphql.Client
}
func (m pipelineWidgetList) Init() tea.Cmd {
return nil
}
func (m pipelineWidgetList) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.list.SetWidth(msg.Width - 10)
m.list.SetHeight(msg.Height - 10)
case tea.KeyMsg:
switch msg.String() {
case "down":
if m.list.Index() < len(m.list.Items()) {
m.list.Select(m.list.Index() + 1)
}
case "up":
if m.list.Index() > 0 {
m.list.Select(m.list.Index() - 1)
}
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)
// }
//}
} else {
return m, func() tea.Msg {
view, err := createPipelineCreateForm(m.client, m.list.Width(), m.list.Height())
if err != nil {
return err
}
return pipelineWidgetScreenSwitch(view)
}
}
}
}
return m, nil
}
func (m pipelineWidgetList) View() string {
return m.list.View()
}
type pipelineListItem struct {
name string
id string
}
func createPipelineWidgetList(client graphql.Client) (tea.Model, error) {
getPipelineResp, err := queries.GetPipelines(context.Background(), client)
if err != nil {
return pipelineWidget{}, fmt.Errorf("Could not connect to server: %w", err)
}
var content []list.Item
if getPipelineResp.Pipelines != nil {
for _, pipeline := range getPipelineResp.Pipelines {
if pipeline != nil {
content = append(content, pipelineListItem{
name: pipeline.Name,
id: pipeline.Id,
})
}
}
}
content = append(content, pipelineCreateListItem("[Create Pipeline]"))
pipelineList := list.New(content, pipelineListItemDelegate{}, 0, 0)
pipelineList.SetShowStatusBar(false)
pipelineList.Title = "Pipelines"
return pipelineWidgetList{
list: pipelineList,
client: client,
}, nil
}