import PropTypes, { string } from 'prop-types';
import moment from 'moment';
import { ThemeProvider } from 'styled-components';
import React, { useState, Fragment, useEffect } from 'react';
import { isEmpty } from 'lodash';
import { ORDER_TYPE } from './constants';
import {
NestedListContainer,
RowsContainer,
BorderedContainer,
RowContainer,
Container,
FixedRowContainer,
FixedRowsContainer,
PaginatorContainer,
GlobalContainer,
} from './styledComponents';
import HeaderRow from './components/HeaderRow/HeaderRow';
import EmptyState from './components/EmptyState';
import LoadingState from './components/LoadingState/LoadingStateDisplay';
import useInteractDataRowAndGraph from './customHook/useInteractDataRowAndGraph';
import Row from './components/Row/Row';
import { getTheme } from '../utils/theme';
import { Props } from './interface';
import Paginator from '../Paginator';
const NestedList = (props: Props): JSX.Element => {
const {
theme,
headers,
modalHeaders,
data,
fixedRowsData,
isLoading,
isExpandable,
defaultOrderBy,
defaultOrderType,
customMultipleOrder,
minWidth,
customModalIcon,
labelEmptyState,
iconEmptyState,
iconSizeEmptyState,
modalTitle,
labelModalEmptyState,
graphEmptyStateLabel,
languageCode,
hasNestedData,
hasPagination,
maxPerPageOptions,
hideAllPerPageOption,
customSortProperty,
customSortFunc,
customNestedContentPadding,
currentPage,
setCurrentPage,
maxPerPage,
setMaxPerPage,
customContentHeight,
} = props;
const updatedTheme = getTheme(theme);
const [orderBy, setOrderBy] = useState(defaultOrderBy);
const [multipleOrderBy, setMultipleOrderBy] = useState(
customMultipleOrder.orderBy
);
const [orderType, setOrderType] = useState<'asc' | 'desc'>(defaultOrderType);
const [multipleOrderType, setMultipleOrderType] = useState(
customMultipleOrder.orderType
);
useEffect(() => {
moment.locale(languageCode);
}, [languageCode]);
useEffect(() => {
setOrderBy(defaultOrderBy);
}, [defaultOrderBy]);
useEffect(() => {
if (!isEmpty(customMultipleOrder)) {
setMultipleOrderBy(customMultipleOrder.orderBy);
setMultipleOrderType(customMultipleOrder.orderType);
}
}, [customMultipleOrder]);
const setOrderColumn = (headerPropertyKey) => {
if (orderBy === headerPropertyKey) {
const newOrderType =
orderType === ORDER_TYPE.ASCENDING
? ORDER_TYPE.DESCENDING
: ORDER_TYPE.ASCENDING;
setOrderType(newOrderType);
if (!isEmpty(customMultipleOrder)) {
setMultipleOrderType([newOrderType, ...customMultipleOrder.orderType]);
}
return;
}
setOrderBy(headerPropertyKey);
setOrderType(ORDER_TYPE.ASCENDING);
if (!isEmpty(customMultipleOrder)) {
setMultipleOrderBy([headerPropertyKey, ...customMultipleOrder.orderBy]);
setMultipleOrderType([
ORDER_TYPE.ASCENDING,
...customMultipleOrder.orderType,
]);
}
};
const interactData = useInteractDataRowAndGraph({
data,
headers,
orderBy,
orderType,
maxPerPage,
currentPage,
hasPagination,
customSortProperty,
customSortFunc,
multipleOrderBy,
multipleOrderType,
customMultipleOrder,
});
const handleOpenRow = (item, rowIndex: number, isRowFixed: boolean): void => {
if (
!isExpandable ||
isRowFixed ||
(!item.nestedContent && !item.graphContent && !item.nestedData)
) {
return;
}
interactData.openRow(rowIndex, !!hasNestedData);
};
const renderRow = (item, index, isFixed = false) => {
return (
handleOpenRow(item, index, isFixed)}
openModal={() => interactData.openModal(index, 'modalOpened')}
customModalIcon={customModalIcon}
modalTitle={modalTitle}
modalHeaders={modalHeaders || []}
labelModalEmptyState={labelModalEmptyState || ''}
graphEmptyStateLabel={graphEmptyStateLabel}
customNestedContentPadding={customNestedContentPadding}
isBold={isFixed}
hasNestedData={hasNestedData}
/>
);
};
if (isLoading) {
return (
);
}
if (!data.length) {
return (
;
);
}
return (
{/*
Handle display of fix rows on top of the listing from fixedRowsData props
(usually TOTAL lines or something else)
*/}
{fixedRowsData.length > 0 && (
{fixedRowsData.map((item, index) => (
{renderRow(item, index, true)}
))}
)}
{/* Handle display of each element in the listing from data props */}
{interactData.dataState.map((item, index) => (
{renderRow(item, index)}
))}
{hasPagination && data.length > 0 && (
)}
);
};
NestedList.propTypes = {
minWidth: PropTypes.string,
headers: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
propertyKey: PropTypes.string.isRequired,
isNumber: PropTypes.bool,
unit: PropTypes.string,
tooltipDisplay: PropTypes.string,
isSortable: PropTypes.bool.isRequired,
large: PropTypes.bool,
narrow: PropTypes.bool,
customModalRender: PropTypes.bool,
})
).isRequired,
data: PropTypes.arrayOf(PropTypes.objectOf(PropTypes.any)).isRequired,
fixedRowsData: PropTypes.arrayOf(PropTypes.objectOf(PropTypes.any)),
isLoading: PropTypes.bool,
isExpandable: PropTypes.bool,
defaultOrderBy: PropTypes.string,
defaultOrderType: PropTypes.string,
customMultipleOrder: PropTypes.shape({
orderBy: PropTypes.arrayOf(string),
orderType: PropTypes.arrayOf(string),
customOrderByFunc: PropTypes.func,
}),
customModalIcon: PropTypes.string,
labelEmptyState: PropTypes.string,
// eslint-disable-next-line react/forbid-prop-types
iconEmptyState: PropTypes.any,
iconSizeEmptyState: PropTypes.string,
labelModalEmptyState: PropTypes.string,
modalTitle: PropTypes.string,
modalHeaders: PropTypes.arrayOf(
PropTypes.shape({
propertyKey: PropTypes.string.isRequired,
})
),
// eslint-disable-next-line react/forbid-prop-types
theme: PropTypes.objectOf(PropTypes.any),
graphEmptyStateLabel: PropTypes.string,
languageCode: PropTypes.string,
hasNestedData: PropTypes.bool,
hasPagination: PropTypes.bool,
maxPerPageOptions: PropTypes.arrayOf(PropTypes.number),
hideAllPerPageOption: PropTypes.bool,
customSortProperty: PropTypes.string,
customSortFunc: PropTypes.func,
customNestedContentPadding: PropTypes.string,
customContentHeight: PropTypes.string,
};
NestedList.defaultProps = {
minWidth: '1200px',
isLoading: false,
isExpandable: true,
defaultOrderBy: undefined,
defaultOrderType: ORDER_TYPE.ASCENDING,
customMultipleOrder: {},
customModalIcon: null,
theme: null,
labelEmptyState: 'Aucun résultat ne correspond à votre recherche',
iconEmptyState: null,
iconSizeEmptyState: null,
labelModalEmptyState:
'Aucune commande dans les 15 prochains jours pour cet ingrédient',
modalTitle: null,
modalHeaders: [],
fixedRowsData: [],
graphEmptyStateLabel: '',
languageCode: 'fr',
hasNestedData: false,
hasPagination: false,
maxPerPageOptions: [10, 20, 50, 100],
hideAllPerPageOption: false,
customSortProperty: null,
customSortFunc: null,
customNestedContentPadding: '',
customContentHeight: '',
};
export default NestedList;