Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: select child resources based on parent key #31

Merged
merged 10 commits into from
Mar 18, 2024
52 changes: 44 additions & 8 deletions internal/setup/environments.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ type environment struct {
func (p environment) FilterValue() string { return "" }

type environmentModel struct {
choice string
err error
list list.Model
choice string
err error
list list.Model
parentKey string
}

func NewEnvironment() tea.Model {
environments := []environment{
var environments = map[string][]environment{
"proj1": {
{
Key: "env1",
Name: "environment 1",
Expand All @@ -41,9 +42,38 @@ func NewEnvironment() tea.Model {
Key: "env2",
Name: "environment 2",
},
}
},
"proj2": {
{
Key: "env3",
Name: "environment 3",
},
{
Key: "env4",
Name: "environment 4",
},
},
"proj3": {
{
Key: "env5",
Name: "environment 5",
},
{
Key: "env6",
Name: "environment 6",
},
},
}

l := list.New(environmentsToItems(environments), envDelegate{}, 30, 14)
func getEnvironments(projKey string) ([]environment, error) {
envList := environments[projKey]
createNewOption := environment{Key: CreateNewResourceKey, Name: "Create a new environment"}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right now choosing this option won't actually do anything (except for projects)

envList = append(envList, createNewOption)
return envList, nil
}

func NewEnvironment() tea.Model {
l := list.New(nil, envDelegate{}, 30, 14)
l.Title = "Select an environment"
l.SetShowStatusBar(false)
l.SetFilteringEnabled(false)
Expand All @@ -57,10 +87,16 @@ func (p environmentModel) Init() tea.Cmd {
return nil
}

// This method has drifted from the ProjectModel's version, but it should do something similar.
func (m environmentModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case fetchResources:
envs, err := getEnvironments(m.parentKey)
if err != nil {
m.err = err
return m, nil
}
m.list.SetItems(environmentsToItems(envs))
case tea.KeyMsg:
switch {
case key.Matches(msg, keys.Enter):
Expand Down
81 changes: 74 additions & 7 deletions internal/setup/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ type flag struct {
func (p flag) FilterValue() string { return "" }

type flagModel struct {
choice string
err error
list list.Model
choice string
err error
list list.Model
parentKey string
}

func NewFlag() tea.Model {
flags := []flag{
var flags = map[string][]flag{
"env1": {
{
Key: "flag1",
Name: "flag 1",
Expand All @@ -41,9 +42,61 @@ func NewFlag() tea.Model {
Key: "flag2",
Name: "flag 2",
},
}
},
"env2": {
{
Key: "flag3",
Name: "flag 3",
},
{
Key: "flag4",
Name: "flag 4",
},
},
"env3": {
{
Key: "flag5",
Name: "flag 5",
},
{
Key: "flag6",
Name: "flag 6",
},
},
"env4": {
{
Key: "flag7",
Name: "flag 7",
},
{
Key: "flag8",
Name: "flag 8",
},
},
"env5": {
{
Key: "flag9",
Name: "flag 9",
},
{
Key: "flag10",
Name: "flag 10",
},
},
"env6": {
{
Key: "flag11",
Name: "flag 11",
},
{
Key: "flag12",
Name: "flag 12",
},
},
}

l := list.New(flagsToItems(flags), flagDelegate{}, 30, 14)
func NewFlag() tea.Model {
l := list.New(nil, flagDelegate{}, 30, 14)
l.Title = "Select a flag"
l.SetShowStatusBar(false)
l.SetFilteringEnabled(false)
Expand All @@ -61,6 +114,13 @@ func (p flagModel) Init() tea.Cmd {
func (m flagModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case fetchResources:
fs, err := getFlags(m.parentKey)
if err != nil {
m.err = err
return m, nil
}
m.list.SetItems(flagsToItems(fs))
case tea.KeyMsg:
switch {
case key.Matches(msg, keys.Enter):
Expand All @@ -82,6 +142,13 @@ func (m flagModel) View() string {
return "\n" + m.list.View()
}

func getFlags(envKey string) ([]flag, error) {
flagList := flags[envKey]
createNewOption := flag{Key: CreateNewResourceKey, Name: "Create a new flag"}
flagList = append(flagList, createNewOption)
return flagList, nil
}

type flagDelegate struct{}

func (d flagDelegate) Height() int { return 1 }
Expand Down
82 changes: 61 additions & 21 deletions internal/setup/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"github.com/charmbracelet/lipgloss"
)

const CreateNewResourceKey string = "create-new"

var (
projectStyle = lipgloss.NewStyle().PaddingLeft(4)
selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("170"))
Expand All @@ -26,9 +28,11 @@ type project struct {
func (p project) FilterValue() string { return "" }

type projectModel struct {
choice string
err error
list list.Model
choice string
err error
list list.Model
showInput bool
textInput tea.Model
}

func NewProject() tea.Model {
Expand All @@ -48,8 +52,30 @@ func (p projectModel) Init() tea.Cmd {

func (m projectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
if m.showInput {
m.textInput, cmd = m.textInput.Update(msg)

// catch the enter key here to update the model when a final value is provided
switch msg := msg.(type) {
case tea.KeyMsg:
switch {
case key.Matches(msg, keys.Enter):
iModel, ok := m.textInput.(inputModel)
if ok {
m.choice = iModel.textInput.Value()
m.showInput = false
}

// TODO: send request to create project, hardcoding for now
projects = append(projects, project{Key: m.choice, Name: m.choice})
}
default:

}
return m, cmd
}
switch msg := msg.(type) {
case fetchProjects:
case fetchResources:
projects, err := getProjects()
if err != nil {
m.err = err
Expand All @@ -59,9 +85,16 @@ func (m projectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case tea.KeyMsg:
switch {
case key.Matches(msg, keys.Enter):

i, ok := m.list.SelectedItem().(project)
if ok {
m.choice = i.Key
if i.Key == CreateNewResourceKey {
iModel := newTextInputModel("desired-proj-key", "Enter project name")
m.textInput = iModel
m.showInput = true
} else {
m.choice = i.Key
}
}
case key.Matches(msg, keys.Quit):
return m, tea.Quit
Expand All @@ -74,6 +107,10 @@ func (m projectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}

func (m projectModel) View() string {
if m.showInput {
return m.textInput.View()
}

return "\n" + m.list.View()
}

Expand Down Expand Up @@ -110,27 +147,30 @@ func projectsToItems(projects []project) []list.Item {
return items
}

type fetchProjects struct{}

// type projectsResponse struct {
// Items []project `json:"items"`
// }

var projects = []project{
{
Key: "proj1",
Name: "project 1",
},
{
Key: "proj2",
Name: "project 2",
},
{
Key: "proj3",
Name: "project 3",
},
}

func getProjects() ([]project, error) {
return []project{
{
Key: "proj1",
Name: "project 1",
},
{
Key: "proj2",
Name: "project 2",
},
{
Key: "proj3",
Name: "project 3",
},
}, nil
projectList := projects
createNewOption := project{Key: CreateNewResourceKey, Name: "Create a new project"}
projectList = append(projectList, createNewOption)
return projectList, nil

// uncomment out below to fetch projects locally after adding an access token to the
// Authorization header
Expand Down
62 changes: 62 additions & 0 deletions internal/setup/text_input.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package setup

import (
"fmt"

"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
)

type inputModel struct {
textInput textinput.Model
done bool
title string
err error
}

func newTextInputModel(placeholder, title string) inputModel {
ti := textinput.New()
ti.Placeholder = placeholder
ti.Focus()
ti.CharLimit = 156
ti.Width = 20

return inputModel{
title: title,
textInput: ti,
err: nil,
}
}

func (m inputModel) Init() tea.Cmd {
return textinput.Blink
}

func (m inputModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd

switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.Type {
case tea.KeyEnter:
m.done = true
return m, nil
case tea.KeyCtrlC, tea.KeyEsc:
return m, tea.Quit
}

// TODO: Handle errors
}

m.textInput, cmd = m.textInput.Update(msg)
return m, cmd
}

func (m inputModel) View() string {
return fmt.Sprintf(
"%s\n\n%s\n\n%s",
m.title,
m.textInput.View(),
"(esc to quit)",
) + "\n"
}
Loading