mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-03-13 02:18:16 +01:00
# Description of Changes - Added the show javascript tool. --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] 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) - [ ] I have performed a self-review of my own code - [ ] 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) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] 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.
151 lines
4.8 KiB
TypeScript
151 lines
4.8 KiB
TypeScript
import React, { useEffect, useMemo, useRef } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import CodeRoundedIcon from '@mui/icons-material/CodeRounded';
|
|
import { createToolFlow } from '@app/components/tools/shared/createToolFlow';
|
|
import { useBaseTool } from '@app/hooks/tools/shared/useBaseTool';
|
|
import type { BaseToolProps, ToolComponent } from '@app/types/tool';
|
|
import { useShowJSParameters, defaultParameters } from '@app/hooks/tools/showJS/useShowJSParameters';
|
|
import { useShowJSOperation, type ShowJSOperationHook } from '@app/hooks/tools/showJS/useShowJSOperation';
|
|
import { useToolWorkflow } from '@app/contexts/ToolWorkflowContext';
|
|
import { useNavigationActions, useNavigationState } from '@app/contexts/NavigationContext';
|
|
import ShowJSView from '@app/components/tools/showJS/ShowJSView';
|
|
import { useFileSelection } from '@app/contexts/file/fileHooks';
|
|
|
|
const ShowJS = (props: BaseToolProps) => {
|
|
const { t } = useTranslation();
|
|
const { actions: navigationActions } = useNavigationActions();
|
|
const navigationState = useNavigationState();
|
|
|
|
const {
|
|
registerCustomWorkbenchView,
|
|
unregisterCustomWorkbenchView,
|
|
setCustomWorkbenchViewData,
|
|
clearCustomWorkbenchViewData,
|
|
} = useToolWorkflow();
|
|
|
|
const VIEW_ID = 'showJSView';
|
|
const WORKBENCH_ID = 'custom:showJS' as const;
|
|
const viewIcon = useMemo(() => <CodeRoundedIcon fontSize="small" />, []);
|
|
|
|
const base = useBaseTool('showJS', useShowJSParameters, useShowJSOperation, props, { minFiles: 1 });
|
|
const operation = base.operation as ShowJSOperationHook;
|
|
const hasResults = Boolean(operation.scriptText);
|
|
const { clearSelections } = useFileSelection();
|
|
|
|
useEffect(() => {
|
|
registerCustomWorkbenchView({
|
|
id: VIEW_ID,
|
|
workbenchId: WORKBENCH_ID,
|
|
label: t('showJS.view.title', 'JavaScript'),
|
|
icon: viewIcon,
|
|
component: ({ data }) => <ShowJSView data={data} />,
|
|
});
|
|
|
|
return () => {
|
|
clearCustomWorkbenchViewData(VIEW_ID);
|
|
unregisterCustomWorkbenchView(VIEW_ID);
|
|
};
|
|
}, [clearCustomWorkbenchViewData, registerCustomWorkbenchView, t, unregisterCustomWorkbenchView, viewIcon]);
|
|
|
|
const lastShownRef = useRef<number | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (operation.scriptText) {
|
|
setCustomWorkbenchViewData(VIEW_ID, {
|
|
scriptText: operation.scriptText,
|
|
downloadUrl: operation.downloadUrl,
|
|
downloadFilename: operation.downloadFilename,
|
|
});
|
|
const marker = operation.scriptText.length;
|
|
const isNew = lastShownRef.current == null || marker !== lastShownRef.current;
|
|
if (isNew) {
|
|
lastShownRef.current = marker;
|
|
if (navigationState.selectedTool === 'showJS' && navigationState.workbench !== WORKBENCH_ID) {
|
|
navigationActions.setWorkbench(WORKBENCH_ID);
|
|
}
|
|
}
|
|
} else {
|
|
clearCustomWorkbenchViewData(VIEW_ID);
|
|
lastShownRef.current = null;
|
|
}
|
|
}, [
|
|
clearCustomWorkbenchViewData,
|
|
navigationActions,
|
|
navigationState.selectedTool,
|
|
navigationState.workbench,
|
|
operation.scriptText,
|
|
setCustomWorkbenchViewData,
|
|
]);
|
|
|
|
useEffect(() => {
|
|
if ((base.selectedFiles?.length ?? 0) === 0) {
|
|
try { base.operation.resetResults(); } catch { /* noop */ }
|
|
try { clearCustomWorkbenchViewData(VIEW_ID); } catch { /* noop */ }
|
|
if (navigationState.workbench === WORKBENCH_ID) {
|
|
try { navigationActions.setWorkbench('fileEditor'); } catch { /* noop */ }
|
|
}
|
|
lastShownRef.current = null;
|
|
}
|
|
}, [
|
|
base.selectedFiles?.length,
|
|
base.operation,
|
|
clearCustomWorkbenchViewData,
|
|
navigationActions,
|
|
navigationState.workbench,
|
|
]);
|
|
|
|
return createToolFlow({
|
|
files: {
|
|
selectedFiles: base.selectedFiles,
|
|
isCollapsed: false,
|
|
},
|
|
steps: [],
|
|
executeButton: {
|
|
text: hasResults ? t('back', 'Back') : t('showJS.submit', 'Extract JavaScript'),
|
|
loadingText: t('loading', 'Loading...'),
|
|
onClick: hasResults
|
|
? async () => {
|
|
// Clear results and deselect files so user can pick another file
|
|
try {
|
|
await base.operation.resetResults();
|
|
} catch { /* noop */ }
|
|
try {
|
|
clearSelections();
|
|
} catch { /* noop */ }
|
|
// Close the custom JS view and send user back to file manager to pick another file
|
|
try {
|
|
clearCustomWorkbenchViewData(VIEW_ID);
|
|
} catch { /* noop */ }
|
|
try {
|
|
navigationActions.setWorkbench('fileEditor');
|
|
} catch { /* noop */ }
|
|
}
|
|
: base.handleExecute,
|
|
disabled: hasResults
|
|
? false
|
|
: (
|
|
!base.hasFiles ||
|
|
(base.selectedFiles?.length ?? 0) !== 1 ||
|
|
base.operation.isLoading ||
|
|
base.endpointLoading ||
|
|
base.endpointEnabled === false
|
|
),
|
|
isVisible: true,
|
|
},
|
|
review: {
|
|
isVisible: hasResults,
|
|
operation: base.operation,
|
|
title: t('showJS.results', 'Result'),
|
|
onUndo: undefined,
|
|
},
|
|
});
|
|
};
|
|
|
|
const ShowJSTool = ShowJS as ToolComponent;
|
|
ShowJSTool.tool = () => useShowJSOperation;
|
|
ShowJSTool.getDefaultParameters = () => ({ ...defaultParameters });
|
|
|
|
export default ShowJSTool;
|
|
|
|
|