Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parameterized search #509

Merged
merged 24 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1b407ac
Add edit state on search pipeline and delete resources btn
ohltyler Dec 2, 2024
47250e4
Get new button working on search to autoopen inspector panel
ohltyler Dec 2, 2024
7c18291
Add searching and toggle without pipeline in tools search panel
ohltyler Dec 2, 2024
3773e04
Add empty states and guardrails for when to run search and what optio…
ohltyler Dec 2, 2024
d890800
Add note about resetting state if we want in future
ohltyler Dec 2, 2024
0536f42
Set up edit query boilerplate
ohltyler Dec 2, 2024
edfcf2e
Add search and error handling in modal
ohltyler Dec 2, 2024
cb9e3b4
Get auto-param generation and injection working
ohltyler Dec 3, 2024
fe685d6
Refactor to standalone component; add some error state handling
ohltyler Dec 3, 2024
db32b91
Expose query params component in inspector
ohltyler Dec 3, 2024
dff5c7c
Add custom query as an option
ohltyler Dec 4, 2024
108d283
Override widths for most modals; add type field to queryparam
ohltyler Dec 4, 2024
5dba8d2
Add binary conversion for images when doing query params
ohltyler Dec 4, 2024
ab0ef54
Fix modal width for delete workflow
ohltyler Dec 4, 2024
1f56cf2
update test
ohltyler Dec 4, 2024
0ba11dc
Add guardrails on search btn eligibility
ohltyler Dec 4, 2024
1106554
More state management; fix some spacing
ohltyler Dec 4, 2024
5df8d53
fix inspector panel overflow
ohltyler Dec 4, 2024
b2a23e5
Remove test query btn
ohltyler Dec 4, 2024
4d00f8a
Add more guardrails on ingest
ohltyler Dec 4, 2024
d0209c0
Fully fix spacing; add empty state modal for ingest in inspector
ohltyler Dec 4, 2024
880401e
Update UT
ohltyler Dec 4, 2024
423e13e
prevent running ingest until docs populated
ohltyler Dec 4, 2024
1b7353d
fix UT
ohltyler Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -522,3 +522,32 @@ export enum SOURCE_OPTIONS {
UPLOAD = 'upload',
EXISTING_INDEX = 'existing_index',
}
export enum INSPECTOR_TAB_ID {
INGEST = 'ingest',
QUERY = 'query',
ERRORS = 'errors',
RESOURCES = 'resources',
}

export const INSPECTOR_TABS = [
{
id: INSPECTOR_TAB_ID.INGEST,
name: 'Ingest response',
disabled: false,
},
{
id: INSPECTOR_TAB_ID.QUERY,
name: 'Search response',
disabled: false,
},
{
id: INSPECTOR_TAB_ID.ERRORS,
name: 'Errors',
disabled: false,
},
{
id: INSPECTOR_TAB_ID.RESOURCES,
name: 'Resources',
disabled: false,
},
];
8 changes: 8 additions & 0 deletions common/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,14 @@ export type QuickConfigureFields = {
llmResponseField?: string;
};

export type QueryParamType = 'Text' | 'Binary';

export type QueryParam = {
name: string;
type: QueryParamType;
value: string;
};

/**
********** OPENSEARCH TYPES/INTERFACES ************
*/
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 @@ -6,4 +6,5 @@
export { MultiSelectFilter } from './multi_select_filter';
export { ProcessorsTitle } from './processors_title';
export { ExperimentalBadge } from './experimental_badge';
export { QueryParamsList } from './query_params_list';
export * from './service_card';
152 changes: 152 additions & 0 deletions public/general_components/query_params_list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { get } from 'lodash';
import {
EuiFlexGroup,
EuiFlexItem,
EuiText,
EuiFieldText,
EuiComboBox,
EuiCompressedFilePicker,
} from '@elastic/eui';
import { QueryParam, QueryParamType } from '../../common';

interface QueryParamsListProps {
queryParams: QueryParam[];
setQueryParams: (params: QueryParam[]) => void;
}

// The keys will be more static in general. Give more space for values where users
// will typically be writing out more complex transforms/configuration (in the case of ML inference processors).
const KEY_FLEX_RATIO = 3;
const TYPE_FLEX_RATIO = 2;
const VALUE_FLEX_RATIO = 5;

const OPTIONS = [
{
label: 'Text' as QueryParamType,
},
{
label: 'Binary' as QueryParamType,
},
];

/**
* Basic, reusable component for displaying a list of query parameters, and allowing
* users to freely enter values for each.
*/
export function QueryParamsList(props: QueryParamsListProps) {
return (
<>
{props.queryParams?.length > 0 && (
<EuiFlexItem grow={false}>
<EuiFlexGroup direction="column" gutterSize="xs">
<EuiFlexItem grow={false}>
<EuiFlexGroup direction="row" gutterSize="s">
<EuiFlexItem grow={KEY_FLEX_RATIO}>
<EuiText size="s" color="subdued">
Parameter
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={TYPE_FLEX_RATIO}>
<EuiText size="s" color="subdued">
Type
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={VALUE_FLEX_RATIO}>
<EuiText size="s" color="subdued">
Value
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
{props.queryParams.map((queryParam, idx) => {
return (
<EuiFlexItem grow={false} key={idx}>
<EuiFlexGroup direction="row" gutterSize="s">
<EuiFlexItem grow={KEY_FLEX_RATIO}>
<EuiText size="s" style={{ paddingTop: '4px' }}>
{queryParam.name}
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={TYPE_FLEX_RATIO}>
<EuiComboBox
fullWidth={true}
compressed={true}
placeholder={`Type`}
singleSelection={{ asPlainText: true }}
isClearable={false}
options={OPTIONS}
selectedOptions={[{ label: queryParam.type || 'Text' }]}
onChange={(options) => {
props.setQueryParams(
props.queryParams.map((qp, i) =>
i === idx
? { ...qp, type: get(options, '0.label') }
: qp
)
);
}}
/>
</EuiFlexItem>
<EuiFlexItem grow={VALUE_FLEX_RATIO}>
{queryParam.type === 'Binary' ? (
// For binary filetypes, accept images
<EuiCompressedFilePicker
accept="image/*"
multiple={false}
initialPromptText="Select or drag and drop an image"
onChange={(files) => {
if (files && files.length > 0) {
const fileReader = new FileReader();
fileReader.onload = (e) => {
try {
const binaryData = e.target?.result as string;
const base64Str = binaryData.split(',')[1];
props.setQueryParams(
props.queryParams.map((qp, i) =>
i === idx
? { ...qp, value: base64Str }
: qp
)
);
} catch {}
};
fileReader.readAsDataURL(files[0]);
}
}}
display="default"
/>
) : (
// Default to freeform text input
<EuiFieldText
compressed={true}
fullWidth={true}
placeholder={`Value`}
value={queryParam.value}
onChange={(e) => {
props.setQueryParams(
props.queryParams.map((qp, i) =>
i === idx
? { ...qp, value: e?.target?.value }
: qp
)
);
}}
/>
)}
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
);
})}
</EuiFlexGroup>
</EuiFlexItem>
)}
</>
);
}
6 changes: 5 additions & 1 deletion public/pages/workflow_detail/components/export_modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ export function ExportModal(props: ExportModalProps) {
}, [props.workflow, selectedOption]);

return (
<EuiModal onClose={() => props.setIsExportModalOpen(false)}>
<EuiModal
maxWidth={false}
style={{ width: '70vw' }}
onClose={() => props.setIsExportModalOpen(false)}
>
<EuiModalHeader>
<EuiModalHeaderTitle>
<p>{`Export ${getCharacterLimitedString(
Expand Down
17 changes: 16 additions & 1 deletion public/pages/workflow_detail/resizable_workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '@elastic/eui';
import {
CONFIG_STEP,
INSPECTOR_TAB_ID,
Workflow,
WorkflowConfig,
customStringify,
Expand Down Expand Up @@ -78,9 +79,13 @@ export function ResizableWorkspace(props: ResizableWorkspaceProps) {
setIsToolsPanelOpen(!isToolsPanelOpen);
};

// ingest / search response states to be populated in the Tools panel
// Inspector panel state vars. Actions taken in the form can update the Inspector panel,
// hence we keep top-level vars here to pass to both form and inspector components.
const [ingestResponse, setIngestResponse] = useState<string>('');
const [queryResponse, setQueryResponse] = useState<string>('');
const [selectedInspectorTabId, setSelectedInspectorTabId] = useState<
INSPECTOR_TAB_ID
>(INSPECTOR_TAB_ID.INGEST);

// is valid workflow state, + associated hook to set it as such
const [isValidWorkflow, setIsValidWorkflow] = useState<boolean>(true);
Expand Down Expand Up @@ -132,6 +137,12 @@ export function ResizableWorkspace(props: ResizableWorkspaceProps) {
setSelectedStep={props.setSelectedStep}
setUnsavedIngestProcessors={props.setUnsavedIngestProcessors}
setUnsavedSearchProcessors={props.setUnsavedSearchProcessors}
displaySearchPanel={() => {
if (!isToolsPanelOpen) {
onToggleToolsChange();
}
setSelectedInspectorTabId(INSPECTOR_TAB_ID.QUERY);
}}
/>
</EuiResizablePanel>
<EuiResizableButton />
Expand Down Expand Up @@ -198,6 +209,10 @@ export function ResizableWorkspace(props: ResizableWorkspaceProps) {
workflow={props.workflow}
ingestResponse={ingestResponse}
queryResponse={queryResponse}
setQueryResponse={setQueryResponse}
selectedTabId={selectedInspectorTabId}
setSelectedTabId={setSelectedInspectorTabId}
selectedStep={props.selectedStep}
/>
</EuiResizablePanel>
</>
Expand Down
45 changes: 30 additions & 15 deletions public/pages/workflow_detail/tools/ingest/ingest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
*/

import React from 'react';
import { EuiCodeEditor } from '@elastic/eui';
import { isEmpty } from 'lodash';
import { EuiCodeEditor, EuiEmptyPrompt, EuiText } from '@elastic/eui';

interface IngestProps {
ingestResponse: string;
Expand All @@ -19,19 +20,33 @@ export function Ingest(props: IngestProps) {
// TODO: known issue with the editor where resizing the resizablecontainer does not
// trigger vertical scroll updates. Updating the window, or reloading the component
// by switching tabs etc. will refresh it correctly
<EuiCodeEditor
mode="json"
theme="textmate"
width="100%"
height="100%"
value={props.ingestResponse}
readOnly={true}
setOptions={{
fontSize: '12px',
autoScrollEditorIntoView: true,
wrap: true,
}}
tabSize={2}
/>
<>
{isEmpty(props.ingestResponse) ? (
<EuiEmptyPrompt
title={<h2>No data</h2>}
titleSize="s"
body={
<>
<EuiText size="s">Run ingest and view the response here.</EuiText>
</>
}
/>
) : (
<EuiCodeEditor
mode="json"
theme="textmate"
width="100%"
height="100%"
value={props.ingestResponse}
readOnly={true}
setOptions={{
fontSize: '12px',
autoScrollEditorIntoView: true,
wrap: true,
}}
tabSize={2}
/>
)}
</>
);
}
Loading
Loading