Skip to content

Commit

Permalink
feat(ui): add confirmation before delete (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
eremid authored Jan 23, 2023
1 parent b53d755 commit be3c1a2
Show file tree
Hide file tree
Showing 11 changed files with 604 additions and 260 deletions.
23 changes: 12 additions & 11 deletions tools/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/FrangipaneTeam/bean/config"
"github.com/FrangipaneTeam/bean/pkg/crd"
"github.com/FrangipaneTeam/bean/tui"
"github.com/FrangipaneTeam/bean/tui/pages/k8s"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/glamour"
Expand Down Expand Up @@ -47,17 +48,20 @@ type ErrorMsg struct {
}

// Kubectl runs a kubectl command
func Kubectl(verb string, file string, cmdID string) tea.Cmd {
func Kubectl(k8sCmd *k8s.Cmd) tea.Cmd {
return func() tea.Msg {
if verb == "" || file == "" {
if k8sCmd.Verb == "" || len(k8sCmd.Files) == 0 {
return nil
}

var args []string
if verb == "managed" {
switch k8sCmd.Verb {
case "managed":
args = []string{"get", "managed"}
} else {
args = []string{verb, "-f", file}
case "apply":
args = []string{k8sCmd.Verb, "-f", k8sCmd.JoinedFiles()}
case "delete":
args = []string{k8sCmd.Verb, "--wait=false", "-f", k8sCmd.JoinedFiles()}
}

cmd := exec.Command("kubectl", args...)
Expand All @@ -69,15 +73,12 @@ func Kubectl(verb string, file string, cmdID string) tea.Cmd {
return ErrorMsg{
Reason: fmt.Sprintf("command kubectl %s failed", strings.Join(args, " ")),
Cause: errors.New(stderr.String()),
CmdID: cmdID,
CmdID: k8sCmd.ID,
}
}

return KubectlResult{
Out: stdout.String(),
Verb: verb,
CmdID: cmdID,
}
k8sCmd.Result = stdout.String()
return k8sCmd
}
}

Expand Down
27 changes: 27 additions & 0 deletions tui/keymap.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ type ListKeyMap struct {
Quit key.Binding
UpDown key.Binding
LeftRight key.Binding
Left key.Binding
Right key.Binding
Apply key.Binding
Delete key.Binding
Print key.Binding
Expand Down Expand Up @@ -90,6 +92,14 @@ func NewListKeyMap() *ListKeyMap {
key.WithKeys("T"),
key.WithHelp("T", "generate list tested"),
),
Left: key.NewBinding(
key.WithKeys("left"),
key.WithHelp("←", "left"),
),
Right: key.NewBinding(
key.WithKeys("right"),
key.WithHelp("→", "right"),
),
VpKM: viewport.DefaultKeyMap(),
ListKeyMap: list.DefaultKeyMap(),
}
Expand Down Expand Up @@ -144,6 +154,9 @@ func (m *ListKeyMap) EnableViewPortKeys() {
m.LeftRight.SetEnabled(false)
m.Back.SetEnabled(true)
m.ListKeyMap.Filter.SetEnabled(false)
m.ShowRessources.SetEnabled(false)
m.ShowTested.SetEnabled(false)
m.GenerateListTested.SetEnabled(false)
}

func (m *ListKeyMap) disableViewPortKeys() {
Expand Down Expand Up @@ -184,6 +197,8 @@ func (m *ListKeyMap) EnableRootKeys() {
m.Select.SetEnabled(true)
m.Get.SetEnabled(true)
m.Help.SetEnabled(true)
m.UpDown.SetEnabled(true)
m.LeftRight.SetEnabled(true)
m.ListKeyMap.Filter.SetEnabled(true)
m.ShowRessources.SetEnabled(true)
m.ShowTested.SetEnabled(true)
Expand All @@ -192,6 +207,7 @@ func (m *ListKeyMap) EnableRootKeys() {

// EnableKindListKeys is the set of keys for the kind list
func (m *ListKeyMap) EnableKindListKeys() {
m.disableViewPortKeys()
m.enableK8SKeys()
m.Help.SetEnabled(true)
m.ListKeyMap.Filter.SetEnabled(true)
Expand All @@ -213,3 +229,14 @@ func (m *ListKeyMap) EnablePrintK8SKeys() {
m.UpDown.SetEnabled(false)
m.LeftRight.SetEnabled(false)
}

// EnableDialogBoxKeys is the set of keys for the dialog box
func (m *ListKeyMap) EnableDialogBoxKeys() {
m.disableK8SKeys()
m.disableViewPortKeys()
m.Back.SetEnabled(false)
m.ListKeyMap.Filter.SetEnabled(false)
m.LeftRight.SetEnabled(true)
m.Help.SetEnabled(false)
m.Select.SetEnabled(true)
}
139 changes: 139 additions & 0 deletions tui/pages/dialogbox/dialogbox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package dialogbox

import (
"strings"

"github.com/FrangipaneTeam/bean/tui"
"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)

const (
questionSize = 50
dialogHeight = 9
)

var (
// Dialog.

subtle = lipgloss.AdaptiveColor{Light: "#D9DCCF", Dark: "#383838"}

dialogBoxStyle = lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("#874BFD")).
Padding(1, 0).
BorderTop(true).
BorderLeft(true).
BorderRight(true).
BorderBottom(true)

buttonStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#FFF7DB")).
Background(lipgloss.Color("#888B7E")).
Padding(0, 1).
MarginTop(1)

activeButtonStyle = buttonStyle.Copy().
Foreground(lipgloss.Color("#FFF7DB")).
Background(lipgloss.Color("#F25D94"))
)

// Model is the model of the error panel.
type Model struct {
tea.Model
keys *tui.ListKeyMap
width int
height int
question string
okValue string
cancelValue string
ActiveButton int
}

// New returns a new model of the error panel.
func New(w int, h int, keymap *tui.ListKeyMap) Model {
return Model{
width: w,
height: h,
keys: keymap,
ActiveButton: 2,
}
}

// Init initializes the model.
func (m Model) Init() tea.Cmd {
return nil
}

// Update updates the model.
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
var (
// cmd tea.Cmd
cmds []tea.Cmd
)

switch msg := msg.(type) {
case tea.KeyMsg:
switch {
case key.Matches(msg, m.keys.Left):
m.ActiveButton = 1

case key.Matches(msg, m.keys.Right):
m.ActiveButton = 2
}
}
return m, tea.Batch(cmds...)
}

// View renders the model.
func (m Model) View() string {
var doc strings.Builder

okButton := activeButtonStyle.MarginRight(2).Render(m.okValue)
cancelButton := buttonStyle.Render(m.cancelValue)
// okButton := buttonStyle.MarginRight(2).Render(m.okValue)
// cancelButton := activeButtonStyle.Render(m.cancelValue)

if m.ActiveButton == 2 {
okButton = buttonStyle.MarginRight(2).Render(m.okValue)
cancelButton = activeButtonStyle.Render(m.cancelValue)
}

question := lipgloss.NewStyle().
Width(questionSize).
Align(lipgloss.Center).
Render(m.question)

buttons := lipgloss.JoinHorizontal(lipgloss.Top, okButton, cancelButton)
ui := lipgloss.JoinVertical(lipgloss.Center, question, buttons)

dialog := lipgloss.Place(m.width, m.height,
lipgloss.Center, lipgloss.Center,
dialogBoxStyle.Render(ui),
lipgloss.WithWhitespaceChars("frangipane"),
lipgloss.WithWhitespaceForeground(subtle),
)

// dialog = lipgloss.NewStyle().Width(m.width - 2).Render(dialog)

doc.WriteString(dialog)

return doc.String()
}

func (m *Model) SetWidth(w int) {
m.width = w
}

func (m *Model) SetSize(w int, h int) {
m.width = w
m.height = h
}

func (m *Model) SetDialogBox(question string, okValue string, cancelValue string) {
m.ActiveButton = 2
m.question = question
m.okValue = okValue
m.cancelValue = cancelValue
}
14 changes: 10 additions & 4 deletions tui/pages/errorpanel/errorpanel.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,17 @@ func (m Model) View() string {
panel := lipgloss.JoinVertical(
lipgloss.Top,
lipgloss.NewStyle().Render(wordwrap.String(reason, m.width)),
lipgloss.NewStyle().Margin(0, 0, 2, 0).Render(desc),
lipgloss.NewStyle().Margin(0, 0, 0, 0).Render(desc),
)

b.WriteString(panel)
panelWithBorder := lipgloss.NewStyle().
Height(m.height - 2).
Width(m.width - 2).
MaxHeight(m.height).
Border(lipgloss.HiddenBorder()).
Render(panel)

b.WriteString(panelWithBorder)
return b.String()
}

Expand All @@ -104,10 +111,9 @@ func (m Model) RaiseError(reason string, cause error) Model {
}

// Resize resizes the model
func (m Model) Resize(width, height int) Model {
func (m *Model) SetSize(width, height int) {
m.width = width
m.height = height
return m
}

// Width returns the width of the model
Expand Down
Loading

0 comments on commit be3c1a2

Please sign in to comment.