diff --git a/common/interfaces.ts b/common/interfaces.ts index 39c53f01..57481697 100644 --- a/common/interfaces.ts +++ b/common/interfaces.ts @@ -71,7 +71,6 @@ export type SearchIndexConfig = { export type IngestConfig = { enabled: IConfigField; - source: {}; pipelineName: IConfigField; enrich: ProcessorsConfig; index: IndexConfig; diff --git a/common/utils.ts b/common/utils.ts index 2242b028..2992ee71 100644 --- a/common/utils.ts +++ b/common/utils.ts @@ -35,3 +35,7 @@ export function getCharacterLimitedString( : input : ''; } + +export function customStringify(jsonObj: {}): string { + return JSON.stringify(jsonObj, undefined, 2); +} diff --git a/public/pages/workflow_detail/components/export_modal.tsx b/public/pages/workflow_detail/components/export_modal.tsx index 7c4e1b52..55d20a61 100644 --- a/public/pages/workflow_detail/components/export_modal.tsx +++ b/public/pages/workflow_detail/components/export_modal.tsx @@ -22,6 +22,7 @@ import { import { CREATE_WORKFLOW_LINK, Workflow, + customStringify, getCharacterLimitedString, } from '../../../../common'; import { reduceToTemplate } from '../../../utils'; @@ -62,7 +63,7 @@ export function ExportModal(props: ExportModalProps) { if (props.workflow) { const workflowTemplate = reduceToTemplate(props.workflow); if (selectedOption === EXPORT_OPTION.JSON) { - setFormattedConfig(JSON.stringify(workflowTemplate, undefined, 2)); + setFormattedConfig(customStringify(workflowTemplate)); } else if (selectedOption === EXPORT_OPTION.YAML) { setFormattedConfig(yaml.dump(workflowTemplate)); } diff --git a/public/pages/workflow_detail/resizable_workspace.tsx b/public/pages/workflow_detail/resizable_workspace.tsx index cabc76eb..8c089c06 100644 --- a/public/pages/workflow_detail/resizable_workspace.tsx +++ b/public/pages/workflow_detail/resizable_workspace.tsx @@ -28,7 +28,6 @@ import { uiConfigToFormik, uiConfigToSchema, } from '../../utils'; -import { AppState, setDirty, useAppDispatch } from '../../store'; import { WorkflowInputs } from './workflow_inputs'; import { Workspace } from './workspace'; import { Tools } from './tools'; @@ -49,11 +48,6 @@ const TOOLS_PANEL_ID = 'tools_panel_id'; * panels - the ReactFlow workspace panel and the selected component details panel. */ export function ResizableWorkspace(props: ResizableWorkspaceProps) { - const dispatch = useAppDispatch(); - - // Overall workspace state - const { isDirty } = useSelector((state: AppState) => state.form); - // Workflow state const [workflow, setWorkflow] = useState( props.workflow @@ -135,16 +129,6 @@ export function ResizableWorkspace(props: ResizableWorkspaceProps) { } }, [uiConfig]); - /** - * Function to pass down to the Formik
components as a listener to propagate - * form changes to this parent component to re-enable save button, etc. - */ - function onFormChange() { - if (!isDirty) { - dispatch(setDirty()); - } - } - return isValidWorkflow ? ( void; } const CONFIG_FIELD_SPACER_SIZE = 'm'; @@ -42,7 +41,6 @@ export function ConfigFieldList(props: ConfigFieldListProps) { label={camelCaseToTitleString(field.id)} fieldPath={`${props.baseConfigPath}.${props.configId}.${field.id}`} showError={true} - onFormChange={props.onFormChange} /> @@ -55,7 +53,6 @@ export function ConfigFieldList(props: ConfigFieldListProps) { @@ -68,7 +65,6 @@ export function ConfigFieldList(props: ConfigFieldListProps) { @@ -104,7 +99,6 @@ export function ConfigFieldList(props: ConfigFieldListProps) { @@ -118,7 +112,6 @@ export function ConfigFieldList(props: ConfigFieldListProps) { validate={false} label={camelCaseToTitleString(field.id)} fieldPath={`${props.baseConfigPath}.${props.configId}.${field.id}`} - onFormChange={props.onFormChange} /> diff --git a/public/pages/workflow_detail/workflow_inputs/ingest_inputs/advanced_settings.tsx b/public/pages/workflow_detail/workflow_inputs/ingest_inputs/advanced_settings.tsx index d4841358..7402ba3e 100644 --- a/public/pages/workflow_detail/workflow_inputs/ingest_inputs/advanced_settings.tsx +++ b/public/pages/workflow_detail/workflow_inputs/ingest_inputs/advanced_settings.tsx @@ -12,9 +12,7 @@ import { } from '@elastic/eui'; import { JsonField } from '../input_fields'; -interface AdvancedSettingsProps { - onFormChange: () => void; -} +interface AdvancedSettingsProps {} /** * Input component for configuring ingest-side advanced settings @@ -30,14 +28,12 @@ export function AdvancedSettings(props: AdvancedSettingsProps) { diff --git a/public/pages/workflow_detail/workflow_inputs/ingest_inputs/enrich_data.tsx b/public/pages/workflow_detail/workflow_inputs/ingest_inputs/enrich_data.tsx index 53f37f06..4cb03de7 100644 --- a/public/pages/workflow_detail/workflow_inputs/ingest_inputs/enrich_data.tsx +++ b/public/pages/workflow_detail/workflow_inputs/ingest_inputs/enrich_data.tsx @@ -10,7 +10,6 @@ import { PROCESSOR_CONTEXT, WorkflowConfig } from '../../../../../common'; import { ProcessorsTitle } from '../../../../general_components'; interface EnrichDataProps { - onFormChange: () => void; uiConfig: WorkflowConfig; setUiConfig: (uiConfig: WorkflowConfig) => void; } @@ -27,7 +26,6 @@ export function EnrichData(props: EnrichDataProps) { /> void; -} +interface IngestDataProps {} /** * Input component for configuring the data ingest (the OpenSearch index) @@ -24,14 +22,10 @@ export function IngestData(props: IngestDataProps) { - + - + ); diff --git a/public/pages/workflow_detail/workflow_inputs/ingest_inputs/ingest_inputs.tsx b/public/pages/workflow_detail/workflow_inputs/ingest_inputs/ingest_inputs.tsx index e1a96acf..6b3c7f0d 100644 --- a/public/pages/workflow_detail/workflow_inputs/ingest_inputs/ingest_inputs.tsx +++ b/public/pages/workflow_detail/workflow_inputs/ingest_inputs/ingest_inputs.tsx @@ -11,7 +11,6 @@ import { IngestData } from './ingest_data'; import { WorkflowConfig } from '../../../../../common'; interface IngestInputsProps { - onFormChange: () => void; setIngestDocs: (docs: string) => void; uiConfig: WorkflowConfig; setUiConfig: (uiConfig: WorkflowConfig) => void; @@ -24,26 +23,19 @@ export function IngestInputs(props: IngestInputsProps) { return ( - + - + - + ); diff --git a/public/pages/workflow_detail/workflow_inputs/ingest_inputs/source_data.tsx b/public/pages/workflow_detail/workflow_inputs/ingest_inputs/source_data.tsx index e078a408..009794a2 100644 --- a/public/pages/workflow_detail/workflow_inputs/ingest_inputs/source_data.tsx +++ b/public/pages/workflow_detail/workflow_inputs/ingest_inputs/source_data.tsx @@ -25,7 +25,6 @@ import { WorkspaceFormValues } from '../../../../../common'; interface SourceDataProps { setIngestDocs: (docs: string) => void; - onFormChange: () => void; } /** @@ -87,9 +86,6 @@ export function SourceData(props: SourceDataProps) { label="Documents" fieldPath={'ingest.docs'} helpText="Documents should be formatted as a valid JSON array." - // when ingest doc values change, don't update the form - // since we initially only support running ingest once per configuration - onFormChange={() => {}} editorHeight="25vh" readOnly={false} /> @@ -127,9 +123,6 @@ export function SourceData(props: SourceDataProps) { label="Documents" fieldPath={'ingest.docs'} helpText="Documents should be formatted as a valid JSON array." - // when ingest doc values change, don't update the form - // since we initially only support running ingest once per configuration - onFormChange={() => {}} editorHeight="25vh" readOnly={true} /> diff --git a/public/pages/workflow_detail/workflow_inputs/input_fields/boolean_field.tsx b/public/pages/workflow_detail/workflow_inputs/input_fields/boolean_field.tsx index cf9dbcd3..ed391ec7 100644 --- a/public/pages/workflow_detail/workflow_inputs/input_fields/boolean_field.tsx +++ b/public/pages/workflow_detail/workflow_inputs/input_fields/boolean_field.tsx @@ -16,7 +16,6 @@ import { camelCaseToTitleString } from '../../../../utils'; interface BooleanFieldProps { fieldPath: string; // the full path in string-form to the field (e.g., 'ingest.enrich.processors.text_embedding_processor.inputField') - onFormChange: () => void; enabledOption: EuiRadioGroupOption; disabledOption: EuiRadioGroupOption; label?: string; @@ -60,7 +59,6 @@ export function BooleanField(props: BooleanFieldProps) { } onChange={(id) => { form.setFieldValue(field.name, !field.value); - props.onFormChange(); }} /> diff --git a/public/pages/workflow_detail/workflow_inputs/input_fields/json_field.tsx b/public/pages/workflow_detail/workflow_inputs/input_fields/json_field.tsx index 1459596c..e5423f53 100644 --- a/public/pages/workflow_detail/workflow_inputs/input_fields/json_field.tsx +++ b/public/pages/workflow_detail/workflow_inputs/input_fields/json_field.tsx @@ -11,12 +11,11 @@ import { EuiLink, EuiText, } from '@elastic/eui'; -import { WorkspaceFormValues } from '../../../../../common'; +import { WorkspaceFormValues, customStringify } from '../../../../../common'; import { camelCaseToTitleString } from '../../../../utils'; interface JsonFieldProps { fieldPath: string; // the full path in string-form to the field (e.g., 'ingest.enrich.processors.text_embedding_processor.inputField') - onFormChange: () => void; validate?: boolean; label?: string; helpLink?: string; @@ -85,13 +84,12 @@ export function JsonField(props: JsonFieldProps) { try { form.setFieldValue( field.name, - JSON.stringify(JSON.parse(jsonStr), undefined, 2) + customStringify(JSON.parse(jsonStr)) ); } catch (error) { form.setFieldValue(field.name, jsonStr); } finally { form.setFieldTouched(field.name); - props.onFormChange(); } }} readOnly={props.readOnly || false} diff --git a/public/pages/workflow_detail/workflow_inputs/input_fields/map_array_field.tsx b/public/pages/workflow_detail/workflow_inputs/input_fields/map_array_field.tsx index be004acd..b42d1661 100644 --- a/public/pages/workflow_detail/workflow_inputs/input_fields/map_array_field.tsx +++ b/public/pages/workflow_detail/workflow_inputs/input_fields/map_array_field.tsx @@ -32,7 +32,6 @@ interface MapArrayFieldProps { helpText?: string; keyPlaceholder?: string; valuePlaceholder?: string; - onFormChange: () => void; onMapAdd?: (curArray: MapArrayFormValue) => void; onMapDelete?: (idxToDelete: number) => void; keyOptions?: any[]; @@ -51,7 +50,6 @@ export function MapArrayField(props: MapArrayFieldProps) { function addMap(curMapArray: MapArrayFormValue): void { setFieldValue(props.fieldPath, [...curMapArray, []]); setFieldTouched(props.fieldPath, true); - props.onFormChange(); if (props.onMapAdd) { props.onMapAdd(curMapArray); } @@ -66,7 +64,6 @@ export function MapArrayField(props: MapArrayFieldProps) { updatedMapArray.splice(entryIndexToDelete, 1); setFieldValue(props.fieldPath, updatedMapArray); setFieldTouched(props.fieldPath, true); - props.onFormChange(); if (props.onMapDelete) { props.onMapDelete(entryIndexToDelete); } @@ -123,7 +120,6 @@ export function MapArrayField(props: MapArrayFieldProps) { fieldPath={`${props.fieldPath}.${idx}`} keyPlaceholder={props.keyPlaceholder} valuePlaceholder={props.valuePlaceholder} - onFormChange={props.onFormChange} keyOptions={props.keyOptions} valueOptions={props.valueOptions} /> diff --git a/public/pages/workflow_detail/workflow_inputs/input_fields/map_field.tsx b/public/pages/workflow_detail/workflow_inputs/input_fields/map_field.tsx index b8664da2..523eff0c 100644 --- a/public/pages/workflow_detail/workflow_inputs/input_fields/map_field.tsx +++ b/public/pages/workflow_detail/workflow_inputs/input_fields/map_field.tsx @@ -31,7 +31,6 @@ interface MapFieldProps { helpText?: string; keyPlaceholder?: string; valuePlaceholder?: string; - onFormChange: () => void; keyOptions?: any[]; valueOptions?: any[]; } @@ -51,7 +50,6 @@ export function MapField(props: MapFieldProps) { const updatedEntries = [...curEntries, { key: '', value: '' } as MapEntry]; setFieldValue(props.fieldPath, updatedEntries); setFieldTouched(props.fieldPath, true); - props.onFormChange(); } // Deleting a map entry @@ -63,7 +61,6 @@ export function MapField(props: MapFieldProps) { updatedEntries.splice(entryIndexToDelete, 1); setFieldValue(props.fieldPath, updatedEntries); setFieldTouched(props.fieldPath, true); - props.onFormChange(); } return ( @@ -111,14 +108,12 @@ export function MapField(props: MapFieldProps) { fieldPath={`${props.fieldPath}.${idx}.key`} options={props.keyOptions as any[]} placeholder={props.keyPlaceholder || 'Input'} - onFormChange={props.onFormChange} /> ) : ( )} @@ -138,7 +133,6 @@ export function MapField(props: MapFieldProps) { placeholder={ props.valuePlaceholder || 'Output' } - onFormChange={props.onFormChange} /> ) : ( )} diff --git a/public/pages/workflow_detail/workflow_inputs/input_fields/model_field.tsx b/public/pages/workflow_detail/workflow_inputs/input_fields/model_field.tsx index d42de5b3..c33b5fdb 100644 --- a/public/pages/workflow_detail/workflow_inputs/input_fields/model_field.tsx +++ b/public/pages/workflow_detail/workflow_inputs/input_fields/model_field.tsx @@ -29,7 +29,6 @@ interface ModelFieldProps { fieldPath: string; // the full path in string-form to the field (e.g., 'ingest.enrich.processors.text_embedding_processor.inputField') hasModelInterface: boolean; onModelChange: (modelId: string) => void; - onFormChange: () => void; } type ModelItem = ModelFormValue & { @@ -126,7 +125,6 @@ export function ModelField(props: ModelFieldProps) { form.setFieldValue(props.fieldPath, { id: option, } as ModelFormValue); - props.onFormChange(); props.onModelChange(option); }} isInvalid={ diff --git a/public/pages/workflow_detail/workflow_inputs/input_fields/number_field.tsx b/public/pages/workflow_detail/workflow_inputs/input_fields/number_field.tsx index 7bca568c..a9b818e1 100644 --- a/public/pages/workflow_detail/workflow_inputs/input_fields/number_field.tsx +++ b/public/pages/workflow_detail/workflow_inputs/input_fields/number_field.tsx @@ -16,7 +16,6 @@ import { camelCaseToTitleString, getInitialValue } from '../../../../utils'; interface NumberFieldProps { fieldPath: string; // the full path in string-form to the field (e.g., 'ingest.enrich.processors.text_embedding_processor.inputField') - onFormChange: () => void; label?: string; helpLink?: string; helpText?: string; @@ -57,7 +56,6 @@ export function NumberField(props: NumberFieldProps) { value={field.value || getInitialValue('number')} onChange={(e) => { form.setFieldValue(props.fieldPath, e.target.value); - props.onFormChange(); }} /> diff --git a/public/pages/workflow_detail/workflow_inputs/input_fields/select_field.tsx b/public/pages/workflow_detail/workflow_inputs/input_fields/select_field.tsx index 23d4deb2..e58afae8 100644 --- a/public/pages/workflow_detail/workflow_inputs/input_fields/select_field.tsx +++ b/public/pages/workflow_detail/workflow_inputs/input_fields/select_field.tsx @@ -17,7 +17,6 @@ import { camelCaseToTitleString } from '../../../../utils'; interface SelectFieldProps { field: IConfigField; fieldPath: string; // the full path in string-form to the field (e.g., 'ingest.enrich.processors.text_embedding_processor.inputField') - onFormChange: () => void; onSelectChange?: (option: string) => void; } @@ -54,7 +53,6 @@ export function SelectField(props: SelectFieldProps) { onChange={(option: string) => { form.setFieldTouched(props.fieldPath, true); form.setFieldValue(props.fieldPath, option); - props.onFormChange(); if (props.onSelectChange) { props.onSelectChange(option); } diff --git a/public/pages/workflow_detail/workflow_inputs/input_fields/select_with_custom_options.tsx b/public/pages/workflow_detail/workflow_inputs/input_fields/select_with_custom_options.tsx index f3afe702..12adb49f 100644 --- a/public/pages/workflow_detail/workflow_inputs/input_fields/select_with_custom_options.tsx +++ b/public/pages/workflow_detail/workflow_inputs/input_fields/select_with_custom_options.tsx @@ -13,7 +13,6 @@ interface SelectWithCustomOptionsProps { fieldPath: string; placeholder: string; options: any[]; - onFormChange: () => void; } /** @@ -47,7 +46,6 @@ export function SelectWithCustomOptions(props: SelectWithCustomOptionsProps) { } setFieldTouched(props.fieldPath, true); setFieldValue(props.fieldPath, searchValue); - props.onFormChange(); } // custom render fn. @@ -79,7 +77,6 @@ export function SelectWithCustomOptions(props: SelectWithCustomOptionsProps) { onChange={(options) => { setFieldTouched(props.fieldPath, true); setFieldValue(props.fieldPath, get(options, '0.label')); - props.onFormChange(); }} onCreateOption={onCreateOption} customOptionText="Add {searchValue} as a custom option" diff --git a/public/pages/workflow_detail/workflow_inputs/input_fields/text_field.tsx b/public/pages/workflow_detail/workflow_inputs/input_fields/text_field.tsx index a84c82dd..9602bf2c 100644 --- a/public/pages/workflow_detail/workflow_inputs/input_fields/text_field.tsx +++ b/public/pages/workflow_detail/workflow_inputs/input_fields/text_field.tsx @@ -16,7 +16,6 @@ import { getInitialValue } from '../../../../utils'; interface TextFieldProps { fieldPath: string; // the full path in string-form to the field (e.g., 'ingest.enrich.processors.text_embedding_processor.inputField') - onFormChange: () => void; label?: string; helpLink?: string; helpText?: string; @@ -57,7 +56,6 @@ export function TextField(props: TextFieldProps) { value={field.value || getInitialValue('string')} onChange={(e) => { form.setFieldValue(props.fieldPath, e.target.value); - props.onFormChange(); }} /> diff --git a/public/pages/workflow_detail/workflow_inputs/processor_inputs/input_transform_modal.tsx b/public/pages/workflow_detail/workflow_inputs/processor_inputs/input_transform_modal.tsx index f49420c7..a6e4efb1 100644 --- a/public/pages/workflow_detail/workflow_inputs/processor_inputs/input_transform_modal.tsx +++ b/public/pages/workflow_detail/workflow_inputs/processor_inputs/input_transform_modal.tsx @@ -33,6 +33,7 @@ import { SimulateIngestPipelineResponse, WorkflowConfig, WorkflowFormValues, + customStringify, } from '../../../../../common'; import { formikToPartialPipeline, @@ -57,7 +58,6 @@ interface InputTransformModalProps { inputMapFieldPath: string; inputFields: any[]; onClose: () => void; - onFormChange: () => void; } // TODO: InputTransformModal and OutputTransformModal are very similar, and can @@ -175,7 +175,7 @@ export function InputTransformModal(props: InputTransformModalProps) { dispatch( searchIndex({ apiBody: { - index: values.ingest.index.name, + index: values.search.index.name, body: JSON.stringify({ ...JSON.parse(values.search.request as string), search_pipeline: curSearchPipeline, @@ -248,7 +248,6 @@ export function InputTransformModal(props: InputTransformModalProps) { : 'Document field' } keyOptions={props.inputFields} - onFormChange={props.onFormChange} // If the map we are adding is the first one, populate the selected option to index 0 onMapAdd={(curArray) => { if (isEmpty(curArray)) { @@ -301,9 +300,7 @@ export function InputTransformModal(props: InputTransformModalProps) { sampleSourceInput, map[selectedOutputOption] ); - setTransformedOutput( - JSON.stringify(output, undefined, 2) - ); + setTransformedOutput(customStringify(output)); } catch {} } }} diff --git a/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs.tsx b/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs.tsx index 719aa908..223338f7 100644 --- a/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs.tsx +++ b/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs.tsx @@ -43,7 +43,6 @@ interface MLProcessorInputsProps { uiConfig: WorkflowConfig; config: IProcessorConfig; baseConfigPath: string; // the base path of the nested config, if applicable. e.g., 'ingest.enrich' - onFormChange: () => void; context: PROCESSOR_CONTEXT; } @@ -158,7 +157,6 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) { inputMapField={inputMapField} inputMapFieldPath={inputMapFieldPath} inputFields={inputFields} - onFormChange={props.onFormChange} onClose={() => setIsInputTransformModalOpen(false)} /> )} @@ -170,7 +168,6 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) { outputMapField={outputMapField} outputMapFieldPath={outputMapFieldPath} outputFields={outputFields} - onFormChange={props.onFormChange} onClose={() => setIsOutputTransformModalOpen(false)} /> )} @@ -179,7 +176,6 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) { fieldPath={modelFieldPath} hasModelInterface={hasModelInterface} onModelChange={onModelChange} - onFormChange={props.onFormChange} /> {!isEmpty(getIn(values, modelFieldPath)?.id) && ( <> @@ -234,7 +230,6 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) { ? 'Query field' : 'Document field' } - onFormChange={props.onFormChange} keyOptions={inputFields} /> @@ -283,7 +278,6 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) { : 'Document field' } valuePlaceholder="Model output field" - onFormChange={props.onFormChange} valueOptions={outputFields} /> @@ -317,7 +311,6 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) { configId={props.config.id} configFields={props.config.optionalFields || []} baseConfigPath={props.baseConfigPath} - onFormChange={props.onFormChange} /> diff --git a/public/pages/workflow_detail/workflow_inputs/processor_inputs/output_transform_modal.tsx b/public/pages/workflow_detail/workflow_inputs/processor_inputs/output_transform_modal.tsx index 6cd6ff0c..94396457 100644 --- a/public/pages/workflow_detail/workflow_inputs/processor_inputs/output_transform_modal.tsx +++ b/public/pages/workflow_detail/workflow_inputs/processor_inputs/output_transform_modal.tsx @@ -34,6 +34,7 @@ import { SimulateIngestPipelineResponse, WorkflowConfig, WorkflowFormValues, + customStringify, } from '../../../../../common'; import { formikToPartialPipeline, @@ -58,7 +59,6 @@ interface OutputTransformModalProps { outputMapFieldPath: string; outputFields: any[]; onClose: () => void; - onFormChange: () => void; } /** @@ -237,7 +237,6 @@ export function OutputTransformModal(props: OutputTransformModalProps) { keyPlaceholder="Document field" valuePlaceholder="Model output field" valueOptions={props.outputFields} - onFormChange={props.onFormChange} // If the map we are adding is the first one, populate the selected option to index 0 onMapAdd={(curArray) => { if (isEmpty(curArray)) { @@ -290,9 +289,7 @@ export function OutputTransformModal(props: OutputTransformModalProps) { sampleSourceInput, map[selectedOutputOption] ); - setTransformedOutput( - JSON.stringify(output, undefined, 2) - ); + setTransformedOutput(customStringify(output)); } catch {} } }} diff --git a/public/pages/workflow_detail/workflow_inputs/processor_inputs/processor_inputs.tsx b/public/pages/workflow_detail/workflow_inputs/processor_inputs/processor_inputs.tsx index 975dc8f3..0f941340 100644 --- a/public/pages/workflow_detail/workflow_inputs/processor_inputs/processor_inputs.tsx +++ b/public/pages/workflow_detail/workflow_inputs/processor_inputs/processor_inputs.tsx @@ -24,7 +24,6 @@ interface ProcessorInputsProps { uiConfig: WorkflowConfig; config: IProcessorConfig; baseConfigPath: string; // the base path of the nested config, if applicable. e.g., 'ingest.enrich' - onFormChange: () => void; context: PROCESSOR_CONTEXT; } @@ -49,7 +48,6 @@ export function ProcessorInputs(props: ProcessorInputsProps) { uiConfig={props.uiConfig} config={props.config} baseConfigPath={props.baseConfigPath} - onFormChange={props.onFormChange} context={props.context} /> @@ -64,7 +62,6 @@ export function ProcessorInputs(props: ProcessorInputsProps) { uiConfig={props.uiConfig} config={props.config} baseConfigPath={props.baseConfigPath} - onFormChange={props.onFormChange} context={props.context} /> @@ -80,7 +77,6 @@ export function ProcessorInputs(props: ProcessorInputsProps) { configId={props.config.id} configFields={props.config.fields} baseConfigPath={props.baseConfigPath} - onFormChange={props.onFormChange} /> {!isEmpty(props.config.optionalFields) && ( )} diff --git a/public/pages/workflow_detail/workflow_inputs/processor_inputs/text_chunking_processor_inputs.tsx b/public/pages/workflow_detail/workflow_inputs/processor_inputs/text_chunking_processor_inputs.tsx index 607be6f9..593fe393 100644 --- a/public/pages/workflow_detail/workflow_inputs/processor_inputs/text_chunking_processor_inputs.tsx +++ b/public/pages/workflow_detail/workflow_inputs/processor_inputs/text_chunking_processor_inputs.tsx @@ -26,7 +26,6 @@ interface TextChunkingProcessorInputsProps { uiConfig: WorkflowConfig; config: IProcessorConfig; baseConfigPath: string; // the base path of the nested config, if applicable. e.g., 'ingest.enrich' - onFormChange: () => void; context: PROCESSOR_CONTEXT; } @@ -76,7 +75,6 @@ export function TextChunkingProcessorInputs( {fieldMapValue?.length === 0 && ( @@ -119,7 +116,6 @@ export function TextChunkingProcessorInputs( ) || []), ]} baseConfigPath={props.baseConfigPath} - onFormChange={props.onFormChange} /> diff --git a/public/pages/workflow_detail/workflow_inputs/processors_list.tsx b/public/pages/workflow_detail/workflow_inputs/processors_list.tsx index bee13710..64ac0be0 100644 --- a/public/pages/workflow_detail/workflow_inputs/processors_list.tsx +++ b/public/pages/workflow_detail/workflow_inputs/processors_list.tsx @@ -37,7 +37,6 @@ import { import { ProcessorInputs } from './processor_inputs'; interface ProcessorsListProps { - onFormChange: () => void; uiConfig: WorkflowConfig; setUiConfig: (uiConfig: WorkflowConfig) => void; context: PROCESSOR_CONTEXT; @@ -101,7 +100,6 @@ export function ProcessorsList(props: ProcessorsListProps) { } } props.setUiConfig(newConfig); - props.onFormChange(); } // Deleting a processor from the config. Fetch the existing one @@ -132,7 +130,6 @@ export function ProcessorsList(props: ProcessorsListProps) { } props.setUiConfig(newConfig); - props.onFormChange(); } return ( @@ -167,7 +164,6 @@ export function ProcessorsList(props: ProcessorsListProps) { ? 'search.enrichRequest' : 'search.enrichResponse' } - onFormChange={props.onFormChange} context={props.context} /> diff --git a/public/pages/workflow_detail/workflow_inputs/search_inputs/configure_search_request.tsx b/public/pages/workflow_detail/workflow_inputs/search_inputs/configure_search_request.tsx index b65f006d..92712fc6 100644 --- a/public/pages/workflow_detail/workflow_inputs/search_inputs/configure_search_request.tsx +++ b/public/pages/workflow_detail/workflow_inputs/search_inputs/configure_search_request.tsx @@ -35,7 +35,6 @@ import { getDataSourceId } from '../../../../utils/utils'; interface ConfigureSearchRequestProps { setQuery: (query: string) => void; setQueryResponse: (queryResponse: string) => void; - onFormChange: () => void; } /** @@ -102,7 +101,6 @@ export function ConfigureSearchRequest(props: ConfigureSearchRequestProps) { @@ -146,7 +144,6 @@ export function ConfigureSearchRequest(props: ConfigureSearchRequestProps) { setSelectedIndex(option); setFieldValue(searchIndexNameFormPath, option); setFieldTouched(searchIndexNameFormPath, true); - props.onFormChange(); }} isInvalid={selectedIndex === undefined} /> @@ -167,7 +164,6 @@ export function ConfigureSearchRequest(props: ConfigureSearchRequestProps) { diff --git a/public/pages/workflow_detail/workflow_inputs/search_inputs/enrich_search_request.tsx b/public/pages/workflow_detail/workflow_inputs/search_inputs/enrich_search_request.tsx index 22c0d927..763eb6cf 100644 --- a/public/pages/workflow_detail/workflow_inputs/search_inputs/enrich_search_request.tsx +++ b/public/pages/workflow_detail/workflow_inputs/search_inputs/enrich_search_request.tsx @@ -12,7 +12,6 @@ import { ProcessorsList } from '../processors_list'; interface EnrichSearchRequestProps { uiConfig: WorkflowConfig; setUiConfig: (uiConfig: WorkflowConfig) => void; - onFormChange: () => void; } /** @@ -29,7 +28,6 @@ export function EnrichSearchRequest(props: EnrichSearchRequestProps) { /> void; - onFormChange: () => void; } /** @@ -29,7 +28,6 @@ export function EnrichSearchResponse(props: EnrichSearchResponseProps) { /> void; setQuery: (query: string) => void; setQueryResponse: (queryResponse: string) => void; - onFormChange: () => void; } /** @@ -28,7 +27,6 @@ export function SearchInputs(props: SearchInputsProps) { @@ -38,7 +36,6 @@ export function SearchInputs(props: SearchInputsProps) { @@ -48,7 +45,6 @@ export function SearchInputs(props: SearchInputsProps) { diff --git a/public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx b/public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx index 19a88d21..6c178901 100644 --- a/public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx +++ b/public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx @@ -36,17 +36,16 @@ import { WorkflowConfig, WorkflowFormValues, WorkflowTemplate, + customStringify, getCharacterLimitedString, } from '../../../../common'; import { IngestInputs } from './ingest_inputs'; import { SearchInputs } from './search_inputs'; import { - AppState, bulk, deprovisionWorkflow, getWorkflow, provisionWorkflow, - removeDirty, searchIndex, updateWorkflow, useAppDispatch, @@ -70,7 +69,6 @@ import '../workspace/workspace-styles.scss'; interface WorkflowInputsProps { workflow: Workflow | undefined; - onFormChange: () => void; uiConfig: WorkflowConfig | undefined; setUiConfig: (uiConfig: WorkflowConfig) => void; setIngestResponse: (ingestResponse: string) => void; @@ -103,13 +101,11 @@ export function WorkflowInputs(props: WorkflowInputsProps) { setFieldValue, values, touched, + dirty, } = useFormikContext(); const dispatch = useAppDispatch(); const dataSourceId = getDataSourceId(); - // Overall form state - const { isDirty } = useSelector((state: AppState) => state.form); - // running ingest/search state const [isRunningIngest, setIsRunningIngest] = useState(false); const [isRunningSearch, setIsRunningSearch] = useState(false); @@ -489,8 +485,7 @@ export function WorkflowInputs(props: WorkflowInputsProps) { dispatch(bulk({ apiBody: { body: bulkBody }, dataSourceId })) .unwrap() .then(async (resp) => { - props.setIngestResponse(JSON.stringify(resp, undefined, 2)); - dispatch(removeDirty()); + props.setIngestResponse(customStringify(resp)); }) .catch((error: any) => { props.setIngestResponse(''); @@ -548,7 +543,6 @@ export function WorkflowInputs(props: WorkflowInputsProps) { 2 ) ); - dispatch(removeDirty()); }) .catch((error: any) => { props.setQueryResponse(''); @@ -658,7 +652,7 @@ export function WorkflowInputs(props: WorkflowInputsProps) { )} {onIngest && - isDirty && + dirty && hasProvisionedSearchResources(props.workflow) && ( {onIngest ? ( )} @@ -774,7 +765,6 @@ export function WorkflowInputs(props: WorkflowInputsProps) { disabled={false} onClick={() => { setSelectedStep(STEP.SEARCH); - dispatch(removeDirty()); }} > {`Search pipeline >`} diff --git a/public/pages/workflow_detail/workspace/workspace.tsx b/public/pages/workflow_detail/workspace/workspace.tsx index 7b30afca..f72a282b 100644 --- a/public/pages/workflow_detail/workspace/workspace.tsx +++ b/public/pages/workflow_detail/workspace/workspace.tsx @@ -21,7 +21,6 @@ import { EuiFilterButton, EuiCodeEditor, } from '@elastic/eui'; -import { setDirty, useAppDispatch } from '../../../store'; import { IComponentData, Workflow, WorkflowConfig } from '../../../../common'; import { IngestGroupComponent, @@ -50,8 +49,6 @@ const nodeTypes = { const edgeTypes = { customEdge: DeletableEdge }; export function Workspace(props: WorkspaceProps) { - const dispatch = useAppDispatch(); - // Visual/JSON toggle states const [visualSelected, setVisualSelected] = useState(true); function toggleSelection(): void { @@ -92,7 +89,6 @@ export function Workspace(props: WorkspaceProps) { eds ) ); - dispatch(setDirty()); }, [setEdges] ); diff --git a/public/pages/workflow_detail/workspace/workspace_edge/deletable_edge.tsx b/public/pages/workflow_detail/workspace/workspace_edge/deletable_edge.tsx index 84a0bccf..27b6ab92 100644 --- a/public/pages/workflow_detail/workspace/workspace_edge/deletable_edge.tsx +++ b/public/pages/workflow_detail/workspace/workspace_edge/deletable_edge.tsx @@ -13,7 +13,6 @@ import { getBezierPath, useReactFlow, } from 'reactflow'; -import { setDirty, useAppDispatch } from '../../../../store'; // styling import './deletable-edge-styles.scss'; @@ -26,8 +25,6 @@ type DeletableEdgeProps = EdgeProps; * see https://reactflow.dev/docs/examples/edges/edge-types/ */ export function DeletableEdge(props: DeletableEdgeProps) { - const dispatch = useAppDispatch(); - const [edgePath, labelX, labelY] = getBezierPath({ sourceX: props.sourceX, sourceY: props.sourceY, @@ -43,7 +40,6 @@ export function DeletableEdge(props: DeletableEdgeProps) { reactFlowInstance.setEdges( reactFlowInstance.getEdges().filter((edge: Edge) => edge.id !== edgeId) ); - dispatch(setDirty()); }; const onEdgeClick = (event: any, edgeId: string) => { diff --git a/public/pages/workflows/new_workflow/utils.ts b/public/pages/workflows/new_workflow/utils.ts index bcbf309f..1d88febe 100644 --- a/public/pages/workflows/new_workflow/utils.ts +++ b/public/pages/workflows/new_workflow/utils.ts @@ -12,6 +12,7 @@ import { UIState, WORKFLOW_TYPE, FETCH_ALL_QUERY_BODY, + customStringify, } from '../../../../common'; import { generateId } from '../../../utils'; @@ -51,7 +52,6 @@ function fetchEmptyMetadata(): UIState { type: 'boolean', value: true, }, - source: {}, pipelineName: { id: 'pipelineName', type: 'string', @@ -64,10 +64,14 @@ function fetchEmptyMetadata(): UIState { name: { id: 'indexName', type: 'string', + value: 'my-new-index', }, mappings: { id: 'indexMappings', type: 'json', + value: customStringify({ + properties: {}, + }), }, settings: { id: 'indexSettings', @@ -79,7 +83,7 @@ function fetchEmptyMetadata(): UIState { request: { id: 'request', type: 'json', - value: JSON.stringify(FETCH_ALL_QUERY_BODY, undefined, 2), + value: customStringify(FETCH_ALL_QUERY_BODY), }, pipelineName: { id: 'pipelineName', @@ -109,6 +113,10 @@ function fetchSemanticSearchMetadata(): UIState { let baseState = fetchEmptyMetadata(); baseState.type = WORKFLOW_TYPE.SEMANTIC_SEARCH; baseState.config.ingest.enrich.processors = [new MLIngestProcessor().toObj()]; + baseState.config.ingest.index.name.value = 'my-knn-index'; + baseState.config.ingest.index.settings.value = customStringify({ + [`index.knn`]: true, + }); return baseState; } diff --git a/public/store/reducers/form_reducer.ts b/public/store/reducers/form_reducer.ts deleted file mode 100644 index c3ca6609..00000000 --- a/public/store/reducers/form_reducer.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import { createSlice } from '@reduxjs/toolkit'; - -const initialState = { - isDirty: false, -}; - -const formSlice = createSlice({ - name: 'form', - initialState, - reducers: { - setDirty(state) { - state.isDirty = true; - }, - removeDirty(state) { - state.isDirty = false; - }, - }, -}); - -export const formReducer = formSlice.reducer; -export const { setDirty, removeDirty } = formSlice.actions; diff --git a/public/store/reducers/index.ts b/public/store/reducers/index.ts index 9c3e99fe..9aeff271 100644 --- a/public/store/reducers/index.ts +++ b/public/store/reducers/index.ts @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -export * from './form_reducer'; export * from './opensearch_reducer'; export * from './workflows_reducer'; export * from './presets_reducer'; diff --git a/public/store/store.ts b/public/store/store.ts index 337a9e4c..3d0c4214 100644 --- a/public/store/store.ts +++ b/public/store/store.ts @@ -11,11 +11,9 @@ import { workflowsReducer, presetsReducer, modelsReducer, - formReducer, } from './reducers'; const rootReducer = combineReducers({ - form: formReducer, workflows: workflowsReducer, presets: presetsReducer, models: modelsReducer, diff --git a/public/utils/utils.ts b/public/utils/utils.ts index 8198900c..11a71a59 100644 --- a/public/utils/utils.ts +++ b/public/utils/utils.ts @@ -19,6 +19,7 @@ import { WORKFLOW_RESOURCE_TYPE, WORKFLOW_STEP_TYPE, Workflow, + customStringify, } from '../../common'; import { getCore, getDataSourceEnabled } from '../services'; import { MDSQueryParams } from '../../common/interfaces'; @@ -161,7 +162,7 @@ export function unwrapTransformedDocs( `Failed to simulate ingest on all documents: ${errorDuringSimulate}` ); } - return JSON.stringify(transformedDocsSources, undefined, 2); + return customStringify(transformedDocsSources); } // ML inference processors will use standard dot notation or JSONPath depending on the input.