personen anfang

This commit is contained in:
Simon Martens
2025-02-22 23:36:04 +01:00
parent 3d54725283
commit 9c15836e7d
7 changed files with 307 additions and 132 deletions

View File

@@ -103,16 +103,64 @@ func AgentsForContents(app core.App, contents []*Content) (map[string]*Agent, Ag
return agentsMap, relationMap, nil return agentsMap, relationMap, nil
} }
func LettersForAgents(app core.App) ([]string, error) { func LettersForAgents(app core.App, filter string) ([]string, error) {
letters := []core.Record{} letters := []core.Record{}
ids := []string{} ids := []string{}
err := app.RecordQuery(AGENTS_TABLE). if filter == "" || filter == "noorg" {
Select("upper(substr(" + AGENTS_NAME_FIELD + ", 1, 1)) AS id"). err := app.RecordQuery(AGENTS_TABLE).
Distinct(true). Select("upper(substr(" + AGENTS_NAME_FIELD + ", 1, 1)) AS id").
All(&letters) Distinct(true).
if err != nil { Where(dbx.HashExp{AGENTS_CORP_FIELD: false}).
return nil, err All(&letters)
if err != nil {
return nil, err
}
} else if filter == "org" {
err := app.RecordQuery(AGENTS_TABLE).
Select("upper(substr(" + AGENTS_NAME_FIELD + ", 1, 1)) AS id").
Distinct(true).
Where(dbx.HashExp{AGENTS_CORP_FIELD: true}).
All(&letters)
if err != nil {
return nil, err
}
} else if filter == "musik" {
err := app.RecordQuery(AGENTS_TABLE).
Select("upper(substr(" + AGENTS_NAME_FIELD + ", 1, 1)) AS id").
Distinct(true).
Where(dbx.Like(AGENTS_PROFESSION_FIELD, "Musik").Match(true, true)).
All(&letters)
if err != nil {
return nil, err
}
} else if filter == "autor" {
err := app.RecordQuery(AGENTS_TABLE).
Select("upper(substr(" + AGENTS_NAME_FIELD + ", 1, 1)) AS id").
Distinct(true).
Where(dbx.Like(AGENTS_PROFESSION_FIELD, "Text").Match(true, true)).
All(&letters)
if err != nil {
return nil, err
}
} else if filter == "graphik" {
err := app.RecordQuery(AGENTS_TABLE).
Select("upper(substr(" + AGENTS_NAME_FIELD + ", 1, 1)) AS id").
Distinct(true).
Where(dbx.Like(AGENTS_PROFESSION_FIELD, "Graphik").Match(true, true)).
All(&letters)
if err != nil {
return nil, err
}
} else if filter == "hrsg" {
err := app.RecordQuery(AGENTS_TABLE).
Select("upper(substr(" + AGENTS_NAME_FIELD + ", 1, 1)) AS id").
Distinct(true).
Where(dbx.Like(AGENTS_PROFESSION_FIELD, "Hrsg").Match(true, true)).
All(&letters)
if err != nil {
return nil, err
}
} }
for _, l := range letters { for _, l := range letters {

View File

@@ -32,22 +32,14 @@ func (p *PersonenPage) Setup(router *router.Router[*core.RequestEvent], app core
if e.Request.URL.Query().Get(PARAM_SEARCH) != "" { if e.Request.URL.Query().Get(PARAM_SEARCH) != "" {
return p.SearchRequest(app, engine, e) return p.SearchRequest(app, engine, e)
} }
if e.Request.URL.Query().Get(PARAM_FILTER) != "" {
return p.FilterRequest(app, engine, e)
}
return p.LetterRequest(app, engine, e) return p.FilterRequest(app, engine, e)
}) })
return nil return nil
} }
func (p *PersonenPage) CommonData(app core.App, data map[string]interface{}) error { func (p *PersonenPage) CommonData(app core.App, data map[string]interface{}) error {
letters, err := dbmodels.LettersForAgents(app)
if err != nil {
return err
}
data["letters"] = letters
return nil return nil
} }
@@ -58,6 +50,11 @@ func (p *PersonenPage) FilterRequest(app core.App, engine *templating.Engine, e
if letter == "" { if letter == "" {
letter = "A" letter = "A"
} }
if filter == "" {
filter = "noorg"
}
data := map[string]interface{}{} data := map[string]interface{}{}
var err error = nil var err error = nil
@@ -94,6 +91,13 @@ func (p *PersonenPage) FilterRequest(app core.App, engine *templating.Engine, e
data["filter"] = filter data["filter"] = filter
data["letter"] = letter data["letter"] = letter
letters, err := dbmodels.LettersForAgents(app, filter)
if err != nil {
return engine.Response404(e, err, data)
}
data["letters"] = letters
return p.Get(e, engine, data) return p.Get(e, engine, data)
} }
@@ -116,24 +120,6 @@ func (p *PersonenPage) SearchRequest(app core.App, engine *templating.Engine, e
return p.Get(e, engine, data) return p.Get(e, engine, data)
} }
func (p *PersonenPage) LetterRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error {
letter := e.Request.URL.Query().Get(PARAM_LETTER)
if letter == "" {
letter = "A"
}
data := map[string]interface{}{}
data["letter"] = letter
agents, err := dbmodels.AgentsForLetter(app, letter)
if err != nil {
return engine.Response404(e, err, data)
}
dbmodels.SortAgentsByName(agents)
data["agents"] = agents
return p.Get(e, engine, data)
}
func (p *PersonenPage) Get(request *core.RequestEvent, engine *templating.Engine, data map[string]interface{}) error { func (p *PersonenPage) Get(request *core.RequestEvent, engine *templating.Engine, data map[string]interface{}) error {
err := p.CommonData(request.App, data) err := p.CommonData(request.App, data)
if err != nil { if err != nil {

File diff suppressed because one or more lines are too long

View File

@@ -1,88 +1,203 @@
{{ $model := . }} {{ $model := . }}
{{ template "_alphabet" Dict "active" .letter "letters" .letters }} {{ $isPerson := and $model.filter (or (eq $model.filter "noorg") (eq $model.filter "musik") (eq $model.filter "autor") (eq $model.filter "graphik") (eq $model.filter "hrsg")) }}
{{ $isNoOrg := and $model.filter (eq $model.filter "noorg") }}
{{ $isOrg := and $model.filter (eq $model.filter "org") }}
{{ $isMusik := and $model.filter (eq $model.filter "musik") }}
{{ $isAutor := and $model.filter (eq $model.filter "autor") }}
{{ $isGraphik := and $model.filter (eq $model.filter "graphik") }}
{{ $isHrsg := and $model.filter (eq $model.filter "hrsg") }}
<input <div class="container-normal mt-4" x-data="{ search : '{{ $model.search }}'}">
class="form-control" {{- if not $model.search -}}
type="search" <div
name="search" id="persontype"
placeholder="Suche" class="flex flex-row justify-end align-right text-right mr-4 gap-x-3"
hx-get="/personen" :class="search ? 'inactive' : ''">
hx-trigger="input changed delay:200ms, keyup[key=='Enter']" <a
hx-select="#agents" href="/personen{{ if .letter }}?letter={{ .letter }}{{ end }}"
hx-target="#agents" /> {{ if $isPerson -}}aria-current="page"{{- end -}}
>Personen</a
>
<div> <a
<a href="/personen{{ if .letter }}?letter={{ .letter }}{{ end }}">Alle</a> href="/personen?filter=org{{ if .letter }}&letter={{ .letter }}{{ end }}"
<a href="/personen?filter=org{{ if .letter }}&letter={{ .letter }}{{ end }}" {{ if $isOrg -}}aria-current="page"{{- end -}}
>Verlage u. Druckereien</a >Verlage, Druckereien &amp; Vertriebe</a
> >
<a href="/personen?filter=noorg{{ if .letter }}&letter={{ .letter }}{{ end }}">Personen</a> </div>
<a href="/personen?filter=musik{{ if .letter }}&letter={{ .letter }}{{ end }}">Musiker:innen</a> {{- end -}}
<a href="/personen?filter=autor{{ if .letter }}&letter={{ .letter }}{{ end }}">Autor:innen</a>
<a href="/personen?filter=graphik{{ if .letter }}&letter={{ .letter }}{{ end }}"
>Graphiker:innen</a
>
<a href="/personen?filter=hrsg{{ if .letter }}&letter={{ .letter }}{{ end }}"
>Herausgeber:innen</a
>
</div>
<div id="agents">
{{ if or .agents .altagents }} <div class="flex flex-row">
{{ if .agents }} {{- if and $model.letters (not $model.search) -}}
<table class="w-full [&_td]:!align-top"> <div id="personalphabet" class="flex flex-col text-xl pt-8 relative">
{{ range $count, $agent := .agents }} {{- range $id, $r := .letters -}}
<tr> <a
<td> class="odd:bg-stone-100 even:bg-zinc-100 mb-1 border-zinc-300 border-y border-l [&>a[aria-current='page']]:font-bold
<a href="/person/{{ $agent.Id }}"> px-2 no-underline transition-all duration-75
{{ $agent.Name }} {{ if not $model.letter -}}inactive{{- end -}}"
{{ if $agent.Pseudonyms }} :class="search ? 'inactive' : 'active'"
<br /> href="?letter={{ $r }}{{- if $model.filter }}&filter={{ $model.filter }}{{- end -}}"
({{ $agent.Pseudonyms }}) {{ if eq $model.letter $r }}aria-current="page"{{ end }}
hx-select="main"
hx-target="main"
hx-swap="outerHTML scroll:#pageheading:top"
>{{ $r }}</a
>
{{- end -}}
</div>
{{- end -}}
<div class="w-full">
<div id="personheader" class="border-t border-r border-zinc-300 relative w-full">
<h1
class="text-3xl font-bold px-3 relative -translate-y-[55%] w-min whitespace-nowrap bg-stone-50 ml-24 z-20">
<span x-show="!search">
{{- if $isPerson -}}
Personen
{{- else if $isOrg -}}
Verlage, Druckereien &amp; Vertriebe
{{- end -}}
</span>
<span x-show="search"> Suche &middot; Alle Personen &amp; Körperschaften </span>
</h1>
<div class="flex flex-row justify-between">
<div class="w-[60%] shrink-0 grow-0">
<div class="min-w-[22.5rem] max-w-96 flex flex-row relative mt-9 ml-auto">
<div class="">
<i class="ri-search-line"></i
><i class="-ml-0.5 inline-block ri-arrow-right-s-line"></i>
</div>
<div class="pb-0 border-b-4 border-zinc-300 grow">
<input
class="px-1.5 font-serif placeholder:italic w-full"
type="search"
name="search"
value="{{ $model.search }}"
placeholder="Suchbegriff"
x-model="search"
hx-get=""
hx-trigger="input changed delay=500ms, keyup[key=='Enter']"
hx-sync="this:replace"
hx-select="#searchresults"
hx-target="#searchresults"
autocomplete="off"
{{ if $model.active }}autofocus="true"{{ end }}
{{ if $model.search }}disabled="true"{{ end }} />
</div>
<div id="permalink" class="font-serif ml-3 min-w-7 pb-1">
<tool-tip position="right" x-show="search">
<a
:href="'/personen/?search=' + search"
x-show="search"
class="inline-block px-1
text-white no-underline bg-stone-700 hover:bg-stone-900 rounded"
hx-boost="false">
<i class="ri-links-line"></i
></a>
<div class="data-tip">Link zu dieser Suchanfrage</div>
</tool-tip>
</div>
</div>
</div>
{{- if $isPerson -}}
<div x-show="!search" class="flex flex-row gap-x-3 font-serif mr-6 items-end">
<label
for="filter"
class="align-bottom h-min self-end pb-1 text-sm font-sans text-stone-700"
>Anzeige:</label
>
<select
class="h-min pb-1 border-b-4 border-zinc-300 px-1.5"
name="filter"
id="filter"
hx-get="/personen{{- if .letter -}}?letter={{ .letter }}{{- end -}}"
trigger="change"
hx-push-url="true"
hx-select="main"
hx-target="main">
<option value="noorg" {{ if $isNoOrg }}selected{{ end }}>Alle Personen</option>
<option value="musik" {{ if $isMusik }}selected{{ end }}>Musiker:innen</option>
<option value="autor" {{ if $isAutor }}selected{{ end }}>Autor:innen</option>
<option value="graphik" {{ if $isGraphik }}selected{{ end }}>
Graphiker:innen
</option>
<option value="hrsg" {{ if $isHrsg }}selected{{ end }}>Herausgeber:innen</option>
</select>
</div>
{{- end -}}
</div>
</div>
<div class="mt-4 ml-4 font-serif font-lg" id="searchresults">
{{ if or .agents .altagents }}
{{ if .agents }}
<table class="w-full [&_td]:!align-top">
{{ range $count, $agent := .agents }}
<tr>
<td>
<a href="/person/{{ $agent.Id }}" class="font-bold">
{{ $agent.Name }}
{{ if $agent.Pseudonyms }}
<br />
({{ $agent.Pseudonyms }})
{{ end }}
</a>
</td>
<td>
{{ if $agent.CorporateBody }}
Körperschaft
{{ else }}
{{ $agent.Profession }},
{{ $agent.BiographicalData }}
{{ end }}
</td>
<td>{{ $agent.References }}</td>
</tr>
{{ end }} {{ end }}
</a>
</td>
<td>
{{ if $agent.CorporateBody }}
Körperschaft
{{ else }}
{{ $agent.Profession }},
{{ $agent.BiographicalData }}
{{ end }}
</td>
<td>{{ $agent.References }}</td>
</tr>
{{ end }}
</table> </table>
{{ end }} {{ end }}
{{ if .altagents }} {{ if .altagents }}
<table class="w-full mt-6"> <table class="w-full mt-6">
{{ range $count, $agent := .altagents }} {{ range $count, $agent := .altagents }}
<tr> <tr>
<td> <td>
{{ $agent.Name }} {{ $agent.Name }}
{{ if $agent.Pseudonyms }} {{ if $agent.Pseudonyms }}
<br /> <br />
({{ $agent.Pseudonyms }}) ({{ $agent.Pseudonyms }})
{{ end }} {{ end }}
</td> </td>
<td> <td>
{{ if $agent.CorporateBody }} {{ if $agent.CorporateBody }}
Körperschaft Körperschaft
{{ else }} {{ else }}
{{ $agent.Profession }}, {{ $agent.Profession }},
{{ $agent.BiographicalData }} {{ $agent.BiographicalData }}
{{ end }} {{ end }}
</td> </td>
<td>{{ $agent.References }}</td> <td>{{ $agent.References }}</td>
</tr> </tr>
{{ end }} {{ end }}
</table> </table>
{{ end }} {{ end }}
{{ else }} {{ else }}
<p>Keine Personen gefunden.</p> <p>Keine Personen gefunden.</p>
{{ end }} {{ end }}
</div>
</div>
</div>
</div>
</div> </div>

View File

@@ -4,7 +4,11 @@
<div id="searchcontrol" class="container-normal"> <div id="searchcontrol" class="container-normal">
<div id="searchheading" class="flex flex-row justify-between min-h-14 items-end relative"> <div id="searchheading" class="flex flex-row justify-between min-h-14 items-end relative">
<nav id="searchnav" class="flex flex-row items-end"> <nav id="searchnav" class="flex flex-row items-end">
<div class="align-bottom h-min self-end pb-0.5 hidden">Durchsuchen:</div> <div
class="align-bottom text-lg h-min self-end pb-0.5 italic font-bold
text-zinc-800">
Suche nach:
</div>
<a <a
href="/suche/reihen" href="/suche/reihen"
class="block no-underline" class="block no-underline"
@@ -15,13 +19,13 @@
href="/suche/baende" href="/suche/baende"
class="block no-underline" class="block no-underline"
{{ if eq $model.type "baende" }}aria-current="page"{{- end -}} {{ if eq $model.type "baende" }}aria-current="page"{{- end -}}
>Bände</a >Bänden</a
> >
<a <a
href="/suche/beitraege" href="/suche/beitraege"
class="block no-underline" class="block no-underline"
{{ if eq $model.type "beitraege" }}aria-current="page"{{- end -}} {{ if eq $model.type "beitraege" }}aria-current="page"{{- end -}}
>Beiträge</a >Beiträgen</a
> >
<a <a
href="/suche/personen" href="/suche/personen"

View File

@@ -34,16 +34,6 @@
{{- end -}} /> {{- end -}} />
<label for="title">Titel</label> <label for="title">Titel</label>
</div> </div>
<div class="selectgroup-option">
<input
type="checkbox"
name="annotations"
id="annotations"
{{ if $includeAnnotations -}}
checked
{{- end -}} />
<label for="annotations">Anmerkungen</label>
</div>
<div class="selectgroup-option"> <div class="selectgroup-option">
<input <input
type="checkbox" type="checkbox"
@@ -54,6 +44,16 @@
{{- end -}} /> {{- end -}} />
<label for="references">Nachweise</label> <label for="references">Nachweise</label>
</div> </div>
<div class="selectgroup-option">
<input
type="checkbox"
name="annotations"
id="annotations"
{{ if $includeAnnotations -}}
checked
{{- end -}} />
<label for="annotations">Anmerkungen</label>
</div>
</fieldset> </fieldset>
{{ template "infotextsimple" false }} {{ template "infotextsimple" false }}
</div> </div>
@@ -79,14 +79,14 @@
<input type="checkbox" name="profession" id="profession" checked /> <input type="checkbox" name="profession" id="profession" checked />
<label for="profession">Beruf(e)</label> <label for="profession">Beruf(e)</label>
</div> </div>
<div class="selectgroup-option">
<input type="checkbox" name="annotations" id="annotations" checked />
<label for="annotations">Anmerkungen</label>
</div>
<div class="selectgroup-option"> <div class="selectgroup-option">
<input type="checkbox" name="references" id="references" checked /> <input type="checkbox" name="references" id="references" checked />
<label for="references">Nachweise</label> <label for="references">Nachweise</label>
</div> </div>
<div class="selectgroup-option">
<input type="checkbox" name="annotations" id="annotations" checked />
<label for="annotations">Anmerkungen</label>
</div>
</fieldset> </fieldset>
{{ template "infotextsimple" false }} {{ template "infotextsimple" false }}
</div> </div>

View File

@@ -199,7 +199,7 @@
} }
#searchnav > a:nth-of-type(1) { #searchnav > a:nth-of-type(1) {
@apply ml-12; @apply ml-6;
} }
#searchnav > a { #searchnav > a {
@@ -251,4 +251,26 @@
#searchform .selectgroup .selectgroup-option label { #searchform .selectgroup .selectgroup-option label {
@apply whitespace-nowrap; @apply whitespace-nowrap;
} }
#searchform .selectgroup input:not(:checked) + label {
@apply decoration-slate-900 line-through;
}
#persontype a {
@apply px-1.5 border-b-[5px] border-zinc-300 no-underline font-serif mx-2.5;
}
#persontype a[aria-current="page"]:not(#persontype.inactive a) {
@apply font-bold;
}
#personheader:before {
content: "";
@apply bg-zinc-300 w-[50%] absolute bottom-0 left-[50%] h-[1px];
}
#personalphabet:after {
content: "";
@apply absolute right-0 top-0 h-[44em] border-r border-zinc-300;
}
} }