Allerhand Kleinigkeiten; Einzelansichten Reihen u Personen; Bandansicht

This commit is contained in:
Simon Martens
2025-02-25 02:39:29 +01:00
parent 6b5fa3dbc3
commit 24f1e4fd55
33 changed files with 843 additions and 154 deletions

View File

@@ -23,6 +23,37 @@ func AgentForId(app core.App, id string) (*Agent, error) {
return agent, nil return agent, nil
} }
func FTS5SearchAgents(app core.App, query string) ([]*Agent, error) {
a := []*Agent{}
q := NormalizeQuery(query)
if len(q) == 0 {
return a, nil
}
ids, err := FTS5Search(app, AGENTS_TABLE, FTS5QueryRequest{
Fields: []string{AGENTS_NAME_FIELD, AGENTS_PSEUDONYMS_FIELD, REFERENCES_FIELD, AGENTS_BIOGRAPHICAL_DATA_FIELD, ANNOTATION_FIELD},
Query: q,
})
if err != nil {
return nil, err
}
idany := []any{}
for _, id := range ids {
idany = append(idany, id.ID)
}
err = app.RecordQuery(AGENTS_TABLE).
Where(dbx.HashExp{ID_FIELD: idany}).
All(&a)
if err != nil {
return nil, err
}
return a, nil
}
func AgentsForEntries(app core.App, entries []*Entry) (map[string]*Agent, AgentsEntries, error) { func AgentsForEntries(app core.App, entries []*Entry) (map[string]*Agent, AgentsEntries, error) {
eids := []any{} eids := []any{}
for _, e := range entries { for _, e := range entries {

View File

@@ -103,6 +103,17 @@ func EntryForId(app core.App, id string) (*Entry, error) {
return entry, nil return entry, nil
} }
func EntriesForIds(app core.App, ids []any) ([]*Entry, error) {
entries := []*Entry{}
err := app.RecordQuery(ENTRIES_TABLE).
Where(dbx.HashExp{ID_FIELD: ids}).
All(&entries)
if err != nil {
return nil, err
}
return entries, nil
}
func EntryForMusenalmID(app core.App, id string) (*Entry, error) { func EntryForMusenalmID(app core.App, id string) (*Entry, error) {
entry := &Entry{} entry := &Entry{}
err := app.RecordQuery(ENTRIES_TABLE). err := app.RecordQuery(ENTRIES_TABLE).

View File

@@ -31,6 +31,7 @@ var AGENTS_FTS5_FIELDS = []string{
AGENTS_PSEUDONYMS_FIELD, AGENTS_PSEUDONYMS_FIELD,
ANNOTATION_FIELD, ANNOTATION_FIELD,
COMMENT_FIELD, COMMENT_FIELD,
REFERENCES_FIELD,
} }
var PLACES_FTS5_FIELDS = []string{ var PLACES_FTS5_FIELDS = []string{
@@ -384,6 +385,7 @@ func FTS5ValuesAgent(agent *Agent) []string {
agent.Pseudonyms(), agent.Pseudonyms(),
datatypes.DeleteTags(agent.Annotation()), datatypes.DeleteTags(agent.Annotation()),
datatypes.DeleteTags(agent.Comment()), datatypes.DeleteTags(agent.Comment()),
agent.References(),
} }
} }

57
dbmodels/queries.go Normal file
View File

@@ -0,0 +1,57 @@
package dbmodels
import (
"github.com/pocketbase/pocketbase/core"
)
// INFO: Queries to be reused
// Rules
// 1. Only one return type + error for every function
// 2. Parameters can only be two
// - core.App
// - any id or multiple IDs (of an indexed field)
// 3. Naming convention: <TableName>_<FilteredField>[s]
// For scanning, with an Iter_ prefix, yields single row results
func REntriesAgents_Agent(app core.App, id string) ([]*REntriesAgents, error) {
return TableByField[[]*REntriesAgents](
app,
RelationTableName(ENTRIES_TABLE, AGENTS_TABLE),
AGENTS_TABLE,
id,
)
}
func RContentsAgents_Agent(app core.App, id string) ([]*RContentsAgents, error) {
return TableByField[[]*RContentsAgents](
app,
RelationTableName(CONTENTS_TABLE, AGENTS_TABLE),
AGENTS_TABLE,
id,
)
}
func REntriesSeries_Entries(app core.App, ids any) ([]*REntriesSeries, error) {
return TableByField[[]*REntriesSeries](
app,
RelationTableName(ENTRIES_TABLE, SERIES_TABLE),
ENTRIES_TABLE,
ids,
)
}
func Agents_ID(app core.App, id string) (*Agent, error) {
return TableByID[*Agent](app, AGENTS_TABLE, id)
}
func Entries_IDs(app core.App, ids []any) ([]*Entry, error) {
return TableByID[[]*Entry](app, ENTRIES_TABLE, ids)
}
func Series_IDs(app core.App, ids []any) ([]*Series, error) {
return TableByID[[]*Series](app, SERIES_TABLE, ids)
}
func Contents_IDs(app core.App, ids []any) ([]*Content, error) {
return TableByID[[]*Content](app, CONTENTS_TABLE, ids)
}

37
dbmodels/queries_iter.go Normal file
View File

@@ -0,0 +1,37 @@
package dbmodels
import (
"iter"
"github.com/pocketbase/pocketbase/core"
)
// INFO: Iterator queries to be reused
// Rules
// 1. Only iterator return type + error for every function
// 2. Parameters can only be two
// - core.App
// - any id or multiple IDs (of an indexed field)
// 3. Naming convention: Iter_<TableName>_<FilteredField>[s]
// BUG: this is not working as expected, see Iter_TableByField in queryhelpers.go
func Iter_REntriesAgents_Agent(app core.App, id string) (iter.Seq2[*REntriesAgents, error], error) {
innerIterator, err := Iter_TableByField[REntriesAgents](
app,
RelationTableName(ENTRIES_TABLE, AGENTS_TABLE),
AGENTS_TABLE,
id,
)
if err != nil {
return nil, err
}
return func(yield func(*REntriesAgents, error) bool) {
for item, err := range innerIterator {
if !yield(item, err) {
return
}
}
}, nil
}

99
dbmodels/queryhelpers.go Normal file
View File

@@ -0,0 +1,99 @@
package dbmodels
import (
"iter"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/core"
)
// INFO: These functions are very abstract interfaces to the DB that help w querying
// BUG: this is not working:
// github.com/pocketbase/pocketbase/apis.NewRouter.panicRecover.func3.1()
// /home/simon/go/pkg/mod/github.com/pocketbase/pocketbase@v0.25.5/apis/middlewares.go:269 +0x13c
// panic({0x15b34c0?, 0x2831680?})
// /usr/local/go/src/runtime/panic.go:787 +0x132
// github.com/pocketbase/pocketbase/core.(*Record).FieldsData(0xc000632820)
// /home/simon/go/pkg/mod/github.com/pocketbase/pocketbase@v0.25.5/core/record_model.go:774 +0x1a
// github.com/pocketbase/pocketbase/core.(*Record).PostScan(0xc000632820)
// /home/simon/go/pkg/mod/github.com/pocketbase/pocketbase@v0.25.5/core/record_model.go:591 +0x4e
// github.com/pocketbase/dbx.(*Rows).ScanStruct(0xc00052e6d0, {0x175f840?, 0xc000586060?})
// /home/simon/go/pkg/mod/github.com/pocketbase/dbx@v1.11.0/rows.go:97 +0x32e
// github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels.Iter_TableByField[...].func1()
// /home/simon/source/musenalm/dbmodels/queryhelpers.go:23 +0x65
// github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels.Iter_REntriesAgents_Agent.func1(0xc000624840)
// /home/simon/source/musenalm/dbmodels/queries_iter.go:30 +0xae
// github.com/Theodor-Springmann-Stiftung/musenalm/pages.(*PersonResult).FilterEntriesByPerson(0x1762c40?, {0x1dfba88, 0xc000438870}, {0xc00004627c, 0xf}, 0xc000064720)
// /home/simon/source/musenalm/pages/person.go:111 +0x248
// github.com/Theodor-Springmann-Stiftung/musenalm/pages.NewPersonResult({0x1dfba88, 0xc000438870}, {0xc00004627c, 0xf})
// /home/simon/source/musenalm/pages/person.go:92 +0x4f
// github.com/Theodor-Springmann-Stiftung/musenalm/pages.(*PersonPage).Setup.func1(0xc0002da000)
// /home/simon/source/musenalm/pages/person.go:46 +0x1ee
// github.com/pocketbase/pocketbase/tools/hook.(*Hook[...]).Trigger.func1()
// /home/simon/go/pkg/mod/github.com/pocketbase/pocketbase@v0.25.5/tools/hook/hook.go:169 +0x5d
// github.com/pocketbase/pocketbase/tools/hook.(*Event).Next(0xc0002da000?)
// /home/simon/go/pkg/mod/github.com/pocketbase/pocketbase@v0.25.5/tools/hook/event.go:32 +0x17
// github.com/pocketbase/pocketbase/apis.NewRouter.BodyLimit.func7(0xc0002da000)
// /home
func Iter_TableByField[T interface{}](app core.App, table, field string, value interface{}) (iter.Seq2[*T, error], error) {
rows, err := app.RecordQuery(table).
Where(dbx.HashExp{field: value}).
Rows()
if err != nil {
return nil, err
}
return func(yield func(*T, error) bool) {
for rows.Next() {
var item T
err := rows.ScanStruct(&item)
if !yield(&item, err) {
return
}
}
}, nil
}
func Iter_TableByID[T interface{}](app core.App, table, id interface{}) (iter.Seq2[*T, error], error) {
rows, err := app.RecordQuery(table).
Where(dbx.HashExp{ID_FIELD: id}).
Rows()
if err != nil {
return nil, err
}
return func(yield func(*T, error) bool) {
for rows.Next() {
var item T
rows.Scan(&item)
if !yield(&item, nil) {
return
}
}
}, nil
}
func TableByField[T interface{}](app core.App, table, field string, value interface{}) (T, error) {
var ret T
err := app.RecordQuery(table).
Where(dbx.HashExp{field: value}).
All(&ret)
if err != nil {
return ret, err
}
return ret, nil
}
func TableByID[T interface{}](app core.App, table, id interface{}) (T, error) {
var ret T
err := app.RecordQuery(table).
Where(dbx.HashExp{ID_FIELD: id}).
All(&ret)
if err != nil {
return ret, err
}
return ret, nil
}

View File

@@ -8,19 +8,11 @@ import (
"github.com/pocketbase/dbx" "github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/core"
"golang.org/x/text/cases" "golang.org/x/text/cases"
"golang.org/x/text/collate"
"golang.org/x/text/language" "golang.org/x/text/language"
) )
type SeriesEntries map[string][]*REntriesSeries type SeriesEntries map[string][]*REntriesSeries
func SortSeriessesByTitle(series []*Series) {
collator := collate.New(language.German)
slices.SortFunc(series, func(i, j *Series) int {
return collator.CompareString(i.Title(), j.Title())
})
}
func MusenalmIDSearchSeries(app core.App, query string) ([]*Series, error) { func MusenalmIDSearchSeries(app core.App, query string) ([]*Series, error) {
series := []*Series{} series := []*Series{}
err := app.RecordQuery(SERIES_TABLE). err := app.RecordQuery(SERIES_TABLE).

43
dbmodels/sorting.go Normal file
View File

@@ -0,0 +1,43 @@
package dbmodels
import (
"slices"
"golang.org/x/text/collate"
"golang.org/x/text/language"
)
func Sort_Series_Title(series []*Series) {
collator := collate.New(language.German)
slices.SortFunc(series, func(i, j *Series) int {
return collator.CompareString(i.Title(), j.Title())
})
}
func Sort_Entries_Title_Year(entries []*Entry) {
collator := collate.New(language.German)
slices.SortFunc(entries, func(i, j *Entry) int {
if i.PreferredTitle() == j.PreferredTitle() {
return i.Year() - j.Year()
}
return collator.CompareString(i.PreferredTitle(), j.PreferredTitle())
})
}
func Sort_Entries_Year_Title(entries []*Entry) {
collator := collate.New(language.German)
slices.SortFunc(entries, func(i, j *Entry) int {
if i.Year() == j.Year() {
return collator.CompareString(i.PreferredTitle(), j.PreferredTitle())
}
return i.Year() - j.Year()
})
}
func Sort_REntriesSeries_Year(entries []*REntriesSeries, entriesMap map[string]*Entry) {
slices.SortFunc(entries, func(i, j *REntriesSeries) int {
ientry := entriesMap[i.Entry()]
jentry := entriesMap[j.Entry()]
return ientry.Year() - jentry.Year()
})
}

View File

@@ -1 +1,9 @@
package datatypes package datatypes
func ToAny[T any](s []T) []any {
result := make([]any, len(s))
for i, v := range s {
result[i] = v
}
return result
}

View File

@@ -4,6 +4,10 @@ func Length(arr []any) int {
return len(arr) return len(arr)
} }
func MapLen[T comparable, U any](m map[T]U) int {
return len(m)
}
func Contains(arr []string, val string) bool { func Contains(arr []string, val string) bool {
for _, v := range arr { for _, v := range arr {
if v == val { if v == val {

View File

@@ -1,6 +1,9 @@
package functions package functions
import "html/template" import (
"html/template"
"strings"
)
func Safe(s string) template.HTML { func Safe(s string) template.HTML {
if len(s) == 0 { if len(s) == 0 {
@@ -8,3 +11,7 @@ func Safe(s string) template.HTML {
} }
return template.HTML(s) return template.HTML(s)
} }
func ReplaceSlashParen(s string) string {
return strings.ReplaceAll(s, "/)", "<p>")
}

View File

@@ -1,6 +1,8 @@
package pages package pages
import ( import (
"database/sql"
"github.com/Theodor-Springmann-Stiftung/musenalm/app" "github.com/Theodor-Springmann-Stiftung/musenalm/app"
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels" "github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
"github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels" "github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels"
@@ -36,45 +38,164 @@ func (p *PersonPage) Setup(router *router.Router[*core.RequestEvent], app core.A
data := make(map[string]interface{}) data := make(map[string]interface{})
data[PARAM_PERSON] = person data[PARAM_PERSON] = person
agent, err := dbmodels.AgentForId(app, person) result, err := NewAgentResult(app, person)
if err != nil { if err != nil {
return engine.Response404(e, err, data) return engine.Response404(e, err, data)
} }
data["a"] = agent data["result"] = result
series, relations, entries, err := dbmodels.SeriesForAgent(app, person)
if err != nil {
return engine.Response404(e, err, data)
}
dbmodels.SortSeriessesByTitle(series)
data["series"] = series
data["relations"] = relations
data["entries"] = entries
contents, err := dbmodels.ContentsForAgent(app, person)
if err != nil {
return engine.Response404(e, err, data)
}
agents, crelations, err := dbmodels.AgentsForContents(app, contents)
if err != nil {
return engine.Response404(e, err, data)
}
data["agents"] = agents
data["crelations"] = crelations
centries, err := dbmodels.EntriesForContents(app, contents)
if err != nil {
return engine.Response404(e, err, data)
}
data["centries"] = centries
dbmodels.SortContentsByEntryNumbering(contents, centries)
data["contents"] = contents
return engine.Response200(e, p.Template, data, p.Layout) return engine.Response200(e, p.Template, data, p.Layout)
}) })
return nil return nil
} }
type AgentResult struct {
Agent *dbmodels.Agent
BResult []*dbmodels.Series // Sorted
Entries map[string]*dbmodels.Entry // KEY: Entry ID
EntriesSeries map[string][]*dbmodels.REntriesSeries // KEY: Series ID
EntriesAgents map[string][]*dbmodels.REntriesAgents // KEY: Entry ID
// INFO: we could save a DB query by quering the entries table only once
CResult []*dbmodels.Entry /// Sorted
Contents map[string][]*dbmodels.Content // KEY: entry ID
ContentsAgents map[string][]*dbmodels.RContentsAgents // KEY: Content ID
}
func NewAgentResult(app core.App, id string) (*AgentResult, error) {
agent, err := dbmodels.AgentForId(app, id)
if err != nil {
return nil, err
}
res := &AgentResult{
Agent: agent,
}
err = res.FilterEntriesByPerson(app, id, res)
if err != nil {
return nil, err
}
return res, nil
}
func (p *AgentResult) FilterEntriesByPerson(app core.App, id string, res *AgentResult) error {
// 1. DB Hit
relations, err := dbmodels.REntriesAgents_Agent(app, id)
if err != nil && err != sql.ErrNoRows {
return err
}
if len(relations) == 0 {
return nil
}
entriesagents := make(map[string][]*dbmodels.REntriesAgents)
entryIds := []any{}
for _, r := range relations {
entryIds = append(entryIds, r.Entry())
entriesagents[r.Entry()] = append(entriesagents[r.Entry()], r)
}
res.EntriesAgents = entriesagents
// 2. DB Hit
entries, err := dbmodels.Entries_IDs(app, entryIds)
if err != nil {
return err
}
entryMap := make(map[string]*dbmodels.Entry, len(entries))
for _, e := range entries {
entryMap[e.Id] = e
}
res.Entries = entryMap
// 3. DB Hit
entriesseries, err := dbmodels.REntriesSeries_Entries(app, entryIds)
if err != nil {
return err
}
entriesseriesmap := make(map[string][]*dbmodels.REntriesSeries, len(entriesseries))
for _, r := range entriesseries {
entriesseriesmap[r.Series()] = append(entriesseriesmap[r.Series()], r)
}
for _, r := range entriesseriesmap {
dbmodels.Sort_REntriesSeries_Year(r, entryMap)
}
res.EntriesSeries = entriesseriesmap
seriesIds := []any{}
for _, s := range entriesseries {
seriesIds = append(seriesIds, s.Series())
}
// 4. DB Hit
series, err := dbmodels.Series_IDs(app, seriesIds)
if err != nil {
return err
}
res.BResult = series
return nil
}
func (p *AgentResult) FilterContentsByEntry(app core.App, id string, res *AgentResult) error {
// 1. DB Hit
relations, err := dbmodels.RContentsAgents_Agent(app, id)
if err != nil && err != sql.ErrNoRows {
return err
}
if len(relations) == 0 {
return nil
}
contentsagents := make(map[string][]*dbmodels.RContentsAgents)
contentIds := []any{}
for _, r := range relations {
contentIds = append(contentIds, r.Content())
contentsagents[r.Content()] = append(contentsagents[r.Content()], r)
}
res.ContentsAgents = contentsagents
// 2. DB Hit
contents, err := dbmodels.Contents_IDs(app, contentIds)
if err != nil {
return err
}
contentMap := make(map[string][]*dbmodels.Content, len(contents))
entrykeys := []any{}
for _, c := range contents {
contentMap[c.Entry()] = append(contentMap[c.Entry()], c)
entrykeys = append(entrykeys, c.Entry())
}
res.Contents = contentMap
// 3. DB Hit
entries, err := dbmodels.Entries_IDs(app, entrykeys)
if err != nil {
return err
}
res.CResult = entries
return nil
}
func (p *AgentResult) LenEntries() int {
return len(p.Entries)
}
func (p *AgentResult) LenSeries() int {
return len(p.BResult)
}
func (p *AgentResult) LenContents() int {
return len(p.Contents)
}

View File

@@ -104,11 +104,26 @@ func (p *PersonenPage) FilterRequest(app core.App, engine *templating.Engine, e
func (p *PersonenPage) SearchRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error { func (p *PersonenPage) SearchRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error {
search := e.Request.URL.Query().Get(PARAM_SEARCH) search := e.Request.URL.Query().Get(PARAM_SEARCH)
data := map[string]interface{}{} data := map[string]interface{}{}
agents := []*dbmodels.Agent{}
altagents := []*dbmodels.Agent{}
agents, altagents, err := dbmodels.BasicSearchAgents(app, search) a, err := dbmodels.FTS5SearchAgents(app, search)
if err != nil { if err != nil {
return engine.Response404(e, err, data) return engine.Response404(e, err, data)
} }
agents = a
if len(agents) == 0 {
// INFO: Fallback to regular search, if FTS5 fails
a, aa, err := dbmodels.BasicSearchAgents(app, search)
if err != nil {
return engine.Response404(e, err, data)
}
agents = a
altagents = aa
} else {
data["FTS"] = true
}
dbmodels.SortAgentsByName(agents) dbmodels.SortAgentsByName(agents)
dbmodels.SortAgentsByName(altagents) dbmodels.SortAgentsByName(altagents)

View File

@@ -100,7 +100,7 @@ func (p *ReihenPage) LetterRequest(app core.App, engine *templating.Engine, e *c
return engine.Response404(e, err, data) return engine.Response404(e, err, data)
} }
// INFO: We sort again since the query can't sort german umlauts correctly // INFO: We sort again since the query can't sort german umlauts correctly
dbmodels.SortSeriessesByTitle(series) dbmodels.Sort_Series_Title(series)
data["series"] = series data["series"] = series
rmap, bmap, err := dbmodels.EntriesForSeriesses(app, series) rmap, bmap, err := dbmodels.EntriesForSeriesses(app, series)
@@ -129,7 +129,7 @@ func (p *ReihenPage) PersonRequest(app core.App, engine *templating.Engine, e *c
if err != nil { if err != nil {
return engine.Response404(e, err, data) return engine.Response404(e, err, data)
} }
dbmodels.SortSeriessesByTitle(series) dbmodels.Sort_Series_Title(series)
data["series"] = series data["series"] = series
data["relations"] = relations data["relations"] = relations
data["entries"] = entries data["entries"] = entries
@@ -172,8 +172,8 @@ func (p *ReihenPage) SearchRequest(app core.App, engine *templating.Engine, e *c
if err != nil { if err != nil {
return engine.Response404(e, err, data) return engine.Response404(e, err, data)
} }
dbmodels.SortSeriessesByTitle(series) dbmodels.Sort_Series_Title(series)
dbmodels.SortSeriessesByTitle(altseries) dbmodels.Sort_Series_Title(altseries)
data["series"] = series data["series"] = series
data["altseries"] = altseries data["altseries"] = altseries
@@ -208,7 +208,7 @@ func (p *ReihenPage) SearchRequest(app core.App, engine *templating.Engine, e *c
return engine.Response404(e, err, data) return engine.Response404(e, err, data)
} }
dbmodels.SortSeriessesByTitle(idseries) dbmodels.Sort_Series_Title(idseries)
data["idseries"] = idseries data["idseries"] = idseries
if err != nil { if err != nil {

View File

@@ -141,7 +141,7 @@ func (p *SuchePage) SimpleSearchReihenRequest(app core.App, engine *templating.E
return engine.Response500(e, err, nil) return engine.Response500(e, err, nil)
} }
dbmodels.SortSeriessesByTitle(series) dbmodels.Sort_Series_Title(series)
data["series"] = series data["series"] = series
data["relations"] = rmap data["relations"] = rmap
data["entries"] = bmap data["entries"] = bmap

View File

@@ -58,6 +58,10 @@ func (e *Engine) funcs() error {
e.AddFunc("HasPrefix", strings.HasPrefix) e.AddFunc("HasPrefix", strings.HasPrefix)
e.AddFunc("Contains", functions.Contains) e.AddFunc("Contains", functions.Contains)
e.AddFunc("Add", functions.Add) e.AddFunc("Add", functions.Add)
e.AddFunc("Len", functions.Length)
// String Functions
e.AddFunc("ReplaceSlashParen", functions.ReplaceSlashParen)
// Time & Date Functions // Time & Date Functions
e.AddFunc("Today", functions.Today) e.AddFunc("Today", functions.Today)

File diff suppressed because one or more lines are too long

View File

@@ -33,7 +33,7 @@
<body class="w-full text-lg" hx-ext="response-targets" hx-boost="true"> <body class="w-full text-lg" hx-ext="response-targets" hx-boost="true">
<div class="flex flex-col min-h-screen w-full"> <div class="flex flex-col min-h-screen w-full">
<header class="container-normal" id="header"> <header class="container-normal pb-0" id="header">
{{ block "_menu" . }} {{ block "_menu" . }}
<!-- Default app menu... --> <!-- Default app menu... -->
{{ end }} {{ end }}

View File

@@ -4,7 +4,35 @@
{{ $isEng := false }} {{ $isEng := false }}
<div class="container-normal" id=""> <div id="breadcrumbs">
{{- range $i, $s := $model.series -}}
<div>
<div class="{{ if $i -}}opacity-0 pointer-events-none select-none{{- end -}}">
Reihentitel <i class="ri-arrow-right-wide-line"></i>
</div>
<div>
<a href="/reihe/{{- $s.MusenalmID -}}">{{ $s.Title }}</a>
</div>
<div>
{{- if $model.entry.Year -}}
<i class="ri-arrow-right-wide-line"></i> <b>{{ $model.entry.Year }}</b>
{{- else -}}
<i class="ri-arrow-right-wide-line"></i> <b>{{ $model.entry.PreferredTitle }}</b>
{{- end -}}
</div>
<div class="grow"></div>
{{- if not $i -}}
<div class="backbutton">
<a href="/reihen/?letter=A" class="no-underline">
<i class="ri-arrow-left-long-line"></i> Alle Bände nach Reihentiteln
</a>
</div>
{{- end -}}
</div>
{{- end -}}
</div>
<div class="container-normal mt-12" id="">
<div class="flex flex-col" id="entrydata"> <div class="flex flex-col" id="entrydata">
<div class="entryrow"> <div class="entryrow">
<div class="fieldlabel">Almanach-Nummer</div> <div class="fieldlabel">Almanach-Nummer</div>
@@ -150,7 +178,7 @@
<div class="entryrow"> <div class="entryrow">
<div class="fieldlabel">Anmerkungen</div> <div class="fieldlabel">Anmerkungen</div>
<div class="fieldvalue"> <div class="fieldvalue">
{{- Safe $model.entry.Annotation -}} {{- Safe (ReplaceSlashParen $model.entry.Annotation) -}}
</div> </div>
</div> </div>
{{- end -}} {{- end -}}

View File

@@ -35,7 +35,9 @@
</div> </div>
<div class="grow lg:px-0 ml-3 lg:ml-8"> <div class="grow lg:px-0 ml-3 lg:ml-8">
<div class="-indent-3"> <div class="-indent-3">
<span class="font-bold reihen-text">{{ $r.Title }}</span> <span class="font-bold reihen-text">
{{ $r.Title }}
</span>
{{ if $r.Annotation }} {{ if $r.Annotation }}
<span>&ensp;&middot;&ensp;</span> <span>&ensp;&middot;&ensp;</span>
<span class="{{ if $marka }}reihen-text{{ end }}">{{ Safe $r.Annotation }}</span> <span class="{{ if $marka }}reihen-text{{ end }}">{{ Safe $r.Annotation }}</span>

View File

@@ -11,7 +11,7 @@
{{- if $bd -}} {{- if $bd -}}
<div class="flex flex-row odd:bg-zinc-100 px-3 ml-2 py-0.5 justify-between w-full"> <div class="flex flex-row odd:bg-zinc-100 px-3 ml-2 py-0.5 justify-between w-full">
<a href="/almanach/{{ $bd.MusenalmID }}" class="no-underline"> <a href="/almanach/{{ $bd.MusenalmID }}" class="no-underline">
<div class=""> <div class="{{- if eq $bd.EditState "Edited" -}}font-bold{{- end -}}">
{{- if $bd.PreferredTitle -}} {{- if $bd.PreferredTitle -}}
{{ $bd.PreferredTitle }} {{ $bd.PreferredTitle }}
{{- else if ne $bd.Year 0 -}} {{- else if ne $bd.Year 0 -}}

View File

@@ -1 +1 @@
<title>{{ .site.title }} &ndash; {{ .record.title }}</title> <title>{{ .site.title }} &ndash; {{ .record.Title }}</title>

View File

@@ -1,25 +1,54 @@
{{/* .result:
type AgentResult struct {
Agent *dbmodels.Agent
BResult []*dbmodels.Series // Sorted
Entries map[string]*dbmodels.Entry // KEY: Entry ID
EntriesSeries map[string][]*dbmodels.REntriesSeries // KEY: Series ID
EntriesAgents map[string][]*dbmodels.REntriesAgents // KEY: Entry ID
CResult []*dbmodels.Entry /// Sorted
Contents map[string][]*dbmodels.Content // KEY: entry ID
ContentsAgents map[string][]*dbmodels.RContentsAgents // KEY: Content ID
}
*/}}
{{ $model := . }} {{ $model := . }}
<div class="container-normal font-serif"> <div id="breadcrumbs">
{{ if $model.a.CorporateBody }} <div>
<div class="notifier font-sans"> <div>
Personen und Körperschaften <i class="ri-arrow-right-wide-line"></i> Einzelansicht
<i class="ri-arrow-right-wide-line"></i> <b>{{ $model.result.Agent.Name }}</b>
</div>
<div class="backbutton">
<a href="/personen/" class="no-underline">
<i class="ri-arrow-left-long-line"></i> Alle Personen &amp; Körperschaften
</a>
</div>
</div>
</div>
<div class="container-normal font-serif mt-12">
{{ if $model.result.Agent.CorporateBody }}
<div class="font-sans">
<i class="ri-team-line"></i> <i class="ri-team-line"></i>
<span class="filtercategory">Verlag, Druckerei oder Vertrieb</span> <span class="filtercategory">Körperschaft</span>
</div> </div>
{{ else }} {{ else }}
<div class="notifier font-sans"> <div class="font-sans">
<i class="ri-user-line"></i> <i class="ri-user-line"></i>
<span class="filtercategory">Person</span> <span class="filtercategory">Person</span>
</div> </div>
{{ end }} {{ end }}
<h1 class="text-3xl font-bold">{{ $model.a.Name }}</h1> <h1 class="text-3xl font-bold">{{ $model.result.Agent.Name }}</h1>
<div> <div>
<span class=""> <span class="">
{{ $model.a.BiographicalData }} {{ $model.result.Agent.BiographicalData }}
</span> </span>
<span class=""> <span class="">
{{- $arr := $model.a.ProfessionArray -}} {{- $arr := $model.result.Agent.ProfessionArray -}}
{{- if $arr -}} {{- if $arr -}}
{{- range $i, $p := $arr -}} {{- range $i, $p := $arr -}}
<div <div
@@ -32,10 +61,25 @@
</div> </div>
</div> </div>
{{ if .entries }} {{- if .result.BResult -}}
<div class="container-normal flex flex-col font-serif mt-7 gap-y-6"> <div class="container-normal flex flex-col font-serif mt-7 gap-y-6">
<h2>Bände nach Reihentiteln</h2> <h2 class="font-bold">
{{ range $id, $r := .series }} <i class="ri-information-2-line"></i>
{{ if eq $model.result.LenEntries 1 }}
Ein Band
{{- else }}
{{- $model.result.LenEntries }}
Bände
{{- end }}
in
{{- if eq $model.result.LenSeries 1 }}
einer Reihe
{{- else }}
{{ $model.result.LenSeries }} Reihen
{{- end }}
gefunden:
</h2>
{{ range $id, $r := .result.BResult }}
<div class="grow-0 max-w-[48rem]"> <div class="grow-0 max-w-[48rem]">
<div> <div>
<span class="font-bold">{{ $r.Title }}</span> <span class="font-bold">{{ $r.Title }}</span>
@@ -46,14 +90,18 @@
</div> </div>
{{ end }} {{ end }}
<div class=""> <div class="">
{{- $bds := index $model.relations $r.Id -}} {{- $bds := index $model.result.EntriesSeries $r.Id -}}
{{ template "reiherelations" (Arr $r $bds $model.entries true $model.relations) }} {{ template "personreiherelations" (Arr $r $bds $model.result.Entries true
$model.result.EntriesAgents)
}}
</div> </div>
</div> </div>
{{ end }} {{ end }}
</div> </div>
{{ end }} {{ end }}
<!--
{{ if .contents }} {{ if .contents }}
<h2>Inhalte</h2> <h2>Inhalte</h2>
{{ range $id, $c := .contents }} {{ range $id, $c := .contents }}
@@ -65,3 +113,4 @@
</div> </div>
{{ end }} {{ end }}
{{ end }} {{ end }}
-->

View File

@@ -1,51 +0,0 @@
{{ $reihe := index . 0 }}
{{ $rels := index . 1 }}
{{ $entries := index . 2 }}
{{ $shownos := index . 3 }}
{{- if $rels -}}
<div class="reiherelations flex flex-col text-base font-sans w-full pt-1 -ml-3">
{{- range $_, $rel := $rels -}}
{{- $bd := index $entries $rel.Entry -}}
{{- if $bd -}}
<div class="flex flex-row odd:bg-zinc-100 px-3 py-0.5 justify-between w-full">
<a href="/almanach/{{ $bd.MusenalmID }}" class="no-underline">
<div class="">
{{- if $bd.PreferredTitle -}}
{{ $bd.PreferredTitle }}
{{- else if ne $bd.Year 0 -}}
{{- $bd.Year -}}
{{- else -}}
[o.J.]
{{- end -}}
</div>
{{- if not (eq $rel.Type "Bevorzugter Reihentitel") -}}
<div class="text-xs whitespace-nowrap">
{{- if eq $rel.Type "Früherer Reihentitel" -}}
Titelauflage aus einer anderen Reihe
{{- else if eq $rel.Type "Späterer Reihentitel" -}}
Titelauflage
{{- else if eq $rel.Type "In anderer Sprache" -}}
{{- if Contains $bd.Language "ger" -}}
In deutscher Sprache
{{- else -}}
In französischer Sprache
{{- end -}}
{{- else -}}
{{ $rel.Type }}
{{- end -}}
</div>
{{- end -}}
</a>
<div class="whitespace-nowrap align-top">
Alm
{{ $bd.MusenalmID }}
</div>
</div>
{{- end -}}
{{- end -}}
</div>
{{- end -}}

View File

@@ -0,0 +1,4 @@
<title>
{{ .site.title }} &ndash;
{{ if .result -}}{{ .result.Agent.Name }}{{ else -}}Einzelpersonenansicht{{- end -}}
</title>

View File

@@ -0,0 +1,70 @@
{{ $reihe := index . 0 }}
{{ $rels := index . 1 }}
{{ $entries := index . 2 }}
{{ $shownos := index . 3 }}
{{ $relations := index . 4 }}
{{- if $rels -}}
<div class="reiherelations flex flex-col text-base font-sans w-full pt-1 -ml-3">
{{- range $_, $rel := $rels -}}
{{- $bd := index $entries $rel.Entry -}}
{{- $arels := index $relations $rel.Entry -}}
{{- if $bd -}}
<div class="flex flex-row odd:bg-zinc-100 pr-3 py-0.5 w-full items-start">
{{- if $arels -}}
<div class="min-w-32">
{{- range $i, $arel := $arels -}}
<div
class="inline font-bold text-sm font-sans bg-slate-200 pl-2 pr-3 py-0.5
rounded-r-full mr-1.5 ">
{{- $arel.Type -}}
</div>
{{- end -}}
</div>
{{- end -}}
<div>
<a
href="/almanach/{{ $bd.MusenalmID }}"
class="no-underline {{ if eq
$bd.EditState "Edited"
-}}
font-bold
{{- end -}}">
{{- if $bd.PreferredTitle -}}
{{ $bd.PreferredTitle }}
{{- else if ne $bd.Year 0 -}}
{{- $bd.Year -}}
{{- else -}}
[o.J.]
{{- end -}}
{{- if not (eq $rel.Type "Bevorzugter Reihentitel") -}}
<div class="text-xs whitespace-nowrap">
{{- if eq $rel.Type "Früherer Reihentitel" -}}
Titelauflage aus einer anderen Reihe
{{- else if eq $rel.Type "Späterer Reihentitel" -}}
Titelauflage
{{- else if eq $rel.Type "In anderer Sprache" -}}
{{- if Contains $bd.Language "ger" -}}
In deutscher Sprache
{{- else -}}
In französischer Sprache
{{- end -}}
{{- else -}}
{{ $rel.Type }}
{{- end -}}
</div>
{{- end -}}
</a>
</div>
<div class="whitespace-nowrap align-top grow text-right">
Alm
{{ $bd.MusenalmID }}
</div>
</div>
{{- end -}}
{{- end -}}
</div>
{{- end -}}

View File

@@ -16,9 +16,8 @@
<!-- INFO: 4. Header --> <!-- INFO: 4. Header -->
<div id="personheader" class="border-t border-r border-zinc-300 relative w-full"> <div id="personheader" class="border-t border-r border-zinc-300 relative w-full">
{{ template "heading" . }} {{ template "heading" . }}
<div class="flex flex-row justify-end mt-12 items-end">
{{ template "notifier" . }}
<div class="flex flex-row justify-end mt-12">
{{ template "professionselectbox" . }} {{ template "professionselectbox" . }}
{{ template "searchbox" . }} {{ template "searchbox" . }}
</div> </div>
@@ -35,7 +34,11 @@
<a href="/person/{{ $agent.Id }}" class="search-result font-bold"> <a href="/person/{{ $agent.Id }}" class="search-result font-bold">
{{ $agent.Name }} {{ $agent.Name }}
</a> </a>
<span class="inline-block font-sans text-sm"> <span
class="inline-block font-sans text-sm
{{ if $model.FTS -}}
search-result
{{- end -}}">
{{ if not $agent.CorporateBody }} {{ if not $agent.CorporateBody }}
{{ $agent.BiographicalData }} {{ $agent.BiographicalData }}
{{ end }} {{ end }}
@@ -68,7 +71,9 @@
{{- end -}} {{- end -}}
</div> </div>
<div class="w-64 ml-4 shrink-0">{{ $agent.References }}</div> <div class="w-64 ml-4 shrink-0 {{ if $model.FTS -}}search-result{{- end -}}">
{{ $agent.References }}
</div>
</div> </div>
{{ end }} {{ end }}

View File

@@ -1,7 +1,7 @@
{{ $model := . }} {{ $model := . }}
{{- if and $model.letters (not $model.search) -}} {{- if and $model.letters (not $model.search) -}}
<div id="personalphabet" class="flex flex-col text-xl pt-[4.875rem] pb-4 relative"> <div id="personalphabet" class="flex flex-col text-xl pt-[5.875rem] pb-4 relative">
{{- range $id, $r := .letters -}} {{- range $id, $r := .letters -}}
<a <a
class="{{ if not $model.letter -}}inactive{{- end -}}" class="{{ if not $model.letter -}}inactive{{- end -}}"

View File

@@ -7,14 +7,16 @@
{{ $isOrg := and $model.filter (eq $model.filter "org") }} {{ $isOrg := and $model.filter (eq $model.filter "org") }}
<h1 <div>
class="text-3xl font-bold px-3 relative -translate-y-[55%] w-min whitespace-nowrap bg-stone-50 ml-24 z-20"> <h1
<span x-show="!search"> class="text-3xl font-bold px-3 relative -translate-y-[55%] w-min whitespace-nowrap bg-stone-50 ml-24 z-20">
{{- if $isPerson -}} <span x-show="!search">
Personen {{- if $isPerson -}}
{{- else if $isOrg -}} Personen
Verlage, Druckereien &amp; Vertriebe {{- else if $isOrg -}}
{{- end -}} Verlage, Druckereien &amp; Vertriebe
</span> {{- end -}}
<span x-show="search"> Suche &middot; Alle Personen &amp; Körperschaften </span> </span>
</h1> <span x-show="search"> Suche &middot; Alle Personen &amp; Körperschaften </span>
</h1>
</div>

View File

@@ -0,0 +1,91 @@
{{ $model := . }}
{{ $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")) }}
{{ $isProfession := and $model.filter (or (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") }}
<div class="justify-self-start grow flex flex-row px-3 ml-6 mt-2 mr-2">
{{ if .letter }}
{{- if $isNoOrg -}}
<div class="notifier" x-show="!search">
<i class="ri-sort-alphabet-asc"></i>
<span class="filtercategory">Alle Personen</span> &middot;
<span class="">Anfangsbuchstabe <span class="filterterm">{{ .letter }}</span></span>
</div>
{{- else if $isMusik -}}
<div class="notifier" x-show="!search">
<i class="ri-sort-alphabet-asc"></i>
<span class="filtercategory">Musiker:innen</span> &middot;
<span class="">Anfangsbuchstabe <span class="filterterm">{{ .letter }}</span></span>
</div>
{{- else if $isAutor -}}
<div class="notifier" x-show="!search">
<i class="ri-sort-alphabet-asc"></i>
<span class="filtercategory">Autor:innen</span> &middot;
<span class="">Anfangsbuchstabe <span class="filterterm">{{ .letter }}</span></span>
</div>
{{- else if $isGraphik -}}
<div class="notifier" x-show="!search">
<i class="ri-sort-alphabet-asc"></i>
<span class="filtercategory">Graphiker:innen</span> &middot;
<span class="">Anfangsbuchstabe <span class="filterterm">{{ .letter }}</span></span>
</div>
{{- else if $isHrsg -}}
<div class="notifier" x-show="!search">
<i class="ri-sort-alphabet-asc"></i>
<span class="filtercategory">Herausgeber:innen</span> &middot;
<span class="">Anfangsbuchstabe <span class="filterterm">{{ .letter }}</span></span>
</div>
{{- else if $isOrg -}}
<div class="notifier" x-show="!search">
<i class="ri-sort-alphabet-asc"></i>
<span class="filtercategory">Verlage, Druckereien &amp; Vertriebe</span> &middot;
<span class="">Anfangsbuchstabe <span class="filterterm">{{ .letter }}</span></span>
</div>
{{- end -}}
{{ end }}
<div class="notifier" x-show="search">
<i class="ri-search-line"></i>
<span class="filtercategory">Suche</span>
&middot; <span class="filterterm" x-text="search"></span>
</div>
{{ if .search }}
<div class="notifier" x-show="search">
<i class="ri-links-line"></i>
<span class="filtercategory">Link</span>
&middot; <span class="filterterm" x-text="window.location.href"></span>
</div>
{{ end }}
{{ if or (not .letter) $isProfession }}
<div class="notifier ml-2" x-show="!search">
<a href="/personen/" class="no-underline">
<i class="ri-arrow-left-long-line"></i> Alle Personen
</a>
</div>
{{ end }}
<div class="notifier ml-2" x-show="search">
<a href="/personen/" class="no-underline">
<i class="ri-arrow-left-long-line"></i> Alle Personen
</a>
</div>
</div>

View File

@@ -2,22 +2,61 @@
{{ $r := $model.series }} {{ $r := $model.series }}
<div class="container-normal flex flex-col font-serif mt-16"> <div id="breadcrumbs">
<div class="grow-0 max-w-[48rem]"> <div>
<div> <div>
<span class="font-bold">{{ $r.Title }}</span> Reihen <i class="ri-arrow-right-wide-line"></i> Einzelansicht
<i class="ri-arrow-right-wide-line"></i> <b>{{ $r.Title }}</b>
</div>
<div class="backbutton">
<a href="/reihen/?letter=A" class="no-underline">
<i class="ri-arrow-left-long-line"></i> Alle Reihen
</a>
</div>
</div>
</div>
<div class="container-normal flex flex-col font-serif mt-12">
<div class="font-sans">
<svg
class="w-[0.9rem] h-[0.9rem] relative bottom-[0.04rem] inline-block"
width="65px"
height="65px"
viewBox="0 0 28 28"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
fill="currentColor">
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
<g id="SVGRepo_iconCarrier">
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="ic_fluent_library_28_filled" fill="currentColor" fill-rule="nonzero">
<path
d="M5.9897,3 C7.0937,3 7.9897,3.896 7.9897,5 L7.9897,23 C7.9897,24.104 7.0937,25 5.9897,25 L4.0007,25 C2.8957,25 2.0007,24.104 2.0007,23 L2.0007,5 C2.0007,3.896 2.8957,3 4.0007,3 L5.9897,3 Z M12.9897,3 C14.0937,3 14.9897,3.896 14.9897,5 L14.9897,23 C14.9897,24.104 14.0937,25 12.9897,25 L10.9947,25 C9.8897,25 8.9947,24.104 8.9947,23 L8.9947,5 C8.9947,3.896 9.8897,3 10.9947,3 L12.9897,3 Z M22.0701,6.5432 L25.9301,22.0262 C26.1971,23.0972 25.5441,24.1832 24.4731,24.4512 L22.5101,24.9402 C21.4391,25.2072 20.3531,24.5552 20.0861,23.4832 L16.2261,8.0002 C15.9581,6.9282 16.6111,5.8432 17.6821,5.5752 L19.6451,5.0862 C20.7161,4.8182 21.8021,5.4712 22.0701,6.5432 Z"
id="🎨-Color"></path>
</g>
</g>
</g>
</svg>
Reihe
</div>
<div class="grow-0">
<div>
<span class="font-bold text-3xl mr-2">{{ $r.Title }}</span>
{{ if $r.References }} {{ if $r.References }}
<div class="text-sm font-sans px-2 py-1 ml-2 bg-stone-100 w-max inline-block"> <div class="text-sm font-sans px-2 py-1 bg-stone-100 w-max inline-block mr-2">
{{ $r.References }} {{ $r.References }}
</div> </div>
{{ end }} {{ end }}
</div> </div>
{{ if $r.Annotation }} {{ if $r.Annotation }}
<div class="max-w-[48rem]"> <div class="max-w-[48rem] mt-1">
<span class="">{{ Safe $r.Annotation }}</span> <span class="">{{ Safe $r.Annotation }}</span>
</div> </div>
{{ end }} {{ end }}
<div class=""> <div class="max-w-[64rem] [&_*]:!text-lg mt-6">
{{ template "_reiherelations" (Arr $r $model.relations $model.entries true) }} {{ template "_reiherelations" (Arr $r $model.relations $model.entries true) }}
</div> </div>
</div> </div>

View File

@@ -56,7 +56,7 @@
{{ if not .letter }} {{ if not .letter }}
<div class="notifier ml-2" x-show="!search"> <div class="notifier ml-2" x-show="!search">
<a href="/reihen" class="no-underline"> <a href="/reihen/?letter=A" class="no-underline">
<i class="ri-arrow-left-long-line"></i> Alle Reihen anzeigen <i class="ri-arrow-left-long-line"></i> Alle Reihen anzeigen
</a> </a>
</div> </div>
@@ -64,7 +64,7 @@
<div class="notifier ml-2" x-show="search"> <div class="notifier ml-2" x-show="search">
<a href="/reihen" class="no-underline"> <a href="/reihen/?letter=A" class="no-underline">
<i class="ri-arrow-left-long-line"></i> Alle Reihen anzeigen <i class="ri-arrow-left-long-line"></i> Alle Reihen anzeigen
</a> </a>
</div> </div>

View File

@@ -121,6 +121,13 @@
@apply !text-gray-400; @apply !text-gray-400;
} }
#alphabet a[aria-current="page"]:not(.inactive):before {
aspect-ratio: 1;
clip-path: polygon(100% 80%, 80% 100%, 100% 100%);
content: " ";
@apply bg-red-600 absolute -bottom-[1px] -right-[1px] h-full z-30;
}
.headingcontainer:before { .headingcontainer:before {
content: ""; content: "";
@apply bg-zinc-300 w-[50%] absolute top-0 left-[50%] h-[1px]; @apply bg-zinc-300 w-[50%] absolute top-0 left-[50%] h-[1px];
@@ -138,15 +145,15 @@
@apply border-l-4 border-zinc-300 font-bold; @apply border-l-4 border-zinc-300 font-bold;
} }
.headingcontainer .notifier { .notifier {
@apply bg-stone-100 text-center text-base px-2.5 py-1 font-sans rounded; @apply bg-stone-100 text-center text-base px-2.5 py-1 font-sans rounded;
} }
.headingcontainer .notifier i { .notifier i {
@apply inline-block pr-0.5; @apply inline-block pr-0.5;
} }
.headingcontainer .notifier .filterterm { .notifier .filterterm {
@apply font-bold; @apply font-bold;
} }
@@ -289,11 +296,11 @@
} }
#persontype a { #persontype a {
@apply px-1.5 border-b-[5px] border-zinc-300 no-underline font-serif mx-2.5; @apply px-1.5 border-b-[5px] border-transparent hover:border-zinc-200 no-underline font-serif mx-2.5;
} }
#persontype a[aria-current="page"]:not(#persontype.inactive a) { #persontype a[aria-current="page"]:not(#persontype.inactive a) {
@apply font-bold; @apply font-bold border-zinc-300;
} }
#persontype.inactive a { #persontype.inactive a {
@@ -326,15 +333,15 @@
} }
#personalphabet a:hover:not([aria-current="page"]:not(.inactive)) { #personalphabet a:hover:not([aria-current="page"]:not(.inactive)) {
@apply !bg-stone-50 -ml-2 relative; @apply !bg-stone-50 -ml-2 relative text-stone-900;
} }
#personalphabet a.inactive { #personalphabet a.inactive {
@apply !text-gray-400; @apply text-gray-400;
} }
#entrydata .fieldlabel { #entrydata .fieldlabel {
@apply font-bold text-base font-sans whitespace-nowrap w-60 grow-0 shrink-0 pt-0.5; @apply font-bold text-base font-sans whitespace-nowrap min-w-48 grow-0 shrink-0 pt-0.5;
} }
#entrydata .fieldvalue { #entrydata .fieldvalue {
@@ -342,7 +349,7 @@
} }
#entrydata .entryrow { #entrydata .entryrow {
@apply flex flex-row gap-x-3.5 items-start py-0.5 px-4; @apply flex flex-row gap-x-3.5 items-start py-0.5;
} }
#entrydata { #entrydata {
@@ -351,4 +358,16 @@
int-link { int-link {
@apply text-slate-700 hover:text-slate-900 underline decoration-dotted hover:decoration-solid; @apply text-slate-700 hover:text-slate-900 underline decoration-dotted hover:decoration-solid;
} }
#breadcrumbs {
@apply w-full max-w-(--breakpoint-xl) mx-auto px-3 pb-4 relative pt-1.5;
}
#breadcrumbs > div {
@apply flex flex-row gap-x-2.5 justify-between;
}
#breadcrumbs .backbutton {
@apply ml-4 bg-stone-100 py-0.5 px-2.5 rounded font-sans text-base text-center mr-1.5;
}
} }