WEB APP: P8PDataGrid и applicationReducer отвязаны от использования глобальных объектов, исправлена ошибка с неподдерживаемым тегом "nowrap"

This commit is contained in:
Mikhail Chechnev 2023-09-25 16:35:27 +03:00
parent ce455e485b
commit 746f8a1e23
9 changed files with 57 additions and 33 deletions

View File

@ -9,7 +9,6 @@
import React, { useState } from "react"; //Классы React import React, { useState } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента import PropTypes from "prop-types"; //Контроль свойств компонента
import { deepCopyObject } from "../core/utils"; //Вспомогательные процедуры и функции
import { P8PTable, P8P_TABLE_SIZE, P8P_TABLE_DATA_TYPE, P8P_TABLE_FILTER_SHAPE } from "./p8p_table"; //Таблица import { P8PTable, P8P_TABLE_SIZE, P8P_TABLE_DATA_TYPE, P8P_TABLE_FILTER_SHAPE } from "./p8p_table"; //Таблица
//--------- //---------
@ -55,7 +54,8 @@ const P8PDataGrid = ({
valueFormatter, valueFormatter,
onOrderChanged, onOrderChanged,
onFilterChanged, onFilterChanged,
onPagesCountChanged onPagesCountChanged,
objectsCopier
}) => { }) => {
//Собственное состояние - сортировки //Собственное состояние - сортировки
const [orders, setOrders] = useState([]); const [orders, setOrders] = useState([]);
@ -65,7 +65,7 @@ const P8PDataGrid = ({
//При изменении состояния сортировки //При изменении состояния сортировки
const handleOrderChanged = ({ columnName, direction }) => { const handleOrderChanged = ({ columnName, direction }) => {
let newOrders = deepCopyObject(orders); let newOrders = objectsCopier(orders);
const curOrder = newOrders.find(o => o.name == columnName); const curOrder = newOrders.find(o => o.name == columnName);
if (direction == null && curOrder) newOrders.splice(newOrders.indexOf(curOrder), 1); if (direction == null && curOrder) newOrders.splice(newOrders.indexOf(curOrder), 1);
if (direction != null && !curOrder) newOrders.push({ name: columnName, direction }); if (direction != null && !curOrder) newOrders.push({ name: columnName, direction });
@ -76,7 +76,7 @@ const P8PDataGrid = ({
//При изменении состояния фильтра //При изменении состояния фильтра
const handleFilterChanged = ({ columnName, from, to }) => { const handleFilterChanged = ({ columnName, from, to }) => {
let newFilters = deepCopyObject(filters); let newFilters = objectsCopier(filters);
let curFilter = newFilters.find(f => f.name == columnName); let curFilter = newFilters.find(f => f.name == columnName);
if (from == null && to == null && curFilter) newFilters.splice(newFilters.indexOf(curFilter), 1); if (from == null && to == null && curFilter) newFilters.splice(newFilters.indexOf(curFilter), 1);
if ((from != null || to != null) && !curFilter) newFilters.push({ name: columnName, from, to }); if ((from != null || to != null) && !curFilter) newFilters.push({ name: columnName, from, to });
@ -152,7 +152,8 @@ P8PDataGrid.propTypes = {
valueFormatter: PropTypes.func, valueFormatter: PropTypes.func,
onOrderChanged: PropTypes.func, onOrderChanged: PropTypes.func,
onFilterChanged: PropTypes.func, onFilterChanged: PropTypes.func,
onPagesCountChanged: PropTypes.func onPagesCountChanged: PropTypes.func,
objectsCopier: PropTypes.func.isRequired
}; };
//---------------- //----------------

View File

@ -35,7 +35,7 @@ export const ApplicationСtx = createContext();
//Провайдер контекста приложения //Провайдер контекста приложения
export const ApplicationContext = ({ errors, displaySizeGetter, guidGenerator, children }) => { export const ApplicationContext = ({ errors, displaySizeGetter, guidGenerator, children }) => {
//Подключим редьюсер состояния //Подключим редьюсер состояния
const [state, dispatch] = useReducer(applicationReducer, INITIAL_STATE); const [state, dispatch] = useReducer(applicationReducer, INITIAL_STATE(displaySizeGetter));
//Подключение к контексту взаимодействия с сервером //Подключение к контексту взаимодействия с сервером
const { getConfig, getRespPayload } = useContext(BackEndСtx); const { getConfig, getRespPayload } = useContext(BackEndСtx);

View File

@ -3,12 +3,6 @@
Контекст: Приложение - редьюсер состояния Контекст: Приложение - редьюсер состояния
*/ */
//---------------------
//Подключение библиотек
//---------------------
import { getDisplaySize } from "../core/utils"; //Вспомогательные функции
//--------- //---------
//Константы //Константы
//--------- //---------
@ -21,12 +15,12 @@ const APP_AT = {
}; };
//Состояние приложения по умолчанию //Состояние приложения по умолчанию
const INITIAL_STATE = { const INITIAL_STATE = displaySizeGetter => ({
displaySize: getDisplaySize(), displaySize: displaySizeGetter(),
panels: [], panels: [],
panelsLoaded: false, panelsLoaded: false,
initialized: false initialized: false
}; });
//----------- //-----------
//Тело модуля //Тело модуля

View File

@ -12,7 +12,29 @@ import PropTypes from "prop-types"; //Контроль свойств компо
import { P8PAppProgress } from "../components/p8p_app_progress"; //Индикатор процесса import { P8PAppProgress } from "../components/p8p_app_progress"; //Индикатор процесса
import { P8PAppMessage } from "../components/p8p_app_message"; //Диалог сообщения import { P8PAppMessage } from "../components/p8p_app_message"; //Диалог сообщения
import { MSG_AT, MSG_DLGT, INITIAL_STATE, messagingReducer } from "./messaging_reducer"; //Редьюсер состояния import { MSG_AT, MSG_DLGT, INITIAL_STATE, messagingReducer } from "./messaging_reducer"; //Редьюсер состояния
import { TITLES, TEXTS, BUTTONS } from "../../app.text"; //Текстовые ресурсы и константы
//---------
//Константы
//---------
//Структура объекта с описанием типовых заголовков
const MESSAGING_CONTEXT_TITLES_SHAPE = PropTypes.shape({
ERR: PropTypes.string.isRequired,
WARN: PropTypes.string.isRequired,
INFO: PropTypes.string.isRequired
});
//Структура объекта с описанием типовых текстов
const MESSAGING_CONTEXT_TEXTS_SHAPE = PropTypes.shape({
LOADING: PropTypes.string.isRequired
});
//Структура объекта с описанием типовых кнопок
const MESSAGING_CONTEXT_BUTTONS_SHAPE = PropTypes.shape({
CLOSE: PropTypes.string.isRequired,
OK: PropTypes.string.isRequired,
CANCEL: PropTypes.string.isRequired
});
//---------------- //----------------
//Интерфейс модуля //Интерфейс модуля
@ -22,7 +44,7 @@ import { TITLES, TEXTS, BUTTONS } from "../../app.text"; //Текстовые р
export const MessagingСtx = createContext(); export const MessagingСtx = createContext();
//Провайдер контекста сообщений //Провайдер контекста сообщений
export const MessagingContext = ({ children }) => { export const MessagingContext = ({ titles, texts, buttons, children }) => {
//Подключим редьюсер состояния //Подключим редьюсер состояния
const [state, dispatch] = useReducer(messagingReducer, INITIAL_STATE); const [state, dispatch] = useReducer(messagingReducer, INITIAL_STATE);
@ -82,20 +104,20 @@ export const MessagingContext = ({ children }) => {
msgState: state msgState: state
}} }}
> >
{state.loading ? <P8PAppProgress open={true} text={state.loadingMessage || TEXTS.LOADING} /> : null} {state.loading ? <P8PAppProgress open={true} text={state.loadingMessage || texts.LOADING} /> : null}
{state.msg ? ( {state.msg ? (
<P8PAppMessage <P8PAppMessage
open={true} open={true}
variant={state.msgType} variant={state.msgType}
text={state.msgText} text={state.msgText}
title title
titleText={state.msgType == MSG_DLGT.ERR ? TITLES.ERR : state.msgType == MSG_DLGT.WARN ? TITLES.WARN : TITLES.INFO} titleText={state.msgType == MSG_DLGT.ERR ? titles.ERR : state.msgType == MSG_DLGT.WARN ? titles.WARN : titles.INFO}
okBtn={true} okBtn={true}
onOk={handleMessageOkClick} onOk={handleMessageOkClick}
okBtnCaption={[MSG_DLGT.ERR, MSG_DLGT.INFO].includes(state.msgType) ? BUTTONS.CLOSE : BUTTONS.OK} okBtnCaption={[MSG_DLGT.ERR, MSG_DLGT.INFO].includes(state.msgType) ? buttons.CLOSE : buttons.OK}
cancelBtn={state.msgType == MSG_DLGT.WARN} cancelBtn={state.msgType == MSG_DLGT.WARN}
onCancel={handleMessageCancelClick} onCancel={handleMessageCancelClick}
cancelBtnCaption={BUTTONS.CANCEL} cancelBtnCaption={buttons.CANCEL}
/> />
) : null} ) : null}
{children} {children}
@ -105,5 +127,8 @@ export const MessagingContext = ({ children }) => {
//Контроль свойств - Провайдер контекста сообщений //Контроль свойств - Провайдер контекста сообщений
MessagingContext.propTypes = { MessagingContext.propTypes = {
titles: MESSAGING_CONTEXT_TITLES_SHAPE,
texts: MESSAGING_CONTEXT_TEXTS_SHAPE,
buttons: MESSAGING_CONTEXT_BUTTONS_SHAPE,
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]) children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node])
}; };

View File

@ -10,7 +10,7 @@
import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента import PropTypes from "prop-types"; //Контроль свойств компонента
import { Grid, Icon, Stack, Link, Button, Table, TableBody, TableRow, TableCell, Typography, Box, Paper, IconButton } from "@mui/material"; //Интерфейсные компоненты import { Grid, Icon, Stack, Link, Button, Table, TableBody, TableRow, TableCell, Typography, Box, Paper, IconButton } from "@mui/material"; //Интерфейсные компоненты
import { hasValue, formatDateRF, formatNumberRFCurrency, object2Base64XML } from "../../core/utils"; //Вспомогательные процедуры и функции import { deepCopyObject, hasValue, formatDateRF, formatNumberRFCurrency, object2Base64XML } from "../../core/utils"; //Вспомогательные процедуры и функции
import { BUTTONS, TEXTS, INPUTS } from "../../../app.text"; //Тектовые ресурсы и константы import { BUTTONS, TEXTS, INPUTS } from "../../../app.text"; //Тектовые ресурсы и константы
import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
@ -163,8 +163,8 @@ const rowExpandRender = ({ columnsDef, row }, pOnlineShowDocument, showProjectPa
{cardColumns.map((cardColumn, i) => ( {cardColumns.map((cardColumn, i) => (
<TableRow key={i}> <TableRow key={i}>
<TableCell sx={{ width: "1px", whiteSpace: "nowrap" }}> <TableCell sx={{ width: "1px", whiteSpace: "nowrap" }}>
<Typography variant="h6" color="primary"> <Typography variant="h6" color="primary" noWrap>
<nowrap>{cardColumn.caption}:</nowrap> {cardColumn.caption}:
</Typography> </Typography>
</TableCell> </TableCell>
<TableCell sx={{ paddingLeft: 0 }}> <TableCell sx={{ paddingLeft: 0 }}>
@ -321,6 +321,7 @@ const Projects = ({ onStagesOpen }) => {
onOrderChanged={handleOrderChanged} onOrderChanged={handleOrderChanged}
onFilterChanged={handleFilterChanged} onFilterChanged={handleFilterChanged}
onPagesCountChanged={handlePagesCountChanged} onPagesCountChanged={handlePagesCountChanged}
objectsCopier={deepCopyObject}
/> />
) : null} ) : null}
</> </>

View File

@ -10,7 +10,7 @@
import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента import PropTypes from "prop-types"; //Контроль свойств компонента
import { Box, Icon, Stack, Link } from "@mui/material"; //Интерфейсные компоненты import { Box, Icon, Stack, Link } from "@mui/material"; //Интерфейсные компоненты
import { hasValue, formatNumberRFCurrency, object2Base64XML } from "../../core/utils"; //Вспомогательные процедуры и функции import { deepCopyObject, hasValue, formatNumberRFCurrency, object2Base64XML } from "../../core/utils"; //Вспомогательные процедуры и функции
import { BUTTONS, TEXTS, INPUTS } from "../../../app.text"; //Тектовые ресурсы и константы import { BUTTONS, TEXTS, INPUTS } from "../../../app.text"; //Тектовые ресурсы и константы
import { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_FILTER_SHAPE } from "../../components/p8p_data_grid"; //Таблица данных import { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_FILTER_SHAPE } from "../../components/p8p_data_grid"; //Таблица данных
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
@ -182,6 +182,7 @@ const StageArts = ({ stage, filters }) => {
dataCellRender={prms => dataCellRender(prms, showStageArtCostNotes, showStageArtContracts)} dataCellRender={prms => dataCellRender(prms, showStageArtCostNotes, showStageArtContracts)}
valueFormatter={valueFormatter} valueFormatter={valueFormatter}
onFilterChanged={handleFilterChanged} onFilterChanged={handleFilterChanged}
objectsCopier={deepCopyObject}
/> />
) : null} ) : null}
</Box> </Box>

View File

@ -10,7 +10,7 @@
import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента import PropTypes from "prop-types"; //Контроль свойств компонента
import { Box, Stack, Grid, Paper, Table, TableBody, TableRow, TableCell, Typography, Button, Link } from "@mui/material"; //Интерфейсные компоненты import { Box, Stack, Grid, Paper, Table, TableBody, TableRow, TableCell, Typography, Button, Link } from "@mui/material"; //Интерфейсные компоненты
import { hasValue, formatDateRF, formatNumberRFCurrency, object2Base64XML } from "../../core/utils"; //Вспомогательные процедуры и функции import { deepCopyObject, hasValue, formatDateRF, formatNumberRFCurrency, object2Base64XML } from "../../core/utils"; //Вспомогательные процедуры и функции
import { BUTTONS, TEXTS, INPUTS } from "../../../app.text"; //Тектовые ресурсы и константы import { BUTTONS, TEXTS, INPUTS } from "../../../app.text"; //Тектовые ресурсы и константы
import { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_FILTER_SHAPE } from "../../components/p8p_data_grid"; //Таблица данных import { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_FILTER_SHAPE } from "../../components/p8p_data_grid"; //Таблица данных
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
@ -93,8 +93,8 @@ const rowExpandRender = ({ columnsDef, row }, pOnlineShowDocument) => {
{cardColumns.map((cardColumn, i) => ( {cardColumns.map((cardColumn, i) => (
<TableRow key={i}> <TableRow key={i}>
<TableCell sx={{ width: "1px", whiteSpace: "nowrap" }}> <TableCell sx={{ width: "1px", whiteSpace: "nowrap" }}>
<Typography variant="h6" color="primary"> <Typography variant="h6" color="primary" noWrap>
{cardColumn.caption}:&nbsp; {cardColumn.caption}:
</Typography> </Typography>
</TableCell> </TableCell>
<TableCell sx={{ paddingLeft: 0 }}> <TableCell sx={{ paddingLeft: 0 }}>
@ -237,6 +237,7 @@ const StageContracts = ({ stage, filters }) => {
onOrderChanged={handleOrderChanged} onOrderChanged={handleOrderChanged}
onFilterChanged={handleFilterChanged} onFilterChanged={handleFilterChanged}
onPagesCountChanged={handlePagesCountChanged} onPagesCountChanged={handlePagesCountChanged}
objectsCopier={deepCopyObject}
/> />
) : null} ) : null}
</Box> </Box>

View File

@ -10,7 +10,7 @@
import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента import PropTypes from "prop-types"; //Контроль свойств компонента
import { Box, Icon, Stack, Grid, Paper, Table, TableBody, TableRow, TableCell, Typography, Button, IconButton, Link } from "@mui/material"; //Интерфейсные компоненты import { Box, Icon, Stack, Grid, Paper, Table, TableBody, TableRow, TableCell, Typography, Button, IconButton, Link } from "@mui/material"; //Интерфейсные компоненты
import { hasValue, formatDateRF, formatNumberRFCurrency, object2Base64XML } from "../../core/utils"; //Вспомогательные процедуры и функции import { deepCopyObject, hasValue, formatDateRF, formatNumberRFCurrency, object2Base64XML } from "../../core/utils"; //Вспомогательные процедуры и функции
import { BUTTONS, TEXTS, INPUTS } from "../../../app.text"; //Тектовые ресурсы и константы import { BUTTONS, TEXTS, INPUTS } from "../../../app.text"; //Тектовые ресурсы и константы
import { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_FILTER_SHAPE } from "../../components/p8p_data_grid"; //Таблица данных import { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_FILTER_SHAPE } from "../../components/p8p_data_grid"; //Таблица данных
import { P8PFullScreenDialog } from "../../components/p8p_fullscreen_dialog"; //Полноэкранный диалог import { P8PFullScreenDialog } from "../../components/p8p_fullscreen_dialog"; //Полноэкранный диалог
@ -178,8 +178,8 @@ const rowExpandRender = ({ columnsDef, row }, pOnlineShowDocument, showStageArts
{cardColumns.map((cardColumn, i) => ( {cardColumns.map((cardColumn, i) => (
<TableRow key={i}> <TableRow key={i}>
<TableCell sx={{ width: "1px", whiteSpace: "nowrap" }}> <TableCell sx={{ width: "1px", whiteSpace: "nowrap" }}>
<Typography variant="h6" color="primary"> <Typography variant="h6" color="primary" noWrap>
{cardColumn.caption}:&nbsp; {cardColumn.caption}:
</Typography> </Typography>
</TableCell> </TableCell>
<TableCell sx={{ paddingLeft: 0 }}> <TableCell sx={{ paddingLeft: 0 }}>
@ -372,6 +372,7 @@ const Stages = ({ project, projectName, filters }) => {
onOrderChanged={handleOrderChanged} onOrderChanged={handleOrderChanged}
onFilterChanged={handleFilterChanged} onFilterChanged={handleFilterChanged}
onPagesCountChanged={handlePagesCountChanged} onPagesCountChanged={handlePagesCountChanged}
objectsCopier={deepCopyObject}
/> />
) : null} ) : null}
{stagesDataGrid.showStageContracts ? ( {stagesDataGrid.showStageContracts ? (

View File

@ -12,7 +12,7 @@ import { MessagingContext } from "./context/messaging"; //Контекст со
import { BackEndContext } from "./context/backend"; //Контекст взаимодействия с сервером import { BackEndContext } from "./context/backend"; //Контекст взаимодействия с сервером
import { ApplicationContext } from "./context/application"; //Контекст приложения import { ApplicationContext } from "./context/application"; //Контекст приложения
import { App } from "./app"; //Приложение import { App } from "./app"; //Приложение
import { ERRORS } from "../app.text"; //Текстовые ресурсы и константы import { ERRORS, TITLES, TEXTS, BUTTONS } from "../app.text"; //Текстовые ресурсы и константы
import { getDisplaySize, genGUID } from "./core/utils"; //Вспомогательные функции import { getDisplaySize, genGUID } from "./core/utils"; //Вспомогательные функции
import client from "./core/client"; //Клиент для взаимодействия с сервером import client from "./core/client"; //Клиент для взаимодействия с сервером
@ -23,7 +23,7 @@ import client from "./core/client"; //Клиент для взаимодейст
//Обёртка для контекста //Обёртка для контекста
const Root = () => { const Root = () => {
return ( return (
<MessagingContext> <MessagingContext titles={TITLES} texts={TEXTS} buttons={BUTTONS}>
<BackEndContext client={client}> <BackEndContext client={client}>
<ApplicationContext errors={ERRORS} displaySizeGetter={getDisplaySize} guidGenerator={genGUID}> <ApplicationContext errors={ERRORS} displaySizeGetter={getDisplaySize} guidGenerator={genGUID}>
<App /> <App />