/* Парус 8 - Панели мониторинга - Редактор настройки регламентированного отчёта Пользовательские хуки */ //--------------------- //Подключение библиотек //--------------------- import { useState, useContext, useEffect, useCallback, useLayoutEffect } from "react"; //Классы React import { ApplicationСtx } from "../../context/application"; //Контекст приложения import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений import { object2Base64XML, deepCopyObject } from "../../core/utils"; //Вспомогательные функции import dayjs from "dayjs"; //Работа с датами //--------- //Константы //--------- //Цвета статусов export const COLORS = [ "mediumSlateBlue", "lightSalmon", "fireBrick", "orange", "gold", "limeGreen", "yellowGreen", "mediumAquaMarine", "paleTurquoise", "steelBlue", "skyBlue", "tan" ]; //--------------------------------------------- //Вспомогательные функции форматирования данных //--------------------------------------------- //Формирование случайного цвета const randomColor = index => { const hue = index * 137.508; return `hsl(${hue},50%,75%)`; }; //Хук для отработки изменений ширины и высоты рабочей области окна const useWindowResize = () => { //Состояние размера рабочей области const [size, setSize] = useState([0, 0]); //При изменении размера useLayoutEffect(() => { const updateSize = () => { setSize([document.documentElement.clientWidth, document.documentElement.clientHeight]); }; window.addEventListener("resize", updateSize); updateSize(); return () => window.removeEventListener("resize", updateSize); }, []); //Вернём размеры return size; }; //----------- //Тело модуля //----------- //Хук основных данных const useTasks = () => { //Состояние открытия формы события const [taskFormOpen, setTaskFormOpen] = useState(false); //Состояние изменения настройки статуса const [cardSettings, setCardSettings] = useState({ isOpen: false, settings: {} }); //Состояние маршрута события const [eventRoutes, setEventRoutes] = useState([]); //Состояние учётных документов const [docLinks, setDocLinks] = useState([]); //Состояние событий const [tasks, setTasks] = useState({ groupsLoaded: false, tasksLoaded: false, orders: [], filters: { isOpen: true, isSetByUser: false, needSave: false, values: { type: "", sendPerson: "", sendDivision: "", sendUsrGrp: "", docLink: "" }, fArray: [ { name: "SEVTYPE_CODE", from: "", to: "" }, { name: "SSEND_PERSON", from: "", to: "" }, { name: "SSEND_DIVISION", from: "", to: "" }, { name: "SSEND_USRGRP", from: "", to: "" }, { name: "NLINKED_RN", from: "", to: "" } ] }, rows: [], statuses: [], openCardForm: false, reload: true }); //Подключение к контексту взаимодействия с сервером const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx); //Подключение к контексту приложения const { pOnlineShowDictionary } = useContext(ApplicationСtx); //Инициализация параметров события const initTask = (id, gp, task) => { return { id: id, name: task.SPREF_NUMB, category: gp, nrn: task.NRN, scrn: "", sprefix: task.SEVPREF, snumber: task.SEVNUMB, stype: task.SEVTYPE_CODE, sstatus: task.SEVSTAT_NAME, sdescription: task.SEVDESCR, sclnt_clnclients: "", sclnt_clnperson: "", dstart_date: task.DREG_DATE, dplan_date: task.DPLAN_DATE, sinit_clnperson: task.SINIT_PERSON, sinit_user: "", sinit_reason: "", sto_company: "", sto_department: "", sto_clnpost: "", sto_clnpsdep: "", sto_clnperson: "", sto_fcstaffgrp: "", sto_user: task.SSEND_PERSON, sto_usergrp: task.SSEND_USRGRP, scurrent_user: "" }; }; //При открытии диалога фильтра const handleFilterClick = () => setFilterOpen(true); //При изменении фильтра в диалоге const handleFilterOk = filter => { setFilterValues(filter); setFilterOpen(false); }; //При закрытии диалога фильтра const handleFilterCancel = () => setFilterOpen(false); //Установить значение фильтра const setFilterValues = (values, ns = true) => { //Считываем массив фильтров let filterArr = tasks.filters.fArray.slice(); //Тип filterArr.find(f => f.name === "SEVTYPE_CODE").from = values.type ? values.type : null; //Исполнитель filterArr.find(f => f.name === "SSEND_PERSON").from = values.sendPerson ? values.sendPerson : null; //Подразделение filterArr.find(f => f.name === "SSEND_DIVISION").from = values.sendDivision ? values.sendDivision : null; //Группа пользователей filterArr.find(f => f.name === "SSEND_USRGRP").from = values.sendUsrGrp ? values.sendUsrGrp : null; //Учётный документ filterArr.find(f => f.name === "NLINKED_RN").from = values.docLink ? values.docLink : null; //Устанавливаем фильтры setTasks(pv => ({ ...pv, filters: { ...pv.filters, isSetByUser: true, needSave: ns, values: { ...values }, fArray: [...filterArr] }, reload: true })); }; //Загрузка значений фильтра из локального хранилища браузера const loadLocalFilter = useCallback(async () => { let vs = { ...tasks.filters.values }; Object.keys(vs).map(function (k) { k !== "docLink" ? (vs[k] = localStorage.getItem(k)) : null; }); setFilterValues(vs, false); setFilterOpen(false); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); //При закрытии панели useEffect(() => { tasks.filters.needSave ? window.addEventListener("beforeunload", function () { Object.keys(tasks.filters.values).map(function (k) { k !== "docLink" ? localStorage.setItem(k, tasks.filters.values[k]) : null; }); }) : null; }, [tasks.filters.needSave, tasks.filters.values]); //При отсутствии пользовательских настроек фильтра useEffect(() => { if (!tasks.filters.isSetByUser) setFilterOpen(true); }, [tasks.filters.isSetByUser]); //При подключении к странице useEffect(() => { localStorage.length > 0 ? loadLocalFilter() : null; }, [loadLocalFilter]); //Показать/скрыть фильтр const setFilterOpen = isOpen => { setTasks(pv => ({ ...pv, filters: { ...pv.filters, isOpen } })); }; //Открытие настройки статуса const handleCardSettingsClick = curSettings => { setCardSettings({ isOpen: true, settings: { ...curSettings } }); }; //Закрытие настройки статуса const handleCardSettingsCancel = () => setCardSettings(pv => ({ ...pv, isOpen: false })); //Применение настройки статуса const handleCardSettingsOk = settings => { //Считываем статусы let cloneS = tasks.statuses.slice(); //Изменяем статус у выбранного cloneS[tasks.statuses.findIndex(x => x.id === settings.id)] = { ...settings }; setTasks(pv => ({ ...pv, statuses: cloneS })); setCardSettings({ isOpen: false, settings: {} }); }; //При изменении сортировки const handleOrderChanged = useCallback( columnName => { let newOrders = deepCopyObject(tasks.orders); const colOrder = newOrders.find(o => o.name == columnName); const newDirection = colOrder?.direction == "ASC" ? "DESC" : colOrder?.direction == "DESC" ? null : "ASC"; if (newDirection == null && colOrder) newOrders.splice(newOrders.indexOf(colOrder), 1); if (newDirection != null && !colOrder) newOrders.push({ name: columnName, direction: newDirection }); if (newDirection != null && colOrder) colOrder.direction = newDirection; setTasks(pv => ({ ...pv, orders: newOrders, reload: true })); }, [tasks.orders] ); //Изменение статуса события (переносом) const handleStateChange = useCallback( async (nEvent, sNextStat) => { try { //Выполняем инициализацию параметров const firstStep = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE", args: { NSTEP: 1, NEVENT: nEvent, SNEXT_STAT: sNextStat } }); if (firstStep) { //Если требуется выбрать получателя if (firstStep.NSELECT_EXEC === 1) { //Открываем раздел "Маршруты событий (исполнители в точках)" для выбора исполнителя pOnlineShowDictionary({ unitCode: "EventRoutesPointExecuters", showMethod: "executers", inputParameters: [ { name: "in_IDENT", value: firstStep.NIDENT }, { name: "in_EVENT", value: nEvent }, { name: "in_EVENT_TYPE", value: firstStep.SEVENT_TYPE }, { name: "in_EVENT_STAT", value: firstStep.SEVENT_STAT }, { name: "in_INIT_PERSON", value: firstStep.SINIT_PERSON }, { name: "in_INIT_AUTHNAME", value: firstStep.SINIT_AUTHNAME }, { name: "in_CLIENT_CLIENT", value: firstStep.SCLIENT_CLIENT }, { name: "in_CLIENT_PERSON", value: firstStep.SCLIENT_PERSON } ], callBack: async send => { //Выполняем переход к выбранной точке с исполнителем await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE", args: { NIDENT: firstStep.NIDENT, NSTEP: 3, SEVENT_STAT: firstStep.SEVENT_STAT, SSEND_CLIENT: send.outParameters.out_CLIENT_CODE, SSEND_DIVISION: send.outParameters.out_DIVISION_CODE, SSEND_POST: send.outParameters.out_POST_CODE, SSEND_PERFORM: send.outParameters.out_POST_IN_DIV_CODE, SSEND_PERSON: send.outParameters.out_PERSON_CODE, SSEND_STAFFGRP: send.outParameters.out_STAFFGRP_CODE, SSEND_USER_GROUP: send.outParameters.out_USER_GROUP_CODE, SSEND_USER_NAME: send.outParameters.out_USER_NAME, NSEND_PREDEFINED_EXEC: send.outParameters.out_PREDEFINED_EXEC, NSEND_PREDEFINED_PROC: send.outParameters.out_PREDEFINED_PROC } }); //Необходимо обновить данные setTasks(pv => ({ ...pv, reload: true })); } }); } else { //Выполняем переход к выбранной точке с предопределенным исполнителем await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE", args: { NIDENT: firstStep.NIDENT, NSTEP: 3, SEVENT_STAT: firstStep.SEVENT_STAT } }); //Необходимо обновить данные setTasks(pv => ({ ...pv, reload: true })); } } } catch (e) { //Необходимо обновить данные setTasks(pv => ({ ...pv, reload: true })); } }, [executeStored, pOnlineShowDictionary] ); //При необходимости обновить события const handleReload = useCallback(() => { setTasks(pv => ({ ...pv, reload: true })); }, []); //Взаимодействие с событием (через перенос) const onDragEnd = useCallback( result => { //Определяем нужные параметры const { source, destination } = result; //Если путь не указан if (!destination) { return; } //Если происходит изменение статуса if (destination.droppableId !== source.droppableId) { //Считываем строку, у которой изменяется статус let row = tasks.rows.find(f => f.id === parseInt(result.draggableId)); //Формируем события с учетом изменения let rows = tasks.rows.map(task => task.id === parseInt(result.draggableId) ? { ...task, category: parseInt(result.destination.droppableId) } : task ); //Переинициализируем строки с учетом изменений (для визуального отображения) setTasks(pv => ({ ...pv, rows: [...rows] })); //Изменяем статус события handleStateChange(row.nrn, tasks.statuses.find(s => s.id == destination.droppableId).code); } }, [handleStateChange, tasks.rows, tasks.statuses] ); useEffect(() => { //Считываем дополнительные данные let getEventData = async () => { const data = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_INFO_BY_CODE", args: { SCODE: tasks.filters.values.type }, respArg: "COUT" }); //Инициализируем маршруты событий let newRoutes = []; //Если найдены маршруты if (data.XEVROUTES) { data.XEVROUTES.map(r => { newRoutes.push({ src: r.SSOURCE, dest: r.SDESTINATION }); }); } //Инициализируем учётные документы let newDocLinks = []; //Если найдены учётные документы if (data.XDOCLINKS) { data.XDOCLINKS.map(d => { newDocLinks.push({ id: d.NRN, descr: d.SDESCR }); }); } //Указываем сформированные маршруты setEventRoutes([...newRoutes]); //Указываем сформированные учётные документы setDocLinks([...newDocLinks]); }; //Если указан тип событий if (tasks.filters.values.type) { //Загружаем данные getEventData(); } }, [tasks.filters.values.type, executeStored]); useEffect(() => { //Считывание данных с учетом фильтрации let getTasks = async () => { const data = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_DATASET", args: { CFILTERS: { VALUE: object2Base64XML(tasks.filters.fArray, { arrayNodeName: "filters" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB }, CORDERS: { VALUE: object2Base64XML(tasks.orders, { arrayNodeName: "orders" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB }, NINCLUDE_DEF: tasks.tasksLoaded ? 0 : 1 }, respArg: "COUT" }); //Инициализируем статусы и события let newGroups = []; let newRows = []; //Если статусы есть if (data.XGROUPS) { //Формируем структуру статусов data.XGROUPS.map((group, i) => { newGroups.push({ id: i, code: group.name, caption: group.caption, color: randomColor(i + 1) }); }); //Если есть события if (data.XROWS) { //Формируем структуру событий data.XROWS.map((task, i) => { newRows.push(initTask(i, newGroups.find(x => x.caption === task.groupName).id, task)); }); } } //Указываем сформированные данные setTasks(pv => ({ ...pv, groupsLoaded: true, tasksLoaded: true, statuses: [...newGroups], rows: [...newRows], reload: false })); }; //Если необходимо загрузить данные и указан тип событий if (tasks.reload && tasks.filters.values.type) { //Загружаем данные getTasks(); } }, [ tasks.reload, tasks.filters.values.type, tasks.filters.fArray, tasks.orders, tasks.tasksLoaded, tasks.statuses.length, tasks.rows.length, executeStored, SERV_DATA_TYPE_CLOB ]); return [ tasks, eventRoutes, docLinks, taskFormOpen, setTaskFormOpen, cardSettings, handleFilterOk, handleFilterCancel, handleFilterClick, handleCardSettingsClick, handleCardSettingsOk, handleCardSettingsCancel, handleReload, onDragEnd, handleOrderChanged ]; }; //Хук для события const useClientEvent = (taskRn, taskType = "", taskStatus = "") => { //Собственное состояние const [task, setTask] = useState({ init: true, nrn: taskRn, scrn: "", sprefix: "", snumber: "", stype: taskType, sstatus: taskStatus, sdescription: "", sclnt_clnclients: "", sclnt_clnperson: "", dstart_date: "", sinit_clnperson: "", sinit_user: "", sinit_reason: "", sto_company: "", sto_department: "", sto_clnpost: "", sto_clnpsdep: "", sto_clnperson: "", sto_fcstaffgrp: "", sto_user: "", sto_usergrp: "", scurrent_user: "", isUpdate: false, insertDisabled: true, updateDisabled: true }); //Подключение к контексту взаимодействия с сервером const { executeStored } = useContext(BackEndСtx); //Подключение к контексту приложения const { pOnlineShowDictionary } = useContext(ApplicationСtx); const initEventType = useCallback(async () => { //Считываем параметры исходя из типа события const data = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVNTYPES_INIT", args: { SEVENT_TYPE: task.stype, SCURRENT_PREF: task.sprefix }, tagValueProcessor: () => undefined }); if (data) { setTask(pv => ({ ...pv, sprefix: data.SPREF, snumber: data.SNUMB })); } }, [task.sprefix, task.stype, executeStored]); //Отображение раздела "Типы событий" // const handleTypeOpen = useCallback(async () => { // pOnlineShowDictionary({ // unitCode: "ClientEventTypes", // showMethod: "main", // inputParameters: [{ name: "in_EVNTYPE_NAME", value: task.stype }], // callBack: async res => { // if (res.success) { // //Считываем параметры исходя из типа события // const data = await executeStored({ // stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVNTYPES_INIT", // args: { // SEVENT_TYPE: res.outParameters.out_EVNTYPE_CODE, // SCURRENT_PREF: task.sprefix // }, // tagValueProcessor: () => undefined // }); // if (data) { // setTask(pv => ({ // ...pv, // stype: res.outParameters.out_EVNTYPE_CODE, // sprefix: data.SPREF, // snumber: data.SNUMB, // sstatus: data.SDEFAULT_STATUS // })); // } // } // } // }); // }, [executeStored, pOnlineShowDictionary, task.sprefix, task.stype]); //Отображение раздела "Статусы типового события" // const handleStatusOpen = useCallback(async () => { // pOnlineShowDictionary({ // unitCode: "ClientEventTypesStates", // showMethod: "main", // inputParameters: [ // { name: "in_SEVNTYPE_CODE", value: task.stype }, // { name: "in_EVENT_STATUS_EVNSTAT_CODE", value: task.sstatus } // ], // callBack: res => { // res.success // ? setTask(pv => ({ // ...pv, // sstatus: res.outParameters.out_EVENT_STATUS_EVNSTAT_CODE // })) // : null; // } // }); // }, [pOnlineShowDictionary, task.sstatus, task.stype]); //Отображение раздела "Клиенты" const handleClientClientsOpen = useCallback(async () => { pOnlineShowDictionary({ unitCode: "ClientClients", showMethod: "main", inputParameters: [{ name: "in_CLIENT_CODE", value: task.sclnt_clnclients }], callBack: res => { res.success ? setTask(pv => ({ ...pv, sclnt_clnclients: res.outParameters.out_CLIENT_CODE, sclnt_clnperson: "" })) : null; } }); }, [pOnlineShowDictionary, task.sclnt_clnclients]); //Отображение раздела "Сотрудники" const handleClientPersonOpen = useCallback( //Тип открытия (0 - для клиента, 1 - для инициатора) async (nType = 0) => { pOnlineShowDictionary({ unitCode: "ClientPersons", showMethod: "main", inputParameters: [{ name: "in_CODE", value: nType === 0 ? task.sclnt_clnperson : task.sinit_clnperson }], callBack: res => { if (res.success) { if (nType === 0) { setTask(pv => ({ ...pv, sclnt_clnperson: res.outParameters.out_CODE, sclnt_clnclients: "" })); } else { setTask(pv => ({ ...pv, sinit_clnperson: res.outParameters.out_CODE })); } } } }); }, [pOnlineShowDictionary, task.sclnt_clnperson, task.sinit_clnperson] ); //Отображение раздела "Каталоги" для событий const handleCrnOpen = useCallback(async () => { pOnlineShowDictionary({ unitCode: "CatalogTree", showMethod: "main", inputParameters: [ { name: "in_DOCNAME", value: "ClientEvents" }, { name: "in_NAME", value: task.scrn } ], callBack: res => { res.success ? setTask(pv => ({ ...pv, scrn: res.outParameters.out_NAME })) : null; } }); }, [pOnlineShowDictionary, task.scrn]); //Считывание следующего номера события const getEventNextNumb = useCallback(async () => { const data = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_NEXTNUMB_GET", args: { SPREFIX: task.sprefix } }); if (data) { setTask(pv => ({ ...pv, snumber: data.SEVENT_NUMB })); } }, [executeStored, task.sprefix]); //Добавление события const insertEvent = useCallback( async callBack => { await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_INSERT", args: { SCRN: task.scrn, SPREF: task.sprefix, SNUMB: task.snumber, STYPE: task.stype, SSTATUS: task.sstatus, SPLAN_DATE: task.dstart_date ? dayjs(task.dstart_date).format("DD.MM.YYYY HH:mm") : null, SINIT_PERSON: task.sinit_clnperson, SCLIENT_CLIENT: task.sclnt_clnclients, SCLIENT_PERSON: task.sclnt_clnperson, SDESCRIPTION: task.sdescription, SREASON: task.sinit_reason } }); callBack(); }, [ executeStored, task.dstart_date, task.sclnt_clnclients, task.sclnt_clnperson, task.scrn, task.sdescription, task.sinit_clnperson, task.sinit_reason, task.snumber, task.sprefix, task.sstatus, task.stype ] ); //Исправление события const updateEvent = useCallback( async callBack => { await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_UPDATE", args: { NCLNEVENTS: task.nrn, SCLIENT_CLIENT: task.sclnt_clnclients, SCLIENT_PERSON: task.sclnt_clnperson, SDESCRIPTION: task.sdescription } }); callBack(); }, [executeStored, task.nrn, task.sclnt_clnclients, task.sclnt_clnperson, task.sdescription] ); useEffect(() => { if (task.init) { if (taskRn) { //Считывание параметров события const readEvent = async () => { const data = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_GET", args: { NCLNEVENTS: task.nrn }, respArg: "COUT" }); setTask(pv => ({ ...pv, scrn: data.XEVENT.SCRN, sprefix: data.XEVENT.SPREF, snumber: data.XEVENT.SNUMB, stype: data.XEVENT.STYPE, sstatus: data.XEVENT.SSTATUS, sdescription: data.XEVENT.SDESCRIPTION, sclnt_clnclients: data.XEVENT.SCLIENT_CLIENT, sclnt_clnperson: data.XEVENT.SCLIENT_PERSON, dstart_date: data.XEVENT.SPLAN_DATE ? dayjs(data.XEVENT.SPLAN_DATE).format("YYYY-MM-DD HH:mm") : "", sinit_clnperson: data.XEVENT.SINIT_PERSON, sinit_user: data.XEVENT.SINIT_AUTHID, sinit_reason: data.XEVENT.SREASON, sto_company: data.XEVENT.SSEND_CLIENT, sto_department: data.XEVENT.SSEND_DIVISION, sto_clnpost: data.XEVENT.SSEND_POST, sto_clnpsdep: data.XEVENT.SSEND_PERFORM, sto_clnperson: data.XEVENT.SSEND_PERSON, sto_fcstaffgrp: data.XEVENT.SSEND_STAFFGRP, sto_user: data.XEVENT.SSEND_USER_NAME, sto_usergrp: data.XEVENT.SSEND_USER_GROUP, scurrent_user: data.XEVENT.SINIT_AUTHID, isUpdate: true, init: false })); }; //Инициализация параметров события readEvent(); } else { //Считывание изначальных параметров события const initEvent = async () => { const data = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_INIT", args: {} }); if (data) { setTask(pv => ({ ...pv, sprefix: data.SPREF, snumber: data.SNUMB, scurrent_user: data.SINIT_AUTHNAME, sinit_clnperson: data.SINIT_PERSON, sinit_user: !data.SINIT_PERSON ? data.SINIT_AUTHNAME : "", init: false })); } }; //Инициализация изначальных параметров события initEvent(); initEventType(); } } if (!task.init) { setTask(pv => ({ ...pv, sinit_user: !task.sinit_clnperson ? task.scurrent_user : "" })); } }, [executeStored, task.init, task.nrn, task.stype, task.scurrent_user, task.sinit_clnperson, taskRn, initEventType]); //Проверка доступности действия useEffect(() => { setTask(pv => ({ ...pv, insertDisabled: !task.scrn || !task.sprefix || !task.snumber || !task.stype || !task.sstatus || !task.sdescription || (!task.sinit_clnperson && !task.sinit_user), updateDisabled: !task.sdescription })); }, [task.scrn, task.sdescription, task.sinit_clnperson, task.sinit_user, task.snumber, task.sprefix, task.sstatus, task.stype]); return [ task, setTask, insertEvent, updateEvent, //handleTypeOpen, //handleStatusOpen, handleClientClientsOpen, handleClientPersonOpen, handleCrnOpen, getEventNextNumb ]; }; //Карточка события const useTaskCard = () => { //Собственное состояние const [taskCard, setTaskCard] = useState({ openEdit: false }); //Состояние действий const [cardActions, setCardActions] = useState({ anchorMenuMethods: null, openMethods: false }); //Подключение к контексту взаимодействия с сервером const { executeStored } = useContext(BackEndСtx); //Подключение к контексту сообщений const { showMsgWarn } = useContext(MessagingСtx); //Подключение к контексту приложения const { pOnlineShowDictionary } = useContext(ApplicationСtx); //Удаление контрагента const deleteTask = useCallback( async (nEvent, handleReload) => { await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_DELETE", args: { NCLNEVENTS: nEvent } }); //Если требуется перезагрузить данные if (handleReload) { handleReload(); } }, [executeStored] ); //Возврат в предыдущую точку события const returnTask = useCallback( async (nEvent, handleReload) => { await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_RETURN", args: { NCLNEVENTS: nEvent } }); //Если требуется перезагрузить данные if (handleReload) { handleReload(); } }, [executeStored] ); //По нажатию на открытие меню действий const handleMethodsMenuButtonClick = event => { setCardActions(pv => ({ ...pv, anchorMenuMethods: event.currentTarget, openMethods: true })); }; //При закрытии меню const handleMethodsMenuClose = () => { setCardActions(pv => ({ ...pv, anchorMenuMethods: null, openMethods: false })); }; //По нажатия действия "Редактировать" const handleTaskEdit = () => { setTaskCard(pv => ({ ...pv, openEdit: true })); }; //По нажатию действия "Удалить" const handleTaskDelete = (nEvent, handleReload) => { showMsgWarn("Удалить событие?", () => deleteTask(nEvent, handleReload)); }; //По нажатию действия "Выполнить возврат" const handleTaskReturn = (nEvent, handleReload) => { showMsgWarn("Выполнить возврат события в предыдущую точку?", () => returnTask(nEvent, handleReload)); }; //По нажатию действия "Примечания" const handleEventNotesOpen = useCallback( async nEvent => { pOnlineShowDictionary({ unitCode: "ClientEventsNotes", showMethod: "main", inputParameters: [{ name: "in_PRN", value: nEvent }] }); }, [pOnlineShowDictionary] ); //По нажатию действия "Присоединенные документы" const handleFileLinksOpen = useCallback( async nEvent => { pOnlineShowDictionary({ unitCode: "FileLinks", showMethod: "main_link", inputParameters: [ { name: "in_PRN", value: nEvent }, { name: "in_UNITCODE", value: "ClientEvents" } ] }); }, [pOnlineShowDictionary] ); //По нажатию действия "Перейти" const handleStateChange = useCallback( async (nEvent, handleReload) => { //Выполняем инициализацию параметров const firstStep = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE", args: { NSTEP: 1, NEVENT: nEvent } }); if (firstStep) { //Открываем раздел "Маршруты событий (точки перехода)" для выбора следующей точки pOnlineShowDictionary({ unitCode: "EventRoutesPointsPasses", showMethod: "main_passes", inputParameters: [ { name: "in_ENVTYPE_CODE", value: firstStep.SEVENT_TYPE }, { name: "in_ENVSTAT_CODE", value: firstStep.SEVENT_STAT }, { name: "in_POINT", value: firstStep.NPOINT } ], callBack: async point => { //Выполняем проверку необходимости выбора исполнителя const secondStep = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE", args: { NIDENT: firstStep.NIDENT, NSTEP: 2, NPASS: point.outParameters.out_RN } }); if (secondStep) { //Если требуется выбрать получателя if (secondStep.NSELECT_EXEC === 1) { //Открываем раздел "Маршруты событий (исполнители в точках)" для выбора исполнителя pOnlineShowDictionary({ unitCode: "EventRoutesPointExecuters", showMethod: "executers", inputParameters: [ { name: "in_IDENT", value: firstStep.NIDENT }, { name: "in_EVENT", value: nEvent }, { name: "in_EVENT_TYPE", value: firstStep.SEVENT_TYPE }, { name: "in_EVENT_STAT", value: firstStep.SEVENT_STAT }, { name: "in_INIT_PERSON", value: firstStep.SINIT_PERSON }, { name: "in_INIT_AUTHNAME", value: firstStep.SINIT_AUTHNAME }, { name: "in_CLIENT_CLIENT", value: firstStep.SCLIENT_CLIENT }, { name: "in_CLIENT_PERSON", value: firstStep.SCLIENT_PERSON } ], callBack: async send => { //Выполняем переход к выбранной точке с исполнителем await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE", args: { NIDENT: firstStep.NIDENT, NSTEP: 3, SEVENT_STAT: point.outParameters.out_NEXT_POINT, SSEND_CLIENT: send.outParameters.out_CLIENT_CODE, SSEND_DIVISION: send.outParameters.out_DIVISION_CODE, SSEND_POST: send.outParameters.out_POST_CODE, SSEND_PERFORM: send.outParameters.out_POST_IN_DIV_CODE, SSEND_PERSON: send.outParameters.out_PERSON_CODE, SSEND_STAFFGRP: send.outParameters.out_STAFFGRP_CODE, SSEND_USER_GROUP: send.outParameters.out_USER_GROUP_CODE, SSEND_USER_NAME: send.outParameters.out_USER_NAME, NSEND_PREDEFINED_EXEC: send.outParameters.out_PREDEFINED_EXEC, NSEND_PREDEFINED_PROC: send.outParameters.out_PREDEFINED_PROC } }); //Если требуется перезагрузить данные if (handleReload) { handleReload(); } } }); } else { //Выполняем переход к выбранной точке с предопределенным исполнителем await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE", args: { NIDENT: firstStep.NIDENT, NSTEP: 3, SEVENT_STAT: point.outParameters.out_NEXT_POINT } }); //Если требуется перезагрузить данные if (handleReload) { handleReload(); } } } } }); } }, [executeStored, pOnlineShowDictionary] ); //Изменение статуса события const handleSend = useCallback( async (nEvent, handleReload) => { //Выполняем инициализацию параметров const firstStep = await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_SEND", args: { NSTEP: 1, NEVENT: nEvent } }); if (firstStep) { //Открываем раздел "Маршруты событий (исполнители в точках)" для выбора исполнителя pOnlineShowDictionary({ unitCode: "EventRoutesPointExecuters", showMethod: "executers", inputParameters: [ { name: "in_IDENT", value: firstStep.NIDENT }, { name: "in_EVENT", value: nEvent }, { name: "in_PERSON_CODE", value: firstStep.SSEND_PERSON }, { name: "in_USER_NAME", value: firstStep.SSEND_USER_NAME }, { name: "in_EVENT_TYPE", value: firstStep.SEVENT_TYPE }, { name: "in_EVENT_STAT", value: firstStep.SEVENT_STAT }, { name: "in_INIT_PERSON", value: firstStep.SINIT_PERSON }, { name: "in_INIT_AUTHNAME", value: firstStep.SINIT_AUTHNAME }, { name: "in_CLIENT_CLIENT", value: firstStep.SCLIENT_CLIENT }, { name: "in_CLIENT_PERSON", value: firstStep.SCLIENT_PERSON } ], callBack: async send => { //Выполняем проверку необходимости выбора исполнителя await executeStored({ stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_SEND", args: { NIDENT: firstStep.NIDENT, NSTEP: 2, SSEND_CLIENT: send.outParameters.out_CLIENT_CODE, SSEND_DIVISION: send.outParameters.out_DIVISION_CODE, SSEND_POST: send.outParameters.out_POST_CODE, SSEND_PERFORM: send.outParameters.out_POST_IN_DIV_CODE, SSEND_PERSON: send.outParameters.out_PERSON_CODE, SSEND_STAFFGRP: send.outParameters.out_STAFFGRP_CODE, SSEND_USER_GROUP: send.outParameters.out_USER_GROUP_CODE, SSEND_USER_NAME: send.outParameters.out_USER_NAME, NSEND_PREDEFINED_EXEC: send.outParameters.out_PREDEFINED_EXEC, NSEND_PREDEFINED_PROC: send.outParameters.out_PREDEFINED_PROC } }); //Если требуется перезагрузить данные if (handleReload) { handleReload(); } } }); } }, [executeStored, pOnlineShowDictionary] ); //Формируем меню показателей const menuItems = [ { method: "EDIT", name: "Исправить", icon: "edit", delimiter: false, needReload: false, func: handleTaskEdit }, { method: "DELETE", name: "Удалить", icon: "delete", delimiter: true, needReload: true, func: handleTaskDelete }, { method: "TASK_STATE_CHANGE", name: "Перейти", icon: "turn_right", delimiter: false, needReload: true, func: handleStateChange }, { method: "TASK_RETURN", name: "Выполнить возврат", icon: "turn_left", delimiter: false, needReload: true, func: handleTaskReturn }, { method: "TASK_SEND", name: "Направить", icon: "send", delimiter: true, needReload: true, func: handleSend }, { method: "NOTES", name: "Примечания", icon: "event_note", delimiter: true, needReload: false, func: handleEventNotesOpen }, { method: "FILE_LINKS", name: "Присоединенные документы", icon: "attach_file", delimiter: false, needReload: false, func: handleFileLinksOpen } ]; return [taskCard, setTaskCard, cardActions, handleMethodsMenuButtonClick, handleMethodsMenuClose, menuItems]; }; //Хук для сортировок const useOrders = () => { //Состояние меню сортировки const [menuOrders, setMenuOrders] = useState({ anchorMenuOrders: null, openOrders: false }); //По нажатию на открытие меню сортировки const handleOrdersMenuButtonClick = event => { setMenuOrders(pv => ({ ...pv, anchorMenuOrders: event.currentTarget, openOrders: true })); }; //При закрытии меню const handleOrdersMenuClose = () => { setMenuOrders(pv => ({ ...pv, anchorMenuOrders: null, openOrders: false })); }; return [menuOrders, handleOrdersMenuButtonClick, handleOrdersMenuClose]; }; export { useTasks, useClientEvent, useTaskCard, useOrders, useWindowResize };