frontend: Add privacy link with multilingual support

Introduced a "Privacy" link in the footer, localized for supported languages. Default to German for DE UI, and English for all others.
This commit is contained in:
mhoennig
2026-07-22 11:20:38 +02:00
parent a92a87f135
commit a334c60fd1
2 changed files with 16 additions and 1 deletions
+1 -1
View File
@@ -147,7 +147,7 @@
</div> </div>
</div> </div>
<footer class="site-footer"><a href="https://github.com/mhoennig/werkbaum" target="_blank" rel="noopener">Werkbaum</a>&nbsp;<a class="ver" href="https://github.com/mhoennig/werkbaum/commits/main" target="_blank" rel="noopener">1.0</a> © 2026 <a href="https://michael.hoennig.de" target="_blank" rel="noopener">Michael Hönnig</a> · <span class="vibe" title="Fable 5 and Opus 4.8">Built with Claude Code</span> <a href="../LICENSE" target="_blank" rel="noopener">MIT-License</a> · <a href="https://michael.hoennig.de/imprint.html" target="_blank" rel="noopener" data-i18n="imprint">Impressum</a></footer> <footer class="site-footer"><a href="https://github.com/mhoennig/werkbaum" target="_blank" rel="noopener">Werkbaum</a>&nbsp;<a class="ver" href="https://github.com/mhoennig/werkbaum/commit/main" target="_blank" rel="noopener">1.0</a> © 2026 <a href="https://michael.hoennig.de" target="_blank" rel="noopener">Michael Hönnig</a> · <span class="vibe" title="Fable 5 and Opus 4.8">Built with Claude Code</span> <a href="../LICENSE" target="_blank" rel="noopener">License</a> · <a href="https://michael.hoennig.de/imprint.html" target="_blank" rel="noopener" data-i18n="imprint">Impressum</a> · <a id="privacyLink" href="https://michael.hoennig.de/datenschutzerklaerung.html" target="_blank" rel="noopener" data-i18n="privacy">Datenschutz</a></footer>
<script type="module" src="./src/app.js"></script> <script type="module" src="./src/app.js"></script>
</body> </body>
+15
View File
@@ -538,6 +538,7 @@ const I18N = {
subtitle:"Werkbaum Ein Text-basierter WBS/Projektstrukturplan/Feature-Tree/Requirements-Baum Diagramm-Editor.", subtitle:"Werkbaum Ein Text-basierter WBS/Projektstrukturplan/Feature-Tree/Requirements-Baum Diagramm-Editor.",
subtitleShort:"WBS, Feature- & Requirements-Bäume als Text", subtitleShort:"WBS, Feature- & Requirements-Bäume als Text",
imprint:"Impressum", imprint:"Impressum",
privacy:"Datenschutz",
legendTooltip:"Legende ein-/ausblenden", legendTooltip:"Legende ein-/ausblenden",
ghostTooltip:"Ab Größe M sollte ein Element weiter untergliedert werden.", ghostTooltip:"Ab Größe M sollte ein Element weiter untergliedert werden.",
discardedTooltip:"Verworfene Knoten samt Teilbaum ein-/ausblenden", discardedTooltip:"Verworfene Knoten samt Teilbaum ein-/ausblenden",
@@ -577,6 +578,7 @@ const I18N = {
subtitle:"Werkbaum A text-based WBS / work breakdown structure / feature-tree / requirements-tree diagram editor.", subtitle:"Werkbaum A text-based WBS / work breakdown structure / feature-tree / requirements-tree diagram editor.",
subtitleShort:"WBS, feature & requirements trees as text", subtitleShort:"WBS, feature & requirements trees as text",
imprint:"Imprint (Impressum)", imprint:"Imprint (Impressum)",
privacy:"Privacy",
legendTooltip:"Show/hide legend", legendTooltip:"Show/hide legend",
ghostTooltip:"From size M upward, an item should be broken down further.", ghostTooltip:"From size M upward, an item should be broken down further.",
discardedTooltip:"Show/hide discarded nodes and their subtree", discardedTooltip:"Show/hide discarded nodes and their subtree",
@@ -616,6 +618,7 @@ const I18N = {
subtitle:"Werkbaum Un editor de diagramas basado en texto para EDT / estructura de desglose del trabajo / árbol de características / árbol de requisitos.", subtitle:"Werkbaum Un editor de diagramas basado en texto para EDT / estructura de desglose del trabajo / árbol de características / árbol de requisitos.",
subtitleShort:"EDT y árboles de características y requisitos", subtitleShort:"EDT y árboles de características y requisitos",
imprint:"Aviso legal (Impressum)", imprint:"Aviso legal (Impressum)",
privacy:"Privacidad",
legendTooltip:"Mostrar u ocultar la leyenda", legendTooltip:"Mostrar u ocultar la leyenda",
ghostTooltip:"A partir de la talla M, un elemento debería desglosarse más.", ghostTooltip:"A partir de la talla M, un elemento debería desglosarse más.",
discardedTooltip:"Mostrar u ocultar los nodos descartados y su subárbol", discardedTooltip:"Mostrar u ocultar los nodos descartados y su subárbol",
@@ -655,6 +658,7 @@ const I18N = {
subtitle:"Werkbaum Un éditeur de diagrammes basé sur le texte pour WBS / organigramme des tâches / arbre de fonctionnalités / arbre d'exigences.", subtitle:"Werkbaum Un éditeur de diagrammes basé sur le texte pour WBS / organigramme des tâches / arbre de fonctionnalités / arbre d'exigences.",
subtitleShort:"WBS, arbres de fonctionnalités et d'exigences", subtitleShort:"WBS, arbres de fonctionnalités et d'exigences",
imprint:"Mentions légales (Impressum)", imprint:"Mentions légales (Impressum)",
privacy:"Confidentialité",
legendTooltip:"Afficher/masquer la légende", legendTooltip:"Afficher/masquer la légende",
ghostTooltip:"À partir de la taille M, un élément devrait être décomposé davantage.", ghostTooltip:"À partir de la taille M, un élément devrait être décomposé davantage.",
discardedTooltip:"Afficher/masquer les nœuds abandonnés et leur sous-arbre", discardedTooltip:"Afficher/masquer les nœuds abandonnés et leur sous-arbre",
@@ -694,6 +698,7 @@ const I18N = {
subtitle:"Werkbaum Edytor diagramów oparty na tekście: WBS / struktura podziału pracy / drzewo funkcji / drzewo wymagań.", subtitle:"Werkbaum Edytor diagramów oparty na tekście: WBS / struktura podziału pracy / drzewo funkcji / drzewo wymagań.",
subtitleShort:"WBS, drzewa funkcji i wymagań jako tekst", subtitleShort:"WBS, drzewa funkcji i wymagań jako tekst",
imprint:"Nota prawna (Impressum)", imprint:"Nota prawna (Impressum)",
privacy:"Prywatność",
legendTooltip:"Pokaż/ukryj legendę", legendTooltip:"Pokaż/ukryj legendę",
ghostTooltip:"Od rozmiaru M element powinien być dalej podzielony.", ghostTooltip:"Od rozmiaru M element powinien być dalej podzielony.",
discardedTooltip:"Pokaż/ukryj odrzucone węzły wraz z poddrzewem", discardedTooltip:"Pokaż/ukryj odrzucone węzły wraz z poddrzewem",
@@ -733,6 +738,7 @@ const I18N = {
subtitle:"Werkbaum – текстовый редактор диаграмм: СДР / структура декомпозиции работ / дерево функций / дерево требований.", subtitle:"Werkbaum – текстовый редактор диаграмм: СДР / структура декомпозиции работ / дерево функций / дерево требований.",
subtitleShort:"СДР, деревья функций и требований", subtitleShort:"СДР, деревья функций и требований",
imprint:"Выходные данные (Impressum)", imprint:"Выходные данные (Impressum)",
privacy:"Конфиденциальность",
legendTooltip:"Показать/скрыть легенду", legendTooltip:"Показать/скрыть легенду",
ghostTooltip:"Начиная с размера M элемент следует далее декомпозировать.", ghostTooltip:"Начиная с размера M элемент следует далее декомпозировать.",
discardedTooltip:"Показать/скрыть отклонённые узлы вместе с поддеревом", discardedTooltip:"Показать/скрыть отклонённые узлы вместе с поддеревом",
@@ -772,6 +778,7 @@ const I18N = {
subtitle:"Werkbaum – टेक्स्ट-आधारित आरेख संपादक: WBS / कार्य विभाजन संरचना / फ़ीचर-ट्री / रिक्वायरमेंट-ट्री।", subtitle:"Werkbaum – टेक्स्ट-आधारित आरेख संपादक: WBS / कार्य विभाजन संरचना / फ़ीचर-ट्री / रिक्वायरमेंट-ट्री।",
subtitleShort:"WBS, फ़ीचर और रिक्वायरमेंट ट्री", subtitleShort:"WBS, फ़ीचर और रिक्वायरमेंट ट्री",
imprint:"प्रकाशन विवरण (Impressum)", imprint:"प्रकाशन विवरण (Impressum)",
privacy:"गोपनीयता",
legendTooltip:"लेजेंड दिखाएँ/छिपाएँ", legendTooltip:"लेजेंड दिखाएँ/छिपाएँ",
ghostTooltip:"आकार M से ऊपर किसी तत्व को और अधिक उप-विभाजित करना चाहिए।", ghostTooltip:"आकार M से ऊपर किसी तत्व को और अधिक उप-विभाजित करना चाहिए।",
discardedTooltip:"अस्वीकृत नोड्स और उनके उप-वृक्ष दिखाएँ/छिपाएँ", discardedTooltip:"अस्वीकृत नोड्स और उनके उप-वृक्ष दिखाएँ/छिपाएँ",
@@ -811,6 +818,7 @@ const I18N = {
subtitle:"Werkbaum 基于文本的图表编辑器:WBS / 工作分解结构 / 功能树 / 需求树。", subtitle:"Werkbaum 基于文本的图表编辑器:WBS / 工作分解结构 / 功能树 / 需求树。",
subtitleShort:"WBS、功能树与需求树", subtitleShort:"WBS、功能树与需求树",
imprint:"法律声明(Impressum", imprint:"法律声明(Impressum",
privacy:"隐私",
legendTooltip:"显示/隐藏图例", legendTooltip:"显示/隐藏图例",
brandTooltip:"「Werkbaum」大致意为‘工作之树’——即工作分解结构(WBS)之树。", brandTooltip:"「Werkbaum」大致意为‘工作之树’——即工作分解结构(WBS)之树。",
fullscreenTooltip:"全屏——面板占据整个窗口宽度", fullscreenTooltip:"全屏——面板占据整个窗口宽度",
@@ -850,6 +858,7 @@ const I18N = {
subtitle:"Werkbaum – テキストベースの図エディター:WBS / 作業分解構成図 / フィーチャーツリー / 要件ツリー。", subtitle:"Werkbaum – テキストベースの図エディター:WBS / 作業分解構成図 / フィーチャーツリー / 要件ツリー。",
subtitleShort:"WBS・機能ツリー・要件ツリー", subtitleShort:"WBS・機能ツリー・要件ツリー",
imprint:"運営者情報(Impressum", imprint:"運営者情報(Impressum",
privacy:"プライバシー",
legendTooltip:"凡例を表示/非表示", legendTooltip:"凡例を表示/非表示",
brandTooltip:"「Werkbaum」はおおよそ『作業の木』の意味 — 作業分解構成図(WBS)のツリーです。", brandTooltip:"「Werkbaum」はおおよそ『作業の木』の意味 — 作業分解構成図(WBS)のツリーです。",
fullscreenTooltip:"全画面 — パネルがウィンドウ幅いっぱいを使用", fullscreenTooltip:"全画面 — パネルがウィンドウ幅いっぱいを使用",
@@ -921,6 +930,12 @@ function applyLang(l){
document.querySelectorAll('[data-i18n-title]').forEach(el => el.title = t(el.dataset.i18nTitle)); document.querySelectorAll('[data-i18n-title]').forEach(el => el.title = t(el.dataset.i18nTitle));
document.querySelectorAll('[data-i18n-aria]').forEach(el => el.setAttribute('aria-label', t(el.dataset.i18nAria))); document.querySelectorAll('[data-i18n-aria]').forEach(el => el.setAttribute('aria-label', t(el.dataset.i18nAria)));
document.getElementById('hint').innerHTML = buildHint(); document.getElementById('hint').innerHTML = buildHint();
/* Datenschutzerklärung gibt es nur DE + EN: deutsche UI -> deutsche Fassung,
alle anderen Sprachen -> englische Fassung (Art. 12 DSGVO: verständlich). */
const privacyLink = document.getElementById('privacyLink');
if(privacyLink) privacyLink.href = l==='de'
? 'https://michael.hoennig.de/datenschutzerklaerung.html'
: 'https://michael.hoennig.de/privacy-policy.html';
document.querySelectorAll('.langsel button[data-lang]').forEach(b => b.classList.toggle('active', b.dataset.lang===l)); document.querySelectorAll('.langsel button[data-lang]').forEach(b => b.classList.toggle('active', b.dataset.lang===l));
/* Ist eine aufklappbare Sprache aktiv, den erweiterten Bereich offen halten. /* Ist eine aufklappbare Sprache aktiv, den erweiterten Bereich offen halten.
Auf kleinem Bildschirm nicht — dort bleibt die Leiste schlank (EN + aktive Auf kleinem Bildschirm nicht — dort bleibt die Leiste schlank (EN + aktive