This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new d29c2a471 RANGER-4010: updated react UI to support multiple 
resource-sets in policies
d29c2a471 is described below

commit d29c2a471be3c4fc46016378b946b75400569a77
Author: Dhaval.Rajpara <dhavalrajpara1...@gmail.com>
AuthorDate: Thu Oct 26 02:23:18 2023 -0700

    RANGER-4010: updated react UI to support multiple resource-sets in policies
    
    Signed-off-by: Madhan Neethiraj <mad...@apache.org>
---
 .../react-webapp/src/components/Editable.jsx       |  16 +-
 .../main/webapp/react-webapp/src/styles/style.css  |   5 +
 .../webapp/react-webapp/src/utils/XAMessages.js    |   4 +-
 .../main/webapp/react-webapp/src/utils/XAUtils.js  |  28 +-
 .../AuditEvent/AdminLogs/PolicyViewDetails.jsx     | 179 +++++----
 .../views/PolicyListing/AddUpdatePolicyForm.jsx    | 430 +++++++++++++++------
 .../views/PolicyListing/PolicyConditionsComp.jsx   |   2 +-
 .../src/views/PolicyListing/PolicyListing.jsx      |  15 +-
 .../views/PolicyListing/PolicyPermissionItem.jsx   | 106 +++--
 .../src/views/Resources/ModalResourceComp.jsx      |   1 +
 .../src/views/Resources/ResourceComp.jsx           |  66 ++--
 .../src/views/Resources/ResourceSelectComp.jsx     |  20 +-
 .../src/views/SecurityZone/SecurityZoneForm.jsx    |   1 -
 .../views/ServiceManager/ServiceAuditFilter.jsx    |   1 -
 14 files changed, 571 insertions(+), 303 deletions(-)

diff --git 
a/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx 
b/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx
index eab4060d0..98495f6cc 100644
--- a/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx
@@ -57,7 +57,7 @@ const CheckboxComp = (props) => {
     setVal(val);
   };
 
-  const handleAllChekced = (e) => {
+  const handleAllChecked = (e) => {
     let val = [];
     if (e.target.checked) {
       val = [...options];
@@ -92,7 +92,7 @@ const CheckboxComp = (props) => {
             checked={isAllChecked()}
             type="checkbox"
             label={selectAllLabel}
-            onChange={(e) => handleAllChekced(e)}
+            onChange={(e) => handleAllChecked(e)}
           />
         </Form.Group>
       )}
@@ -126,7 +126,7 @@ const RadioBtnComp = (props) => {
   ));
 };
 
-const InputboxComp = (props) => {
+const InputBoxComp = (props) => {
   const { value = "", valRef } = props;
   const [selectedInputVal, setInputVal] = useState(value);
   const handleChange = (e) => {
@@ -160,7 +160,7 @@ const CustomCondition = (props) => {
   return (
     <>
       {conditionDefVal?.length > 0 &&
-        conditionDefVal.map((m) => {
+        conditionDefVal.map((m, index) => {
           let uiHintAttb =
             m.uiHint != undefined && m.uiHint != "" ? JSON.parse(m.uiHint) : 
"";
           if (uiHintAttb != "") {
@@ -249,7 +249,7 @@ const CustomCondition = (props) => {
                           position="right"
                           message={
                             <p className="pd-10">
-                              {RegexMessage.MESSAGE.policyconditioninfoicon}
+                              {RegexMessage.MESSAGE.policyConditionInfoIcon}
                             </p>
                           }
                         />
@@ -312,7 +312,7 @@ const CustomCondition = (props) => {
   );
 };
 
-const innitialState = (props) => {
+const initialState = (props) => {
   const { type, selectProps, value } = props;
   let val = value;
   if (!val) {
@@ -369,7 +369,7 @@ const Editable = (props) => {
     state: false,
     errorMSG: ""
   });
-  const [state, dispatch] = useReducer(reducer, props, innitialState);
+  const [state, dispatch] = useReducer(reducer, props, initialState);
   const { show, value, target } = state;
   let isListenerAttached = false;
 
@@ -714,7 +714,7 @@ const Editable = (props) => {
         ) : type === TYPE_RADIO ? (
           <RadioBtnComp value={value} options={options} valRef={selectValRef} 
/>
         ) : type === TYPE_INPUT ? (
-          <InputboxComp value={value} valRef={selectValRef} />
+          <InputBoxComp value={value} valRef={selectValRef} />
         ) : type === TYPE_CUSTOM ? (
           <CustomCondition
             value={value}
diff --git a/security-admin/src/main/webapp/react-webapp/src/styles/style.css 
b/security-admin/src/main/webapp/react-webapp/src/styles/style.css
index b29d23b12..46e8eeda1 100644
--- a/security-admin/src/main/webapp/react-webapp/src/styles/style.css
+++ b/security-admin/src/main/webapp/react-webapp/src/styles/style.css
@@ -2554,3 +2554,8 @@ li.list-group-item:hover {
 .text-word-break {
   word-break: break-all;
 }
+.resource-block {
+  padding: 0.5rem 0;
+  border-bottom: 1px solid #dddddd;
+  margin:1rem 2rem;
+}
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js 
b/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js
index aae75199b..d22ecfa7c 100644
--- a/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js
+++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js
@@ -21,7 +21,7 @@ import React from "react";
 
 export const RegexMessage = {
   MESSAGE: {
-    policynameinfoiconmessage:
+    policyNameInfoIconMessage:
       "Please avoid these characters (&, <, >, ', \", `) for policy name.",
     userNameValidationMsg: (
       <>
@@ -49,7 +49,7 @@ export const RegexMessage = {
         </p>
       </>
     ),
-    policyconditioninfoicon:
+    policyConditionInfoIcon:
       "1. JavaScript Condition Examples :\
                       country_code == 'USA', time_range >= 900 time_range <= 
1800 etc.\
                       2. Dragging bottom-right corner of javascript condition 
editor(Textarea) can resizable",
diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js 
b/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
index 20dece45f..93629855c 100644
--- a/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
+++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
@@ -19,7 +19,13 @@
 
 import React, { useState } from "react";
 import { getUserProfile } from "Utils/appState";
-import { UserRoles, PathAssociateWithModule, QueryParams } from 
"Utils/XAEnums";
+import {
+  UserRoles,
+  PathAssociateWithModule,
+  QueryParams,
+  RangerPolicyType,
+  ServiceType
+} from "Utils/XAEnums";
 import {
   filter,
   find,
@@ -34,7 +40,8 @@ import {
   isUndefined,
   isNull,
   some,
-  has
+  has,
+  sortBy
 } from "lodash";
 import { matchRoutes } from "react-router-dom";
 import dateFormat from "dateformat";
@@ -43,7 +50,6 @@ import CustomBreadcrumb from "../views/CustomBreadcrumb";
 import { CustomTooltip } from "../components/CommonComponents";
 import InfiniteScroll from "react-infinite-scroll-component";
 import { toast } from "react-toastify";
-import { RangerPolicyType, ServiceType } from "./XAEnums";
 import { policyInfoMessage } from "./XAMessages";
 import { fetchApi } from "Utils/fetchAPI";
 
@@ -1436,3 +1442,19 @@ export const policyConditionUpdatedJSON = (policyCond) 
=> {
   });
   return newPolicyConditionJSON;
 };
+
+// Get resources with help of policy type
+
+export const getResourcesDefVal = (serviceDef, policyType) => {
+  let resources = [];
+  if (RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value == policyType) {
+    resources = sortBy(serviceDef.dataMaskDef.resources, "itemId");
+  } else if (
+    RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value == policyType
+  ) {
+    resources = sortBy(serviceDef.rowFilterDef.resources, "itemId");
+  } else {
+    resources = sortBy(serviceDef.resources, "itemId");
+  }
+  return resources;
+};
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/PolicyViewDetails.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/PolicyViewDetails.jsx
index 7d18afbcc..aa541bf72 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/PolicyViewDetails.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/PolicyViewDetails.jsx
@@ -23,8 +23,8 @@ import { Table, Badge, Row, Col } from "react-bootstrap";
 import { RangerPolicyType, DefStatus } from "../../../utils/XAEnums";
 import dateFormat from "dateformat";
 import { toast } from "react-toastify";
-import { find, isEmpty, sortBy } from "lodash";
-import { serverError } from "../../../utils/XAUtils";
+import { find, isEmpty, map, sortBy } from "lodash";
+import { getResourcesDefVal, serverError } from "../../../utils/XAUtils";
 import { ModalLoader } from "../../../components/CommonComponents";
 import { getServiceDef } from "../../../utils/appState";
 
@@ -34,6 +34,7 @@ export function PolicyViewDetails(props) {
   const [serviceDef, setServiceDef] = useState({});
   const { updateServices } = props;
   let { allServiceDefs } = getServiceDef();
+  const isMultiResources = true;
 
   useEffect(() => {
     if (props.paramsData.isRevert) {
@@ -42,7 +43,7 @@ export function PolicyViewDetails(props) {
       if (props.paramsData.isChangeVersion) {
         fetchByVersion();
       } else {
-        fetchInitalData();
+        fetchInitialData();
       }
     }
   }, [
@@ -50,7 +51,7 @@ export function PolicyViewDetails(props) {
       ? props.paramsData.isRevert
       : props.paramsData.version || props.paramsData.policyVersion
   ]);
-  const fetchInitalData = async () => {
+  const fetchInitialData = async () => {
     await fetchByEventTime();
   };
 
@@ -144,8 +145,70 @@ export function PolicyViewDetails(props) {
     createdBy,
     createTime,
     validitySchedules,
-    zoneName
+    zoneName,
+    additionalResources
   } = access;
+  let additionalResourcesVal = [];
+  if (isMultiResources) {
+    additionalResourcesVal = [resources, ...(additionalResources || [])];
+  }
+
+  const getPolicyResources = (policyType, resourceval) => {
+    var filterResources = [];
+    let serviceTypeData = serviceDef;
+    var resourceDef = getResourcesDefVal(serviceTypeData, policyType);
+    for (let key in resourceval) {
+      let filterResourcesVal = find(resourceDef, { name: key });
+      let resource = {};
+      resource.label = filterResourcesVal && filterResourcesVal.label;
+      resource.level = filterResourcesVal && filterResourcesVal.level;
+      resource.values = resourceval[key].values;
+      if (filterResourcesVal && filterResourcesVal.recursiveSupported) {
+        resource.Rec_Recursive = resourceval[key].isRecursive
+          ? DefStatus.RecursiveStatus.STATUS_RECURSIVE.label
+          : DefStatus.RecursiveStatus.STATUS_NONRECURSIVE.label;
+      }
+      if (filterResourcesVal && filterResourcesVal.excludesSupported) {
+        resource.Rec_Exc = resourceval[key].isExcludes
+          ? DefStatus.ExcludeStatus.STATUS_EXCLUDE.label
+          : DefStatus.ExcludeStatus.STATUS_INCLUDE.label;
+      }
+      filterResources.push(resource);
+    }
+    return (
+      <>
+        {sortBy(filterResources, "level").map((obj) => (
+          <tr key={obj.level}>
+            <td>{obj.label}</td>
+            <td>
+              <Row>
+                <Col>
+                  {obj.values.map((val, index) => (
+                    <h6 className="d-inline mr-1" key={index}>
+                      <Badge className="d-inline mr-1" variant="info" 
key={val}>
+                        {val}
+                      </Badge>
+                    </h6>
+                  ))}
+                </Col>
+                <Col className="text-right">
+                  <h6 className="d-inline mr-1">
+                    <Badge variant="dark text-capitalize">{obj.Rec_Exc}</Badge>
+                  </h6>
+
+                  <h6 className="d-inline mr-1">
+                    <Badge variant="dark text-capitalize">
+                      {obj.Rec_Recursive}
+                    </Badge>
+                  </h6>
+                </Col>
+              </Row>
+            </td>
+          </tr>
+        ))}
+      </>
+    );
+  };
 
   const getPolicyDetails = () => {
     const getPolicyType = (policyTypeVal) => {
@@ -207,78 +270,6 @@ export function PolicyViewDetails(props) {
       );
     };
 
-    const getPolicyResources = (policyType, resourceval) => {
-      var resourceDef;
-      var filterResources = [];
-      let serviceTypeData = serviceDef;
-      if (policyType == RangerPolicyType.RANGER_ACCESS_POLICY_TYPE.value) {
-        resourceDef = serviceTypeData && serviceTypeData.resources;
-      }
-      if (policyType == RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value) {
-        resourceDef = serviceTypeData && serviceTypeData.dataMaskDef.resources;
-      }
-      if (policyType == RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value) {
-        resourceDef = serviceTypeData && 
serviceTypeData.rowFilterDef.resources;
-      }
-      for (let key in resourceval) {
-        let filterResourcesVal = find(resourceDef, { name: key });
-        let resource = {};
-        resource.label = filterResourcesVal && filterResourcesVal.label;
-        resource.level = filterResourcesVal && filterResourcesVal.level;
-        resource.values = resourceval[key].values;
-        if (filterResourcesVal && filterResourcesVal.recursiveSupported) {
-          resource.Rec_Recursive = resourceval[key].isRecursive
-            ? DefStatus.RecursiveStatus.STATUS_RECURSIVE.label
-            : DefStatus.RecursiveStatus.STATUS_NONRECURSIVE.label;
-        }
-        if (filterResourcesVal && filterResourcesVal.excludesSupported) {
-          resource.Rec_Exc = resourceval[key].isExcludes
-            ? DefStatus.ExcludeStatus.STATUS_EXCLUDE.label
-            : DefStatus.ExcludeStatus.STATUS_INCLUDE.label;
-        }
-        filterResources.push(resource);
-      }
-      return (
-        <>
-          {sortBy(filterResources, "level").map((obj) => (
-            <tr key={obj.level}>
-              <td>{obj.label}</td>
-              <td>
-                <Row>
-                  <Col>
-                    {obj.values.map((val, index) => (
-                      <h6 className="d-inline mr-1" key={index}>
-                        <Badge
-                          className="d-inline mr-1"
-                          variant="info"
-                          key={val}
-                        >
-                          {val}
-                        </Badge>
-                      </h6>
-                    ))}
-                  </Col>
-                  <Col className="text-right">
-                    <h6 className="d-inline mr-1">
-                      <Badge variant="dark text-capitalize">
-                        {obj.Rec_Exc}
-                      </Badge>
-                    </h6>
-
-                    <h6 className="d-inline mr-1">
-                      <Badge variant="dark text-capitalize">
-                        {obj.Rec_Recursive}
-                      </Badge>
-                    </h6>
-                  </Col>
-                </Row>
-              </td>
-            </tr>
-          ))}
-        </>
-      );
-    };
-
     return loader ? (
       <ModalLoader />
     ) : (
@@ -323,7 +314,7 @@ export function PolicyViewDetails(props) {
               : "--"}
           </td>
         </tr>
-        {getPolicyResources(policyType, resources)}
+        {!isMultiResources && getPolicyResources(policyType, resources)}
         <tr>
           <td className="text-nowrap">Description</td>
           <td>{!isEmpty(description) ? description : "--"}</td>
@@ -547,7 +538,7 @@ export function PolicyViewDetails(props) {
     return tableRow;
   };
 
-  const getPolicyConditions = (conditions, serviceDef, serviceType) => {
+  const getPolicyConditions = (conditions, serviceDef) => {
     let filterServiceDef = serviceDef;
     const getConditionLabel = (label) => {
       let filterLabel = "";
@@ -631,6 +622,7 @@ export function PolicyViewDetails(props) {
       )
     );
   };
+
   return loader ? (
     <ModalLoader />
   ) : (
@@ -653,16 +645,41 @@ export function PolicyViewDetails(props) {
           <tbody>{getPolicyDetails(serviceDef)}</tbody>
         </Table>
       </div>
+      {isMultiResources && (
+        <>
+          <p className="form-header">Policy Resource :</p>
+          {additionalResourcesVal &&
+            map(additionalResourcesVal, (resourcesVal, index) => (
+              <>
+                <Table
+                  bordered
+                  size="sm"
+                  className="table-audit-filter-ready-only"
+                  key={index}
+                >
+                  <thead>
+                    <tr>
+                      <th className="text-left" colSpan={2}>
+                        #{index + 1}
+                      </th>
+                    </tr>
+                  </thead>
+                  <tbody>{getPolicyResources(policyType, resourcesVal)}</tbody>
+                </Table>
+              </>
+            ))}
+        </>
+      )}
       {(policyType == RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value ||
         RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value) &&
         !isEmpty(validitySchedules) &&
         getValidityPeriod(validitySchedules)}
       {policyType == RangerPolicyType.RANGER_ACCESS_POLICY_TYPE.value && (
-        <>{getPolicyConditions(conditions, serviceDef, serviceType)}</>
+        <>{getPolicyConditions(conditions, serviceDef)}</>
       )}
       {policyType == RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value &&
         serviceType == "tag" && (
-          <>{getPolicyConditions(conditions, serviceDef, serviceType)}</>
+          <>{getPolicyConditions(conditions, serviceDef)}</>
         )}
 
       {policyType == RangerPolicyType.RANGER_ACCESS_POLICY_TYPE.value && (
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/AddUpdatePolicyForm.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/AddUpdatePolicyForm.jsx
index 60cc1f268..90595f1b8 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/AddUpdatePolicyForm.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/AddUpdatePolicyForm.jsx
@@ -37,12 +37,14 @@ import {
   find,
   isEmpty,
   pick,
-  isObject,
   isArray,
   isEqual,
   forIn,
   has,
-  maxBy
+  maxBy,
+  map,
+  isUndefined,
+  forEach
 } from "lodash";
 import { toast } from "react-toastify";
 import { Loader, scrollToError } from "Components/CommonComponents";
@@ -58,7 +60,8 @@ import moment from "moment";
 import {
   InfoIcon,
   commonBreadcrumb,
-  isPolicyExpired
+  isPolicyExpired,
+  getResourcesDefVal
 } from "../../utils/XAUtils";
 import { useAccordionToggle } from "react-bootstrap/AccordionToggle";
 import AccordionContext from "react-bootstrap/AccordionContext";
@@ -67,12 +70,15 @@ import { RegexMessage } from "../../utils/XAMessages";
 import { policyInfo } from "Utils/XAUtils";
 import { BlockUi } from "../../components/CommonComponents";
 import { getServiceDef } from "../../utils/appState";
+import { FieldArray } from "react-final-form-arrays";
 
 const noneOptions = {
   label: "None",
   value: "none"
 };
 
+const isMultiResources = true;
+
 const initialState = {
   loader: true,
   serviceDetails: null,
@@ -81,7 +87,7 @@ const initialState = {
   formData: {}
 };
 
-const PromtDialog = (props) => {
+const PromptDialog = (props) => {
   const { isDirtyField, isUnblock } = props;
   usePrompt("Are you sure you want to leave", isDirtyField && !isUnblock);
   return null;
@@ -109,7 +115,7 @@ const Condition = ({ when, is, children }) => (
   </Field>
 );
 
-export default function AddUpdatePolicyForm(props) {
+export default function AddUpdatePolicyForm() {
   let { serviceId, policyType, policyId } = useParams();
   const navigate = useNavigate();
   const { state } = useLocation();
@@ -127,9 +133,11 @@ export default function AddUpdatePolicyForm(props) {
   const [showDelete, setShowDelete] = useState(false);
   const [blockUI, setBlockUI] = useState(false);
   const toastId = React.useRef(null);
+  const [changePolicyItemPermissions, setChangePolicyItemPermissions] =
+    useState(false);
 
   useEffect(() => {
-    fetchInitalData();
+    fetchInitialData();
   }, []);
 
   const showDeleteModal = () => {
@@ -213,11 +221,11 @@ export default function AddUpdatePolicyForm(props) {
     }));
   };
 
-  const fetchInitalData = async () => {
+  const fetchInitialData = async () => {
     let serviceData = await fetchServiceDetails();
 
-    let serviceCompData = serviceDefs?.allServiceDefs?.find((servicedef) => {
-      return servicedef.name == serviceData.type;
+    let serviceCompData = serviceDefs?.allServiceDefs?.find((serviceDef) => {
+      return serviceDef.name == serviceData.type;
     });
     if (serviceCompData) {
       let serviceDefPolicyType = 0;
@@ -359,6 +367,20 @@ export default function AddUpdatePolicyForm(props) {
             serviceCompData
           )
         : [{}];
+    let serviceCompResourcesDetails = getResourcesDefVal(
+      serviceCompData,
+      data.policyType
+    );
+    if (serviceCompResourcesDetails) {
+      forEach(serviceCompResourcesDetails, (val) => {
+        if (
+          val.accessTypeRestrictions &&
+          val.accessTypeRestrictions.length > 0
+        ) {
+          setChangePolicyItemPermissions(true);
+        }
+      });
+    }
     if (policyId) {
       data.policyName = policyData?.name;
       data.isEnabled = policyData?.isEnabled;
@@ -370,51 +392,91 @@ export default function AddUpdatePolicyForm(props) {
         policyData?.policyLabels?.map((val) => {
           return { label: val, value: val };
         });
-      let serviceCompResourcesDetails;
-      if (
-        RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value ==
-        policyData?.policyType
-      ) {
-        serviceCompResourcesDetails = serviceCompData?.dataMaskDef?.resources;
-      } else if (
-        RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value ==
-        policyData?.policyType
-      ) {
-        serviceCompResourcesDetails = serviceCompData?.rowFilterDef?.resources;
-      } else {
-        serviceCompResourcesDetails = serviceCompData?.resources;
-      }
       if (policyData?.resources) {
-        let lastResourceLevel = [];
-        Object.entries(policyData?.resources).map(([key, value]) => {
-          let setResources = find(serviceCompResourcesDetails, ["name", key]);
-          data[`resourceName-${setResources?.level}`] = setResources;
-          data[`value-${setResources?.level}`] = value.values.map((m) => {
-            return { label: m, value: m };
+        if (!isMultiResources) {
+          let lastResourceLevel = [];
+          Object.entries(policyData?.resources).map(([key, value]) => {
+            let setResources = find(serviceCompResourcesDetails, ["name", 
key]);
+            data[`resourceName-${setResources?.level}`] = setResources;
+            data[`value-${setResources?.level}`] = value.values.map((m) => {
+              return { label: m, value: m };
+            });
+            if (setResources?.excludesSupported) {
+              data[`isExcludesSupport-${setResources?.level}`] =
+                value.isExcludes == false;
+            }
+            if (setResources?.recursiveSupported) {
+              data[`isRecursiveSupport-${setResources?.level}`] =
+                value?.isRecursive;
+            }
+            lastResourceLevel.push({
+              level: setResources.level,
+              name: setResources.name
+            });
           });
-          if (setResources?.excludesSupported) {
-            data[`isExcludesSupport-${setResources?.level}`] =
-              value.isExcludes == false;
+          lastResourceLevel = maxBy(lastResourceLevel, "level");
+          let setLastResources = find(serviceCompResourcesDetails, [
+            "parent",
+            lastResourceLevel.name
+          ]);
+          if (setLastResources && setLastResources?.isValidLeaf) {
+            data[`resourceName-${setLastResources.level}`] = {
+              label: "None",
+              value: "none"
+            };
           }
-          if (setResources?.recursiveSupported) {
-            data[`isRecursiveSupport-${setResources?.level}`] =
-              value?.isRecursive;
+        } else {
+          if (policyData.additionalResources || policyData.resources) {
+            policyData.additionalResources = [
+              policyData.resources,
+              ...(policyData.additionalResources || [])
+            ];
+            data.additionalResources = [];
+            map(policyData.additionalResources, function (resourceObj) {
+              let lastResourceLevel = [],
+                additionalResourcesObj = {};
+              Object.entries(resourceObj).map(([key, value]) => {
+                let setResources = find(serviceCompResourcesDetails, [
+                  "name",
+                  key
+                ]);
+                additionalResourcesObj[`resourceName-${setResources?.level}`] =
+                  setResources;
+                additionalResourcesObj[`value-${setResources?.level}`] =
+                  value.values.map((m) => {
+                    return { label: m, value: m };
+                  });
+                if (setResources?.excludesSupported) {
+                  additionalResourcesObj[
+                    `isExcludesSupport-${setResources?.level}`
+                  ] = value.isExcludes == false;
+                }
+                if (setResources?.recursiveSupported) {
+                  additionalResourcesObj[
+                    `isRecursiveSupport-${setResources?.level}`
+                  ] = value?.isRecursive;
+                }
+                lastResourceLevel.push({
+                  level: setResources.level,
+                  name: setResources.name
+                });
+              });
+              lastResourceLevel = maxBy(lastResourceLevel, "level");
+              let setLastResources = find(serviceCompResourcesDetails, [
+                "parent",
+                lastResourceLevel.name
+              ]);
+              if (setLastResources && setLastResources?.isValidLeaf) {
+                additionalResourcesObj[
+                  `resourceName-${setLastResources.level}`
+                ] = {
+                  label: "None",
+                  value: "none"
+                };
+              }
+              data.additionalResources.push(additionalResourcesObj);
+            });
           }
-          lastResourceLevel.push({
-            level: setResources.level,
-            name: setResources.name
-          });
-        });
-        lastResourceLevel = maxBy(lastResourceLevel, "level");
-        let setLastResources = find(serviceCompResourcesDetails, [
-          "parent",
-          lastResourceLevel.name
-        ]);
-        if (setLastResources && setLastResources?.isValidLeaf) {
-          data[`resourceName-${setLastResources.level}`] = {
-            label: "None",
-            value: "none"
-          };
         }
       }
       if (policyData?.validitySchedules) {
@@ -439,7 +501,6 @@ export default function AddUpdatePolicyForm(props) {
       /* Policy condition */
       if (policyData?.conditions?.length > 0) {
         data.conditions = {};
-
         for (let val of policyData.conditions) {
           let conditionObj = find(
             policyConditionUpdatedJSON(serviceCompData?.policyConditions),
@@ -459,6 +520,9 @@ export default function AddUpdatePolicyForm(props) {
         }
       }
     }
+    if (isMultiResources && isUndefined(data.additionalResources)) {
+      data.additionalResources = [{}];
+    }
     data.isDenyAllElse = policyData?.isDenyAllElse || false;
     return data;
   };
@@ -573,8 +637,8 @@ export default function AddUpdatePolicyForm(props) {
         }
         let tableList = [];
         let tagAccessType = groupBy(accessTypesObj, function (m) {
-          let tagval = m;
-          return tagval.substr(0, tagval.indexOf(":"));
+          let tagVal = m;
+          return tagVal.substr(0, tagVal.indexOf(":"));
         });
         for (let tagObjData in tagAccessType) {
           tableList.push({
@@ -689,17 +753,10 @@ export default function AddUpdatePolicyForm(props) {
     data.service = serviceDetails.name;
     let serviceCompRes;
     if (values.policyType != null) {
-      if (
-        values.policyType == RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value
-      )
-        serviceCompRes = serviceCompDetails.dataMaskDef.resources;
-      if (
-        values.policyType ==
-        RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value
-      )
-        serviceCompRes = serviceCompDetails.rowFilterDef.resources;
-      if (values.policyType == 
RangerPolicyType.RANGER_ACCESS_POLICY_TYPE.value)
-        serviceCompRes = serviceCompDetails.resources;
+      serviceCompRes = getResourcesDefVal(
+        serviceCompDetails,
+        values.policyType
+      );
     }
     const grpResources = groupBy(serviceCompRes || [], "level");
     let grpResourcesKeys = [];
@@ -708,28 +765,80 @@ export default function AddUpdatePolicyForm(props) {
     }
     grpResourcesKeys = grpResourcesKeys.sort();
     data.resources = {};
-    for (const level of grpResourcesKeys) {
-      if (
-        values[`resourceName-${level}`] &&
-        values[`resourceName-${level}`].value !== noneOptions.value
-      ) {
-        let defObj = serviceCompRes.find(function (m) {
-          if (m.name == values[`resourceName-${level}`].name) {
-            return m;
+    if (!isMultiResources) {
+      for (const level of grpResourcesKeys) {
+        if (
+          values[`resourceName-${level}`] &&
+          values[`resourceName-${level}`].value !== noneOptions.value
+        ) {
+          let defObj = serviceCompRes.find(function (m) {
+            if (m.name == values[`resourceName-${level}`].name) {
+              return m;
+            }
+          });
+          data.resources[values[`resourceName-${level}`].name] = {
+            values: isArray(values[`value-${level}`])
+              ? values[`value-${level}`]?.map(({ value }) => value)
+              : [values[`value-${level}`].value]
+          };
+          if (defObj?.excludesSupported) {
+            data.resources[values[`resourceName-${level}`].name]["isExcludes"] 
=
+              defObj.excludesSupported &&
+              values[`isExcludesSupport-${level}`] == false;
           }
-        });
-        data.resources[values[`resourceName-${level}`].name] = {
-          isExcludes:
-            defObj.excludesSupported &&
-            values[`isExcludesSupport-${level}`] == false,
-          isRecursive:
-            defObj.recursiveSupported &&
-            !(values[`isRecursiveSupport-${level}`] === false),
-          values: isArray(values[`value-${level}`])
-            ? values[`value-${level}`]?.map(({ value }) => value)
-            : [values[`value-${level}`].value]
-        };
+          if (defObj?.recursiveSupported) {
+            data.resources[values[`resourceName-${level}`].name][
+              "isRecursive"
+            ] =
+              defObj.recursiveSupported &&
+              !(values[`isRecursiveSupport-${level}`] === false);
+          }
+        }
       }
+    } else {
+      data["additionalResources"] = [];
+      map(values.additionalResources, (resourceValue) => {
+        let additionalResourcesObj = {};
+        for (const level of grpResourcesKeys) {
+          if (
+            resourceValue[`resourceName-${level}`] &&
+            resourceValue[`resourceName-${level}`].value !== noneOptions.value
+          ) {
+            let defObj = serviceCompRes.find(function (m) {
+              if (m.name == resourceValue[`resourceName-${level}`].name) {
+                return m;
+              }
+            });
+
+            additionalResourcesObj[
+              resourceValue[`resourceName-${level}`].name
+            ] = {
+              values: isArray(resourceValue[`value-${level}`])
+                ? resourceValue[`value-${level}`]?.map(({ value }) => value)
+                : [resourceValue[`value-${level}`].value]
+            };
+            if (defObj?.excludesSupported) {
+              additionalResourcesObj[
+                resourceValue[`resourceName-${level}`].name
+              ]["isExcludes"] =
+                defObj.excludesSupported &&
+                resourceValue[`isExcludesSupport-${level}`] == false;
+            }
+            if (defObj?.recursiveSupported) {
+              additionalResourcesObj[
+                resourceValue[`resourceName-${level}`].name
+              ]["isRecursive"] =
+                defObj.recursiveSupported &&
+                !(resourceValue[`isRecursiveSupport-${level}`] === false);
+            }
+          }
+        }
+        data["additionalResources"].push(additionalResourcesObj);
+      });
+    }
+    if (data?.additionalResources?.length > 0) {
+      data.resources = data.additionalResources[0];
+      data.additionalResources.shift();
     }
     if (values?.validitySchedules) {
       data["validitySchedules"] = [];
@@ -908,19 +1017,10 @@ export default function AddUpdatePolicyForm(props) {
   };
 
   const resourceErrorCheck = (errors, values) => {
-    let serviceCompResourcesDetails;
-    if (
-      RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value == values.policyType
-    ) {
-      serviceCompResourcesDetails = serviceCompDetails.dataMaskDef.resources;
-    } else if (
-      RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value == values.policyType
-    ) {
-      serviceCompResourcesDetails = serviceCompDetails.rowFilterDef.resources;
-    } else {
-      serviceCompResourcesDetails = serviceCompDetails.resources;
-    }
-
+    let serviceCompResourcesDetails = getResourcesDefVal(
+      serviceCompDetails,
+      values.policyType
+    );
     const grpResources = groupBy(serviceCompResourcesDetails || [], "level");
     let grpResourcesKeys = [];
     for (const resourceKey in grpResources) {
@@ -928,8 +1028,14 @@ export default function AddUpdatePolicyForm(props) {
     }
     grpResourcesKeys = grpResourcesKeys.sort();
     for (const key of grpResourcesKeys) {
-      if (errors[`value-${key}`] !== undefined) {
-        return true;
+      if (isMultiResources) {
+        if (errors?.additionalResources?.length > 0) {
+          return true;
+        }
+      } else {
+        if (errors[`value-${key}`] !== undefined) {
+          return true;
+        }
       }
     }
   };
@@ -1020,21 +1126,19 @@ export default function AddUpdatePolicyForm(props) {
               }}
               render={({
                 handleSubmit,
-                submitting,
                 values,
                 invalid,
                 errors,
                 dirty,
                 form: {
-                  mutators: { push: addPolicyItem, pop: removePolicyItem, move 
}
+                  mutators: { push: addPolicyItem, pop: removePolicyItem }
                 },
-                form,
                 dirtyFields,
                 modified,
                 initialValues
               }) => (
                 <>
-                  <PromtDialog
+                  <PromptDialog
                     isDirtyField={
                       dirty == true || !isEqual(initialValues, values)
                         ? isDirtyFieldCheck(
@@ -1105,7 +1209,7 @@ export default function AddUpdatePolicyForm(props) {
                         </Alert>
                       )}
                     <fieldset>
-                      <p className="formHeader">Policy Details</p>
+                      <p className="formHeader">Policy Details : </p>
                     </fieldset>
                     <Row className="user-role-grp-form">
                       <Col md={8}>
@@ -1195,7 +1299,7 @@ export default function AddUpdatePolicyForm(props) {
                                         >
                                           {
                                             RegexMessage.MESSAGE
-                                              .policynameinfoiconmessage
+                                              .policyNameInfoIconMessage
                                           }
                                         </p>
                                       }
@@ -1278,16 +1382,17 @@ export default function AddUpdatePolicyForm(props) {
                             </FormB.Group>
                           )}
                         />
-                        <ResourceComp
-                          serviceDetails={serviceDetails}
-                          serviceCompDetails={serviceCompDetails}
-                          formValues={values}
-                          policyType={
-                            policyId ? policyData.policyType : policyType
-                          }
-                          policyItem={true}
-                          policyId={policyId}
-                        />
+                        {!isMultiResources && (
+                          <ResourceComp
+                            serviceDetails={serviceDetails}
+                            serviceCompDetails={serviceCompDetails}
+                            formValues={values}
+                            policyType={
+                              policyId ? policyData.policyType : policyType
+                            }
+                            policyId={policyId}
+                          />
+                        )}
                         <Field
                           className="form-control"
                           name="description"
@@ -1388,7 +1493,7 @@ export default function AddUpdatePolicyForm(props) {
                                   {values?.conditions &&
                                   !isEmpty(values.conditions) ? (
                                     Object.keys(values.conditions).map(
-                                      (keyName, keyIndex) => {
+                                      (keyName) => {
                                         if (
                                           values.conditions[keyName] != "" &&
                                           values.conditions[keyName] != null
@@ -1442,7 +1547,64 @@ export default function AddUpdatePolicyForm(props) {
                         )}
                       </Col>
                     </Row>
-                    {/* ------------------------------------------------- */}
+                    {/* --------------------- Multiple Resources 
---------------------------- */}
+                    {isMultiResources && (
+                      <>
+                        <fieldset>
+                          <p className="formHeader">Resources :</p>
+                        </fieldset>
+                        <>
+                          <FieldArray name="additionalResources">
+                            {({ fields }) =>
+                              fields.map((name, index) => (
+                                <Row className="resource-block">
+                                  <Col md={8}>
+                                    <ResourceComp
+                                      serviceDetails={serviceDetails}
+                                      serviceCompDetails={serviceCompDetails}
+                                      formValues={
+                                        values.additionalResources[index]
+                                      }
+                                      policyType={policyType}
+                                      name={name}
+                                      isMultiResources={isMultiResources}
+                                    />
+                                  </Col>
+                                  {values.additionalResources.length > 1 && (
+                                    <Col md={4}>
+                                      <Button
+                                        variant="danger"
+                                        size="sm"
+                                        title="Remove"
+                                        onClick={() => fields.remove(index)}
+                                        data-action="delete"
+                                        data-cy="delete"
+                                      >
+                                        <i className="fa-fw fa fa-remove"></i>
+                                      </Button>
+                                    </Col>
+                                  )}
+                                </Row>
+                              ))
+                            }
+                          </FieldArray>
+                          <div className="wrap">
+                            <Button
+                              type="button"
+                              className="btn-mini"
+                              onClick={() =>
+                                addPolicyItem("additionalResources", {})
+                              }
+                              data-action="addTime"
+                              data-cy="addTime"
+                            >
+                              <i className="fa-fw fa fa-plus"></i> Add Resource
+                            </Button>
+                          </div>
+                        </>
+                      </>
+                    )}
+                    {/*----------------------- Policy Item 
--------------------------- */}
                     {values.policyType == 0 ? (
                       <div>
                         <div>
@@ -1465,6 +1627,10 @@ export default function AddUpdatePolicyForm(props) {
                                         fetchUsersData={fetchUsersData}
                                         fetchGroupsData={fetchGroupsData}
                                         fetchRolesData={fetchRolesData}
+                                        changePolicyItemPermissions={
+                                          changePolicyItemPermissions
+                                        }
+                                        isMultiResources={isMultiResources}
                                       />
                                     </div>
                                     {serviceCompDetails?.options
@@ -1489,6 +1655,10 @@ export default function AddUpdatePolicyForm(props) {
                                             fetchUsersData={fetchUsersData}
                                             fetchGroupsData={fetchGroupsData}
                                             fetchRolesData={fetchRolesData}
+                                            changePolicyItemPermissions={
+                                              changePolicyItemPermissions
+                                            }
+                                            isMultiResources={isMultiResources}
                                           />
                                         </div>
                                       </>
@@ -1554,6 +1724,10 @@ export default function AddUpdatePolicyForm(props) {
                                             fetchUsersData={fetchUsersData}
                                             fetchGroupsData={fetchGroupsData}
                                             fetchRolesData={fetchRolesData}
+                                            changePolicyItemPermissions={
+                                              changePolicyItemPermissions
+                                            }
+                                            isMultiResources={isMultiResources}
                                           />
                                         </div>
                                         <fieldset>
@@ -1574,6 +1748,10 @@ export default function AddUpdatePolicyForm(props) {
                                             fetchUsersData={fetchUsersData}
                                             fetchGroupsData={fetchGroupsData}
                                             fetchRolesData={fetchRolesData}
+                                            changePolicyItemPermissions={
+                                              changePolicyItemPermissions
+                                            }
+                                            isMultiResources={isMultiResources}
                                           />
                                         </div>
                                       </>
@@ -1605,6 +1783,10 @@ export default function AddUpdatePolicyForm(props) {
                                     fetchUsersData={fetchUsersData}
                                     fetchGroupsData={fetchGroupsData}
                                     fetchRolesData={fetchRolesData}
+                                    changePolicyItemPermissions={
+                                      changePolicyItemPermissions
+                                    }
+                                    isMultiResources={isMultiResources}
                                   />
                                 </div>
                               </>
@@ -1633,6 +1815,10 @@ export default function AddUpdatePolicyForm(props) {
                                       fetchUsersData={fetchUsersData}
                                       fetchGroupsData={fetchGroupsData}
                                       fetchRolesData={fetchRolesData}
+                                      changePolicyItemPermissions={
+                                        changePolicyItemPermissions
+                                      }
+                                      isMultiResources={isMultiResources}
                                     />
                                   </div>
                                 </>
@@ -1653,15 +1839,15 @@ export default function AddUpdatePolicyForm(props) {
                                   resourceErrorCheck(errors, values)
                                 ) {
                                   let selector =
-                                    document.getElementById("isError") ||
-                                    document.getElementById(key) ||
-                                    document.querySelector(
+                                    document?.getElementById("isError") ||
+                                    document?.getElementById(key) ||
+                                    document?.querySelector(
                                       `input[name=${key}]`
                                     ) ||
-                                    document.querySelector(
+                                    document?.querySelector(
                                       `input[id=${key}]`
                                     ) ||
-                                    document.querySelector(
+                                    document?.querySelector(
                                       `span[className="invalid-field"]`
                                     );
                                   scrollToError(selector);
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyConditionsComp.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyConditionsComp.jsx
index 47240bce6..f9aaa3a40 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyConditionsComp.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyConditionsComp.jsx
@@ -169,7 +169,7 @@ export default function PolicyConditionsComp(props) {
                                       <p className="pd-10">
                                         {
                                           RegexMessage.MESSAGE
-                                            .policyconditioninfoicon
+                                            .policyConditionInfoIcon
                                         }
                                       </p>
                                     }
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyListing.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyListing.jsx
index 6d6facb91..c1752c252 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyListing.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyListing.jsx
@@ -57,11 +57,11 @@ import {
   isSystemAdmin,
   isKeyAdmin,
   isUser,
-  parseSearchFilter
+  parseSearchFilter,
+  getResourcesDefVal
 } from "../../utils/XAUtils";
 import {
   alertMessage,
-  RangerPolicyType,
   ResourcesOverrideInfoMsg,
   ServerAttrName
 } from "../../utils/XAEnums";
@@ -668,15 +668,8 @@ function PolicyListing(props) {
     let resourceSearchOpt = [];
     let serverRsrcAttrName = [];
     let policySearchInfoMsg = [];
-    if (RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value == policyType) {
-      resources = serviceDef.dataMaskDef?.resources || [];
-    } else if (
-      RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value == policyType
-    ) {
-      resources = serviceDef.rowFilterDef?.resources || [];
-    } else {
-      resources = serviceDef?.resources || [];
-    }
+
+    resources = getResourcesDefVal(serviceDef, policyType);
 
     resourceSearchOpt = map(resources, function (resource) {
       return {
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyPermissionItem.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyPermissionItem.jsx
index 4c3f71bef..ab9b3ce88 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyPermissionItem.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/PolicyPermissionItem.jsx
@@ -23,7 +23,17 @@ import { FieldArray } from "react-final-form-arrays";
 import { Col } from "react-bootstrap";
 import { Field } from "react-final-form";
 import AsyncSelect from "react-select/async";
-import { find, groupBy, isEmpty, isArray } from "lodash";
+import {
+  find,
+  groupBy,
+  isEmpty,
+  isArray,
+  has,
+  map,
+  filter,
+  some,
+  isEqual
+} from "lodash";
 import { toast } from "react-toastify";
 import Editable from "Components/Editable";
 import { RangerPolicyType } from "Utils/XAEnums";
@@ -49,7 +59,9 @@ export default function PolicyPermissionItem(props) {
     fetchUsersData,
     fetchGroupsData,
     fetchRolesData,
-    formValues
+    formValues,
+    changePolicyItemPermissions,
+    isMultiResources
   } = props;
   const dragItem = useRef();
   const dragOverItem = useRef();
@@ -104,38 +116,70 @@ export default function PolicyPermissionItem(props) {
   }, []);
 
   const getAccessTypeOptions = () => {
-    let srcOp = [];
-    for (let i = grpResourcesKeys.length - 1; i >= 0; i--) {
-      let selectedResource = `resourceName-${grpResourcesKeys[i]}`;
-      if (
-        formValues[selectedResource] &&
-        formValues[selectedResource].value !== noneOptions.value
-      ) {
-        if (
-          RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value ==
-          formValues.policyType
-        ) {
-          srcOp = serviceCompDetails.dataMaskDef.accessTypes;
-        } else if (
-          RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value ==
-          formValues.policyType
-        ) {
-          srcOp = serviceCompDetails.rowFilterDef.accessTypes;
-        } else {
-          srcOp = serviceCompDetails.accessTypes;
-        }
-        if (formValues[selectedResource].accessTypeRestrictions?.length > 0) {
-          let op = [];
-          for (const name of formValues[selectedResource]
-            .accessTypeRestrictions) {
-            let typeOp = find(srcOp, { name });
-            if (typeOp) {
-              op.push(typeOp);
+    let srcOp = [],
+      multiplePermissionItem = [];
+    if (
+      RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value == 
formValues.policyType
+    ) {
+      srcOp = serviceCompDetails.dataMaskDef.accessTypes;
+    } else if (
+      RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value ==
+      formValues.policyType
+    ) {
+      srcOp = serviceCompDetails.rowFilterDef.accessTypes;
+    } else {
+      srcOp = serviceCompDetails.accessTypes;
+    }
+    if (changePolicyItemPermissions) {
+      if (isMultiResources) {
+        map(formValues.additionalResources, (resourceObj) => {
+          for (let i = grpResourcesKeys.length - 1; i >= 0; i--) {
+            let selectedResource = `resourceName-${grpResourcesKeys[i]}`;
+            if (
+              resourceObj[selectedResource] &&
+              resourceObj[selectedResource].value !== noneOptions.value
+            ) {
+              if (
+                resourceObj[selectedResource].accessTypeRestrictions?.length > 0
+              ) {
+                let op = [];
+                for (const name of resourceObj[selectedResource]
+                  .accessTypeRestrictions) {
+                  let typeOp = find(srcOp, { name });
+                  if (typeOp) {
+                    op.push(typeOp);
+                  }
+                }
+                multiplePermissionItem = [...multiplePermissionItem, ...op];
+              }
+              break;
+            }
+          }
+        });
+        srcOp = [...new Set(multiplePermissionItem)];
+      } else {
+        for (let i = grpResourcesKeys.length - 1; i >= 0; i--) {
+          let selectedResource = `resourceName-${grpResourcesKeys[i]}`;
+          if (
+            formValues[selectedResource] &&
+            formValues[selectedResource].value !== noneOptions.value
+          ) {
+            if (
+              formValues[selectedResource].accessTypeRestrictions?.length > 0
+            ) {
+              let op = [];
+              for (const name of formValues[selectedResource]
+                .accessTypeRestrictions) {
+                let typeOp = find(srcOp, { name });
+                if (typeOp) {
+                  op.push(typeOp);
+                }
+              }
+              srcOp = op;
             }
+            break;
           }
-          srcOp = op;
         }
-        break;
       }
     }
     return srcOp.map(({ label, name: value }) => ({
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/Resources/ModalResourceComp.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/Resources/ModalResourceComp.jsx
index 5c04ce3b8..f6e559041 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/Resources/ModalResourceComp.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/Resources/ModalResourceComp.jsx
@@ -68,6 +68,7 @@ export default function ModalResourceComp(props) {
                         serviceCompDetails={serviceCompDetails}
                         formValues={values}
                         policyType={0}
+                        isMultiResources={false}
                       />
                     </div>
                   )}
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/Resources/ResourceComp.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/Resources/ResourceComp.jsx
index 452f05ace..0067e6ee9 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/Resources/ResourceComp.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/Resources/ResourceComp.jsx
@@ -22,11 +22,11 @@ import { Form as FormB, Row, Col } from "react-bootstrap";
 import { Field } from "react-final-form";
 import Select from "react-select";
 import BootstrapSwitchButton from "bootstrap-switch-button-react";
-import { filter, groupBy, some, sortBy } from "lodash";
+import { filter, groupBy, some } from "lodash";
 import { toast } from "react-toastify";
 import { udfResourceWarning } from "../../utils/XAMessages";
-import { RangerPolicyType } from "Utils/XAEnums";
 import ResourceSelectComp from "./ResourceSelectComp";
+import { getResourcesDefVal } from "../../utils/XAUtils";
 
 const noneOptions = {
   label: "None",
@@ -39,20 +39,14 @@ export default function ResourceComp(props) {
     formValues,
     serviceDetails,
     policyType,
-    policyItem,
-    policyId
+    policyId,
+    name,
+    isMultiResources
   } = props;
   const [rsrcState, setLoader] = useState({ loader: false, resourceKey: -1 });
   const toastId = useRef(null);
 
-  let resources = sortBy(serviceCompDetails.resources, "itemId");
-  if (RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value == policyType) {
-    resources = sortBy(serviceCompDetails.dataMaskDef.resources, "itemId");
-  } else if (
-    RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value == policyType
-  ) {
-    resources = sortBy(serviceCompDetails.rowFilterDef.resources, "itemId");
-  }
+  let resources = getResourcesDefVal(serviceCompDetails, policyType);
 
   useEffect(() => {
     if (rsrcState.loader) {
@@ -139,14 +133,7 @@ export default function ResourceComp(props) {
       delete formValues[`isExcludesSupport-${levelKey}`];
       delete formValues[`isRecursiveSupport-${levelKey}`];
     }
-    if (policyItem) {
-      removedSeletedAccess();
-    }
     delete formValues[`value-${grpResourcesKeys[index]}`];
-    setLoader({
-      loader: true,
-      resourceKey: grpResourcesKeys[index]
-    });
     let CurrentSelectedResourcs = selectedVal.name;
     for (let j = index + 1; j < grpResourcesKeys.length; j++) {
       let level = grpResourcesKeys[j];
@@ -167,21 +154,10 @@ export default function ResourceComp(props) {
     }
 
     input.onChange(selectedVal);
-  };
-
-  const removedSeletedAccess = () => {
-    for (const name of [
-      "policyItems",
-      "allowExceptions",
-      "denyPolicyItems",
-      "denyExceptions"
-    ]) {
-      for (const policyObj of formValues[name]) {
-        if (policyObj?.accesses) {
-          policyObj.accesses = [];
-        }
-      }
-    }
+    setLoader({
+      loader: true,
+      resourceKey: grpResourcesKeys[index]
+    });
   };
 
   return grpResourcesKeys.map((levelKey, index) => {
@@ -215,8 +191,12 @@ export default function ResourceComp(props) {
           <Field
             defaultValue={!policyId && getResourceLabelOp(levelKey, index)[0]}
             className="form-control"
-            name={`resourceName-${levelKey}`}
-            render={({ input, meta }) =>
+            name={
+              isMultiResources
+                ? `${name}.resourceName-${levelKey}`
+                : `resourceName-${levelKey}`
+            }
+            render={({ input }) =>
               formValues[resourceKey] ? (
                 renderResourceSelect(levelKey, index) ? (
                   <span className="pull-right fnt-14">
@@ -254,6 +234,8 @@ export default function ResourceComp(props) {
                 formValues={formValues}
                 grpResourcesKeys={grpResourcesKeys}
                 serviceDetails={serviceDetails}
+                name={name}
+                isMultiResources={isMultiResources}
               />
             </Col>
           </>
@@ -265,7 +247,11 @@ export default function ResourceComp(props) {
                 <Col sm={5}>
                   <Field
                     className="form-control"
-                    name={`isExcludesSupport-${levelKey}`}
+                    name={
+                      isMultiResources
+                        ? `${name}.isExcludesSupport-${levelKey}`
+                        : `isExcludesSupport-${levelKey}`
+                    }
                     render={({ input }) => (
                       <BootstrapSwitchButton
                         {...input}
@@ -286,7 +272,11 @@ export default function ResourceComp(props) {
                 <Col sm={5} className="toggle-switch">
                   <Field
                     className="form-control"
-                    name={`isRecursiveSupport-${levelKey}`}
+                    name={
+                      isMultiResources
+                        ? `${name}.isRecursiveSupport-${levelKey}`
+                        : `isRecursiveSupport-${levelKey}`
+                    }
                     render={({ input }) => (
                       <BootstrapSwitchButton
                         {...input}
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/Resources/ResourceSelectComp.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/Resources/ResourceSelectComp.jsx
index 1b8903c97..9e8456d3f 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/Resources/ResourceSelectComp.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/Resources/ResourceSelectComp.jsx
@@ -30,7 +30,15 @@ const noneOptions = {
 };
 
 export default function ResourceSelectComp(props) {
-  const { formValues, grpResourcesKeys, levelKey, serviceDetails } = props;
+  const {
+    formValues,
+    grpResourcesKeys,
+    levelKey,
+    serviceDetails,
+    name,
+    isMultiResources,
+    changePolicyItemPermissions
+  } = props;
   const [options, setOptions] = useState([]);
   const [isLoading, setIsLoading] = useState(false);
   const toastId = useRef(null);
@@ -161,7 +169,9 @@ export default function ResourceSelectComp(props) {
     <Field
       key={formValues[`resourceName-${levelKey}`].name}
       className="form-control"
-      name={`value-${levelKey}`}
+      name={
+        isMultiResources ? `${name}.value-${levelKey}` : `value-${levelKey}`
+      }
       validate={
         formValues &&
         formValues[`resourceName-${levelKey}`]?.mandatory &&
@@ -174,9 +184,10 @@ export default function ResourceSelectComp(props) {
             id={
               formValues &&
               formValues[`resourceName-${levelKey}`]?.mandatory &&
-              meta.error &&
-              meta.touched
+              meta.error
                 ? "isError"
+                : isMultiResources
+                ? `${name}.value-${levelKey}`
                 : `value-${levelKey}`
             }
             
isMulti={supportMultipleVal(formValues[`resourceName-${levelKey}`])}
@@ -186,6 +197,7 @@ export default function ResourceSelectComp(props) {
             }
             options={options}
             onFocus={(e) => {
+              e.stopPropagation();
               setOptions([]);
               fetchResourceLookup(
                 "",
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx
index 91d2a3758..d97dcf041 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx
@@ -1365,7 +1365,6 @@ const SecurityZoneForm = () => {
                     modelState={modelState}
                     handleSave={handleSave}
                     handleClose={handleClose}
-                    policyItem={true}
                   />
                 </Col>
               </Row>
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceAuditFilter.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceAuditFilter.jsx
index 7dff7457a..ae05a1f2c 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceAuditFilter.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceAuditFilter.jsx
@@ -561,7 +561,6 @@ export default function ServiceAuditFilter(props) {
         handleSave={handleSave}
         modelState={modelState}
         handleClose={handleClose}
-        policyItem={false}
       />
     </div>
   );

Reply via email to