mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-29 09:15:33 +00:00
FEATURE: Beiträge auf der Almanach-Seite filtern
This commit is contained in:
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
URL_ALMANACH = "/almanach/{id}"
|
URL_ALMANACH = "/almanach/{id}/"
|
||||||
TEMPLATE_ALMANACH = "/almanach/"
|
TEMPLATE_ALMANACH = "/almanach/"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,11 +35,13 @@ func (p *AlmanachPage) Setup(router *router.Router[*core.RequestEvent], app core
|
|||||||
router.GET(p.URL, func(e *core.RequestEvent) error {
|
router.GET(p.URL, func(e *core.RequestEvent) error {
|
||||||
id := e.Request.PathValue("id")
|
id := e.Request.PathValue("id")
|
||||||
data := make(map[string]interface{})
|
data := make(map[string]interface{})
|
||||||
result, err := NewAlmanachResult(app, id)
|
filters := NewBeitraegeFilterParameters(e)
|
||||||
|
result, err := NewAlmanachResult(app, id, filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
engine.Response404(e, err, nil)
|
engine.Response404(e, err, nil)
|
||||||
}
|
}
|
||||||
data["result"] = result
|
data["result"] = result
|
||||||
|
data["filters"] = filters
|
||||||
|
|
||||||
abbrs, err := pagemodels.GetAbks(app)
|
abbrs, err := pagemodels.GetAbks(app)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -62,11 +64,11 @@ type AlmanachResult struct {
|
|||||||
EntriesAgents []*dbmodels.REntriesAgents
|
EntriesAgents []*dbmodels.REntriesAgents
|
||||||
ContentsAgents map[string][]*dbmodels.RContentsAgents // <- Key is content id
|
ContentsAgents map[string][]*dbmodels.RContentsAgents // <- Key is content id
|
||||||
|
|
||||||
CInfoByCollection map[string]dbmodels.CollectionInfo
|
Types []string
|
||||||
CInfoByContent map[int][]dbmodels.CollectionInfo
|
HasScans bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAlmanachResult(app core.App, id string) (*AlmanachResult, error) {
|
func NewAlmanachResult(app core.App, id string, params BeitraegeFilterParameters) (*AlmanachResult, error) {
|
||||||
// INFO: what about sql.ErrNoRows?
|
// INFO: what about sql.ErrNoRows?
|
||||||
// We don't get sql.ErrNoRows here, since dbx converts every empty slice or
|
// We don't get sql.ErrNoRows here, since dbx converts every empty slice or
|
||||||
// empty id to a WHERE 0=1 query, which will not error.
|
// empty id to a WHERE 0=1 query, which will not error.
|
||||||
@@ -102,6 +104,33 @@ func NewAlmanachResult(app core.App, id string) (*AlmanachResult, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
types := Types_Contents(contents)
|
||||||
|
hs := HasScans(contents)
|
||||||
|
|
||||||
|
if params.OnlyScans {
|
||||||
|
cscans := []*dbmodels.Content{}
|
||||||
|
for _, c := range contents {
|
||||||
|
if len(c.Scans()) > 0 {
|
||||||
|
cscans = append(cscans, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contents = cscans
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Type != "" {
|
||||||
|
cfiltered := []*dbmodels.Content{}
|
||||||
|
outer:
|
||||||
|
for _, c := range contents {
|
||||||
|
for _, t := range c.MusenalmType() {
|
||||||
|
if t == params.Type {
|
||||||
|
cfiltered = append(cfiltered, c)
|
||||||
|
continue outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contents = cfiltered
|
||||||
|
}
|
||||||
|
|
||||||
dbmodels.Sort_Contents_Numbering(contents)
|
dbmodels.Sort_Contents_Numbering(contents)
|
||||||
|
|
||||||
contentsagents, err := dbmodels.RContentsAgents_Contents(app, dbmodels.Ids(contents))
|
contentsagents, err := dbmodels.RContentsAgents_Contents(app, dbmodels.Ids(contents))
|
||||||
@@ -140,6 +169,8 @@ func NewAlmanachResult(app core.App, id string) (*AlmanachResult, error) {
|
|||||||
EntriesSeries: srelationsMap,
|
EntriesSeries: srelationsMap,
|
||||||
EntriesAgents: entriesagents,
|
EntriesAgents: entriesagents,
|
||||||
ContentsAgents: caMap,
|
ContentsAgents: caMap,
|
||||||
|
Types: types,
|
||||||
|
HasScans: hs,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.Collections()
|
ret.Collections()
|
||||||
@@ -158,5 +189,29 @@ func (r *AlmanachResult) Collections() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Types_Contents(contents []*dbmodels.Content) []string {
|
||||||
|
types := map[string]bool{}
|
||||||
|
for _, c := range contents {
|
||||||
|
for _, t := range c.MusenalmType() {
|
||||||
|
types[t] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := make([]string, 0, len(types))
|
||||||
|
for t, _ := range types {
|
||||||
|
ret = append(ret, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func HasScans(contents []*dbmodels.Content) bool {
|
||||||
|
for _, c := range contents {
|
||||||
|
if len(c.Scans()) > 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -66,21 +66,108 @@
|
|||||||
<div class="flex relative justify-center">
|
<div class="flex relative justify-center">
|
||||||
<div class="-translate-y-[50%] flex flex-col items-center">
|
<div class="-translate-y-[50%] flex flex-col items-center">
|
||||||
<h2 class="relative bg-stone-50 px-5 font-bold text-3xl w-max mb-1">Inhalt</h2>
|
<h2 class="relative bg-stone-50 px-5 font-bold text-3xl w-max mb-1">Inhalt</h2>
|
||||||
<div class="bg-stone-200 text-sm px-3 py-0.5 rounded mt-1">
|
<div class="flex flex-row justify-center">
|
||||||
<b>{{- len $model.result.Contents }}</b> erfasste Beiträge ·
|
<div class="bg-stone-200 text-sm px-3 py-0.5 rounded mt-1">
|
||||||
<i class="ri-sort-number-asc"></i> Anzeige nach Reihenfolge
|
{{- if $model.filters.Type -}}
|
||||||
|
{{- $i := len $model.result.Contents -}}
|
||||||
|
{{- if eq $i 1 -}}
|
||||||
|
<b>{{- $i }}</b> Beitrag der Kategorie <b>{{ $model.filters.Type }}</b> ·
|
||||||
|
{{- else -}}
|
||||||
|
<b>{{- $i }}</b> Beiträge der Kategorie <b>{{ $model.filters.Type }}</b> ·
|
||||||
|
{{- end -}}
|
||||||
|
{{- else if $model.filters.OnlyScans -}}
|
||||||
|
<i class="ri-image-line"></i>
|
||||||
|
{{- $i := len $model.result.Contents -}}
|
||||||
|
{{- if eq $i 1 -}}
|
||||||
|
<b>{{- $i }} Digitalisat · </b>
|
||||||
|
{{- else -}}
|
||||||
|
<b>{{- $i }} Digitalisate ·</b>
|
||||||
|
{{- end -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- if eq (len $model.result.Contents) 1 -}}
|
||||||
|
<b>{{- len $model.result.Contents }}</b> erfasster Beitrag ·
|
||||||
|
{{- else -}}
|
||||||
|
<b>{{- len $model.result.Contents }}</b> erfasste Beiträge ·
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
<i class="ri-sort-number-asc"></i> Anzeige nach Reihenfolge
|
||||||
|
</div>
|
||||||
|
{{- if or $model.filters.Type $model.filters.OnlyScans -}}
|
||||||
|
<div class="flex flex-row items-center justify-center ml-2.5">
|
||||||
|
<div class="block bg-stone-200 text-sm px-3 py-0.5 rounded mt-1">
|
||||||
|
<i class="ri-arrow-left-long-line"></i>
|
||||||
|
<a
|
||||||
|
href="./"
|
||||||
|
hx-target="#almanachcontents"
|
||||||
|
hx-select="#almanachcontents"
|
||||||
|
hx-swap="outerHTML show:none"
|
||||||
|
hx-indicator="body">
|
||||||
|
Alle Beiträge anzeigen
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center"></div>
|
<div>
|
||||||
<div class="mt-8">
|
<div class="flex flex-row justify-end">
|
||||||
{{- range $i, $c := $model.result.Contents -}}
|
{{- if gt (len $model.result.Types) 1 -}}
|
||||||
{{- $rels := index $model.result.ContentsAgents $c.Id -}}
|
<div>
|
||||||
{{- $coll := index $model.result.CInfoByContent $c.MusenalmID -}}
|
<label
|
||||||
{{- if and $coll (index $coll 0) -}}
|
for="typefilter"
|
||||||
|
class="align-baseline h-min self-end pb-1 mr-1.5 text-sm font-sans text-stone-700">
|
||||||
|
Kategorie
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
class="h-min pb-1 border-b-4 border-zinc-300 px-1.5 mr-8"
|
||||||
|
name="typefilter"
|
||||||
|
id="typefilter"
|
||||||
|
autocomplete="off"
|
||||||
|
hx-get="./"
|
||||||
|
trigger="change"
|
||||||
|
hx-indicator="body"
|
||||||
|
hx-select="#almanachcontents"
|
||||||
|
hx-target="#almanachcontents"
|
||||||
|
hx-swap="outerHTML show:none">
|
||||||
|
<option value="">Alle</option>
|
||||||
|
{{- range $i, $t := $model.result.Types -}}
|
||||||
|
<option value="{{- $t -}}" {{- if eq $model.filters.Type $t -}}selected{{- end -}}>
|
||||||
|
{{- $t -}}
|
||||||
|
</option>
|
||||||
|
{{- end -}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- template "_content" Arr $c $model.result.Entry $rels $model.result.Agents -}}
|
{{- if and $model.result.HasScans (gt (len $model.result.Contents) 1) -}}
|
||||||
{{- end -}}
|
<div>
|
||||||
|
<label
|
||||||
|
for="onlyscans"
|
||||||
|
class="align-baseline h-min self-end pb-1 mr-1.5 text-sm font-sans text-stone-700">
|
||||||
|
Nur Digitalisate anzeigen
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
class=""
|
||||||
|
type="checkbox"
|
||||||
|
id="onlyscans"
|
||||||
|
name="onlyscans"
|
||||||
|
autocomplete="off"
|
||||||
|
hx-get="./"
|
||||||
|
trigger="change"
|
||||||
|
hx-select="#almanachcontents"
|
||||||
|
hx-target="#almanachcontents"
|
||||||
|
hx-swap="outerHTML show:none"
|
||||||
|
hx-indicator="body"
|
||||||
|
{{ if $model.filters.OnlyScans -}}checked{{- end -}} />
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
<div class="mt-8">
|
||||||
|
{{- range $i, $c := $model.result.Contents -}}
|
||||||
|
{{- $rels := index $model.result.ContentsAgents $c.Id -}}
|
||||||
|
{{- template "_content" Arr $c $model.result.Entry $rels $model.result.Agents -}}
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{{ if and .result .result.Entry }}
|
{{ if and .result .result.Entry }}
|
||||||
<title>Musenalm – result.Entry.PreferredTitle</title>
|
<title>Musenalm – {{ .result.Entry.PreferredTitle -}}</title>
|
||||||
<meta name="description" content="Almanach: {{ .result.Entry.PreferredTitle }}" />
|
<meta name="description" content="Almanach: {{ .result.Entry.PreferredTitle }}" />
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<title>Musenalm – Almanach</title>
|
<title>Musenalm – Almanach</title>
|
||||||
|
|||||||
Reference in New Issue
Block a user