234 lines
11 KiB
JavaScript
234 lines
11 KiB
JavaScript
/*
|
||
Парус 8 - Панели мониторинга - ТОиР - Аналитика по ремонтам АТС
|
||
Панель мониторинга: Корневая панель аналитики по ремонтам АТС
|
||
*/
|
||
|
||
//---------------------
|
||
//Подключение библиотек
|
||
//---------------------
|
||
|
||
import React, { useState, useEffect, useMemo } from "react"; //Классы React
|
||
import { Box, Grid, Paper, Fab, Icon } from "@mui/material"; //Интерфейсные компоненты
|
||
import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Заголовок страницы
|
||
import { P8PChart } from "../../components/p8p_chart"; //График
|
||
import { APP_STYLES } from "../../../app.styles"; //Типовые стили
|
||
import { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_MORE_HEIGHT, P8P_DATA_GRID_FILTERS_HEIGHT } from "../../components/p8p_data_grid"; //Таблица данных
|
||
import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
|
||
import { FilterDialog } from "./filter_dialog"; //Диалог фильтра
|
||
import { Filter } from "./filter"; //Фильтры
|
||
import { useFilters } from "./hooks/filter_hooks"; //Хуки фильтров
|
||
import { useChartStatuses, useChartSpendings, useTableRepairs } from "./hooks/hooks";
|
||
import { useDictionary } from "./hooks/dict_hooks";
|
||
import { dataCellRender, valueFormatter, formatFilterValues } from "./layouts";
|
||
import { ChartFilter } from "./chart_filter";
|
||
import { hasValue } from "../../core/utils";
|
||
|
||
//---------
|
||
//Константы
|
||
//---------
|
||
|
||
//Высота графиков
|
||
const CHART_HEIGHT = "300px";
|
||
|
||
//Стили
|
||
const STYLES = {
|
||
TABLE_PROJECTS: (showCharts, morePages, filters, isChartsFiltered) => ({
|
||
height: `calc(100vh - ${APP_BAR_HEIGHT} - ${showCharts ? CHART_HEIGHT : "0px"} - ${morePages ? P8P_DATA_GRID_MORE_HEIGHT : "0px"} - ${
|
||
filters ? P8P_DATA_GRID_FILTERS_HEIGHT : "0px"
|
||
} - ${showCharts && isChartsFiltered ? "53px" : "0px"} - 90px)`,
|
||
maxWidth: `calc(100vw - 16px)`,
|
||
...APP_STYLES.SCROLL
|
||
}),
|
||
CHART: { maxHeight: CHART_HEIGHT, display: "flex", justifyContent: "center" },
|
||
CHART_PAPER: { height: "100%", paddingBottom: "5px" },
|
||
CHART_FAB: { position: "absolute", top: 80, left: 16 }
|
||
};
|
||
|
||
//Графики страницы
|
||
const CHART_NAMES = {
|
||
repairs: "REPAIRS",
|
||
spendings: "SPENDINGS"
|
||
};
|
||
|
||
//-----------
|
||
//Тело модуля
|
||
//-----------
|
||
|
||
//Корневая панель аналитики по ремонтам АТС
|
||
const RepairAnlATC = () => {
|
||
//Собственное состояние - признак отображения фильтров
|
||
const [isFilterOpen, setIsFilterOpen] = useState(true);
|
||
|
||
//Состояния графиков
|
||
const [showCharts, setShowCharts] = useState(true);
|
||
|
||
//Собственное состояние - общие фильтры
|
||
const [filterValues, isFiltersLoaded, filtersInit, handleFilterChange] = useFilters();
|
||
|
||
//Собственное состояние - фильтры ремонтов
|
||
const [filterRepairs, setFilterRepairs] = useState({ nState: null });
|
||
|
||
//Собственное состояние - фильтры затрат
|
||
const [filterSpendings, setFilterSpendings] = useState({ nType: null });
|
||
|
||
//Общие фильтры панели
|
||
const allFilters = useMemo(() => {
|
||
return { ...filterValues, nState: filterRepairs.nState, nType: filterSpendings.nType };
|
||
}, [filterRepairs.nState, filterSpendings.nType, filterValues]);
|
||
|
||
//Состояние графика статусов
|
||
const { chartStatuses, handleReload: handleChartStatusesReload } = useChartStatuses({ storedArgs: allFilters });
|
||
|
||
//Состояние графика трудовых затрат
|
||
const { chartSpendings, handleReload: handleChartSpendingsReload } = useChartSpendings({ storedArgs: allFilters });
|
||
|
||
//Состояние таблицы ремонтных ведомостей
|
||
const {
|
||
dataGrid,
|
||
handleReload: handleTableRepairsReload,
|
||
handleFilterChanged,
|
||
handleOrderChanged,
|
||
handlePagesCountChanged
|
||
} = useTableRepairs({
|
||
storedArgs: formatFilterValues(allFilters)
|
||
});
|
||
|
||
//Вспомогательные функции открытия раздела
|
||
const { handleEquipRepairSheetsOpen } = useDictionary();
|
||
|
||
//При изменении фильтра в диалоге
|
||
const handleFilterOk = filter => {
|
||
//Обновляем фильтры
|
||
handleFilterChange({ filter });
|
||
//Закрываем диалог фильтра
|
||
setIsFilterOpen(false);
|
||
};
|
||
|
||
//При закрытии диалога фильтра
|
||
const handleFilterCancel = () => setIsFilterOpen(false);
|
||
|
||
//При открытии диалога фильтра
|
||
const handleFilterDialogOpen = () => setIsFilterOpen(true);
|
||
|
||
//При нажатии на элемент графика "Ремонты"
|
||
const handleChartStatusesClick = ({ item }) => {
|
||
setFilterRepairs({ nState: item.NSTATE });
|
||
};
|
||
|
||
//При нажатии на элемент графика "Трудовые затраты"
|
||
const handleChartSpendingsClick = ({ item }) => {
|
||
//Если тип не соответствует текущему
|
||
if (item.NTYPE !== filterSpendings.nType) setFilterSpendings({ nType: item.NTYPE });
|
||
};
|
||
|
||
//При изменении фильтра графика
|
||
const handleChartFilterChange = ({ chartName, filter }) => {
|
||
//При изменении фильтров графика "Ремонты"
|
||
if (chartName === CHART_NAMES.repairs) {
|
||
setFilterRepairs({ ...filter });
|
||
}
|
||
//При изменении фильтров графика "Трудовые затраты"
|
||
if (chartName === CHART_NAMES.spendings) setFilterSpendings({ ...filter });
|
||
};
|
||
|
||
//При изменении фильтра
|
||
useEffect(() => {
|
||
//Если фильтр установлен
|
||
if (!filtersInit) {
|
||
handleChartStatusesReload();
|
||
handleChartSpendingsReload();
|
||
handleTableRepairsReload();
|
||
}
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||
}, [allFilters, filtersInit]);
|
||
|
||
//Генерация содержимого
|
||
return (
|
||
<Box p={1}>
|
||
{!filtersInit ? <Filter filter={filterValues} onFilterOpen={handleFilterDialogOpen} /> : null}
|
||
<Grid container spacing={1}>
|
||
{showCharts ? (
|
||
<>
|
||
<Grid item xs={6}>
|
||
<Paper elevation={3} sx={STYLES.CHART_PAPER}>
|
||
{hasValue(filterRepairs.nState) ? (
|
||
<ChartFilter chartName={CHART_NAMES.repairs} filter={filterRepairs} onFilterChange={handleChartFilterChange} />
|
||
) : null}
|
||
{chartStatuses.loaded ? (
|
||
<P8PChart {...chartStatuses} style={STYLES.CHART} onClick={handleChartStatusesClick} legendPosition={"top"} />
|
||
) : null}
|
||
</Paper>
|
||
</Grid>
|
||
<Grid item xs={6}>
|
||
<Paper elevation={3} sx={STYLES.CHART_PAPER}>
|
||
{hasValue(filterSpendings.nType) ? (
|
||
<ChartFilter
|
||
chartName={CHART_NAMES.spendings}
|
||
filter={filterSpendings}
|
||
onFilterChange={handleChartFilterChange}
|
||
/>
|
||
) : null}
|
||
{chartSpendings.loaded ? (
|
||
<P8PChart
|
||
{...chartSpendings}
|
||
style={STYLES.CHART}
|
||
options={{
|
||
scales: {
|
||
x: {
|
||
stacked: true
|
||
},
|
||
y: {
|
||
stacked: true
|
||
}
|
||
}
|
||
}}
|
||
legendPosition={"top"}
|
||
onClick={handleChartSpendingsClick}
|
||
/>
|
||
) : null}
|
||
</Paper>
|
||
</Grid>
|
||
</>
|
||
) : null}
|
||
<Grid item xs={12}>
|
||
{dataGrid.dataLoaded ? (
|
||
<P8PDataGrid
|
||
{...P8P_DATA_GRID_CONFIG_PROPS}
|
||
{...dataGrid}
|
||
size={P8P_DATA_GRID_SIZE.LARGE}
|
||
containerComponentProps={{
|
||
sx: STYLES.TABLE_PROJECTS(
|
||
showCharts,
|
||
dataGrid.morePages,
|
||
(dataGrid.filters || []).length > 0,
|
||
hasValue(filterRepairs.nState) || hasValue(filterSpendings.nType)
|
||
)
|
||
}}
|
||
filtersInitial={dataGrid.filters}
|
||
onOrderChanged={handleOrderChanged}
|
||
onFilterChanged={handleFilterChanged}
|
||
onPagesCountChanged={handlePagesCountChanged}
|
||
dataCellRender={prms => dataCellRender({ ...prms, showEquipRepairSheets: handleEquipRepairSheetsOpen })}
|
||
valueFormatter={valueFormatter}
|
||
/>
|
||
) : null}
|
||
</Grid>
|
||
</Grid>
|
||
{chartStatuses.loaded && chartSpendings.loaded ? (
|
||
<Fab size="small" color="secondary" sx={STYLES.CHART_FAB} onClick={() => setShowCharts(!showCharts)}>
|
||
<Icon>{showCharts ? "expand_less" : "expand_more"}</Icon>
|
||
</Fab>
|
||
) : null}
|
||
{isFilterOpen && isFiltersLoaded ? (
|
||
<FilterDialog initial={filterValues} isFiltersInit={filtersInit} onOk={handleFilterOk} onCancel={handleFilterCancel} />
|
||
) : null}
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
//----------------
|
||
//Интерфейс модуля
|
||
//----------------
|
||
|
||
export { RepairAnlATC };
|