mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-28 16:55:32 +00:00
Abschluss einfache Inhaltsuche
This commit is contained in:
@@ -67,6 +67,39 @@ func (p *BeitraegeFilterParameters) FieldSetBeitraege() []dbmodels.FTS5QueryRequ
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p BeitraegeFilterParameters) ToQueryParams() string {
|
||||
r := ""
|
||||
if p.Agent != "" {
|
||||
r += "&" + FILTER_PARAM_BEIAEGE_AGENT + "=" + p.Agent
|
||||
}
|
||||
if p.Type != "" {
|
||||
r += "&" + FILTER_PARAM_BEIAEGE_TYPE + "=" + p.Type
|
||||
}
|
||||
if p.Year != "" {
|
||||
r += "&" + FILTER_PARAM_BEIAEGE_YEAR + "=" + p.Year
|
||||
}
|
||||
if p.OnlyScans {
|
||||
r += "&" + FILTER_PARAM_BEIAEGE_ONLYSCANS + "=on"
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func (p BeitraegeFilterParameters) ToQueryParamsWOScans() string {
|
||||
r := ""
|
||||
if p.Agent != "" {
|
||||
r += "&" + FILTER_PARAM_BEIAEGE_AGENT + "=" + p.Agent
|
||||
}
|
||||
if p.Type != "" {
|
||||
r += "&" + FILTER_PARAM_BEIAEGE_TYPE + "=" + p.Type
|
||||
}
|
||||
if p.Year != "" {
|
||||
r += "&" + FILTER_PARAM_BEIAEGE_YEAR + "=" + p.Year
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
type SearchResultBeitraege struct {
|
||||
Queries []dbmodels.FTS5QueryRequest
|
||||
|
||||
|
||||
@@ -21,14 +21,12 @@
|
||||
{{ end }}
|
||||
|
||||
|
||||
<script type="module" src="/assets/scripts.js"></script>
|
||||
|
||||
<script src="/assets/js/alpine.min.js" defer></script>
|
||||
<script src="/assets/js/htmx.min.js" defer></script>
|
||||
<script src="/assets/js/htmx-response-targets.js" defer></script>
|
||||
<script src="/assets/js/client-side-templates.js" defer></script>
|
||||
<script src="/assets/js/mark.min.js" defer></script>
|
||||
|
||||
<script type="module" src="/assets/scripts.js"></script>
|
||||
<link href="/assets/css/remixicon.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/fonts.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/assets/style.css" />
|
||||
|
||||
@@ -140,14 +140,15 @@
|
||||
|
||||
{{- template "_fieldscript" -}}
|
||||
{{- if $model.parameters.IsBeitraegeSearch -}}
|
||||
<div class="cotents" id="searchresult">
|
||||
<div class="cotents" id="searchresults">
|
||||
{{- if $model.result.Hits -}}
|
||||
{{ template "_filterlist" $model }}
|
||||
{{- end -}}
|
||||
|
||||
|
||||
<div class="container-normal">
|
||||
<div class="container-normal" id="subresults">
|
||||
{{ template "tablehead" $model }}
|
||||
{{ template "pills" $model }}
|
||||
{{- if $model.result.Hits -}}
|
||||
<div class="mt-8" id="almanachcontents">
|
||||
{{- range $_, $hit := $model.result.Hits -}}
|
||||
|
||||
38
views/routes/suche/beitraege/pills.gohtml
Normal file
38
views/routes/suche/beitraege/pills.gohtml
Normal file
@@ -0,0 +1,38 @@
|
||||
{{ $model := . }}
|
||||
|
||||
{{- $isFiltered := or $model.filters.Agent $model.filters.Year $model.filters.Type
|
||||
$model.filters.OnlyScans
|
||||
-}}
|
||||
|
||||
{{- if $isFiltered -}}
|
||||
<div class="flex flex-row gap-x-3" id="searchpills">
|
||||
{{- if $model.filters.Agent -}}
|
||||
<filter-pill
|
||||
data-queryparam="agentfilter"
|
||||
data-value="{{ $model.filters.Agent }}"
|
||||
data-text="Person">
|
||||
</filter-pill>
|
||||
{{- end -}}
|
||||
{{- if $model.filters.Year -}}
|
||||
<filter-pill
|
||||
data-queryparam="yearfilter"
|
||||
data-value="{{ $model.filters.Year }}"
|
||||
data-text="Jahr">
|
||||
</filter-pill>
|
||||
{{- end -}}
|
||||
{{- if $model.filters.Type -}}
|
||||
<filter-pill
|
||||
data-queryparam="typefilter"
|
||||
data-value="{{ $model.filters.Type }}"
|
||||
data-text="Typ">
|
||||
</filter-pill>
|
||||
{{- end -}}
|
||||
{{- if $model.filters.OnlyScans -}}
|
||||
<filter-pill
|
||||
data-queryparam="onlyscans"
|
||||
data-value="{{ $model.filters.OnlyScans }}"
|
||||
data-text="Nur Digitalisate">
|
||||
</filter-pill>
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- end -}}
|
||||
@@ -63,11 +63,12 @@
|
||||
id="onlyscans"
|
||||
name="onlyscans"
|
||||
autocomplete="off"
|
||||
hx-get="{{- $model.parameters.ToQueryParamsBeitraege -}}"
|
||||
hx-get="{{- $model.parameters.ToQueryParamsBeitraege -}} {{- $model.filters.ToQueryParamsWOScans -}}"
|
||||
trigger="change"
|
||||
hx-push-url="true"
|
||||
hx-select="main"
|
||||
hx-target="main"
|
||||
hx-select="#searchresults"
|
||||
hx-target="#searchresults"
|
||||
hx-swap="outerHTML"
|
||||
{{ if $model.filters.OnlyScans -}}checked{{- end -}} />
|
||||
|
||||
<label
|
||||
@@ -82,11 +83,12 @@
|
||||
name="sort"
|
||||
id="sort"
|
||||
autocomplete="off"
|
||||
hx-get="{{- $model.parameters.ToQueryParamsBeitraege -}}"
|
||||
hx-get="{{- $model.parameters.ToQueryParamsBeitraege -}}{{- $model.filters.ToQueryParams -}}"
|
||||
trigger="change"
|
||||
hx-push-url="true"
|
||||
hx-select="main"
|
||||
hx-target="main">
|
||||
hx-select="#subresults"
|
||||
hx-target="#subresults"
|
||||
hx-swap="outerHTML show:window:top">
|
||||
<option
|
||||
value="year"
|
||||
{{ if eq $model.parameters.Sort "year" -}}
|
||||
|
||||
@@ -3,21 +3,24 @@
|
||||
{{- $isFiltered := or $model.filters.Agent $model.filters.Year $model.filters.Type -}}
|
||||
|
||||
|
||||
<div class="container-oversize " x-data="{ filters: '{{- $isFiltered -}}' }">
|
||||
<div class="container-oversize ">
|
||||
<button
|
||||
class="w-full flex flex-row bg-slate-100 py-3 border-2 border-slate-100 hover:border-slate-900
|
||||
cursor-pointer box-content hover:[&>_h2]:font-slate-900 select-none"
|
||||
@click="filters = !filters">
|
||||
id="filterlistbtn">
|
||||
<h2 class="text-2xl text-stone-700 px-32">
|
||||
Filter
|
||||
<i class="ri-arrow-right-s-line" x-show="!filters"></i>
|
||||
<i class="ri-arrow-down-s-line" x-show="filters"></i>
|
||||
<i class="ri-arrow-right-s-line show-closed"></i>
|
||||
<i class="ri-arrow-down-s-line show-opened"></i>
|
||||
</h2>
|
||||
</button>
|
||||
<div
|
||||
class="flex flex-row px-24 justify-between bg-slate-100 py-12 border-t-4 border-stone-50"
|
||||
id="searchfilter"
|
||||
x-show="filters">
|
||||
class="flex flex-row px-24 justify-between bg-slate-100 py-12 border-t-4 border-stone-50 {{ if
|
||||
$isFiltered
|
||||
}}
|
||||
hidden
|
||||
{{ end }}"
|
||||
id="searchfilter">
|
||||
<div class="w-[30%] grow-0 shrink-0">
|
||||
<filter-list
|
||||
class=""
|
||||
@@ -48,6 +51,30 @@
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
let button = document.getElementById("filterlistbtn");
|
||||
let filter = document.getElementById("searchfilter");
|
||||
if (button && filter) {
|
||||
toggleFilter();
|
||||
if (button && filter) {
|
||||
button.addEventListener("click", () => {
|
||||
toggleFilter();
|
||||
});
|
||||
}
|
||||
|
||||
function toggleFilter() {
|
||||
if (filter.classList.contains("hidden")) {
|
||||
filter.classList.remove("hidden");
|
||||
button.querySelector(".show-closed").classList.add("hidden");
|
||||
button.querySelector(".show-opened").classList.remove("hidden");
|
||||
} else {
|
||||
filter.classList.add("hidden");
|
||||
button.querySelector(".show-closed").classList.remove("hidden");
|
||||
button.querySelector(".show-opened").classList.add("hidden");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let agentList = document.getElementById("agent-list");
|
||||
if (agentList) {
|
||||
agentList.items = {{ $model.result.AgentsList }};
|
||||
|
||||
@@ -17,6 +17,7 @@ const ABBREV_TOOLTIPS_ELEMENT = "abbrev-tooltips";
|
||||
const INT_LINK_ELEMENT = "int-link";
|
||||
const POPUP_IMAGE_ELEMENT = "popup-image";
|
||||
const TABLIST_ELEMENT = "tab-list";
|
||||
const FILTER_PILL_ELEMENT = "filter-pill";
|
||||
|
||||
class XSLTParseProcess {
|
||||
#processors;
|
||||
@@ -107,6 +108,100 @@ function setup_templates() {
|
||||
});
|
||||
}
|
||||
|
||||
class FilterPill extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this._value = "";
|
||||
this.render();
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["data-text", "data-queryparam", "data-value"];
|
||||
}
|
||||
|
||||
set value(value) {
|
||||
this.setAttribute("data-value", value);
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.getAttribute("data-value") || "";
|
||||
}
|
||||
|
||||
set text(value) {
|
||||
this.setAttribute("data-text", value);
|
||||
}
|
||||
|
||||
get text() {
|
||||
return this.getAttribute("data-text") || "";
|
||||
}
|
||||
|
||||
set queryparam(value) {
|
||||
this.setAttribute("data-queryparam", value);
|
||||
}
|
||||
|
||||
get queryparam() {
|
||||
return this.getAttribute("data-queryparam") || "";
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this._filter = this.text;
|
||||
this._queryparam = this.queryparam;
|
||||
this.render();
|
||||
htmx.process(this);
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (oldValue !== newValue) {
|
||||
if (name === "data-text") {
|
||||
this._filter = newValue;
|
||||
}
|
||||
if (name === "data-queryparam") {
|
||||
this._queryparam = newValue;
|
||||
}
|
||||
if (name === "data-value") {
|
||||
this._value = newValue;
|
||||
}
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
getURL() {
|
||||
if (this._queryparam) {
|
||||
let url = new URL(window.location);
|
||||
let params = new URLSearchParams(url.search);
|
||||
params.delete(this._queryparam);
|
||||
params.delete("page");
|
||||
url.search = params.toString();
|
||||
return url.toString();
|
||||
}
|
||||
return "#";
|
||||
}
|
||||
|
||||
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">
|
||||
<div class="flex flex-row filter-pill rounded-lg bg-orange-100 hover:-saturate-100 px-2.5 mt-2">
|
||||
<div href="${this.getURL()}" class="filter-pill-close no-underline font-bold mr-1 text-orange-900 hover:text-orange-800">
|
||||
<i class="ri-close-circle-line"></i>
|
||||
</div>
|
||||
<div class="flex flex-row filter-pill-label-value !items-baseline text-slate-700">
|
||||
<div class="filter-pill-label font-bold mr-1.5 align-baseline">${this.text}</div>
|
||||
${this.renderValue()}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
|
||||
renderValue() {
|
||||
const isBool = this.value === "true" || this.value === "false";
|
||||
if (isBool) return ``;
|
||||
return `
|
||||
<div class="filter-pill-value">${this.value}</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
class FilterList extends HTMLElement {
|
||||
#hiddenlist = false;
|
||||
#activequery = "";
|
||||
@@ -318,6 +413,7 @@ class FilterList extends HTMLElement {
|
||||
let url = new URL(window.location);
|
||||
let params = new URLSearchParams(url.search);
|
||||
params.set(this._queryparam, this.getHREF(item));
|
||||
params.delete("page");
|
||||
url.search = params.toString();
|
||||
return url.toString();
|
||||
}
|
||||
@@ -1018,5 +1114,6 @@ customElements.define(SCROLL_BUTTON_ELEMENT, ScrollButton);
|
||||
customElements.define(TOOLTIP_ELEMENT, ToolTip);
|
||||
customElements.define(POPUP_IMAGE_ELEMENT, PopupImage);
|
||||
customElements.define(TABLIST_ELEMENT, Tablist);
|
||||
customElements.define(FILTER_PILL_ELEMENT, FilterPill);
|
||||
|
||||
export { XSLTParseProcess, FilterList, ScrollButton, AbbreviationTooltips };
|
||||
|
||||
@@ -312,6 +312,18 @@
|
||||
@apply border shadow-inner;
|
||||
}
|
||||
|
||||
#searchpills {
|
||||
@apply flex flex-row gap-x-2.5;
|
||||
}
|
||||
|
||||
#searchpills filter-pill .filter-pill {
|
||||
@appply px-2.5 rounded-lg bg-orange-300;
|
||||
}
|
||||
|
||||
#searchresults .filter-list-item[aria-current="page"] {
|
||||
@apply text-orange-800 border-orange-900 bg-orange-100 pointer-events-none;
|
||||
}
|
||||
|
||||
#persontype a {
|
||||
@apply px-1.5 border-b-[5px] border-transparent hover:border-zinc-200 no-underline font-serif mx-2.5;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user