From 78182f3ba64b0b0e2825a8537c5a62ad752d0972 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Mon, 15 Jun 2026 12:29:51 +0200 Subject: [PATCH] feat(filters): "Share view" link button in the sidebar Add a share button next to Clear all that copies a link reproducing the current filter view (filters, sort, scope) to the clipboard, with a confirmation toast. This is the opt-in replacement for the old always-on URL mirroring. Trilingual. --- frontend/src/components/Sidebar.tsx | 22 ++++++++++++++++++++++ frontend/src/i18n/locales/de/sidebar.json | 3 +++ frontend/src/i18n/locales/en/sidebar.json | 3 +++ frontend/src/i18n/locales/hu/sidebar.json | 3 +++ 4 files changed, 31 insertions(+) diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 260134b..95a8980 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -10,6 +10,7 @@ import { Pencil, RefreshCw, RotateCcw, + Share2, X, } from "lucide-react"; import { @@ -33,6 +34,8 @@ import { type SidebarLayout, type WidgetId, } from "../lib/sidebarLayout"; +import { shareUrl } from "../lib/urlState"; +import { notify } from "../lib/notifications"; // Filter ids; display labels resolved at render time via t("sidebar.sort.") etc. const SORT_IDS = [ @@ -196,6 +199,15 @@ export default function Sidebar({ (dateActive ? 1 : 0); const active = activeCount > 0; + async function shareView() { + try { + await navigator.clipboard.writeText(shareUrl(filters)); + notify({ message: t("sidebar.shareCopied") }); + } catch { + notify({ level: "warning", message: t("sidebar.shareFailed") }); + } + } + function clearAll() { setCustomDates(false); setFilters({ ...DEFAULT_SIDEBAR_FILTERS, q: filters.q, scope: filters.scope }); @@ -486,6 +498,16 @@ export default function Sidebar({ {t("sidebar.clearAll")} )} + {!editing && ( + + )} {editing && (