Refactored into generic cardSelector

This commit is contained in:
Connor Yoh 2025-09-16 12:40:14 +01:00
parent 55f3c97f2a
commit 0a8d763f5c
3 changed files with 72 additions and 78 deletions

View File

@ -1,39 +1,50 @@
import { Stack, Card, Text, Flex } from '@mantine/core';
import { Tooltip } from '../../shared/Tooltip';
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<T = string> {
value: T;
prefixKey: string;
nameKey: string;
tooltipKey?: string;
tooltipContent?: any[];
}
const SplitMethodSelector = ({
onMethodSelect,
disabled = false
}: SplitMethodSelectorProps) => {
export interface CardSelectorProps<T, K extends CardOption<T>> {
options: K[];
onSelect: (value: T) => void;
disabled?: boolean;
getTooltipContent?: (option: K) => any[];
}
const CardSelector = <T, K extends CardOption<T>>({
options,
onSelect,
disabled = false,
getTooltipContent
}: CardSelectorProps<T, K>) => {
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 (
<Stack gap="sm">
{METHOD_OPTIONS.map((option) => (
{options.map((option) => (
<Tooltip
key={option.method}
key={option.value as string}
sidebarTooltip
tips={getMethodTooltip(option.method)}
tips={getTooltips(option)}
>
<Card
radius="md"
@ -62,11 +73,11 @@ const SplitMethodSelector = ({
e.currentTarget.style.boxShadow = 'none';
}
}}
onClick={() => handleMethodClick(option.method)}
onClick={() => handleOptionClick(option.value)}
>
<Flex align={'center'} w="100%" >
<Text size="sm" c="dimmed" ta="center" fw={350} >
{t(option.prefixKey, "Split by")}
<Flex align={'center'} pl="sm" w="100%">
<Text size="sm" c="dimmed" ta="center" fw={350}>
{t(option.prefixKey, "Prefix")}
</Text>
<Text
fw={600}
@ -75,7 +86,7 @@ const SplitMethodSelector = ({
ta="center"
style={{ marginLeft: '0.25rem' }}
>
{t(option.nameKey, "Method Name")}
{t(option.nameKey, "Option Name")}
</Text>
</Flex>
</Card>
@ -85,4 +96,4 @@ const SplitMethodSelector = ({
);
};
export default SplitMethodSelector;
export default CardSelector;

View File

@ -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<SplitMethod> {
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"

View File

@ -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: (
<SplitMethodSelector
onMethodSelect={(method) => base.params.updateParameter('method', method)}
<CardSelector<SplitMethod, MethodOption>
options={METHOD_OPTIONS}
onSelect={(method) => base.params.updateParameter('method', method)}
disabled={base.endpointLoading}
getTooltipContent={getMethodTooltip}
/>
),
},