Skip to content

Commit

Permalink
task/FP-1102 - Add ability to compress folder to folder download mess…
Browse files Browse the repository at this point in the history
…age modal (#499)

* Updated DataFilesDownloadMessageModal.js to compress folders for download

* added fixture and updated DataFilesDownloadMessageModal.test.js

* fixed linting errors

* fixed one more linting error

* Added styleName to match recent changes to DataFileCompressModal.js

Co-authored-by: Sal Tijerina <r.sal.tijerina@gmail.com>
  • Loading branch information
swillrich5 and rstijerina authored Sep 29, 2021
1 parent b59f54b commit c91caf3
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,102 @@
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { Icon } from '_common';
import './DataFilesDownloadMessageModal.module.scss';
import React, { useMemo } from 'react';
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import {
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Input,
InputGroupAddon
} from 'reactstrap';
import {
LoadingSpinner,
FormField,
Icon,
InlineMessage,
SectionMessage
} from '_common';
import { useHistory, useLocation } from 'react-router-dom';
import { Formik, Form } from 'formik';
import * as yup from 'yup';
import './DataFilesCompressModal.module.scss';

const DataFilesDownloadMessageModal = () => {
const history = useHistory();
const location = useLocation();
const dispatch = useDispatch();
const status = useSelector(
state => state.files.operationStatus.compress,
shallowEqual
);

const isOpen = useSelector(state => state.files.modals.downloadMessage);

const dispatch = useDispatch();
const params = useSelector(
state => state.files.params.FilesListing,
shallowEqual
);

const selectedFiles = useSelector(
({ files: { selected, listing } }) =>
selected.FilesListing.map(i => ({
...listing.FilesListing[i]
})),
shallowEqual
);
const selected = useMemo(() => selectedFiles, [isOpen]);
const formRef = React.useRef();

const onOpened = () => {
dispatch({
type: 'FETCH_FILES_MODAL',
payload: { ...params, section: 'modal' }
});
};

const onClosed = () => {
dispatch({ type: 'DATA_FILES_MODAL_CLOSE' });
if (status) {
dispatch({
type: 'DATA_FILES_SET_OPERATION_STATUS',
payload: { status: {}, operation: 'compress' }
});
history.push(location.pathname);
}
};

const compressCallback = () => {
const { filenameDisplay, filetype } = formRef.current.values;
const filename = `${filenameDisplay}${filetype}`;
dispatch({
type: 'DATA_FILES_COMPRESS',
payload: { filename, files: selected }
});
};

let buttonIcon;
if (status === 'RUNNING') {
buttonIcon = <LoadingSpinner placement="inline" />;
} else if (status === 'ERROR') {
buttonIcon = <Icon name="alert" />;
} else {
buttonIcon = null;
}
const initialValues = {
filenameDisplay:
selectedFiles[0] && selectedFiles.length === 1
? selectedFiles[0].name
: '',
filetype: '.zip'
};
const validationSchema = yup.object().shape({
filenameDisplay: yup
.string()
.trim('The filename cannot include leading and trailing spaces')
.strict(true)
.required('The filename is required')
});

const toggle = () => {
dispatch({
type: 'DATA_FILES_TOGGLE_MODAL',
Expand All @@ -16,27 +105,83 @@ const DataFilesDownloadMessageModal = () => {
};

return (
<Modal isOpen={isOpen} toggle={toggle} size="md" className="dataFilesModal">
<Modal
isOpen={isOpen}
onOpened={onOpened}
onClosed={onClosed}
toggle={toggle}
className="dataFilesModal"
>
<ModalHeader toggle={toggle} charCode="&#xe912;">
Download
Download Folder
</ModalHeader>
<ModalBody>
<p styleName="title">Folders must be compressed before download.</p>
<ol>
<li>Select the folder(s).</li>
<li>
Press the &quot;
<Icon name="compress"></Icon> Compress&quot; icon above the table.
</li>
<li>Complete and submit the form.</li>
<li>After the job finishes, you may download the compressed file.</li>
</ol>
</ModalBody>
<ModalFooter>
<Button type="button" className="data-files-btn" onClick={toggle}>
Close
</Button>
</ModalFooter>
<Formik
innerRef={formRef}
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={compressCallback}
>
{({ setFieldValue, values, isValid }) => {
const handleSelectChange = e => {
setFieldValue('filetype', e.target.value);
};
const formDisabled = status === 'RUNNING' || status === 'SUCCESS';
const buttonDisabled =
formDisabled || !isValid || values.filenameDisplay === '';
return (
<Form>
<ModalBody>
<SectionMessage type="warning">
Folders must be compressed before downloading
</SectionMessage>
<FormField
label="Compressed File Name"
name="filenameDisplay"
disabled={formDisabled}
addonType="append"
addon={
<InputGroupAddon addonType="append" styleName="input-field">
<Input
type="select"
name="filetype"
bsSize="sm"
onChange={handleSelectChange}
disabled={formDisabled}
>
<option value=".zip">.zip</option>
<option value=".tar.gz">.tar.gz</option>
</Input>
</InputGroupAddon>
}
/>
<p>
<em>
A job to compress this folder will be submitted. The
compressed file will appear in this directory for you to
download.
</em>
</p>
</ModalBody>
<ModalFooter>
<InlineMessage isVisible={status === 'SUCCESS'} type="success">
Successfully started compress job
</InlineMessage>
<Button
className="data-files-btn"
disabled={buttonDisabled}
styleName="submit-button"
type="submit"
>
{buttonIcon}
<span styleName={buttonIcon ? 'with-icon' : ''}>
Compress
</span>
</Button>
</ModalFooter>
</Form>
);
}}
</Formik>
</Modal>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const DataFilesDownloadMessageModalFixture = {
operationStatus: {
copy: {},
compress: {}
},
listing: {
FilesListing: {
name: 'testfile',
path: '/testfile',
lastModified: '2020-07-01T10:12:36-05:00',
length: 4096,
permissions: 'ALL',
format: 'folder',
system: 'test.system',
mimeType: 'text/directory',
type: 'dir'
}
},
params: {
FilesListing: {
api: 'tapis',
scheme: 'private',
system: 'test.system',
path: ''
}
},
selected: {
FilesListing: [0],
modal: []
},
modals: {
copy: true,
downloadMessage: true
}
};

export default DataFilesDownloadMessageModalFixture;
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import React from 'react';
import configureStore from 'redux-mock-store';
import renderComponent from 'utils/testing';
import DataFilesDownloadMessageModalFixture from './DataFilesDownloadMessageModal.fixture';
import DataFilesDownloadMessageModal from '../DataFilesDownloadMessageModal';

const mockStore = configureStore();
const initialMockState = {
files: {
modals: {
downloadMessage: true
}
}
files: DataFilesDownloadMessageModalFixture
};

describe('DataFilesDownloadMessageModal', () => {
Expand Down

0 comments on commit c91caf3

Please sign in to comment.