From e37b8099a38bb37f3eca45d6bc6ac7dfaacd2521 Mon Sep 17 00:00:00 2001 From: Leon Mika Date: Tue, 2 Apr 2024 23:00:19 +1100 Subject: [PATCH] Fixed a glaring error where the user cannot close the column selector Cause of this was that the close event type was also being used by the related overlay, and the event was being caught by that even though the overlay was hidden. Also started working on changing the sort order within the column selector by pressing S. --- cmd/dynamo-browse/main.go | 2 +- internal/dynamo-browse/controllers/columns.go | 40 ++++++++- .../dynamo-browse/controllers/tableread.go | 8 ++ .../controllers/tablewrite_test.go | 2 +- .../dynamo-browse/models/columns/columns.go | 29 +------ internal/dynamo-browse/models/evaluators.go | 15 ++++ .../dynamo-browse/models/evaluators/equals.go | 25 ++++++ internal/dynamo-browse/models/models.go | 12 ++- .../models/queryexpr/expr_test.go | 6 ++ .../models/queryexpr/fieldevaluator.go | 15 ++++ internal/dynamo-browse/models/sorted.go | 84 ++++++++++++++----- internal/dynamo-browse/models/sorted_test.go | 6 +- .../dynamo-browse/services/tables/service.go | 3 +- .../dynamo-browse/ui/keybindings/defaults.go | 1 + .../ui/keybindings/keybindings.go | 1 + .../ui/teamodels/colselector/colmodel.go | 9 +- .../ui/teamodels/colselector/model.go | 1 + .../ui/teamodels/colselector/tblmodel.go | 15 +++- .../ui/teamodels/relselector/listmdl.go | 4 +- .../ui/teamodels/relselector/model.go | 2 +- 20 files changed, 213 insertions(+), 67 deletions(-) create mode 100644 internal/dynamo-browse/models/evaluators.go create mode 100644 internal/dynamo-browse/models/evaluators/equals.go create mode 100644 internal/dynamo-browse/models/queryexpr/fieldevaluator.go diff --git a/cmd/dynamo-browse/main.go b/cmd/dynamo-browse/main.go index ccaf034..8adcce4 100644 --- a/cmd/dynamo-browse/main.go +++ b/cmd/dynamo-browse/main.go @@ -123,7 +123,7 @@ func main() { *flagTable, ) tableWriteController := controllers.NewTableWriteController(state, tableService, jobsController, tableReadController, settingStore) - columnsController := controllers.NewColumnsController(eventBus) + columnsController := controllers.NewColumnsController(tableReadController, eventBus) exportController := controllers.NewExportController(state, tableService, jobsController, columnsController, pasteboardProvider) settingsController := controllers.NewSettingsController(settingStore, eventBus) keyBindings := keybindings.Default() diff --git a/internal/dynamo-browse/controllers/columns.go b/internal/dynamo-browse/controllers/columns.go index 8080477..23dbd35 100644 --- a/internal/dynamo-browse/controllers/columns.go +++ b/internal/dynamo-browse/controllers/columns.go @@ -5,19 +5,22 @@ import ( "github.com/lmika/dynamo-browse/internal/common/ui/events" "github.com/lmika/dynamo-browse/internal/dynamo-browse/models" "github.com/lmika/dynamo-browse/internal/dynamo-browse/models/columns" + "github.com/lmika/dynamo-browse/internal/dynamo-browse/models/evaluators" "github.com/lmika/dynamo-browse/internal/dynamo-browse/models/queryexpr" bus "github.com/lmika/events" "strings" ) type ColumnsController struct { + tr *TableReadController + // State colModel *columns.Columns resultSet *models.ResultSet } -func NewColumnsController(eventBus *bus.Bus) *ColumnsController { - cc := &ColumnsController{} +func NewColumnsController(tr *TableReadController, eventBus *bus.Bus) *ColumnsController { + cc := &ColumnsController{tr: tr} eventBus.On(newResultSetEvent, cc.onNewResultSet) return cc @@ -80,7 +83,7 @@ func (cc *ColumnsController) AddColumn(afterIndex int) tea.Msg { newCol := columns.Column{ Name: colExpr.String(), - Evaluator: columns.ExprFieldValueEvaluator{Expr: colExpr}, + Evaluator: queryexpr.ExprFieldValueEvaluator{Expr: colExpr}, } if afterIndex >= len(cc.colModel.Columns)-1 { @@ -117,6 +120,25 @@ func (cc *ColumnsController) DeleteColumn(afterIndex int) tea.Msg { return ColumnsUpdated{} } +func (cc *ColumnsController) SortByColumn(index int) tea.Msg { + if index >= len(cc.colModel.Columns) { + return nil + } + + column := cc.colModel.Columns[index] + newCriteria := models.SortCriteria{ + Fields: []models.SortField{ + {Field: column.Evaluator, Asc: true}, + }, + } + if ff := cc.SortCriteria().FirstField(); evaluators.Equals(ff.Field, column.Evaluator) { + newCriteria.Fields[0].Asc = !ff.Asc + } + + cc.SetSortCriteria(newCriteria) + return ColumnsUpdated{} +} + func (c *ColumnsController) AttributesWithPrefix(prefix string) []string { options := make([]string, 0) for _, col := range c.resultSet.Columns() { @@ -126,3 +148,15 @@ func (c *ColumnsController) AttributesWithPrefix(prefix string) []string { } return options } + +func (cc *ColumnsController) SortCriteria() models.SortCriteria { + if cc.resultSet == nil { + return models.SortCriteria{} + } + + return cc.resultSet.SortCriteria() +} + +func (cc *ColumnsController) SetSortCriteria(criteria models.SortCriteria) { + cc.tr.SortResultSet(criteria) +} diff --git a/internal/dynamo-browse/controllers/tableread.go b/internal/dynamo-browse/controllers/tableread.go index bfc650d..6ef6e18 100644 --- a/internal/dynamo-browse/controllers/tableread.go +++ b/internal/dynamo-browse/controllers/tableread.go @@ -35,6 +35,7 @@ const ( resultSetUpdateTouch resultSetUpdateNextPage resultSetUpdateScript + resultSetUpdateResort ) type MarkOp int @@ -150,6 +151,13 @@ func (c *TableReadController) ScanTable(name string) tea.Msg { }).OnEither(c.handleResultSetFromJobResult(c.state.Filter(), true, false, resultSetUpdateInit)).Submit() } +func (c *TableReadController) SortResultSet(newCriteria models.SortCriteria) { + c.state.withResultSet(func(rs *models.ResultSet) { + rs.Sort(newCriteria.Append(models.PKSKSortFilter(rs.TableInfo))) + }) + c.eventBus.Fire(newResultSetEvent, c.state.resultSet, resultSetUpdateResort) +} + func (c *TableReadController) PromptForQuery() tea.Msg { return events.PromptForInputMsg{ Prompt: "query: ", diff --git a/internal/dynamo-browse/controllers/tablewrite_test.go b/internal/dynamo-browse/controllers/tablewrite_test.go index ac2d32a..efd0c14 100644 --- a/internal/dynamo-browse/controllers/tablewrite_test.go +++ b/internal/dynamo-browse/controllers/tablewrite_test.go @@ -632,7 +632,7 @@ func newService(t *testing.T, cfg serviceConfig) *services { ) writeController := controllers.NewTableWriteController(state, service, jobsController, readController, settingStore) settingsController := controllers.NewSettingsController(settingStore, eventBus) - columnsController := controllers.NewColumnsController(eventBus) + columnsController := controllers.NewColumnsController(readController, eventBus) exportController := controllers.NewExportController(state, service, jobsController, columnsController, pasteboardprovider.NilProvider{}) scriptController := controllers.NewScriptController(scriptService, readController, jobsController, settingsController, eventBus) diff --git a/internal/dynamo-browse/models/columns/columns.go b/internal/dynamo-browse/models/columns/columns.go index bdf290d..3342a95 100644 --- a/internal/dynamo-browse/models/columns/columns.go +++ b/internal/dynamo-browse/models/columns/columns.go @@ -1,9 +1,7 @@ package columns import ( - "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/lmika/dynamo-browse/internal/dynamo-browse/models" - "github.com/lmika/dynamo-browse/internal/dynamo-browse/models/queryexpr" ) type Columns struct { @@ -19,7 +17,7 @@ func NewColumnsFromResultSet(rs *models.ResultSet) *Columns { for i, c := range rsCols { cols[i] = Column{ Name: c, - Evaluator: SimpleFieldValueEvaluator(c), + Evaluator: models.SimpleFieldValueEvaluator(c), } } @@ -44,7 +42,7 @@ func (cols *Columns) AddMissingColumns(rs *models.ResultSet) { if _, hasCol := existingColumns[c]; !hasCol { newCols = append(newCols, Column{ Name: c, - Evaluator: SimpleFieldValueEvaluator(c), + Evaluator: models.SimpleFieldValueEvaluator(c), }) } } @@ -56,7 +54,7 @@ func (cols *Columns) AddMissingColumns(rs *models.ResultSet) { } else { newCols[i] = Column{ Name: c, - Evaluator: SimpleFieldValueEvaluator(c), + Evaluator: models.SimpleFieldValueEvaluator(c), } } } @@ -82,25 +80,6 @@ func (cols *Columns) VisibleColumns() []Column { type Column struct { Name string - Evaluator FieldValueEvaluator + Evaluator models.FieldValueEvaluator Hidden bool } - -type FieldValueEvaluator interface { - EvaluateForItem(item models.Item) types.AttributeValue -} - -type SimpleFieldValueEvaluator string - -func (sfve SimpleFieldValueEvaluator) EvaluateForItem(item models.Item) types.AttributeValue { - return item[string(sfve)] -} - -type ExprFieldValueEvaluator struct { - Expr *queryexpr.QueryExpr -} - -func (sfve ExprFieldValueEvaluator) EvaluateForItem(item models.Item) types.AttributeValue { - val, _ := sfve.Expr.EvalItem(item) - return val -} diff --git a/internal/dynamo-browse/models/evaluators.go b/internal/dynamo-browse/models/evaluators.go new file mode 100644 index 0000000..85ffa26 --- /dev/null +++ b/internal/dynamo-browse/models/evaluators.go @@ -0,0 +1,15 @@ +package models + +import ( + "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" +) + +type FieldValueEvaluator interface { + EvaluateForItem(item Item) types.AttributeValue +} + +type SimpleFieldValueEvaluator string + +func (sfve SimpleFieldValueEvaluator) EvaluateForItem(item Item) types.AttributeValue { + return item[string(sfve)] +} diff --git a/internal/dynamo-browse/models/evaluators/equals.go b/internal/dynamo-browse/models/evaluators/equals.go new file mode 100644 index 0000000..ec1f0dc --- /dev/null +++ b/internal/dynamo-browse/models/evaluators/equals.go @@ -0,0 +1,25 @@ +package evaluators + +import ( + "github.com/lmika/dynamo-browse/internal/dynamo-browse/models" + "github.com/lmika/dynamo-browse/internal/dynamo-browse/models/queryexpr" +) + +func Equals(x, y models.FieldValueEvaluator) bool { + if x == nil { + return y == nil + } + + switch xt := x.(type) { + case models.SimpleFieldValueEvaluator: + if yt, ok := y.(models.SimpleFieldValueEvaluator); ok { + return xt == yt + } + case queryexpr.ExprFieldValueEvaluator: + if yt, ok := y.(queryexpr.ExprFieldValueEvaluator); ok { + return xt.Expr.Equal(yt.Expr) + } + } + + return false +} diff --git a/internal/dynamo-browse/models/models.go b/internal/dynamo-browse/models/models.go index 0aed4f1..03d0421 100644 --- a/internal/dynamo-browse/models/models.go +++ b/internal/dynamo-browse/models/models.go @@ -18,7 +18,8 @@ type ResultSet struct { items []Item attributes []ItemAttribute - columns []string + columns []string + sortCriteria SortCriteria } type Queryable interface { @@ -48,6 +49,10 @@ func (rs *ResultSet) SetItems(items []Item) { rs.attributes = make([]ItemAttribute, len(items)) } +func (rs *ResultSet) SortCriteria() SortCriteria { + return rs.sortCriteria +} + func (rs *ResultSet) AddNewItem(item Item, attrs ItemAttribute) { rs.items = append(rs.items, item) rs.attributes = append(rs.attributes, attrs) @@ -141,3 +146,8 @@ func (rs *ResultSet) RefreshColumns() { func (rs *ResultSet) HasNextPage() bool { return rs.LastEvaluatedKey != nil } + +func (rs *ResultSet) Sort(criteria SortCriteria) { + rs.sortCriteria = criteria + Sort(rs.items, criteria) +} diff --git a/internal/dynamo-browse/models/queryexpr/expr_test.go b/internal/dynamo-browse/models/queryexpr/expr_test.go index 76e7a02..2352329 100644 --- a/internal/dynamo-browse/models/queryexpr/expr_test.go +++ b/internal/dynamo-browse/models/queryexpr/expr_test.go @@ -53,6 +53,11 @@ func TestModExpr_Query(t *testing.T) { `#0 = :0`, exprNameIsString(0, 0, "pk", "prefix"), ), + //scanCase("when request pk is fixed (reverse)", + // `prefix="pk"`, + // `#0 = :0`, + // exprNameIsString(0, 0, "pk", "prefix"), + //), scanCase("when request pk is fixed in parens #1", `(pk="prefix")`, `#0 = :0`, @@ -513,6 +518,7 @@ func TestQueryExpr_EvalItem(t *testing.T) { {expr: "three <= 2", expected: &types.AttributeValueMemberBOOL{Value: false}}, // Between + {expr: "3 between 1 and 5", expected: &types.AttributeValueMemberBOOL{Value: true}}, {expr: "three between 1 and 5", expected: &types.AttributeValueMemberBOOL{Value: true}}, {expr: "three between one and five", expected: &types.AttributeValueMemberBOOL{Value: true}}, {expr: "three between 10 and 15", expected: &types.AttributeValueMemberBOOL{Value: false}}, diff --git a/internal/dynamo-browse/models/queryexpr/fieldevaluator.go b/internal/dynamo-browse/models/queryexpr/fieldevaluator.go new file mode 100644 index 0000000..616e339 --- /dev/null +++ b/internal/dynamo-browse/models/queryexpr/fieldevaluator.go @@ -0,0 +1,15 @@ +package queryexpr + +import ( + "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" + "github.com/lmika/dynamo-browse/internal/dynamo-browse/models" +) + +type ExprFieldValueEvaluator struct { + Expr *QueryExpr +} + +func (sfve ExprFieldValueEvaluator) EvaluateForItem(item models.Item) types.AttributeValue { + val, _ := sfve.Expr.EvalItem(item) + return val +} diff --git a/internal/dynamo-browse/models/sorted.go b/internal/dynamo-browse/models/sorted.go index dd8e200..29c5e49 100644 --- a/internal/dynamo-browse/models/sorted.go +++ b/internal/dynamo-browse/models/sorted.go @@ -8,13 +8,60 @@ import ( // sortedItems is a collection of items that is sorted. // Items are sorted based on the PK, and SK in ascending order type sortedItems struct { - tableInfo *TableInfo - items []Item + criteria SortCriteria + items []Item +} + +type SortField struct { + Field FieldValueEvaluator + Asc bool +} + +type SortCriteria struct { + Fields []SortField +} + +func (sc SortCriteria) FirstField() SortField { + if len(sc.Fields) == 0 { + return SortField{} + } + return sc.Fields[0] +} + +func (sc SortCriteria) Equals(osc SortCriteria) bool { + if len(sc.Fields) != len(osc.Fields) { + return false + } + + for i := range osc.Fields { + if sc.Fields[i].Field != osc.Fields[i].Field || + sc.Fields[i].Asc != osc.Fields[i].Asc { + return false + } + } + + return true +} + +func (sc SortCriteria) Append(osc SortCriteria) SortCriteria { + newItems := make([]SortField, 0, len(osc.Fields)) + newItems = append(newItems, sc.Fields...) + newItems = append(newItems, osc.Fields...) + return SortCriteria{Fields: newItems} +} + +func PKSKSortFilter(ti *TableInfo) SortCriteria { + return SortCriteria{ + Fields: []SortField{ + {Field: SimpleFieldValueEvaluator(ti.Keys.PartitionKey), Asc: true}, + {Field: SimpleFieldValueEvaluator(ti.Keys.SortKey), Asc: true}, + }, + } } // Sort sorts the items in place -func Sort(items []Item, tableInfo *TableInfo) { - si := sortedItems{items: items, tableInfo: tableInfo} +func Sort(items []Item, criteria SortCriteria) { + si := sortedItems{items: items, criteria: criteria} sort.Sort(&si) } @@ -23,30 +70,21 @@ func (si *sortedItems) Len() int { } func (si *sortedItems) Less(i, j int) bool { - // Compare primary keys - pv1, pv2 := si.items[i][si.tableInfo.Keys.PartitionKey], si.items[j][si.tableInfo.Keys.PartitionKey] - pc, ok := attrutils.CompareScalarAttributes(pv1, pv2) - if !ok { - return i < j - } - - if pc < 0 { - return true - } else if pc > 0 { - return false - } - - // Partition keys are equal, compare sort key - if sortKey := si.tableInfo.Keys.SortKey; sortKey != "" { - sv1, sv2 := si.items[i][sortKey], si.items[j][sortKey] - sc, ok := attrutils.CompareScalarAttributes(sv1, sv2) + for _, field := range si.criteria.Fields { + // Compare primary keys + pv1, pv2 := field.Field.EvaluateForItem(si.items[i]), field.Field.EvaluateForItem(si.items[j]) + pc, ok := attrutils.CompareScalarAttributes(pv1, pv2) if !ok { return i < j } - if sc < 0 { + if !field.Asc { + pc = -pc + } + + if pc < 0 { return true - } else if sc > 0 { + } else if pc > 0 { return false } } diff --git a/internal/dynamo-browse/models/sorted_test.go b/internal/dynamo-browse/models/sorted_test.go index 5cb1fc6..5b39d6b 100644 --- a/internal/dynamo-browse/models/sorted_test.go +++ b/internal/dynamo-browse/models/sorted_test.go @@ -15,7 +15,7 @@ func TestSort(t *testing.T) { items := make([]models.Item, len(testStringData)) copy(items, testStringData) - models.Sort(items, tableInfo) + models.Sort(items, models.PKSKSortFilter(tableInfo)) assert.Equal(t, items[0], testStringData[1]) assert.Equal(t, items[1], testStringData[2]) @@ -28,7 +28,7 @@ func TestSort(t *testing.T) { items := make([]models.Item, len(testNumberData)) copy(items, testNumberData) - models.Sort(items, tableInfo) + models.Sort(items, models.PKSKSortFilter(tableInfo)) assert.Equal(t, items[0], testNumberData[2]) assert.Equal(t, items[1], testNumberData[1]) @@ -41,7 +41,7 @@ func TestSort(t *testing.T) { items := make([]models.Item, len(testBoolData)) copy(items, testBoolData) - models.Sort(items, tableInfo) + models.Sort(items, models.PKSKSortFilter(tableInfo)) assert.Equal(t, items[0], testBoolData[2]) assert.Equal(t, items[1], testBoolData[1]) diff --git a/internal/dynamo-browse/services/tables/service.go b/internal/dynamo-browse/services/tables/service.go index 993b4be..52f97bb 100644 --- a/internal/dynamo-browse/services/tables/service.go +++ b/internal/dynamo-browse/services/tables/service.go @@ -86,8 +86,6 @@ func (s *Service) doScan( }, errors.Wrapf(err, "unable to scan table %v", tableInfo.Name) } - models.Sort(results, tableInfo) - resultSet := &models.ResultSet{ TableInfo: tableInfo, Created: time.Now(), @@ -97,6 +95,7 @@ func (s *Service) doScan( } resultSet.SetItems(results) resultSet.RefreshColumns() + resultSet.Sort(models.PKSKSortFilter(tableInfo)) return resultSet, err } diff --git a/internal/dynamo-browse/ui/keybindings/defaults.go b/internal/dynamo-browse/ui/keybindings/defaults.go index cc49dd1..818919a 100644 --- a/internal/dynamo-browse/ui/keybindings/defaults.go +++ b/internal/dynamo-browse/ui/keybindings/defaults.go @@ -12,6 +12,7 @@ func Default() *KeyBindings { ResetColumns: key.NewBinding(key.WithKeys("R", "reset columns")), AddColumn: key.NewBinding(key.WithKeys("a", "add new column")), DeleteColumn: key.NewBinding(key.WithKeys("d", "delete column")), + SortByColumn: key.NewBinding(key.WithKeys("s", "sort by column")), }, TableView: &TableKeyBinding{ MoveUp: key.NewBinding(key.WithKeys("i", "up")), diff --git a/internal/dynamo-browse/ui/keybindings/keybindings.go b/internal/dynamo-browse/ui/keybindings/keybindings.go index d0c7fc3..96c24b3 100644 --- a/internal/dynamo-browse/ui/keybindings/keybindings.go +++ b/internal/dynamo-browse/ui/keybindings/keybindings.go @@ -16,6 +16,7 @@ type FieldsPopupBinding struct { ResetColumns key.Binding `keymap:"reset-columns"` AddColumn key.Binding `keymap:"add-column"` DeleteColumn key.Binding `keymap:"delete-column"` + SortByColumn key.Binding `keymap:"sort-by-column"` } type TableKeyBinding struct { diff --git a/internal/dynamo-browse/ui/teamodels/colselector/colmodel.go b/internal/dynamo-browse/ui/teamodels/colselector/colmodel.go index f6221b0..514c8ac 100644 --- a/internal/dynamo-browse/ui/teamodels/colselector/colmodel.go +++ b/internal/dynamo-browse/ui/teamodels/colselector/colmodel.go @@ -6,6 +6,7 @@ import ( "github.com/charmbracelet/lipgloss" "github.com/lmika/dynamo-browse/internal/common/ui/events" "github.com/lmika/dynamo-browse/internal/dynamo-browse/controllers" + "github.com/lmika/dynamo-browse/internal/dynamo-browse/models" "github.com/lmika/dynamo-browse/internal/dynamo-browse/models/columns" "github.com/lmika/dynamo-browse/internal/dynamo-browse/ui/keybindings" "github.com/lmika/dynamo-browse/internal/dynamo-browse/ui/teamodels/layout" @@ -25,8 +26,9 @@ type colListModel struct { keyBinding *keybindings.KeyBindings colController *controllers.ColumnsController - rows []table.Row - table table.Model + rows []table.Row + table table.Model + sortCriteria models.SortCriteria } func newColListModel(keyBinding *keybindings.KeyBindings, colController *controllers.ColumnsController) *colListModel { @@ -68,6 +70,8 @@ func (m *colListModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, events.SetTeaMessage(m.colController.AddColumn(m.table.Cursor())) case key.Matches(msg, m.keyBinding.ColumnPopup.DeleteColumn): return m, events.SetTeaMessage(m.colController.DeleteColumn(m.table.Cursor())) + case key.Matches(msg, m.keyBinding.ColumnPopup.SortByColumn): + return m, events.SetTeaMessage(m.colController.SortByColumn(m.table.Cursor())) // Main table nav case key.Matches(msg, m.keyBinding.TableView.ColLeft): @@ -122,6 +126,7 @@ func (c *colListModel) Resize(w, h int) layout.ResizingModel { func (c *colListModel) refreshTable() { colsFromController := c.colController.Columns() + c.sortCriteria = c.colController.SortCriteria() if len(c.rows) != len(colsFromController.Columns) { c.setColumnsFromModel(colsFromController) } diff --git a/internal/dynamo-browse/ui/teamodels/colselector/model.go b/internal/dynamo-browse/ui/teamodels/colselector/model.go index 2b572d7..8a6aabb 100644 --- a/internal/dynamo-browse/ui/teamodels/colselector/model.go +++ b/internal/dynamo-browse/ui/teamodels/colselector/model.go @@ -42,6 +42,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cc utils.CmdCollector switch msg := msg.(type) { case controllers.ShowColumnOverlay: + m.colListModel.sortCriteria = m.columnsController.SortCriteria() m.colListModel.setColumnsFromModel(m.columnsController.Columns()) m.compositor.SetOverlay(m.colListModel, m.w/2-overlayWidth/2, m.h/2-overlayHeight/2, overlayWidth, overlayHeight) case controllers.HideColumnOverlay: diff --git a/internal/dynamo-browse/ui/teamodels/colselector/tblmodel.go b/internal/dynamo-browse/ui/teamodels/colselector/tblmodel.go index 505d2e7..6d4b3b4 100644 --- a/internal/dynamo-browse/ui/teamodels/colselector/tblmodel.go +++ b/internal/dynamo-browse/ui/teamodels/colselector/tblmodel.go @@ -3,6 +3,7 @@ package colselector import ( "fmt" "github.com/charmbracelet/lipgloss" + "github.com/lmika/dynamo-browse/internal/dynamo-browse/models/evaluators" table "github.com/lmika/go-bubble-table" "io" ) @@ -23,9 +24,17 @@ func (clr colListRowModel) Render(w io.Writer, model table.Model, index int) { } col := clr.m.colController.Columns().Columns[index] - if !col.Hidden { - fmt.Fprintln(w, style.Render(fmt.Sprintf("⋅\t%v", col.Name))) - } else { + ff := clr.m.sortCriteria.FirstField() + switch { + case col.Hidden: fmt.Fprintln(w, style.Render(fmt.Sprintf("✕\t%v", col.Name))) + case evaluators.Equals(ff.Field, col.Evaluator): + if ff.Asc { + fmt.Fprintln(w, style.Render(fmt.Sprintf("v\t%v", col.Name))) + } else { + fmt.Fprintln(w, style.Render(fmt.Sprintf("^\t%v", col.Name))) + } + default: + fmt.Fprintln(w, style.Render(fmt.Sprintf("⋅\t%v", col.Name))) } } diff --git a/internal/dynamo-browse/ui/teamodels/relselector/listmdl.go b/internal/dynamo-browse/ui/teamodels/relselector/listmdl.go index 3bd601f..dc91665 100644 --- a/internal/dynamo-browse/ui/teamodels/relselector/listmdl.go +++ b/internal/dynamo-browse/ui/teamodels/relselector/listmdl.go @@ -90,9 +90,9 @@ func (m *listModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if onSel := m.event.OnSelected; onSel != nil { cc.Add(events.SetTeaMessage(onSel(m.event.Items[m.list.Index()]))) } - return m, events.SetTeaMessage(controllers.HideColumnOverlay{}) + return m, events.SetTeaMessage(controllers.HideRelatedItemsOverlay{}) case key.Matches(msg, keyEsc): - return m, events.SetTeaMessage(controllers.HideColumnOverlay{}) + return m, events.SetTeaMessage(controllers.HideRelatedItemsOverlay{}) default: m.list = cc.Collect(m.list.Update(msg)).(list.Model) } diff --git a/internal/dynamo-browse/ui/teamodels/relselector/model.go b/internal/dynamo-browse/ui/teamodels/relselector/model.go index 45658ec..6721763 100644 --- a/internal/dynamo-browse/ui/teamodels/relselector/model.go +++ b/internal/dynamo-browse/ui/teamodels/relselector/model.go @@ -45,7 +45,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.listModel.setItems(msg, newHeight) m.compositor.SetOverlay(m.listModel, m.w/2-overlayWidth/2, m.h/2-newHeight/2, overlayWidth, newHeight) - case controllers.HideColumnOverlay: + case controllers.HideRelatedItemsOverlay: m.compositor.ClearOverlay() case tea.KeyMsg: m.compositor = cc.Collect(m.compositor.Update(msg)).(*layout.Compositor)