diff --git a/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.js b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.js
index eb2d28d110..6fb9f6c919 100644
--- a/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.js
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.js
@@ -16,6 +16,7 @@ import {
BooleanField,
InputField,
ObjectField,
+ InputAlertField,
} from '../../shared/SharedFields';
import { RevertAllAlert, RevertFormActionGroup } from '../../shared';
import { formatJson, pluck } from '../../shared/settingUtils';
@@ -211,7 +212,7 @@ function MiscAuthenticationEdit() {
name="ALLOW_OAUTH2_FOR_EXTERNAL_USERS"
config={authentication.ALLOW_OAUTH2_FOR_EXTERNAL_USERS}
/>
-
diff --git a/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.test.js b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.test.js
index 1f08edd0a7..b3cbd31db2 100644
--- a/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.test.js
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.test.js
@@ -64,6 +64,46 @@ describe('', () => {
await waitForElement(wrapper, 'ContentLoading', (el) => el.length === 0);
});
+ test('should enable edit login redirect once alert is confirmed', async () => {
+ expect(
+ wrapper.find('TextInput#LOGIN_REDIRECT_OVERRIDE').prop('isDisabled')
+ ).toBe(true);
+ await act(async () =>
+ wrapper
+ .find('Button[ouiaId="confirm-edit-login-redirect"]')
+ .simulate('click')
+ );
+ wrapper.update();
+ const modal = wrapper.find('AlertModal');
+ expect(modal).toHaveLength(1);
+ expect(modal.prop('isOpen')).toEqual(true);
+ await act(async () =>
+ modal
+ .find('Button[aria-label="confirm edit login redirect"]')
+ .simulate('click')
+ );
+ wrapper.update();
+ expect(
+ wrapper.find('TextInput#LOGIN_REDIRECT_OVERRIDE').prop('isDisabled')
+ ).toBe(false);
+
+ await act(async () => {
+ wrapper.find('TextInput#LOGIN_REDIRECT_OVERRIDE').invoke('onChange')(
+ null,
+ {
+ target: {
+ name: 'LOGIN_REDIRECT_OVERRIDE',
+ value: 'bar',
+ },
+ }
+ );
+ });
+ wrapper.update();
+ expect(
+ wrapper.find('TextInput#LOGIN_REDIRECT_OVERRIDE').prop('value')
+ ).toEqual('bar');
+ });
+
test('initially renders without crashing', async () => {
expect(wrapper.find('MiscAuthenticationEdit').length).toBe(1);
});
diff --git a/awx/ui_next/src/screens/Setting/shared/SharedFields.js b/awx/ui_next/src/screens/Setting/shared/SharedFields.js
index 90bae3c6af..bb39074b88 100644
--- a/awx/ui_next/src/screens/Setting/shared/SharedFields.js
+++ b/awx/ui_next/src/screens/Setting/shared/SharedFields.js
@@ -10,8 +10,11 @@ import {
Switch,
TextArea,
TextInput,
+ Tooltip,
+ ButtonVariant,
} from '@patternfly/react-core';
import FileUploadIcon from '@patternfly/react-icons/dist/js/icons/file-upload-icon';
+import { ExclamationCircleIcon as PFExclamationCircleIcon } from '@patternfly/react-icons';
import styled from 'styled-components';
import AnsibleSelect from 'components/AnsibleSelect';
import CodeEditor from 'components/CodeEditor';
@@ -22,6 +25,12 @@ import { combine, integer, minMaxValue, required, url } from 'util/validators';
import AlertModal from 'components/AlertModal';
import RevertButton from './RevertButton';
+const ExclamationCircleIcon = styled(PFExclamationCircleIcon)`
+ && {
+ color: var(--pf-global--danger-color--100);
+ }
+`;
+
const FormGroup = styled(PFFormGroup)`
.pf-c-form__group-label {
display: inline-flex;
@@ -30,6 +39,13 @@ const FormGroup = styled(PFFormGroup)`
}
`;
+const Selected = styled.div`
+ display: flex;
+ justify-content: space-between;
+ background-color: white;
+ border-bottom-color: var(--pf-global--BorderColor--200);
+`;
+
const SettingGroup = ({
children,
defaultValue,
@@ -114,7 +130,9 @@ const BooleanField = ({
{t`Cancel`}
,
]}
- >{t`Are you sure you want to disable local authentication? Doing so could impact users' ability to log in and the system administrator's ability to reverse this change.`}
+ >
+ {t`Are you sure you want to disable local authentication? Doing so could impact users' ability to log in and the system administrator's ability to reverse this change.`}
+
);
}
@@ -215,6 +233,106 @@ EncryptedField.propTypes = {
config: shape({}).isRequired,
};
+const InputAlertField = ({ name, config }) => {
+ const [field, meta] = useField({ name });
+ const isValid = !(meta.touched && meta.error);
+ const [isModalOpen, setIsModalOpen] = useState(false);
+ const [isDisable, setIsDisable] = useState(true);
+
+ const handleSetIsOpen = () => {
+ setIsModalOpen(true);
+ };
+
+ const handleEnableTextInput = () => {
+ setIsDisable(false);
+ };
+
+ return config ? (
+ <>
+
+
+ {isDisable && (
+
+
+
+ )}
+ {
+ field.onChange(event);
+ }}
+ isDisabled={isDisable}
+ />
+
+
+ {isModalOpen && isDisable && (
+ {
+ setIsModalOpen(false);
+ }}
+ actions={[
+ ,
+ ,
+ ]}
+ >
+ {t`Are you sure you want to edit login redirect override URL? Doing so could impact users' ability to log in to the system once local authentication is also disabled.`}
+
+ )}
+ >
+ ) : null;
+};
+
+InputAlertField.propTypes = {
+ name: string.isRequired,
+ config: shape({}).isRequired,
+};
+
const InputField = ({ name, config, type = 'text', isRequired = false }) => {
const min_value = config?.min_value ?? Number.MIN_SAFE_INTEGER;
const max_value = config?.max_value ?? Number.MAX_SAFE_INTEGER;
@@ -407,4 +525,5 @@ export {
InputField,
ObjectField,
TextAreaField,
+ InputAlertField,
};
diff --git a/awx/ui_next/src/screens/Setting/shared/SharedFields.test.js b/awx/ui_next/src/screens/Setting/shared/SharedFields.test.js
index 35c494fe83..a081945e5b 100644
--- a/awx/ui_next/src/screens/Setting/shared/SharedFields.test.js
+++ b/awx/ui_next/src/screens/Setting/shared/SharedFields.test.js
@@ -9,6 +9,7 @@ import {
ChoiceField,
EncryptedField,
FileUploadField,
+ InputAlertField,
InputField,
ObjectField,
TextAreaField,
@@ -158,6 +159,30 @@ describe('Setting form fields', () => {
expect(wrapper.find('TextInputBase').prop('value')).toEqual(0);
});
+ test('InputAlertField initially renders disable TextInput', async () => {
+ const wrapper = mountWithContexts(
+
+ {() => (
+
+ )}
+
+ );
+ expect(wrapper.find('TextInput')).toHaveLength(1);
+ expect(wrapper.find('TextInput').prop('value')).toEqual('');
+ expect(wrapper.find('TextInput').prop('isDisabled')).toBe(true);
+ });
+
test('TextAreaField renders the expected content', async () => {
const wrapper = mountWithContexts(