Skip to content

Commit

Permalink
Merge branch 'main' into refactor/WP-791-dropdown-menu
Browse files Browse the repository at this point in the history
  • Loading branch information
chandra-tacc authored Jan 8, 2025
2 parents c5bdf9c + 29e1bce commit 260d811
Show file tree
Hide file tree
Showing 27 changed files with 969 additions and 190 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
align-items: center;
gap: 1rem;
}

.combined-breadcrumbs :global(.breadcrumb-container) button {
font-size: 1rem;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
.h-100 {
padding: 0 10px;
}
.breadcrumb-container {
font-size: 0.75rem;
}
.breadcrumbs {
font-size: 12px;
padding-top: 5px;
padding-bottom: 5px;
color: #707070;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}`;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -271,7 +268,7 @@ const DataFilesToolbar = ({ scheme, api }) => {
<ToolbarButton
text={!inTrash ? 'Trash' : 'Empty'}
iconName="trash"
onClick={!inTrash ? trash : empty}
onClick={!inTrash ? trashCallback : empty}
disabled={!inTrash ? !canTrash : !canEmpty}
className={!inTrash ? '' : 'is-empty'}
/>
Expand Down
25 changes: 21 additions & 4 deletions client/src/components/DataFiles/tests/DataFiles.test.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
import React from 'react';
import React, { version } from 'react';
import { createMemoryHistory } from 'history';
import configureStore from 'redux-mock-store';
import DataFiles from '../DataFiles';
import systemsFixture from '../fixtures/DataFiles.systems.fixture';
import filesFixture from '../fixtures/DataFiles.files.fixture';
import renderComponent from 'utils/testing';
import { projectsFixture } from '../../../redux/sagas/fixtures/projects.fixture';
import { vi } from 'vitest';
import { useExtract } from 'hooks/datafiles/mutations';

const mockStore = configureStore();
global.fetch = vi.fn();

describe('DataFiles', () => {
it('should render Data Files with multiple private systems', () => {
afterEach(() => {
fetch.mockClear();
});
it.skip('should render Data Files with multiple private systems', () => {
const history = createMemoryHistory();
const store = mockStore({
workbench: {
config: {
extract: '',
compress: '',
extract: {
id: 'extract',
version: '0.0.1',
},
compress: {
id: 'compress',
version: '0.0.3',
},
},
},
allocations: {
portal_alloc: 'TACC-ACI',
active: [{ projectId: 'active-project' }],
},
systems: systemsFixture,
files: filesFixture,
pushKeys: {
Expand All @@ -39,6 +55,7 @@ describe('DataFiles', () => {
},
},
});
fetch.mockResolvedValue(useExtract());
const { getByText, getAllByText, queryByText } = renderComponent(
<DataFiles />,
store,
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Tickets/TicketCreateForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ function TicketCreateForm({
<FormField
name="cc"
label="Cc"
description="Separate emails with commas"
description="Separate emails with commas. NOTE: Emails listed here will only receive emails on replies to tickets."
/>
</Col>
</Row>
Expand Down
4 changes: 3 additions & 1 deletion client/src/components/_common/Button/Button.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@
}

.root.as-link {
font-size: 1rem;
font-size: inherit;
}



.icon--before {
composes: c-button__icon--before from '../../../styles/components/c-button--new.css';
}
Expand Down
17 changes: 16 additions & 1 deletion client/src/components/_common/Form/FileInputDropZone.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* FP-993: Allow use by DataFilesUploadModal */
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { Button, InlineMessage } from '_common';
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -45,6 +45,13 @@ function FileInputDropZone({
}
};

const removeRejectedFile = (i) => {
const newRejectedFiles = rejectedFiles.filter(
(file) => file !== rejectedFiles[i]
);
setRejectedFiles(newRejectedFiles);
};

const showFileList = (files && files.length > 0) || rejectedFiles.length > 0;

return (
Expand Down Expand Up @@ -74,6 +81,14 @@ function FileInputDropZone({
<InlineMessage type="error">
Exceeds File Size Limit
</InlineMessage>
<Button
type="link"
onClick={() => {
removeRejectedFile(i);
}}
>
Remove
</Button>
</div>
))}
{files &&
Expand Down
27 changes: 0 additions & 27 deletions client/src/hooks/datafiles/mutations/useCompress.js

This file was deleted.

156 changes: 156 additions & 0 deletions client/src/hooks/datafiles/mutations/useCompress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { useMutation } from '@tanstack/react-query';
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { getCompressParams } from 'utils/getCompressParams';
import { apiClient } from 'utils/apiClient';
import { TTapisFile, TPortalSystem } from 'utils/types';
import { TJobBody, TJobPostResponse } from './useSubmitJob';

async function submitJobUtil(body: TJobBody) {
const res = await apiClient.post<TJobPostResponse>(
`/api/workspace/jobs`,
body
);
return res.data.response;
}

function useCompress() {
const dispatch = useDispatch();
const status = useSelector(
(state: any) => state.files.operationStatus.compress,
shallowEqual
);

const setStatus = (newStatus: any) => {
dispatch({
type: 'DATA_FILES_SET_OPERATION_STATUS',
payload: { status: newStatus, operation: 'compress' },
});
};

const compressErrorAction = (errorMessage: any) => {
return {
type: 'DATA_FILES_SET_OPERATION_STATUS',
payload: {
status: { type: 'ERROR', message: errorMessage },
operation: 'compress',
},
};
};

const compressApp = useSelector(
(state: any) => state.workbench.config.compressApp
);

const defaultAllocation = useSelector(
(state: any) =>
state.allocations.portal_alloc || state.allocations.active[0].projectName
);

const systems = useSelector(
(state: any) => state.systems.storage.configuration
);

const { mutateAsync } = useMutation({ mutationFn: submitJobUtil });

const compress = ({
scheme,
files,
filename,
compressionType,
}: {
scheme: string;
files: TTapisFile[];
filename: string;
compressionType: string;
}) => {
dispatch({
type: 'DATA_FILES_SET_OPERATION_STATUS',
payload: { status: 'RUNNING', operation: 'compress' },
});

let defaultPrivateSystem: TPortalSystem | undefined;

if (files[0].scheme === 'private' && files[0].api === 'tapis') {
defaultPrivateSystem = undefined;
}

if (scheme !== 'private' && scheme !== 'projects') {
defaultPrivateSystem = systems.find((s: any) => s.default);

if (!defaultPrivateSystem) {
throw new Error('Folder downloads are unavailable in this portal', {
cause: 'compressError',
});
}
}

const params = getCompressParams(
files,
filename,
compressionType,
compressApp,
defaultAllocation,
defaultPrivateSystem
);

return mutateAsync(
{
job: params,
},
{
onSuccess: (response: any) => {
// If the execution system requires pushing keys, then
// bring up the modal and retry the compress action
if (response.execSys) {
dispatch({
type: 'SYSTEMS_TOGGLE_MODAL',
payload: {
operation: 'pushKeys',
props: {
system: response.execSys,
onCancel: compressErrorAction('An error has occurred'),
},
},
});
} else if (response.status === 'PENDING') {
dispatch({
type: 'DATA_FILES_SET_OPERATION_STATUS',
payload: { status: { type: 'SUCCESS' }, operation: 'compress' },
});
dispatch({
type: 'ADD_TOAST',
payload: {
message: 'Compress job submitted.',
},
});
dispatch({
type: 'DATA_FILES_SET_OPERATION_STATUS',
payload: { operation: 'compress', status: {} },
});
dispatch({
type: 'DATA_FILES_TOGGLE_MODAL',
payload: { operation: 'compress', 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: 'compress',
},
});
},
}
);
};

return { compress, status, setStatus };
}

export default useCompress;
27 changes: 0 additions & 27 deletions client/src/hooks/datafiles/mutations/useExtract.js

This file was deleted.

Loading

0 comments on commit 260d811

Please sign in to comment.