Basis Suche Inhalte

This commit is contained in:
Simon Martens
2025-02-28 22:31:19 +01:00
parent 4581f34dd9
commit ca33ec7be3
20 changed files with 1290 additions and 594 deletions

View File

@@ -2,6 +2,9 @@
<html class="w-full h-full" {{ if .lang }}lang="{{ .lang }}"{{ end }}>
<head>
<meta charset="UTF-8" />
<meta
name="htmx-config"
content='{"defaultSwapStyle":"outerHTML", "scrollBehavior": "instant"}' />
{{ block "head" . }}
<!-- Default Head elements -->

View File

@@ -4,6 +4,32 @@
.3 - []*RContentsAgents
.4 - map[string]*Agent
.5 bool SingleView
.6 .parameters:
type SearchParameters struct {
Parameters
Sort string
Annotations bool
Persons bool
Title bool
Series bool
Places bool
Refs bool
Year bool
Entry bool
Incipit bool
AnnotationsString string
PersonsString string
TitleString string
AlmString string
SeriesString string
PlacesString string
RefsString string
YearString string
EntryString string
IncipitString string
}
*/}}
{{- $content := index . 0 -}}
@@ -21,6 +47,27 @@
{{- $entrySubView = index . 5 -}}
{{- end -}}
{{ $isAlm := false }}
{{ $isTitle := false }}
{{ $isYear := false }}
{{ $isPerson := false }}
{{ $isAnnotation := false }}
{{ $isIncipit := false }}
{{ $isEntry := false }}
{{- $searchparameters := false -}}
{{- if gt (len .) 6 -}}
{{- $searchparameters = index . 6 -}}
{{- $isAlm = $searchparameters.AlmString -}}
{{- $isTitle = or $searchparameters.Title $searchparameters.TitleString -}}
{{- $isYear = or $searchparameters.Year $searchparameters.YearString -}}
{{- $isPerson = or $searchparameters.Persons $searchparameters.PersonsString -}}
{{- $isAnnotation = or $searchparameters.Annotations $searchparameters.AnnotationsString -}}
{{- $isIncipit = or $searchparameters.Incipit $searchparameters.IncipitString -}}
{{- $isEntry = or $searchparameters.Entry $searchparameters.EntryString -}}
{{- end -}}
<div
class="content flex flex-row font-serif {{ if or $entrySubView $singleView -}}text-lg{{- end -}}"
@@ -50,8 +97,8 @@
<div class="fields">
{{- if or $singleView $entrySubView -}}
<div class="fieldlabel">Almanach</div>
<div class="fieldvalue">
<a href="/almanach/{{- $entry.MusenalmID -}}">
<div class="fieldvalue {{ if $isEntry }}search-text{{ end }}">
<a href="/almanach/{{- $entry.MusenalmID -}}#{{- $content.MusenalmID -}}">
{{- $entry.PreferredTitle -}}
</a>
{{- if $content.Extent -}}
@@ -62,15 +109,21 @@
{{- end -}}
{{- if $content.TitleStmt -}}
<div class="fieldlabel">Titel</div>
<div class="italic fieldvalue">{{- $content.TitleStmt -}}</div>
<div class="italic fieldvalue {{ if $isTitle }}search-text{{ end }}">
{{- $content.TitleStmt -}}
</div>
{{- end -}}
{{- if $content.IncipitStmt -}}
<div class="fieldlabel">Incipit</div>
<div class="italic fieldvalue">{{ $content.IncipitStmt }}…</div>
<div class="italic fieldvalue {{ if $isIncipit }}search-text{{ end }}">
{{ $content.IncipitStmt }}…
</div>
{{- end -}}
{{- if $content.ResponsibilityStmt -}}
<div class="fieldlabel">Autorangabe</div>
<div class="fieldvalue italic">{{- $content.ResponsibilityStmt -}}</div>
<div class="fieldvalue italic {{ if $isPerson }}search-text{{ end }}">
{{- $content.ResponsibilityStmt -}}
</div>
{{- end -}}
{{- if $rcas -}}
<div class="fieldlabel">Personen</div>
@@ -79,7 +132,11 @@
{{- range $_, $rca := $rcas -}}
{{- $agent := index $agents $rca.Agent -}}
<div class="font-sans text-base bg-stone-100 px-1 py-0.5 rounded w-max">
<a href="/person/{{- $agent.Id -}}">{{- $agent.Name -}}</a>
<a
href="/person/{{- $agent.Id -}}"
class="inline-block {{ if $isPerson }}search-text{{ end }}">
{{- $agent.Name -}}
</a>
({{ $agent.BiographicalData -}})
</div>
{{- end -}}
@@ -87,10 +144,11 @@
</div>
{{- end -}}
{{- if $content.Annotation -}}
{{- $link := printf "%s%s" "/almanach/" $entry.MusenalmIDString -}}
<div class="fieldlabel">Anmerkung</div>
<div class="fieldvalue">
<div class="fieldvalue {{ if $isAnnotation }}search-text{{ end }}">
{{- Safe (LinksAnnotation (ReplaceSlashParen
$content.Annotation))
$content.Annotation) $link)
-}}
</div>
{{- end -}}
@@ -131,7 +189,9 @@
<div class="w-24 shrink-0 grow-0 items-end flex flex-col gap-y-1 columnfour">
<div class="font-sans text-sm bg-stone-100 px-2 font-bold py-0.5 rounded w-max">
<span class="text-xs font-normal pr-1">NR</span>
{{ $content.MusenalmID -}}
<span class="{{ if $isAlm }}search-text{{ end }}">
{{- $content.MusenalmID -}}
</span>
</div>
{{- if $entrySubView -}}
{{- if $content.MusenalmType -}}

View File

@@ -1,5 +1,5 @@
<div class="container-normal">
<div class="text">
<div class="text mt-6">
{{ Safe .record.Text }}
</div>
</div>

View File

@@ -68,25 +68,7 @@
<div id="searchcontrol" class="container-normal">
{{- template "_heading" $model.parameters -}}
<div id="searchform" class="border-l border-zinc-300 px-8 py-10 relative">
<form
id="lookupform"
class="w-full font-serif grid grid-cols-12 gap-x-4 mb-4"
method="get"
action="/suche/baende"
autocomplete="off">
<label for="almstring" class="col-span-3 align-middle hidden">Almanach-Nummer:</label>
<input
autocomplete="off"
minlength="1"
required="true"
type="search"
name="almstring"
id="almstring"
value="{{ $model.parameters.AlmString }}"
placeholder="Alm-Nummer"
class="w-full col-span-3 placeholder:italic" />
<button id="submitbutton" type="submit" class="col-span-2">Nachschlagen</button>
</form>
{{- template "_musenalmidbox" Arr $model.parameters.AlmString "baende" -}}
<form
id="simplesearchform"
class="w-full font-serif"
@@ -122,11 +104,7 @@
type="checkbox"
name="persons"
id="persons"
{{ if or $isBase
$isPersons
-}}
checked
{{- end -}} />
{{ if or $isBase $isPersons -}}checked{{- end -}} />
<label for="persons">Personen &amp; Verlage</label>
</div>
<div class="selectgroup-option">
@@ -266,7 +244,7 @@
class="h-min pb-1 border-b-4 border-zinc-300 px-1.5"
name="sort"
id="sort"
hx-get="{{- $model.parameters.ToQueryParams -}}"
hx-get="{{- $model.parameters.ToQueryParamsBaende -}}"
trigger="change"
hx-push-url="true"
hx-select="main"
@@ -315,7 +293,7 @@
let mark_instance = new Mark(elements);
// INFO: we wait a little bit before marking, to settle everything
setTimeout(() => {
mark_instance.mark('{{ $model.parameters.AllSearchTerms }}', {
mark_instance.mark('{{ $model.parameters.AllSearchTermsBaende }}', {
"seperateWordSearch": true,
});
}, 200);
@@ -326,40 +304,3 @@
<div class="container-normal">Keine Bände gefunden.</div>
{{- end -}}
{{- end -}}
<script type="module">
const form = document.getElementById("simplesearchform");
let submitBtn = null;
if (form) {
submitBtn = form.querySelector("#submitbutton");
}
function checkValidity(f, btn) {
if (f.checkValidity()) {
btn.disabled = false;
} else {
btn.disabled = true;
}
}
if (form && submitBtn) {
checkValidity(form, submitBtn);
form.addEventListener("input", (event) => {
checkValidity(form, submitBtn);
});
}
const lookupform = document.getElementById("lookupform");
let lookupsubmitBtn = null;
if (lookupform) {
lookupsubmitBtn = lookupform.querySelector("#submitbutton");
}
if (lookupform && lookupsubmitBtn) {
checkValidity(lookupform, lookupsubmitBtn);
lookupform.addEventListener("input", (event) => {
checkValidity(lookupform, lookupsubmitBtn);
});
}
</script>

View File

@@ -1,11 +1,69 @@
{{ $model := . }}
{{/* .result:
type SearchResultBeitraege struct {
Queries []dbmodels.FTS5QueryRequest
// these are the sorted IDs for hits
Hits []string
Entries map[string]*dbmodels.Entry // <- Key: Entry ID
Agents map[string]*dbmodels.Agent // <- Key: Agent IDs
Contents map[string][]*dbmodels.Content // <- Key: Entry ID, or year
ContentsAgents map[string][]*dbmodels.RContentsAgents // <- Key: Content ID
}
.parameters:
type SearchParameters struct {
Parameters
Sort string
Annotations bool
Persons bool
Title bool
Series bool
Places bool
Refs bool
Year bool
Entry bool
Incipit bool
AnnotationsString string
PersonsString string
TitleString string
AlmString string
SeriesString string
PlacesString string
RefsString string
YearString string
EntryString string
IncipitString string
}
*/}}
{{ $isAlm := false }}
{{ $isTitle := false }}
{{ $isYear := false }}
{{ $isPerson := false }}
{{ $isAnnotation := false }}
{{ $isIncipit := false }}
{{ $isEntry := false }}
{{- $isAlm = $model.parameters.AlmString -}}
{{- $isTitle = or $model.parameters.Title $model.parameters.TitleString -}}
{{- $isYear = or $model.parameters.Year $model.parameters.YearString -}}
{{- $isPerson = or $model.parameters.Persons $model.parameters.PersonsString -}}
{{- $isAnnotation = or $model.parameters.Annotations $model.parameters.AnnotationsString -}}
{{- $isIncipit = or $model.parameters.Incipit $model.parameters.IncipitString -}}
{{- $isEntry = or $model.parameters.Entry $model.parameters.EntryString -}}
{{- $isBase := not (or $isTitle $isYear $isPerson $isAnnotation $isIncipit $isEntry) -}}
<div id="searchcontrol" class="container-normal">
{{- template "_heading" $model.parameters -}}
<div id="" class="border-l border-zinc-300 px-8 py-10 relative">
<div id="searchform" class="border-l border-zinc-300 px-8 py-10 relative">
{{- template "_musenalmidbox" Arr $model.parameters.AlmString "beitraege" -}}
<form
id="searchform"
id="simplesearchform"
class="w-full font-serif"
method="get"
action="/suche/beitraege"
@@ -18,29 +76,35 @@
{{ template "_searchboxsimple" Arr $model.parameters true $q }}
<fieldset class="selectgroup">
<div class="selectgroup-option">
<input type="checkbox" name="number" id="number" checked />
<label for="number">Almanach-Nr.</label>
<input type="checkbox" name="title" id="title"
{{ if or $isBase $isTitle -}}checked{{- end -}} />
<label for="title">Titel</label>
</div>
<div class="selectgroup-option">
<input type="checkbox" name="title" id="title" checked />
<label for="title">Titelinformationen</label>
<input type="checkbox" name="incipit" id="incipit"
{{ if or $isBase $isIncipit -}}checked{{- end -}} />
<label for="incipit">Incipit</label>
</div>
<div class="selectgroup-option">
<input type="checkbox" name="entry" id="entry" checked />
<label for="entry">Bandtitel</label>
</div>
<div class="selectgroup-option">
<input type="checkbox" name="person" id="person" checked />
<input type="checkbox" name="persons" id="persons"
{{ if or $isBase $isPerson -}}checked{{- end -}} />
<label for="person">Personen &amp; Pseudonyme</label>
</div>
<div class="selectgroup-option">
<input type="checkbox" name="annotations" id="annotations" checked />
<label for="annotations">Anmerkungen</label>
<input type="checkbox" name="entry" id="entry"
{{ if or $isBase $isEntry -}}checked{{- end -}} />
<label for="entry">Bandtitel</label>
</div>
<div class="selectgroup-option">
<input type="checkbox" name="year" id="year" checked />
<input type="checkbox" name="year" id="year"
{{ if or $isBase $isYear -}}checked{{- end -}} />
<label for="year">Jahr</label>
</div>
<div class="selectgroup-option">
<input type="checkbox" name="annotations" id="annotations"
{{ if or $isBase $isAnnotation -}}checked{{- end -}} />
<label for="annotations">Anmerkungen</label>
</div>
</fieldset>
{{ template "_infotextsimple" true }}
</div>
@@ -49,3 +113,127 @@
</div>
{{- template "_fieldscript" -}}
{{- if $model.parameters.IsBeitraegeSearch -}}
<div class="container-normal" id="searchresults">
<div class="border-b border-zinc-300 flex flex-row justify-between">
<div>
{{ if $model.parameters.Query -}}
Suche nach <b>»{{ $model.parameters.Query }}«</b> &middot;
{{- end -}}
{{- if $isAlm -}}
Inhaltsnummer <b>»{{ $model.parameters.AlmString }}«</b> &middot;
{{- end -}}
<i class="ri-book-line"></i>
{{ if eq $model.result.Count 1 -}}
Ein Beitrag
{{ else -}}
{{ $model.result.Count }} Beiträge
{{- end }}
in
{{ if eq ($model.result.Entries | len) 1 -}}
einem Band
{{ else -}}
{{ $model.result.Entries | len }} Bänden
{{- end -}}
</div>
{{- if gt (len $model.result.Pages) 1 }}
<div>
{{ if gt $model.parameters.Page 1 -}}
<a
href="{{- $model.parameters.ToQueryParamsBeitraege -}}&page={{ $model.parameters.Prev
}}" class="mr-1.5">
<i class="ri-arrow-left-long-line"></i>
</a>
{{- end -}}
S. {{ $model.parameters.Page }} /
{{ $model.result.PagesCount }}
{{ if lt $model.parameters.Page ($model.result.PagesCount) -}}
<a
href="{{- $model.parameters.ToQueryParamsBeitraege -}}&page={{ $model.parameters.Next
}}" class="ml-1.5">
<i class="ri-arrow-right-long-line"></i>
</a>
{{- end -}}
</div>
{{- end -}}
{{- if not $isAlm -}}
<div>
<label
for="sort"
class="align-baseline h-min self-end pb-1 mr-2 text-sm font-sans
text-stone-700"
>Sortierung</label
>
{{/* INFO: We always redrect to letter = A bc some letters dont exist for other professions */}}
<select
class="h-min pb-1 border-b-4 border-zinc-300 px-1.5"
name="sort"
id="sort"
autocomplete="off"
hx-get="{{- $model.parameters.ToQueryParamsBeitraege -}}"
trigger="change"
hx-push-url="true"
hx-select="main"
hx-target="main">
<option
value="year"
{{ if eq $model.parameters.Sort "year" -}}
selected
{{- end -}}>
Jahr
</option>
<option value="entry" {{ if eq $model.parameters.Sort "entry" -}}selected{{- end -}}>
Bände A-Z
</option>
</select>
</div>
{{- end -}}
</div>
{{- if $model.result.Hits -}}
<div class="mt-8" id="almanachcontents">
{{- range $_, $hit := $model.result.Hits -}}
{{- $e := index $model.result.Entries $hit -}}
{{- $contents := index $model.result.Contents $e.Id -}}
<div
class="font-serif flex flex-row justify-between text-stone-800
font-bold border-b pb-0.5 mb-2 tab-list-head items-end">
<div>
{{ $e.PreferredTitle }}
</div>
<div
class="inline-block font-sans bg-slate-800 text-white h-max text-sm px-1.5 rounded">
{{- len $contents -}}
</div>
</div>
<div class="mb-7 tab-list-panel">
{{- range $i, $c := $contents -}}
{{- $rels := index $model.result.ContentsAgents $c.Id -}}
{{- template "_content" Arr $c $e $rels $model.result.Agents false true
$model.parameters
-}}
{{- end -}}
</div>
{{- end -}}
</div>
{{- end -}}
</div>
<script type="module">
let elements = document.querySelectorAll('.search-text');
let mark_instance = new Mark(elements);
// INFO: we wait a little bit before marking, to settle everything
setTimeout(() => {
mark_instance.mark('{{ $model.parameters.AllSearchTermsBaende }}', {
"seperateWordSearch": true,
});
}, 200);
</script>
</div>
{{- end -}}

View File

@@ -14,4 +14,38 @@
}
}
});
const form = document.getElementById("simplesearchform");
let submitBtn = null;
if (form) {
submitBtn = form.querySelector("#submitbutton");
}
function checkValidity(f, btn) {
if (f.checkValidity()) {
btn.disabled = false;
} else {
btn.disabled = true;
}
}
if (form && submitBtn) {
checkValidity(form, submitBtn);
form.addEventListener("input", (event) => {
checkValidity(form, submitBtn);
});
}
const lookupform = document.getElementById("lookupform");
let lookupsubmitBtn = null;
if (lookupform) {
lookupsubmitBtn = lookupform.querySelector("#submitbutton");
}
if (lookupform && lookupsubmitBtn) {
checkValidity(lookupform, lookupsubmitBtn);
lookupform.addEventListener("input", (event) => {
checkValidity(lookupform, lookupsubmitBtn);
});
}
</script>

View File

@@ -0,0 +1,21 @@
{{ $p := index . 0 }}
{{ $t := index . 1 }}
<form
id="lookupform"
class="w-full font-serif grid grid-cols-12 gap-x-4 mb-4"
method="get"
action="/suche/{{- $t -}}"
autocomplete="off">
<label for="almstring" class="col-span-3 align-middle hidden">Almanach-Nummer:</label>
<input
autocomplete="off"
minlength="1"
required="true"
type="search"
name="almstring"
id="almstring"
value="{{ $p }}"
placeholder="Alm-Nummer"
class="w-full col-span-3 placeholder:italic" />
<button id="submitbutton" type="submit" class="col-span-2">Nachschlagen</button>
</form>

View File

@@ -46,6 +46,7 @@
@layer components {
html {
font-size: 16px;
scroll-behavior: auto !important;
}
@media (max-width: 1280px) {
html {
@@ -458,4 +459,8 @@
@apply bg-stone-100 pr-6 py-4;
/*direction: rtl;*/
}
.tab-list-head[aria-pressed="true"] {
@apply !text-slate-800 bg-stone-50;
}
}