+some small frontend annoyances

This commit is contained in:
Simon Martens
2026-01-21 23:35:45 +01:00
parent 8f4558e331
commit c0146aadfb
8 changed files with 1183 additions and 1062 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -73,7 +73,7 @@
<div class="mt-8">
{{- range $i, $c := $model.result.Contents -}}
{{- $rels := index $model.result.ContentsAgents $c.Id -}}
{{- template "_content" Arr $c $model.result.Entry $rels $model.result.Agents -}}
{{- template "_content" Arr $c $model.result.Entry $rels $model.result.Agents false false false $model.request -}}
{{- end -}}
</div>
</div>

View File

@@ -185,8 +185,8 @@
<span>Neuer Beitrag</span>
</button>
</div>
<div class="mx-4 mt-2 rounded-md border border-slate-200 bg-white flex flex-col overflow-hidden" data-role="contents-panel">
<div class="flex-1 min-h-0 overflow-y-auto">
<div class="mx-4 mt-2 rounded-md border border-slate-300 bg-white flex flex-col overflow-hidden p-1" data-role="contents-panel">
<div class="flex-1 min-h-0 overflow-y-scroll">
<div class="flex flex-col gap-0"
data-role="contents-list"
data-order-endpoint="/almanach/{{ $model.result.Entry.MusenalmID }}/contents/edit">
@@ -562,12 +562,26 @@
});
};
const setContentsPanelHeight = () => {
const panel = document.querySelector("[data-role='contents-panel']");
if (!panel) {
return;
}
const rect = panel.getBoundingClientRect();
const viewportHeight = window.innerHeight || document.documentElement.clientHeight || 0;
const bottomGap = 16;
const available = Math.max(200, viewportHeight - rect.top - bottomGap);
panel.style.height = `${available}px`;
};
const initPage = () => {
list = document.querySelector("[data-role='contents-list']");
if (!list) {
return;
}
setContentsPanelHeight();
const getItems = () => Array.from(list.querySelectorAll("[data-role='content-item']"));
if (getItems().length === 0) {
return;
@@ -903,4 +917,10 @@
initPage();
}
});
if (!window.__contentsPanelResizeBound) {
window.__contentsPanelResizeBound = true;
window.addEventListener("resize", () => {
setContentsPanelHeight();
});
}
</script>

View File

@@ -34,7 +34,15 @@
</div>
<div class="container-normal mt-12 flex flex-col font-serif">
<div class="font-sans mb-1"><i class="ri-article-line"></i> Einzelbeitrag</div>
<div class="font-sans mb-1 flex items-center gap-2">
<div><i class="ri-article-line"></i> Einzelbeitrag</div>
{{- if (IsAdminOrEditor $model.request.user) -}}
<div>
&middot;&nbsp;<i class="ri-edit-line"></i>
<a href="/almanach/{{- $model.result.Entry.MusenalmID -}}/contents/{{- $model.result.Content.MusenalmID -}}/edit">Bearbeiten</a>
</div>
{{- end -}}
</div>
<h1 class="text-3xl font-bold">
{{ $model.result.Entry.PreferredTitle }},
{{ if $model.result.Content.Extent -}}

View File

@@ -58,7 +58,10 @@
{{- $searchparameters := false -}}
{{- if gt (len .) 6 -}}
{{- $searchparameters = index . 6 -}}
{{- if or (eq (printf "%T" $searchparameters) "bool") (eq (printf "%T" $searchparameters) "<nil>") -}}
{{- $searchparameters = false -}}
{{- end -}}
{{- if $searchparameters -}}
{{- $isAlm = $searchparameters.AlmString -}}
{{- $isTitle = or $searchparameters.Title $searchparameters.TitleString -}}
{{- $isYear = or $searchparameters.Year $searchparameters.YearString -}}
@@ -66,6 +69,12 @@
{{- $isAnnotation = or $searchparameters.Annotations $searchparameters.AnnotationsString -}}
{{- $isIncipit = or $searchparameters.Incipit $searchparameters.IncipitString -}}
{{- $isEntry = or $searchparameters.Entry $searchparameters.EntryString -}}
{{- end -}}
{{- end -}}
{{- $request := false -}}
{{- if gt (len .) 7 -}}
{{- $request = index . 7 -}}
{{- end -}}
@@ -204,12 +213,19 @@
</div>
{{- end -}}
{{- end -}}
<div class="font-sans py-0.5 text-sm">
<div class="font-sans py-0.5 text-sm flex flex-col items-end gap-1">
<a
href="/beitrag/{{ $content.MusenalmID }}"
class="no-underline rounded bg-stone-100 px-1.5">
Link <i class="ri-links-line"></i>
</a>
{{- if and $request (IsAdminOrEditor $request.user) -}}
<a
href="/almanach/{{- $entry.MusenalmID -}}/contents/{{- $content.MusenalmID -}}/edit"
class="no-underline rounded bg-stone-100 px-1.5">
<i class="ri-edit-line"></i> Bearbeiten
</a>
{{- end -}}
</div>
</div>
{{- end -}}

View File

@@ -35,7 +35,7 @@
{{- if (IsAdminOrEditor $request.user) -}}
<a href="/reihe/{{ $r.MusenalmID }}/edit" class="no-underline rounded bg-stone-100 px-1.5">
<i class="ri-edit-line"></i>
Edit
Bearbeiten
</a>
{{- end -}}
</div>

View File

@@ -25,6 +25,9 @@ export class FabMenu extends HTMLElement {
let hasEntry = false,
entryId = "",
entryUpdated = "";
let hasContent = false,
contentId = "",
contentEntryId = "";
let hasPage = false,
pageKey = "";
@@ -59,6 +62,20 @@ export class FabMenu extends HTMLElement {
}
}
// Content detail page: /beitrag/{id}
const contentMatch = path.match(/^\/beitrag\/([^\/]+)\/?$/);
if (contentMatch) {
hasContent = true;
contentId = contentMatch[1];
const entryLink = document.querySelector('#breadcrumbs a[href^="/almanach/"]');
if (entryLink) {
const match = entryLink.getAttribute("href")?.match(/^\/almanach\/([^\/#]+)/);
if (match) {
contentEntryId = match[1];
}
}
}
// Page views use page editor keys via meta tag or URL mapping
const pageKeyMeta = document.querySelector('meta[name="page-key"]');
if (pageKeyMeta && pageKeyMeta.content) {
@@ -95,11 +112,11 @@ export class FabMenu extends HTMLElement {
}
const hasCsrf = csrfToken !== "";
this.hasContext = hasReihe || hasPerson || hasEntry || hasPage;
this.hasContext = hasReihe || hasPerson || hasEntry || hasContent || hasPage;
// Build half-open menu content
let halfOpenContent = "";
if (hasReihe) {
if (isAdminOrEditor && hasReihe) {
halfOpenContent = `
<div class="px-3 py-1.5 text-xs font-semibold text-gray-500 uppercase tracking-wider">
Reihe
@@ -109,7 +126,7 @@ export class FabMenu extends HTMLElement {
<span class="text-gray-900">Bearbeiten</span>
</a>
`;
} else if (hasPerson) {
} else if (isAdminOrEditor && hasPerson) {
halfOpenContent = `
<div class="px-3 py-1.5 text-xs font-semibold text-gray-500 uppercase tracking-wider">
Person
@@ -119,7 +136,7 @@ export class FabMenu extends HTMLElement {
<span class="text-gray-900">Bearbeiten</span>
</a>
`;
} else if (hasEntry) {
} else if (isAdminOrEditor && hasEntry) {
halfOpenContent = `
<div class="px-3 py-1.5 text-xs font-semibold text-gray-500 uppercase tracking-wider">
Almanach
@@ -128,8 +145,34 @@ export class FabMenu extends HTMLElement {
<i class="ri-edit-line text-base text-gray-700 mr-2.5"></i>
<span class="text-gray-900">Bearbeiten</span>
</a>
<a href="/almanach/${entryId}/contents/edit" class="flex items-center px-4 py-2 hover:bg-gray-100 transition-colors no-underline text-sm">
<i class="ri-file-list-3-line text-base text-gray-700 mr-2.5"></i>
<span class="text-gray-900">Beiträge bearbeiten</span>
</a>
<a href="/almanach/${entryId}/contents/new" class="flex items-center px-4 py-2 hover:bg-gray-100 transition-colors no-underline text-sm">
<i class="ri-add-line text-base text-gray-700 mr-2.5"></i>
<span class="text-gray-900">Neuer Beitrag</span>
</a>
`;
} else if (hasPage) {
} else if (isAdminOrEditor && hasContent && contentEntryId) {
halfOpenContent = `
<div class="px-3 py-1.5 text-xs font-semibold text-gray-500 uppercase tracking-wider">
Beitrag
</div>
<a href="/almanach/${contentEntryId}/contents/${contentId}/edit" class="flex items-center px-4 py-2 hover:bg-gray-100 transition-colors no-underline text-sm">
<i class="ri-edit-line text-base text-gray-700 mr-2.5"></i>
<span class="text-gray-900">Bearbeiten</span>
</a>
<a href="/almanach/${contentEntryId}/contents/edit" class="flex items-center px-4 py-2 hover:bg-gray-100 transition-colors no-underline text-sm">
<i class="ri-file-list-3-line text-base text-gray-700 mr-2.5"></i>
<span class="text-gray-900">Beiträge bearbeiten</span>
</a>
<a href="/almanach/${contentEntryId}/contents/new" class="flex items-center px-4 py-2 hover:bg-gray-100 transition-colors no-underline text-sm">
<i class="ri-add-line text-base text-gray-700 mr-2.5"></i>
<span class="text-gray-900">Neuer Beitrag</span>
</a>
`;
} else if (isAdminOrEditor && hasPage) {
halfOpenContent = `
<div class="px-3 py-1.5 text-xs font-semibold text-gray-500 uppercase tracking-wider">
Seite