forked from CITKParus/P8-Panels
201 lines
9.1 KiB
JavaScript
201 lines
9.1 KiB
JavaScript
import React, { useState } from "react";
|
||
|
||
import { hasValue } from "../../core/utils";
|
||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||
import { Stack, Chip, Typography, Box } from "@mui/material"; //Интерфейсные компоненты
|
||
import { P8P_DATA_TYPES } from "../../core/data_types";
|
||
import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper";
|
||
import { P8P_BOX_HEADER_FILTER_CUSTOM } from "../../theme/styles/box";
|
||
import { P8P_TYPOGRAPHY_VARIANT } from "../../theme/p8p_typography";
|
||
import { P8P_TYPOGRAPHY_MAX_LINES } from "../../theme/styles/typography";
|
||
import { P8P_STACK_HEADER_FILTER } from "../../theme/styles/stack";
|
||
import { P8PTableColumnFilterDialog } from "../p8p_table/p8p_table_column_filter_dialog";
|
||
|
||
const FilterComponent = ({ filter, columnDef, valueFromCaption, valueToCaption, valueFormatter, onFilterChanged }) => {
|
||
//Собственное состояние - фильтруемая колонка
|
||
const [filterColumn, setFilterColumn] = useState(null);
|
||
const isClickable = false;
|
||
|
||
//Значения фильтра фильтруемой колонки
|
||
const [filterColumnFrom, filterColumnTo] = filterColumn
|
||
? (() => {
|
||
return filter ? [filter.from == null ? "" : filter.from, filter.to == null ? "" : filter.to] : ["", ""];
|
||
})()
|
||
: ["", ""];
|
||
|
||
//Отработка ввода значения фильтра колонки
|
||
const handleFilterOk = (columnName, from, to) => {
|
||
if (onFilterChanged) onFilterChanged({ columnName, from: from === "" ? null : from, to: to === "" ? null : to });
|
||
setFilterColumn(null);
|
||
};
|
||
|
||
//Отработка очистки значения фильтра колонки
|
||
const handleFilterClear = columnName => {
|
||
if (onFilterChanged) onFilterChanged({ columnName, from: null, to: null });
|
||
setFilterColumn(null);
|
||
};
|
||
|
||
//Отработка отмены ввода значения фильтра колонки
|
||
const handleFilterCancel = () => {
|
||
setFilterColumn(null);
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<Stack sx={P8P_STACK_HEADER_FILTER({ isClickable })}>
|
||
<Typography
|
||
sx={P8P_TYPOGRAPHY_MAX_LINES({ maxLines: 1 })}
|
||
variant={P8P_TYPOGRAPHY_VARIANT.BODY2}
|
||
color="P8PText.secondary"
|
||
title={columnDef.name}
|
||
noWrap
|
||
>
|
||
{columnDef.name}
|
||
</Typography>
|
||
<Box typography={"P8PBody2"} sx={P8P_BOX_HEADER_FILTER_CUSTOM} onClick={() => setFilterColumn(columnDef.name)}>
|
||
<Typography variant={P8P_TYPOGRAPHY_VARIANT.BODY2}>
|
||
{hasValue(filter.from) && !columnDef.values && columnDef.dataType != P8P_DATA_TYPES.STR
|
||
? `${valueFromCaption.toLowerCase()} `
|
||
: null}
|
||
{hasValue(filter.from) ? (valueFormatter ? valueFormatter({ value: filter.from, columnDef }) : filter.from) : null}
|
||
{hasValue(filter.to) && !columnDef.values && columnDef.dataType != P8P_DATA_TYPES.STR
|
||
? ` ${valueToCaption.toLowerCase()} `
|
||
: null}
|
||
{hasValue(filter.to) ? (valueFormatter ? valueFormatter({ value: filter.to, columnDef }) : filter.to) : null}
|
||
</Typography>
|
||
</Box>
|
||
</Stack>
|
||
{filterColumn ? (
|
||
<P8PTableColumnFilterDialog
|
||
columnDef={columnDef}
|
||
from={filterColumnFrom}
|
||
to={filterColumnTo}
|
||
valueCaption={P8P_DATA_GRID_CONFIG_PROPS.valueFilterCaption}
|
||
valueFromCaption={P8P_DATA_GRID_CONFIG_PROPS.valueFromFilterCaption}
|
||
valueToCaption={P8P_DATA_GRID_CONFIG_PROPS.valueToFilterCaption}
|
||
okBtnCaption={P8P_DATA_GRID_CONFIG_PROPS.okFilterBtnCaption}
|
||
clearBtnCaption={P8P_DATA_GRID_CONFIG_PROPS.clearFilterBtnCaption}
|
||
cancelBtnCaption={P8P_DATA_GRID_CONFIG_PROPS.cancelFilterBtnCaption}
|
||
valueFormatter={valueFormatter}
|
||
onOk={handleFilterOk}
|
||
onClear={handleFilterClear}
|
||
onCancel={handleFilterCancel}
|
||
/>
|
||
) : null}
|
||
</>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Текст
|
||
FilterComponent.propTypes = {
|
||
filter: PropTypes.object,
|
||
columnDef: PropTypes.object,
|
||
valueFromCaption: PropTypes.string,
|
||
valueToCaption: PropTypes.string,
|
||
valueFormatter: PropTypes.func,
|
||
onFilterChanged: PropTypes.func
|
||
};
|
||
|
||
//Форматирование фильтра таблицы
|
||
const formatFilterDataGrid = ({
|
||
filters,
|
||
columnsDef,
|
||
valueFromCaption = P8P_DATA_GRID_CONFIG_PROPS.valueFromCaption,
|
||
valueToCaption = P8P_DATA_GRID_CONFIG_PROPS.valueToCaption,
|
||
valueFormatter,
|
||
onClick,
|
||
onFilterChanged,
|
||
objectsCopier
|
||
}) => {
|
||
//Форматируем фильтры под заголовок
|
||
const formattedFilters = filters.map(filter => {
|
||
//Определяем колонку
|
||
const columnDef = columnsDef.find(columnDef => columnDef.name == filter.name);
|
||
//Формирование содержимого фильтра
|
||
const buildFilterContent = () => {
|
||
//Инициализируем части
|
||
const parts = [];
|
||
//Если есть "Значение с"
|
||
if (hasValue(filter.from)) {
|
||
//Если необходимо добавить префикс
|
||
if (!columnDef.values && columnDef.dataType != P8P_DATA_TYPES.STR) {
|
||
parts.push(`${valueFromCaption.toLowerCase()} `);
|
||
}
|
||
//Добавляем "Значение с"
|
||
parts.push(valueFormatter ? valueFormatter({ value: filter.from, columnDef }) : filter.from);
|
||
}
|
||
//Если есть "Значение по"
|
||
if (hasValue(filter.to)) {
|
||
//Если необходимо добавить префикс
|
||
if (!columnDef.values && columnDef.dataType != P8P_DATA_TYPES.STR) {
|
||
parts.push(` ${valueToCaption.toLowerCase()} `);
|
||
}
|
||
//Добавляем "Значение по"
|
||
parts.push(valueFormatter ? valueFormatter({ value: filter.to, columnDef }) : filter.to);
|
||
}
|
||
//Возвращаем массив элементов
|
||
return parts;
|
||
};
|
||
|
||
//При изменении состояния фильтра
|
||
const handleFilterChanged = ({ columnName, from, to }) => {
|
||
let newFilters = objectsCopier(filters);
|
||
let curFilter = newFilters.find(f => f.name == columnName);
|
||
if (from == null && to == null && curFilter) newFilters.splice(newFilters.indexOf(curFilter), 1);
|
||
if ((from != null || to != null) && !curFilter) newFilters.push({ name: columnName, from, to });
|
||
if ((from != null || to != null) && curFilter) {
|
||
curFilter.from = from;
|
||
curFilter.to = to;
|
||
}
|
||
if (onFilterChanged) onFilterChanged({ filters: newFilters });
|
||
};
|
||
//Инициализируем содержмое значения
|
||
const content = buildFilterContent();
|
||
//Возвращаем результат
|
||
return {
|
||
caption: columnDef.caption,
|
||
// from: valueFormatter ? (
|
||
// <Box typography={"P8PBody2"} sx={P8P_BOX_HEADER_FILTER_CUSTOM}>
|
||
// {React.Children.toArray(content)}
|
||
// </Box>
|
||
// ) : (
|
||
// content.join("")
|
||
// ),
|
||
from: (
|
||
<FilterComponent
|
||
filter={filter}
|
||
columnDef={columnDef}
|
||
valueFromCaption={valueFromCaption}
|
||
valueToCaption={valueToCaption}
|
||
valueFormatter={valueFormatter}
|
||
/>
|
||
),
|
||
customView: (
|
||
<FilterComponent
|
||
filter={filter}
|
||
columnDef={columnDef}
|
||
valueFromCaption={valueFromCaption}
|
||
valueToCaption={valueToCaption}
|
||
valueFormatter={valueFormatter}
|
||
onFilterChanged={handleFilterChanged}
|
||
/>
|
||
),
|
||
onClick: () => onClick && onClick(columnDef.name)
|
||
};
|
||
});
|
||
return formattedFilters;
|
||
};
|
||
|
||
export const P8P_HEADER_FILTER_FORMAT = {
|
||
DATA_GRID: ({
|
||
filters,
|
||
columnsDef,
|
||
valueFromCaption = P8P_DATA_GRID_CONFIG_PROPS.valueFromCaption,
|
||
valueToCaption = P8P_DATA_GRID_CONFIG_PROPS.valueToCaption,
|
||
valueFormatter,
|
||
onClick,
|
||
onFilterChanged,
|
||
objectsCopier
|
||
}) => formatFilterDataGrid({ filters, columnsDef, valueFromCaption, valueToCaption, valueFormatter, onClick, onFilterChanged, objectsCopier })
|
||
};
|