import React, { useEffect, useState, useRef, memo } from 'react'; import PropTypes from 'prop-types'; import { Modal, ModalFooter, PopUpWarning, useGlobalContext, request } from 'strapi-helper-plugin'; import { Button } from '@buffetjs/core'; import { getRequestUrl, getTrad } from '../../utils'; import ModalHeader from '../../components/ModalHeader'; import pluginId from '../../pluginId'; import stepper from './stepper'; import useModalContext from '../../hooks/useModalContext'; const InputModalStepper = ({ isOpen, onToggle, onInputMediaChange }) => { const { formatMessage } = useGlobalContext(); const [shouldDeleteFile, setShouldDeleteFile] = useState(false); const { addFilesToUpload, currentStep, fetchMediaLib, filesToUpload, fileToEdit, goTo, handleAbortUpload, handleCancelFileToUpload, handleCleanFilesError, handleClose, handleEditExistingFile, handleFileSelection, handleFileToEditChange, handleFormDisabled, handleGoToEditNewFile, handleRemoveFileToUpload, handleResetFileToEdit, handleSetCropResult, handleUploadFiles, isFormDisabled, isWarningDeleteOpen, multiple, selectedFiles, submitEditExistingFile, toggleModalWarning, } = useModalContext(); const { Component, components, headerBreadcrumbs, next, prev, withBackButton, HeaderComponent, } = stepper[currentStep]; const filesToUploadLength = filesToUpload.length; const editModalRef = useRef(); const handleReplaceMedia = () => { editModalRef.current.click(); }; useEffect(() => { if (currentStep === 'upload' && filesToUploadLength === 0) { // Go to the modal list view when file uploading is over goToList(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [filesToUploadLength, currentStep]); const goToList = () => { fetchMediaLib(); goTo('list'); }; const handleConfirmDeleteFile = () => { setShouldDeleteFile(true); toggleModalWarning(); }; const addFilesToUploadList = ({ target: { value } }) => { addFilesToUpload({ target: { value } }); goNext(); }; const handleClickDeleteFile = async () => { toggleModalWarning(); }; const handleClickDeleteFileToUpload = fileIndex => { handleRemoveFileToUpload(fileIndex); if (currentStep === 'edit-new') { handleResetFileToEdit(); goNext(); } }; const handleGoToAddBrowseFiles = () => { handleCleanFilesError(); goBack(); }; const handleSubmitEditNewFile = e => { e.preventDefault(); goNext(); }; const handleSubmit = e => { e.preventDefault(); onInputMediaChange(multiple ? selectedFiles : selectedFiles[0]); goNext(); }; const handleCloseModalWarning = async () => { if (shouldDeleteFile) { const { id } = fileToEdit; try { const requestURL = getRequestUrl(`files/${id}`); await request(requestURL, { method: 'DELETE' }); setShouldDeleteFile(false); // Remove file from selected files on delete and go back to the list. handleFileSelection({ target: { name: id } }); goToList(); } catch (err) { console.log(err); } } }; const handleSubmitEditExistingFile = async ( e, shouldDuplicateMedia = false, file = fileToEdit.file ) => { e.preventDefault(); submitEditExistingFile(); const headers = {}; const formData = new FormData(); // If the file has been cropped we need to add it to the formData // otherwise we just don't send it const didCropFile = file instanceof File; const { abortController, id, fileInfo } = fileToEdit; const requestURL = shouldDuplicateMedia ? `/${pluginId}` : `/${pluginId}?id=${id}`; if (didCropFile) { formData.append('files', file); } formData.append('fileInfo', JSON.stringify(fileInfo)); try { const editedFile = await request( requestURL, { method: 'POST', headers, body: formData, signal: abortController.signal, }, false, false ); handleEditExistingFile(editedFile); goToList(); } catch (err) { console.log(err); } }; const handleToggle = () => { if (filesToUploadLength > 0 || selectedFiles.length > 0) { // eslint-disable-next-line no-alert const confirm = window.confirm(formatMessage({ id: getTrad('window.confirm.close-modal') })); if (!confirm) { return; } } onToggle(); }; 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); }; return ( <> {/* header title */} {/* body of the modal */} {Component && ( )} {formatMessage({ id: 'app.components.Button.cancel' })} {currentStep === 'upload' && ( {formatMessage( { id: getTrad( `modal.upload-list.footer.button.${ filesToUploadLength > 1 ? 'plural' : 'singular' }` ), }, { number: filesToUploadLength } )} )} {currentStep === 'edit-new' && ( {formatMessage({ id: 'form.button.finish' })} )} {currentStep === 'edit' && ( Replace media {formatMessage({ id: 'form.button.finish' })} )} {currentStep === 'list' && ( {formatMessage({ id: 'form.button.finish' })} )} > ); }; InputModalStepper.defaultProps = { onToggle: () => {}, }; InputModalStepper.propTypes = { isOpen: PropTypes.bool.isRequired, onInputMediaChange: PropTypes.func.isRequired, onToggle: PropTypes.func, }; export default memo(InputModalStepper);