(defaultSearchInput);
useEffect(() => {
setSearchInput(defaultSearchInput);
}, [defaultSearchInput]);
useEffect(() => {
if (Number.isInteger(defaultMaxPerPage) && defaultMaxPerPage > 0) {
return setMaxPerPage(defaultMaxPerPage);
}
return setMaxPerPage(DEFAULT_PROPS.maxPerPage);
}, [defaultMaxPerPage]);
useEffect(() => {
const columnPropertyKeys = columns.map((column) => column.propertyKey);
if (columnPropertyKeys.includes(defaultOrderBy)) {
return setOrderBy(defaultOrderBy);
}
return setOrderBy(columnPropertyKeys[0]);
}, [columns, defaultOrderBy]);
useEffect(() => {
if (
defaultOrderType === ORDER_TYPE.ASCENDING ||
defaultOrderType === ORDER_TYPE.DESCENDING
) {
return setOrderType(defaultOrderType);
}
return setOrderType(ORDER_TYPE.ASCENDING);
}, [defaultOrderType]);
const [filteredDataCount, setFilteredDataCount] = useState(
queryParams ? countElements : filteredData.length
);
const [filterablePropertyKeys, setFilterablePropertyKeys] = useState<
string[]
>([]);
const [paginatedData, setPaginatedData] = useState([[]]);
const [notSelectableItemsCount, setNotSelectableItemsCount] = useState(0);
const selectAllRows = () => {
const items = disableFooter
? filteredData
: paginatedData[
onQueryParamsChange && !!currentPage ? 0 : currentPage - 1
];
const areRowsSelected = selectedCount > 0;
const areAllRowsSelected = !!items && selectedCount === items.length;
const selectedItems: unknown[] = [];
// eslint-disable-next-line no-nested-ternary
const startPaginatedIndex = disableFooter
? 0
: onQueryParamsChange
? 0
: (currentPage - 1) * maxPerPage;
// eslint-disable-next-line no-nested-ternary
const endPaginatedIndex = disableFooter
? (items || []).length
: onQueryParamsChange
? maxPerPage
: currentPage * maxPerPage;
const updatedFilteredData = filteredData.map((item, index) => {
if (item.isNotSelectable) {
return item;
}
if (index < startPaginatedIndex || index >= endPaginatedIndex) {
return {
...item,
isRowSelected: false,
};
}
if (areRowsSelected && !areAllRowsSelected) {
return {
...item,
isRowSelected: false,
};
}
if (!areAllRowsSelected) {
selectedItems.push(item);
}
return {
...item,
isRowSelected: !areAllRowsSelected,
};
});
setFilteredData(updatedFilteredData);
setSelectedCount(selectedItems.length);
if (setSelectedItems) {
setSelectedItems(selectedItems);
}
};
const resetSelection = () => {
if (disableResetSelectionOnNavigation) {
return;
}
const startPaginatedIndex = (currentPage - 1) * maxPerPage;
const endPaginatedIndex = currentPage * maxPerPage;
const updatedFilteredData = filteredData.map((item, index) => {
if (index >= startPaginatedIndex && index <= endPaginatedIndex) {
return {
...item,
isRowSelected: false,
};
}
return item;
});
setFilteredData(updatedFilteredData);
if (setSelectedItems) {
setSelectedItems([]);
}
setSelectedCount(0);
};
useEffect(() => {
i18next.changeLanguage(languageCode);
}, [languageCode]);
useEffect(() => {
const propertyKeys = columns
.filter((column) => !column.excludeFromSearch)
.map((column) => column.propertyKey);
if (!_.isEqual(propertyKeys, filterablePropertyKeys)) {
setFilterablePropertyKeys(propertyKeys);
}
}, [columns, filterablePropertyKeys]);
useEffect(() => {
if (onQueryParamsChange) {
setFilteredData(data);
return;
}
const filteredAndSortedData = filterAndSortListBy(
_.cloneDeep(data),
orderBy,
orderType,
filterablePropertyKeys,
searchInput
);
setFilteredData(filteredAndSortedData);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filterablePropertyKeys, searchInput, data, onQueryParamsChange]);
useEffect(() => {
if (!data || !data.length || !filteredData.length) {
return;
}
if (allSelectedByDefault) {
selectAllRows();
return;
}
if (!queryParams) {
const alreadySelectedItems = data.filter((item) => item.isRowSelected);
setSelectedCount(alreadySelectedItems.length);
if (setSelectedItems) {
setSelectedItems(alreadySelectedItems);
}
const itemsNotSelectable = data.filter((item) => item.isNotSelectable);
setNotSelectableItemsCount(itemsNotSelectable.length);
return;
}
if (setSelectedItems) {
setSelectedItems([]);
}
setSelectedCount(0);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data]);
useEffect(() => {
if (currentPage === 1 && onQueryParamsChange) {
onQueryParamsChange({
...queryParams,
});
}
const itemsCount = onQueryParamsChange ? countElements : filteredDataCount;
setCurrentPage(
defaultCurrentPage > 0 &&
defaultCurrentPage <= Math.ceil(itemsCount / maxPerPage)
? defaultCurrentPage
: DEFAULT_PROPS.currentPage
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
countElements,
filteredDataCount,
maxPerPage,
searchInput,
orderBy,
orderType,
]);
// Order list if no dynamic pagination is set
useEffect(() => {
if (!onQueryParamsChange) {
const sortedFilteredData = sortListBy(filteredData, orderBy, orderType);
setFilteredData(sortedFilteredData);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [orderBy, orderType]);
useEffect(() => {
if (queryParams && onQueryParamsChange) {
onQueryParamsChange({
...queryParams,
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentPage]);
useEffect(() => {
if (filteredDataCount !== filteredData.length) {
setFilteredDataCount(
onQueryParamsChange ? countElements : filteredData.length
);
const alreadySelectedItems = filteredData.filter(
(item) => item.isRowSelected
);
setSelectedCount(alreadySelectedItems.length);
const itemsNotSelectable = filteredData.filter(
(item) => item.isNotSelectable
);
setNotSelectableItemsCount(itemsNotSelectable.length);
}
setPaginatedData(getPaginatedData(filteredData, maxPerPage));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
countElements,
filteredData,
maxPerPage,
filteredDataCount,
setFilteredDataCount,
]);
useImperativeHandle(ref, () => ({
resetPagination() {
if (currentPage !== 1) {
setCurrentPage(1);
}
},
getFilteredData() {
return filteredData;
},
}));
const setOrder = (columnId) => {
let updatedOrderType: 'asc' | 'desc' = 'asc';
if (orderBy === columnId) {
updatedOrderType =
orderType === ORDER_TYPE.ASCENDING
? ORDER_TYPE.DESCENDING
: ORDER_TYPE.ASCENDING;
} else {
setOrderBy(columnId);
if (handleOrderByChange && handleCurrentPageChange) {
handleOrderByChange(columnId);
handleCurrentPageChange(1);
}
}
setOrderType(updatedOrderType);
if (handleOrderTypeChange && handleCurrentPageChange) {
handleOrderTypeChange(updatedOrderType);
handleCurrentPageChange(1);
}
};
const selectRow = (_row, index) => {
const indexInFilteredData =
!currentPage || onQueryParamsChange
? index
: (currentPage - 1) * maxPerPage + index;
if (!filteredData[indexInFilteredData]) {
return;
}
if (disableMultipleSelection) {
const { isRowSelected } = filteredData[indexInFilteredData];
const updatedFilteredData = filteredData.map((item) => {
return { ...item, isRowSelected: false };
});
updatedFilteredData[indexInFilteredData].isRowSelected = !isRowSelected;
if (!isRowSelected) {
setSelectedCount(1);
} else {
setSelectedCount(0);
}
setFilteredData(updatedFilteredData);
if (setSelectedItems) {
const selectedRows = updatedFilteredData.filter(
(item) => item.isRowSelected
);
setSelectedItems(selectedRows);
}
return;
}
const updatedFilteredData = _.cloneDeep(filteredData);
const { isRowSelected } = updatedFilteredData[indexInFilteredData];
updatedFilteredData[indexInFilteredData].isRowSelected = !isRowSelected;
setFilteredData(updatedFilteredData);
if (!isRowSelected) {
setSelectedCount((count) => count + 1);
} else {
setSelectedCount((count) => count - 1);
}
if (setSelectedItems) {
const selectedRows = updatedFilteredData.filter(
(item) => item.isRowSelected
);
setSelectedItems(selectedRows);
}
};
const renderContent = (): JSX.Element => {
if (!filteredData.length && !isLoading) {
return (
{renderEmptyState && (renderEmptyState() as string)}
);
}
// eslint-disable-next-line no-nested-ternary
const isSelectable = forceEnableSelection
? true
: disableSelection
? false
: !!actions?.length;
return (
{isLoading && renderLoadingState(columns)}
{!isLoading && (
)}
);
};
return (
{!disableListOptions && (
{
resetSelection();
setSearchInput(input);
if (handleSearchInputChange && handleCurrentPageChange) {
handleSearchInputChange(input);
handleCurrentPageChange(1);
}
}}
maxActionsInLine={maxActionsInLine || 0}
itemsCount={
onQueryParamsChange ? countElements : filteredDataCount
}
selectedRows={filteredData.filter((row) => row.isRowSelected)}
exportFunction={exportFunction}
placeholderShape={placeholderShape}
placeholderShapePlural={placeholderShapePlural}
renderFilterButton={renderFilterButton}
minActionsInActionsDropdown={minActionsInActionsDropdown}
/>
)}
{renderContent()}
{!disableFooter && filteredData.length > 0 && (
{
resetSelection();
setMaxPerPage(option);
if (handleMaxPerPageChange && handleCurrentPageChange) {
handleMaxPerPageChange(option);
handleCurrentPageChange(1);
}
}}
currentPage={currentPage}
setCurrentPage={(indexCurrentPage) => {
resetSelection();
setCurrentPage(indexCurrentPage);
if (handleCurrentPageChange) {
handleCurrentPageChange(indexCurrentPage);
}
}}
isLoading={isLoading}
maxPerPageOptions={maxPerPageOptions}
hideAllPerPageOption={hideAllPerPageOption}
/>
)}
);
});
ListView.defaultProps = {
isLoading: false,
minWidth: 800,
countElements: 0,
defaultCurrentPage: DEFAULT_PROPS.currentPage,
handleCurrentPageChange: undefined,
defaultOrderBy: undefined,
handleOrderByChange: undefined,
defaultOrderType: ORDER_TYPE.ASCENDING,
handleOrderTypeChange: undefined,
defaultMaxPerPage: DEFAULT_PROPS.maxPerPage,
handleMaxPerPageChange: undefined,
maxPerPageOptions: [10, 20, 50, 100],
hideAllPerPageOption: false,
hideSearchbar: false,
defaultSearchInput: '',
handleSearchInputChange: undefined,
actions: undefined,
actionsOnHover: undefined,
rowActions: undefined,
renderEmptyState: undefined,
maxActionsInLine: 2,
exportFunction: undefined,
renderFilterButton: undefined,
actionOnClick: undefined,
placeholderShape: undefined,
placeholderShapePlural: undefined,
padding: '0',
margin: null,
setSelectedItems: undefined,
queryParams: null,
onQueryParamsChange: undefined,
languageCode: 'fr',
forceEnableSelection: false,
disableSelection: false,
disableMultipleSelection: false,
disableResetSelectionOnNavigation: false,
theme: null,
disableListOptions: false,
disableFooter: false,
markerConfiguration: undefined,
allSelectedByDefault: false,
minActionsInActionsDropdown: 2,
};
export default ListView;