diff --git a/app/panels/eqs_prfrm/eqs_prfrm.js b/app/panels/eqs_prfrm/eqs_prfrm.js index debbcaf..f5bb5b2 100644 --- a/app/panels/eqs_prfrm/eqs_prfrm.js +++ b/app/panels/eqs_prfrm/eqs_prfrm.js @@ -8,26 +8,7 @@ //--------------------- import React, { useState, useContext, useCallback, useEffect } from "react"; //Классы React -import { - Grid, - Paper, - Box, - Link, - Button, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - InputLabel, - FormControl, - OutlinedInput, - InputAdornment, - IconButton, - Icon, - Select, - MenuItem, - FormHelperText -} from "@mui/material"; +import { Grid, Paper, Box, Link } from "@mui/material"; //Интерфейсные компоненты import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером @@ -35,6 +16,7 @@ import { ApplicationСtx } from "../../context/application"; //Контекст import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений import { headCellRender, dataCellRender, groupCellRender, DIGITS_REG_EXP, MONTH_NAME_REG_EXP, DAY_NAME_REG_EXP } from "./layouts"; //Дополнительная разметка и вёрстка клиентских элементов import { TEXTS } from "../../../app.text"; //Тектовые ресурсы и константы +import { FilterDialog } from "./filter_dialog"; //Компонент диалогового окна фильтра отбора //----------- //Тело модуля @@ -51,10 +33,7 @@ const EqsPrfrm = () => { reload: false }); - // Состояние информации о трудоёмкости - const [info, setInfo] = useState({ cntP: 0, sumP: 0, cntF: 0, sumF: 0 }); - - // Состояние фильтра + //Состояние фильтра const [filter, setFilter] = useState({ belong: "", prodObj: "", @@ -65,22 +44,24 @@ const EqsPrfrm = () => { toMonth: 1, toYear: 1990 }); - // Состояние открытия фильтра - const [filterOpen, setFilterOpen] = useState(true); - // Состояние данных по умолчанию для фильтра - const [defaultLoaded, setDefaultLoaded] = useState(false); - // Состояние хранения копии фильтра - const [filterCopy, setFilterCopy] = useState({ ...filter }); - // Состояние ограничения редактирования фильтра - const [filterLock, setFilterLock] = useState(false); - // Состояние ячейки заголовка даты (по раскрытию/скрытию) + //Состояние хранения копии фильтра + const [filterCopy, setFilterCopy] = useState({ ...filter }); + + //Состояние открытия фильтра + const [filterOpen, setFilterOpen] = useState(true); + + //Состояние данных по умолчанию для фильтра + const [defaultLoaded, setDefaultLoaded] = useState(false); + + //Состояние ячейки заголовка даты (по раскрытию/скрытию) const [activeRef, setActiveRef] = useState(); - // Состояние актуальности ссылки на ячейку + + //Состояние актуальности ссылки на ячейку const [refIsDeprecated, setRidFlag] = useState(true); //Подключение к контексту приложения - const { pOnlineShowDictionary, pOnlineShowUnit } = useContext(ApplicationСtx); + const { pOnlineShowUnit } = useContext(ApplicationСtx); //Подключение к контексту взаимодействия с сервером const { executeStored } = useContext(BackEndСtx); @@ -146,7 +127,6 @@ const EqsPrfrm = () => { } }); } - setInfo({ cntP: cP, sumP: sP, cntF: cF, sumF: sF }); setDataGrid(pv => ({ ...pv, columnsDef: data.XCOLUMNS_DEF ? [...data.XCOLUMNS_DEF] : pv.columnsDef, @@ -164,23 +144,17 @@ const EqsPrfrm = () => { stored: "PKG_P8PANELS_EQUIPSRV.GET_DEFAULT_FP", respArg: "COUT" }); - setFilter(pv => ({ ...pv, belong: data.JURPERS, fromMonth: 1, fromYear: data.YEAR, toMonth: 12, toYear: data.YEAR })); setDefaultLoaded(true); }, [executeStored]); - // Отбор документа (ТОиР или Ремонтных ведомостей) по ячейке даты + //Отбор документа (ТОиР или Ремонтных ведомостей) по ячейке даты const showEquipSrv = async ({ date, workType, info }) => { const [techName, servKind] = info.split("_"); let type; - if (workType == "План") type = 0; else type = 1; - let [year, month, day] = date.substring(1).split("_"); - - //if (day == undefined) day = null; - const data = await executeStored({ stored: "PKG_P8PANELS_EQUIPSRV.SELECT_EQUIPSRV", args: { @@ -202,47 +176,26 @@ const EqsPrfrm = () => { } else showMsgErr(TEXTS.NO_DATA_FOUND); }; - // Открыть фильтр + //Открыть фильтр const openFilter = () => { setFilterOpen(true); }; - // Закрыть фильтр - const closeFilter = e => { - if (filterLock && e != undefined) setFilter(filterCopy); - setFilterOpen(false); - }; - - // Очистить фильтр - const clearFilter = () => { - setFilter({ - belong: "", - prodObj: "", - techServ: "", - respDep: "", - fromMonth: "", - fromYear: "", - toMonth: "", - toYear: "" - }); - }; - - // Отработка события скрытия/раскрытия ячейки даты + //Отработка события скрытия/раскрытия ячейки даты const handleClick = (e, ref) => { const curCell = ref.current; - if (e.target.type == "button" || e.target.offsetParent.type == "button") { setActiveRef(curCell); setRidFlag(false); } }; - // При необходимости обновить данные таблицы + //При необходимости обновить данные таблицы useEffect(() => { loadData(); }, [loadData, dataGrid.reload]); - // При открытом фильтре + //При открытом фильтре useEffect(() => { if (filterOpen) { { @@ -250,10 +203,10 @@ const EqsPrfrm = () => { if (!defaultLoaded) loadDefaultFilter(); } } - // eslint-disable-next-line react-hooks/exhaustive-deps + //eslint-disable-next-line react-hooks/exhaustive-deps }, [filterOpen]); - // При нажатии скрытии/раскрытии ячейки даты, фокус на неё + //При нажатии скрытии/раскрытии ячейки даты, фокус на неё useEffect(() => { if (!refIsDeprecated) { if (activeRef) { @@ -262,313 +215,20 @@ const EqsPrfrm = () => { setRidFlag(true); } } - // eslint-disable-next-line react-hooks/exhaustive-deps + //eslint-disable-next-line react-hooks/exhaustive-deps }, [refIsDeprecated]); - let yearArray = []; - const monthArray = ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"]; - let today = new Date(); - - // Получение списка лет - const getYearArray = () => { - for (let i = 1990; i <= today.getFullYear(); i++) { - yearArray.push(i); - } - }; - //Генерация содержимого return (
- {getYearArray()} - - Фильтр отбора - theme.palette.grey[500] - }} - > - close - - - - - - Принадлежность - - { - pOnlineShowDictionary({ - unitCode: "JuridicalPersons", - callBack: res => - res.success === true - ? setFilter(pv => ({ ...pv, belong: res.outParameters.out_CODE })) - : null - }); - }} - edge="end" - > - list - - - } - aria-describedby="belong-outlined-helper-text" - label="Принадлежность" - /> - {filter.belong ? null : ( - - *Обязательное поле - - )} - - - - - Производственный объект - - { - pOnlineShowDictionary({ - unitCode: "EquipConfiguration", - callBack: res => - res.success === true - ? setFilter(pv => ({ ...pv, prodObj: res.outParameters.out_CODE })) - : null - }); - }} - edge="end" - > - list - - - } - aria-describedby="prodObj-outlined-helper-text" - label="Производственный объект" - /> - {filter.prodObj ? null : ( - - *Обязательное поле - - )} - - - - - Техническая служба - - { - pOnlineShowDictionary({ - unitCode: "INS_DEPARTMENT", - callBack: res => - res.success === true - ? setFilter(pv => ({ ...pv, techServ: res.outParameters.out_CODE })) - : null - }); - }} - edge="end" - > - list - - - } - label="Техническая служба" - /> - - - - - Ответственное подразделение - - { - pOnlineShowDictionary({ - unitCode: "INS_DEPARTMENT", - callBack: res => - res.success === true - ? setFilter(pv => ({ ...pv, respDep: res.outParameters.out_CODE })) - : null - }); - }} - edge="end" - > - list - - - } - label="Ответственное подразделение" - /> - - - - - - Начало периода: - - - - Месяц - - {filter.fromMonth ? null : ( - - *Обязательное поле - - )} - - - - - Год - - {filter.fromYear ? null : ( - - *Обязательное поле - - )} - - - - - - - - Конец периода: - - - - Месяц - - {filter.toMonth ? null : ( - - *Обязательное поле - - )} - - - - - Год - - {filter.toYear ? null : ( - - *Обязательное поле - - )} - - - - - - - - - - - - + Фильтр отбора: {filter.belong ? `Принадлежность: ${filter.belong}` : ""}{" "} {filter.prodObj ? `Производственный объект: ${filter.prodObj}` : ""} {filter.techServ ? `Техническая служба: ${filter.techServ}` : ""}{" "} @@ -592,9 +252,7 @@ const EqsPrfrm = () => { rows={dataGrid.rows} size={P8P_DATA_GRID_SIZE.LARGE} reloading={dataGrid.reload} - headCellRender={prms => - headCellRender({ ...prms }, handleClick, filter.techServ, info.cntP, info.sumP, info.cntF, info.sumF) - } + headCellRender={prms => headCellRender({ ...prms }, handleClick)} dataCellRender={prms => dataCellRender({ ...prms }, showEquipSrv)} groupCellRender={prms => groupCellRender({ ...prms })} showCellRightBorder={true} diff --git a/app/panels/eqs_prfrm/filter_dialog.js b/app/panels/eqs_prfrm/filter_dialog.js new file mode 100644 index 0000000..8786ffa --- /dev/null +++ b/app/panels/eqs_prfrm/filter_dialog.js @@ -0,0 +1,257 @@ +/* + Парус 8 - Панели мониторинга - ТОиР - Выполнение работ + Панель мониторинга: Диалоговое окно фильтра отбора +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useState, useContext, useEffect, useCallback } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Dialog, DialogTitle, IconButton, Icon, DialogContent, DialogActions, Button, Paper, Box, Grid } from "@mui/material"; //Интерфейсные компоненты +import { FilterInputField } from "./filter_input_field"; //Компонент поля ввода +import { ApplicationСtx } from "../../context/application"; //Контекст приложения +import { STYLES } from "./layouts"; //Стили + +//--------- +//Константы +//--------- + +//Массив месяцев +export const MONTH_ARRAY = ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"]; + +//--------------- +//Тело компонента +//--------------- + +//Диалоговое окно фильтра отбора +const FilterDialog = props => { + //Свойства + const { filter, filterCopy, filterOpen, setFilter, setFilterOpen, setDataGrid } = props; + + //Состояние ограничения редактирования фильтра + const [filterLock, setFilterLock] = useState(false); + + //Состояние массива лет + const [years, setYears] = useState({ array: [1990], filled: false }); + + //Подключение к контексту приложения + const { pOnlineShowDictionary } = useContext(ApplicationСtx); + + //Закрыть фильтр + const closeFilter = e => { + if (filterLock && e != undefined) setFilter(filterCopy); + setFilterOpen(false); + }; + + //Очистить фильтр + const clearFilter = () => { + setFilter({ + belong: "", + prodObj: "", + techServ: "", + respDep: "", + fromMonth: "", + fromYear: "", + toMonth: "", + toYear: "" + }); + }; + + //Заполнение состояния массива лет + const getYearArray = useCallback(async () => { + const today = new Date(); + for (let i = years.array[0] + 1; i <= today.getFullYear(); i++) { + setYears(pv => ({ ...pv, array: [...pv.array, i] })); + } + setYears(pv => ({ ...pv, filled: true })); + //eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + //Только при первичном рендере + useEffect(() => { + if (filterOpen && !years.filled) getYearArray(); + }, [filterOpen, getYearArray, years.filled]); + + //Генерация содержимого + return ( +
+ + Фильтр отбора + theme.palette.grey[500] + }} + > + close + + + + + { + pOnlineShowDictionary({ + unitCode: "JuridicalPersons", + callBack: res => + res.success === true ? setFilter(pv => ({ ...pv, belong: res.outParameters.out_CODE })) : null + }); + }} + required={true} + /> + + + { + pOnlineShowDictionary({ + unitCode: "EquipConfiguration", + callBack: res => + res.success === true ? setFilter(pv => ({ ...pv, prodObj: res.outParameters.out_CODE })) : null + }); + }} + required={true} + /> + + + { + pOnlineShowDictionary({ + unitCode: "INS_DEPARTMENT", + callBack: res => + res.success === true ? setFilter(pv => ({ ...pv, techServ: res.outParameters.out_CODE })) : null + }); + }} + /> + + + { + pOnlineShowDictionary({ + unitCode: "INS_DEPARTMENT", + callBack: res => + res.success === true ? setFilter(pv => ({ ...pv, respDep: res.outParameters.out_CODE })) : null + }); + }} + /> + + + + + Начало периода: + + + setFilter(pv => ({ ...pv, fromMonth: e.target.value }))} + required={true} + isDateField={true} + /> + + + setFilter(pv => ({ ...pv, fromYear: e.target.value }))} + required={true} + isDateField={true} + yearArray={years.array} + /> + + + + + + + Конец периода: + + + setFilter(pv => ({ ...pv, toMonth: e.target.value }))} + required={true} + isDateField={true} + /> + + + setFilter(pv => ({ ...pv, toYear: e.target.value }))} + required={true} + isDateField={true} + yearArray={years.array} + /> + + + + + + + + + + + +
+ ); +}; + +//Контроль свойств компонента - Диалоговое окно фильтра отбора +FilterDialog.propTypes = { + filter: PropTypes.object.isRequired, + filterCopy: PropTypes.object.isRequired, + filterOpen: PropTypes.bool.isRequired, + setFilter: PropTypes.func.isRequired, + setFilterOpen: PropTypes.func.isRequired, + setDataGrid: PropTypes.func.isRequired +}; + +//-------------------- +//Интерфейс компонента +//-------------------- + +export { FilterDialog }; diff --git a/app/panels/eqs_prfrm/filter_input_field.js b/app/panels/eqs_prfrm/filter_input_field.js new file mode 100644 index 0000000..65f6a04 --- /dev/null +++ b/app/panels/eqs_prfrm/filter_input_field.js @@ -0,0 +1,121 @@ +/* + Парус 8 - Панели мониторинга - ТОиР - Выполнение работ + Панель мониторинга: Компонент поля ввода +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useEffect, useState, useCallback } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { FormControl, InputLabel, Input, InputAdornment, IconButton, Icon, FormHelperText, Select, MenuItem } from "@mui/material"; //Интерфейсные компоненты +import { MONTH_ARRAY } from "./filter_dialog"; //Название месяцев + +//--------------- +//Тело компонента +//--------------- + +//Поле ввода +const FilterInputField = props => { + //Свойства + const { elementCode, elementValue, labelText, changeFunc, required, isDateField, yearArray } = props; + + //Состояние идентификатора элемента + const [elementId, setElementId] = useState(""); + + //Формирование идентификатора элемента + const generateId = useCallback(async () => { + setElementId(!isDateField ? `${elementCode}-input` : `${elementCode}-select`); + }, [elementCode, isDateField]); + + //При рендере поля ввода + useEffect(() => { + generateId(); + }, [generateId]); + + //Генерация поля с выбором из словаря Парус + const renderInput = () => { + return ( + + + list + + + } + aria-describedby={`${elementId}-helper-text`} + label={labelText} + /> + ); + }; + + //Генерация поля с выпадающим списком + const renderSelect = () => { + return ( + + ); + }; + + //Генерация содержимого + return ( + + {labelText} + {isDateField ? renderSelect() : renderInput()} + {required && !elementValue ? ( + + *Обязательное поле + + ) : null} + + ); +}; + +//Контроль свойств - Поле ввода +FilterInputField.propTypes = { + elementCode: PropTypes.string.isRequired, + elementValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + labelText: PropTypes.string.isRequired, + changeFunc: PropTypes.func.isRequired, + required: PropTypes.bool, + isDateField: PropTypes.bool, + yearArray: PropTypes.arrayOf(PropTypes.number) +}; + +//Значения по умолчанию - Поле ввода +FilterInputField.defaultProps = { + required: false, + isDateField: false +}; + +//-------------------- +//Интерфейс компонента +//-------------------- + +export { FilterInputField }; diff --git a/app/panels/eqs_prfrm/layouts.js b/app/panels/eqs_prfrm/layouts.js index ac7d2ee..af12aed 100644 --- a/app/panels/eqs_prfrm/layouts.js +++ b/app/panels/eqs_prfrm/layouts.js @@ -1,5 +1,5 @@ /* - Парус 8 - + Парус 8 - Панели мониторинга - ТОиР - Выполнение работ Дополнительная разметка и вёрстка клиентских элементов */ @@ -8,7 +8,7 @@ //--------------------- import React, { createRef } from "react"; //Классы React -import { Grid, Stack } from "@mui/material"; +import { Grid, Stack } from "@mui/material"; //Интерфейсные компоненты //--------- //Константы @@ -19,28 +19,39 @@ export const DIGITS_REG_EXP = /\d+,?\d*/g; export const MONTH_NAME_REG_EXP = /_\d{4}_\d{1,2}/; export const DAY_NAME_REG_EXP = /_\d{4}_\d{1,2}_\d{1,2}/; -let curParent = ""; -let x = 0; +//Стили +export const STYLES = { + HIDE_CELL_STYLE: { display: "none" }, + HCR_MAIN_STYLE: { border: "1px solid rgba(0, 0, 0)", textAlign: "center" }, + HCR_DATE_STYLE: { padding: "5px", minWidth: "25px", maxWidth: "25px" }, + DCR_MAIN_STYLE: { padding: "2px", border: "1px solid rgba(0, 0, 0) !important", textAlign: "center" }, + DCR_OBJECT_INFO_STYLE: { textAlign: "right", fontWeight: "bold" }, + DCR_PLAN_CELL_STYLE: { cursor: "pointer", backgroundColor: "lightblue", border: "1px solid rgba(0, 0, 0) !important" }, + DCR_FACT_RELATED_CELL_STYLE: { cursor: "pointer", backgroundColor: "green", border: "1px solid rgba(0, 0, 0) !important" }, + DCR_FACT_NOT_RELATED_CELL_STYLE: { cursor: "pointer", backgroundColor: "crimson", border: "1px solid rgba(0, 0, 0) !important" }, + FILTER_DIALOG_ACTIONS: { justifyContent: "center" } +}; //----------- //Тело модуля //----------- -const formatDate = date => { - const [year, month, day] = date.substring(1).split("_"); - let nd; - if (day == null) nd = `${month < 10 ? "0" + month : month}.${year}`; - else nd = `${day < 10 ? "0" + day : day}.${month < 10 ? "0" + month : month}.${year}`; - return nd; +//Формирование даты полной и даты без дней из наименования ячейки +const formatDate = dateCellName => { + const [year, month, day] = dateCellName.substring(1).split("_"); + let date; + if (day == null) date = `${month < 10 ? "0" + month : month}.${year}`; + else date = `${day < 10 ? "0" + day : day}.${month < 10 ? "0" + month : month}.${year}`; + return date; }; -// eslint-disable-next-line no-unused-vars -export const headCellRender = ({ columnDef }, hClick, podr, cntP, sumP, cntF, sumF) => { - let cellStyle = { border: "1px solid rgba(0, 0, 0)", textAlign: "center" }; +//Генерация представления заголовка колонки +export const headCellRender = ({ columnDef }, hClick) => { + let cellStyle = STYLES.HCR_MAIN_STYLE; let cellProps = {}; let stackStyle = {}; let data = columnDef.caption; - + //Для разворачивающихся колонок if (columnDef.expandable) { const ref = createRef(); cellStyle = { ...cellStyle, padding: "5px" }; @@ -51,49 +62,51 @@ export const headCellRender = ({ columnDef }, hClick, podr, cntP, sumP, cntF, su hClick(e, ref); } }; - stackStyle = { flexDirection: "column" }; } - if (columnDef.name == "SOBJINFO") cellStyle = { display: "none" }; + //Скрываем ненужные колонки + if (columnDef.name == "SOBJINFO" || columnDef.name == "SWRKTYPE") cellStyle = STYLES.HIDE_CELL_STYLE; + //Объединение нужных колонок и строк if (columnDef.name == "SINFO" || columnDef.name == "SWRKTYPE") { cellProps = { colSpan: 2 }; if (columnDef.name == "SINFO") cellProps = { ...cellProps, rowSpan: 2 }; } - - if (columnDef.name == "SWRKTYPE") cellStyle = { display: "none" }; - + //Изменения в заголовках с датами if (columnDef.visible && DAY_NAME_REG_EXP.test(columnDef.name)) { - cellStyle = { ...cellStyle, padding: "5px", minWidth: "25px", maxWidth: "25px" }; + cellStyle = { ...cellStyle, ...STYLES.HCR_DATE_STYLE }; stackStyle = { justifyContent: "center" }; } - return { cellStyle, cellProps, stackStyle, data }; }; +//Генерация представления ячейки export const dataCellRender = ({ row, columnDef }, showEquipSrv) => { - let cellStyle = { - padding: "2px", - border: "1px solid rgba(0, 0, 0) !important", - textAlign: "center" - }; + let curParent = ""; + let cellDate; + let cellStyle = STYLES.DCR_MAIN_STYLE; let cellProps = {}; let data = " "; - + //Если строка с трудоёмкостью по объекту ремонта if (row["SWRKTYPE"] == undefined) { + //Ячейка "Информация по объекту ремонта" if (columnDef.name == "SOBJINFO") { cellProps = { colSpan: 2 }; - cellStyle = { ...cellStyle, textAlign: "right", fontWeight: "bold" }; + cellStyle = { ...cellStyle, ...STYLES.DCR_OBJECT_INFO_STYLE }; } - if (columnDef.name == "SWRKTYPE") cellStyle = { display: "none" }; + //Ячейка "Тип работ" + if (columnDef.name == "SWRKTYPE") cellStyle = STYLES.HIDE_CELL_STYLE; + //Ячейки колонок месяцев if (columnDef.parent == "" && columnDef.expandable == true && columnDef.expanded == false) { curParent = columnDef.name; return { cellStyle: { ...cellStyle, height: "25px" }, data }; - } else if (columnDef.name != "SWRKTYPE" && columnDef.parent != "" && columnDef.expandable == false && columnDef.expanded == true) { + } + //Поиск развёрнутых месяцев + else if (columnDef.name != "SWRKTYPE" && columnDef.parent != "" && columnDef.expandable == false && columnDef.expanded == true) { if (columnDef.name.endsWith("_1")) { curParent = columnDef.parent; const [year, month] = curParent.substring(1).split("_"); - x = new Date(year, month, 0).getDate(); - cellProps = { colSpan: x }; + cellDate = new Date(year, month, 0).getDate(); + cellProps = { colSpan: cellDate }; data = row[curParent]; return { cellStyle, cellProps, data }; } else { @@ -101,17 +114,19 @@ export const dataCellRender = ({ row, columnDef }, showEquipSrv) => { } } } + //Строка плана по объекту ремонта if (columnDef.name == "SOBJINFO" && row["SWRKTYPE"] == "План") { cellStyle = { ...cellStyle }; cellProps = { rowSpan: 2 }; } + //Строка факта по объекту ремонта if (columnDef.name == "SOBJINFO" && row["SWRKTYPE"] == "Факт") { cellStyle = { display: "none" }; } - + //Закрашивание ячеек switch (row[columnDef.name]) { case "blue": - cellStyle = { ...cellStyle, cursor: "pointer", backgroundColor: "lightblue", border: "1px solid rgba(0, 0, 0) !important" }; + cellStyle = { ...cellStyle, ...STYLES.DCR_PLAN_CELL_STYLE }; cellProps = { title: formatDate(columnDef.name), onClick: () => { @@ -120,7 +135,7 @@ export const dataCellRender = ({ row, columnDef }, showEquipSrv) => { }; return { cellStyle, cellProps, data }; case "green": - cellStyle = { ...cellStyle, cursor: "pointer", backgroundColor: "green", border: "1px solid rgba(0, 0, 0) !important" }; + cellStyle = { ...cellStyle, ...STYLES.DCR_FACT_RELATED_CELL_STYLE }; cellProps = { title: formatDate(columnDef.name), onClick: () => { @@ -129,7 +144,7 @@ export const dataCellRender = ({ row, columnDef }, showEquipSrv) => { }; return { cellStyle, cellProps, data }; case "red": - cellStyle = { ...cellStyle, cursor: "pointer", backgroundColor: "crimson", border: "1px solid rgba(0, 0, 0) !important" }; + cellStyle = { ...cellStyle, ...STYLES.DCR_FACT_NOT_RELATED_CELL_STYLE }; cellProps = { title: formatDate(columnDef.name), onClick: () => { @@ -137,6 +152,7 @@ export const dataCellRender = ({ row, columnDef }, showEquipSrv) => { } }; return { cellStyle, cellProps, data }; + //Случай двойного закрашивания месяца case "green red": case "red green": cellStyle = { ...cellStyle, padding: "unset" }; @@ -167,7 +183,9 @@ export const dataCellRender = ({ row, columnDef }, showEquipSrv) => { return { cellStyle, cellProps }; }; +//Генерация представления заголовка группы export const groupCellRender = () => { - let cellStyle = { display: "none" }; + //Скрываем все группы + let cellStyle = STYLES.HIDE_CELL_STYLE; return { cellStyle }; }; diff --git a/db/PKG_P8PANELS_EQUIPSRV.pck b/db/PKG_P8PANELS_EQUIPSRV.pck index 3deb778..22d188c 100644 --- a/db/PKG_P8PANELS_EQUIPSRV.pck +++ b/db/PKG_P8PANELS_EQUIPSRV.pck @@ -226,9 +226,9 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as SPRJ_GROUP_NAME PKG_STD.TSTRING; -- Наименование группы для проекта BEXPANDED boolean; -- Флаг раскрытости уровня RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы - RDG_ROW0 PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы0 - RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы - RDG_ROW2 PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы2 + RDG_ROW_INFO PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы с информацией по объекту ремонта + RDG_ROW_PLAN PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы с планом по объекту ремонта + RDG_ROW_FACT PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы с фактом по объекту ремонта NCURYEAR PKG_STD.TNUMBER; -- Текущий год NCURMONTH PKG_STD.TNUMBER; -- Текущий месяц NTOTALDAYS PKG_STD.TNUMBER; -- Дней в текущем месяце @@ -270,7 +270,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as TT.DDATEPRD_BEG DDATEPLANBEG, TT.DDATEPRD_END DDATEPLANEND, EQJ.DATEFACT_BEG DDATEFACTBEG, - COALESCE(EQJ.DATEFACT_END, EQJ.DATEFACT_BEG) DDATEFACTEND, -- + COALESCE(EQJ.DATEFACT_END, EQJ.DATEFACT_BEG) DDATEFACTEND, EK.CODE STECSRVKINDCODE, EK.NAME STECSRVKINDNAME, COALESCE(EW.NSUM, (TT.DDATEPRD_END - TT.DDATEPRD_BEG) * 24) NSUMWORKPLAN, @@ -554,7 +554,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as /* Если новый объект ремонта */ if ((SCURTECHOBJ != QQ.STECHOBJNAME) or (SCURTECHOBJ is null)) then /* Если строка с трудоёмкостью по объекту ремонта сформирована */ - if (RDG_ROW0.RCOLS is not null) then + if (RDG_ROW_INFO.RCOLS is not null) then /* Цикл по годам периода */ for Y in NFROMYEAR .. NTOYEAR loop @@ -562,7 +562,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as if (NFROMYEAR = NTOYEAR) then NMS := NFROMMONTH; NME := NTOMONTH; - /* Иначе вычисляем кол-во месяцев в каждом году периода отчёта*/ + /* Иначе вычисляем кол-во месяцев в каждом году периода отчёта */ else if (Y = NFROMYEAR) then NMS := NFROMMONTH; @@ -579,7 +579,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as for M in NMS .. NME loop SPERIODNAME := '_' || TO_CHAR(Y) || '_' || TO_CHAR(M); - PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW0, + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW_INFO, SNAME => SPERIODNAME, SVALUE => 'план: ' || HOURS_STR(NHOURS => TRUNC(PKG_CONTVALLOC1S.GETN(RCONTAINER => YM, SROWID => SPERIODNAME || '_P'), @@ -594,7 +594,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as end loop; end loop; /* Добавление строки с трудоёмкостью */ - PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW0); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW_INFO); end if; /* Добавление группы с объектом ремонта */ SCURTECHOBJ := QQ.STECHOBJNAME; @@ -603,29 +603,29 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as SNAME => SPRJ_GROUP_NAME, SCAPTION => QQ.STECHOBJNAME, BEXPANDABLE => false); - RDG_ROW0 := PKG_P8PANELS_VISUAL.TROW_MAKE(SGROUP => SPRJ_GROUP_NAME); - PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW0, SNAME => 'SOBJINFO', SVALUE => SCURTECHOBJ); + RDG_ROW_INFO := PKG_P8PANELS_VISUAL.TROW_MAKE(SGROUP => SPRJ_GROUP_NAME); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW_INFO, SNAME => 'SOBJINFO', SVALUE => SCURTECHOBJ); end if; /* Формируем имя группы для вида ремонта */ SCURTSKCODE := SCURTECHOBJ || '_' || QQ.STECSRVKINDCODE; /* Если по данной группе еще нет строк плана и факта */ if (PKG_CONTVALLOC1S.EXISTS_(RCONTAINER => GF, SROWID => SCURTSKCODE) = false) then /* Добавляем строку плана */ - if (RDG_ROW.RCOLS is not null) then - PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); + if (RDG_ROW_PLAN.RCOLS is not null) then + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW_PLAN); end if; /* Добавляем строку факта */ - if (RDG_ROW2.RCOLS is not null) then + if (RDG_ROW_FACT.RCOLS is not null) then CR := PKG_CONTVALLOC1S.FIRST_(RCONTAINER => MCLR); /* Цикл по коллекции для закрашивания месяцев */ for Z in 1 .. PKG_CONTVALLOC1S.COUNT_(RCONTAINER => MCLR) loop - PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW2, + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW_FACT, SNAME => CR, SVALUE => PKG_CONTVALLOC1S.GETS(RCONTAINER => MCLR, SROWID => CR)); CR := PKG_CONTVALLOC1S.NEXT_(RCONTAINER => MCLR, SROWID => CR); end loop; - PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW2); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW_FACT); end if; PKG_CONTVALLOC1S.PURGE(RCONTAINER => MCLR); /* Добвим группу для вида ремонта */ @@ -635,12 +635,12 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as SCAPTION => QQ.STECSRVKINDCODE, BEXPANDABLE => false); /* Строка плана */ - RDG_ROW := PKG_P8PANELS_VISUAL.TROW_MAKE(SGROUP => SPRJ_GROUP_NAME); - PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SOBJINFO', SVALUE => QQ.STECSRVKINDCODE); - PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SWRKTYPE', SVALUE => 'План'); + RDG_ROW_PLAN := PKG_P8PANELS_VISUAL.TROW_MAKE(SGROUP => SPRJ_GROUP_NAME); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW_PLAN, SNAME => 'SOBJINFO', SVALUE => QQ.STECSRVKINDCODE); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW_PLAN, SNAME => 'SWRKTYPE', SVALUE => 'План'); /* Строка факта */ - RDG_ROW2 := PKG_P8PANELS_VISUAL.TROW_MAKE(SGROUP => SPRJ_GROUP_NAME); - PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW2, SNAME => 'SWRKTYPE', SVALUE => 'Факт'); + RDG_ROW_FACT := PKG_P8PANELS_VISUAL.TROW_MAKE(SGROUP => SPRJ_GROUP_NAME); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW_FACT, SNAME => 'SWRKTYPE', SVALUE => 'Факт'); /* Добавляем в заполненные группы */ PKG_CONTVALLOC1S.PUTS(RCONTAINER => GF, SROWID => SPRJ_GROUP_NAME, SVALUE => ''); end if; @@ -665,7 +665,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as /* Закрашивание месяца плана синим */ if (PKG_CONTVALLOC1S.EXISTS_(RCONTAINER => COLS, SROWID => SPRJ_GROUP_NAME || ' ' || SPERIODNAME || ' PLAN') = false) then - PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => SPERIODNAME, SVALUE => 'blue'); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW_PLAN, SNAME => SPERIODNAME, SVALUE => 'blue'); PKG_CONTVALLOC1S.PUTS(RCONTAINER => COLS, SROWID => SPRJ_GROUP_NAME || ' ' || SPERIODNAME || ' PLAN', SVALUE => ''); @@ -675,7 +675,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as /* Закрашивание дня плана синим */ if (PKG_CONTVALLOC1S.EXISTS_(RCONTAINER => COLS, SROWID => SPRJ_GROUP_NAME || ' ' || SPERIODNAME || ' PLAN') = false) then - PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => SPERIODNAME, SVALUE => 'blue'); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW_PLAN, SNAME => SPERIODNAME, SVALUE => 'blue'); PKG_CONTVALLOC1S.PUTS(RCONTAINER => COLS, SROWID => SPRJ_GROUP_NAME || ' ' || SPERIODNAME || ' PLAN', SVALUE => ''); @@ -749,7 +749,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as end if; end loop; end if; - if ((RDG_ROW0.RCOLS is not null) and (NROWS = 0)) then + if ((RDG_ROW_INFO.RCOLS is not null) and (NROWS = 0)) then /* Цикл по годам периода */ for Y in NFROMYEAR .. NTOYEAR loop @@ -772,7 +772,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as for M in NMS .. NME loop SPERIODNAME := '_' || TO_CHAR(Y) || '_' || TO_CHAR(M); - PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW0, + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW_INFO, SNAME => SPERIODNAME, SVALUE => 'план: ' || HOURS_STR(NHOURS => TRUNC(PKG_CONTVALLOC1S.GETN(RCONTAINER => YM, SROWID => SPERIODNAME || '_P'), @@ -782,23 +782,23 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as 1))); end loop; end loop; - PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW0); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW_INFO); end if; /* План для последней записи */ - if ((RDG_ROW.RCOLS is not null) and (NROWS = 0)) then - PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); + if ((RDG_ROW_PLAN.RCOLS is not null) and (NROWS = 0)) then + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW_PLAN); end if; /* Факт для последней записи */ - if ((RDG_ROW2.RCOLS is not null) and (NROWS = 0)) then + if ((RDG_ROW_FACT.RCOLS is not null) and (NROWS = 0)) then CR := PKG_CONTVALLOC1S.FIRST_(RCONTAINER => MCLR); for Z in 1 .. PKG_CONTVALLOC1S.COUNT_(RCONTAINER => MCLR) loop - PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW2, + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW_FACT, SNAME => CR, SVALUE => PKG_CONTVALLOC1S.GETS(RCONTAINER => MCLR, SROWID => CR)); CR := PKG_CONTVALLOC1S.NEXT_(RCONTAINER => MCLR, SROWID => CR); end loop; - PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW2); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW_FACT); end if; end loop; /* Сериализуем описание */