mirror of
https://github.com/strapi/strapi.git
synced 2025-09-21 14:31:16 +00:00
356 lines
9.6 KiB
JavaScript
356 lines
9.6 KiB
JavaScript
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 { isEmpty } from 'lodash';
|
|
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 [displayNextButton, setDisplayNextButton] = useState(false);
|
|
const {
|
|
addFilesToUpload,
|
|
currentStep,
|
|
downloadFiles,
|
|
fetchMediaLib,
|
|
filesToDownload,
|
|
filesToUpload,
|
|
fileToEdit,
|
|
formErrors,
|
|
goTo,
|
|
handleAbortUpload,
|
|
handleCancelFileToUpload,
|
|
handleCleanFilesError,
|
|
handleClickNextButton,
|
|
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') {
|
|
// Go to the modal list view when file uploading is over
|
|
|
|
if (filesToUploadLength === 0) {
|
|
goToList();
|
|
} else {
|
|
downloadFiles();
|
|
}
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [filesToUploadLength, currentStep]);
|
|
|
|
const addFilesToUploadList = ({ target: { value } }) => {
|
|
addFilesToUpload({ target: { value } });
|
|
|
|
goNext();
|
|
};
|
|
|
|
const goBack = () => {
|
|
goTo(prev);
|
|
};
|
|
|
|
const goNext = () => {
|
|
if (next === null) {
|
|
onToggle();
|
|
|
|
return;
|
|
}
|
|
|
|
goTo(next);
|
|
};
|
|
|
|
const goToList = () => {
|
|
fetchMediaLib();
|
|
goTo('list');
|
|
};
|
|
|
|
const handleClickDeleteFile = async () => {
|
|
toggleModalWarning();
|
|
};
|
|
|
|
const handleClickDeleteFileToUpload = fileIndex => {
|
|
handleRemoveFileToUpload(fileIndex);
|
|
|
|
if (currentStep === 'edit-new') {
|
|
handleResetFileToEdit();
|
|
|
|
goNext();
|
|
}
|
|
};
|
|
|
|
const handleCloseModal = () => {
|
|
setDisplayNextButton(false);
|
|
handleClose();
|
|
};
|
|
|
|
const handleConfirmDeleteFile = () => {
|
|
setShouldDeleteFile(true);
|
|
toggleModalWarning();
|
|
};
|
|
|
|
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.files') })
|
|
);
|
|
|
|
if (!confirm) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
onToggle(true);
|
|
};
|
|
|
|
const shouldDisplayNextButton = currentStep === 'browse' && displayNextButton;
|
|
const isFinishButtonDisabled = filesToUpload.some(file => file.isDownloading);
|
|
|
|
return (
|
|
<>
|
|
<Modal isOpen={isOpen} onToggle={handleToggle} onClosed={handleCloseModal}>
|
|
{/* header title */}
|
|
<ModalHeader
|
|
goBack={goBack}
|
|
HeaderComponent={HeaderComponent}
|
|
headerBreadcrumbs={headerBreadcrumbs}
|
|
withBackButton={withBackButton}
|
|
/>
|
|
{/* body of the modal */}
|
|
{Component && (
|
|
<Component
|
|
addFilesToUpload={addFilesToUploadList}
|
|
components={components}
|
|
filesToDownload={filesToDownload}
|
|
filesToUpload={filesToUpload}
|
|
fileToEdit={fileToEdit}
|
|
formErrors={formErrors}
|
|
isEditingUploadedFile={currentStep === 'edit'}
|
|
isFormDisabled={isFormDisabled}
|
|
onAbortUpload={handleAbortUpload}
|
|
onChange={handleFileToEditChange}
|
|
onClickCancelUpload={handleCancelFileToUpload}
|
|
onClickDeleteFileToUpload={
|
|
currentStep === 'edit' ? handleClickDeleteFile : handleClickDeleteFileToUpload
|
|
}
|
|
onSubmitEdit={
|
|
currentStep === 'edit' ? handleSubmitEditExistingFile : handleSubmitEditNewFile
|
|
}
|
|
onClickEditNewFile={handleGoToEditNewFile}
|
|
onGoToAddBrowseFiles={handleGoToAddBrowseFiles}
|
|
onSubmitEditNewFile={handleSubmitEditNewFile}
|
|
ref={currentStep === 'edit' ? editModalRef : null}
|
|
toggleDisableForm={handleFormDisabled}
|
|
onToggle={handleToggle}
|
|
setCropResult={handleSetCropResult}
|
|
setShouldDisplayNextButton={setDisplayNextButton}
|
|
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}
|
|
disabled={isFinishButtonDisabled}
|
|
>
|
|
{formatMessage(
|
|
{
|
|
id: getTrad(
|
|
`modal.upload-list.footer.button.${
|
|
filesToUploadLength > 1 ? 'plural' : 'singular'
|
|
}`
|
|
),
|
|
},
|
|
{ number: filesToUploadLength }
|
|
)}
|
|
</Button>
|
|
)}
|
|
{shouldDisplayNextButton && (
|
|
<Button
|
|
type="button"
|
|
color="primary"
|
|
onClick={handleClickNextButton}
|
|
disabled={isEmpty(filesToDownload)}
|
|
>
|
|
{formatMessage({ id: getTrad('button.next') })}
|
|
</Button>
|
|
)}
|
|
{currentStep === 'edit-new' && (
|
|
<Button color="success" type="button" onClick={handleSubmitEditNewFile}>
|
|
{formatMessage({ id: 'form.button.finish' })}
|
|
</Button>
|
|
)}
|
|
{currentStep === 'edit' && (
|
|
<div style={{ margin: 'auto 0' }}>
|
|
<Button
|
|
disabled={isFormDisabled}
|
|
color="primary"
|
|
onClick={handleReplaceMedia}
|
|
style={{ marginRight: 10 }}
|
|
>
|
|
Replace media
|
|
</Button>
|
|
|
|
<Button
|
|
disabled={isFormDisabled}
|
|
color="success"
|
|
type="button"
|
|
onClick={handleSubmitEditExistingFile}
|
|
>
|
|
{formatMessage({ id: 'form.button.finish' })}
|
|
</Button>
|
|
</div>
|
|
)}
|
|
{currentStep === 'list' && (
|
|
<Button color="success" type="button" onClick={handleSubmit}>
|
|
{formatMessage({ id: 'form.button.finish' })}
|
|
</Button>
|
|
)}
|
|
</section>
|
|
</ModalFooter>
|
|
</Modal>
|
|
<PopUpWarning
|
|
onClosed={handleCloseModalWarning}
|
|
isOpen={isWarningDeleteOpen}
|
|
toggleModal={toggleModalWarning}
|
|
popUpWarningType="danger"
|
|
onConfirm={handleConfirmDeleteFile}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
InputModalStepper.defaultProps = {
|
|
onToggle: () => {},
|
|
};
|
|
|
|
InputModalStepper.propTypes = {
|
|
isOpen: PropTypes.bool.isRequired,
|
|
onInputMediaChange: PropTypes.func.isRequired,
|
|
onToggle: PropTypes.func,
|
|
};
|
|
|
|
export default memo(InputModalStepper);
|