internal/components/search.go (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | package components
import (
"time"
g "alin.ovh/gomponents"
. "alin.ovh/gomponents/html"
"alin.ovh/searchix/internal/config"
"alin.ovh/searchix/internal/importer"
)
func SearchForm(tdata TemplateData, r ResultData) g.Node {
return Search(Form(
ID("search"),
FieldSet(
Legend(
ID("legend"),
H2(g.Textf("%s search", sourceNameAndType(tdata.Source))),
),
Input(
ID("query"),
Aria("labelledby", "legend"),
MinLength("2"),
Name("query"),
Type("search"),
Value(r.Query),
AutoFocus(),
g.Attr("spellcheck", "false"),
g.Attr("autocapitalize", "none"),
),
Button(g.Text("Search")),
),
))
}
func SearchPage(tdata TemplateData, r ResultData, children ...g.Node) g.Node {
return Page(
tdata,
P(
g.Text("Search Nix packages and options from "),
MapCommaList(tdata.Sources, func(source *config.Source) g.Node {
return A(Href(source.Repo.String()), g.Text(source.Name))
}),
),
g.If(importer.Job.InProgress,
P(Class("notice"),
g.Text("Indexing in progress, started "),
Time(
DateTime(importer.Job.StartedAt.Format(time.RFC3339)),
Title(importer.Job.StartedAt.Format(time.DateTime)),
g.Text(time.Since(importer.Job.StartedAt).Round(time.Second).String()),
),
g.Text(" ago. "),
g.If(!importer.Job.FinishedAt.IsZero(),
g.Group([]g.Node{
g.Text("Last run took "),
Time(
DateTime(importer.Job.FinishedAt.Format(time.RFC3339)),
Title(importer.Job.FinishedAt.Format(time.DateTime)),
g.Text(time.Since(importer.Job.FinishedAt).Round(time.Minute).String()),
),
}),
),
),
P(
g.Text("Indexing last ran "),
Time(
DateTime(importer.Job.FinishedAt.Format(time.RFC3339)),
Title(importer.Job.FinishedAt.Format(time.DateTime)),
g.Textf("%.0f hours ago", time.Since(importer.Job.FinishedAt).Hours()),
),
g.Text(", will run again in "),
Time(
DateTime(importer.Job.NextRun.Format(time.RFC3339)),
Title(importer.Job.NextRun.Format(time.DateTime)),
g.Textf("%.0f hours", time.Until(importer.Job.NextRun).Hours()),
),
g.Text("."),
),
),
script(tdata.Assets.ByPath["/static/search.js"]),
SearchForm(tdata, r),
Section(
ID("results"),
Role("list"),
Aria("label", "search results"),
g.Group(children),
),
Dialog(
ID("dialog"),
Button(AutoFocus(), g.Text("Close")),
),
NoScript(
P(
Class("notice"),
g.Text("Everything should work fine without JavaScript. If that is not the case, "),
A(
Href("https://codeberg.org/alanpearce/searchix/issues"),
g.Text("report an issue"),
),
),
),
)
}
func MapCommaList[T any](items []T, fn func(T) g.Node) g.Node {
out := make([]g.Node, (len(items) * 2))
j := 0
last := len(items) - 2
for i := range items {
out[j] = fn(items[i])
j++
if i <= last {
if i == last {
out[j] = g.Text(" and ")
} else {
out[j] = g.Text(", ")
}
}
j++
}
return g.Group(out)
}
|