This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch RANGER-3923
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/RANGER-3923 by this push:
new 2f7f76261 RANGER-4283: GDS UI - updated request listing page, created
history tab in dataset and datashare detail view
2f7f76261 is described below
commit 2f7f76261b579ffb5b672f9f052fd51efb3a8ddc
Author: Anand Nadar <[email protected]>
AuthorDate: Mon Jan 8 07:47:42 2024 -0800
RANGER-4283: GDS UI - updated request listing page, created history tab in
dataset and datashare detail view
Signed-off-by: Madhan Neethiraj <[email protected]>
---
.../react-webapp/src/images/history-details.svg | 1 +
.../GovernedData/Dataset/DatasetDetailLayout.jsx | 206 ++++++++++++++++-
.../GovernedData/Datashare/AddDatashareView.jsx | 23 ++
.../Datashare/AddSharedResourceComp.jsx | 2 +
.../Datashare/DatashareDetailLayout.jsx | 247 +++++++++++++++++++--
.../GovernedData/Datashare/MyDatashareListing.jsx | 8 +-
.../views/GovernedData/Request/RequestListing.jsx | 151 ++++++++++---
7 files changed, 567 insertions(+), 71 deletions(-)
diff --git
a/security-admin/src/main/webapp/react-webapp/src/images/history-details.svg
b/security-admin/src/main/webapp/react-webapp/src/images/history-details.svg
new file mode 100644
index 000000000..ce012c1dd
--- /dev/null
+++ b/security-admin/src/main/webapp/react-webapp/src/images/history-details.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960"
width="24"><path d="M324.616-184.617q-24.75
0-42.374-17.625-17.625-17.624-17.625-42.374v-99.998h115.384v-110.002q-36.538
3.001-72.269-8.961-35.731-11.961-61.731-38.577v-50.154h-51.385L73.847-673.076q35.231-38.692
83.615-55.961 48.384-17.269 98.538-17.269 32.725 0 63.632 7.461 30.908 7.462
60.369 24.616v-64.231h439.998v493.844q0 41.923-29.038 70.961-29.039
29.038-70.961 29.038H324.616ZM440-344.614h240v59.998q0 17 [...]
\ No newline at end of file
diff --git
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/DatasetDetailLayout.jsx
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/DatasetDetailLayout.jsx
index a08faba49..cba038c8b 100755
---
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/DatasetDetailLayout.jsx
+++
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/DatasetDetailLayout.jsx
@@ -17,10 +17,18 @@
* under the License.
*/
-import React, { useState, useEffect, useCallback, useReducer } from "react";
+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,
@@ -44,6 +52,8 @@ import {
useSearchParams
} from "react-router-dom";
import {
+ getTableSortBy,
+ getTableSortType,
serverError,
isSystemAdmin,
parseSearchFilter
@@ -52,6 +62,7 @@ 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";
@@ -59,6 +70,7 @@ 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,
@@ -180,6 +192,19 @@ const DatasetDetailLayout = () => {
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 {
@@ -292,6 +317,124 @@ const DatasetDetailLayout = () => {
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",
@@ -1278,6 +1421,16 @@ const DatasetDetailLayout = () => {
}
};
+ const getDefaultSort = React.useMemo(
+ () => [
+ {
+ id: "createdDate",
+ desc: true
+ }
+ ],
+ []
+ );
+
return (
<>
<React.Fragment>
@@ -1938,12 +2091,45 @@ const DatasetDetailLayout = () => {
</Tab>
)}
- {false &&
- (isSystemAdmin() ||
- userAclPerm === "ADMIN" ||
- userAclPerm === "AUDIT") && (
- <Tab eventKey="history" title="HISTORY" />
- )}
+ {(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"
@@ -2179,6 +2365,12 @@ const DatasetDetailLayout = () => {
</Button>
</Modal.Footer>
</Modal>
+
+ <OperationAdminModal
+ show={showrowmodal}
+ data={rowdata}
+ onHide={handleClosed}
+ ></OperationAdminModal>
</React.Fragment>
)}
</React.Fragment>
diff --git
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddDatashareView.jsx
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddDatashareView.jsx
index 30be71988..4306864cb 100755
---
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddDatashareView.jsx
+++
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddDatashareView.jsx
@@ -196,6 +196,27 @@ const AddDatashareView = () => {
}
};
+ const serviceSelectTheme = (theme) => {
+ return {
+ ...theme,
+ colors: {
+ ...theme.colors,
+ primary: "#0081ab"
+ }
+ };
+ };
+
+ const customStyles = {
+ control: (provided) => ({
+ ...provided,
+ maxHeight: "40px",
+ width: "172px"
+ }),
+ indicatorsContainer: (provided) => ({
+ ...provided
+ })
+ };
+
const fetchServiceDef = async (serviceDefName) => {
let serviceDefsResp = [];
try {
@@ -633,6 +654,8 @@ const AddDatashareView = () => {
onFocus={() => {
onFocusServiceSelect();
}}
+ // theme={serviceSelectTheme}
+ // styles={customStyles}
components={{
DropdownIndicator: () => null,
IndicatorSeparator: () => null
diff --git
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddSharedResourceComp.jsx
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddSharedResourceComp.jsx
index ecb14c7b2..23c34d2e7 100755
---
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddSharedResourceComp.jsx
+++
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/AddSharedResourceComp.jsx
@@ -209,6 +209,8 @@ const AddSharedResourceComp = ({
? values[`value-${level}`]?.map(({ value }) => value)
: [values[`value-${level}`].value]
};
+ data.resource[values[`resourceName-${level}`].name]["isRecursive"] =
+ values[`resourceName-${level}`].recursiveSupported;
}
}
data.conditionExpr = values.booleanExpression;
diff --git
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/DatashareDetailLayout.jsx
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/DatashareDetailLayout.jsx
index 57630ea5c..dfa3d4027 100755
---
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/DatashareDetailLayout.jsx
+++
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/DatashareDetailLayout.jsx
@@ -56,6 +56,8 @@ import AddSharedResourceComp from "./AddSharedResourceComp";
import CustomBreadcrumb from "../../CustomBreadcrumb";
import PolicyConditionsComp from "../../PolicyListing/PolicyConditionsComp";
import {
+ getTableSortBy,
+ getTableSortType,
isSystemAdmin,
parseSearchFilter,
serverError,
@@ -68,11 +70,14 @@ import { getServiceDef } from "../../../utils/appState";
import DatashareInDatasetListComp from "../Dataset/DatashareInDatasetListComp";
import { isEmpty, isObject, isEqual } from "lodash";
import Select from "react-select";
+import OperationAdminModal from "../../AuditEvent/OperationAdminModal";
+import historyDetailsIcon from "../../../images/history-details.svg";
+import { ClassTypes } from "../../../utils/XAEnums";
const DatashareDetailLayout = () => {
let { datashareId } = useParams();
const { state } = useLocation();
- const userAclPerm = state?.userAclPerm;
+ const userAclPerm = state == null ? fetchDatashareSummary :
state.userAclPerm;
const [datashareName, setDatashareName] = useState(state?.datashareName);
const [activeKey, setActiveKey] = useState("overview");
const [datashareInfo, setDatashareInfo] = useState({});
@@ -153,11 +158,55 @@ const DatashareDetailLayout = () => {
});
const [accessTypeOptions, setAccessTypeOptions] = useState([]);
const [accessType, setAccessType] = useState([]);
+ const [cancel, setCancel] = useState(true);
+ let cancelFlag = false;
+ let saveFlag = false;
+ const [showrowmodal, setShowRowModal] = useState(false);
+ const [rowdata, setRowData] = useState([]);
+ const handleClosed = () => setShowRowModal(false);
+ const [searchHistoryFilterParams, setSearchHistoryFilterParams] = useState(
+ []
+ );
+ const [historyListData, setHistoryListData] = useState([]);
+ const [historyEntries, setHistoryEntries] = useState([]);
+ const [historyLoader, setHistoryLoader] = useState(false);
+ const [pageCount, setPageCount] = useState(
+ state && state.showLastPage ? state.addPageData.totalPage : 0
+ );
+
+ const fetchDatashareSummary = async () => {
+ setLoader(false);
+ let resp = [];
+ let params = { ...searchFilterParams };
+ params["dataShareId"] = dataShareId;
+ try {
+ resp = await fetchApi({
+ url: "gds/datashare/summary",
+ params: params
+ });
+ return resp.data.list[0].permissionForCaller;
+ } catch (error) {
+ serverError(error);
+ console.error(
+ `Error occurred while fetching Datashare summary! ${error}`
+ );
+ }
+ setLoader(false);
+ };
useEffect(() => {
fetchDatashareInfo(datashareId);
}, []);
+ const historySearchFilterOptions = [
+ {
+ category: "owner",
+ label: "User",
+ urlLabel: "owner",
+ type: "text"
+ }
+ ];
+
const fetchShareStatusMetrics = async (requestSearchFilterOptions) => {
try {
setLoader(true);
@@ -231,6 +280,7 @@ const DatashareDetailLayout = () => {
const onAccessTypeChange = (event, input) => {
setAccessType(event);
+ showSaveCancelButton(true);
input.onChange(event);
};
@@ -239,7 +289,6 @@ const DatashareDetailLayout = () => {
setShowConfirmModal(true);
} else {
if (key == "sharedWith") {
- //fetchDatashareRequestList(undefined, 0, false);
fetchShareStatusMetrics();
}
setActiveKey(key);
@@ -286,11 +335,12 @@ const DatashareDetailLayout = () => {
`Error occurred while fetching datashare details ! ${error}`
);
}
- if (datashareResp.data.conditionExpr !== undefined) {
+ if (datashareResp?.data?.conditionExpr !== undefined) {
datashareResp.data.conditions = {
expression: datashareResp.data.conditionExpr
};
}
+ setDatashareConditionExpr(datashareResp.data.conditionExpr);
setAccessType(
datashareResp.data.defaultAccessTypes?.map((item) => ({
label: capitalizeFirstLetter(item),
@@ -535,12 +585,15 @@ const DatashareDetailLayout = () => {
}
isDatashareNameEditable(false);
showSaveCancelButton(false);
+ saveFlag = true;
setBlockUI(false);
setShowConfirmModal(false);
};
const removeChanges = () => {
fetchDatashareInfo(datashareId);
+ cancelFlag = true;
+ setCancel(true);
showSaveCancelButton(false);
setShowConfirmModal(false);
isDatashareNameEditable(false);
@@ -689,6 +742,68 @@ const DatashareDetailLayout = () => {
fetchShareStatusMetrics(searchFilterParam);
};
+ const updateHistorySearchFilter = (filter) => {
+ let { searchFilterParam, searchParam } = parseSearchFilter(
+ filter,
+ historySearchFilterOptions
+ );
+ setSearchHistoryFilterParams(searchFilterParam);
+ };
+
+ const openOperationalModal = async (row) => {
+ setShowRowModal(true);
+ setRowData(row);
+ };
+
+ 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_DATA_SHARE.value;
+ params["objectId"] = datashareId;
+ 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 Datashare History! ${error}`
+ );
+ }
+ setHistoryListData(historyList);
+ setHistoryEntries(resp.data);
+ setPageCount(Math.ceil(totalCount / pageSize));
+ //setResetpage({ page: gotoPage });
+ setHistoryLoader(false);
+ }
+ },
+ [searchHistoryFilterParams]
+ );
+
const fetchSharedResourcetList = useCallback(
async ({ pageSize, pageIndex }) => {
setResourceContentLoader(true);
@@ -874,7 +989,7 @@ const DatashareDetailLayout = () => {
const FormChange = (props) => {
const { isDirtyField, formValues } = props;
- if (isDirtyField) {
+ if (isDirtyField && (!cancelFlag || !saveFlag)) {
setDatashareConditionExpr(props.formValues.conditions?.expression);
showSaveCancelButton(true);
}
@@ -884,14 +999,64 @@ const DatashareDetailLayout = () => {
const isDirtyFieldCheck = (values, initialValues) => {
let modifiedVal = false;
if (
- !isEqual(values?.conditions, initialValues?.conditions) ||
- !isEqual(values?.defaultAccessTypes, initialValues?.defaultAccessTypes)
+ values?.conditions?.expression &&
+ !isEqual(values?.conditions?.expression, datashareConditionExpr)
) {
modifiedVal = true;
+ saveFlag = false;
+ cancelFlag = false;
}
return modifiedVal;
};
+ 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
+ }
+ ],
+ []
+ );
+
return (
<>
<Form
@@ -1070,14 +1235,17 @@ const DatashareDetailLayout = () => {
<Tab eventKey="overview" title="OVERVIEW">
{activeKey == "overview" ? (
<div>
- <FormChange
- isDirtyField={
- dirty == true || !isEqual(initialValues, values)
- ? isDirtyFieldCheck(values, initialValues)
- : false
- }
- formValues={values}
- />
+ {!cancelFlag && !saveFlag && (
+ <FormChange
+ isDirtyField={
+ dirty == !isEqual(initialValues, values)
+ ? isDirtyFieldCheck(values, initialValues)
+ : false
+ }
+ formValues={values}
+ />
+ )}
+
<div className="gds-tab-content gds-content-border
px-3">
<div className="gds-inline-field-grp">
<div className="wrapper">
@@ -1240,7 +1408,7 @@ const DatashareDetailLayout = () => {
<div className="gds-action-card mb-5 gds-tab-content
gds-content-border px-3">
<div className="gds-section-title">
<p className="gds-card-heading">
- Default access types:
+ Default access types
</p>
</div>
<div className="gds-flex mg-b-10 mg-t-20">
@@ -1298,7 +1466,7 @@ const DatashareDetailLayout = () => {
{activeKey == "resources" ? (
<div className="gds-request-content">
<div className="mb-3">
- <div className="w-100 d-flex gap-1 mb-3">
+ <div className="w-100 d-flex gap-1 mb-3 mg-t-20">
<StructuredFilter
key="shared-reource-search-filter"
placeholder="Search resources..."
@@ -1480,12 +1648,41 @@ const DatashareDetailLayout = () => {
)}
</Tab>
- {false &&
- (isSystemAdmin() ||
- userAclPerm == "ADMIN" ||
- userAclPerm == "AUDIT") && (
- <Tab eventKey="history" title="HISTORY"></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={
+ historyEntries && historyEntries.totalCount
+ }
+ loading={historyLoader}
+ pageCount={pageCount}
+ columnHide={false}
+ columnResizable={false}
+ columnSort={true}
+ defaultSort={getDefaultSort}
+ />
+ </div>
+ )}
+ </Tab>
+ )}
<Tab eventKey="termsOfUse" title="TERMS OF USE">
<div className="gds-tab-content gds-content-border">
@@ -1689,6 +1886,12 @@ const DatashareDetailLayout = () => {
setResourceUpdateTable={setResourceUpdateTable}
resourceModalUpdateTable={resourceModalUpdateTable}
/>
+
+ <OperationAdminModal
+ show={showrowmodal}
+ data={rowdata}
+ onHide={handleClosed}
+ ></OperationAdminModal>
</React.Fragment>
)}
<BlockUi isUiBlock={blockUI} />
diff --git
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/MyDatashareListing.jsx
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/MyDatashareListing.jsx
index 15c3d5688..bf6732b17 100755
---
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/MyDatashareListing.jsx
+++
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Datashare/MyDatashareListing.jsx
@@ -22,19 +22,13 @@ import XATableLayout from
"../../../components/XATableLayout";
import { Loader } from "../../../components/CommonComponents";
import { Button, Row, Col } from "react-bootstrap";
import StructuredFilter from
"../../../components/structured-filter/react-typeahead/tokenizer";
-import {
- useSearchParams,
- useNavigate,
- useLocation,
- Link
-} from "react-router-dom";
+import { useSearchParams, useNavigate, useLocation } from "react-router-dom";
import { fetchApi } from "../../../utils/fetchAPI";
import dateFormat from "dateformat";
import {
getTableSortBy,
getTableSortType,
serverError,
- isSystemAdmin,
parseSearchFilter
} from "../../../utils/XAUtils";
import moment from "moment-timezone";
diff --git
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestListing.jsx
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestListing.jsx
index b29b900a0..2ba7bc51a 100755
---
a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestListing.jsx
+++
b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Request/RequestListing.jsx
@@ -18,23 +18,19 @@
*/
import React, { useState, useEffect, useCallback, useRef } from "react";
-import { useNavigate, useLocation } from "react-router-dom";
+import { useNavigate, useLocation, useSearchParams } from "react-router-dom";
import { Row, Col, Button } from "react-bootstrap";
import StructuredFilter from
"../../../components/structured-filter/react-typeahead/tokenizer";
import XATableLayout from "../../../components/XATableLayout";
import { fetchApi } from "../../../utils/fetchAPI";
import dateFormat from "dateformat";
-import {
- CustomTooltip,
- Loader,
- BlockUi
-} from "../../../components/CommonComponents";
-import moment from "moment-timezone";
+import { Loader, BlockUi } from "../../../components/CommonComponents";
import CustomBreadcrumb from "../../CustomBreadcrumb";
import {
getTableSortBy,
getTableSortType,
- serverError
+ serverError,
+ parseSearchFilter
} from "../../../utils/XAUtils";
const RequestListing = () => {
@@ -51,6 +47,78 @@ const RequestListing = () => {
state && state.showLastPage ? state.addPageData.totalPage : 0
);
const { state } = useLocation();
+ const [searchParams, setSearchParams] = useSearchParams();
+ const [defaultSearchFilterParams, setDefaultSearchFilterParams] = useState(
+ []
+ );
+
+ const searchFilterOptions = [
+ {
+ category: "dataShareNamePartial",
+ label: "Datashare Name",
+ urlLabel: "dataShareNamePartial",
+ type: "text"
+ },
+ {
+ category: "datasetNamePartial",
+ label: "Dataset Name",
+ urlLabel: "datasetNamePartial",
+ type: "text"
+ },
+ {
+ category: "shareStatus",
+ label: "Status",
+ urlLabel: "shareStatus",
+ type: "textoptions",
+ options: () => {
+ return [
+ { value: "REQUESTED", label: "REQUESTED" },
+ { value: "GRANTED", label: "GRANTED" },
+ { value: "ACTIVE", label: "ACTIVE" },
+ { value: "DENIED", label: "DENIED" }
+ ];
+ }
+ },
+ {
+ category: "createdBy",
+ label: "Requested By",
+ urlLabel: "createdBy",
+ type: "text"
+ },
+ {
+ category: "approver",
+ label: "Approved By",
+ urlLabel: "approver",
+ type: "text"
+ }
+ ];
+
+ useEffect(() => {
+ let searchFilterParam = {};
+ let searchParam = {};
+ let defaultSearchFilterParam = [];
+
+ // Get Search Filter Params from current search params
+ const currentParams = Object.fromEntries([...searchParams]);
+ for (const param in currentParams) {
+ let category = param;
+ let value = currentParams[param];
+ searchFilterParam[category] = value;
+ defaultSearchFilterParam.push({
+ category: category,
+ value: value
+ });
+ }
+ setSearchParams({ ...currentParams, ...searchParam });
+ if (
+ JSON.stringify(searchFilterParams) !== JSON.stringify(searchFilterParam)
+ ) {
+ setSearchFilterParams(searchFilterParam);
+ }
+ setDefaultSearchFilterParams(defaultSearchFilterParam);
+ setContentLoader(false);
+ localStorage.setItem("newDataAdded", state && state.showLastPage);
+ }, [searchParams]);
const fetchRequestList = useCallback(
async ({ pageSize, pageIndex, sortBy, gotoPage }) => {
@@ -77,14 +145,14 @@ const RequestListing = () => {
}
try {
resp = await fetchApi({
- url: "gds/datashare/dataset",
+ url: "gds/datashare/dataset/summary",
params: params
});
requestList = resp.data.list;
totalCount = resp.data.totalCount;
} catch (error) {
serverError(error);
- console.error(`Error occurred while fetching Dataset list!
${error}`);
+ console.error(`Error occurred while fetching Request list!
${error}`);
}
setRequestListData(requestList);
setEntries(resp.data);
@@ -103,7 +171,7 @@ const RequestListing = () => {
const columns = React.useMemo(
() => [
{
- Header: "Id",
+ Header: "ID",
accessor: "id",
width: 80,
disableResizing: true,
@@ -135,16 +203,16 @@ const RequestListing = () => {
}
},
{
- Header: "Name",
- accessor: "name",
+ Header: "For Datashare",
+ accessor: "dataShareName",
width: 250,
disableResizing: true,
disableSortBy: true,
getResizerProps: () => {}
},
{
- Header: "Type",
- accessor: "type",
+ Header: "Into Dataset",
+ accessor: "datasetName",
width: 250,
disableResizing: true,
disableSortBy: true,
@@ -152,12 +220,28 @@ const RequestListing = () => {
},
{
Header: "Status",
- accessor: "status",
+ accessor: "shareStatus",
width: 108,
disableResizing: true,
disableSortBy: true,
getResizerProps: () => {}
},
+ {
+ Header: "Requested By",
+ accessor: "createdBy",
+ width: 100,
+ disableResizing: true,
+ disableSortBy: true,
+ getResizerProps: () => {}
+ },
+ {
+ Header: "Approved By",
+ accessor: "approver",
+ width: 250,
+ disableResizing: true,
+ disableSortBy: true,
+ getResizerProps: () => {}
+ },
{
Header: "Created",
accessor: "createTime",
@@ -177,22 +261,6 @@ const RequestListing = () => {
width: 170,
disableResizing: true,
getResizerProps: () => {}
- },
- {
- Header: "Created By",
- accessor: "createdBy",
- width: 100,
- disableResizing: true,
- disableSortBy: true,
- getResizerProps: () => {}
- },
- {
- Header: "Approver",
- accessor: "approvedBy",
- width: 250,
- disableResizing: true,
- disableSortBy: true,
- getResizerProps: () => {}
}
],
[]
@@ -208,6 +276,19 @@ const RequestListing = () => {
[]
);
+ const updateSearchFilter = (filter) => {
+ let { searchFilterParam, searchParam } = parseSearchFilter(
+ filter,
+ searchFilterOptions
+ );
+ setSearchFilterParams(searchFilterParam);
+ setSearchParams(searchParam);
+
+ if (typeof resetPage?.page === "function") {
+ resetPage.page(0);
+ }
+ };
+
return contentLoader ? (
<Loader />
) : (
@@ -224,9 +305,9 @@ const RequestListing = () => {
<StructuredFilter
key="user-listing-search-filter"
placeholder="Search..."
- //options={sortBy(searchFilterOptions, ["label"])}
- //onChange={updateSearchFilter}
- //defaultSelected={defaultSearchFilterParams}
+ options={searchFilterOptions}
+ onChange={updateSearchFilter}
+ defaultSelected={defaultSearchFilterParams}
/>
</Col>
</Row>