merge changes

This commit is contained in:
EthanHealy01 2025-09-15 16:54:36 +01:00
parent f54b0a9325
commit 7853ddfd9b
5 changed files with 59 additions and 16 deletions

View File

@ -1018,7 +1018,8 @@
"title": "Remove Pages", "title": "Remove Pages",
"pageNumbers": { "pageNumbers": {
"label": "Pages to Remove", "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", "filenamePrefix": "pages_removed",
"files": { "files": {

View File

@ -747,7 +747,8 @@
"title": "Remove Pages", "title": "Remove Pages",
"pageNumbers": { "pageNumbers": {
"label": "Pages to Remove", "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", "filenamePrefix": "pages_removed",
"files": { "files": {

View File

@ -13,7 +13,7 @@ const RemoveBlanksSettings = ({ parameters, onParameterChange, disabled = false
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Stack gap="md"> <Stack gap="lg" mt="md">
<Stack gap="xs"> <Stack gap="xs">
<NumberInputWithUnit <NumberInputWithUnit
label={t('removeBlanks.threshold.label', 'Pixel Whiteness Threshold')} label={t('removeBlanks.threshold.label', 'Pixel Whiteness Threshold')}
@ -24,9 +24,6 @@ const RemoveBlanksSettings = ({ parameters, onParameterChange, disabled = false
max={255} max={255}
disabled={disabled} disabled={disabled}
/> />
<Text size="xs" c="dimmed">
{t('removeBlanks.threshold.desc', "Threshold for determining how white a white pixel must be to be classed as 'White'. 0 = Black, 255 pure white.")}
</Text>
</Stack> </Stack>
<Stack gap="xs"> <Stack gap="xs">
@ -39,9 +36,6 @@ const RemoveBlanksSettings = ({ parameters, onParameterChange, disabled = false
max={100} max={100}
disabled={disabled} disabled={disabled}
/> />
<Text size="xs" c="dimmed">
{t('removeBlanks.whitePercent.desc', "Percent of page that must be 'white' pixels to be removed")}
</Text>
</Stack> </Stack>
<Stack gap="xs"> <Stack gap="xs">
@ -52,9 +46,6 @@ const RemoveBlanksSettings = ({ parameters, onParameterChange, disabled = false
label={ label={
<div> <div>
<Text size="sm">{t('removeBlanks.includeBlankPages.label', 'Include detected blank pages')}</Text> <Text size="sm">{t('removeBlanks.includeBlankPages.label', 'Include detected blank pages')}</Text>
<Text size="xs" c="dimmed">
{t('removeBlanks.includeBlankPages.desc', 'Include the detected blank pages as a separate PDF in the output')}
</Text>
</div> </div>
} }
/> />

View File

@ -8,15 +8,41 @@ interface RemovePagesSettingsProps {
disabled?: boolean; 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 RemovePagesSettings = ({ parameters, onParameterChange, disabled = false }: RemovePagesSettingsProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const handlePageNumbersChange = (value: string) => { const handlePageNumbersChange = (value: string) => {
// Remove spaces and normalize input // Allow user to type naturally - don't normalize input in real-time
const normalized = value.replace(/\s+/g, ''); onParameterChange('pageNumbers', value);
onParameterChange('pageNumbers', normalized);
}; };
// Check if current input is valid
const isValid = validatePageNumbers(parameters.pageNumbers);
const hasValue = parameters.pageNumbers.trim().length > 0;
return ( return (
<Stack gap="md"> <Stack gap="md">
<TextInput <TextInput
@ -26,6 +52,7 @@ const RemovePagesSettings = ({ parameters, onParameterChange, disabled = false }
placeholder={t('removePages.pageNumbers.placeholder', 'e.g., 1,3,5-8,10')} placeholder={t('removePages.pageNumbers.placeholder', 'e.g., 1,3,5-8,10')}
disabled={disabled} disabled={disabled}
required required
error={hasValue && !isValid ? t('removePages.pageNumbers.error', 'Invalid page number format. Use numbers, ranges (1-5), or mathematical expressions (2n+1)') : undefined}
/> />
</Stack> </Stack>
); );

View File

@ -11,10 +11,33 @@ export const defaultParameters: RemovePagesParameters = {
export type RemovePagesParametersHook = BaseParametersHook<RemovePagesParameters>; export type RemovePagesParametersHook = BaseParametersHook<RemovePagesParameters>;
// 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 => { export const useRemovePagesParameters = (): RemovePagesParametersHook => {
return useBaseParameters({ return useBaseParameters({
defaultParameters, defaultParameters,
endpointName: 'remove-pages', endpointName: 'remove-pages',
validateFn: (p) => p.pageNumbers.trim().length > 0, validateFn: (p) => validatePageNumbers(p.pageNumbers),
}); });
}; };