Enable ESLint no-unused-vars rule (#4367)

# Description of Changes
Enable ESLint [no-unused-vars
rule](https://typescript-eslint.io/rules/no-unused-vars/)
This commit is contained in:
James Brunton
2025-09-05 11:16:17 +00:00
committed by GitHub
parent 87c63efcec
commit bd13f6bf57
102 changed files with 303 additions and 825 deletions
@@ -1,8 +1,6 @@
import React, { useRef, useEffect, useState, useCallback } from 'react';
import { Box } from '@mantine/core';
import { useVirtualizer } from '@tanstack/react-virtual';
import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
import styles from './PageEditor.module.css';
import { GRID_CONSTANTS } from './constants';
interface DragDropItem {
@@ -22,65 +20,60 @@ interface DragDropGridProps<T extends DragDropItem> {
const DragDropGrid = <T extends DragDropItem>({
items,
selectedItems,
selectionMode,
isAnimating,
onReorderPages,
renderItem,
renderSplitMarker,
}: DragDropGridProps<T>) => {
const itemRefs = useRef<Map<string, HTMLDivElement>>(new Map());
const containerRef = useRef<HTMLDivElement>(null);
// Responsive grid configuration
const [itemsPerRow, setItemsPerRow] = useState(4);
const OVERSCAN = items.length > 1000 ? GRID_CONSTANTS.OVERSCAN_LARGE : GRID_CONSTANTS.OVERSCAN_SMALL;
// Calculate items per row based on container width
const calculateItemsPerRow = useCallback(() => {
if (!containerRef.current) return 4; // Default fallback
const containerWidth = containerRef.current.offsetWidth;
if (containerWidth === 0) return 4; // Container not measured yet
// Convert rem to pixels for calculation
const remToPx = parseFloat(getComputedStyle(document.documentElement).fontSize);
const ITEM_WIDTH = parseFloat(GRID_CONSTANTS.ITEM_WIDTH) * remToPx;
const ITEM_GAP = parseFloat(GRID_CONSTANTS.ITEM_GAP) * remToPx;
// Calculate how many items fit: (width - gap) / (itemWidth + gap)
const availableWidth = containerWidth - ITEM_GAP; // Account for first gap
const itemWithGap = ITEM_WIDTH + ITEM_GAP;
const calculated = Math.floor(availableWidth / itemWithGap);
return Math.max(1, calculated); // At least 1 item per row
}, []);
// Update items per row when container resizes
useEffect(() => {
const updateLayout = () => {
const newItemsPerRow = calculateItemsPerRow();
setItemsPerRow(newItemsPerRow);
};
// Initial calculation
updateLayout();
// Listen for window resize
window.addEventListener('resize', updateLayout);
// Use ResizeObserver for container size changes
const resizeObserver = new ResizeObserver(updateLayout);
if (containerRef.current) {
resizeObserver.observe(containerRef.current);
}
return () => {
window.removeEventListener('resize', updateLayout);
resizeObserver.disconnect();
};
}, [calculateItemsPerRow]);
// Virtualization with react-virtual library
const rowVirtualizer = useVirtualizer({
count: Math.ceil(items.length / itemsPerRow),
@@ -92,8 +85,6 @@ const DragDropGrid = <T extends DragDropItem>({
overscan: OVERSCAN,
});
// Calculate optimal width for centering
const remToPx = parseFloat(getComputedStyle(document.documentElement).fontSize);
const itemWidth = parseFloat(GRID_CONSTANTS.ITEM_WIDTH) * remToPx;
@@ -101,9 +92,9 @@ const DragDropGrid = <T extends DragDropItem>({
const gridWidth = itemsPerRow * itemWidth + (itemsPerRow - 1) * itemGap;
return (
<Box
<Box
ref={containerRef}
style={{
style={{
// Basic container styles
width: '100%',
height: '100%',
@@ -122,7 +113,7 @@ const DragDropGrid = <T extends DragDropItem>({
const startIndex = virtualRow.index * itemsPerRow;
const endIndex = Math.min(startIndex + itemsPerRow, items.length);
const rowItems = items.slice(startIndex, endIndex);
return (
<div
key={virtualRow.index}
@@ -154,7 +145,7 @@ const DragDropGrid = <T extends DragDropItem>({
</React.Fragment>
);
})}
</div>
</div>
);
@@ -1,5 +1,5 @@
import React, { useState, useCallback, useRef, useMemo, useEffect } from 'react';
import { Text, ActionIcon, CheckboxIndicator } from '@mantine/core';
import { ActionIcon, CheckboxIndicator } from '@mantine/core';
import { useTranslation } from 'react-i18next';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import DownloadOutlinedIcon from '@mui/icons-material/DownloadOutlined';
@@ -44,7 +44,6 @@ const FileThumbnail = ({
selectedFiles,
onToggleFile,
onDeleteFile,
onViewFile,
onSetStatus,
onReorderFiles,
onDownloadFile,
@@ -93,40 +92,6 @@ const FileThumbnail = ({
// ---- Selection ----
const isSelected = selectedFiles.includes(file.id);
// ---- Meta formatting ----
const prettySize = useMemo(() => {
const bytes = file.size ?? 0;
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
}, [file.size]);
const extUpper = useMemo(() => {
const m = /\.([a-z0-9]+)$/i.exec(file.name ?? '');
return (m?.[1] || '').toUpperCase();
}, [file.name]);
const pageLabel = useMemo(
() =>
file.pageCount > 0
? `${file.pageCount} ${file.pageCount === 1 ? 'Page' : 'Pages'}`
: '',
[file.pageCount]
);
const dateLabel = useMemo(() => {
const d =
file.modifiedAt != null ? new Date(file.modifiedAt) : new Date(); // fallback
if (Number.isNaN(d.getTime())) return '';
return new Intl.DateTimeFormat(undefined, {
month: 'short',
day: '2-digit',
year: 'numeric',
}).format(d);
}, [file.modifiedAt]);
// ---- Drag & drop wiring ----
const fileElementRef = useCallback((element: HTMLDivElement | null) => {
if (!element) return;
@@ -1,13 +1,7 @@
import React, { useState, useCallback, useRef, useEffect, useMemo } from "react";
import {
Button, Text, Center, Box,
Notification, TextInput, LoadingOverlay, Modal, Alert,
Stack, Group, Portal
} from "@mantine/core";
import { useTranslation } from "react-i18next";
import { useFileState, useFileActions, useCurrentFile, useFileSelection } from "../../contexts/FileContext";
import { PDFDocument, PDFPage, PageEditorFunctions } from "../../types/pageEditor";
import { ProcessedFile as EnhancedProcessedFile } from "../../types/processing";
import { useState, useCallback, useRef, useEffect } from "react";
import { Text, Center, Box, LoadingOverlay, Stack } from "@mantine/core";
import { useFileState, useFileActions } from "../../contexts/FileContext";
import { PDFDocument, PageEditorFunctions } from "../../types/pageEditor";
import { pdfExportService } from "../../services/pdfExportService";
import { documentManipulationService } from "../../services/documentManipulationService";
// Thumbnail generation is now handled by individual PageThumbnail components
@@ -19,16 +13,11 @@ import NavigationWarningModal from '../shared/NavigationWarningModal';
import { FileId } from "../../types/file";
import {
DOMCommand,
RotatePageCommand,
DeletePagesCommand,
ReorderPagesCommand,
SplitCommand,
BulkRotateCommand,
BulkSplitCommand,
SplitAllCommand,
PageBreakCommand,
BulkPageBreakCommand,
UndoManager
} from './commands/pageCommands';
import { GRID_CONSTANTS } from './constants';
@@ -49,35 +38,24 @@ const PageEditor = ({
// Prefer IDs + selectors to avoid array identity churn
const activeFileIds = state.files.ids;
const primaryFileId = activeFileIds[0] ?? null;
const selectedFiles = selectors.getSelectedFiles();
// Stable signature for effects (prevents loops)
const filesSignature = selectors.getFilesSignature();
// UI state
const globalProcessing = state.ui.isProcessing;
const processingProgress = state.ui.processingProgress;
const hasUnsavedChanges = state.ui.hasUnsavedChanges;
// Edit state management
const [editedDocument, setEditedDocument] = useState<PDFDocument | null>(null);
const [hasUnsavedDraft, setHasUnsavedDraft] = useState(false);
const [showResumeModal, setShowResumeModal] = useState(false);
const [foundDraft, setFoundDraft] = useState<any>(null);
const autoSaveTimer = useRef<number | null>(null);
// DOM-first undo manager (replaces the old React state undo system)
const undoManagerRef = useRef(new UndoManager());
// Document state management
const { document: mergedPdfDocument, isVeryLargeDocument, isLoading: documentLoading } = usePageDocument();
const { document: mergedPdfDocument } = usePageDocument();
// UI state management
const {
selectionMode, selectedPageIds, movingPage, isAnimating, splitPositions, exportLoading,
setSelectionMode, setSelectedPageIds, setMovingPage, setIsAnimating, setSplitPositions, setExportLoading,
setSelectionMode, setSelectedPageIds, setMovingPage, setSplitPositions, setExportLoading,
togglePage, toggleSelectAll, animateReorder
} = usePageEditorState();
@@ -146,12 +124,6 @@ const PageEditor = ({
}).filter(id => id !== '');
}, [displayDocument]);
// Convert selectedPageIds to numbers for components that still need numbers
const selectedPageNumbers = useMemo(() =>
getPageNumbersFromIds(selectedPageIds),
[selectedPageIds, getPageNumbersFromIds]
);
// Select all pages by default when document initially loads
const hasInitializedSelection = useRef(false);
useEffect(() => {
@@ -1,4 +1,3 @@
import React from "react";
import {
Tooltip,
ActionIcon,
@@ -9,9 +8,7 @@ import ContentCutIcon from "@mui/icons-material/ContentCut";
import RotateLeftIcon from "@mui/icons-material/RotateLeft";
import RotateRightIcon from "@mui/icons-material/RotateRight";
import DeleteIcon from "@mui/icons-material/Delete";
import CloseIcon from "@mui/icons-material/Close";
import InsertPageBreakIcon from "@mui/icons-material/InsertPageBreak";
import DownloadIcon from "@mui/icons-material/Download";
interface PageEditorControlsProps {
// Close/Reset functions
@@ -46,7 +43,6 @@ interface PageEditorControlsProps {
}
const PageEditorControls = ({
onClosePdf,
onUndo,
onRedo,
canUndo,
@@ -54,12 +50,7 @@ const PageEditorControls = ({
onRotate,
onDelete,
onSplit,
onSplitAll,
onPageBreak,
onPageBreakAll,
onExportAll,
exportLoading,
selectionMode,
selectedPageIds,
displayDocument,
splitPositions,
@@ -52,16 +52,13 @@ const PageThumbnail: React.FC<PageThumbnailProps> = ({
pageRefs,
onReorderPages,
onTogglePage,
onAnimateReorder,
onExecuteCommand,
onSetStatus,
onSetMovingPage,
onDeletePage,
createRotateCommand,
createDeleteCommand,
createSplitCommand,
pdfDocument,
setPdfDocument,
splitPositions,
onInsertFiles,
}: PageThumbnailProps) => {
@@ -172,7 +169,7 @@ const PageThumbnail: React.FC<PageThumbnailProps> = ({
type: 'page',
pageNumber: page.pageNumber
}),
onDrop: ({ source }) => {}
onDrop: (_) => {}
});
(element as any).__dragCleanup = () => {
@@ -68,7 +68,6 @@ export function usePageDocument(): PageDocumentHook {
// Build pages by interleaving original pages with insertions
let pages: PDFPage[] = [];
let totalPageCount = 0;
// Helper function to create pages from a file
const createPagesFromFile = (fileId: FileId, startPageNumber: number): PDFPage[] => {
@@ -144,8 +143,6 @@ export function usePageDocument(): PageDocumentHook {
});
}
totalPageCount = pages.length;
if (pages.length === 0) {
return null;
}