blob: a8857e0ebb75ad6396e031e38407bcac8767ff41 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,Row
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, {
useState,
useEffect,
useCallback,
useReducer,
useRef
} from "react";
import withRouter from "Hooks/withRouter";
import { fetchApi } from "../../../utils/fetchAPI";
import dateFormat from "dateformat";
import XATableLayout from "../../../components/XATableLayout";
import { ClassTypes } from "../../../utils/XAEnums";
import {
Button,
Tab,
Tabs,
Modal,
Accordion,
Card,
DropdownButton,
Dropdown
} from "react-bootstrap";
import StructuredFilter from "../../../components/structured-filter/react-typeahead/tokenizer";
import AccessGrantForm from "./AccessGrantForm";
import { toast } from "react-toastify";
import { Form } from "react-final-form";
import { CustomTooltip, Loader } from "../../../components/CommonComponents";
import moment from "moment-timezone";
import {
useParams,
useNavigate,
useLocation,
useSearchParams
} from "react-router-dom";
import {
getTableSortBy,
getTableSortType,
serverError,
isSystemAdmin,
parseSearchFilter
} from "../../../utils/XAUtils";
import Select from "react-select";
import userColourIcon from "../../../images/user-colour.svg";
import groupColourIcon from "../../../images/group-colour.svg";
import roleColourIcon from "../../../images/role-colour.svg";
import historyDetailsIcon from "../../../images/history-details.svg";
import arrayMutators from "final-form-arrays";
import { groupBy, isEmpty, isArray } from "lodash";
import PrinciplePermissionComp from "./PrinciplePermissionComp";
import ReactPaginate from "react-paginate";
import CustomBreadcrumb from "../../CustomBreadcrumb";
import ErrorPage from "../../../views/ErrorPage";
import DatashareInDatasetListComp from "./DatashareInDatasetListComp";
import OperationAdminModal from "../../AuditEvent/OperationAdminModal";
const initialState = {
loader: false,
preventUnBlock: false,
blockUI: false
};
const datasetFormReducer = (state, action) => {
switch (action.type) {
case "SET_SELECTED_PRINCIPLE":
return {
...state,
selectedPrinciple: action.selectedPrinciple
};
case "SET_PREVENT_ALERT":
return {
...state,
preventUnBlock: action.preventUnBlock
};
case "SET_BLOCK_UI":
return {
...state,
blockUI: action.blockUI
};
default:
throw new Error();
}
};
const DatasetDetailLayout = () => {
let { datasetId } = useParams();
const { state } = useLocation();
const [userAclPerm, setUserAclPerm] = useState(state?.userAclPerm);
const toastId = React.useRef(null);
const [loader, setLoader] = useState(true);
const [datasetInfo, setDatasetInfo] = useState({});
const [datasetName, setDatasetName] = useState();
const [datasetDescription, setDatasetDescription] = useState();
const [datasetTerms, setDatasetTerms] = useState();
const [datashareSearch, setDatashareSearch] = useState();
const [dataShareModal, setDatashareModal] = useState(false);
const [datashareList, setDatashareList] = useState([]);
const [selectedDatashareList, setSelectedDatashareList] = useState([]);
const [serviceDef, setServiceDef] = useState({});
const [dataSetDetails, dispatch] = useReducer(
datasetFormReducer,
initialState
);
const [acceptTerms, setAcceptTerms] = useState(false);
const [dataShareRequestsList, setDatashareRequestsList] = useState([]);
const [userSharedWithAccordion, setUserSharedWithAccordion] = useState(false);
const [groupSharedWithAccordion, setGroupSharedWithAccordion] =
useState(false);
const [roleSharedWithAccordion, setRoleSharedWithAccordion] = useState(false);
const [userList, setUserList] = useState([]);
const [groupList, setGroupList] = useState([]);
const [roleList, setRoleList] = useState([]);
const [activeKey, setActiveKey] = useState("overview");
const [requestActiveKey, setRequestActiveKey] = useState("All");
const [userSharedWithMap, setUserSharedWithMap] = useState(new Map());
const [groupSharedWithMap, setGroupSharedWithMap] = useState(new Map());
const [roleSharedWithMap, setRoleSharedWithMap] = useState(new Map());
const [filteredUserSharedWithMap, setFilteredUserSharedWithMap] = useState();
const [filteredGroupSharedWithMap, setFilteredGroupSharedWithMap] =
useState();
const [filteredRoleSharedWithMap, setFilteredRoleSharedWithMap] = useState();
const [sharedWithPrincipleName, setSharedWithPrincipleName] = useState();
const [sharedWithAccessFilter, setSharedWithAccessFilter] = useState();
const [saveCancelButtons, showSaveCancelButton] = useState(false);
const [showConfirmModal, setShowConfirmModal] = useState(false);
const navigate = useNavigate();
const [accessGrantFormValues, setAccessGrantFormValues] = useState();
const [blockUI, setBlockUI] = useState(false);
const [policyData, setPolicyData] = useState();
const [
showDatashareRequestDeleteConfirmModal,
setShowDatashareRequestDeleteConfirmModal
] = useState(false);
const [deleteDatashareReqInfo, setDeleteDatashareReqInfo] = useState({});
const [tabTitle] = useState({
all: "",
requested: "",
granted: "",
active: ""
});
const [showDeleteDatasetModal, setShowDeleteDatasetModal] = useState(false);
const [requestCurrentPage, setRequestCurrentPage] = useState(0);
const [requestPageCount, setRequestPageCount] = useState();
const [datashareCurrentPage, setDatashareCurrentPage] = useState(0);
const [datasharePageCount, setDatasharePageCount] = useState();
const [requestAccordionState, setRequestAccordionState] = useState({});
const itemsPerPage = 5;
const datashareItemsPerPage = 10;
const [showActivateRequestModal, setShowActivateRequestModal] =
useState(false);
const [datashareInfo, setDatashareInfo] = useState();
const [datashareRequestInfo, setDatashareRequestInfo] = useState();
const [completeDatashareRequestsList, setCompleteDatashareRequestsList] =
useState([]);
const [datashareTotalCount, setDatashareTotalCount] = useState(0);
const [datashareRequestTotalCount, setDatashareRequestTotalCount] =
useState(0);
const toggleConfirmModalForDatasetDelete = () => {
setShowDeleteDatasetModal(true);
};
const [loadRequestListDataCounter, setLoadRequestListDataCounter] = useState(
Math.random()
);
const [updateTable, setUpdateTable] = useState(moment.now());
const gdsServiceDefName = "gds";
const [datasetNameEditable, isDatasetNameEditable] = useState(false);
const [requestSearchFilterParams, setRequestSearchFilterParams] = useState(
[]
);
const [shareStatusMetrics, setShareStatusMetrics] = useState({
totalCount: 0,
REQUESTED: 0,
GRANTED: 0,
ACTIVE: 0,
DENIED: 0
});
const [searchHistoryFilterParams, setSearchHistoryFilterParams] = useState(
[]
);
const fetchIdRef = useRef(0);
const [historyListData, setHistoryListData] = useState([]);
const [historyLoader, setHistoryLoader] = useState(false);
const [entries, setEntries] = useState([]);
const [pageCount, setPageCount] = useState(
state && state.showLastPage ? state.addPageData.totalPage : 0
);
const [showrowmodal, setShowRowModal] = useState(false);
const [rowdata, setRowData] = useState([]);
const handleClosed = () => setShowRowModal(false);
const fetchShareStatusMetrics = async (requestSearchFilterParams) => {
try {
setLoader(true);
let requestList = [];
let params =
requestSearchFilterParams != undefined
? { ...requestSearchFilterParams }
: {};
params["pageSize"] = 999999999;
params["datasetId"] = datasetId;
try {
let resp = await fetchApi({
url: "gds/datashare/summary",
params: params
});
if (resp.data.list.length > 0) {
requestList = resp.data.list;
requestList?.forEach((datashare) => {
for (let i = 0; i < datashare.datasets.length; i++) {
if (datashare.datasets[i].datasetId == datasetId) {
datashare.shareStatus = datashare.datasets[i].shareStatus;
datashare.requestId = datashare.datasets[i].id;
datashare.datasetName = datashare.datasets[i].datasetName;
break;
}
}
});
}
} catch (error) {
serverError(error);
console.error(
`Error occurred while fetching Datashare request metrics! ${error}`
);
}
let activeCount = 0;
let requestedCount = 0;
let grantedCount = 0;
let deniedCount = 0;
requestList.forEach((request) => {
switch (request.shareStatus) {
case "REQUESTED":
requestedCount += 1;
break;
case "GRANTED":
grantedCount += 1;
break;
case "ACTIVE":
activeCount += 1;
break;
case "DENIED":
deniedCount += 1;
break;
}
});
setShareStatusMetrics({
totalCount: requestList.length,
REQUESTED: requestedCount,
GRANTED: grantedCount,
ACTIVE: activeCount,
DENIED: deniedCount
});
} catch (error) {
console.error(
`Error occurred while fetching dataset summary details ! ${error}`
);
}
setLoader(false);
};
const handleDatasetDeleteClick = async () => {
toggleClose();
try {
let params = {};
params["forceDelete"] = true;
setBlockUI(true);
await fetchApi({
url: `gds/dataset/${datasetId}`,
method: "DELETE",
params: params
});
setBlockUI(false);
toast.success(" Success! Dataset deleted successfully");
navigate("/gds/mydatasetlisting");
} catch (error) {
setBlockUI(false);
let errorMsg = "Failed to delete dataset : ";
if (error?.response?.data?.msgDesc) {
errorMsg += error.response.data.msgDesc;
}
toast.error(errorMsg);
console.error("Error occurred during deleting dataset : " + error);
}
};
const getServiceDefData = async () => {
let data = null;
let resp = {};
try {
resp = await fetchApi({
url: `plugins/definitions/name/${gdsServiceDefName}`
});
setServiceDef(resp.data);
} catch (error) {
console.error(
`Error occurred while fetching Service Definition or CSRF headers! ${error}`
);
}
return data;
};
const historySearchFilterOptions = [
{
category: "owner",
label: "User",
urlLabel: "owner",
type: "text"
}
];
const updateHistorySearchFilter = (filter) => {
let { searchFilterParam, searchParam } = parseSearchFilter(
filter,
historySearchFilterOptions
);
setSearchHistoryFilterParams(searchFilterParam);
};
const fetchHistoryList = useCallback(
async ({ pageSize, pageIndex, sortBy, gotoPage }) => {
setHistoryLoader(true);
let resp = [];
let historyList = [];
let totalCount = 0;
let page =
state && state.showLastPage
? state.addPageData.totalPage - 1
: pageIndex;
let totalPageCount = 0;
const fetchId = ++fetchIdRef.current;
let params = { ...searchHistoryFilterParams };
if (fetchId === fetchIdRef.current) {
params["pageSize"] = pageSize;
params["startIndex"] =
state && state.showLastPage
? (state.addPageData.totalPage - 1) * pageSize
: pageIndex * pageSize;
if (sortBy.length > 0) {
params["sortBy"] = getTableSortBy(sortBy);
params["sortType"] = getTableSortType(sortBy);
}
params["objectClassType"] = ClassTypes.CLASS_TYPE_RANGER_DATASET.value;
params["objectId"] = datasetId;
try {
resp = await fetchApi({
url: "assets/report",
params: params
});
historyList = resp.data.vXTrxLogs;
totalCount = resp.data.totalCount;
} catch (error) {
serverError(error);
console.error(
`Error occurred while fetching Dataset History! ${error}`
);
}
setHistoryListData(historyList);
setEntries(resp.data);
setPageCount(Math.ceil(totalCount / pageSize));
//setResetpage({ page: gotoPage });
setHistoryLoader(false);
}
},
[searchHistoryFilterParams]
);
const openOperationalModal = async (row) => {
setShowRowModal(true);
setRowData(row);
};
const historyColumns = React.useMemo(
() => [
{
Header: "Time",
accessor: "createDate",
Cell: (rawValue) => {
return dateFormat(rawValue.value, "mm/dd/yyyy h:MM:ss TT");
},
width: 170,
disableResizing: true,
getResizerProps: () => {}
},
{
Header: "User",
accessor: "owner",
width: 650,
disableResizing: true,
disableSortBy: true,
getResizerProps: () => {}
},
{
Header: "",
accessor: "actions",
width: 30,
Cell: ({ row: { original } }) => {
return (
<div className="d-flex gap-half align-items-start">
<div className="d-flex gap-half align-items-start">
<Button
variant="outline-dark"
size="sm"
title="showDetails"
onClick={() => openOperationalModal(original)}
data-name="showDetails"
data-id="showDetails"
>
<img src={historyDetailsIcon} height="30px" width="30px" />
</Button>
</div>
</div>
);
},
disableSortBy: true
}
],
[]
);
const requestSearchFilterOptions = [
{
category: "dataShareNamePartial",
label: "Name",
urlLabel: "dataShareNamePartial",
type: "text"
},
{
category: "serviceNamePartial",
label: "Service",
urlLabel: "serviceNamePartial",
type: "text"
},
{
category: "zoneNamePartial",
label: "Zone",
urlLabel: "zoneNamePartial",
type: "text"
}
];
const updateRequestSearchFilter = (filter) => {
let { searchFilterParam, searchParam } = parseSearchFilter(
filter,
requestSearchFilterOptions
);
setRequestSearchFilterParams(searchFilterParam);
fetchShareStatusMetrics(searchFilterParam);
};
useEffect(() => {
fetchDatasetInfo(datasetId);
getServiceDefData();
if (userAclPerm == undefined) fetchDatasetSummary(datasetId);
if (activeKey == "sharedWith") {
fetchAccessGrantInfo();
}
}, []);
const fetchDatasetSummary = async (datasetId) => {
try {
let params = {};
params["datasetId"] = datasetId;
setLoader(true);
const resp = await fetchApi({
url: `gds/dataset/summary`,
params: params
});
setLoader(false);
setUserAclPerm(resp.data.list[0].permissionForCaller);
} catch (error) {
setLoader(false);
if (error.response.status == 401 || error.response.status == 400) {
<ErrorPage errorCode="401" />;
}
console.error(
`Error occurred while fetching dataset summary details ! ${error}`
);
}
};
const fetchDatashareRequestList = async (
datashareName,
currentPage,
getCompleteList
) => {
try {
let params = {};
let itemPerPageCount = getCompleteList ? 999999999 : itemsPerPage;
params["pageSize"] = itemPerPageCount;
params["page"] = currentPage;
params["startIndex"] = currentPage * itemPerPageCount;
params["datasetId"] = datasetId;
const resp = await fetchApi({
url: `gds/datashare/dataset`,
params: params
});
let accordianState = {};
resp.data.list.map(
(item) =>
(accordianState = { ...accordianState, ...{ [item.id]: false } })
);
setRequestAccordionState(accordianState);
setRequestPageCount(Math.ceil(resp.data.totalCount / itemsPerPage));
if (!getCompleteList) {
setDatashareRequestsList(resp.data.list);
tabTitle.all = "All (" + resp.data.totalCount + ")";
} else {
setCompleteDatashareRequestsList(resp.data.list);
}
setDatashareRequestTotalCount(resp.data.totalCount);
return resp.data.list;
} catch (error) {
console.error(
`Error occurred while fetching Datashare requests details ! ${error}`
);
}
};
const setPrincipleAccordianData = (principle) => {
let userPrinciples = principle.users;
let groupPrinciples = principle.groups;
let rolePrinciples = principle.roles;
let tempUserList = [];
let tempGroupList = [];
let tempRoleList = [];
let userList = [];
let groupList = [];
let roleList = [];
if (userPrinciples != undefined) {
Object.entries(userPrinciples).map(([key, value]) => {
tempUserList.push({ name: key, type: "USER", perm: value });
});
}
if (groupPrinciples != undefined) {
Object.entries(groupPrinciples).map(([key, value]) => {
tempGroupList.push({ name: key, type: "GROUP", perm: value });
});
}
if (rolePrinciples != undefined) {
Object.entries(rolePrinciples).map(([key, value]) => {
tempRoleList.push({ name: key, type: "ROLE", perm: value });
});
}
setUserList([...userList, ...tempUserList]);
setGroupList([...groupList, ...tempGroupList]);
setRoleList([...roleList, ...tempRoleList]);
};
const fetchAccessGrantInfo = async () => {
let policyData = {};
try {
const resp = await fetchApi({
url: `gds/dataset/${datasetId}/policy`
});
policyData = resp.data[0];
} catch (error) {
console.error(
`Error occurred while fetching dataset access grant details ! ${error}`
);
}
let grantItems = undefined;
if (policyData != undefined) {
grantItems = policyData.policyItems;
const userMap = new Map();
const groupMap = new Map();
const roleMap = new Map();
grantItems?.forEach((item) => {
if (item.users !== undefined) {
item.users.forEach((user) => {
let accessList = [];
if (userMap.get(user) !== undefined) {
accessList = userMap.get(user);
}
userMap.set(user, [...accessList, ...item.accesses]);
});
}
if (item.groups !== undefined) {
item.groups.forEach((group) => {
let accessList = [];
if (groupMap[group] !== undefined) {
accessList = groupMap[group];
}
groupMap.set(group, [...accessList, ...item.accesses]);
});
}
if (item.roles !== undefined) {
item.roles.forEach((role) => {
let accessList = [];
if (roleMap[role] !== undefined) {
accessList = roleMap[role];
}
roleMap.set(role, [...accessList, ...item.accesses]);
});
}
setUserSharedWithMap(userMap);
setGroupSharedWithMap(groupMap);
setRoleSharedWithMap(roleMap);
setFilteredUserSharedWithMap(userMap);
setFilteredGroupSharedWithMap(groupMap);
setFilteredRoleSharedWithMap(roleMap);
});
}
return grantItems;
};
const onSharedWithAccessFilterChange = (e) => {
setSharedWithAccessFilter(e);
filterSharedWithPrincipleList(
undefined,
false,
e != undefined ? e.label : undefined,
true
);
};
const fetchDatasetInfo = async (datasetId) => {
try {
setLoader(true);
const resp = await fetchApi({
url: `gds/dataset/${datasetId}`
});
setLoader(false);
setDatasetInfo(resp.data);
setDatasetName(resp.data.name);
setDatasetDescription(resp.data.description);
setDatasetTerms(resp.data.termsOfUse);
if (resp.data.acl != undefined) setPrincipleAccordianData(resp.data.acl);
setLoader(false);
} catch (error) {
setLoader(false);
if (error.response.status == 401 || error.response.status == 400) {
<ErrorPage errorCode="401" />;
}
console.error(`Error occurred while fetching dataset details ! ${error}`);
}
};
const addAccessGrant = () => {
navigate(`/gds/dataset/${datasetInfo.id}/accessGrant`);
};
const datasetDescriptionChange = (event) => {
setDatasetDescription(event.target.value);
showSaveCancelButton(true);
console.log("DatasetDescription is:", datasetDescription);
};
const datasetTermsAndConditionsChange = (event) => {
setDatasetTerms(event.target.value);
showSaveCancelButton(true);
console.log("datasetTermsAndConditions is:", datasetTerms);
};
const requestDatashare = () => {
setSelectedDatashareList([]);
fetchDatashareList(undefined, 0);
};
const toggleClose = () => {
setDatashareModal(false);
setShowDeleteDatasetModal(false);
setShowActivateRequestModal(false);
};
const toggleConfirmModalClose = () => {
setShowConfirmModal(false);
};
const toggleDatashareRequestDelete = () => {
setShowDatashareRequestDeleteConfirmModal(false);
};
const updateDatashareSearch = (event) => {
setDatashareSearch(event.target.value);
fetchDatashareList(event.target.value, datashareCurrentPage);
};
const submitDatashareRequest = async () => {
console.log("Selected datasharelist");
console.log(selectedDatashareList);
let payloadObj = [];
for (let i = 0; i < selectedDatashareList.length; i++) {
let data = {};
data["datasetId"] = datasetId;
data["dataShareId"] = selectedDatashareList[i];
data["status"] = "REQUESTED";
payloadObj.push(data);
}
if (payloadObj.length > 0) {
try {
dispatch({
type: "SET_BLOCK_UI",
blockUI: true
});
const createDatasetResp = await fetchApi({
url: `gds/dataset/${datasetId}/datashare`,
method: "post",
data: payloadObj
});
dispatch({
type: "SET_BLOCK_UI",
blockUI: false
});
toast.success("Request created successfully!!");
setDatashareModal(false);
fetchShareStatusMetrics();
setUpdateTable(moment.now());
} catch (error) {
dispatch({
type: "SET_BLOCK_UI",
blockUI: false
});
serverError(error);
console.error(
`Error occurred while creating Datashare request ${error}`
);
}
} else {
toast.error("Please select a datashare");
}
};
const fetchDatashareList = useCallback(
async (dataShareSearchObj, datashareCurrentPage) => {
let resp = [];
let totalCount = 0;
let params = {};
let dataShareName = "";
params["pageSize"] = datashareItemsPerPage;
params["page"] = datashareCurrentPage;
params["startIndex"] = datashareCurrentPage * datashareItemsPerPage;
//params["dataShareName"] = datasetId;
if (dataShareSearchObj != undefined) {
dataShareName = dataShareSearchObj;
} else {
dataShareName = datashareSearch;
}
try {
params["dataShareNamePartial"] = dataShareName;
resp = await fetchApi({
url: "gds/datashare",
params: params
});
setDatashareList(resp.data.list);
setDatasharePageCount(
Math.ceil(resp.data.totalCount / datashareItemsPerPage)
);
//totalCount = resp.data.totalCount;
setDatashareTotalCount(resp.data.totalCount);
setDatashareModal(true);
} catch (error) {
serverError(error);
console.error(`Error occurred while fetching Datashare list! ${error}`);
}
},
[]
);
const checkBocChange = (event) => {
if (
event.target.checked == true &&
!selectedDatashareList.includes(event.target.value)
) {
setSelectedDatashareList([...selectedDatashareList, event.target.value]);
} else if (
event.target.checked == false &&
selectedDatashareList.includes(event.target.value)
) {
setSelectedDatashareList(
selectedDatashareList.filter((item) => item !== event.target.value)
);
}
};
const handleSubmit = async (formData) => {};
const onUserSharedWithAccordianChange = () => {
setUserSharedWithAccordion(!userSharedWithAccordion);
};
const onGroupSharedWithAccordianChange = () => {
setGroupSharedWithAccordion(!groupSharedWithAccordion);
};
const onRoleSharedWithAccordianChange = () => {
setRoleSharedWithAccordion(!roleSharedWithAccordion);
};
const serviceSelectTheme = (theme) => {
return {
...theme,
colors: {
...theme.colors,
primary: "#0081ab"
}
};
};
const customStyles = {
control: (provided) => ({
...provided,
maxHeight: "40px",
width: "172px"
}),
indicatorsContainer: (provided) => ({
...provided
})
};
const dropDownStyle = {
control: (provided) => ({ ...provided, display: none })
};
const onChangeSharedWithPrincipleName = (event) => {
setSharedWithPrincipleName(event.target.value);
filterSharedWithPrincipleList(event.target.value, true, undefined, false);
};
const filterSharedWithPrincipleList = (
name,
nameChange,
perm,
permChange
) => {
if (name === undefined && !nameChange) {
name =
sharedWithPrincipleName != undefined &&
sharedWithPrincipleName.length > 0
? sharedWithPrincipleName
: undefined;
}
if (perm === undefined && !permChange) {
perm =
sharedWithAccessFilter != undefined
? sharedWithAccessFilter.name
: undefined;
}
let newUserMap = new Map();
let newGroupMap = new Map();
let newRoleMap = new Map();
const conditionFunction = (value, key) => {
if (name != undefined && perm != undefined) {
let accessMatch = false;
for (const accessObj of value) {
if (accessObj.type == perm) {
accessMatch = true;
}
}
return key.startsWith(name, 0) && accessMatch;
} else if (name != undefined) {
return key.startsWith(name, 0);
} else if (perm != undefined) {
for (const accessObj of value) {
if (accessObj.type == perm) return true;
}
} else {
return true;
}
};
userSharedWithMap.forEach((value, key) => {
if (conditionFunction(value, key)) {
newUserMap.set(key, value);
}
});
groupSharedWithMap.forEach((value, key) => {
if (conditionFunction(value, key)) {
newGroupMap.set(key, value);
}
});
roleSharedWithMap.forEach((value, key) => {
if (conditionFunction(value, key)) {
newRoleMap.set(key, value);
}
});
setFilteredUserSharedWithMap(newUserMap);
setFilteredGroupSharedWithMap(newGroupMap);
setFilteredRoleSharedWithMap(newRoleMap);
};
const handleDataChange = (userList, groupList, roleList) => {
setUserList(userList);
setGroupList(groupList);
setRoleList(roleList);
showSaveCancelButton(true);
};
const handleTabSelect = (key) => {
if (saveCancelButtons == true && userAclPerm != "AUDIT") {
setShowConfirmModal(true);
} else {
setActiveKey(key);
if (key == "sharedWith") {
fetchAccessGrantInfo();
} else if (key == "datashares") {
fetchShareStatusMetrics();
}
}
};
const handleRequestTabSelect = (key) => {
setRequestActiveKey(key);
};
const updateDatasetAndAccessGrant = async () => {
updateDatasetDetails();
updateDatasetAccessGrant();
};
const updateDatasetDetails = async () => {
datasetInfo.name = datasetName;
datasetInfo.description = datasetDescription;
datasetInfo.termsOfUse = datasetTerms;
datasetInfo.acl = { users: {}, groups: {}, roles: {} };
userList.forEach((user) => {
datasetInfo.acl.users[user.name] = user.perm;
});
groupList.forEach((group) => {
datasetInfo.acl.groups[group.name] = group.perm;
});
roleList.forEach((role) => {
datasetInfo.acl.roles[role.name] = role.perm;
});
try {
dispatch({
type: "SET_BLOCK_UI",
blockUI: true
});
await fetchApi({
url: `gds/dataset/${datasetId}`,
method: "put",
data: datasetInfo
});
dispatch({
type: "SET_BLOCK_UI",
blockUI: false
});
toast.success("Dataset updated successfully!!");
isDatasetNameEditable(false);
showSaveCancelButton(false);
} catch (error) {
dispatch({
type: "SET_BLOCK_UI",
blockUI: false
});
serverError(error);
console.error(`Error occurred while updating dataset ${error}`);
}
};
const handleAccessGrantChange = (accessGrantData, policyData) => {
if (userAclPerm != "AUDIT") {
if (accessGrantData != undefined) {
setAccessGrantFormValues(accessGrantData);
}
if (policyData != undefined) {
setPolicyData(policyData);
}
showSaveCancelButton(true);
}
};
const updateDatasetAccessGrant = async () => {
let data = {};
let values = accessGrantFormValues;
let errorList = [];
data.policyItems = getPolicyItemsVal(values, "policyItems", errorList);
data.description = values.description;
data.isAuditEnabled = values.isAuditEnabled;
data.isDenyAllElse = values.isDenyAllElse;
data.isEnabled = values.isEnabled;
data.name = values.policyName;
data.policyLabels = (values.policyLabel || [])?.map(({ value }) => value);
data.policyPriority = values.policyPriority ? "1" : "0";
data.policyType = values.policyType;
//data.service = policyData?.service;
let serviceCompRes;
if (values.policyType != null) {
serviceCompRes = serviceDef.resources;
}
const grpResources = groupBy(serviceCompRes || [], "level");
let grpResourcesKeys = [];
for (const resourceKey in grpResources) {
grpResourcesKeys.push(+resourceKey);
}
grpResourcesKeys = grpResourcesKeys.sort();
let value = { values: [datasetInfo.name] };
data.resources = { dataset: value };
if (values?.validitySchedules) {
data["validitySchedules"] = [];
values.validitySchedules.filter((val) => {
if (val) {
let timeObj = {};
if (val.startTime) {
timeObj["startTime"] = moment(val.startTime).format(
"YYYY/MM/DD HH:mm:ss"
);
}
if (val.endTime) {
timeObj["endTime"] = moment(val.endTime).format(
"YYYY/MM/DD HH:mm:ss"
);
}
if (val.timeZone) {
timeObj["timeZone"] = val.timeZone.id;
}
if (!isEmpty(timeObj)) {
data["validitySchedules"].push(timeObj);
}
}
});
}
/*Policy Condition*/
if (values?.conditions) {
data.conditions = [];
Object.entries(values.conditions).map(([key, value]) => {
return data.conditions.push({
type: key,
values: value?.split(",")
});
});
} else {
data["conditions"] = [];
}
if (errorList.length == 0) {
if (policyData != undefined) {
let dataVal = {
...policyData,
...data
};
try {
setLoader(true);
const resp = await fetchApi({
url: `gds/dataset/${datasetId}/policy/${policyData.id}`,
method: "PUT",
data: dataVal
});
setLoader(false);
toast.dismiss(toastId.current);
toastId.current = toast.success(
"Access Grant updated successfully!!"
);
showSaveCancelButton(false);
setAccessGrantFormValues();
} catch (error) {
setLoader(false);
let errorMsg = `Failed to update Access Grant`;
if (error?.response?.data?.msgDesc) {
errorMsg = `Error! ${error.response.data.msgDesc}`;
}
toast.error(errorMsg);
console.error(`Error while updating Access Grant! ${error}`);
}
} else {
try {
setLoader(true);
const resp = await fetchApi({
url: `gds/dataset/${datasetId}/policy`,
method: "POST",
data: data
});
setLoader(false);
toast.dismiss(toastId.current);
toastId.current = toast.success(
"Access Grant created successfully!!"
);
showSaveCancelButton(false);
setAccessGrantFormValues();
} catch (error) {
setLoader(false);
let errorMsg = `Failed to create Access Grant`;
if (error?.response?.data?.msgDesc) {
errorMsg = `Error! ${error.response.data.msgDesc}`;
}
toast.error(errorMsg);
console.error(`Error while creating Access Grant! ${error}`);
}
}
}
};
const getPolicyItemsVal = (formData, name, errorList) => {
var policyResourceItem = [];
let errorMsg = "";
if (formData == undefined || formData == null) {
errorMsg = "Please add access grant details";
errorList.push(errorMsg);
toast.error(errorMsg);
return null;
}
if (formData[name] != undefined) {
for (let key of formData[name]) {
if (!isEmpty(key) && Object.entries(key).length > 0) {
let obj = {};
if (key.delegateAdmin != "undefined" && key.delegateAdmin != null) {
obj.delegateAdmin = key.delegateAdmin;
}
if (key.accesses != undefined && key.accesses.length > 0) {
obj.accesses = key.accesses.map(({ value }) => ({
type: value,
isAllowed: true
}));
} else {
errorMsg = "Please select Permission";
errorList.push(errorMsg);
toast.error(errorMsg);
return null;
}
if (key.principle != undefined && key.principle.length > 0) {
obj.users = [];
obj.groups = [];
obj.roles = [];
if (key.principle && key.principle.length > 0) {
for (let i = 0; i < key.principle.length; i++) {
let principleObj = key.principle[i];
if (principleObj.type == "USER") {
obj.users.push(principleObj.value);
} else if (principleObj.type == "GROUP") {
obj.groups.push(principleObj.value);
} else if (principleObj.type == "ROLE") {
obj.roles.push(principleObj.value);
}
}
}
} else {
errorMsg = "Please select Principal";
errorList.push(errorMsg);
toast.error(errorMsg);
return null;
}
if (key?.conditions) {
obj.conditions = [];
Object.entries(key.conditions).map(
([conditionKey, conditionValue]) => {
return obj.conditions.push({
type: conditionKey,
values: isArray(conditionValue)
? conditionValue.map((m) => {
return m.value;
})
: [conditionValue]
});
}
);
}
if (
!isEmpty(obj) &&
!isEmpty(obj?.delegateAdmin) &&
Object.keys(obj)?.length > 1
) {
policyResourceItem.push(obj);
}
if (
!isEmpty(obj) &&
isEmpty(obj?.delegateAdmin) &&
Object.keys(obj)?.length > 1
) {
policyResourceItem.push(obj);
}
}
}
}
return policyResourceItem;
};
const removeChanges = () => {
fetchDatasetInfo(datasetId);
showSaveCancelButton(false);
isDatasetNameEditable(false);
toggleConfirmModalClose();
};
const viewDatashareDetail = (datashareId) => {
navigate(`/gds/datashare/${datashareId}/detail`);
};
const toggleConfirmModalForDelete = (id, name, status) => {
let deleteMsg = "";
if (status == "ACTIVE") {
deleteMsg = `Do you want to remove Datashare ${id} from ${datasetInfo.name}`;
} else {
deleteMsg = `Do you want to delete request of Datashare ${id}`;
}
let data = { id: id, name: name, status: status, msg: deleteMsg };
setDeleteDatashareReqInfo(data);
setShowDatashareRequestDeleteConfirmModal(true);
};
const deleteDatashareRequest = async () => {
try {
setLoader(true);
await fetchApi({
url: `gds/datashare/dataset/${deleteDatashareReqInfo.id}`,
method: "DELETE"
});
let successMsg = "";
if (deleteDatashareReqInfo.status == "ACTIVE") {
successMsg = "Success! Datashare removed from dataset successfully";
} else {
successMsg = "Success! Datashare request deleted successfully";
}
setShowDatashareRequestDeleteConfirmModal(false);
toast.success(successMsg);
setLoader(false);
} catch (error) {
let errorMsg = "";
if (deleteDatashareReqInfo.status == "ACTIVE") {
errorMsg = "Failed to remove datashare from dataset ";
} else {
errorMsg = "Failed to delete datashare request ";
}
setLoader(false);
if (error?.response?.data?.msgDesc) {
errorMsg += error.response.data.msgDesc;
}
toast.error(errorMsg);
console.error(
"Error occurred during deleting Datashare request : " + error
);
}
};
const downloadJsonFile = async () => {
let jsonData = datasetInfo;
jsonData.datashares = await fetchDatashareRequestList(undefined, 0, true);
if (
userAclPerm == "ADMIN" ||
userAclPerm == "AUDIT" ||
userAclPerm == "POLICY_ADMIN"
) {
jsonData.sharedWith = { users: {}, groups: {}, roles: {} };
let policyItems = await fetchAccessGrantInfo();
for (const item of policyItems) {
let accessList = [];
item.accesses.forEach((item) => {
accessList.push(item.type);
});
item.users?.forEach((user) => {
if (jsonData.sharedWith.users[user] != undefined) {
let newAccessTypeList = [
...jsonData.sharedWith.users[user],
...accessList
];
jsonData.sharedWith.users[user] = [...new Set(newAccessTypeList)];
} else {
jsonData.sharedWith.users[user] = accessList;
}
});
item.groups?.forEach((group) => {
if (jsonData.sharedWith.groups[group] != undefined) {
let newAccessTypeList = [
...jsonData.sharedWith.groups[group],
...accessList
];
jsonData.sharedWith.groups[group] = [...new Set(newAccessTypeList)];
} else {
jsonData.sharedWith.groups[group] = accessList;
}
});
item.roles?.forEach((role) => {
if (jsonData.sharedWith.roles[role] != undefined) {
let newAccessTypeList = [
...jsonData.sharedWith.roles[role],
...accessList
];
jsonData.sharedWith.roles[role] = [...new Set(newAccessTypeList)];
} else {
jsonData.sharedWith.roles[role] = accessList;
}
});
}
}
const jsonContent = JSON.stringify(jsonData);
const blob = new Blob([jsonContent], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = datasetInfo.name + ".json";
a.click();
URL.revokeObjectURL(url);
};
const termsCheckBocChange = () => {
setAcceptTerms(true);
};
const copyURL = () => {
navigator.clipboard.writeText(window.location.href).then(() => {
toast.success("URL copied!!");
});
};
const handleRequestPageClick = ({ selected }) => {
setRequestCurrentPage(selected);
//fetchDatashareRequestList(undefined, selected, false);
};
const handleDatasharePageClick = ({ selected }) => {
setDatashareCurrentPage(selected);
fetchDatashareList(undefined, selected);
};
const onRequestAccordionChange = (id) => {
setRequestAccordionState({
...requestAccordionState,
...{ [id]: !requestAccordionState[id] }
});
};
const showActiveateRequestModal = (requestInfo) => {
setShowActivateRequestModal(true);
setDatashareRequestInfo(requestInfo);
fetchDatashareById(requestInfo.dataShareId);
};
const fetchDatashareById = async (datashareId) => {
let resp = {};
try {
resp = await fetchApi({
url: `gds/datashare/${datashareId}`
});
} catch (error) {
let errorMsg = "Failed to delete dataset : ";
if (error?.response?.data?.msgDesc) {
errorMsg += error.response.data.msgDesc;
}
console.error("Error occurred during deleting dataset : " + error);
}
setDatashareInfo(resp.data);
};
const activateDatashareRequest = async (datashareInfo) => {
if (datashareInfo.termsOfUse != undefined && !acceptTerms) {
toast.error("Please accept terms & conditions");
return null;
}
datashareRequestInfo["status"] = "ACTIVE";
try {
setLoader(true);
const resp = await fetchApi({
url: `gds/datashare/dataset/${datashareRequestInfo.id}`,
method: "PUT",
data: datashareRequestInfo
});
setLoader(false);
toast.success("Request updated successfully!!");
//showSaveCancelButton(false);
} catch (error) {
setLoader(false);
let errorMsg = `Failed to update request`;
if (error?.response?.data?.msgDesc) {
errorMsg = `Error! ${error.response.data.msgDesc}`;
}
toast.error(errorMsg);
console.error(`Error while updating request! ${error}`);
}
setShowActivateRequestModal(false);
};
const navidateToFullViewPage = () => {
navigate(`/gds/dataset/${datasetId}/fullview`, {
state: {
userAclPerm: userAclPerm
}
});
};
const onDatasetNameChange = (event) => {
setDatasetName(event.target.value);
showSaveCancelButton(true);
};
const handleEditClick = () => {
if (isSystemAdmin() || userAclPerm == "ADMIN") {
isDatasetNameEditable(true);
showSaveCancelButton(true);
}
};
const getDefaultSort = React.useMemo(
() => [
{
id: "createdDate",
desc: true
}
],
[]
);
return (
<>
<React.Fragment>
<div
className={
saveCancelButtons
? "gds-header-wrapper gap-half pt-2 pb-2"
: "gds-header-wrapper gap-half"
}
>
<Button
variant="light"
className="border-0 bg-transparent"
onClick={() => window.history.back()}
size="sm"
data-id="back"
data-cy="back"
>
<i className="fa fa-angle-left fa-lg font-weight-bold" />
</Button>
<h3 className="gds-header bold">
<div className="d-flex align-items-center">
<span className="mr-1">Dataset: </span>
{!datasetNameEditable ? (
<span
title={datasetName}
className="text-truncate"
style={{ maxWidth: "700px", display: "inline-block" }}
onClick={() => handleEditClick()}
>
{datasetName}
</span>
) : (
<input
type="text"
name="datasetName"
style={{ height: "39px" }}
className="form-control"
data-cy="datasetName"
value={datasetName}
onChange={onDatasetNameChange}
/>
)}
</div>
</h3>
{!datasetNameEditable && !saveCancelButtons && (
<>
<CustomBreadcrumb />
<span className="pipe" />
</>
)}
{datasetNameEditable ||
((isSystemAdmin() ||
userAclPerm == "ADMIN" ||
userAclPerm == "POLICY_ADMIN") &&
saveCancelButtons) ? (
<div className="gds-header-btn-grp">
<Button
variant="secondary"
onClick={() => removeChanges()}
size="sm"
data-id="cancel"
data-cy="cancel"
>
Cancel
</Button>
<Button
variant="primary"
onClick={() => {
if(datasetName.length > 512) {
toast.error('Dataset name must be 512 characters or less');
}
else {
if (
activeKey === 'accessGrants' &&
accessGrantFormValues !== undefined &&
datasetNameEditable
) {
updateDatasetAndAccessGrant();
} else if (
activeKey !== 'accessGrants' ||
(activeKey === 'accessGrants' && datasetNameEditable)
) {
updateDatasetDetails();
} else {
updateDatasetAccessGrant();
}
}
}}
size="sm"
data-id="save"
data-cy="save"
>
Save
</Button>
</div>
) : (
<div></div>
)}
{!datasetNameEditable && !saveCancelButtons && (
<div>
<DropdownButton
id="dropdown-item-button"
title={<i className="fa fa-ellipsis-v" fontSize="36px" />}
size="sm"
className="hide-arrow"
>
<Dropdown.Item
as="button"
onClick={() => {
navidateToFullViewPage();
}}
data-name="fullView"
data-id="fullView"
data-cy="fullView"
>
Full View
</Dropdown.Item>
<Dropdown.Item
as="button"
onClick={() => {
copyURL();
}}
data-name="copyDatasetLink"
data-id="copyDatasetLink"
data-cy="copyDatasetLink"
>
Copy Dataset Link
</Dropdown.Item>
<Dropdown.Item
as="button"
onClick={() => downloadJsonFile()}
data-name="downloadJson"
data-id="downloadJson"
data-cy="downloadJson"
>
Download Json
</Dropdown.Item>
<hr />
<Dropdown.Item
as="button"
onClick={() => {
toggleConfirmModalForDatasetDelete();
}}
data-name="deleteDataset"
data-id="deleteDataset"
data-cy="deleteDataset"
>
Delete Dataset
</Dropdown.Item>
</DropdownButton>
</div>
)}
</div>
{loader ? (
<Loader />
) : (
<React.Fragment>
<div>
<Tabs
id="DatasetDetailLayout"
activeKey={activeKey}
onSelect={handleTabSelect}
>
<Tab eventKey="overview" title="OVERVIEW">
{activeKey == "overview" ? (
<div>
<Form
onSubmit={handleSubmit}
mutators={{
...arrayMutators
}}
render={({}) => (
<div>
<div className="gds-tab-content gds-content-border">
<div className="gds-inline-field-grp">
<div className="wrapper">
<div
className="gds-left-inline-field"
height="30px"
>
<span className="gds-label-color">ID</span>
</div>
<div line-height="30px">{datasetInfo.id}</div>
</div>
<div className="wrapper">
<div
className="gds-left-inline-field"
height="30px"
>
<span className="gds-label-color">
Date Updated
</span>
</div>
<div line-height="30px">
{dateFormat(
datasetInfo.updateTime,
"mm/dd/yyyy hh:MM:ss TT"
)}
</div>
</div>
<div className="wrapper">
<div
className="gds-left-inline-field"
line-height="30px"
>
<span className="gds-label-color">
Date Created
</span>
</div>
<div line-height="30px">
{dateFormat(
datasetInfo.createTime,
"mm/dd/yyyy hh:MM:ss TT"
)}
</div>
</div>
</div>
<div>
<div>
<span className="gds-label-color">
Description
</span>
</div>
</div>
<div>
<div>
<textarea
placeholder="Dataset Description"
className="form-control gds-description pl-1"
id="description"
data-cy="description"
readOnly={
!isSystemAdmin() && userAclPerm != "ADMIN"
}
onChange={datasetDescriptionChange}
value={datasetDescription}
rows={5}
/>
</div>
</div>
</div>
{(isSystemAdmin() || userAclPerm != "VIEW") && (
<PrinciplePermissionComp
userList={userList}
groupList={groupList}
roleList={roleList}
type="dataset"
isAdmin={
isSystemAdmin() || userAclPerm == "ADMIN"
? true
: false
}
isDetailView={true}
onDataChange={handleDataChange}
/>
)}
</div>
)}
/>
</div>
) : (
<div></div>
)}
</Tab>
<Tab eventKey="datashares" title="DATASHARES">
{activeKey == "datashares" ? (
<div className="gds-request-content">
<div className="mb-3">
<div className="usr-grp-role-search-width mb-3">
<StructuredFilter
key="user-listing-search-filter"
placeholder="Search datashares..."
onChange={updateRequestSearchFilter}
options={requestSearchFilterOptions}
/>
</div>
{(isSystemAdmin() || userAclPerm == "ADMIN") && (
<div className="gds-header-btn-grp">
<Button
variant="primary"
onClick={requestDatashare}
size="sm"
data-id="addADatashare"
data-cy="addADatashare"
>
Add a Data Share
</Button>
</div>
)}
</div>
<div>
<div className="usr-grp-role-search-width">
<Tabs
id="DatashareTabs"
className="mg-b-10"
activeKey={requestActiveKey}
onSelect={handleRequestTabSelect}
>
<Tab
eventKey="All"
title={
"All (" + shareStatusMetrics.totalCount + ")"
}
>
{requestActiveKey == "All" && (
<DatashareInDatasetListComp
id={Number(datasetId)}
type="dataset"
setUpdateTable={setUpdateTable}
updateTable={updateTable}
userAclPerm={userAclPerm}
searchFilter={requestSearchFilterParams}
fetchShareStatusMetrics={
fetchShareStatusMetrics
}
/>
)}
</Tab>
<Tab
eventKey="Active"
title={
"Active (" + shareStatusMetrics.ACTIVE + ")"
}
>
{requestActiveKey == "Active" && (
<DatashareInDatasetListComp
id={Number(datasetId)}
type="dataset"
shareStatus="ACTIVE"
setUpdateTable={setUpdateTable}
updateTable={updateTable}
userAclPerm={userAclPerm}
searchFilter={requestSearchFilterParams}
fetchShareStatusMetrics={
fetchShareStatusMetrics
}
/>
)}
</Tab>
<Tab
eventKey="Requested"
title={
"Requested (" +
shareStatusMetrics.REQUESTED +
")"
}
>
{requestActiveKey == "Requested" && (
<DatashareInDatasetListComp
id={Number(datasetId)}
type="dataset"
shareStatus="REQUESTED"
setUpdateTable={setUpdateTable}
updateTable={updateTable}
userAclPerm={userAclPerm}
searchFilter={requestSearchFilterParams}
fetchShareStatusMetrics={
fetchShareStatusMetrics
}
/>
)}
</Tab>
<Tab
eventKey="Granted"
title={
"Granted (" + shareStatusMetrics.GRANTED + ")"
}
>
{requestActiveKey == "Granted" && (
<DatashareInDatasetListComp
id={Number(datasetId)}
type="dataset"
shareStatus="GRANTED"
setUpdateTable={setUpdateTable}
updateTable={updateTable}
userAclPerm={userAclPerm}
searchFilter={requestSearchFilterParams}
fetchShareStatusMetrics={
fetchShareStatusMetrics
}
/>
)}
</Tab>
<Tab
eventKey="Denied"
title={
"Denied (" + shareStatusMetrics.DENIED + ")"
}
>
{requestActiveKey == "Denied" && (
<DatashareInDatasetListComp
id={Number(datasetId)}
type="dataset"
shareStatus="DENIED"
setUpdateTable={setUpdateTable}
updateTable={updateTable}
userAclPerm={userAclPerm}
searchFilter={requestSearchFilterParams}
fetchShareStatusMetrics={
fetchShareStatusMetrics
}
/>
)}
</Tab>
</Tabs>
</div>
</div>
</div>
) : (
<div></div>
)}
</Tab>
{(isSystemAdmin() ||
userAclPerm === "ADMIN" ||
userAclPerm === "AUDIT" ||
userAclPerm === "POLICY_ADMIN") && (
<Tab eventKey="sharedWith" title="SHARED WITH">
{activeKey == "sharedWith" ? (
<div className="gds-tab-content gds-content-border">
<div>
<div className="usr-grp-role-search-width">
<p className="gds-content-header">Shared with</p>
</div>
<div className="gds-flex mg-b-10">
<input
type="search"
className="form-control gds-input"
placeholder="Search Users, Groups and Roles..."
onChange={(e) =>
onChangeSharedWithPrincipleName(e)
}
value={sharedWithPrincipleName}
/>
<Select
theme={serviceSelectTheme}
styles={customStyles}
options={serviceDef.accessTypes}
onChange={(e) =>
onSharedWithAccessFilterChange(e)
}
value={sharedWithAccessFilter}
menuPlacement="auto"
placeholder="Select Permission"
isClearable
/>
</div>
<Accordion className="mg-b-10" defaultActiveKey="0">
<Card>
<div className="border-bottom">
<Accordion.Toggle
as={Card.Header}
eventKey="1"
onClick={onUserSharedWithAccordianChange}
className="border-bottom-0 d-flex align-items-center justify-content-between gds-acc-card-header"
data-id="panel"
data-cy="panel"
>
<div className="d-flex align-items-center gap-half">
<img
src={userColourIcon}
height="30px"
width="30px"
/>
Users (
{filteredUserSharedWithMap == undefined
? 0
: filteredUserSharedWithMap.size}
)
</div>
{userSharedWithAccordion ? (
<i className="fa fa-angle-up fa-lg font-weight-bold"></i>
) : (
<i className="fa fa-angle-down fa-lg font-weight-bold"></i>
)}
</Accordion.Toggle>
</div>
<Accordion.Collapse eventKey="1">
<Card.Body>
{filteredUserSharedWithMap != undefined &&
filteredUserSharedWithMap.size > 0 ? (
Array.from(filteredUserSharedWithMap).map(
([key, value]) => (
<div
className="gds-principle-listing"
key={key}
>
<span title={key}>{key}</span>
<div className="gds-chips gap-one-fourth">
{value.map((accessObj) => (
<span
className="badge badge-light badge-sm"
title={accessObj.type}
key={accessObj.type}
>
{accessObj.type}
</span>
))}
</div>
</div>
)
)
) : (
<p className="mt-1">--</p>
)}
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
<Accordion className="mg-b-10" defaultActiveKey="0">
<Card>
<div className="border-bottom">
<Accordion.Toggle
as={Card.Header}
eventKey="1"
onClick={onGroupSharedWithAccordianChange}
className="border-bottom-0 d-flex align-items-center justify-content-between gds-acc-card-header"
data-id="panel"
data-cy="panel"
>
<div className="d-flex align-items-center gap-half">
<img
src={groupColourIcon}
height="30px"
width="30px"
/>
Groups (
{filteredGroupSharedWithMap == undefined
? 0
: filteredGroupSharedWithMap.size}
)
</div>
{groupSharedWithAccordion ? (
<i className="fa fa-angle-up fa-lg font-weight-bold"></i>
) : (
<i className="fa fa-angle-down fa-lg font-weight-bold"></i>
)}
</Accordion.Toggle>
</div>
<Accordion.Collapse eventKey="1">
<Card.Body>
{filteredGroupSharedWithMap != undefined &&
filteredGroupSharedWithMap.size > 0 ? (
Array.from(filteredGroupSharedWithMap).map(
([key, value]) => (
<div
className="gds-principle-listing"
key={key}
>
<span title={key}>{key}</span>
<div className="gds-chips gap-one-fourth">
{value.map((accessObj) => (
<span
className="badge badge-light badge-sm"
title={accessObj.type}
key={accessObj.type}
>
{accessObj.type}
</span>
))}
</div>
</div>
)
)
) : (
<p className="mt-1">--</p>
)}
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
<Accordion className="mg-b-10" defaultActiveKey="0">
<Card>
<div className="border-bottom">
<Accordion.Toggle
as={Card.Header}
eventKey="1"
onClick={onRoleSharedWithAccordianChange}
className="border-bottom-0 d-flex align-items-center justify-content-between gds-acc-card-header"
data-id="panel"
data-cy="panel"
>
<div className="d-flex align-items-center gap-half">
<img
src={roleColourIcon}
height="30px"
width="30px"
/>
Roles (
{filteredRoleSharedWithMap == undefined
? 0
: filteredRoleSharedWithMap.size}
)
</div>
{roleSharedWithAccordion ? (
<i className="fa fa-angle-up fa-lg font-weight-bold"></i>
) : (
<i className="fa fa-angle-down fa-lg font-weight-bold"></i>
)}
</Accordion.Toggle>
</div>
<Accordion.Collapse eventKey="1">
<Card.Body>
{filteredRoleSharedWithMap != undefined &&
filteredRoleSharedWithMap.size > 0 ? (
Array.from(filteredRoleSharedWithMap).map(
([key, value]) => (
<div
className="gds-principle-listing"
key={key}
>
<span title={key}>{key}</span>
<div className="gds-chips gap-one-fourth">
{value.map((accessObj) => (
<span
className="badge badge-light badge-sm"
title={accessObj.type}
key={accessObj.type}
>
{accessObj.type}
</span>
))}
</div>
</div>
)
)
) : (
<p className="mt-1">--</p>
)}
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
</div>
</div>
) : (
<div></div>
)}
</Tab>
)}
{(isSystemAdmin() ||
userAclPerm === "ADMIN" ||
userAclPerm === "AUDIT" ||
userAclPerm === "POLICY_ADMIN") && (
<Tab eventKey="accessGrants" title="ACCESS GRANTS">
<div className="wrap-gds">
{activeKey == "accessGrants" ? (
<AccessGrantForm
dataset={datasetInfo}
onDataChange={handleAccessGrantChange}
serviceCompDetails={serviceDef}
isAdmin={
isSystemAdmin() ||
userAclPerm == "ADMIN" ||
userAclPerm == "POLICY_ADMIN"
}
/>
) : (
<div></div>
)}
</div>
</Tab>
)}
{(isSystemAdmin() ||
userAclPerm === "ADMIN" ||
userAclPerm === "AUDIT") && (
<Tab eventKey="history" title="HISTORY">
{activeKey == "history" && (
<div className="gds-request-content">
<div className="mb-3">
<div className="usr-grp-role-search-width mb-3 mg-t-20">
<StructuredFilter
key="dataset-history-search-filter"
placeholder="Search..."
onChange={updateHistorySearchFilter}
options={historySearchFilterOptions}
/>
</div>
<div className="gds-header-btn-grp"></div>
</div>
<XATableLayout
data={historyListData}
columns={historyColumns}
fetchData={fetchHistoryList}
totalCount={entries && entries.totalCount}
loading={historyLoader}
pageCount={pageCount}
getRowProps={(row) => ({
onClick: (e) => {
e.stopPropagation();
// rowModal(row);
}
})}
columnHide={false}
columnResizable={false}
columnSort={true}
defaultSort={getDefaultSort}
/>
</div>
)}
</Tab>
)}
<Tab
eventKey="termsOfUse"
title="TERMS OF USE"
//onClick={() => handleTabClick("TERMS OF USE")}
>
{activeKey == "termsOfUse" ? (
<div className="gds-tab-content gds-content-border">
<div>
<div className="usr-grp-role-search-width">
<p className="gds-content-header">
Terms & Conditions
</p>
</div>
</div>
<div>
<div>
<textarea
placeholder="Terms & Conditions"
className="form-control"
id="termsAndConditions"
data-cy="termsAndConditions"
onChange={datasetTermsAndConditionsChange}
value={datasetTerms}
readOnly={
!isSystemAdmin() && userAclPerm != "ADMIN"
}
rows={16}
/>
</div>
</div>
</div>
) : (
<div></div>
)}
</Tab>
</Tabs>
</div>
<Modal
show={showDatashareRequestDeleteConfirmModal}
onHide={toggleDatashareRequestDelete}
>
<Modal.Header closeButton>
<h3 className="gds-header bold">
{deleteDatashareReqInfo.msg}
</h3>
</Modal.Header>
<Modal.Footer>
<Button
variant="secondary"
size="sm"
onClick={() => removeChanges()}
>
No
</Button>
<Button
variant="primary"
size="sm"
onClick={() => deleteDatashareRequest()}
>
Yes
</Button>
</Modal.Footer>
</Modal>
<Modal show={showConfirmModal} onHide={toggleConfirmModalClose}>
<Modal.Header closeButton>
<h3 className="gds-header bold">
Would you like to save the changes?
</h3>
</Modal.Header>
<Modal.Footer>
<Button
variant="secondary"
size="sm"
onClick={() => removeChanges()}
>
No
</Button>
<Button
variant="primary"
size="sm"
onClick={updateDatasetDetails}
>
Yes
</Button>
</Modal.Footer>
</Modal>
<Modal show={dataShareModal} onHide={toggleClose}>
<Modal.Header closeButton>
<h3 className="gds-header bold">Request a Datashare</h3>
</Modal.Header>
<Modal.Body>
<input
type="search"
className="form-control gds-input mb-3"
placeholder="Search Datashare..."
onChange={(e) => updateDatashareSearch(e)}
value={datashareSearch}
/>
{datashareList != undefined && datashareList.length > 0 ? (
datashareList.map((obj, index) => {
return (
<div className="d-flex align-items-center gap-half mg-b-10 ">
<input
type="checkbox"
name={obj.name}
value={obj.id}
id={obj.id}
checked={selectedDatashareList.includes(
obj.id.toString()
)}
onChange={checkBocChange}
/>
<span
title={obj.name}
className="fnt-14 text-truncate"
style={{ maxWidth: "300px", display: "inline-block" }}
>
{obj.name}
</span>
<CustomTooltip
placement="right"
content={
<p className="pd-10" style={{ fontSize: "small" }}>
{obj.description}
</p>
}
icon="fa-fw fa fa-info-circle gds-opacity-lowest"
/>
</div>
);
})
) : (
<div></div>
)}
{datashareTotalCount > itemsPerPage && (
<div className="d-flex">
<ReactPaginate
previousLabel={"<"}
nextLabel={">"}
pageClassName="page-item"
pageLinkClassName="page-link"
previousClassName="page-item"
previousLinkClassName="page-link"
nextClassName="page-item"
nextLinkClassName="page-link"
breakLabel={"..."}
pageCount={datasharePageCount}
onPageChange={handleDatasharePageClick}
breakClassName="page-item"
breakLinkClassName="page-link"
containerClassName="pagination"
activeClassName="active"
/>
</div>
)}
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" size="sm" onClick={toggleClose}>
Cancel
</Button>
<Button
variant="primary"
size="sm"
onClick={submitDatashareRequest}
>
Send Request
</Button>
</Modal.Footer>
</Modal>
<Modal show={showDeleteDatasetModal} onHide={toggleClose}>
<Modal.Header closeButton>
<span className="text-word-break">
Are you sure you want to delete dataset&nbsp;"
<b>{datasetInfo.name}</b>" ?
</span>
</Modal.Header>
<Modal.Footer>
<Button variant="secondary" size="sm" onClick={toggleClose}>
No
</Button>
<Button
variant="primary"
size="sm"
onClick={() => handleDatasetDeleteClick()}
>
Yes
</Button>
</Modal.Footer>
</Modal>
<Modal show={showActivateRequestModal} onHide={toggleClose}>
<Modal.Header closeButton>
<h3 className="gds-header bold">Activate Datashare</h3>
</Modal.Header>
<Modal.Body>
<div>
<p>Terms & Conditions</p>
<span>{datashareInfo?.termsOfUse}</span>
</div>
{datashareInfo?.termsOfUse != undefined ? (
<div className="d-flex align-items-center gap-half my-2">
<input
type="checkbox"
name="acceptTerms"
//value={obj.id}
onChange={termsCheckBocChange}
/>
<span className="fnt-14">
{" "}
I accept the terms and conditions
</span>
</div>
) : (
<div></div>
)}
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" size="sm" onClick={toggleClose}>
Cancel
</Button>
<Button
variant="primary"
size="sm"
onClick={() => activateDatashareRequest(datashareInfo)}
>
Activate
</Button>
</Modal.Footer>
</Modal>
<OperationAdminModal
show={showrowmodal}
data={rowdata}
onHide={handleClosed}
></OperationAdminModal>
</React.Fragment>
)}
</React.Fragment>
</>
);
};
export default withRouter(DatasetDetailLayout);