Merge pull request #354 from bkmeneguello/mark

Allow to select multiple resources and add support to Delete/Kill all together
mine
Fernand Galiana 2019-11-08 08:17:01 -08:00 committed by GitHub
commit 3d0de988ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 75 additions and 14 deletions

View File

@ -99,6 +99,7 @@ type (
FgColor string `yaml:"fgColor"`
BgColor string `yaml:"bgColor"`
CursorColor string `yaml:"cursorColor"`
MarkColor string `yaml:"markColor"`
Header TableHeader `yaml:"header"`
}
@ -215,6 +216,7 @@ func newTable() Table {
FgColor: "aqua",
BgColor: "black",
CursorColor: "aqua",
MarkColor: "darkgoldenrod",
Header: newTableHeader(),
}
}

View File

@ -204,6 +204,7 @@ const (
KeyHelp = 63
KeySlash = 47
KeyColon = 58
KeySpace = 32
)
// Define Shift Keys
@ -253,6 +254,7 @@ var NumKeys = map[int]int32{
func initKeys() {
tcell.KeyNames[tcell.Key(KeyHelp)] = "?"
tcell.KeyNames[tcell.Key(KeySlash)] = "/"
tcell.KeyNames[tcell.Key(KeySpace)] = "space"
initNumbKeys()
initStdKeys()

View File

@ -42,6 +42,7 @@ type Table struct {
selectedRow int
selectedFn func(string) string
selListeners []SelectedRowFunc
marks map[string]bool
}
// NewTable returns a new table view.
@ -53,6 +54,7 @@ func NewTable(title string, styles *config.Styles) *Table {
cmdBuff: NewCmdBuff('/', FilterBuff),
baseTitle: title,
sortCol: SortColumn{0, 0, true},
marks: make(map[string]bool),
}
v.SetFixed(1, 0)
@ -169,6 +171,20 @@ func (v *Table) GetSelectedItem() string {
return v.selectedItem
}
// GetSelectedItems return currently marked or selected items names.
func (v *Table) GetSelectedItems() []string {
if len(v.marks) > 0 {
var items []string
for item, marked := range v.marks {
if marked {
items = append(items, item)
}
}
return items
}
return []string{v.GetSelectedItem()}
}
func (v *Table) keyboard(evt *tcell.EventKey) *tcell.EventKey {
key := evt.Key()
if key == tcell.KeyRune {
@ -323,6 +339,7 @@ func (v *Table) buildRow(row int, data resource.TableData, sk string, pads MaxyP
if v.colorerFn != nil {
f = v.colorerFn
}
m := v.isMarked(sk)
for col, field := range data.Rows[sk].Fields {
header := data.Header[col]
field, align := v.formatCell(data.NumCols[header], header, field+Deltas(data.Rows[sk].Deltas[col], field), pads[col])
@ -331,6 +348,9 @@ func (v *Table) buildRow(row int, data resource.TableData, sk string, pads MaxyP
c.SetExpansion(1)
c.SetAlign(align)
c.SetTextColor(f(data.Namespace, data.Rows[sk]))
if m {
c.SetBackgroundColor(config.AsColor(v.styles.Table().MarkColor))
}
}
v.SetCell(row, col, c)
}
@ -527,3 +547,12 @@ func (v *Table) SortInvertCmd(evt *tcell.EventKey) *tcell.EventKey {
return nil
}
// ToggleMark toggles marked row
func (v *Table) ToggleMark() {
v.marks[v.GetSelectedItem()] = !v.marks[v.GetSelectedItem()]
}
func (v *Table) isMarked(item string) bool {
return v.marks[item]
}

View File

@ -115,15 +115,17 @@ func (v *podView) killCmd(evt *tcell.EventKey) *tcell.EventKey {
return evt
}
sel := v.masterPage().GetSelectedItem()
sel := v.masterPage().GetSelectedItems()
v.masterPage().ShowDeleted()
v.app.Flash().Infof("Delete resource %s %s", v.list.GetName(), sel)
if err := v.list.Resource().Delete(sel, true, false); err != nil {
v.app.Flash().Errf("Delete failed with %s", err)
} else {
deletePortForward(v.app.forwarders, sel)
v.refresh()
for _, res := range sel {
v.app.Flash().Infof("Delete resource %s %s", v.list.GetName(), res)
if err := v.list.Resource().Delete(res, true, false); err != nil {
v.app.Flash().Errf("Delete failed with %s", err)
} else {
deletePortForward(v.app.forwarders, res)
}
}
v.refresh()
return nil
}

View File

@ -192,23 +192,45 @@ func (v *resourceView) deleteCmd(evt *tcell.EventKey) *tcell.EventKey {
return evt
}
sel := v.masterPage().GetSelectedItem()
msg := fmt.Sprintf("Delete %s %s?", v.list.GetName(), sel)
sel := v.masterPage().GetSelectedItems()
var msg string
if len(sel) > 1 {
msg = fmt.Sprintf("Delete %d selected %s?", len(sel), v.list.GetName())
} else {
msg = fmt.Sprintf("Delete %s %s?", v.list.GetName(), sel[0])
}
dialog.ShowDelete(v.Pages, msg, func(cascade, force bool) {
v.masterPage().ShowDeleted()
v.app.Flash().Infof("Delete resource %s %s", v.list.GetName(), sel)
if err := v.list.Resource().Delete(sel, cascade, force); err != nil {
v.app.Flash().Errf("Delete failed with %s", err)
if len(sel) > 1 {
v.app.Flash().Infof("Delete %d selected %s", len(sel), v.list.GetName())
} else {
deletePortForward(v.app.forwarders, sel)
v.refresh()
v.app.Flash().Infof("Delete resource %s %s", v.list.GetName(), sel[0])
}
for _, res := range sel {
if err := v.list.Resource().Delete(res, cascade, force); err != nil {
v.app.Flash().Errf("Delete failed with %s", err)
} else {
deletePortForward(v.app.forwarders, res)
}
}
v.refresh()
}, func() {
v.switchPage("master")
})
return nil
}
func (v *resourceView) markCmd(evt *tcell.EventKey) *tcell.EventKey {
if !v.masterPage().RowSelected() {
return evt
}
v.masterPage().ToggleMark()
v.refresh()
v.app.Draw()
return nil
}
func deletePortForward(ff map[string]forwarder, sel string) {
for k, v := range ff {
tokens := strings.Split(k, ":")
@ -375,6 +397,7 @@ func (v *resourceView) refreshActions() {
tcell.KeyEnter: ui.NewKeyAction("Enter", v.enterCmd, false),
tcell.KeyCtrlR: ui.NewKeyAction("Refresh", v.refreshCmd, false),
}
aa[ui.KeySpace] = ui.NewKeyAction("Mark", v.markCmd, true)
v.namespaceActions(aa)
v.defaultActions(aa)

View File

@ -35,6 +35,7 @@ k9s:
fgColor: white
bgColor: black
cursorColor: white
markColor: darkgoldenrod
header:
fgColor: darkgray
bgColor: black

View File

@ -37,6 +37,7 @@ k9s:
fgColor: blue
bgColor: darkblue
cursorColor: aqua
markColor: mediumslateblue
header:
fgColor: white
bgColor: darkblue

View File

@ -35,6 +35,7 @@ k9s:
fgColor: blue
bgColor: black
cursorColor: aqua
markColor: darkgoldenrod
header:
fgColor: white
bgColor: black