P8PanelsCEMROS/hauler_anl/hauler_anl.js

235 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Парус 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, dataCellRender } 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, handleHaulerUnitsCardsOpen } = 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}
dataCellRender={prms => dataCellRender({ ...prms, showHaulerUnitsCards: handleHaulerUnitsCardsOpen })}
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 };