diff --git a/frontend/public/locales/en-GB/translation.json b/frontend/public/locales/en-GB/translation.json index e4979fbbd..d29f2407b 100644 --- a/frontend/public/locales/en-GB/translation.json +++ b/frontend/public/locales/en-GB/translation.json @@ -1018,7 +1018,8 @@ "title": "Remove Pages", "pageNumbers": { "label": "Pages to Remove", - "placeholder": "e.g., 1,3,5-8,10" + "placeholder": "e.g., 1,3,5-8,10", + "error": "Invalid page number format. Use numbers, ranges (1-5), or mathematical expressions (2n+1)" }, "filenamePrefix": "pages_removed", "files": { diff --git a/frontend/public/locales/en-US/translation.json b/frontend/public/locales/en-US/translation.json index ff3ccaaf7..359b27160 100644 --- a/frontend/public/locales/en-US/translation.json +++ b/frontend/public/locales/en-US/translation.json @@ -747,7 +747,8 @@ "title": "Remove Pages", "pageNumbers": { "label": "Pages to Remove", - "placeholder": "e.g., 1,3,5-8,10" + "placeholder": "e.g., 1,3,5-8,10", + "error": "Invalid page number format. Use numbers, ranges (1-5), or mathematical expressions (2n+1)" }, "filenamePrefix": "pages_removed", "files": { diff --git a/frontend/src/components/tools/removeBlanks/RemoveBlanksSettings.tsx b/frontend/src/components/tools/removeBlanks/RemoveBlanksSettings.tsx index f40435267..0806423c5 100644 --- a/frontend/src/components/tools/removeBlanks/RemoveBlanksSettings.tsx +++ b/frontend/src/components/tools/removeBlanks/RemoveBlanksSettings.tsx @@ -13,7 +13,7 @@ const RemoveBlanksSettings = ({ parameters, onParameterChange, disabled = false const { t } = useTranslation(); return ( - + - - {t('removeBlanks.threshold.desc', "Threshold for determining how white a white pixel must be to be classed as 'White'. 0 = Black, 255 pure white.")} - @@ -39,9 +36,6 @@ const RemoveBlanksSettings = ({ parameters, onParameterChange, disabled = false max={100} disabled={disabled} /> - - {t('removeBlanks.whitePercent.desc', "Percent of page that must be 'white' pixels to be removed")} - @@ -52,9 +46,6 @@ const RemoveBlanksSettings = ({ parameters, onParameterChange, disabled = false label={
{t('removeBlanks.includeBlankPages.label', 'Include detected blank pages')} - - {t('removeBlanks.includeBlankPages.desc', 'Include the detected blank pages as a separate PDF in the output')} -
} /> diff --git a/frontend/src/components/tools/removePages/RemovePagesSettings.tsx b/frontend/src/components/tools/removePages/RemovePagesSettings.tsx index 052455f14..3ffa115d9 100644 --- a/frontend/src/components/tools/removePages/RemovePagesSettings.tsx +++ b/frontend/src/components/tools/removePages/RemovePagesSettings.tsx @@ -8,15 +8,41 @@ interface RemovePagesSettingsProps { disabled?: boolean; } +// Validation function for page numbers (same as in parameters hook) +const validatePageNumbers = (pageNumbers: string): boolean => { + if (!pageNumbers.trim()) return false; + + // Normalize input for validation: remove spaces around commas and other spaces + const normalized = pageNumbers.replace(/\s*,\s*/g, ',').replace(/\s+/g, ''); + const parts = normalized.split(','); + + // Regular expressions for different page number formats + const singlePageRegex = /^\d+$/; // Single page: 1, 2, 3, etc. + const rangeRegex = /^\d+-\d*$/; // Range: 1-5, 10-, etc. + const negativeRegex = /^-\d+$/; // Negative: -3 (last 3 pages) + const mathRegex = /^\d*[n]\d*[+\-*/]\d+$/; // Mathematical: 2n+1, n-1, etc. + + return parts.every(part => { + if (!part) return false; + return singlePageRegex.test(part) || + rangeRegex.test(part) || + negativeRegex.test(part) || + mathRegex.test(part); + }); +}; + const RemovePagesSettings = ({ parameters, onParameterChange, disabled = false }: RemovePagesSettingsProps) => { const { t } = useTranslation(); const handlePageNumbersChange = (value: string) => { - // Remove spaces and normalize input - const normalized = value.replace(/\s+/g, ''); - onParameterChange('pageNumbers', normalized); + // Allow user to type naturally - don't normalize input in real-time + onParameterChange('pageNumbers', value); }; + // Check if current input is valid + const isValid = validatePageNumbers(parameters.pageNumbers); + const hasValue = parameters.pageNumbers.trim().length > 0; + return ( ); diff --git a/frontend/src/hooks/tools/removePages/useRemovePagesParameters.ts b/frontend/src/hooks/tools/removePages/useRemovePagesParameters.ts index 6a2830f2e..cdbb03eef 100644 --- a/frontend/src/hooks/tools/removePages/useRemovePagesParameters.ts +++ b/frontend/src/hooks/tools/removePages/useRemovePagesParameters.ts @@ -11,10 +11,33 @@ export const defaultParameters: RemovePagesParameters = { export type RemovePagesParametersHook = BaseParametersHook; +// Validation function for page numbers +const validatePageNumbers = (pageNumbers: string): boolean => { + if (!pageNumbers.trim()) return false; + + // Normalize input for validation: remove spaces around commas and other spaces + const normalized = pageNumbers.replace(/\s*,\s*/g, ',').replace(/\s+/g, ''); + const parts = normalized.split(','); + + // Regular expressions for different page number formats + const singlePageRegex = /^\d+$/; // Single page: 1, 2, 3, etc. + const rangeRegex = /^\d+-\d*$/; // Range: 1-5, 10-, etc. + const negativeRegex = /^-\d+$/; // Negative: -3 (last 3 pages) + const mathRegex = /^\d*[n]\d*[+\-*/]\d+$/; // Mathematical: 2n+1, n-1, etc. + + return parts.every(part => { + if (!part) return false; + return singlePageRegex.test(part) || + rangeRegex.test(part) || + negativeRegex.test(part) || + mathRegex.test(part); + }); +}; + export const useRemovePagesParameters = (): RemovePagesParametersHook => { return useBaseParameters({ defaultParameters, endpointName: 'remove-pages', - validateFn: (p) => p.pageNumbers.trim().length > 0, + validateFn: (p) => validatePageNumbers(p.pageNumbers), }); };