Skip to content

Commit

Permalink
workspace select
Browse files Browse the repository at this point in the history
  • Loading branch information
rusq committed Nov 16, 2024
1 parent effcf78 commit 984fc0f
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 35 deletions.
44 changes: 24 additions & 20 deletions cmd/slackdump/internal/workspace/wiz_select.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,42 +44,46 @@ func wizSelect(ctx context.Context, cmd *base.Command, args []string) error {
}

// newWspSelectModel creates a new workspace selection model.
func newWspSelectModel(ctx context.Context, m manager) (tea.Model, error) {
wspList, err := m.List()
func newWspSelectModel(ctx context.Context, m *cache.Manager) (tea.Model, error) {
_, err := m.List()
if err != nil {
if errors.Is(err, cache.ErrNoWorkspaces) {
if err := workspaceui.ShowUI(ctx, true); err != nil {
return nil, err
}
// retry
wspList, err = m.List()
if err != nil {
return nil, err
}
} else {
base.SetExitStatus(base.SUserError)
return nil, err
}
}

current, err := m.Current()
if err != nil {
if _, err := m.Current(); err != nil {
base.SetExitStatus(base.SWorkspaceError)
return nil, fmt.Errorf("error getting the current workspace: %s", err)
}

columns := []table.Column{
{Title: "C", Width: 1},
{Title: "Name", Width: 14},
{Title: "Team", Width: 15},
{Title: "User", Width: 15},
{Title: "Status", Width: 30},
}
var refreshFn = func() (cols []table.Column, rows []table.Row, err error) {
cols = []table.Column{
{Title: "C", Width: 1},
{Title: "Name", Width: 14},
{Title: "Team", Width: 15},
{Title: "User", Width: 15},
{Title: "Status", Width: 30},
}

var rows []table.Row
for _, w := range wspInfo(ctx, m, current, wspList) {
rows = append(rows, table.Row{w[0], w[1], w[4], w[5], w[6]})
wspList, err := m.List()
if err != nil {
return
}
current, err := m.Current()
if err != nil {
return
}
for _, w := range wspInfo(ctx, m, current, wspList) {
rows = append(rows, table.Row{w[0], w[1], w[4], w[5], w[6]})
}
return cols, rows, nil
}

return workspaceui.NewSelectModel(columns, rows), nil
return workspaceui.NewSelectModel(m, refreshFn), nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
//go:generate mockgen -package workspaceui -destination=test_mock_manager.go -source api.go manager
type manager interface {
CreateAndSelect(ctx context.Context, p auth.Provider) (string, error)
Select(name string) error
Delete(name string) error
}

func WorkspaceNew(ctx context.Context, _ *base.Command, _ []string) error {
Expand Down
76 changes: 61 additions & 15 deletions cmd/slackdump/internal/workspace/workspaceui/select.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package workspaceui

import (
"strings"

"github.com/charmbracelet/bubbles/help"
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/table"
Expand All @@ -10,16 +12,22 @@ import (
)

type SelectModel struct {
Selected string
Selected string
m manager
refreshFn TableRefreshFunc

table table.Model
finished bool
style style
keymap selKeymap
help help.Model
lastErr error
}

func NewSelectModel(columns []table.Column, rows []table.Row) SelectModel {
type TableRefreshFunc func() ([]table.Column, []table.Row, error)

func NewSelectModel(m manager, refreshFn TableRefreshFunc) SelectModel {
columns, rows, err := refreshFn()
t := table.New(
table.WithColumns(columns),
table.WithRows(rows),
Expand All @@ -35,23 +43,33 @@ func NewSelectModel(columns []table.Column, rows []table.Row) SelectModel {
t.SetStyles(s)
t.Focus()
return SelectModel{
table: t,
table: t,
m: m,
refreshFn: refreshFn,
style: style{
FocusedBorder: ui.DefaultTheme().Focused.Border,
Title: ui.DefaultTheme().Focused.Title,
Description: ui.DefaultTheme().Focused.Description,
Error: ui.DefaultTheme().Error,
},
keymap: defSelKeymap(),
help: help.New(),
keymap: defSelKeymap(),
help: help.New(),
lastErr: err,
}
}

type style struct {
FocusedBorder lipgloss.Style
Title lipgloss.Style
Description lipgloss.Style
Error lipgloss.Style
}

type selKeymap struct {
Select key.Binding
Delete key.Binding
Quit key.Binding
Select key.Binding
Delete key.Binding
Quit key.Binding
Refresh key.Binding
}

func (k selKeymap) Bindings() []key.Binding {
Expand All @@ -60,27 +78,45 @@ func (k selKeymap) Bindings() []key.Binding {

func defSelKeymap() selKeymap {
return selKeymap{
Select: key.NewBinding(key.WithKeys("enter"), key.WithHelp("Enter", "Select")),
Delete: key.NewBinding(key.WithKeys("x", "delete"), key.WithHelp("del", "Delete")),
Quit: key.NewBinding(key.WithKeys("q", "ctrl+c", "esc"), key.WithHelp("esc", "Quit")),
Select: key.NewBinding(key.WithKeys("enter"), key.WithHelp("Enter", "Select")),
Delete: key.NewBinding(key.WithKeys("x", "delete"), key.WithHelp("del", "Delete")),
Quit: key.NewBinding(key.WithKeys("q", "ctrl+c", "esc"), key.WithHelp("esc", "Quit")),
Refresh: key.NewBinding(key.WithKeys("ctrl+r"), key.WithHelp("^r", "Refresh")),
}
}

func (m SelectModel) Init() tea.Cmd { return nil }

func (m SelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var refresh = func() {
columns, rows, err := m.refreshFn()
m.table.SetColumns(columns)
m.table.SetRows(rows)
m.lastErr = err
}

var cmd tea.Cmd
var cmds []tea.Cmd
switch msg := msg.(type) {
case tea.KeyMsg:
switch {
case key.Matches(msg, m.keymap.Quit):
m.finished = true
cmds = append(cmds, tea.Quit)
case key.Matches(msg, m.keymap.Select):
if len(m.table.SelectedRow()) == 0 {
break
}
m.Selected = m.table.SelectedRow()[1]
fallthrough
case key.Matches(msg, m.keymap.Quit):
m.finished = true
cmds = append(cmds, tea.Quit)
case key.Matches(msg, m.keymap.Delete):
if len(m.table.SelectedRow()) == 0 {
break
}
m.lastErr = m.m.Delete(m.table.SelectedRow()[1])
refresh()
case key.Matches(msg, m.keymap.Refresh):
refresh()
}
}
m.table, cmd = m.table.Update(msg)
Expand All @@ -92,5 +128,15 @@ func (m SelectModel) View() string {
if m.finished {
return "" // don't render the table if we've selected a workspace
}
return m.style.FocusedBorder.Render((m.table.View()) + "\n\n" + m.help.ShortHelpView(m.keymap.Bindings()))
var b strings.Builder

b.WriteString(m.style.Title.Render("Slackdump Workspaces") + "\n")
b.WriteString(m.style.Description.Render("Select a workspace to work with") + "\n\n")
b.WriteString(m.table.View() + "\n")
if m.lastErr != nil {
b.WriteString(m.style.Error.Render(m.lastErr.Error()) + "\n")
}
b.WriteString(m.help.ShortHelpView(m.keymap.Bindings()))

return m.style.FocusedBorder.Render(b.String())
}

0 comments on commit 984fc0f

Please sign in to comment.