Skip to content

Commit 096bdfa

Browse files
authored
UX fit-n-finish updates IV (opensearch-project#565)
Signed-off-by: Tyler Ohlsen <ohltyler@amazon.com>
1 parent cd07da0 commit 096bdfa

File tree

22 files changed

+373
-90
lines changed

22 files changed

+373
-90
lines changed

common/constants.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ export enum WORKFLOW_TYPE {
166166
MULTIMODAL_SEARCH = 'Multimodal search',
167167
HYBRID_SEARCH = 'Hybrid search',
168168
RAG = 'Retrieval-augmented generation',
169+
VECTOR_SEARCH_WITH_RAG = 'Vector search with retrieval-augmented generation',
169170
CUSTOM = 'Custom',
170171
UNKNOWN = 'Unknown',
171172
}
@@ -281,12 +282,13 @@ export const VECTOR = 'vector';
281282
export const VECTOR_PATTERN = `{{${VECTOR}}}`;
282283
export const VECTOR_TEMPLATE_PLACEHOLDER = `\$\{${VECTOR}\}`;
283284
export const DEFAULT_K = 10;
285+
export const DEFAULT_FETCH_SIZE = 10;
284286

285287
export const FETCH_ALL_QUERY = {
286288
query: {
287289
match_all: {},
288290
},
289-
size: 1000,
291+
size: DEFAULT_FETCH_SIZE,
290292
};
291293
export const TERM_QUERY_TEXT = {
292294
query: {
@@ -578,6 +580,7 @@ export const EMPTY_FIELD_STRING = '--';
578580
export const OMIT_SYSTEM_INDEX_PATTERN = '*,-.*';
579581
export const INDEX_NOT_FOUND_EXCEPTION = 'index_not_found_exception';
580582
export const ERROR_GETTING_WORKFLOW_MSG = 'Failed to retrieve template';
583+
export const INVALID_DATASOURCE_MSG = 'No Living connections';
581584
export const NO_TEMPLATES_FOUND_MSG = 'There are no templates';
582585
export const NO_MODIFICATIONS_FOUND_TEXT =
583586
'Template does not contain any modifications';

common/interfaces.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,8 @@ export type PromptPreset = {
544544
};
545545

546546
export type QuickConfigureFields = {
547-
modelId?: string;
547+
embeddingModelId?: string;
548+
llmId?: string;
548549
vectorField?: string;
549550
textField?: string;
550551
imageField?: string;

common/utils.ts

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export function isVectorSearchUseCase(workflow: Workflow | undefined): boolean {
4747
WORKFLOW_TYPE.HYBRID_SEARCH,
4848
WORKFLOW_TYPE.MULTIMODAL_SEARCH,
4949
WORKFLOW_TYPE.SEMANTIC_SEARCH,
50+
WORKFLOW_TYPE.VECTOR_SEARCH_WITH_RAG,
5051
].includes(workflow?.ui_metadata?.type)
5152
);
5253
}

public/pages/workflow_detail/components/export_modal.tsx

+51-23
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
import React, { useEffect, useState } from 'react';
77
import yaml from 'js-yaml';
8+
import { isEmpty, toLower } from 'lodash';
89
import {
910
EuiCodeBlock,
1011
EuiFlexGroup,
1112
EuiFlexItem,
12-
EuiCompressedRadioGroup,
1313
EuiText,
1414
EuiLink,
1515
EuiModal,
@@ -20,6 +20,7 @@ import {
2020
EuiSmallButtonEmpty,
2121
EuiCallOut,
2222
EuiSpacer,
23+
EuiSmallButtonGroup,
2324
} from '@elastic/eui';
2425
import {
2526
CREATE_WORKFLOW_LINK,
@@ -38,21 +39,10 @@ interface ExportModalProps {
3839
}
3940

4041
enum EXPORT_OPTION {
41-
JSON = 'json',
42-
YAML = 'yaml',
42+
JSON = 'JSON',
43+
YAML = 'YAML',
4344
}
4445

45-
const exportOptions = [
46-
{
47-
id: EXPORT_OPTION.JSON,
48-
label: 'JSON',
49-
},
50-
{
51-
id: EXPORT_OPTION.YAML,
52-
label: 'YAML',
53-
},
54-
];
55-
5646
/**
5747
* Modal containing all of the export options
5848
*/
@@ -75,6 +65,18 @@ export function ExportModal(props: ExportModalProps) {
7565
}
7666
}, [props.workflow, selectedOption]);
7767

68+
// client-side file to be downloaded if the user so chooses. Generate a file
69+
// and its corresponding URL.
70+
const [formattedConfigHref, setFormattedConfigHref] = useState<string>('');
71+
useEffect(() => {
72+
if (!isEmpty(formattedConfig)) {
73+
const formattedConfigFile = new Blob([formattedConfig], {
74+
type: `text/${toLower(selectedOption)}`,
75+
});
76+
setFormattedConfigHref(URL.createObjectURL(formattedConfigFile));
77+
}
78+
}, [formattedConfig]);
79+
7880
return (
7981
<EuiModal
8082
maxWidth={false}
@@ -115,19 +117,45 @@ export function ExportModal(props: ExportModalProps) {
115117
>{`Note: certain resource IDs in the template, such as model IDs, may be cluster-specific and not work out-of-the-box
116118
in other environments. Ensure these values are updated before attempting to provision in other environments.`}</EuiText>
117119
</EuiFlexItem>
118-
<EuiFlexItem grow={false}>
119-
<EuiCompressedRadioGroup
120-
options={exportOptions}
121-
idSelected={selectedOption}
122-
onChange={(option) => {
123-
setSelectedOption(option as EXPORT_OPTION);
124-
}}
125-
/>
120+
<EuiFlexItem>
121+
<EuiFlexGroup direction="row" justifyContent="spaceBetween">
122+
<EuiFlexItem grow={false}>
123+
<EuiSmallButtonGroup
124+
legend="Choose how to view your workflow"
125+
options={[
126+
{
127+
id: EXPORT_OPTION.JSON,
128+
label: EXPORT_OPTION.JSON,
129+
},
130+
{
131+
id: EXPORT_OPTION.YAML,
132+
label: EXPORT_OPTION.YAML,
133+
},
134+
]}
135+
idSelected={selectedOption}
136+
onChange={(id) => setSelectedOption(id as EXPORT_OPTION)}
137+
data-testid="exportDataToggleButtonGroup"
138+
/>
139+
</EuiFlexItem>
140+
<EuiFlexItem grow={false}>
141+
<EuiSmallButtonEmpty
142+
iconType="download"
143+
iconSide="right"
144+
href={formattedConfigHref}
145+
download={`${props.workflow?.name}.${toLower(
146+
selectedOption
147+
)}`}
148+
onClick={() => {}}
149+
>
150+
{`Download ${selectedOption} file`}
151+
</EuiSmallButtonEmpty>
152+
</EuiFlexItem>
153+
</EuiFlexGroup>
126154
</EuiFlexItem>
127155
{props.workflow !== undefined && (
128156
<EuiFlexItem grow={false}>
129157
<EuiCodeBlock
130-
language={selectedOption}
158+
language={toLower(selectedOption)}
131159
fontSize="m"
132160
isCopyable={true}
133161
>

public/pages/workflow_detail/workflow_detail.test.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ describe('WorkflowDetail Page Functionality (Custom Workflow)', () => {
113113
jest.clearAllMocks();
114114
});
115115
test('tests Export button, Tools panel toggling, and Workspace preview', async () => {
116+
global.URL.createObjectURL = jest.fn();
116117
const { getByText, container, getByTestId } = renderWithRouter(
117118
workflowId,
118119
workflowName,

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

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export function JsonField(props: JsonFieldProps) {
7979
value={jsonStr}
8080
onChange={(input) => {
8181
setJsonStr(input);
82+
form.setFieldValue(field.name, input);
8283
}}
8384
onBlur={() => {
8485
try {

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

+1
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ export function OverrideQueryModal(props: OverrideQueryModalProps) {
234234
validate={false}
235235
label={'Query template'}
236236
fieldPath={'request'}
237+
editorHeight="30vh"
237238
/>
238239
{finalModelOutputs.length > 0 && (
239240
<>

public/pages/workflow_detail/workflow_inputs/search_inputs/search_inputs.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export function SearchInputs(props: SearchInputsProps) {
3939
<ConfigureSearchRequest />
4040
</EuiFlexItem>
4141
<EuiFlexItem grow={false}>
42-
<EuiHorizontalRule margin="none" />
42+
<EuiHorizontalRule margin="m" />
4343
</EuiFlexItem>
4444
<EuiFlexItem grow={false}>
4545
<EnrichSearchRequest
@@ -48,7 +48,7 @@ export function SearchInputs(props: SearchInputsProps) {
4848
/>
4949
</EuiFlexItem>
5050
<EuiFlexItem grow={false}>
51-
<EuiHorizontalRule margin="none" />
51+
<EuiHorizontalRule margin="m" />
5252
</EuiFlexItem>
5353
<EuiFlexItem grow={false}>
5454
<EnrichSearchResponse

public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ export function WorkflowInputs(props: WorkflowInputsProps) {
506506
);
507507
dispatch(bulk({ apiBody: { body: bulkBody }, dataSourceId }))
508508
.unwrap()
509-
.then(async (resp) => {
509+
.then(async (resp: any) => {
510510
props.setIngestResponse(customStringify(resp));
511511
props.setIsRunningIngest(false);
512512
setLastIngested(Date.now());

0 commit comments

Comments
 (0)