mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-29 09:15:33 +00:00
Merge branch 'main' of github.com:Theodor-Springmann-Stiftung/musenalm
This commit is contained in:
@@ -28,33 +28,8 @@ Modelle umwandeln (zzt RecordProxy)
|
||||
- Ersellen & Abfragen FTS5-Tabellen
|
||||
- Erstellen Textseiten
|
||||
|
||||
- Technologie-Stack auf Server-Rendering / Go Templates umgestellt
|
||||
- Die Seiten sollten jetzt insgesamt schneller laden
|
||||
|
||||
- Man kann auf der Startseite und in der Suche nach Almanach-Nummern suchen
|
||||
- Überall werden die Almanachnummer und Inhaltsnummer angezeigt
|
||||
- Die URL referenziert die Almanachnummern, nicht mher die Datenbank-IDs
|
||||
|
||||
- In der Almanach-Ansicht werden die Abkürzungen erklärt
|
||||
- In der Almanach- und Suchansicht werden Sammlungen abgehoben
|
||||
- In der Almanach- und Suchansicht werden auch mehrere Bilder zu einem Eintrag angezeigt, falls vorhanden
|
||||
- In der Almanach- und Suchansicht kann nach Inhalten frei gefiltert werden, oder nach Typ
|
||||
|
||||
- Es gibt URLs, die fest verlinkt werden können für einzelne:
|
||||
- Personen
|
||||
- Reihen
|
||||
- Bände
|
||||
- Beiträge
|
||||
- Alle Suchanfragen
|
||||
|
||||
- Die Suche ist klar nach Typ unterteilt und insgesamt zuverlässiger
|
||||
- Zusätzlich zur jetzigen Suchfunktion gibt es für Beiträge und Bände noch eine Detailsuche
|
||||
- Suchergebnisse können nach Typ, Person, Jahr gefiltert werden
|
||||
- Suchergebnisse könnnen nach Jahr und Band, nach Band und Jahr (nach Personen) sortiert werden
|
||||
|
||||
|
||||
TODO danach:
|
||||
- Google-Suchoptimierung
|
||||
- Error Pages prüfen & error-Verhalten von HTMX
|
||||
- Weißraum in den Antworten
|
||||
- Antworten komprimieren
|
||||
|
||||
@@ -3,7 +3,7 @@ var x = (r) => {
|
||||
};
|
||||
var _ = (r, t, e) => t.has(r) || x("Cannot " + e);
|
||||
var c = (r, t, e) => (_(r, t, "read from private field"), e ? e.call(r) : t.get(r)), n = (r, t, e) => t.has(r) ? x("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(r) : t.set(r, e), u = (r, t, e, i) => (_(r, t, "write to private field"), i ? i.call(r, e) : t.set(r, e), e), g = (r, t, e) => (_(r, t, "access private method"), e);
|
||||
const S = "script[xslt-onload]", w = "xslt-template", k = "xslt-transformed", M = "filter-list", m = "filter-list-list", C = "filter-list-item", I = "filter-list-input", y = "filter-list-searchable", B = "scroll-button", q = "tool-tip", P = "abbrev-tooltips", R = "int-link", H = "popup-image", $ = "tab-list", N = "filter-pill", F = "image-reel";
|
||||
const S = "script[xslt-onload]", w = "xslt-template", k = "xslt-transformed", M = "filter-list", m = "filter-list-list", C = "filter-list-item", I = "filter-list-input", y = "filter-list-searchable", B = "scroll-button", q = "tool-tip", P = "abbrev-tooltips", H = "int-link", R = "popup-image", $ = "tab-list", N = "filter-pill", F = "image-reel";
|
||||
var d, b, E;
|
||||
class V {
|
||||
constructor() {
|
||||
@@ -77,7 +77,7 @@ class O extends HTMLElement {
|
||||
}
|
||||
render() {
|
||||
this.innerHTML = `
|
||||
<a href="${this.getURL()}" class="!no-underline block text-base" hx-target="#searchresults" hx-select="#searchresults" hx-swap="outerHTML show:window:top">
|
||||
<a href="${this.getURL()}" class="!no-underline block text-base" hx-target="#searchresults" hx-select="#searchresults" hx-indicator="body" hx-swap="outerHTML show:window:top">
|
||||
<div class="flex flex-row filter-pill rounded-lg bg-orange-100 hover:saturate-50 px-2.5">
|
||||
${this.renderIcon()}
|
||||
<div class="flex flex-row filter-pill-label-value !items-baseline text-slate-700">
|
||||
@@ -119,7 +119,7 @@ class U extends HTMLElement {
|
||||
return ["data-url"];
|
||||
}
|
||||
set items(e) {
|
||||
Array.isArray(e) && (this._items = e, this.render()), htmx && htmx.process(this);
|
||||
Array.isArray(e) && (this._items = e, this.render());
|
||||
}
|
||||
get items() {
|
||||
return this._items;
|
||||
@@ -216,7 +216,7 @@ class U extends HTMLElement {
|
||||
${this.Input()}
|
||||
${this.List()}
|
||||
</div>
|
||||
`;
|
||||
`, htmx && htmx.process(this);
|
||||
}
|
||||
ActiveDot(e) {
|
||||
return g(this, f, L).call(this, e), "";
|
||||
@@ -252,6 +252,10 @@ class U extends HTMLElement {
|
||||
(i, s) => `
|
||||
<a
|
||||
href="${this.getURL(i)}"
|
||||
hx-indicator="body"
|
||||
hx-swap="outerHTML show:none"
|
||||
hx-select="main"
|
||||
hx-target="main"
|
||||
class="${C} block px-2.5 py-0.5 hover:bg-slate-200 no-underline ${s % 2 === 0 ? "bg-stone-100" : "bg-stone-50"}"
|
||||
${g(this, f, L).call(this, i) ? 'aria-current="page"' : ""}>
|
||||
${this.ActiveDot(i)}
|
||||
@@ -741,12 +745,12 @@ class X extends HTMLElement {
|
||||
}
|
||||
}
|
||||
v = new WeakMap();
|
||||
customElements.define(R, K);
|
||||
customElements.define(H, K);
|
||||
customElements.define(P, p);
|
||||
customElements.define(M, U);
|
||||
customElements.define(B, D);
|
||||
customElements.define(q, z);
|
||||
customElements.define(H, G);
|
||||
customElements.define(R, G);
|
||||
customElements.define($, j);
|
||||
customElements.define(N, O);
|
||||
customElements.define(F, X);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -43,9 +43,10 @@
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="w-full h-full min-h-full" hx-ext="response-targets" hx-boost="true">
|
||||
<body class="w-full min-h-full" hx-ext="response-targets" hx-boost="true">
|
||||
<div class="pb-12">
|
||||
{{ block "body" . }}
|
||||
<!-- Default app body... -->
|
||||
<!-- Default app body... -->
|
||||
{{ end }}
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
Musenalm – {{ .result.Entry.PreferredTitle }},
|
||||
{{ if .result.Content.TitleStmt -}}
|
||||
{{ .result.Content.TitleStmt }}
|
||||
{{ else if .result.Content.Incipit -}}
|
||||
{{ .result.Content.Incipit }}
|
||||
{{ else if .result.Content.IncipitStmt -}}
|
||||
{{ .result.Content.IncipitStmt }}
|
||||
{{ else -}}
|
||||
Nr.
|
||||
{{ .result.Content.MusenalmID }}
|
||||
@@ -15,8 +15,8 @@
|
||||
content="Almanach: {{ .result.Entry.PreferredTitle }},
|
||||
{{ if .result.Content.TitleStmt -}}
|
||||
{{ .result.Content.TitleStmt }}
|
||||
{{ else if .result.Content.Incipit -}}
|
||||
{{ .result.Content.Incipit }}
|
||||
{{ else if .result.Content.IncipitStmt -}}
|
||||
{{ .result.Content.IncipitStmt }}
|
||||
{{ else -}}
|
||||
Nr.
|
||||
{{ .result.Content.MusenalmID }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{{- $model := . -}}
|
||||
<div id="intropageroot">
|
||||
<div id="intropageroot" class="!mb-12">
|
||||
<image-reel class="hidden lg:block max-w-full my-8 mx-12 relative" id="imagecontainer">
|
||||
<div class="overflow-hidden flex flex-row justify-between">
|
||||
{{- range $i, $img := $model.bilder -}}
|
||||
@@ -22,8 +22,8 @@
|
||||
</div>
|
||||
</image-reel>
|
||||
|
||||
<div class="w-full min-h-full mt-8">
|
||||
<div class="text-center relative max-w-screen-xl mx-auto" data-="">
|
||||
<div class="w-full min-h-full mt-8 mb-12">
|
||||
<div class="text-center relative max-w-screen-xl mx-auto">
|
||||
<img
|
||||
src="/assets/musen.png"
|
||||
class="max-w-[28rem] mx-auto lg:absolute left-2/3 top-2"
|
||||
@@ -43,7 +43,7 @@
|
||||
{{- Safe $model.texte.Abs2 -}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center mt-8 startlinks font-serif text-xl" data-="">
|
||||
<div class="text-center mt-8 startlinks font-serif text-xl">
|
||||
<a href="/redaktion/einfuehrung" class="">Einleitung</a>
|
||||
<div class="inline px-1">|</div>
|
||||
<a href="/reihen" class="font-bold">Alle Bände<i class="ri-arrow-right-double-line"></i></a>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
placeholder="Suchbegriff"
|
||||
x-model="search"
|
||||
hx-get=""
|
||||
hx-trigger="input[if: this.value.length >= 3] delay:3000ms, keyup[enter, if: this.value.length >= 2]"
|
||||
hx-trigger="input delay:1000ms, keyup[enter]"
|
||||
hx-select="#searchresults"
|
||||
hx-target="#searchresults"
|
||||
hx-swap="outerHTML"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="text ">
|
||||
{{ if .record.Title }}<h1 class="mb-12">{{ .record.Title }}</h1>{{ end }}
|
||||
<div class="flex flex-row gap-x-6 justify-between ">
|
||||
<div class="grow shrink-0 text indented">
|
||||
<div class="grow shrink-0 text indented jumptext">
|
||||
{{ Safe .record.Text }}
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -11,12 +11,16 @@
|
||||
:class="search ? 'inactive' : 'active'"
|
||||
href="?letter={{ $r }}"
|
||||
{{ if eq $model.active $r }}aria-current="page"{{ end }}
|
||||
hx-indicator="body"
|
||||
hx-select="main"
|
||||
hx-target="main"
|
||||
hx-swap="outerHTML scroll:#pageheading:top"
|
||||
hx-swap="outerHTML show:none"
|
||||
>{{ $r }}</a
|
||||
>
|
||||
{{ end }}
|
||||
|
||||
|
||||
<i class="ml-2 pb-1 ri-hourglass-2-fill request-indicator spinning"></i>
|
||||
</div>
|
||||
|
||||
<div class="flex-grow"></div>
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
id="simplesearchform"
|
||||
class="w-full font-serif"
|
||||
method="get"
|
||||
hx-indicator="body"
|
||||
action="/suche/baende"
|
||||
autocomplete="off">
|
||||
{{- if not $model.parameters.Extended -}}
|
||||
@@ -212,6 +213,10 @@
|
||||
<div class="container-normal" id="searchresults">
|
||||
<div class="border-b border-zinc-300 flex flex-row justify-between">
|
||||
<div>
|
||||
<div class="inline-block">
|
||||
<i class="ri-hourglass-2-fill request-indicator spinning"></i>
|
||||
</div>
|
||||
<div class="request-indicator">·</div>
|
||||
{{ if $model.parameters.Query -}}
|
||||
Suche nach <b>»{{ $model.parameters.Query }}«</b> ·
|
||||
{{- end -}}
|
||||
@@ -247,6 +252,7 @@
|
||||
name="sort"
|
||||
id="sort"
|
||||
hx-get="{{- $model.parameters.ToQueryParamsBaende -}}"
|
||||
hx-indicator="body"
|
||||
trigger="change"
|
||||
hx-push-url="true"
|
||||
hx-select="main"
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
id="simplesearchform"
|
||||
class="w-full font-serif"
|
||||
method="get"
|
||||
hx-indicator="body"
|
||||
action="/suche/beitraege"
|
||||
autocomplete="off">
|
||||
{{- if not $model.parameters.Extended -}}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
{{ if gt $model.parameters.Page 1 -}}
|
||||
<a
|
||||
href="{{- $model.parameters.ToQueryParamsBeitraege -}}&page={{ $model.parameters.Prev }}"
|
||||
hx-indicator="body"
|
||||
class="mr-1.5 text-stone-500 hover:text-slate-900">
|
||||
<i class="ri-arrow-left-long-line"></i>
|
||||
</a>
|
||||
@@ -13,6 +14,7 @@
|
||||
{{ if lt $model.parameters.Page ($model.result.PagesCount) -}}
|
||||
<a
|
||||
href="{{- $model.parameters.ToQueryParamsBeitraege -}}&page={{ $model.parameters.Next }}"
|
||||
hx-indicator="body"
|
||||
class="ml-1.5 text-stone-500 hover:text-slate-900">
|
||||
<i class="ri-arrow-right-long-line"></i>
|
||||
</a>
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
<div class="border-b border-zinc-300 flex flex-row justify-between">
|
||||
<div class="flex flex-row gap-x-2">
|
||||
<div><i class="ri-hourglass-2-fill request-indicator spinning"></i></div>
|
||||
<div class="request-indicator">·</div>
|
||||
{{ if $model.parameters.Query -}}
|
||||
<div>Suche nach <b>»{{ $model.parameters.Query }}«</b></div>
|
||||
<div>·</div>
|
||||
@@ -69,6 +71,7 @@
|
||||
hx-select="#searchresults"
|
||||
hx-target="#searchresults"
|
||||
hx-swap="outerHTML"
|
||||
hx-indicator="body"
|
||||
{{ if $model.filters.OnlyScans -}}checked{{- end -}} />
|
||||
|
||||
<label
|
||||
@@ -87,6 +90,7 @@
|
||||
trigger="change"
|
||||
hx-push-url="true"
|
||||
hx-select="#subresults"
|
||||
hx-indicator="body"
|
||||
hx-target="#subresults"
|
||||
hx-swap="outerHTML show:window:top">
|
||||
<option
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{{ $extendable := . }}
|
||||
|
||||
|
||||
<div class="col-span-6 flex flex-row text-stone-700 gap-x-2">
|
||||
<div class="flex flex-row text-stone-700 gap-x-2">
|
||||
<div>
|
||||
<i class="ri-information-2-fill"></i>
|
||||
</div>
|
||||
<div class="font-sans hyphens-auto text-sm pt-1">
|
||||
<div class="font-sans hyphens-auto text-sm pt-1 max-w-[48rem]">
|
||||
Die Suche durchsucht ganze Datensätze nach dem Vorkommen aller eingegebenen Suchbegriffe. Felder
|
||||
können oben einzeln aus der Suche ausgeschlossen werden. Auch partielle Treffer in Worten werden
|
||||
angezeigt. Wörter mit weniger als drei Zeichen, Sonderzeichen – auch Satzzeichen –
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
placeholder="Suchbegriff (min. 3 Zeichen)"
|
||||
class="w-full grow
|
||||
placeholder:italic font-serif placeholder:font-sans" />
|
||||
<button id="submitbutton" type="submit" class="min-w-36" form="simplesearchform">Suchen</button>
|
||||
<button id="submitbutton" type="submit" class="min-w-36" form="simplesearchform">
|
||||
<i class="ri-hourglass-2-fill request-indicator spinning mr-1"></i>Suchen
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{ if $extendable }}
|
||||
|
||||
@@ -180,7 +180,7 @@ class FilterPill extends HTMLElement {
|
||||
|
||||
render() {
|
||||
this.innerHTML = `
|
||||
<a href="${this.getURL()}" class="!no-underline block text-base" hx-target="#searchresults" hx-select="#searchresults" hx-swap="outerHTML show:window:top">
|
||||
<a href="${this.getURL()}" class="!no-underline block text-base" hx-target="#searchresults" hx-select="#searchresults" hx-indicator="body" hx-swap="outerHTML show:window:top">
|
||||
<div class="flex flex-row filter-pill rounded-lg bg-orange-100 hover:saturate-50 px-2.5">
|
||||
${this.renderIcon()}
|
||||
<div class="flex flex-row filter-pill-label-value !items-baseline text-slate-700">
|
||||
@@ -242,8 +242,6 @@ class FilterList extends HTMLElement {
|
||||
this._items = data;
|
||||
this.render();
|
||||
}
|
||||
if (!htmx) return;
|
||||
htmx.process(this);
|
||||
}
|
||||
|
||||
get items() {
|
||||
@@ -451,6 +449,8 @@ class FilterList extends HTMLElement {
|
||||
${this.List()}
|
||||
</div>
|
||||
`;
|
||||
if (!htmx) return;
|
||||
htmx.process(this);
|
||||
}
|
||||
|
||||
ActiveDot(item) {
|
||||
@@ -505,6 +505,10 @@ class FilterList extends HTMLElement {
|
||||
(item, index) => `
|
||||
<a
|
||||
href="${this.getURL(item)}"
|
||||
hx-indicator="body"
|
||||
hx-swap="outerHTML show:none"
|
||||
hx-select="main"
|
||||
hx-target="main"
|
||||
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"
|
||||
}"
|
||||
|
||||
@@ -484,7 +484,35 @@
|
||||
/*direction: rtl;*/
|
||||
}
|
||||
|
||||
body .request-indicator {
|
||||
@apply !hidden;
|
||||
}
|
||||
|
||||
.spinning {
|
||||
animation: spin 1s ease-out infinite;
|
||||
}
|
||||
|
||||
body.htmx-request #simplesearchform #sumbmitbutton {
|
||||
@apply cursor-wait pointer-events-none;
|
||||
}
|
||||
|
||||
body.htmx-request .request-indicator {
|
||||
@apply !inline-block;
|
||||
}
|
||||
|
||||
.tab-list-head[aria-pressed="true"] {
|
||||
@apply !text-slate-900 bg-stone-50;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
80% {
|
||||
transform: rotate(360deg);
|
||||
} /* Most rotation happens early */
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
} /* Pause at the final position */
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user