Change dashboard tabs to use custom sub widgets
This commit is contained in:
+20
-21
@@ -50,7 +50,7 @@ var (
|
||||
|
||||
type Dashboard struct {
|
||||
Tabs []string
|
||||
TabContent []list.Model
|
||||
TabContent []tea.Model
|
||||
activeTab int
|
||||
width int
|
||||
height int
|
||||
@@ -67,8 +67,9 @@ func (m Dashboard) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.width = msg.Width
|
||||
m.height = msg.Height
|
||||
for i := 0; i < len(m.TabContent); i++ {
|
||||
m.TabContent[i].SetWidth(m.width - 10)
|
||||
m.TabContent[i].SetHeight(m.height - 10)
|
||||
m.TabContent[i].Update(msg)
|
||||
// m.TabContent[i].SetWidth(m.width - 10)
|
||||
// m.TabContent[i].SetHeight(m.height - 10)
|
||||
}
|
||||
case tea.KeyMsg:
|
||||
switch keypress := msg.String(); keypress {
|
||||
@@ -160,34 +161,32 @@ func createDashboard(s CursoriusServer) (Dashboard, error) {
|
||||
client := graphql.NewClient(s.Url, http.DefaultClient)
|
||||
|
||||
tabs := []string{"Pipelines", "Secrets", "Clone Credentials", "Runners"}
|
||||
//testTabs := []list.Item{dashboardItem("Pipelines"), dashboardItem("Secrets"), dashboardItem("Clone Credentials"), dashboardItem("Runners")}
|
||||
|
||||
pipelineWidget, err := widget.CreatePipelineWidget(client)
|
||||
if err != nil {
|
||||
return Dashboard{}, fmt.Errorf("Could not create Pipelines tab: %w", err)
|
||||
}
|
||||
|
||||
secretWidget, err := widget.CreateSecretWidget(client)
|
||||
if err != nil {
|
||||
return Dashboard{}, fmt.Errorf("Could not create Secrets tab: %w", err)
|
||||
}
|
||||
//secretWidget, err := widget.CreateSecretWidget(client)
|
||||
//if err != nil {
|
||||
// return Dashboard{}, fmt.Errorf("Could not create Secrets tab: %w", err)
|
||||
//}
|
||||
|
||||
cloneCredentialWidget, err := widget.CreateCloneCredentialWidget(client)
|
||||
if err != nil {
|
||||
return Dashboard{}, fmt.Errorf("Could not create Clone Credentials tab: %w", err)
|
||||
}
|
||||
//cloneCredentialWidget, err := widget.CreateCloneCredentialWidget(client)
|
||||
//if err != nil {
|
||||
// return Dashboard{}, fmt.Errorf("Could not create Clone Credentials tab: %w", err)
|
||||
//}
|
||||
|
||||
runnerWidget, err := widget.CreateRunnerWidget(client)
|
||||
if err != nil {
|
||||
return Dashboard{}, fmt.Errorf("Could not create Runner tab: %w", err)
|
||||
}
|
||||
//runnerWidget, err := widget.CreateRunnerWidget(client)
|
||||
//if err != nil {
|
||||
// return Dashboard{}, fmt.Errorf("Could not create Runner tab: %w", err)
|
||||
//}
|
||||
|
||||
tabContent := []list.Model{
|
||||
//list.New(testTabs, dashboardItemDelegate{}, 50, 50),
|
||||
tabContent := []tea.Model{
|
||||
pipelineWidget,
|
||||
secretWidget,
|
||||
cloneCredentialWidget,
|
||||
runnerWidget,
|
||||
//secretWidget,
|
||||
//cloneCredentialWidget,
|
||||
//runnerWidget,
|
||||
}
|
||||
|
||||
return Dashboard{
|
||||
|
||||
+227
-18
@@ -7,16 +7,175 @@ import (
|
||||
|
||||
"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
|
||||
|
||||
type pipelineWidget struct {
|
||||
currentView tea.Model
|
||||
width int
|
||||
height int
|
||||
}
|
||||
|
||||
func (m pipelineWidget) Init() tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m pipelineWidget) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case tea.WindowSizeMsg:
|
||||
m.width = msg.Width
|
||||
m.height = msg.Height
|
||||
case pipelineWidgetScreenSwitch:
|
||||
m.currentView = msg
|
||||
}
|
||||
|
||||
var cmd tea.Cmd
|
||||
m.currentView, cmd = m.currentView.Update(msg)
|
||||
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
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 "" }
|
||||
@@ -54,28 +213,78 @@ func (d pipelineListItemDelegate) Render(w io.Writer, m list.Model, index int, l
|
||||
}
|
||||
}
|
||||
|
||||
func CreatePipelineWidget(client graphql.Client) (list.Model, error) {
|
||||
content := []list.Item{}
|
||||
type createPipelineItem struct {
|
||||
field textinput.Model
|
||||
}
|
||||
|
||||
getPipelineResp, err := queries.GetPipelines(context.Background(), client)
|
||||
if err != nil {
|
||||
return list.Model{}, fmt.Errorf("Could not connect to server: %w", err)
|
||||
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)
|
||||
}
|
||||
|
||||
if getPipelineResp.Pipelines != nil {
|
||||
for _, pipeline := range getPipelineResp.Pipelines {
|
||||
content = append(content, pipelineListItem{
|
||||
name: pipeline.Name,
|
||||
id: pipeline.Id,
|
||||
})
|
||||
fn := itemStyle.Render
|
||||
if index == m.Index() {
|
||||
fn = func(s string) string {
|
||||
return selectedItemStyle.Render("> " + s)
|
||||
}
|
||||
}
|
||||
|
||||
content = append(content, pipelineCreateListItem("[Create Pipeline]"))
|
||||
|
||||
model := list.New(content, pipelineListItemDelegate{}, 50, 50)
|
||||
model.SetShowStatusBar(false)
|
||||
model.Title = "Pipelines"
|
||||
|
||||
return model, nil
|
||||
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)
|
||||
if err != nil {
|
||||
return pipelineWidget{}, err
|
||||
}
|
||||
|
||||
return pipelineWidget{
|
||||
currentView: view,
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user