Refactor pipeline widget into multiple files
This commit is contained in:
@@ -1,16 +1,8 @@
|
|||||||
package widget
|
package widget
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/Khan/genqlient/graphql"
|
"github.com/Khan/genqlient/graphql"
|
||||||
"github.com/charmbracelet/bubbles/list"
|
|
||||||
"github.com/charmbracelet/bubbles/textinput"
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
|
||||||
"git.ohea.xyz/cursorius/tui/queries"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type pipelineWidgetScreenSwitch tea.Model
|
type pipelineWidgetScreenSwitch tea.Model
|
||||||
@@ -44,239 +36,6 @@ func (m pipelineWidget) View() string {
|
|||||||
return m.currentView.View()
|
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) {
|
func CreatePipelineWidget(client graphql.Client) (tea.Model, error) {
|
||||||
|
|
||||||
view, err := createPipelineWidgetList(client)
|
view, err := createPipelineWidgetList(client)
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user