Skip to content

Commit

Permalink
Fix conflicts with elastic#58679!
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeelmers committed Mar 10, 2020
1 parent 3e6e179 commit 576df79
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,65 +17,91 @@
* under the License.
*/

import React, { useEffect } from 'react';
import React, { useState, useMemo, useCallback } from 'react';

import { EuiFormRow, EuiIconTip, EuiTextArea } from '@elastic/eui';
import { EuiFormRow, EuiIconTip, EuiCodeEditor, EuiScreenReaderOnly } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';

import { isValidJson } from '../../utils';
import { AggParamEditorProps } from '../agg_param_props';

function RawJsonParamEditor({
agg,
showValidation,
value = '',
setValidity,
setValue,
setTouched,
}: AggParamEditorProps<string>) {
const label = (
<>
<FormattedMessage id="visDefaultEditor.controls.jsonInputLabel" defaultMessage="JSON input" />{' '}
<EuiIconTip
position="right"
content={i18n.translate('visDefaultEditor.controls.jsonInputTooltip', {
defaultMessage:
"Any JSON formatted properties you add here will be merged with the elasticsearch aggregation definition for this section. For example 'shard_size' on a terms aggregation.",
})}
type="questionInCircle"
/>
</>
const [isFieldValid, setFieldValidity] = useState(true);
const [editorReady, setEditorReady] = useState(false);

const editorTooltipText = useMemo(
() =>
i18n.translate('visDefaultEditor.controls.jsonInputTooltip', {
defaultMessage:
"Any JSON formatted properties you add here will be merged with the elasticsearch aggregation definition for this section. For example 'shard_size' on a terms aggregation.",
}),
[]
);
const isValid = isValidJson(value);

const onChange = (ev: React.ChangeEvent<HTMLTextAreaElement>) => {
const textValue = ev.target.value;
setValue(textValue);
setValidity(isValidJson(textValue));
};
const jsonEditorLabelText = useMemo(
() =>
i18n.translate('visDefaultEditor.controls.jsonInputLabel', {
defaultMessage: 'JSON input',
}),
[]
);

useEffect(() => {
setValidity(isValid);
}, [isValid]);
const label = useMemo(
() => (
<>
{jsonEditorLabelText}{' '}
<EuiIconTip position="right" content={editorTooltipText} type="questionInCircle" />
</>
),
[jsonEditorLabelText, editorTooltipText]
);

const onEditorValidate = useCallback(
(annotations: unknown[]) => {
// The first onValidate returned from EuiCodeEditor is a false negative
if (editorReady) {
const validity = annotations.length === 0;
setFieldValidity(validity);
setValidity(validity);
} else {
setEditorReady(true);
}
},
[setValidity, editorReady]
);

return (
<EuiFormRow
label={label}
isInvalid={showValidation ? !isValid : false}
isInvalid={showValidation ? !isFieldValid : false}
fullWidth={true}
compressed
>
<EuiTextArea
id={`visEditorRawJson${agg.id}`}
isInvalid={showValidation ? !isValid : false}
value={value}
onChange={onChange}
rows={2}
fullWidth={true}
onBlur={setTouched}
compressed
/>
<>
<EuiCodeEditor
mode="json"
theme="github"
width="100%"
height="250px"
value={value}
onValidate={onEditorValidate}
setOptions={{
fontSize: '14px',
}}
onChange={setValue}
onBlur={setTouched}
aria-label={jsonEditorLabelText}
aria-describedby="jsonEditorDescription"
/>
<EuiScreenReaderOnly>
<p id="jsonEditorDescription">{editorTooltipText}</p>
</EuiScreenReaderOnly>
</>
</EuiFormRow>
);
}
Expand Down
29 changes: 1 addition & 28 deletions src/legacy/core_plugins/vis_default_editor/public/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import { groupAndSortBy, isValidJson } from './utils';
import { groupAndSortBy } from './utils';
import { AggGroupNames } from './legacy_imports';

jest.mock('ui/new_platform');
Expand Down Expand Up @@ -195,30 +195,3 @@ describe('Default Editor groupAggregationsBy', () => {
expect(groupAndSortBy(aggs, 'subtype', 'title')).toEqual(groupedAggs);
});
});

describe('DefaultEditor isValidJson', () => {
const input = {
valid: '{ "test": "json input" }',
invalid: 'strings are not json',
};

it('should return true when empty string', () => {
expect(isValidJson('')).toBeTruthy();
});

it('should return true when undefine', () => {
expect(isValidJson(undefined as any)).toBeTruthy();
});

it('should return false when invalid string', () => {
expect(isValidJson(input.invalid)).toBeFalsy();
});

it('should return true when valid string', () => {
expect(isValidJson(input.valid)).toBeTruthy();
});

it('should return false if a number', () => {
expect(isValidJson('0')).toBeFalsy();
});
});
29 changes: 0 additions & 29 deletions src/legacy/core_plugins/vis_default_editor/public/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,32 +78,3 @@ export function groupAndSortBy<
function sortByLabel<T>(a: GroupOrOption<T>, b: GroupOrOption<T>) {
return (a.label || '').toLowerCase().localeCompare((b.label || '').toLowerCase());
}

/**
* Check a string if it's a valid JSON.
*
* @param {string} value a string that should be validated
* @returns {boolean} true if value is a valid JSON or if value is an empty string, or a string with whitespaces, otherwise false
*/
export function isValidJson(value: string): boolean {
if (!value || value.length === 0) {
return true;
}

const trimmedValue = value.trim();

if (trimmedValue.length === 0) {
return true;
}

if (trimmedValue[0] === '{' || trimmedValue[0] === '[') {
try {
JSON.parse(trimmedValue);
return true;
} catch (e) {
return false;
}
} else {
return false;
}
}

0 comments on commit 576df79

Please sign in to comment.