This is an automated email from the ASF dual-hosted git repository. dhavaljrajpara pushed a commit to branch RANGER-5445 in repository https://gitbox.apache.org/repos/asf/ranger.git
commit f493ea804d24b5d523733fe47faca47e5ae6ee1e Author: Dhaval Rajpara <[email protected]> AuthorDate: Fri Jul 17 08:22:12 2026 +0530 RANGER-5445 : Implement Confirmation Modal for Users/Groups/Roles Removal --- .../src/components/CommonComponents.jsx | 64 ++++++++++++++++- .../main/webapp/react-webapp/src/styles/style.css | 36 ++++++++-- .../webapp/react-webapp/src/utils/XAMessages.js | 14 ++-- .../main/webapp/react-webapp/src/utils/XAUtils.js | 12 +++- .../Admin/AdminLogs/PolicyViewDetails.jsx | 26 +++---- .../views/PolicyListing/AddUpdatePolicyForm.jsx | 23 +++--- .../views/PolicyListing/PolicyConditionsComp.jsx | 2 +- .../views/PolicyListing/PolicyPermissionItem.jsx | 39 +++++++--- .../src/views/Reports/SearchPolicyTable.jsx | 83 ++++++++++++++++------ .../src/views/Reports/UserAccessLayout.jsx | 2 +- .../src/views/SecurityZone/SecurityZoneForm.jsx | 27 +++++-- .../src/views/ServiceManager/ServiceDefinition.jsx | 2 +- .../src/views/ServiceManager/ServiceForm.jsx | 9 ++- .../UserGroupRoleListing/role_details/RoleForm.jsx | 15 +++- .../users_details/UserForm.jsx | 7 +- 15 files changed, 285 insertions(+), 76 deletions(-) diff --git a/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx b/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx index 0830f5e1d..e70345d6a 100644 --- a/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx @@ -20,10 +20,18 @@ import { isEmpty, isObject, lastIndexOf } from "lodash"; import moment from "moment-timezone"; import React, { Component, useEffect, useMemo, useState } from "react"; -import { Alert, Badge, Button, OverlayTrigger, Popover } from "react-bootstrap"; +import { + Alert, + Badge, + Button, + OverlayTrigger, + Popover, + Modal +} from "react-bootstrap"; import { Field } from "react-final-form"; import { useLocation } from "react-router-dom"; import blockLoading from "Images/blockLoading.gif"; +import { components as selectComponents } from "react-select"; export const Loader = () => { return ( @@ -336,7 +344,6 @@ export const CustomPopoverOnClick = ({ × </i> </Popover.Header> - <Popover.Body>{content}</Popover.Body> </Popover> } @@ -594,3 +601,56 @@ export const trimInputValue = (e, input) => { } input.onBlur(e); // Always call onBlur to trigger validation }; + +export const ConfirmationClearIndicator = (props) => { + const [show, setShow] = useState(false); + + const message = `Are you sure you want to remove all selected ${props?.selectProps?.clearConfirmMessage} from this field?`; + + const open = (e) => { + e.preventDefault(); + e.stopPropagation(); + setShow(true); + }; + + const onNo = (e) => { + e.stopPropagation(); + setShow(false); + }; + + const onYes = (e) => { + e.stopPropagation(); + props.clearValue(); // clears all selected values (global clear) + props?.selectProps?.onClearConfirmed?.(); + setShow(false); + }; + + // Remove react-select's default inner event handlers so clicks only on our icon trigger the modal + const { innerProps = {}, ...rest } = props; + const { onMouseDown, ...cleanInnerProps } = innerProps; + + return ( + <> + <selectComponents.ClearIndicator {...rest} innerProps={cleanInnerProps}> + <span + style={{ cursor: "pointer" }} + onMouseDown={open} + title="Clear all" + > + <i className="fa fa-times fa-2"></i> + </span> + </selectComponents.ClearIndicator> + <Modal show={show} onHide={() => setShow(false)}> + <Modal.Body>{message}</Modal.Body> + <Modal.Footer> + <Button variant="secondary" size="sm" onMouseDown={onNo}> + No + </Button> + <Button variant="danger" size="sm" onMouseDown={onYes}> + Yes + </Button> + </Modal.Footer> + </Modal> + </> + ); +}; diff --git a/security-admin/src/main/webapp/react-webapp/src/styles/style.css b/security-admin/src/main/webapp/react-webapp/src/styles/style.css index a5c9cff2d..e273bd3e7 100644 --- a/security-admin/src/main/webapp/react-webapp/src/styles/style.css +++ b/security-admin/src/main/webapp/react-webapp/src/styles/style.css @@ -574,9 +574,9 @@ h3.wrap-header { margin-top: 5px; margin-bottom: 5px; border-radius: 5px; - font-size: 70%; - font-weight: 700; padding: 3px; + font-size: 14px; + display: block; } .rule-condition-wrapper { @@ -635,6 +635,7 @@ table.no-bg-color thead tr th:first-child { white-space: nowrap; vertical-align: sub; display: inline-block; + font-size: 14px; } .service-name, @@ -1607,7 +1608,6 @@ header { display: inline-flex; flex-wrap: wrap; font-size: 1rem; - max-height: 100px; overflow-y: auto; width: 100%; } @@ -1617,7 +1617,6 @@ header { flex-wrap: wrap; font-size: 1rem; overflow-y: auto; - max-height: 100px; width: 100%; } @@ -3053,3 +3052,32 @@ table a { .switch[class*="btn-outline"] .switch-handle { background-color: #6c757d !important; } + +.line-clamp-3 { + --line-clamp: 3; +} + +.line-clamp-5 { + --line-clamp: 5; +} + +.line-clamp { + white-space: normal; + word-break: break-all; + width: 100%; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: var(--line-clamp, 3); + overflow: auto; + line-height: 21px; +} + +.condition-group-table td { + font-size: 14px; + color: rgb(33, 37, 41); +} + +.condition-group-table th { + font-size: 15px !important; + color: #333; +} diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js b/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js index a9cf53944..806a34cae 100644 --- a/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js +++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js @@ -50,10 +50,16 @@ export const RegexMessage = { </p> </> ), - policyConditionInfoIcon: - "1. Boolean expression Examples :\ - country_code == 'USA', time_range >= 900 time_range <= 1800 etc.\ - 2. Dragging bottom-right corner of condition editor(Textarea) can resizable", + policyConditionInfoIcon:( + <> + <span className="mb-0" style={{ fontSize: "small" }}> + 1. Boolean expression Examples: + <br /> + country_code == 'USA', time_range >= 900 time_range <= 1800 etc. + <br /> + 2. The condition editor (textarea) can be resized by dragging its bottom-right corner. + </span> + </>), firstNameValidationMsg: ( <> <p className="pd-10 mb-0" style={{ fontSize: "small" }}> 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 d0ca53f8f..ceb4c3aef 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 @@ -1590,7 +1590,17 @@ export const currentTimeZone = (timeZoneDate) => { // Common function to get display label for policy condition export const getPolicyConditionDisplayLbl = (lbl) => { - return policyConditionDisplayLabel.hasOwnProperty(lbl) + return has(policyConditionDisplayLabel, lbl) ? policyConditionDisplayLabel[lbl] : lbl; }; + +// Common function to safeguard JSON parsing +export const safeJsonParse = (value, fallback) => { + try { + return JSON.parse(value); + } catch (error) { + console.error("JSON Parsing Error:", error); + return fallback; + } +}; 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 6feefb53c..2f011b6d4 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 @@ -454,7 +454,7 @@ export function PolicyViewDetails(props) { {!isEmpty( filterServiceDef && filterServiceDef.policyConditions ) && ( - <td className="text-center"> + <td> {!isEmpty(items.conditions) ? items.conditions.map((obj, index) => { let conditionObj = @@ -462,15 +462,13 @@ export function PolicyViewDetails(props) { return e.name == obj.type; }); return ( - <h6 className="d-inline me-1" key={index}> - <Badge - bg="info" - className="d-inline me-1" - key={obj.values} - >{`${getPolicyConditionDisplayLbl( - conditionObj.label - )}: ${obj.values.join(", ")}`}</Badge> - </h6> + <Badge + bg="info" + className="me-1 line-clamp line-clamp-3 text-start" + key={obj.values} + >{`${getPolicyConditionDisplayLbl( + conditionObj.label + )}: ${obj.values.join(", ")}`}</Badge> ); }) : "--"} @@ -565,8 +563,12 @@ export function PolicyViewDetails(props) { <tbody> {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> + <td width="30%">{getConditionLabel(obj.type)}</td> + <td width="70%"> + <span className="line-clamp line-clamp-5 text-start"> + {obj.values.join(", ")} + </span> + </td> </tr> ))} </tbody> 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 617c3d270..b4e6f03ab 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 @@ -72,7 +72,8 @@ import { getResourcesDefVal, getAllTimeZoneList, policyConditionUpdatedJSON, - policyInfo + policyInfo, + getPolicyConditionDisplayLbl } from "Utils/XAUtils"; import { useAccordionButton } from "react-bootstrap/AccordionButton"; import AccordionContext from "react-bootstrap/AccordionContext"; @@ -1550,23 +1551,25 @@ export default function AddUpdatePolicyForm() { return ( <tr key={keyName}> <td> - <center> - {conditionObj.label} - </center> + <span> + {getPolicyConditionDisplayLbl( + conditionObj.label + )} + </span> </td> <td> {isArray( values?.conditions[keyName] ) ? ( - <center> + <span className="line-clamp line-clamp-3"> {values.conditions[ keyName ].join(", ")} - </center> + </span> ) : ( - <center> + <span className="line-clamp line-clamp-3"> {values.conditions[keyName]} - </center> + </span> )} </td> </tr> @@ -1577,7 +1580,9 @@ export default function AddUpdatePolicyForm() { ) : ( <tr> <td> - <center> No Conditions </center> + <center className="text-muted"> + No Conditions + </center> </td> </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 357053436..60ed5e3e6 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 @@ -379,7 +379,7 @@ export default function PolicyConditionsComp(props) { : "form-control" } as="textarea" - rows={3} + rows={12} onBlur={(e) => trimInputValue(e, input) } 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 169f4ab52..6240525b8 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 @@ -43,9 +43,10 @@ import { drop, dragOver, policyConditionUpdatedJSON, - getPolicyConditionDisplayLbl + getPolicyConditionDisplayLbl, + safeJsonParse } from "Utils/XAUtils"; -import { selectInputCustomStyles } from "Components/CommonComponents"; +import { selectInputCustomStyles, ConfirmationClearIndicator } from "Components/CommonComponents"; import PolicyConditionsComp from "./PolicyConditionsComp"; import { getSelectedLeafResourceTypes, @@ -378,7 +379,7 @@ export default function PolicyPermissionItem(props) { }); }; - const policyConditionDisplayValue = (value) => { + const ruleConditionDisplayValue = (value) => { const selectVal = value; let ipRangVal, uiHintVal; if (selectVal) { @@ -392,7 +393,7 @@ export default function PolicyPermissionItem(props) { } ); if (conditionObj?.uiHint && conditionObj?.uiHint != "") { - uiHintVal = JSON.parse(conditionObj.uiHint); + uiHintVal = safeJsonParse(conditionObj.uiHint, {}); } if (isArray(selectVal[property])) { ipRangVal = (selectVal[property] || []) @@ -402,19 +403,21 @@ export default function PolicyPermissionItem(props) { .join(", "); } return ( - <h6 key={property}> - <div + <div key={property}> + <span className={`${ uiHintVal?.isMultiline ? "editable-label rule-condition-wrapper" : "badge bg-dark rule-condition-wrapper" }`} > - {`${getPolicyConditionDisplayLbl(conditionObj.label)}: ${ + <span className="line-clamp line-clamp-5 text-start"> + {`${getPolicyConditionDisplayLbl(conditionObj.label)}: ${ isArray(selectVal[property]) ? ipRangVal : selectVal[property] }`} - </div> - </h6> + </span> + </span> + </div> ); }); } @@ -475,6 +478,11 @@ export default function PolicyPermissionItem(props) { isMulti tabSelectsValue={false} placeholder="Select Roles" + clearConfirmMessage="Roles" + components={{ + ClearIndicator: + ConfirmationClearIndicator + }} /> </div> )} @@ -508,6 +516,11 @@ export default function PolicyPermissionItem(props) { isMulti tabSelectsValue={false} placeholder="Select Groups" + clearConfirmMessage="Groups" + components={{ + ClearIndicator: + ConfirmationClearIndicator + }} /> </div> )} @@ -541,6 +554,11 @@ export default function PolicyPermissionItem(props) { isMulti tabSelectsValue={false} placeholder="Select Users" + clearConfirmMessage="Users" + components={{ + ClearIndicator: + ConfirmationClearIndicator + }} /> </div> )} @@ -587,7 +605,6 @@ export default function PolicyPermissionItem(props) { serviceCompDetails?.name } actionReqsMap={actionReqsMap} - actionFilterContext={{ selectedAccessTypes: getSelectedAccessTypesForRow( @@ -780,7 +797,7 @@ export default function PolicyPermissionItem(props) { )} </div> ) : ( - <div> + <div className="text-center"> <span className="editable-add-text text-secondary"> Select Masking Option </span> 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 b88f664fd..c8f581eb4 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 @@ -280,7 +280,7 @@ function SearchPolicyTable(props) { </Accordion.Body> </Accordion.Item> </Accordion> - <Modal show={showModal} onHide={hidePolicyConditionModal} size="lg"> + <Modal show={showModal} onHide={hidePolicyConditionModal} size="xl"> <Modal.Header closeButton> <Modal.Title>Policy Condition Details</Modal.Title> </Modal.Header> @@ -330,22 +330,20 @@ function PolicyConditionData(props) { )} </td> {!isEmpty(props?.serviceDef?.policyConditions) && ( - <td className="text-center"> + <td> {!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} - >{`${getPolicyConditionDisplayLbl( - conditionObj.label - )}: ${obj.values.join(", ")}`}</Badge> - </h6> + <Badge + bg="info" + className="me-1 line-clamp line-clamp-3 text-start" + key={index} + >{`${getPolicyConditionDisplayLbl( + conditionObj.label + )}: ${obj.values.join(", ")}`}</Badge> ); }) : "--"} @@ -358,6 +356,15 @@ function PolicyConditionData(props) { <div className="text-center">--</div> )} </td> + {props?.serviceDef?.name != "tag" && ( + <td className="text-center"> + <input + type="checkbox" + checked={items.delegateAdmin === false ? false : true} + disabled="disabled" + /> + </td> + )} </tr> ); }); @@ -366,7 +373,7 @@ function PolicyConditionData(props) { <tr key="no-data"> <td className="text-center" - colSpan={!isEmpty(props?.serviceDef?.policyConditions) ? "5" : "4"} + colSpan={!isEmpty(props?.serviceDef?.policyConditions) ? "6" : "5"} > <span className="text-muted">"No data to show!!"</span> </td> @@ -406,17 +413,20 @@ function PolicyConditionData(props) { )} </td> {!isEmpty(props?.serviceDef?.policyConditions) && ( - <td className="text-center"> + <td> {!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> - </h6> + <Badge + bg="info" + className="me-1 line-clamp line-clamp-3 text-start" + key={index} + >{`${getPolicyConditionDisplayLbl( + conditionObj.label + )}: ${obj.values.join(", ")}`}</Badge> ); }) : "--"} @@ -487,6 +497,26 @@ function PolicyConditionData(props) { <div className="text-center">--</div> )} </td> + {!isEmpty(props?.serviceDef?.policyConditions) && ( + <td> + {!isEmpty(items.conditions) + ? items.conditions.map((obj, index) => { + let conditionObj = props.serviceDef.policyConditions.find( + (condition) => condition.name === obj.type + ); + return ( + <Badge + bg="info" + className="me-1 line-clamp line-clamp-3 text-start" + key={index} + >{`${getPolicyConditionDisplayLbl( + conditionObj.label + )}: ${obj.values.join(", ")}`}</Badge> + ); + }) + : "--"} + </td> + )} <td> {!isEmpty(access) ? ( <MoreLess data={access} /> @@ -540,6 +570,7 @@ function PolicyConditionData(props) { <th className="text-center text-nowrap">Rule Conditions</th> )} <th>Accesses</th> + {props?.serviceDef?.name != "tag" && <th>Delegate Admin</th>} </tr> </thead> <tbody>{getPolicyData(props.policyData.policyItems)}</tbody> @@ -566,6 +597,9 @@ function PolicyConditionData(props) { </th> )} <th>Accesses</th> + {props?.serviceDef?.name != "tag" && ( + <th>Delegate Admin</th> + )} </tr> </thead> <tbody> @@ -591,6 +625,9 @@ function PolicyConditionData(props) { </th> )} <th>Accesses</th> + {props?.serviceDef?.name != "tag" && ( + <th>Delegate Admin</th> + )} </tr> </thead> <tbody> @@ -616,6 +653,9 @@ function PolicyConditionData(props) { </th> )} <th>Accesses</th> + {props?.serviceDef?.name != "tag" && ( + <th>Delegate Admin</th> + )} </tr> </thead> <tbody> @@ -671,6 +711,9 @@ function PolicyConditionData(props) { <th>Roles</th> <th>Groups</th> <th>Users</th> + {!isEmpty(props?.serviceDef?.policyConditions) && ( + <th className="text-center text-nowrap">Rule Conditions</th> + )} <th>Accesses</th> <th>Row Level Filter</th> </tr> diff --git a/security-admin/src/main/webapp/react-webapp/src/views/Reports/UserAccessLayout.jsx b/security-admin/src/main/webapp/react-webapp/src/views/Reports/UserAccessLayout.jsx index 5dc1c6914..f9fe792f9 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/Reports/UserAccessLayout.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/Reports/UserAccessLayout.jsx @@ -494,7 +494,7 @@ function UserAccessLayout() { <Accordion.Body> <Form onSubmit={onSubmit} - initialValues={getInitialSearchParams} + initialValues={getInitialSearchParams()} render={({ handleSubmit, submitting, values }) => ( <form onSubmit={handleSubmit}> <Row className="form-group"> diff --git a/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx b/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx index 7d9ad9d31..817320331 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx @@ -49,7 +49,8 @@ import { scrollToError, selectInputCustomStyles, selectInputCustomErrorStyles, - trimInputValue + trimInputValue, + ConfirmationClearIndicator } from "Components/CommonComponents"; import usePrompt from "Hooks/usePrompt"; import { getServiceDef } from "Utils/appState"; @@ -873,11 +874,13 @@ const SecurityZoneForm = () => { isMulti components={{ DropdownIndicator: () => null, - IndicatorSeparator: () => null + IndicatorSeparator: () => null, + ClearIndicator: ConfirmationClearIndicator }} isClearable={true} placeholder="Select Users" tabSelectsValue={false} + clearConfirmMessage="Users" /> </Col> </Row> @@ -918,11 +921,13 @@ const SecurityZoneForm = () => { isMulti components={{ DropdownIndicator: () => null, - IndicatorSeparator: () => null + IndicatorSeparator: () => null, + ClearIndicator: ConfirmationClearIndicator }} isClearable={true} placeholder="Select Groups" tabSelectsValue={false} + clearConfirmMessage="Groups" /> </Col> </Row> @@ -963,11 +968,13 @@ const SecurityZoneForm = () => { isMulti components={{ DropdownIndicator: () => null, - IndicatorSeparator: () => null + IndicatorSeparator: () => null, + ClearIndicator: ConfirmationClearIndicator }} isClearable={true} placeholder="Select Roles" tabSelectsValue={false} + clearConfirmMessage="Roles" /> {meta.touched && meta.error && ( <span className="invalid-field"> @@ -1013,11 +1020,13 @@ const SecurityZoneForm = () => { isMulti components={{ DropdownIndicator: () => null, - IndicatorSeparator: () => null + IndicatorSeparator: () => null, + ClearIndicator: ConfirmationClearIndicator }} isClearable={true} placeholder="Select Users" tabSelectsValue={false} + clearConfirmMessage="Users" /> </Col> </Row> @@ -1058,11 +1067,13 @@ const SecurityZoneForm = () => { isMulti components={{ DropdownIndicator: () => null, - IndicatorSeparator: () => null + IndicatorSeparator: () => null, + ClearIndicator: ConfirmationClearIndicator }} isClearable={true} placeholder="Select Groups" tabSelectsValue={false} + clearConfirmMessage="Groups" /> </Col> </Row> @@ -1103,11 +1114,13 @@ const SecurityZoneForm = () => { isMulti components={{ DropdownIndicator: () => null, - IndicatorSeparator: () => null + IndicatorSeparator: () => null, + ClearIndicator: ConfirmationClearIndicator }} isClearable={true} placeholder="Select Roles" tabSelectsValue={false} + clearConfirmMessage="Roles" /> {meta.error && meta.touched && ( <span className="invalid-field"> diff --git a/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceDefinition.jsx b/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceDefinition.jsx index cc60cd305..0fb63700e 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceDefinition.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceDefinition.jsx @@ -178,7 +178,7 @@ class ServiceDefinition extends Component { pathname: `/service/${s.id}/policies/${RangerPolicyType.RANGER_ACCESS_POLICY_TYPE.value}`, detail: this.props.selectedZone }} - className="service-name text-info" + className="service-name" > {s.displayName !== undefined ? s.displayName : s.name} </Link> 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 cb4d4e65f..6196cea37 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 @@ -42,7 +42,8 @@ import { Loader, scrollToError, selectInputCustomStyles, - trimInputValue + trimInputValue, + ConfirmationClearIndicator } from "Components/CommonComponents"; import { difference, @@ -706,6 +707,12 @@ class ServiceForm extends Component { isClearable={true} styles={selectInputCustomStyles} isMulti + clearConfirmMessage={ + additionalConfig.type == "user" ? "Users" : "Groups" + } + components={{ + ClearIndicator: ConfirmationClearIndicator + }} /> </Col> </Row> diff --git a/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/role_details/RoleForm.jsx b/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/role_details/RoleForm.jsx index 746ff55a6..e459c2f12 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/role_details/RoleForm.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/role_details/RoleForm.jsx @@ -26,7 +26,8 @@ import { Loader, CustomTooltip, selectInputCustomStyles, - trimInputValue + trimInputValue, + ConfirmationClearIndicator } from "Components/CommonComponents"; import { FieldArray } from "react-final-form-arrays"; import arrayMutators from "final-form-arrays"; @@ -639,6 +640,10 @@ function RoleForm() { styles={selectInputCustomStyles} tabSelectsValue={false} placeholder="Select Users" + clearConfirmMessage="Users" + components={{ + ClearIndicator: ConfirmationClearIndicator + }} /> </div> <div className="col-sm-3"> @@ -748,6 +753,10 @@ function RoleForm() { styles={selectInputCustomStyles} tabSelectsValue={false} placeholder="Select Groups" + clearConfirmMessage="Groups" + components={{ + ClearIndicator: ConfirmationClearIndicator + }} /> </div> <div className="col-sm-3"> @@ -857,6 +866,10 @@ function RoleForm() { styles={selectInputCustomStyles} tabSelectsValue={false} placeholder="Select Roles" + clearConfirmMessage="Roles" + components={{ + ClearIndicator: ConfirmationClearIndicator + }} /> </div> <div className="col-sm-3"> diff --git a/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserForm.jsx b/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserForm.jsx index e00333e7d..068475d0f 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserForm.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserForm.jsx @@ -24,7 +24,8 @@ import { BlockUi, scrollToError, selectInputCustomStyles, - trimInputValue + trimInputValue, + ConfirmationClearIndicator } from "Components/CommonComponents"; import AsyncSelect from "react-select/async"; import Select from "react-select"; @@ -244,6 +245,10 @@ function UserForm(props) { styles={selectInputCustomStyles} tabSelectsValue={false} placeholder="Select Groups" + clearConfirmMessage="Groups" + components={{ + ClearIndicator: ConfirmationClearIndicator + }} /> ); };
