WEB APP: Панель "Производственная программа" - рефакторинг имён констант и компонентов, удаление лишних стилей и лишней вёрстки, расстановка комментов по регламенту, удалён isArray для типовых структурных элементов ("XGANTT_TASKS"), удалена лишняя консольная выдача

This commit is contained in:
Mikhail Chechnev 2024-02-08 14:52:16 +03:00
parent afa14d8c89
commit 92d3371b4d
2 changed files with 58 additions and 67 deletions

View File

@ -1,5 +1,19 @@
import React from "react";
/*
Парус 8 - Панели мониторинга - ПУП - Производственная программа
Кастомные хуки
*/
//---------------------
//Подключение библиотек
//---------------------
import React from "react"; //Классы React
//-----------
//Тело модуля
//-----------
//Клиентский отбор загруженных планов по поисковой фразе
export const useFilteredPlans = (plans, filter) => {
const filteredPlans = React.useMemo(() => {
return plans.filter(project => project.SDOC_INFO.toLowerCase().includes(filter));

View File

@ -31,32 +31,50 @@ const GANTT_WIDTH = "98vw";
//Стили
const STYLES = {
PROJECTS_FINDER: { marginTop: "10px", marginLeft: "10px", width: "93%" },
PROJECTS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
PROJECTS_LIST_ITEM_SECONDARY: { wordWrap: "break-word", fontSize: "0.5rem", textTransform: "uppercase" },
PROJECTS_LIST_ITEM_SECONDARY_NOJOBS: { color: "red" },
PROJECTS_LIST_ITEM_SECONDARY_NOEDIT: { color: "gray" },
PROJECTS_LIST_ITEM_SECONDARY_CHANGED: { color: "green" },
PROJECTS_BUTTON: { position: "absolute" },
PROJECTS_DRAWER: {
PLANS_FINDER: { marginTop: "10px", marginLeft: "10px", width: "93%" },
PLANS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
PLANS_BUTTON: { position: "absolute" },
PLANS_DRAWER: {
minWidth: "250px",
display: "inline-block",
flexShrink: 0,
[`& .MuiDrawer-paper`]: { minWidth: "250px", display: "inline-block", boxSizing: "border-box" }
},
GANTT_CONTAINER: { height: GANTT_HEIGHT, width: GANTT_WIDTH },
GANTT_TITLE: { paddingLeft: "100px", paddingRight: "120px" },
PERIODS_BUTTON: { position: "absolute", right: "20px" },
PERIODS_DRAWER: { width: "1000px", flexShrink: 0, [`& .MuiDrawer-paper`]: { width: "1000px", boxSizing: "border-box" } }
GANTT_TITLE: { paddingLeft: "100px", paddingRight: "120px" }
};
//Список проектов
const ProjectsList = ({ plans = [], selectedPlan, filter, setFilter, onClick } = {}) => {
//------------------------------------
//Вспомогательные функции и компоненты
//------------------------------------
//Разбор XML с данными спецификации производственной программы
const parseProdPlanSpXML = xmlDoc => {
return new Promise((resolve, reject) => {
try {
const parser = new XMLParser({
ignoreDeclaration: true,
ignoreAttributes: false,
parseAttributeValue: true,
attributeNamePrefix: "",
attributeValueProcessor: (name, val) =>
name == "numb" ? undefined : ["start", "end"].includes(name) ? formatDateJSONDateOnly(val) : val
});
const data = parser.parse(xmlDoc);
resolve(data.XDATA);
} catch (e) {
reject(e);
}
});
};
//Список планов
const PlansList = ({ plans = [], selectedPlan, filter, setFilter, onClick } = {}) => {
//Генерация содержимого
return (
<div>
<TextField
sx={STYLES.PROJECTS_FINDER}
sx={STYLES.PLANS_FINDER}
name="planFilter"
label="План"
value={filter}
@ -69,21 +87,7 @@ const ProjectsList = ({ plans = [], selectedPlan, filter, setFilter, onClick } =
<List>
{plans.map(p => (
<ListItemButton key={p.NRN} selected={p.NRN === selectedPlan} onClick={() => (onClick ? onClick(p) : null)}>
<ListItemText
primary={<Typography sx={STYLES.PROJECTS_LIST_ITEM_PRIMARY}>{p.SDOC_INFO}</Typography>}
secondary={
<Typography
sx={{
...STYLES.PROJECTS_LIST_ITEM_SECONDARY,
...(p.NJOBS == 0
? STYLES.PROJECTS_LIST_ITEM_SECONDARY_NOJOBS
: p.NCHANGED == 1
? STYLES.PROJECTS_LIST_ITEM_SECONDARY_CHANGED
: STYLES.PROJECTS_LIST_ITEM_SECONDARY_NOEDIT)
}}
></Typography>
}
/>
<ListItemText primary={<Typography sx={STYLES.PLANS_LIST_ITEM_PRIMARY}>{p.SDOC_INFO}</Typography>} />
</ListItemButton>
))}
</List>
@ -91,8 +95,8 @@ const ProjectsList = ({ plans = [], selectedPlan, filter, setFilter, onClick } =
);
};
//Контроль свойств - Список проектов
ProjectsList.propTypes = {
//Контроль свойств - Список планов
PlansList.propTypes = {
plans: PropTypes.array,
selectedPlan: PropTypes.number,
onClick: PropTypes.func,
@ -104,26 +108,6 @@ ProjectsList.propTypes = {
//Тело модуля
//-----------
//Разбор XML
const parseXML = (xmlDoc, attributeValueProcessor) => {
return new Promise((resolve, reject) => {
try {
let opts = {
ignoreDeclaration: true,
ignoreAttributes: false,
parseAttributeValue: true,
attributeNamePrefix: ""
};
if (attributeValueProcessor) opts.attributeValueProcessor = attributeValueProcessor;
const parser = new XMLParser(opts);
const data = parser.parse(xmlDoc);
resolve(data.XDATA);
} catch (e) {
reject(e);
}
});
};
//Корневая панель производственной программы
const MechRecCostProdPlans = () => {
//Собственное состояние
@ -160,14 +144,10 @@ const MechRecCostProdPlans = () => {
const data = await executeStored({
stored: "PKG_P8PANELS_MECHREC.PRODPLAN_INIT",
args: {},
respArg: "COUT"
respArg: "COUT",
isArray: name => name === "XFCPRODPLANS"
});
setState(pv => ({
...pv,
init: true,
plans: [...(data?.XFCPRODPLANS || [])],
plansLoaded: true
}));
setState(pv => ({ ...pv, init: true, plans: [...(data?.XFCPRODPLANS || [])], plansLoaded: true }));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [state.init, executeStored]);
@ -208,11 +188,7 @@ const MechRecCostProdPlans = () => {
stored: "PKG_P8PANELS_MECHREC.FCPRODPLANSP_GET",
args: { NFCPRODPLAN: state.selectedPlan, NLEVEL: level }
});
let doc = await parseXML(data.COUT, (name, val) =>
name == "numb" ? undefined : ["start", "end"].includes(name) ? formatDateJSONDateOnly(val) : val
);
console.log(doc.XGANTT_DEF);
console.log(doc.XGANTT_TASKS);
let doc = await parseProdPlanSpXML(data.COUT);
setState(pv => ({
...pv,
selectedPlanMaxLevel: data.NMAX_LEVEL,
@ -256,19 +232,20 @@ const MechRecCostProdPlans = () => {
loadPlanSpecs(selectedLevel);
setState(pv => ({ ...pv, selectedPlanLevel: selectedLevel }));
};
//Генерация содержимого
return (
<Box p={2}>
<Fab variant="extended" sx={STYLES.PROJECTS_BUTTON} onClick={() => setState(pv => ({ ...pv, showPlanList: !pv.showPlanList }))}>
<Fab variant="extended" sx={STYLES.PLANS_BUTTON} onClick={() => setState(pv => ({ ...pv, showPlanList: !pv.showPlanList }))}>
Планы
</Fab>
<Drawer
anchor={"left"}
open={state.showPlanList}
onClose={() => setState(pv => ({ ...pv, showPlanList: false }))}
sx={STYLES.PROJECTS_DRAWER}
sx={STYLES.PLANS_DRAWER}
>
<ProjectsList
<PlansList
plans={filteredPlans}
selectedPlan={state.selectedPlan}
filter={filter}