mirror of
https://github.com/hanzoai/insights.git
synced 2026-11-03 00:52:32 +00:00
Modules declare go 1.27.1 and the build images follow. go fix applied the modernizers, and the ptr helper went once new(expr) could say it; omitzero is not applied, since it changes what the JSON says. Co-authored-by: Hanzo Dev <[email protected]>
154 lines
3.4 KiB
Go
154 lines
3.4 KiB
Go
package views
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/charmbracelet/lipgloss"
|
|
"github.com/insights/insights/livestream/tui/sse"
|
|
)
|
|
|
|
type DetailView struct {
|
|
event *sse.EventMsg
|
|
scroll int
|
|
width int
|
|
height int
|
|
lines []string
|
|
visible bool
|
|
}
|
|
|
|
func NewDetailView() *DetailView {
|
|
return &DetailView{}
|
|
}
|
|
|
|
func (v *DetailView) SetEvent(e *sse.EventMsg) {
|
|
v.event = e
|
|
v.scroll = 0
|
|
v.visible = e != nil
|
|
v.buildLines()
|
|
}
|
|
|
|
func (v *DetailView) SetSize(w, h int) {
|
|
v.width = w
|
|
v.height = h
|
|
}
|
|
|
|
func (v *DetailView) IsVisible() bool {
|
|
return v.visible
|
|
}
|
|
|
|
func (v *DetailView) Close() {
|
|
v.visible = false
|
|
v.event = nil
|
|
}
|
|
|
|
func (v *DetailView) ScrollUp() {
|
|
if v.scroll > 0 {
|
|
v.scroll--
|
|
}
|
|
}
|
|
|
|
func (v *DetailView) ScrollDown() {
|
|
maxScroll := max(len(v.lines)-v.contentHeight(), 0)
|
|
if v.scroll < maxScroll {
|
|
v.scroll++
|
|
}
|
|
}
|
|
|
|
func (v *DetailView) contentHeight() int {
|
|
return max(v.height-6, 1)
|
|
}
|
|
|
|
func (v *DetailView) buildLines() {
|
|
if v.event == nil {
|
|
v.lines = nil
|
|
return
|
|
}
|
|
|
|
keyStyle := lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("#8F8F8F")).
|
|
Bold(true)
|
|
valStyle := lipgloss.NewStyle().
|
|
Foreground(lipgloss.AdaptiveColor{Light: "#1D1F27", Dark: "#EDEDEC"})
|
|
|
|
var lines []string
|
|
lines = append(lines, keyStyle.Render("Event: ")+valStyle.Render(v.event.Event))
|
|
lines = append(lines, keyStyle.Render("UUID: ")+valStyle.Render(v.event.UUID))
|
|
lines = append(lines, keyStyle.Render("Distinct ID: ")+valStyle.Render(v.event.DistinctID))
|
|
lines = append(lines, keyStyle.Render("Person ID: ")+valStyle.Render(v.event.PersonID))
|
|
lines = append(lines, keyStyle.Render("Timestamp: ")+valStyle.Render(fmt.Sprint(v.event.Timestamp)))
|
|
lines = append(lines, "")
|
|
lines = append(lines, keyStyle.Render("Properties:"))
|
|
|
|
if v.event.Properties != nil {
|
|
// border (2) + padding (2*2) + indent (2) = 8 chars of overhead
|
|
maxValWidth := max(v.width-8, 20)
|
|
|
|
keys := make([]string, 0, len(v.event.Properties))
|
|
for k := range v.event.Properties {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
for _, k := range keys {
|
|
val := v.event.Properties[k]
|
|
valStr := formatValue(val)
|
|
// key prefix takes up space: " " + key + ": "
|
|
available := max(maxValWidth-len(k)-4, 10)
|
|
if len(valStr) > available {
|
|
valStr = valStr[:available-3] + "..."
|
|
}
|
|
lines = append(lines, " "+keyStyle.Render(k+": ")+valStyle.Render(valStr))
|
|
}
|
|
}
|
|
|
|
v.lines = lines
|
|
}
|
|
|
|
func formatValue(v any) string {
|
|
switch val := v.(type) {
|
|
case string:
|
|
return val
|
|
case nil:
|
|
return "null"
|
|
default:
|
|
b, err := json.Marshal(val)
|
|
if err != nil {
|
|
return fmt.Sprint(val)
|
|
}
|
|
return string(b)
|
|
}
|
|
}
|
|
|
|
func (v *DetailView) View() string {
|
|
if !v.visible || v.event == nil {
|
|
return ""
|
|
}
|
|
|
|
borderStyle := lipgloss.NewStyle().
|
|
Border(lipgloss.RoundedBorder()).
|
|
BorderForeground(lipgloss.AdaptiveColor{Light: "#333333", Dark: "#CCCCCC"}).
|
|
Padding(1, 2).
|
|
Width(v.width - 4).
|
|
Height(v.height - 2)
|
|
|
|
titleStyle := lipgloss.NewStyle().
|
|
Bold(true).
|
|
Foreground(lipgloss.AdaptiveColor{Light: "#333333", Dark: "#CCCCCC"})
|
|
|
|
ch := v.contentHeight()
|
|
end := min(v.scroll+ch, len(v.lines))
|
|
start := min(v.scroll, len(v.lines))
|
|
|
|
hintStyle := lipgloss.NewStyle().
|
|
Foreground(lipgloss.AdaptiveColor{Light: "#888888", Dark: "#666666"})
|
|
|
|
visible := v.lines[start:end]
|
|
title := titleStyle.Render("Event Detail") + " " + hintStyle.Render("(esc to go back, j/k to scroll)")
|
|
content := title + "\n\n" + strings.Join(visible, "\n")
|
|
|
|
return borderStyle.Render(content)
|
|
}
|