diff --git a/app/panels/rrp_conf_editor/custom_dialog.js b/app/panels/rrp_conf_editor/custom_dialog.js deleted file mode 100644 index ec21389..0000000 --- a/app/panels/rrp_conf_editor/custom_dialog.js +++ /dev/null @@ -1,155 +0,0 @@ -/* - Кастомный Dialog -*/ - -//--------------------- -//Подключение библиотек -//--------------------- - -import React from "react"; //Классы React -import PropTypes from "prop-types"; //Контроль свойств компонента -import { Dialog, DialogTitle, IconButton, Icon, DialogContent, Typography, DialogActions, Button } from "@mui/material"; //Интерфейсные компоненты -import { CustomFormControl } from "./custom_form_control"; //Кастомные строки ввода -import { Statuses, STYLES } from "./layouts"; //Статусы и стили диалогового окна - -//----------- -//Тело модуля -//----------- - -const CustomDialog = props => { - const { - formOpen, - closeForm, - curStatus, - curCode, - curName, - curColCode, - curRowCode, - btnOkClick, - codeOnChange, - nameOnChange, - dictColumnClick, - dictRowClick - } = props; - - //Формирование заголовка диалогового окна - const formTitle = () => { - switch (curStatus) { - case Statuses.CREATE: - return "Добавление раздела"; - case Statuses.EDIT: - return "Исправление раздела"; - case Statuses.DELETE: - return "Удаление раздела"; - case Statuses.COLUMNROW_CREATE: - return "Добавление показателя раздела"; - case Statuses.COLUMNROW_EDIT: - return "Исправление показателя раздела"; - case Statuses.COLUMNROW_DELETE: - return "Удаление показателя раздела"; - } - }; - - //Отрисовка диалогового окна - const renderSwitch = () => { - var btnText = ""; - switch (curStatus) { - case Statuses.CREATE: - case Statuses.COLUMNROW_CREATE: - btnText = "Добавить"; - break; - case Statuses.EDIT: - case Statuses.COLUMNROW_EDIT: - btnText = "Исправить"; - break; - case Statuses.DELETE: - case Statuses.COLUMNROW_DELETE: - btnText = "Удалить"; - break; - } - return ( - - ); - }; - - return ( - - {formTitle()} - theme.palette.grey[500] - }} - > - close - - - {curStatus == Statuses.DELETE || curStatus == Statuses.COLUMNROW_DELETE ? ( - curStatus == Statuses.DELETE ? ( - Вы хотите удалить раздел {curName}? - ) : ( - Вы хотите удалить показатель раздела {curName}? - ) - ) : ( -
- {curStatus != Statuses.COLUMNROW_EDIT ? ( - - ) : null} - - {curStatus == Statuses.COLUMNROW_CREATE ? ( -
- - -
- ) : null} -
- )} -
- - {renderSwitch()} - - -
- ); -}; - -CustomDialog.propTypes = { - formOpen: PropTypes.bool.isRequired, - closeForm: PropTypes.func.isRequired, - curStatus: PropTypes.oneOf(Object.values(Statuses).filter(x => typeof x === "number")), - curCode: PropTypes.string, - curName: PropTypes.string, - curColCode: PropTypes.string, - curRowCode: PropTypes.string, - btnOkClick: PropTypes.func.isRequired, - codeOnChange: PropTypes.func.isRequired, - nameOnChange: PropTypes.func.isRequired, - dictColumnClick: PropTypes.func.isRequired, - dictRowClick: PropTypes.func.isRequired -}; - -//---------------- -//Интерфейс модуля -//---------------- - -export { CustomDialog }; diff --git a/app/panels/rrp_conf_editor/custom_form_control.js b/app/panels/rrp_conf_editor/custom_form_control.js deleted file mode 100644 index 2e9cc01..0000000 --- a/app/panels/rrp_conf_editor/custom_form_control.js +++ /dev/null @@ -1,58 +0,0 @@ -/* - Кастомный FormControl -*/ - -//--------------------- -//Подключение библиотек -//--------------------- - -import React from "react"; //Классы React -import PropTypes from "prop-types"; //Контроль свойств компонента -import { Box, FormControl, InputLabel, OutlinedInput, InputAdornment, IconButton, Icon } from "@mui/material"; //Интерфейсные компоненты -import { STYLES } from "./layouts"; //Стили диалогового окна - -//----------- -//Тело модуля -//----------- - -const CustomFormControl = props => { - const { elementCode, elementValue, labelText, changeFunc, withDictionary, ...other } = props; - - return ( - - - {labelText} - changeFunc(e.target.value) : null} - aria-describedby={`${elementCode}-outlined-helper-text`} - label={labelText} - endAdornment={ - withDictionary ? ( - - - list - - - ) : null - } - /> - - - ); -}; - -CustomFormControl.propTypes = { - elementCode: PropTypes.string.isRequired, - elementValue: PropTypes.string, - labelText: PropTypes.string.isRequired, - changeFunc: PropTypes.func.isRequired, - withDictionary: PropTypes.bool -}; - -//---------------- -//Интерфейс модуля -//---------------- - -export { CustomFormControl }; diff --git a/app/panels/rrp_conf_editor/custom_tab_panel.js b/app/panels/rrp_conf_editor/custom_tab_panel.js deleted file mode 100644 index 083db8e..0000000 --- a/app/panels/rrp_conf_editor/custom_tab_panel.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - Кастомный Tab -*/ - -//--------------------- -//Подключение библиотек -//--------------------- - -import React from "react"; //Классы React -import PropTypes from "prop-types"; //Контроль свойств компонента -import { Box, Typography } from "@mui/material"; //Интерфейсные компоненты - -//----------- -//Тело модуля -//----------- - -const CustomTabPanel = props => { - const { children, value, index, ...other } = props; - - return ( - - ); -}; - -CustomTabPanel.propTypes = { - children: PropTypes.node, - index: PropTypes.number.isRequired, - value: PropTypes.number.isRequired -}; - -//---------------- -//Интерфейс модуля -//---------------- - -export { CustomTabPanel }; diff --git a/app/panels/rrp_conf_editor/iud_form_dialog.js b/app/panels/rrp_conf_editor/iud_form_dialog.js new file mode 100644 index 0000000..5c734f3 --- /dev/null +++ b/app/panels/rrp_conf_editor/iud_form_dialog.js @@ -0,0 +1,333 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Панель мониторинга: Диалог добавления/исправления/удаления компонентов настройки регламентированного отчёта +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useState, useContext, useCallback, useEffect } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Dialog, DialogTitle, IconButton, Icon, DialogContent, Typography, DialogActions, Button } from "@mui/material"; //Интерфейсные компоненты +import { ApplicationСtx } from "../../context/application"; //Контекст приложения +import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером +import { IUDFormTextField } from "./iud_form_text_field"; //Компонент поля ввода +import { STATUSES } from "./layouts"; //Статусы и стили диалогового окна + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + CLOSE_BUTTON: { + position: "absolute", + right: 8, + top: 8, + color: theme => theme.palette.grey[500] + }, + PADDING_DIALOG_BUTTONS_RIGHT: { paddingRight: "32px" } +}; + +//--------------- +//Тело компонента +//--------------- + +const IUDFormDialog = ({ initial, onClose, onReload }) => { + //Собственное состояние + const [formData, setFormData] = useState({ ...initial }); + + //Подключение к контексту приложения + const { pOnlineShowDictionary } = useContext(ApplicationСtx); + + //Подключение к контексту взаимодействия с сервером + const { executeStored } = useContext(BackEndСtx); + + //При закрытии диалога без изменений + const handleCancel = () => (onClose ? onClose() : null); + + //При закрытии диалога с изменениями + const handleOK = () => { + if (onClose) { + changeSections(); + onClose(); + } else null; + }; + + //Отработка добавления/изсправления/удаления элемента + const handleReload = () => { + if (onReload) { + onReload(); + } else null; + }; + + //При изменении значения элемента + const handleDialogItemChange = (item, value) => setFormData(pv => ({ ...pv, [item]: value })); + + //Отработка изменений в разделе или показателе раздела + const changeSections = useCallback(async () => { + switch (formData.status) { + case STATUSES.CREATE: + await insertSections(); + break; + case STATUSES.EDIT: + await updateSections(); + break; + case STATUSES.DELETE: + await deleteSections(); + break; + case STATUSES.RRPCONFSCTNMRK_CREATE: + await addRRPCONFSCTNMRK(); + break; + case STATUSES.RRPCONFSCTNMRK_EDIT: + await editRRPCONFSCTNMRK(); + break; + case STATUSES.RRPCONFSCTNMRK_DELETE: + await deleteRRPCONFSCTNMRK(); + break; + } + handleReload(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [formData]); + + //Добавление раздела + const insertSections = useCallback(async () => { + const data = await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_INSERT", + args: { + NPRN: formData.prn, + SCODE: formData.code, + SNAME: formData.name + } + }); + setFormData(pv => ({ + ...pv, + rn: Number(data.NRN) + })); + }, [formData.prn, formData.code, formData.name, executeStored]); + + //Исправление раздела + const updateSections = useCallback(async () => { + await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_UPDATE", + args: { + NRN: formData.rn, + SCODE: formData.code, + SNAME: formData.name + } + }); + }, [formData.name, formData.code, formData.rn, executeStored]); + + //Удаление раздела + const deleteSections = useCallback(async () => { + await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_DELETE", + args: { + NRN: formData.rn + } + }); + }, [formData.rn, executeStored]); + + //Добавление показателя раздела + const addRRPCONFSCTNMRK = useCallback(async () => { + await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_INSERT", + args: { + NPRN: formData.prn, + SCODE: formData.code, + SNAME: formData.name, + SCOLCODE: formData.colCode, + SCOLVER: formData.colVCode, + SROWCODE: formData.rowCode, + SROWVER: formData.rowVCode + } + }); + }, [executeStored, formData.code, formData.colVCode, formData.colCode, formData.name, formData.prn, formData.rowCode, formData.rowVCode]); + + //Исправление показателя раздела + const editRRPCONFSCTNMRK = useCallback(async () => { + await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_UPDATE", + args: { NRN: formData.rn, SNAME: formData.name } + }); + }, [executeStored, formData.name, formData.rn]); + + //Удаление показателя раздела + const deleteRRPCONFSCTNMRK = useCallback(async () => { + await executeStored({ stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_DELETE", args: { NRN: formData.rn } }); + }, [executeStored, formData.rn]); + + //Формирование заголовка диалогового окна + const formTitle = () => { + switch (formData.status) { + case STATUSES.CREATE: + return "Добавление раздела"; + case STATUSES.EDIT: + return "Исправление раздела"; + case STATUSES.DELETE: + return "Удаление раздела"; + case STATUSES.RRPCONFSCTNMRK_CREATE: + return "Добавление показателя раздела"; + case STATUSES.RRPCONFSCTNMRK_EDIT: + return "Исправление показателя раздела"; + case STATUSES.RRPCONFSCTNMRK_DELETE: + return "Удаление показателя раздела"; + } + }; + + //Отрисовка диалогового окна + const renderSwitch = () => { + var btnText = ""; + switch (formData.status) { + case STATUSES.CREATE: + case STATUSES.RRPCONFSCTNMRK_CREATE: + btnText = "Добавить"; + break; + case STATUSES.EDIT: + case STATUSES.RRPCONFSCTNMRK_EDIT: + btnText = "Исправить"; + break; + case STATUSES.DELETE: + case STATUSES.RRPCONFSCTNMRK_DELETE: + btnText = "Удалить"; + break; + } + return ( + + ); + }; + + //Выбор строки + const selectRow = (showDictionary, callBack) => { + showDictionary({ + unitCode: "RRPRow", + callBack: res => { + if (res.success === true) { + callBack(res.outParameters.out_CODE, res.outParameters.out_RRPVERSION_CODE, res.outParameters.out_RRPVERSION); + setFormData(pv => ({ + ...pv, + rowCode: res.outParameters.out_CODE, + rowVCode: res.outParameters.out_RRPVERSION_CODE, + rowVRn: res.outParameters.out_RRPVERSION + })); + } else callBack(null); + } + }); + }; + + //Выбор графы + const selectColumn = (showDictionary, callBack) => { + showDictionary({ + unitCode: "RRPColumn", + callBack: res => { + if (res.success === true) { + callBack(res.outParameters.out_CODE, res.outParameters.out_RRPVERSION_CODE, res.outParameters.out_RRPVERSION); + setFormData(pv => ({ + ...pv, + colCode: res.outParameters.out_CODE, + colVCode: res.outParameters.out_RRPVERSION_CODE, + colVRn: res.outParameters.out_RRPVERSION + })); + } else callBack(null); + } + }); + }; + + //Получение мнемокода и наименования показателя раздела + const getSctnMrkCodeName = useCallback(async () => { + const data = await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_GET_CODE_NAME", + args: { SSCTNCODE: formData.sctnCode, SROWCODE: formData.rowCode, SCOLUMNCODE: formData.colCode } + }); + setFormData(pv => ({ + ...pv, + code: data.SCODE, + name: data.SNAME + })); + }, [executeStored, formData.colCode, formData.rowCode, formData.sctnCode]); + + //Получение наименования и мнемокода показателя раздела при заполнении необходимых полей + useEffect(() => { + formData.status == STATUSES.RRPCONFSCTNMRK_CREATE && formData.sctnName && formData.sctnCode && formData.colCode && formData.rowCode + ? getSctnMrkCodeName() + : null; + }, [formData.colCode, formData.rowCode, formData.sctnCode, formData.sctnName, formData.status, getSctnMrkCodeName]); + + //Генерация содержимого + return ( + + {formTitle()} + + close + + + {formData.status == STATUSES.DELETE || formData.status == STATUSES.RRPCONFSCTNMRK_DELETE ? ( + formData.status == STATUSES.DELETE ? ( + Вы хотите удалить раздел {formData.name}? + ) : ( + Вы хотите удалить показатель раздела {formData.name}? + ) + ) : ( +
+ {formData.status != STATUSES.RRPCONFSCTNMRK_EDIT ? ( + + ) : null} + + {formData.status == STATUSES.RRPCONFSCTNMRK_CREATE ? ( +
+ selectRow(pOnlineShowDictionary, callBack)} + /> + selectColumn(pOnlineShowDictionary, callBack)} + /> +
+ ) : null} +
+ )} +
+ + {renderSwitch()} + + +
+ ); +}; + +//Контроль свойств - Диалог +IUDFormDialog.propTypes = { + initial: PropTypes.object.isRequired, + onClose: PropTypes.func, + onReload: PropTypes.func +}; + +//-------------------- +//Интерфейс компонента +//-------------------- + +export { IUDFormDialog }; diff --git a/app/panels/rrp_conf_editor/iud_form_text_field.js b/app/panels/rrp_conf_editor/iud_form_text_field.js new file mode 100644 index 0000000..4ef0877 --- /dev/null +++ b/app/panels/rrp_conf_editor/iud_form_text_field.js @@ -0,0 +1,86 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Панель мониторинга: Компонент поля ввода +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useState, useEffect } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Box, FormControl, InputLabel, Input, InputAdornment, IconButton, Icon } from "@mui/material"; //Интерфейсные компоненты + +//--------- +//Константы +//--------- + +//Стили +export const STYLES = { + DIALOG_WINDOW_WIDTH: { width: 400 } +}; + +//--------------- +//Тело компонента +//--------------- + +const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dictionary, ...other }) => { + //Значение элемента + const [value, setValue] = useState(elementValue); + + //При получении нового значения из вне + useEffect(() => { + setValue(elementValue); + }, [elementValue]); + + //Выбор значения из словаря + const handleDictionaryClick = () => + dictionary ? dictionary(res => (res ? handleChange({ target: { name: elementCode, value: res } }) : null)) : null; + + //Изменение значения элемента + const handleChange = e => { + setValue(e.target.value); + if (onChange) onChange(e.target.name, e.target.value); + }; + + //Генерация содержимого + return ( + + + {labelText} + + + list + + + ) : null + } + onChange={handleChange} + multiline + maxRows={4} + /> + + + ); +}; + +//Контроль свойств - Поле ввода +IUDFormTextField.propTypes = { + elementCode: PropTypes.string.isRequired, + elementValue: PropTypes.string, + labelText: PropTypes.string.isRequired, + onChange: PropTypes.func, + dictionary: PropTypes.func +}; + +//-------------------- +//Интерфейс компонента +//-------------------- + +export { IUDFormTextField }; diff --git a/app/panels/rrp_conf_editor/layouts.js b/app/panels/rrp_conf_editor/layouts.js index 7e968df..4b25d30 100644 --- a/app/panels/rrp_conf_editor/layouts.js +++ b/app/panels/rrp_conf_editor/layouts.js @@ -1,5 +1,5 @@ /* - Парус 8 - + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта Дополнительная разметка и вёрстка клиентских элементов */ @@ -8,38 +8,46 @@ //--------------------- import React from "react"; //Классы React -import { Stack, IconButton, Icon, Typography } from "@mui/material"; //Интерфейсные компоненты +import { Box, IconButton, Icon, Link } from "@mui/material"; //Интерфейсные компоненты //--------- //Константы //--------- +//Стили export const STYLES = { - DIALOG_WINDOW_WIDTH: { width: 400 }, - PADDING_DIALOG_BUTTONS_RIGHT: { paddingRight: "32px" } + BOX_ROW: { display: "flex", justifyContent: "center", alignItems: "center" }, + LINK_STYLE: { component: "button", width: "-webkit-fill-available" } }; //Статусы диалогового окна -export const Statuses = { CREATE: 0, EDIT: 1, DELETE: 2, COLUMNROW_CREATE: 3, COLUMNROW_EDIT: 4, COLUMNROW_DELETE: 5 }; +export const STATUSES = { CREATE: 0, EDIT: 1, DELETE: 2, RRPCONFSCTNMRK_CREATE: 3, RRPCONFSCTNMRK_EDIT: 4, RRPCONFSCTNMRK_DELETE: 5 }; //----------- //Тело модуля //----------- //Генерация представления ячейки c данными -export const dataCellRender = ({ row, columnDef }, editCR, deleteCR) => { +export const dataCellRender = ({ row, columnDef }, showRrpConfSctnMrk, editCR, deleteCR) => { let data = row[columnDef.name]; columnDef.name != "SROW_NAME" && data != undefined && columnDef.visible == true ? (data = ( - - {row[columnDef.name]} - editCR(row["NRN_" + columnDef.name.substring(5)], row[columnDef.name])}> + + { + showRrpConfSctnMrk(row["NRN_" + columnDef.name.substring(5)]); + }} + > + {row[columnDef.name]} + + editCR(row["NRN_" + columnDef.name.substring(5)], row[columnDef.name])}> edit - deleteCR(row["NRN_" + columnDef.name.substring(5)], row[columnDef.name])}> + deleteCR(row["NRN_" + columnDef.name.substring(5)], row[columnDef.name])}> delete - + )) : null; return { data }; diff --git a/app/panels/rrp_conf_editor/rrp_conf_editor.js b/app/panels/rrp_conf_editor/rrp_conf_editor.js index 3cdc7db..80ebec0 100644 --- a/app/panels/rrp_conf_editor/rrp_conf_editor.js +++ b/app/panels/rrp_conf_editor/rrp_conf_editor.js @@ -1,5 +1,6 @@ /* - Парус 8 - Редактор настройки регламентированного отчёта + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Панель мониторинга: Корневая панель редактора */ //--------------------- @@ -10,12 +11,25 @@ import React, { useCallback, useContext, useState, useEffect } from "react"; // import { Box, Tab, Tabs, IconButton, Icon, Stack, Button } from "@mui/material"; //Интерфейсные компоненты import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения +import { ApplicationСtx } from "../../context/application"; //Контекст приложения import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером import { NavigationCtx } from "../../context/navigation"; //Контекст навигации -import { CustomTabPanel } from "./custom_tab_panel"; //Кастомный Tab -import { ApplicationСtx } from "../../context/application"; //Контекст приложения -import { Statuses, dataCellRender } from "./layouts"; //Дополнительная разметка и вёрстка клиентских элементов -import { CustomDialog } from "./custom_dialog"; //Кастомное диалоговое окно +import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений +import { SectionTabPanel } from "./section_tab_panel"; //Компонент вкладки раздела +import { IUDFormDialog } from "./iud_form_dialog"; //Диалог добавления/исправления/удаления компонентов настройки регламентированного отчёта +import { STATUSES, dataCellRender } from "./layouts"; //Дополнительная разметка и вёрстка клиентских элементов +import { TEXTS } from "../../../app.text"; //Текстовые константы +import { STYLES as COMMON_STYLES } from "./layouts"; //Общие стили + +//--------- +//Константы +//--------- + +//Стили +export const STYLES = { + TABS_BOTTOM_LINE: { borderBottom: 1, borderColor: "divider" }, + TABS_PADDING: { paddingTop: 1, paddingBottom: 1 } +}; //----------- //Тело модуля @@ -31,6 +45,8 @@ const RrpConfEditor = () => { columnsDef: [], groups: [], rows: [], + fixedHeader: false, + fixedColumns: 0, reload: false }; @@ -52,7 +68,6 @@ const RrpConfEditor = () => { //Состояние диалогового окна const [formData, setFormData] = useState({ - filled: false, rn: "", prn: "", sctnName: "", @@ -75,17 +90,24 @@ const RrpConfEditor = () => { setForm(true); }; - //Закрытие диалогового окна - const closeForm = () => { - setForm(false); - }; - //Очистка диалогового окна const clearFormData = () => { setFormData({ rn: "", + prn: "", + sctnName: "", + sctnCode: "", + status: "", code: "", - name: "" + name: "", + colName: "", + colCode: "", + colVCode: "", + colVRn: 0, + rowName: "", + rowCode: "", + rowVCode: "", + rowVRn: 0 }); }; @@ -93,11 +115,14 @@ const RrpConfEditor = () => { const { executeStored } = useContext(BackEndСtx); //Подключение к контексту приложения - const { pOnlineShowDictionary } = useContext(ApplicationСtx); + const { pOnlineShowUnit } = useContext(ApplicationСtx); //Подключение к контексту навигации const { getNavigationSearch } = useContext(NavigationCtx); + //Подключение к контексту сообщений + const { showMsgErr } = useContext(MessagingСtx); + //Переключение раздела const handleChange = (event, newValue) => { setTabValue(newValue); @@ -105,87 +130,40 @@ const RrpConfEditor = () => { //Отработка нажатия на кнопку добавления секции const addSectionClick = () => { - setFormData({ status: Statuses.CREATE, prn: Number(getNavigationSearch().NRN) }); + setFormData({ status: STATUSES.CREATE, prn: Number(getNavigationSearch().NRN) }); openForm(); }; //Отработка нажатия на кнопку исправления секции const editSectionClick = (rn, code, name) => { - setFormData({ rn: rn, code: code, name: name, status: Statuses.EDIT }); + setFormData({ rn: rn, code: code, name: name, status: STATUSES.EDIT }); openForm(); }; //Отработка нажатия на кнопку удаления секции const deleteSectionClick = (rn, code, name) => { - setFormData({ rn: rn, code: code, name: name, status: Statuses.DELETE }); + setFormData({ rn: rn, code: code, name: name, status: STATUSES.DELETE }); openForm(); }; //Отработка нажатия на кнопку добавления показателя раздела - const addColumnRowClick = (prn, sctnCode, sctnName) => { - setFormData({ status: Statuses.COLUMNROW_CREATE, prn: prn, sctnCode: sctnCode, sctnName: sctnName }); + const addRRPCONFSCTNMRKClick = (prn, sctnCode, sctnName) => { + setFormData({ status: STATUSES.RRPCONFSCTNMRK_CREATE, prn: prn, sctnCode: sctnCode, sctnName: sctnName }); openForm(); }; //Отработка нажатия на кнопку исправления показателя раздела - const editColumnRowClick = (rn, name) => { - setFormData({ status: Statuses.COLUMNROW_EDIT, rn: rn, name: name }); + const editRRPCONFSCTNMRKClick = (rn, name) => { + setFormData({ status: STATUSES.RRPCONFSCTNMRK_EDIT, rn: rn, name: name }); openForm(); }; //Отработка нажатия на кнопку удаления показателя раздела - const deleteColumnRowClick = (rn, name) => { - setFormData({ status: Statuses.COLUMNROW_DELETE, rn: rn, name: name }); + const deleteRRPCONFSCTNMRKClick = (rn, name) => { + setFormData({ status: STATUSES.RRPCONFSCTNMRK_DELETE, rn: rn, name: name }); openForm(); }; - //Отработка нажатия на словарь граф - const dictColumnClick = () => { - pOnlineShowDictionary({ - unitCode: "RRPColumn", - callBack: res => - res.success === true - ? setFormData(pv => ({ - ...pv, - colCode: res.outParameters.out_CODE, - colVCode: res.outParameters.out_RRPVERSION_CODE, - colVRn: res.outParameters.out_RRPVERSION - })) - : null - }); - }; - - //Отработка нажатия на словарь строк - const dictRowClick = () => { - pOnlineShowDictionary({ - unitCode: "RRPRow", - callBack: res => - res.success === true - ? setFormData(pv => ({ - ...pv, - rowCode: res.outParameters.out_CODE, - rowVCode: res.outParameters.out_RRPVERSION_CODE, - rowVRn: res.outParameters.out_RRPVERSION - })) - : null - }); - }; - - //Нажатие на кнопку подтверждения создания/исправления/удаления на форме - const formBtnOkClick = () => { - let formStateProps = {}; - if (formData.status === (Statuses.CREATE || Statuses.EDIT || Statuses.COLUMNROW_CREATE)) - formStateProps = { ...formStateProps, code: document.querySelector("#code-outlined").value }; - if (formData.status === (Statuses.CREATE || Statuses.EDIT || Statuses.COLUMNROW_CREATE || Statuses.COLUMNROW_EDIT)) - formStateProps = { ...formStateProps, name: document.querySelector("#name-outlined").value }; - setFormData(pv => ({ - ...pv, - ...formStateProps, - filled: true - })); - closeForm(); - }; - //Формирование разделов const a11yProps = index => { return { @@ -194,120 +172,6 @@ const RrpConfEditor = () => { }; }; - //Отработка изменений в разделе или показателе раздела - const changeSections = useCallback(async () => { - if (formData.filled) { - switch (formData.status) { - case Statuses.CREATE: - insertSections(); - clearFormData(); - break; - case Statuses.EDIT: - updateSections(); - clearFormData(); - break; - case Statuses.DELETE: - deleteSections(); - clearFormData(); - break; - case Statuses.COLUMNROW_CREATE: - addColumnRow(); - clearFormData(); - break; - case Statuses.COLUMNROW_EDIT: - editColumnRow(); - clearFormData(); - break; - case Statuses.COLUMNROW_DELETE: - deleteColumnRow(); - clearFormData(); - break; - } - setRrpDoc(pv => ({ ...pv, reload: true })); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [formData]); - - //Добавление раздела - const insertSections = useCallback(async () => { - const data = await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.INSERT_RRPCONF_SECTIONS", - args: { - NPRN: formData.prn, - SCODE: formData.code, - SNAME: formData.name - } - }); - setFormData(pv => ({ - ...pv, - rn: Number(data.NRN) - })); - }, [formData.prn, formData.code, formData.name, executeStored]); - - //Исправление раздела - const updateSections = useCallback(async () => { - await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.UPDATE_RRPCONF_SECTIONS", - args: { - NRN: formData.rn, - SCODE: formData.code, - SNAME: formData.name - } - }); - }, [formData.name, formData.code, formData.rn, executeStored]); - - //Удаление раздела - const deleteSections = useCallback(async () => { - await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.DELETE_RRPCONF_SECTIONS", - args: { - NRN: formData.rn - } - }); - }, [formData.rn, executeStored]); - - //Добавление показателя раздела - const addColumnRow = useCallback(async () => { - await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.INSERT_RRPCONF_COLUMNROW", - args: { - NPRN: formData.prn, - SCODE: formData.code, - SNAME: formData.name, - SCOLCODE: formData.colCode, - SCOLVER: formData.colVCode, - SROWCODE: formData.rowCode, - SROWVER: formData.rowVCode - } - }); - }, [executeStored, formData.code, formData.colVCode, formData.colCode, formData.name, formData.prn, formData.rowCode, formData.rowVCode]); - - //Исправление показателя раздела - const editColumnRow = useCallback(async () => { - await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.UPDATE_RRPCONF_COLUMNROW", - args: { NRN: formData.rn, SNAME: formData.name } - }); - }, [executeStored, formData.name, formData.rn]); - - //Удаление показателя раздела - const deleteColumnRow = useCallback(async () => { - await executeStored({ stored: "PKG_P8PANELS_RRPCONFED.DELETE_RRPCONF_COLUMNROW", args: { NRN: formData.rn } }); - }, [executeStored, formData.rn]); - - //Получение мнемокода и наименования показателя раздела - const getSctnMrkCodeName = useCallback(async () => { - const data = await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.GET_RRPCONFSCTNMRK_CODE_NAME", - args: { SSCTNCODE: formData.sctnCode, SROWCODE: formData.rowCode, SCOLUMNCODE: formData.colCode } - }); - setFormData(pv => ({ - ...pv, - code: data.SCODE, - name: data.SNAME - })); - }, [executeStored, formData.colCode, formData.rowCode, formData.sctnCode]); - //Загрузка данных разделов регламентированного отчёта const loadData = useCallback(async () => { if (rrpDoc.reload) { @@ -325,7 +189,7 @@ const RrpConfEditor = () => { //Копирование массива уже загруженных разделов let cloneDGs = dataGrids.slice(); //Массив из нескольких разделов и из одного - const sections = data.SECTIONS.length ? data.SECTIONS : [data.SECTIONS]; + const sections = data.SECTIONS ? (data.SECTIONS.length ? data.SECTIONS : [data.SECTIONS]) : []; //Заполнение очередного раздела по шаблону sections.map(s => { let dg = {}; @@ -337,6 +201,8 @@ const RrpConfEditor = () => { columnsDef: [...(s.XDATA.XCOLUMNS_DEF || [])], groups: [...(s.XDATA.XGROUPS || [])], rows: [...(s.XDATA.XROWS || [])], + fixedHeader: s.XDATA.XDATA_GRID.fixedHeader, + fixedColumns: s.XDATA.XDATA_GRID.fixedColumns, reload: false }); //Ищем загружен ли уже раздел с таким же ид. @@ -370,7 +236,9 @@ const RrpConfEditor = () => { //Устаревший раздел удаляем из массива данных dataGrids.splice(curIndex, 1); //Фокус на предшествующий раздел - tabFocus = curIndex - 1; + if (curIndex > 0) tabFocus = curIndex - 1; + //Иначе фокус на следующий, если был удалён первый раздел + else tabFocus = curIndex; }); setRrpDoc(pv => ({ ...pv, @@ -383,89 +251,94 @@ const RrpConfEditor = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [rrpDoc.reload, rrpDoc.docLoaded, dataGrid.reload, dataGrid.docLoaded, executeStored]); + //Отбор показателя раздела по ид. + const showRrpConfSctnMrk = async rn => { + const data = await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.SELECT_RRPCONFSCTNMRK", + args: { + NRN: rn + } + }); + if (data.NIDENT) { + pOnlineShowUnit({ unitCode: "RRPConfigSectionMark", inputParameters: [{ name: "in_SelectList_Ident", value: data.NIDENT }] }); + } else showMsgErr(TEXTS.NO_DATA_FOUND); + }; + //При необходимости обновить данные таблицы useEffect(() => { loadData(); }, [rrpDoc.reload, dataGrid.reload, loadData]); - //Обновление при изменении разделов - useEffect(() => { - changeSections(); - }, [changeSections]); + //При изменениях элемента + const handleDialogReload = () => { + setRrpDoc(pv => ({ ...pv, reload: true })); + }; - //Получение наименования и мнемокода показателя раздела при заполнении необходимых полей - useEffect(() => { - formData.status == Statuses.COLUMNROW_CREATE && formData.sctnName && formData.sctnCode && formData.colCode && formData.rowCode - ? getSctnMrkCodeName() - : null; - }, [formData.colCode, formData.rowCode, formData.sctnCode, formData.sctnName, formData.status, getSctnMrkCodeName]); + //При закрытии диалога + const handleDialogClose = () => { + setForm(false); + clearFormData(); + }; //Генерация содержимого return ( - {formOpen ? ( - setFormData(pv => ({ ...pv, code: v }))} - nameOnChange={v => setFormData(pv => ({ ...pv, name: v }))} - dictColumnClick={dictColumnClick} - dictRowClick={dictRowClick} - /> - ) : null} + {formOpen ? : null} {rrpDoc.docLoaded ? ( - - + + {rrpDoc.sections.map((s, i) => { return ( + {s.name} - editSectionClick(s.rn, s.code, s.name)}> + editSectionClick(s.rn, s.code, s.name)}> edit - deleteSectionClick(s.rn, s.code, s.name)}> + deleteSectionClick(s.rn, s.code, s.name)}> delete - + } wrapped /> ); })} - - add - + + + add + + {rrpDoc.sections.map((s, i) => { return ( - - + + {s.dataLoaded ? ( - dataCellRender({ ...prms }, editColumnRowClick, deleteColumnRowClick)} - /> + + + dataCellRender({ ...prms }, showRrpConfSctnMrk, editRRPCONFSCTNMRKClick, deleteRRPCONFSCTNMRKClick) + } + /> + ) : null} - + ); })} diff --git a/app/panels/rrp_conf_editor/section_tab_panel.js b/app/panels/rrp_conf_editor/section_tab_panel.js new file mode 100644 index 0000000..ff67ee9 --- /dev/null +++ b/app/panels/rrp_conf_editor/section_tab_panel.js @@ -0,0 +1,44 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Панель мониторинга: Компонент вкладки раздела +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Box, Typography } from "@mui/material"; //Интерфейсные компоненты + +//--------------- +//Тело компонента +//--------------- + +const SectionTabPanel = props => { + const { children, value, index, ...other } = props; + + //Генерация содержимого + return ( + + ); +}; + +//Контроль свойств - Вкладка раздела +SectionTabPanel.propTypes = { + children: PropTypes.node, + index: PropTypes.number.isRequired, + value: PropTypes.number.isRequired +}; + +//-------------------- +//Интерфейс компонента +//-------------------- + +export { SectionTabPanel }; diff --git a/db/PKG_P8PANELS_RRPCONFED.pck b/db/PKG_P8PANELS_RRPCONFED.pck index 74be876..e957024 100644 --- a/db/PKG_P8PANELS_RRPCONFED.pck +++ b/db/PKG_P8PANELS_RRPCONFED.pck @@ -1,7 +1,7 @@ create or replace package PKG_P8PANELS_RRPCONFED as /* Добавление раздела регламентированного отчёта */ - procedure INSERT_RRPCONF_SECTIONS + procedure RRPCONFSCTN_INSERT ( NPRN in number, -- Ид. настройки форм регламентированного отчёта SCODE in varchar2, -- Мнемокод @@ -10,7 +10,7 @@ create or replace package PKG_P8PANELS_RRPCONFED as ); /* Исправление раздела регламентированного отчёта */ - procedure UPDATE_RRPCONF_SECTIONS + procedure RRPCONFSCTN_UPDATE ( NRN in number, -- Ид. раздела SCODE in varchar2, -- Мнемокод раздела @@ -18,13 +18,13 @@ create or replace package PKG_P8PANELS_RRPCONFED as ); /* Удаление раздела регламентированного отчёта */ - procedure DELETE_RRPCONF_SECTIONS + procedure RRPCONFSCTN_DELETE ( - NRN in number -- Ид. раздела + NRN in number -- Ид. раздела ); /* Добавление показателя раздела регламентированного отчёта */ - procedure INSERT_RRPCONF_COLUMNROW + procedure RRPCONFSCTNMRK_INSERT ( NPRN in number, -- Ид. раздела SCODE in varchar2, -- Мнемокод показателя раздела @@ -37,20 +37,20 @@ create or replace package PKG_P8PANELS_RRPCONFED as ); /* Исправление показателя раздела регламентированного отчёта */ - procedure UPDATE_RRPCONF_COLUMNROW + procedure RRPCONFSCTNMRK_UPDATE ( NRN in number, -- Ид. показателя раздела SNAME in varchar2 -- Новое наименование ); /* Удаление показателя раздела регламентированного отчёта */ - procedure DELETE_RRPCONF_COLUMNROW + procedure RRPCONFSCTNMRK_DELETE ( NRN in number -- Ид. показателя раздела ); /* Формирование кода и наименования показателя раздела регламентированного отчёта */ - procedure GET_RRPCONFSCTNMRK_CODE_NAME + procedure RRPCONFSCTNMRK_GET_CODE_NAME ( SSCTNCODE in varchar2, -- Мнемокод раздела SROWCODE in varchar2, -- Мнемокод строки @@ -58,6 +58,13 @@ create or replace package PKG_P8PANELS_RRPCONFED as SCODE out varchar2, -- Мнемокод показателя раздела SNAME out varchar2 -- Наименование показателя раздела ); + + /* Отбор показателя раздела по ид. */ + procedure SELECT_RRPCONFSCTNMRK + ( + NRN in number, -- Ид. показателя раздела + NIDENT out number -- Ид. буфера подобранных (списка отмеченных записей, null - не найдено) + ); /* Получение разделов регламентированного отчёта */ procedure GET_RRPCONF_SECTIONS @@ -71,7 +78,7 @@ end PKG_P8PANELS_RRPCONFED; create or replace package body PKG_P8PANELS_RRPCONFED as /* Добавление раздела регламентированного отчёта */ - procedure INSERT_RRPCONF_SECTIONS + procedure RRPCONFSCTN_INSERT ( NPRN in number, -- Ид. настройки форм регламентированного отчёта SCODE in varchar2, -- Мнемокод @@ -95,10 +102,10 @@ create or replace package body PKG_P8PANELS_RRPCONFED as NLINKS_UPDATE => 0, NDUP_RN => null, NRN => NRN); - end INSERT_RRPCONF_SECTIONS; + end RRPCONFSCTN_INSERT; /* Исправление раздела регламентированного отчёта */ - procedure UPDATE_RRPCONF_SECTIONS + procedure RRPCONFSCTN_UPDATE ( NRN in number, -- Ид. раздела SCODE in varchar2, -- Мнемокод раздела @@ -120,10 +127,10 @@ create or replace package body PKG_P8PANELS_RRPCONFED as SCLSF_CODE => null, NFORMULA_UPDATE => 0, NMARK_UPDATE => 0); - end UPDATE_RRPCONF_SECTIONS; + end RRPCONFSCTN_UPDATE; /* Удаление раздела регламентированного отчёта */ - procedure DELETE_RRPCONF_SECTIONS + procedure RRPCONFSCTN_DELETE ( NRN in number -- Ид. раздела ) @@ -131,10 +138,10 @@ create or replace package body PKG_P8PANELS_RRPCONFED as NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации begin P_RRPCONFSCTN_DELETE(NRN => NRN, NCOMPANY => NCOMPANY); - end DELETE_RRPCONF_SECTIONS; + end RRPCONFSCTN_DELETE; /* Добавление показателя раздела регламентированного отчёта */ - procedure INSERT_RRPCONF_COLUMNROW + procedure RRPCONFSCTNMRK_INSERT ( NPRN in number, -- Ид. раздела SCODE in varchar2, -- Мнемокод показателя раздела @@ -170,10 +177,10 @@ create or replace package body PKG_P8PANELS_RRPCONFED as SNOTE => null, NDUP_RN => null, NRN => NRN); - end INSERT_RRPCONF_COLUMNROW; + end RRPCONFSCTNMRK_INSERT; /* Исправление показателя раздела регламентированного отчёта */ - procedure UPDATE_RRPCONF_COLUMNROW + procedure RRPCONFSCTNMRK_UPDATE ( NRN in number, -- Ид. показателя раздела SNAME in varchar2 -- Новое наименование @@ -228,10 +235,10 @@ create or replace package body PKG_P8PANELS_RRPCONFED as SCLSF_CODE => null, NFORMULA_UPDATE => 0, SNOTE => null); - end UPDATE_RRPCONF_COLUMNROW; + end RRPCONFSCTNMRK_UPDATE; /* Удаление показателя раздела регламентированного отчёта */ - procedure DELETE_RRPCONF_COLUMNROW + procedure RRPCONFSCTNMRK_DELETE ( NRN in number -- Ид. показателя раздела ) @@ -239,10 +246,10 @@ create or replace package body PKG_P8PANELS_RRPCONFED as NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации begin P_RRPCONFSCTNMRK_DELETE(NCOMPANY => NCOMPANY, NRN => NRN); - end DELETE_RRPCONF_COLUMNROW; + end RRPCONFSCTNMRK_DELETE; /* Формирование кода и наименования показателя раздела регламентированного отчёта */ - procedure GET_RRPCONFSCTNMRK_CODE_NAME + procedure RRPCONFSCTNMRK_GET_CODE_NAME ( SSCTNCODE in varchar2, -- Мнемокод раздела SROWCODE in varchar2, -- Мнемокод строки @@ -267,7 +274,34 @@ create or replace package body PKG_P8PANELS_RRPCONFED as NCHANGE_NAME => 1, NCHANGE_NAME_PARENT => 0, SNAME => SNAME); - end GET_RRPCONFSCTNMRK_CODE_NAME; + end RRPCONFSCTNMRK_GET_CODE_NAME; + + /* Отбор показателя раздела по ид. */ + procedure SELECT_RRPCONFSCTNMRK + ( + NRN in number, -- Ид. показателя раздела + NIDENT out number -- Ид. буфера подобранных (списка отмеченных записей, null - не найдено) + ) + is + NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации + NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных + begin + /* Сформируем идентификатор буфера */ + if (NIDENT is null) then + NIDENT := GEN_IDENT(); + end if; + /* Добавим подобранное в список отмеченных записей */ + P_SELECTLIST_BASE_INSERT(NIDENT => NIDENT, + NCOMPANY => NCOMPANY, + NDOCUMENT => NRN, + SUNITCODE => 'RRPConfigSectionMark', + SACTIONCODE => null, + NCRN => null, + NDOCUMENT1 => null, + SUNITCODE1 => null, + SACTIONCODE1 => null, + NRN => NSELECTLIST); + end SELECT_RRPCONFSCTNMRK; /* Получение разделов регламентированного отчёта */ procedure GET_RRPCONF_SECTIONS @@ -343,12 +377,13 @@ create or replace package body PKG_P8PANELS_RRPCONFED as and T.VERSION = NVERSION) loop /* Инициализируем таблицу данных */ - RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE(); + RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE(BFIXED_HEADER => true, NFIXED_COLUMNS => 1); /* Формируем структуру заголовка */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SROW_NAME', SCAPTION => 'Наименование строки', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + NWIDTH => 150); /* Цикл формирования колонок с графами */ for CL in CN(C.NRN) loop