Вызов клиенткой процедуры формирования карточки класса оборудования, кнопки вызова процедур загрузки и передачи файлов выгрузки

This commit is contained in:
Mikhail Chechnev 2024-08-08 11:46:03 +03:00
parent acd2b6978e
commit 1cb78fc446
3 changed files with 264 additions and 118 deletions

View File

@ -22,6 +22,7 @@ import {
DS_RN_DEFAULT,
useEquipDataSelectionList,
useEquipDataSelectionClassMachineList,
useEquipDataSelectionClassMachineCard,
useEquipDataSelectionClassMachineFilesList,
useEquipDataSelectionClassMachineModelsList
} from "./admin_tab_hooks"; //Вспомогательные хуки
@ -31,7 +32,13 @@ import {
//---------
//Начальное состояние флагов обновления
const REFRESH_INITIAL = { action: null, dataSelection: null, dataSelectionClassMachine: null, dataSelectionClassMachineFilesList: 0 };
const REFRESH_INITIAL = {
action: null,
dataSelection: null,
dataSelectionClassMachine: null,
dataSelectionClassMachineCard: 0,
dataSelectionClassMachineFilesList: 0
};
//Стили
const STYLES = {
@ -69,6 +76,12 @@ const AdminTab = () => {
//Загрузка классов оборудования выбранной выборки данных
const { equipDataSelectionClassMachineList } = useEquipDataSelectionClassMachineList(equipDataSelection, refresh.dataSelectionClassMachine);
//Загрузка карточки класса оборудования
const { equipDataSelectionClassMachineCard } = useEquipDataSelectionClassMachineCard(
equipDataSelectionClassMachine,
refresh.dataSelectionClassMachineCard
);
//Загрузка файлов класса оборудования
const { equipDataSelectionClassMachineFilesList } = useEquipDataSelectionClassMachineFilesList(
equipDataSelectionClassMachine,
@ -112,9 +125,9 @@ const AdminTab = () => {
const handleAddEquipDataSelectionClassMachine = () => setDialogs(pv => ({ ...pv, dataSelectionClassMachineIU: true }));
//При нажатии на "Удалить класс оборудования"
const handleDeleteEquipDataSelectionClassMachine = async rn => {
await executeStored({ stored: "UDO_PKG_EQUIPDS.CM_DEL", args: { NRN: rn } });
setRefresh(pv => ({ ...pv, dataSelectionClassMachine: rn * 2, action: "DEL" }));
const handleDeleteEquipDataSelectionClassMachine = async equipDSCM => {
await executeStored({ stored: "UDO_PKG_EQUIPDS.CM_DEL", args: { NRN: equipDSCM } });
setRefresh(pv => ({ ...pv, dataSelectionClassMachine: equipDSCM * 2, action: "DEL" }));
setDataSelectionClassMachine(null);
};
@ -142,15 +155,37 @@ const AdminTab = () => {
};
//При нажатии "Сформировать" в списке файлов карточки класса оборудования
const handleMakeEquipDataSelectionClassMachineFiles = (rn, procedure) => {
const handleMakeEquipDataSelectionClassMachineFiles = (equipDSCM, procedure) => {
pOnlineUserProcedure({
code: procedure,
inputParameters: [{ name: "NEQUIPDSCM", value: rn }],
inputParameters: [{ name: "NEQUIPDSCM", value: equipDSCM }],
callBack: res =>
res.success ? setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 })) : null
});
};
//При нажатии "Загрузить на сервер" в списке файлов карточки класса оборудования
const handleUploadEquipDataSelectionClassMachineFiles = async equipDSCM => {
await executeStored({
stored: "UDO_PKG_EQUIPDS.CMFL_UPLOAD",
args: {
NEQUIPDSCM: equipDSCM
}
});
setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 }));
};
//При нажатии "Передать внешней системе" в списке файлов карточки класса оборудования
const handleSendMdEquipDataSelectionClassMachineFiles = async equipDSCM => {
await executeStored({
stored: "UDO_PKG_EQUIPDS.CMFL_SEND_MD",
args: {
NEQUIPDSCM: equipDSCM
}
});
setRefresh(pv => ({ ...pv, dataSelectionClassMachineFilesList: pv.dataSelectionClassMachineFilesList + 1 }));
};
//При изменении списка выборок данных
useEffect(() => {
if (refresh.action == "INS" && refresh.dataSelection) {
@ -209,11 +244,13 @@ const AdminTab = () => {
</Grid>
<Grid item xs={10} hidden={equipDataSelectionClassMachine == null}>
<EquipDataSelectionClassMachineCard
card={{ NRN: equipDataSelectionClassMachine, SUSERPROCS_DATA: "ФормДанВыгрОбучМод" }}
card={equipDataSelectionClassMachineCard}
filesList={equipDataSelectionClassMachineFilesList}
modelsList={equipDataSelectionClassMachineModelsList}
onCardDelete={handleDeleteEquipDataSelectionClassMachine}
onClassMachineFilesMake={handleMakeEquipDataSelectionClassMachineFiles}
onClassMachineFilesUpload={handleUploadEquipDataSelectionClassMachineFiles}
onClassMachineFilesSendMd={handleSendMdEquipDataSelectionClassMachineFiles}
/>
</Grid>
</Grid>

View File

@ -98,6 +98,40 @@ const useEquipDataSelectionClassMachineList = (dataSelection, refresh) => {
return { equipDataSelectionClassMachineList: data, equipDataSelectionClassMachineListIsLoading: isLoading };
};
//Загрузка карточки класса оборудования
const useEquipDataSelectionClassMachineCard = (classMachine, refresh) => {
//Собственное состояние - флаг загрузки
const [isLoading, setLoading] = useState(false);
//Собственное состояние - данные карточки
const [data, setData] = useState({});
//Подключение к контексту взаимодействия с сервером
const { executeStored } = useContext(BackEndСtx);
//Загрузка данных при изменении зависимостей
useEffect(() => {
const loadData = async () => {
try {
setLoading(true);
const data = await executeStored({
stored: "UDO_PKG_EQUIPDS.CM_CARD",
args: { NEQUIPDSCM: classMachine },
respArg: "COUT",
loader: false
});
setData(data.XEQUIPDSCM);
} finally {
setLoading(false);
}
};
if (classMachine) loadData();
}, [classMachine, refresh, executeStored]);
//Вернём данные
return { equipDataSelectionClassMachineCard: data, equipDataSelectionClassMachineCardIsLoading: isLoading };
};
//Загрузка списка файлов класса оборудования
const useEquipDataSelectionClassMachineFilesList = (classMachine, refresh) => {
//Собственное состояние - флаг загрузки
@ -192,6 +226,7 @@ export {
DS_RN_DEFAULT,
useEquipDataSelectionList,
useEquipDataSelectionClassMachineList,
useEquipDataSelectionClassMachineCard,
useEquipDataSelectionClassMachineFilesList,
useEquipDataSelectionClassMachineModelsList
};

View File

@ -84,7 +84,19 @@ const STYLES = {
FL_ML_TABLE: {
height: `200px`,
...SCROLL_STYLES
}
},
EXTRA_CAPTION_BUTTON_CONTAINER: (theme, maxWidth) => ({
borderWidth: "1px",
borderStyle: "solid",
borderColor: theme.palette.grey[400],
maxWidth,
borderRadius: theme.shape.borderRadius,
paddingLeft: "10px",
paddingRight: "10px",
paddingTop: "2px",
paddingBottom: "2px"
}),
EXTRA_CAPTION_BUTTON_TITLE: { whiteSpace: "nowrap", textOverflow: "ellipsis", overflow: "hidden" }
};
//------------------------------------
@ -145,6 +157,78 @@ IUDFormTextField.propTypes = {
dictionary: PropTypes.func
};
//Кнопка с дополнительной подписью
const ExtraCaptionButton = ({ caption, title, subtitle, maxWidth, onClick, theme }) => {
//При нажатии на кнопку
const handleClick = () => (onClick ? onClick() : null);
//Генерация содержимого
return (
<Stack sx={STYLES.EXTRA_CAPTION_BUTTON_CONTAINER(theme, maxWidth)}>
<Button onClick={handleClick}>{caption}</Button>
<Typography variant="caption" color="text.secondary" sx={STYLES.EXTRA_CAPTION_BUTTON_TITLE} title={subtitle}>
<b>{title}</b> {subtitle}
</Typography>
</Stack>
);
};
//Контроль свойств - Кнопка с дополнительной подписью
ExtraCaptionButton.propTypes = {
caption: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
subtitle: PropTypes.string.isRequired,
maxWidth: PropTypes.string,
onClick: PropTypes.func,
theme: PropTypes.object.isRequired
};
//Формирование значения для колонки "Состояние" файла класса оборудования выборки данных
const formatFileStateValue = (theme, value, err) => {
const [text, icon, color] =
value == 0
? ["Зарегистрирован", "app_registration", null]
: value == 1
? ["Загружается на сервер", "file_upload", theme.palette.warning.main]
: value == 2
? ["Успешно загружен на сервер", "dns", theme.palette.primary.main]
: value == 3
? [`Ошибка загрузки на сервер: ${err}`, "error", theme.palette.error.main]
: value == 4
? ["Загружается во внешнюю систему", "cloud_upload", theme.palette.warning.main]
: value == 5
? ["Успешно передан внешней системе", "cloud_done", theme.palette.success.main]
: [`Ошибка передачи внешней системе: ${err}`, "error", theme.palette.error.main];
return (
<Stack direction="row" gap={0.5} alignItems="center" justifyContent="left" color={color}>
<Icon title={text}>{icon}</Icon>
{text}
</Stack>
);
};
//Форматирование колонок таблицы файлов класса оборудования выборки данных
const filesListDataCellRender = ({ row, columnDef, theme }) => {
switch (columnDef.name) {
case "NSTATUS":
return {
cellProps: { align: "left" },
data: formatFileStateValue(theme, row.NSTATUS, row.SERR)
};
}
};
//Форматирование ячеек заголовка таблиц файлов и моделей класса оборудования выборки данных
const classMachineCardTableHeadCellRender = ({ columnDef }) => {
switch (columnDef.name) {
case "NSTATUS":
return {
stackProps: { justifyContent: "left" },
cellProps: { align: "left" }
};
}
};
//-----------
//Тело модуля
//-----------
@ -371,7 +455,15 @@ EquipDataSelectionClassMachineList.propTypes = {
};
//Карточка класса оборудования выборки данных
const EquipDataSelectionClassMachineCard = ({ card, filesList, modelsList, onCardDelete, onClassMachineFilesMake }) => {
const EquipDataSelectionClassMachineCard = ({
card,
filesList,
modelsList,
onCardDelete,
onClassMachineFilesMake,
onClassMachineFilesUpload,
onClassMachineFilesSendMd
}) => {
//Подключаемся к теме
const theme = useTheme();
@ -381,72 +473,98 @@ const EquipDataSelectionClassMachineCard = ({ card, filesList, modelsList, onCar
//При нажатии на "Сформировать" для файлов данных
const handleClassMachineFilesMakeClick = () => (onClassMachineFilesMake ? onClassMachineFilesMake(card.NRN, card.SUSERPROCS_DATA) : null);
//При нажатии на "Загрузить на сервер" для файлов данных
const handleClassMachineFilesUploadClick = () => (onClassMachineFilesUpload ? onClassMachineFilesUpload(card.NRN) : null);
//При нажатии на "Загрузить на сервер" для файлов данных
const handleClassMachineFilesSendMdClick = () => (onClassMachineFilesSendMd ? onClassMachineFilesSendMd(card.NRN) : null);
//Генерация содержимого
return (
<Box p={2} sx={STYLES.EQUIP_DSCM_CARD}>
<Stack spacing={2}>
<Card>
<CardContent>
<Stack spacing={2} direction={"row"} alignItems={"center"}>
<Typography variant="h5" component="div">
Наименование технического объекта
</Typography>
<IconButton onClick={handleCardDeleteClick}>
<Icon>delete</Icon>
</IconButton>
</Stack>
<Typography sx={{ mb: 1.5 }} color="text.secondary">
Состояние: готов к ...
{card.NRN ? (
<Stack spacing={2}>
<Stack spacing={2} direction={"row"} alignItems={"center"}>
<Typography variant="h5" component="div">
{card.SNAME}
</Typography>
<Typography variant="body2">фывафывафва</Typography>
</CardContent>
</Card>
<Card>
<CardContent>
<Stack spacing={2} direction={"row"} alignItems={"center"}>
<Typography variant="h6" component="div">
Файлы данных
</Typography>
<Button onClick={handleClassMachineFilesMakeClick}>Сформировать</Button>
</Stack>
<P8PDataGrid
{...{ ...P8P_DATA_GRID_CONFIG_PROPS }}
containerComponentProps={{
sx: STYLES.FL_ML_TABLE,
elevation: 0
}}
columnsDef={filesList.columnsDef}
rows={filesList.rows}
size={P8P_DATA_GRID_SIZE.SMALL}
morePages={false}
fixedHeader={true}
reloading={false}
headCellRender={filesListHeadCellRender}
dataCellRender={prms => filesListDataCellRender({ ...prms, theme })}
/>
</CardContent>
</Card>
<Card>
<CardContent>
<Typography variant="h6" component="div">
Модели
</Typography>
<P8PDataGrid
{...{ ...P8P_DATA_GRID_CONFIG_PROPS }}
containerComponentProps={{
sx: STYLES.FL_ML_TABLE,
elevation: 0
}}
columnsDef={modelsList.columnsDef}
rows={modelsList.rows}
size={P8P_DATA_GRID_SIZE.SMALL}
morePages={false}
fixedHeader={true}
reloading={false}
/>
</CardContent>
</Card>
</Stack>
<IconButton onClick={handleCardDeleteClick}>
<Icon>delete</Icon>
</IconButton>
</Stack>
<Card elevation={6}>
<CardContent>
<Stack spacing={2} direction={"row"} alignItems={"center"}>
<Typography variant="h6" component="div">
Файлы данных
</Typography>
<ExtraCaptionButton
caption="Сформировать"
title="ПП:"
subtitle={card.SUSERPROCS_DATA}
maxWidth="150px"
onClick={handleClassMachineFilesMakeClick}
theme={theme}
/>
<ExtraCaptionButton
caption="Загрузить на сервер"
title="СО:"
subtitle={card.SEXSSERVICE_UPLOAD}
maxWidth="210px"
onClick={handleClassMachineFilesUploadClick}
theme={theme}
/>
<ExtraCaptionButton
caption="Передать внешней системе"
title="СО:"
subtitle={card.SEXSSERVICE_SEND_MD}
maxWidth="260px"
onClick={handleClassMachineFilesSendMdClick}
theme={theme}
/>
</Stack>
<P8PDataGrid
{...{ ...P8P_DATA_GRID_CONFIG_PROPS }}
containerComponentProps={{
sx: STYLES.FL_ML_TABLE,
elevation: 0
}}
columnsDef={filesList.columnsDef}
rows={filesList.rows}
size={P8P_DATA_GRID_SIZE.SMALL}
morePages={false}
fixedHeader={true}
reloading={false}
headCellRender={classMachineCardTableHeadCellRender}
dataCellRender={prms => filesListDataCellRender({ ...prms, theme })}
/>
</CardContent>
</Card>
<Card elevation={6}>
<CardContent>
<Stack spacing={2} direction={"row"} alignItems={"center"}>
<Typography variant="h6" component="div">
Модели
</Typography>
</Stack>
<P8PDataGrid
{...{ ...P8P_DATA_GRID_CONFIG_PROPS }}
containerComponentProps={{
sx: STYLES.FL_ML_TABLE,
elevation: 0
}}
columnsDef={modelsList.columnsDef}
rows={modelsList.rows}
size={P8P_DATA_GRID_SIZE.SMALL}
morePages={false}
fixedHeader={true}
reloading={false}
headCellRender={classMachineCardTableHeadCellRender}
/>
</CardContent>
</Card>
</Stack>
) : null}
</Box>
);
};
@ -457,53 +575,9 @@ EquipDataSelectionClassMachineCard.propTypes = {
filesList: PropTypes.object.isRequired,
modelsList: PropTypes.object.isRequired,
onCardDelete: PropTypes.func,
onClassMachineFilesMake: PropTypes.func
};
//Формирование значения для колонки "Состояние" проекта
const formatFileStateValue = (theme, value, err) => {
const [text, icon, color] =
value == 0
? ["Зарегистрирован", "app_registration", null]
: value == 1
? ["Загружается на сервер", "file_upload", theme.palette.warning.main]
: value == 2
? ["Успешно загружен на сервер", "dns", theme.palette.primary.main]
: value == 3
? [`Ошибка загрузки на сервер: ${err}`, "error", theme.palette.error.main]
: value == 4
? ["Загружается во внешнюю систему", "cloud_upload", theme.palette.warning.main]
: value == 5
? ["Успешно загружен во внешнюю систему", "cloud_done", theme.palette.success.main]
: [`Ошибка загрузки во внешнюю систему: ${err}`, "error", theme.palette.error.main];
return (
<Stack direction="row" gap={0.5} alignItems="center" justifyContent="left" color={color}>
<Icon title={text}>{icon}</Icon>
{text}
</Stack>
);
};
//Форматирование колонок таблицы файлов класса оборудования выборки данных
const filesListDataCellRender = ({ row, columnDef, theme }) => {
switch (columnDef.name) {
case "NSTATUS":
return {
cellProps: { align: "left" },
data: formatFileStateValue(theme, row.NSTATUS, row.SERR)
};
}
};
//Генерация представления ячейки заголовка
const filesListHeadCellRender = ({ columnDef }) => {
switch (columnDef.name) {
case "NSTATUS":
return {
stackProps: { justifyContent: "left" },
cellProps: { align: "left" }
};
}
onClassMachineFilesMake: PropTypes.func,
onClassMachineFilesUpload: PropTypes.func,
onClassMachineFilesSendMd: PropTypes.func
};
//----------------