267 lines
6.4 KiB
JavaScript
Raw Normal View History

import React, { useEffect, useReducer, useRef } from 'react';
import PropTypes from 'prop-types';
import { get } from 'lodash';
import { Modal, ModalFooter, useGlobalContext, request } from 'strapi-helper-plugin';
import { Button } from '@buffetjs/core';
import { FormattedMessage } from 'react-intl';
import pluginId from '../../pluginId';
import ModalHeader from '../../components/ModalHeader';
import stepper from './utils/stepper';
import init from './init';
import reducer, { initialState } from './reducer';
import getTrad from '../../utils/getTrad';
const ModalStepper = ({ isOpen, onToggle }) => {
const { formatMessage } = useGlobalContext();
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
const { currentStep, fileToEdit, filesToUpload } = reducerState.toJS();
const { Component, headers, next, prev, withBackButton } = stepper[currentStep];
const filesToUploadLength = filesToUpload.length;
const toggleRef = useRef();
toggleRef.current = onToggle;
useEffect(() => {
if (currentStep === 'upload' && filesToUploadLength === 0) {
// Close modal when file uploading is over
toggleRef.current();
}
}, [filesToUploadLength, currentStep]);
const addFilesToUpload = ({ target: { value } }) => {
dispatch({
type: 'ADD_FILES_TO_UPLOAD',
filesToUpload: value,
});
goTo(next);
};
const handleCancelFileToUpload = fileIndex => {
const fileToCancel = get(filesToUpload, fileIndex, {});
// Cancel upload
fileToCancel.abortController.abort();
dispatch({
type: 'REMOVE_FILE_TO_UPLOAD',
fileIndex,
});
};
const handleChange = ({ target: { name, value } }) => {
dispatch({
type: 'ON_CHANGE',
keys: name,
value,
});
};
const handleClickDeleteFileToUpload = fileIndex => {
dispatch({
type: 'REMOVE_FILE_TO_UPLOAD',
fileIndex,
});
if (currentStep === 'edit-new') {
dispatch({
type: 'RESET_FILE_TO_EDIT',
});
goNext();
}
};
const handleClosed = () => {
dispatch({
type: 'RESET_PROPS',
});
};
const handleGoToEditNewFile = fileIndex => {
dispatch({
type: 'SET_FILE_TO_EDIT',
fileIndex,
});
goTo('edit-new');
};
const handleGoToAddBrowseFiles = () => {
dispatch({
type: 'CLEAN_FILES_ERROR',
});
goBack();
};
const handleSetCropResult = blob => {
dispatch({
type: 'SET_CROP_RESULT',
blob,
});
};
const handleSubmitEditNewFile = e => {
e.preventDefault();
dispatch({
type: 'ON_SUBMIT_EDIT_NEW_FILE',
});
goNext();
};
const handleToggle = () => {
if (filesToUploadLength > 0) {
// eslint-disable-next-line no-alert
const confirm = window.confirm(formatMessage({ id: getTrad('window.confirm.close-modal') }));
if (!confirm) {
return;
}
}
onToggle();
};
const handleUploadFiles = async () => {
dispatch({
type: 'SET_FILES_UPLOADING_STATE',
});
const requests = filesToUpload.map(
async ({ file, fileInfo, originalIndex, abortController }) => {
const formData = new FormData();
const headers = {};
formData.append('files', file);
formData.append('fileInfo', JSON.stringify(fileInfo));
try {
await request(
`/${pluginId}`,
{
method: 'POST',
headers,
body: formData,
signal: abortController.signal,
},
false,
false
);
dispatch({
type: 'REMOVE_FILE_TO_UPLOAD',
fileIndex: originalIndex,
});
} catch (err) {
const errorMessage = get(
err,
['response', 'payload', 'message', '0', 'messages', '0', 'message'],
null
);
dispatch({
type: 'SET_FILE_ERROR',
fileIndex: originalIndex,
errorMessage,
});
}
}
);
await Promise.all(requests);
};
const goBack = () => {
goTo(prev);
};
// FIXME: when back button needed
// eslint-disable-next-line no-unused-vars
const goNext = () => {
if (next === null) {
onToggle();
return;
}
goTo(next);
};
const goTo = to => {
dispatch({
type: 'GO_TO',
to,
});
};
return (
<Modal isOpen={isOpen} onToggle={handleToggle} onClosed={handleClosed}>
{/* header title */}
<ModalHeader
goBack={goBack}
headers={headers.map(headerTrad => ({
key: headerTrad,
element: <FormattedMessage id={headerTrad} />,
}))}
withBackButton={withBackButton}
/>
{/* body of the modal */}
{Component && (
<Component
addFilesToUpload={addFilesToUpload}
fileToEdit={fileToEdit}
filesToUpload={filesToUpload}
onChange={handleChange}
onClickCancelUpload={handleCancelFileToUpload}
onClickDeleteFileToUpload={handleClickDeleteFileToUpload}
onClickEditNewFile={handleGoToEditNewFile}
onGoToAddBrowseFiles={handleGoToAddBrowseFiles}
onSubmitEditNewFile={handleSubmitEditNewFile}
onToggle={handleToggle}
setCropResult={handleSetCropResult}
withBackButton={withBackButton}
/>
)}
<ModalFooter>
<section>
<Button type="button" color="cancel" onClick={handleToggle}>
{formatMessage({ id: 'app.components.Button.cancel' })}
</Button>
{currentStep === 'upload' && (
<Button type="button" color="success" onClick={handleUploadFiles}>
{formatMessage(
{
id: getTrad(
`modal.upload-list.footer.button.${
filesToUploadLength > 1 ? 'plural' : 'singular'
}`
),
},
{ number: filesToUploadLength }
)}
</Button>
)}
{currentStep === 'edit-new' && (
<Button color="success" type="button" onClick={handleSubmitEditNewFile}>
{formatMessage({ id: 'form.button.finish' })}
</Button>
)}
</section>
</ModalFooter>
</Modal>
);
};
ModalStepper.defaultProps = {
onToggle: () => {},
};
ModalStepper.propTypes = {
isOpen: PropTypes.bool.isRequired,
onToggle: PropTypes.func,
};
export default ModalStepper;