mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-29 09:15:33 +00:00
Beitragsansicht
This commit is contained in:
126
dbmodels/collectionhelper.go
Normal file
126
dbmodels/collectionhelper.go
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
package dbmodels
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CollectionInfo holds only the ID, a list of single references, and the Recorded flag.
|
||||||
|
type CollectionInfo struct {
|
||||||
|
Collection *Content
|
||||||
|
Singles []int
|
||||||
|
Recorded bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ci CollectionInfo) String() string {
|
||||||
|
marshalled, _ := json.Marshal(ci)
|
||||||
|
return string(marshalled)
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseAnnotation detects "nicht erfasst" references (Recorded=false),
|
||||||
|
// then finds all "INr" references (both single values and ranges).
|
||||||
|
// Ranges like "100-105" are fully expanded to singles. Duplicates are removed.
|
||||||
|
// Any references not in `inos` are ignored.
|
||||||
|
func ParseAnnotation(c *Content, annotation string, inos []int) CollectionInfo {
|
||||||
|
ci := CollectionInfo{
|
||||||
|
Collection: c,
|
||||||
|
Singles: []int{},
|
||||||
|
Recorded: true, // Default
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1) Detect phrases like "nicht erfasst", "nicht aufgenommen", etc.
|
||||||
|
notRecordedPatterns := []string{"erfasst", "aufgenommen", "verzeichnet", "registriert"}
|
||||||
|
lowerAnn := strings.ToLower(annotation)
|
||||||
|
if strings.Contains(lowerAnn, "nicht") {
|
||||||
|
for _, kw := range notRecordedPatterns {
|
||||||
|
if strings.Contains(lowerAnn, kw) {
|
||||||
|
ci.Recorded = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We'll keep singles in a map for deduplication
|
||||||
|
singlesMap := make(map[int]struct{})
|
||||||
|
|
||||||
|
// 2) Regex that matches "INr" plus the numeric portion (including dash / punctuation).
|
||||||
|
re := regexp.MustCompile(`(?i)\bINr[.:]?\s+([\d,\-\s–—;/.]+)`)
|
||||||
|
matches := re.FindAllStringSubmatch(annotation, -1)
|
||||||
|
|
||||||
|
// Regex to unify different dash characters into a simple '-'
|
||||||
|
dashRegex := regexp.MustCompile(`[–—−‒]`)
|
||||||
|
|
||||||
|
// Helper to expand a range, e.g. 10615–10621 => 10615..10621
|
||||||
|
expandRange := func(fromVal, toVal int) {
|
||||||
|
// If reversed, its a typo
|
||||||
|
if fromVal > toVal {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for v := fromVal; v <= toVal; v++ {
|
||||||
|
if inList(v, inos) {
|
||||||
|
singlesMap[v] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m := range matches {
|
||||||
|
numericChunk := m[1]
|
||||||
|
|
||||||
|
// Replace typographic dashes with ASCII hyphen
|
||||||
|
numericChunk = dashRegex.ReplaceAllString(numericChunk, "-")
|
||||||
|
|
||||||
|
// Also unify semicolons or slashes to commas
|
||||||
|
extraDelims := regexp.MustCompile(`[;/]+`)
|
||||||
|
numericChunk = extraDelims.ReplaceAllString(numericChunk, ",")
|
||||||
|
|
||||||
|
// Now split on commas
|
||||||
|
parts := strings.Split(numericChunk, ",")
|
||||||
|
for _, p := range parts {
|
||||||
|
p = strings.TrimSpace(p)
|
||||||
|
if p == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// If we see a hyphen, treat it as a range
|
||||||
|
if strings.Contains(p, "-") {
|
||||||
|
rangeParts := strings.SplitN(p, "-", 2)
|
||||||
|
if len(rangeParts) == 2 {
|
||||||
|
fromStr := strings.TrimSpace(rangeParts[0])
|
||||||
|
toStr := strings.TrimSpace(rangeParts[1])
|
||||||
|
if fromVal, errFrom := strconv.Atoi(fromStr); errFrom == nil {
|
||||||
|
if toVal, errTo := strconv.Atoi(toStr); errTo == nil {
|
||||||
|
expandRange(fromVal, toVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Single integer reference
|
||||||
|
if val, err := strconv.Atoi(p); err == nil {
|
||||||
|
if inList(val, inos) {
|
||||||
|
singlesMap[val] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flatten the map into a sorted slice
|
||||||
|
for s := range singlesMap {
|
||||||
|
ci.Singles = append(ci.Singles, s)
|
||||||
|
}
|
||||||
|
sort.Ints(ci.Singles)
|
||||||
|
|
||||||
|
return ci
|
||||||
|
}
|
||||||
|
|
||||||
|
// inList checks membership in `inos`
|
||||||
|
func inList(x int, list []int) bool {
|
||||||
|
for _, item := range list {
|
||||||
|
if item == x {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
@@ -157,6 +157,14 @@ func (c *Content) SetScans(scans []*filesystem.File) {
|
|||||||
c.Set(SCAN_FIELD, scans)
|
c.Set(SCAN_FIELD, scans)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Content) ImagePaths() []string {
|
||||||
|
ret := []string{}
|
||||||
|
for _, s := range r.Scans() {
|
||||||
|
ret = append(ret, "/api/files/"+r.TableName()+"/"+r.Id+"/"+s)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Content) Numbering() float64 {
|
func (c *Content) Numbering() float64 {
|
||||||
return c.GetFloat(NUMBERING_FIELD)
|
return c.GetFloat(NUMBERING_FIELD)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package dbmodels
|
|||||||
import (
|
import (
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
|
"github.com/Theodor-Springmann-Stiftung/musenalm/helpers/datatypes"
|
||||||
"golang.org/x/text/collate"
|
"golang.org/x/text/collate"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
)
|
)
|
||||||
@@ -41,3 +42,9 @@ func Sort_REntriesSeries_Year(entries []*REntriesSeries, entriesMap map[string]*
|
|||||||
return ientry.Year() - jentry.Year()
|
return ientry.Year() - jentry.Year()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Sort_Contents_Numbering(contents []*Content) {
|
||||||
|
slices.SortFunc(contents, func(i, j *Content) int {
|
||||||
|
return datatypes.CompareFloat(i.Numbering(), j.Numbering())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
15
helpers/datatypes/float64.go
Normal file
15
helpers/datatypes/float64.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package datatypes
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
const float64EqualityThreshold = 1e-9
|
||||||
|
|
||||||
|
func CompareFloat(a, b float64) int {
|
||||||
|
if math.Abs(a-b) < float64EqualityThreshold {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if a < b {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
@@ -1,13 +1,17 @@
|
|||||||
package functions
|
package functions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/text/cases"
|
"golang.org/x/text/cases"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var linksexp = regexp.MustCompile(`INr\s*([0-9]+)(?:\s*[-,;]\s*[0-9]*)*\s*(?:,|;)?\s*(?:obj|Obj)?\s*[0-9]*(?:\s*[-,;]\s*[0-9]*)*`)
|
||||||
|
|
||||||
func Safe(s string) template.HTML {
|
func Safe(s string) template.HTML {
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return ""
|
return ""
|
||||||
@@ -39,3 +43,15 @@ func First(s string) string {
|
|||||||
|
|
||||||
return string(r[0])
|
return string(r[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LinksAnnotation(s string) string {
|
||||||
|
annotation := linksexp.ReplaceAllStringFunc(s, func(match string) string {
|
||||||
|
submatches := linksexp.FindStringSubmatch(match)
|
||||||
|
if len(submatches) > 1 {
|
||||||
|
return fmt.Sprintf(`<a href="#%s" class="link-default oldstyle-nums">%s</a>`, submatches[1], match)
|
||||||
|
}
|
||||||
|
return match
|
||||||
|
})
|
||||||
|
|
||||||
|
return annotation
|
||||||
|
}
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ type AlmanachResult struct {
|
|||||||
EntriesSeries map[string]*dbmodels.REntriesSeries // <- Key is series id
|
EntriesSeries map[string]*dbmodels.REntriesSeries // <- Key is series id
|
||||||
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
|
||||||
|
CInfoByContent map[int][]dbmodels.CollectionInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAlmanachResult(app core.App, id string) (*AlmanachResult, error) {
|
func NewAlmanachResult(app core.App, id string) (*AlmanachResult, error) {
|
||||||
@@ -110,6 +113,8 @@ func NewAlmanachResult(app core.App, id string) (*AlmanachResult, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbmodels.Sort_Contents_Numbering(contents)
|
||||||
|
|
||||||
contentsagents, err := dbmodels.RContentsAgents_Contents(app, dbmodels.Ids(contents))
|
contentsagents, err := dbmodels.RContentsAgents_Contents(app, dbmodels.Ids(contents))
|
||||||
caids := []any{}
|
caids := []any{}
|
||||||
caMap := map[string][]*dbmodels.RContentsAgents{}
|
caMap := map[string][]*dbmodels.RContentsAgents{}
|
||||||
@@ -137,7 +142,7 @@ func NewAlmanachResult(app core.App, id string) (*AlmanachResult, error) {
|
|||||||
agentsMap[a.Id] = a
|
agentsMap[a.Id] = a
|
||||||
}
|
}
|
||||||
|
|
||||||
return &AlmanachResult{
|
ret := &AlmanachResult{
|
||||||
Entry: entry,
|
Entry: entry,
|
||||||
Places: places,
|
Places: places,
|
||||||
Series: series,
|
Series: series,
|
||||||
@@ -146,6 +151,35 @@ func NewAlmanachResult(app core.App, id string) (*AlmanachResult, error) {
|
|||||||
EntriesSeries: srelationsMap,
|
EntriesSeries: srelationsMap,
|
||||||
EntriesAgents: entriesagents,
|
EntriesAgents: entriesagents,
|
||||||
ContentsAgents: caMap,
|
ContentsAgents: caMap,
|
||||||
}, nil
|
}
|
||||||
|
|
||||||
|
ret.Collections()
|
||||||
|
return ret, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *AlmanachResult) Collections() {
|
||||||
|
ids := []int{}
|
||||||
|
collections := []*dbmodels.Content{}
|
||||||
|
for _, s := range r.Contents {
|
||||||
|
ids = append(ids, s.MusenalmID())
|
||||||
|
for _, t := range s.MusenalmType() {
|
||||||
|
if t == "Sammlung" {
|
||||||
|
collections = append(collections, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ccontentcollectionmap := map[int][]dbmodels.CollectionInfo{}
|
||||||
|
ccollectioncontentmap := map[string]dbmodels.CollectionInfo{}
|
||||||
|
for _, v := range collections {
|
||||||
|
cinfo := dbmodels.ParseAnnotation(v, v.Annotation(), ids)
|
||||||
|
ccollectioncontentmap[v.Id] = cinfo
|
||||||
|
for _, c := range cinfo.Singles {
|
||||||
|
ccontentcollectionmap[c] = append(ccontentcollectionmap[c], cinfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r.CInfoByCollection = ccollectioncontentmap
|
||||||
|
r.CInfoByContent = ccontentcollectionmap
|
||||||
|
}
|
||||||
|
|||||||
10
pages/contents.go
Normal file
10
pages/contents.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package pages
|
||||||
|
|
||||||
|
type ContentListFilterParams struct {
|
||||||
|
Agent string
|
||||||
|
Type string
|
||||||
|
Page int
|
||||||
|
OnlyScans bool
|
||||||
|
AlmNumber int
|
||||||
|
Entry string
|
||||||
|
}
|
||||||
@@ -130,6 +130,7 @@ func (e *Engine) funcs() error {
|
|||||||
e.AddFunc("First", functions.First)
|
e.AddFunc("First", functions.First)
|
||||||
e.AddFunc("ReplaceSlashParen", functions.ReplaceSlashParen)
|
e.AddFunc("ReplaceSlashParen", functions.ReplaceSlashParen)
|
||||||
e.AddFunc("ReplaceSlashParenSlash", functions.ReplaceSlashParenSlash)
|
e.AddFunc("ReplaceSlashParenSlash", functions.ReplaceSlashParenSlash)
|
||||||
|
e.AddFunc("LinksAnnotation", functions.LinksAnnotation)
|
||||||
|
|
||||||
// Time & Date Functions
|
// Time & Date Functions
|
||||||
e.AddFunc("Today", functions.Today)
|
e.AddFunc("Today", functions.Today)
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
{{/* .result:
|
{{/* .result:
|
||||||
type AlmanachResult struct {
|
type AlmanachResult struct {
|
||||||
Entry *dbmodels.Entry
|
Entry *dbmodels.Entry
|
||||||
|
Agent *dbmodels.Agent
|
||||||
|
Entries map[string]*dbmodels.Entry
|
||||||
Places []*dbmodels.Place
|
Places []*dbmodels.Place
|
||||||
Series []*dbmodels.Series
|
Series []*dbmodels.Series
|
||||||
Contents []*dbmodels.Content
|
Contents []*dbmodels.Content
|
||||||
@@ -9,11 +11,23 @@
|
|||||||
EntriesSeries map[string]*dbmodels.REntriesSeries // <- Key is series id
|
EntriesSeries map[string]*dbmodels.REntriesSeries // <- Key is series id
|
||||||
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
|
||||||
|
CInfoByContent map[int][]*dbmodels.CollectionInfo
|
||||||
}
|
}
|
||||||
*/}}
|
|
||||||
{{ $isGer := false }}
|
|
||||||
{{ $isFra := false }}
|
.parameters {
|
||||||
{{ $isEng := false }}
|
Sort string
|
||||||
|
MusenalmID string
|
||||||
|
PersonFilter string
|
||||||
|
TitleFilter string
|
||||||
|
EntryFilter string
|
||||||
|
TypeFilter []string
|
||||||
|
Scanfilter bool
|
||||||
|
}
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
|
||||||
<div id="breadcrumbs">
|
<div id="breadcrumbs">
|
||||||
@@ -44,175 +58,15 @@
|
|||||||
{{- end -}}
|
{{- end -}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container-oversize mt-12">
|
{{ template "entrydata" $model }}
|
||||||
<div class="pb-1.5 ml-32"><i class="ri-book-line"></i> Almanach</div>
|
|
||||||
<div class=" border relative pt-0">
|
|
||||||
<div class="ml-32 relative pt-2 bg-stone-50 mt-0 w-max flex flex-col">
|
|
||||||
</div>
|
|
||||||
<div class="container-normal !py-8" id="">
|
|
||||||
<div class="flex flex-col" id="entrydata">
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Almanach-Nummer</div>
|
|
||||||
<div class="fieldvalue">{{ $model.result.Entry.MusenalmID }}</div>
|
|
||||||
</div>
|
|
||||||
{{- if $model.result.Entry.PreferredTitle -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Kurztitel</div>
|
|
||||||
<div class="fieldvalue">{{ $model.result.Entry.PreferredTitle }}</div>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
{{- if $model.result.Entry.TitleStmt -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Titel</div>
|
|
||||||
<div class="fieldvalue">{{ $model.result.Entry.TitleStmt }}</div>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Jahr</div>
|
|
||||||
<div class="fieldvalue">
|
|
||||||
{{- if $model.result.Entry.Year -}}
|
|
||||||
<a href="/reihen?year={{ $model.result.Entry.Year }}&hidden=true"
|
|
||||||
>{{ $model.result.Entry.Year }}</a
|
|
||||||
>
|
|
||||||
{{- else -}}
|
|
||||||
[keine Angabe]
|
|
||||||
{{- end -}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{- if $model.result.Entry.ResponsibilityStmt -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Herausgeberangabe</div>
|
|
||||||
<div class="fieldvalue">{{ $model.result.Entry.ResponsibilityStmt }}</div>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
{{- if $model.result.Entry.Extent -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Umfang</div>
|
|
||||||
<div class="fieldvalue">
|
|
||||||
<abbrev-tooltips data-text="{{ $model.result.Entry.Extent }}"></abbrev-tooltips>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
{{- if $model.result.Entry.Language -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Sprache</div>
|
|
||||||
<div class="fieldvalue">
|
|
||||||
{{- range $i, $lang := $model.result.Entry.Language -}}
|
|
||||||
{{- if $i -}},{{- end -}}
|
|
||||||
{{- if eq $lang "ger" -}}
|
|
||||||
{{ $isGer = true }}
|
|
||||||
Deutsch
|
|
||||||
{{- else if eq $lang "eng" -}}
|
|
||||||
{{ $isEng = true }}
|
|
||||||
Englisch
|
|
||||||
{{- else if eq $lang "fre" -}}
|
|
||||||
{{ $isFra = true }}
|
|
||||||
Französisch
|
|
||||||
{{- else if eq $lang "ita" -}}
|
|
||||||
Italienisch
|
|
||||||
{{- else if eq $lang "lat" -}}
|
|
||||||
Latein
|
|
||||||
{{- else -}}
|
|
||||||
{{ $lang }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
{{- if $model.result.Entry.References -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Nachweise</div>
|
|
||||||
<div class="fieldvalue">
|
|
||||||
{{- $model.result.Entry.References -}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
{{- if $model.result.Series -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Reihen</div>
|
|
||||||
<div class="fieldvalue">
|
|
||||||
{{- range $i, $s := $model.result.Series -}}
|
|
||||||
<div>
|
|
||||||
{{- $rel := index $model.result.EntriesSeries $s.Id -}}
|
|
||||||
{{- if $rel -}}
|
|
||||||
{{- if not (eq $rel.Type "Bevorzugter Reihentitel") -}}
|
|
||||||
<span class="text-sm font-sans mr-2">
|
|
||||||
{{- if eq $rel.Type "Früherer Reihentitel" -}}
|
|
||||||
hat Titelauflage s.a.
|
|
||||||
{{- else if eq $rel.Type "Späterer Reihentitel" -}}
|
|
||||||
ist Titelauflage von, s.a.
|
|
||||||
{{- else if eq $rel.Type "In anderer Sprache" -}}
|
|
||||||
{{- if $isFra -}}
|
|
||||||
In deutscher Sprache s.a.
|
|
||||||
{{- else -}}
|
|
||||||
In französischer Sprache s.a.
|
|
||||||
{{- end -}}
|
|
||||||
{{- else if eq $rel.Type "Alternatives Titelblatt" -}}
|
|
||||||
alternatives Titelblatt, s.a.
|
|
||||||
{{- end -}}
|
|
||||||
</span>
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
<a href="/reihe/{{ $s.MusenalmID }}">{{ $s.Title }}</a>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
{{- if $model.result.Places -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Orte</div>
|
|
||||||
<div class="fieldvalue">
|
|
||||||
{{- range $i, $p := $model.result.Places -}}
|
|
||||||
<div>
|
|
||||||
<a href="/reihen?place={{ $p.Id }}&hidden=true">{{ $p.Name }}</a>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
{{- if $model.result.EntriesAgents -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Personen</div>
|
|
||||||
<div class="fieldvalue">
|
|
||||||
{{- range $i, $r := $model.result.EntriesAgents -}}
|
|
||||||
{{- $a := index $model.result.Agents $r.Agent -}}
|
|
||||||
{{- if $a -}}
|
|
||||||
<div>
|
|
||||||
<a href="/person/{{ $a.Id }}">
|
|
||||||
{{ $a.Name }}
|
|
||||||
</a>
|
|
||||||
<span
|
|
||||||
class="ml-2 px-2 py-0.5 rounded text-sm font-sans bg-slate-200 inline-block">
|
|
||||||
{{- $r.Type -}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
{{- if $model.result.Entry.Annotation -}}
|
|
||||||
<div class="entryrow">
|
|
||||||
<div class="fieldlabel">Anmerkungen</div>
|
|
||||||
<div class="fieldvalue">
|
|
||||||
{{- Safe (ReplaceSlashParen $model.result.Entry.Annotation) -}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{- end -}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
let abbrevs = {{- $model.abbrs -}};
|
|
||||||
let ats = document.querySelectorAll('abbrev-tooltips');
|
|
||||||
if (ats) {
|
|
||||||
ats.forEach((at) => {
|
|
||||||
at.setAbbrevMap(abbrevs);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
<div class="container-oversize" id="almanachcontents">
|
||||||
|
{{- range $i, $c := $model.result.Contents -}}
|
||||||
|
{{- $rels := index $model.result.ContentsAgents $c.Id -}}
|
||||||
|
{{- $coll := index $model.result.CInfoByContent $c.MusenalmID -}}
|
||||||
|
{{- if and $coll (index $coll 0) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- template "_content" Arr $c $model.result.Entry $rels $model.result.Agents -}}
|
||||||
|
{{- end -}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
188
views/routes/almanach/components/entrydata.gohtml
Normal file
188
views/routes/almanach/components/entrydata.gohtml
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
{{ $model := . }}
|
||||||
|
{{/* .result:
|
||||||
|
type AlmanachResult struct {
|
||||||
|
Entry *dbmodels.Entry
|
||||||
|
Places []*dbmodels.Place
|
||||||
|
Series []*dbmodels.Series
|
||||||
|
Contents []*dbmodels.Content
|
||||||
|
Agents map[string]*dbmodels.Agent // <- Key is agent id
|
||||||
|
EntriesSeries map[string]*dbmodels.REntriesSeries // <- Key is series id
|
||||||
|
EntriesAgents []*dbmodels.REntriesAgents
|
||||||
|
ContentsAgents map[string][]*dbmodels.RContentsAgents // <- Key is content id
|
||||||
|
}
|
||||||
|
*/}}
|
||||||
|
{{ $isGer := false }}
|
||||||
|
{{ $isFra := false }}
|
||||||
|
{{ $isEng := false }}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container-oversize mt-12">
|
||||||
|
<div class="pb-1.5 ml-32"><i class="ri-book-line"></i> Almanach</div>
|
||||||
|
<div class=" border relative pt-0">
|
||||||
|
<div class="ml-32 relative pt-2 bg-stone-50 mt-0 w-max flex flex-col"></div>
|
||||||
|
<div class="container-normal !py-8" id="">
|
||||||
|
<div class="flex flex-col" id="entrydata">
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Almanach-Nummer</div>
|
||||||
|
<div class="fieldvalue">{{ $model.result.Entry.MusenalmID }}</div>
|
||||||
|
</div>
|
||||||
|
{{- if $model.result.Entry.PreferredTitle -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Kurztitel</div>
|
||||||
|
<div class="fieldvalue">{{ $model.result.Entry.PreferredTitle }}</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $model.result.Entry.TitleStmt -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Titel</div>
|
||||||
|
<div class="fieldvalue">{{ $model.result.Entry.TitleStmt }}</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Jahr</div>
|
||||||
|
<div class="fieldvalue">
|
||||||
|
{{- if $model.result.Entry.Year -}}
|
||||||
|
<a href="/reihen?year={{ $model.result.Entry.Year }}&hidden=true"
|
||||||
|
>{{ $model.result.Entry.Year }}</a
|
||||||
|
>
|
||||||
|
{{- else -}}
|
||||||
|
[keine Angabe]
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{- if $model.result.Entry.ResponsibilityStmt -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Herausgeberangabe</div>
|
||||||
|
<div class="fieldvalue">{{ $model.result.Entry.ResponsibilityStmt }}</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $model.result.Entry.Extent -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Umfang</div>
|
||||||
|
<div class="fieldvalue">
|
||||||
|
<abbrev-tooltips data-text="{{ $model.result.Entry.Extent }}"></abbrev-tooltips>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $model.result.Entry.Language -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Sprache</div>
|
||||||
|
<div class="fieldvalue">
|
||||||
|
{{- range $i, $lang := $model.result.Entry.Language -}}
|
||||||
|
{{- if $i -}},{{- end -}}
|
||||||
|
{{- if eq $lang "ger" -}}
|
||||||
|
{{ $isGer = true }}
|
||||||
|
Deutsch
|
||||||
|
{{- else if eq $lang "eng" -}}
|
||||||
|
{{ $isEng = true }}
|
||||||
|
Englisch
|
||||||
|
{{- else if eq $lang "fre" -}}
|
||||||
|
{{ $isFra = true }}
|
||||||
|
Französisch
|
||||||
|
{{- else if eq $lang "ita" -}}
|
||||||
|
Italienisch
|
||||||
|
{{- else if eq $lang "lat" -}}
|
||||||
|
Latein
|
||||||
|
{{- else -}}
|
||||||
|
{{ $lang }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $model.result.Entry.References -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Nachweise</div>
|
||||||
|
<div class="fieldvalue">
|
||||||
|
{{- $model.result.Entry.References -}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $model.result.Series -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Reihen</div>
|
||||||
|
<div class="fieldvalue">
|
||||||
|
{{- range $i, $s := $model.result.Series -}}
|
||||||
|
<div>
|
||||||
|
{{- $rel := index $model.result.EntriesSeries $s.Id -}}
|
||||||
|
{{- if $rel -}}
|
||||||
|
{{- if not (eq $rel.Type "Bevorzugter Reihentitel") -}}
|
||||||
|
<span class="text-sm font-sans mr-2">
|
||||||
|
{{- if eq $rel.Type "Früherer Reihentitel" -}}
|
||||||
|
hat Titelauflage s.a.
|
||||||
|
{{- else if eq $rel.Type "Späterer Reihentitel" -}}
|
||||||
|
ist Titelauflage von, s.a.
|
||||||
|
{{- else if eq $rel.Type "In anderer Sprache" -}}
|
||||||
|
{{- if $isFra -}}
|
||||||
|
In deutscher Sprache s.a.
|
||||||
|
{{- else -}}
|
||||||
|
In französischer Sprache s.a.
|
||||||
|
{{- end -}}
|
||||||
|
{{- else if eq $rel.Type "Alternatives Titelblatt" -}}
|
||||||
|
alternatives Titelblatt, s.a.
|
||||||
|
{{- end -}}
|
||||||
|
</span>
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
<a href="/reihe/{{ $s.MusenalmID }}">{{ $s.Title }}</a>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $model.result.Places -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Orte</div>
|
||||||
|
<div class="fieldvalue">
|
||||||
|
{{- range $i, $p := $model.result.Places -}}
|
||||||
|
<div>
|
||||||
|
<a href="/reihen?place={{ $p.Id }}&hidden=true">{{ $p.Name }}</a>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $model.result.EntriesAgents -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Personen</div>
|
||||||
|
<div class="fieldvalue">
|
||||||
|
{{- range $i, $r := $model.result.EntriesAgents -}}
|
||||||
|
{{- $a := index $model.result.Agents $r.Agent -}}
|
||||||
|
{{- if $a -}}
|
||||||
|
<div>
|
||||||
|
<a href="/person/{{ $a.Id }}">
|
||||||
|
{{ $a.Name }}
|
||||||
|
</a>
|
||||||
|
<span
|
||||||
|
class="ml-2 px-2 py-0.5 rounded text-sm font-sans bg-slate-200 inline-block">
|
||||||
|
{{- $r.Type -}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $model.result.Entry.Annotation -}}
|
||||||
|
<div class="entryrow">
|
||||||
|
<div class="fieldlabel">Anmerkungen</div>
|
||||||
|
<div class="fieldvalue">
|
||||||
|
{{- Safe (ReplaceSlashParen $model.result.Entry.Annotation) -}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
let abbrevs = {{- $model.abbrs -}};
|
||||||
|
let ats = document.querySelectorAll('abbrev-tooltips');
|
||||||
|
if (ats) {
|
||||||
|
ats.forEach((at) => {
|
||||||
|
at.setAbbrevMap(abbrevs);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
118
views/routes/components/_content.gohtml
Normal file
118
views/routes/components/_content.gohtml
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
{{ $model := . }}
|
||||||
|
{{/* .1 - *Content
|
||||||
|
.2 - *Entry
|
||||||
|
.3 - []*RContentsAgents
|
||||||
|
.4 - map[string]*Agent
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{- $content := index . 0 -}}
|
||||||
|
{{- $entry := index . 1 -}}
|
||||||
|
{{- $rcas := index . 2 -}}
|
||||||
|
{{- $agents := index . 3 -}}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="content flex flex-row font-serif" id="{{- $content.Id -}}">
|
||||||
|
<div class="w-36 shrink-0 grow-0 flex flex-col items-end columnone">
|
||||||
|
{{- if $content.Extent -}}
|
||||||
|
<div>
|
||||||
|
<span class="font-sans text-sm">S. </span>
|
||||||
|
<b>{{- $content.Extent -}}</b>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $content.MusenalmType -}}
|
||||||
|
<div class="flex flex-col gap-y-1 items-end">
|
||||||
|
{{- range $_, $t := $content.MusenalmType -}}
|
||||||
|
<div class="font-sans text-sm bg-stone-100 px-1 py-0.5 rounded w-max">
|
||||||
|
{{- $t -}}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grow columntwo">
|
||||||
|
<div class="fields">
|
||||||
|
{{- if $content.TitleStmt -}}
|
||||||
|
<div class="fieldlabel">Titel</div>
|
||||||
|
<div class="italic fieldvalue">{{- $content.TitleStmt -}}</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $content.IncipitStmt -}}
|
||||||
|
<div class="fieldlabel">Incipit</div>
|
||||||
|
<div class="italic fieldvalue">{{ $content.IncipitStmt }}…</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $content.ResponsibilityStmt -}}
|
||||||
|
<div class="fieldlabel">Autorangabe</div>
|
||||||
|
<div class="fieldvalue italic">{{- $content.ResponsibilityStmt -}}</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $rcas -}}
|
||||||
|
<div class="fieldlabel">Personen</div>
|
||||||
|
<div class="fieldvalue">
|
||||||
|
{{- range $_, $rca := $rcas -}}
|
||||||
|
<div class="flex flex-col gap-y-2">
|
||||||
|
{{- $agent := index $agents $rca.Agent -}}
|
||||||
|
{{- if $agent -}}
|
||||||
|
<div class="font-sans text-base bg-stone-100 px-1 py-0.5 rounded w-max mb-1">
|
||||||
|
<a href="/person/{{- $agent.Id -}}">{{- $agent.Name -}}</a>
|
||||||
|
({{ $agent.BiographicalData -}})
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $content.Annotation -}}
|
||||||
|
<div class="fieldlabel">Anmerkung</div>
|
||||||
|
<div class="fieldvalue">
|
||||||
|
{{- Safe (LinksAnnotation (ReplaceSlashParen
|
||||||
|
$content.Annotation))
|
||||||
|
-}}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{- $scans := $content.ImagePaths -}}
|
||||||
|
{{- $slen := len $scans -}}
|
||||||
|
{{- $double := false -}}
|
||||||
|
{{- if gt $slen 2 -}}
|
||||||
|
{{- $double = true -}}
|
||||||
|
{{- end -}}
|
||||||
|
<div
|
||||||
|
class="{{- if $double }}
|
||||||
|
w-[20rem]
|
||||||
|
{{- else }}
|
||||||
|
w-[10rem]
|
||||||
|
{{- end }} grow-0 shrink-0 columnthree">
|
||||||
|
{{- if $scans -}}
|
||||||
|
<div class="{{- if $double -}}grid grid-cols-2{{- end -}}">
|
||||||
|
{{- range $_, $scan := $scans -}}
|
||||||
|
<div
|
||||||
|
class="border-6 hover:border-zinc-400 transition-all duration-75
|
||||||
|
border-zinc-100 overflow-hidden">
|
||||||
|
<popup-image data-image-url="{{- $scan -}}">
|
||||||
|
<img
|
||||||
|
src="{{- $scan -}}?thumb=300x0"
|
||||||
|
class="w-36 h-36 object-cover
|
||||||
|
cursor-pointer" />
|
||||||
|
</popup-image>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-24 shrink-0 grow-0 items-end flex flex-col columnfour">
|
||||||
|
<div class="font-sans text-sm bg-stone-100 px-2 font-bold py-0.5 rounded w-max">
|
||||||
|
<span class="text-xs font-normal pr-1">NR</span>
|
||||||
|
{{ $content.MusenalmID -}}
|
||||||
|
</div>
|
||||||
|
<div class="font-sans py-0.5 text-xs">
|
||||||
|
<a
|
||||||
|
href="/beitreag/{{ $content.MusenalmID }}"
|
||||||
|
class="no-underline rounded bg-stone-100 px-1.5">
|
||||||
|
<i class="ri-links-line"></i> Permalink
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
23
views/routes/components/_contentlist.gohtml
Normal file
23
views/routes/components/_contentlist.gohtml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{{ $model := . }}
|
||||||
|
{{/* .result:
|
||||||
|
type AlmanachResult struct {
|
||||||
|
Entry *dbmodels.Entry
|
||||||
|
Places []*dbmodels.Place
|
||||||
|
Series []*dbmodels.Series
|
||||||
|
Contents []*dbmodels.Content
|
||||||
|
Agents map[string]*dbmodels.Agent // <- Key is agent id
|
||||||
|
EntriesSeries map[string]*dbmodels.REntriesSeries // <- Key is series id
|
||||||
|
EntriesAgents []*dbmodels.REntriesAgents
|
||||||
|
ContentsAgents map[string][]*dbmodels.RContentsAgents // <- Key is content id
|
||||||
|
}
|
||||||
|
|
||||||
|
.parameters {
|
||||||
|
Sort string
|
||||||
|
MusenalmID string
|
||||||
|
PersonFilter string
|
||||||
|
TitleFilter string
|
||||||
|
EntryFilter string
|
||||||
|
TypeFilter []string
|
||||||
|
Scanfilter bool
|
||||||
|
}
|
||||||
|
*/}}
|
||||||
@@ -15,6 +15,7 @@ const SCROLL_BUTTON_ELEMENT = "scroll-button";
|
|||||||
const TOOLTIP_ELEMENT = "tool-tip";
|
const TOOLTIP_ELEMENT = "tool-tip";
|
||||||
const ABBREV_TOOLTIPS_ELEMENT = "abbrev-tooltips";
|
const ABBREV_TOOLTIPS_ELEMENT = "abbrev-tooltips";
|
||||||
const INT_LINK_ELEMENT = "int-link";
|
const INT_LINK_ELEMENT = "int-link";
|
||||||
|
const POPUP_IMAGE_ELEMENT = "popup-image";
|
||||||
|
|
||||||
class XSLTParseProcess {
|
class XSLTParseProcess {
|
||||||
#processors;
|
#processors;
|
||||||
@@ -567,6 +568,88 @@ class ToolTip extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PopupImage extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.overlay = null;
|
||||||
|
this._preview = null;
|
||||||
|
this._description = null;
|
||||||
|
this._imageURL = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
this._imageURL = this.getAttribute("data-image-url") || "";
|
||||||
|
this._preview = this.querySelector("img");
|
||||||
|
this._description = this.querySelector(".image-description");
|
||||||
|
|
||||||
|
if (this._preview) {
|
||||||
|
this._preview.addEventListener("click", () => {
|
||||||
|
this.showOverlay();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
// Optionally remove the overlay if the element is removed from the DOM
|
||||||
|
if (this.overlay && this.overlay.parentNode) {
|
||||||
|
this.overlay.parentNode.removeChild(this.overlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showOverlay() {
|
||||||
|
const descriptionHtml = this._description ? this._description.innerHTML : "";
|
||||||
|
this.overlay = document.createElement("div");
|
||||||
|
this.overlay.classList.add(
|
||||||
|
"fixed",
|
||||||
|
"inset-0",
|
||||||
|
"z-50",
|
||||||
|
"bg-black/70",
|
||||||
|
"flex",
|
||||||
|
"items-center",
|
||||||
|
"justify-center",
|
||||||
|
"p-4",
|
||||||
|
);
|
||||||
|
|
||||||
|
this.overlay.innerHTML = `
|
||||||
|
<div class="relative w-max max-w-dvw max-h-dvh shadow-lg flex flex-col items-center gap-4">
|
||||||
|
<button class="absolute top-0 -right-16 text-white hover:text-gray-300 cursor-pointer focus:outline-none" aria-label="Close popup">
|
||||||
|
<i class="ri-close-fill text-4xl"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<img
|
||||||
|
src="${this._imageURL}"
|
||||||
|
alt="Popup Image"
|
||||||
|
class="max-h-[90vh] max-w-[80vw] object-contain"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="text-center text-gray-700 description-content">
|
||||||
|
${descriptionHtml}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const closeButton = this.overlay.querySelector("button");
|
||||||
|
if (closeButton) {
|
||||||
|
closeButton.addEventListener("click", () => {
|
||||||
|
this.hideOverlay();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.overlay.addEventListener("click", (evt) => {
|
||||||
|
if (evt.target === this.overlay) {
|
||||||
|
this.hideOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.appendChild(this.overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
hideOverlay() {
|
||||||
|
this.overlay.parentNode.removeChild(this.overlay);
|
||||||
|
this.overlay = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class AbbreviationTooltips extends HTMLElement {
|
class AbbreviationTooltips extends HTMLElement {
|
||||||
static get observedAttributes() {
|
static get observedAttributes() {
|
||||||
return ["data-text", "data-abbrevmap"];
|
return ["data-text", "data-abbrevmap"];
|
||||||
@@ -772,5 +855,6 @@ customElements.define(ABBREV_TOOLTIPS_ELEMENT, AbbreviationTooltips);
|
|||||||
customElements.define(FILTER_LIST_ELEMENT, FilterList);
|
customElements.define(FILTER_LIST_ELEMENT, FilterList);
|
||||||
customElements.define(SCROLL_BUTTON_ELEMENT, ScrollButton);
|
customElements.define(SCROLL_BUTTON_ELEMENT, ScrollButton);
|
||||||
customElements.define(TOOLTIP_ELEMENT, ToolTip);
|
customElements.define(TOOLTIP_ELEMENT, ToolTip);
|
||||||
|
customElements.define("popup-image", PopupImage);
|
||||||
|
|
||||||
export { XSLTParseProcess, FilterList, ScrollButton, AbbreviationTooltips };
|
export { XSLTParseProcess, FilterList, ScrollButton, AbbreviationTooltips };
|
||||||
|
|||||||
@@ -406,4 +406,37 @@
|
|||||||
#extendedsearchcolumn label {
|
#extendedsearchcolumn label {
|
||||||
@apply col-span-3 bg-stone-200 align-middle px-2.5 text-slate-900 items-center flex text-base;
|
@apply col-span-3 bg-stone-200 align-middle px-2.5 text-slate-900 items-center flex text-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content .fields {
|
||||||
|
@apply grid grid-cols-10 gap-y-0.5 w-full gap-x-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content .fieldlabel {
|
||||||
|
@apply col-span-1 font-bold whitespace-nowrap grow-0 shrink-0 font-sans text-sm align-baseline mt-1 text-right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content .fieldvalue {
|
||||||
|
@apply col-span-9 font-serif text-left grow align-top max-w-[60ch];
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
@apply text-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
#almanachcontents .content {
|
||||||
|
@apply border-b-8 border-stone-50;
|
||||||
|
}
|
||||||
|
|
||||||
|
#almanachcontents .columnone {
|
||||||
|
@apply bg-stone-50 pt-2 pr-3 mr-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#almanachcontents .columntwo {
|
||||||
|
@apply bg-stone-100 py-4 pl-6 ml-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#almanachcontents .columnthree {
|
||||||
|
@apply bg-stone-100 pr-6 py-4;
|
||||||
|
/*direction: rtl;*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user