diff --git a/frontend/src/core/components/annotation/shared/DrawingCanvas.tsx b/frontend/src/core/components/annotation/shared/DrawingCanvas.tsx index 4b9de1cbb..e8600e0a2 100644 --- a/frontend/src/core/components/annotation/shared/DrawingCanvas.tsx +++ b/frontend/src/core/components/annotation/shared/DrawingCanvas.tsx @@ -3,6 +3,7 @@ import { Paper, Button, Modal, Stack, Text, Popover, ColorPicker as MantineColor import { ColorSwatchButton } from '@app/components/annotation/shared/ColorPicker'; import PenSizeSelector from '@app/components/tools/sign/PenSizeSelector'; import SignaturePad from 'signature_pad'; +import { PrivateContent } from '@app/components/shared/PrivateContent'; interface DrawingCanvasProps { selectedColor: string; @@ -177,19 +178,21 @@ export const DrawingCanvas: React.FC = ({ Draw your signature - + + + Click to open drawing canvas @@ -246,23 +249,25 @@ export const DrawingCanvas: React.FC = ({ - { - modalCanvasRef.current = el; - if (el) initPad(el); - }} - style={{ - border: '1px solid #ccc', - borderRadius: '4px', - display: 'block', - touchAction: 'none', - backgroundColor: 'white', - width: '100%', - maxWidth: '800px', - height: '400px', - cursor: 'crosshair', - }} - /> + + { + modalCanvasRef.current = el; + if (el) initPad(el); + }} + style={{ + border: '1px solid #ccc', + borderRadius: '4px', + display: 'block', + touchAction: 'none', + backgroundColor: 'white', + width: '100%', + maxWidth: '800px', + height: '400px', + cursor: 'crosshair', + }} + /> +
diff --git a/frontend/src/core/components/pageEditor/PageThumbnail.tsx b/frontend/src/core/components/pageEditor/PageThumbnail.tsx index f0124b2c6..2546a607e 100644 --- a/frontend/src/core/components/pageEditor/PageThumbnail.tsx +++ b/frontend/src/core/components/pageEditor/PageThumbnail.tsx @@ -14,6 +14,7 @@ import { useThumbnailGeneration } from '@app/hooks/useThumbnailGeneration'; import { useFilesModalContext } from '@app/contexts/FilesModalContext'; import styles from '@app/components/pageEditor/PageEditor.module.css'; import HoverActionMenu, { HoverAction } from '@app/components/shared/HoverActionMenu'; +import { PrivateContent } from '@app/components/shared/PrivateContent'; interface PageThumbnailProps { @@ -442,21 +443,22 @@ const PageThumbnail: React.FC = ({ }}> ) : thumbnailUrl ? ( - {`Page + + {`Page + ) : (
📄 diff --git a/frontend/src/core/components/shared/FileDropdownMenu.tsx b/frontend/src/core/components/shared/FileDropdownMenu.tsx index 8a78e7631..24583ea77 100644 --- a/frontend/src/core/components/shared/FileDropdownMenu.tsx +++ b/frontend/src/core/components/shared/FileDropdownMenu.tsx @@ -3,6 +3,7 @@ import { Menu, Loader, Group, Text } from '@mantine/core'; import VisibilityIcon from '@mui/icons-material/Visibility'; import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; import FitText from '@app/components/shared/FitText'; +import { PrivateContent } from '@app/components/shared/PrivateContent'; interface FileDropdownMenuProps { displayName: string; @@ -31,7 +32,9 @@ export const FileDropdownMenu: React.FC = ({ ) : ( )} - + + +
@@ -61,7 +64,9 @@ export const FileDropdownMenu: React.FC = ({ >
- + + +
{file.versionNumber && file.versionNumber > 1 && ( diff --git a/frontend/src/core/components/shared/PrivateContent.tsx b/frontend/src/core/components/shared/PrivateContent.tsx new file mode 100644 index 000000000..3ed11bfc6 --- /dev/null +++ b/frontend/src/core/components/shared/PrivateContent.tsx @@ -0,0 +1,40 @@ +import React from 'react'; + +interface PrivateContentProps extends React.HTMLAttributes { + children: React.ReactNode; +} + +/** + * Wrapper component for content that should not be captured by analytics tools. + * Currently applies the 'ph-no-capture' className to prevent PostHog capture. + * + * Uses `display: contents` to be layout-invisible - the wrapper exists in the DOM + * for analytics filtering, but doesn't affect layout, flexbox, grid, or styling. + * + * Use this component to wrap any content containing sensitive or private information + * that should be excluded from analytics tracking. + * + * @example + * + * Sensitive filename.pdf + * + * + * + * preview + * + */ +export const PrivateContent: React.FC = ({ + children, + className = '', + style, + ...props +}) => { + const combinedClassName = `ph-no-capture${className ? ` ${className}` : ''}`; + const combinedStyle = { display: 'contents' as const, ...style }; + + return ( + + {children} + + ); +}; diff --git a/frontend/src/core/components/shared/TopControls.tsx b/frontend/src/core/components/shared/TopControls.tsx index 6c6ac6999..64c78b8f1 100644 --- a/frontend/src/core/components/shared/TopControls.tsx +++ b/frontend/src/core/components/shared/TopControls.tsx @@ -9,6 +9,7 @@ import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf"; import { WorkbenchType, isValidWorkbench } from '@app/types/workbench'; import type { CustomWorkbenchViewInstance } from '@app/contexts/ToolWorkflowContext'; import { FileDropdownMenu } from '@app/components/shared/FileDropdownMenu'; +import { PrivateContent } from '@app/components/shared/PrivateContent'; const viewOptionStyle: React.CSSProperties = { @@ -54,7 +55,7 @@ const createViewOptions = ( ) : ( )} - {displayName} + {displayName} ), value: "viewer", diff --git a/frontend/src/core/components/shared/filePreview/DocumentThumbnail.tsx b/frontend/src/core/components/shared/filePreview/DocumentThumbnail.tsx index ffa465fc9..5ace7d03f 100644 --- a/frontend/src/core/components/shared/filePreview/DocumentThumbnail.tsx +++ b/frontend/src/core/components/shared/filePreview/DocumentThumbnail.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { Box, Center, Image } from '@mantine/core'; import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf'; import { StirlingFileStub } from '@app/types/fileContext'; +import { PrivateContent } from '@app/components/shared/PrivateContent'; export interface DocumentThumbnailProps { file: File | StirlingFileStub | null; @@ -35,13 +36,14 @@ const DocumentThumbnail: React.FC = ({ if (thumbnail) { return ( - {`Preview + + {`Preview + {children} ); @@ -50,13 +52,14 @@ const DocumentThumbnail: React.FC = ({ return (
- + + +
{children}
diff --git a/frontend/src/core/components/tools/addPageNumbers/PageNumberPreview.tsx b/frontend/src/core/components/tools/addPageNumbers/PageNumberPreview.tsx index 830703f21..8edb8fa2c 100644 --- a/frontend/src/core/components/tools/addPageNumbers/PageNumberPreview.tsx +++ b/frontend/src/core/components/tools/addPageNumbers/PageNumberPreview.tsx @@ -4,6 +4,7 @@ import { AddPageNumbersParameters } from '@app/components/tools/addPageNumbers/u import { pdfWorkerManager } from '@app/services/pdfWorkerManager'; import { useThumbnailGeneration } from '@app/hooks/useThumbnailGeneration'; import styles from '@app/components/tools/addPageNumbers/PageNumberPreview.module.css'; +import { PrivateContent } from '@app/components/shared/PrivateContent'; // Simple utilities for page numbers (adapted from stamp) const A4_ASPECT_RATIO = 0.707; @@ -197,12 +198,14 @@ export default function PageNumberPreview({ parameters, onParameterChange, file, style={containerStyle} > {pageThumbnail && ( - page preview + + page preview + )} {/* Quick position overlay grid - EXACT copy from stamp */} diff --git a/frontend/src/core/components/tools/shared/FileStatusIndicator.tsx b/frontend/src/core/components/tools/shared/FileStatusIndicator.tsx index aed2c5d6e..0c39da957 100644 --- a/frontend/src/core/components/tools/shared/FileStatusIndicator.tsx +++ b/frontend/src/core/components/tools/shared/FileStatusIndicator.tsx @@ -7,6 +7,7 @@ import { useFilesModalContext } from "@app/contexts/FilesModalContext"; import { useAllFiles } from "@app/contexts/FileContext"; import { useFileManager } from "@app/hooks/useFileManager"; import { StirlingFile } from "@app/types/fileContext"; +import { PrivateContent } from "@app/components/shared/PrivateContent" export interface FileStatusIndicatorProps { selectedFiles?: StirlingFile[]; @@ -134,7 +135,9 @@ const FileStatusIndicator = ({ return ( - ✓ {selectedFiles.length === 1 ? t("fileSelected", "Selected: {{filename}}", { filename: selectedFiles[0]?.name }) : t("filesSelected", "{{count}} files selected", { count: selectedFiles.length })} + ✓ {selectedFiles.length === 1 + ? {t("fileSelected", "Selected: {{filename}}", { filename: selectedFiles[0]?.name }) } + : t("filesSelected", "{{count}} files selected", { count: selectedFiles.length })} ); }; diff --git a/frontend/src/core/components/tools/shared/ResultsPreview.tsx b/frontend/src/core/components/tools/shared/ResultsPreview.tsx index feb4004f7..9a4921af0 100644 --- a/frontend/src/core/components/tools/shared/ResultsPreview.tsx +++ b/frontend/src/core/components/tools/shared/ResultsPreview.tsx @@ -3,6 +3,7 @@ import { Box, Text, Loader, Stack, Center, Flex } from '@mantine/core'; import FilePreview from '@app/components/shared/FilePreview'; import FileMetadata from '@app/components/tools/shared/FileMetadata'; import NavigationControls from '@app/components/tools/shared/NavigationControls'; +import { PrivateContent } from '@app/components/shared/PrivateContent'; export interface ReviewFile { file: File; @@ -62,7 +63,6 @@ const ResultsPreview = ({ {/* File name at the top */} - {currentFile.file.name} + {currentFile.file.name} diff --git a/frontend/src/core/components/viewer/LocalEmbedPDF.tsx b/frontend/src/core/components/viewer/LocalEmbedPDF.tsx index bfe75df2f..0d963eeca 100644 --- a/frontend/src/core/components/viewer/LocalEmbedPDF.tsx +++ b/frontend/src/core/components/viewer/LocalEmbedPDF.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useMemo, useState } from 'react'; import { createPluginRegistration } from '@embedpdf/core'; import { EmbedPDF } from '@embedpdf/core/react'; import { usePdfiumEngine } from '@embedpdf/engines/react'; +import { PrivateContent } from '@app/components/shared/PrivateContent'; // Import the essential plugins import { Viewport, ViewportPluginPackage } from '@embedpdf/plugin-viewport/react'; @@ -184,18 +185,17 @@ export function LocalEmbedPDF({ file, url, enableAnnotations = false, onSignatur // Wrap your UI with the provider return ( -
+ +
-
+
+ ); } diff --git a/frontend/src/core/components/viewer/ThumbnailSidebar.tsx b/frontend/src/core/components/viewer/ThumbnailSidebar.tsx index 510a6c1a6..48fce6ae1 100644 --- a/frontend/src/core/components/viewer/ThumbnailSidebar.tsx +++ b/frontend/src/core/components/viewer/ThumbnailSidebar.tsx @@ -1,6 +1,7 @@ import { useState, useEffect } from 'react'; import { Box, ScrollArea } from '@mantine/core'; import { useViewer } from '@app/contexts/ViewerContext'; +import { PrivateContent } from '@app/components/shared/PrivateContent'; interface ThumbnailSidebarProps { visible: boolean; @@ -145,18 +146,19 @@ export function ThumbnailSidebar({ visible, onToggle: _onToggle, activeFileIndex > {/* Thumbnail Image */} {thumbnails[pageIndex] && thumbnails[pageIndex] !== 'error' ? ( - {`Page + + {`Page + ) : thumbnails[pageIndex] === 'error' ? (