diff --git a/awx/ui_next/src/components/CodeEditor/VariablesDetail.jsx b/awx/ui_next/src/components/CodeEditor/VariablesDetail.jsx index beda9dcacd..3e8b08f69e 100644 --- a/awx/ui_next/src/components/CodeEditor/VariablesDetail.jsx +++ b/awx/ui_next/src/components/CodeEditor/VariablesDetail.jsx @@ -49,6 +49,9 @@ function VariablesDetail({ } const modeMatches = isJsonString(value) === (mode === JSON_MODE); if (modeMatches) { + if (mode === JSON_MODE) { + return JSON.stringify(JSON.parse(value), null, 2); + } return value; } return mode === YAML_MODE ? jsonToYaml(value) : yamlToJson(value); diff --git a/awx/ui_next/src/components/CodeEditor/VariablesDetail.test.jsx b/awx/ui_next/src/components/CodeEditor/VariablesDetail.test.jsx index c28061cf3f..8b5da1a9e3 100644 --- a/awx/ui_next/src/components/CodeEditor/VariablesDetail.test.jsx +++ b/awx/ui_next/src/components/CodeEditor/VariablesDetail.test.jsx @@ -24,7 +24,15 @@ describe('', () => { const input = wrapper.find('VariablesDetail___StyledCodeEditor'); expect(input).toHaveLength(1); expect(input.prop('mode')).toEqual('javascript'); - expect(input.prop('value')).toEqual('{"foo": "bar"}'); + }); + + test('should format JSON', () => { + const wrapper = mountWithContexts( + + ); + const input = wrapper.find('VariablesDetail___StyledCodeEditor'); + expect(input).toHaveLength(1); + expect(input.prop('value')).toEqual('{\n "foo": "bar"\n}'); }); test('should convert between modes', () => { diff --git a/awx/ui_next/src/components/CodeEditor/VariablesField.jsx b/awx/ui_next/src/components/CodeEditor/VariablesField.jsx index aec4e4824f..58fee94765 100644 --- a/awx/ui_next/src/components/CodeEditor/VariablesField.jsx +++ b/awx/ui_next/src/components/CodeEditor/VariablesField.jsx @@ -57,11 +57,12 @@ function VariablesField({ ); const [field, meta, helpers] = useField({ name, validate }); - // mode's useState above couldn't be initialized to JSON_MODE because - // the field value had to be defined below it - useEffect(function initializeMode() { + useEffect(function initializeJSON() { if (isJsonString(field.value)) { + // mode's useState above couldn't be initialized to JSON_MODE because + // the field value had to be defined below it setMode(JSON_MODE); + helpers.setValue(JSON.stringify(JSON.parse(field.value), null, 2)); } }, []); // eslint-disable-line react-hooks/exhaustive-deps @@ -193,7 +194,14 @@ function VariablesFieldInternals({ setShouldValidate, handleChange, }) { - const [field, meta] = useField(name); + const [field, meta, helpers] = useField(name); + + useEffect(function formatJsonString() { + if (mode === YAML_MODE) { + return; + } + helpers.setValue(JSON.stringify(JSON.parse(field.value), null, 2)); + }, []); // eslint-disable-line react-hooks/exhaustive-deps return (
diff --git a/awx/ui_next/src/components/CodeEditor/VariablesField.test.jsx b/awx/ui_next/src/components/CodeEditor/VariablesField.test.jsx index 977fb4a724..6925d7b3b1 100644 --- a/awx/ui_next/src/components/CodeEditor/VariablesField.test.jsx +++ b/awx/ui_next/src/components/CodeEditor/VariablesField.test.jsx @@ -5,10 +5,6 @@ import { mountWithContexts } from '../../../testUtils/enzymeHelpers'; import VariablesField from './VariablesField'; describe('VariablesField', () => { - beforeEach(() => { - document.body.createTextRange = jest.fn(); - }); - it('should render code editor', () => { const value = '---\n'; const wrapper = mountWithContexts( @@ -200,18 +196,26 @@ describe('VariablesField', () => { it('should initialize to JSON if value is JSON', async () => { const value = '{"foo": "bar"}'; - const wrapper = mountWithContexts( - - {formik => ( -
- - - - )} -
- ); + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + {formik => ( +
+ + + + )} +
+ ); + }); + wrapper.update(); expect(wrapper.find('CodeEditor').prop('mode')).toEqual('javascript'); }); @@ -238,4 +242,32 @@ describe('VariablesField', () => { expect(wrapper.find('Modal').prop('isOpen')).toEqual(true); expect(wrapper.find('Modal CodeEditor')).toHaveLength(1); }); + + it('should format JSON for code editor', async () => { + const value = '{"foo": "bar"}'; + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + + {formik => ( +
+ + + + )} +
+ ); + }); + wrapper.update(); + + expect(wrapper.find('CodeEditor').prop('value')).toEqual( + '{\n "foo": "bar"\n}' + ); + }); });