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 { useChartInfo, useChartCalcs, useTableATC } from "./hooks/hooks";
|
||
import { valueFormatter } from "./layouts"; //Вспомогательные функции верстки
|
||
import { ChartFilter } from "./chart_filter"; //Фильтр графика
|
||
import { hasValue } from "../../core/utils"; //Вспомогательные функции
|
||
import { useDictionary } from "./hooks/dict_hooks"; //Хуки для открытия раздела
|
||
|
||
//---------
|
||
//Константы
|
||
//---------
|
||
|
||
//Высота графиков
|
||
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 = {
|
||
info: "INFO",
|
||
calcs: "CALCS"
|
||
};
|
||
|
||
//-----------
|
||
//Тело модуля
|
||
//-----------
|
||
|
||
//Корневая панель гаражки
|
||
const HaulerAnl = () => {
|
||
//Вспомогательные функции открытия раздела
|
||
const { handleEquipRepairSheetsOpen } = useDictionary();
|
||
|
||
//Собственное состояние - признак отображения фильтров
|
||
const [isFilterOpen, setIsFilterOpen] = useState(true);
|
||
|
||
//Состояния графиков
|
||
const [showCharts, setShowCharts] = useState(true);
|
||
|
||
//Собственное состояние - общие фильтры
|
||
const [filterValues, isFiltersLoaded, filtersInit, handleFilterChange] = useFilters();
|
||
|
||
//Собственное состояние - фильтры информации
|
||
const [filterInfo, setFilterInfo] = useState({ nState: null });
|
||
|
||
//Собственное состояние - фильтры расчетов
|
||
const [filterCalcs, setFilterCalcs] = useState({ sDepartment: null });
|
||
|
||
//Общие фильтры панели
|
||
const allFilters = useMemo(() => {
|
||
return { ...filterValues, nState: filterInfo.nState, sDepartment: filterCalcs.sDepartment };
|
||
}, [filterValues, filterInfo, filterCalcs]);
|
||
|
||
//Состояние графика информации АТС
|
||
const { chartInfo, handleReload: handleChartInfoReload } = useChartInfo({ storedArgs: allFilters });
|
||
|
||
//Состояние графика расчетов
|
||
const { chartCalcs, handleReload: handleChartCalcsReload } = useChartCalcs({ storedArgs: allFilters });
|
||
|
||
//Состояние таблицы ремонтных ведомостей
|
||
const {
|
||
dataGrid,
|
||
handleReload: handleTableATCReload,
|
||
handleFilterChanged,
|
||
handleOrderChanged,
|
||
handlePagesCountChanged
|
||
} = useTableATC({
|
||
storedArgs: allFilters
|
||
});
|
||
|
||
//При изменении фильтра в диалоге
|
||
const handleFilterOk = async filter => {
|
||
//Обновляем фильтры
|
||
await handleFilterChange({ filter });
|
||
//Если указан общий и внутренний фильтр по подразделению
|
||
if (filter.sCustomerDept && filterCalcs.sDepartment) {
|
||
//Очищаем внутренний
|
||
setFilterCalcs({ sDepartment: null, ignoreReload: true });
|
||
}
|
||
//Закрываем диалог фильтра
|
||
setIsFilterOpen(false);
|
||
};
|
||
|
||
//При закрытии диалога фильтра
|
||
const handleFilterCancel = () => setIsFilterOpen(false);
|
||
|
||
//При открытии диалога фильтра
|
||
const handleFilterDialogOpen = () => setIsFilterOpen(true);
|
||
|
||
//При нажатии на элемент графика "Информация АТС"
|
||
const handleChartInfoClick = ({ item }) => {
|
||
setFilterInfo({ nState: item.NSTATE });
|
||
};
|
||
|
||
//При нажатии на элемент графика расчетов
|
||
const handleChartCalcsClick = ({ item }) => {
|
||
//Если подразделение не соответствует текущему
|
||
if (item.SCODE !== filterCalcs.sDepartment && !filterValues.sCustomerDept) setFilterCalcs({ sDepartment: item.SCODE });
|
||
};
|
||
|
||
//При изменении фильтра графика
|
||
const handleChartFilterChange = ({ chartName, filter }) => {
|
||
//При изменении фильтров графика "Информация АТС"
|
||
if (chartName === CHART_NAMES.info) {
|
||
setFilterInfo({ ...filter });
|
||
}
|
||
//При изменении фильтров графика расчетов
|
||
if (chartName === CHART_NAMES.calcs) setFilterCalcs({ ...filter });
|
||
};
|
||
|
||
//При изменении фильтра
|
||
useEffect(() => {
|
||
//Если фильтр установлен
|
||
if (!filtersInit) {
|
||
handleChartInfoReload();
|
||
handleChartCalcsReload();
|
||
handleTableATCReload();
|
||
}
|
||
// 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(filterInfo.nState) ? (
|
||
<ChartFilter chartName={CHART_NAMES.info} filter={filterInfo} onFilterChange={handleChartFilterChange} />
|
||
) : null}
|
||
{chartInfo.loaded ? (
|
||
<P8PChart {...chartInfo} style={STYLES.CHART} onClick={handleChartInfoClick} legendPosition={"top"} />
|
||
) : null}
|
||
</Paper>
|
||
</Grid>
|
||
<Grid item xs={6}>
|
||
<Paper elevation={3} sx={STYLES.CHART_PAPER}>
|
||
{hasValue(filterCalcs.sDepartment) ? (
|
||
<ChartFilter chartName={CHART_NAMES.calcs} filter={filterCalcs} onFilterChange={handleChartFilterChange} />
|
||
) : null}
|
||
{chartCalcs.loaded ? (
|
||
<P8PChart
|
||
{...chartCalcs}
|
||
style={STYLES.CHART}
|
||
options={{
|
||
scales: {
|
||
x: {
|
||
stacked: true
|
||
},
|
||
y: {
|
||
stacked: true
|
||
}
|
||
}
|
||
}}
|
||
legendPosition={"top"}
|
||
onClick={handleChartCalcsClick}
|
||
/>
|
||
) : 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(filterInfo.nState) || hasValue(filterCalcs.sDepartment)
|
||
)
|
||
}}
|
||
filtersInitial={dataGrid.filters}
|
||
onOrderChanged={handleOrderChanged}
|
||
onFilterChanged={handleFilterChanged}
|
||
onPagesCountChanged={handlePagesCountChanged}
|
||
valueFormatter={prms => valueFormatter({ ...prms, onRepairSheetOpen: handleEquipRepairSheetsOpen })}
|
||
/>
|
||
) : null}
|
||
</Grid>
|
||
</Grid>
|
||
{chartInfo.loaded && chartCalcs.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 { HaulerAnl };
|