1113 lines
48 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

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

/*
Парус 8 - Панели мониторинга - Редактор настройки регламентированного отчёта
Пользовательские хуки
*/
//---------------------
//Подключение библиотек
//---------------------
import { 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 };