feat: l for details; details for vaults, scopes and files; getting started; the age of cached lists (#17)
- `l` goes to the details of what is selected; `enter` still drills in - vaults, scopes and files show their details (vault settings from the listing, no extra requests) - with nothing to show, the right pane says how to get started - a list from the cache says how old it is while it reloads - what is expiring, in the status pane and `lazysecrets expiring` - when access is refused, what to check, for Azure and Databricks - no group list in an account's details, and no Microsoft Graph call for it Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit was merged in pull request #17.
This commit is contained in:
1 parent
9b0329e9da
commit
09bacd8438
32 files changed
+1321
-254
No files matched your search
@@ -34,6 +34,9 @@ type List[T any] struct {
|
||||
Empty string // shown when loaded with no items
|
||||
Loading bool
|
||||
Err error
|
||||
// Age says how old the items are ("2h ago") while they reload, by
|
||||
// the counter.
|
||||
Age string
|
||||
|
||||
item Item[T]
|
||||
items []T
|
||||
@@ -88,6 +91,7 @@ func (l *List[T]) SetError(err error) {
|
||||
func (l *List[T]) Refresh() {
|
||||
l.Loading = true
|
||||
l.Err = nil
|
||||
l.Age = ""
|
||||
}
|
||||
|
||||
func (l *List[T]) SetLoading() {
|
||||
@@ -330,7 +334,7 @@ func (l List[T]) View(st styles.Styles, focused bool, spin string) string {
|
||||
case l.Loading && len(l.items) == 0:
|
||||
body = append(body, " "+spin+" loading…")
|
||||
case l.Err != nil:
|
||||
for _, line := range strings.Split(ansi.Wrap(l.Err.Error(), inner-1, " -/"), "\n") {
|
||||
for _, line := range wrapLines(l.Err.Error(), inner-1) {
|
||||
body = append(body, st.Error.Render(" "+line))
|
||||
}
|
||||
case len(l.visible) == 0 && len(l.items) > 0:
|
||||
@@ -369,6 +373,9 @@ func (l List[T]) View(st styles.Styles, focused bool, spin string) string {
|
||||
if len(l.visible) > 0 {
|
||||
counter = fmt.Sprintf("%d of %d", l.cursor+1, len(l.visible))
|
||||
}
|
||||
if l.Loading && l.Age != "" && len(l.items) > 0 {
|
||||
counter = "cached " + l.Age + " · " + counter
|
||||
}
|
||||
return BoxCounted(st, title, "", counter, body, l.w, l.h, focused)
|
||||
}
|
||||
|
||||
@@ -386,3 +393,22 @@ func (l *List[T]) scroll() {
|
||||
}
|
||||
l.offset = max(0, min(l.offset, len(l.visible)-rows))
|
||||
}
|
||||
|
||||
// wrapLines wraps text to width, line by line; a "• " item's further
|
||||
// lines line up under its text.
|
||||
func wrapLines(text string, width int) []string {
|
||||
var out []string
|
||||
for _, line := range strings.Split(text, "\n") {
|
||||
indent := ""
|
||||
if strings.HasPrefix(line, "• ") {
|
||||
indent = " "
|
||||
}
|
||||
for i, l := range strings.Split(ansi.Wrap(line, max(1, width-len(indent)), " -/"), "\n") {
|
||||
if i > 0 {
|
||||
l = indent + l
|
||||
}
|
||||
out = append(out, l)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in new issue
Block a user