Hello world 👋
Release / Build and publish (push) Successful in 22s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kebandClaude Opus 5.5 committed 2026-10-10 23:58:25 +02:00
commit 6fab41703e
111 files changed
+22988

No files matched your search

+93
View File
@@ -0,0 +1,93 @@
package app
import (
"strings"
"charm.land/bubbles/v2/textinput"
tea "charm.land/bubbletea/v2"
"github.com/charmbracelet/x/ansi"
"git.kebcloud.no/keb/lazysecrets/internal/provider"
"git.kebcloud.no/keb/lazysecrets/internal/store"
"git.kebcloud.no/keb/lazysecrets/internal/ui/styles"
)
// Notes: n writes a short note on the selected subscription, vault or
// secret, kept in its store record. Notes show dimmed on the right of rows
// and in the detail pane, and the filter matches them.
// withNote right-aligns a dimmed note in a row of the given width. The
// note gives way first when space is short.
func withNote(st styles.Styles, left, note string, width int) string {
if note == "" {
return left
}
room := width - ansi.StringWidth(left) - 2
if room < 4 {
return left
}
note = ansi.Truncate(note, room, "…")
pad := width - ansi.StringWidth(left) - ansi.StringWidth(note)
return left + strings.Repeat(" ", pad) + st.Muted.Render(note)
}
// editNote opens a popup to write the focused item's note.
func (m *Model) editNote() tea.Cmd {
var key, name string
var path []string
var src provider.Source
switch m.focus {
case paneSources:
s, ok := m.selectedSource()
if !ok {
m.flash = warning("select a subscription or workspace to add a note")
return nil
}
key, name, src = sourceKey(s), s.Name, s
case paneContainers:
c, ok := m.containers.Selected()
if !ok {
return nil
}
key, name, path, src = storeKey(c), c.Name, []string{c.Source.Name}, c.Source
default:
o, ok := m.detail.Secret()
if !ok {
return nil
}
c := o.Container
key, name, path, src = objectKey(o), o.Name, []string{c.Source.Name, c.Name}, c.Source
}
in := textinput.New()
in.Prompt = "note: "
in.Placeholder = "e.g. prod SQL admin"
in.CharLimit = 80
in.SetWidth(48)
in.SetValue(m.store.Node(key).Note)
in.CursorEnd()
m.prompt = &modal{
title: "Note on " + name, input: &in,
lines: []string{m.st.Muted.Render("Shown on the right of the row. Empty removes it.")},
submit: func(m *Model, text string) tea.Cmd {
note := strings.Join(strings.Fields(text), " ") // one line
if err := m.remember(key, name, path, src, func(n *store.Node) { n.Note = note }); err != nil {
m.flash = flash{text: "saving: " + err.Error(), isErr: true}
return nil
}
m.refreshDetailNote()
return nil
},
footer: footer(hint(m.keys.PopupSelect, "save"), hint(m.keys.PopupClose, "cancel")),
}
m.flash = flash{}
return m.prompt.input.Focus()
}
// refreshDetailNote shows the note of whatever the detail pane shows.
func (m *Model) refreshDetailNote() {
if o, ok := m.detail.Secret(); ok {
m.detail.SetNote(m.store.Node(objectKey(o)).Note)
} else if c, ok := m.detail.Container(); ok {
m.detail.SetNote(m.store.Node(storeKey(c)).Note)
}
}