diff --git a/cmd/dynamo-browse/main.go b/cmd/dynamo-browse/main.go index 803afd4..ee61135 100644 --- a/cmd/dynamo-browse/main.go +++ b/cmd/dynamo-browse/main.go @@ -21,6 +21,7 @@ import ( "github.com/lmika/awstools/internal/dynamo-browse/services/tables" "github.com/lmika/awstools/internal/dynamo-browse/ui" "github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels" + "github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/dynamoitemview" "github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/dynamotableview" "github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/frame" "github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/layout" @@ -81,7 +82,7 @@ func main() { layout.NewVBox( layout.LastChildFixedAt(11), frame.NewFrame("This is the header", true, dynamotableview.New(tableReadController)), - frame.NewFrame("This is another header", false, layout.Model(newTestModel("this is the bottom"))), + frame.NewFrame("This is another header", false, dynamoitemview.New()), ), "Hello world", ) diff --git a/internal/dynamo-browse/ui/teamodels/dynamoitemview/events.go b/internal/dynamo-browse/ui/teamodels/dynamoitemview/events.go new file mode 100644 index 0000000..c3db12a --- /dev/null +++ b/internal/dynamo-browse/ui/teamodels/dynamoitemview/events.go @@ -0,0 +1,8 @@ +package dynamoitemview + +import "github.com/lmika/awstools/internal/dynamo-browse/models" + +type NewItemSelected struct { + ResultSet *models.ResultSet + Item models.Item +} diff --git a/internal/dynamo-browse/ui/teamodels/dynamoitemview/model.go b/internal/dynamo-browse/ui/teamodels/dynamoitemview/model.go new file mode 100644 index 0000000..6c962b7 --- /dev/null +++ b/internal/dynamo-browse/ui/teamodels/dynamoitemview/model.go @@ -0,0 +1,89 @@ +package dynamoitemview + +import ( + "fmt" + "strings" + "text/tabwriter" + + "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" + "github.com/charmbracelet/bubbles/viewport" + tea "github.com/charmbracelet/bubbletea" + "github.com/lmika/awstools/internal/dynamo-browse/models" + "github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/layout" +) + +type Model struct { + ready bool + viewport viewport.Model + w, h int + + // model state + currentResultSet *models.ResultSet + selectedItem models.Item +} + +func New() Model { + return Model{ + viewport: viewport.New(100, 100), + } +} + +func (Model) Init() tea.Cmd { + return nil +} + +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case NewItemSelected: + m.currentResultSet = msg.ResultSet + m.selectedItem = msg.Item + m.updateViewportToSelectedMessage() + return m, nil + } + return m, nil +} + +func (m Model) View() string { + if !m.ready { + return "" + } + return m.viewport.View() +} + +func (m Model) Resize(w, h int) layout.ResizingModel { + m.w, m.h = w, h + if !m.ready { + m.viewport = viewport.New(w, h-1) + m.ready = true + } else { + m.viewport.Width = w + m.viewport.Height = h + } + return m +} + +func (m *Model) updateViewportToSelectedMessage() { + if m.selectedItem == nil { + m.viewport.SetContent("") + } + + viewportContent := &strings.Builder{} + tabWriter := tabwriter.NewWriter(viewportContent, 0, 1, 1, ' ', 0) + for _, colName := range m.currentResultSet.Columns { + switch colVal := m.selectedItem[colName].(type) { + case nil: + break + case *types.AttributeValueMemberS: + fmt.Fprintf(tabWriter, "%v\tS\t%s\n", colName, colVal.Value) + case *types.AttributeValueMemberN: + fmt.Fprintf(tabWriter, "%v\tN\t%s\n", colName, colVal.Value) + default: + fmt.Fprintf(tabWriter, "%v\t?\t%s\n", colName, "(other)") + } + } + + tabWriter.Flush() + m.viewport.Width = m.w + m.viewport.Height = m.h + m.viewport.SetContent(viewportContent.String()) +} diff --git a/internal/dynamo-browse/ui/teamodels/dynamotableview/model.go b/internal/dynamo-browse/ui/teamodels/dynamotableview/model.go index 925d067..09b0d1b 100644 --- a/internal/dynamo-browse/ui/teamodels/dynamotableview/model.go +++ b/internal/dynamo-browse/ui/teamodels/dynamotableview/model.go @@ -5,6 +5,7 @@ import ( tea "github.com/charmbracelet/bubbletea" "github.com/lmika/awstools/internal/dynamo-browse/controllers" "github.com/lmika/awstools/internal/dynamo-browse/models" + "github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/dynamoitemview" "github.com/lmika/awstools/internal/dynamo-browse/ui/teamodels/layout" ) @@ -34,16 +35,16 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case controllers.NewResultSet: m.resultSet = msg.ResultSet m.updateTable() - return m, nil + return m, m.postSelectedItemChanged case tea.KeyMsg: switch msg.String() { // Table nav case "i", "up": m.table.GoUp() - return m, nil + return m, m.postSelectedItemChanged case "k", "down": m.table.GoDown() - return m, nil + return m, m.postSelectedItemChanged // TEMP case "s": @@ -91,6 +92,15 @@ func (m *Model) selectedItem() (itemTableRow, bool) { return itemTableRow{}, false } +func (m *Model) postSelectedItemChanged() tea.Msg { + item, ok := m.selectedItem() + if !ok { + return nil + } + + return dynamoitemview.NewItemSelected{ResultSet: item.resultSet, Item: item.item} +} + /* func (m *Model) updateViewportToSelectedMessage() { selectedItem, ok := m.selectedItem()