forked from CITKParus/P8-Panels
172 lines
8.0 KiB
JavaScript
172 lines
8.0 KiB
JavaScript
/*
|
||
Парус 8 - Панели мониторинга - Циклограмма
|
||
Компонент: Представление циклограммы
|
||
*/
|
||
|
||
//---------------------
|
||
//Подключение библиотек
|
||
//---------------------
|
||
|
||
import React from "react"; //Классы React
|
||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||
import { Box, Typography } from "@mui/material"; //Интерфейсные компоненты
|
||
import { hasValue } from "../../core/utils"; //Вспомогательный функции
|
||
import { P8P_TYPOGRAPHY_VARIANT } from "../../theme/p8p_typography"; //Варианты шрифтов
|
||
import { P8P_BOX_CYCLOGRAM_GROUP } from "../../theme/styles/box"; //Стили контейнеров
|
||
import { NDEFAULT_HEADER_HEIGHT } from "./p8p_cyclogram_constants"; //Константы циклограммы
|
||
import { P8PCyclogramTask } from "./p8p_cyclogram_task"; //Задача циклограммы
|
||
import { P8PCyclogramHeader } from "./p8p_cyclogram_header"; //Заголовок циклограммы
|
||
import { getGroupStyles } from "./p8p_cyclogram_utils"; //Вспомогательные функции циклограммы
|
||
import { P8P_TYPOGRAPHY_CG_GROUP } from "../../theme/styles/typography"; //Стили текста
|
||
|
||
//-----------
|
||
//Тело модуля
|
||
//-----------
|
||
|
||
//Представление циклограммы
|
||
const P8PCyclogramView = ({
|
||
columns,
|
||
groups,
|
||
tasks,
|
||
shift,
|
||
lineHeight,
|
||
maxWidth,
|
||
maxHeight,
|
||
openTaskEditor,
|
||
groupHeaderRenderer,
|
||
taskRenderer,
|
||
columnRenderer,
|
||
headerBlock
|
||
}) => {
|
||
//Инициализируем коллекцию тасков с группами
|
||
const tasksWithGroup = tasks.filter(task => hasValue(task.groupName));
|
||
//Инициализируем коллекцию тасков без групп
|
||
const tasksWithoutGroup = tasks.filter(task => !hasValue(task.groupName));
|
||
//Инициализируем коллекцию отображаемых групп
|
||
const visibleGroups = groups ? groups.filter(group => group.visible) : [];
|
||
return (
|
||
<g className="main">
|
||
<g className="tasks">
|
||
{visibleGroups.length !== 0
|
||
? visibleGroups.map((grp, indexGrp) => {
|
||
//Считываем задачи группы
|
||
let groupTasks = tasksWithGroup.filter(task => task.groupName === grp.name);
|
||
//Если по данной группе нет тасков - ничего не выводим
|
||
if (groupTasks.length === 0) {
|
||
return null;
|
||
}
|
||
return (
|
||
<g className={`TaskGrp${indexGrp}`} key={indexGrp}>
|
||
{groupTasks.map((task, index) => (
|
||
<P8PCyclogramTask
|
||
task={task}
|
||
indexGrp={indexGrp}
|
||
shift={shift}
|
||
lineHeight={lineHeight}
|
||
openTaskEditor={openTaskEditor}
|
||
taskRenderer={taskRenderer}
|
||
key={index}
|
||
/>
|
||
))}
|
||
<style>{getGroupStyles(indexGrp, grp.highlightColor)}</style>
|
||
</g>
|
||
);
|
||
})
|
||
: null}
|
||
<g className={`TasksWithoutGroups`}>
|
||
{tasksWithoutGroup.map((task, index) => {
|
||
return (
|
||
<P8PCyclogramTask
|
||
task={task}
|
||
shift={shift}
|
||
lineHeight={lineHeight}
|
||
openTaskEditor={openTaskEditor}
|
||
taskRenderer={taskRenderer}
|
||
key={index}
|
||
/>
|
||
);
|
||
})}
|
||
</g>
|
||
</g>
|
||
<P8PCyclogramHeader
|
||
columns={columns}
|
||
shift={shift}
|
||
maxWidth={maxWidth}
|
||
maxHeight={maxHeight}
|
||
columnRenderer={columnRenderer}
|
||
headerBlock={headerBlock}
|
||
/>
|
||
{visibleGroups.length !== 0 ? (
|
||
<g className="groups">
|
||
{visibleGroups.map((grp, indexGrp) => {
|
||
//Инициализируем параметры группы
|
||
let defaultView = null;
|
||
let customView = null;
|
||
let groupHeaderX = 0;
|
||
let groupHeaderY = 0;
|
||
let groupTasks = tasksWithGroup.filter(task => task.groupName === grp.name);
|
||
//Если по данной группе нет тасков - ничего не выводим
|
||
if (groupTasks.length === 0) {
|
||
return null;
|
||
}
|
||
//Если требуется отображать заголовок группы
|
||
if (grp.visible) {
|
||
//Формируем отображение по умолчанию
|
||
defaultView = (
|
||
<Box sx={P8P_BOX_CYCLOGRAM_GROUP({ height: grp.height })}>
|
||
<Typography
|
||
sx={P8P_TYPOGRAPHY_CG_GROUP({ maxWidth: grp.width, maxHeight: grp.height })}
|
||
variant={P8P_TYPOGRAPHY_VARIANT.BODY3_LIGHT}
|
||
>
|
||
{grp.name}
|
||
</Typography>
|
||
</Box>
|
||
);
|
||
//Формируем собственное отображение, если требуется
|
||
customView = groupHeaderRenderer ? groupHeaderRenderer({ group: grp }) : null;
|
||
//Рассчитываем координаты заголовка группы
|
||
groupHeaderX = Math.min(...groupTasks.map(o => o.start)) * shift;
|
||
groupHeaderY = NDEFAULT_HEADER_HEIGHT + Math.min(...groupTasks.map(o => o.lineNumb)) * lineHeight - grp.height - 5;
|
||
}
|
||
return (
|
||
<foreignObject
|
||
x={groupHeaderX}
|
||
y={groupHeaderY}
|
||
width={grp.width}
|
||
height={grp.height}
|
||
className={`TaskGrpHeader${indexGrp}`}
|
||
display="none"
|
||
key={indexGrp}
|
||
>
|
||
{customView ? customView : defaultView}
|
||
</foreignObject>
|
||
);
|
||
})}
|
||
</g>
|
||
) : null}
|
||
</g>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Представление циклограммы
|
||
P8PCyclogramView.propTypes = {
|
||
columns: PropTypes.array.isRequired,
|
||
groups: PropTypes.array,
|
||
tasks: PropTypes.array.isRequired,
|
||
shift: PropTypes.number.isRequired,
|
||
lineHeight: PropTypes.number.isRequired,
|
||
maxWidth: PropTypes.number.isRequired,
|
||
maxHeight: PropTypes.number.isRequired,
|
||
openTaskEditor: PropTypes.func.isRequired,
|
||
groupHeaderRenderer: PropTypes.func,
|
||
taskRenderer: PropTypes.func,
|
||
columnRenderer: PropTypes.func,
|
||
headerBlock: PropTypes.object
|
||
};
|
||
|
||
//----------------
|
||
//Интерфейс модуля
|
||
//----------------
|
||
|
||
export { P8PCyclogramView };
|