WIP Phase 2: content loader, stage contract, search index, templ components
This commit is contained in:
223
internal/web/templates/view.go
Normal file
223
internal/web/templates/view.go
Normal file
@@ -0,0 +1,223 @@
|
||||
// Package templates holds every templ component and the view models they read.
|
||||
// Layout never branches on the stage driver: it renders the binding it is given.
|
||||
package templates
|
||||
|
||||
import (
|
||||
stdhtml "html"
|
||||
"strings"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
|
||||
"gitea.lab.audasmedia.com.au/sam/ai-resume/internal/content"
|
||||
"gitea.lab.audasmedia.com.au/sam/ai-resume/internal/search"
|
||||
"gitea.lab.audasmedia.com.au/sam/ai-resume/internal/stage"
|
||||
)
|
||||
|
||||
// NavItem is one left-nav entry.
|
||||
type NavItem struct {
|
||||
Title string
|
||||
Href string
|
||||
Gutter string
|
||||
Current bool
|
||||
}
|
||||
|
||||
// Crumb is one breadcrumb.
|
||||
type Crumb struct {
|
||||
Label string
|
||||
Href string
|
||||
}
|
||||
|
||||
// LayoutView is everything the chrome needs.
|
||||
type LayoutView struct {
|
||||
Title string
|
||||
Description string
|
||||
Area string
|
||||
Nav []NavItem
|
||||
Crumbs []Crumb
|
||||
Stage stage.Binding
|
||||
SearchQuery string
|
||||
Year int
|
||||
SkipAI bool // true on Mode A pages, which never need a model
|
||||
}
|
||||
|
||||
// StageView wraps the binding so the Stage component has one argument.
|
||||
type StageView struct {
|
||||
Binding stage.Binding
|
||||
// Fragment, when set, is rendered into the panel at build time.
|
||||
Fragment *stage.Fragment
|
||||
}
|
||||
|
||||
// MetricView is one approved chip.
|
||||
type MetricView struct {
|
||||
Label string
|
||||
Value string
|
||||
}
|
||||
|
||||
// LinkView is a drill-down link. HXGet makes it a stage trigger; Href keeps it
|
||||
// a working link when JavaScript is off.
|
||||
type LinkView struct {
|
||||
Label string
|
||||
Href string
|
||||
HXGet string
|
||||
Kind string
|
||||
Note string
|
||||
Confidence string
|
||||
}
|
||||
|
||||
// EvidenceRow is one row of an EvidenceTable.
|
||||
type EvidenceRow struct {
|
||||
Label string
|
||||
Href string
|
||||
HXGet string
|
||||
Kind string
|
||||
Confidence string
|
||||
}
|
||||
|
||||
// EvidenceGroup groups rows by area on the evidence index.
|
||||
type EvidenceGroup struct {
|
||||
AreaTitle string
|
||||
Href string
|
||||
Rows []EvidenceRow
|
||||
}
|
||||
|
||||
// TimelineItem is one row of a timeline.
|
||||
type TimelineItem struct {
|
||||
Period string
|
||||
Title string
|
||||
Href string
|
||||
Confidence string
|
||||
Claim string
|
||||
}
|
||||
|
||||
// PillarCardView is one of the six landing cards.
|
||||
type PillarCardView struct {
|
||||
Area content.Area
|
||||
Title string
|
||||
Claim string
|
||||
Href string
|
||||
Metrics []MetricView
|
||||
Tech []string
|
||||
Confidence string
|
||||
Level int
|
||||
Pages int
|
||||
}
|
||||
|
||||
// Layout of each page kind.
|
||||
type (
|
||||
// HomeView is the landing page.
|
||||
HomeView struct {
|
||||
Layout LayoutView
|
||||
Positioning string
|
||||
Support string
|
||||
Location string
|
||||
Cards []PillarCardView
|
||||
Artifacts int
|
||||
Pages int
|
||||
Areas int
|
||||
}
|
||||
|
||||
// DocView is an L1, L2 or L3 content page.
|
||||
DocView struct {
|
||||
Layout LayoutView
|
||||
Doc *content.Document
|
||||
AreaTitle string
|
||||
Role string
|
||||
Body templ.Component
|
||||
Metrics []MetricView
|
||||
Tech []string
|
||||
Evidence []LinkView
|
||||
Backlinks []LinkView
|
||||
SubPages []LinkView
|
||||
Timeline []TimelineItem
|
||||
LevelLabel string
|
||||
}
|
||||
|
||||
// EvidenceView is the index of every artefact.
|
||||
EvidenceView struct {
|
||||
Layout LayoutView
|
||||
Groups []EvidenceGroup
|
||||
Total int
|
||||
}
|
||||
|
||||
// SearchView is the keyword search page.
|
||||
SearchView struct {
|
||||
Layout LayoutView
|
||||
Query string
|
||||
Results []search.Result
|
||||
Total int
|
||||
Indexed int
|
||||
Failed bool
|
||||
}
|
||||
|
||||
// StreamView is the SSE-driven stage demonstration page.
|
||||
StreamView struct {
|
||||
Layout LayoutView
|
||||
Frames int
|
||||
Fragment []LinkView
|
||||
}
|
||||
|
||||
// NotFoundView is the 404 page.
|
||||
NotFoundView struct {
|
||||
Layout LayoutView
|
||||
}
|
||||
)
|
||||
|
||||
// MarkdownBody wraps pre-rendered Markdown HTML.
|
||||
func MarkdownBody(html string) templ.Component { return templ.Raw(html) }
|
||||
|
||||
// SafeSnippet escapes a search snippet but keeps the <mark> tags the index
|
||||
// inserted. Content is in-repo and trusted; escaping is defence in depth.
|
||||
func SafeSnippet(s string) templ.Component {
|
||||
s = stdhtml.EscapeString(s)
|
||||
s = strings.ReplaceAll(s, "<mark>", "<mark>")
|
||||
s = strings.ReplaceAll(s, "</mark>", "</mark>")
|
||||
return templ.Raw(s)
|
||||
}
|
||||
|
||||
// ConfidenceClass maps a confidence value onto a CSS class. The value itself is
|
||||
// always displayed — never softened.
|
||||
func ConfidenceClass(c string) string {
|
||||
switch c {
|
||||
case content.ConfidenceDelivered:
|
||||
return "conf conf-delivered"
|
||||
case content.ConfidenceRunning:
|
||||
return "conf conf-running"
|
||||
case content.ConfidenceInProgress:
|
||||
return "conf conf-in-progress"
|
||||
case content.ConfidenceAbandoned:
|
||||
return "conf conf-abandoned"
|
||||
case content.ConfidenceHistoric:
|
||||
return "conf conf-historic"
|
||||
}
|
||||
return "conf"
|
||||
}
|
||||
|
||||
// ConfidenceNote is the sentence shown under a status badge.
|
||||
func ConfidenceNote(c string) string {
|
||||
switch c {
|
||||
case content.ConfidenceDelivered:
|
||||
return "Delivered."
|
||||
case content.ConfidenceRunning:
|
||||
return "Running today."
|
||||
case content.ConfidenceInProgress:
|
||||
return "In progress — not finished."
|
||||
case content.ConfidenceAbandoned:
|
||||
return "Abandoned. Kept in the record deliberately."
|
||||
case content.ConfidenceHistoric:
|
||||
return "Historic — worked on, not maintained today."
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// LevelLabel names a depth level for the page kicker.
|
||||
func LevelLabel(level int) string {
|
||||
switch level {
|
||||
case 1:
|
||||
return "Level 1 · capability in one screen"
|
||||
case 2:
|
||||
return "Level 2 · what is actually run"
|
||||
case 3:
|
||||
return "Level 3 · artefact"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user