Skip to content

Commit d52b16b

Browse files
committed
Switch to jsonlines in all components and parsing
Signed-off-by: Tyler Ohlsen <ohltyler@amazon.com>
1 parent e2e6c5a commit d52b16b

File tree

8 files changed

+64
-52
lines changed

8 files changed

+64
-52
lines changed

public/pages/workflow_detail/workflow_inputs/ingest_inputs/source_data.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ export function SourceData(props: SourceDataProps) {
4444
// empty/populated docs state
4545
let docs = [];
4646
try {
47-
docs = JSON.parse(getIn(values, 'ingest.docs', []));
47+
const lines = getIn(values, 'ingest.docs', '').split('\n') as string[];
48+
lines.forEach((line) => docs.push(JSON.parse(line)));
4849
} catch {}
4950
const docsPopulated = docs.length > 0;
5051

public/pages/workflow_detail/workflow_inputs/ingest_inputs/source_data_modal.tsx

+11-5
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ import {
2222
EuiButtonGroup,
2323
EuiCompressedComboBox,
2424
} from '@elastic/eui';
25-
import { JsonField } from '../input_fields';
25+
import { JsonLinesField } from '../input_fields';
2626
import {
2727
customStringify,
28+
customStringifySingleLine,
2829
FETCH_ALL_QUERY_LARGE,
2930
IConfigField,
3031
IndexMappings,
@@ -177,8 +178,14 @@ export function SourceDataModal(props: SourceDataProps) {
177178
.then((resp) => {
178179
const docObjs = resp?.hits?.hits
179180
?.slice(0, MAX_DOCS_TO_IMPORT)
180-
?.map((hit: SearchHit) => hit?._source);
181-
formikProps.setFieldValue('docs', customStringify(docObjs));
181+
?.map((hit: SearchHit) => hit?._source) as {}[];
182+
let jsonLinesStr = '';
183+
try {
184+
docObjs.forEach((docObj) => {
185+
jsonLinesStr += customStringifySingleLine(docObj) + '\n';
186+
});
187+
} catch {}
188+
formikProps.setFieldValue('docs', jsonLinesStr);
182189
});
183190
}
184191
}, [selectedIndex]);
@@ -287,14 +294,13 @@ export function SourceDataModal(props: SourceDataProps) {
287294
<EuiSpacer size="xs" />
288295
</>
289296
)}
290-
<JsonField
297+
<JsonLinesField
291298
label="Documents to be imported"
292299
fieldPath={'docs'}
293300
helpText="Documents must be in JSON lines format."
294301
editorHeight="40vh"
295302
readOnly={false}
296303
validate={true}
297-
validateInline={true}
298304
/>
299305
</>
300306
</EuiModalBody>

public/pages/workflow_detail/workflow_inputs/input_fields/json_lines_field.tsx

+38-40
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import { camelCaseToTitleString } from '../../../../utils';
2020
interface JsonLinesFieldProps {
2121
fieldPath: string; // the full path in string-form to the field (e.g., 'ingest.enrich.processors.text_embedding_processor.inputField')
2222
validate?: boolean;
23-
validateInline?: boolean;
2423
label?: string;
2524
helpLink?: string;
2625
helpText?: string;
@@ -34,12 +33,14 @@ interface JsonLinesFieldProps {
3433
*/
3534
export function JsonLinesField(props: JsonLinesFieldProps) {
3635
const validate = props.validate ?? true;
37-
const validateInline = props.validateInline ?? true;
3836

3937
const { errors, touched, values } = useFormikContext<WorkflowFormValues>();
4038

4139
// temp input state. only format when users click out of the code editor
4240
const [jsonStr, setJsonStr] = useState<string>('{}');
41+
const [customErrMsg, setCustomErrMsg] = useState<string | undefined>(
42+
undefined
43+
);
4344

4445
// initializing the text to be the stringified form value
4546
useEffect(() => {
@@ -54,6 +55,16 @@ export function JsonLinesField(props: JsonLinesFieldProps) {
5455
return (
5556
<Field name={props.fieldPath}>
5657
{({ field, form }: FieldProps) => {
58+
let errMsgToDisplay = undefined as string | undefined;
59+
if (validate) {
60+
if (customErrMsg) {
61+
errMsgToDisplay = customErrMsg;
62+
} else if (getIn(errors, field.name)) {
63+
errMsgToDisplay = getIn(errors, field.name);
64+
} else {
65+
errMsgToDisplay = undefined;
66+
}
67+
}
5768
return (
5869
<EuiCompressedFormRow
5970
fullWidth={true}
@@ -69,75 +80,62 @@ export function JsonLinesField(props: JsonLinesFieldProps) {
6980
) : undefined
7081
}
7182
helpText={props.helpText || undefined}
72-
error={validate ? getIn(errors, field.name) : undefined}
83+
error={errMsgToDisplay}
7384
isInvalid={
7485
validate
7586
? getIn(errors, field.name) && getIn(touched, field.name)
7687
: false
7788
}
7889
>
7990
<EuiCodeEditor
80-
mode="json"
91+
mode="hjson"
8192
theme="textmate"
8293
width="100%"
8394
height={props.editorHeight || '15vh'}
8495
value={jsonStr}
8596
onChange={(input) => {
8697
setJsonStr(input);
8798
form.setFieldValue(field.name, input);
99+
setCustomErrMsg(undefined);
88100
}}
89101
onBlur={() => {
102+
form.setFieldTouched(field.name);
90103
let finalJsonStr = '';
104+
let curIdx = -1;
91105
try {
92-
jsonStr?.split('\n').forEach((line: string) => {
106+
const lines = jsonStr?.split('\n');
107+
lines.forEach((line: string, idx) => {
108+
curIdx = idx;
93109
if (line.trim() !== '') {
94-
try {
95-
finalJsonStr +=
96-
customStringifySingleLine(JSON.parse(line)) + '\n';
97-
} catch (e) {}
110+
finalJsonStr +=
111+
customStringifySingleLine(JSON.parse(line)) + '\n';
98112
}
99113
});
100-
} catch (error) {}
101-
102-
console.log('final json str: ', finalJsonStr);
103-
form.setFieldValue(field.name, finalJsonStr);
104-
form.setFieldTouched(field.name);
105-
106-
// TODO: format under regular scenario, leave alone if JSONLines scenario
107-
// try {
108-
// form.setFieldValue(
109-
// field.name,
110-
// customStringify(JSON.parse(jsonStr))
111-
// );
112-
// } catch (error) {
113-
// form.setFieldValue(field.name, jsonStr);
114-
// } finally {
115-
// form.setFieldTouched(field.name);
116-
// }
114+
// remove trailing newline
115+
if (finalJsonStr !== '') {
116+
finalJsonStr = finalJsonStr.slice(0, -1);
117+
}
118+
form.setFieldValue(field.name, finalJsonStr);
119+
} catch (error) {
120+
setCustomErrMsg(
121+
`Error on line ${curIdx + 1}: ${getIn(
122+
error,
123+
'message',
124+
'Invalid JSON'
125+
).replace(/^(.*?)\s+in JSON.*/, '$1')}`
126+
);
127+
}
117128
}}
118129
readOnly={props.readOnly || false}
119130
setOptions={{
120131
fontSize: '14px',
121-
useWorker: validateInline,
132+
useWorker: false,
122133
highlightActiveLine: !props.readOnly,
123134
highlightSelectedWord: !props.readOnly,
124135
highlightGutterLine: !props.readOnly,
125136
wrap: true,
126137
}}
127138
aria-label="Code Editor"
128-
tabSize={2}
129-
// onValidate={(props) => {
130-
// console.log('validate props: ', props);
131-
// return [];
132-
// }}
133-
// annotations={[
134-
// {
135-
// column: 0,
136-
// row: 1,
137-
// text: 'Invalid JSON',
138-
// type: 'error',
139-
// },
140-
// ]}
141139
/>
142140
</EuiCompressedFormRow>
143141
);

public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_expression_modal.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ export function ConfigureExpressionModal(props: ConfigureExpressionModalProps) {
123123
const docs = getIn(values, 'ingest.docs');
124124
let docObjs = [] as {}[] | undefined;
125125
try {
126-
docObjs = JSON.parse(docs);
126+
const lines = docs?.split('\n') as string[];
127+
lines.forEach((line) => docObjs?.push(JSON.parse(line)));
127128
} catch {}
128129
const query = getIn(values, 'search.request');
129130
let queryObj = {} as {} | undefined;

public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_multi_expression_modal.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ export function ConfigureMultiExpressionModal(
129129
const docs = getIn(values, 'ingest.docs');
130130
let docObjs = [] as {}[] | undefined;
131131
try {
132-
docObjs = JSON.parse(docs);
132+
const lines = docs?.split('\n') as string[];
133+
lines.forEach((line) => docObjs?.push(JSON.parse(line)));
133134
} catch {}
134135
const query = getIn(values, 'search.request');
135136
let queryObj = {} as {} | undefined;

public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_template_modal.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ export function ConfigureTemplateModal(props: ConfigureTemplateModalProps) {
149149
const docs = getIn(values, 'ingest.docs');
150150
let docObjs = [] as {}[] | undefined;
151151
try {
152-
docObjs = JSON.parse(docs);
152+
const lines = docs?.split('\n') as string[];
153+
lines.forEach((line) => docObjs?.push(JSON.parse(line)));
153154
} catch {}
154155
const query = getIn(values, 'search.request');
155156
let queryObj = {} as {} | undefined;

public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,9 @@ export function WorkflowInputs(props: WorkflowInputsProps) {
275275
useEffect(() => {
276276
let parsedDocsObjs = [] as {}[];
277277
try {
278-
parsedDocsObjs = JSON.parse(props.ingestDocs);
279-
} catch (e) {}
278+
const lines = props.ingestDocs?.split('\n') as string[];
279+
lines.forEach((line) => parsedDocsObjs.push(JSON.parse(line)));
280+
} catch {}
280281
setDocsPopulated(parsedDocsObjs.length > 0 && !isEmpty(parsedDocsObjs[0]));
281282
}, [props.ingestDocs]);
282283

@@ -607,7 +608,8 @@ export function WorkflowInputs(props: WorkflowInputsProps) {
607608
try {
608609
let ingestDocsObjs = [] as {}[];
609610
try {
610-
ingestDocsObjs = JSON.parse(props.ingestDocs);
611+
const lines = props.ingestDocs?.split('\n') as string[];
612+
lines.forEach((line) => ingestDocsObjs.push(JSON.parse(line)));
611613
} catch (e) {}
612614
if (ingestDocsObjs.length > 0 && !isEmpty(ingestDocsObjs[0])) {
613615
success = await validateAndUpdateWorkflow(false, true, false);

public/utils/utils.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ export function prepareDocsForSimulate(
176176
let docObjs = [] as {}[];
177177
try {
178178
docObjs = JSON.parse(docs) as {}[];
179+
const lines = docs?.split('\n') as string[];
180+
lines.forEach((line) => docObjs.push(JSON.parse(line)));
179181
} catch {}
180182
docObjs.forEach((doc) => {
181183
preparedDocs.push({

0 commit comments

Comments
 (0)