Skip to content

Commit

Permalink
Misc improvements (#540)
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Ohlsen <[email protected]>
  • Loading branch information
ohltyler authored Dec 17, 2024
1 parent 292d4ec commit d1be4db
Show file tree
Hide file tree
Showing 9 changed files with 398 additions and 225 deletions.
1 change: 1 addition & 0 deletions common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ export const MAX_DOCS = 1000;
export const MAX_STRING_LENGTH = 100;
export const MAX_JSON_STRING_LENGTH = 10000;
export const MAX_TEMPLATE_STRING_LENGTH = 10000;
export const MAX_BYTES = 1048576; // OSD REST request payload size limit
export const MAX_WORKFLOW_NAME_TO_DISPLAY = 40;
export const WORKFLOW_NAME_REGEXP = RegExp('^[a-zA-Z0-9_-]*$');
export const EMPTY_MAP_ENTRY = { key: '', value: '' } as MapEntry;
Expand Down
1 change: 1 addition & 0 deletions public/general_components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
83 changes: 83 additions & 0 deletions public/general_components/jsonpath_examples_table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { isEmpty } from 'lodash';
import {
EuiInMemoryTable,
EuiCode,
EuiText,
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';

interface JsonPathExamplesTableProps {
headerText?: string;
}

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) => <EuiCode>{expression}</EuiCode>,
},
{
field: 'meaning',
name: 'Meaning',
width: '50%',
sortable: false,
render: (meaning: string) => <EuiText size="s">{meaning}</EuiText>,
},
{
field: 'example',
name: 'Example',
width: '25%',
sortable: false,
render: (example: string) => <EuiCode>{example}</EuiCode>,
},
];

/**
* A stateless component containing JSONPath examples in a table. Optionally takes in
* a header text for some more contextual information.
*/
export function JsonPathExamplesTable(props: JsonPathExamplesTableProps) {
return (
<EuiFlexItem style={{ width: '20vw' }}>
<EuiFlexGroup direction="column" gutterSize="xs">
{!isEmpty(props.headerText) && (
<EuiFlexItem grow={false}>
<EuiText size="s">{props.headerText}</EuiText>
</EuiFlexItem>
)}
<EuiFlexItem>
<EuiInMemoryTable<JSONPathExample>
items={examples}
columns={columns}
pagination={false}
sorting={false}
hasActions={false}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
);
}
147 changes: 81 additions & 66 deletions public/pages/workflow_detail/tools/query/query.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import React, { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { isEmpty } from 'lodash';
import { useFormikContext } from 'formik';
import {
Expand All @@ -13,7 +14,7 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiSmallButton,
EuiSwitch,
EuiSmallButtonEmpty,
EuiText,
} from '@elastic/eui';
import {
Expand All @@ -24,7 +25,7 @@ import {
SearchResponse,
WorkflowFormValues,
} from '../../../../../common';
import { searchIndex, useAppDispatch } from '../../../../store';
import { AppState, searchIndex, useAppDispatch } from '../../../../store';
import {
containsEmptyValues,
containsSameValues,
Expand Down Expand Up @@ -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<WorkflowFormValues>();

// use custom query state
const [useCustomQuery, setUseCustomQuery] = useState<boolean>(false);

// query response state
const [queryResponse, setQueryResponse] = useState<
SearchResponse | undefined
Expand Down Expand Up @@ -158,11 +158,41 @@ export function Query(props: QueryProps) {
<EuiFlexItem grow={false}>
<EuiFlexGroup direction="row" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiText size="m">Search</EuiText>
<EuiFlexGroup direction="row" justifyContent="flexStart">
<EuiFlexItem grow={false}>
<EuiText size="m">Search</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiComboBox
fullWidth={false}
style={{ width: '250px' }}
compressed={true}
singleSelection={{ asPlainText: true }}
isClearable={false}
options={
props.hasSearchPipeline &&
props.selectedStep === CONFIG_STEP.SEARCH
? SEARCH_OPTIONS
: [SEARCH_OPTIONS[1]]
}
selectedOptions={
props.hasSearchPipeline &&
includePipeline &&
props.selectedStep === CONFIG_STEP.SEARCH
? [SEARCH_OPTIONS[0]]
: [SEARCH_OPTIONS[1]]
}
onChange={(options) => {
setIncludePipeline(!includePipeline);
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiSmallButton
fill={true}
isLoading={loading}
disabled={
containsEmptyValues(queryParams) ||
isEmpty(indexToSearch)
Expand Down Expand Up @@ -200,69 +230,54 @@ export function Query(props: QueryProps) {
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiComboBox
fullWidth={false}
style={{ width: '250px' }}
compressed={true}
singleSelection={{ asPlainText: true }}
isClearable={false}
options={
props.hasSearchPipeline &&
props.selectedStep === CONFIG_STEP.SEARCH
? SEARCH_OPTIONS
: [SEARCH_OPTIONS[1]]
}
selectedOptions={
props.hasSearchPipeline &&
includePipeline &&
props.selectedStep === CONFIG_STEP.SEARCH
? [SEARCH_OPTIONS[0]]
: [SEARCH_OPTIONS[1]]
}
onChange={(options) => {
setIncludePipeline(!includePipeline);
}}
/>
<EuiFlexGroup direction="row" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiText size="s">Query</EuiText>
</EuiFlexItem>
{props.selectedStep === CONFIG_STEP.SEARCH &&
!isEmpty(values?.search?.request) &&
values?.search?.request !== tempRequest && (
<EuiFlexItem grow={false} style={{ marginBottom: '0px' }}>
<EuiSmallButtonEmpty
disabled={false}
onClick={() => {
setTempRequest(values?.search?.request);
}}
>
Revert to query definition
</EuiSmallButtonEmpty>
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiSwitch
label={`Use custom query`}
checked={useCustomQuery}
onChange={(e) => setUseCustomQuery(!useCustomQuery)}
<EuiFlexItem grow={true}>
<EuiCodeEditor
mode="json"
theme="textmate"
width="100%"
height={'100%'}
value={tempRequest}
onChange={(input) => {
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}
/>
</EuiFlexItem>
{useCustomQuery && (
<EuiFlexItem grow={true}>
<EuiCodeEditor
mode="json"
theme="textmate"
width="100%"
height={'100%'}
value={tempRequest}
onChange={(input) => {
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}
/>
</EuiFlexItem>
)}
<EuiFlexItem grow={false}>
{/**
* This may return nothing if the list of params are empty
Expand Down
Loading

0 comments on commit d1be4db

Please sign in to comment.