Untitled
unknown
plain_text
9 months ago
30 kB
11
Indexable
/**
* @author a.azmat
* @descrption Standard Specs component
*/
import React, { useState, useEffect } from "react";
import {
Grid,
Button,
Menu,
Divider,
Box,
Typography,
Stack,
Chip,
Pagination
} from "@mui/material";
import ToggleButtonComponent from "common/toggleButtonComponent";
import StandardToggleButton from "../StandardToggleButton";
import { styled, alpha } from "@mui/material/styles";
import StandardSpecsCard from "./StandardSpecsCards";
import CheckCircleRoundedIcon from "@mui/icons-material/CheckCircleRounded";
import CloseIcon from "@mui/icons-material/Close";
import EditOutlinedIcon from "@mui/icons-material/EditOutlined";
import CloseOutlinedIcon from "@mui/icons-material/CloseOutlined";
import useStyles from "./StandardSpecsStyles";
import { useNavigate, useLocation } from "react-router-dom";
import routePath from "constants/routePath";
import { useDispatch, useSelector } from "react-redux";
import {
secondarySearch,
} from "services/standardSpecsServices";
import {
domainListSelector,
setSelectedDomainList,
setRadioBtnSelectedValue,
} from "./standardSpecsReducer";
import { setSnackbar } from "common/reducer/common";
import { standardDomainFilterDropDowns } from "constants/enumsData";
import SpecsDomainList from "components/StandardListing/StandardSpecs/SpecsDomainList/SpecsDomainList";
import { selectPermissions } from "common/reducer/userMatrix";
import SpecsHeader from "./StandardSpecsLineage/SpecsHeader";
import { setRightPanelData } from "components/Studies/studyDetails/sce/sceReducer";
import usePagination from "common/Pagination";
import CustomTooltip from "common/EntityCards/CustomTooltip";
const StandardSpecs = () => {
const location = useLocation();
const { permissions } = useSelector(selectPermissions);
const { selectedPurpose } = useSelector((state) => state.studyReducer);
const [fieldValues, setFieldValues] = React.useState({});
const [alignment, setAlignment] = useState(2);
const [searchString, setSearchString] = useState(location?.hash?.slice(1) || "");
const [anchorEl, setAnchorEl] = useState(null);
const selectedDomains = useSelector(domainListSelector);
const [selectedAction, setSelectedAction] = useState(
selectedDomains?.length > 0 ? 0 : -1
);
const dispatch = useDispatch();
const [domainListData, setDomainListData] = useState([]);
const classes = useStyles();
const navigate = useNavigate();
const openOption = Boolean(anchorEl);
const [listselected, setListSelected] = useState();
const [showRightSide, setShowRightSide] = useState(false);
const [radioBtnVal, setRadioBtnVal] = useState("adam");
const [openFilter, setOpenFilter] = useState(false);
const [appliedFilters, setAppliedFilters] = useState([]);
const [IGVersion, setIGVersion] = useState([]);
const [filters, setFilters] = useState({});
const { currentFile } = useSelector((state) => state.sceReducer);
const initialStyle = {
background: "#fff",
mt:"10px",
borderRadius: "10px",
py:2,
height: "125vh",
};
const StyledMenu = styled((props) => (
<Menu
elevation={0}
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
{...props}
/>
))(({ theme }) => ({
"& .MuiPopover-paper": {
right: "60px !important",
left: "unset !important",
marginTop: "8px !important", // Adjust the margin as needed
},
"& .MuiPaper-root": {
borderRadius: 6,
marginTop: theme.spacing(1),
minWidth: 100,
color:
theme.palette.mode === "light"
? "rgb(55, 65, 81)"
: theme.palette.grey[300],
boxShadow:
"rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px",
"& .MuiMenu-list": {
padding: "4px 0",
},
"& .MuiMenuItem-root": {
"& .MuiSvgIcon-root": {
fontSize: 18,
color: theme.palette.text.secondary,
marginRight: theme.spacing(1.5),
},
"&:active": {
backgroundColor: alpha(
theme.palette.primary.main,
theme.palette.action.selectedOpacity
),
},
},
},
}));
const PER_PAGE = 20;
const [page, setPage] = useState({
pageNo: 1,
totalPages: 1,
totalElements: 1,
numberOfElements: 1,
pageSize: PER_PAGE,
});
const count = Math.ceil(page.totalElements / PER_PAGE);
const _DATA = usePagination(page.totalElements, domainListData, PER_PAGE);
/**
* @function handleAlignment
* @param {String} v
*/
const handleAlignment = (v) => {
setAlignment(v);
switch (v) {
case 0:
navigate(routePath.StandardSpecs);
return;
case 1:
navigate(routePath.STANDARDPROGRAMS);
return;
case 2:
navigate(routePath.STANDARDMODULES);
return;
case 3:
navigate(routePath.STANDARDISSUES);
return;
case 4:
navigate(routePath.STANDARDQUERIES);
return;
default:
return;
}
};
/**
* @function handleClose
*/
const handleClose = () => {
setAnchorEl(null);
};
/**
* @function clearSearch
*/
const clearSearch = () => {
setSearchString("");
navigate(routePath.StandardSpecs);
fetchAllDomains();
};
/**
* @function handleSelectDomain
* @param {*} domain
* @description select and deselect domains
*/
const handleSelectDomain = (domain) => {
let tempFiles = [];
const domains = [...selectedDomains];
let exist = domains?.filter((f) => f.id === domain.id)?.length > 0;
if (exist) {
tempFiles = domains?.filter((f) => f.id !== domain.id);
} else {
tempFiles = [...domains, domain];
}
dispatch(setSelectedDomainList(tempFiles));
// dispatch(setRightPanelData(domain));
};
/**
* @function handleAllSelectedFiles
* @param {String} type
* @description select and deselect all (domains)
*/
const handleAllSelectedFiles = (type) => {
if (type === "clear") {
dispatch(setSelectedDomainList([]));
} else if (type === "select") {
dispatch(setSelectedDomainList(domainListData));
} else {
return false;
}
};
/**
* @function handleProceed
* @description Navigate to target purpose
*/
const handleProceed = () => {
navigate(routePath.StandardSpecsTargetPurpose);
};
/**
* @function handleCancel
* @description reseting states
*/
const handleCancel = () => {
setSelectedAction(-1);
dispatch(setSelectedDomainList([]));
};
/**
* @function handleSearch
* @param {Event} e
*/
const handleSearch = (e) => {
const { value } = e?.target || "";
if (value?.trim().length === 0 && searchString?.trim()?.length > 0) {
setSearchString("");
navigate(routePath.StandardSpecs);
fetchAllDomains();
} else {
setSearchString(value);
}
};
/**
* @function fetchSearchResults
* @description Primary search api
*/
const fetchSearchResults = (params = { pageNumber: 0, pageSize: PER_PAGE }) => {
if(!searchString){
dispatch(setSnackbar({ open: true, message: "Please enter a search criteria", severity: "error", vertical: 'top', horizontal: 'center' }))
return;
}
if (searchString.length > 0) {
setFieldValues({});
}
let payload = {
searchRequest: {
search: !!location?.hash ? location?.hash.slice(1) : searchString,
},
adamIGVersion: [IGVersion?.title || ""],
};
// primarySearch(searchString)
secondarySearch(params, payload)
.then((res) => {
if (res.status === 200) {
if (res?.data?.errorCode) {
dispatch(
setSnackbar({
open: true,
message: res?.data?.message,
severity: "error",
})
);
} else {
setDomainListData(res?.data?.content);
setListSelected(res?.data?.content[0]);
if (!!location?.hash && res?.data?.content?.length>0) {
setShowRightSide(true);
} else {
// setShowRightSide(false);
if (radioBtnVal === "adam") {
setShowRightSide(false);
}
}
let {
pageNumber,
totalElements,
// numberOfElements,
totalPages,
} = res?.data || {};
setPage({
pageNo: pageNumber + 1 || 1,
totalElements,
// numberOfElements,
// totalPages: totalElements / PER_PAGE - 1 || 1,
totalPages: totalPages - 1,
});
}
}
})
.catch((e) =>
dispatch(
setSnackbar({
open: true,
message: e.message,
severity: "error",
})
)
);
};
const handleChange = (e, p) => {
setPage({ ...page, pageNo: p });
const params = {
pageNumber: p - 1,
pageSize: PER_PAGE,
};
if (Object.keys(fieldValues)?.length > 0) {
handleApply(fieldValues, params);
setSearchString("");
} else if (searchString?.length > 0) {
fetchSearchResults(params);
setFieldValues({});
} else {
fetchAllDomains(params);
setSearchString("");
setFieldValues({});
}
_DATA.jump(p);
};
/**
* @function fetchAllDomains
*/
const fetchAllDomains = (params = { pageNumber: 0, pageSize: PER_PAGE }) => {
// getDomainList()
// let params = {
// pageNumber: 0,
// pageSize: 2,
// }
let payload = {
...filters,
adamIGVersion: [IGVersion?.title || ""]
};
secondarySearch(params, payload)
.then((res) => {
if (res.status === 200) {
setDomainListData(res?.data?.content);
let {
pageNumber,
totalElements,
// numberOfElements,
totalPages,
} = res?.data || {};
setPage({
pageNo: pageNumber + 1 || 1,
totalElements,
// numberOfElements,
// totalPages: totalElements / PER_PAGE - 1 || 1,
totalPages: totalPages - 1,
});
// setShowRightSide(false);
if (radioBtnVal === "adam") {
setShowRightSide(false);
}
}
})
.catch((err) => {
console.log(err);
});
};
/**
* @function handleApply
* @description Secondary filter api
*/
const handleApply = (values, params = { pageNumber: 0, pageSize: PER_PAGE }) => {
if (searchString.length > 0) {
setSearchString("");
}
// let tempValues = { ...values };
let variableLabel = !!values?.variableLabel ? [values.variableLabel] : [];
let domainLabel = !!values?.domainLabel ? [values.domainLabel] : [];
let derivationLabel = !!values?.derivationLabel
? [values.derivationLabel]
: [];
let derivationDescription = !!values?.derivationDescription
? [values.derivationDescription]
: [];
let tempValues = {
...values,
derivationLabel: derivationLabel,
domainLabel: domainLabel,
variableLabel: variableLabel,
derivationDescription: derivationDescription,
};
Object.keys(standardDomainFilterDropDowns).forEach((d) => {
if (tempValues[d]) {
tempValues[d] =
typeof standardDomainFilterDropDowns[d] === "string"
? tempValues[d]
: tempValues[d]?.map((v) => v.title) || "";
}
});
// saved applied filters to show
const isfilters = Object.keys(standardDomainFilterDropDowns).filter((d) => {
if (fieldValues[d]) {
if (fieldValues[d].length > 0) return d;
}
});
setAppliedFilters(isfilters);
// api call
// secondarySearch(tempValues)
setFilters(tempValues);
secondarySearch(params, {...tempValues, adamIGVersion: [IGVersion?.title || ""]})
.then((res) => {
if (res?.status === 200) {
if (res?.data?.errorCode) {
dispatch(
setSnackbar({
open: true,
message: res?.data?.message,
severity: "error",
})
);
} else {
setOpenFilter(false);
setDomainListData(res?.data?.content);
// setShowRightSide(false);
if (radioBtnVal === "adam") {
setShowRightSide(false);
}
let {
pageNumber,
totalElements,
// numberOfElements,
totalPages,
} = res?.data || {};
setPage({
pageNo: pageNumber + 1 || 1,
totalElements,
// numberOfElements,
// totalPages: totalElements / PER_PAGE - 1 || 1,
totalPages: totalPages - 1,
});
}
}
})
.catch((err) =>
dispatch(
setSnackbar({
open: true,
message: err?.message,
severity: "error",
})
)
);
};
const clearFilter = () => {
setFieldValues({});
fetchAllDomains();
setOpenFilter(false);
setAppliedFilters([]);
setShowRightSide(false)
};
useEffect(() => {
dispatch(setSelectedDomainList([]));
// if(searchString?.length===0) fetchAllDomains();
setSelectedAction(-1);
dispatch(setRadioBtnSelectedValue("adam"));
// setRadioBtnVal(location?.state?.radioBtnVal || "adam");
// if (location?.state?.radioBtnVal === "masters") {
// setShowRightSide(false);
// }
/**
* component will-unmount
*/
return () => {
setDomainListData([]);
setSelectedAction(-1);
setAnchorEl(null);
};
}, []);
/**
* This is important condition when user navigate Menu drawer : Standard Specs
*/
useEffect(() => {
if (!!location?.hash) {
// when we are redirecting from lineage view
setSearchString(location?.hash.slice(1));
fetchSearchResults();
} else
if (
location?.state === null ||
location?.state?.radioBtnVal === "adam"
) {
setShowRightSide(false);
setRadioBtnVal("adam");
} else if (location?.state?.navigate === "standardDomainCardView") {
let domainId = location?.state?.domainId;
setShowRightSide(true);
setListSelected(currentFile);
// setShowRightSide(!showRightSide);
dispatch(setRightPanelData(currentFile));
} else if (location?.state?.radioBtnVal === "masters") {
setRadioBtnVal(location?.state?.radioBtnVal);
setShowRightSide(true);
if (currentFile) {
setListSelected(currentFile);
}
} else {
setRadioBtnVal(location?.state?.radioBtnVal || "adam");
setShowRightSide(false);
}
}, [location]);
useEffect(() => {
if (IGVersion?.title?.length > 0)
{ fetchAllDomains();}
}, [IGVersion]);
/* @method: @{handleSelectCard} this method is we need to check the selected content for this card
like there dataset attributes and variable list before the copy of the domain
*/
const handleSelectCard = (data) => {
setListSelected(data);
setShowRightSide(!showRightSide);
dispatch(setRightPanelData(data));
};
const handleRadioChange = (event) => {
dispatch(setRadioBtnSelectedValue(event.target.value));
setRadioBtnVal(event.target.value);
if (event.target.value === "adam") {
setShowRightSide(false);
} else {
setShowRightSide(true);
// setRadioBtnVal(event.target.value);
if (currentFile) {
setListSelected(currentFile);
dispatch(setRightPanelData(currentFile));
}
}
};
/**
* @function removeFilter
* @param {String} key
* @param {String} type
* @param {Object} value
*/
const removeFilter = (key, type, value) => {
let tempValues = { ...fieldValues };
if (type === "string") {
delete tempValues[key];
} else {
tempValues[key] = tempValues[key].filter((v) => v.title !== value.title);
}
const isFilter = Object.keys(standardDomainFilterDropDowns).filter((d) => {
if (tempValues[d]) {
if (tempValues[d].length > 0) return d;
}
});
setAppliedFilters(isFilter);
if (isFilter.length > 0) {
handleApply(tempValues);
} else {
fetchAllDomains();
}
setFieldValues(tempValues);
};
return (
<Box sx={initialStyle}>
<StandardToggleButton handleAlignment={handleAlignment} alignment={0}/>
<SpecsHeader
radioBtnVal={radioBtnVal}
handleRadioChange={handleRadioChange}
fetchSearchResults={fetchSearchResults}
handleSearch={handleSearch}
clearSearch={clearSearch}
searchString={searchString}
setSearchString={setSearchString}
openFilter={openFilter}
setOpenFilter={setOpenFilter}
handleApply={handleApply}
fieldValues={fieldValues}
setFieldValues={setFieldValues}
clearFilter={clearFilter}
showRightSide={showRightSide}
setIGVersion={setIGVersion}
IGVersion={IGVersion}
/>
<Grid
container
display={"flex"}
justifyContent={selectedAction !== -1 ? "space-between" : "end"}
>
{selectedAction === 0 && (
<Stack direction="row" spacing={0}>
<CheckCircleRoundedIcon
onClick={(e) => {
e.stopPropagation();
handleAllSelectedFiles(
selectedDomains.length > 0 ? "clear" : "select"
);
}}
sx={{
cursor: "pointer",
margin: "10px",
color: selectedDomains.length > 0 ? "#05a358" : "#d0d0d0",
fontSize: "30px",
}}
/>
<Typography lineHeight={"3rem"}>
{selectedDomains.length > 0 ? "Deselect All" : "Select All"}
</Typography>
</Stack>
)}
{/* {!showRightSide && (
<Box display={"flex"} alignItems={"center"} pr={"20px"}>
<Button
className={classes.successButton}
id="demo-customized-button"
aria-controls={
openOption ? "demo-customized-menu" : undefined
}
aria-haspopup="true"
aria-expanded={openOption ? "true" : undefined}
variant="contained"
disableElevation
onClick={handleClick}
endIcon={<KeyboardArrowDownIcon />}
>
Actions
</Button>
<StyledMenu
id="demo-customized-menu"
MenuListProps={{
"aria-labelledby": "demo-customized-button",
}}
anchorEl={anchorEl}
open={openOption}
onClose={handleClose}
>
{actions.map((action, index) => (
<div>
<MenuItem
key={index}
onClick={() => {
setSelectedAction(action.id);
handleClose();
}}
disableRipple
disabled={
!permissions?.includes("createADAMSpec") ||
selectedPurpose?.userAccess === false ||
action.id > 0
}
sx={{ m: 0, py: 0 }}
>
{action.icon}
<Typography fontSize={14}> {action.name}</Typography>
</MenuItem>
{action.id < 2 && <Divider />}
</div>
))}
</StyledMenu>
<InfoOutlinedIcon
sx={{
color: "#0064BF",
fontSize: "25px",
ml: "20px",
}}
/>
</Box>
)} */}
</Grid>
{appliedFilters?.length > 0 && (
<Grid
container
rowSpacing={2}
sx={{ backgroundColor: "#eff7ff", width : "auto" }}
p={2}
m={1}
pt={"5px"}
>
<Typography sx={{ marginTop: "18px" }} fontWeight={600}>
Filtered On -{" "}
</Typography>{" "}
{appliedFilters?.length > 0 &&
appliedFilters?.map((f) => {
const result = f.replace(/([A-Z])/g, " $1");
const finalResult =
result.charAt(0).toUpperCase() + result.slice(1);
return (
<Grid item key={f}>
<span>{finalResult} </span>
{" : "}
{typeof fieldValues[f] === "string" ? (
<CustomTooltip title={fieldValues[f]}>
<Chip
label={fieldValues[f]?.length > 20 ? fieldValues[f]?.substring(0, 20) : fieldValues[f]}
variant="outlined"
sx={{
border: "0.5px solid #0164C1",
borderRadius: "5px",
background: "#fff",
color: "#0164C1",
fontSize: "14px",
fontWeight: "600",
}}
onDelete={(e) => removeFilter(f, "string")}
/>
</CustomTooltip>
) : (
// <Stack direction={"row"}spacing={1}>
fieldValues[f]?.map((v) => (
<>
<Chip
label={v.title}
variant="outlined"
sx={{
border: "0.5px solid #0164C1",
borderRadius: "5px",
background: "#fff",
color: "#0164C1",
fontSize: "14px",
fontWeight: "600",
}}
onDelete={(e) => removeFilter(f, "object", v)}
/>
<span> </span>
</>
))
// {/* </Stack> */}
)}
</Grid>
);
})}
<Typography
sx={{
mt: "22px",
ml: 1,
textDecoration: "underline",
cursor: "pointer",
}}
onClick={clearFilter}
variant={"cardTitle"}
>
{" "}
Clear All
</Typography>
<EditOutlinedIcon
sx={{
mt: "20px",
ml: 1,
colo: "#0166c7",
cursor: "pointer",
float: "right",
}}
onClick={() => setOpenFilter(true)}
/>
<CloseOutlinedIcon
sx={{
mt: "20px",
ml: 1,
colo: "#0166c7",
cursor: "pointer",
float: "right",
}}
onClick={clearFilter}
/>
</Grid>
)}
{!showRightSide && radioBtnVal === "adam" && (
<Grid
container
md={12}
overflow={"auto"}
style={{ backgroundColor: "#fff", margin: "0px!important" }}
>
{domainListData?.length > 0 ? domainListData?.map((data) => {
const isSelected =
selectedDomains?.filter((f) => f.name === data.name)?.length >
0 || false;
return (
<Grid item xs={12} sm={6} md={4} lg={3} fhd={3} qhd={2} uhd={2} p={1}>
<StandardSpecsCard
key={data?.id}
isSelected={isSelected}
action={selectedAction}
data={data}
handleSelectDomain={handleSelectDomain}
handleSelectCard={handleSelectCard}
/>
</Grid>
);
}) :
<Grid item md={12} sx={{mt:2}}>
<Typography textAlign={"center"} variant={"greyLabel"}>No records found.</Typography>
</Grid>
}
</Grid>
)}
{showRightSide && domainListData && (
<SpecsDomainList
domainListData={domainListData}
defaultSelected={listselected}
handleSelectCard={handleSelectCard}
selectedRadio={radioBtnVal}
showMasterTab={location?.state?.tabName}
backButton={location?.state?.navigate}
radioBtnVal={radioBtnVal}
handleRadioChange={handleRadioChange}
fetchSearchResults={fetchSearchResults}
handleSearch={handleSearch}
clearSearch={clearSearch}
searchString={searchString}
setSearchString={setSearchString}
openFilter={openFilter}
setOpenFilter={setOpenFilter}
handleApply={handleApply}
fieldValues={fieldValues}
setFieldValues={setFieldValues}
clearFilter={clearFilter}
showRightSide={showRightSide}
/>
)}
{!showRightSide && radioBtnVal === "adam" && <Box display={"flex"} justifyContent="end" sx={{ mt: "30px" }}>
<Pagination
count={count}
size=""
page={page.pageNo}
color="primary"
onChange={handleChange}
hidePrevButton={page.pageNo === 1 ? true : false}
hideNextButton={page?.pageNo === count ? true : false}
/>
</Box>}
<Grid container md={12} sx={{ backgroundColor: "#fff" }}>
{selectedAction !== -1 && (
<>
<Divider color="#c2c7cd" />
<Grid md={9}>
{selectedDomains.length > 0 && (
<Box
mt={1}
sx={{
// overflowY: "scroll",
// height: "100px",
display: "flex",
// mt: "20px",
}}
>
<Typography sx={{ margin: "5px" }}>
{" "}
Selected Specs
</Typography>
{selectedDomains?.map((d) => (
<Chip
key={d?.id}
sx={{
backgroundColor: "#eff7ff",
color: "#0164C1",
borderColor: "#eff7ff",
m: "2px",
borderRadius: "5px",
fontWeight: "600",
}}
label={d?.name}
variant="outlined"
clickable
onDelete={() => handleSelectDomain(d)}
deleteIcon={
<CloseIcon sx={{ color: "#0164C1 !important" }} />
}
/>
))}
</Box>
)}
</Grid>
<Grid md={3}>
<Box
sx={{
display: "flex",
justifyContent: "end",
position: "initial",
top: "100%",
right: "1%",
marginTop: "20px",
}}
>
<Button
size="large"
sx={{
// height: "161px",
ml: "88px",
background: "#FFFFFF",
border: "1px solid #d9d9d9",
color: "#383838",
}}
variant="outlined"
onClick={handleCancel}
>
Cancel
</Button>
<Button
size="large"
sx={{
ml: "20px",
// height: "161px",
boxShadow: "0px 2px 8px rgba(0, 0, 0, 0.2)",
}}
disabled={selectedDomains?.length ? false : true}
onClick={handleProceed}
variant="contained"
color="success"
>
Next
</Button>
</Box>
</Grid>
</>
)}
</Grid>
</Box>
);
};
export default StandardSpecs;
Editor is loading...
Leave a Comment