2020-03-09 16:49:12 +01:00
|
|
|
import React, { useReducer, useEffect } from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import { request, generateSearchFromFilters } from 'strapi-helper-plugin';
|
2020-03-23 16:24:26 +01:00
|
|
|
import { get } from 'lodash';
|
2020-03-26 10:57:31 +01:00
|
|
|
import pluginId from '../../pluginId';
|
2020-03-23 16:24:26 +01:00
|
|
|
import { getRequestUrl, compactParams } from '../../utils';
|
2020-03-09 16:49:12 +01:00
|
|
|
import InputModalStepperContext from '../../contexts/InputModal/InputModalDataManager';
|
2020-03-26 10:57:31 +01:00
|
|
|
import init from './init';
|
2020-03-09 16:49:12 +01:00
|
|
|
import reducer, { initialState } from './reducer';
|
|
|
|
|
2020-03-25 15:48:10 +01:00
|
|
|
const InputModalStepperProvider = ({
|
2020-03-25 17:55:06 +01:00
|
|
|
children,
|
|
|
|
initialFileToEdit,
|
2020-03-29 18:44:00 +02:00
|
|
|
initialFilters,
|
2020-03-25 15:48:10 +01:00
|
|
|
isOpen,
|
|
|
|
multiple,
|
|
|
|
onInputMediaChange,
|
|
|
|
selectedFiles,
|
2020-03-25 17:55:06 +01:00
|
|
|
step,
|
2020-03-25 15:48:10 +01:00
|
|
|
}) => {
|
|
|
|
const [reducerState, dispatch] = useReducer(reducer, initialState, state =>
|
|
|
|
init({
|
|
|
|
...state,
|
2020-03-25 17:55:06 +01:00
|
|
|
currentStep: step,
|
|
|
|
fileToEdit: initialFileToEdit,
|
2020-03-25 15:48:10 +01:00
|
|
|
selectedFiles: Array.isArray(selectedFiles) ? selectedFiles : [selectedFiles],
|
2020-03-29 18:44:00 +02:00
|
|
|
params: {
|
|
|
|
...state.params,
|
|
|
|
filters: initialFilters,
|
|
|
|
},
|
2020-03-25 15:48:10 +01:00
|
|
|
})
|
|
|
|
);
|
2020-03-25 17:55:06 +01:00
|
|
|
const { params, filesToUpload, fileToEdit } = reducerState;
|
2020-03-09 16:49:12 +01:00
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (isOpen) {
|
|
|
|
fetchMediaLib();
|
|
|
|
}
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
}, [isOpen, params]);
|
|
|
|
|
|
|
|
const handleRemoveFileToUpload = fileIndex => {
|
|
|
|
dispatch({
|
|
|
|
type: 'REMOVE_FILE_TO_UPLOAD',
|
|
|
|
fileIndex,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleFileToEditChange = ({ target: { name, value } }) => {
|
|
|
|
dispatch({
|
|
|
|
type: 'ON_CHANGE',
|
|
|
|
keys: name,
|
|
|
|
value,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-03-26 10:22:09 +01:00
|
|
|
const handleMoveAsset = (dragIndex, hoverIndex) => {
|
|
|
|
dispatch({
|
|
|
|
type: 'MOVE_ASSET',
|
|
|
|
dragIndex,
|
|
|
|
hoverIndex,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-03-25 17:55:06 +01:00
|
|
|
const toggleModalWarning = () => {
|
|
|
|
dispatch({
|
|
|
|
type: 'TOGGLE_MODAL_WARNING',
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const submitEditExistingFile = () => {
|
|
|
|
dispatch({
|
|
|
|
type: 'ON_SUBMIT_EDIT_EXISTING_FILE',
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleEditExistingFile = file => {
|
|
|
|
dispatch({
|
|
|
|
type: 'EDIT_EXISTING_FILE',
|
|
|
|
file,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-03-09 16:49:12 +01:00
|
|
|
const handleResetFileToEdit = () => {
|
|
|
|
dispatch({
|
|
|
|
type: 'RESET_FILE_TO_EDIT',
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const removeFilter = index => {
|
|
|
|
dispatch({
|
|
|
|
type: 'REMOVE_FILTER',
|
|
|
|
filterToRemove: index,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleClose = () => {
|
|
|
|
dispatch({
|
|
|
|
type: 'RESET_PROPS',
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-03-30 14:07:24 +02:00
|
|
|
const handleFileSelection = ({ target: { name } }) => {
|
2020-03-09 16:49:12 +01:00
|
|
|
dispatch({
|
|
|
|
type: 'ON_FILE_SELECTION',
|
2020-03-30 14:07:24 +02:00
|
|
|
id: name,
|
2020-03-09 16:49:12 +01:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-03-23 16:24:26 +01:00
|
|
|
const handleAllFilesSelection = () => {
|
2020-03-09 16:49:12 +01:00
|
|
|
dispatch({
|
|
|
|
type: 'TOGGLE_SELECT_ALL',
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const setParam = param => {
|
|
|
|
dispatch({
|
|
|
|
type: 'SET_PARAM',
|
|
|
|
param,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const goTo = to => {
|
|
|
|
dispatch({
|
|
|
|
type: 'GO_TO',
|
|
|
|
to,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleGoToEditNewFile = fileIndex => {
|
|
|
|
dispatch({
|
2020-03-25 17:55:06 +01:00
|
|
|
type: 'SET_NEW_FILE_TO_EDIT',
|
2020-03-09 16:49:12 +01:00
|
|
|
fileIndex,
|
|
|
|
});
|
|
|
|
|
|
|
|
goTo('edit-new');
|
|
|
|
};
|
|
|
|
|
2020-03-25 17:55:06 +01:00
|
|
|
const handleGoToEditFile = fileId => {
|
|
|
|
dispatch({
|
|
|
|
type: 'SET_FILE_TO_EDIT',
|
|
|
|
fileId,
|
|
|
|
});
|
|
|
|
|
|
|
|
goTo('edit');
|
|
|
|
};
|
|
|
|
|
2020-03-09 16:49:12 +01:00
|
|
|
const handleCleanFilesError = () => {
|
|
|
|
dispatch({
|
|
|
|
type: 'CLEAN_FILES_ERROR',
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleSetCropResult = blob => {
|
|
|
|
dispatch({
|
|
|
|
type: 'SET_CROP_RESULT',
|
|
|
|
blob,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-03-25 17:55:06 +01:00
|
|
|
const handleFormDisabled = isFormDisabled => {
|
|
|
|
dispatch({
|
|
|
|
type: 'SET_FORM_DISABLED',
|
|
|
|
isFormDisabled,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleAbortUpload = () => {
|
|
|
|
const { abortController } = fileToEdit;
|
|
|
|
|
|
|
|
abortController.abort();
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: 'ON_ABORT_UPLOAD',
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-03-09 16:49:12 +01:00
|
|
|
const handleCancelFileToUpload = fileIndex => {
|
|
|
|
const fileToCancel = get(filesToUpload, fileIndex, {});
|
|
|
|
|
|
|
|
// Cancel upload
|
|
|
|
fileToCancel.abortController.abort();
|
|
|
|
|
|
|
|
handleRemoveFileToUpload(fileIndex);
|
|
|
|
};
|
|
|
|
|
|
|
|
const fetchMediaLibFilesCount = async () => {
|
|
|
|
const requestURL = getRequestUrl('files/count');
|
|
|
|
|
|
|
|
try {
|
2020-03-23 16:24:26 +01:00
|
|
|
return await request(`${requestURL}`, {
|
2020-03-09 16:49:12 +01:00
|
|
|
method: 'GET',
|
|
|
|
});
|
|
|
|
} catch (err) {
|
|
|
|
strapi.notification.error('notification.error');
|
2020-03-23 16:24:26 +01:00
|
|
|
|
|
|
|
return err;
|
2020-03-09 16:49:12 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const fetchMediaLib = async () => {
|
2020-03-23 16:24:26 +01:00
|
|
|
const [files, count] = await Promise.all([fetchMediaLibFiles(), fetchMediaLibFilesCount()]);
|
|
|
|
dispatch({
|
|
|
|
type: 'GET_DATA_SUCCEEDED',
|
|
|
|
files,
|
|
|
|
countData: count,
|
|
|
|
});
|
2020-03-09 16:49:12 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const fetchMediaLibFiles = async () => {
|
|
|
|
const requestURL = getRequestUrl('files');
|
|
|
|
|
2020-03-23 16:24:26 +01:00
|
|
|
const compactedParams = compactParams(params);
|
|
|
|
const paramsToSend = generateSearchFromFilters(compactedParams);
|
2020-03-09 16:49:12 +01:00
|
|
|
|
|
|
|
try {
|
2020-03-23 16:24:26 +01:00
|
|
|
return await request(`${requestURL}?${paramsToSend}`, {
|
2020-03-09 16:49:12 +01:00
|
|
|
method: 'GET',
|
|
|
|
});
|
|
|
|
} catch (err) {
|
|
|
|
strapi.notification.error('notification.error');
|
2020-03-23 16:24:26 +01:00
|
|
|
|
|
|
|
return err;
|
2020-03-09 16:49:12 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const addFilesToUpload = ({ target: { value } }) => {
|
|
|
|
dispatch({
|
|
|
|
type: 'ADD_FILES_TO_UPLOAD',
|
|
|
|
filesToUpload: value,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
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 {
|
|
|
|
const data = await request(
|
|
|
|
`/${pluginId}`,
|
|
|
|
{
|
|
|
|
method: 'POST',
|
|
|
|
headers,
|
|
|
|
body: formData,
|
|
|
|
signal: abortController.signal,
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
false
|
|
|
|
);
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: 'REMOVE_FILE_TO_UPLOAD',
|
|
|
|
fileIndex: originalIndex,
|
|
|
|
addToSelectedFiles: data,
|
|
|
|
multiple,
|
|
|
|
});
|
|
|
|
} 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);
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<InputModalStepperContext.Provider
|
|
|
|
value={{
|
|
|
|
...reducerState,
|
2020-03-23 16:24:26 +01:00
|
|
|
addFilesToUpload,
|
2020-03-09 16:49:12 +01:00
|
|
|
fetchMediaLib,
|
|
|
|
goTo,
|
2020-03-25 17:55:06 +01:00
|
|
|
handleAbortUpload,
|
2020-03-23 16:24:26 +01:00
|
|
|
handleAllFilesSelection,
|
2020-03-09 16:49:12 +01:00
|
|
|
handleCancelFileToUpload,
|
|
|
|
handleCleanFilesError,
|
2020-03-23 16:24:26 +01:00
|
|
|
handleClose,
|
2020-03-25 17:55:06 +01:00
|
|
|
handleEditExistingFile,
|
2020-03-23 16:24:26 +01:00
|
|
|
handleFileSelection,
|
|
|
|
handleFileToEditChange,
|
2020-03-25 17:55:06 +01:00
|
|
|
handleFormDisabled,
|
|
|
|
handleGoToEditFile,
|
2020-03-09 16:49:12 +01:00
|
|
|
handleGoToEditNewFile,
|
|
|
|
handleRemoveFileToUpload,
|
2020-03-23 16:24:26 +01:00
|
|
|
handleResetFileToEdit,
|
|
|
|
handleSetCropResult,
|
|
|
|
handleUploadFiles,
|
2020-03-26 10:22:09 +01:00
|
|
|
moveAsset: handleMoveAsset,
|
2020-03-23 16:24:26 +01:00
|
|
|
multiple,
|
2020-03-24 00:11:16 +01:00
|
|
|
onInputMediaChange,
|
2020-03-23 16:24:26 +01:00
|
|
|
removeFilter,
|
|
|
|
setParam,
|
2020-03-25 17:55:06 +01:00
|
|
|
submitEditExistingFile,
|
|
|
|
toggleModalWarning,
|
2020-03-09 16:49:12 +01:00
|
|
|
}}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</InputModalStepperContext.Provider>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
InputModalStepperProvider.propTypes = {
|
|
|
|
children: PropTypes.node.isRequired,
|
2020-03-25 17:55:06 +01:00
|
|
|
initialFileToEdit: PropTypes.object,
|
2020-03-29 18:44:00 +02:00
|
|
|
initialFilters: PropTypes.arrayOf(PropTypes.object),
|
2020-03-23 16:24:26 +01:00
|
|
|
isOpen: PropTypes.bool,
|
2020-03-09 16:49:12 +01:00
|
|
|
multiple: PropTypes.bool.isRequired,
|
2020-03-24 00:11:16 +01:00
|
|
|
onInputMediaChange: PropTypes.func,
|
2020-03-25 15:48:10 +01:00
|
|
|
selectedFiles: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
2020-03-25 17:55:06 +01:00
|
|
|
step: PropTypes.string.isRequired,
|
2020-03-09 16:49:12 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
InputModalStepperProvider.defaultProps = {
|
2020-03-25 17:55:06 +01:00
|
|
|
initialFileToEdit: null,
|
2020-03-29 18:44:00 +02:00
|
|
|
initialFilters: [],
|
2020-03-09 16:49:12 +01:00
|
|
|
isOpen: false,
|
2020-03-24 00:11:16 +01:00
|
|
|
onInputMediaChange: () => {},
|
2020-03-25 15:48:10 +01:00
|
|
|
selectedFiles: null,
|
2020-03-09 16:49:12 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
export default InputModalStepperProvider;
|