From 640591da3588b58ad5508960356d7c4dcb341cea Mon Sep 17 00:00:00 2001 From: Jacob Lowe Date: Wed, 6 Nov 2024 14:25:06 -0600 Subject: [PATCH 1/8] initial typescript --- .../mutations/{useCopy.js => useCopy.ts} | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) rename client/src/hooks/datafiles/mutations/{useCopy.js => useCopy.ts} (63%) diff --git a/client/src/hooks/datafiles/mutations/useCopy.js b/client/src/hooks/datafiles/mutations/useCopy.ts similarity index 63% rename from client/src/hooks/datafiles/mutations/useCopy.js rename to client/src/hooks/datafiles/mutations/useCopy.ts index f0e2e640c..115efea86 100644 --- a/client/src/hooks/datafiles/mutations/useCopy.js +++ b/client/src/hooks/datafiles/mutations/useCopy.ts @@ -7,20 +7,34 @@ function useCopy() { const { selectedFiles: selected } = useSelectedFiles(); const status = useSelector( - (state) => state.files.operationStatus.copy, + (state: any) => state.files.operationStatus.copy, shallowEqual ); - const setStatus = (newStatus) => + const setStatus = (newStatus: string) => dispatch({ type: 'DATA_FILES_SET_OPERATION_STATUS', payload: { operation: 'copy', status: newStatus }, }); - const copy = ({ srcApi, destApi, destSystem, destPath, name, callback }) => { + const copy = ({ + srcApi, + destApi, + destSystem, + destPath, + name, + callback, + }: { + srcApi: string; + destApi: string; + destSystem: string; + destPath: string; + name: string; + callback: any; + }) => { const filteredSelected = selected - .filter((f) => status[f.id] !== 'SUCCESS') - .map((f) => ({ ...f, api: srcApi })); + .filter((f: any) => status[f.id] !== 'SUCCESS') + .map((f: any) => ({ ...f, api: srcApi })); dispatch({ type: 'DATA_FILES_COPY', payload: { From 1ee88ad69b9a8f6dbf0f51ef6af20991bbe0e6cb Mon Sep 17 00:00:00 2001 From: Jacob Lowe Date: Wed, 6 Nov 2024 15:31:46 -0600 Subject: [PATCH 2/8] saga logic move --- .../src/hooks/datafiles/mutations/useCopy.ts | 115 +++++++++++++++++- 1 file changed, 110 insertions(+), 5 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useCopy.ts b/client/src/hooks/datafiles/mutations/useCopy.ts index 115efea86..c9ad49bc3 100644 --- a/client/src/hooks/datafiles/mutations/useCopy.ts +++ b/client/src/hooks/datafiles/mutations/useCopy.ts @@ -1,5 +1,68 @@ import { useDispatch, useSelector, shallowEqual } from 'react-redux'; import { useSelectedFiles } from 'hooks/datafiles'; +import Cookies from 'js-cookie'; +import { apiClient } from 'utils/apiClient'; +import { useMutation } from '@tanstack/react-query'; +import truncateMiddle from 'utils/truncateMiddle'; + +export async function copyFileUtil({ + api, + scheme, + system, + path, + filename, + filetype, + destApi, + destSystem, + destPath, + destPathName, +}: { + api: string; + scheme: string; + system: string; + path: string; + filename: string; + filetype: string; + destApi: string; + destSystem: string; + destPath: string; + destPathName: string; +}) { + let url: string, body: any; + if (api === destApi) { + url = `/api/datafiles/${api}/copy/${scheme}/${system}/${path}/`; + url = url.replace(/\/{2,}/g, '/'); + body = { + dest_system: destSystem, + dest_path: destPath, + file_name: filename, + filetype, + dest_path_name: destPathName, + }; + } else { + url = `/api/datafiles/transfer/${filetype}/`; + url = url.replace(/\/{2,}/g, '/'); + body = { + src_api: api, + dest_api: destApi, + src_system: system, + dest_system: destSystem, + src_path: path, + dest_path: destPath, + dest_path_name: destPathName, + dirname: filename, + }; + } + + const request = await apiClient.put(url, body, { + headers: { 'X-CSRFToken': Cookies.get('csrftoken') || '' }, + withCredentials: true, + }); + if (request.status < 200 || request.status >= 300) { + throw new Error(request.status.toString()); + } + return request.data; +} function useCopy() { const dispatch = useDispatch(); @@ -17,6 +80,7 @@ function useCopy() { payload: { operation: 'copy', status: newStatus }, }); + const { mutate } = useMutation({ mutationFn: copyFileUtil }); const copy = ({ srcApi, destApi, @@ -35,16 +99,57 @@ function useCopy() { const filteredSelected = selected .filter((f: any) => status[f.id] !== 'SUCCESS') .map((f: any) => ({ ...f, api: srcApi })); + const copyCalls = filteredSelected.map((file: any) => { + // Copy File + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', + payload: { status: 'RUNNING', key: file.id, operation: 'copy' }, + }); + mutate( + { + api: file.api, + scheme: file.scheme, + system: file.system, + path: file.path, + filename: file.name, + filetype: file.type, + destApi, + destSystem, + destPath, + destPathName: name, + }, + { + onSuccess: () => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', + payload: { status: 'SUCCESS', key: file.id, operation: 'copy' }, + }); + dispatch({ + type: 'DATA_FILES_TOGGLE_MODAL', + payload: { operation: 'copy', props: {} }, + }); + }, + onError: (error) => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', + payload: { status: 'ERROR', key: file.id, operation: 'copy' }, + }); + }, + } + ); + }); + // Result + const result = copyCalls; dispatch({ - type: 'DATA_FILES_COPY', + type: 'ADD_TOAST', payload: { - dest: { system: destSystem, path: destPath, api: destApi, name }, - src: filteredSelected, - reloadCallback: callback, + message: `${ + copyCalls.length > 1 ? `${copyCalls.length} files` : 'File' + } copied to ${truncateMiddle(`${destPath}`, 20) || '/'}`, }, }); + callback(); }; - return { copy, status, setStatus }; } From 195d5a578b87dc3f71ca5fb0efa9ea453b26cc40 Mon Sep 17 00:00:00 2001 From: Jacob Lowe Date: Thu, 7 Nov 2024 14:17:18 -0600 Subject: [PATCH 3/8] url param undefined fix --- client/src/hooks/datafiles/mutations/useCopy.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useCopy.ts b/client/src/hooks/datafiles/mutations/useCopy.ts index c9ad49bc3..ad4128ef0 100644 --- a/client/src/hooks/datafiles/mutations/useCopy.ts +++ b/client/src/hooks/datafiles/mutations/useCopy.ts @@ -54,14 +54,17 @@ export async function copyFileUtil({ }; } - const request = await apiClient.put(url, body, { + const request = await fetch(url, { + method: 'PUT', headers: { 'X-CSRFToken': Cookies.get('csrftoken') || '' }, - withCredentials: true, + credentials: 'same-origin', + body: JSON.stringify(body), }); - if (request.status < 200 || request.status >= 300) { + if (!request.ok) { throw new Error(request.status.toString()); } - return request.data; + const responseData = await request.json(); + return responseData; } function useCopy() { @@ -74,6 +77,7 @@ function useCopy() { shallowEqual ); + const {scheme} = useSelector((state :any) => state.files.params.FilesListing); const setStatus = (newStatus: string) => dispatch({ type: 'DATA_FILES_SET_OPERATION_STATUS', @@ -105,10 +109,11 @@ function useCopy() { type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', payload: { status: 'RUNNING', key: file.id, operation: 'copy' }, }); + mutate( { api: file.api, - scheme: file.scheme, + scheme: scheme, system: file.system, path: file.path, filename: file.name, From ad88eff04f9445ae73ce51e77a8adef9edb05cf8 Mon Sep 17 00:00:00 2001 From: Jacob Lowe Date: Thu, 7 Nov 2024 14:40:58 -0600 Subject: [PATCH 4/8] linting --- client/src/hooks/datafiles/mutations/useCopy.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useCopy.ts b/client/src/hooks/datafiles/mutations/useCopy.ts index ad4128ef0..dc115de48 100644 --- a/client/src/hooks/datafiles/mutations/useCopy.ts +++ b/client/src/hooks/datafiles/mutations/useCopy.ts @@ -77,7 +77,9 @@ function useCopy() { shallowEqual ); - const {scheme} = useSelector((state :any) => state.files.params.FilesListing); + const { scheme } = useSelector( + (state: any) => state.files.params.FilesListing + ); const setStatus = (newStatus: string) => dispatch({ type: 'DATA_FILES_SET_OPERATION_STATUS', @@ -109,7 +111,7 @@ function useCopy() { type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', payload: { status: 'RUNNING', key: file.id, operation: 'copy' }, }); - + mutate( { api: file.api, From c215d646c88a18d6e583e93fc1090c9fd1f21270 Mon Sep 17 00:00:00 2001 From: Jacob Lowe Date: Mon, 11 Nov 2024 09:49:55 -0600 Subject: [PATCH 5/8] axios update --- client/src/hooks/datafiles/mutations/useCopy.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useCopy.ts b/client/src/hooks/datafiles/mutations/useCopy.ts index dc115de48..378bd6fc9 100644 --- a/client/src/hooks/datafiles/mutations/useCopy.ts +++ b/client/src/hooks/datafiles/mutations/useCopy.ts @@ -54,17 +54,11 @@ export async function copyFileUtil({ }; } - const request = await fetch(url, { - method: 'PUT', + const response = await apiClient.put(url, body, { headers: { 'X-CSRFToken': Cookies.get('csrftoken') || '' }, - credentials: 'same-origin', - body: JSON.stringify(body), + withCredentials: true, }); - if (!request.ok) { - throw new Error(request.status.toString()); - } - const responseData = await request.json(); - return responseData; + return response.data; } function useCopy() { @@ -137,6 +131,7 @@ function useCopy() { }); }, onError: (error) => { + console.log('The error is ', error); dispatch({ type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', payload: { status: 'ERROR', key: file.id, operation: 'copy' }, From be77df859ea74a8ea5cdf75160d719267a0b7884 Mon Sep 17 00:00:00 2001 From: Jacob Lowe Date: Thu, 21 Nov 2024 15:16:50 -0600 Subject: [PATCH 6/8] mutateAsync changes --- .../src/hooks/datafiles/mutations/useCopy.ts | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useCopy.ts b/client/src/hooks/datafiles/mutations/useCopy.ts index 378bd6fc9..0cfdeb935 100644 --- a/client/src/hooks/datafiles/mutations/useCopy.ts +++ b/client/src/hooks/datafiles/mutations/useCopy.ts @@ -80,8 +80,8 @@ function useCopy() { payload: { operation: 'copy', status: newStatus }, }); - const { mutate } = useMutation({ mutationFn: copyFileUtil }); - const copy = ({ + const { mutateAsync } = useMutation({ mutationFn: copyFileUtil }); + const copy = async ({ srcApi, destApi, destSystem, @@ -105,43 +105,37 @@ function useCopy() { type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', payload: { status: 'RUNNING', key: file.id, operation: 'copy' }, }); - - mutate( - { - api: file.api, - scheme: scheme, - system: file.system, - path: file.path, - filename: file.name, - filetype: file.type, - destApi, - destSystem, - destPath, - destPathName: name, - }, - { - onSuccess: () => { - dispatch({ - type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', - payload: { status: 'SUCCESS', key: file.id, operation: 'copy' }, - }); - dispatch({ - type: 'DATA_FILES_TOGGLE_MODAL', - payload: { operation: 'copy', props: {} }, - }); - }, - onError: (error) => { - console.log('The error is ', error); - dispatch({ - type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', - payload: { status: 'ERROR', key: file.id, operation: 'copy' }, - }); - }, - } - ); + mutateAsync({ + api: file.api, + scheme: scheme, + system: file.system, + path: file.path, + filename: file.name, + filetype: file.type, + destApi, + destSystem, + destPath, + destPathName: name, + }) + .then(() => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', + payload: { status: 'SUCCESS', key: file.id, operation: 'copy' }, + }); + }) + .catch((error: any) => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', + payload: { status: 'ERROR', key: file.id, operation: 'copy' }, + }); + }); }); // Result - const result = copyCalls; + await Promise.all(copyCalls); + dispatch({ + type: 'DATA_FILES_TOGGLE_MODAL', + payload: { operation: 'copy', props: {} }, + }); dispatch({ type: 'ADD_TOAST', payload: { From 5fc9b5008166de371508f56eebeed6c1b1fbe7d0 Mon Sep 17 00:00:00 2001 From: Jacob Lowe Date: Thu, 21 Nov 2024 15:29:46 -0600 Subject: [PATCH 7/8] onSuccess, onError with async --- .../src/hooks/datafiles/mutations/useCopy.ts | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useCopy.ts b/client/src/hooks/datafiles/mutations/useCopy.ts index 0cfdeb935..fccdc3526 100644 --- a/client/src/hooks/datafiles/mutations/useCopy.ts +++ b/client/src/hooks/datafiles/mutations/useCopy.ts @@ -105,30 +105,34 @@ function useCopy() { type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', payload: { status: 'RUNNING', key: file.id, operation: 'copy' }, }); - mutateAsync({ - api: file.api, - scheme: scheme, - system: file.system, - path: file.path, - filename: file.name, - filetype: file.type, - destApi, - destSystem, - destPath, - destPathName: name, - }) - .then(() => { - dispatch({ - type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', - payload: { status: 'SUCCESS', key: file.id, operation: 'copy' }, - }); - }) - .catch((error: any) => { - dispatch({ - type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', - payload: { status: 'ERROR', key: file.id, operation: 'copy' }, - }); - }); + mutateAsync( + { + api: file.api, + scheme: scheme, + system: file.system, + path: file.path, + filename: file.name, + filetype: file.type, + destApi, + destSystem, + destPath, + destPathName: name, + }, + { + onSuccess: () => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', + payload: { status: 'SUCCESS', key: file.id, operation: 'copy' }, + }); + }, + onError: (error: any) => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', + payload: { status: 'ERROR', key: file.id, operation: 'copy' }, + }); + }, + } + ); }); // Result await Promise.all(copyCalls); From 71709a71009a699d4ddab1cfa66bff1cd153d576 Mon Sep 17 00:00:00 2001 From: Jacob Lowe Date: Thu, 21 Nov 2024 15:49:42 -0600 Subject: [PATCH 8/8] copyCalls as an array of Promises on return --- .../src/hooks/datafiles/mutations/useCopy.ts | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useCopy.ts b/client/src/hooks/datafiles/mutations/useCopy.ts index fccdc3526..3398feade 100644 --- a/client/src/hooks/datafiles/mutations/useCopy.ts +++ b/client/src/hooks/datafiles/mutations/useCopy.ts @@ -81,7 +81,7 @@ function useCopy() { }); const { mutateAsync } = useMutation({ mutationFn: copyFileUtil }); - const copy = async ({ + const copy = ({ srcApi, destApi, destSystem, @@ -99,13 +99,13 @@ function useCopy() { const filteredSelected = selected .filter((f: any) => status[f.id] !== 'SUCCESS') .map((f: any) => ({ ...f, api: srcApi })); - const copyCalls = filteredSelected.map((file: any) => { + const copyCalls: Promise[] = filteredSelected.map((file: any) => { // Copy File dispatch({ type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', payload: { status: 'RUNNING', key: file.id, operation: 'copy' }, }); - mutateAsync( + return mutateAsync( { api: file.api, scheme: scheme, @@ -135,20 +135,21 @@ function useCopy() { ); }); // Result - await Promise.all(copyCalls); - dispatch({ - type: 'DATA_FILES_TOGGLE_MODAL', - payload: { operation: 'copy', props: {} }, - }); - dispatch({ - type: 'ADD_TOAST', - payload: { - message: `${ - copyCalls.length > 1 ? `${copyCalls.length} files` : 'File' - } copied to ${truncateMiddle(`${destPath}`, 20) || '/'}`, - }, + Promise.all(copyCalls).then(() => { + dispatch({ + type: 'DATA_FILES_TOGGLE_MODAL', + payload: { operation: 'copy', props: {} }, + }); + dispatch({ + type: 'ADD_TOAST', + payload: { + message: `${ + copyCalls.length > 1 ? `${copyCalls.length} files` : 'File' + } copied to ${truncateMiddle(`${destPath}`, 20) || '/'}`, + }, + }); + callback(); }); - callback(); }; return { copy, status, setStatus }; }