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(() => , []);
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 }) => ,
});
return () => {
clearCustomWorkbenchViewData(VIEW_ID);
unregisterCustomWorkbenchView(VIEW_ID);
};
}, [clearCustomWorkbenchViewData, registerCustomWorkbenchView, t, unregisterCustomWorkbenchView, viewIcon]);
const lastShownRef = useRef(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;