diff --git a/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx b/client/src/components/DataFiles/DataFilesToolbar/DataFilesToolbar.jsx
index 9f4fd9255..685073bbe 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,20 +174,15 @@ const DataFilesToolbar = ({ scheme, api }) => {
}
};
- const trash = useCallback(() => {
- const filteredSelected = selectedFiles.filter(
- (f) => status[f.system + f.path] !== 'SUCCESS'
- );
+ const homeDir = selectedSystem?.homeDir;
- dispatch({
- type: 'DATA_FILES_TRASH',
- payload: {
- src: filteredSelected,
- homeDir: selectedSystem?.homeDir || '',
- reloadCallback: reloadPage,
- },
+ const trashCallback = useCallback(() => {
+ trash({
+ destSystem: selectedSystem.system,
+ homeDir: homeDir,
+ callback: reloadPage,
});
- }, [selectedFiles, selectedSystem, reloadPage]);
+ }, [selectedFiles, reloadPage, status]);
const empty = () => {
dispatch({
@@ -271,7 +268,7 @@ const DataFilesToolbar = ({ scheme, api }) => {
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..546d2dfc8
--- /dev/null
+++ b/client/src/hooks/datafiles/mutations/useTrash.ts
@@ -0,0 +1,127 @@
+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,
+ scheme,
+ system,
+ path,
+ homeDir,
+}: {
+ api: string;
+ scheme: string;
+ system: string;
+ path: string;
+ homeDir: string;
+}): Promise<{ file: any; path: string }> {
+ const url = `/api/datafiles/${api}/trash/${scheme}/${system}/${path}/`;
+ const body = {
+ homeDir: homeDir,
+ };
+ const response = await apiClient.put(url, body, {
+ headers: {
+ 'X-CSRFToken': Cookies.get('csrftoken' || ''),
+ },
+ withCredentials: true,
+ });
+
+ return response.data;
+}
+
+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' },
+ });
+ };
+
+ const { mutateAsync } = useMutation({ mutationFn: trashUtil });
+
+ const trash = ({
+ destSystem,
+ homeDir,
+ callback,
+ }: {
+ destSystem: string;
+ homeDir: any;
+ callback: any;
+ }) => {
+ const filteredSelected = selected.filter(
+ (f: any) => status[f.id] !== 'SUCCESS'
+ );
+ const trashCalls: Promise[] = filteredSelected.map((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,
+ system: destSystem,
+ path: file.path,
+ homeDir: homeDir,
+ },
+ {
+ onSuccess: (response: any) => {
+ dispatch({
+ type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY',
+ payload: {
+ status: 'SUCCESS',
+ key: (index: string) => index,
+ operation: 'trash',
+ },
+ });
+
+ callback();
+ },
+ onError: () => {
+ dispatch({
+ type: 'DATA_FILES_SET_OPERATION_STATUS_BY_KEY',
+ payload: {
+ status: 'ERROR',
+ key: (index: string) => index,
+ operation: 'trash',
+ },
+ });
+ },
+ }
+ );
+ });
+ 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 };
+}
+
+export default useTrash;