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 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"; //Таблица
//---------
@ -55,7 +54,8 @@ const P8PDataGrid = ({
valueFormatter,
onOrderChanged,
onFilterChanged,
onPagesCountChanged
onPagesCountChanged,
objectsCopier
}) => {
//Собственное состояние - сортировки
const [orders, setOrders] = useState([]);
@ -65,7 +65,7 @@ const P8PDataGrid = ({
//При изменении состояния сортировки
const handleOrderChanged = ({ columnName, direction }) => {
let newOrders = deepCopyObject(orders);
let newOrders = objectsCopier(orders);
const curOrder = newOrders.find(o => o.name == columnName);
if (direction == null && curOrder) newOrders.splice(newOrders.indexOf(curOrder), 1);
if (direction != null && !curOrder) newOrders.push({ name: columnName, direction });
@ -76,7 +76,7 @@ const P8PDataGrid = ({
//При изменении состояния фильтра
const handleFilterChanged = ({ columnName, from, to }) => {
let newFilters = deepCopyObject(filters);
let newFilters = objectsCopier(filters);
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.push({ name: columnName, from, to });
@ -152,7 +152,8 @@ P8PDataGrid.propTypes = {
valueFormatter: PropTypes.func,
onOrderChanged: 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 }) => {
//Подключим редьюсер состояния
const [state, dispatch] = useReducer(applicationReducer, INITIAL_STATE);
const [state, dispatch] = useReducer(applicationReducer, INITIAL_STATE(displaySizeGetter));
//Подключение к контексту взаимодействия с сервером
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 = {
displaySize: getDisplaySize(),
const INITIAL_STATE = displaySizeGetter => ({
displaySize: displaySizeGetter(),
panels: [],
panelsLoaded: false,
initialized: false
};
});
//-----------
//Тело модуля

View File

@ -12,7 +12,29 @@ import PropTypes from "prop-types"; //Контроль свойств компо
import { P8PAppProgress } from "../components/p8p_app_progress"; //Индикатор процесса
import { P8PAppMessage } from "../components/p8p_app_message"; //Диалог сообщения
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 MessagingContext = ({ children }) => {
export const MessagingContext = ({ titles, texts, buttons, children }) => {
//Подключим редьюсер состояния
const [state, dispatch] = useReducer(messagingReducer, INITIAL_STATE);
@ -82,20 +104,20 @@ export const MessagingContext = ({ children }) => {
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 ? (
<P8PAppMessage
open={true}
variant={state.msgType}
text={state.msgText}
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}
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}
onCancel={handleMessageCancelClick}
cancelBtnCaption={BUTTONS.CANCEL}
cancelBtnCaption={buttons.CANCEL}
/>
) : null}
{children}
@ -105,5 +127,8 @@ export const MessagingContext = ({ children }) => {
//Контроль свойств - Провайдер контекста сообщений
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])
};

View File

@ -10,7 +10,7 @@
import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
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 { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
@ -163,8 +163,8 @@ const rowExpandRender = ({ columnsDef, row }, pOnlineShowDocument, showProjectPa
{cardColumns.map((cardColumn, i) => (
<TableRow key={i}>
<TableCell sx={{ width: "1px", whiteSpace: "nowrap" }}>
<Typography variant="h6" color="primary">
<nowrap>{cardColumn.caption}:</nowrap>
<Typography variant="h6" color="primary" noWrap>
{cardColumn.caption}:
</Typography>
</TableCell>
<TableCell sx={{ paddingLeft: 0 }}>
@ -321,6 +321,7 @@ const Projects = ({ onStagesOpen }) => {
onOrderChanged={handleOrderChanged}
onFilterChanged={handleFilterChanged}
onPagesCountChanged={handlePagesCountChanged}
objectsCopier={deepCopyObject}
/>
) : null}
</>

View File

@ -10,7 +10,7 @@
import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
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 { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_FILTER_SHAPE } from "../../components/p8p_data_grid"; //Таблица данных
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
@ -182,6 +182,7 @@ const StageArts = ({ stage, filters }) => {
dataCellRender={prms => dataCellRender(prms, showStageArtCostNotes, showStageArtContracts)}
valueFormatter={valueFormatter}
onFilterChanged={handleFilterChanged}
objectsCopier={deepCopyObject}
/>
) : null}
</Box>

View File

@ -10,7 +10,7 @@
import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
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 { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_FILTER_SHAPE } from "../../components/p8p_data_grid"; //Таблица данных
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
@ -93,8 +93,8 @@ const rowExpandRender = ({ columnsDef, row }, pOnlineShowDocument) => {
{cardColumns.map((cardColumn, i) => (
<TableRow key={i}>
<TableCell sx={{ width: "1px", whiteSpace: "nowrap" }}>
<Typography variant="h6" color="primary">
{cardColumn.caption}:&nbsp;
<Typography variant="h6" color="primary" noWrap>
{cardColumn.caption}:
</Typography>
</TableCell>
<TableCell sx={{ paddingLeft: 0 }}>
@ -237,6 +237,7 @@ const StageContracts = ({ stage, filters }) => {
onOrderChanged={handleOrderChanged}
onFilterChanged={handleFilterChanged}
onPagesCountChanged={handlePagesCountChanged}
objectsCopier={deepCopyObject}
/>
) : null}
</Box>

View File

@ -10,7 +10,7 @@
import React, { useState, useCallback, useEffect, useContext } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
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 { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_FILTER_SHAPE } from "../../components/p8p_data_grid"; //Таблица данных
import { P8PFullScreenDialog } from "../../components/p8p_fullscreen_dialog"; //Полноэкранный диалог
@ -178,8 +178,8 @@ const rowExpandRender = ({ columnsDef, row }, pOnlineShowDocument, showStageArts
{cardColumns.map((cardColumn, i) => (
<TableRow key={i}>
<TableCell sx={{ width: "1px", whiteSpace: "nowrap" }}>
<Typography variant="h6" color="primary">
{cardColumn.caption}:&nbsp;
<Typography variant="h6" color="primary" noWrap>
{cardColumn.caption}:
</Typography>
</TableCell>
<TableCell sx={{ paddingLeft: 0 }}>
@ -372,6 +372,7 @@ const Stages = ({ project, projectName, filters }) => {
onOrderChanged={handleOrderChanged}
onFilterChanged={handleFilterChanged}
onPagesCountChanged={handlePagesCountChanged}
objectsCopier={deepCopyObject}
/>
) : null}
{stagesDataGrid.showStageContracts ? (

View File

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