mirror of
https://github.com/strapi/strapi.git
synced 2025-12-05 03:21:22 +00:00
Merge pull request #5975 from strapi/front/media-lib-loader
Media lib listView loadingBar and loadingIndicator
This commit is contained in:
commit
8194a255d8
@ -41,18 +41,13 @@ class Notification extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const options =
|
||||
this.options[this.props.notification.status] || this.options.info;
|
||||
const options = this.options[this.props.notification.status] || this.options.info;
|
||||
const {
|
||||
notification: { message },
|
||||
} = this.props;
|
||||
const content =
|
||||
isObject(message) && message.id ? (
|
||||
<FormattedMessage
|
||||
id={message.id}
|
||||
defaultMessage={message.id}
|
||||
values={message.values}
|
||||
/>
|
||||
<FormattedMessage id={message.id} defaultMessage={message.id} values={message.values} />
|
||||
) : (
|
||||
<FormattedMessage id={message} defaultMessage={message} />
|
||||
);
|
||||
|
||||
@ -31,11 +31,7 @@ function StaticLinks() {
|
||||
|
||||
return (
|
||||
<li key={label}>
|
||||
<StyledLink
|
||||
href={destination}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<StyledLink href={destination} target="_blank" rel="noopener noreferrer">
|
||||
<FontAwesomeIcon icon={icon} />
|
||||
<FormattedMessage id={`app.components.LeftMenuFooter.${label}`} />
|
||||
</StyledLink>
|
||||
|
||||
@ -402,7 +402,6 @@ exports[`Admin | containers | EditView should match the snapshot 1`] = `
|
||||
font-size: 2.4rem;
|
||||
line-height: normal;
|
||||
font-weight: 600;
|
||||
text-transform: capitalize;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
@ -151,7 +151,6 @@ exports[`Admin | containers | ListView should match the snapshot 1`] = `
|
||||
font-size: 2.4rem;
|
||||
line-height: normal;
|
||||
font-weight: 600;
|
||||
text-transform: capitalize;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
@ -22,12 +22,12 @@
|
||||
"@babel/preset-env": "^7.9.5",
|
||||
"@babel/preset-react": "^7.9.4",
|
||||
"@babel/runtime": "^7.9.2",
|
||||
"@buffetjs/core": "3.1.0-next.2",
|
||||
"@buffetjs/custom": "3.1.0-next.2",
|
||||
"@buffetjs/hooks": "3.0.6",
|
||||
"@buffetjs/icons": "3.1.0-next.2",
|
||||
"@buffetjs/styles": "3.1.0-next.2",
|
||||
"@buffetjs/utils": "3.0.6",
|
||||
"@buffetjs/core": "3.1.0-next.3",
|
||||
"@buffetjs/custom": "3.1.0-next.3",
|
||||
"@buffetjs/hooks": "3.1.0-next.3",
|
||||
"@buffetjs/icons": "3.1.0-next.3",
|
||||
"@buffetjs/styles": "3.1.0-next.3",
|
||||
"@buffetjs/utils": "3.1.0-next.3",
|
||||
"@fortawesome/fontawesome-free": "^5.11.2",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.25",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.11.2",
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { PageFooter, useQuery } from 'strapi-helper-plugin';
|
||||
import { generatePageFromStart, generateStartFromPage } from '../../../utils';
|
||||
|
||||
import List from '../../../components/List';
|
||||
import ListEmpty from '../../../components/ListEmpty';
|
||||
import Padded from '../../../components/Padded';
|
||||
|
||||
const HomePageList = ({
|
||||
areResultsEmptyWithSettings,
|
||||
data,
|
||||
dataCount,
|
||||
dataToDelete,
|
||||
onCardCheck,
|
||||
onCardClick,
|
||||
onChange,
|
||||
onClick,
|
||||
}) => {
|
||||
const query = useQuery();
|
||||
|
||||
const limit = parseInt(query.get('_limit'), 10) || 10;
|
||||
const start = parseInt(query.get('_start'), 10) || 0;
|
||||
|
||||
const params = {
|
||||
_limit: limit,
|
||||
_page: generatePageFromStart(start, limit),
|
||||
};
|
||||
|
||||
const handleChangeListParams = ({ target: { name, value } }) => {
|
||||
if (name.includes('_page')) {
|
||||
onChange({
|
||||
target: { name: '_start', value: generateStartFromPage(value, limit) },
|
||||
});
|
||||
} else {
|
||||
onChange({ target: { name: '_limit', value } });
|
||||
}
|
||||
};
|
||||
|
||||
if (dataCount > 0 && !areResultsEmptyWithSettings) {
|
||||
return (
|
||||
<>
|
||||
<List
|
||||
data={data}
|
||||
onChange={onCardCheck}
|
||||
onCardClick={onCardClick}
|
||||
selectedItems={dataToDelete}
|
||||
/>
|
||||
<Padded left right size="sm">
|
||||
<Padded left right size="xs">
|
||||
<PageFooter
|
||||
context={{ emitEvent: () => {} }}
|
||||
count={dataCount}
|
||||
onChangeParams={handleChangeListParams}
|
||||
params={params}
|
||||
/>
|
||||
</Padded>
|
||||
</Padded>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return <ListEmpty onClick={onClick} hasSearchApplied={areResultsEmptyWithSettings} />;
|
||||
};
|
||||
|
||||
HomePageList.defaultProps = {
|
||||
areResultsEmptyWithSettings: false,
|
||||
data: [],
|
||||
dataCount: 0,
|
||||
dataToDelete: [],
|
||||
onCardCheck: () => {},
|
||||
onCardClick: () => {},
|
||||
onChange: () => {},
|
||||
onClick: () => {},
|
||||
};
|
||||
|
||||
HomePageList.propTypes = {
|
||||
areResultsEmptyWithSettings: PropTypes.bool,
|
||||
data: PropTypes.array,
|
||||
dataCount: PropTypes.number,
|
||||
dataToDelete: PropTypes.array,
|
||||
onCardCheck: PropTypes.func,
|
||||
onCardClick: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
onClick: PropTypes.func,
|
||||
};
|
||||
|
||||
export default HomePageList;
|
||||
@ -0,0 +1,85 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useDebounce } from '@buffetjs/hooks';
|
||||
import { HeaderSearch, useGlobalContext, useQuery } from 'strapi-helper-plugin';
|
||||
import { getTrad, getFileModelTimestamps } from '../../../utils';
|
||||
|
||||
import ControlsWrapper from '../../../components/ControlsWrapper';
|
||||
import Filters from '../../../components/Filters';
|
||||
import Padded from '../../../components/Padded';
|
||||
import SelectAll from '../../../components/SelectAll';
|
||||
import SortPicker from '../../../components/SortPicker';
|
||||
|
||||
const HomePageSettings = ({
|
||||
areAllCheckboxesSelected,
|
||||
filters,
|
||||
hasSomeCheckboxSelected,
|
||||
onChange,
|
||||
onFilterDelete,
|
||||
onSelectAll,
|
||||
}) => {
|
||||
const { formatMessage, plugins } = useGlobalContext();
|
||||
const [, updated_at] = getFileModelTimestamps(plugins);
|
||||
const query = useQuery();
|
||||
const [searchValue, setSearchValue] = useState(query.get('_q') || '');
|
||||
const debouncedSearch = useDebounce(searchValue, 300);
|
||||
const pluginName = formatMessage({ id: getTrad('plugin.name') });
|
||||
|
||||
useEffect(() => {
|
||||
onChange({ target: { name: '_q', value: debouncedSearch } });
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [debouncedSearch]);
|
||||
|
||||
const handleChangeSearchValue = ({ target: { value } }) => {
|
||||
setSearchValue(value);
|
||||
};
|
||||
|
||||
const handleClearSearch = () => {
|
||||
setSearchValue('');
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeaderSearch
|
||||
label={pluginName}
|
||||
onChange={handleChangeSearchValue}
|
||||
onClear={handleClearSearch}
|
||||
placeholder={formatMessage({ id: getTrad('search.placeholder') })}
|
||||
name="_q"
|
||||
value={searchValue}
|
||||
/>
|
||||
<ControlsWrapper>
|
||||
<SelectAll
|
||||
onChange={onSelectAll}
|
||||
checked={areAllCheckboxesSelected}
|
||||
someChecked={hasSomeCheckboxSelected && !areAllCheckboxesSelected}
|
||||
/>
|
||||
<Padded right />
|
||||
<SortPicker onChange={onChange} value={query.get('_sort') || `${updated_at}:DESC`} />
|
||||
<Padded right />
|
||||
<Filters onChange={onChange} filters={filters} onClick={onFilterDelete} />
|
||||
</ControlsWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
HomePageSettings.defaultProps = {
|
||||
areAllCheckboxesSelected: false,
|
||||
filters: [],
|
||||
hasSomeCheckboxSelected: false,
|
||||
onChange: () => {},
|
||||
onFilterDelete: () => {},
|
||||
onSelectAll: () => {},
|
||||
};
|
||||
|
||||
HomePageSettings.propTypes = {
|
||||
areAllCheckboxesSelected: PropTypes.bool,
|
||||
filters: PropTypes.array,
|
||||
hasSomeCheckboxSelected: PropTypes.bool,
|
||||
onChange: PropTypes.func,
|
||||
onFilterDelete: PropTypes.func,
|
||||
onSelectAll: PropTypes.func,
|
||||
};
|
||||
|
||||
export default HomePageSettings;
|
||||
@ -0,0 +1,86 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { generateFiltersFromSearch, useQuery } from 'strapi-helper-plugin';
|
||||
|
||||
import HomePageSettings from './HomePageSettings';
|
||||
import HomePageList from './HomePageList';
|
||||
|
||||
const HomePageContent = ({
|
||||
data,
|
||||
dataCount,
|
||||
dataToDelete,
|
||||
onCardCheck,
|
||||
onCardClick,
|
||||
onClick,
|
||||
onFilterDelete,
|
||||
onParamsChange,
|
||||
onSelectAll,
|
||||
}) => {
|
||||
const query = useQuery();
|
||||
const { search } = useLocation();
|
||||
const filters = generateFiltersFromSearch(search);
|
||||
|
||||
const hasSomeCheckboxSelected = data.some(item =>
|
||||
dataToDelete.find(itemToDelete => item.id.toString() === itemToDelete.id.toString())
|
||||
);
|
||||
|
||||
const areAllCheckboxesSelected =
|
||||
data.every(item =>
|
||||
dataToDelete.find(itemToDelete => item.id.toString() === itemToDelete.id.toString())
|
||||
) && hasSomeCheckboxSelected;
|
||||
|
||||
const hasFilters = !isEmpty(filters);
|
||||
const hasSearch = !isEmpty(query.get('_q'));
|
||||
const areResultsEmptyWithSearchOrFilters = isEmpty(data) && (hasSearch || hasFilters);
|
||||
|
||||
return (
|
||||
<>
|
||||
<HomePageSettings
|
||||
areAllCheckboxesSelected={areAllCheckboxesSelected}
|
||||
filters={filters}
|
||||
hasSomeCheckboxSelected={hasSomeCheckboxSelected}
|
||||
onChange={onParamsChange}
|
||||
onFilterDelete={onFilterDelete}
|
||||
onSelectAll={onSelectAll}
|
||||
/>
|
||||
<HomePageList
|
||||
areResultsEmptyWithSettings={areResultsEmptyWithSearchOrFilters}
|
||||
data={data}
|
||||
dataCount={dataCount}
|
||||
dataToDelete={dataToDelete}
|
||||
onCardCheck={onCardCheck}
|
||||
onCardClick={onCardClick}
|
||||
onClick={onClick}
|
||||
onChange={onParamsChange}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
HomePageContent.defaultProps = {
|
||||
data: [],
|
||||
dataCount: 0,
|
||||
dataToDelete: [],
|
||||
onCardCheck: () => {},
|
||||
onCardClick: () => {},
|
||||
onClick: () => {},
|
||||
onFilterDelete: () => {},
|
||||
onParamsChange: () => {},
|
||||
onSelectAll: () => {},
|
||||
};
|
||||
|
||||
HomePageContent.propTypes = {
|
||||
data: PropTypes.array,
|
||||
dataCount: PropTypes.number,
|
||||
dataToDelete: PropTypes.array,
|
||||
onCardCheck: PropTypes.func,
|
||||
onCardClick: PropTypes.func,
|
||||
onClick: PropTypes.func,
|
||||
onFilterDelete: PropTypes.func,
|
||||
onParamsChange: PropTypes.func,
|
||||
onSelectAll: PropTypes.func,
|
||||
};
|
||||
|
||||
export default HomePageContent;
|
||||
@ -1,35 +1,20 @@
|
||||
import React, { useReducer, useState, useRef, useEffect } from 'react';
|
||||
import { includes, isEmpty, toString, isEqual, intersectionWith } from 'lodash';
|
||||
import React, { useReducer, useRef, useState, useEffect } from 'react';
|
||||
import { includes, toString, isEqual, intersectionWith } from 'lodash';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { Header } from '@buffetjs/custom';
|
||||
import { useDebounce } from '@buffetjs/hooks';
|
||||
import {
|
||||
HeaderSearch,
|
||||
PageFooter,
|
||||
PopUpWarning,
|
||||
LoadingIndicatorPage,
|
||||
LoadingIndicator,
|
||||
useGlobalContext,
|
||||
generateFiltersFromSearch,
|
||||
generateSearchFromFilters,
|
||||
request,
|
||||
useQuery,
|
||||
} from 'strapi-helper-plugin';
|
||||
import {
|
||||
formatFileForEditing,
|
||||
getRequestUrl,
|
||||
getTrad,
|
||||
generatePageFromStart,
|
||||
generateStartFromPage,
|
||||
getFileModelTimestamps,
|
||||
} from '../../utils';
|
||||
import { formatFileForEditing, getRequestUrl, getTrad, getFileModelTimestamps } from '../../utils';
|
||||
import Container from '../../components/Container';
|
||||
import ControlsWrapper from '../../components/ControlsWrapper';
|
||||
import HomePageContent from './HomePageContent';
|
||||
import Padded from '../../components/Padded';
|
||||
import SelectAll from '../../components/SelectAll';
|
||||
import SortPicker from '../../components/SortPicker';
|
||||
import Filters from '../../components/Filters';
|
||||
import List from '../../components/List';
|
||||
import ListEmpty from '../../components/ListEmpty';
|
||||
import ModalStepper from '../ModalStepper';
|
||||
import { generateStringFromParams, getHeaderLabel } from './utils';
|
||||
import init from './init';
|
||||
@ -45,25 +30,17 @@ const HomePage = () => {
|
||||
const [fileToEdit, setFileToEdit] = useState(null);
|
||||
const [shouldRefetch, setShouldRefetch] = useState(false);
|
||||
const [modalInitialStep, setModalInitialStep] = useState('browse');
|
||||
const [searchValue, setSearchValue] = useState(query.get('_q') || '');
|
||||
const { push } = useHistory();
|
||||
const { search } = useLocation();
|
||||
const isMounted = useRef(true);
|
||||
const { data, dataCount, dataToDelete, isLoading } = reducerState.toJS();
|
||||
const pluginName = formatMessage({ id: getTrad('plugin.name') });
|
||||
const paramsKeys = ['_limit', '_start', '_q', '_sort'];
|
||||
const debouncedSearch = useDebounce(searchValue, 300);
|
||||
|
||||
useEffect(() => {
|
||||
return () => (isMounted.current = false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
handleChangeParams({ target: { name: '_q', value: debouncedSearch } });
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [debouncedSearch]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchListData();
|
||||
|
||||
@ -84,20 +61,6 @@ const HomePage = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const fetchListData = async () => {
|
||||
dispatch({ type: 'GET_DATA' });
|
||||
|
||||
const [data, count] = await Promise.all([fetchData(), fetchDataCount()]);
|
||||
|
||||
if (isMounted.current) {
|
||||
dispatch({
|
||||
type: 'GET_DATA_SUCCEEDED',
|
||||
data,
|
||||
count,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const fetchData = async () => {
|
||||
const dataRequestURL = getRequestUrl('files');
|
||||
const params = generateStringFromParams(query);
|
||||
@ -142,6 +105,28 @@ const HomePage = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
const fetchListData = async () => {
|
||||
dispatch({ type: 'GET_DATA' });
|
||||
|
||||
const [data, count] = await Promise.all([fetchData(), fetchDataCount()]);
|
||||
|
||||
if (isMounted.current) {
|
||||
dispatch({
|
||||
type: 'GET_DATA_SUCCEEDED',
|
||||
data,
|
||||
count,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const generateNewSearch = (updatedParams = {}) => {
|
||||
return {
|
||||
...getSearchParams(),
|
||||
filters: generateFiltersFromSearch(search),
|
||||
...updatedParams,
|
||||
};
|
||||
};
|
||||
|
||||
const getSearchParams = () => {
|
||||
const params = {};
|
||||
|
||||
@ -154,14 +139,6 @@ const HomePage = () => {
|
||||
return params;
|
||||
};
|
||||
|
||||
const generateNewSearch = (updatedParams = {}) => {
|
||||
return {
|
||||
...getSearchParams(),
|
||||
filters: generateFiltersFromSearch(search),
|
||||
...updatedParams,
|
||||
};
|
||||
};
|
||||
|
||||
const handleChangeCheck = ({ target: { name } }) => {
|
||||
dispatch({
|
||||
type: 'ON_CHANGE_DATA_TO_DELETE',
|
||||
@ -169,16 +146,6 @@ const HomePage = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const handleChangeListParams = ({ target: { name, value } }) => {
|
||||
if (name.includes('_page')) {
|
||||
handleChangeParams({
|
||||
target: { name: '_start', value: generateStartFromPage(value, limit) },
|
||||
});
|
||||
} else {
|
||||
handleChangeParams({ target: { name: '_limit', value } });
|
||||
}
|
||||
};
|
||||
|
||||
const handleChangeParams = ({ target: { name, value } }) => {
|
||||
let updatedQueryParams = generateNewSearch({ [name]: value });
|
||||
|
||||
@ -203,10 +170,6 @@ const HomePage = () => {
|
||||
push({ search: encodeURI(newSearch) });
|
||||
};
|
||||
|
||||
const handleChangeSearchValue = ({ target: { value } }) => {
|
||||
setSearchValue(value);
|
||||
};
|
||||
|
||||
const handleClickEditFile = id => {
|
||||
const file = formatFileForEditing(data.find(file => toString(file.id) === toString(id)));
|
||||
|
||||
@ -215,10 +178,6 @@ const HomePage = () => {
|
||||
handleClickToggleModal();
|
||||
};
|
||||
|
||||
const handleClearSearch = () => {
|
||||
setSearchValue('');
|
||||
};
|
||||
|
||||
const handleClickToggleModal = (refetch = false) => {
|
||||
setIsModalOpen(prev => !prev);
|
||||
setShouldRefetch(refetch);
|
||||
@ -316,7 +275,7 @@ const HomePage = () => {
|
||||
},
|
||||
content: formatMessage(
|
||||
{
|
||||
id: getTrad(getHeaderLabel(data)),
|
||||
id: getTrad(getHeaderLabel(dataCount)),
|
||||
},
|
||||
{ number: dataCount }
|
||||
),
|
||||
@ -339,80 +298,25 @@ const HomePage = () => {
|
||||
],
|
||||
};
|
||||
|
||||
const limit = parseInt(query.get('_limit'), 10) || 10;
|
||||
const start = parseInt(query.get('_start'), 10) || 0;
|
||||
|
||||
const params = {
|
||||
_limit: limit,
|
||||
_page: generatePageFromStart(start, limit),
|
||||
};
|
||||
|
||||
const hasSomeCheckboxSelected = data.some(item =>
|
||||
dataToDelete.find(itemToDelete => item.id.toString() === itemToDelete.id.toString())
|
||||
);
|
||||
|
||||
const areAllCheckboxesSelected =
|
||||
data.every(item =>
|
||||
dataToDelete.find(itemToDelete => item.id.toString() === itemToDelete.id.toString())
|
||||
) && hasSomeCheckboxSelected;
|
||||
|
||||
if (isLoading) {
|
||||
return <LoadingIndicatorPage />;
|
||||
}
|
||||
|
||||
const filters = generateFiltersFromSearch(search);
|
||||
const hasFilters = !isEmpty(filters);
|
||||
const hasSearch = !isEmpty(searchValue);
|
||||
const areResultsEmptyWithSearchOrFilters = isEmpty(data) && (hasSearch || hasFilters);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Header {...headerProps} />
|
||||
<HeaderSearch
|
||||
label={pluginName}
|
||||
onChange={handleChangeSearchValue}
|
||||
onClear={handleClearSearch}
|
||||
placeholder={formatMessage({ id: getTrad('search.placeholder') })}
|
||||
name="_q"
|
||||
value={searchValue}
|
||||
/>
|
||||
<ControlsWrapper>
|
||||
<SelectAll
|
||||
onChange={handleSelectAll}
|
||||
checked={areAllCheckboxesSelected}
|
||||
someChecked={hasSomeCheckboxSelected && !areAllCheckboxesSelected}
|
||||
/>
|
||||
<Padded right />
|
||||
<SortPicker
|
||||
onChange={handleChangeParams}
|
||||
value={query.get('_sort') || `${updated_at}:DESC`}
|
||||
/>
|
||||
<Padded right />
|
||||
<Filters onChange={handleChangeParams} filters={filters} onClick={handleDeleteFilter} />
|
||||
</ControlsWrapper>
|
||||
{dataCount > 0 && !areResultsEmptyWithSearchOrFilters ? (
|
||||
<Header {...headerProps} isLoading={isLoading} />
|
||||
{isLoading ? (
|
||||
<>
|
||||
<List
|
||||
data={data}
|
||||
onChange={handleChangeCheck}
|
||||
onCardClick={handleClickEditFile}
|
||||
selectedItems={dataToDelete}
|
||||
/>
|
||||
<Padded left right size="sm">
|
||||
<Padded left right size="xs">
|
||||
<PageFooter
|
||||
context={{ emitEvent: () => {} }}
|
||||
count={dataCount}
|
||||
onChangeParams={handleChangeListParams}
|
||||
params={params}
|
||||
/>
|
||||
</Padded>
|
||||
</Padded>
|
||||
<Padded top bottom size="lg" />
|
||||
<LoadingIndicator />
|
||||
</>
|
||||
) : (
|
||||
<ListEmpty
|
||||
<HomePageContent
|
||||
data={data}
|
||||
dataCount={dataCount}
|
||||
dataToDelete={dataToDelete}
|
||||
onCardCheck={handleChangeCheck}
|
||||
onCardClick={handleClickEditFile}
|
||||
onClick={handleClickToggleModal}
|
||||
hasSearchApplied={areResultsEmptyWithSearchOrFilters}
|
||||
onFilterDelete={handleDeleteFilter}
|
||||
onParamsChange={handleChangeParams}
|
||||
onSelectAll={handleSelectAll}
|
||||
/>
|
||||
)}
|
||||
<ModalStepper
|
||||
|
||||
@ -40,6 +40,10 @@ const reducer = (state, action) => {
|
||||
|
||||
return state.removeIn(['dataToDelete', index]);
|
||||
}
|
||||
case 'ON_DELETE_MEDIA_SUCCEEDED':
|
||||
return state
|
||||
.update('data', list => list.filter(item => item.get('id') !== action.mediaId))
|
||||
.update('dataCount', count => count - 1);
|
||||
case 'TOGGLE_SELECT_ALL': {
|
||||
const isSelected = state.get('data').every(item => state.get('dataToDelete').includes(item));
|
||||
|
||||
@ -57,10 +61,6 @@ const reducer = (state, action) => {
|
||||
return dataToDelete.concat(newItems);
|
||||
});
|
||||
}
|
||||
case 'ON_DELETE_MEDIA_SUCCEEDED':
|
||||
return state
|
||||
.update('data', list => list.filter(item => item.get('id') !== action.mediaId))
|
||||
.update('dataCount', count => count - 1);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
const getHeaderLabel = array => {
|
||||
const getHeaderLabel = count => {
|
||||
let headerLabel = 'header.content.assets-single';
|
||||
|
||||
if (array.length === 0) {
|
||||
if (count === 0) {
|
||||
headerLabel = 'header.content.assets-empty';
|
||||
} else if (array.length > 1) {
|
||||
} else if (count > 1) {
|
||||
headerLabel = 'header.content.assets-multiple';
|
||||
}
|
||||
|
||||
|
||||
@ -2,25 +2,25 @@ import getHeaderLabel from '../getHeaderLabel';
|
||||
|
||||
describe('MEDIA LIBRARY | containers | HomePage | utils', () => {
|
||||
describe('getHeaderLabel', () => {
|
||||
it('should return the header translation with this empty suffix if there is no data', () => {
|
||||
const data = [];
|
||||
it('should return the header translation with this empty suffix if count is 0', () => {
|
||||
const count = 0;
|
||||
const expected = 'header.content.assets-empty';
|
||||
|
||||
expect(getHeaderLabel(data)).toEqual(expected);
|
||||
expect(getHeaderLabel(count)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return the header translation with this single suffix if there is 1 element', () => {
|
||||
const data = ['test'];
|
||||
it('should return the header translation with this single suffix if count is 1', () => {
|
||||
const count = 1;
|
||||
const expected = 'header.content.assets-single';
|
||||
|
||||
expect(getHeaderLabel(data)).toEqual(expected);
|
||||
expect(getHeaderLabel(count)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return the header translation with this multiple suffix if there is more than 1 element', () => {
|
||||
const data = ['test', 'test2'];
|
||||
it('should return the header translation with this multiple suffix if count is greater than 1', () => {
|
||||
const count = 2;
|
||||
const expected = 'header.content.assets-multiple';
|
||||
|
||||
expect(getHeaderLabel(data)).toEqual(expected);
|
||||
expect(getHeaderLabel(count)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
62
yarn.lock
62
yarn.lock
@ -992,15 +992,15 @@
|
||||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@buffetjs/core@3.1.0-next.2":
|
||||
version "3.1.0-next.2"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/core/-/core-3.1.0-next.2.tgz#4c18ce545badf8803fea47080a274c932bcd0c87"
|
||||
integrity sha512-TaCat7SN+NZPvTh2ly+mo/7Xbub1Q5ASqgmeFkLzZxWliONwy1YV4zIFELXSXug3Tw7b5VI/a1v1Qrrm7qwzSg==
|
||||
"@buffetjs/core@3.1.0-next.3":
|
||||
version "3.1.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/core/-/core-3.1.0-next.3.tgz#307276cae9616be940cc005a9fd4046037e45a15"
|
||||
integrity sha512-KPIgtqfb4RwYG+VYHgHVgYv/a7IQT0PTNxyvLwlOflEGlsIULE8Bx5VfFamaPDkcpQBlGvfXrPYDIHP1tizZ1g==
|
||||
dependencies:
|
||||
"@buffetjs/hooks" "3.0.6"
|
||||
"@buffetjs/icons" "3.1.0-next.2"
|
||||
"@buffetjs/styles" "3.1.0-next.2"
|
||||
"@buffetjs/utils" "3.0.6"
|
||||
"@buffetjs/hooks" "3.1.0-next.3"
|
||||
"@buffetjs/icons" "3.1.0-next.3"
|
||||
"@buffetjs/styles" "3.1.0-next.3"
|
||||
"@buffetjs/utils" "3.1.0-next.3"
|
||||
"@fortawesome/fontawesome-svg-core" "^1.2.25"
|
||||
"@fortawesome/free-regular-svg-icons" "^5.11.2"
|
||||
"@fortawesome/free-solid-svg-icons" "^5.11.2"
|
||||
@ -1011,31 +1011,31 @@
|
||||
react-dates "^21.5.1"
|
||||
react-moment-proptypes "^1.7.0"
|
||||
|
||||
"@buffetjs/custom@3.1.0-next.2":
|
||||
version "3.1.0-next.2"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/custom/-/custom-3.1.0-next.2.tgz#41d83cdd2fbdb64119062b3250b2d587970d87dd"
|
||||
integrity sha512-UmY6FN0CrlQw4LaOLVHjfyb6v7Q9keHAcCNePyQtmA1S2rGm0USwG0DDRNFnFbHKcnysnISfSRMoyHW5VS1v5g==
|
||||
"@buffetjs/custom@3.1.0-next.3":
|
||||
version "3.1.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/custom/-/custom-3.1.0-next.3.tgz#d3f1a593653812746efe0c3b084b40a08b963fa9"
|
||||
integrity sha512-Pn8mQPRYFDEKONOpJ1Oai1WnHq8V/O9dtWYZKmNJBCBxUIQPHNO0qJGWMPXY1udJvT2OQFn0XWp/EeuE36pkhg==
|
||||
dependencies:
|
||||
"@buffetjs/core" "3.1.0-next.2"
|
||||
"@buffetjs/styles" "3.1.0-next.2"
|
||||
"@buffetjs/utils" "3.0.6"
|
||||
"@buffetjs/core" "3.1.0-next.3"
|
||||
"@buffetjs/styles" "3.1.0-next.3"
|
||||
"@buffetjs/utils" "3.1.0-next.3"
|
||||
moment "^2.24.0"
|
||||
react-moment-proptypes "^1.7.0"
|
||||
|
||||
"@buffetjs/hooks@3.0.6":
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/hooks/-/hooks-3.0.6.tgz#98b3780fa005193a06f32af2b23e0782358ce5a6"
|
||||
integrity sha512-boxLYVT/4RauTQmgLkdZWrwdMPS624/91rk4TqWARRmnXeP4+99MErHwqz5z3Bk8aBa3yNWpayu1p25fdoti6A==
|
||||
"@buffetjs/hooks@3.1.0-next.3":
|
||||
version "3.1.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/hooks/-/hooks-3.1.0-next.3.tgz#5550c7416aefb56322c56ca3b627836a5ae86b48"
|
||||
integrity sha512-VnsapTdY1c5dTgoTrHYfoz+hpqZ4C2Ihx+Gp+CJr+J1in3wnkf9TC+vWSIo+jDr+VloSQSNq+ISEu9cEVdPIIw==
|
||||
|
||||
"@buffetjs/icons@3.1.0-next.2":
|
||||
version "3.1.0-next.2"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/icons/-/icons-3.1.0-next.2.tgz#08134a31aa367f7bef454fda4e5a88a7064319f1"
|
||||
integrity sha512-C3kHl4dRo5vYjcJZlKxiEMVe/gPRyJJEiGQESqpq6oACaiz1TBz3o0GNAIi17dOJuOEqYadVXCogz2u2Ef64+g==
|
||||
"@buffetjs/icons@3.1.0-next.3":
|
||||
version "3.1.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/icons/-/icons-3.1.0-next.3.tgz#b745038be6f3214f9136088776b8da07b61d9f26"
|
||||
integrity sha512-zEA+9iocFlmP0lEDcv12o7AlXJdhEHheRpDXwZFunIMtl/JvCsY58BVUAwCamiX884oGjjv4XvOc6g4FJQO5ew==
|
||||
|
||||
"@buffetjs/styles@3.1.0-next.2":
|
||||
version "3.1.0-next.2"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/styles/-/styles-3.1.0-next.2.tgz#d1e9f7b1b69b6987f3baa9791b5ef0541e8a5435"
|
||||
integrity sha512-r4+cLqAmvIlN2rBw2imEcxAlWkO3DNTZ8RWPzmsufBhoImsN1ebuL1zcYVSGAttZnI4G80uyDxNywe9Di9iHcw==
|
||||
"@buffetjs/styles@3.1.0-next.3":
|
||||
version "3.1.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/styles/-/styles-3.1.0-next.3.tgz#2646a976c3fb5250ad0e8fe0156a508fa3938c68"
|
||||
integrity sha512-IDmzrU9YQPi/dK/aocNsVvc9hrMxKdFmDgUbHxq84++2rppOIqOUNkGdOoAzcNq9B6e9f7Alu0JQ1AIFTthUXg==
|
||||
dependencies:
|
||||
"@fortawesome/fontawesome-free" "^5.12.0"
|
||||
"@fortawesome/fontawesome-svg-core" "^1.2.22"
|
||||
@ -1044,10 +1044,10 @@
|
||||
"@fortawesome/react-fontawesome" "^0.1.4"
|
||||
react-dates "^21.1.0"
|
||||
|
||||
"@buffetjs/utils@3.0.6":
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/utils/-/utils-3.0.6.tgz#87f7e0822d907397ae62b4764edcddc516e3ad27"
|
||||
integrity sha512-DfYrHtmta2KXTc8iy892uGzbs1ygZ37hiXLAYmSWZfJNNk8pamAqnRLcfjVDA/SgTQIVO8unmaPxi3141xfe/Q==
|
||||
"@buffetjs/utils@3.1.0-next.3":
|
||||
version "3.1.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/@buffetjs/utils/-/utils-3.1.0-next.3.tgz#968f6fd992d477024de86443c67bd0faa246ab15"
|
||||
integrity sha512-JCJ2wKsjSP3uhVn/xjq5AYenw3ZtWhNSAc8QDK0cJoblntMjsf0MAJKTfVCc1s7SNbkHvIQnLJXOniywOAWxlA==
|
||||
dependencies:
|
||||
yup "^0.27.0"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user