diff --git a/apps/compliance-portal/src/pages/documents/_components/DocumentEntry.tsx b/apps/compliance-portal/src/pages/documents/_components/DocumentEntry.tsx index 0fa6a01d1..6ac3c81b2 100644 --- a/apps/compliance-portal/src/pages/documents/_components/DocumentEntry.tsx +++ b/apps/compliance-portal/src/pages/documents/_components/DocumentEntry.tsx @@ -18,7 +18,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { Toast } from "@base-ui/react/toast"; import { LinkSimpleIcon } from "@phosphor-icons/react"; import { Checkbox } from "@probo/ui/src/v2/Checkbox/Checkbox"; import { IconButton } from "@probo/ui/src/v2/IconButton/IconButton"; @@ -29,6 +28,8 @@ import type { ReactNode } from "react"; import { useTranslation } from "react-i18next"; import { Link as RouterLink } from "react-router"; +import { useCopyDocumentLink } from "../_lib/useCopyDocumentLink"; + import { DocumentAccessAction } from "./DocumentAccessAction"; import { documentEntry } from "./variants"; @@ -70,7 +71,7 @@ export function DocumentEntry({ onSelectedChange, }: DocumentEntryProps) { const { t } = useTranslation("documents"); - const toast = Toast.useToastManager(); + const copyDocumentLink = useCopyDocumentLink(); const slots = documentEntry(); // Only locked rows (not yet authorized, no pending request) can be requested, @@ -85,11 +86,7 @@ export function DocumentEntry({ : t("actions.getAccess"); const handleCopyLink = () => { - const url = new URL(viewHref, window.location.origin); - navigator.clipboard.writeText(url.href).then( - () => toast.add({ title: t("viewer.linkCopied"), type: "success" }), - () => {}, - ); + copyDocumentLink(new URL(viewHref, window.location.origin).href); }; return ( diff --git a/apps/compliance-portal/src/pages/documents/_components/DocumentViewerToolbar.tsx b/apps/compliance-portal/src/pages/documents/_components/DocumentViewerToolbar.tsx index f17d40334..e78fa39a9 100644 --- a/apps/compliance-portal/src/pages/documents/_components/DocumentViewerToolbar.tsx +++ b/apps/compliance-portal/src/pages/documents/_components/DocumentViewerToolbar.tsx @@ -18,7 +18,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { Toast } from "@base-ui/react/toast"; import { CaretLeftIcon, CaretRightIcon, @@ -34,6 +33,7 @@ import { Text } from "@probo/ui/src/v2/typography/Text"; import { useTranslation } from "react-i18next"; import { downloadDataUri } from "../_lib/dataUri"; +import { useCopyDocumentLink } from "../_lib/useCopyDocumentLink"; import { documentViewerToolbar } from "./variants"; @@ -72,14 +72,11 @@ export function DocumentViewerToolbar({ downloadName, }: DocumentViewerToolbarProps) { const { t } = useTranslation("documents"); - const toast = Toast.useToastManager(); + const copyDocumentLink = useCopyDocumentLink(); const slots = documentViewerToolbar(); const handleCopyLink = () => { - navigator.clipboard.writeText(window.location.href).then( - () => toast.add({ title: t("viewer.linkCopied"), type: "success" }), - () => {}, - ); + copyDocumentLink(window.location.href); }; const handleDownload = () => { diff --git a/apps/compliance-portal/src/pages/documents/_lib/useCopyDocumentLink.ts b/apps/compliance-portal/src/pages/documents/_lib/useCopyDocumentLink.ts new file mode 100644 index 000000000..a0ad101c2 --- /dev/null +++ b/apps/compliance-portal/src/pages/documents/_lib/useCopyDocumentLink.ts @@ -0,0 +1,38 @@ +// Copyright (c) 2026 Probo Inc . +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import { Toast } from "@base-ui/react/toast"; +import { useTranslation } from "react-i18next"; + +// Copies a document URL to the clipboard and toasts on success. Shared by list +// rows and the viewer toolbar so feedback stays in sync. +export function useCopyDocumentLink() { + const { t } = useTranslation("documents"); + const toast = Toast.useToastManager(); + + return (url: string) => { + void navigator.clipboard.writeText(url).then( + () => { + toast.add({ title: t("viewer.linkCopied"), type: "success" }); + }, + () => {}, + ); + }; +} diff --git a/apps/compliance-portal/src/pages/subprocessors/_locales/uk-UA.json b/apps/compliance-portal/src/pages/subprocessors/_locales/uk-UA.json index fad53b8a3..50ae2880f 100644 --- a/apps/compliance-portal/src/pages/subprocessors/_locales/uk-UA.json +++ b/apps/compliance-portal/src/pages/subprocessors/_locales/uk-UA.json @@ -15,7 +15,10 @@ "regions": { "global": "Глобально", "eu": "Європейський Союз", - "moreRegions": "Показати ще {{count}} регіонів" + "moreRegions_one": "Показати ще {{count}} регіон", + "moreRegions_few": "Показати ще {{count}} регіони", + "moreRegions_many": "Показати ще {{count}} регіонів", + "moreRegions_other": "Показати ще {{count}} регіонів" }, "categories": { "ANALYTICS": {