578 lines
28 KiB
JavaScript
578 lines
28 KiB
JavaScript
/*
|
||
Парус 8 - Панели мониторинга - УДП - Доски задач
|
||
Компонент: Карточка события
|
||
*/
|
||
|
||
//---------------------
|
||
//Подключение библиотек
|
||
//---------------------
|
||
|
||
import React, { useState, useContext, useCallback } 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 { EVENT_INDICATORS, indicatorColorRule, bgColorRule } from "../layouts"; //Дополнительная разметка и вёрстка клиентских элементов
|
||
|
||
//---------
|
||
//Константы
|
||
//---------
|
||
|
||
//Стили
|
||
const STYLES = {
|
||
CONTAINER: { margin: "5px 0px", textAlign: "center" },
|
||
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_DESC: { padding: 0, cursor: "pointer" },
|
||
CARD_CONTENT: { padding: "4px !important" },
|
||
CARD_CONTENT_BOX: { display: "flex", alignItems: "center" },
|
||
ACCOUNT_STACK: { alignItems: "center", marginLeft: "auto" },
|
||
SECONDARY_TEXT: {
|
||
color: "text.secondary",
|
||
fontSize: 14
|
||
},
|
||
ICON_COLOR: linked => {
|
||
return { color: theme => (linked ? EVENT_INDICATORS.LINKED : theme.palette.grey[500]) };
|
||
}
|
||
};
|
||
|
||
//------------------------------------
|
||
//Вспомогательные функции и компоненты
|
||
//------------------------------------
|
||
|
||
//Действия карточки события
|
||
const DataCellCardActions = ({
|
||
taskRn,
|
||
menuItems,
|
||
cardActions,
|
||
onMethodsMenuButtonClick,
|
||
onMethodsMenuClose,
|
||
onReload,
|
||
eventPoints,
|
||
pointSettings,
|
||
onOpenNoteDialog
|
||
}) => {
|
||
return (
|
||
<Box sx={STYLES.BOX_ROW}>
|
||
<IconButton id={`${taskRn}_menu_button`} aria-haspopup="true" onClick={onMethodsMenuButtonClick}>
|
||
<Icon>more_vert</Icon>
|
||
</IconButton>
|
||
<Menu id={`${taskRn}_menu`} anchorEl={cardActions.anchorMenuMethods} open={cardActions.openMethods} onClose={onMethodsMenuClose}>
|
||
{menuItems.map(action => {
|
||
if (action.visible)
|
||
return (
|
||
<MenuItem
|
||
sx={action.delimiter ? STYLES.MENU_ITEM_DELIMITER : {}}
|
||
key={`${taskRn}_${action.method}`}
|
||
onClick={() => {
|
||
if (onOpenNoteDialog && action.method === "TASK_STATE_CHANGE") {
|
||
action.func(taskRn, action.needReload ? onReload : null, eventPoints, onOpenNoteDialog);
|
||
} else if (onOpenNoteDialog && action.method === "TASK_SEND" && pointSettings.addNoteOnSend) {
|
||
onOpenNoteDialog(n => action.func(taskRn, action.needReload ? onReload : null, n));
|
||
} else {
|
||
//Выполняем действие
|
||
action.func(taskRn, action.needReload ? onReload : null);
|
||
}
|
||
//Закрываем меню
|
||
onMethodsMenuClose();
|
||
}}
|
||
>
|
||
<Icon>{action.icon}</Icon>
|
||
<Typography pl={1}>{action.name}</Typography>
|
||
</MenuItem>
|
||
);
|
||
})}
|
||
</Menu>
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Действия карточки события
|
||
DataCellCardActions.propTypes = {
|
||
taskRn: PropTypes.number.isRequired,
|
||
menuItems: PropTypes.array.isRequired,
|
||
cardActions: PropTypes.object.isRequired,
|
||
onMethodsMenuButtonClick: PropTypes.func.isRequired,
|
||
onMethodsMenuClose: PropTypes.func.isRequired,
|
||
onReload: PropTypes.func,
|
||
eventPoints: PropTypes.array,
|
||
pointSettings: PropTypes.object,
|
||
onOpenNoteDialog: PropTypes.func
|
||
};
|
||
|
||
//-----------
|
||
//Тело модуля
|
||
//-----------
|
||
|
||
//Карточка события
|
||
const TaskCard = ({ task, avatar, index, onReload, eventPoints, colorRule, pointSettings, onOpenNoteDialog }) => {
|
||
//Состояние диалога события
|
||
const [taskDialogOpen, setTaskDialogOpen] = useState(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 { pOnlineShowDocument } = 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 = () => {
|
||
setTaskDialogOpen(true);
|
||
};
|
||
|
||
//По нажатия действия "Редактировать в разделе"
|
||
const handleTaskEditClient = useCallback(
|
||
async nEvent => {
|
||
const data = await executeStored({
|
||
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_SELECT",
|
||
args: {
|
||
NCLNEVENTS: nEvent
|
||
}
|
||
});
|
||
if (data.NIDENT) {
|
||
pOnlineShowDictionary({
|
||
unitCode: "ClientEvents",
|
||
inputParameters: [{ name: "in_Ident", value: data.NIDENT }]
|
||
});
|
||
}
|
||
},
|
||
[executeStored, pOnlineShowDictionary]
|
||
);
|
||
|
||
//По нажатию действия "Удалить"
|
||
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, evPoints, handleNote) => {
|
||
//Выполняем инициализацию параметров
|
||
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
|
||
}
|
||
});
|
||
const pointSettings = evPoints.find(ep => ep.point === point.outParameters.out_NEXT_POINT);
|
||
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 => {
|
||
//Общие аргументы
|
||
const mainArgs = {
|
||
NIDENT: firstStep.NIDENT,
|
||
NSTEP: 3,
|
||
NEVENT: nEvent,
|
||
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
|
||
};
|
||
//Выполняем переход к выбранной точке с исполнителем
|
||
pointSettings.addNoteOnChst
|
||
? handleNote(async n => {
|
||
//Если требуется примечание
|
||
await executeStored({
|
||
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE",
|
||
args: {
|
||
...mainArgs,
|
||
...{ SNOTE_HEADER: n.header, SNOTE: n.text }
|
||
}
|
||
});
|
||
//Если требуется перезагрузить данные
|
||
if (handleReload) {
|
||
handleReload();
|
||
}
|
||
})
|
||
: await executeStored({
|
||
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE",
|
||
args: mainArgs
|
||
});
|
||
//Если требуется перезагрузить данные
|
||
if (handleReload && !pointSettings.addNoteOnChst) {
|
||
handleReload();
|
||
}
|
||
}
|
||
});
|
||
} else {
|
||
//Общие аргументы
|
||
const mainArgs = {
|
||
NIDENT: firstStep.NIDENT,
|
||
NSTEP: 3,
|
||
NEVENT: nEvent,
|
||
SEVENT_STAT: point.outParameters.out_NEXT_POINT
|
||
};
|
||
//Выполняем переход к выбранной точке с предопределенным исполнителем
|
||
pointSettings.addNoteOnChst
|
||
? handleNote(async n => {
|
||
//Если требуется примечание
|
||
await executeStored({
|
||
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE",
|
||
args: {
|
||
...mainArgs,
|
||
...{ SNOTE_HEADER: n.header, SNOTE: n.text }
|
||
}
|
||
});
|
||
//Если требуется перезагрузить данные
|
||
if (handleReload) {
|
||
handleReload();
|
||
}
|
||
})
|
||
: await executeStored({
|
||
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE",
|
||
args: mainArgs
|
||
});
|
||
//Если требуется перезагрузить данные
|
||
if (handleReload && !pointSettings.addNoteOnChst) {
|
||
handleReload();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
},
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||
[executeStored, pOnlineShowDictionary]
|
||
);
|
||
|
||
//Изменение статуса события
|
||
const handleSend = useCallback(
|
||
async (nEvent, handleReload, note = null) => {
|
||
//Выполняем инициализацию параметров
|
||
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,
|
||
NEVENT: nEvent,
|
||
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,
|
||
SNOTE_HEADER: note.text ? note.header : null,
|
||
SNOTE: note.text ? note.text : null
|
||
}
|
||
});
|
||
//Если требуется перезагрузить данные
|
||
if (handleReload) {
|
||
handleReload();
|
||
}
|
||
}
|
||
});
|
||
}
|
||
},
|
||
[executeStored, pOnlineShowDictionary]
|
||
);
|
||
|
||
const mItems = [
|
||
{ method: "EDIT", name: "Исправить", icon: "edit", visible: false, delimiter: false, needReload: false, func: handleTaskEdit },
|
||
{
|
||
method: "EDIT_CLIENT",
|
||
name: "Исправить в разделе",
|
||
icon: "edit_note",
|
||
visible: true,
|
||
delimiter: false,
|
||
needReload: false,
|
||
func: handleTaskEditClient
|
||
},
|
||
{ method: "DELETE", name: "Удалить", icon: "delete", visible: true, delimiter: true, needReload: true, func: handleTaskDelete },
|
||
{
|
||
method: "TASK_STATE_CHANGE",
|
||
name: "Перейти",
|
||
icon: "turn_right",
|
||
visible: true,
|
||
delimiter: false,
|
||
needReload: true,
|
||
func: handleStateChange
|
||
},
|
||
{
|
||
method: "TASK_RETURN",
|
||
name: "Выполнить возврат",
|
||
icon: "turn_left",
|
||
visible: true,
|
||
delimiter: false,
|
||
needReload: true,
|
||
func: handleTaskReturn
|
||
},
|
||
{ method: "TASK_SEND", name: "Направить", icon: "send", visible: true, delimiter: true, needReload: true, func: handleSend },
|
||
{ method: "NOTES", name: "Примечания", icon: "event_note", visible: true, delimiter: true, needReload: false, func: handleEventNotesOpen },
|
||
{
|
||
method: "FILE_LINKS",
|
||
name: "Присоединенные документы",
|
||
icon: "attach_file",
|
||
visible: true,
|
||
delimiter: false,
|
||
needReload: false,
|
||
func: handleFileLinksOpen
|
||
}
|
||
];
|
||
|
||
//Генерация содержимого
|
||
return (
|
||
<Box>
|
||
{taskDialogOpen ? (
|
||
<TaskDialog
|
||
taskRn={task.nrn}
|
||
taskType={task.stype}
|
||
editable={pointSettings.banUpdate ? false : true}
|
||
onReload={onReload}
|
||
onClose={() => {
|
||
setTaskDialogOpen(false);
|
||
}}
|
||
/>
|
||
) : null}
|
||
<Draggable draggableId={task.id.toString()} key={task.id} index={index}>
|
||
{provided => (
|
||
<Card
|
||
ref={provided.innerRef}
|
||
{...provided.draggableProps}
|
||
{...provided.dragHandleProps}
|
||
sx={STYLES.CARD(indicatorColorRule(task), colorRule.color ? bgColorRule(task, colorRule) : null)}
|
||
>
|
||
<CardHeader
|
||
title={
|
||
<Typography
|
||
className="task-info"
|
||
sx={STYLES.CARD_HEADER_TITLE}
|
||
lang="ru"
|
||
onClick={() => {
|
||
mItems.find(a => (a.method === "EDIT" ? a.func(task.nrn, a.needReload ? onReload : null) : null));
|
||
}}
|
||
>
|
||
{task.sdescription}
|
||
</Typography>
|
||
}
|
||
sx={STYLES.CARD_HEADER_DESC}
|
||
action={
|
||
<DataCellCardActions
|
||
taskRn={task.nrn}
|
||
menuItems={mItems}
|
||
cardActions={cardActions}
|
||
onMethodsMenuButtonClick={handleMethodsMenuButtonClick}
|
||
onMethodsMenuClose={handleMethodsMenuClose}
|
||
onReload={onReload}
|
||
eventPoints={eventPoints}
|
||
pointSettings={pointSettings}
|
||
onOpenNoteDialog={onOpenNoteDialog}
|
||
/>
|
||
}
|
||
/>
|
||
<CardContent sx={STYLES.CARD_CONTENT}>
|
||
<Box sx={STYLES.CARD_CONTENT_BOX}>
|
||
<IconButton
|
||
title={task.nlinked_rn ? "Событие получено по статусной модели" : null}
|
||
onClick={
|
||
task.nlinked_rn ? () => pOnlineShowDocument({ unitCode: task.slinked_unit, document: task.nlinked_rn }) : null
|
||
}
|
||
sx={STYLES.ICON_COLOR(task.nlinked_rn)}
|
||
disabled={!task.nlinked_rn}
|
||
>
|
||
<Icon>assignment</Icon>
|
||
</IconButton>
|
||
<Typography sx={STYLES.SECONDARY_TEXT}>{task.name}</Typography>
|
||
{task.sSender ? (
|
||
<Stack direction="row" spacing={0.5} sx={STYLES.ACCOUNT_STACK}>
|
||
<Typography sx={STYLES.SECONDARY_TEXT}>{task.sSender}</Typography>
|
||
<Avatar src={avatar ? `data:image/png;base64,${avatar}` : null} />
|
||
</Stack>
|
||
) : null}
|
||
</Box>
|
||
</CardContent>
|
||
</Card>
|
||
)}
|
||
</Draggable>
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
//Контроль свойств - Карточка события
|
||
TaskCard.propTypes = {
|
||
task: PropTypes.object.isRequired,
|
||
avatar: PropTypes.string,
|
||
index: PropTypes.number.isRequired,
|
||
onReload: PropTypes.func,
|
||
eventPoints: PropTypes.array,
|
||
colorRule: PropTypes.object,
|
||
pointSettings: PropTypes.object,
|
||
onOpenNoteDialog: PropTypes.func
|
||
};
|
||
|
||
//----------------
|
||
//Интерфейс модуля
|
||
//----------------
|
||
|
||
export { TaskCard };
|