mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-09-23 20:16:15 +00:00
Compare commits
4 Commits
668c47d5a0
...
1ac062155f
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1ac062155f | ||
![]() |
83d8553e38 | ||
![]() |
2e68f2d062 | ||
![]() |
c60a7dfc27 |
24
frontend/package-lock.json
generated
24
frontend/package-lock.json
generated
@ -14,6 +14,7 @@
|
||||
"@emotion/styled": "^11.14.0",
|
||||
"@iconify/react": "^6.0.0",
|
||||
"@mantine/core": "^8.0.1",
|
||||
"@mantine/dates": "^8.0.1",
|
||||
"@mantine/dropzone": "^8.0.1",
|
||||
"@mantine/hooks": "^8.0.1",
|
||||
"@mui/icons-material": "^7.1.0",
|
||||
@ -1653,6 +1654,22 @@
|
||||
"react-dom": "^18.x || ^19.x"
|
||||
}
|
||||
},
|
||||
"node_modules/@mantine/dates": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-8.0.1.tgz",
|
||||
"integrity": "sha512-YCmV5jiGE9Ts2uhNS217IA1Hd5kAa8oaEtfnU0bS1sL36zKEf2s6elmzY718XdF8tFil0jJWAj0jiCrA3/udMg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@mantine/core": "8.0.1",
|
||||
"@mantine/hooks": "8.0.1",
|
||||
"dayjs": ">=1.0.0",
|
||||
"react": "^18.x || ^19.x",
|
||||
"react-dom": "^18.x || ^19.x"
|
||||
}
|
||||
},
|
||||
"node_modules/@mantine/dropzone": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@mantine/dropzone/-/dropzone-8.0.1.tgz",
|
||||
@ -4367,6 +4384,13 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.18",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz",
|
||||
"integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
||||
|
@ -10,6 +10,7 @@
|
||||
"@emotion/styled": "^11.14.0",
|
||||
"@iconify/react": "^6.0.0",
|
||||
"@mantine/core": "^8.0.1",
|
||||
"@mantine/dates": "^8.0.1",
|
||||
"@mantine/dropzone": "^8.0.1",
|
||||
"@mantine/hooks": "^8.0.1",
|
||||
"@mui/icons-material": "^7.1.0",
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Stack, TextInput, Text } from "@mantine/core";
|
||||
import { Stack, Text } from "@mantine/core";
|
||||
import { DateTimePicker } from "@mantine/dates";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ChangeMetadataParameters } from "../../../../hooks/tools/changeMetadata/useChangeMetadataParameters";
|
||||
|
||||
@ -15,26 +16,45 @@ const DocumentDatesStep = ({
|
||||
}: DocumentDatesStepProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const parseDate = (dateString: string): Date | null => {
|
||||
if (!dateString) return null;
|
||||
const date = new Date(dateString.replace(/(\d{4})\/(\d{2})\/(\d{2}) (\d{2}):(\d{2}):(\d{2})/, '$1-$2-$3T$4:$5:$6'));
|
||||
return isNaN(date.getTime()) ? null : date;
|
||||
};
|
||||
|
||||
const formatDate = (date: Date | null): string => {
|
||||
if (!date) return '';
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<Text size="xs" c="dimmed">
|
||||
{t('changeMetadata.dates.format', 'Format: yyyy/MM/dd HH:mm:ss')}
|
||||
</Text>
|
||||
|
||||
<TextInput
|
||||
<DateTimePicker
|
||||
label={t('changeMetadata.creationDate.label', 'Creation Date')}
|
||||
placeholder={t('changeMetadata.creationDate.placeholder', 'e.g. 2025/01/17 14:30:00')}
|
||||
value={parameters.creationDate}
|
||||
onChange={(e) => onParameterChange('creationDate', e.target.value)}
|
||||
value={parseDate(parameters.creationDate)}
|
||||
onChange={(date) => onParameterChange('creationDate', formatDate(parseDate(date)))}
|
||||
disabled={disabled}
|
||||
clearable
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
<DateTimePicker
|
||||
label={t('changeMetadata.modificationDate.label', 'Modification Date')}
|
||||
placeholder={t('changeMetadata.modificationDate.placeholder', 'e.g. 2025/01/17 14:30:00')}
|
||||
value={parameters.modificationDate}
|
||||
onChange={(e) => onParameterChange('modificationDate', e.target.value)}
|
||||
value={parseDate(parameters.modificationDate)}
|
||||
onChange={(date) => onParameterChange('modificationDate', formatDate(parseDate(date)))}
|
||||
disabled={disabled}
|
||||
clearable
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
|
@ -17,6 +17,14 @@ import {
|
||||
useAdvancedOptionsTips
|
||||
} from "../components/tooltips/useChangeMetadataTips";
|
||||
|
||||
enum MetadataStep {
|
||||
NONE = 'none',
|
||||
DELETE_ALL = 'deleteAll',
|
||||
STANDARD_METADATA = 'standardMetadata',
|
||||
DOCUMENT_DATES = 'documentDates',
|
||||
ADVANCED_OPTIONS = 'advancedOptions'
|
||||
}
|
||||
|
||||
const ChangeMetadata = (props: BaseToolProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -26,11 +34,8 @@ const ChangeMetadata = (props: BaseToolProps) => {
|
||||
const documentDatesTips = useDocumentDatesTips();
|
||||
const advancedOptionsTips = useAdvancedOptionsTips();
|
||||
|
||||
// Individual step collapse states
|
||||
const [deleteAllCollapsed, setDeleteAllCollapsed] = useState(false);
|
||||
const [standardMetadataCollapsed, setStandardMetadataCollapsed] = useState(false);
|
||||
const [documentDatesCollapsed, setDocumentDatesCollapsed] = useState(true);
|
||||
const [advancedOptionsCollapsed, setAdvancedOptionsCollapsed] = useState(true);
|
||||
// Individual step collapse states - only one can be open at a time
|
||||
const [openStep, setOpenStep] = useState<MetadataStep>(MetadataStep.DELETE_ALL);
|
||||
|
||||
const base = useBaseTool(
|
||||
'changeMetadata',
|
||||
@ -42,68 +47,55 @@ const ChangeMetadata = (props: BaseToolProps) => {
|
||||
// Extract metadata from uploaded files
|
||||
const { isExtractingMetadata } = useMetadataExtraction(base.params);
|
||||
|
||||
// Compute actual collapsed state based on results and user state
|
||||
const getActualCollapsedState = (userCollapsed: boolean) => {
|
||||
return (!base.hasFiles || base.hasResults) ? true : userCollapsed; // Force collapse when results are shown
|
||||
// Compute actual collapsed state based on results and accordion behavior
|
||||
const getActualCollapsedState = (stepName: MetadataStep) => {
|
||||
return (!base.hasFiles || base.hasResults) ? true : openStep !== stepName;
|
||||
};
|
||||
|
||||
return createToolFlow({
|
||||
files: {
|
||||
selectedFiles: base.selectedFiles,
|
||||
isCollapsed: base.hasResults,
|
||||
},
|
||||
steps: [
|
||||
{
|
||||
title: t("changeMetadata.deleteAll.label", "Delete All Metadata"),
|
||||
isCollapsed: getActualCollapsedState(deleteAllCollapsed),
|
||||
onCollapsedClick: base.hasResults
|
||||
? (base.settingsCollapsed ? base.handleSettingsReset : undefined)
|
||||
: () => setDeleteAllCollapsed(!deleteAllCollapsed),
|
||||
tooltip: deleteAllTips,
|
||||
content: (
|
||||
<DeleteAllStep
|
||||
parameters={base.params.parameters}
|
||||
onParameterChange={base.params.updateParameter}
|
||||
disabled={base.endpointLoading || isExtractingMetadata}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
// Handle step toggle for accordion behavior
|
||||
const handleStepToggle = (stepName: MetadataStep) => {
|
||||
if (base.hasResults) {
|
||||
if (base.settingsCollapsed) {
|
||||
base.handleSettingsReset();
|
||||
}
|
||||
return;
|
||||
}
|
||||
setOpenStep(openStep === stepName ? MetadataStep.NONE : stepName);
|
||||
};
|
||||
|
||||
// Create step objects
|
||||
const createStandardMetadataStep = () => ({
|
||||
title: t("changeMetadata.standardFields.title", "Standard Metadata"),
|
||||
isCollapsed: getActualCollapsedState(standardMetadataCollapsed),
|
||||
onCollapsedClick: base.hasResults
|
||||
? (base.settingsCollapsed ? base.handleSettingsReset : undefined)
|
||||
: () => setStandardMetadataCollapsed(!standardMetadataCollapsed),
|
||||
isCollapsed: getActualCollapsedState(MetadataStep.STANDARD_METADATA),
|
||||
onCollapsedClick: () => handleStepToggle(MetadataStep.STANDARD_METADATA),
|
||||
tooltip: standardMetadataTips,
|
||||
content: (
|
||||
<StandardMetadataStep
|
||||
parameters={base.params.parameters}
|
||||
onParameterChange={base.params.updateParameter}
|
||||
disabled={base.endpointLoading || base.params.parameters.deleteAll || isExtractingMetadata}
|
||||
disabled={base.endpointLoading || isExtractingMetadata}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
});
|
||||
|
||||
const createDocumentDatesStep = () => ({
|
||||
title: t("changeMetadata.dates.title", "Document Dates"),
|
||||
isCollapsed: getActualCollapsedState(documentDatesCollapsed),
|
||||
onCollapsedClick: base.hasResults
|
||||
? (base.settingsCollapsed ? base.handleSettingsReset : undefined)
|
||||
: () => setDocumentDatesCollapsed(!documentDatesCollapsed),
|
||||
isCollapsed: getActualCollapsedState(MetadataStep.DOCUMENT_DATES),
|
||||
onCollapsedClick: () => handleStepToggle(MetadataStep.DOCUMENT_DATES),
|
||||
tooltip: documentDatesTips,
|
||||
content: (
|
||||
<DocumentDatesStep
|
||||
parameters={base.params.parameters}
|
||||
onParameterChange={base.params.updateParameter}
|
||||
disabled={base.endpointLoading || base.params.parameters.deleteAll || isExtractingMetadata}
|
||||
disabled={base.endpointLoading || isExtractingMetadata}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
});
|
||||
|
||||
const createAdvancedOptionsStep = () => ({
|
||||
title: t("changeMetadata.advanced.title", "Advanced Options"),
|
||||
isCollapsed: getActualCollapsedState(advancedOptionsCollapsed),
|
||||
onCollapsedClick: base.hasResults
|
||||
? (base.settingsCollapsed ? base.handleSettingsReset : undefined)
|
||||
: () => setAdvancedOptionsCollapsed(!advancedOptionsCollapsed),
|
||||
isCollapsed: getActualCollapsedState(MetadataStep.ADVANCED_OPTIONS),
|
||||
onCollapsedClick: () => handleStepToggle(MetadataStep.ADVANCED_OPTIONS),
|
||||
tooltip: advancedOptionsTips,
|
||||
content: (
|
||||
<AdvancedOptionsStep
|
||||
@ -115,8 +107,43 @@ const ChangeMetadata = (props: BaseToolProps) => {
|
||||
updateCustomMetadata={base.params.updateCustomMetadata}
|
||||
/>
|
||||
),
|
||||
});
|
||||
|
||||
// Build steps array based on deleteAll state
|
||||
const buildSteps = () => {
|
||||
const steps = [
|
||||
{
|
||||
title: t("changeMetadata.deleteAll.label", "Delete All Metadata"),
|
||||
isCollapsed: getActualCollapsedState(MetadataStep.DELETE_ALL),
|
||||
onCollapsedClick: () => handleStepToggle(MetadataStep.DELETE_ALL),
|
||||
tooltip: deleteAllTips,
|
||||
content: (
|
||||
<DeleteAllStep
|
||||
parameters={base.params.parameters}
|
||||
onParameterChange={base.params.updateParameter}
|
||||
disabled={base.endpointLoading || isExtractingMetadata}
|
||||
/>
|
||||
),
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
if (!base.params.parameters.deleteAll) {
|
||||
steps.push(
|
||||
createStandardMetadataStep(),
|
||||
createDocumentDatesStep(),
|
||||
createAdvancedOptionsStep()
|
||||
);
|
||||
}
|
||||
|
||||
return steps;
|
||||
};
|
||||
|
||||
return createToolFlow({
|
||||
files: {
|
||||
selectedFiles: base.selectedFiles,
|
||||
isCollapsed: base.hasResults,
|
||||
},
|
||||
steps: buildSteps(),
|
||||
executeButton: {
|
||||
text: t("changeMetadata.submit", "Update Metadata"),
|
||||
isVisible: !base.hasResults,
|
||||
|
Loading…
x
Reference in New Issue
Block a user