ЦИТК-1002 - панель "Доски задач", обработка аннулированных событий
This commit is contained in:
parent
ea83eba5b5
commit
6a58902069
@ -26,10 +26,13 @@ import { useTasksFunctions } from "../hooks/tasks_hooks"; //Состояние
|
|||||||
//Стили
|
//Стили
|
||||||
const STYLES = {
|
const STYLES = {
|
||||||
MENU_ITEM_DELIMITER: { borderBottom: "1px solid lightgrey" },
|
MENU_ITEM_DELIMITER: { borderBottom: "1px solid lightgrey" },
|
||||||
CARD: (indicatorClr, bgClr) => {
|
CARD: (task, colorRule) => {
|
||||||
const i = indicatorClr ? { borderLeft: `solid ${indicatorClr}` } : null;
|
const expiredColor = getTaskExpiredColor(task);
|
||||||
const bc = bgClr ? { backgroundColor: bgClr } : null;
|
const backgroundColor = task.nClosed ? "#d3d3d3" : colorRule.SCOLOR ? getTaskBgColorByRule(task, colorRule) : null;
|
||||||
return { ...i, ...bc };
|
return {
|
||||||
|
...(expiredColor ? { borderLeft: `solid ${expiredColor}` } : {}),
|
||||||
|
...(backgroundColor ? { backgroundColor: backgroundColor } : {})
|
||||||
|
};
|
||||||
},
|
},
|
||||||
CARD_HEADER_TITLE: {
|
CARD_HEADER_TITLE: {
|
||||||
padding: "4px",
|
padding: "4px",
|
||||||
@ -42,14 +45,12 @@ const STYLES = {
|
|||||||
},
|
},
|
||||||
CARD_HEADER: { padding: 0, cursor: "pointer" },
|
CARD_HEADER: { padding: 0, cursor: "pointer" },
|
||||||
CARD_CONTENT: { padding: "4px !important" },
|
CARD_CONTENT: { padding: "4px !important" },
|
||||||
CARD_CONTENT_BOX: { display: "flex", alignItems: "center" },
|
CARD_CONTENT_BOX: { display: "flex", alignItems: "center", width: "100%" },
|
||||||
STACK_SENDER: { alignItems: "center", marginLeft: "auto" },
|
STACK_SENDER: { alignItems: "center", marginLeft: "auto", width: "50%", justifyContent: "flex-end", paddingLeft: "10px", gap: "5px" },
|
||||||
TYPOGRAPHY_SECONDARY: {
|
TYPOGRAPHY_TASK: { color: "text.secondary", fontSize: 14, width: "40%", overflow: "hidden" },
|
||||||
color: "text.secondary",
|
TYPOGRAPHY_SENDER: { color: "text.secondary", fontSize: 14, width: "80%", overflow: "hidden", textAlign: "end" },
|
||||||
fontSize: 14
|
|
||||||
},
|
|
||||||
ICON_COLOR: linked => {
|
ICON_COLOR: linked => {
|
||||||
return { color: theme => (linked ? TASK_COLORS.LINKED : theme.palette.grey[500]) };
|
return { color: theme => (linked ? TASK_COLORS.LINKED : theme.palette.grey[500]), width: "10%" };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ const STYLES = {
|
|||||||
//Действия карточки события
|
//Действия карточки события
|
||||||
const CardActions = ({
|
const CardActions = ({
|
||||||
taskRn,
|
taskRn,
|
||||||
|
taskClosed,
|
||||||
menuItems,
|
menuItems,
|
||||||
cardActions,
|
cardActions,
|
||||||
onMethodsMenuButtonClick,
|
onMethodsMenuButtonClick,
|
||||||
@ -92,6 +94,7 @@ const CardActions = ({
|
|||||||
sx={action.delimiter ? STYLES.MENU_ITEM_DELIMITER : {}}
|
sx={action.delimiter ? STYLES.MENU_ITEM_DELIMITER : {}}
|
||||||
key={`${taskRn}_${action.method}`}
|
key={`${taskRn}_${action.method}`}
|
||||||
onClick={() => handleActionClick(action)}
|
onClick={() => handleActionClick(action)}
|
||||||
|
disabled={taskClosed === 1 && action.disableClosed ? true : false}
|
||||||
>
|
>
|
||||||
<Icon>{action.icon}</Icon>
|
<Icon>{action.icon}</Icon>
|
||||||
<Typography pl={1}>{action.name}</Typography>
|
<Typography pl={1}>{action.name}</Typography>
|
||||||
@ -106,6 +109,7 @@ const CardActions = ({
|
|||||||
//Контроль свойств - Действия карточки события
|
//Контроль свойств - Действия карточки события
|
||||||
CardActions.propTypes = {
|
CardActions.propTypes = {
|
||||||
taskRn: PropTypes.number.isRequired,
|
taskRn: PropTypes.number.isRequired,
|
||||||
|
taskClosed: PropTypes.oneOf([0, 1]).isRequired,
|
||||||
menuItems: PropTypes.array.isRequired,
|
menuItems: PropTypes.array.isRequired,
|
||||||
cardActions: PropTypes.object.isRequired,
|
cardActions: PropTypes.object.isRequired,
|
||||||
onMethodsMenuButtonClick: PropTypes.func.isRequired,
|
onMethodsMenuButtonClick: PropTypes.func.isRequired,
|
||||||
@ -330,12 +334,7 @@ const TaskCard = ({ task, index, onTasksReload, colorRule, pointSettings, onOpen
|
|||||||
) : null}
|
) : null}
|
||||||
<Draggable draggableId={task.id.toString()} key={task.id} index={index}>
|
<Draggable draggableId={task.id.toString()} key={task.id} index={index}>
|
||||||
{provided => (
|
{provided => (
|
||||||
<Card
|
<Card ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} sx={STYLES.CARD(task, colorRule)}>
|
||||||
ref={provided.innerRef}
|
|
||||||
{...provided.draggableProps}
|
|
||||||
{...provided.dragHandleProps}
|
|
||||||
sx={STYLES.CARD(getTaskExpiredColor(task), colorRule.SCOLOR ? getTaskBgColorByRule(task, colorRule) : null)}
|
|
||||||
>
|
|
||||||
<CardHeader
|
<CardHeader
|
||||||
title={
|
title={
|
||||||
<Typography
|
<Typography
|
||||||
@ -347,6 +346,7 @@ const TaskCard = ({ task, index, onTasksReload, colorRule, pointSettings, onOpen
|
|||||||
action.method === "EDIT" ? action.func(task.nRn, action.tasksReload ? onTasksReload : null) : null
|
action.method === "EDIT" ? action.func(task.nRn, action.tasksReload ? onTasksReload : null) : null
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
title={task.sDescription}
|
||||||
>
|
>
|
||||||
{task.sDescription}
|
{task.sDescription}
|
||||||
</Typography>
|
</Typography>
|
||||||
@ -355,6 +355,7 @@ const TaskCard = ({ task, index, onTasksReload, colorRule, pointSettings, onOpen
|
|||||||
action={
|
action={
|
||||||
<CardActions
|
<CardActions
|
||||||
taskRn={task.nRn}
|
taskRn={task.nRn}
|
||||||
|
taskClosed={task.nClosed}
|
||||||
menuItems={menuItems}
|
menuItems={menuItems}
|
||||||
cardActions={cardActions}
|
cardActions={cardActions}
|
||||||
onMethodsMenuButtonClick={handleMethodsMenuButtonClick}
|
onMethodsMenuButtonClick={handleMethodsMenuButtonClick}
|
||||||
@ -377,10 +378,14 @@ const TaskCard = ({ task, index, onTasksReload, colorRule, pointSettings, onOpen
|
|||||||
>
|
>
|
||||||
<Icon>assignment</Icon>
|
<Icon>assignment</Icon>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Typography sx={STYLES.TYPOGRAPHY_SECONDARY}>{task.name}</Typography>
|
<Typography sx={STYLES.TYPOGRAPHY_TASK} noWrap title={task.name}>
|
||||||
|
{task.name}
|
||||||
|
</Typography>
|
||||||
{task.sSender ? (
|
{task.sSender ? (
|
||||||
<Stack direction="row" spacing={0.5} sx={STYLES.STACK_SENDER}>
|
<Stack direction="row" spacing={0.5} sx={STYLES.STACK_SENDER}>
|
||||||
<Typography sx={STYLES.TYPOGRAPHY_SECONDARY}>{task.sSender}</Typography>
|
<Typography sx={STYLES.TYPOGRAPHY_SENDER} title={task.sSender} noWrap>
|
||||||
|
{task.sSender}
|
||||||
|
</Typography>
|
||||||
<Avatar src={task.avatar ? `data:image/png;base64,${task.avatar}` : null} />
|
<Avatar src={task.avatar ? `data:image/png;base64,${task.avatar}` : null} />
|
||||||
</Stack>
|
</Stack>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@ -7,14 +7,12 @@
|
|||||||
//Подключение библиотек
|
//Подключение библиотек
|
||||||
//---------------------
|
//---------------------
|
||||||
|
|
||||||
import React, { useState, useEffect, useCallback } from "react"; //Классы React
|
import React, { useState, useCallback } from "react"; //Классы React
|
||||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||||
import { Box, Typography, Tabs, Tab, InputAdornment, IconButton, Icon } from "@mui/material"; //Интерфейсные компоненты
|
import { Box, Typography, Tabs, Tab, InputAdornment, IconButton, Icon } from "@mui/material"; //Интерфейсные компоненты
|
||||||
import { TaskFormTabInfo } from "./task_form_tab_info"; //Вкладка основной информации
|
import { TaskFormTabInfo } from "./task_form_tab_info"; //Вкладка основной информации
|
||||||
import { TaskFormTabExecutor } from "./task_form_tab_executor"; //Вкладка информации об исполнителе
|
import { TaskFormTabExecutor } from "./task_form_tab_executor"; //Вкладка информации об исполнителе
|
||||||
import { TaskFormTabProps } from "./task_form_tab_props"; //Вкладка информации со свойствами
|
import { TaskFormTabProps } from "./task_form_tab_props"; //Вкладка информации со свойствами
|
||||||
import { useDocsProps } from "../hooks/task_dialog_hooks"; //Хук для получения свойств раздела "События"
|
|
||||||
import { hasValue } from "../../../core/utils";
|
|
||||||
|
|
||||||
//---------
|
//---------
|
||||||
//Константы
|
//Константы
|
||||||
@ -74,13 +72,10 @@ export const getInputProps = (onClick, disabled = false, icon = "list") => {
|
|||||||
//-----------
|
//-----------
|
||||||
|
|
||||||
//Форма события
|
//Форма события
|
||||||
const TaskForm = ({ task, taskType, onTaskChange, editable, onEventNextNumbGet, onDPReady }) => {
|
const TaskForm = ({ task, taskType, editable, docProps, onTaskChange, onEventNextNumbGet }) => {
|
||||||
//Состояние вкладки
|
//Состояние вкладки
|
||||||
const [tab, setTab] = useState(0);
|
const [tab, setTab] = useState(0);
|
||||||
|
|
||||||
//Состояние допустимых дополнительных свойств
|
|
||||||
const [docProps] = useDocsProps(taskType);
|
|
||||||
|
|
||||||
//При изменении вкладки
|
//При изменении вкладки
|
||||||
const handleTabChange = (e, newValue) => {
|
const handleTabChange = (e, newValue) => {
|
||||||
setTab(newValue);
|
setTab(newValue);
|
||||||
@ -107,24 +102,16 @@ const TaskForm = ({ task, taskType, onTaskChange, editable, onEventNextNumbGet,
|
|||||||
[onTaskChange, task.docProps]
|
[onTaskChange, task.docProps]
|
||||||
);
|
);
|
||||||
|
|
||||||
//Проверка заполненности всех обязательных доп. свойств
|
|
||||||
useEffect(() => {
|
|
||||||
//Считываем количество незаполненных обязательных свойств
|
|
||||||
let notFilled = docProps.props.filter(docProp => docProp.BREQUIRE === true && !hasValue(task.docProps[docProp.SFORMATTED_ID])).length;
|
|
||||||
//Если доп. свойства загрузились и количество незаполненных = 0 - доп. свойства готовы, иначе не готовы
|
|
||||||
docProps.loaded && notFilled === 0 ? onDPReady(true) : onDPReady(false);
|
|
||||||
}, [docProps, onDPReady, task.docProps]);
|
|
||||||
|
|
||||||
//Генерация содержимого
|
//Генерация содержимого
|
||||||
return (
|
return (
|
||||||
<Box sx={STYLES.CONTAINER}>
|
<Box sx={STYLES.CONTAINER}>
|
||||||
<Typography pb={1} variant="h6">
|
<Typography pb={1} variant="h6">
|
||||||
{task.nRn ? "Исправление события" : "Добавление события"}
|
{task.nRn ? `Исправление события${task.nClosed ? " (событые аннулировано)" : ""}` : "Добавление события"}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Tabs value={tab} onChange={handleTabChange} aria-label="tabs of values">
|
<Tabs value={tab} onChange={handleTabChange} aria-label="tabs of values">
|
||||||
<Tab label="Событие" {...a11yProps(0)} />
|
<Tab label="Событие" {...a11yProps(0)} />
|
||||||
<Tab label="Исполнитель" {...a11yProps(1)} />
|
<Tab label="Исполнитель" {...a11yProps(1)} />
|
||||||
{docProps.props.length > 0 ? <Tab label="Свойства" {...a11yProps(2)} /> : null}
|
{docProps.length > 0 ? <Tab label="Свойства" {...a11yProps(2)} /> : null}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<CustomTabPanel value={tab} index={0}>
|
<CustomTabPanel value={tab} index={0}>
|
||||||
<TaskFormTabInfo task={task} editable={editable} onFieldEdit={handleFieldEdit} onEventNextNumbGet={onEventNextNumbGet} />
|
<TaskFormTabInfo task={task} editable={editable} onFieldEdit={handleFieldEdit} onEventNextNumbGet={onEventNextNumbGet} />
|
||||||
@ -132,7 +119,7 @@ const TaskForm = ({ task, taskType, onTaskChange, editable, onEventNextNumbGet,
|
|||||||
<CustomTabPanel value={tab} index={1}>
|
<CustomTabPanel value={tab} index={1}>
|
||||||
<TaskFormTabExecutor task={task} onFieldEdit={handleFieldEdit} />
|
<TaskFormTabExecutor task={task} onFieldEdit={handleFieldEdit} />
|
||||||
</CustomTabPanel>
|
</CustomTabPanel>
|
||||||
{docProps.props.length > 0 ? (
|
{docProps.length > 0 ? (
|
||||||
<CustomTabPanel value={tab} index={2}>
|
<CustomTabPanel value={tab} index={2}>
|
||||||
<TaskFormTabProps task={task} taskType={taskType} docProps={docProps} onPropEdit={handlePropEdit} />
|
<TaskFormTabProps task={task} taskType={taskType} docProps={docProps} onPropEdit={handlePropEdit} />
|
||||||
</CustomTabPanel>
|
</CustomTabPanel>
|
||||||
@ -145,10 +132,10 @@ const TaskForm = ({ task, taskType, onTaskChange, editable, onEventNextNumbGet,
|
|||||||
TaskForm.propTypes = {
|
TaskForm.propTypes = {
|
||||||
task: PropTypes.object.isRequired,
|
task: PropTypes.object.isRequired,
|
||||||
taskType: PropTypes.string.isRequired,
|
taskType: PropTypes.string.isRequired,
|
||||||
onTaskChange: PropTypes.func.isRequired,
|
|
||||||
editable: PropTypes.bool.isRequired,
|
editable: PropTypes.bool.isRequired,
|
||||||
onEventNextNumbGet: PropTypes.func.isRequired,
|
docProps: PropTypes.array,
|
||||||
onDPReady: PropTypes.func.isRequired
|
onTaskChange: PropTypes.func.isRequired,
|
||||||
|
onEventNextNumbGet: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------
|
//----------------
|
||||||
|
|||||||
@ -89,7 +89,7 @@ const TaskFormTabInfo = ({ task, editable, onFieldEdit, onEventNextNumbGet }) =>
|
|||||||
value={task.sCrn}
|
value={task.sCrn}
|
||||||
variant="standard"
|
variant="standard"
|
||||||
onChange={onFieldEdit}
|
onChange={onFieldEdit}
|
||||||
InputProps={getInputProps(handleCrnChange)}
|
InputProps={getInputProps(handleCrnChange, task.isUpdate || task.nClosed === 1)}
|
||||||
required
|
required
|
||||||
disabled={task.isUpdate}
|
disabled={task.isUpdate}
|
||||||
/>
|
/>
|
||||||
@ -159,8 +159,8 @@ const TaskFormTabInfo = ({ task, editable, onFieldEdit, onEventNextNumbGet }) =>
|
|||||||
value={task.sClntClients}
|
value={task.sClntClients}
|
||||||
variant="standard"
|
variant="standard"
|
||||||
onChange={onFieldEdit}
|
onChange={onFieldEdit}
|
||||||
disabled={!task.sType}
|
disabled={!task.sType || task.nClosed === 1}
|
||||||
InputProps={getInputProps(() => handleClntClientsChange(), !task.sType)}
|
InputProps={getInputProps(() => handleClntClientsChange(), !task.sType || task.nClosed === 1)}
|
||||||
></TextField>
|
></TextField>
|
||||||
<TextField
|
<TextField
|
||||||
sx={COMMON_STYLES.TASK_FORM_TEXT_FIELD()}
|
sx={COMMON_STYLES.TASK_FORM_TEXT_FIELD()}
|
||||||
@ -169,8 +169,8 @@ const TaskFormTabInfo = ({ task, editable, onFieldEdit, onEventNextNumbGet }) =>
|
|||||||
value={task.sClntClnperson}
|
value={task.sClntClnperson}
|
||||||
variant="standard"
|
variant="standard"
|
||||||
onChange={onFieldEdit}
|
onChange={onFieldEdit}
|
||||||
disabled={!task.sType}
|
disabled={!task.sType || task.nClosed === 1}
|
||||||
InputProps={getInputProps(() => handleClntClnpersonChange(), !task.sType)}
|
InputProps={getInputProps(() => handleClntClnpersonChange(), !task.sType || task.nClosed === 1)}
|
||||||
></TextField>
|
></TextField>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -101,7 +101,7 @@ const TaskFormTabProps = ({ task, docProps, onPropEdit }) => {
|
|||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Box sx={COMMON_STYLES.BOX_WITH_LEGEND} component="fieldset">
|
<Box sx={COMMON_STYLES.BOX_WITH_LEGEND} component="fieldset">
|
||||||
{docProps.props.map((docProp, index) => {
|
{docProps.map((docProp, index) => {
|
||||||
return docProp.BSHOW_IN_GRID ? (
|
return docProp.BSHOW_IN_GRID ? (
|
||||||
<TextField
|
<TextField
|
||||||
error={
|
error={
|
||||||
@ -158,7 +158,7 @@ const TaskFormTabProps = ({ task, docProps, onPropEdit }) => {
|
|||||||
//Контроль свойств - Вкладка информации со свойствами
|
//Контроль свойств - Вкладка информации со свойствами
|
||||||
TaskFormTabProps.propTypes = {
|
TaskFormTabProps.propTypes = {
|
||||||
task: PropTypes.object.isRequired,
|
task: PropTypes.object.isRequired,
|
||||||
docProps: PropTypes.object.isRequired,
|
docProps: PropTypes.array.isRequired,
|
||||||
onPropEdit: PropTypes.func.isRequired
|
onPropEdit: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -74,6 +74,7 @@ const useClientEvent = (taskRn, taskType = "") => {
|
|||||||
setTask(pv => ({
|
setTask(pv => ({
|
||||||
...pv,
|
...pv,
|
||||||
sCrn: data.XEVENT.SCRN,
|
sCrn: data.XEVENT.SCRN,
|
||||||
|
nClosed: data.XEVENT.NCLOSED,
|
||||||
sPrefix: data.XEVENT.SPREF,
|
sPrefix: data.XEVENT.SPREF,
|
||||||
sNumber: data.XEVENT.SNUMB,
|
sNumber: data.XEVENT.SNUMB,
|
||||||
sType: data.XEVENT.STYPE,
|
sType: data.XEVENT.STYPE,
|
||||||
|
|||||||
@ -326,6 +326,7 @@ const useTasks = (filterValues, ordersValues) => {
|
|||||||
nRn: task.NRN,
|
nRn: task.NRN,
|
||||||
sCrn: "",
|
sCrn: "",
|
||||||
nCrn: task.NCRN,
|
nCrn: task.NCRN,
|
||||||
|
nClosed: task.NCLOSED,
|
||||||
sPrefix: task.SEVPREF,
|
sPrefix: task.SEVPREF,
|
||||||
sNumber: task.SEVNUMB,
|
sNumber: task.SEVNUMB,
|
||||||
sType: task.SEVTYPE_CODE,
|
sType: task.SEVTYPE_CODE,
|
||||||
|
|||||||
@ -208,6 +208,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
|
|||||||
delimiter: false,
|
delimiter: false,
|
||||||
tasksReload: false,
|
tasksReload: false,
|
||||||
needAccountsReload: false,
|
needAccountsReload: false,
|
||||||
|
disableClosed: false,
|
||||||
func: onEdit
|
func: onEdit
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -218,6 +219,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
|
|||||||
delimiter: false,
|
delimiter: false,
|
||||||
tasksReload: false,
|
tasksReload: false,
|
||||||
needAccountsReload: false,
|
needAccountsReload: false,
|
||||||
|
disableClosed: false,
|
||||||
func: onEditClient
|
func: onEditClient
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -228,6 +230,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
|
|||||||
delimiter: false,
|
delimiter: false,
|
||||||
tasksReload: true,
|
tasksReload: true,
|
||||||
needAccountsReload: false,
|
needAccountsReload: false,
|
||||||
|
disableClosed: false,
|
||||||
func: onMove
|
func: onMove
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -238,6 +241,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
|
|||||||
delimiter: true,
|
delimiter: true,
|
||||||
tasksReload: true,
|
tasksReload: true,
|
||||||
needAccountsReload: false,
|
needAccountsReload: false,
|
||||||
|
disableClosed: false,
|
||||||
func: onDelete
|
func: onDelete
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -248,6 +252,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
|
|||||||
delimiter: false,
|
delimiter: false,
|
||||||
tasksReload: true,
|
tasksReload: true,
|
||||||
needAccountsReload: true,
|
needAccountsReload: true,
|
||||||
|
disableClosed: true,
|
||||||
func: onStateChange
|
func: onStateChange
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -258,6 +263,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
|
|||||||
delimiter: false,
|
delimiter: false,
|
||||||
tasksReload: true,
|
tasksReload: true,
|
||||||
needAccountsReload: true,
|
needAccountsReload: true,
|
||||||
|
disableClosed: true,
|
||||||
func: onReturn
|
func: onReturn
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -268,6 +274,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
|
|||||||
delimiter: true,
|
delimiter: true,
|
||||||
tasksReload: true,
|
tasksReload: true,
|
||||||
needAccountsReload: true,
|
needAccountsReload: true,
|
||||||
|
disableClosed: true,
|
||||||
func: onSend
|
func: onSend
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -278,6 +285,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
|
|||||||
delimiter: true,
|
delimiter: true,
|
||||||
tasksReload: false,
|
tasksReload: false,
|
||||||
needAccountsReload: false,
|
needAccountsReload: false,
|
||||||
|
disableClosed: false,
|
||||||
func: onNotesOpen
|
func: onNotesOpen
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -288,6 +296,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
|
|||||||
delimiter: false,
|
delimiter: false,
|
||||||
tasksReload: false,
|
tasksReload: false,
|
||||||
needAccountsReload: false,
|
needAccountsReload: false,
|
||||||
|
disableClosed: false,
|
||||||
func: onFileLinksOpen
|
func: onFileLinksOpen
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@ -7,14 +7,16 @@
|
|||||||
//Подключение библиотек
|
//Подключение библиотек
|
||||||
//---------------------
|
//---------------------
|
||||||
|
|
||||||
import React, { useState, useCallback, useContext } from "react"; //Классы React
|
import React, { useState, useCallback, useContext, useEffect } from "react"; //Классы React
|
||||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||||
import { Dialog, DialogContent, DialogActions, Button } from "@mui/material"; //Интерфейсные компоненты
|
import { Dialog, DialogContent, DialogActions, Button } from "@mui/material"; //Интерфейсные компоненты
|
||||||
import { useClientEvent } from "./hooks/task_dialog_hooks"; //Хук для события
|
import { useClientEvent } from "./hooks/task_dialog_hooks"; //Хук для события
|
||||||
|
import { useDocsProps } from "./hooks/task_dialog_hooks"; //Хук для получения доп. свойств раздела "События"
|
||||||
import { TaskForm } from "./components/task_form"; //Форма события
|
import { TaskForm } from "./components/task_form"; //Форма события
|
||||||
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
|
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
|
||||||
import { object2Base64XML } from "../../core/utils"; //Вспомогательные функции
|
import { object2Base64XML } from "../../core/utils"; //Вспомогательные функции
|
||||||
import { COMMON_STYLES } from "./styles"; //Общие стили
|
import { COMMON_STYLES } from "./styles"; //Общие стили
|
||||||
|
import { hasValue } from "../../core/utils"; //Вспомогательные процедуры и функции
|
||||||
|
|
||||||
//---------
|
//---------
|
||||||
//Константы
|
//Константы
|
||||||
@ -39,15 +41,15 @@ const TaskDialog = ({ taskRn, taskType, editable, onTasksReload, onClose }) => {
|
|||||||
//Собственное состояние
|
//Собственное состояние
|
||||||
const [task, setTask] = useClientEvent(taskRn, taskType);
|
const [task, setTask] = useClientEvent(taskRn, taskType);
|
||||||
|
|
||||||
//Состояние заполненности всех обязательных свойств
|
//Состояние допустимых дополнительных свойств
|
||||||
const [dpReady, setDPReady] = useState(false);
|
const [docProps] = useDocsProps(taskType);
|
||||||
|
|
||||||
|
//Состояние заполненности всех обязательных доп. свойств
|
||||||
|
const [docPropsReady, setDocPropsReady] = useState(false);
|
||||||
|
|
||||||
//Подключение к контексту взаимодействия с сервером
|
//Подключение к контексту взаимодействия с сервером
|
||||||
const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx);
|
const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx);
|
||||||
|
|
||||||
//При изменении заполненности всех обязательных свойств
|
|
||||||
const handleDPReady = useCallback(v => setDPReady(v), []);
|
|
||||||
|
|
||||||
//При изменении информации о задаче
|
//При изменении информации о задаче
|
||||||
const handleTaskChange = useCallback(
|
const handleTaskChange = useCallback(
|
||||||
newTaskValues => {
|
newTaskValues => {
|
||||||
@ -129,17 +131,33 @@ const TaskDialog = ({ taskRn, taskType, editable, onTasksReload, onClose }) => {
|
|||||||
}
|
}
|
||||||
}, [executeStored, setTask, task.sPrefix]);
|
}, [executeStored, setTask, task.sPrefix]);
|
||||||
|
|
||||||
|
//Проверка заполненности всех обязательных доп. свойств
|
||||||
|
useEffect(() => {
|
||||||
|
//Если доп. свойства загрузились
|
||||||
|
if (docProps.loaded) {
|
||||||
|
//Проверяем остались ли обязательные незаполненные свойства
|
||||||
|
let notFilled = docProps.props.some(docProp => docProp.BREQUIRE === true && !hasValue(task.docProps[docProp.SFORMATTED_ID]));
|
||||||
|
//Если незаполненных обязательных доп. свойств не осталось - доп. свойства готовы, иначе не готовы
|
||||||
|
setDocPropsReady(!notFilled);
|
||||||
|
} else {
|
||||||
|
//Доп. свойства не готовы
|
||||||
|
setDocPropsReady(false);
|
||||||
|
}
|
||||||
|
}, [docProps.loaded, docProps.props, task.docProps]);
|
||||||
|
|
||||||
//Генерация содержимого
|
//Генерация содержимого
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{!task.init && docProps.loaded && (
|
||||||
<Dialog open onClose={onClose ? onClose : null} fullWidth>
|
<Dialog open onClose={onClose ? onClose : null} fullWidth>
|
||||||
<DialogContent sx={STYLES.DIALOG_CONTENT}>
|
<DialogContent sx={STYLES.DIALOG_CONTENT}>
|
||||||
<TaskForm
|
<TaskForm
|
||||||
task={task}
|
task={task}
|
||||||
taskType={taskType}
|
taskType={taskType}
|
||||||
onTaskChange={handleTaskChange}
|
|
||||||
editable={!taskRn || editable ? true : false}
|
editable={!taskRn || editable ? true : false}
|
||||||
|
docProps={docProps.props}
|
||||||
|
onTaskChange={handleTaskChange}
|
||||||
onEventNextNumbGet={handleEventNextNumbGet}
|
onEventNextNumbGet={handleEventNextNumbGet}
|
||||||
onDPReady={handleDPReady}
|
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
{onClose ? (
|
{onClose ? (
|
||||||
@ -147,12 +165,15 @@ const TaskDialog = ({ taskRn, taskType, editable, onTasksReload, onClose }) => {
|
|||||||
{taskRn ? (
|
{taskRn ? (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => handleUpdateEvent(onClose).then(onTasksReload)}
|
onClick={() => handleUpdateEvent(onClose).then(onTasksReload)}
|
||||||
disabled={task.updateDisabled || !editable || !dpReady}
|
disabled={task.updateDisabled || !editable || !docPropsReady}
|
||||||
>
|
>
|
||||||
Исправить
|
Исправить
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button onClick={() => handleInsertTask(onClose).then(onTasksReload)} disabled={task.insertDisabled || !dpReady}>
|
<Button
|
||||||
|
onClick={() => handleInsertTask(onClose).then(onTasksReload)}
|
||||||
|
disabled={task.insertDisabled || !docPropsReady}
|
||||||
|
>
|
||||||
Добавить
|
Добавить
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@ -160,6 +181,8 @@ const TaskDialog = ({ taskRn, taskType, editable, onTasksReload, onClose }) => {
|
|||||||
</DialogActions>
|
</DialogActions>
|
||||||
) : null}
|
) : null}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
)}{" "}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1396,6 +1396,7 @@ create or replace package body PKG_P8PANELS_CLNTTSKBRD as
|
|||||||
PKG_XFAST.DOWN_NODE(SNAME => 'XDATA');
|
PKG_XFAST.DOWN_NODE(SNAME => 'XDATA');
|
||||||
PKG_XFAST.DOWN_NODE(SNAME => 'XEVENT');
|
PKG_XFAST.DOWN_NODE(SNAME => 'XEVENT');
|
||||||
PKG_XFAST.ATTR(SNAME => 'SCRN', SVALUE => SCRN);
|
PKG_XFAST.ATTR(SNAME => 'SCRN', SVALUE => SCRN);
|
||||||
|
PKG_XFAST.ATTR(SNAME => 'NCLOSED', NVALUE => RCLNEVENTS.CLOSED);
|
||||||
PKG_XFAST.ATTR(SNAME => 'SPREF', SVALUE => RCLNEVENTS.EVENT_PREF);
|
PKG_XFAST.ATTR(SNAME => 'SPREF', SVALUE => RCLNEVENTS.EVENT_PREF);
|
||||||
PKG_XFAST.ATTR(SNAME => 'SNUMB', SVALUE => RCLNEVENTS.EVENT_NUMB);
|
PKG_XFAST.ATTR(SNAME => 'SNUMB', SVALUE => RCLNEVENTS.EVENT_NUMB);
|
||||||
PKG_XFAST.ATTR(SNAME => 'STYPE', SVALUE => STYPE);
|
PKG_XFAST.ATTR(SNAME => 'STYPE', SVALUE => STYPE);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user