mirror of
https://github.com/strapi/strapi.git
synced 2025-08-07 16:29:18 +00:00
Merge branch 'features/media-lib' of github.com:strapi/strapi into media-lib/wysiwyg
This commit is contained in:
commit
3553025d59
@ -15,6 +15,7 @@ import CardControl from '../CardControl';
|
||||
|
||||
const BrowseAssets = () => {
|
||||
const {
|
||||
allowedTypes,
|
||||
count,
|
||||
files,
|
||||
goTo,
|
||||
@ -136,6 +137,7 @@ const BrowseAssets = () => {
|
||||
onChange={handleFileSelection}
|
||||
selectedItems={selectedFiles}
|
||||
onCardClick={handleListCardClick}
|
||||
allowedTypes={allowedTypes}
|
||||
smallCards
|
||||
renderCardControl={renderCardControl}
|
||||
/>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { memo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { formatBytes, getExtension, getType } from '../../utils';
|
||||
import { useGlobalContext } from 'strapi-helper-plugin';
|
||||
import { formatBytes, getExtension, getType, getTrad } from '../../utils';
|
||||
|
||||
import Flex from '../Flex';
|
||||
import Text from '../Text';
|
||||
@ -15,6 +16,7 @@ import Wrapper from '../CardWrapper';
|
||||
|
||||
const Card = ({
|
||||
id,
|
||||
isDisabled,
|
||||
checked,
|
||||
children,
|
||||
errorMessage,
|
||||
@ -33,15 +35,21 @@ const Card = ({
|
||||
withFileCaching,
|
||||
withoutFileInfo,
|
||||
}) => {
|
||||
const { formatMessage } = useGlobalContext();
|
||||
const fileSize = formatBytes(size, 0);
|
||||
const fileType = mime || type;
|
||||
|
||||
const handleClick = () => {
|
||||
if (!isDisabled) {
|
||||
onClick(id);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Wrapper onClick={handleClick}>
|
||||
<Wrapper
|
||||
title={isDisabled ? formatMessage({ id: getTrad('list.assets.type-not-allowed') }) : null}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<CardImgWrapper checked={checked} small={small}>
|
||||
<CardPreview
|
||||
hasError={hasError}
|
||||
@ -84,6 +92,7 @@ Card.defaultProps = {
|
||||
children: null,
|
||||
errorMessage: null,
|
||||
id: null,
|
||||
isDisabled: false,
|
||||
hasError: false,
|
||||
hasIcon: false,
|
||||
height: null,
|
||||
@ -102,6 +111,7 @@ Card.defaultProps = {
|
||||
|
||||
Card.propTypes = {
|
||||
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
isDisabled: PropTypes.bool,
|
||||
checked: PropTypes.bool,
|
||||
children: PropTypes.node,
|
||||
errorMessage: PropTypes.string,
|
||||
|
@ -11,10 +11,12 @@ const Wrapper = styled.div`
|
||||
`;
|
||||
|
||||
Wrapper.defaultProps = {
|
||||
isDisabled: false,
|
||||
isDraggable: false,
|
||||
};
|
||||
|
||||
Wrapper.propTypes = {
|
||||
isDisabled: PropTypes.bool,
|
||||
isDraggable: PropTypes.bool,
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,7 @@ import Padded from '../Padded';
|
||||
const Filters = ({ onChange, onClick, filters }) => {
|
||||
return (
|
||||
<>
|
||||
<FiltersPicker filters={filters} onChange={onChange} />
|
||||
<FiltersPicker onChange={onChange} />
|
||||
<Padded left size="sm" />
|
||||
<FiltersList filters={filters} onClick={onClick} />
|
||||
</>
|
||||
|
@ -12,7 +12,7 @@ import InputWrapper from './InputWrapper';
|
||||
import FilterButton from './FilterButton';
|
||||
import FilterInput from './FilterInput';
|
||||
|
||||
const FiltersCard = ({ onChange, filters }) => {
|
||||
const FiltersCard = ({ onChange }) => {
|
||||
const { plugins } = useGlobalContext();
|
||||
const timestamps = getFileModelTimestamps(plugins);
|
||||
const [state, dispatch] = useReducer(reducer, initialState, () => init(initialState, timestamps));
|
||||
@ -20,9 +20,7 @@ const FiltersCard = ({ onChange, filters }) => {
|
||||
|
||||
const type = filtersForm[name].type;
|
||||
const filtersOptions = getFilterType(type);
|
||||
const options = ['image', 'video', 'file'].filter(
|
||||
f => !filters.find(e => e.value === f && e.isDisabled)
|
||||
);
|
||||
const options = ['image', 'video', 'file'];
|
||||
|
||||
const handleChange = ({ target: { name, value } }) => {
|
||||
dispatch({
|
||||
@ -89,12 +87,10 @@ const FiltersCard = ({ onChange, filters }) => {
|
||||
};
|
||||
|
||||
FiltersCard.defaultProps = {
|
||||
filters: [],
|
||||
onChange: () => {},
|
||||
};
|
||||
|
||||
FiltersCard.propTypes = {
|
||||
filters: PropTypes.arrayOf(PropTypes.object),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
|
@ -9,7 +9,7 @@ import Picker from '../Picker';
|
||||
|
||||
import formatFilter from './utils/formatFilter';
|
||||
|
||||
const FiltersPicker = ({ onChange, filters }) => {
|
||||
const FiltersPicker = ({ onChange }) => {
|
||||
const handleChange = ({ target: { value } }) => {
|
||||
onChange({ target: { name: 'filters', value: formatFilter(value) } });
|
||||
};
|
||||
@ -25,7 +25,6 @@ const FiltersPicker = ({ onChange, filters }) => {
|
||||
)}
|
||||
renderSectionContent={onToggle => (
|
||||
<FiltersCard
|
||||
filters={filters}
|
||||
onChange={e => {
|
||||
handleChange(e);
|
||||
onToggle();
|
||||
@ -38,12 +37,10 @@ const FiltersPicker = ({ onChange, filters }) => {
|
||||
};
|
||||
|
||||
FiltersPicker.defaultProps = {
|
||||
filters: [],
|
||||
onChange: () => {},
|
||||
};
|
||||
|
||||
FiltersPicker.propTypes = {
|
||||
filters: PropTypes.arrayOf(PropTypes.object),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import { Checkbox } from '@buffetjs/core';
|
||||
import { get } from 'lodash';
|
||||
import { prefixFileUrlWithBackendUrl } from 'strapi-helper-plugin';
|
||||
import { getTrad } from '../../utils';
|
||||
import { getTrad, getType } from '../../utils';
|
||||
import Card from '../Card';
|
||||
import CardControlsWrapper from '../CardControlsWrapper';
|
||||
import ListWrapper from '../ListWrapper';
|
||||
@ -12,6 +12,7 @@ import ListCell from './ListCell';
|
||||
import ListRow from './ListRow';
|
||||
|
||||
const List = ({
|
||||
allowedTypes,
|
||||
clickable,
|
||||
data,
|
||||
onChange,
|
||||
@ -23,7 +24,7 @@ const List = ({
|
||||
}) => {
|
||||
const selectedAssets = selectedItems.length;
|
||||
|
||||
const handleClick = e => {
|
||||
const handleCheckboxClick = e => {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
@ -40,12 +41,15 @@ const List = ({
|
||||
{data.map(item => {
|
||||
const { id } = item;
|
||||
const url = get(item, ['formats', 'thumbnail', 'url'], item.url);
|
||||
const isAllowed =
|
||||
allowedTypes.length > 0 ? allowedTypes.includes(getType(item.mime)) : true;
|
||||
const checked = selectedItems.findIndex(file => file.id === id) !== -1;
|
||||
const fileUrl = prefixFileUrlWithBackendUrl(url);
|
||||
|
||||
return (
|
||||
<ListCell key={id}>
|
||||
<Card
|
||||
isDisabled={!isAllowed}
|
||||
checked={checked}
|
||||
{...item}
|
||||
hasIcon={clickable}
|
||||
@ -55,14 +59,16 @@ const List = ({
|
||||
>
|
||||
{(checked || canSelect) && (
|
||||
<>
|
||||
{isAllowed && (
|
||||
<CardControlsWrapper leftAlign className="card-control-wrapper">
|
||||
<Checkbox
|
||||
name={`${id}`}
|
||||
onChange={onChange}
|
||||
onClick={handleClick}
|
||||
onClick={handleCheckboxClick}
|
||||
value={checked}
|
||||
/>
|
||||
</CardControlsWrapper>
|
||||
)}
|
||||
{renderCardControl && (
|
||||
<CardControlsWrapper className="card-control-wrapper">
|
||||
{renderCardControl(id)}
|
||||
@ -80,6 +86,7 @@ const List = ({
|
||||
};
|
||||
|
||||
List.defaultProps = {
|
||||
allowedTypes: [],
|
||||
clickable: false,
|
||||
canSelect: true,
|
||||
data: [],
|
||||
@ -91,6 +98,7 @@ List.defaultProps = {
|
||||
};
|
||||
|
||||
List.propTypes = {
|
||||
allowedTypes: PropTypes.array,
|
||||
clickable: PropTypes.bool,
|
||||
canSelect: PropTypes.bool,
|
||||
data: PropTypes.array,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useReducer, useState, useRef, useEffect } from 'react';
|
||||
import { includes, isEmpty, toString } from 'lodash';
|
||||
import { includes, isEmpty, toString, isEqual, intersectionWith } from 'lodash';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { Header } from '@buffetjs/custom';
|
||||
import { useDebounce } from '@buffetjs/hooks';
|
||||
@ -183,10 +183,16 @@ const HomePage = () => {
|
||||
let updatedQueryParams = generateNewSearch({ [name]: value });
|
||||
|
||||
if (name === 'filters') {
|
||||
const filters = [...generateFiltersFromSearch(search), value];
|
||||
const existingFilters = generateFiltersFromSearch(search);
|
||||
const canAddFilter = intersectionWith(existingFilters, [value], isEqual).length === 0;
|
||||
updatedQueryParams = generateNewSearch({ [name]: existingFilters });
|
||||
|
||||
if (canAddFilter) {
|
||||
const filters = [...existingFilters, value];
|
||||
|
||||
updatedQueryParams = generateNewSearch({ [name]: filters });
|
||||
}
|
||||
}
|
||||
|
||||
if (name === '_limit') {
|
||||
updatedQueryParams = generateNewSearch({ [name]: value, _start: 0 });
|
||||
|
@ -20,13 +20,6 @@ const InputModal = ({
|
||||
step,
|
||||
}) => {
|
||||
const singularTypes = allowedTypes.map(type => type.substring(0, type.length - 1));
|
||||
const typesToDisable = ['video', 'image', 'file'].filter(f => !singularTypes.includes(f));
|
||||
const nContainsFilters = typesToDisable.map(type => ({
|
||||
name: 'mime',
|
||||
filter: '_ncontains',
|
||||
value: type,
|
||||
isDisabled: true,
|
||||
}));
|
||||
|
||||
return (
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
@ -35,7 +28,6 @@ const InputModal = ({
|
||||
onClosed={onClosed}
|
||||
initialFilesToUpload={filesToUpload}
|
||||
initialFileToEdit={fileToEdit}
|
||||
initialFilters={nContainsFilters}
|
||||
isOpen={isOpen}
|
||||
multiple={multiple}
|
||||
noNavigation={noNavigation}
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
createNewFilesToUploadArray,
|
||||
urlSchema,
|
||||
getFileModelTimestamps,
|
||||
formatFilters,
|
||||
} from '../../utils';
|
||||
import InputModalStepperContext from '../../contexts/InputModal/InputModalDataManager';
|
||||
import init from './init';
|
||||
@ -24,7 +25,6 @@ const InputModalStepperProvider = ({
|
||||
children,
|
||||
initialFilesToUpload,
|
||||
initialFileToEdit,
|
||||
initialFilters,
|
||||
isOpen,
|
||||
multiple,
|
||||
noNavigation,
|
||||
@ -39,6 +39,7 @@ const InputModalStepperProvider = ({
|
||||
const [reducerState, dispatch] = useReducer(reducer, initialState, state =>
|
||||
init({
|
||||
...state,
|
||||
allowedTypes,
|
||||
currentStep: step,
|
||||
fileToEdit: initialFileToEdit,
|
||||
selectedFiles: Array.isArray(selectedFiles) ? selectedFiles : [selectedFiles],
|
||||
@ -50,7 +51,6 @@ const InputModalStepperProvider = ({
|
||||
: [],
|
||||
params: {
|
||||
...state.params,
|
||||
filters: initialFilters,
|
||||
_sort: `${updated_at}:DESC`,
|
||||
},
|
||||
})
|
||||
@ -294,10 +294,16 @@ const InputModalStepperProvider = ({
|
||||
handleRemoveFileToUpload(fileIndex);
|
||||
};
|
||||
|
||||
const getFilters = () => {
|
||||
const compactedParams = compactParams(params);
|
||||
const searchParams = generateSearchFromFilters(compactedParams, ['_limit', '_sort', '_start']);
|
||||
|
||||
return formatFilters(searchParams);
|
||||
};
|
||||
|
||||
const fetchMediaLibFilesCount = async () => {
|
||||
const requestURL = getRequestUrl('files/count');
|
||||
const compactedParams = compactParams(params);
|
||||
const paramsToSend = generateSearchFromFilters(compactedParams, ['_limit', '_sort', '_start']);
|
||||
const paramsToSend = getFilters();
|
||||
|
||||
try {
|
||||
return await request(`${requestURL}?${paramsToSend}`, {
|
||||
@ -322,8 +328,7 @@ const InputModalStepperProvider = ({
|
||||
|
||||
const fetchMediaLibFiles = async () => {
|
||||
const requestURL = getRequestUrl('files');
|
||||
const compactedParams = compactParams(params);
|
||||
const paramsToSend = generateSearchFromFilters(compactedParams);
|
||||
const paramsToSend = getFilters();
|
||||
|
||||
try {
|
||||
return await request(`${requestURL}?${paramsToSend}`, {
|
||||
@ -474,7 +479,6 @@ InputModalStepperProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
initialFilesToUpload: PropTypes.object,
|
||||
initialFileToEdit: PropTypes.object,
|
||||
initialFilters: PropTypes.arrayOf(PropTypes.object),
|
||||
isOpen: PropTypes.bool,
|
||||
multiple: PropTypes.bool.isRequired,
|
||||
noNavigation: PropTypes.bool,
|
||||
@ -486,7 +490,6 @@ InputModalStepperProvider.propTypes = {
|
||||
|
||||
InputModalStepperProvider.defaultProps = {
|
||||
initialFileToEdit: null,
|
||||
initialFilters: [],
|
||||
initialFilesToUpload: null,
|
||||
isOpen: false,
|
||||
noNavigation: false,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import produce from 'immer';
|
||||
import { intersectionWith, differenceWith, unionWith, set } from 'lodash';
|
||||
import { intersectionWith, differenceWith, unionWith, set, isEqual } from 'lodash';
|
||||
|
||||
import {
|
||||
createNewFilesToDownloadArray,
|
||||
@ -30,6 +30,17 @@ const reducer = (state, action) =>
|
||||
// eslint-disable-next-line consistent-return
|
||||
produce(state, draftState => {
|
||||
switch (action.type) {
|
||||
case 'ADD_FILES_TO_UPLOAD': {
|
||||
draftState.filesToUpload = [
|
||||
...draftState.filesToUpload,
|
||||
...createNewFilesToUploadArray(action.filesToUpload),
|
||||
].map((fileToUpload, index) => ({
|
||||
...fileToUpload,
|
||||
originalIndex: index,
|
||||
}));
|
||||
draftState.currentStep = action.nextStep;
|
||||
break;
|
||||
}
|
||||
case 'ADD_URLS_TO_FILES_TO_UPLOAD': {
|
||||
draftState.filesToUpload = [
|
||||
...draftState.filesToUpload,
|
||||
@ -43,12 +54,32 @@ const reducer = (state, action) =>
|
||||
|
||||
break;
|
||||
}
|
||||
case 'CLEAN_FILES_ERROR': {
|
||||
draftState.filesToUpload.forEach((fileToUpload, index) => {
|
||||
draftState.filesToUpload[index] = {
|
||||
...fileToUpload,
|
||||
hasError: false,
|
||||
errorMessage: null,
|
||||
};
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'CLEAR_FILES_TO_UPLOAD_AND_DOWNLOAD': {
|
||||
draftState.filesToUpload = [];
|
||||
draftState.filesToDownload = [];
|
||||
|
||||
break;
|
||||
}
|
||||
case 'EDIT_EXISTING_FILE': {
|
||||
const index = draftState.selectedFiles.findIndex(
|
||||
selectedFile => selectedFile.id === action.file.id
|
||||
);
|
||||
|
||||
if (index !== -1) {
|
||||
draftState.selectedFiles[index] = action.file;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'FILE_DOWNLOADED': {
|
||||
const index = state.filesToUpload.findIndex(file => file.tempId === action.fileTempId);
|
||||
|
||||
@ -60,32 +91,13 @@ const reducer = (state, action) =>
|
||||
|
||||
break;
|
||||
}
|
||||
case 'ON_CHANGE': {
|
||||
set(draftState.fileToEdit, action.keys.split('.'), action.value);
|
||||
break;
|
||||
}
|
||||
case 'ON_CHANGE_URLS_TO_DOWNLOAD': {
|
||||
set(draftState, ['filesToDownload'], action.value);
|
||||
break;
|
||||
}
|
||||
case 'GET_DATA_SUCCEEDED': {
|
||||
draftState.files = action.files;
|
||||
draftState.count = action.countData.count;
|
||||
break;
|
||||
}
|
||||
case 'SET_PARAM': {
|
||||
const { name, value } = action.param;
|
||||
|
||||
if (name === 'filters') {
|
||||
draftState.params.filters.push(value);
|
||||
break;
|
||||
}
|
||||
|
||||
if (name === '_limit') {
|
||||
draftState.params._start = 0;
|
||||
}
|
||||
|
||||
draftState.params[name] = value;
|
||||
case 'GO_TO': {
|
||||
draftState.currentStep = action.to;
|
||||
break;
|
||||
}
|
||||
case 'MOVE_ASSET': {
|
||||
@ -97,6 +109,18 @@ const reducer = (state, action) =>
|
||||
|
||||
break;
|
||||
}
|
||||
case 'ON_ABORT_UPLOAD': {
|
||||
draftState.fileToEdit.isUploading = false;
|
||||
break;
|
||||
}
|
||||
case 'ON_CHANGE': {
|
||||
set(draftState.fileToEdit, action.keys.split('.'), action.value);
|
||||
break;
|
||||
}
|
||||
case 'ON_CHANGE_URLS_TO_DOWNLOAD': {
|
||||
set(draftState, ['filesToDownload'], action.value);
|
||||
break;
|
||||
}
|
||||
case 'ON_FILE_SELECTION': {
|
||||
const { id } = action;
|
||||
const stringId = id.toString();
|
||||
@ -111,71 +135,8 @@ const reducer = (state, action) =>
|
||||
draftState.selectedFiles.push(fileToStore);
|
||||
break;
|
||||
}
|
||||
case 'TOGGLE_SELECT_ALL': {
|
||||
const comparator = (first, second) => first.id === second.id;
|
||||
const isSelected =
|
||||
intersectionWith(state.selectedFiles, state.files, comparator).length ===
|
||||
state.files.length;
|
||||
|
||||
if (isSelected) {
|
||||
draftState.selectedFiles = differenceWith(state.selectedFiles, state.files, comparator);
|
||||
break;
|
||||
}
|
||||
|
||||
draftState.selectedFiles = unionWith(state.selectedFiles, state.files, comparator);
|
||||
break;
|
||||
}
|
||||
case 'SET_FILE_ERROR': {
|
||||
draftState.filesToUpload.forEach((fileToUpload, index) => {
|
||||
if (fileToUpload.originalIndex === action.fileIndex) {
|
||||
draftState.filesToUpload[index] = {
|
||||
...draftState.filesToUpload[index],
|
||||
isUploading: false,
|
||||
hasError: true,
|
||||
errorMessage: action.errorMessage,
|
||||
};
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'REMOVE_FILTER': {
|
||||
const { filterToRemove } = action;
|
||||
|
||||
draftState.params.filters.splice(filterToRemove, 1);
|
||||
break;
|
||||
}
|
||||
case 'GO_TO': {
|
||||
draftState.currentStep = action.to;
|
||||
break;
|
||||
}
|
||||
case 'RESET_PROPS': {
|
||||
if (action.defaultSort) {
|
||||
draftState.params._sort = action.defaultSort;
|
||||
} else {
|
||||
return initialState;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'SET_FILES_UPLOADING_STATE': {
|
||||
draftState.filesToUpload.forEach((fileToUpload, index) => {
|
||||
draftState.filesToUpload[index] = {
|
||||
...fileToUpload,
|
||||
isUploading: true,
|
||||
hasError: false,
|
||||
errorMessage: null,
|
||||
};
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'ADD_FILES_TO_UPLOAD': {
|
||||
draftState.filesToUpload = [
|
||||
...draftState.filesToUpload,
|
||||
...createNewFilesToUploadArray(action.filesToUpload),
|
||||
].map((fileToUpload, index) => ({
|
||||
...fileToUpload,
|
||||
originalIndex: index,
|
||||
}));
|
||||
draftState.currentStep = action.nextStep;
|
||||
case 'ON_SUBMIT_EDIT_EXISTING_FILE': {
|
||||
draftState.fileToEdit.isUploading = true;
|
||||
break;
|
||||
}
|
||||
case 'REMOVE_FILE_TO_UPLOAD': {
|
||||
@ -195,30 +156,37 @@ const reducer = (state, action) =>
|
||||
draftState.filesToUpload.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
case 'REMOVE_FILTER': {
|
||||
const { filterToRemove } = action;
|
||||
|
||||
draftState.params.filters.splice(filterToRemove, 1);
|
||||
break;
|
||||
}
|
||||
case 'RESET_PROPS': {
|
||||
if (action.defaultSort) {
|
||||
draftState.params._sort = action.defaultSort;
|
||||
} else {
|
||||
return initialState;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'SET_CROP_RESULT': {
|
||||
draftState.fileToEdit.file = action.blob;
|
||||
break;
|
||||
}
|
||||
case 'CLEAN_FILES_ERROR': {
|
||||
case 'SET_FILE_ERROR': {
|
||||
draftState.filesToUpload.forEach((fileToUpload, index) => {
|
||||
if (fileToUpload.originalIndex === action.fileIndex) {
|
||||
draftState.filesToUpload[index] = {
|
||||
...fileToUpload,
|
||||
hasError: false,
|
||||
errorMessage: null,
|
||||
...draftState.filesToUpload[index],
|
||||
isUploading: false,
|
||||
hasError: true,
|
||||
errorMessage: action.errorMessage,
|
||||
};
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'SET_NEW_FILE_TO_EDIT': {
|
||||
draftState.fileToEdit = draftState.filesToUpload[action.fileIndex];
|
||||
break;
|
||||
}
|
||||
case 'SET_FILE_TO_EDIT': {
|
||||
draftState.fileToEdit = formatFileForEditing(
|
||||
state.files.find(file => file.id.toString() === action.fileId.toString())
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'SET_FILE_TO_DOWNLOAD_ERROR': {
|
||||
const index = state.filesToUpload.findIndex(file => file.tempId === action.fileTempId);
|
||||
|
||||
@ -231,20 +199,10 @@ const reducer = (state, action) =>
|
||||
|
||||
break;
|
||||
}
|
||||
case 'SET_FORM_DISABLED': {
|
||||
draftState.isFormDisabled = action.isFormDisabled;
|
||||
break;
|
||||
}
|
||||
case 'ON_ABORT_UPLOAD': {
|
||||
draftState.fileToEdit.isUploading = false;
|
||||
break;
|
||||
}
|
||||
case 'TOGGLE_MODAL_WARNING': {
|
||||
draftState.isWarningDeleteOpen = !state.isWarningDeleteOpen;
|
||||
break;
|
||||
}
|
||||
case 'ON_SUBMIT_EDIT_EXISTING_FILE': {
|
||||
draftState.fileToEdit.isUploading = true;
|
||||
case 'SET_FILE_TO_EDIT': {
|
||||
draftState.fileToEdit = formatFileForEditing(
|
||||
state.files.find(file => file.id.toString() === action.fileId.toString())
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'SET_FILE_TO_EDIT_ERROR': {
|
||||
@ -253,14 +211,61 @@ const reducer = (state, action) =>
|
||||
draftState.fileToEdit.errorMessage = action.errorMessage;
|
||||
break;
|
||||
}
|
||||
case 'EDIT_EXISTING_FILE': {
|
||||
const index = draftState.selectedFiles.findIndex(
|
||||
selectedFile => selectedFile.id === action.file.id
|
||||
);
|
||||
|
||||
if (index !== -1) {
|
||||
draftState.selectedFiles[index] = action.file;
|
||||
case 'SET_FILES_UPLOADING_STATE': {
|
||||
draftState.filesToUpload.forEach((fileToUpload, index) => {
|
||||
draftState.filesToUpload[index] = {
|
||||
...fileToUpload,
|
||||
isUploading: true,
|
||||
hasError: false,
|
||||
errorMessage: null,
|
||||
};
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'SET_FORM_DISABLED': {
|
||||
draftState.isFormDisabled = action.isFormDisabled;
|
||||
break;
|
||||
}
|
||||
case 'SET_NEW_FILE_TO_EDIT': {
|
||||
draftState.fileToEdit = draftState.filesToUpload[action.fileIndex];
|
||||
break;
|
||||
}
|
||||
case 'SET_PARAM': {
|
||||
const { name, value } = action.param;
|
||||
|
||||
if (name === 'filters') {
|
||||
const canAddFilter =
|
||||
intersectionWith(state.params.filters, [value], isEqual).length === 0;
|
||||
|
||||
if (canAddFilter) {
|
||||
draftState.params.filters.push(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (name === '_limit') {
|
||||
draftState.params._start = 0;
|
||||
}
|
||||
|
||||
draftState.params[name] = value;
|
||||
break;
|
||||
}
|
||||
case 'TOGGLE_MODAL_WARNING': {
|
||||
draftState.isWarningDeleteOpen = !state.isWarningDeleteOpen;
|
||||
break;
|
||||
}
|
||||
case 'TOGGLE_SELECT_ALL': {
|
||||
const comparator = (first, second) => first.id === second.id;
|
||||
const isSelected =
|
||||
intersectionWith(state.selectedFiles, state.files, comparator).length ===
|
||||
state.files.length;
|
||||
|
||||
if (isSelected) {
|
||||
draftState.selectedFiles = differenceWith(state.selectedFiles, state.files, comparator);
|
||||
break;
|
||||
}
|
||||
|
||||
draftState.selectedFiles = unionWith(state.selectedFiles, state.files, comparator);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1933,4 +1933,105 @@ describe('UPLOAD | containers | ModalStepper | reducer', () => {
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SET_PARAM', () => {
|
||||
it('should set the _start param to 0 if the pagination limit changed', () => {
|
||||
const action = {
|
||||
type: 'SET_PARAM',
|
||||
param: {
|
||||
name: '_limit',
|
||||
value: 50,
|
||||
},
|
||||
};
|
||||
const state = {
|
||||
params: {
|
||||
_start: 10,
|
||||
},
|
||||
};
|
||||
const expected = {
|
||||
params: {
|
||||
_start: 0,
|
||||
_limit: 50,
|
||||
},
|
||||
};
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should add filter to params', () => {
|
||||
const action = {
|
||||
type: 'SET_PARAM',
|
||||
param: {
|
||||
name: 'filters',
|
||||
value: {
|
||||
name: 'mime',
|
||||
filter: '_contains',
|
||||
value: 'image',
|
||||
},
|
||||
},
|
||||
};
|
||||
const state = {
|
||||
params: {
|
||||
_start: 0,
|
||||
filters: [],
|
||||
},
|
||||
};
|
||||
const expected = {
|
||||
params: {
|
||||
_start: 0,
|
||||
filters: [
|
||||
{
|
||||
name: 'mime',
|
||||
filter: '_contains',
|
||||
value: 'image',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should not add filter to params if it is already exist', () => {
|
||||
const action = {
|
||||
type: 'SET_PARAM',
|
||||
param: {
|
||||
name: 'filters',
|
||||
value: {
|
||||
name: 'mime',
|
||||
filter: '_contains',
|
||||
value: 'image',
|
||||
},
|
||||
},
|
||||
};
|
||||
const state = {
|
||||
params: {
|
||||
_start: 0,
|
||||
_limit: 50,
|
||||
filters: [
|
||||
{
|
||||
name: 'mime',
|
||||
filter: '_contains',
|
||||
value: 'image',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const expected = {
|
||||
params: {
|
||||
_start: 0,
|
||||
_limit: 50,
|
||||
filters: [
|
||||
{
|
||||
name: 'mime',
|
||||
filter: '_contains',
|
||||
value: 'image',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -30,6 +30,7 @@
|
||||
"list.assets-empty.title": "There is no asset yet",
|
||||
"list.assets-empty.title-withSearch": "There is no asset with the applied filters",
|
||||
"list.assets-empty.subtitle": "Add a first one to the list.",
|
||||
"list.assets.type-not-allowed": "This type of file is not allowed.",
|
||||
"list.assets.selected.plural": "{number} assets selected",
|
||||
"list.assets.selected.singular": "{number} asset selected",
|
||||
"modal.header.browse": "Upload assets",
|
||||
|
@ -0,0 +1,23 @@
|
||||
const formatFilters = params => {
|
||||
const indexOfFileFilterContains = params.indexOf('mime_contains=file');
|
||||
const indexOfFileFilterNContains = params.indexOf('mime_ncontains=file');
|
||||
let paramsToReturn = params;
|
||||
|
||||
if (indexOfFileFilterContains !== -1) {
|
||||
paramsToReturn = paramsToReturn.replace(
|
||||
'mime_contains=file',
|
||||
'mime_ncontains=image&mime_ncontains=video'
|
||||
);
|
||||
}
|
||||
|
||||
if (indexOfFileFilterNContains !== -1) {
|
||||
paramsToReturn = paramsToReturn.replace(
|
||||
'mime_ncontains=file',
|
||||
'mime_contains=image&mime_contains=video'
|
||||
);
|
||||
}
|
||||
|
||||
return paramsToReturn;
|
||||
};
|
||||
|
||||
export default formatFilters;
|
@ -6,6 +6,7 @@ export { default as createNewFilesToDownloadArray } from './createNewFilesToDown
|
||||
export { default as createNewFilesToUploadArray } from './createNewFilesToUploadArray';
|
||||
export { default as formatBytes } from './formatBytes';
|
||||
export { default as formatFileForEditing } from './formatFileForEditing';
|
||||
export { default as formatFilters } from './formatFilters';
|
||||
export { default as generatePageFromStart } from './generatePageFromStart';
|
||||
export { default as generateStartFromPage } from './generateStartFromPage';
|
||||
export { default as getExtension } from './getExtension';
|
||||
|
@ -0,0 +1,21 @@
|
||||
import formatFilters from '../formatFilters';
|
||||
|
||||
describe('UPLOAD | utils | formatFilters', () => {
|
||||
it('should remove the file filter and add image and video filters', () => {
|
||||
const stringParams = '&mime_ncontains=file&mime_contains=file';
|
||||
|
||||
const actual = formatFilters(stringParams);
|
||||
const expected =
|
||||
'&mime_contains=image&mime_contains=video&mime_ncontains=image&mime_ncontains=video';
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return the string params if there is no file filter', () => {
|
||||
const stringParams = '&mime_contains=image&mime_contains=video';
|
||||
|
||||
const actual = formatFilters(stringParams);
|
||||
const expected = '&mime_contains=image&mime_contains=video';
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user