From da780c9d7c945158c74eec53b66a7e69122c5f5c Mon Sep 17 00:00:00 2001 From: Keith Grant Date: Fri, 28 Jun 2019 14:48:40 -0700 Subject: [PATCH] make VariablesInput detect whether value is JSON or YAML on init --- .../CodeMirrorInput/VariablesInput.jsx | 19 +++++++++++++++---- awx/ui_next/src/util/strings.js | 8 ++++++-- awx/ui_next/src/util/strings.test.js | 12 +++++++++++- awx/ui_next/src/util/yaml.js | 12 ++++++++++++ 4 files changed, 44 insertions(+), 7 deletions(-) rename {src => awx/ui_next/src}/components/CodeMirrorInput/VariablesInput.jsx (81%) diff --git a/src/components/CodeMirrorInput/VariablesInput.jsx b/awx/ui_next/src/components/CodeMirrorInput/VariablesInput.jsx similarity index 81% rename from src/components/CodeMirrorInput/VariablesInput.jsx rename to awx/ui_next/src/components/CodeMirrorInput/VariablesInput.jsx index 2d4e96e3f7..efd43f643e 100644 --- a/src/components/CodeMirrorInput/VariablesInput.jsx +++ b/awx/ui_next/src/components/CodeMirrorInput/VariablesInput.jsx @@ -3,7 +3,7 @@ import { string, func, bool, number } from 'prop-types'; import { Button, Split, SplitItem } from '@patternfly/react-core'; import styled from 'styled-components'; import ButtonGroup from '@components/ButtonGroup'; -import { yamlToJson, jsonToYaml } from '@util/yaml'; +import { yamlToJson, jsonToYaml, isJson } from '@util/yaml'; import CodeMirrorInput from './CodeMirrorInput'; const YAML_MODE = 'yaml'; @@ -15,8 +15,19 @@ const SmallButton = styled(Button)` `; function VariablesInput (props) { - const { id, label, value, readOnly, rows, error, onChange, onError, className } = props; - const [mode, setMode] = useState(YAML_MODE); + const { id, label, readOnly, rows, error, onError, className } = props; + // eslint-disable-next-line react/destructuring-assignment + const [value, setValue] = useState(props.value); + const [mode, setMode] = useState(isJson(value) ? JSON_MODE : YAML_MODE); + // eslint-disable-next-line react/destructuring-assignment + const isControlled = !!props.onChange; + + const onChange = (newValue) => { + if (isControlled) { + props.onChange(newValue); + } + setValue(newValue); + }; return (
@@ -88,7 +99,7 @@ VariablesInput.propTypes = { }; VariablesInput.defaultProps = { readOnly: false, - onChange: () => {}, + onChange: null, rows: 6, error: null, onError: () => {}, diff --git a/awx/ui_next/src/util/strings.js b/awx/ui_next/src/util/strings.js index cc5e00e68e..588bc8b7b6 100644 --- a/awx/ui_next/src/util/strings.js +++ b/awx/ui_next/src/util/strings.js @@ -14,9 +14,13 @@ export function ucFirst(str) { return `${str[0].toUpperCase()}${str.substr(1)}`; } -export const toTitleCase = string => - string +export const toTitleCase = string => { + if (!string) { + return ''; + } + return string .toLowerCase() .split('_') .map(word => word.charAt(0).toUpperCase() + word.slice(1)) .join(' '); +}; diff --git a/awx/ui_next/src/util/strings.test.js b/awx/ui_next/src/util/strings.test.js index ec2e6f3c13..b69db2f489 100644 --- a/awx/ui_next/src/util/strings.test.js +++ b/awx/ui_next/src/util/strings.test.js @@ -1,4 +1,4 @@ -import { pluralize, getArticle, ucFirst } from './strings'; +import { pluralize, getArticle, ucFirst, toTitleCase } from './strings'; describe('string utils', () => { describe('pluralize', () => { @@ -31,4 +31,14 @@ describe('string utils', () => { expect(ucFirst('team')).toEqual('Team'); }); }); + + describe('toTitleCase', () => { + test('should upper case each word', () => { + expect(toTitleCase('a_string_of_words')).toEqual('A String Of Words'); + }); + + test('should return empty string for undefined', () => { + expect(toTitleCase(undefined)).toEqual(''); + }); + }); }); diff --git a/awx/ui_next/src/util/yaml.js b/awx/ui_next/src/util/yaml.js index 22a2cf9815..27b99d0b63 100644 --- a/awx/ui_next/src/util/yaml.js +++ b/awx/ui_next/src/util/yaml.js @@ -21,3 +21,15 @@ export function jsonToYaml(jsonString) { } return yaml.safeDump(value); } + +export function isJson (jsonString) { + if (typeof jsonString !== 'string') { return false; } + let value; + try { + value = JSON.parse(jsonString); + } catch (e) { + return false; + } + + return typeof value === 'object' && value !== null; +}