From 63251dcfb970ec922529373893d02dfe3f2bd5ef Mon Sep 17 00:00:00 2001 From: Tyler Ohlsen Date: Tue, 17 Dec 2024 09:14:51 -0800 Subject: [PATCH] always show query; allow reverting query; add loading states; add jsonpath table unused Signed-off-by: Tyler Ohlsen --- public/general_components/index.ts | 1 + .../jsonpath_examples_table.tsx | 62 ++++++++ .../workflow_detail/tools/query/query.tsx | 147 ++++++++++-------- .../search_inputs/edit_query_modal.tsx | 5 +- 4 files changed, 148 insertions(+), 67 deletions(-) create mode 100644 public/general_components/jsonpath_examples_table.tsx diff --git a/public/general_components/index.ts b/public/general_components/index.ts index 60528d1e..ed0d4957 100644 --- a/public/general_components/index.ts +++ b/public/general_components/index.ts @@ -7,5 +7,6 @@ export { MultiSelectFilter } from './multi_select_filter'; export { ProcessorsTitle } from './processors_title'; export { ExperimentalBadge } from './experimental_badge'; export { QueryParamsList } from './query_params_list'; +export { JsonPathExamplesTable } from './jsonpath_examples_table'; export * from './results'; export * from './service_card'; diff --git a/public/general_components/jsonpath_examples_table.tsx b/public/general_components/jsonpath_examples_table.tsx new file mode 100644 index 00000000..f336cb02 --- /dev/null +++ b/public/general_components/jsonpath_examples_table.tsx @@ -0,0 +1,62 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { EuiInMemoryTable, EuiCode, EuiText } from '@elastic/eui'; + +interface JsonPathExamplesTableProps {} + +type JSONPathExample = { + expression: string; + meaning: string; + example: string; +}; + +const examples = [ + { + expression: '$.data', + meaning: 'The entire input', + example: '$.data', + }, +] as JSONPathExample[]; + +const columns = [ + { + field: 'expression', + name: 'Expression', + width: '25%', + sortable: false, + render: (expression: string) => {expression}, + }, + { + field: 'meaning', + name: 'Meaning', + width: '50%', + sortable: false, + render: (meaning: string) => {meaning}, + }, + { + field: 'example', + name: 'Example', + width: '25%', + sortable: false, + render: (example: string) => {example}, + }, +]; + +/** + * A stateless component containing JSONPath examples in a table. + */ +export function JsonPathExamplesTable(props: JsonPathExamplesTableProps) { + return ( + + items={examples} + columns={columns} + pagination={false} + sorting={false} + hasActions={false} + /> + ); +} diff --git a/public/pages/workflow_detail/tools/query/query.tsx b/public/pages/workflow_detail/tools/query/query.tsx index 155751d6..4d4be165 100644 --- a/public/pages/workflow_detail/tools/query/query.tsx +++ b/public/pages/workflow_detail/tools/query/query.tsx @@ -4,6 +4,7 @@ */ import React, { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; import { isEmpty } from 'lodash'; import { useFormikContext } from 'formik'; import { @@ -13,7 +14,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiSmallButton, - EuiSwitch, + EuiSmallButtonEmpty, EuiText, } from '@elastic/eui'; import { @@ -24,7 +25,7 @@ import { SearchResponse, WorkflowFormValues, } from '../../../../../common'; -import { searchIndex, useAppDispatch } from '../../../../store'; +import { AppState, searchIndex, useAppDispatch } from '../../../../store'; import { containsEmptyValues, containsSameValues, @@ -57,12 +58,11 @@ export function Query(props: QueryProps) { const dispatch = useAppDispatch(); const dataSourceId = getDataSourceId(); + const { loading } = useSelector((state: AppState) => state.opensearch); + // Form state const { values } = useFormikContext(); - // use custom query state - const [useCustomQuery, setUseCustomQuery] = useState(false); - // query response state const [queryResponse, setQueryResponse] = useState< SearchResponse | undefined @@ -158,11 +158,41 @@ export function Query(props: QueryProps) { - Search + + + Search + + + { + setIncludePipeline(!includePipeline); + }} + /> + + - { - setIncludePipeline(!includePipeline); - }} - /> + + + Query + + {props.selectedStep === CONFIG_STEP.SEARCH && + !isEmpty(values?.search?.request) && + values?.search?.request !== tempRequest && ( + + { + setTempRequest(values?.search?.request); + }} + > + Revert to query definition + + + )} + - - setUseCustomQuery(!useCustomQuery)} + + { + setTempRequest(input); + }} + onBlur={() => { + try { + setTempRequest(customStringify(JSON.parse(tempRequest))); + } catch (error) {} + }} + readOnly={false} + setOptions={{ + fontSize: '14px', + useWorker: true, + highlightActiveLine: true, + highlightSelectedWord: true, + highlightGutterLine: true, + wrap: true, + }} + aria-label="Code Editor" + tabSize={2} /> - {useCustomQuery && ( - - { - setTempRequest(input); - }} - onBlur={() => { - try { - setTempRequest( - customStringify(JSON.parse(tempRequest)) - ); - } catch (error) {} - }} - readOnly={false} - setOptions={{ - fontSize: '14px', - useWorker: true, - highlightActiveLine: true, - highlightSelectedWord: true, - highlightGutterLine: true, - wrap: true, - }} - aria-label="Code Editor" - tabSize={2} - /> - - )} {/** * This may return nothing if the list of params are empty diff --git a/public/pages/workflow_detail/workflow_inputs/search_inputs/edit_query_modal.tsx b/public/pages/workflow_detail/workflow_inputs/search_inputs/edit_query_modal.tsx index 3823bd29..ce18a570 100644 --- a/public/pages/workflow_detail/workflow_inputs/search_inputs/edit_query_modal.tsx +++ b/public/pages/workflow_detail/workflow_inputs/search_inputs/edit_query_modal.tsx @@ -4,6 +4,7 @@ */ import React, { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; import { Formik, getIn, useFormikContext } from 'formik'; import * as yup from 'yup'; import { isEmpty } from 'lodash'; @@ -42,7 +43,7 @@ import { getPlaceholdersFromQuery, injectParameters, } from '../../../../utils'; -import { searchIndex, useAppDispatch } from '../../../../store'; +import { AppState, searchIndex, useAppDispatch } from '../../../../store'; import { QueryParamsList, Results } from '../../../../general_components'; interface EditQueryModalProps { @@ -57,6 +58,7 @@ interface EditQueryModalProps { export function EditQueryModal(props: EditQueryModalProps) { const dispatch = useAppDispatch(); const dataSourceId = getDataSourceId(); + const { loading } = useSelector((state: AppState) => state.opensearch); // sub-form values/schema const requestFormValues = { @@ -257,6 +259,7 @@ export function EditQueryModal(props: EditQueryModalProps) { { dispatch(