From 2702ed78a28c09b37cb5c3d79bf314aa7823b669 Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Tue, 10 Dec 2024 14:38:22 -0600 Subject: [PATCH] Set up new branch to branch off of Compress branch --- .../hooks/datafiles/mutations/useExtract.js | 27 ---- .../hooks/datafiles/mutations/useExtract.ts | 126 ++++++++++++++++++ client/src/utils/getExtractParams.ts | 41 ++++++ server/portal/settings/settings_default.py | 2 +- 4 files changed, 168 insertions(+), 28 deletions(-) delete mode 100644 client/src/hooks/datafiles/mutations/useExtract.js create mode 100644 client/src/hooks/datafiles/mutations/useExtract.ts create mode 100644 client/src/utils/getExtractParams.ts diff --git a/client/src/hooks/datafiles/mutations/useExtract.js b/client/src/hooks/datafiles/mutations/useExtract.js deleted file mode 100644 index 78e07eb41..000000000 --- a/client/src/hooks/datafiles/mutations/useExtract.js +++ /dev/null @@ -1,27 +0,0 @@ -import { useSelector, useDispatch, shallowEqual } from 'react-redux'; - -function useExtract() { - const dispatch = useDispatch(); - const status = useSelector( - (state) => state.files.operationStatus.extract, - shallowEqual - ); - - const setStatus = (newStatus) => { - dispatch({ - type: 'DATA_FILES_SET_OPERATION_STATUS', - payload: { status: newStatus, operation: 'extract' }, - }); - }; - - const extract = ({ file }) => { - dispatch({ - type: 'DATA_FILES_EXTRACT', - payload: { file }, - }); - }; - - return { extract, status, setStatus }; -} - -export default useExtract; diff --git a/client/src/hooks/datafiles/mutations/useExtract.ts b/client/src/hooks/datafiles/mutations/useExtract.ts new file mode 100644 index 000000000..5c7ffb4ce --- /dev/null +++ b/client/src/hooks/datafiles/mutations/useExtract.ts @@ -0,0 +1,126 @@ +import { useMutation } from '@tanstack/react-query'; +import { useSelector, useDispatch, shallowEqual } from 'react-redux'; +import { getExtractParams } from 'utils/getExtractParams'; +import { apiClient } from 'utils/apiClient'; +import { fetchUtil } from 'utils/fetchUtil'; +import { TTapisFile } from 'utils/types'; +import { TJobBody, TJobPostResponse } from './useSubmitJob'; + +const getAppUtil = async function fetchAppDefinitionUtil( + appId: string, + appVersion: string +) { + const params = { appId, appVersion }; + const result = await fetchUtil({ + url: '/api/workspace/apps', + params, + }); + return result.response; +}; + +async function submitJobUtil(body: TJobBody) { + const res = await apiClient.post( + `/api/workspace/jobs`, + body + ); + return res.data.response; +} + +function useExtract() { + const dispatch = useDispatch(); + const status = useSelector( + (state: any) => state.files.operationStatus.extract, + shallowEqual + ); + + const setStatus = (newStatus: any) => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS', + payload: { status: newStatus, operation: 'extract' }, + }); + }; + + const extractApp = useSelector( + (state: any) => state.workbench.config.extractApp + ); + + const defaultAllocation = useSelector( + (state: any) => + state.allocations.portal_alloc || state.allocations.active[0].projectName + ); + + const latestExtract = getAppUtil(extractApp.id, extractApp.version); + + const { mutateAsync } = useMutation({ mutationFn: submitJobUtil }); + + const extract = ({ file }: { file: TTapisFile }) => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS', + payload: { status: 'RUNNING', operation: 'extract' }, + }); + + const params = getExtractParams( + file, + extractApp, + latestExtract, + defaultAllocation + ); + + return mutateAsync( + { + job: params, + }, + { + onSuccess: (response: any) => { + if (response.execSys) { + dispatch({ + type: 'SYSTEMS_TOGGLE_MODAL', + payload: { + operation: 'pushKeys', + props: { + system: response.execSys, + }, + }, + }); + } else if (response.status === 'PENDING') { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS', + payload: { status: { type: 'SUCCESS' }, operation: 'extract' }, + }); + dispatch({ + type: 'ADD_TOAST', + payload: { + message: 'File extraction in progress', + }, + }); + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS', + payload: { operation: 'extract', status: {} }, + }); + dispatch({ + type: 'DATA_FILES_TOGGLE_MODAL', + payload: { operation: 'extract', props: {} }, + }); + } + }, + onError: (response) => { + const errorMessage = + response.cause === 'compressError' + ? response.message + : 'An error has occurred.'; + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS', + payload: { + status: { type: 'ERROR', message: errorMessage }, + operation: 'extract', + }, + }); + }, + } + ); + }; + + return { extract, status, setStatus }; +} + +export default useExtract; diff --git a/client/src/utils/getExtractParams.ts b/client/src/utils/getExtractParams.ts new file mode 100644 index 000000000..623fc61ea --- /dev/null +++ b/client/src/utils/getExtractParams.ts @@ -0,0 +1,41 @@ +import { TTapisFile } from './types'; + +export const getExtractParams = ( + file: TTapisFile, + extractApp: { + id: string; + version: string; + }, + latestExtract: any, + defaultAllocation: string +) => { + const inputFile = `tapis://${file.system}/${file.path}`; + const archivePath = `${file.path.slice(0, -file.name.length)}`; + return { + fileInputs: [ + { + name: 'Input File', + sourceUrl: inputFile, + }, + ], + name: `${extractApp.id}-${extractApp.version}_${ + new Date().toISOString().split('.')[0] + }`, + archiveSystemId: file.system, + archiveSystemDir: archivePath, + archiveOnAppError: false, + appId: extractApp.id, + appVersion: extractApp.version, + parameterSet: { + appArgs: [], + schedulerOptions: [ + { + name: 'TACC Allocation', + description: 'The TACC allocation associated with this job execution', + include: true, + arg: `-A ${defaultAllocation}`, + }, + ], + }, + }; +}; diff --git a/server/portal/settings/settings_default.py b/server/portal/settings/settings_default.py index 101ba612f..ea734a781 100644 --- a/server/portal/settings/settings_default.py +++ b/server/portal/settings/settings_default.py @@ -228,7 +228,7 @@ }, "extractApp": { "id": "extract", - "version": "0.0.3" + "version": "0.0.1" }, "makePublic": True, "hideApps": False,