Checkpoint commit
Have got a basic table select model working. Now will try to setup modal models to support prompts and confirmations
This commit is contained in:
parent
33115c7c13
commit
6ac22aad1f
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
|
@ -24,7 +24,7 @@ jobs:
|
|||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17
|
||||
go-version: 1.18
|
||||
- name: Configure
|
||||
run: |
|
||||
git config --global url."https://${{ secrets.GO_MODULES_TOKEN }}:x-oauth-basic@github.com/lmika".insteadOf "https://github.com/lmika"
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
|
@ -17,6 +15,8 @@ import (
|
|||
"github.com/lmika/awstools/internal/dynamo-browse/services/tables"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/ui"
|
||||
"github.com/lmika/gopkgs/cli"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -58,6 +58,18 @@ func main() {
|
|||
p := tea.NewProgram(uiModel, tea.WithAltScreen())
|
||||
loopback.program = p
|
||||
|
||||
// TEMP -- profiling
|
||||
//cf, err := os.Create("trace.out")
|
||||
//if err != nil {
|
||||
// log.Fatal("could not create CPU profile: ", err)
|
||||
//}
|
||||
//defer cf.Close() // error handling omitted for example
|
||||
//if err := trace.Start(cf); err != nil {
|
||||
// log.Fatal("could not start CPU profile: ", err)
|
||||
//}
|
||||
//defer trace.Stop()
|
||||
// END TEMP
|
||||
|
||||
f, err := tea.LogToFile("debug.log", "debug")
|
||||
if err != nil {
|
||||
fmt.Println("fatal:", err)
|
||||
|
@ -65,6 +77,7 @@ func main() {
|
|||
}
|
||||
defer f.Close()
|
||||
|
||||
log.Println("launching")
|
||||
if err := p.Start(); err != nil {
|
||||
fmt.Printf("Alas, there's been an error: %v", err)
|
||||
os.Exit(1)
|
||||
|
|
6
docker-compose.yml
Normal file
6
docker-compose.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
version: '3'
|
||||
services:
|
||||
dynamo:
|
||||
image: amazon/dynamodb-local:latest
|
||||
ports:
|
||||
- 8000:8000
|
13
go.mod
13
go.mod
|
@ -1,27 +1,30 @@
|
|||
module github.com/lmika/awstools
|
||||
|
||||
go 1.17
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/alecthomas/participle/v2 v2.0.0-alpha7
|
||||
github.com/asdine/storm v2.1.2+incompatible
|
||||
github.com/aws/aws-sdk-go-v2 v1.15.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.13.1
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.8.0
|
||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.8.0
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.15.0
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.16.0
|
||||
github.com/brianvoe/gofakeit/v6 v6.15.0
|
||||
github.com/calyptia/go-bubble-table v0.1.0
|
||||
github.com/charmbracelet/bubbles v0.10.3
|
||||
github.com/charmbracelet/bubbletea v0.20.0
|
||||
github.com/charmbracelet/lipgloss v0.5.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/lmika/events v0.0.0-20200906102219-a2269cd4394e
|
||||
github.com/lmika/gopkgs v0.0.0-20211210041137-0dc91e939890
|
||||
github.com/lmika/shellwords v0.0.0-20140714114018-ce258dd729fe
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/stretchr/testify v1.7.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/alecthomas/participle/v2 v2.0.0-alpha7 // indirect
|
||||
github.com/asdine/storm v2.1.2+incompatible // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.10.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.6 // indirect
|
||||
|
@ -34,13 +37,10 @@ require (
|
|||
github.com/aws/aws-sdk-go-v2/service/sso v1.9.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.14.0 // indirect
|
||||
github.com/aws/smithy-go v1.11.1 // indirect
|
||||
github.com/brianvoe/gofakeit/v6 v6.15.0 // indirect
|
||||
github.com/containerd/console v1.0.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/juju/ansiterm v0.0.0-20210929141451-8b71cc96ebdc // indirect
|
||||
github.com/lmika/shellwords v0.0.0-20140714114018-ce258dd729fe // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/lunixbochs/vtclean v1.0.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
|
@ -50,6 +50,7 @@ require (
|
|||
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/sahilm/fuzzy v0.1.0 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
|
|
1
go.sum
1
go.sum
|
@ -116,6 +116,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
|
||||
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
|
|
|
@ -34,10 +34,12 @@ type uiModel struct {
|
|||
table table.Model
|
||||
viewport viewport.Model
|
||||
|
||||
// TEMP
|
||||
tableSelect tea.Model
|
||||
|
||||
tableWidth, tableHeight int
|
||||
|
||||
ready bool
|
||||
//resultSet *models.ResultSet
|
||||
state controllers.State
|
||||
message string
|
||||
|
||||
|
@ -62,6 +64,11 @@ func NewModel(dispatcher *dispatcher.Dispatcher, commandController *commandctrl.
|
|||
message: "Press s to scan",
|
||||
textInput: textInput,
|
||||
|
||||
// TEMP
|
||||
tableSelect: newSizeWaitModel(func(w, h int) tea.Model {
|
||||
return newTableSelectModel(w, h)
|
||||
}),
|
||||
|
||||
dispatcher: dispatcher,
|
||||
commandController: commandController,
|
||||
tableReadController: tableReadController,
|
||||
|
@ -72,7 +79,7 @@ func NewModel(dispatcher *dispatcher.Dispatcher, commandController *commandctrl.
|
|||
}
|
||||
|
||||
func (m uiModel) Init() tea.Cmd {
|
||||
m.invokeOperation(context.Background(), m.tableReadController.Scan())
|
||||
//m.invokeOperation(context.Background(), m.tableReadController.Scan())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -215,11 +222,13 @@ func (m uiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
|
||||
updatedTable, tableMsgs := m.table.Update(msg)
|
||||
updatedViewport, viewportMsgs := m.viewport.Update(msg)
|
||||
updatedTableSelectModel, tableSelectMsgs := m.tableSelect.Update(msg)
|
||||
|
||||
m.table = updatedTable
|
||||
m.viewport = updatedViewport
|
||||
m.tableSelect = updatedTableSelectModel
|
||||
|
||||
return m, tea.Batch(textInputCommands, tableMsgs, viewportMsgs)
|
||||
return m, tea.Batch(textInputCommands, tableMsgs, viewportMsgs, tableSelectMsgs)
|
||||
}
|
||||
|
||||
func (m uiModel) invokeOperation(ctx context.Context, op uimodels.Operation) {
|
||||
|
@ -233,6 +242,10 @@ func (m uiModel) invokeOperation(ctx context.Context, op uimodels.Operation) {
|
|||
}
|
||||
|
||||
func (m uiModel) View() string {
|
||||
// TEMP
|
||||
return m.tableSelect.View()
|
||||
|
||||
/*
|
||||
if !m.ready {
|
||||
return "Initializing"
|
||||
}
|
||||
|
@ -254,6 +267,7 @@ func (m uiModel) View() string {
|
|||
m.viewport.View(),
|
||||
m.footerView(),
|
||||
)
|
||||
*/
|
||||
}
|
||||
|
||||
func (m uiModel) headerView() string {
|
||||
|
|
48
internal/dynamo-browse/ui/sizewaitmodel.go
Normal file
48
internal/dynamo-browse/ui/sizewaitmodel.go
Normal file
|
@ -0,0 +1,48 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"log"
|
||||
)
|
||||
|
||||
// sizeWaitModel is a model which waits until the first screen size message comes through. It then creates the
|
||||
// submodel and delegates calls to that model
|
||||
type sizeWaitModel struct {
|
||||
constr func(width, height int) tea.Model
|
||||
model tea.Model
|
||||
}
|
||||
|
||||
func newSizeWaitModel(constr func(width, height int) tea.Model) tea.Model {
|
||||
return sizeWaitModel{constr: constr}
|
||||
}
|
||||
|
||||
func (s sizeWaitModel) Init() tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s sizeWaitModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch m := msg.(type) {
|
||||
case tea.WindowSizeMsg:
|
||||
log.Println("got window size message")
|
||||
if s.model == nil {
|
||||
log.Println("creating model")
|
||||
s.model = s.constr(m.Width, m.Height)
|
||||
s.model.Init()
|
||||
}
|
||||
}
|
||||
|
||||
var submodelCmds tea.Cmd
|
||||
if s.model != nil {
|
||||
log.Println("starting update")
|
||||
s.model, submodelCmds = s.model.Update(msg)
|
||||
log.Println("ending update")
|
||||
}
|
||||
return s, submodelCmds
|
||||
}
|
||||
|
||||
func (s sizeWaitModel) View() string {
|
||||
if s.model == nil {
|
||||
return ""
|
||||
}
|
||||
return s.model.View()
|
||||
}
|
95
internal/dynamo-browse/ui/tableselectmodel.go
Normal file
95
internal/dynamo-browse/ui/tableselectmodel.go
Normal file
|
@ -0,0 +1,95 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"github.com/charmbracelet/bubbles/list"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
var (
|
||||
titleStyle = lipgloss.NewStyle().MarginLeft(2)
|
||||
itemStyle = lipgloss.NewStyle().PaddingLeft(4)
|
||||
selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("170"))
|
||||
paginationStyle = list.DefaultStyles().PaginationStyle.PaddingLeft(4)
|
||||
helpStyle = list.DefaultStyles().HelpStyle.PaddingLeft(4).PaddingBottom(1)
|
||||
quitTextStyle = lipgloss.NewStyle().Margin(1, 0, 2, 4)
|
||||
)
|
||||
|
||||
type tableSelectModel struct {
|
||||
list list.Model
|
||||
}
|
||||
|
||||
func (t tableSelectModel) Init() tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t tableSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case tea.WindowSizeMsg:
|
||||
t.list.SetHeight(msg.Height)
|
||||
t.list.SetWidth(msg.Width)
|
||||
return t, nil
|
||||
|
||||
case tea.KeyMsg:
|
||||
switch keypress := msg.String(); keypress {
|
||||
case "ctrl+c":
|
||||
return t, tea.Quit
|
||||
|
||||
case "enter":
|
||||
//i, ok := m.list.SelectedItem().(item)
|
||||
//if ok {
|
||||
// m.choice = string(i)
|
||||
//}
|
||||
return t, tea.Quit
|
||||
}
|
||||
}
|
||||
|
||||
var cmd tea.Cmd
|
||||
t.list, cmd = t.list.Update(msg)
|
||||
return t, cmd
|
||||
}
|
||||
|
||||
func (t tableSelectModel) View() string {
|
||||
return t.list.View()
|
||||
}
|
||||
|
||||
func newTableSelectModel(w, h int) tableSelectModel {
|
||||
tableItems := []tableItem{
|
||||
{name: "alpha"},
|
||||
{name: "beta"},
|
||||
{name: "gamma"},
|
||||
}
|
||||
|
||||
items := toListItems(tableItems)
|
||||
|
||||
delegate := list.NewDefaultDelegate()
|
||||
delegate.ShowDescription = false
|
||||
|
||||
return tableSelectModel{
|
||||
list: list.New(items, delegate, w, h),
|
||||
}
|
||||
}
|
||||
|
||||
type tableItem struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (ti tableItem) FilterValue() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (ti tableItem) Title() string {
|
||||
return ti.name
|
||||
}
|
||||
|
||||
func (ti tableItem) Description() string {
|
||||
return "abc"
|
||||
}
|
||||
|
||||
func toListItems[T list.Item](xs []T) []list.Item {
|
||||
ls := make([]list.Item, len(xs))
|
||||
for i, x := range xs {
|
||||
ls[i] = x
|
||||
}
|
||||
return ls
|
||||
}
|
Loading…
Reference in a new issue