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>
);
})