import React, { memo, useCallback, useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators, compose } from 'redux';
import { capitalize, get, sortBy } from 'lodash';
import { FormattedMessage } from 'react-intl';
import { Header, HeaderActions, HeaderTitle } from '@buffetjs/core';
import { PopUpWarning, getQueryParameters } from 'strapi-helper-plugin';
import pluginId from '../../pluginId';
import DisplayedFieldsDropdown from '../../components/DisplayedFieldsDropdown';
import FilterLogo from '../../assets/images/icon_filter.png';
import Container from '../../components/Container';
import CustomTable from '../../components/CustomTable';
import FilterPicker from '../../components/FilterPicker';
import Search from '../../components/Search';
import {
generateFiltersFromSearch,
generateSearchFromFilters,
} from '../../utils/search';
import ListViewProvider from '../ListViewProvider';
import { onChangeListLabels, resetListLabels } from '../Main/actions';
import { AddFilterCta, Img, Wrapper } from './components';
import Filter from './Filter';
import Footer from './Footer';
import {
getData,
onChangeBulk,
onChangeBulkSelectall,
onDeleteData,
onDeleteSeveralData,
resetProps,
toggleModalDelete,
toggleModalDeleteAll,
} from './actions';
import reducer from './reducer';
import saga from './saga';
import makeSelectListView from './selectors';
function ListView({
count,
data,
emitEvent,
entriesToDelete,
location: { pathname, search },
getData,
layouts,
history: { push },
onChangeBulk,
onChangeBulkSelectall,
onChangeListLabels,
onDeleteData,
onDeleteSeveralData,
resetListLabels,
resetProps,
shouldRefetchData,
showWarningDelete,
slug,
toggleModalDelete,
showWarningDeleteAll,
toggleModalDeleteAll,
}) {
strapi.useInjectReducer({ key: 'listView', reducer, pluginId });
strapi.useInjectSaga({ key: 'listView', saga, pluginId });
const getLayoutSettingRef = useRef();
const [isLabelPickerOpen, setLabelPickerState] = useState(false);
const [isFilterPickerOpen, setFilterPickerState] = useState(false);
const [idToDelete, setIdToDelete] = useState(null);
const contentTypePath = [slug, 'contentType'];
getLayoutSettingRef.current = settingName =>
get(layouts, [...contentTypePath, 'settings', settingName], '');
const getSearchParams = useCallback(
(updatedParams = {}) => {
return {
_limit:
getQueryParameters(search, '_limit') ||
getLayoutSettingRef.current('pageSize'),
_page: getQueryParameters(search, '_page') || 1,
_q: getQueryParameters(search, '_q') || '',
_sort:
getQueryParameters(search, '_sort') ||
`${getLayoutSettingRef.current(
'defaultSortBy'
)}:${getLayoutSettingRef.current('defaultSortOrder')}`,
source: getQueryParameters(search, 'source'),
filters: generateFiltersFromSearch(search),
...updatedParams,
};
},
[getLayoutSettingRef, search]
);
useEffect(() => {
getData(slug, getSearchParams());
return () => {
resetProps();
setFilterPickerState(false);
};
/* eslint-disable-next-line react-hooks/exhaustive-deps */
}, [slug, shouldRefetchData]);
const toggleLabelPickerState = () => {
if (!isLabelPickerOpen) {
emitEvent('willChangeDisplayedFields');
}
setLabelPickerState(prevState => !prevState);
};
const toggleFilterPickerState = () => {
setFilterPickerState(prevState => !prevState);
};
// Helpers
const getMetaDatas = (path = []) =>
get(layouts, [...contentTypePath, 'metadatas', ...path], {});
const getListLayout = () =>
get(layouts, [...contentTypePath, 'layouts', 'list'], []);
const getAllLabels = () => {
return sortBy(
Object.keys(getMetaDatas())
.filter(
key =>
!['json', 'component', 'relation', 'richtext'].includes(
get(
layouts,
[...contentTypePath, 'schema', 'attributes', key, 'type'],
''
)
)
)
.map(label => ({
name: label,
value: getListLayout().includes(label),
})),
['label', 'name']
);
};
const getFirstSortableElement = (name = '') => {
return get(
getListLayout().filter(h => {
return h !== name && getMetaDatas([h, 'list', 'sortable']) === true;
}),
['0'],
'id'
);
};
const getTableHeaders = () => {
return getListLayout().map(label => {
return { ...getMetaDatas([label, 'list']), name: label };
});
};
const handleChangeListLabels = ({ name, value }) => {
const currentSort = getSearchParams()._sort;
if (value && getListLayout().length === 1) {
strapi.notification.error(
'content-manager.notification.error.displayedFields'
);
return;
}
if (currentSort.split(':')[0] === name && value) {
emitEvent('didChangeDisplayedFields');
handleChangeParams({
target: {
name: '_sort',
value: `${getFirstSortableElement(name)}:ASC`,
},
});
}
onChangeListLabels({
target: { name: `${slug}.${name}`, value: !value },
});
};
const handleChangeParams = ({ target: { name, value } }) => {
const updatedSearch = getSearchParams({ [name]: value });
const newSearch = generateSearchFromFilters(updatedSearch);
if (name === '_limit') {
emitEvent('willChangeNumberOfEntriesPerPage');
}
push({ search: newSearch });
resetProps();
getData(slug, updatedSearch);
};
const handleClickDelete = id => {
setIdToDelete(id);
toggleModalDelete();
};
const handleSubmit = (filters = []) => {
emitEvent('didFilterEntries');
toggleFilterPickerState();
handleChangeParams({ target: { name: 'filters', value: filters } });
};
const filterPickerActions = [
{
label: `${pluginId}.components.FiltersPickWrapper.PluginHeader.actions.clearAll`,
kind: 'secondary',
onClick: () => {
toggleFilterPickerState();
handleChangeParams({ target: { name: 'filters', value: [] } });
},
},
{
label: `${pluginId}.components.FiltersPickWrapper.PluginHeader.actions.apply`,
kind: 'primary',
type: 'submit',
},
];
const headerAction = [
{
title: (