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'; 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) { // Passing true to the onToggle prop will refetch the data when the modal closes toggleRef.current(true); } }, [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 ( {/* header title */} ({ key: headerTrad, element: , }))} withBackButton={withBackButton} /> {/* body of the modal */} {Component && ( )}
{currentStep === 'upload' && ( )} {currentStep === 'edit-new' && ( )}
); }; ModalStepper.defaultProps = { onToggle: () => {}, }; ModalStepper.propTypes = { isOpen: PropTypes.bool.isRequired, onToggle: PropTypes.func, }; export default ModalStepper;