From 1eb463b5a36d2f53566865f0ac66c915056a75a9 Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Tue, 5 Nov 2024 13:32:56 -0600 Subject: [PATCH 01/12] Converted useTrash mutation to use React Query and TypeScript --- client/package-lock.json | 27 +++-- client/package.json | 2 +- .../src/hooks/datafiles/mutations/useTrash.js | 29 ----- .../src/hooks/datafiles/mutations/useTrash.ts | 107 ++++++++++++++++++ 4 files changed, 125 insertions(+), 40 deletions(-) delete mode 100644 client/src/hooks/datafiles/mutations/useTrash.js create mode 100644 client/src/hooks/datafiles/mutations/useTrash.ts diff --git a/client/package-lock.json b/client/package-lock.json index 2709309a0..d762d8b97 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -12,7 +12,7 @@ "@emotion/styled": "^11.13.0", "@mui/material": "^6.1.1", "@niivue/niivue": "^0.32.0", - "@tanstack/react-query": "^5.59.16", + "@tanstack/react-query": "^5.59.19", "axios": "^1.7.7", "bowser": "^2.9.0", "cross-fetch": "^3.1.4", @@ -4569,20 +4569,22 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.59.16", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.16.tgz", - "integrity": "sha512-crHn+G3ltqb5JG0oUv6q+PMz1m1YkjpASrXTU+sYWW9pLk0t2GybUHNRqYPZWhxgjPaVGC4yp92gSFEJgYEsPw==", + "version": "5.59.17", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.17.tgz", + "integrity": "sha512-jWdDiif8kaqnRGHNXAa9CnudtxY5v9DUxXhodgqX2Rwzj+1UwStDHEbBd9IA5C7VYAaJ2s+BxFR6PUBs8ERorA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/react-query": { - "version": "5.59.16", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.16.tgz", - "integrity": "sha512-MuyWheG47h6ERd4PKQ6V8gDyBu3ThNG22e1fRVwvq6ap3EqsFhyuxCAwhNP/03m/mLg+DAb0upgbPaX6VB+CkQ==", + "version": "5.59.19", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.19.tgz", + "integrity": "sha512-xLRfyFyQOFcLltKCds0LijfC6/HQJrrTTnZB8ciyn74LIkVAm++vZJ6eUVG20RmJtdP8REdy7vSOYW4M3//XLA==", + "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.59.16" + "@tanstack/query-core": "5.59.17" }, "funding": { "type": "github", @@ -5763,6 +5765,7 @@ "version": "1.7.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -5773,6 +5776,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -8275,6 +8279,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -12329,7 +12334,8 @@ "node_modules/js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", - "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -15265,7 +15271,8 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/psl": { "version": "1.9.0", diff --git a/client/package.json b/client/package.json index 057b0d963..bdeaeee88 100644 --- a/client/package.json +++ b/client/package.json @@ -8,7 +8,7 @@ "@emotion/styled": "^11.13.0", "@mui/material": "^6.1.1", "@niivue/niivue": "^0.32.0", - "@tanstack/react-query": "^5.59.16", + "@tanstack/react-query": "^5.59.19", "axios": "^1.7.7", "bowser": "^2.9.0", "cross-fetch": "^3.1.4", diff --git a/client/src/hooks/datafiles/mutations/useTrash.js b/client/src/hooks/datafiles/mutations/useTrash.js deleted file mode 100644 index 8280b82fd..000000000 --- a/client/src/hooks/datafiles/mutations/useTrash.js +++ /dev/null @@ -1,29 +0,0 @@ -import { useSelector, useDispatch, shallowEqual } from 'react-redux'; - -function useTrash() { - const dispatch = useDispatch(); - const status = useSelector( - (state) => state.files.operationStatus.trash, - shallowEqual - ); - - const setStatus = (newStatus) => { - dispatch({ - type: 'DATA_FILES_SET_OPERATION_STATUS', - payload: { status: newStatus, operation: 'trash' }, - }); - }; - - const trash = ({ selection, callback }) => - dispatch({ - type: 'DATA_FILES_TRASH', - payload: { - src: selection, - reloadCallback: callback, - }, - }); - - return { trash, status, setStatus }; -} - -export default useTrash; diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts new file mode 100644 index 000000000..2383be69e --- /dev/null +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -0,0 +1,107 @@ +import { useSelector, useDispatch, shallowEqual } from 'react-redux'; +import { useMutation } from '@tanstack/react-query'; +import { apiClient } from 'utils/apiClient'; +import Cookies from 'js-cookie'; + +export async function trashUtil({ + // Per TypeScript, declare variables... + api, + scheme, + system, + path, + homeDir +}: { + // ...and their types for use in this function + api: string; + scheme: string; + system: string; + path: string; + homeDir: string; +}): Promise<{ name: string; path: string }> { + const url = `/api/datafiles/${api}/trash/${scheme}/${system}/${path}/`; + const request = await apiClient.put<{ name: string; path: string }>(url, { + method: 'PUT', + headers: { + 'X-CSRFToken': Cookies.get('csrftoken') + }, + credentials: 'same-origin', + body: JSON.stringify({ + homeDir: homeDir, + }), + }); + + return request.data; +} + +function useTrash() { + const dispatch = useDispatch(); + const status = useSelector( + (state: any) => state.files.operationStatus.trash, + shallowEqual + ); + + const setStatus = (newStatus: any) => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS', + payload: { status: newStatus, operation: 'trash' }, + }); + }; + // Establish mutate using trashUtil as its mutation function + const { mutate } = useMutation({ mutationFn: trashUtil }); + + const trash = ({ + // Per TypeScript, declare variables... + selection, + callback + }: { + // ...and their types for use in this function + selection: any; + callback: (name: string, path: string) => any; + }) => { + dispatch({ + type: 'DATA_FILES_TRASH', + payload: { + src: selection, + reloadCallback: callback, + }, + }); + + // Establish the parameters of mutate + mutate( + { + api: selection.api, + scheme: selection.scheme, + system: selection.system, + path: '/' + selection.path, + homeDir: selection.homeDir + }, + { + // Sends the file to the Trash if successful + onSuccess: (response) => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS', + payload: { status: 'SUCCESS', operation: 'trash' }, + }); + callback(response.name, response.path); + dispatch({ + type: 'ADD_TOAST', + payload: { + message: `${selection} moved to Trash` + }, + }); + }, + // Sends an error message if it's not successful + onError: () => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS', + payload: { status: 'ERROR', operation: 'trash' }, + }); + } + } + ); + }; + + return { trash, status, setStatus }; +}; + +export default useTrash; From 181bc71431cf25c8e521ef517c6e870ef85e1238 Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Tue, 5 Nov 2024 13:49:08 -0600 Subject: [PATCH 02/12] Linted code to meet quality standards --- .../src/hooks/datafiles/mutations/useTrash.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts index 2383be69e..2cbeb20d1 100644 --- a/client/src/hooks/datafiles/mutations/useTrash.ts +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -5,11 +5,11 @@ import Cookies from 'js-cookie'; export async function trashUtil({ // Per TypeScript, declare variables... - api, - scheme, - system, - path, - homeDir + api, + scheme, + system, + path, + homeDir, }: { // ...and their types for use in this function api: string; @@ -21,8 +21,8 @@ export async function trashUtil({ const url = `/api/datafiles/${api}/trash/${scheme}/${system}/${path}/`; const request = await apiClient.put<{ name: string; path: string }>(url, { method: 'PUT', - headers: { - 'X-CSRFToken': Cookies.get('csrftoken') + headers: { + 'X-CSRFToken': Cookies.get('csrftoken'), }, credentials: 'same-origin', body: JSON.stringify({ @@ -49,10 +49,10 @@ function useTrash() { // Establish mutate using trashUtil as its mutation function const { mutate } = useMutation({ mutationFn: trashUtil }); - const trash = ({ + const trash = ({ // Per TypeScript, declare variables... - selection, - callback + selection, + callback, }: { // ...and their types for use in this function selection: any; @@ -69,11 +69,11 @@ function useTrash() { // Establish the parameters of mutate mutate( { - api: selection.api, - scheme: selection.scheme, + api: selection.api, + scheme: selection.scheme, system: selection.system, path: '/' + selection.path, - homeDir: selection.homeDir + homeDir: selection.homeDir, }, { // Sends the file to the Trash if successful @@ -86,7 +86,7 @@ function useTrash() { dispatch({ type: 'ADD_TOAST', payload: { - message: `${selection} moved to Trash` + message: `${selection} moved to Trash`, }, }); }, @@ -96,12 +96,12 @@ function useTrash() { type: 'DATA_FILES_SET_OPERATION_STATUS', payload: { status: 'ERROR', operation: 'trash' }, }); - } + }, } ); }; - + return { trash, status, setStatus }; -}; +} export default useTrash; From 98936a4968cfb336380d8dbc86e768e8c6d4c0da Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Thu, 7 Nov 2024 08:56:53 -0600 Subject: [PATCH 03/12] Removed superfluous comments --- client/src/hooks/datafiles/mutations/useTrash.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts index 2cbeb20d1..517e77656 100644 --- a/client/src/hooks/datafiles/mutations/useTrash.ts +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -4,14 +4,12 @@ import { apiClient } from 'utils/apiClient'; import Cookies from 'js-cookie'; export async function trashUtil({ - // Per TypeScript, declare variables... api, scheme, system, path, homeDir, }: { - // ...and their types for use in this function api: string; scheme: string; system: string; @@ -50,11 +48,9 @@ function useTrash() { const { mutate } = useMutation({ mutationFn: trashUtil }); const trash = ({ - // Per TypeScript, declare variables... selection, callback, }: { - // ...and their types for use in this function selection: any; callback: (name: string, path: string) => any; }) => { From 9286b7eb76d676c8331967f1f866706be76df5c1 Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Mon, 11 Nov 2024 10:02:51 -0600 Subject: [PATCH 04/12] Removed extraneous dispatch calls and ran mutations on each selected file --- .../src/hooks/datafiles/mutations/useTrash.ts | 97 +++++++++++-------- 1 file changed, 56 insertions(+), 41 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts index 517e77656..ec0037d42 100644 --- a/client/src/hooks/datafiles/mutations/useTrash.ts +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -1,7 +1,8 @@ import { useSelector, useDispatch, shallowEqual } from 'react-redux'; import { useMutation } from '@tanstack/react-query'; -import { apiClient } from 'utils/apiClient'; +import { useSelectedFiles } from 'hooks/datafiles'; import Cookies from 'js-cookie'; +import { apiClient } from 'utils/apiClient'; export async function trashUtil({ api, @@ -17,12 +18,11 @@ export async function trashUtil({ homeDir: string; }): Promise<{ name: string; path: string }> { const url = `/api/datafiles/${api}/trash/${scheme}/${system}/${path}/`; - const request = await apiClient.put<{ name: string; path: string }>(url, { - method: 'PUT', + const request = await apiClient.put(url, { headers: { - 'X-CSRFToken': Cookies.get('csrftoken'), + 'X-CSRFToken': Cookies.get('csrftoken') || '', }, - credentials: 'same-origin', + withCredentials: true, body: JSON.stringify({ homeDir: homeDir, }), @@ -33,18 +33,22 @@ export async function trashUtil({ function useTrash() { const dispatch = useDispatch(); + const { selectedFiles: selected } = useSelectedFiles(); const status = useSelector( (state: any) => state.files.operationStatus.trash, shallowEqual ); + const { api, scheme } = useSelector( + (state: any) => state.files.params.FilesListing + ); const setStatus = (newStatus: any) => { dispatch({ type: 'DATA_FILES_SET_OPERATION_STATUS', payload: { status: newStatus, operation: 'trash' }, }); }; - // Establish mutate using trashUtil as its mutation function + const { mutate } = useMutation({ mutationFn: trashUtil }); const trash = ({ @@ -54,47 +58,58 @@ function useTrash() { selection: any; callback: (name: string, path: string) => any; }) => { + const filteredSelected = selected.filter( + (f: any) => status[f.id] !== 'SUCCESS' + ); dispatch({ - type: 'DATA_FILES_TRASH', + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', payload: { - src: selection, - reloadCallback: callback, + status: 'RUNNING', + key: (index: string) => index, + operation: 'trash', }, }); - // Establish the parameters of mutate - mutate( - { - api: selection.api, - scheme: selection.scheme, - system: selection.system, - path: '/' + selection.path, - homeDir: selection.homeDir, - }, - { - // Sends the file to the Trash if successful - onSuccess: (response) => { - dispatch({ - type: 'DATA_FILES_SET_OPERATION_STATUS', - payload: { status: 'SUCCESS', operation: 'trash' }, - }); - callback(response.name, response.path); - dispatch({ - type: 'ADD_TOAST', - payload: { - message: `${selection} moved to Trash`, - }, - }); - }, - // Sends an error message if it's not successful - onError: () => { - dispatch({ - type: 'DATA_FILES_SET_OPERATION_STATUS', - payload: { status: 'ERROR', operation: 'trash' }, - }); + filteredSelected.forEach(() => { + mutate( + { + api: api, + scheme: scheme, + system: selection.system, + path: selection.path, + homeDir: selection.homeDir, }, - } - ); + { + onSuccess: (response: any) => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', + payload: { + status: 'SUCCESS', + key: (index: string) => index, + operation: 'trash', + }, + }); + callback(response.name, response.path); + dispatch({ + type: 'ADD_TOAST', + payload: { + message: `${selection} moved to Trash`, + }, + }); + }, + onError: () => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', + payload: { + status: 'ERROR', + key: (index: string) => index, + operation: 'trash', + }, + }); + }, + } + ); + }); }; return { trash, status, setStatus }; From a8b48994bed30905706f42f53aa80244beb22188 Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Tue, 26 Nov 2024 11:12:38 -0600 Subject: [PATCH 05/12] Added more asynchronous calls to further streamline process --- .../src/hooks/datafiles/mutations/useTrash.ts | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts index ec0037d42..d14a245f2 100644 --- a/client/src/hooks/datafiles/mutations/useTrash.ts +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -49,7 +49,7 @@ function useTrash() { }); }; - const { mutate } = useMutation({ mutationFn: trashUtil }); + const { mutateAsync } = useMutation({ mutationFn: trashUtil }); const trash = ({ selection, @@ -61,17 +61,16 @@ function useTrash() { const filteredSelected = selected.filter( (f: any) => status[f.id] !== 'SUCCESS' ); - dispatch({ - type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', - payload: { - status: 'RUNNING', - key: (index: string) => index, - operation: 'trash', - }, - }); - - filteredSelected.forEach(() => { - mutate( + const trashCalls: Promise[] = filteredSelected.forEach((file: any) => { + dispatch({ + type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', + payload: { + status: 'RUNNING', + key: (index: string) => index, + operation: 'trash', + }, + }); + return mutateAsync( { api: api, scheme: scheme, @@ -89,13 +88,13 @@ function useTrash() { operation: 'trash', }, }); - callback(response.name, response.path); dispatch({ type: 'ADD_TOAST', payload: { message: `${selection} moved to Trash`, }, }); + callback(response.name, response.path); }, onError: () => { dispatch({ @@ -110,6 +109,8 @@ function useTrash() { } ); }); + // filteredSelected.forEach(() => { + // }); }; return { trash, status, setStatus }; From d3de63fcf57e6f23bf3ba4159547bce5485ad1f6 Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Thu, 5 Dec 2024 08:30:08 -0600 Subject: [PATCH 06/12] Still in the process of getting the trash mutation to work correctly --- .../DataFilesToolbar/DataFilesToolbar.jsx | 29 ++++++++---- .../src/hooks/datafiles/mutations/useTrash.ts | 47 ++++++++++++------- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx b/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx index 9f4fd9255..715214666 100644 --- a/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx +++ b/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx @@ -7,6 +7,7 @@ import getFilePermissions from 'utils/filePermissions'; import { useModal, useSelectedFiles, useFileListing } from 'hooks/datafiles'; import { useSystemRole } from '../DataFilesProjectMembers/_cells/SystemRoleSelector'; import './DataFilesToolbar.scss'; +import { useTrash } from 'hooks/datafiles/mutations'; export const ToolbarButton = ({ text, iconName, onClick, disabled }) => { const iconClassName = `action icon-${iconName}`; @@ -40,6 +41,7 @@ const DataFilesToolbar = ({ scheme, api }) => { const { toggle } = useModal(); const { selectedFiles } = useSelectedFiles(); const { params } = useFileListing('FilesListing'); + const { trash } = useTrash(); const history = useHistory(); const location = useLocation(); @@ -172,21 +174,30 @@ const DataFilesToolbar = ({ scheme, api }) => { } }; - const trash = useCallback(() => { + const trashCallback = useCallback(() => { const filteredSelected = selectedFiles.filter( (f) => status[f.system + f.path] !== 'SUCCESS' ); - - dispatch({ - type: 'DATA_FILES_TRASH', - payload: { - src: filteredSelected, - homeDir: selectedSystem?.homeDir || '', - reloadCallback: reloadPage, - }, + trash({ + filteredSelected, reloadPage }); + + + + // dispatch({ + // type: 'DATA_FILES_TRASH', + // payload: { + // src: filteredSelected, + // homeDir: selectedSystem?.homeDir || '', + // reloadCallback: reloadPage, + // }, + // }); }, [selectedFiles, selectedSystem, reloadPage]); + + + // const { status: trashStatus } = useTrash(); + const empty = () => { dispatch({ type: 'DATA_FILES_TOGGLE_MODAL', diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts index d14a245f2..8b4d61083 100644 --- a/client/src/hooks/datafiles/mutations/useTrash.ts +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -16,19 +16,33 @@ export async function trashUtil({ system: string; path: string; homeDir: string; -}): Promise<{ name: string; path: string }> { +}) { + // const body = { + // homeDir: homeDir + // }; + console.log(homeDir); const url = `/api/datafiles/${api}/trash/${scheme}/${system}/${path}/`; - const request = await apiClient.put(url, { - headers: { - 'X-CSRFToken': Cookies.get('csrftoken') || '', - }, - withCredentials: true, + // const request = await apiClient.put(url, { + // headers: { + // 'X-CSRFToken': Cookies.get('csrftoken'), + // }, + // withCredentials: true, + // body: JSON.stringify({ + // homeDir: homeDir, + // }), + // }); + const request = await fetch(url, { + method: 'PUT', + headers: { 'X-CSRFToken': Cookies.get('csrftoken') || ''}, + credentials: 'same-origin', body: JSON.stringify({ homeDir: homeDir, }), }); - - return request.data; + // const request = await apiClient.put(url, body); + console.log(request); + + return request; } function useTrash() { @@ -39,7 +53,7 @@ function useTrash() { shallowEqual ); - const { api, scheme } = useSelector( + const { api, scheme, homeDir } = useSelector( (state: any) => state.files.params.FilesListing ); const setStatus = (newStatus: any) => { @@ -53,10 +67,10 @@ function useTrash() { const trash = ({ selection, - callback, + // callback, }: { selection: any; - callback: (name: string, path: string) => any; + // callback: any; }) => { const filteredSelected = selected.filter( (f: any) => status[f.id] !== 'SUCCESS' @@ -70,13 +84,14 @@ function useTrash() { operation: 'trash', }, }); + console.log("File", file); return mutateAsync( { api: api, scheme: scheme, - system: selection.system, - path: selection.path, - homeDir: selection.homeDir, + system: file.system, + path: file.path, + homeDir: homeDir, }, { onSuccess: (response: any) => { @@ -94,7 +109,7 @@ function useTrash() { message: `${selection} moved to Trash`, }, }); - callback(response.name, response.path); + // callback; }, onError: () => { dispatch({ @@ -109,8 +124,6 @@ function useTrash() { } ); }); - // filteredSelected.forEach(() => { - // }); }; return { trash, status, setStatus }; From 754f583e97ce70718066d8a1ca4f6da21830f3fe Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Thu, 5 Dec 2024 10:45:12 -0600 Subject: [PATCH 07/12] Trash mutation actually works as intended --- .../DataFilesToolbar/DataFilesToolbar.jsx | 34 ++++++------------- .../src/hooks/datafiles/mutations/useTrash.ts | 31 +++++++---------- 2 files changed, 24 insertions(+), 41 deletions(-) diff --git a/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx b/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx index 715214666..cf3550e68 100644 --- a/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx +++ b/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx @@ -174,29 +174,17 @@ const DataFilesToolbar = ({ scheme, api }) => { } }; - const trashCallback = useCallback(() => { - const filteredSelected = selectedFiles.filter( - (f) => status[f.system + f.path] !== 'SUCCESS' - ); - trash({ - filteredSelected, reloadPage - }); - - - - // dispatch({ - // type: 'DATA_FILES_TRASH', - // payload: { - // src: filteredSelected, - // homeDir: selectedSystem?.homeDir || '', - // reloadCallback: reloadPage, - // }, - // }); - }, [selectedFiles, selectedSystem, reloadPage]); + const homeDir = selectedSystem?.homeDir; - - - // const { status: trashStatus } = useTrash(); + const trashCallback = useCallback(() => { + trash({ + destSystem: selectedSystem.system, + homeDir: homeDir, + callback: reloadPage, + }); + }, + [selectedFiles, reloadPage, status] + ); const empty = () => { dispatch({ @@ -282,7 +270,7 @@ const DataFilesToolbar = ({ scheme, api }) => { diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts index 8b4d61083..a6bd90c92 100644 --- a/client/src/hooks/datafiles/mutations/useTrash.ts +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -2,7 +2,6 @@ import { useSelector, useDispatch, shallowEqual } from 'react-redux'; import { useMutation } from '@tanstack/react-query'; import { useSelectedFiles } from 'hooks/datafiles'; import Cookies from 'js-cookie'; -import { apiClient } from 'utils/apiClient'; export async function trashUtil({ api, @@ -17,19 +16,12 @@ export async function trashUtil({ path: string; homeDir: string; }) { - // const body = { - // homeDir: homeDir - // }; - console.log(homeDir); const url = `/api/datafiles/${api}/trash/${scheme}/${system}/${path}/`; - // const request = await apiClient.put(url, { + // const request = await apiClient.put(url, body, { // headers: { - // 'X-CSRFToken': Cookies.get('csrftoken'), + // 'X-CSRFToken': Cookies.get('csrftoken' || ''), // }, // withCredentials: true, - // body: JSON.stringify({ - // homeDir: homeDir, - // }), // }); const request = await fetch(url, { method: 'PUT', @@ -53,9 +45,10 @@ function useTrash() { shallowEqual ); - const { api, scheme, homeDir } = useSelector( + const { api, scheme } = useSelector( (state: any) => state.files.params.FilesListing ); + const setStatus = (newStatus: any) => { dispatch({ type: 'DATA_FILES_SET_OPERATION_STATUS', @@ -66,11 +59,13 @@ function useTrash() { const { mutateAsync } = useMutation({ mutationFn: trashUtil }); const trash = ({ - selection, - // callback, + destSystem, + homeDir, + callback, }: { - selection: any; - // callback: any; + destSystem: string; + homeDir: any; + callback: any; }) => { const filteredSelected = selected.filter( (f: any) => status[f.id] !== 'SUCCESS' @@ -89,7 +84,7 @@ function useTrash() { { api: api, scheme: scheme, - system: file.system, + system: destSystem, path: file.path, homeDir: homeDir, }, @@ -106,10 +101,10 @@ function useTrash() { dispatch({ type: 'ADD_TOAST', payload: { - message: `${selection} moved to Trash`, + message: `File moved to Trash`, }, }); - // callback; + callback(); }, onError: () => { dispatch({ From bcb9b6e2c82bfb25fb03fe9dd551ddf559421481 Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Thu, 5 Dec 2024 10:49:05 -0600 Subject: [PATCH 08/12] Linted client-side code --- .../DataFilesToolbar/DataFilesToolbar.jsx | 14 ++++++-------- client/src/hooks/datafiles/mutations/useTrash.ts | 6 ++---- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx b/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx index cf3550e68..685073bbe 100644 --- a/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx +++ b/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx @@ -177,14 +177,12 @@ const DataFilesToolbar = ({ scheme, api }) => { const homeDir = selectedSystem?.homeDir; const trashCallback = useCallback(() => { - trash({ - destSystem: selectedSystem.system, - homeDir: homeDir, - callback: reloadPage, - }); - }, - [selectedFiles, reloadPage, status] - ); + trash({ + destSystem: selectedSystem.system, + homeDir: homeDir, + callback: reloadPage, + }); + }, [selectedFiles, reloadPage, status]); const empty = () => { dispatch({ diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts index a6bd90c92..6d9d4a143 100644 --- a/client/src/hooks/datafiles/mutations/useTrash.ts +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -25,15 +25,14 @@ export async function trashUtil({ // }); const request = await fetch(url, { method: 'PUT', - headers: { 'X-CSRFToken': Cookies.get('csrftoken') || ''}, + headers: { 'X-CSRFToken': Cookies.get('csrftoken') || '' }, credentials: 'same-origin', body: JSON.stringify({ homeDir: homeDir, }), }); // const request = await apiClient.put(url, body); - console.log(request); - + return request; } @@ -79,7 +78,6 @@ function useTrash() { operation: 'trash', }, }); - console.log("File", file); return mutateAsync( { api: api, From b46e99a6cd662b61461cbe917438a55ac454d0c7 Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Thu, 5 Dec 2024 13:30:41 -0600 Subject: [PATCH 09/12] Reverting changes made to package and package-lock --- client/package-lock.json | 27 ++++++++++----------------- client/package.json | 2 +- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index d762d8b97..2709309a0 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -12,7 +12,7 @@ "@emotion/styled": "^11.13.0", "@mui/material": "^6.1.1", "@niivue/niivue": "^0.32.0", - "@tanstack/react-query": "^5.59.19", + "@tanstack/react-query": "^5.59.16", "axios": "^1.7.7", "bowser": "^2.9.0", "cross-fetch": "^3.1.4", @@ -4569,22 +4569,20 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.59.17", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.17.tgz", - "integrity": "sha512-jWdDiif8kaqnRGHNXAa9CnudtxY5v9DUxXhodgqX2Rwzj+1UwStDHEbBd9IA5C7VYAaJ2s+BxFR6PUBs8ERorA==", - "license": "MIT", + "version": "5.59.16", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.16.tgz", + "integrity": "sha512-crHn+G3ltqb5JG0oUv6q+PMz1m1YkjpASrXTU+sYWW9pLk0t2GybUHNRqYPZWhxgjPaVGC4yp92gSFEJgYEsPw==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/react-query": { - "version": "5.59.19", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.19.tgz", - "integrity": "sha512-xLRfyFyQOFcLltKCds0LijfC6/HQJrrTTnZB8ciyn74LIkVAm++vZJ6eUVG20RmJtdP8REdy7vSOYW4M3//XLA==", - "license": "MIT", + "version": "5.59.16", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.16.tgz", + "integrity": "sha512-MuyWheG47h6ERd4PKQ6V8gDyBu3ThNG22e1fRVwvq6ap3EqsFhyuxCAwhNP/03m/mLg+DAb0upgbPaX6VB+CkQ==", "dependencies": { - "@tanstack/query-core": "5.59.17" + "@tanstack/query-core": "5.59.16" }, "funding": { "type": "github", @@ -5765,7 +5763,6 @@ "version": "1.7.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -5776,7 +5773,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -8279,7 +8275,6 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -12334,8 +12329,7 @@ "node_modules/js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", - "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", - "license": "MIT" + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -15271,8 +15265,7 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/psl": { "version": "1.9.0", diff --git a/client/package.json b/client/package.json index bdeaeee88..057b0d963 100644 --- a/client/package.json +++ b/client/package.json @@ -8,7 +8,7 @@ "@emotion/styled": "^11.13.0", "@mui/material": "^6.1.1", "@niivue/niivue": "^0.32.0", - "@tanstack/react-query": "^5.59.19", + "@tanstack/react-query": "^5.59.16", "axios": "^1.7.7", "bowser": "^2.9.0", "cross-fetch": "^3.1.4", From 3796d486459092180d5cf99afebfd7085ca65c3a Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Thu, 5 Dec 2024 15:30:21 -0600 Subject: [PATCH 10/12] Refined trash mutation hook to use Axios and Promises --- .../src/hooks/datafiles/mutations/useTrash.ts | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts index 6d9d4a143..6a5454614 100644 --- a/client/src/hooks/datafiles/mutations/useTrash.ts +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -2,6 +2,7 @@ import { useSelector, useDispatch, shallowEqual } from 'react-redux'; import { useMutation } from '@tanstack/react-query'; import { useSelectedFiles } from 'hooks/datafiles'; import Cookies from 'js-cookie'; +import { apiClient } from 'utils/apiClient'; export async function trashUtil({ api, @@ -17,23 +18,26 @@ export async function trashUtil({ homeDir: string; }) { const url = `/api/datafiles/${api}/trash/${scheme}/${system}/${path}/`; - // const request = await apiClient.put(url, body, { - // headers: { - // 'X-CSRFToken': Cookies.get('csrftoken' || ''), - // }, - // withCredentials: true, - // }); - const request = await fetch(url, { - method: 'PUT', - headers: { 'X-CSRFToken': Cookies.get('csrftoken') || '' }, - credentials: 'same-origin', - body: JSON.stringify({ - homeDir: homeDir, - }), + const body = { + homeDir: homeDir + }; + const response = await apiClient.put(url, body, { + headers: { + 'X-CSRFToken': Cookies.get('csrftoken' || ''), + }, + withCredentials: true, }); + // const request = await fetch(url, { + // method: 'PUT', + // headers: { 'X-CSRFToken': Cookies.get('csrftoken') || '' }, + // credentials: 'same-origin', + // body: JSON.stringify({ + // homeDir: homeDir, + // }), + // }); // const request = await apiClient.put(url, body); - return request; + return response.data; } function useTrash() { @@ -69,7 +73,7 @@ function useTrash() { const filteredSelected = selected.filter( (f: any) => status[f.id] !== 'SUCCESS' ); - const trashCalls: Promise[] = filteredSelected.forEach((file: any) => { + const trashCalls: Promise[] = filteredSelected.map((file: any) => { dispatch({ type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY', payload: { @@ -96,12 +100,7 @@ function useTrash() { operation: 'trash', }, }); - dispatch({ - type: 'ADD_TOAST', - payload: { - message: `File moved to Trash`, - }, - }); + callback(); }, onError: () => { @@ -117,6 +116,18 @@ function useTrash() { } ); }); + Promise.all(trashCalls).then(() => { + dispatch({ + type: 'ADD_TOAST', + payload: { + message: `${ + filteredSelected.length > 1 + ? `${filteredSelected.length} files moved to Trash` + : 'File moved to Trash' + }`, + }, + }); + }); }; return { trash, status, setStatus }; From e3ceba7a8610fc653154ae464623b2e8c033e199 Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Thu, 5 Dec 2024 15:38:31 -0600 Subject: [PATCH 11/12] Linted client-side code again --- client/src/hooks/datafiles/mutations/useTrash.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts index 6a5454614..f87fd123b 100644 --- a/client/src/hooks/datafiles/mutations/useTrash.ts +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -19,7 +19,7 @@ export async function trashUtil({ }) { const url = `/api/datafiles/${api}/trash/${scheme}/${system}/${path}/`; const body = { - homeDir: homeDir + homeDir: homeDir, }; const response = await apiClient.put(url, body, { headers: { @@ -100,7 +100,7 @@ function useTrash() { operation: 'trash', }, }); - + callback(); }, onError: () => { @@ -121,8 +121,8 @@ function useTrash() { type: 'ADD_TOAST', payload: { message: `${ - filteredSelected.length > 1 - ? `${filteredSelected.length} files moved to Trash` + filteredSelected.length > 1 + ? `${filteredSelected.length} files moved to Trash` : 'File moved to Trash' }`, }, From 2a3a07214a6941d055bf15a260acfb693b4c84c8 Mon Sep 17 00:00:00 2001 From: Jeff McMillen Date: Fri, 6 Dec 2024 10:15:49 -0600 Subject: [PATCH 12/12] Ensured a Promise is returned --- client/src/hooks/datafiles/mutations/useTrash.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/client/src/hooks/datafiles/mutations/useTrash.ts b/client/src/hooks/datafiles/mutations/useTrash.ts index f87fd123b..546d2dfc8 100644 --- a/client/src/hooks/datafiles/mutations/useTrash.ts +++ b/client/src/hooks/datafiles/mutations/useTrash.ts @@ -16,7 +16,7 @@ export async function trashUtil({ system: string; path: string; homeDir: string; -}) { +}): Promise<{ file: any; path: string }> { const url = `/api/datafiles/${api}/trash/${scheme}/${system}/${path}/`; const body = { homeDir: homeDir, @@ -27,15 +27,6 @@ export async function trashUtil({ }, withCredentials: true, }); - // const request = await fetch(url, { - // method: 'PUT', - // headers: { 'X-CSRFToken': Cookies.get('csrftoken') || '' }, - // credentials: 'same-origin', - // body: JSON.stringify({ - // homeDir: homeDir, - // }), - // }); - // const request = await apiClient.put(url, body); return response.data; }