diff --git a/app/panels/clnt_task_board/components/task_card.js b/app/panels/clnt_task_board/components/task_card.js
index 4b69c66..cbe6642 100644
--- a/app/panels/clnt_task_board/components/task_card.js
+++ b/app/panels/clnt_task_board/components/task_card.js
@@ -26,10 +26,13 @@ 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: (task, colorRule) => {
+ const expiredColor = getTaskExpiredColor(task);
+ const backgroundColor = task.nClosed ? "#d3d3d3" : colorRule.SCOLOR ? getTaskBgColorByRule(task, colorRule) : null;
+ return {
+ ...(expiredColor ? { borderLeft: `solid ${expiredColor}` } : {}),
+ ...(backgroundColor ? { backgroundColor: backgroundColor } : {})
+ };
},
CARD_HEADER_TITLE: {
padding: "4px",
@@ -42,14 +45,12 @@ const STYLES = {
},
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
- },
+ CARD_CONTENT_BOX: { display: "flex", alignItems: "center", width: "100%" },
+ STACK_SENDER: { alignItems: "center", marginLeft: "auto", width: "50%", justifyContent: "flex-end", paddingLeft: "10px", gap: "5px" },
+ TYPOGRAPHY_TASK: { color: "text.secondary", fontSize: 14, width: "40%", overflow: "hidden" },
+ TYPOGRAPHY_SENDER: { color: "text.secondary", fontSize: 14, width: "80%", overflow: "hidden", textAlign: "end" },
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 = ({
taskRn,
+ taskClosed,
menuItems,
cardActions,
onMethodsMenuButtonClick,
@@ -92,6 +94,7 @@ const CardActions = ({
sx={action.delimiter ? STYLES.MENU_ITEM_DELIMITER : {}}
key={`${taskRn}_${action.method}`}
onClick={() => handleActionClick(action)}
+ disabled={taskClosed === 1 && action.disableClosed ? true : false}
>
{action.icon}
{action.name}
@@ -106,6 +109,7 @@ const CardActions = ({
//Контроль свойств - Действия карточки события
CardActions.propTypes = {
taskRn: PropTypes.number.isRequired,
+ taskClosed: PropTypes.oneOf([0, 1]).isRequired,
menuItems: PropTypes.array.isRequired,
cardActions: PropTypes.object.isRequired,
onMethodsMenuButtonClick: PropTypes.func.isRequired,
@@ -330,12 +334,7 @@ const TaskCard = ({ task, index, onTasksReload, colorRule, pointSettings, onOpen
) : null}
{provided => (
-
+
{task.sDescription}
@@ -355,6 +355,7 @@ const TaskCard = ({ task, index, onTasksReload, colorRule, pointSettings, onOpen
action={
assignment
- {task.name}
+
+ {task.name}
+
{task.sSender ? (
- {task.sSender}
+
+ {task.sSender}
+
) : null}
diff --git a/app/panels/clnt_task_board/components/task_form.js b/app/panels/clnt_task_board/components/task_form.js
index 12d5882..1cfaf21 100644
--- a/app/panels/clnt_task_board/components/task_form.js
+++ b/app/panels/clnt_task_board/components/task_form.js
@@ -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 { Box, Typography, Tabs, Tab, InputAdornment, IconButton, Icon } from "@mui/material"; //Интерфейсные компоненты
import { TaskFormTabInfo } from "./task_form_tab_info"; //Вкладка основной информации
import { TaskFormTabExecutor } from "./task_form_tab_executor"; //Вкладка информации об исполнителе
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 [docProps] = useDocsProps(taskType);
-
//При изменении вкладки
const handleTabChange = (e, newValue) => {
setTab(newValue);
@@ -107,24 +102,16 @@ const TaskForm = ({ task, taskType, onTaskChange, editable, onEventNextNumbGet,
[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 (
- {task.nRn ? "Исправление события" : "Добавление события"}
+ {task.nRn ? `Исправление события${task.nClosed ? " (событые аннулировано)" : ""}` : "Добавление события"}
- {docProps.props.length > 0 ? : null}
+ {docProps.length > 0 ? : null}
@@ -132,7 +119,7 @@ const TaskForm = ({ task, taskType, onTaskChange, editable, onEventNextNumbGet,
- {docProps.props.length > 0 ? (
+ {docProps.length > 0 ? (
@@ -145,10 +132,10 @@ const TaskForm = ({ task, taskType, onTaskChange, editable, onEventNextNumbGet,
TaskForm.propTypes = {
task: PropTypes.object.isRequired,
taskType: PropTypes.string.isRequired,
- onTaskChange: PropTypes.func.isRequired,
editable: PropTypes.bool.isRequired,
- onEventNextNumbGet: PropTypes.func.isRequired,
- onDPReady: PropTypes.func.isRequired
+ docProps: PropTypes.array,
+ onTaskChange: PropTypes.func.isRequired,
+ onEventNextNumbGet: PropTypes.func.isRequired
};
//----------------
diff --git a/app/panels/clnt_task_board/components/task_form_tab_info.js b/app/panels/clnt_task_board/components/task_form_tab_info.js
index b97f7c8..9dcfa6a 100644
--- a/app/panels/clnt_task_board/components/task_form_tab_info.js
+++ b/app/panels/clnt_task_board/components/task_form_tab_info.js
@@ -89,7 +89,7 @@ const TaskFormTabInfo = ({ task, editable, onFieldEdit, onEventNextNumbGet }) =>
value={task.sCrn}
variant="standard"
onChange={onFieldEdit}
- InputProps={getInputProps(handleCrnChange)}
+ InputProps={getInputProps(handleCrnChange, task.isUpdate || task.nClosed === 1)}
required
disabled={task.isUpdate}
/>
@@ -159,8 +159,8 @@ const TaskFormTabInfo = ({ task, editable, onFieldEdit, onEventNextNumbGet }) =>
value={task.sClntClients}
variant="standard"
onChange={onFieldEdit}
- disabled={!task.sType}
- InputProps={getInputProps(() => handleClntClientsChange(), !task.sType)}
+ disabled={!task.sType || task.nClosed === 1}
+ InputProps={getInputProps(() => handleClntClientsChange(), !task.sType || task.nClosed === 1)}
>
value={task.sClntClnperson}
variant="standard"
onChange={onFieldEdit}
- disabled={!task.sType}
- InputProps={getInputProps(() => handleClntClnpersonChange(), !task.sType)}
+ disabled={!task.sType || task.nClosed === 1}
+ InputProps={getInputProps(() => handleClntClnpersonChange(), !task.sType || task.nClosed === 1)}
>
diff --git a/app/panels/clnt_task_board/components/task_form_tab_props.js b/app/panels/clnt_task_board/components/task_form_tab_props.js
index dc89940..acfccb2 100644
--- a/app/panels/clnt_task_board/components/task_form_tab_props.js
+++ b/app/panels/clnt_task_board/components/task_form_tab_props.js
@@ -101,7 +101,7 @@ const TaskFormTabProps = ({ task, docProps, onPropEdit }) => {
return (
- {docProps.props.map((docProp, index) => {
+ {docProps.map((docProp, index) => {
return docProp.BSHOW_IN_GRID ? (
{
//Контроль свойств - Вкладка информации со свойствами
TaskFormTabProps.propTypes = {
task: PropTypes.object.isRequired,
- docProps: PropTypes.object.isRequired,
+ docProps: PropTypes.array.isRequired,
onPropEdit: PropTypes.func.isRequired
};
diff --git a/app/panels/clnt_task_board/hooks/task_dialog_hooks.js b/app/panels/clnt_task_board/hooks/task_dialog_hooks.js
index 414c369..3433fc7 100644
--- a/app/panels/clnt_task_board/hooks/task_dialog_hooks.js
+++ b/app/panels/clnt_task_board/hooks/task_dialog_hooks.js
@@ -74,6 +74,7 @@ const useClientEvent = (taskRn, taskType = "") => {
setTask(pv => ({
...pv,
sCrn: data.XEVENT.SCRN,
+ nClosed: data.XEVENT.NCLOSED,
sPrefix: data.XEVENT.SPREF,
sNumber: data.XEVENT.SNUMB,
sType: data.XEVENT.STYPE,
diff --git a/app/panels/clnt_task_board/hooks/tasks_hooks.js b/app/panels/clnt_task_board/hooks/tasks_hooks.js
index a6437e9..7175217 100644
--- a/app/panels/clnt_task_board/hooks/tasks_hooks.js
+++ b/app/panels/clnt_task_board/hooks/tasks_hooks.js
@@ -326,6 +326,7 @@ const useTasks = (filterValues, ordersValues) => {
nRn: task.NRN,
sCrn: "",
nCrn: task.NCRN,
+ nClosed: task.NCLOSED,
sPrefix: task.SEVPREF,
sNumber: task.SEVNUMB,
sType: task.SEVTYPE_CODE,
diff --git a/app/panels/clnt_task_board/layouts.js b/app/panels/clnt_task_board/layouts.js
index 474ef56..3187dcc 100644
--- a/app/panels/clnt_task_board/layouts.js
+++ b/app/panels/clnt_task_board/layouts.js
@@ -208,6 +208,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
delimiter: false,
tasksReload: false,
needAccountsReload: false,
+ disableClosed: false,
func: onEdit
},
{
@@ -218,6 +219,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
delimiter: false,
tasksReload: false,
needAccountsReload: false,
+ disableClosed: false,
func: onEditClient
},
{
@@ -228,6 +230,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
delimiter: false,
tasksReload: true,
needAccountsReload: false,
+ disableClosed: false,
func: onMove
},
{
@@ -238,6 +241,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
delimiter: true,
tasksReload: true,
needAccountsReload: false,
+ disableClosed: false,
func: onDelete
},
{
@@ -248,6 +252,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
delimiter: false,
tasksReload: true,
needAccountsReload: true,
+ disableClosed: true,
func: onStateChange
},
{
@@ -258,6 +263,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
delimiter: false,
tasksReload: true,
needAccountsReload: true,
+ disableClosed: true,
func: onReturn
},
{
@@ -268,6 +274,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
delimiter: true,
tasksReload: true,
needAccountsReload: true,
+ disableClosed: true,
func: onSend
},
{
@@ -278,6 +285,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
delimiter: true,
tasksReload: false,
needAccountsReload: false,
+ disableClosed: false,
func: onNotesOpen
},
{
@@ -288,6 +296,7 @@ export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChan
delimiter: false,
tasksReload: false,
needAccountsReload: false,
+ disableClosed: false,
func: onFileLinksOpen
}
];
diff --git a/app/panels/clnt_task_board/task_dialog.js b/app/panels/clnt_task_board/task_dialog.js
index d616134..549aac8 100644
--- a/app/panels/clnt_task_board/task_dialog.js
+++ b/app/panels/clnt_task_board/task_dialog.js
@@ -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 { Dialog, DialogContent, DialogActions, Button } from "@mui/material"; //Интерфейсные компоненты
import { useClientEvent } from "./hooks/task_dialog_hooks"; //Хук для события
+import { useDocsProps } from "./hooks/task_dialog_hooks"; //Хук для получения доп. свойств раздела "События"
import { TaskForm } from "./components/task_form"; //Форма события
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { object2Base64XML } from "../../core/utils"; //Вспомогательные функции
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 [dpReady, setDPReady] = useState(false);
+ //Состояние допустимых дополнительных свойств
+ const [docProps] = useDocsProps(taskType);
+
+ //Состояние заполненности всех обязательных доп. свойств
+ const [docPropsReady, setDocPropsReady] = useState(false);
//Подключение к контексту взаимодействия с сервером
const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx);
- //При изменении заполненности всех обязательных свойств
- const handleDPReady = useCallback(v => setDPReady(v), []);
-
//При изменении информации о задаче
const handleTaskChange = useCallback(
newTaskValues => {
@@ -129,37 +131,58 @@ const TaskDialog = ({ taskRn, taskType, editable, onTasksReload, onClose }) => {
}
}, [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 (
-
+ <>
+ {!task.init && docProps.loaded && (
+
+ )}{" "}
+ >
);
};
diff --git a/db/PKG_P8PANELS_CLNTTSKBRD.pck b/db/PKG_P8PANELS_CLNTTSKBRD.pck
index 979b611..be12480 100644
--- a/db/PKG_P8PANELS_CLNTTSKBRD.pck
+++ b/db/PKG_P8PANELS_CLNTTSKBRD.pck
@@ -1396,6 +1396,7 @@ create or replace package body PKG_P8PANELS_CLNTTSKBRD as
PKG_XFAST.DOWN_NODE(SNAME => 'XDATA');
PKG_XFAST.DOWN_NODE(SNAME => 'XEVENT');
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 => 'SNUMB', SVALUE => RCLNEVENTS.EVENT_NUMB);
PKG_XFAST.ATTR(SNAME => 'STYPE', SVALUE => STYPE);