mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
Fix more any type usages in frontend code (#7334)
# Description of Changes Continued effort towards removing all uses of the any type in our frontend code (last PR was #7326). This PR fixes 7 more folders and removes them from the exclude list. All of them were localised within the folder in the exclude list so again were pretty easy to fix.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React, { createContext, useContext, ReactNode } from "react";
|
||||
import { SignParameters } from "@app/hooks/tools/sign/useSignParameters";
|
||||
|
||||
interface PDFAnnotationContextValue {
|
||||
// Drawing mode management
|
||||
@@ -22,8 +23,8 @@ interface PDFAnnotationContextValue {
|
||||
isPlacementMode: boolean;
|
||||
|
||||
// Signature configuration
|
||||
signatureConfig: any | null;
|
||||
setSignatureConfig: (config: any | null) => void;
|
||||
signatureConfig: SignParameters | null;
|
||||
setSignatureConfig: (config: SignParameters | null) => void;
|
||||
}
|
||||
|
||||
const PDFAnnotationContext = createContext<
|
||||
@@ -43,8 +44,8 @@ interface PDFAnnotationProviderProps {
|
||||
storeImageData: (id: string, data: string) => void;
|
||||
getImageData: (id: string) => string | undefined;
|
||||
isPlacementMode: boolean;
|
||||
signatureConfig: any | null;
|
||||
setSignatureConfig: (config: any | null) => void;
|
||||
signatureConfig: SignParameters | null;
|
||||
setSignatureConfig: (config: SignParameters | null) => void;
|
||||
}
|
||||
|
||||
export const PDFAnnotationProvider: React.FC<PDFAnnotationProviderProps> = ({
|
||||
|
||||
@@ -14,9 +14,17 @@ export interface AnnotationToolConfig {
|
||||
placeButtonText?: string;
|
||||
}
|
||||
|
||||
interface InjectedAnnotationToolProps {
|
||||
selectedColor: string;
|
||||
signatureData: string | null;
|
||||
onSignatureDataChange: (data: string | null) => void;
|
||||
onColorSwatchClick: () => void;
|
||||
disabled: boolean;
|
||||
}
|
||||
|
||||
interface BaseAnnotationToolProps {
|
||||
config: AnnotationToolConfig;
|
||||
children: React.ReactNode;
|
||||
children: React.ReactElement<Partial<InjectedAnnotationToolProps>>;
|
||||
onSignatureDataChange?: (data: string | null) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
@@ -90,7 +98,7 @@ export const BaseAnnotationTool: React.FC<BaseAnnotationToolProps> = ({
|
||||
/>
|
||||
|
||||
{/* Tool Content */}
|
||||
{React.cloneElement(children as React.ReactElement<any>, {
|
||||
{React.cloneElement(children, {
|
||||
selectedColor,
|
||||
signatureData,
|
||||
onSignatureDataChange: handleSignatureDataChange,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import DragDropGrid from "@app/components/pageEditor/DragDropGrid";
|
||||
import DragDropGrid, {
|
||||
type DragHandleProps,
|
||||
} from "@app/components/pageEditor/DragDropGrid";
|
||||
|
||||
interface MockGridItem {
|
||||
id: string;
|
||||
@@ -22,7 +24,7 @@ const renderItem = (
|
||||
clearBoxSelection: () => void,
|
||||
activeDragIds: string[],
|
||||
justMoved: boolean,
|
||||
dragHandleProps?: any,
|
||||
dragHandleProps?: DragHandleProps,
|
||||
zoomLevel?: number,
|
||||
) => {
|
||||
const { ref: dndRef, ...restDragProps } = dragHandleProps ?? {};
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
DragEndEvent,
|
||||
DragStartEvent,
|
||||
DragOverlay,
|
||||
DraggableAttributes,
|
||||
useSensor,
|
||||
useSensors,
|
||||
PointerSensor,
|
||||
@@ -28,6 +29,10 @@ import {
|
||||
useDroppable,
|
||||
} from "@dnd-kit/core";
|
||||
|
||||
export type DragHandleProps = DraggableAttributes & {
|
||||
ref: React.RefCallback<HTMLElement>;
|
||||
} & Record<string, unknown>;
|
||||
|
||||
interface DragDropItem {
|
||||
id: string;
|
||||
splitAfter?: boolean;
|
||||
@@ -51,7 +56,7 @@ interface DragDropGridProps<T extends DragDropItem> {
|
||||
clearBoxSelection: () => void,
|
||||
activeDragIds: string[],
|
||||
justMoved: boolean,
|
||||
dragHandleProps?: any,
|
||||
dragHandleProps?: DragHandleProps,
|
||||
zoomLevel?: number,
|
||||
) => React.ReactNode;
|
||||
getThumbnailData?: (
|
||||
@@ -232,7 +237,7 @@ interface DraggableItemProps<T extends DragDropItem> {
|
||||
clearBoxSelection: () => void,
|
||||
activeDragIds: string[],
|
||||
justMoved: boolean,
|
||||
dragHandleProps?: any,
|
||||
dragHandleProps?: DragHandleProps,
|
||||
zoomLevel?: number,
|
||||
) => React.ReactNode;
|
||||
zoomLevel: number;
|
||||
@@ -253,7 +258,7 @@ const DraggableItemInner = <T extends DragDropItem>({
|
||||
zoomLevel,
|
||||
}: DraggableItemProps<T>) => {
|
||||
const isPlaceholder = Boolean(item.isPlaceholder);
|
||||
const pageNumber = (item as any).pageNumber ?? index + 1;
|
||||
const pageNumber = item.pageNumber ?? index + 1;
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
|
||||
@@ -11,7 +11,9 @@ import { PageEditorFunctions, PDFPage } from "@app/types/pageEditor";
|
||||
// Thumbnail generation is now handled by individual PageThumbnail components
|
||||
import "@app/components/pageEditor/PageEditor.module.css";
|
||||
import PageThumbnail from "@app/components/pageEditor/PageThumbnail";
|
||||
import DragDropGrid from "@app/components/pageEditor/DragDropGrid";
|
||||
import DragDropGrid, {
|
||||
type DragHandleProps,
|
||||
} from "@app/components/pageEditor/DragDropGrid";
|
||||
import SkeletonLoader from "@app/components/shared/SkeletonLoader";
|
||||
import { FileId } from "@app/types/file";
|
||||
import { GRID_CONSTANTS } from "@app/components/pageEditor/constants";
|
||||
@@ -33,6 +35,13 @@ export interface PageEditorProps {
|
||||
onFunctionsReady?: (functions: PageEditorFunctions) => void;
|
||||
}
|
||||
|
||||
interface PageEditorFileEntry {
|
||||
fileId: FileId;
|
||||
name: string;
|
||||
versionNumber: number | undefined;
|
||||
isSelected: boolean;
|
||||
}
|
||||
|
||||
const PageEditor = ({ onFunctionsReady }: PageEditorProps) => {
|
||||
const { t } = useTranslation();
|
||||
// Use split contexts to prevent re-renders
|
||||
@@ -106,14 +115,14 @@ const PageEditor = ({ onFunctionsReady }: PageEditorProps) => {
|
||||
const selectedIdsKey = [...state.ui.selectedFileIds].sort().join(",");
|
||||
const filesSignature = selectors.getFilesSignature();
|
||||
|
||||
const fileObjectsRef = useRef(new Map<FileId, any>());
|
||||
const fileObjectsRef = useRef(new Map<FileId, PageEditorFileEntry>());
|
||||
const gridItemRefsRef = useRef<React.MutableRefObject<
|
||||
Map<string, HTMLDivElement>
|
||||
> | null>(null);
|
||||
|
||||
const pageEditorFiles = useMemo(() => {
|
||||
const cache = fileObjectsRef.current;
|
||||
const newFiles: any[] = [];
|
||||
const newFiles: PageEditorFileEntry[] = [];
|
||||
|
||||
fileOrder.forEach((fileId) => {
|
||||
const stub = selectors.getStirlingFileStub(fileId);
|
||||
@@ -605,7 +614,7 @@ const PageEditor = ({ onFunctionsReady }: PageEditorProps) => {
|
||||
clearBoxSelection: () => void,
|
||||
activeDragIds: string[],
|
||||
justMoved: boolean,
|
||||
dragHandleProps?: any,
|
||||
dragHandleProps?: DragHandleProps,
|
||||
zoomLevelParam?: number,
|
||||
) => {
|
||||
gridItemRefsRef.current = refs;
|
||||
|
||||
@@ -17,6 +17,7 @@ import AddIcon from "@mui/icons-material/Add";
|
||||
import { PDFPage, PDFDocument } from "@app/types/pageEditor";
|
||||
import { useFilesModalContext } from "@app/contexts/FilesModalContext";
|
||||
import { getFileColorWithOpacity } from "@app/components/pageEditor/fileColors";
|
||||
import { type DragHandleProps } from "@app/components/pageEditor/DragDropGrid";
|
||||
import styles from "@app/components/pageEditor/PageEditor.module.css";
|
||||
import HoverActionMenu, {
|
||||
HoverAction,
|
||||
@@ -38,7 +39,7 @@ interface PageThumbnailProps {
|
||||
activeDragIds: string[];
|
||||
justMoved?: boolean;
|
||||
pageRefs: React.MutableRefObject<Map<string, HTMLDivElement>>;
|
||||
dragHandleProps?: any;
|
||||
dragHandleProps?: DragHandleProps;
|
||||
onReorderPages: (
|
||||
sourcePageNumber: number,
|
||||
targetIndex: number,
|
||||
|
||||
@@ -58,8 +58,8 @@ const FullscreenToolList = ({
|
||||
);
|
||||
const recommendedItems = useMemo(() => {
|
||||
if (!quickSection)
|
||||
return [] as Array<{ id: string; tool: ToolRegistryEntry }>;
|
||||
const items: Array<{ id: string; tool: ToolRegistryEntry }> = [];
|
||||
return [] as Array<{ id: ToolId; tool: ToolRegistryEntry }>;
|
||||
const items: Array<{ id: ToolId; tool: ToolRegistryEntry }> = [];
|
||||
quickSection.subcategories.forEach((sc) =>
|
||||
sc.tools.forEach((t) => items.push(t)),
|
||||
);
|
||||
@@ -217,13 +217,13 @@ const FullscreenToolList = ({
|
||||
</header>
|
||||
{showDescriptions ? (
|
||||
<div className="tool-panel__fullscreen-grid tool-panel__fullscreen-grid--detailed">
|
||||
{recommendedItems.map((item: any) =>
|
||||
{recommendedItems.map((item) =>
|
||||
renderToolItem(item.id, item.tool),
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="tool-panel__fullscreen-list">
|
||||
{recommendedItems.map((item: any) =>
|
||||
{recommendedItems.map((item) =>
|
||||
renderToolItem(item.id, item.tool),
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,10 @@ import FileUploadButton from "@app/components/shared/FileUploadButton";
|
||||
|
||||
interface CertificateFilesSettingsProps {
|
||||
parameters: CertSignParameters;
|
||||
onParameterChange: (key: keyof CertSignParameters, value: any) => void;
|
||||
onParameterChange: <K extends keyof CertSignParameters>(
|
||||
key: K,
|
||||
value: CertSignParameters[K],
|
||||
) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,10 @@ import { CertSignParameters } from "@app/hooks/tools/certSign/useCertSignParamet
|
||||
|
||||
interface CertificateFormatSettingsProps {
|
||||
parameters: CertSignParameters;
|
||||
onParameterChange: (key: keyof CertSignParameters, value: any) => void;
|
||||
onParameterChange: <K extends keyof CertSignParameters>(
|
||||
key: K,
|
||||
value: CertSignParameters[K],
|
||||
) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,10 @@ import { useAppConfig } from "@app/contexts/AppConfigContext";
|
||||
|
||||
interface CertificateTypeSettingsProps {
|
||||
parameters: CertSignParameters;
|
||||
onParameterChange: (key: keyof CertSignParameters, value: any) => void;
|
||||
onParameterChange: <K extends keyof CertSignParameters>(
|
||||
key: K,
|
||||
value: CertSignParameters[K],
|
||||
) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
|
||||
+22
-11
@@ -22,7 +22,10 @@ import {
|
||||
|
||||
interface HardwareCertificateSettingsProps {
|
||||
parameters: CertSignParameters;
|
||||
onParameterChange: (key: keyof CertSignParameters, value: any) => void;
|
||||
onParameterChange: <K extends keyof CertSignParameters>(
|
||||
key: K,
|
||||
value: CertSignParameters[K],
|
||||
) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
@@ -176,16 +179,20 @@ const HardwareCertificateSettings = ({
|
||||
setError(null);
|
||||
listWindowsCertificates()
|
||||
.then(applyCerts)
|
||||
.catch((e: any) =>
|
||||
.catch((e) => {
|
||||
const err = e as {
|
||||
response?: { data?: { message?: string } };
|
||||
message?: string;
|
||||
};
|
||||
setError(
|
||||
e?.response?.data?.message ||
|
||||
e?.message ||
|
||||
err?.response?.data?.message ||
|
||||
err?.message ||
|
||||
t(
|
||||
"certSign.hardware.windowsLoadError",
|
||||
"Could not read the Windows certificate store",
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
})
|
||||
.finally(() => setLoading(false));
|
||||
}, [applyCerts, t]);
|
||||
|
||||
@@ -221,16 +228,20 @@ const HardwareCertificateSettings = ({
|
||||
pin: parameters.password,
|
||||
})
|
||||
.then(applyCerts)
|
||||
.catch((e: any) =>
|
||||
.catch((e) => {
|
||||
const err = e as {
|
||||
response?: { data?: { message?: string } };
|
||||
message?: string;
|
||||
};
|
||||
setError(
|
||||
e?.response?.data?.message ||
|
||||
e?.message ||
|
||||
err?.response?.data?.message ||
|
||||
err?.message ||
|
||||
t(
|
||||
"certSign.hardware.pkcs11LoadError",
|
||||
"Could not read certificates from the token. Check the PIN and driver.",
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
})
|
||||
.finally(() => setLoading(false));
|
||||
}, [
|
||||
applyCerts,
|
||||
|
||||
@@ -5,7 +5,10 @@ import { CertSignParameters } from "@app/hooks/tools/certSign/useCertSignParamet
|
||||
|
||||
interface SignatureAppearanceSettingsProps {
|
||||
parameters: CertSignParameters;
|
||||
onParameterChange: (key: keyof CertSignParameters, value: any) => void;
|
||||
onParameterChange: <K extends keyof CertSignParameters>(
|
||||
key: K,
|
||||
value: CertSignParameters[K],
|
||||
) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
@@ -101,7 +104,12 @@ const SignatureAppearanceSettings = ({
|
||||
<NumberInput
|
||||
label={t("certSign.pageNumber", "Page Number")}
|
||||
value={parameters.pageNumber}
|
||||
onChange={(value) => onParameterChange("pageNumber", value || 1)}
|
||||
onChange={(value) =>
|
||||
onParameterChange(
|
||||
"pageNumber",
|
||||
typeof value === "number" ? value : 1,
|
||||
)
|
||||
}
|
||||
min={1}
|
||||
disabled={disabled}
|
||||
/>
|
||||
|
||||
@@ -24,7 +24,10 @@ const SignatureSettingsInput = ({
|
||||
}: SignatureSettingsInputProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChange = (key: keyof SignatureSettings, val: any) => {
|
||||
const handleChange = <K extends keyof SignatureSettings>(
|
||||
key: K,
|
||||
val: SignatureSettings[K],
|
||||
) => {
|
||||
onChange({ ...value, [key]: val });
|
||||
};
|
||||
|
||||
@@ -104,7 +107,9 @@ const SignatureSettingsInput = ({
|
||||
<NumberInput
|
||||
label={t("certSign.pageNumber", "Page Number")}
|
||||
value={value.pageNumber || 1}
|
||||
onChange={(val) => handleChange("pageNumber", val || 1)}
|
||||
onChange={(val) =>
|
||||
handleChange("pageNumber", typeof val === "number" ? val : 1)
|
||||
}
|
||||
min={1}
|
||||
disabled={disabled}
|
||||
size="xs"
|
||||
|
||||
@@ -52,6 +52,14 @@ import {
|
||||
const MAX_RENDER_WIDTH = 820;
|
||||
const MIN_BOX_SIZE = 18;
|
||||
|
||||
// Firefox-only fallback for document.caretRangeFromPoint (not in lib.dom.d.ts).
|
||||
const docWithCaret = document as Document & {
|
||||
caretPositionFromPoint?: (
|
||||
x: number,
|
||||
y: number,
|
||||
) => { offsetNode: Node; offset: number } | null;
|
||||
};
|
||||
|
||||
const normalizeFontFormat = (format?: string | null): string => {
|
||||
if (!format) {
|
||||
return "ttf";
|
||||
@@ -352,7 +360,7 @@ const PdfTextEditorView = ({ data }: PdfTextEditorViewProps) => {
|
||||
new Map(),
|
||||
);
|
||||
const draggingImageRef = useRef<string | null>(null);
|
||||
const rndRefs = useRef<Map<string, any>>(new Map());
|
||||
const rndRefs = useRef<Map<string, Rnd>>(new Map());
|
||||
const pendingDragUpdateRef = useRef<number | null>(null);
|
||||
const [fontFamilies, setFontFamilies] = useState<Map<string, string>>(
|
||||
new Map(),
|
||||
@@ -1378,7 +1386,7 @@ const PdfTextEditorView = ({ data }: PdfTextEditorViewProps) => {
|
||||
const cssTop = (pageHeight - bounds.top) * scale;
|
||||
|
||||
// Get current position from Rnd component
|
||||
const currentState = rndRef.state || {};
|
||||
const currentState = (rndRef.state as { x?: number; y?: number }) || {};
|
||||
const currentX = currentState.x ?? 0;
|
||||
const currentY = currentState.y ?? 0;
|
||||
|
||||
@@ -2851,11 +2859,13 @@ const PdfTextEditorView = ({ data }: PdfTextEditorViewProps) => {
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
(document as any).caretPositionFromPoint
|
||||
docWithCaret.caretPositionFromPoint
|
||||
) {
|
||||
const pos = (
|
||||
document as any
|
||||
).caretPositionFromPoint(clickX, clickY);
|
||||
const pos =
|
||||
docWithCaret.caretPositionFromPoint(
|
||||
clickX,
|
||||
clickY,
|
||||
);
|
||||
if (pos) {
|
||||
const range = document.createRange();
|
||||
range.setStart(
|
||||
|
||||
@@ -447,10 +447,8 @@ export async function addFiles(
|
||||
if (file.type === "application/pdf") {
|
||||
try {
|
||||
if (await FileAnalyzer.isPDFUserPasswordProtected(file)) {
|
||||
fileStub.processedFile = (fileStub.processedFile || {
|
||||
pages: [],
|
||||
}) as any;
|
||||
fileStub.processedFile!.isEncrypted = true;
|
||||
fileStub.processedFile = fileStub.processedFile || { pages: [] };
|
||||
fileStub.processedFile.isEncrypted = true;
|
||||
}
|
||||
} catch (error) {
|
||||
// Never block upload on analysis failure — but log so it's debuggable
|
||||
@@ -699,7 +697,7 @@ export async function undoConsumeFiles(
|
||||
file: File,
|
||||
fileId: FileId,
|
||||
existingThumbnail?: string,
|
||||
) => Promise<any>;
|
||||
) => Promise<StirlingFileStub>;
|
||||
deleteFile: (fileId: FileId) => Promise<void>;
|
||||
bumpRevision?: () => void;
|
||||
} | null,
|
||||
|
||||
@@ -398,7 +398,7 @@ export function useFileContext() {
|
||||
addFiles: actions.addFiles,
|
||||
consumeFiles: actions.consumeFiles,
|
||||
undoConsumeFiles: actions.undoConsumeFiles,
|
||||
recordOperation: (_fileId: FileId, _operation: any) => {}, // Operation tracking not implemented
|
||||
recordOperation: (_fileId: FileId, _operation: unknown) => {}, // Operation tracking not implemented
|
||||
markOperationApplied: (_fileId: FileId, _operationId: string) => {}, // Operation tracking not implemented
|
||||
markOperationFailed: (
|
||||
_fileId: FileId,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import { FileId } from "@app/types/file";
|
||||
import {
|
||||
FileContextAction,
|
||||
FileContextState,
|
||||
StirlingFileStub,
|
||||
ProcessedFilePage,
|
||||
} from "@app/types/fileContext";
|
||||
@@ -39,7 +40,7 @@ export class FileLifecycleManager {
|
||||
*/
|
||||
cleanupFile = (
|
||||
fileId: FileId,
|
||||
stateRef?: React.MutableRefObject<any>,
|
||||
stateRef?: React.MutableRefObject<FileContextState>,
|
||||
): void => {
|
||||
// Use comprehensive cleanup (same as removeFiles)
|
||||
this.cleanupAllResourcesForFile(fileId, stateRef);
|
||||
@@ -77,7 +78,7 @@ export class FileLifecycleManager {
|
||||
scheduleCleanup = (
|
||||
fileId: FileId,
|
||||
delay: number = 30000,
|
||||
stateRef?: React.MutableRefObject<any>,
|
||||
stateRef?: React.MutableRefObject<FileContextState>,
|
||||
): void => {
|
||||
// Cancel existing timer
|
||||
const existingTimer = this.cleanupTimers.get(fileId);
|
||||
@@ -116,7 +117,7 @@ export class FileLifecycleManager {
|
||||
*/
|
||||
removeFiles = (
|
||||
fileIds: FileId[],
|
||||
stateRef?: React.MutableRefObject<any>,
|
||||
stateRef?: React.MutableRefObject<FileContextState>,
|
||||
): void => {
|
||||
fileIds.forEach((fileId) => {
|
||||
// Clean up all resources for this file
|
||||
@@ -132,7 +133,7 @@ export class FileLifecycleManager {
|
||||
*/
|
||||
private cleanupAllResourcesForFile = (
|
||||
fileId: FileId,
|
||||
stateRef?: React.MutableRefObject<any>,
|
||||
stateRef?: React.MutableRefObject<FileContextState>,
|
||||
): void => {
|
||||
// Remove from files ref
|
||||
this.filesRef.current.delete(fileId);
|
||||
@@ -188,7 +189,7 @@ export class FileLifecycleManager {
|
||||
updateStirlingFileStub = (
|
||||
fileId: FileId,
|
||||
updates: Partial<StirlingFileStub>,
|
||||
stateRef?: React.MutableRefObject<any>,
|
||||
stateRef?: React.MutableRefObject<FileContextState>,
|
||||
): void => {
|
||||
// Guard against updating removed files (race condition protection)
|
||||
if (!this.filesRef.current.has(fileId)) {
|
||||
|
||||
@@ -345,11 +345,15 @@ export const useConvertOperation = (parameters?: ConvertParameters) => {
|
||||
...convertOperationConfig,
|
||||
customProcessor: customConvertProcessor, // Use instance-specific processor for translation support
|
||||
getErrorMessage: (error) => {
|
||||
if (error.response?.data && typeof error.response.data === "string") {
|
||||
return error.response.data;
|
||||
const err = error as {
|
||||
response?: { data?: unknown };
|
||||
message?: string;
|
||||
};
|
||||
if (err.response?.data && typeof err.response.data === "string") {
|
||||
return err.response.data;
|
||||
}
|
||||
if (error.message) {
|
||||
return error.message;
|
||||
if (err.message) {
|
||||
return err.message;
|
||||
}
|
||||
return t(
|
||||
"convert.errorConversion",
|
||||
|
||||
@@ -179,13 +179,15 @@ export const useOCROperation = () => {
|
||||
const ocrConfig: ToolOperationConfig<OCRParameters> = {
|
||||
...ocrOperationConfig,
|
||||
responseHandler,
|
||||
getErrorMessage: (error) =>
|
||||
error.message?.includes("OCR tools") &&
|
||||
error.message?.includes("not installed")
|
||||
getErrorMessage: (error) => {
|
||||
const message = (error as { message?: string }).message;
|
||||
return message?.includes("OCR tools") &&
|
||||
message?.includes("not installed")
|
||||
? "OCR tools (OCRmyPDF or Tesseract) are not installed on the server. Use the standard or fat Docker image instead of ultra-lite, or install OCR tools manually."
|
||||
: createStandardErrorHandler(
|
||||
t("ocr.error.failed", "OCR operation failed"),
|
||||
)(error),
|
||||
)(error);
|
||||
},
|
||||
};
|
||||
|
||||
return useToolOperation(ocrConfig);
|
||||
|
||||
@@ -74,7 +74,7 @@ interface BaseToolOperationConfig<TParams, TEndpoint extends ToolEndpoint> {
|
||||
responseHandler?: ResponseHandler;
|
||||
|
||||
/** Extract user-friendly error messages from API errors */
|
||||
getErrorMessage?: (error: any) => string;
|
||||
getErrorMessage?: (error: unknown) => string;
|
||||
|
||||
/** Default parameter values for automation */
|
||||
defaultParameters?: TParams;
|
||||
|
||||
@@ -218,7 +218,7 @@ export const useToolOperation = <TParams>(
|
||||
// Listen for global error file id events from HTTP interceptor during this run
|
||||
let externalErrorFileIds: string[] = [];
|
||||
const errorListener = (e: Event) => {
|
||||
const detail = (e as CustomEvent)?.detail as any;
|
||||
const detail = (e as CustomEvent<{ fileIds?: unknown }>)?.detail;
|
||||
if (detail?.fileIds) {
|
||||
externalErrorFileIds = Array.isArray(detail.fileIds)
|
||||
? detail.fileIds
|
||||
@@ -588,7 +588,7 @@ export const useToolOperation = <TParams>(
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (error: any) {
|
||||
} catch (error) {
|
||||
try {
|
||||
const handled = await handle422Error(error, (id) =>
|
||||
fileActions.markFileError(id as FileId),
|
||||
@@ -691,21 +691,22 @@ export const useToolOperation = <TParams>(
|
||||
|
||||
// Show success message
|
||||
actions.setStatus(t("undoSuccess", "Operation undone successfully"));
|
||||
} catch (error: any) {
|
||||
} catch (error) {
|
||||
let errorMessage = extractErrorMessage(error);
|
||||
|
||||
// Provide more specific error messages based on error type
|
||||
if (error.message?.includes("Mismatch between input files")) {
|
||||
const err = error as { message?: string; name?: string };
|
||||
if (err.message?.includes("Mismatch between input files")) {
|
||||
errorMessage = t(
|
||||
"undoDataMismatch",
|
||||
"Cannot undo: operation data is corrupted",
|
||||
);
|
||||
} else if (error.message?.includes("IndexedDB")) {
|
||||
} else if (err.message?.includes("IndexedDB")) {
|
||||
errorMessage = t(
|
||||
"undoStorageError",
|
||||
"Undo completed but some files could not be saved to storage",
|
||||
);
|
||||
} else if (error.name === "QuotaExceededError") {
|
||||
} else if (err.name === "QuotaExceededError") {
|
||||
errorMessage = t(
|
||||
"undoQuotaError",
|
||||
"Cannot undo: insufficient storage space",
|
||||
|
||||
@@ -74,21 +74,14 @@ const modernGlobals: OxlintGlobals = {
|
||||
|
||||
// Folders not yet conformant to the stricter no-explicit-any rule
|
||||
const noExplicitAnyExcludes = [
|
||||
"editor/src/core/components/annotation/**/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/components/pageEditor/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/components/shared/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/components/shared/config/configSections/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/components/tools/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/components/tools/addStamp/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/components/tools/automate/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/components/tools/certSign/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/components/tools/pdfTextEditor/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/components/viewer/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/contexts/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/contexts/file/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/contexts/viewer/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/hooks/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/hooks/tools/shared/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/services/*.{js,mjs,jsx,ts,tsx}",
|
||||
"editor/src/core/tools/annotate/useAnnotationSelection.ts",
|
||||
"editor/src/core/types/*.{js,mjs,jsx,ts,tsx}",
|
||||
|
||||
Reference in New Issue
Block a user