[V2] feat(split): add split mode options and custom page selection to section split (#5277)

# Description of Changes


This pull request adds a new "Split Mode" feature to the "Split by
Sections" tool, allowing users to customize how pages are split,
including options to exclude the first/last pages or specify custom
pages. The changes include updates to the UI, form data handling,
parameter definitions, and validation logic to support these new
options.

**Split by Sections: New Split Mode Feature**

*UI Enhancements:*
- Added a `Radio.Group` in `SplitSettings.tsx` to let users choose the
split mode (split all, exclude first/last, or custom pages), and a
conditional `TextInput` for custom page numbers when "Custom" is
selected.

*Localization:*
- Updated `translation.toml` with new labels and descriptions for the
split mode options and custom page numbers.

*Parameter Handling:*
- Extended the `SplitParameters` interface to include `splitMode` and
`customPages`, and set their default values.

*Form Submission:*
- Modified `buildSplitFormData` to include the selected split mode and
custom page numbers (if applicable) in the form data sent to the
backend.

*Validation Logic:*
- Updated the validation logic in `useSplitParameters` to require custom
page numbers when the custom split mode is selected.

<img width="363" height="998" alt="image"
src="https://github.com/user-attachments/assets/c9f781a6-cf7e-4f3d-8514-57cfe468e0c8"
/>




<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [X] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [X] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [X] I have performed a self-review of my own code
- [X] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [X] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [X] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
This commit is contained in:
Balázs Szücs 2025-12-22 20:28:00 +01:00 committed by GitHub
parent d9622d0fac
commit 7baf503d60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 50 additions and 2 deletions

View File

@ -3375,6 +3375,19 @@ placeholder = "Enter number of horizontal divisions"
label = "Vertical Divisions"
placeholder = "Enter number of vertical divisions"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Stamp, Add image, center image, Watermark, PDF, Embed, Customize,Customise"
header = "Stamp PDF"

View File

@ -1,4 +1,4 @@
import { Stack, TextInput, Checkbox, Anchor, Text } from '@mantine/core';
import { Stack, TextInput, Checkbox, Anchor, Text, Select } from '@mantine/core';
import LocalIcon from '@app/components/shared/LocalIcon';
import { useTranslation } from 'react-i18next';
import { SPLIT_METHODS } from '@app/constants/splitConstants';
@ -49,6 +49,29 @@ const SplitSettings = ({
placeholder={t("split-by-sections.vertical.placeholder", "Enter number of vertical divisions")}
disabled={disabled}
/>
<Select
label={t("split-by-sections.splitMode.label", "Split Mode")}
value={parameters.splitMode || 'SPLIT_ALL'}
onChange={(value) => onParameterChange('splitMode', value || 'SPLIT_ALL')}
description={t("split-by-sections.splitMode.description", "Choose how to split the pages")}
data={[
{ value: 'SPLIT_ALL', label: t("split-by-sections.splitMode.splitAll", "Split all pages") },
{ value: 'SPLIT_ALL_EXCEPT_FIRST', label: t("split-by-sections.splitMode.splitAllExceptFirst", "Split all except first") },
{ value: 'SPLIT_ALL_EXCEPT_LAST', label: t("split-by-sections.splitMode.splitAllExceptLast", "Split all except last") },
{ value: 'SPLIT_ALL_EXCEPT_FIRST_AND_LAST', label: t("split-by-sections.splitMode.splitAllExceptFirstAndLast", "Split all except first and last") },
{ value: 'CUSTOM', label: t("split-by-sections.splitMode.custom", "Custom pages") },
]}
disabled={disabled}
/>
{parameters.splitMode === 'CUSTOM' && (
<TextInput
label={t("split-by-sections.customPages.label", "Custom Page Numbers")}
placeholder={t("split-by-sections.customPages.placeholder", "e.g. 2,4,6")}
value={parameters.customPages || ''}
onChange={(e) => onParameterChange('customPages', e.target.value)}
disabled={disabled}
/>
)}
<Checkbox
label={t("split-by-sections.merge", "Merge sections into one PDF")}
checked={parameters.merge}

View File

@ -20,6 +20,10 @@ export const buildSplitFormData = (parameters: SplitParameters, file: File): For
formData.append("horizontalDivisions", parameters.hDiv);
formData.append("verticalDivisions", parameters.vDiv);
formData.append("merge", parameters.merge.toString());
formData.append("splitMode", parameters.splitMode || 'SPLIT_ALL');
if (parameters.splitMode === 'CUSTOM' && parameters.customPages) {
formData.append("pageNumbers", parameters.customPages);
}
break;
case SPLIT_METHODS.BY_SIZE:
formData.append("splitType", "0");

View File

@ -13,6 +13,8 @@ export interface SplitParameters extends BaseParameters {
includeMetadata: boolean;
allowDuplicates: boolean;
duplexMode: boolean;
splitMode?: string;
customPages?: string;
}
export type SplitParametersHook = BaseParametersHook<SplitParameters>;
@ -28,6 +30,8 @@ export const defaultParameters: SplitParameters = {
includeMetadata: false,
allowDuplicates: false,
duplexMode: false,
splitMode: 'SPLIT_ALL',
customPages: '',
};
export const useSplitParameters = (): SplitParametersHook => {
@ -44,7 +48,11 @@ export const useSplitParameters = (): SplitParametersHook => {
case SPLIT_METHODS.BY_PAGES:
return params.pages.trim() !== "";
case SPLIT_METHODS.BY_SECTIONS:
return params.hDiv !== "" && params.vDiv !== "";
if (params.hDiv === "" || params.vDiv === "") return false;
if (params.splitMode === 'CUSTOM') {
return (params.customPages || '').trim() !== "";
}
return true;
case SPLIT_METHODS.BY_SIZE:
case SPLIT_METHODS.BY_PAGE_COUNT:
case SPLIT_METHODS.BY_DOC_COUNT: