ЦИТК-802 - Изменения блока выбора каталога

This commit is contained in:
Mikhail Chechnev 2024-02-16 17:33:12 +03:00 committed by GitHub
commit 4ef6940330
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 118 additions and 15 deletions

View File

@ -13,10 +13,14 @@ import React from "react"; //Классы React
//Тело модуля
//-----------
//Клиентский отбор загруженных планов по поисковой фразе
//Клиентский отбор каталогов по поисковой фразе и наличию планов
export const useFilteredPlanCtlgs = (planCtlgs, filter) => {
const filteredPlanCtlgs = React.useMemo(() => {
return planCtlgs.filter(catalog => catalog.SNAME.toString().toLowerCase().includes(filter));
return planCtlgs.filter(
catalog =>
catalog.SNAME.toString().toLowerCase().includes(filter.ctlgName) &&
(filter.haveDocs ? catalog.NCOUNT_DOCS > 0 : catalog.NCOUNT_DOCS >= 0)
);
}, [planCtlgs, filter]);
return filteredPlanCtlgs;

View File

@ -9,7 +9,23 @@
import React, { useContext, useState, useCallback, useEffect } from "react"; //Классы React
import PropTypes from "prop-types"; //Контроль свойств компонента
import { Drawer, Fab, Box, List, ListItemButton, ListItemText, Typography, Grid, TextField, Select, MenuItem, InputLabel } from "@mui/material"; //Интерфейсные элементы
import {
Drawer,
Fab,
Box,
List,
ListItemButton,
ListItemText,
Typography,
Grid,
TextField,
Select,
MenuItem,
InputLabel,
FormGroup,
FormControlLabel,
Checkbox
} from "@mui/material"; //Интерфейсные элементы
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений
import { P8P_GANTT_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
@ -21,6 +37,9 @@ import { useFilteredPlanCtlgs } from "./hooks"; //Вспомогательные
//Константы
//---------
//Склонения для документов
const DECLINATIONS = ["план", "плана", "планов"];
//Поля сортировки
const SORT_REP_DATE = "DREP_DATE";
const SORT_REP_DATE_TO = "DREP_DATE_TO";
@ -34,13 +53,16 @@ const GANTT_WIDTH = "98vw";
//Стили
const STYLES = {
PLANS_FINDER: { marginTop: "10px", marginLeft: "10px", width: "93%" },
PLANS_CHECKBOX_HAVEDOCS: { alignContent: "space-around" },
PLANS_LIST_ITEM_ZERODOCS: { backgroundColor: "#ebecec" },
PLANS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
PLANS_LIST_ITEM_SECONDARY: { wordWrap: "break-word", fontSize: "0.6rem", textTransform: "uppercase" },
PLANS_BUTTON: { position: "absolute" },
PLANS_DRAWER: {
minWidth: "250px",
width: "350px",
display: "inline-block",
flexShrink: 0,
[`& .MuiDrawer-paper`]: { minWidth: "250px", display: "inline-block", boxSizing: "border-box" }
[`& .MuiDrawer-paper`]: { width: "350px", display: "inline-block", boxSizing: "border-box" }
},
GANTT_CONTAINER: { height: GANTT_HEIGHT, width: GANTT_WIDTH },
GANTT_TITLE: { paddingLeft: "100px", paddingRight: "120px" }
@ -59,6 +81,26 @@ const parseProdPlanSpXML = async xmlDoc => {
return data.XDATA;
};
//Форматирование для отображения количества документов
const formatCountDocs = nCountDocs => {
//Получаем последнюю цифру в значении
let num = (nCountDocs % 100) % 10;
//Документов
if (nCountDocs > 10 && nCountDocs < 20) {
return `${nCountDocs} ${DECLINATIONS[2]}`;
}
//Документа
if (num > 1 && num < 5) {
return `${nCountDocs} ${DECLINATIONS[1]}`;
}
//Документ
if (num == 1) {
return `${nCountDocs} ${DECLINATIONS[0]}`;
}
//Документов
return `${nCountDocs} ${DECLINATIONS[2]}`;
};
//Список каталогов планов
const PlanCtlgsList = ({ planCtlgs = [], selectedPlanCtlg, filter, setFilter, onClick } = {}) => {
//Генерация содержимого
@ -67,18 +109,48 @@ const PlanCtlgsList = ({ planCtlgs = [], selectedPlanCtlg, filter, setFilter, on
<TextField
sx={STYLES.PLANS_FINDER}
name="planFilter"
label="План"
value={filter}
label="Каталог"
value={filter.ctlgName}
variant="standard"
fullWidth
onChange={event => {
setFilter(event.target.value);
setFilter(pv => ({ ...pv, ctlgName: event.target.value }));
}}
></TextField>
<FormGroup sx={STYLES.PLANS_CHECKBOX_HAVEDOCS}>
<FormControlLabel
control={
<Checkbox
checked={filter.haveDocs}
onChange={event => {
setFilter(pv => ({ ...pv, haveDocs: event.target.checked }));
}}
/>
}
label="Только с планами"
labelPlacement="end"
/>
</FormGroup>
<List>
{planCtlgs.map(p => (
<ListItemButton key={p.NRN} selected={p.NRN === selectedPlanCtlg} onClick={() => (onClick ? onClick(p) : null)}>
<ListItemText primary={<Typography sx={STYLES.PLANS_LIST_ITEM_PRIMARY}>{p.SNAME}</Typography>} />
<ListItemButton
sx={p.NCOUNT_DOCS == 0 ? STYLES.PLANS_LIST_ITEM_ZERODOCS : null}
key={p.NRN}
selected={p.NRN === selectedPlanCtlg}
onClick={() => (onClick ? onClick(p) : null)}
>
<ListItemText
primary={<Typography sx={STYLES.PLANS_LIST_ITEM_PRIMARY}>{p.SNAME}</Typography>}
secondary={
<Typography
sx={{
...STYLES.PLANS_LIST_ITEM_SECONDARY
}}
>
{formatCountDocs(p.NCOUNT_DOCS)}
</Typography>
}
/>
</ListItemButton>
))}
</List>
@ -116,9 +188,10 @@ const MechRecCostProdPlans = () => {
selectedPlanCtlgGanttDef: {},
selectedPlanCtlgSpecs: []
});
//Состояние для фильтра каталогов
const [filter, setFilter] = useState({ ctlgName: "", haveLinks: false });
const [filter, setFilter] = useState("");
//Массив отфильтрованных каталогов
const filteredPlanCtgls = useFilteredPlanCtlgs(state.planCtlgs, filter);
//Подключение к контексту сообщений

View File

@ -207,8 +207,8 @@ create or replace package body PKG_P8PANELS_MECHREC as
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
/* Значения спецификации */
NTASK_RN PKG_STD.TREF; -- Рег. номер спецификации
NTASK_PRN PKG_STD.TREF; -- Рег. номер родителя спецификации
NTASK_RN PKG_STD.TREF; -- Рег. номер спецификации
NTASK_PRN PKG_STD.TREF; -- Рег. номер родителя спецификации
STASK_PROD_ORDER PKG_STD.TSTRING; -- Заказ
DTASK_REP_DATE PKG_STD.TLDATE; -- Дата запуска
DTASK_REP_DATE_TO PKG_STD.TLDATE; -- Дата выпуска
@ -557,7 +557,32 @@ create or replace package body PKG_P8PANELS_MECHREC as
PKG_XFAST.DOWN_NODE(SNAME => 'XDATA');
/* Цикл по планам и отчетам производства изделий */
for REC in (select T.RN as NRN,
T.NAME as SNAME
T.NAME as SNAME,
(select count(P.RN)
from FCPRODPLAN P,
FINSTATE FS
where P.CRN = T.RN
and P.CATEGORY = NFCPRODPLAN_CATEGORY
and P.STATUS = NFCPRODPLAN_STATUS
and FS.RN = P.TYPE
and FS.CODE = SFCPRODPLAN_TYPE
and exists
(select /*+ INDEX(UP I_USERPRIV_JUR_PERS_ROLEID) */
null
from USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'CostProductPlans'
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_JUR_PERS_AUTHID) */
null
from USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'CostProductPlans'
and UP.AUTHID = UTILIZER)) as NCOUNT_DOCS
from ACATALOG T,
UNITLIST UL
where T.DOCNAME = 'CostProductPlans'
@ -577,6 +602,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
/* Описываем план */
PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => REC.NRN);
PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => REC.SNAME);
PKG_XFAST.ATTR(SNAME => 'NCOUNT_DOCS', NVALUE => REC.NCOUNT_DOCS);
/* Закрываем план */
PKG_XFAST.UP();
end loop;