/* Парус 8 - Панели мониторинга - Редакторы панелей Компонент: Диалог настройки источника данных */ //--------------------- //Подключение библиотек //--------------------- import React, { useState, useEffect, useContext } from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента import { Stack, IconButton, Icon, TextField, InputAdornment, MenuItem, Menu } from "@mui/material"; //Интерфейсные элементы import { ApplicationСtx } from "../../context/application"; //Контекст приложения import { TITLES, CAPTIONS } from "../../../app.text"; //Общие текстовые ресурсы import { P8PConfigDialog } from "./p8p_config_dialog"; //Типовой диалог настройки import { P8P_DATA_SOURCE_TYPE, P8P_DATA_SOURCE_SHAPE, P8P_DATA_SOURCE_ARGUMENT_INITIAL, P8P_DATA_SOURCE_INITIAL } from "./p8p_data_source_common"; //Общие ресурсы компонента "Источник данных" import { useUserProcDesc } from "./p8p_data_source_hooks"; //Хуки источников данных import { P8PDataSourceQuerySelector } from "./p8p_data_source_query_selector"; //Диалог выбора записи редактора запросов import { hasValue } from "../../core/utils"; //Вспомогательные функции //----------- //Тело модуля //----------- //Диалог настройки источника данных const P8PDataSourceConfigDialog = ({ dataSource = null, valueProviders = {}, onOk = null, onCancel = null } = {}) => { //Собственное состояние - параметры элемента формы const [state, setState] = useState({ ...P8P_DATA_SOURCE_INITIAL, ...dataSource }); //Собственное состояние - флаги обновление данных const [refresh, setRefresh] = useState({ userProcDesc: 0 }); //Собственное состояние - элемент привязки меню выбора источника const [valueProvidersMenuAnchorEl, setValueProvidersMenuAnchorEl] = useState(null); //Описание выбранной пользовательской процедуры const [userProcDesc] = useUserProcDesc({ code: state.userProc, refresh: refresh.userProcDesc }); //Собственное состояние - отображение диалога выбора запроса const [openQuerySelector, setOpenQuerySelector] = useState(false); //Собственное состояние - доступность полей выбора источника const [disabledFields, setDisabledFields] = useState({ query: false, userProc: false }); //Подключение к контексту приложения const { pOnlineShowDictionary } = useContext(ApplicationСtx); //Установка значения/привязки аргумента const setArgumentValueSource = (index, value, valueSource) => setState(pv => ({ ...pv, arguments: pv.arguments.map((argument, i) => ({ ...argument, ...(i == index ? { value, valueSource } : {}) })) })); //Открытие/сокрытие меню выбора источника const toggleValueProvidersMenu = target => setValueProvidersMenuAnchorEl(target instanceof Element ? target : null); //При нажатии на очистку наименования пользовательской процедуры const handleUserProcClearClick = () => setState({ ...P8P_DATA_SOURCE_INITIAL }); //При нажатии на выбор пользовательской процедуры в качестве источника данных const handleUserProcSelectClick = () => { pOnlineShowDictionary({ unitCode: "UserProcedures", showMethod: "main", inputParameters: [{ name: "in_CODE", value: state.userProc }], callBack: res => { if (res.success) { setState(pv => ({ ...pv, type: P8P_DATA_SOURCE_TYPE.USER_PROC, userProc: res.outParameters.out_CODE })); setRefresh(pv => ({ ...pv, userProcDesc: pv.userProcDesc + 1 })); } } }); }; //При закрытии дилога с сохранением const handleOk = () => onOk && onOk({ ...state }); //При закртии диалога отменой const handleCancel = () => onCancel && onCancel(); //При очистке значения/связывания аргумента const handleArgumentClearClick = index => setArgumentValueSource(index, "", ""); //При отображении меню связывания аргумента с поставщиком данных const handleArgumentLinkMenuClick = e => setValueProvidersMenuAnchorEl(e.currentTarget); //При выборе элемента меню связывания аргумента с поставщиком данных const handleArgumentLinkClick = valueSource => { setArgumentValueSource(valueProvidersMenuAnchorEl.id, "", valueSource); toggleValueProvidersMenu(); }; //При вводе значения аргумента const handleArgumentChange = (index, value) => setArgumentValueSource(index, value, ""); //Открытие диалога выбора запроса const handleOpenQuerySelector = () => setOpenQuerySelector(true); //Закрытие диалога выбора запроса const handleCancelQuerySelector = () => setOpenQuerySelector(false); //При нажатии на очистку мнемокода запроса const handleQueryClearClick = () => setState({ ...P8P_DATA_SOURCE_INITIAL }); //При нажатии на выбор запроса в качестве источника данных const handleQuerySelectClick = query => { setState(pv => ({ ...pv, type: P8P_DATA_SOURCE_TYPE.QUERY, query: query.code })); handleCancelQuerySelector(); }; //При изменении описания пользовательской процедуры useEffect(() => { if (userProcDesc) setState(pv => ({ ...pv, stored: userProcDesc?.stored?.name, respArg: userProcDesc?.stored?.respArg, arguments: (userProcDesc?.arguments || []).map(argument => ({ ...P8P_DATA_SOURCE_ARGUMENT_INITIAL, ...argument })) })); }, [userProcDesc]); //При изменении источника useEffect(() => { /* Если выбран запрос - блокируем выбор процедуры Если выбрана процедура - блокируем выбор запроса Ничего не выбрано - доступны все варианты */ hasValue(state.query) ? setDisabledFields({ query: false, userProc: true }) : hasValue(state.userProc) ? setDisabledFields({ query: true, userProc: false }) : setDisabledFields({ query: false, userProc: false }); }, [state.query, state.userProc]); //Список значений const values = Object.keys(valueProviders); //Наличие значений const isValues = values && values.length > 0 ? true : false; //Меню привязки к поставщикам значений const valueProvidersMenu = isValues && ( {values.map((value, i) => ( handleArgumentLinkClick(value)}> {value} ))} ); //Доступность сохранения настройки источника данных const okDisabled = !state.query && !state.userProc ? true : false; //Формирование представления return ( <> {openQuerySelector ? ( ) : null} {valueProvidersMenu} {/* ДОРАБАТЫВАТЬ ПОСЛЕ РЕАЛИЗАЦИИ ЗАПРОСОВ */} clear list ) }} disabled={disabledFields.query} /> clear list ) }} disabled={disabledFields.userProc} /> {Array.isArray(state?.arguments) && state.arguments.map((argument, i) => ( handleArgumentChange(i, e.target.value)} InputLabelProps={{ shrink: true }} InputProps={{ endAdornment: ( handleArgumentClearClick(i)}> clear {isValues && ( settings_ethernet )} ) }} /> ))} ); }; //Контроль свойств компонента - Диалог настройки источника данных P8PDataSourceConfigDialog.propTypes = { dataSource: P8P_DATA_SOURCE_SHAPE, valueProviders: PropTypes.object, onOk: PropTypes.func, onCancel: PropTypes.func }; //---------------- //Интерфейс модуля //---------------- export { P8PDataSourceConfigDialog };