mirror of
https://github.com/ansible/awx.git
synced 2026-02-26 07:26:03 -03:30
add VariablesField YAML/JSON validation
This commit is contained in:
@@ -73,6 +73,8 @@ function CodeEditor({
|
|||||||
id,
|
id,
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
|
onFocus,
|
||||||
|
onBlur,
|
||||||
mode,
|
mode,
|
||||||
readOnly,
|
readOnly,
|
||||||
hasErrors,
|
hasErrors,
|
||||||
@@ -140,6 +142,8 @@ function CodeEditor({
|
|||||||
theme="github"
|
theme="github"
|
||||||
onChange={debounce(onChange, 250)}
|
onChange={debounce(onChange, 250)}
|
||||||
value={value}
|
value={value}
|
||||||
|
onFocus={onFocus}
|
||||||
|
onBlur={onBlur}
|
||||||
name={id || 'code-editor'}
|
name={id || 'code-editor'}
|
||||||
editorProps={{ $blockScrolling: true }}
|
editorProps={{ $blockScrolling: true }}
|
||||||
fontSize={16}
|
fontSize={16}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import { string, bool } from 'prop-types';
|
import { string, bool } from 'prop-types';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
@@ -33,9 +33,45 @@ function VariablesField({
|
|||||||
promptId,
|
promptId,
|
||||||
tooltip,
|
tooltip,
|
||||||
}) {
|
}) {
|
||||||
const [field, meta] = useField(name);
|
// track focus manually, because the Code Editor library doesn't wire
|
||||||
const [mode, setMode] = useState(
|
// into Formik completely
|
||||||
isJsonString(field.value) ? JSON_MODE : YAML_MODE
|
const [shouldValidate, setShouldValidate] = useState(false);
|
||||||
|
const [mode, setMode] = useState(YAML_MODE);
|
||||||
|
const validate = useCallback(
|
||||||
|
value => {
|
||||||
|
if (!shouldValidate) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (mode === YAML_MODE) {
|
||||||
|
yamlToJson(value);
|
||||||
|
} else {
|
||||||
|
JSON.parse(value);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return error.message;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
[shouldValidate, mode]
|
||||||
|
);
|
||||||
|
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() {
|
||||||
|
if (isJsonString(field.value)) {
|
||||||
|
setMode(JSON_MODE);
|
||||||
|
}
|
||||||
|
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
function validateOnBlur() {
|
||||||
|
if (shouldValidate) {
|
||||||
|
helpers.setError(validate(field.value));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[shouldValidate, validate] // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
);
|
);
|
||||||
const [isExpanded, setIsExpanded] = useState(false);
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
|
|
||||||
@@ -52,6 +88,7 @@ function VariablesField({
|
|||||||
onExpand={() => setIsExpanded(true)}
|
onExpand={() => setIsExpanded(true)}
|
||||||
mode={mode}
|
mode={mode}
|
||||||
setMode={setMode}
|
setMode={setMode}
|
||||||
|
setShouldValidate={setShouldValidate}
|
||||||
/>
|
/>
|
||||||
<Modal
|
<Modal
|
||||||
variant="xlarge"
|
variant="xlarge"
|
||||||
@@ -82,6 +119,7 @@ function VariablesField({
|
|||||||
fullHeight
|
fullHeight
|
||||||
mode={mode}
|
mode={mode}
|
||||||
setMode={setMode}
|
setMode={setMode}
|
||||||
|
setShouldValidate={setShouldValidate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
@@ -117,6 +155,7 @@ function VariablesFieldInternals({
|
|||||||
mode,
|
mode,
|
||||||
setMode,
|
setMode,
|
||||||
onExpand,
|
onExpand,
|
||||||
|
setShouldValidate,
|
||||||
}) {
|
}) {
|
||||||
const [field, meta, helpers] = useField(name);
|
const [field, meta, helpers] = useField(name);
|
||||||
|
|
||||||
@@ -178,6 +217,8 @@ function VariablesFieldInternals({
|
|||||||
helpers.setValue(newVal);
|
helpers.setValue(newVal);
|
||||||
}}
|
}}
|
||||||
fullHeight={fullHeight}
|
fullHeight={fullHeight}
|
||||||
|
onFocus={() => setShouldValidate(false)}
|
||||||
|
onBlur={() => setShouldValidate(true)}
|
||||||
hasErrors={!!meta.error}
|
hasErrors={!!meta.error}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user