/*
Парус 8 - Панели мониторинга - УДП - Доски задач
Компонент: Карточка события
*/
//---------------------
//Подключение библиотек
//---------------------
import React, { useState, useContext, useCallback, useEffect } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Draggable } from "react-beautiful-dnd"; //Работа с drag&drop
import { Card, CardHeader, Typography, IconButton, Icon, Box, Menu, MenuItem, CardContent, Avatar, Stack } from "@mui/material"; //Интерфейсные компоненты
import { TaskDialog } from "../task_dialog"; //Форма события
import { ApplicationСtx } from "../../../context/application"; //Контекст приложения
import { BackEndСtx } from "../../../context/backend"; //Контекст взаимодействия с сервером
import { MessagingСtx } from "../../../context/messaging"; //Контекст сообщений
import { TASK_COLORS, getTaskExpiredColor, getTaskBgColorByRule, makeCardActionsArray } from "../layouts"; //Дополнительная разметка и вёрстка клиентских элементов
import { useDictionary } from "../hooks/dict_hooks"; //Состояние открытия разделов
import { useTasksFunctions } from "../hooks/tasks_hooks"; //Состояние вспомогательных функций событий
//---------
//Константы
//---------
//Стили
const STYLES = {
MENU_ITEM_DELIMITER: { borderBottom: "1px solid lightgrey" },
CARD: (indicatorClr, bgClr) => {
const i = indicatorClr ? { borderLeft: `solid ${indicatorClr}` } : null;
const bc = bgClr ? { backgroundColor: bgClr } : null;
return { ...i, ...bc };
},
CARD_HEADER_TITLE: {
padding: "4px",
width: "292px",
display: "-webkit-box",
hyphens: "auto",
WebkitBoxOrient: "vertical",
WebkitLineClamp: 2,
overflow: "hidden"
},
CARD_HEADER: { padding: 0, cursor: "pointer" },
CARD_CONTENT: { padding: "4px !important" },
CARD_CONTENT_BOX: { display: "flex", alignItems: "center" },
STACK_SENDER: { alignItems: "center", marginLeft: "auto" },
TYPOGRAPHY_SECONDARY: {
color: "text.secondary",
fontSize: 14
},
ICON_COLOR: linked => {
return { color: theme => (linked ? TASK_COLORS.LINKED : theme.palette.grey[500]) };
}
};
//------------------------------------
//Вспомогательные функции и компоненты
//------------------------------------
//Действия карточки события
const CardActions = ({
taskRn,
menuItems,
cardActions,
onMethodsMenuButtonClick,
onMethodsMenuClose,
onTasksReload,
pointSettings,
onOpenNoteDialog
}) => {
//При нажатии на действие меню
const handleActionClick = action => {
//Выполняем действие
action.func({
nEvent: taskRn,
onReload: action.tasksReload ? () => onTasksReload(action.needAccountsReload) : null,
onNoteOpen: pointSettings.ADDNOTE_ONSEND ? onOpenNoteDialog : null
});
//Закрываем меню действий
onMethodsMenuClose();
};
return (
);
};
//Контроль свойств - Действия карточки события
CardActions.propTypes = {
taskRn: PropTypes.number.isRequired,
menuItems: PropTypes.array.isRequired,
cardActions: PropTypes.object.isRequired,
onMethodsMenuButtonClick: PropTypes.func.isRequired,
onMethodsMenuClose: PropTypes.func.isRequired,
onTasksReload: PropTypes.func,
pointSettings: PropTypes.object,
onOpenNoteDialog: PropTypes.func
};
//-----------
//Тело модуля
//-----------
//Карточка события
const TaskCard = ({ task, index, onTasksReload, colorRule, pointSettings, onOpenNoteDialog }) => {
//Состояние диалога события
const [taskDialogOpen, setTaskDialogOpen] = useState(false);
//Состояние действий события
const [cardActions, setCardActions] = useState({ anchorMenuMethods: null, openMethods: false });
//Состояние списка действий меню
const [menuItems, setMenuItems] = useState([]);
//Вспомогательные функции открытия раздела
const { handleClientEventsOpen, handleClientEventsNotesOpen, handleFileLinksOpen } = useDictionary();
//Состояние вспомогательных функций событий
const { handleTaskStateChange, handleTaskSend } = useTasksFunctions();
//Подключение к контексту взаимодействия с сервером
const { executeStored } = useContext(BackEndСtx);
//Подключение к контексту сообщений
const { showMsgWarn } = useContext(MessagingСtx);
//Подключение к контексту приложения
const { pOnlineShowDocument } = useContext(ApplicationСtx);
//По нажатию на открытие меню действий
const handleMethodsMenuButtonClick = useCallback(event => {
setCardActions(pv => ({ ...pv, anchorMenuMethods: event.currentTarget, openMethods: true }));
}, []);
//При закрытии меню
const handleMethodsMenuClose = useCallback(() => {
setCardActions(pv => ({ ...pv, anchorMenuMethods: null, openMethods: false }));
}, []);
//При удалении контрагента
const handleTaskDelete = useCallback(
async ({ nEvent, onReload }) => {
await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_DELETE",
args: { NCLNEVENTS: nEvent }
});
//Если требуется перезагрузить данные
onReload ? onReload() : null;
},
[executeStored]
);
//При возврате в предыдущую точку события
const handleTaskReturn = useCallback(
async ({ nEvent, onReload }) => {
await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_RETURN",
args: { NCLNEVENTS: nEvent }
});
//Если требуется перезагрузить данные
onReload ? onReload() : null;
},
[executeStored]
);
//По нажатию действия "Направить"
const handleSendAction = useCallback(
async ({ nEvent, onReload, onNoteOpen }) => {
//Выполняем направление события
handleTaskSend({ nEvent, onReload, onNoteOpen });
},
[handleTaskSend]
);
//По нажатия действия "Редактировать"
const handleTaskEditAction = useCallback(() => {
setTaskDialogOpen(true);
}, []);
//По нажатия действия "Редактировать в разделе"
const handleTaskEditClientAction = useCallback(
async ({ nEvent }) => {
const data = await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_SELECT",
args: {
NCLNEVENTS: nEvent
}
});
if (data.NIDENT) {
//Открываем раздел "События" с фильтром по записи
handleClientEventsOpen({ nIdent: data.NIDENT });
}
},
[executeStored, handleClientEventsOpen]
);
//По нажатию действия "Удалить"
const handleTaskDeleteAction = useCallback(
({ nEvent, onReload }) => {
showMsgWarn("Удалить событие?", () => handleTaskDelete({ nEvent, onReload }));
},
[handleTaskDelete, showMsgWarn]
);
//По нажатию действия "Выполнить возврат"
const handleTaskReturnAction = useCallback(
({ nEvent, onReload }) => {
showMsgWarn("Выполнить возврат события в предыдущую точку?", () => handleTaskReturn({ nEvent, onReload }));
},
[handleTaskReturn, showMsgWarn]
);
//По нажатию действия "Примечания"
const handleEventNotesOpenAction = useCallback(
({ nEvent }) => {
handleClientEventsNotesOpen({ nPrn: nEvent });
},
[handleClientEventsNotesOpen]
);
//По нажатию действия "Присоединенные документы"
const handleTaskFileLinksOpenAction = useCallback(
({ nEvent }) => {
handleFileLinksOpen({ nPrn: nEvent, sUnitCode: "ClientEvents" });
},
[handleFileLinksOpen]
);
//По нажатию действия "Перейти"
const handleStateChangeAction = useCallback(
async ({ nEvent, onReload, onNoteOpen }) => {
//Выполняем изменения статуса события
handleTaskStateChange({ nEvent, onReload, onNoteOpen });
},
[handleTaskStateChange]
);
//При изменении ссылок в меню действий (для того, чтобы ссылка на объект менялась при реальной необходимости)
useEffect(() => {
//Устанавливаем список меню
setMenuItems(
makeCardActionsArray(
handleTaskEditAction,
handleTaskEditClientAction,
handleTaskDeleteAction,
handleStateChangeAction,
handleTaskReturnAction,
handleSendAction,
handleEventNotesOpenAction,
handleTaskFileLinksOpenAction
)
);
}, [
handleEventNotesOpenAction,
handleTaskFileLinksOpenAction,
handleSendAction,
handleStateChangeAction,
handleTaskDeleteAction,
handleTaskEditAction,
handleTaskEditClientAction,
handleTaskReturnAction
]);
//Генерация содержимого
return (
{taskDialogOpen ? (
{
setTaskDialogOpen(false);
}}
/>
) : null}
{provided => (
{
menuItems.find(action =>
action.method === "EDIT" ? action.func(task.nRn, action.tasksReload ? onTasksReload : null) : null
);
}}
>
{task.sDescription}
}
sx={STYLES.CARD_HEADER}
action={
}
/>
pOnlineShowDocument({ unitCode: task.sLinkedUnit, document: task.nLinkedRn }) : null
}
sx={STYLES.ICON_COLOR(task.nLinkedRn)}
disabled={!task.nLinkedRn}
>
assignment
{task.name}
{task.sSender ? (
{task.sSender}
) : null}
)}
);
};
//Контроль свойств - Карточка события
TaskCard.propTypes = {
task: PropTypes.object.isRequired,
index: PropTypes.number.isRequired,
onTasksReload: PropTypes.func,
colorRule: PropTypes.object,
pointSettings: PropTypes.object,
onOpenNoteDialog: PropTypes.func
};
//----------------
//Интерфейс модуля
//----------------
export { TaskCard };