forked from CITKParus/P8-Panels
WEB APP: P8PDataGrid - поддержка фиксированных заголовка и колонок
This commit is contained in:
parent
44069b0bc9
commit
4b5938e3b1
@ -35,6 +35,8 @@ const P8PDataGrid = ({
|
|||||||
groups,
|
groups,
|
||||||
rows,
|
rows,
|
||||||
size,
|
size,
|
||||||
|
fixedHeader = false,
|
||||||
|
fixedColumns = 0,
|
||||||
morePages = false,
|
morePages = false,
|
||||||
reloading,
|
reloading,
|
||||||
expandable,
|
expandable,
|
||||||
@ -111,6 +113,8 @@ const P8PDataGrid = ({
|
|||||||
orders={orders}
|
orders={orders}
|
||||||
filters={filters}
|
filters={filters}
|
||||||
size={size || P8P_DATA_GRID_SIZE.MEDIUM}
|
size={size || P8P_DATA_GRID_SIZE.MEDIUM}
|
||||||
|
fixedHeader={fixedHeader}
|
||||||
|
fixedColumns={fixedColumns}
|
||||||
morePages={morePages}
|
morePages={morePages}
|
||||||
reloading={reloading}
|
reloading={reloading}
|
||||||
expandable={expandable}
|
expandable={expandable}
|
||||||
@ -147,6 +151,8 @@ P8PDataGrid.propTypes = {
|
|||||||
groups: PropTypes.array,
|
groups: PropTypes.array,
|
||||||
rows: PropTypes.array.isRequired,
|
rows: PropTypes.array.isRequired,
|
||||||
size: PropTypes.string,
|
size: PropTypes.string,
|
||||||
|
fixedHeader: PropTypes.bool,
|
||||||
|
fixedColumns: PropTypes.number,
|
||||||
morePages: PropTypes.bool,
|
morePages: PropTypes.bool,
|
||||||
reloading: PropTypes.bool.isRequired,
|
reloading: PropTypes.bool.isRequired,
|
||||||
expandable: PropTypes.bool,
|
expandable: PropTypes.bool,
|
||||||
|
@ -33,6 +33,7 @@ import {
|
|||||||
Container,
|
Container,
|
||||||
Link
|
Link
|
||||||
} from "@mui/material"; //Интерфейсные компоненты
|
} from "@mui/material"; //Интерфейсные компоненты
|
||||||
|
import { useTheme } from "@mui/material/styles"; //Взаимодействие со стилями MUI
|
||||||
import { P8PAppInlineError } from "./p8p_app_message"; //Встраиваемое сообщение об ошибке
|
import { P8PAppInlineError } from "./p8p_app_message"; //Встраиваемое сообщение об ошибке
|
||||||
import { P8P_TABLE_AT, HEADER_INITIAL_STATE, hasValue, p8pTableReducer } from "./p8p_table_reducer"; //Редьюсер состояния
|
import { P8P_TABLE_AT, HEADER_INITIAL_STATE, hasValue, p8pTableReducer } from "./p8p_table_reducer"; //Редьюсер состояния
|
||||||
|
|
||||||
@ -85,9 +86,30 @@ const STYLES = {
|
|||||||
TABLE: {
|
TABLE: {
|
||||||
with: "100%"
|
with: "100%"
|
||||||
},
|
},
|
||||||
|
TABLE_HEAD_STICKY: {
|
||||||
|
position: "sticky",
|
||||||
|
top: 0,
|
||||||
|
zIndex: 1000
|
||||||
|
},
|
||||||
|
TABLE_HEAD_CELL_STICKY: (theme, left) => ({
|
||||||
|
position: "sticky",
|
||||||
|
left,
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
zIndex: 1000
|
||||||
|
}),
|
||||||
TABLE_ROW: {
|
TABLE_ROW: {
|
||||||
"&:last-child td, &:last-child th": { border: 0 }
|
"&:last-child td, &:last-child th": { border: 0 }
|
||||||
},
|
},
|
||||||
|
TABLE_CELL_STICKY: (theme, left) => ({
|
||||||
|
position: "sticky",
|
||||||
|
left,
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
zIndex: 500
|
||||||
|
}),
|
||||||
|
TABLE_CELL_EXPAND_CONTROL: {
|
||||||
|
minWidth: "60px",
|
||||||
|
maxWidth: "60px"
|
||||||
|
},
|
||||||
TABLE_CELL_EXPAND_CONTAINER: {
|
TABLE_CELL_EXPAND_CONTAINER: {
|
||||||
paddingBottom: 0,
|
paddingBottom: 0,
|
||||||
paddingTop: 0
|
paddingTop: 0
|
||||||
@ -95,6 +117,10 @@ const STYLES = {
|
|||||||
TABLE_CELL_GROUP_HEADER: {
|
TABLE_CELL_GROUP_HEADER: {
|
||||||
backgroundColor: "lightgray"
|
backgroundColor: "lightgray"
|
||||||
},
|
},
|
||||||
|
TABLE_CELL_GROUP_HEADER_STICKY: {
|
||||||
|
position: "sticky",
|
||||||
|
left: 0
|
||||||
|
},
|
||||||
TABLE_COLUMN_STACK: {
|
TABLE_COLUMN_STACK: {
|
||||||
alignItems: "center"
|
alignItems: "center"
|
||||||
},
|
},
|
||||||
@ -460,6 +486,8 @@ const P8PTable = ({
|
|||||||
orders,
|
orders,
|
||||||
filters,
|
filters,
|
||||||
size,
|
size,
|
||||||
|
fixedHeader = false,
|
||||||
|
fixedColumns = 0,
|
||||||
morePages = false,
|
morePages = false,
|
||||||
reloading,
|
reloading,
|
||||||
expandable,
|
expandable,
|
||||||
@ -501,6 +529,9 @@ const P8PTable = ({
|
|||||||
//Собственное состояние - колонка с отображаемой подсказкой
|
//Собственное состояние - колонка с отображаемой подсказкой
|
||||||
const [displayHintColumn, setDisplayHintColumn] = useState(null);
|
const [displayHintColumn, setDisplayHintColumn] = useState(null);
|
||||||
|
|
||||||
|
//Стили
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
//Описание фильтруемой колонки
|
//Описание фильтруемой колонки
|
||||||
const filterColumnDef = filterColumn ? columnsDef.find(columnDef => columnDef.name == filterColumn) || null : null;
|
const filterColumnDef = filterColumn ? columnsDef.find(columnDef => columnDef.name == filterColumn) || null : null;
|
||||||
|
|
||||||
@ -516,12 +547,12 @@ const P8PTable = ({
|
|||||||
: ["", ""];
|
: ["", ""];
|
||||||
|
|
||||||
//Формирование заголовка таблицы
|
//Формирование заголовка таблицы
|
||||||
const setHeader = ({ columnsDef, expandable, objectsCopier }) =>
|
const setHeader = ({ columnsDef, expandable, fixedColumns, objectsCopier }) =>
|
||||||
dispatchHeaderAction({ type: P8P_TABLE_AT.SET_HEADER, payload: { columnsDef, expandable, objectsCopier } });
|
dispatchHeaderAction({ type: P8P_TABLE_AT.SET_HEADER, payload: { columnsDef, expandable, fixedColumns, objectsCopier } });
|
||||||
|
|
||||||
//Сворачивание/разворачивание уровня заголовка таблицы
|
//Сворачивание/разворачивание уровня заголовка таблицы
|
||||||
const toggleHeaderExpand = ({ columnName, objectsCopier }) =>
|
const toggleHeaderExpand = ({ columnName, objectsCopier }) =>
|
||||||
dispatchHeaderAction({ type: P8P_TABLE_AT.TOGGLE_HEADER_EXPAND, payload: { columnName, expandable, objectsCopier } });
|
dispatchHeaderAction({ type: P8P_TABLE_AT.TOGGLE_HEADER_EXPAND, payload: { columnName, expandable, fixedColumns, objectsCopier } });
|
||||||
|
|
||||||
//Выравнивание в зависимости от типа данных
|
//Выравнивание в зависимости от типа данных
|
||||||
const getAlignByDataType = ({ dataType, hasChild }) =>
|
const getAlignByDataType = ({ dataType, hasChild }) =>
|
||||||
@ -621,38 +652,46 @@ const P8PTable = ({
|
|||||||
|
|
||||||
//При изменении описания колонок
|
//При изменении описания колонок
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setHeader({ columnsDef, expandable, objectsCopier });
|
setHeader({ columnsDef, expandable, fixedColumns, objectsCopier });
|
||||||
}, [columnsDef, expandable, objectsCopier]);
|
}, [columnsDef, expandable, fixedColumns, objectsCopier]);
|
||||||
|
|
||||||
//Генерация заголовка группы
|
//Генерация заголовка группы
|
||||||
const renderGroupCell = group => {
|
const renderGroupCell = group => {
|
||||||
let customRender = {};
|
let customRender = {};
|
||||||
if (groupCellRender) customRender = groupCellRender({ columnsDef: header.columnsDef, group }) || {};
|
if (groupCellRender) customRender = groupCellRender({ columnsDef: header.columnsDef, group }) || {};
|
||||||
return (
|
return header.displayDataColumns.map((columnDef, i) => (
|
||||||
<TableCell
|
<TableCell
|
||||||
colSpan={header.displayDataColumnsCount}
|
key={`group-header-cell-${i}`}
|
||||||
sx={{ ...STYLES.TABLE_CELL_GROUP_HEADER, ...customRender.cellStyle }}
|
|
||||||
{...customRender.cellProps}
|
{...customRender.cellProps}
|
||||||
|
sx={{
|
||||||
|
...STYLES.TABLE_CELL_GROUP_HEADER,
|
||||||
|
...customRender.cellStyle,
|
||||||
|
...(columnDef.width ? { minWidth: columnDef.width, maxWidth: columnDef.width } : {}),
|
||||||
|
...(i == 0 && fixedColumns ? STYLES.TABLE_CELL_GROUP_HEADER_STICKY : {})
|
||||||
|
}}
|
||||||
|
colSpan={expandable && rowExpandRender ? 2 : 1}
|
||||||
>
|
>
|
||||||
<Stack direction="row" sx={STYLES.TABLE_COLUMN_STACK}>
|
{i == 0 ? (
|
||||||
{group.expandable ? (
|
<Stack direction="row" sx={STYLES.TABLE_COLUMN_STACK}>
|
||||||
<IconButton
|
{group.expandable ? (
|
||||||
onClick={() => {
|
<IconButton
|
||||||
setExpandedGroups(pv => ({ ...pv, ...{ [group.name]: !pv[group.name] } }));
|
onClick={() => {
|
||||||
}}
|
setExpandedGroups(pv => ({ ...pv, ...{ [group.name]: !pv[group.name] } }));
|
||||||
>
|
}}
|
||||||
<Icon>{expandedGroups[group.name] ? "indeterminate_check_box" : "add_box"}</Icon>
|
>
|
||||||
</IconButton>
|
<Icon>{expandedGroups[group.name] ? "indeterminate_check_box" : "add_box"}</Icon>
|
||||||
) : null}
|
</IconButton>
|
||||||
{customRender.data ? customRender.data : group.caption}
|
) : null}
|
||||||
</Stack>
|
{customRender.data ? customRender.data : group.caption}
|
||||||
|
</Stack>
|
||||||
|
) : null}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
);
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
//Генерация содержимого
|
//Генерация содержимого
|
||||||
return (
|
return (
|
||||||
<>
|
<div>
|
||||||
{displayHintColumn ? (
|
{displayHintColumn ? (
|
||||||
<P8PTableColumnHintDialog columnDef={displayHintColumnDef} okBtnCaption={okFilterBtnCaption} onOk={handleHintOk} />
|
<P8PTableColumnHintDialog columnDef={displayHintColumnDef} okBtnCaption={okFilterBtnCaption} onOk={handleHintOk} />
|
||||||
) : null}
|
) : null}
|
||||||
@ -684,13 +723,22 @@ const P8PTable = ({
|
|||||||
valueFormatter={valueFormatter}
|
valueFormatter={valueFormatter}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<TableContainer component={containerComponent ? containerComponent : Paper} {...(containerComponentProps ? containerComponentProps : {})}>
|
<TableContainer component={containerComponent ? containerComponent : Paper} {...(containerComponentProps ? containerComponentProps : {})}>
|
||||||
<Table sx={STYLES.TABLE} size={size || P8P_TABLE_SIZE.MEDIUM}>
|
<Table stickyHeader={fixedHeader} sx={STYLES.TABLE} size={size || P8P_TABLE_SIZE.MEDIUM}>
|
||||||
<TableHead>
|
<TableHead sx={fixedHeader ? STYLES.TABLE_HEAD_STICKY : {}}>
|
||||||
{header.displayLevels.map(level => (
|
{header.displayLevels.map((level, i) => (
|
||||||
<TableRow key={level}>
|
<TableRow key={level}>
|
||||||
{expandable && rowExpandRender ? <TableCell key="head-cell-expand-control" align="center"></TableCell> : null}
|
{expandable && rowExpandRender && i == 0 ? (
|
||||||
|
<TableCell
|
||||||
|
key="head-cell-expand-control"
|
||||||
|
align="center"
|
||||||
|
sx={{
|
||||||
|
...STYLES.TABLE_CELL_EXPAND_CONTROL,
|
||||||
|
...(fixedColumns ? STYLES.TABLE_HEAD_CELL_STICKY(theme, 0) : {})
|
||||||
|
}}
|
||||||
|
rowSpan={header.displayLevelsColumns[level][0].rowSpan}
|
||||||
|
></TableCell>
|
||||||
|
) : null}
|
||||||
{header.displayLevelsColumns[level].map((columnDef, j) => {
|
{header.displayLevelsColumns[level].map((columnDef, j) => {
|
||||||
let customRender = {};
|
let customRender = {};
|
||||||
if (headCellRender) customRender = headCellRender({ columnDef }) || {};
|
if (headCellRender) customRender = headCellRender({ columnDef }) || {};
|
||||||
@ -698,7 +746,11 @@ const P8PTable = ({
|
|||||||
<TableCell
|
<TableCell
|
||||||
key={`head-cell-${j}`}
|
key={`head-cell-${j}`}
|
||||||
align={getAlignByDataType(columnDef)}
|
align={getAlignByDataType(columnDef)}
|
||||||
sx={{ ...customRender.cellStyle }}
|
sx={{
|
||||||
|
...customRender.cellStyle,
|
||||||
|
...(columnDef.width ? { minWidth: columnDef.width, maxWidth: columnDef.width } : {}),
|
||||||
|
...(columnDef.fixed ? STYLES.TABLE_HEAD_CELL_STICKY(theme, columnDef.fixedLeft) : {})
|
||||||
|
}}
|
||||||
rowSpan={columnDef.rowSpan}
|
rowSpan={columnDef.rowSpan}
|
||||||
colSpan={columnDef.colSpan}
|
colSpan={columnDef.colSpan}
|
||||||
{...customRender.cellProps}
|
{...customRender.cellProps}
|
||||||
@ -753,7 +805,14 @@ const P8PTable = ({
|
|||||||
<React.Fragment key={`data-${i}`}>
|
<React.Fragment key={`data-${i}`}>
|
||||||
<TableRow key={`data-row-${i}`} sx={STYLES.TABLE_ROW}>
|
<TableRow key={`data-row-${i}`} sx={STYLES.TABLE_ROW}>
|
||||||
{expandable && rowExpandRender ? (
|
{expandable && rowExpandRender ? (
|
||||||
<TableCell key={`data-cell-expand-control-${i}`} align="center">
|
<TableCell
|
||||||
|
key={`data-cell-expand-control-${i}`}
|
||||||
|
align="center"
|
||||||
|
sx={{
|
||||||
|
...STYLES.TABLE_CELL_EXPAND_CONTROL,
|
||||||
|
...(fixedColumns ? STYLES.TABLE_CELL_STICKY(theme, 0) : {})
|
||||||
|
}}
|
||||||
|
>
|
||||||
<IconButton onClick={() => handleExpandClick(i)}>
|
<IconButton onClick={() => handleExpandClick(i)}>
|
||||||
<Icon>{expanded[i] === true ? "keyboard_arrow_down" : "keyboard_arrow_right"}</Icon>
|
<Icon>{expanded[i] === true ? "keyboard_arrow_down" : "keyboard_arrow_right"}</Icon>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@ -766,7 +825,13 @@ const P8PTable = ({
|
|||||||
<TableCell
|
<TableCell
|
||||||
key={`data-cell-${j}`}
|
key={`data-cell-${j}`}
|
||||||
align={getAlignByDataType(columnDef)}
|
align={getAlignByDataType(columnDef)}
|
||||||
sx={{ ...customRender.cellStyle }}
|
sx={{
|
||||||
|
...customRender.cellStyle,
|
||||||
|
...(columnDef.width
|
||||||
|
? { minWidth: columnDef.width, maxWidth: columnDef.width }
|
||||||
|
: {}),
|
||||||
|
...(columnDef.fixed ? STYLES.TABLE_CELL_STICKY(theme, columnDef.fixedLeft) : {})
|
||||||
|
}}
|
||||||
{...customRender.cellProps}
|
{...customRender.cellProps}
|
||||||
>
|
>
|
||||||
{customRender.data
|
{customRender.data
|
||||||
@ -780,7 +845,15 @@ const P8PTable = ({
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
{expandable && rowExpandRender && expanded[i] === true ? (
|
{expandable && rowExpandRender && expanded[i] === true ? (
|
||||||
<TableRow key={`data-row-expand-${i}`}>
|
<TableRow key={`data-row-expand-${i}`}>
|
||||||
<TableCell sx={STYLES.TABLE_CELL_EXPAND_CONTAINER} colSpan={header.displayDataColumnsCount}>
|
<TableCell
|
||||||
|
sx={{
|
||||||
|
...STYLES.TABLE_CELL_EXPAND_CONTAINER,
|
||||||
|
...(fixedColumns ? STYLES.TABLE_CELL_STICKY(theme, 0) : {})
|
||||||
|
}}
|
||||||
|
colSpan={
|
||||||
|
fixedColumns ? header.displayFixedColumnsCount + 1 : header.displayDataColumnsCount
|
||||||
|
}
|
||||||
|
>
|
||||||
{rowExpandRender({ columnsDef, row })}
|
{rowExpandRender({ columnsDef, row })}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
@ -800,19 +873,19 @@ const P8PTable = ({
|
|||||||
: null}
|
: null}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
{rows.length == 0 ? (
|
|
||||||
noDataFoundText && !reloading ? (
|
|
||||||
<P8PAppInlineError text={noDataFoundText} />
|
|
||||||
) : null
|
|
||||||
) : morePages ? (
|
|
||||||
<Container style={STYLES.MORE_BUTTON_CONTAINER}>
|
|
||||||
<Button fullWidth onClick={handleMorePagesBtnClick}>
|
|
||||||
{morePagesBtnCaption}
|
|
||||||
</Button>
|
|
||||||
</Container>
|
|
||||||
) : null}
|
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
</>
|
{rows.length == 0 ? (
|
||||||
|
noDataFoundText && !reloading ? (
|
||||||
|
<P8PAppInlineError text={noDataFoundText} />
|
||||||
|
) : null
|
||||||
|
) : morePages ? (
|
||||||
|
<Container style={STYLES.MORE_BUTTON_CONTAINER}>
|
||||||
|
<Button fullWidth onClick={handleMorePagesBtnClick}>
|
||||||
|
{morePagesBtnCaption}
|
||||||
|
</Button>
|
||||||
|
</Container>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -829,7 +902,8 @@ P8PTable.propTypes = {
|
|||||||
values: PropTypes.array,
|
values: PropTypes.array,
|
||||||
parent: PropTypes.string,
|
parent: PropTypes.string,
|
||||||
expandable: PropTypes.bool.isRequired,
|
expandable: PropTypes.bool.isRequired,
|
||||||
expanded: PropTypes.bool.isRequired
|
expanded: PropTypes.bool.isRequired,
|
||||||
|
width: PropTypes.number
|
||||||
})
|
})
|
||||||
).isRequired,
|
).isRequired,
|
||||||
groups: PropTypes.arrayOf(
|
groups: PropTypes.arrayOf(
|
||||||
@ -849,6 +923,8 @@ P8PTable.propTypes = {
|
|||||||
).isRequired,
|
).isRequired,
|
||||||
filters: PropTypes.arrayOf(P8P_TABLE_FILTER_SHAPE).isRequired,
|
filters: PropTypes.arrayOf(P8P_TABLE_FILTER_SHAPE).isRequired,
|
||||||
size: PropTypes.string,
|
size: PropTypes.string,
|
||||||
|
fixedHeader: PropTypes.bool,
|
||||||
|
fixedColumns: PropTypes.number,
|
||||||
morePages: PropTypes.bool,
|
morePages: PropTypes.bool,
|
||||||
reloading: PropTypes.bool.isRequired,
|
reloading: PropTypes.bool.isRequired,
|
||||||
expandable: PropTypes.bool,
|
expandable: PropTypes.bool,
|
||||||
|
@ -19,7 +19,8 @@ const HEADER_INITIAL_STATE = () => ({
|
|||||||
displayLevels: [],
|
displayLevels: [],
|
||||||
displayLevelsColumns: {},
|
displayLevelsColumns: {},
|
||||||
displayDataColumnsCount: 0,
|
displayDataColumnsCount: 0,
|
||||||
displayDataColumns: []
|
displayDataColumns: [],
|
||||||
|
displayFixedColumnsCount: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
//Состояние описания ячейки заголовка таблицы по умолчанию
|
//Состояние описания ячейки заголовка таблицы по умолчанию
|
||||||
@ -28,6 +29,8 @@ const HEADER_COLUMN_INITIAL_STATE = ({ columnDef, objectsCopier }) => {
|
|||||||
if (!hasValue(tmp.parent)) tmp.parent = "";
|
if (!hasValue(tmp.parent)) tmp.parent = "";
|
||||||
if (!hasValue(tmp.expandable)) tmp.expandable = false;
|
if (!hasValue(tmp.expandable)) tmp.expandable = false;
|
||||||
if (!hasValue(tmp.expanded)) tmp.expanded = true;
|
if (!hasValue(tmp.expanded)) tmp.expanded = true;
|
||||||
|
if (!hasValue(tmp.fixed)) tmp.fixed = false;
|
||||||
|
if (!hasValue(tmp.fixedLeft)) tmp.fixedLeft = 0;
|
||||||
return tmp;
|
return tmp;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,8 +58,23 @@ const getDisplayColumnColSpan = (displayTree, columnDef) => {
|
|||||||
} else return 1;
|
} else return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Определения признака зафиксированности колонки
|
||||||
|
const getFixedColumns = (displayTree, parentFixed, parentLeft, fixedColumns) => {
|
||||||
|
if (fixedColumns) {
|
||||||
|
let left = parentLeft;
|
||||||
|
displayTree.forEach((columnDef, i) => {
|
||||||
|
left += columnDef.width;
|
||||||
|
if ((columnDef.level == 1 && i + 1 <= fixedColumns) || (columnDef.level > 1 && parentFixed)) {
|
||||||
|
columnDef.fixed = true;
|
||||||
|
columnDef.fixedLeft = left - columnDef.width;
|
||||||
|
} else columnDef.fixed = false;
|
||||||
|
if (columnDef.hasChild) getFixedColumns(columnDef.child, columnDef.fixed, columnDef.fixedLeft, fixedColumns);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//Формирование дерева отображаемых элементов заголовка
|
//Формирование дерева отображаемых элементов заголовка
|
||||||
const buildDisplayTree = (columnsDef, parent, level) => {
|
const buildDisplayTree = (columnsDef, parent, level, expandable, fixedColumns) => {
|
||||||
const baseBuild = (columnsDef, parent, level) => {
|
const baseBuild = (columnsDef, parent, level) => {
|
||||||
let maxLevel = level - 1;
|
let maxLevel = level - 1;
|
||||||
const res = columnsDef
|
const res = columnsDef
|
||||||
@ -77,6 +95,7 @@ const buildDisplayTree = (columnsDef, parent, level) => {
|
|||||||
};
|
};
|
||||||
const [displayTree, maxLevel] = baseBuild(columnsDef, parent, level);
|
const [displayTree, maxLevel] = baseBuild(columnsDef, parent, level);
|
||||||
getDisplayColumnRowSpan(displayTree, maxLevel);
|
getDisplayColumnRowSpan(displayTree, maxLevel);
|
||||||
|
getFixedColumns(displayTree, false, expandable ? 60 : 0, fixedColumns);
|
||||||
return [displayTree, maxLevel];
|
return [displayTree, maxLevel];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -106,28 +125,41 @@ const buildDisplayDataColumns = (displayTree, expandable) => {
|
|||||||
return [displayDataColumns, displayDataColumns.length + (expandable === true ? 1 : 0)];
|
return [displayDataColumns, displayDataColumns.length + (expandable === true ? 1 : 0)];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Подсчёт количества отображаемых фиксированных колонок
|
||||||
|
const getDisplayFixedColumnsCount = displayTree => {
|
||||||
|
let res = 0;
|
||||||
|
const traverseTree = displayTree => {
|
||||||
|
displayTree.forEach(columnDef => (columnDef.hasChild ? traverseTree(columnDef.child) : columnDef.fixed ? res++ : null));
|
||||||
|
};
|
||||||
|
traverseTree(displayTree);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
//Формирование описания отображаемых колонок
|
//Формирование описания отображаемых колонок
|
||||||
const buildDisplay = ({ columnsDef, expandable }) => {
|
const buildDisplay = ({ columnsDef, expandable, fixedColumns }) => {
|
||||||
//Сформируем дерево отображаемых колонок заголовка
|
//Сформируем дерево отображаемых колонок заголовка
|
||||||
const [displayTree, maxLevel] = buildDisplayTree(columnsDef, "", 1);
|
const [displayTree, maxLevel] = buildDisplayTree(columnsDef, "", 1, expandable, fixedColumns);
|
||||||
//Вытянем дерево в удобные для рендеринга структуры
|
//Вытянем дерево в удобные для рендеринга структуры
|
||||||
const [displayLevels, displayLevelsColumns] = buildDisplayLevelsColumns(displayTree, maxLevel);
|
const [displayLevels, displayLevelsColumns] = buildDisplayLevelsColumns(displayTree, maxLevel);
|
||||||
//Сформируем отображаемые колонки данных
|
//Сформируем отображаемые колонки данных
|
||||||
const [displayDataColumns, displayDataColumnsCount] = buildDisplayDataColumns(displayTree, expandable);
|
const [displayDataColumns, displayDataColumnsCount] = buildDisplayDataColumns(displayTree, expandable);
|
||||||
|
//Подсчитаем количество отображаемых фиксированных колонок
|
||||||
|
const displayFixedColumnsCount = getDisplayFixedColumnsCount(displayTree);
|
||||||
//Вернём результат
|
//Вернём результат
|
||||||
return [displayLevels, displayLevelsColumns, displayDataColumns, displayDataColumnsCount];
|
return [displayLevels, displayLevelsColumns, displayDataColumns, displayDataColumnsCount, displayFixedColumnsCount];
|
||||||
};
|
};
|
||||||
|
|
||||||
//Формирование описания заголовка
|
//Формирование описания заголовка
|
||||||
const buildHeaderDef = ({ columnsDef, expandable, objectsCopier }) => {
|
const buildHeaderDef = ({ columnsDef, expandable, fixedColumns, objectsCopier }) => {
|
||||||
//Инициализируем результат
|
//Инициализируем результат
|
||||||
const res = HEADER_INITIAL_STATE();
|
const res = HEADER_INITIAL_STATE();
|
||||||
//Инициализируем внутренне описание колонок и поместим его в результат
|
//Инициализируем внутренне описание колонок и поместим его в результат
|
||||||
columnsDef.forEach(columnDef => res.columnsDef.push(HEADER_COLUMN_INITIAL_STATE({ columnDef, objectsCopier })));
|
columnsDef.forEach(columnDef => res.columnsDef.push(HEADER_COLUMN_INITIAL_STATE({ columnDef, objectsCopier })));
|
||||||
//Добавим в результат сведения об отображаемых данных
|
//Добавим в результат сведения об отображаемых данных
|
||||||
[res.displayLevels, res.displayLevelsColumns, res.displayDataColumns, res.displayDataColumnsCount] = buildDisplay({
|
[res.displayLevels, res.displayLevelsColumns, res.displayDataColumns, res.displayDataColumnsCount, res.displayFixedColumnsCount] = buildDisplay({
|
||||||
columnsDef: res.columnsDef,
|
columnsDef: res.columnsDef,
|
||||||
expandable
|
expandable,
|
||||||
|
fixedColumns
|
||||||
});
|
});
|
||||||
//Сформируем дерево отображаемых колонок заголовка
|
//Сформируем дерево отображаемых колонок заголовка
|
||||||
//const [displayTree, maxLevel] = buildDisplayTree(res.columnsDef, "", 1);
|
//const [displayTree, maxLevel] = buildDisplayTree(res.columnsDef, "", 1);
|
||||||
@ -147,19 +179,20 @@ const buildHeaderDef = ({ columnsDef, expandable, objectsCopier }) => {
|
|||||||
const handlers = {
|
const handlers = {
|
||||||
//Формирование заголовка
|
//Формирование заголовка
|
||||||
[P8P_TABLE_AT.SET_HEADER]: (state, { payload }) => {
|
[P8P_TABLE_AT.SET_HEADER]: (state, { payload }) => {
|
||||||
const { columnsDef, expandable, objectsCopier } = payload;
|
const { columnsDef, expandable, fixedColumns, objectsCopier } = payload;
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
...buildHeaderDef({ columnsDef, expandable, objectsCopier })
|
...buildHeaderDef({ columnsDef, expandable, fixedColumns, objectsCopier })
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[P8P_TABLE_AT.TOGGLE_HEADER_EXPAND]: (state, { payload }) => {
|
[P8P_TABLE_AT.TOGGLE_HEADER_EXPAND]: (state, { payload }) => {
|
||||||
const { columnName, expandable, objectsCopier } = payload;
|
const { columnName, expandable, fixedColumns, objectsCopier } = payload;
|
||||||
const columnsDef = objectsCopier(state.columnsDef);
|
const columnsDef = objectsCopier(state.columnsDef);
|
||||||
columnsDef.forEach(columnDef => (columnDef.name == columnName ? (columnDef.expanded = !columnDef.expanded) : null));
|
columnsDef.forEach(columnDef => (columnDef.name == columnName ? (columnDef.expanded = !columnDef.expanded) : null));
|
||||||
const [displayLevels, displayLevelsColumns, displayDataColumns, displayDataColumnsCount] = buildDisplay({
|
const [displayLevels, displayLevelsColumns, displayDataColumns, displayDataColumnsCount, displayFixedColumnsCount] = buildDisplay({
|
||||||
columnsDef,
|
columnsDef,
|
||||||
expandable
|
expandable,
|
||||||
|
fixedColumns
|
||||||
});
|
});
|
||||||
//const [displayTree, maxLevel] = buildDisplayTree(columnsDef, "", 1);
|
//const [displayTree, maxLevel] = buildDisplayTree(columnsDef, "", 1);
|
||||||
//const [displayLevels, displayLevelsColumns] = buildDisplayLevelsColumns(displayTree, maxLevel);
|
//const [displayLevels, displayLevelsColumns] = buildDisplayLevelsColumns(displayTree, maxLevel);
|
||||||
@ -170,7 +203,8 @@ const handlers = {
|
|||||||
displayLevels,
|
displayLevels,
|
||||||
displayLevelsColumns,
|
displayLevelsColumns,
|
||||||
displayDataColumns,
|
displayDataColumns,
|
||||||
displayDataColumnsCount
|
displayDataColumnsCount,
|
||||||
|
displayFixedColumnsCount
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
//Обработчик по умолчанию
|
//Обработчик по умолчанию
|
||||||
|
Loading…
x
Reference in New Issue
Block a user