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) => { export const useFilteredPlans = (plans, filter) => {
const filteredPlans = React.useMemo(() => { const filteredPlans = React.useMemo(() => {
return plans.filter(project => project.SDOC_INFO.toLowerCase().includes(filter)); return plans.filter(project => project.SDOC_INFO.toLowerCase().includes(filter));

View File

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