ЦИТК-878. Примечание от 11.11.24

This commit is contained in:
Vladislav 2024-11-29 18:57:37 +03:00
parent 434504dda3
commit 8507127c39
7 changed files with 289 additions and 310 deletions

View File

@ -17,7 +17,7 @@ import { FilterDialog } from "./components/filter_dialog"; //Компонент
import { TaskCardSettings } from "./components/task_card_settings.js"; //Компонент настроек карточки события import { TaskCardSettings } from "./components/task_card_settings.js"; //Компонент настроек карточки события
import { useTasks, COLORS } from "./hooks.js"; //Вспомогательные хуки import { useTasks, COLORS } from "./hooks.js"; //Вспомогательные хуки
import { APP_STYLES } from "../../../app.styles"; //Типовые стили import { APP_STYLES } from "../../../app.styles"; //Типовые стили
import { useNoteDialog } from "./components/note_dialog.js"; import { NoteDialog } from "./components/note_dialog.js"; //Диалог примечания
//--------- //---------
//Константы //Константы
@ -79,6 +79,7 @@ const ClntTaskBoard = () => {
tasks, tasks,
eventRoutes, eventRoutes,
eventPoints, eventPoints,
noteTypes,
docLinks, docLinks,
accounts, accounts,
taskFormOpen, taskFormOpen,
@ -97,7 +98,13 @@ const ClntTaskBoard = () => {
] = useTasks(); ] = useTasks();
//Состояние диалога примечания //Состояние диалога примечания
const [noteDialogRender, handleNoteDialogChange] = useNoteDialog(); const [noteDialog, setNoteDialog] = useState({ visible: false, callback: null });
//Открытие диалога примечания
const handleNoteDialogOpen = f => setNoteDialog({ visible: true, callback: v => f(v) });
//Закрытие диалога примечания
const handleNoteDialogClose = () => setNoteDialog({ visible: false, callback: null });
//Состояние доступных маршрутов события //Состояние доступных маршрутов события
const [availableRoutes, setAvailableRoutes] = useState({ sorce: "", routes: [] }); const [availableRoutes, setAvailableRoutes] = useState({ sorce: "", routes: [] });
@ -123,7 +130,6 @@ const ClntTaskBoard = () => {
//Генерация содержимого //Генерация содержимого
return ( return (
<Box sx={STYLES.CONTAINER}> <Box sx={STYLES.CONTAINER}>
<Button onClick={() => handleNoteDialogChange(true)}>Жми</Button>
{tasks.filters.isOpen ? ( {tasks.filters.isOpen ? (
<FilterDialog <FilterDialog
initial={tasks.filters.values} initial={tasks.filters.values}
@ -142,10 +148,7 @@ const ClntTaskBoard = () => {
handleOrderChanged={handleOrderChanged} handleOrderChanged={handleOrderChanged}
sx={STYLES.FILTER} sx={STYLES.FILTER}
/> />
{noteDialogRender( {noteDialog.visible ? <NoteDialog noteTypes={noteTypes} onOk={n => noteDialog.callback(n)} onCancel={handleNoteDialogClose} /> : null}
v => console.log(`Примечание: ${v}`),
() => console.log("Отмена")
)}
{tasks.filters.values.type ? ( {tasks.filters.values.type ? (
<DragDropContext <DragDropContext
onDragStart={e => { onDragStart={e => {
@ -153,7 +156,7 @@ const ClntTaskBoard = () => {
setAvailableRoutes({ sorce: srcCode, routes: [...eventRoutes.filter(r => r.src === srcCode)] }); setAvailableRoutes({ sorce: srcCode, routes: [...eventRoutes.filter(r => r.src === srcCode)] });
}} }}
onDragEnd={e => { onDragEnd={e => {
onDragEnd(e); onDragEnd(e, eventPoints, handleNoteDialogOpen);
clearARState(); clearARState();
}} }}
> >
@ -216,7 +219,9 @@ const ClntTaskBoard = () => {
index={index} index={index}
handleReload={handleReload} handleReload={handleReload}
key={item.id} key={item.id}
extraHandle={handleNoteDialogChange} eventPoints={eventPoints}
pointSettings={eventPoints.find(p => p.point === status.code)}
openNoteDialog={handleNoteDialogOpen}
/> />
))} ))}
{provided.placeholder} {provided.placeholder}

View File

@ -116,21 +116,18 @@ const FilterDialog = ({ initial, docs, onCancel, onOk, getDocLinks }) => {
//Собственное состояние //Собственное состояние
const [filter, setFilter] = useState({ ...initial }); const [filter, setFilter] = useState({ ...initial });
//Состояние текущего типа события
const [curType, setCurType] = useState(initial.type); const [curType, setCurType] = useState(initial.type);
//Состояние учётных документов
const [curDocLinks, setCurDocLinks] = useState([...docs]); const [curDocLinks, setCurDocLinks] = useState([...docs]);
//Состояние изменения типа события
const [typeDif, setTypeDif] = useState(false); const [typeDif, setTypeDif] = useState(false);
//const [catalogs, setCatalogs] = useState(initial.wSubcatalogs ? initial.crn : initial.crn.split(";")[0]);
//const [curDocLink, setCurDocLink] = useState(initial.docLink ? initial.docLink : "");
//Подключение к контексту взаимодействия с сервером //Подключение к контексту взаимодействия с сервером
const { executeStored } = useContext(BackEndСtx); const { executeStored } = useContext(BackEndСtx);
//const promisedSetCrn = crn => new Promise(resolve => setFilter(pv => ({ ...pv, crn: crn }), resolve));
//Получение субкаталогов //Получение субкаталогов
const getSubCatalogs = useCallback(async () => { const getSubCatalogs = useCallback(async () => {
const data = await executeStored({ const data = await executeStored({
@ -140,11 +137,7 @@ const FilterDialog = ({ initial, docs, onCancel, onOk, getDocLinks }) => {
NSUBCAT: filter.wSubcatalogs ? 1 : 0 NSUBCAT: filter.wSubcatalogs ? 1 : 0
} }
}); });
//Заполняем субкаталоги
//setCatalogs(data.SRESULT);
//setFilter(pv => ({ ...pv, crn: data.SRESULT }));
return data.SRESULT; return data.SRESULT;
//await promisedSetCrn(data.SRESULT);
}, [executeStored, filter.catalog, filter.wSubcatalogs]); }, [executeStored, filter.catalog, filter.wSubcatalogs]);
//Подключение к контексту приложения //Подключение к контексту приложения
@ -177,13 +170,6 @@ const FilterDialog = ({ initial, docs, onCancel, onOk, getDocLinks }) => {
crns ? (filterCopy.crn = crns) : null; crns ? (filterCopy.crn = crns) : null;
onOk(filterCopy); onOk(filterCopy);
} else onOk(filter); } else onOk(filter);
// if (filter.catalog && filter.wSubcatalogs) {
// const crns = await getSubCatalogs(filter.crn);
// let filterCopy = { ...filter };
// crns ? (filterCopy.crn = crns) : null;
// onOk(filterCopy);
// } else onOk(filter);
} }
}; };
@ -193,12 +179,6 @@ const FilterDialog = ({ initial, docs, onCancel, onOk, getDocLinks }) => {
//Очистка учётного документа //Очистка учётного документа
const clearDocLink = () => setFilter(pv => ({ ...pv, docLink: "" })); const clearDocLink = () => setFilter(pv => ({ ...pv, docLink: "" }));
//Очистка галочки "Включая подкаталоги"
//const clearWSubcatalogs = () => setFilter(pv => ({ ...pv, wSubcatalogs: false }));
//Очистка сотстояния подкаталогов
//const clearCatalogs = () => setCatalogs("");
//При изменении типа события //При изменении типа события
useEffect(() => { useEffect(() => {
if (curType) { if (curType) {
@ -210,14 +190,6 @@ const FilterDialog = ({ initial, docs, onCancel, onOk, getDocLinks }) => {
} }
}, [curType, filter.type]); }, [curType, filter.type]);
//При очистке каталога
// useEffect(() => {
// if (!filter.catalog && filter.wSubcatalogs) {
// clearWSubcatalogs();
// //clearCatalogs();
// }
// }, [filter.catalog, filter.wSubcatalogs]);
//Обработка изменений с каталогами //Обработка изменений с каталогами
useEffect(() => { useEffect(() => {
if (!filter.catalog && filter.wSubcatalogs) setFilter(pv => ({ ...pv, wSubcatalogs: false })); if (!filter.catalog && filter.wSubcatalogs) setFilter(pv => ({ ...pv, wSubcatalogs: false }));
@ -230,10 +202,6 @@ const FilterDialog = ({ initial, docs, onCancel, onOk, getDocLinks }) => {
setFilter(pv => ({ ...pv, crn: "" })); setFilter(pv => ({ ...pv, crn: "" }));
}, [filter.catalog, filter.crn, filter.wSubcatalogs, initial.catalog, initial.crn, initial.wSubcatalogs]); }, [filter.catalog, filter.crn, filter.wSubcatalogs, initial.catalog, initial.crn, initial.wSubcatalogs]);
// useEffect(() => {
// console.log(`State changed: ${filter.crn}`);
// }, [filter.crn]);
//Генерация содержимого //Генерация содержимого
return ( return (
<div> <div>
@ -331,7 +299,6 @@ const FilterDialog = ({ initial, docs, onCancel, onOk, getDocLinks }) => {
</IconButton> </IconButton>
<IconButton <IconButton
title="Обновить" title="Обновить"
//disabled={!((!curType && filter.type) || (typeDif && filter.type))}
disabled={!((!curType || typeDif) && filter.type)} disabled={!((!curType || typeDif) && filter.type)}
onClick={() => { onClick={() => {
setCurType(filter.type); setCurType(filter.type);

View File

@ -10,6 +10,7 @@
import React, { useEffect, useState } from "react"; //Классы React import React, { useEffect, useState } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента import PropTypes from "prop-types"; //Контроль свойств компонента
import { FormControl, InputLabel, Input, InputAdornment, IconButton, Icon, FormHelperText, Select, MenuItem } from "@mui/material"; //Интерфейсные компоненты import { FormControl, InputLabel, Input, InputAdornment, IconButton, Icon, FormHelperText, Select, MenuItem } from "@mui/material"; //Интерфейсные компоненты
import { APP_STYLES } from "../../../../app.styles"; //Типовые стили
//--------- //---------
//Константы //Константы
@ -17,7 +18,8 @@ import { FormControl, InputLabel, Input, InputAdornment, IconButton, Icon, FormH
//Стили //Стили
const STYLES = { const STYLES = {
HELPER_TEXT: { color: "red" } HELPER_TEXT: { color: "red" },
SELECT_MENU: { overflowY: "auto", ...APP_STYLES.SCROLL }
}; };
//--------------- //---------------
@ -80,6 +82,7 @@ const FilterInputField = ({ elementCode, elementValue, labelText, onChange, requ
value={value} value={value}
aria-describedby={`${elementCode}-helper-text`} aria-describedby={`${elementCode}-helper-text`}
label={labelText} label={labelText}
MenuProps={{ slotProps: { paper: { sx: STYLES.SELECT_MENU } } }}
onChange={handleChange} onChange={handleChange}
{...other} {...other}
> >

View File

@ -7,14 +7,24 @@
//Подключение библиотек //Подключение библиотек
//--------------------- //---------------------
import React, { useEffect, useState } from "react"; //Классы React import React, { useState } from "react"; //Классы React
//import { BackEndСtx } from "../../../context/backend"; //Контекст взаимодействия с сервером import PropTypes from "prop-types"; //Контроль свойств компонента
//import PropTypes from "prop-types"; //Контроль свойств компонента import {
import { Dialog, DialogTitle, IconButton, Icon, DialogContent, DialogActions, Button, TextField } from "@mui/material"; //Интерфейсные компоненты Dialog,
DialogTitle,
//--------- IconButton,
//Константы Icon,
//--------- DialogContent,
DialogActions,
Button,
TextField,
FormControl,
InputLabel,
Select,
MenuItem
} from "@mui/material"; //Интерфейсные компоненты
import { APP_STYLES } from "../../../../app.styles"; //Типовые стили
import { arrayFormer } from "../hooks"; //Формировщик массива
//Стили //Стили
const STYLES = { const STYLES = {
@ -25,76 +35,86 @@ const STYLES = {
top: 8, top: 8,
color: theme => theme.palette.grey[500] color: theme => theme.palette.grey[500]
}, },
DIALOG_CONTENT: { paddingTop: 0, paddingBottom: 0 } DIALOG_CONTENT: { paddingTop: 0, paddingBottom: 0 },
TEXT_FIELD: {
overflowY: "auto",
...APP_STYLES.SCROLL
}
}; };
//-----------------------
//Вспомогательные функции
//-----------------------
//export const NoteDialogCtx = createContext();
//--------------- //---------------
//Тело компонента //Тело компонента
//--------------- //---------------
//Диалоговое окно фильтра отбора const NoteDialog = ({ noteTypes, onOk, onCancel }) => {
const useNoteDialog = () => {
//Собственное состояние //Собственное состояние
const [note, setNote] = useState(); const [note, setNote] = useState({ headerV: 0, text: "" });
//Состояние отображения окна
const [noteDialogOpen, setNoteDialogOpen] = useState(false);
useEffect(() => {
if (noteDialogOpen) console.log(`Сейчас: ${noteDialogOpen}`);
}, [noteDialogOpen]);
const handleNoteDialogChange = (value = null) => (value ? setNoteDialogOpen(value) : setNoteDialogOpen(!noteDialogOpen));
const noteDialogRender = (onOk, onCancel) => {
//При изменении примечания //При изменении примечания
const handleNoteChange = value => setNote(value); const handleNoteChange = value => setNote(pv => ({ ...pv, text: value }));
//При изменении заголовка примечания
const handleNoteHeaderChange = h => {
setNote(pv => ({ ...pv, headerV: h }));
};
//При закрытии диалога с изменением фильтра //При закрытии диалога с изменением фильтра
const handleOK = () => { const handleOK = () => {
setNoteDialogOpen(false); //setNoteDialogOpen(false);
onOk(note); onOk({ header: noteTypes[note.headerV], text: note.text });
setNote(); onCancel();
}; };
//При закрытии диалога без изменения фильтра //При закрытии диалога без изменения фильтра
const handleCancel = () => { const handleCancel = () => {
setNoteDialogOpen(false);
setNote();
onCancel(); onCancel();
}; };
//Генерация содержимого //Генерация содержимого
return ( return (
<div>
{noteDialogOpen ? (
<Dialog open onClose={handleCancel} fullWidth maxWidth="sm"> <Dialog open onClose={handleCancel} fullWidth maxWidth="sm">
<DialogTitle>Примечание</DialogTitle> <DialogTitle>Примечание</DialogTitle>
<IconButton aria-label="close" onClick={handleCancel} sx={STYLES.CLOSE_BUTTON}> <IconButton aria-label="close" onClick={handleCancel} sx={STYLES.CLOSE_BUTTON}>
<Icon>close</Icon> <Icon>close</Icon>
</IconButton> </IconButton>
<DialogContent sx={STYLES.DIALOG_CONTENT}> <DialogContent sx={STYLES.DIALOG_CONTENT}>
<FormControl fullWidth variant="standard">
<InputLabel htmlFor="noteHeader">Заголовок примечания</InputLabel>
<Select
id="noteHeader"
name="noteHeader"
value={note.headerV}
aria-describedby="noteHeader-helper-text"
label="Заголовок примечания"
margin="dense"
onChange={e => handleNoteHeaderChange(e.target.value)}
>
{noteTypes
? arrayFormer(noteTypes).map((item, i) => (
<MenuItem key={i} value={i}>
{item}
</MenuItem>
))
: null}
</Select>
</FormControl>
<TextField <TextField
id="note" id="note"
label="Примечание" label="Описание"
variant="standard" variant="standard"
fullWidth fullWidth
required required
multiline multiline
minRows={7} minRows={7}
maxRows={7} maxRows={7}
value={note} value={note.text}
margin="normal"
inputProps={{ sx: STYLES.TEXT_FIELD }}
onChange={e => handleNoteChange(e.target.value)} onChange={e => handleNoteChange(e.target.value)}
/> />
</DialogContent> </DialogContent>
<DialogActions sx={STYLES.DIALOG_ACTIONS}> <DialogActions sx={STYLES.DIALOG_ACTIONS}>
<Button disabled={!note} variant="text" onClick={handleOK}> <Button disabled={!note.text} variant="text" onClick={handleOK}>
ОК ОК
</Button> </Button>
<Button variant="text" onClick={handleCancel}> <Button variant="text" onClick={handleCancel}>
@ -102,40 +122,18 @@ const useNoteDialog = () => {
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
) : null}
</div>
); );
};
return [noteDialogRender, handleNoteDialogChange];
}; };
// const NoteDialog = (onOk, onCancel) => { //Контроль свойств - Диалоговое окно примечания
// //const { noteDialogRender } = useContext(NoteDialogContext); NoteDialog.propTypes = {
// const noteDialogRender = useNoteDialog()[1]; noteTypes: PropTypes.array,
onOk: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired
};
// //const [noteDialog] = useState(); //----------------
//Интерфейс модуля
//----------------
// // useEffect(() => { export { NoteDialog };
// // setNoteDialog(noteDialogRender(onOk, onCancel));
// // }, [noteDialogRender, onCancel, onOk]);
// //const onCancel1 = () => console.log("Cancel");
// return noteDialogRender(onOk, onCancel);
// //const { Btn, handleChange } = useComp();
// //return <Btn onOk={onOk} />;
// };
// //Контроль свойств компонента - Диалоговое окно фильтра отбора
// NoteDialog.propTypes = {
// onOk: PropTypes.func,
// onCancel: PropTypes.func
// };
//--------------------
//Интерфейс компонента
//--------------------
export { useNoteDialog };

View File

@ -54,7 +54,9 @@ const DataCellCardActions = ({
handleMethodsMenuButtonClick, handleMethodsMenuButtonClick,
handleMethodsMenuClose, handleMethodsMenuClose,
handleReload, handleReload,
extraHandle = null eventPoints,
pointSettings,
openNoteDialog
}) => { }) => {
return ( return (
<Box sx={STYLES.BOX_ROW}> <Box sx={STYLES.BOX_ROW}>
@ -68,11 +70,15 @@ const DataCellCardActions = ({
<MenuItem <MenuItem
sx={action.delimiter ? STYLES.MENU_ITEM_DELIMITER : {}} sx={action.delimiter ? STYLES.MENU_ITEM_DELIMITER : {}}
key={`${taskRn}_${action.method}`} key={`${taskRn}_${action.method}`}
onClick={async () => { onClick={() => {
//one().then(two).then(three) if (openNoteDialog && action.method === "TASK_STATE_CHANGE") {
action.method === "TASK_STATE_CHANGE" && extraHandle ? extraHandle() : null; action.func(taskRn, action.needReload ? handleReload : null, eventPoints, openNoteDialog);
} else if (openNoteDialog && action.method === "TASK_SEND" && pointSettings.addNoteOnSend) {
openNoteDialog(n => action.func(taskRn, action.needReload ? handleReload : null, n));
} else {
//Выполняем действие //Выполняем действие
action.func(taskRn, action.needReload ? handleReload : null); action.func(taskRn, action.needReload ? handleReload : null);
}
//Закрываем меню //Закрываем меню
handleMethodsMenuClose(); handleMethodsMenuClose();
}} }}
@ -95,7 +101,9 @@ DataCellCardActions.propTypes = {
handleMethodsMenuButtonClick: PropTypes.func.isRequired, handleMethodsMenuButtonClick: PropTypes.func.isRequired,
handleMethodsMenuClose: PropTypes.func.isRequired, handleMethodsMenuClose: PropTypes.func.isRequired,
handleReload: PropTypes.func, handleReload: PropTypes.func,
extraHandle: PropTypes.func eventPoints: PropTypes.array,
pointSettings: PropTypes.object,
openNoteDialog: PropTypes.func
}; };
//----------- //-----------
@ -103,7 +111,7 @@ DataCellCardActions.propTypes = {
//----------- //-----------
//Карточка события //Карточка события
const TaskCard = ({ task, account, index, handleReload, extraHandle = null }) => { const TaskCard = ({ task, account, index, handleReload, eventPoints, pointSettings, openNoteDialog }) => {
//Собственное состояние //Собственное состояние
const [taskCard, setTaskCard, cardActions, handleMethodsMenuButtonClick, handleMethodsMenuClose, menuItems] = useTaskCard(); const [taskCard, setTaskCard, cardActions, handleMethodsMenuButtonClick, handleMethodsMenuClose, menuItems] = useTaskCard();
@ -135,7 +143,9 @@ const TaskCard = ({ task, account, index, handleReload, extraHandle = null }) =>
handleMethodsMenuButtonClick={handleMethodsMenuButtonClick} handleMethodsMenuButtonClick={handleMethodsMenuButtonClick}
handleMethodsMenuClose={handleMethodsMenuClose} handleMethodsMenuClose={handleMethodsMenuClose}
handleReload={handleReload} handleReload={handleReload}
extraHandle={extraHandle} eventPoints={eventPoints}
pointSettings={pointSettings}
openNoteDialog={openNoteDialog}
/> />
} }
/> />
@ -157,6 +167,7 @@ const TaskCard = ({ task, account, index, handleReload, extraHandle = null }) =>
{taskCard.openEdit ? ( {taskCard.openEdit ? (
<TaskFormDialog <TaskFormDialog
taskRn={task.nrn} taskRn={task.nrn}
editable={pointSettings.banUpdate ? false : true}
onClose={() => { onClose={() => {
setTaskCard(pv => ({ ...pv, openEdit: false })); setTaskCard(pv => ({ ...pv, openEdit: false }));
}} }}
@ -172,7 +183,9 @@ TaskCard.propTypes = {
account: PropTypes.object, account: PropTypes.object,
index: PropTypes.number.isRequired, index: PropTypes.number.isRequired,
handleReload: PropTypes.func, handleReload: PropTypes.func,
extraHandle: PropTypes.func eventPoints: PropTypes.array,
pointSettings: PropTypes.object,
openNoteDialog: PropTypes.func
}; };
//---------------- //----------------

View File

@ -92,7 +92,15 @@ CustomTabPanel.propTypes = {
}; };
//Вкладка основной информации //Вкладка основной информации
const MainEventInfoTab = ({ task, handleFieldEdit, handleClientClientsOpen, handleClientPersonOpen, handleCrnOpen, handleEventNextNumbGet }) => { const MainEventInfoTab = ({
task,
editable,
handleFieldEdit,
handleClientClientsOpen,
handleClientPersonOpen,
handleCrnOpen,
handleEventNextNumbGet
}) => {
return ( return (
<Box> <Box>
<Box sx={STYLES.BOX_WITH_LEGEND} component="fieldset"> <Box sx={STYLES.BOX_WITH_LEGEND} component="fieldset">
@ -159,7 +167,7 @@ const MainEventInfoTab = ({ task, handleFieldEdit, handleClientClientsOpen, hand
value={task.sdescription} value={task.sdescription}
variant="standard" variant="standard"
onChange={handleFieldEdit} onChange={handleFieldEdit}
disabled={!task.stype} disabled={!task.stype || !editable}
required required
multiline multiline
minRows={7} minRows={7}
@ -197,6 +205,7 @@ const MainEventInfoTab = ({ task, handleFieldEdit, handleClientClientsOpen, hand
//Контроль свойств - Вкладка основной информации //Контроль свойств - Вкладка основной информации
MainEventInfoTab.propTypes = { MainEventInfoTab.propTypes = {
task: PropTypes.object.isRequired, task: PropTypes.object.isRequired,
editable: PropTypes.bool,
handleFieldEdit: PropTypes.func.isRequired, handleFieldEdit: PropTypes.func.isRequired,
handleClientClientsOpen: PropTypes.func.isRequired, handleClientClientsOpen: PropTypes.func.isRequired,
handleClientPersonOpen: PropTypes.func.isRequired, handleClientPersonOpen: PropTypes.func.isRequired,
@ -332,7 +341,7 @@ ExecutorEventInfoTab.propTypes = {
//----------- //-----------
//Форма события //Форма события
const TaskForm = ({ task, setTask, handleClientClientsOpen, handleClientPersonOpen, handleCrnOpen, handleEventNextNumbGet }) => { const TaskForm = ({ task, setTask, editable, handleClientClientsOpen, handleClientPersonOpen, handleCrnOpen, handleEventNextNumbGet }) => {
//Состояние вкладки //Состояние вкладки
const [value, setValue] = useState(0); const [value, setValue] = useState(0);
@ -365,6 +374,7 @@ const TaskForm = ({ task, setTask, handleClientClientsOpen, handleClientPersonOp
<CustomTabPanel value={value} index={0}> <CustomTabPanel value={value} index={0}>
<MainEventInfoTab <MainEventInfoTab
task={task} task={task}
editable={task.nrn ? editable : null}
handleFieldEdit={handleFieldEdit} handleFieldEdit={handleFieldEdit}
handleClientClientsOpen={handleClientClientsOpen} handleClientClientsOpen={handleClientClientsOpen}
handleClientPersonOpen={handleClientPersonOpen} handleClientPersonOpen={handleClientPersonOpen}
@ -383,6 +393,7 @@ const TaskForm = ({ task, setTask, handleClientClientsOpen, handleClientPersonOp
TaskForm.propTypes = { TaskForm.propTypes = {
task: PropTypes.object.isRequired, task: PropTypes.object.isRequired,
setTask: PropTypes.func.isRequired, setTask: PropTypes.func.isRequired,
editable: PropTypes.bool,
handleClientClientsOpen: PropTypes.func.isRequired, handleClientClientsOpen: PropTypes.func.isRequired,
handleClientPersonOpen: PropTypes.func.isRequired, handleClientPersonOpen: PropTypes.func.isRequired,
handleCrnOpen: PropTypes.func.isRequired, handleCrnOpen: PropTypes.func.isRequired,
@ -390,7 +401,7 @@ TaskForm.propTypes = {
}; };
//Диалог с формой события //Диалог с формой события
const TaskFormDialog = ({ taskRn, taskType, taskStatus, onClose }) => { const TaskFormDialog = ({ taskRn, taskType, taskStatus, editable, onClose }) => {
//Собственное состояние //Собственное состояние
const [task, setTask, insertEvent, updateEvent, handleClientClientsOpen, handleClientPersonOpen, handleCrnOpen, handleEventNextNumbGet] = const [task, setTask, insertEvent, updateEvent, handleClientClientsOpen, handleClientPersonOpen, handleCrnOpen, handleEventNextNumbGet] =
useClientEvent(taskRn, taskType, taskStatus); useClientEvent(taskRn, taskType, taskStatus);
@ -401,6 +412,7 @@ const TaskFormDialog = ({ taskRn, taskType, taskStatus, onClose }) => {
<TaskForm <TaskForm
task={task} task={task}
setTask={setTask} setTask={setTask}
editable={taskRn ? editable : null}
handleClientClientsOpen={handleClientClientsOpen} handleClientClientsOpen={handleClientClientsOpen}
handleClientPersonOpen={handleClientPersonOpen} handleClientPersonOpen={handleClientPersonOpen}
handleCrnOpen={handleCrnOpen} handleCrnOpen={handleCrnOpen}
@ -410,7 +422,7 @@ const TaskFormDialog = ({ taskRn, taskType, taskStatus, onClose }) => {
{onClose ? ( {onClose ? (
<DialogActions sx={STYLES.DIALOG_ACTIONS}> <DialogActions sx={STYLES.DIALOG_ACTIONS}>
{taskRn ? ( {taskRn ? (
<Button onClick={() => updateEvent(onClose)} disabled={task.updateDisabled}> <Button onClick={() => updateEvent(onClose)} disabled={task.updateDisabled || !editable}>
Исправить Исправить
</Button> </Button>
) : ( ) : (
@ -430,6 +442,7 @@ TaskFormDialog.propTypes = {
taskRn: PropTypes.number, taskRn: PropTypes.number,
taskType: PropTypes.string, taskType: PropTypes.string,
taskStatus: PropTypes.string, taskStatus: PropTypes.string,
editable: PropTypes.bool,
onClose: PropTypes.func.isRequired onClose: PropTypes.func.isRequired
}; };

View File

@ -45,6 +45,7 @@ const randomColor = index => {
return hslToRgba(hue, 50, 70); return hslToRgba(hue, 50, 70);
}; };
//Цвет из hsl формата в rgba формат
const hslToRgba = (h, s, l) => { const hslToRgba = (h, s, l) => {
s /= 100; s /= 100;
l /= 100; l /= 100;
@ -54,38 +55,10 @@ const hslToRgba = (h, s, l) => {
return `rgba(${Math.floor(255 * f(0))},${Math.floor(255 * f(8))},${Math.floor(255 * f(4))},0.3)`; return `rgba(${Math.floor(255 * f(0))},${Math.floor(255 * f(8))},${Math.floor(255 * f(4))},0.3)`;
}; };
//Формирование случайного цвета rgba //Формирование массива из 0, 1 и 1< элементов
// const randomColorRgba = index => { export const arrayFormer = arr => {
// const s = [255, 204, 153, 102, 51, 0]; return arr ? (arr.length ? arr : [arr]) : [];
// function rValue() { };
// return s[Math.floor(Math.random() * s.length)];
// }
// let t = 3;
// let rgb = [0, 0, 0];
// function howMuchToLearnJS(x) {
// if (t === 0) return;
// rgb[3 - t] = x % 6;
// t--;
// howMuchToLearnJS(Math.floor(x / 6));
// }
// //let r = rValue();
// //let g = rValue();
// //let b = rValue();
// let r, g, b;
// howMuchToLearnJS(index);
// //while ((r === 0 && g === 0 && b === 0) || b === 255) b = rValue();
// return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ",0.2)";
// };
// const ColorContext = createContext("green");
// export const MyColorContextProvider = () => {
// ColorContext = "blue";
// //const [color] = useState();
// return <ColorContext.Consumer>{value => <button>{value}</button>}</ColorContext.Consumer>;
// };
//----------- //-----------
//Тело модуля //Тело модуля
@ -105,8 +78,8 @@ const useTasks = () => {
//Состояние точек маршрута события //Состояние точек маршрута события
const [eventPoints, setEventPoints] = useState([]); const [eventPoints, setEventPoints] = useState([]);
//Подключение к контексту диалога примечания //Состояние типов заголовков событий
//const {noteDialog, setNoteDialog} = useContext(NoteDialogContext); const [noteTypes, setNoteTypes] = useState([]);
//Состояние учётных документов //Состояние учётных документов
const [docLinks, setDocLinks] = useState([]); const [docLinks, setDocLinks] = useState([]);
@ -320,7 +293,7 @@ const useTasks = () => {
//Изменение статуса события (переносом) //Изменение статуса события (переносом)
const handleStateChange = useCallback( const handleStateChange = useCallback(
async (nEvent, sNextStat) => { async (nEvent, sNextStat, note = null) => {
try { try {
//Выполняем инициализацию параметров //Выполняем инициализацию параметров
const firstStep = await executeStored({ const firstStep = await executeStored({
@ -355,6 +328,7 @@ const useTasks = () => {
args: { args: {
NIDENT: firstStep.NIDENT, NIDENT: firstStep.NIDENT,
NSTEP: 3, NSTEP: 3,
NEVENT: nEvent,
SEVENT_STAT: firstStep.SEVENT_STAT, SEVENT_STAT: firstStep.SEVENT_STAT,
SSEND_CLIENT: send.outParameters.out_CLIENT_CODE, SSEND_CLIENT: send.outParameters.out_CLIENT_CODE,
SSEND_DIVISION: send.outParameters.out_DIVISION_CODE, SSEND_DIVISION: send.outParameters.out_DIVISION_CODE,
@ -365,7 +339,9 @@ const useTasks = () => {
SSEND_USER_GROUP: send.outParameters.out_USER_GROUP_CODE, SSEND_USER_GROUP: send.outParameters.out_USER_GROUP_CODE,
SSEND_USER_NAME: send.outParameters.out_USER_NAME, SSEND_USER_NAME: send.outParameters.out_USER_NAME,
NSEND_PREDEFINED_EXEC: send.outParameters.out_PREDEFINED_EXEC, NSEND_PREDEFINED_EXEC: send.outParameters.out_PREDEFINED_EXEC,
NSEND_PREDEFINED_PROC: send.outParameters.out_PREDEFINED_PROC NSEND_PREDEFINED_PROC: send.outParameters.out_PREDEFINED_PROC,
SNOTE_HEADER: note.text ? note.header : null,
SNOTE: note.text ? note.text : null
} }
}); });
//Необходимо обновить данные //Необходимо обновить данные
@ -379,7 +355,10 @@ const useTasks = () => {
args: { args: {
NIDENT: firstStep.NIDENT, NIDENT: firstStep.NIDENT,
NSTEP: 3, NSTEP: 3,
SEVENT_STAT: firstStep.SEVENT_STAT NEVENT: nEvent,
SEVENT_STAT: firstStep.SEVENT_STAT,
SNOTE_HEADER: note.header ? note.header : null,
SNOTE: note.text ? note.text : null
} }
}); });
//Необходимо обновить данные //Необходимо обновить данные
@ -401,7 +380,7 @@ const useTasks = () => {
//Взаимодействие с событием (через перенос) //Взаимодействие с событием (через перенос)
const onDragEnd = useCallback( const onDragEnd = useCallback(
result => { (result, eventPoints, openNoteDialog) => {
//Определяем нужные параметры //Определяем нужные параметры
const { source, destination } = result; const { source, destination } = result;
//Если путь не указан //Если путь не указан
@ -421,11 +400,25 @@ const useTasks = () => {
} }
: task : task
); );
//Мнемокод точки назначения
const destCode = tasks.statuses.find(s => s.id == destination.droppableId).code;
//Получение настройки точки назначения
const pointSettings = eventPoints.find(ep => ep.point === destCode);
//Если необходимо примечание при переходе
if (pointSettings.addNoteOnChst) {
//Изменяем статус события с добавлением примечания
openNoteDialog(n => {
setTasks(pv => ({ ...pv, rows: [...rows] }));
handleStateChange(row.nrn, destCode, n);
});
}
//Изменяем статус события
else {
//Переинициализируем строки с учетом изменений (для визуального отображения) //Переинициализируем строки с учетом изменений (для визуального отображения)
setTasks(pv => ({ ...pv, rows: [...rows] })); setTasks(pv => ({ ...pv, rows: [...rows] }));
//Изменяем статус события
handleStateChange(row.nrn, tasks.statuses.find(s => s.id == destination.droppableId).code); handleStateChange(row.nrn, tasks.statuses.find(s => s.id == destination.droppableId).code);
} }
}
}, },
[handleStateChange, tasks.rows, tasks.statuses] [handleStateChange, tasks.rows, tasks.statuses]
); );
@ -444,7 +437,7 @@ const useTasks = () => {
let newDocLinks = []; let newDocLinks = [];
//Если найдены учётные документы //Если найдены учётные документы
if (data.XDOCLINKS) { if (data.XDOCLINKS) {
data.XDOCLINKS.map(d => { arrayFormer(data.XDOCLINKS).map(d => {
newDocLinks.push({ id: d.NRN, descr: d.SDESCR }); newDocLinks.push({ id: d.NRN, descr: d.SDESCR });
}); });
} }
@ -469,23 +462,29 @@ const useTasks = () => {
let newRoutes = []; let newRoutes = [];
//Если найдены маршруты //Если найдены маршруты
if (data.XEVROUTES) { if (data.XEVROUTES) {
data.XEVROUTES.map(r => { arrayFormer(data.XEVROUTES).map(r => {
newRoutes.push({ src: r.SSOURCE, dest: r.SDESTINATION }); newRoutes.push({ src: r.SSOURCE, dest: r.SDESTINATION });
}); });
} }
//Инициализируем точки событий //Инициализируем точки событий
let newPoints = []; let newPoints = [];
if (data.XEVPOINTS) { if (data.XEVPOINTS) {
data.XEVPOINTS.map(p => { arrayFormer(data.XEVPOINTS).map(p => {
newPoints.push({ point: p.SEVPOINT, addNoteOnChst: p.ADDNOTE_ONCHST, addNoteOnSend: p.ADDNOTE_ONSEND, banUpdate: p.BAN_UPDATE }); newPoints.push({ point: p.SEVPOINT, addNoteOnChst: p.ADDNOTE_ONCHST, addNoteOnSend: p.ADDNOTE_ONSEND, banUpdate: p.BAN_UPDATE });
}); });
} }
//Инициализируем типы заголовков примечаний
let newNoteTypes = [];
if (data.XNOTETYPES) {
arrayFormer(data.XNOTETYPES).map(nt => {
newNoteTypes.push(nt.SNAME);
});
}
//Инициализируем пользователей //Инициализируем пользователей
let newAccounts = []; let newAccounts = [];
//Если найдены пользователи //Если найдены пользователи
if (data.XACCOUNTS) { if (data.XACCOUNTS) {
data.XACCOUNTS.map(a => { arrayFormer(data.XACCOUNTS).map(a => {
//console.log(a.SEVRN_LIST.toString().includes(";"));
newAccounts.push({ newAccounts.push({
agnAbbr: a.SAGNABBR, agnAbbr: a.SAGNABBR,
image: a.BIMAGE, image: a.BIMAGE,
@ -497,6 +496,8 @@ const useTasks = () => {
setEventRoutes([...newRoutes]); setEventRoutes([...newRoutes]);
//Указываем сформированные точки маршрута //Указываем сформированные точки маршрута
setEventPoints([...newPoints]); setEventPoints([...newPoints]);
//Указываем типы заголовков примечаний
setNoteTypes([...newNoteTypes]);
//Указываем сформированные аккаунты //Указываем сформированные аккаунты
setAccounts([...newAccounts]); setAccounts([...newAccounts]);
}; };
@ -527,13 +528,13 @@ const useTasks = () => {
//Если статусы есть //Если статусы есть
if (data.XGROUPS) { if (data.XGROUPS) {
//Формируем структуру статусов //Формируем структуру статусов
data.XGROUPS.map((group, i) => { arrayFormer(data.XGROUPS).map((group, i) => {
newGroups.push({ id: i, code: group.name, caption: group.caption, color: randomColor(i + 1) }); newGroups.push({ id: i, code: group.name, caption: group.caption, color: randomColor(i + 1) });
}); });
//Если есть события //Если есть события
if (data.XROWS) { if (data.XROWS) {
//Формируем структуру событий //Формируем структуру событий
data.XROWS.map((task, i) => { arrayFormer(data.XROWS).map((task, i) => {
newRows.push(initTask(i, newGroups.find(x => x.caption === task.groupName).id, task)); newRows.push(initTask(i, newGroups.find(x => x.caption === task.groupName).id, task));
}); });
} }
@ -569,6 +570,7 @@ const useTasks = () => {
tasks, tasks,
eventRoutes, eventRoutes,
eventPoints, eventPoints,
noteTypes,
docLinks, docLinks,
accounts, accounts,
taskFormOpen, taskFormOpen,
@ -644,57 +646,6 @@ const useClientEvent = (taskRn, taskType = "", taskStatus = "") => {
} }
}, [task.sprefix, task.stype, executeStored]); }, [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 () => { const handleClientClientsOpen = useCallback(async () => {
pOnlineShowDictionary({ pOnlineShowDictionary({
@ -918,18 +869,7 @@ const useClientEvent = (taskRn, taskType = "", taskStatus = "") => {
})); }));
}, [task.scrn, task.sdescription, task.sinit_clnperson, task.sinit_user, task.snumber, task.sprefix, task.sstatus, task.stype]); }, [task.scrn, task.sdescription, task.sinit_clnperson, task.sinit_user, task.snumber, task.sprefix, task.sstatus, task.stype]);
return [ return [task, setTask, insertEvent, updateEvent, handleClientClientsOpen, handleClientPersonOpen, handleCrnOpen, getEventNextNumb];
task,
setTask,
insertEvent,
updateEvent,
//handleTypeOpen,
//handleStatusOpen,
handleClientClientsOpen,
handleClientPersonOpen,
handleCrnOpen,
getEventNextNumb
];
}; };
//Карточка события //Карточка события
@ -1052,7 +992,7 @@ const useTaskCard = () => {
//По нажатию действия "Перейти" //По нажатию действия "Перейти"
const handleStateChange = useCallback( const handleStateChange = useCallback(
async (nEvent, handleReload) => { async (nEvent, handleReload, evPoints, handleNote) => {
//Выполняем инициализацию параметров //Выполняем инициализацию параметров
const firstStep = await executeStored({ const firstStep = await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE", stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE",
@ -1081,6 +1021,7 @@ const useTaskCard = () => {
NPASS: point.outParameters.out_RN NPASS: point.outParameters.out_RN
} }
}); });
const pointSettings = evPoints.find(ep => ep.point === point.outParameters.out_NEXT_POINT);
if (secondStep) { if (secondStep) {
//Если требуется выбрать получателя //Если требуется выбрать получателя
if (secondStep.NSELECT_EXEC === 1) { if (secondStep.NSELECT_EXEC === 1) {
@ -1099,12 +1040,11 @@ const useTaskCard = () => {
{ name: "in_CLIENT_PERSON", value: firstStep.SCLIENT_PERSON } { name: "in_CLIENT_PERSON", value: firstStep.SCLIENT_PERSON }
], ],
callBack: async send => { callBack: async send => {
//Выполняем переход к выбранной точке с исполнителем //Общие аргументы
await executeStored({ const mainArgs = {
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE",
args: {
NIDENT: firstStep.NIDENT, NIDENT: firstStep.NIDENT,
NSTEP: 3, NSTEP: 3,
NEVENT: nEvent,
SEVENT_STAT: point.outParameters.out_NEXT_POINT, SEVENT_STAT: point.outParameters.out_NEXT_POINT,
SSEND_CLIENT: send.outParameters.out_CLIENT_CODE, SSEND_CLIENT: send.outParameters.out_CLIENT_CODE,
SSEND_DIVISION: send.outParameters.out_DIVISION_CODE, SSEND_DIVISION: send.outParameters.out_DIVISION_CODE,
@ -1116,28 +1056,65 @@ const useTaskCard = () => {
SSEND_USER_NAME: send.outParameters.out_USER_NAME, SSEND_USER_NAME: send.outParameters.out_USER_NAME,
NSEND_PREDEFINED_EXEC: send.outParameters.out_PREDEFINED_EXEC, NSEND_PREDEFINED_EXEC: send.outParameters.out_PREDEFINED_EXEC,
NSEND_PREDEFINED_PROC: send.outParameters.out_PREDEFINED_PROC 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 ? n.header : null, SNOTE: n.text ? n.text : null }
} }
}); });
//Если требуется перезагрузить данные //Если требуется перезагрузить данные
if (handleReload) { if (handleReload) {
handleReload(); handleReload();
} }
})
: await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE",
args: mainArgs
});
//Если требуется перезагрузить данные
if (handleReload && !pointSettings.addNoteOnChst) {
handleReload();
}
} }
}); });
} else { } else {
//Общие аргументы
const mainArgs = {
NIDENT: firstStep.NIDENT,
NSTEP: 3,
NEVENT: nEvent,
SEVENT_STAT: point.outParameters.out_NEXT_POINT
};
//Выполняем переход к выбранной точке с предопределенным исполнителем //Выполняем переход к выбранной точке с предопределенным исполнителем
pointSettings.addNoteOnChst
? handleNote(async n => {
//Если требуется примечание
await executeStored({ await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE", stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE",
args: { args: {
NIDENT: firstStep.NIDENT, ...mainArgs,
NSTEP: 3, ...{ SNOTE_HEADER: n.header ? n.header : null, SNOTE: n.text ? n.text : null }
SEVENT_STAT: point.outParameters.out_NEXT_POINT
} }
}); });
//Если требуется перезагрузить данные //Если требуется перезагрузить данные
if (handleReload) { if (handleReload) {
handleReload(); handleReload();
} }
})
: await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_STATE_CHANGE",
args: mainArgs
});
//Если требуется перезагрузить данные
if (handleReload && !pointSettings.addNoteOnChst) {
handleReload();
}
} }
} }
} }
@ -1150,7 +1127,7 @@ const useTaskCard = () => {
//Изменение статуса события //Изменение статуса события
const handleSend = useCallback( const handleSend = useCallback(
async (nEvent, handleReload) => { async (nEvent, handleReload, note = null) => {
//Выполняем инициализацию параметров //Выполняем инициализацию параметров
const firstStep = await executeStored({ const firstStep = await executeStored({
stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_SEND", stored: "PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_SEND",
@ -1183,6 +1160,7 @@ const useTaskCard = () => {
args: { args: {
NIDENT: firstStep.NIDENT, NIDENT: firstStep.NIDENT,
NSTEP: 2, NSTEP: 2,
NEVENT: nEvent,
SSEND_CLIENT: send.outParameters.out_CLIENT_CODE, SSEND_CLIENT: send.outParameters.out_CLIENT_CODE,
SSEND_DIVISION: send.outParameters.out_DIVISION_CODE, SSEND_DIVISION: send.outParameters.out_DIVISION_CODE,
SSEND_POST: send.outParameters.out_POST_CODE, SSEND_POST: send.outParameters.out_POST_CODE,
@ -1192,7 +1170,9 @@ const useTaskCard = () => {
SSEND_USER_GROUP: send.outParameters.out_USER_GROUP_CODE, SSEND_USER_GROUP: send.outParameters.out_USER_GROUP_CODE,
SSEND_USER_NAME: send.outParameters.out_USER_NAME, SSEND_USER_NAME: send.outParameters.out_USER_NAME,
NSEND_PREDEFINED_EXEC: send.outParameters.out_PREDEFINED_EXEC, NSEND_PREDEFINED_EXEC: send.outParameters.out_PREDEFINED_EXEC,
NSEND_PREDEFINED_PROC: send.outParameters.out_PREDEFINED_PROC NSEND_PREDEFINED_PROC: send.outParameters.out_PREDEFINED_PROC,
SNOTE_HEADER: note.text ? note.header : null,
SNOTE: note.text ? note.text : null
} }
}); });
//Если требуется перезагрузить данные //Если требуется перезагрузить данные