185 lines
4.0 KiB
Go
185 lines
4.0 KiB
Go
package ui
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/derailed/k9s/internal/model"
|
|
"github.com/derailed/k9s/internal/render"
|
|
"github.com/derailed/tview"
|
|
"github.com/gdamore/tcell"
|
|
)
|
|
|
|
// Namespaceable represents a namespaceable model.
|
|
type Namespaceable interface {
|
|
// ClusterWide returns true if the model represents resource in all namespaces.
|
|
ClusterWide() bool
|
|
|
|
// GetNamespace returns the model namespace.
|
|
GetNamespace() string
|
|
|
|
// SetNamespace changes the model namespace.
|
|
SetNamespace(string)
|
|
|
|
// InNamespace check if current namespace matches models.
|
|
InNamespace(string) bool
|
|
}
|
|
|
|
// Tabular represents a tabular model.
|
|
type Tabular interface {
|
|
Namespaceable
|
|
|
|
// Empty returns true if model has no data.
|
|
Empty() bool
|
|
|
|
// Peek returns current model data.
|
|
Peek() render.TableData
|
|
|
|
// Watch watches a given resource for changes.
|
|
Watch(context.Context)
|
|
|
|
// SetRefreshRate sets the model watch loop rate.
|
|
SetRefreshRate(time.Duration)
|
|
|
|
// AddListener registers a model listener.
|
|
AddListener(model.TableListener)
|
|
}
|
|
|
|
// SelectTable represents a table with selections.
|
|
type SelectTable struct {
|
|
*tview.Table
|
|
|
|
model Tabular
|
|
selectedRow int
|
|
selectedFn func(string) string
|
|
marks map[string]struct{}
|
|
}
|
|
|
|
// SetModel sets the table model.
|
|
func (s *SelectTable) SetModel(m Tabular) {
|
|
s.model = m
|
|
}
|
|
|
|
// GetModel returns the current model.
|
|
func (s *SelectTable) GetModel() Tabular {
|
|
return s.model
|
|
}
|
|
|
|
// ClearSelection reset selected row.
|
|
func (s *SelectTable) ClearSelection() {
|
|
s.Select(0, 0)
|
|
s.ScrollToBeginning()
|
|
}
|
|
|
|
// SelectFirstRow select first data row if any.
|
|
func (s *SelectTable) SelectFirstRow() {
|
|
if s.GetRowCount() > 0 {
|
|
s.Select(1, 0)
|
|
}
|
|
}
|
|
|
|
// GetSelectedItems return currently marked or selected items names.
|
|
func (s *SelectTable) GetSelectedItems() []string {
|
|
if len(s.marks) == 0 {
|
|
return []string{s.GetSelectedItem()}
|
|
}
|
|
|
|
var items []string
|
|
for item := range s.marks {
|
|
items = append(items, item)
|
|
}
|
|
|
|
return items
|
|
}
|
|
|
|
// GetSelectedItem returns the currently selected item name.
|
|
func (s *SelectTable) GetSelectedItem() string {
|
|
if s.GetSelectedRowIndex() == 0 || s.model.Empty() {
|
|
return ""
|
|
}
|
|
sel, ok := s.GetCell(s.GetSelectedRowIndex(), 0).GetReference().(string)
|
|
if !ok {
|
|
return ""
|
|
}
|
|
if s.selectedFn != nil {
|
|
return s.selectedFn(sel)
|
|
}
|
|
return sel
|
|
}
|
|
|
|
// GetSelectedCell returns the content of a cell for the currently selected row.
|
|
func (s *SelectTable) GetSelectedCell(col int) string {
|
|
return TrimCell(s, s.selectedRow, col)
|
|
}
|
|
|
|
// SetSelectedFn defines a function that cleanse the current selection.
|
|
func (s *SelectTable) SetSelectedFn(f func(string) string) {
|
|
s.selectedFn = f
|
|
}
|
|
|
|
// GetSelectedRowIndex fetch the currently selected row index.
|
|
func (s *SelectTable) GetSelectedRowIndex() int {
|
|
return s.selectedRow
|
|
}
|
|
|
|
// SelectRow select a given row by index.
|
|
func (s *SelectTable) SelectRow(r int, broadcast bool) {
|
|
if !broadcast {
|
|
s.SetSelectionChangedFunc(nil)
|
|
}
|
|
defer s.SetSelectionChangedFunc(s.selectionChanged)
|
|
s.Select(r, 0)
|
|
}
|
|
|
|
// UpdateSelection refresh selected row.
|
|
func (s *SelectTable) updateSelection(broadcast bool) {
|
|
s.SelectRow(s.selectedRow, broadcast)
|
|
}
|
|
|
|
func (s *SelectTable) selectionChanged(r, c int) {
|
|
if r <= 0 {
|
|
return
|
|
}
|
|
s.selectedRow = r
|
|
cell := s.GetCell(r, c)
|
|
s.SetSelectedStyle(tcell.ColorBlack, cell.Color, tcell.AttrBold)
|
|
}
|
|
|
|
// ClearMarks delete all marked items.
|
|
func (s *SelectTable) ClearMarks() {
|
|
for k := range s.marks {
|
|
delete(s.marks, k)
|
|
}
|
|
}
|
|
|
|
// DeleteMark delete a marked item.
|
|
func (s *SelectTable) DeleteMark(k string) {
|
|
delete(s.marks, k)
|
|
}
|
|
|
|
// ToggleMark toggles marked row
|
|
func (s *SelectTable) ToggleMark() {
|
|
sel := s.GetSelectedItem()
|
|
if sel == "" {
|
|
return
|
|
}
|
|
if _, ok := s.marks[sel]; ok {
|
|
delete(s.marks, s.GetSelectedItem())
|
|
} else {
|
|
s.marks[sel] = struct{}{}
|
|
}
|
|
|
|
cell := s.GetCell(s.GetSelectedRowIndex(), 0)
|
|
s.SetSelectedStyle(
|
|
tcell.ColorBlack,
|
|
cell.Color,
|
|
tcell.AttrBold,
|
|
)
|
|
}
|
|
|
|
// IsMarked returns true if this item was marked.
|
|
func (s *Table) IsMarked(item string) bool {
|
|
_, ok := s.marks[item]
|
|
return ok
|
|
}
|