From b2032023f84d5544ff8562f8fd8db590570575e7 Mon Sep 17 00:00:00 2001 From: Connor Yoh Date: Fri, 12 Sep 2025 14:18:33 +0100 Subject: [PATCH] Flattern Split by size, count and document --- .../components/tools/split/SplitSettings.tsx | 61 ++++++++----------- frontend/src/constants/splitConstants.ts | 31 ++++++++-- .../hooks/tools/split/useSplitOperation.ts | 41 +++++++------ .../hooks/tools/split/useSplitParameters.ts | 26 ++++---- 4 files changed, 90 insertions(+), 69 deletions(-) diff --git a/frontend/src/components/tools/split/SplitSettings.tsx b/frontend/src/components/tools/split/SplitSettings.tsx index 936b5a09f..e17f65190 100644 --- a/frontend/src/components/tools/split/SplitSettings.tsx +++ b/frontend/src/components/tools/split/SplitSettings.tsx @@ -1,6 +1,6 @@ import { Stack, TextInput, Select, Checkbox } from '@mantine/core'; import { useTranslation } from 'react-i18next'; -import { isSplitMode, isSplitType, SPLIT_MODES, SPLIT_TYPES } from '../../../constants/splitConstants'; +import { isSplitMethod, SPLIT_METHODS, METHOD_TO_SPLIT_TYPE, SPLIT_TYPES } from '../../../constants/splitConstants'; import { SplitParameters } from '../../../hooks/tools/split/useSplitParameters'; export interface SplitSettingsProps { @@ -57,27 +57,14 @@ const SplitSettings = ({ ); - const renderBySizeOrCountForm = () => ( - - isSplitMode(v) && onParameterChange('mode', v)} + label={t("split.method.label", "Choose split method")} + placeholder={t("split.method.placeholder", "Select how to split the PDF")} + value={parameters.method} + onChange={(v) => isSplitMethod(v) && onParameterChange('method', v)} disabled={disabled} data={[ - { value: SPLIT_MODES.BY_PAGES, label: t("split.header", "Split by Pages") + " (e.g. 1,3,5-10)" }, - { value: SPLIT_MODES.BY_SECTIONS, label: t("split-by-sections.title", "Split by Grid Sections") }, - { value: SPLIT_MODES.BY_SIZE_OR_COUNT, label: t("split-by-size-or-count.title", "Split by Size or Count") }, - { value: SPLIT_MODES.BY_CHAPTERS, label: t("splitByChapters.title", "Split by Chapters") }, + { value: SPLIT_METHODS.BY_PAGES, label: t("split.header", "Split by Pages") + " (e.g. 1,3,5-10)" }, + { value: SPLIT_METHODS.BY_SECTIONS, label: t("split-by-sections.title", "Split by Grid Sections") }, + { value: SPLIT_METHODS.BY_SIZE, label: t("split-by-size-or-count.type.size", "By Size") }, + { value: SPLIT_METHODS.BY_PAGE_COUNT, label: t("split-by-size-or-count.type.pageCount", "By Page Count") }, + { value: SPLIT_METHODS.BY_DOC_COUNT, label: t("split-by-size-or-count.type.docCount", "By Document Count") }, + { value: SPLIT_METHODS.BY_CHAPTERS, label: t("splitByChapters.title", "Split by Chapters") }, ]} /> {/* Parameter Form */} - {parameters.mode === SPLIT_MODES.BY_PAGES && renderByPagesForm()} - {parameters.mode === SPLIT_MODES.BY_SECTIONS && renderBySectionsForm()} - {parameters.mode === SPLIT_MODES.BY_SIZE_OR_COUNT && renderBySizeOrCountForm()} - {parameters.mode === SPLIT_MODES.BY_CHAPTERS && renderByChaptersForm()} + {parameters.method === SPLIT_METHODS.BY_PAGES && renderByPagesForm()} + {parameters.method === SPLIT_METHODS.BY_SECTIONS && renderBySectionsForm()} + {(parameters.method === SPLIT_METHODS.BY_SIZE || + parameters.method === SPLIT_METHODS.BY_PAGE_COUNT || + parameters.method === SPLIT_METHODS.BY_DOC_COUNT) && renderSplitValueForm()} + {parameters.method === SPLIT_METHODS.BY_CHAPTERS && renderByChaptersForm()} ); } diff --git a/frontend/src/constants/splitConstants.ts b/frontend/src/constants/splitConstants.ts index 1e7098669..55230b068 100644 --- a/frontend/src/constants/splitConstants.ts +++ b/frontend/src/constants/splitConstants.ts @@ -1,3 +1,13 @@ +export const SPLIT_METHODS = { + BY_PAGES: 'byPages', + BY_SECTIONS: 'bySections', + BY_SIZE: 'bySize', + BY_PAGE_COUNT: 'byPageCount', + BY_DOC_COUNT: 'byDocCount', + BY_CHAPTERS: 'byChapters' +} as const; + +// Legacy constants for backward compatibility export const SPLIT_MODES = { BY_PAGES: 'byPages', BY_SECTIONS: 'bySections', @@ -12,15 +22,28 @@ export const SPLIT_TYPES = { } as const; export const ENDPOINTS = { - [SPLIT_MODES.BY_PAGES]: 'split-pages', - [SPLIT_MODES.BY_SECTIONS]: 'split-pdf-by-sections', - [SPLIT_MODES.BY_SIZE_OR_COUNT]: 'split-by-size-or-count', - [SPLIT_MODES.BY_CHAPTERS]: 'split-pdf-by-chapters' + [SPLIT_METHODS.BY_PAGES]: 'split-pages', + [SPLIT_METHODS.BY_SECTIONS]: 'split-pdf-by-sections', + [SPLIT_METHODS.BY_SIZE]: 'split-by-size-or-count', + [SPLIT_METHODS.BY_PAGE_COUNT]: 'split-by-size-or-count', + [SPLIT_METHODS.BY_DOC_COUNT]: 'split-by-size-or-count', + [SPLIT_METHODS.BY_CHAPTERS]: 'split-pdf-by-chapters' } as const; +export const METHOD_TO_SPLIT_TYPE = { + [SPLIT_METHODS.BY_SIZE]: SPLIT_TYPES.SIZE, + [SPLIT_METHODS.BY_PAGE_COUNT]: SPLIT_TYPES.PAGES, + [SPLIT_METHODS.BY_DOC_COUNT]: SPLIT_TYPES.DOCS +} as const; + +export type SplitMethod = typeof SPLIT_METHODS[keyof typeof SPLIT_METHODS]; export type SplitMode = typeof SPLIT_MODES[keyof typeof SPLIT_MODES]; export type SplitType = typeof SPLIT_TYPES[keyof typeof SPLIT_TYPES]; +export const isSplitMethod = (value: string | null): value is SplitMethod => { + return Object.values(SPLIT_METHODS).includes(value as SplitMethod); +} + export const isSplitMode = (value: string | null): value is SplitMode => { return Object.values(SPLIT_MODES).includes(value as SplitMode); } diff --git a/frontend/src/hooks/tools/split/useSplitOperation.ts b/frontend/src/hooks/tools/split/useSplitOperation.ts index b18b7c1f5..97e439f48 100644 --- a/frontend/src/hooks/tools/split/useSplitOperation.ts +++ b/frontend/src/hooks/tools/split/useSplitOperation.ts @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import { ToolType, useToolOperation, ToolOperationConfig } from '../shared/useToolOperation'; import { createStandardErrorHandler } from '../../../utils/toolErrorHandler'; import { SplitParameters, defaultParameters } from './useSplitParameters'; -import { SPLIT_MODES } from '../../../constants/splitConstants'; +import { SPLIT_METHODS, METHOD_TO_SPLIT_TYPE } from '../../../constants/splitConstants'; import { useToolResources } from '../shared/useToolResources'; // Static functions that can be used by both the hook and automation executor @@ -12,46 +12,53 @@ export const buildSplitFormData = (parameters: SplitParameters, file: File): For formData.append("fileInput", file); - switch (parameters.mode) { - case SPLIT_MODES.BY_PAGES: + switch (parameters.method) { + case SPLIT_METHODS.BY_PAGES: formData.append("pageNumbers", parameters.pages); break; - case SPLIT_MODES.BY_SECTIONS: + case SPLIT_METHODS.BY_SECTIONS: formData.append("horizontalDivisions", parameters.hDiv); formData.append("verticalDivisions", parameters.vDiv); formData.append("merge", parameters.merge.toString()); break; - case SPLIT_MODES.BY_SIZE_OR_COUNT: - formData.append( - "splitType", - parameters.splitType === "size" ? "0" : parameters.splitType === "pages" ? "1" : "2" - ); + case SPLIT_METHODS.BY_SIZE: + formData.append("splitType", "0"); formData.append("splitValue", parameters.splitValue); break; - case SPLIT_MODES.BY_CHAPTERS: + case SPLIT_METHODS.BY_PAGE_COUNT: + formData.append("splitType", "1"); + formData.append("splitValue", parameters.splitValue); + break; + case SPLIT_METHODS.BY_DOC_COUNT: + formData.append("splitType", "2"); + formData.append("splitValue", parameters.splitValue); + break; + case SPLIT_METHODS.BY_CHAPTERS: formData.append("bookmarkLevel", parameters.bookmarkLevel); formData.append("includeMetadata", parameters.includeMetadata.toString()); formData.append("allowDuplicates", parameters.allowDuplicates.toString()); break; default: - throw new Error(`Unknown split mode: ${parameters.mode}`); + throw new Error(`Unknown split method: ${parameters.method}`); } return formData; }; export const getSplitEndpoint = (parameters: SplitParameters): string => { - switch (parameters.mode) { - case SPLIT_MODES.BY_PAGES: + switch (parameters.method) { + case SPLIT_METHODS.BY_PAGES: return "/api/v1/general/split-pages"; - case SPLIT_MODES.BY_SECTIONS: + case SPLIT_METHODS.BY_SECTIONS: return "/api/v1/general/split-pdf-by-sections"; - case SPLIT_MODES.BY_SIZE_OR_COUNT: + case SPLIT_METHODS.BY_SIZE: + case SPLIT_METHODS.BY_PAGE_COUNT: + case SPLIT_METHODS.BY_DOC_COUNT: return "/api/v1/general/split-by-size-or-count"; - case SPLIT_MODES.BY_CHAPTERS: + case SPLIT_METHODS.BY_CHAPTERS: return "/api/v1/general/split-pdf-by-chapters"; default: - throw new Error(`Unknown split mode: ${parameters.mode}`); + throw new Error(`Unknown split method: ${parameters.method}`); } }; diff --git a/frontend/src/hooks/tools/split/useSplitParameters.ts b/frontend/src/hooks/tools/split/useSplitParameters.ts index e48504304..9722e718d 100644 --- a/frontend/src/hooks/tools/split/useSplitParameters.ts +++ b/frontend/src/hooks/tools/split/useSplitParameters.ts @@ -1,14 +1,13 @@ -import { SPLIT_MODES, SPLIT_TYPES, ENDPOINTS, type SplitMode, SplitType } from '../../../constants/splitConstants'; +import { SPLIT_METHODS, SPLIT_MODES, SPLIT_TYPES, ENDPOINTS, METHOD_TO_SPLIT_TYPE, type SplitMethod, SplitMode, SplitType } from '../../../constants/splitConstants'; import { BaseParameters } from '../../../types/parameters'; import { useBaseParameters, BaseParametersHook } from '../shared/useBaseParameters'; export interface SplitParameters extends BaseParameters { - mode: SplitMode | ''; + method: SplitMethod | ''; pages: string; hDiv: string; vDiv: string; merge: boolean; - splitType: SplitType | ''; splitValue: string; bookmarkLevel: string; includeMetadata: boolean; @@ -18,12 +17,11 @@ export interface SplitParameters extends BaseParameters { export type SplitParametersHook = BaseParametersHook; export const defaultParameters: SplitParameters = { - mode: '', + method: '', pages: '', hDiv: '2', vDiv: '2', merge: false, - splitType: SPLIT_TYPES.SIZE, splitValue: '', bookmarkLevel: '1', includeMetadata: false, @@ -34,20 +32,22 @@ export const useSplitParameters = (): SplitParametersHook => { return useBaseParameters({ defaultParameters, endpointName: (params) => { - if (!params.mode) return ENDPOINTS[SPLIT_MODES.BY_PAGES]; - return ENDPOINTS[params.mode as SplitMode]; + if (!params.method) return ENDPOINTS[SPLIT_METHODS.BY_PAGES]; + return ENDPOINTS[params.method as SplitMethod]; }, validateFn: (params) => { - if (!params.mode) return false; + if (!params.method) return false; - switch (params.mode) { - case SPLIT_MODES.BY_PAGES: + switch (params.method) { + case SPLIT_METHODS.BY_PAGES: return params.pages.trim() !== ""; - case SPLIT_MODES.BY_SECTIONS: + case SPLIT_METHODS.BY_SECTIONS: return params.hDiv !== "" && params.vDiv !== ""; - case SPLIT_MODES.BY_SIZE_OR_COUNT: + case SPLIT_METHODS.BY_SIZE: + case SPLIT_METHODS.BY_PAGE_COUNT: + case SPLIT_METHODS.BY_DOC_COUNT: return params.splitValue.trim() !== ""; - case SPLIT_MODES.BY_CHAPTERS: + case SPLIT_METHODS.BY_CHAPTERS: return params.bookmarkLevel !== ""; default: return false;