diff --git a/frontend/src/components/tools/split/SplitMethodSelector.tsx b/frontend/src/components/shared/CardSelector.tsx similarity index 58% rename from frontend/src/components/tools/split/SplitMethodSelector.tsx rename to frontend/src/components/shared/CardSelector.tsx index dda57d598..a8e4a2725 100644 --- a/frontend/src/components/tools/split/SplitMethodSelector.tsx +++ b/frontend/src/components/shared/CardSelector.tsx @@ -1,39 +1,50 @@ -import { Stack, Card, Text, Flex } from '@mantine/core'; -import { Tooltip } from '../../shared/Tooltip'; +import { Stack, Card, Text, Flex } from '@mantine/core'; +import { Tooltip } from './Tooltip'; import { useTranslation } from 'react-i18next'; -import { type SplitMethod, METHOD_OPTIONS } from '../../../constants/splitConstants'; -import { useSplitSettingsTips } from '../../tooltips/useSplitSettingsTips'; -export interface SplitMethodSelectorProps { - onMethodSelect: (method: SplitMethod) => void; - disabled?: boolean; +export interface CardOption { + value: T; + prefixKey: string; + nameKey: string; + tooltipKey?: string; + tooltipContent?: any[]; } -const SplitMethodSelector = ({ - onMethodSelect, - disabled = false -}: SplitMethodSelectorProps) => { +export interface CardSelectorProps> { + options: K[]; + onSelect: (value: T) => void; + disabled?: boolean; + getTooltipContent?: (option: K) => any[]; +} + +const CardSelector = >({ + options, + onSelect, + disabled = false, + getTooltipContent +}: CardSelectorProps) => { const { t } = useTranslation(); - // Get tooltip content for a specific method - const getMethodTooltip = (method: SplitMethod) => { - const tooltipContent = useSplitSettingsTips(method); - return tooltipContent?.tips || []; + const handleOptionClick = (value: T) => { + if (!disabled) { + onSelect(value); + } }; - const handleMethodClick = (method: SplitMethod) => { - if (!disabled) { - onMethodSelect(method); + const getTooltips = (option: K) => { + if (getTooltipContent) { + return getTooltipContent(option); } + return []; }; return ( - {METHOD_OPTIONS.map((option) => ( + {options.map((option) => ( handleMethodClick(option.method)} + onClick={() => handleOptionClick(option.value)} > - - - {t(option.prefixKey, "Split by")} + + + {t(option.prefixKey, "Prefix")} - {t(option.nameKey, "Method Name")} + > + {t(option.nameKey, "Option Name")} @@ -85,4 +96,4 @@ const SplitMethodSelector = ({ ); }; -export default SplitMethodSelector; +export default CardSelector; diff --git a/frontend/src/constants/splitConstants.ts b/frontend/src/constants/splitConstants.ts index 7bdb38e51..890f94b3c 100644 --- a/frontend/src/constants/splitConstants.ts +++ b/frontend/src/constants/splitConstants.ts @@ -24,52 +24,51 @@ export const isSplitMethod = (value: string | null): value is SplitMethod => { return Object.values(SPLIT_METHODS).includes(value as SplitMethod); } -export interface MethodOption { - method: SplitMethod; - prefixKey: string; - nameKey: string; +import { CardOption } from '../components/shared/CardSelector'; + +export interface MethodOption extends CardOption { tooltipKey: string; } export const METHOD_OPTIONS: MethodOption[] = [ { - method: SPLIT_METHODS.BY_PAGES, + value: SPLIT_METHODS.BY_PAGES, prefixKey: "split.methods.prefix.splitAt", nameKey: "split.methods.byPages.name", tooltipKey: "split.methods.byPages.tooltip" }, { - method: SPLIT_METHODS.BY_CHAPTERS, + value: SPLIT_METHODS.BY_CHAPTERS, prefixKey: "split.methods.prefix.splitBy", nameKey: "split.methods.byChapters.name", tooltipKey: "split.methods.byChapters.tooltip" }, { - method: SPLIT_METHODS.BY_SECTIONS, + value: SPLIT_METHODS.BY_SECTIONS, prefixKey: "split.methods.prefix.splitBy", nameKey: "split.methods.bySections.name", tooltipKey: "split.methods.bySections.tooltip" }, { - method: SPLIT_METHODS.BY_SIZE, + value: SPLIT_METHODS.BY_SIZE, prefixKey: "split.methods.prefix.splitBy", nameKey: "split.methods.bySize.name", tooltipKey: "split.methods.bySize.tooltip" }, { - method: SPLIT_METHODS.BY_PAGE_COUNT, + value: SPLIT_METHODS.BY_PAGE_COUNT, prefixKey: "split.methods.prefix.splitBy", nameKey: "split.methods.byPageCount.name", tooltipKey: "split.methods.byPageCount.tooltip" }, { - method: SPLIT_METHODS.BY_DOC_COUNT, + value: SPLIT_METHODS.BY_DOC_COUNT, prefixKey: "split.methods.prefix.splitBy", nameKey: "split.methods.byDocCount.name", tooltipKey: "split.methods.byDocCount.tooltip" }, { - method: SPLIT_METHODS.BY_PAGE_DIVIDER, + value: SPLIT_METHODS.BY_PAGE_DIVIDER, prefixKey: "split.methods.prefix.splitBy", nameKey: "split.methods.byPageDivider.name", tooltipKey: "split.methods.byPageDivider.tooltip" diff --git a/frontend/src/tools/Split.tsx b/frontend/src/tools/Split.tsx index bd358b132..9ece5037d 100644 --- a/frontend/src/tools/Split.tsx +++ b/frontend/src/tools/Split.tsx @@ -1,6 +1,6 @@ import { useTranslation } from "react-i18next"; import { createToolFlow } from "../components/tools/shared/createToolFlow"; -import SplitMethodSelector from "../components/tools/split/SplitMethodSelector"; +import CardSelector from "../components/shared/CardSelector"; import SplitSettings from "../components/tools/split/SplitSettings"; import { useSplitParameters } from "../hooks/tools/split/useSplitParameters"; import { useSplitOperation } from "../hooks/tools/split/useSplitOperation"; @@ -8,6 +8,7 @@ import { useBaseTool } from "../hooks/tools/shared/useBaseTool"; import { useSplitMethodTips } from "../components/tooltips/useSplitMethodTips"; import { useSplitSettingsTips } from "../components/tooltips/useSplitSettingsTips"; import { BaseToolProps, ToolComponent } from "../types/tool"; +import { type SplitMethod, METHOD_OPTIONS, type MethodOption } from "../constants/splitConstants"; const Split = (props: BaseToolProps) => { const { t } = useTranslation(); @@ -22,43 +23,26 @@ const Split = (props: BaseToolProps) => { const methodTips = useSplitMethodTips(); const settingsTips = useSplitSettingsTips(base.params.parameters.method); + // Get tooltip content for a specific method + const getMethodTooltip = (option: MethodOption) => { + const tooltipContent = useSplitSettingsTips(option.value); + return tooltipContent?.tips || []; + }; + + // Typed parameter updaters + const clearMethod = () => base.params.updateParameter('method', '' as const); + const setMethod = (method: SplitMethod) => base.params.updateParameter('method', method); + // Get the method name for the settings step title const getSettingsTitle = () => { if (!base.params.parameters.method) return t("split.steps.settings", "Settings"); - const methodTitleMap = { - 'byPages': { - prefix: t("split.methods.prefix.splitAt", "Split at"), - name: t("split.methods.byPages.name", "Page Numbers") - }, - 'bySections': { - prefix: t("split.methods.prefix.splitBy", "Split by"), - name: t("split.methods.bySections.name", "Sections") - }, - 'bySize': { - prefix: t("split.methods.prefix.splitBy", "Split by"), - name: t("split.methods.bySize.name", "File Size") - }, - 'byPageCount': { - prefix: t("split.methods.prefix.splitBy", "Split by"), - name: t("split.methods.byPageCount.name", "Page Count") - }, - 'byDocCount': { - prefix: t("split.methods.prefix.splitBy", "Split by"), - name: t("split.methods.byDocCount.name", "Document Count") - }, - 'byChapters': { - prefix: t("split.methods.prefix.splitBy", "Split by"), - name: t("split.methods.byChapters.name", "Chapters") - }, - 'byPageDivider': { - prefix: t("split.methods.prefix.splitBy", "Split by"), - name: t("split.methods.byPageDivider.name", "Page Divider") - }, - }; + const methodOption = METHOD_OPTIONS.find(option => option.value === base.params.parameters.method); + if (!methodOption) return t("split.steps.settings", "Settings"); - const method = methodTitleMap[base.params.parameters.method as keyof typeof methodTitleMap]; - return method ? `${method.prefix} ${method.name}` : t("split.steps.settings", "Settings"); + const prefix = t(methodOption.prefixKey, "Split by"); + const name = t(methodOption.nameKey, "Method Name"); + return `${prefix} ${name}`; }; return createToolFlow({ @@ -70,15 +54,15 @@ const Split = (props: BaseToolProps) => { { title: t("split.steps.chooseMethod", "Choose Method"), isCollapsed: !!base.params.parameters.method, // Collapse when method is selected - onCollapsedClick: () => { - // Clear the selected method to expand the method selection step - base.params.updateParameter('method', ''); - }, + onCollapsedClick: () => base.params.updateParameter('method', '') + , tooltip: methodTips, content: ( - base.params.updateParameter('method', method)} + + options={METHOD_OPTIONS} + onSelect={(method) => base.params.updateParameter('method', method)} disabled={base.endpointLoading} + getTooltipContent={getMethodTooltip} /> ), },