put-items: added a command to put a dirty item
This commit is contained in:
parent
174bab36c3
commit
16cb6bdc6b
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/lmika/awstools/internal/common/ui/events"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/models"
|
||||
"github.com/lmika/awstools/internal/dynamo-browse/services/tables"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type TableWriteController struct {
|
||||
|
@ -46,7 +47,7 @@ func (twc *TableWriteController) NewItem() tea.Cmd {
|
|||
}
|
||||
}
|
||||
|
||||
func (twc *TableWriteController) SetItemValue(idx int, key string) tea.Cmd {
|
||||
func (twc *TableWriteController) SetStringValue(idx int, key string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
return events.PromptForInputMsg{
|
||||
Prompt: "string value: ",
|
||||
|
@ -63,6 +64,31 @@ func (twc *TableWriteController) SetItemValue(idx int, key string) tea.Cmd {
|
|||
}
|
||||
}
|
||||
|
||||
func (twc *TableWriteController) PutItem(idx int) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
resultSet := twc.state.ResultSet()
|
||||
if !resultSet.IsDirty(idx) {
|
||||
return events.Error(errors.New("item is not dirty"))
|
||||
}
|
||||
|
||||
return events.PromptForInputMsg{
|
||||
Prompt: "put item? ",
|
||||
OnDone: func(value string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
if value != "y" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := twc.tableService.PutItemAt(context.Background(), resultSet, idx); err != nil {
|
||||
return events.Error(err)
|
||||
}
|
||||
return ResultSetUpdated{}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (twc *TableWriteController) DeleteMarked() tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
resultSet := twc.state.ResultSet()
|
||||
|
|
|
@ -204,7 +204,7 @@ func TestTableWriteController_NewItem(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestTableWriteController_SetItemValue(t *testing.T) {
|
||||
func TestTableWriteController_SetStringValue(t *testing.T) {
|
||||
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
|
||||
defer cleanupFn()
|
||||
|
||||
|
@ -221,10 +221,97 @@ func TestTableWriteController_SetItemValue(t *testing.T) {
|
|||
assert.Equal(t, "This is some value", before)
|
||||
assert.False(t, state.ResultSet().IsDirty(0))
|
||||
|
||||
invokeCommandWithPrompt(t, writeController.SetItemValue(0, "alpha"), "a new value")
|
||||
invokeCommandWithPrompt(t, writeController.SetStringValue(0, "alpha"), "a new value")
|
||||
|
||||
after, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha")
|
||||
assert.Equal(t, "a new value", after)
|
||||
assert.True(t, state.ResultSet().IsDirty(0))
|
||||
})
|
||||
|
||||
t.Run("should prevent duplicate partition,sort keys", func(t *testing.T) {
|
||||
t.Skip("TODO")
|
||||
})
|
||||
}
|
||||
|
||||
func TestTableWriteController_PutItem(t *testing.T) {
|
||||
t.Run("should put the selected item if dirty", func(t *testing.T) {
|
||||
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
|
||||
defer cleanupFn()
|
||||
|
||||
provider := dynamo.NewProvider(client)
|
||||
service := tables.NewService(provider)
|
||||
|
||||
state := controllers.NewState()
|
||||
readController := controllers.NewTableReadController(state, service, "alpha-table")
|
||||
writeController := controllers.NewTableWriteController(state, service, readController)
|
||||
|
||||
// Read the table
|
||||
invokeCommand(t, readController.Init())
|
||||
before, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha")
|
||||
assert.Equal(t, "This is some value", before)
|
||||
assert.False(t, state.ResultSet().IsDirty(0))
|
||||
|
||||
// Modify the item and put it
|
||||
invokeCommandWithPrompt(t, writeController.SetStringValue(0, "alpha"), "a new value")
|
||||
invokeCommandWithPrompt(t, writeController.PutItem(0), "y")
|
||||
|
||||
// Rescan the table
|
||||
invokeCommand(t, readController.Rescan())
|
||||
after, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha")
|
||||
assert.Equal(t, "a new value", after)
|
||||
assert.False(t, state.ResultSet().IsDirty(0))
|
||||
})
|
||||
|
||||
t.Run("should not put the selected item if user does not confirm", func(t *testing.T) {
|
||||
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
|
||||
defer cleanupFn()
|
||||
|
||||
provider := dynamo.NewProvider(client)
|
||||
service := tables.NewService(provider)
|
||||
|
||||
state := controllers.NewState()
|
||||
readController := controllers.NewTableReadController(state, service, "alpha-table")
|
||||
writeController := controllers.NewTableWriteController(state, service, readController)
|
||||
|
||||
// Read the table
|
||||
invokeCommand(t, readController.Init())
|
||||
before, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha")
|
||||
assert.Equal(t, "This is some value", before)
|
||||
assert.False(t, state.ResultSet().IsDirty(0))
|
||||
|
||||
// Modify the item but do not put it
|
||||
invokeCommandWithPrompt(t, writeController.SetStringValue(0, "alpha"), "a new value")
|
||||
invokeCommandWithPrompt(t, writeController.PutItem(0), "n")
|
||||
|
||||
current, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha")
|
||||
assert.Equal(t, "a new value", current)
|
||||
assert.True(t, state.ResultSet().IsDirty(0))
|
||||
|
||||
// Rescan the table to confirm item is not modified
|
||||
invokeCommand(t, readController.Rescan())
|
||||
after, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha")
|
||||
assert.Equal(t, "This is some value", after)
|
||||
assert.False(t, state.ResultSet().IsDirty(0))
|
||||
})
|
||||
|
||||
t.Run("should not put the selected item if not dirty", func(t *testing.T) {
|
||||
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
|
||||
defer cleanupFn()
|
||||
|
||||
provider := dynamo.NewProvider(client)
|
||||
service := tables.NewService(provider)
|
||||
|
||||
state := controllers.NewState()
|
||||
readController := controllers.NewTableReadController(state, service, "alpha-table")
|
||||
writeController := controllers.NewTableWriteController(state, service, readController)
|
||||
|
||||
// Read the table
|
||||
invokeCommand(t, readController.Init())
|
||||
before, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha")
|
||||
assert.Equal(t, "This is some value", before)
|
||||
assert.False(t, state.ResultSet().IsDirty(0))
|
||||
|
||||
invokeCommandExpectingError(t, writeController.PutItem(0))
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
@ -81,6 +81,17 @@ func (s *Service) Put(ctx context.Context, tableInfo *models.TableInfo, item mod
|
|||
return s.provider.PutItem(ctx, tableInfo.Name, item)
|
||||
}
|
||||
|
||||
func (s *Service) PutItemAt(ctx context.Context, resultSet *models.ResultSet, index int) error {
|
||||
item := resultSet.Items()[index]
|
||||
if err := s.provider.PutItem(ctx, resultSet.TableInfo.Name, item); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resultSet.SetDirty(index, false)
|
||||
resultSet.SetNew(index, false)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) Delete(ctx context.Context, tableInfo *models.TableInfo, items []models.Item) error {
|
||||
for _, item := range items {
|
||||
if err := s.provider.DeleteItem(ctx, tableInfo.Name, item.KeyValue(tableInfo)); err != nil {
|
||||
|
|
|
@ -51,11 +51,14 @@ func NewModel(rc *controllers.TableReadController, wc *controllers.TableWriteCon
|
|||
|
||||
// TEMP
|
||||
"new-item": commandctrl.NoArgCommand(wc.NewItem()),
|
||||
"set": func(args []string) tea.Cmd {
|
||||
"set-string": func(args []string) tea.Cmd {
|
||||
if len(args) != 1 {
|
||||
return events.SetError(errors.New("expected attribute key"))
|
||||
}
|
||||
return wc.SetItemValue(dtv.SelectedItemIndex(), args[0])
|
||||
return wc.SetStringValue(dtv.SelectedItemIndex(), args[0])
|
||||
},
|
||||
"put": func(args []string) tea.Cmd {
|
||||
return wc.PutItem(dtv.SelectedItemIndex())
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
@ -14,6 +14,10 @@ import (
|
|||
var (
|
||||
markedRowStyle = lipgloss.NewStyle().
|
||||
Background(lipgloss.Color("#e1e1e1"))
|
||||
dirtyRowStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#e13131"))
|
||||
newRowStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#31e131"))
|
||||
)
|
||||
|
||||
type itemTableRow struct {
|
||||
|
@ -24,6 +28,8 @@ type itemTableRow struct {
|
|||
|
||||
func (mtr itemTableRow) Render(w io.Writer, model table.Model, index int) {
|
||||
isMarked := mtr.resultSet.Marked(mtr.itemIndex)
|
||||
isDirty := mtr.resultSet.IsDirty(mtr.itemIndex)
|
||||
isNew := mtr.resultSet.IsNew(mtr.itemIndex)
|
||||
|
||||
sb := strings.Builder{}
|
||||
for i, colName := range mtr.resultSet.Columns {
|
||||
|
@ -42,15 +48,20 @@ func (mtr itemTableRow) Render(w io.Writer, model table.Model, index int) {
|
|||
sb.WriteString("(other)")
|
||||
}
|
||||
}
|
||||
|
||||
var style lipgloss.Style
|
||||
|
||||
if index == model.Cursor() {
|
||||
style := model.Styles.SelectedRow
|
||||
if isMarked {
|
||||
style = style.Copy().Inherit(markedRowStyle)
|
||||
}
|
||||
fmt.Fprintln(w, style.Render(sb.String()))
|
||||
} else if isMarked {
|
||||
fmt.Fprintln(w, markedRowStyle.Render(sb.String()))
|
||||
} else {
|
||||
fmt.Fprintln(w, sb.String())
|
||||
style = model.Styles.SelectedRow
|
||||
}
|
||||
if isMarked {
|
||||
style = style.Copy().Inherit(markedRowStyle)
|
||||
}
|
||||
if isNew {
|
||||
style = style.Copy().Inherit(newRowStyle)
|
||||
} else if isDirty {
|
||||
style = style.Copy().Inherit(dirtyRowStyle)
|
||||
}
|
||||
|
||||
fmt.Fprintln(w, style.Render(sb.String()))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue