forked from CITKParus/P8-Panels
WEB APP: Панель "Работы проектов" - отображение параметров инициализации панели и диалог переформирования
This commit is contained in:
parent
f31030cbc5
commit
761237c110
@ -9,13 +9,34 @@
|
|||||||
|
|
||||||
import React, { useContext, useState, useCallback, useEffect } from "react"; //Классы React
|
import React, { useContext, useState, useCallback, useEffect } from "react"; //Классы React
|
||||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
import PropTypes from "prop-types"; //Контроль свойств компонента
|
||||||
import { Drawer, Fab, Box, Grid, List, ListItemButton, ListItemText, ListItemIcon, Icon, Typography } from "@mui/material"; //Интерфейсные элементы
|
import {
|
||||||
|
Drawer,
|
||||||
|
Fab,
|
||||||
|
Box,
|
||||||
|
Grid,
|
||||||
|
List,
|
||||||
|
ListItemButton,
|
||||||
|
ListItemText,
|
||||||
|
ListItemIcon,
|
||||||
|
Icon,
|
||||||
|
Typography,
|
||||||
|
Divider,
|
||||||
|
ListItem,
|
||||||
|
Button,
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions,
|
||||||
|
TextField,
|
||||||
|
DialogTitle
|
||||||
|
} from "@mui/material"; //Интерфейсные элементы
|
||||||
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
|
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
|
||||||
import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений
|
import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений
|
||||||
import { ApplicationСtx } from "../../context/application"; //Контекст приложения
|
import { ApplicationСtx } from "../../context/application"; //Контекст приложения
|
||||||
import { formatDateJSONDateOnly } from "../../core/utils"; //Вспомогательные функции
|
import { formatDateJSONDateOnly } from "../../core/utils"; //Вспомогательные функции
|
||||||
import { P8P_GANTT_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
|
import { P8P_GANTT_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
|
||||||
import { P8PGantt } from "../../components/p8p_gantt"; //Диаграмма Ганта
|
import { P8PGantt } from "../../components/p8p_gantt"; //Диаграмма Ганта
|
||||||
|
import { formatDateRF } from "../../core/utils"; //Вспомогательные функции
|
||||||
|
import { BUTTONS } from "../../../app.text"; //Текстовые ресурсы и константы
|
||||||
import { ResMon } from "./res_mon"; //Монитор ресурсов
|
import { ResMon } from "./res_mon"; //Монитор ресурсов
|
||||||
import { taskAttributeRenderer } from "./layouts"; //Дополнительная разметка и вёрстка клиентских элементов
|
import { taskAttributeRenderer } from "./layouts"; //Дополнительная разметка и вёрстка клиентских элементов
|
||||||
|
|
||||||
@ -31,7 +52,6 @@ const GANTT_WIDTH = "98vw";
|
|||||||
|
|
||||||
//Стили
|
//Стили
|
||||||
const STYLES = {
|
const STYLES = {
|
||||||
PROJECTS_LIST_SAVE_BUTTON: { backgroundColor: "orange" },
|
|
||||||
PROJECTS_LIST_ITEM_NOJOBS: { backgroundColor: "#ff000045" },
|
PROJECTS_LIST_ITEM_NOJOBS: { backgroundColor: "#ff000045" },
|
||||||
PROJECTS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
|
PROJECTS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
|
||||||
PROJECTS_LIST_ITEM_SECONDARY: { wordWrap: "break-word", fontSize: "0.5rem", textTransform: "uppercase" },
|
PROJECTS_LIST_ITEM_SECONDARY: { wordWrap: "break-word", fontSize: "0.5rem", textTransform: "uppercase" },
|
||||||
@ -46,10 +66,77 @@ const STYLES = {
|
|||||||
PERIODS_DRAWER: { width: "1200px", flexShrink: 0, [`& .MuiDrawer-paper`]: { width: "1200px", boxSizing: "border-box" } }
|
PERIODS_DRAWER: { width: "1200px", flexShrink: 0, [`& .MuiDrawer-paper`]: { width: "1200px", boxSizing: "border-box" } }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Единицы измерения длительности
|
||||||
|
const DURATION_MEAS = {
|
||||||
|
0: "День",
|
||||||
|
1: "Неделя",
|
||||||
|
2: "Декада",
|
||||||
|
3: "Месяц",
|
||||||
|
4: "Квартал",
|
||||||
|
5: "Год"
|
||||||
|
};
|
||||||
|
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
//Вспомогательные функции и компоненты
|
//Вспомогательные функции и компоненты
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
|
|
||||||
|
//Диалог параметров инициализации панели
|
||||||
|
const InitDialog = ({ dateBegin, dateFact, onOk, onCancel }) => {
|
||||||
|
//Собственное состояние - значения с-по
|
||||||
|
const [values, setValues] = useState({ dateBegin: formatDateJSONDateOnly(dateBegin), dateFact: formatDateJSONDateOnly(dateFact) });
|
||||||
|
|
||||||
|
//Отработка воода значения в фильтр
|
||||||
|
const handleValueTextFieldChanged = e => setValues(prev => ({ ...prev, [e.target.name]: e.target.value }));
|
||||||
|
|
||||||
|
//Генерация содержимого
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
open={true}
|
||||||
|
aria-labelledby="init-dialog-title"
|
||||||
|
aria-describedby="init-dialog-description"
|
||||||
|
onClose={() => (onCancel ? onCancel() : null)}
|
||||||
|
>
|
||||||
|
<DialogTitle>Параметры инициализации</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<TextField
|
||||||
|
style={{ padding: "10px" }}
|
||||||
|
name="dateBegin"
|
||||||
|
type="date"
|
||||||
|
value={values.dateBegin}
|
||||||
|
onChange={handleValueTextFieldChanged}
|
||||||
|
label="Начало (будет использован первый день месяца)"
|
||||||
|
variant="standard"
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
style={{ padding: "10px" }}
|
||||||
|
name="dateFact"
|
||||||
|
type="date"
|
||||||
|
value={values.dateFact}
|
||||||
|
onChange={handleValueTextFieldChanged}
|
||||||
|
label="Факт на (будет использован последний день месяца)"
|
||||||
|
variant="standard"
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => (onOk ? onOk({ dateBegin: new Date(values.dateBegin), dateFact: new Date(values.dateFact) }) : null)}>
|
||||||
|
{BUTTONS.OK}
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => (onCancel ? onCancel() : null)}>{BUTTONS.CANCEL}</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
//Контроль свойств - Диалог параметров инициализации панели
|
||||||
|
InitDialog.propTypes = {
|
||||||
|
dateBegin: PropTypes.instanceOf(Date).isRequired,
|
||||||
|
dateFact: PropTypes.instanceOf(Date).isRequired,
|
||||||
|
onOk: PropTypes.func,
|
||||||
|
onCancel: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
//Список проектов
|
//Список проектов
|
||||||
const ProjectsList = ({ projects = [], selectedProject, onClick } = {}) => {
|
const ProjectsList = ({ projects = [], selectedProject, onClick } = {}) => {
|
||||||
//Подключение к контексту сообщений
|
//Подключение к контексту сообщений
|
||||||
@ -132,7 +219,8 @@ const PrjJobs = () => {
|
|||||||
selectedProject: null,
|
selectedProject: null,
|
||||||
selectedProjectDocRn: null,
|
selectedProjectDocRn: null,
|
||||||
selectedProjectGanttDef: {},
|
selectedProjectGanttDef: {},
|
||||||
selectedProjectTasks: []
|
selectedProjectTasks: [],
|
||||||
|
showInitDialog: false
|
||||||
});
|
});
|
||||||
|
|
||||||
//Подключение к контексту приложения
|
//Подключение к контексту приложения
|
||||||
@ -216,8 +304,8 @@ const PrjJobs = () => {
|
|||||||
const data = await executeStored({
|
const data = await executeStored({
|
||||||
stored: "PKG_P8PANELS_PROJECTS.JB_INIT",
|
stored: "PKG_P8PANELS_PROJECTS.JB_INIT",
|
||||||
args: {
|
args: {
|
||||||
DBEGIN: state.dateBegin ? new Date(state.dateBegin) : null,
|
DBEGIN: state.dateBegin ? state.dateBegin : null,
|
||||||
DFACT: state.dateFact ? new Date(state.dateFact) : null,
|
DFACT: state.dateFact ? state.dateFact : null,
|
||||||
NDURATION_MEAS: state.durationMeas,
|
NDURATION_MEAS: state.durationMeas,
|
||||||
SLAB_MEAS: state.labMeas,
|
SLAB_MEAS: state.labMeas,
|
||||||
NIDENT: state.ident
|
NIDENT: state.ident
|
||||||
@ -226,8 +314,9 @@ const PrjJobs = () => {
|
|||||||
setState(pv => ({
|
setState(pv => ({
|
||||||
...pv,
|
...pv,
|
||||||
init: true,
|
init: true,
|
||||||
dateBegin: data.DBEGIN,
|
reInit: false,
|
||||||
dateFact: data.DFACT,
|
dateBegin: new Date(data.DBEGIN),
|
||||||
|
dateFact: new Date(data.DFACT),
|
||||||
durationMeas: data.NDURATION_MEAS,
|
durationMeas: data.NDURATION_MEAS,
|
||||||
labMeas: data.SLAB_MEAS,
|
labMeas: data.SLAB_MEAS,
|
||||||
resourceStatus: data.NRESOURCE_STATUS,
|
resourceStatus: data.NRESOURCE_STATUS,
|
||||||
@ -246,11 +335,10 @@ const PrjJobs = () => {
|
|||||||
if (state.selectedProject) loadProjectJobs(false);
|
if (state.selectedProject) loadProjectJobs(false);
|
||||||
}, [state.selectedProject, loadProjectJobs]);
|
}, [state.selectedProject, loadProjectJobs]);
|
||||||
|
|
||||||
//При подключении компонента к странице
|
//При изменении флага инициализации
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initJobs();
|
initJobs();
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
}, [state.init, initJobs]);
|
||||||
}, []);
|
|
||||||
|
|
||||||
//Выбор проекта
|
//Выбор проекта
|
||||||
const selectPoject = (project, projectDocRn) => {
|
const selectPoject = (project, projectDocRn) => {
|
||||||
@ -292,6 +380,16 @@ const PrjJobs = () => {
|
|||||||
if (isMain) modifyJob(task.rn, new Date(start), new Date(end), new Date(state.dateBegin), new Date(state.dateFact), state.durationMeas);
|
if (isMain) modifyJob(task.rn, new Date(start), new Date(end), new Date(state.dateBegin), new Date(state.dateFact), state.durationMeas);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Отработка нажатия на отображения диалога параметров инициализации панели
|
||||||
|
const handleShowInitDialogClick = () => setState(pv => ({ ...pv, showInitDialog: true }));
|
||||||
|
|
||||||
|
//Отработка нажатия на "ОК" в диалоге параметров инициализации панели
|
||||||
|
const handleOKInitDialogClick = values =>
|
||||||
|
setState(pv => ({ ...pv, dateBegin: values.dateBegin, dateFact: values.dateFact, showInitDialog: false, init: false }));
|
||||||
|
|
||||||
|
//Отработка нажатия на "Отмена" в диалоге параметров инициализации панели
|
||||||
|
const handleCancelInitDialogClick = () => setState(pv => ({ ...pv, showInitDialog: false }));
|
||||||
|
|
||||||
//Обработка нажатия на сохранение данных в проект
|
//Обработка нажатия на сохранение данных в проект
|
||||||
const handleSaveToProjectsClick = () => saveProjects();
|
const handleSaveToProjectsClick = () => saveProjects();
|
||||||
|
|
||||||
@ -304,6 +402,14 @@ const PrjJobs = () => {
|
|||||||
//Генерация содержимого
|
//Генерация содержимого
|
||||||
return (
|
return (
|
||||||
<Box p={2}>
|
<Box p={2}>
|
||||||
|
{state.showInitDialog ? (
|
||||||
|
<InitDialog
|
||||||
|
dateBegin={state.dateBegin}
|
||||||
|
dateFact={state.dateFact}
|
||||||
|
onOk={handleOKInitDialogClick}
|
||||||
|
onCancel={handleCancelInitDialogClick}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
<Fab variant="extended" sx={STYLES.PROJECTS_BUTTON} onClick={() => setState(pv => ({ ...pv, showProjectsList: !pv.showProjectsList }))}>
|
<Fab variant="extended" sx={STYLES.PROJECTS_BUTTON} onClick={() => setState(pv => ({ ...pv, showProjectsList: !pv.showProjectsList }))}>
|
||||||
Проекты
|
Проекты
|
||||||
{state.needSave ? (
|
{state.needSave ? (
|
||||||
@ -321,15 +427,50 @@ const PrjJobs = () => {
|
|||||||
>
|
>
|
||||||
{state.projectsLoaded ? (
|
{state.projectsLoaded ? (
|
||||||
<>
|
<>
|
||||||
|
<List>
|
||||||
|
<ListItem>
|
||||||
|
<ListItemText
|
||||||
|
secondary={
|
||||||
|
<>
|
||||||
|
<b>Начало: </b>
|
||||||
|
{formatDateRF(state.dateBegin)}
|
||||||
|
<br />
|
||||||
|
<b>Факт на: </b>
|
||||||
|
{formatDateRF(state.dateFact)}
|
||||||
|
<br />
|
||||||
|
<b>Длительность: </b>
|
||||||
|
{DURATION_MEAS[state.durationMeas]}
|
||||||
|
<br />
|
||||||
|
<b>Трудоёмкость: </b>
|
||||||
|
{state.labMeas}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<Button fullWidth variant="contained" startIcon={<Icon>refresh</Icon>} onClick={handleShowInitDialogClick}>
|
||||||
|
Переформировать...
|
||||||
|
</Button>
|
||||||
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
<Divider />
|
||||||
{state.needSave ? (
|
{state.needSave ? (
|
||||||
<List>
|
<>
|
||||||
<ListItemButton sx={STYLES.PROJECTS_LIST_SAVE_BUTTON} onClick={handleSaveToProjectsClick}>
|
<List>
|
||||||
<ListItemIcon>
|
<ListItem>
|
||||||
<Icon>save</Icon>
|
<Button
|
||||||
</ListItemIcon>
|
fullWidth
|
||||||
<ListItemText primary="Сохранить" secondary="Перенсти изменения в проекты" />
|
color="warning"
|
||||||
</ListItemButton>
|
variant="contained"
|
||||||
</List>
|
startIcon={<Icon>save</Icon>}
|
||||||
|
onClick={handleSaveToProjectsClick}
|
||||||
|
>
|
||||||
|
Сохранить
|
||||||
|
</Button>
|
||||||
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
<Divider />
|
||||||
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
<ProjectsList projects={state.projects} selectedProject={state.selectedProject} onClick={handleProjectClick} />
|
<ProjectsList projects={state.projects} selectedProject={state.selectedProject} onClick={handleProjectClick} />
|
||||||
</>
|
</>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user