You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by dh...@apache.org on 2026/07/17 11:25:09 UTC

(ranger) 01/01: RANGER-5446 : Ensure Policy Conditions modal size and appearance are consistent

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

dhavaljrajpara pushed a commit to branch RANGER-5446
in repository https://gitbox.apache.org/repos/asf/ranger.git

commit 8e94c8f928acbdc1c207619e923e0ca282cf2cbc
Author: Dhaval Rajpara <dh...@gmail.com>
AuthorDate: Fri Jul 17 08:08:25 2026 +0530

    RANGER-5446 : Ensure Policy Conditions modal size and appearance are consistent
---
 .../main/webapp/react-webapp/src/utils/XAEnums.js  |   5 +
 .../main/webapp/react-webapp/src/utils/XAUtils.js  |  10 +-
 .../Admin/AdminLogs/PolicyViewDetails.jsx          |  22 +-
 .../views/GovernedData/Dataset/AccessGrantForm.jsx |   1 +
 .../Datashare/DatashareDetailLayout.jsx            |   1 +
 .../views/PolicyListing/AddUpdatePolicyForm.jsx    |   7 +-
 .../views/PolicyListing/PolicyConditionsComp.jsx   | 280 +++++++++++++++------
 .../views/PolicyListing/PolicyPermissionItem.jsx   | 161 ++++++++++--
 .../src/views/Reports/SearchPolicyTable.jsx        |  13 +-
 9 files changed, 385 insertions(+), 115 deletions(-)

diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js b/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js
index 4e08f3a06..744f7bf82 100755
--- a/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js
+++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js
@@ -986,3 +986,8 @@ export const additionalServiceConfigs = [
     type: "user"
   }
 ];
+export const policyConditionDisplayLabel = {
+  "Accessed after expiry_date (yes/no)?": "Accessed after expiry date",
+  "Enter boolean expression": "Boolean expression",
+  "IP Address Range": "IP Address Range"
+};
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 7d21b06dc..d0ca53f8f 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
@@ -24,7 +24,8 @@ import {
   PathAssociateWithModule,
   QueryParams,
   RangerPolicyType,
-  ServiceType
+  ServiceType,
+  policyConditionDisplayLabel
 } from "Utils/XAEnums";
 import {
   filter,
@@ -1586,3 +1587,10 @@ export const currentTimeZone = (timeZoneDate) => {
         .replace(/^.*GMT.*\(/, "")
         .replace(/\)$/, "");
 };
+
+// Common function to get display label for policy condition
+export const getPolicyConditionDisplayLbl = (lbl) => {
+  return policyConditionDisplayLabel.hasOwnProperty(lbl)
+    ? policyConditionDisplayLabel[lbl]
+    : lbl;
+};
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/Admin/AdminLogs/PolicyViewDetails.jsx b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/Admin/AdminLogs/PolicyViewDetails.jsx
index 6e13cd94e..6feefb53c 100644
--- a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/Admin/AdminLogs/PolicyViewDetails.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/Admin/AdminLogs/PolicyViewDetails.jsx
@@ -24,7 +24,11 @@ import { RangerPolicyType, DefStatus } from "Utils/XAEnums";
 import dateFormat from "dateformat";
 import { toast } from "react-toastify";
 import { cloneDeep, find, isEmpty, map, sortBy } from "lodash";
-import { getResourcesDefVal, serverError } from "Utils/XAUtils";
+import {
+  getResourcesDefVal,
+  serverError,
+  getPolicyConditionDisplayLbl
+} from "Utils/XAUtils";
 import { ModalLoader } from "Components/CommonComponents";
 import { getServiceDef } from "Utils/appState";
 
@@ -463,9 +467,9 @@ export function PolicyViewDetails(props) {
                                     bg="info"
                                     className="d-inline me-1"
                                     key={obj.values}
-                                  >{`${conditionObj.label}: ${obj.values.join(
-                                    ", "
-                                  )}`}</Badge>
+                                  >{`${getPolicyConditionDisplayLbl(
+                                    conditionObj.label
+                                  )}: ${obj.values.join(", ")}`}</Badge>
                                 </h6>
                               );
                             })
@@ -548,7 +552,9 @@ export function PolicyViewDetails(props) {
     const getConditionLabel = (label) => {
       let filterLabel = find(serviceDef.policyConditions, { name: label });
 
-      return filterLabel && filterLabel?.label ? filterLabel.label : "";
+      return filterLabel && filterLabel?.label
+        ? getPolicyConditionDisplayLbl(filterLabel.label)
+        : "";
     };
     return (
       !isEmpty(conditions) && (
@@ -783,14 +789,14 @@ export function PolicyViewDetails(props) {
         )}
       {policyType == RangerPolicyType.RANGER_ROW_FILTER_POLICY_TYPE.value && (
         <>
-          <p className="form-header">Row Level Conditions :</p>
+          <p className="form-header">Row Level Rules :</p>
           <div className="overflow-auto">
             <Table bordered size="sm" className="table-audit-filter-ready-only">
               {getFilterPolicy(
                 rowFilterPolicyItems,
                 serviceDef,
                 serviceType,
-                `No policy items of "Row Level Conditions" are present`
+                `No policy items of "Row Level Rules" are present`
               )}
             </Table>
           </div>
@@ -798,7 +804,7 @@ export function PolicyViewDetails(props) {
       )}
       {policyType == RangerPolicyType.RANGER_MASKING_POLICY_TYPE.value && (
         <>
-          <p className="form-header">Masking Conditions :</p>
+          <p className="form-header">Masking Rules :</p>
           <div className="overflow-auto">
             <Table bordered size="sm" className="table-audit-filter-ready-only">
               {getFilterPolicy(
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/AccessGrantForm.jsx b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/AccessGrantForm.jsx
index 7051d32eb..aed34bddb 100755
--- a/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/AccessGrantForm.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/GovernedData/Dataset/AccessGrantForm.jsx
@@ -733,6 +733,7 @@ function AccessGrantForm({
                               inputVal={input}
                               showModal={showModal}
                               handleCloseModal={policyConditionState}
+                              modalHeader="Policy Conditions"
                             />
                           )}
                         />
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 207cab88f..094ace3fa 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
@@ -1397,6 +1397,7 @@ const DatashareDetailLayout = () => {
                                   inputVal={input}
                                   showModal={showModal}
                                   handleCloseModal={policyConditionState}
+                                  modalHeader="Policy Conditions"
                                 />
                               )}
                             />
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 434c4831f..617c3d270 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
@@ -593,7 +593,7 @@ export default function AddUpdatePolicyForm() {
                 type: conditionKey,
                 values: isArray(conditionValue)
                   ? conditionValue.map((m) => {
-                      return m.value;
+                      return m;
                     })
                   : [conditionValue]
               });
@@ -712,9 +712,7 @@ export default function AddUpdatePolicyForm() {
           if (!isEmpty(conditionObj.uiHint)) {
             obj.conditions[data?.type] = JSON.parse(conditionObj.uiHint)
               .isMultiValue
-              ? data?.values.map((m) => {
-                  return { value: m.trim(), label: m.trim() };
-                })
+              ? data?.values
               : data?.values.toString().trim();
           }
         }
@@ -1510,6 +1508,7 @@ export default function AddUpdatePolicyForm() {
                                             handleCloseModal={
                                               policyConditionState
                                             }
+                                            modalHeader="Policy Conditions"
                                           />
                                         )}
                                       />
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 6e3dbfb94..357053436 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
@@ -17,12 +17,12 @@
  * under the License.
  */
 
-import React from "react";
+import React, { useMemo } from "react";
 import { Col, Form as FormB, Row, Modal, Button } from "react-bootstrap";
 import { Form, Field } from "react-final-form";
 import Select from "react-select";
 import CreatableSelect from "react-select/creatable";
-import { find, isEmpty } from "lodash";
+import { find, isArray, isEmpty } from "lodash";
 import { InfoIcon } from "Utils/XAUtils";
 import { RegexMessage } from "Utils/XAMessages";
 import {
@@ -32,18 +32,117 @@ import {
 import {
   isPerRowCondition,
   getCleanConditions,
-  parseConditionUiHint
+  parseConditionUiHint,
+  sortPolicyConditions,
+  buildActionReqsMapFromConditionDef,
+  getAllowedActionMatchesForCondition
 } from "Utils/policyConditionUtils";
 const esprima = require("esprima");
+const POLICY_SCOPE = "policy";
+const POLICY_ITEM_SCOPE = "policyItem";
+
+const toSelectValue = (val) => {
+  if (!isArray(val) || isEmpty(val)) {
+    return [];
+  }
+  return val
+    .map((m) => {
+      if (typeof m === "object" && m?.value) {
+        const value = String(m.value).trim();
+        return value ? { label: m.label || value, value } : null;
+      }
+      if (typeof m === "string") {
+        const trimmed = m.trim();
+        return trimmed ? { label: trimmed, value: trimmed } : null;
+      }
+      return null;
+    })
+    .filter(Boolean);
+};
+
+const pruneActionMatchesOnSubmit = ({
+  conditions,
+  conditionDefVal,
+  actionFilterContext,
+  actionReqsMap,
+  servicedefName
+}) => {
+  const pruned = { ...conditions };
+
+  for (const conditionName in pruned) {
+    if (!isPerRowCondition(conditionName)) {
+      continue;
+    }
+
+    const conditionDef = find(conditionDefVal, { name: conditionName });
+    const uiHintAttb = parseConditionUiHint(conditionDef?.uiHint);
+    const current = pruned[conditionName];
+
+    if (
+      !uiHintAttb?.isMultiValue ||
+      !Array.isArray(uiHintAttb?.options) ||
+      !Array.isArray(current) ||
+      current.length === 0 ||
+      !actionFilterContext?.selectedAccessTypes?.length
+    ) {
+      continue;
+    }
+
+    const { prunedSelection } = getAllowedActionMatchesForCondition({
+      conditionName,
+      actionFilterContext,
+      actionReqsMap,
+      servicedefName,
+      uiHintAttb,
+      currentSelection: toSelectValue(current)
+    });
+
+    if (prunedSelection?.length > 0) {
+      pruned[conditionName] = prunedSelection.map((o) => o.value);
+    } else {
+      delete pruned[conditionName];
+    }
+  }
+
+  return pruned;
+};
 
 export default function PolicyConditionsComp(props) {
-  const { policyConditionDetails, inputVal, showModal, handleCloseModal } =
-    props;
+  const {
+    policyConditionDetails,
+    inputVal,
+    showModal,
+    handleCloseModal,
+    modalHeader,
+    scope = POLICY_SCOPE,
+    servicedefName,
+    actionFilterContext,
+    actionReqsMap: actionReqsMapProp
+  } = props;
+
+  const isPolicyItemScope = scope === POLICY_ITEM_SCOPE;
 
-  // Policy-level modal only; action-matches is edited on each permission row (Editable).
-  const filteredPolicyConditionDetails = Array.isArray(policyConditionDetails)
-    ? policyConditionDetails.filter((c) => !isPerRowCondition(c?.name))
-    : policyConditionDetails;
+  const conditionDefVal = useMemo(
+    () =>
+      Array.isArray(policyConditionDetails) ? policyConditionDetails : [],
+    [policyConditionDetails]
+  );
+
+  const actionReqsMap = useMemo(
+    () =>
+      actionReqsMapProp ?? buildActionReqsMapFromConditionDef(conditionDefVal),
+    [actionReqsMapProp, conditionDefVal]
+  );
+
+  const filteredPolicyConditionDetails = useMemo(() => {
+    if (!Array.isArray(policyConditionDetails)) {
+      return policyConditionDetails;
+    }
+    const filtered = isPolicyItemScope
+      ? policyConditionDetails
+      : policyConditionDetails.filter((c) => !isPerRowCondition(c?.name));
+    return sortPolicyConditions(filtered);
+  }, [policyConditionDetails, isPolicyItemScope]);
 
   const accessedOpt = [
     { value: "yes", label: "Yes" },
@@ -52,12 +151,24 @@ export default function PolicyConditionsComp(props) {
 
   const handleSubmit = (values) => {
     if (values?.conditions) {
-      const newConditions = getCleanConditions(values.conditions);
-      for (let val in newConditions) {
-        if (isPerRowCondition(val)) {
-          delete newConditions[val];
+      let newConditions = getCleanConditions(values.conditions);
+
+      if (isPolicyItemScope) {
+        newConditions = pruneActionMatchesOnSubmit({
+          conditions: newConditions,
+          conditionDefVal,
+          actionFilterContext,
+          actionReqsMap,
+          servicedefName
+        });
+      } else {
+        for (const val in newConditions) {
+          if (isPerRowCondition(val)) {
+            delete newConditions[val];
+          }
         }
       }
+
       inputVal.onChange(newConditions);
     } else {
       inputVal.onChange(values?.conditions);
@@ -70,20 +181,19 @@ export default function PolicyConditionsComp(props) {
   };
 
   const formInitialData = () => {
-    var conditions = {};
-    if (inputVal && inputVal.value) {
-      for (let val in inputVal.value) {
+    const conditions = {};
+    if (inputVal?.value) {
+      for (const val in inputVal.value) {
         conditions[val] = inputVal.value[val];
       }
     }
-    let formData = { conditions };
-    return formData;
+    return { conditions };
   };
 
   const accessedVal = (val) => {
     let value = null;
     if (val) {
-      let opObj = find(accessedOpt, { value: val });
+      const opObj = find(accessedOpt, { value: val });
       if (opObj) {
         value = opObj;
       }
@@ -98,24 +208,14 @@ export default function PolicyConditionsComp(props) {
   };
 
   const handleChange = (val, input) => {
-    let value = [];
-    if (val) {
-      value = val.map((m) => m.value);
+    if (!val || val.length === 0) {
+      input.onChange(undefined);
+      return;
     }
-    input.onChange(value);
+    input.onChange(val.map((m) => m.value));
   };
 
-  const ipRangeVal = (val) => {
-    let value = [];
-    if (!isEmpty(val)) {
-      // Trim existing values when displaying
-      value = val.map((m) => ({
-        label: m.trim(),
-        value: m.trim()
-      }));
-    }
-    return value;
-  };
+  const ipRangeVal = (val) => toSelectValue(val);
 
   const validater = (values) => {
     let errors = "";
@@ -129,6 +229,75 @@ export default function PolicyConditionsComp(props) {
     return errors;
   };
 
+  const renderMultiValueField = (m, uiHintAttb) => {
+    const isActionMatches =
+      isPolicyItemScope &&
+      isPerRowCondition(m.name) &&
+      Array.isArray(uiHintAttb?.options);
+    if (isActionMatches) {
+      return (
+        <Field
+          className="form-control"
+          name={`conditions.${m.name}`}
+          render={({ input }) => {
+            const { dropdownOptions, prunedSelection } =
+              getAllowedActionMatchesForCondition({
+                conditionName: m.name,
+                actionFilterContext,
+                actionReqsMap,
+                servicedefName,
+                uiHintAttb,
+                currentSelection: toSelectValue(input.value)
+              });
+            const displayedValue =
+              prunedSelection?.length > 0 ? prunedSelection : null;
+            return (
+              <Select
+                isMulti
+                isClearable
+                placeholder=""
+                options={dropdownOptions || []}
+                value={displayedValue}
+                onChange={(e) => handleChange(e, input)}
+                styles={selectInputCustomStyles}
+              />
+            );
+          }}
+        />
+      );
+    }
+
+    return (
+      <Field
+        className="form-control"
+        name={`conditions.${m.name}`}
+        render={({ input }) => (
+          <CreatableSelect
+            {...input}
+            isMulti
+            isClearable
+            placeholder=""
+            width="500px"
+            value={ipRangeVal(input.value)}
+            onChange={(e) => handleChange(e, input)}
+            styles={selectInputCustomStyles}
+            formatCreateLabel={(inputValue) =>
+              `Create "${inputValue.trim()}"`
+            }
+            onCreateOption={(inputValue) => {
+              const trimmedValue = inputValue.trim();
+              if (trimmedValue) {
+                const currentValues = input.value || [];
+                const newValues = [...currentValues, trimmedValue];
+                input.onChange(newValues);
+              }
+            }}
+          />
+        )}
+      />
+    );
+  };
+
   return (
     <>
       <Modal
@@ -140,11 +309,11 @@ export default function PolicyConditionsComp(props) {
       >
         <Form
           onSubmit={handleSubmit}
-          initialValues={formInitialData}
+          initialValues={formInitialData()}
           render={({ handleSubmit }) => (
             <form onSubmit={handleSubmit}>
               <Modal.Header closeButton>
-                <Modal.Title>Policy Condition</Modal.Title>
+                <Modal.Title>{modalHeader}</Modal.Title>
               </Modal.Header>
               <Modal.Body>
                 {filteredPolicyConditionDetails?.length > 0 &&
@@ -156,7 +325,6 @@ export default function PolicyConditionsComp(props) {
                           <div key={m.name}>
                             <FormB.Group className="mb-3">
                               <b>{m.label}:</b>
-
                               <Field
                                 className="form-control"
                                 name={`conditions.${m.name}`}
@@ -235,53 +403,19 @@ export default function PolicyConditionsComp(props) {
                           <div key={m.name}>
                             <FormB.Group className="mb-3">
                               <b>{m.label}:</b>
-
-                              <Field
-                                className="form-control"
-                                name={`conditions.${m.name}`}
-                                render={({ input }) => (
-                                  <CreatableSelect
-                                    {...input}
-                                    isMulti
-                                    isClearable
-                                    placeholder=""
-                                    width="500px"
-                                    value={ipRangeVal(input.value)}
-                                    onChange={(e) => handleChange(e, input)}
-                                    styles={selectInputCustomStyles}
-                                    formatCreateLabel={(inputValue) =>
-                                      `Create "${inputValue.trim()}"`
-                                    }
-                                    onCreateOption={(inputValue) => {
-                                      const trimmedValue = inputValue.trim();
-                                      if (trimmedValue) {
-                                        const newOption = {
-                                          label: trimmedValue,
-                                          value: trimmedValue
-                                        };
-                                        const currentValues = input.value || [];
-                                        const newValues = [
-                                          ...currentValues,
-                                          trimmedValue
-                                        ];
-                                        input.onChange(newValues);
-                                      }
-                                    }}
-                                  />
-                                )}
-                              />
+                              {renderMultiValueField(m, uiHintAttb)}
                             </FormB.Group>
                           </div>
                         );
                       }
                     }
+                    return null;
                   })}
               </Modal.Body>
               <Modal.Footer>
                 <Button variant="secondary" size="sm" onClick={handleClose}>
                   Close
                 </Button>
-
                 <Button title="Save" size="sm" type="submit">
                   Save
                 </Button>
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 0e44e46a7..169f4ab52 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
@@ -42,10 +42,17 @@ import {
   dragEnter,
   drop,
   dragOver,
-  policyConditionUpdatedJSON
+  policyConditionUpdatedJSON,
+  getPolicyConditionDisplayLbl
 } from "Utils/XAUtils";
 import { selectInputCustomStyles } from "Components/CommonComponents";
-import { getSelectedLeafResourceTypes, getSelectedAccessTypesForRow, buildActionReqsMapFromConditionDef, getCleanConditions } from "Utils/policyConditionUtils";
+import PolicyConditionsComp from "./PolicyConditionsComp";
+import {
+  getSelectedLeafResourceTypes,
+  getSelectedAccessTypesForRow,
+  buildActionReqsMapFromConditionDef,
+  getCleanConditions
+} from "Utils/policyConditionUtils";
 import { usePruneStaleConditions } from "../../hooks/usePruneStaleConditions";
 
 const noneOptions = {
@@ -74,6 +81,7 @@ export default function PolicyPermissionItem(props) {
   const [roleLoading, setRoleLoading] = useState(false);
   const [groupLoading, setGroupLoading] = useState(false);
   const [userLoading, setUserLoading] = useState(false);
+  const [activeConditionRow, setActiveConditionRow] = useState(null);
 
   const permList = ["Select Roles", "Select Groups", "Select Users"];
 
@@ -133,7 +141,9 @@ export default function PolicyPermissionItem(props) {
     return `${sel.name ?? ""}:${sel.value ?? ""}`;
   };
 
-  const resourceSelectionSignature = Array.isArray(formValues?.additionalResources)
+  const resourceSelectionSignature = Array.isArray(
+    formValues?.additionalResources
+  )
     ? formValues.additionalResources
         .map((b) =>
           grpResourcesKeys
@@ -368,6 +378,48 @@ export default function PolicyPermissionItem(props) {
     });
   };
 
+  const policyConditionDisplayValue = (value) => {
+    const selectVal = value;
+    let ipRangVal, uiHintVal;
+    if (selectVal) {
+      return Object.keys(selectVal).map((property) => {
+        let conditionObj = find(
+          serviceCompDetails.policyConditions,
+          function (m) {
+            if (m.name == property) {
+              return m;
+            }
+          }
+        );
+        if (conditionObj?.uiHint && conditionObj?.uiHint != "") {
+          uiHintVal = JSON.parse(conditionObj.uiHint);
+        }
+        if (isArray(selectVal[property])) {
+          ipRangVal = (selectVal[property] || [])
+            .map((m) =>
+              typeof m === "object" && m?.value != null ? m.value : m
+            )
+            .join(", ");
+        }
+        return (
+          <h6 key={property}>
+            <div
+              className={`${
+                uiHintVal?.isMultiline
+                  ? "editable-label rule-condition-wrapper"
+                  : "badge bg-dark rule-condition-wrapper"
+              }`}
+            >
+              {`${getPolicyConditionDisplayLbl(conditionObj.label)}: ${
+                isArray(selectVal[property]) ? ipRangVal : selectVal[property]
+              }`}
+            </div>
+          </h6>
+        );
+      });
+    }
+  };
+
   return (
     <div>
       <Col sm="12">
@@ -501,7 +553,6 @@ export default function PolicyPermissionItem(props) {
                             serviceCompDetails?.policyConditions?.length >
                               0 && (
                               <td key={colName} className="align-middle">
-                                {/* Per-row conditions: Editable + actionFilterContext for action-matches */}
                                 <Field
                                   className="form-control"
                                   name={`${name}.conditions`}
@@ -511,29 +562,85 @@ export default function PolicyPermissionItem(props) {
                                       index
                                     )
                                   }
-                                  render={({ input }) => (
-                                    <div className="table-editable permission-item">
-                                      <Editable
-                                        {...input}
-                                        type="custom"
-                                        conditionDefVal={conditionDefVal}
-                                        servicedefName={serviceCompDetails?.name}
-                                        actionFilterContext={{
-                                          selectedAccessTypes:
-                                            getSelectedAccessTypesForRow(formValues, attrName, index),
-                                          leafResourceTypes,
-                                          accessTypeDefs:
-                                            serviceCompDetails?.accessTypes
-                                        }}
-                                        selectProps={{
-                                          isMulti: true,
-                                          // Portal menus to body (see Editable CONDITION_POPOVER_SELECT_PROPS)
-                                          // so a long Action list with ALL permission does not jump the page.
-                                        }}
-                                        popOverheader="Rule Conditions"
-                                      />
-                                    </div>
-                                  )}
+                                  render={({ input }) => {
+                                    const showConditionsModal =
+                                      activeConditionRow === name;
+                                    const hasValue =
+                                      Object.keys(
+                                        getCleanConditions(input?.value || {})
+                                      ).length !== 0;
+                                    return (
+                                      <>
+                                        {showConditionsModal && (
+                                          <PolicyConditionsComp
+                                            policyConditionDetails={
+                                              conditionDefVal
+                                            }
+                                            inputVal={input}
+                                            showModal={true}
+                                            handleCloseModal={() =>
+                                              setActiveConditionRow(null)
+                                            }
+                                            modalHeader="Rule Conditions"
+                                            scope="policyItem"
+                                            servicedefName={
+                                              serviceCompDetails?.name
+                                            }
+                                            actionReqsMap={actionReqsMap}
+
+                                            actionFilterContext={{
+                                              selectedAccessTypes:
+                                                getSelectedAccessTypesForRow(
+                                                  formValues,
+                                                  attrName,
+                                                  index
+                                                ),
+                                              leafResourceTypes,
+                                              accessTypeDefs:
+                                                serviceCompDetails?.accessTypes
+                                            }}
+                                          />
+                                      )}
+                                        <div className="table-editable">
+                                          {hasValue ? (
+                                            <h6>
+                                              {ruleConditionDisplayValue(
+                                                input.value
+                                              )}
+                                              <Button
+                                                className="mg-10 mx-auto d-block btn-mini"
+                                                variant="outline-dark"
+                                                size="sm"
+                                                type="button"
+                                                onClick={() =>
+                                                  setActiveConditionRow(name)
+                                                }
+                                              >
+                                                <i className="fa-fw fa fa-pencil"></i>
+                                              </Button>
+                                            </h6>
+                                          ) : (
+                                            <div className="text-center">
+                                              <span className="editable-add-text">
+                                                Add Conditions
+                                              </span>
+                                              <Button
+                                                className="mg-10 mx-auto d-block btn-mini"
+                                                variant="outline-dark"
+                                                size="sm"
+                                                type="button"
+                                                onClick={() =>
+                                                  setActiveConditionRow(name)
+                                                }
+                                              >
+                                                <i className="fa-fw fa fa-plus"></i>
+                                              </Button>
+                                            </div>
+                                          )}
+                                        </div>
+                                      </>
+                                    );
+                                  }}
                                 />
                               </td>
                             )
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/Reports/SearchPolicyTable.jsx b/security-admin/src/main/webapp/react-webapp/src/views/Reports/SearchPolicyTable.jsx
index c1728f04d..b88f664fd 100644
--- a/security-admin/src/main/webapp/react-webapp/src/views/Reports/SearchPolicyTable.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/Reports/SearchPolicyTable.jsx
@@ -33,7 +33,11 @@ import { MoreLess } from "Components/CommonComponents";
 import XATableLayout from "Components/XATableLayout";
 import { fetchApi } from "Utils/fetchAPI";
 import { Loader } from "Components/CommonComponents";
-import { isAuditor, isKMSAuditor } from "Utils/XAUtils";
+import {
+  isAuditor,
+  isKMSAuditor,
+  getPolicyConditionDisplayLbl
+} from "Utils/XAUtils";
 
 function SearchPolicyTable(props) {
   const [searchPoliciesData, setSearchPolicies] = useState([]);
@@ -329,13 +333,18 @@ function PolicyConditionData(props) {
               <td className="text-center">
                 {!isEmpty(items.conditions)
                   ? items.conditions.map((obj, index) => {
+                      let conditionObj = props.serviceDef.policyConditions.find(
+                        (condition) => condition.name === obj.type
+                      );
                       return (
                         <h6 className="d-inline me-1" key={index}>
                           <Badge
                             bg="info"
                             className="d-inline me-1"
                             key={obj.values}
-                          >{`${obj.type}: ${obj.values.join(", ")}`}</Badge>
+                          >{`${getPolicyConditionDisplayLbl(
+                            conditionObj.label
+                          )}: ${obj.values.join(", ")}`}</Badge>
                         </h6>
                       );
                     })