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

dineshkumar 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 34ab10570 RANGER-4119 - Improvement in policy condition on Ranger 
Admin UI
34ab10570 is described below

commit 34ab1057084e966c581ee785c7f34dbbb6180044
Author: Dhaval Rajpara <[email protected]>
AuthorDate: Tue Jul 25 10:11:42 2023 +0530

    RANGER-4119 - Improvement in policy condition on Ranger Admin UI
    
    Signed-off-by: Dineshkumar Yadav <[email protected]>
---
 .../service-defs/ranger-servicedef-abfs.json       |   3 +-
 .../service-defs/ranger-servicedef-kafka.json      |   4 +-
 .../service-defs/ranger-servicedef-knox.json       |   4 +-
 .../service-defs/ranger-servicedef-ozone.json      |   4 +-
 .../ranger-servicedef-schema-registry.json         |   4 +-
 .../service-defs/ranger-servicedef-solr.json       |   4 +-
 .../service-defs/ranger-servicedef-tag.json        |   3 +-
 .../react-webapp/src/components/Editable.jsx       | 502 +++++++++++++--------
 .../main/webapp/react-webapp/src/utils/XAUtils.js  |  19 +
 .../AuditEvent/AdminLogs/PolicyViewDetails.jsx     |  29 +-
 .../views/PolicyListing/AddUpdatePolicyForm.jsx    |  75 ++-
 .../views/PolicyListing/PolicyConditionsComp.jsx   | 194 ++++----
 .../views/PolicyListing/PolicyPermissionItem.jsx   | 126 +++---
 .../views/ServiceManager/ServiceAuditFilter.jsx    |   3 +-
 .../src/views/ServiceManager/ServiceForm.jsx       |   3 +-
 15 files changed, 556 insertions(+), 421 deletions(-)

diff --git 
a/agents-common/src/main/resources/service-defs/ranger-servicedef-abfs.json 
b/agents-common/src/main/resources/service-defs/ranger-servicedef-abfs.json
index 7dcf38895..879df6b9f 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-abfs.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-abfs.json
@@ -118,7 +118,8 @@
       "name": "ip-range",
       "evaluator": 
"org.apache.ranger.plugin.conditionevaluator.RangerIpMatcher",
       "label": "IP Address Range",
-      "description": "IP Address Range"
+      "description": "IP Address Range",
+      "uiHint" : "{ \"isMultiValue\":true }"
     }
   ]
 }
\ No newline at end of file
diff --git 
a/agents-common/src/main/resources/service-defs/ranger-servicedef-kafka.json 
b/agents-common/src/main/resources/service-defs/ranger-servicedef-kafka.json
index 2f511eff5..b169c6ba9 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-kafka.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-kafka.json
@@ -239,9 +239,9 @@
                        },
                        "validationRegEx":"",
                        "validationMessage":"",
-                       "uiHint":"",
                        "label":"IP Address Range",
-                       "description":"IP Address Range"
+                       "description":"IP Address Range",
+                       "uiHint" : "{ \"isMultiValue\":true }"
                }
        ]
 }
diff --git 
a/agents-common/src/main/resources/service-defs/ranger-servicedef-knox.json 
b/agents-common/src/main/resources/service-defs/ranger-servicedef-knox.json
index 410b9ef58..ee44687b4 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-knox.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-knox.json
@@ -135,9 +135,9 @@
                        "evaluatorOptions": { },
                        "validationRegEx":"",
                        "validationMessage": "",
-                       "uiHint":"",
                        "label": "IP Address Range",
-                       "description": "IP Address Range"
+                       "description": "IP Address Range",
+                       "uiHint" : "{ \"isMultiValue\":true }"
                }
        ]
 }
diff --git 
a/agents-common/src/main/resources/service-defs/ranger-servicedef-ozone.json 
b/agents-common/src/main/resources/service-defs/ranger-servicedef-ozone.json
index 4b899736b..13915130c 100755
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-ozone.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-ozone.json
@@ -254,9 +254,9 @@
                        "evaluatorOptions": { },
                        "validationRegEx":"",
                        "validationMessage": "",
-                       "uiHint":"",
                        "label": "IP Address Range",
-                       "description": "IP Address Range"
+                       "description": "IP Address Range",
+                       "uiHint" : "{ \"isMultiValue\":true }"
                }
 
        ]
diff --git 
a/agents-common/src/main/resources/service-defs/ranger-servicedef-schema-registry.json
 
b/agents-common/src/main/resources/service-defs/ranger-servicedef-schema-registry.json
index 987a50fc5..bdebf406d 100644
--- 
a/agents-common/src/main/resources/service-defs/ranger-servicedef-schema-registry.json
+++ 
b/agents-common/src/main/resources/service-defs/ranger-servicedef-schema-registry.json
@@ -264,9 +264,9 @@
       },
       "validationRegEx":"",
       "validationMessage":"",
-      "uiHint":"",
       "label":"IP Address Range",
-      "description":"IP Address Range"
+      "description":"IP Address Range",
+      "uiHint" : "{ \"isMultiValue\":true }"
     }
 
   ]
diff --git 
a/agents-common/src/main/resources/service-defs/ranger-servicedef-solr.json 
b/agents-common/src/main/resources/service-defs/ranger-servicedef-solr.json
index de3399845..50545f744 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-solr.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-solr.json
@@ -188,9 +188,9 @@
                        },
                        "validationRegEx":"",
                        "validationMessage":"",
-                       "uiHint":"",
                        "label":"IP Address Range",
-                       "description":"IP Address Range"
+                       "description":"IP Address Range",
+                       "uiHint" : "{ \"isMultiValue\":true }"
                }
                
        ]
diff --git 
a/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json 
b/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json
index 7cb523075..add29feed 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json
@@ -88,7 +88,8 @@
       "evaluator": 
"org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator",
       "evaluatorOptions" : {"engineName":"JavaScript", 
"ui.isMultiline":"true"},
       "label":"Enter boolean expression",
-      "description": "Boolean expression"
+      "description": "Boolean expression",
+      "uiHint" : "{ \"isMultiline\":true }"
     }
   ]
 }
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 7dd32ebaa..34eb8c5fa 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
@@ -17,7 +17,13 @@
  * under the License.
  */
 
-import React, { useEffect, useReducer, useRef, useState, useCallback } from 
"react";
+import React, {
+  useEffect,
+  useReducer,
+  useRef,
+  useState,
+  useCallback
+} from "react";
 import {
   OverlayTrigger,
   Popover,
@@ -27,13 +33,14 @@ import {
   Col,
   Badge
 } from "react-bootstrap";
-import { findIndex, isArray } from "lodash";
+import { find, findIndex, isArray, isEmpty, map } from "lodash";
 import { isObject } from "Utils/XAUtils";
 import CreatableSelect from "react-select/creatable";
 import Select from "react-select";
 import { InfoIcon } from "../utils/XAUtils";
 import { RegexMessage } from "../utils/XAMessages";
 
+const esprima = require("esprima");
 const TYPE_SELECT = "select";
 const TYPE_CHECKBOX = "checkbox";
 const TYPE_INPUT = "input";
@@ -75,7 +82,7 @@ const CheckboxComp = (props) => {
 
   return (
     <>
-      {options.map((obj) => (
+      {options.map((obj, index) => (
         <Form.Group className="mb-3" controlId={obj.label} key={obj.label}>
           <Form.Check
             checked={isChecked(obj)}
@@ -146,140 +153,171 @@ const InputboxComp = (props) => {
   );
 };
 
-const CreatableSelectNew = (props) => {
-  const { value, valRef, conditionDefVal, selectProps } = props;
-  const [selectedInputVal, setSelectVal] = useState(value);
-  const handleChange = (e) => {
-    valRef.current = e;
-    setSelectVal(e);
-  };
-
-  return (
-    <>
-      <Form.Group className="mb-3" controlId="Ip-range">
-        <b>{conditionDefVal.label}:</b>
-        <CreatableSelect
-          {...selectProps}
-          defaultValue={
-            selectedInputVal == ""
-              ? null
-              : !isArray(selectedInputVal)
-                ? selectedInputVal["ip-range"]
-                  .split(", ")
-                  .map((obj) => ({ label: obj, value: obj }))
-                : selectedInputVal
-          }
-          onChange={(e) => handleChange(e)}
-          placeholder="enter expression"
-          width="500px"
-        />
-      </Form.Group>
-    </>
-  );
-};
-
 const CustomCondition = (props) => {
-  const { value, valRef, conditionDefVal, selectProps } = props;
-  const accessedOpt = [
-    { value: "yes", label: "Yes" },
-    { value: "no", label: "No" }
-  ];
-  const [selectedCondVal, setCondSelect] = useState(
-    value?.["accessed-after-expiry"] || value
-  );
-  const [selectedJSCondVal, setJSCondVal] = useState(
-    value?.expression || value
-  );
+  const { value, valRef, conditionDefVal, selectProps, validExpression } =
+    props;
   const tagAccessData = (val, key) => {
     if (!isObject(valRef.current)) {
       valRef.current = {};
     }
     valRef.current[key] = val;
   };
-  const selectHandleChange = (e, name) => {
-      setCondSelect(e);
-    tagAccessData(e?.value || null, name);
-  };
-  const textAreaHandleChange = (e, name) => {
-    setJSCondVal(e.target.value);
-    tagAccessData(e.target.value, name);
-  };
-  const accessedVal = (val) => {
-    let value = null;
-    if (val) {
-      let opObj = accessedOpt.filter((m) => {
-        if (m.value == val) {
-          return m;
-        }
-      });
-      if (opObj) {
-        value = opObj;
-      }
-    }
-    return value;
-  };
-  const expressionVal = (val) => {
-    let value = null;
-   if(val?.expression !== undefined){
-    return value = val.expression;
-   }
-   if(val != "" && typeof(val) != "object"){
-    return value = val
-   }
-    return value;
-  };
+
   return (
     <>
       {conditionDefVal?.length > 0 &&
         conditionDefVal.map((m, index) => {
-          if (m.name == "accessed-after-expiry") {
-            return (
-              <Form.Group className="mb-3">
-                <b>{m.label}:</b>
-                <Select
-                  options={accessedOpt}
-                  isClearable
-                  onChange={(e) => selectHandleChange(e, m.name)}
-                  value={
-                    selectedCondVal?.value
-                      ? accessedVal(selectedCondVal.value)
-                      : accessedVal(selectedCondVal)
+          let uiHintAttb =
+            m.uiHint != undefined && m.uiHint != "" ? JSON.parse(m.uiHint) : 
"";
+          if (uiHintAttb != "") {
+            if (uiHintAttb?.singleValue) {
+              const [selectedCondVal, setCondSelect] = useState(
+                value?.[m.name] || value
+              );
+              const accessedOpt = [
+                { value: "yes", label: "Yes" },
+                { value: "no", label: "No" }
+              ];
+              const accessedVal = (val) => {
+                let value = null;
+                if (val) {
+                  let opObj = accessedOpt?.filter((m) => {
+                    if (m.value == (val[0]?.value || val)) {
+                      return m;
+                    }
+                  });
+                  if (opObj) {
+                    value = opObj;
                   }
-                />
-              </Form.Group>
-            );
-          }
-          if (m.name == "expression") {
-            return (
-              <>
-                <Form.Group className="mb-3">
-                  <Row>
-                    <Col>
-                      <b>{m.label}:</b>
-                      <InfoIcon
-                        position="right"
-                        message={
-                          <p className="pd-10">
-                            {RegexMessage.MESSAGE.policyconditioninfoicon}
-                          </p>
-                        }
-                      />
-                    </Col>
-                  </Row>
-                  <Row>
-                    <Col>
-                      <Form.Control
-                        as="textarea"
-                        rows={3}
-                        // value={selectedJSCondVal?.expression !== undefined 
? selectedJSCondVal.expression : selectedJSCondVal}
-                        value={expressionVal(selectedJSCondVal)}
-                        onChange={(e) => textAreaHandleChange(e, m.name)}
-                      />
-                    </Col>
-                  </Row>
-                </Form.Group>
-              </>
-            );
+                }
+                return value;
+              };
+              const selectHandleChange = (e, name) => {
+                let filterVal = accessedOpt?.filter((m) => {
+                  if (m.value != e[0]?.value) {
+                    return m;
+                  }
+                });
+                setCondSelect(
+                  !isEmpty(e) ? (e?.length > 1 ? filterVal : e) : null
+                );
+                tagAccessData(
+                  !isEmpty(e)
+                    ? e?.length > 1
+                      ? filterVal[0].value
+                      : e[0].value
+                    : null,
+                  name
+                );
+              };
+              return (
+                <div key={m.name}>
+                  <Form.Group className="mb-3">
+                    <b>{m.label}:</b>
+                    <Select
+                      options={accessedOpt}
+                      onChange={(e) => selectHandleChange(e, m.name)}
+                      value={
+                        selectedCondVal?.value
+                          ? accessedVal(selectedCondVal.value)
+                          : accessedVal(selectedCondVal)
+                      }
+                      isMulti={true}
+                      isClearable={false}
+                    />
+                  </Form.Group>
+                </div>
+              );
+            }
+            if (uiHintAttb?.isMultiline) {
+              const [selectedJSCondVal, setJSCondVal] = useState(
+                value?.[m.name] || value
+              );
+              const expressionVal = (val) => {
+                let value = null;
+                if (val != "" && typeof val != "object") {
+                  valRef.current[m.name] = val;
+                  return (value = val);
+                }
+                return value !== null ? value : "";
+              };
+              const textAreaHandleChange = (e, name) => {
+                setJSCondVal(e.target.value);
+                tagAccessData(e.target.value, name);
+              };
+              return (
+                <div key={m.name}>
+                  <Form.Group className="mb-3">
+                    <Row>
+                      <Col>
+                        <b>{m.label}:</b>
+                        <InfoIcon
+                          position="right"
+                          message={
+                            <p className="pd-10">
+                              {RegexMessage.MESSAGE.policyconditioninfoicon}
+                            </p>
+                          }
+                        />
+                      </Col>
+                    </Row>
+                    <Row>
+                      <Col>
+                        <Form.Control
+                          as="textarea"
+                          rows={3}
+                          key={m.name}
+                          value={expressionVal(selectedJSCondVal)}
+                          onChange={(e) => textAreaHandleChange(e, m.name)}
+                          isInvalid={validExpression.state}
+                        />
+                        {validExpression.state && (
+                          <div className="text-danger">
+                            {validExpression.errorMSG}
+                          </div>
+                        )}
+                      </Col>
+                    </Row>
+                  </Form.Group>
+                </div>
+              );
+            }
+            if (uiHintAttb?.isMultiValue) {
+              const [selectedInputVal, setSelectVal] = useState(
+                value?.[m.name] || []
+              );
+              const handleChange = (e, name) => {
+                setSelectVal(e);
+                tagAccessData(e, name);
+              };
+              return (
+                <div key={m.name}>
+                  <Form.Group
+                    className="mb-3"
+                    controlId="Ip-range"
+                    key={m.name}
+                  >
+                    <b>{m.label}:</b>
+                    <CreatableSelect
+                      {...selectProps}
+                      defaultValue={
+                        selectedInputVal == ""
+                          ? null
+                          : !isArray(selectedInputVal)
+                          ? selectedInputVal
+                              ?.split(", ")
+                              .map((obj) => ({ label: obj, value: obj }))
+                          : selectedInputVal
+                      }
+                      onChange={(e) => handleChange(e, m.name)}
+                      placeholder="enter expression"
+                      width="500px"
+                      isClearable={false}
+                    />
+                  </Form.Group>
+                </div>
+              );
+            }
           }
         })}
     </>
@@ -339,35 +377,75 @@ const Editable = (props) => {
   const initialLoad = useRef(true);
   const popoverRef = useRef(null);
   const selectValRef = useRef(null);
+  const [validExpression, setValidated] = useState({
+    state: false,
+    errorMSG: ""
+  });
   const [state, dispatch] = useReducer(reducer, props, innitialState);
   const { show, value, target } = state;
   let isListenerAttached = false;
-  
+
   const handleClickOutside = (e) => {
-    if (document.getElementById("popover-basic")?.contains(e?.target) == 
false) {
-          dispatch({
-            type: "SET_POPOVER",
-            show: false,
-            target:null
-          });
-        }
-        e?.stopPropagation()
+    if (
+      document.getElementById("popover-basic")?.contains(e?.target) == false
+    ) {
+      dispatch({
+        type: "SET_POPOVER",
+        show: false,
+        target: null
+      });
+    }
+    e?.stopPropagation();
   };
-  
+
   useEffect(() => {
-    if(!isListenerAttached){
-      document?.addEventListener('mousedown', handleClickOutside);
+    if (!isListenerAttached) {
+      document?.addEventListener("mousedown", handleClickOutside);
       isListenerAttached = true;
       return;
-  }
-      return () => {
-      document?.removeEventListener('mousedown', handleClickOutside);
+    }
+    return () => {
+      document?.removeEventListener("mousedown", handleClickOutside);
     };
   }, []);
 
   const displayValue = () => {
     let val = "--";
     const selectVal = value;
+    const policyConditionDisplayValue = () => {
+      let ipRangVal, uiHintVal;
+      if (selectVal) {
+        return _.sortBy(Object.keys(selectVal)).map((property, index) => {
+          let conditionObj = find(conditionDefVal, 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(function (m) {
+                return m.value;
+              })
+              .join(", ");
+          }
+          return (
+            <div
+              key={property}
+              className={`${
+                uiHintVal?.isMultiline ? "editable-label" : "badge badge-dark"
+              }`}
+            >
+              {`${conditionObj.label}: ${
+                isArray(selectVal[property]) ? ipRangVal : selectVal[property]
+              }`}
+            </div>
+          );
+        });
+      }
+    };
     if (displayFormat) {
       val = displayFormat(selectVal);
     } else {
@@ -377,10 +455,10 @@ const Editable = (props) => {
             servicedefName == "knox" && !isArray(selectVal)
               ? selectVal["ip-range"]
               : selectVal
-                .map(function (m) {
-                  return m.value;
-                })
-                .join(", ");
+                  .map(function (m) {
+                    return m.value;
+                  })
+                  .join(", ");
           val = (
             <h6 className="d-inline mr-1">
               <span
@@ -420,20 +498,20 @@ const Editable = (props) => {
           selectVal && selectVal?.length > 0 ? (
             <>
               <span className="editable-edit-text">
-              {selectVal.map((op, index) => (
+                {selectVal.map((op, index) => (
                   <h6 className="d-inline mr-1" key={index}>
-                  <Badge variant="info">{op.label}</Badge>
+                    <Badge variant="info">{op.label}</Badge>
                   </h6>
-                 ))}
+                ))}
               </span>
-                <Button
-                  className="mg-10 mx-auto d-block btn-mini"
-                  variant="outline-dark"
-                  size="sm"
-                  type="button"
-                >
-                  <i className="fa-fw fa fa-pencil"></i>
-                </Button>
+              <Button
+                className="mg-10 mx-auto d-block btn-mini"
+                variant="outline-dark"
+                size="sm"
+                type="button"
+              >
+                <i className="fa-fw fa fa-pencil"></i>
+              </Button>
             </>
           ) : (
             <div className="text-center">
@@ -458,20 +536,21 @@ const Editable = (props) => {
       } else if (type === TYPE_INPUT) {
         val =
           selectVal && selectVal !== "" ? (
-           <>
-             <span className="editable-edit-text">
+            <>
+              <span className="editable-edit-text">
                 <h6 className="d-inline mr-1">
-                    <Badge variant="info">{selectVal}</Badge>
+                  <Badge variant="info">{selectVal}</Badge>
                 </h6>
-             </span>
-             <Button
-             className="mg-10 mx-auto d-block btn-mini"
-             variant="outline-dark"
-             size="sm"
-             type="button">
-                  <i className="fa-fw fa fa-pencil"></i>
-            </Button>
-          </>
+              </span>
+              <Button
+                className="mg-10 mx-auto d-block btn-mini"
+                variant="outline-dark"
+                size="sm"
+                type="button"
+              >
+                <i className="fa-fw fa fa-pencil"></i>
+              </Button>
+            </>
           ) : (
             <div className="text-center">
               <span className="editable-add-text">Add Row Filter</span>
@@ -488,12 +567,12 @@ const Editable = (props) => {
       } else if (type === TYPE_RADIO) {
         val =
           selectVal && selectVal?.label ? (
-             <>
-             <span className="editable-edit-text">
+            <>
+              <span className="editable-edit-text">
                 <h6 className="d-inline mr-1">
-                <Badge variant="info">{selectVal.label}</Badge>
+                  <Badge variant="info">{selectVal.label}</Badge>
                 </h6>
-             </span>
+              </span>
               <Button
                 className="mg-10 mx-auto d-block btn-mini"
                 variant="outline-dark"
@@ -502,7 +581,7 @@ const Editable = (props) => {
               >
                 <i className="fa-fw fa fa-pencil"></i>
               </Button>
-               </>
+            </>
           ) : (
             <div className="text-center">
               <span className="editable-add-text">Select Masking Option</span>
@@ -517,16 +596,15 @@ const Editable = (props) => {
             </div>
           );
       } else if (type === TYPE_CUSTOM) {
-        if (selectVal?.["accessed-after-expiry"] || selectVal?.expression) {
+        for (const key in selectVal) {
+          if (selectVal[key] == null || selectVal[key] == "") {
+            delete selectVal[key];
+          }
+        }
+        if (Object.keys(selectVal).length != 0) {
           val = (
             <h6>
-              {(selectVal?.["accessed-after-expiry"] !== undefined && 
selectVal?.["accessed-after-expiry"] !== null) &&
-              <div className="badge badge-dark">
-                {`Accessed after expiry_date (yes/no) : 
${selectVal?.["accessed-after-expiry"]}`}
-              </div>}
-              {(selectVal?.expression !==  undefined && selectVal?.expression 
!== "") &&
-              <div className="editable-label">{`Boolean expression : 
${selectVal?.expression}`}
-              </div>}
+              {policyConditionDisplayValue()}
               <Button
                 className="mg-10 mx-auto d-block btn-mini"
                 variant="outline-dark"
@@ -571,21 +649,54 @@ const Editable = (props) => {
     } else {
       initialLoad.current = false;
     }
-    type === TYPE_CUSTOM  ? selectValRef.current = {...editableValue} :
-    selectValRef.current = editableValue;
+    type === TYPE_CUSTOM
+      ? (selectValRef.current = { ...editableValue })
+      : (selectValRef.current = editableValue);
   }, [editableValue]);
 
-  const handleApply = () => {
-    dispatch({
-      type: "SET_VALUE",
-      value: selectValRef.current,
-      show: !show,
-      target: null
-    });
-    onChange(selectValRef.current);
+  const handleApply = (e) => {
+    let errors, uiHintVal;
+    if (selectValRef?.current) {
+      _.sortBy(Object.keys(selectValRef.current)).map((property) => {
+        let conditionObj = find(conditionDefVal, function (m) {
+          if (m.name == property) {
+            return m;
+          }
+        });
+        if (conditionObj != undefined && conditionObj?.uiHint != "") {
+          uiHintVal = JSON.parse(conditionObj.uiHint);
+          if (
+            uiHintVal?.isMultiline &&
+            selectValRef.current[conditionObj.name] != "" &&
+            selectValRef.current[conditionObj.name] != undefined
+          ) {
+            try {
+              let t = esprima.parseScript(
+                selectValRef.current[conditionObj.name]
+              );
+            } catch (e) {
+              errors = e.message;
+            }
+          }
+        }
+      });
+    }
+    if (errors) {
+      setValidated({ state: true, errorMSG: errors });
+    } else {
+      setValidated({ state: false, errorMSG: "" });
+      dispatch({
+        type: "SET_VALUE",
+        value: selectValRef.current,
+        show: !show,
+        target: null
+      });
+      onChange(selectValRef.current);
+    }
   };
 
-  const handleClose = () => {
+  const handleClose = (e) => {
+    setValidated({ state: false, errorMSG: "" });
     dispatch({
       type: "SET_POPOVER",
       show: !show,
@@ -596,8 +707,9 @@ const Editable = (props) => {
   const popoverComp = (
     <Popover
       id="popover-basic"
-      className={`editable-popover ${type === TYPE_CHECKBOX && 
"popover-maxHeight"
-        }`}
+      className={`editable-popover ${
+        type === TYPE_CHECKBOX && "popover-maxHeight"
+      }`}
     >
       <Popover.Title>
         {type === TYPE_CHECKBOX ? "Select" : "Enter"}
@@ -628,6 +740,7 @@ const Editable = (props) => {
             valRef={selectValRef}
             conditionDefVal={props.conditionDefVal}
             selectProps={props.selectProps}
+            validExpression={validExpression}
           />
         ) : null}
       </Popover.Content>
@@ -653,6 +766,7 @@ const Editable = (props) => {
   );
 
   const handleClick = (e) => {
+    setValidated({ state: false, errorMSG: "" });
     let display = !show;
     dispatch({
       type: "SET_POPOVER",
@@ -660,7 +774,7 @@ const Editable = (props) => {
       target: e.target
     });
   };
-  
+
   return (
     <div ref={popoverRef}>
       <OverlayTrigger
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 80ce6acfe..7edee019e 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
@@ -1417,3 +1417,22 @@ export const requestDataTitle = (serviceType) => {
   }
   return title;
 };
+
+//Policy condition evaluation
+
+export const policyConditionUpdatedJSON = (policyCond) => {
+  let newPolicyConditionJSON = [...policyCond];
+  newPolicyConditionJSON.filter(function (key, val) {
+    if (!key?.uiHint || key?.uiHint == "") {
+      if (
+        key.evaluatorOptions &&
+        key.evaluatorOptions?.["ui.isMultiline"] == "true"
+      ) {
+        key["uiHint"] = '{ "isMultiline":true }';
+      } else {
+        key["uiHint"] = '{ "isMultiValue":true }';
+      }
+    }
+  });
+  return newPolicyConditionJSON;
+};
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 7978efda0..7d18afbcc 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
@@ -456,13 +456,17 @@ export function PolicyViewDetails(props) {
                       <td className="text-center">
                         {!isEmpty(items.conditions)
                           ? items.conditions.map((obj, index) => {
+                              let conditionObj =
+                                filterServiceDef.policyConditions.find((e) => {
+                                  return e.name == obj.type;
+                                });
                               return (
                                 <h6 className="d-inline mr-1" key={index}>
                                   <Badge
                                     variant="info"
                                     className="d-inline mr-1"
                                     key={obj.values}
-                                  >{`${obj.type}: ${obj.values.join(
+                                  >{`${conditionObj.label}: ${obj.values.join(
                                     ", "
                                   )}`}</Badge>
                                 </h6>
@@ -559,25 +563,12 @@ export function PolicyViewDetails(props) {
           <div className="overflow-auto">
             <Table bordered size="sm" 
className="table-audit-filter-ready-only">
               <tbody>
-                {serviceType == "tag" ? (
-                  conditions.map((obj) => (
-                    <tr key={obj.type} colSpan="2">
-                      <td width="40%">{getConditionLabel(obj.type)}</td>
-                      <td width="60% text-truncate">{obj.values}</td>
-                    </tr>
-                  ))
-                ) : (
-                  <tr colSpan="2">
-                    <td width="20%">
-                      {filterServiceDef.policyConditions.map(
-                        (obj) => obj.label
-                      )}
-                    </td>
-                    <td className="text-left">
-                      {conditions.map((val) => val.values).join("")}
-                    </td>
+                {conditions.map((obj) => (
+                  <tr key={obj.type} colSpan="2">
+                    <td width="40%">{getConditionLabel(obj.type)}</td>
+                    <td width="60% text-truncate">{obj.values.join(", ")}</td>
                   </tr>
-                )}
+                ))}
               </tbody>
             </Table>
           </div>
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 13a8eaf4f..51df2e378 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
@@ -53,7 +53,7 @@ import PolicyPermissionItem from 
"../PolicyListing/PolicyPermissionItem";
 import { useParams, useNavigate, useLocation } from "react-router-dom";
 import PolicyValidityPeriodComp from "./PolicyValidityPeriodComp";
 import PolicyConditionsComp from "./PolicyConditionsComp";
-import { getAllTimeZoneList } from "Utils/XAUtils";
+import { getAllTimeZoneList, policyConditionUpdatedJSON } from "Utils/XAUtils";
 import moment from "moment";
 import {
   InfoIcon,
@@ -492,39 +492,22 @@ export default function AddUpdatePolicyForm(props) {
             obj.dataMaskInfo.valueExpr = key.dataMaskInfo.valueExpr;
           }
         }
-
-        if (
-          key?.conditions &&
-          isObject(key.conditions) &&
-          serviceCompDetails.name == "tag"
-        ) {
+        if (key?.conditions) {
           obj.conditions = [];
-          Object.entries(key.conditions).map(([key, value]) => {
-            if (!isEmpty(value)) {
+          Object.entries(key.conditions).map(
+            ([conditionKey, conditionValue]) => {
               return obj.conditions.push({
-                type: key,
-                values: value?.split(", ")
-              });
-            }
-          });
-        } else if (
-          !isEmpty(key?.conditions) &&
-          isObject(key.conditions) &&
-          serviceCompDetails.name == "knox"
-        ) {
-          obj.conditions = [
-            {
-              type: "ip-range",
-              values:
-                !isEmpty(Object.keys(key.conditions)) &&
-                !isArray(key.conditions)
-                  ? key.conditions["ip-range"]?.split(", ")
-                  : key.conditions.map((value) => {
-                      return value.value;
+                type: conditionKey,
+                values: !isArray(conditionValue)
+                  ? conditionValue?.split(",")
+                  : conditionValue.map((m) => {
+                      return m.value;
                     })
+              });
             }
-          ];
+          );
         }
+
         if (
           !isEmpty(obj) &&
           !isEmpty(obj?.delegateAdmin) &&
@@ -730,8 +713,8 @@ export default function AddUpdatePolicyForm(props) {
 
     /*Policy Condition*/
     if (values?.conditions) {
+      data.conditions = [];
       Object.entries(values.conditions).map(([key, value]) => {
-        data.conditions = [];
         return data.conditions.push({
           type: key,
           values: value?.split(",")
@@ -1329,9 +1312,9 @@ export default function AddUpdatePolicyForm(props) {
                                         name="conditions"
                                         render={({ input }) => (
                                           <PolicyConditionsComp
-                                            policyConditionDetails={
+                                            
policyConditionDetails={policyConditionUpdatedJSON(
                                               
serviceCompDetails.policyConditions
-                                            }
+                                            )}
                                             inputVal={input}
                                             showModal={showModal}
                                             handleCloseModal={
@@ -1360,11 +1343,25 @@ export default function AddUpdatePolicyForm(props) {
                                   !isEmpty(values.conditions) ? (
                                     Object.keys(values.conditions).map(
                                       (keyName, keyIndex) => {
-                                        return (
-                                          <tr>
-                                            <>
+                                        if (
+                                          values.conditions[keyName] != "" &&
+                                          values.conditions[keyName] != null
+                                        ) {
+                                          let conditionObj = find(
+                                            
serviceCompDetails?.policyConditions,
+                                            function (m) {
+                                              if (m.name == keyName) {
+                                                return m;
+                                              }
+                                            }
+                                          );
+                                          return (
+                                            <tr key={keyName}>
                                               <td>
-                                                <center> {keyName} </center>
+                                                <center>
+                                                  {" "}
+                                                  {conditionObj.label}{" "}
+                                                </center>
                                               </td>
                                               <td>
                                                 {isObject(
@@ -1388,9 +1385,9 @@ export default function AddUpdatePolicyForm(props) {
                                                   </center>
                                                 )}
                                               </td>
-                                            </>
-                                          </tr>
-                                        );
+                                            </tr>
+                                          );
+                                        }
                                       }
                                     )
                                   ) : (
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 9498d3fe3..32d802809 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
@@ -22,7 +22,7 @@ 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, omit } from "lodash";
+import { find } from "lodash";
 import { InfoIcon } from "../../utils/XAUtils";
 import { RegexMessage } from "../../utils/XAMessages";
 const esprima = require("esprima");
@@ -39,7 +39,7 @@ export default function PolicyConditionsComp(props) {
   const handleSubmit = (values) => {
     for (let val in values.conditions) {
       if (values.conditions[val] == null || values.conditions[val] == "") {
-        omit(values.conditions, val);
+        delete values.conditions[val];
       }
     }
     inputVal.onChange(values.conditions);
@@ -126,100 +126,112 @@ export default function PolicyConditionsComp(props) {
               <Modal.Body>
                 {policyConditionDetails?.length > 0 &&
                   policyConditionDetails.map((m, index) => {
-                    if (m.name == "accessed-after-expiry") {
-                      return (
-                        <FormB.Group className="mb-3">
-                          <b>{m.label}:</b>
+                    let uiHintAttb =
+                      m.uiHint != undefined && m.uiHint != ""
+                        ? JSON.parse(m.uiHint)
+                        : "";
+                    if (uiHintAttb != "") {
+                      if (uiHintAttb?.singleValue) {
+                        return (
+                          <div key={m.name}>
+                            <FormB.Group className="mb-3">
+                              <b>{m.label}:</b>
 
-                          <Field
-                            className="form-control"
-                            name={`conditions.${m.name}`}
-                            render={({ input }) => (
-                              <Select
-                                {...input}
-                                options={accessedOpt}
-                                isClearable
-                                value={accessedVal(input.value)}
-                                onChange={(val) => accessedOnChange(val, 
input)}
+                              <Field
+                                className="form-control"
+                                name={`conditions.${m.name}`}
+                                render={({ input }) => (
+                                  <Select
+                                    {...input}
+                                    options={accessedOpt}
+                                    isClearable
+                                    value={accessedVal(input.value)}
+                                    onChange={(val) =>
+                                      accessedOnChange(val, input)
+                                    }
+                                  />
+                                )}
                               />
-                            )}
-                          />
-                        </FormB.Group>
-                      );
-                    }
-                    if (m.name == "expression") {
-                      return (
-                        <>
-                          <FormB.Group className="mb-3">
-                            <Row>
-                              <Col>
-                                <b>{m.label}:</b>
-                                <InfoIcon
-                                  position="right"
-                                  message={
-                                    <p className="pd-10">
-                                      {
-                                        RegexMessage.MESSAGE
-                                          .policyconditioninfoicon
-                                      }
-                                    </p>
-                                  }
-                                />
-                              </Col>
-                            </Row>
-                            <Row>
-                              <Col>
-                                <Field
-                                  name={`conditions.${m.name}`}
-                                  validate={validater}
-                                  render={({ input, meta }) => (
-                                    <>
-                                      <FormB.Control
-                                        {...input}
-                                        className={
-                                          meta.error
-                                            ? "form-control border 
border-danger"
-                                            : "form-control"
+                            </FormB.Group>
+                          </div>
+                        );
+                      }
+                      if (uiHintAttb?.isMultiline) {
+                        return (
+                          <div key={m.name}>
+                            <FormB.Group className="mb-3">
+                              <Row>
+                                <Col>
+                                  <b>{m.label}:</b>
+                                  <InfoIcon
+                                    position="right"
+                                    message={
+                                      <p className="pd-10">
+                                        {
+                                          RegexMessage.MESSAGE
+                                            .policyconditioninfoicon
                                         }
-                                        as="textarea"
-                                        rows={3}
-                                      />
-                                      {meta.error && (
-                                        <span className="invalid-field">
-                                          {meta.error}
-                                        </span>
-                                      )}
-                                    </>
-                                  )}
-                                />
-                              </Col>
-                            </Row>
-                          </FormB.Group>
-                        </>
-                      );
-                    }
-                    if (m.name == "ip-range") {
-                      return (
-                        <FormB.Group className="mb-3">
-                          <b>{m.label}:</b>
+                                      </p>
+                                    }
+                                  />
+                                </Col>
+                              </Row>
+                              <Row>
+                                <Col>
+                                  <Field
+                                    name={`conditions.${m.name}`}
+                                    validate={validater}
+                                    render={({ input, meta }) => (
+                                      <>
+                                        <FormB.Control
+                                          {...input}
+                                          className={
+                                            meta.error
+                                              ? "form-control border 
border-danger"
+                                              : "form-control"
+                                          }
+                                          as="textarea"
+                                          rows={3}
+                                        />
+                                        {meta.error && (
+                                          <span className="invalid-field">
+                                            {meta.error}
+                                          </span>
+                                        )}
+                                      </>
+                                    )}
+                                  />
+                                </Col>
+                              </Row>
+                            </FormB.Group>
+                          </div>
+                        );
+                      }
+                      if (uiHintAttb?.isMultiValue) {
+                        return (
+                          <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="enter expression"
-                                width="500px"
-                                value={ipRangeVal(input.value)}
-                                onChange={(e) => handleChange(e, input)}
+                              <Field
+                                className="form-control"
+                                name={`conditions.${m.name}`}
+                                render={({ input }) => (
+                                  <CreatableSelect
+                                    {...input}
+                                    isMulti
+                                    isClearable
+                                    placeholder="enter expression"
+                                    width="500px"
+                                    value={ipRangeVal(input.value)}
+                                    onChange={(e) => handleChange(e, input)}
+                                  />
+                                )}
                               />
-                            )}
-                          />
-                        </FormB.Group>
-                      );
+                            </FormB.Group>
+                          </div>
+                        );
+                      }
                     }
                   })}
               </Modal.Body>
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 af1191f99..821d39370 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
@@ -28,7 +28,13 @@ import { toast } from "react-toastify";
 import Editable from "Components/Editable";
 import { RangerPolicyType } from "Utils/XAEnums";
 import TagBasePermissionItem from "./TagBasePermissionItem";
-import { dragStart, dragEnter, drop, dragOver } from "../../utils/XAUtils";
+import {
+  dragStart,
+  dragEnter,
+  drop,
+  dragOver,
+  policyConditionUpdatedJSON
+} from "../../utils/XAUtils";
 
 const noneOptions = {
   label: "None",
@@ -171,13 +177,14 @@ export default function PolicyPermissionItem(props) {
 
   const required = (value) => (value ? undefined : "Required");
 
-  const requiredForPermission = (fieldVals, index) => {
+  const requiredForPolicyItem = (fieldVals, index) => {
     if (fieldVals && !isEmpty(fieldVals[index])) {
       let error, accTypes;
       let users = (fieldVals[index]?.users || []).length > 0;
       let grps = (fieldVals[index]?.groups || []).length > 0;
       let roles = (fieldVals[index]?.roles || []).length > 0;
       let delegateAdmin = fieldVals[index]?.delegateAdmin;
+      let policyConditionVal = fieldVals[index]?.conditions;
       if (fieldVals[index]?.accesses && !isArray(fieldVals[index]?.accesses)) {
         if (serviceCompDetails?.name == "tag") {
           accTypes =
@@ -208,26 +215,29 @@ export default function PolicyPermissionItem(props) {
             "Please select users/groups/roles for selected permission item";
         }
       }
-      return error;
-    }
-  };
-
-  const requiredForDeleGateAdmin = (fieldVals, index) => {
-    if (
-      !isEmpty(fieldVals?.[index]) &&
-      has(fieldVals?.[index], "delegateAdmin")
-    ) {
-      let delError;
-      let users = (fieldVals[index]?.users || []).length > 0;
-      let grps = (fieldVals[index]?.groups || []).length > 0;
-      let roles = (fieldVals[index]?.roles || []).length > 0;
-      let delegateAdmin = fieldVals[index]?.delegateAdmin;
-
       if (delegateAdmin && !users && !grps && !roles) {
-        delError =
-          "Please select user/group/role for the selected delegate Admin";
+        error = "Please select user/group/role for the selected delegate 
Admin";
       }
-      return delError;
+      if (policyConditionVal) {
+        for (const key in policyConditionVal) {
+          if (
+            policyConditionVal[key] == null ||
+            policyConditionVal[key] == ""
+          ) {
+            delete policyConditionVal[key];
+          }
+        }
+        if (
+          Object.keys(policyConditionVal).length != 0 &&
+          !users &&
+          !grps &&
+          !roles
+        ) {
+          error =
+            "Please select user/group/role for the entered policy condition";
+        }
+      }
+      return error;
     }
   };
 
@@ -386,47 +396,35 @@ export default function PolicyPermissionItem(props) {
                           );
                         }
                         if (colName == "Policy Conditions") {
-                          return serviceCompDetails?.policyConditions?.length 
==
-                            1 ? (
-                            <td key={colName} className="align-middle">
-                              <Field
-                                className="form-control"
-                                name={`${name}.conditions`}
-                                render={({ input, meta }) => (
-                                  <div className="table-editable">
-                                    <Editable
-                                      {...input}
-                                      placement="auto"
-                                      type="select"
-                                      conditionDefVal={
-                                        serviceCompDetails.policyConditions[0]
-                                      }
-                                      servicedefName={serviceCompDetails.name}
-                                      selectProps={{ isMulti: true }}
-                                    />
-                                  </div>
-                                )}
-                              />
-                            </td>
-                          ) : (
-                            <td key={colName} className="align-middle">
-                              <Field
-                                className="form-control"
-                                name={`${name}.conditions`}
-                                render={({ input, meta }) => (
-                                  <div className="table-editable">
-                                    <Editable
-                                      {...input}
-                                      placement="auto"
-                                      type="custom"
-                                      conditionDefVal={
-                                        serviceCompDetails.policyConditions
-                                      }
-                                    />
-                                  </div>
-                                )}
-                              />
-                            </td>
+                          return (
+                            serviceCompDetails?.policyConditions?.length >
+                              0 && (
+                              <td key={colName} className="align-middle">
+                                <Field
+                                  className="form-control"
+                                  name={`${name}.conditions`}
+                                  validate={(value, formValues) =>
+                                    requiredForPolicyItem(
+                                      formValues[attrName],
+                                      index
+                                    )
+                                  }
+                                  render={({ input, meta }) => (
+                                    <div className="table-editable">
+                                      <Editable
+                                        {...input}
+                                        placement="auto"
+                                        type="custom"
+                                        
conditionDefVal={policyConditionUpdatedJSON(
+                                          serviceCompDetails.policyConditions
+                                        )}
+                                        selectProps={{ isMulti: true }}
+                                      />
+                                    </div>
+                                  )}
+                                />
+                              </td>
+                            )
                           );
                         }
                         if (colName == "Permissions") {
@@ -437,7 +435,7 @@ export default function PolicyPermissionItem(props) {
                                   className="form-control"
                                   name={`${name}.accesses`}
                                   validate={(value, formValues) =>
-                                    requiredForPermission(
+                                    requiredForPolicyItem(
                                       formValues[attrName],
                                       index
                                     )
@@ -463,7 +461,7 @@ export default function PolicyPermissionItem(props) {
                                   className="form-control"
                                   name={`${name}.accesses`}
                                   validate={(value, formValues) =>
-                                    requiredForPermission(
+                                    requiredForPolicyItem(
                                       formValues[attrName],
                                       index
                                     )
@@ -646,7 +644,7 @@ export default function PolicyPermissionItem(props) {
                                   className="form-control"
                                   name={`${name}.delegateAdmin`}
                                   validate={(value, formValues) =>
-                                    requiredForDeleGateAdmin(
+                                    requiredForPolicyItem(
                                       formValues[attrName],
                                       index
                                     )
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 f75ddd4c3..a4ccffb5e 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
@@ -277,7 +277,8 @@ export default function ServiceAuditFilter(props) {
                                 <Select
                                   {...input}
                                   menuPortalTarget={document.body}
-                                  isClearable={false}
+                                  isClearable={true}
+                                  isSearchable={false}
                                   options={[
                                     { value: "DENIED", label: "DENIED" },
                                     { value: "ALLOWED", label: "ALLOWED" },
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceForm.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceForm.jsx
index 83b2b386b..633a934ee 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceForm.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceForm.jsx
@@ -191,7 +191,8 @@ class ServiceForm extends Component {
 
     if (values?.customConfigs !== undefined) {
       values.customConfigs?.map((config) => {
-        config !== undefined &&
+        config?.name !== undefined &&
+          config?.value !== undefined &&
           (serviceJson["configs"][config.name] = config.value);
       });
     }

Reply via email to