mirror of
https://github.com/ansible/awx.git
synced 2026-02-27 07:56:06 -03:30
Refactors YamlJsonToggle component into something a little more generic so that it can be used to toggle between local and utc times in the schedule details view.
This commit is contained in:
@@ -2,9 +2,9 @@ import React, { useState, useEffect } from 'react';
|
|||||||
import { string, node, number } from 'prop-types';
|
import { string, node, number } from 'prop-types';
|
||||||
import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core';
|
import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core';
|
||||||
import { DetailName, DetailValue } from '@components/DetailList';
|
import { DetailName, DetailValue } from '@components/DetailList';
|
||||||
|
import Toggle from '@components/Toggle';
|
||||||
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
|
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
|
||||||
import CodeMirrorInput from './CodeMirrorInput';
|
import CodeMirrorInput from './CodeMirrorInput';
|
||||||
import YamlJsonToggle from './YamlJsonToggle';
|
|
||||||
import { JSON_MODE, YAML_MODE } from './constants';
|
import { JSON_MODE, YAML_MODE } from './constants';
|
||||||
|
|
||||||
function getValueAsMode(value, mode) {
|
function getValueAsMode(value, mode) {
|
||||||
@@ -50,8 +50,12 @@ function VariablesDetail({ value, label, rows }) {
|
|||||||
</div>
|
</div>
|
||||||
</SplitItem>
|
</SplitItem>
|
||||||
<SplitItem>
|
<SplitItem>
|
||||||
<YamlJsonToggle
|
<Toggle
|
||||||
mode={mode}
|
leftLabel="YAML"
|
||||||
|
leftMode={YAML_MODE}
|
||||||
|
rightLabel="JSON"
|
||||||
|
rightMode={JSON_MODE}
|
||||||
|
currentMode={mode}
|
||||||
onChange={newMode => {
|
onChange={newMode => {
|
||||||
try {
|
try {
|
||||||
setCurrentValue(getValueAsMode(currentValue, newMode));
|
setCurrentValue(getValueAsMode(currentValue, newMode));
|
||||||
|
|||||||
@@ -31,12 +31,12 @@ describe('<VariablesDetail>', () => {
|
|||||||
const wrapper = shallow(
|
const wrapper = shallow(
|
||||||
<VariablesDetail value="---foo: bar" label="Variables" />
|
<VariablesDetail value="---foo: bar" label="Variables" />
|
||||||
);
|
);
|
||||||
wrapper.find('YamlJsonToggle').invoke('onChange')('javascript');
|
wrapper.find('Toggle').invoke('onChange')('javascript');
|
||||||
const input = wrapper.find('Styled(CodeMirrorInput)');
|
const input = wrapper.find('Styled(CodeMirrorInput)');
|
||||||
expect(input.prop('mode')).toEqual('javascript');
|
expect(input.prop('mode')).toEqual('javascript');
|
||||||
expect(input.prop('value')).toEqual('{\n "foo": "bar"\n}');
|
expect(input.prop('value')).toEqual('{\n "foo": "bar"\n}');
|
||||||
|
|
||||||
wrapper.find('YamlJsonToggle').invoke('onChange')('yaml');
|
wrapper.find('Toggle').invoke('onChange')('yaml');
|
||||||
const input2 = wrapper.find('Styled(CodeMirrorInput)');
|
const input2 = wrapper.find('Styled(CodeMirrorInput)');
|
||||||
expect(input2.prop('mode')).toEqual('yaml');
|
expect(input2.prop('mode')).toEqual('yaml');
|
||||||
expect(input2.prop('value')).toEqual('foo: bar\n');
|
expect(input2.prop('value')).toEqual('foo: bar\n');
|
||||||
@@ -53,7 +53,7 @@ describe('<VariablesDetail>', () => {
|
|||||||
<VariablesDetail value="---foo: bar" label="Variables" />
|
<VariablesDetail value="---foo: bar" label="Variables" />
|
||||||
);
|
);
|
||||||
act(() => {
|
act(() => {
|
||||||
wrapper.find('YamlJsonToggle').invoke('onChange')('javascript');
|
wrapper.find('Toggle').invoke('onChange')('javascript');
|
||||||
});
|
});
|
||||||
wrapper.setProps({
|
wrapper.setProps({
|
||||||
value: '---bar: baz',
|
value: '---bar: baz',
|
||||||
@@ -73,7 +73,7 @@ describe('<VariablesDetail>', () => {
|
|||||||
test('should default empty json to "{}"', () => {
|
test('should default empty json to "{}"', () => {
|
||||||
const wrapper = mount(<VariablesDetail value="" label="Variables" />);
|
const wrapper = mount(<VariablesDetail value="" label="Variables" />);
|
||||||
act(() => {
|
act(() => {
|
||||||
wrapper.find('YamlJsonToggle').invoke('onChange')('javascript');
|
wrapper.find('Toggle').invoke('onChange')('javascript');
|
||||||
});
|
});
|
||||||
wrapper.setProps({ value: '' });
|
wrapper.setProps({ value: '' });
|
||||||
const input = wrapper.find('Styled(CodeMirrorInput)');
|
const input = wrapper.find('Styled(CodeMirrorInput)');
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import { useField } from 'formik';
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Split, SplitItem } from '@patternfly/react-core';
|
import { Split, SplitItem } from '@patternfly/react-core';
|
||||||
import { CheckboxField } from '@components/FormField';
|
import { CheckboxField } from '@components/FormField';
|
||||||
|
import Toggle from '@components/Toggle';
|
||||||
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
|
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
|
||||||
import CodeMirrorInput from './CodeMirrorInput';
|
import CodeMirrorInput from './CodeMirrorInput';
|
||||||
import YamlJsonToggle from './YamlJsonToggle';
|
|
||||||
import { JSON_MODE, YAML_MODE } from './constants';
|
import { JSON_MODE, YAML_MODE } from './constants';
|
||||||
|
|
||||||
const FieldHeader = styled.div`
|
const FieldHeader = styled.div`
|
||||||
@@ -34,8 +34,12 @@ function VariablesField({ i18n, id, name, label, readOnly, promptId }) {
|
|||||||
</label>
|
</label>
|
||||||
</SplitItem>
|
</SplitItem>
|
||||||
<SplitItem>
|
<SplitItem>
|
||||||
<YamlJsonToggle
|
<Toggle
|
||||||
mode={mode}
|
leftLabel="YAML"
|
||||||
|
leftMode={YAML_MODE}
|
||||||
|
rightLabel="JSON"
|
||||||
|
rightMode={JSON_MODE}
|
||||||
|
currentMode={mode}
|
||||||
onChange={newMode => {
|
onChange={newMode => {
|
||||||
try {
|
try {
|
||||||
const newVal =
|
const newVal =
|
||||||
|
|||||||
@@ -1,21 +1,16 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { string, func, bool, number } from 'prop-types';
|
import { string, func, bool, number } from 'prop-types';
|
||||||
import { Button, Split, SplitItem } from '@patternfly/react-core';
|
import { Split, SplitItem } from '@patternfly/react-core';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
|
import { yamlToJson, jsonToYaml, isJson } from '@util/yaml';
|
||||||
|
import Toggle from '@components/Toggle';
|
||||||
import CodeMirrorInput from './CodeMirrorInput';
|
import CodeMirrorInput from './CodeMirrorInput';
|
||||||
import ButtonGroup from './ButtonGroup';
|
|
||||||
import { JSON_MODE, YAML_MODE } from './constants';
|
import { JSON_MODE, YAML_MODE } from './constants';
|
||||||
|
|
||||||
function formatJson(jsonString) {
|
function formatJson(jsonString) {
|
||||||
return JSON.stringify(JSON.parse(jsonString), null, 2);
|
return JSON.stringify(JSON.parse(jsonString), null, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SmallButton = styled(Button)`
|
|
||||||
padding: 3px 8px;
|
|
||||||
font-size: var(--pf-global--FontSize--xs);
|
|
||||||
`;
|
|
||||||
|
|
||||||
const SplitItemRight = styled(SplitItem)`
|
const SplitItemRight = styled(SplitItem)`
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
`;
|
`;
|
||||||
@@ -47,40 +42,25 @@ function VariablesInput(props) {
|
|||||||
</label>
|
</label>
|
||||||
</SplitItem>
|
</SplitItem>
|
||||||
<SplitItemRight>
|
<SplitItemRight>
|
||||||
<ButtonGroup>
|
<Toggle
|
||||||
<SmallButton
|
leftLabel="YAML"
|
||||||
onClick={() => {
|
leftMode={YAML_MODE}
|
||||||
if (mode === YAML_MODE) {
|
rightLabel="JSON"
|
||||||
return;
|
rightMode={JSON_MODE}
|
||||||
}
|
currentMode={mode}
|
||||||
try {
|
onChange={newMode => {
|
||||||
onChange(jsonToYaml(value));
|
try {
|
||||||
setMode(YAML_MODE);
|
|
||||||
} catch (err) {
|
|
||||||
onError(err.message);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
variant={mode === YAML_MODE ? 'primary' : 'secondary'}
|
|
||||||
>
|
|
||||||
YAML
|
|
||||||
</SmallButton>
|
|
||||||
<SmallButton
|
|
||||||
onClick={() => {
|
|
||||||
if (mode === JSON_MODE) {
|
if (mode === JSON_MODE) {
|
||||||
return;
|
onChange(jsonToYaml(value));
|
||||||
}
|
} else {
|
||||||
try {
|
|
||||||
onChange(yamlToJson(value));
|
onChange(yamlToJson(value));
|
||||||
setMode(JSON_MODE);
|
|
||||||
} catch (err) {
|
|
||||||
onError(err.message);
|
|
||||||
}
|
}
|
||||||
}}
|
setMode(newMode);
|
||||||
variant={mode === JSON_MODE ? 'primary' : 'secondary'}
|
} catch (err) {
|
||||||
>
|
onError(err.message);
|
||||||
JSON
|
}
|
||||||
</SmallButton>
|
}}
|
||||||
</ButtonGroup>
|
/>
|
||||||
</SplitItemRight>
|
</SplitItemRight>
|
||||||
</Split>
|
</Split>
|
||||||
<CodeMirrorInput
|
<CodeMirrorInput
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { oneOf, func } from 'prop-types';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import { Button } from '@patternfly/react-core';
|
|
||||||
import ButtonGroup from './ButtonGroup';
|
|
||||||
|
|
||||||
const SmallButton = styled(Button)`
|
|
||||||
padding: 3px 8px;
|
|
||||||
font-size: var(--pf-global--FontSize--xs);
|
|
||||||
`;
|
|
||||||
|
|
||||||
const YAML_MODE = 'yaml';
|
|
||||||
const JSON_MODE = 'javascript';
|
|
||||||
|
|
||||||
function YamlJsonToggle({ mode, onChange }) {
|
|
||||||
const setMode = newMode => {
|
|
||||||
if (mode !== newMode) {
|
|
||||||
onChange(newMode);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ButtonGroup>
|
|
||||||
<SmallButton
|
|
||||||
onClick={() => setMode(YAML_MODE)}
|
|
||||||
variant={mode === YAML_MODE ? 'primary' : 'secondary'}
|
|
||||||
>
|
|
||||||
YAML
|
|
||||||
</SmallButton>
|
|
||||||
<SmallButton
|
|
||||||
onClick={() => setMode(JSON_MODE)}
|
|
||||||
variant={mode === JSON_MODE ? 'primary' : 'secondary'}
|
|
||||||
>
|
|
||||||
JSON
|
|
||||||
</SmallButton>
|
|
||||||
</ButtonGroup>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
YamlJsonToggle.propTypes = {
|
|
||||||
mode: oneOf([YAML_MODE, JSON_MODE]).isRequired,
|
|
||||||
onChange: func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default YamlJsonToggle;
|
|
||||||
52
awx/ui_next/src/components/Toggle/Toggle.jsx
Normal file
52
awx/ui_next/src/components/Toggle/Toggle.jsx
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { func, string } from 'prop-types';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { Button } from '@patternfly/react-core';
|
||||||
|
import ButtonGroup from './ButtonGroup';
|
||||||
|
|
||||||
|
const SmallButton = styled(Button)`
|
||||||
|
padding: 3px 8px;
|
||||||
|
font-size: var(--pf-global--FontSize--xs);
|
||||||
|
`;
|
||||||
|
|
||||||
|
function Toggle({
|
||||||
|
leftLabel,
|
||||||
|
leftMode,
|
||||||
|
rightLabel,
|
||||||
|
rightMode,
|
||||||
|
currentMode,
|
||||||
|
onChange,
|
||||||
|
}) {
|
||||||
|
const setValue = newValue => {
|
||||||
|
if (currentMode !== newValue) {
|
||||||
|
onChange(newValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ButtonGroup>
|
||||||
|
<SmallButton
|
||||||
|
onClick={() => setValue(leftMode)}
|
||||||
|
variant={currentMode === leftMode ? 'primary' : 'secondary'}
|
||||||
|
>
|
||||||
|
{leftLabel}
|
||||||
|
</SmallButton>
|
||||||
|
<SmallButton
|
||||||
|
onClick={() => setValue(rightMode)}
|
||||||
|
variant={currentMode === rightMode ? 'primary' : 'secondary'}
|
||||||
|
>
|
||||||
|
{rightLabel}
|
||||||
|
</SmallButton>
|
||||||
|
</ButtonGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Toggle.propTypes = {
|
||||||
|
leftLabel: string.isRequired,
|
||||||
|
leftMode: string.isRequired,
|
||||||
|
rightLabel: string.isRequired,
|
||||||
|
rightMode: string.isRequired,
|
||||||
|
currentMode: string.isRequired,
|
||||||
|
onChange: func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Toggle;
|
||||||
1
awx/ui_next/src/components/Toggle/index.js
Normal file
1
awx/ui_next/src/components/Toggle/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { default } from './Toggle';
|
||||||
Reference in New Issue
Block a user