package panes import ( "fmt" "strings" "github.com/charmbracelet/x/ansi" "git.kebcloud.no/keb/lazysecrets/internal/ui/styles" ) // SourceDetail is the fourth pane on a provider's row: what's known about // its account, one field per row, to move through and copy from. type SourceDetail struct { title string fields []Field sel int w, h int } // Field is a row: a value under a label. Info rows (loading, errors) // can't be copied. type Field struct { Label, Value string Info bool } // Set shows fields under title, keeping the cursor where it was for the // same title. func (s *SourceDetail) Set(title string, fields []Field) { if title != s.title { s.sel = 0 } s.title, s.fields = title, fields s.sel = max(0, min(s.sel, len(fields)-1)) } // Shown reports whether there's anything to show. func (s SourceDetail) Shown() bool { return len(s.fields) > 0 } func (s *SourceDetail) SetSize(w, h int) { s.w, s.h = w, h } func (s *SourceDetail) Move(delta int) { s.sel = max(0, min(s.sel+delta, len(s.fields)-1)) } func (s *SourceDetail) Top() { s.sel = 0 } func (s *SourceDetail) Bottom() { s.sel = max(0, len(s.fields)-1) } // Selected is the field under the cursor, unless it's an info row. func (s SourceDetail) Selected() (Field, bool) { if s.sel >= len(s.fields) || s.fields[s.sel].Info { return Field{}, false } return s.fields[s.sel], true } func (s SourceDetail) View(st styles.Styles, focused bool) string { inner := max(1, s.w-2) rows := max(0, s.h-2) offset := 0 if s.sel >= rows { // keep the cursor in view offset = s.sel - rows + 1 } var body []string for i, f := range s.fields[min(offset, len(s.fields)):] { if i >= rows { break } value := f.Value if f.Info { value = st.Muted.Render(value) } line := " " + st.Label.Render(fmt.Sprintf("%-10s", f.Label)) + " " + value line = ansi.Truncate(line, inner, "…") if i+offset == s.sel { pad := strings.Repeat(" ", max(0, inner-ansi.StringWidth(line))) if focused { line = st.Selected.Render(ansi.Strip(line) + pad) } else { line = st.SelectedBlurred.Render(ansi.Strip(line) + pad) } } body = append(body, line) } footer := "" if len(s.fields) > rows { footer = fmt.Sprintf("%d of %d", s.sel+1, len(s.fields)) } return Box(st, TitleStyle(st, focused).Render(s.title), footer, body, s.w, s.h, focused) }