mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-29 09:15:33 +00:00
Filtering now works
This commit is contained in:
@@ -94,6 +94,7 @@ var CONTENTS_FTS5_FIELDS = []string{
|
|||||||
ENTRIES_TABLE,
|
ENTRIES_TABLE,
|
||||||
AGENTS_TABLE,
|
AGENTS_TABLE,
|
||||||
MUSENALMID_FIELD,
|
MUSENALMID_FIELD,
|
||||||
|
MUSENALM_INHALTE_TYPE_FIELD,
|
||||||
ANNOTATION_FIELD,
|
ANNOTATION_FIELD,
|
||||||
COMMENT_FIELD,
|
COMMENT_FIELD,
|
||||||
}
|
}
|
||||||
@@ -375,6 +376,11 @@ func FTS5ValuesContent(content *Content, entry *Entry, agents []*Agent) []string
|
|||||||
entrystring += "; [o.J.]"
|
entrystring += "; [o.J.]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typestring := ""
|
||||||
|
for _, typ := range content.MusenalmType() {
|
||||||
|
typestring += typ + " "
|
||||||
|
}
|
||||||
|
|
||||||
return []string{
|
return []string{
|
||||||
content.PreferredTitle(),
|
content.PreferredTitle(),
|
||||||
content.VariantTitle(),
|
content.VariantTitle(),
|
||||||
@@ -392,6 +398,7 @@ func FTS5ValuesContent(content *Content, entry *Entry, agents []*Agent) []string
|
|||||||
entrystring,
|
entrystring,
|
||||||
agentstring,
|
agentstring,
|
||||||
strconv.Itoa(content.MusenalmID()),
|
strconv.Itoa(content.MusenalmID()),
|
||||||
|
typestring,
|
||||||
datatypes.DeleteTags(content.Annotation()),
|
datatypes.DeleteTags(content.Annotation()),
|
||||||
datatypes.DeleteTags(content.Comment()),
|
datatypes.DeleteTags(content.Comment()),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ func Sort_Series_Title(series []*Series) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Sort_Agents_Name(agents []*Agent) {
|
||||||
|
collator := collate.New(language.German)
|
||||||
|
slices.SortFunc(agents, func(i, j *Agent) int {
|
||||||
|
return collator.CompareString(i.Name(), j.Name())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func Sort_Entries_Title_Year(entries []*Entry) {
|
func Sort_Entries_Title_Year(entries []*Entry) {
|
||||||
collator := collate.New(language.German)
|
collator := collate.New(language.German)
|
||||||
slices.SortFunc(entries, func(i, j *Entry) int {
|
slices.SortFunc(entries, func(i, j *Entry) int {
|
||||||
|
|||||||
@@ -76,12 +76,13 @@ func (p *SuchePage) SimpleSearchReihenRequest(app core.App, engine *templating.E
|
|||||||
|
|
||||||
func (p *SuchePage) SearchBeitraegeRequest(app core.App, engine *templating.Engine, e *core.RequestEvent, params SearchParameters) error {
|
func (p *SuchePage) SearchBeitraegeRequest(app core.App, engine *templating.Engine, e *core.RequestEvent, params SearchParameters) error {
|
||||||
data := make(map[string]interface{})
|
data := make(map[string]interface{})
|
||||||
|
filterparams := NewBeitraegeFilterParameters(e)
|
||||||
result, err := NewSearchBeitraege(app, params)
|
result, err := NewSearchBeitraege(app, params, filterparams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return engine.Response404(e, err, nil)
|
return engine.Response404(e, err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data["filters"] = filterparams
|
||||||
data["parameters"] = params
|
data["parameters"] = params
|
||||||
data["result"] = result
|
data["result"] = result
|
||||||
return engine.Response200(e, p.Template+params.Collection+"/", data, p.Layout)
|
return engine.Response200(e, p.Template+params.Collection+"/", data, p.Layout)
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package pages
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"maps"
|
||||||
|
"slices"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
|
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/helpers/datatypes"
|
"github.com/Theodor-Springmann-Stiftung/musenalm/helpers/datatypes"
|
||||||
@@ -10,8 +13,60 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
DEFAULT_PAGESIZE = 80
|
DEFAULT_PAGESIZE = 80
|
||||||
|
|
||||||
|
FILTER_PARAM_BEIAEGE_AGENT = "agentfilter"
|
||||||
|
FILTER_PARAM_BEIAEGE_TYPE = "typefilter"
|
||||||
|
FILTER_PARAM_BEIAEGE_ONLYSCANS = "onlyscans"
|
||||||
|
FILTER_PARAM_BEIAEGE_YEAR = "yearfilter"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type BeitraegeFilterParameters struct {
|
||||||
|
Agent string
|
||||||
|
Type string
|
||||||
|
Year string
|
||||||
|
OnlyScans bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBeitraegeFilterParameters(ev *core.RequestEvent) BeitraegeFilterParameters {
|
||||||
|
agent := ev.Request.URL.Query().Get(FILTER_PARAM_BEIAEGE_AGENT)
|
||||||
|
typ := ev.Request.URL.Query().Get(FILTER_PARAM_BEIAEGE_TYPE)
|
||||||
|
year := ev.Request.URL.Query().Get(FILTER_PARAM_BEIAEGE_YEAR)
|
||||||
|
onlyscans := ev.Request.URL.Query().Get(FILTER_PARAM_BEIAEGE_ONLYSCANS) == "on"
|
||||||
|
return BeitraegeFilterParameters{
|
||||||
|
Agent: agent,
|
||||||
|
Type: typ,
|
||||||
|
Year: year,
|
||||||
|
OnlyScans: onlyscans,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *BeitraegeFilterParameters) FieldSetBeitraege() []dbmodels.FTS5QueryRequest {
|
||||||
|
ret := []dbmodels.FTS5QueryRequest{}
|
||||||
|
|
||||||
|
if p.Agent != "" {
|
||||||
|
q := "\"" + p.Agent + "\""
|
||||||
|
que := dbmodels.NormalizeQuery(q)
|
||||||
|
req := dbmodels.IntoQueryRequests([]string{dbmodels.AGENTS_TABLE}, que)
|
||||||
|
ret = append(ret, req...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Type != "" {
|
||||||
|
q := "\"" + p.Type + "\""
|
||||||
|
que := dbmodels.NormalizeQuery(q)
|
||||||
|
req := dbmodels.IntoQueryRequests([]string{dbmodels.MUSENALM_INHALTE_TYPE_FIELD}, que)
|
||||||
|
ret = append(ret, req...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.Year != "" {
|
||||||
|
q := "\"" + p.Year + "\""
|
||||||
|
que := dbmodels.NormalizeQuery(q)
|
||||||
|
req := dbmodels.IntoQueryRequests([]string{dbmodels.ENTRIES_TABLE}, que)
|
||||||
|
ret = append(ret, req...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
type SearchResultBeitraege struct {
|
type SearchResultBeitraege struct {
|
||||||
Queries []dbmodels.FTS5QueryRequest
|
Queries []dbmodels.FTS5QueryRequest
|
||||||
|
|
||||||
@@ -23,6 +78,10 @@ type SearchResultBeitraege struct {
|
|||||||
|
|
||||||
ContentsAgents map[string][]*dbmodels.RContentsAgents // <- Key: Content ID
|
ContentsAgents map[string][]*dbmodels.RContentsAgents // <- Key: Content ID
|
||||||
Pages []int
|
Pages []int
|
||||||
|
|
||||||
|
AgentsList []*dbmodels.Agent
|
||||||
|
TypesList []string
|
||||||
|
YearList []int
|
||||||
}
|
}
|
||||||
|
|
||||||
func EmptyResultBeitraege() *SearchResultBeitraege {
|
func EmptyResultBeitraege() *SearchResultBeitraege {
|
||||||
@@ -35,9 +94,11 @@ func EmptyResultBeitraege() *SearchResultBeitraege {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSearchBeitraege(app core.App, params SearchParameters) (*SearchResultBeitraege, error) {
|
func NewSearchBeitraege(app core.App, params SearchParameters, filters BeitraegeFilterParameters) (*SearchResultBeitraege, error) {
|
||||||
contents := []*dbmodels.Content{}
|
contents := []*dbmodels.Content{}
|
||||||
queries := params.FieldSetBeitraege()
|
queries := params.FieldSetBeitraege()
|
||||||
|
fqueries := filters.FieldSetBeitraege()
|
||||||
|
queries = append(queries, fqueries...)
|
||||||
|
|
||||||
if params.AlmString != "" {
|
if params.AlmString != "" {
|
||||||
e, err := dbmodels.Contents_MusenalmID(app, params.AlmString)
|
e, err := dbmodels.Contents_MusenalmID(app, params.AlmString)
|
||||||
@@ -70,14 +131,33 @@ func NewSearchBeitraege(app core.App, params SearchParameters) (*SearchResultBei
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if filters.OnlyScans {
|
||||||
|
scans := []*dbmodels.Content{}
|
||||||
|
for _, c := range cs {
|
||||||
|
if len(c.Scans()) > 0 {
|
||||||
|
scans = append(scans, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cs = scans
|
||||||
|
}
|
||||||
|
|
||||||
contents = append(contents, cs...)
|
contents = append(contents, cs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
resultids := []any{}
|
resultids := []any{}
|
||||||
resultentryids := []string{}
|
uniqueresultentryids := map[string]bool{}
|
||||||
|
types := make(map[string]bool)
|
||||||
for _, content := range contents {
|
for _, content := range contents {
|
||||||
resultids = append(resultids, content.Id)
|
resultids = append(resultids, content.Id)
|
||||||
resultentryids = append(resultentryids, content.Entry())
|
uniqueresultentryids[content.Entry()] = true
|
||||||
|
for _, typ := range content.MusenalmType() {
|
||||||
|
types[typ] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resultentryids := []any{}
|
||||||
|
for entryid, _ := range uniqueresultentryids {
|
||||||
|
resultentryids = append(resultentryids, entryid)
|
||||||
}
|
}
|
||||||
|
|
||||||
entries, err := dbmodels.Entries_IDs(app, datatypes.ToAny(resultentryids))
|
entries, err := dbmodels.Entries_IDs(app, datatypes.ToAny(resultentryids))
|
||||||
@@ -96,9 +176,14 @@ func NewSearchBeitraege(app core.App, params SearchParameters) (*SearchResultBei
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
aids := []any{}
|
uniqueaids := map[string]bool{}
|
||||||
for _, a := range arels {
|
for _, a := range arels {
|
||||||
aids = append(aids, a.Agent())
|
uniqueaids[a.Agent()] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
aids := []any{}
|
||||||
|
for aid, _ := range uniqueaids {
|
||||||
|
aids = append(aids, aid)
|
||||||
}
|
}
|
||||||
|
|
||||||
agents, err := dbmodels.Agents_IDs(app, aids)
|
agents, err := dbmodels.Agents_IDs(app, aids)
|
||||||
@@ -111,6 +196,10 @@ func NewSearchBeitraege(app core.App, params SearchParameters) (*SearchResultBei
|
|||||||
contentsmap[c.Entry()] = append(contentsmap[c.Entry()], c)
|
contentsmap[c.Entry()] = append(contentsmap[c.Entry()], c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, c := range contentsmap {
|
||||||
|
dbmodels.Sort_Contents_Numbering(c)
|
||||||
|
}
|
||||||
|
|
||||||
contentsagents := make(map[string][]*dbmodels.RContentsAgents)
|
contentsagents := make(map[string][]*dbmodels.RContentsAgents)
|
||||||
for _, a := range arels {
|
for _, a := range arels {
|
||||||
contentsagents[a.Content()] = append(contentsagents[a.Content()], a)
|
contentsagents[a.Content()] = append(contentsagents[a.Content()], a)
|
||||||
@@ -122,8 +211,10 @@ func NewSearchBeitraege(app core.App, params SearchParameters) (*SearchResultBei
|
|||||||
}
|
}
|
||||||
|
|
||||||
entriesmap := make(map[string]*dbmodels.Entry)
|
entriesmap := make(map[string]*dbmodels.Entry)
|
||||||
|
years := make(map[int]bool)
|
||||||
for _, e := range entries {
|
for _, e := range entries {
|
||||||
entriesmap[e.Id] = e
|
entriesmap[e.Id] = e
|
||||||
|
years[e.Year()] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
hits := []string{}
|
hits := []string{}
|
||||||
@@ -142,6 +233,14 @@ func NewSearchBeitraege(app core.App, params SearchParameters) (*SearchResultBei
|
|||||||
hits = hits[pages[params.Page-1]:pages[params.Page]]
|
hits = hits[pages[params.Page-1]:pages[params.Page]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tL := slices.Collect(maps.Keys(types))
|
||||||
|
sort.Strings(tL)
|
||||||
|
|
||||||
|
yL := slices.Collect(maps.Keys(years))
|
||||||
|
sort.Ints(yL)
|
||||||
|
|
||||||
|
dbmodels.Sort_Agents_Name(agents)
|
||||||
|
|
||||||
return &SearchResultBeitraege{
|
return &SearchResultBeitraege{
|
||||||
Queries: queries,
|
Queries: queries,
|
||||||
Hits: hits,
|
Hits: hits,
|
||||||
@@ -150,6 +249,9 @@ func NewSearchBeitraege(app core.App, params SearchParameters) (*SearchResultBei
|
|||||||
Contents: contentsmap,
|
Contents: contentsmap,
|
||||||
ContentsAgents: contentsagents,
|
ContentsAgents: contentsagents,
|
||||||
Pages: pages,
|
Pages: pages,
|
||||||
|
AgentsList: agents,
|
||||||
|
TypesList: tL,
|
||||||
|
YearList: yL,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ const (
|
|||||||
BAENDE_PARAM_REFS = "references"
|
BAENDE_PARAM_REFS = "references"
|
||||||
BEITRAEGE_PARAM_ENTRY = "entry"
|
BEITRAEGE_PARAM_ENTRY = "entry"
|
||||||
BEITRAEGE_PARAM_INCIPT = "incipit"
|
BEITRAEGE_PARAM_INCIPT = "incipit"
|
||||||
|
BEITRAEGE_PARAM_TYPE = "type"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SearchParameters struct {
|
type SearchParameters struct {
|
||||||
@@ -48,6 +49,7 @@ type SearchParameters struct {
|
|||||||
YearString string
|
YearString string
|
||||||
EntryString string
|
EntryString string
|
||||||
IncipitString string
|
IncipitString string
|
||||||
|
TypeString string
|
||||||
|
|
||||||
Page int
|
Page int
|
||||||
}
|
}
|
||||||
@@ -61,7 +63,9 @@ func NewSearchParameters(e *core.RequestEvent, p Parameters) (*SearchParameters,
|
|||||||
annotations := e.Request.URL.Query().Get(SEARCH_PARAM_ANNOTATIONS) == "on"
|
annotations := e.Request.URL.Query().Get(SEARCH_PARAM_ANNOTATIONS) == "on"
|
||||||
annotationsstring := e.Request.URL.Query().Get(SEARCH_PARAM_ANNOTATIONS + "string")
|
annotationsstring := e.Request.URL.Query().Get(SEARCH_PARAM_ANNOTATIONS + "string")
|
||||||
year := e.Request.URL.Query().Get(SEARCH_PARAM_YEAR) == "on"
|
year := e.Request.URL.Query().Get(SEARCH_PARAM_YEAR) == "on"
|
||||||
|
|
||||||
yearstring := e.Request.URL.Query().Get(SEARCH_PARAM_YEAR + "string")
|
yearstring := e.Request.URL.Query().Get(SEARCH_PARAM_YEAR + "string")
|
||||||
|
typestring := e.Request.URL.Query().Get(BEITRAEGE_PARAM_TYPE)
|
||||||
|
|
||||||
series := e.Request.URL.Query().Get(BAENDE_PARAM_SERIES) == "on"
|
series := e.Request.URL.Query().Get(BAENDE_PARAM_SERIES) == "on"
|
||||||
seriesstring := e.Request.URL.Query().Get(BAENDE_PARAM_SERIES + "string")
|
seriesstring := e.Request.URL.Query().Get(BAENDE_PARAM_SERIES + "string")
|
||||||
@@ -125,6 +129,7 @@ func NewSearchParameters(e *core.RequestEvent, p Parameters) (*SearchParameters,
|
|||||||
YearString: yearstring,
|
YearString: yearstring,
|
||||||
EntryString: entrystring,
|
EntryString: entrystring,
|
||||||
IncipitString: incipitstring,
|
IncipitString: incipitstring,
|
||||||
|
TypeString: typestring,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +156,7 @@ func (p SearchParameters) AllSearchTermsBeitraege() string {
|
|||||||
res = append(res, p.includedParams(p.YearString)...)
|
res = append(res, p.includedParams(p.YearString)...)
|
||||||
res = append(res, p.includedParams(p.EntryString)...)
|
res = append(res, p.includedParams(p.EntryString)...)
|
||||||
res = append(res, p.includedParams(p.IncipitString)...)
|
res = append(res, p.includedParams(p.IncipitString)...)
|
||||||
|
res = append(res, p.includedParams(p.TypeString)...)
|
||||||
return strings.Join(res, " ")
|
return strings.Join(res, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,6 +205,7 @@ func (p SearchParameters) ToQueryParamsBeitraege() string {
|
|||||||
if p.Incipit {
|
if p.Incipit {
|
||||||
q += "&incipit=on"
|
q += "&incipit=on"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.YearString != "" {
|
if p.YearString != "" {
|
||||||
@@ -225,6 +232,10 @@ func (p SearchParameters) ToQueryParamsBeitraege() string {
|
|||||||
q += fmt.Sprintf("&incipitstring=%s", p.IncipitString)
|
q += fmt.Sprintf("&incipitstring=%s", p.IncipitString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.TypeString != "" {
|
||||||
|
q += fmt.Sprintf("&typestring=%s", p.TypeString)
|
||||||
|
}
|
||||||
|
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,6 +370,12 @@ func (p SearchParameters) FieldSetBeitraege() []dbmodels.FTS5QueryRequest {
|
|||||||
ret = append(ret, req...)
|
ret = append(ret, req...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.TypeString != "" {
|
||||||
|
que := dbmodels.NormalizeQuery(p.TypeString)
|
||||||
|
req := dbmodels.IntoQueryRequests([]string{dbmodels.MUSENALM_INHALTE_TYPE_FIELD}, que)
|
||||||
|
ret = append(ret, req...)
|
||||||
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,11 +61,8 @@ TODO danach:
|
|||||||
- Cache?
|
- Cache?
|
||||||
|
|
||||||
|
|
||||||
- HTMX + Smooth scroll
|
|
||||||
- Personen: related
|
- Personen: related
|
||||||
- Inhaltsliste: Personen sehen komisch aus
|
- Inhaltsliste: Personen sehen komisch aus
|
||||||
- V\Boosted links gen by webcomponents
|
|
||||||
- Sammlungen u. Querverweise müssen die URL als Parameter bekommen
|
|
||||||
- Sammlungen neuer versuch
|
- Sammlungen neuer versuch
|
||||||
- Inhaltsliste Personen
|
- Inhaltsliste Personen
|
||||||
- Sortierung nach Band A-Z?
|
- Sortierung nach Band A-Z?
|
||||||
|
|||||||
@@ -37,6 +37,14 @@
|
|||||||
EntryString string
|
EntryString string
|
||||||
IncipitString string
|
IncipitString string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filters
|
||||||
|
type BeitraegeFilterParameters struct {
|
||||||
|
Agent string
|
||||||
|
Type string
|
||||||
|
Year string
|
||||||
|
OnlyScans bool
|
||||||
|
}
|
||||||
*/}}
|
*/}}
|
||||||
|
|
||||||
{{ $isAlm := false }}
|
{{ $isAlm := false }}
|
||||||
@@ -76,33 +84,51 @@
|
|||||||
{{ template "_searchboxsimple" Arr $model.parameters true $q }}
|
{{ template "_searchboxsimple" Arr $model.parameters true $q }}
|
||||||
<fieldset class="selectgroup">
|
<fieldset class="selectgroup">
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="title" id="title"
|
<input
|
||||||
{{ if or $isBase $isTitle -}}checked{{- end -}} />
|
type="checkbox"
|
||||||
|
name="title"
|
||||||
|
id="title"
|
||||||
|
{{ if or $isBase $isTitle -}}checked{{- end -}} />
|
||||||
<label for="title">Titel</label>
|
<label for="title">Titel</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="incipit" id="incipit"
|
<input
|
||||||
{{ if or $isBase $isIncipit -}}checked{{- end -}} />
|
type="checkbox"
|
||||||
|
name="incipit"
|
||||||
|
id="incipit"
|
||||||
|
{{ if or $isBase $isIncipit -}}checked{{- end -}} />
|
||||||
<label for="incipit">Incipit</label>
|
<label for="incipit">Incipit</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="persons" id="persons"
|
<input
|
||||||
{{ if or $isBase $isPerson -}}checked{{- end -}} />
|
type="checkbox"
|
||||||
|
name="persons"
|
||||||
|
id="persons"
|
||||||
|
{{ if or $isBase $isPerson -}}checked{{- end -}} />
|
||||||
<label for="person">Personen & Pseudonyme</label>
|
<label for="person">Personen & Pseudonyme</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="entry" id="entry"
|
<input
|
||||||
{{ if or $isBase $isEntry -}}checked{{- end -}} />
|
type="checkbox"
|
||||||
|
name="entry"
|
||||||
|
id="entry"
|
||||||
|
{{ if or $isBase $isEntry -}}checked{{- end -}} />
|
||||||
<label for="entry">Bandtitel</label>
|
<label for="entry">Bandtitel</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="year" id="year"
|
<input
|
||||||
{{ if or $isBase $isYear -}}checked{{- end -}} />
|
type="checkbox"
|
||||||
|
name="year"
|
||||||
|
id="year"
|
||||||
|
{{ if or $isBase $isYear -}}checked{{- end -}} />
|
||||||
<label for="year">Jahr</label>
|
<label for="year">Jahr</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="annotations" id="annotations"
|
<input
|
||||||
{{ if or $isBase $isAnnotation -}}checked{{- end -}} />
|
type="checkbox"
|
||||||
|
name="annotations"
|
||||||
|
id="annotations"
|
||||||
|
{{ if or $isBase $isAnnotation -}}checked{{- end -}} />
|
||||||
<label for="annotations">Anmerkungen</label>
|
<label for="annotations">Anmerkungen</label>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -116,114 +142,37 @@
|
|||||||
|
|
||||||
{{- if $model.parameters.IsBeitraegeSearch -}}
|
{{- if $model.parameters.IsBeitraegeSearch -}}
|
||||||
<div class="container-normal" id="searchresults">
|
<div class="container-normal" id="searchresults">
|
||||||
<div class="border-b border-zinc-300 flex flex-row justify-between">
|
{{ template "_filterlist" $model }}
|
||||||
<div>
|
{{ template "tablehead" $model }}
|
||||||
{{ if $model.parameters.Query -}}
|
{{- if $model.result.Hits -}}
|
||||||
Suche nach <b>»{{ $model.parameters.Query }}«</b> ·
|
<div class="mt-8" id="almanachcontents">
|
||||||
{{- end -}}
|
{{- range $_, $hit := $model.result.Hits -}}
|
||||||
{{- if $isAlm -}}
|
{{- $e := index $model.result.Entries $hit -}}
|
||||||
Inhaltsnummer <b>»{{ $model.parameters.AlmString }}«</b> ·
|
{{- $contents := index $model.result.Contents $e.Id -}}
|
||||||
{{- end -}}
|
<div
|
||||||
<i class="ri-book-line"></i>
|
class="font-serif flex flex-row justify-between text-stone-800
|
||||||
{{ if eq $model.result.Count 1 -}}
|
font-bold border-b pb-0.5 mb-2 tab-list-head items-end">
|
||||||
Ein Beitrag
|
<div>
|
||||||
{{ else -}}
|
{{ $e.PreferredTitle }}
|
||||||
{{ $model.result.Count }} Beiträge
|
</div>
|
||||||
{{- end }}
|
<div
|
||||||
in
|
class="inline-block font-sans bg-slate-800 text-white h-max text-sm px-1.5 rounded">
|
||||||
{{ if eq ($model.result.Entries | len) 1 -}}
|
{{- len $contents -}}
|
||||||
einem Band
|
</div>
|
||||||
{{ else -}}
|
</div>
|
||||||
{{ $model.result.Entries | len }} Bänden
|
<div class="mb-7 tab-list-panel">
|
||||||
{{- end -}}
|
{{- range $i, $c := $contents -}}
|
||||||
</div>
|
{{- $rels := index $model.result.ContentsAgents $c.Id -}}
|
||||||
{{- if gt (len $model.result.Pages) 1 }}
|
{{- template "_content" Arr $c $e $rels $model.result.Agents false true
|
||||||
<div>
|
$model.parameters
|
||||||
{{ if gt $model.parameters.Page 1 -}}
|
-}}
|
||||||
<a
|
{{- end -}}
|
||||||
href="{{- $model.parameters.ToQueryParamsBeitraege -}}&page={{ $model.parameters.Prev
|
</div>
|
||||||
}}" class="mr-1.5">
|
|
||||||
<i class="ri-arrow-left-long-line"></i>
|
|
||||||
</a>
|
|
||||||
{{- end -}}
|
{{- 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>
|
</div>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
</div>
|
</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">
|
<script type="module">
|
||||||
let elements = document.querySelectorAll('.search-text');
|
let elements = document.querySelectorAll('.search-text');
|
||||||
let mark_instance = new Mark(elements);
|
let mark_instance = new Mark(elements);
|
||||||
@@ -235,5 +184,4 @@
|
|||||||
}, 200);
|
}, 200);
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|||||||
119
views/routes/suche/beitraege/tablehead.gohtml
Normal file
119
views/routes/suche/beitraege/tablehead.gohtml
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
{{ $model := . }}
|
||||||
|
|
||||||
|
{{ $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 class="border-b border-zinc-300 flex flex-row justify-between">
|
||||||
|
<div class="flex flex-row gap-x-2">
|
||||||
|
{{ if $model.parameters.Query -}}
|
||||||
|
<div>Suche nach <b>»{{ $model.parameters.Query }}«</b></div>
|
||||||
|
<div>·</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $isAlm -}}
|
||||||
|
<div>Inhaltsnummer <b>»{{ $model.parameters.AlmString }}«</b></div>
|
||||||
|
<div>·</div>
|
||||||
|
{{- end -}}
|
||||||
|
<div>
|
||||||
|
<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>·</div>
|
||||||
|
<div class="[&>_a]:no-underline">
|
||||||
|
{{ 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 -}}
|
||||||
|
Seite {{ $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 -}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{- if not $isAlm -}}
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
for="onlyscans"
|
||||||
|
class="align-baseline h-min self-end pb-1 mr-1 text-sm font-sans text-stone-700">
|
||||||
|
Nur Digitalisate
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
class="mr-4"
|
||||||
|
type="checkbox"
|
||||||
|
id="onlyscans"
|
||||||
|
name="onlyscans"
|
||||||
|
autocomplete="off"
|
||||||
|
hx-get="{{- $model.parameters.ToQueryParamsBeitraege -}}"
|
||||||
|
trigger="change"
|
||||||
|
hx-push-url="true"
|
||||||
|
hx-select="main"
|
||||||
|
hx-target="main"
|
||||||
|
{{ if $model.filters.OnlyScans -}}checked{{- end -}} />
|
||||||
|
|
||||||
|
<label
|
||||||
|
for="sort"
|
||||||
|
class="align-baseline h-min self-end pb-1 mr-2 text-sm font-sans
|
||||||
|
text-stone-700"
|
||||||
|
>Sortierung</label
|
||||||
|
>
|
||||||
|
|
||||||
|
<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>
|
||||||
75
views/routes/suche/components/_filterlist.gohtml
Normal file
75
views/routes/suche/components/_filterlist.gohtml
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
{{ $model := . }}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="flex flex-row gap-x-6 mb-4">
|
||||||
|
<filter-list
|
||||||
|
id="agent-list"
|
||||||
|
data-queryparam="personsstring"
|
||||||
|
data-url="{{ $model.parameters.ToQueryParamsBeitraege }}&agentfilter="
|
||||||
|
data-placeholder="Personen und Körperschaften filtern..."></filter-list>
|
||||||
|
|
||||||
|
<filter-list
|
||||||
|
id="year-list"
|
||||||
|
data-queryparam="yearstring"
|
||||||
|
data-url="{{ $model.parameters.ToQueryParamsBeitraege }}&yearfilter="
|
||||||
|
data-placeholder="Jahre filtern..."></filter-list>
|
||||||
|
|
||||||
|
<filter-list
|
||||||
|
id="types-list"
|
||||||
|
data-queryparam="type"
|
||||||
|
data-url="{{ $model.parameters.ToQueryParamsBeitraege }}&typefilter="
|
||||||
|
data-placeholder="Betragskategorien filtern..."></filter-list>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
let agentList = document.getElementById("agent-list");
|
||||||
|
if (agentList) {
|
||||||
|
agentList.items = {{ $model.result.AgentsList }};
|
||||||
|
|
||||||
|
agentList.setSearchTextFunc((item) => {
|
||||||
|
return item.name;
|
||||||
|
});
|
||||||
|
|
||||||
|
agentList.setHREFFunc((item) => {
|
||||||
|
return item.name;
|
||||||
|
});
|
||||||
|
|
||||||
|
agentList.setLinkTextFunc((item) => {
|
||||||
|
return `
|
||||||
|
<span class="filter-list-searchable">${item.name}</span>
|
||||||
|
<span class="text-xs text-stone-500 whitespace-nowrap font-sans">
|
||||||
|
${item.corporate_body ? "Verlag/Druck/Vertrieb" : item.biographical_data}
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let yearList = document.getElementById("year-list");
|
||||||
|
if (yearList) {
|
||||||
|
yearList.items = {{ $model.result.YearList }};
|
||||||
|
|
||||||
|
yearList.setHREFFunc((item) => {
|
||||||
|
return String(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
yearList.setLinkTextFunc((item) => {
|
||||||
|
if (item === 0) return "ohne Jahr";
|
||||||
|
return String(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let typesList = document.getElementById("types-list");
|
||||||
|
if (typesList) {
|
||||||
|
typesList.items = {{ $model.result.TypesList }};
|
||||||
|
|
||||||
|
typesList.setHREFFunc((item) => {
|
||||||
|
return String(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
typesList.setLinkTextFunc((item) => {
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -146,6 +146,10 @@ class FilterList extends HTMLElement {
|
|||||||
this.addEventListener("keydown", this.onEnter.bind(this));
|
this.addEventListener("keydown", this.onEnter.bind(this));
|
||||||
this.addEventListener("focusin", this.onGainFocus.bind(this));
|
this.addEventListener("focusin", this.onGainFocus.bind(this));
|
||||||
this.addEventListener("focusout", this.onLoseFocus.bind(this));
|
this.addEventListener("focusout", this.onLoseFocus.bind(this));
|
||||||
|
|
||||||
|
if (htmx) {
|
||||||
|
htmx.process(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback(name, oldValue, newValue) {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
@@ -253,6 +257,10 @@ class FilterList extends HTMLElement {
|
|||||||
return item.id;
|
return item.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getHREFEncoded(item) {
|
||||||
|
return encodeURIComponent(this.getHREF(item));
|
||||||
|
}
|
||||||
|
|
||||||
getSearchText(item) {
|
getSearchText(item) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return "";
|
return "";
|
||||||
@@ -351,7 +359,7 @@ class FilterList extends HTMLElement {
|
|||||||
.map(
|
.map(
|
||||||
(item, index) => `
|
(item, index) => `
|
||||||
<a
|
<a
|
||||||
href="${this._url}${this.getHREF(item)}"
|
href="${this._url}${this.getHREFEncoded(item)}"
|
||||||
class="${FILTER_LIST_ITEM} block px-2.5 py-0.5 hover:bg-slate-200 no-underline ${
|
class="${FILTER_LIST_ITEM} block px-2.5 py-0.5 hover:bg-slate-200 no-underline ${
|
||||||
index % 2 === 0 ? "bg-stone-100" : "bg-stone-50"
|
index % 2 === 0 ? "bg-stone-100" : "bg-stone-50"
|
||||||
}"
|
}"
|
||||||
|
|||||||
Reference in New Issue
Block a user