From 326d099859eb47605375ba6d74094793a1bb8fde Mon Sep 17 00:00:00 2001 From: Tyler Ohlsen Date: Fri, 21 Jun 2024 15:36:32 -0700 Subject: [PATCH] Add export step (#197) Signed-off-by: Tyler Ohlsen --- package.json | 3 +- .../export_options/export_options.tsx | 83 +++++++++++++++++++ .../workflow_inputs/export_options/index.ts | 6 ++ .../workflow_inputs/workflow_inputs.tsx | 60 ++++++++++++-- yarn.lock | 12 +++ 5 files changed, 156 insertions(+), 8 deletions(-) create mode 100644 public/pages/workflow_detail/workflow_inputs/export_options/export_options.tsx create mode 100644 public/pages/workflow_detail/workflow_inputs/export_options/index.ts diff --git a/package.json b/package.json index eec6cfc9..238d745f 100644 --- a/package.json +++ b/package.json @@ -28,9 +28,10 @@ }, "dependencies": { "formik": "2.4.2", + "js-yaml": "^4.1.0", "reactflow": "^11.8.3", "yup": "^1.3.2" }, "devDependencies": {}, "resolutions": {} -} \ No newline at end of file +} diff --git a/public/pages/workflow_detail/workflow_inputs/export_options/export_options.tsx b/public/pages/workflow_detail/workflow_inputs/export_options/export_options.tsx new file mode 100644 index 00000000..409ca35e --- /dev/null +++ b/public/pages/workflow_detail/workflow_inputs/export_options/export_options.tsx @@ -0,0 +1,83 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React, { useEffect, useState } from 'react'; +import yaml from 'js-yaml'; +import { + EuiCodeBlock, + EuiFlexGroup, + EuiFlexItem, + EuiRadioGroup, +} from '@elastic/eui'; +import { Workflow } from '../../../../../common'; +import { reduceToTemplate } from '../../../../utils'; + +interface SearchInputsProps { + workflow?: Workflow; +} + +enum EXPORT_OPTION { + JSON = 'json', + YAML = 'yaml', +} + +const exportOptions = [ + { + id: EXPORT_OPTION.JSON, + label: 'JSON', + }, + { + id: EXPORT_OPTION.YAML, + label: 'YAML', + }, +]; + +/** + * The base component containing all of the export options + */ +export function ExportOptions(props: SearchInputsProps) { + // format type state + const [selectedOption, setSelectedOption] = useState( + EXPORT_OPTION.JSON + ); + + // formatted string state + const [formattedConfig, setFormattedConfig] = useState(''); + useEffect(() => { + if (props.workflow) { + const workflowTemplate = reduceToTemplate(props.workflow); + if (selectedOption === EXPORT_OPTION.JSON) { + setFormattedConfig(JSON.stringify(workflowTemplate, undefined, 2)); + } else if (selectedOption === EXPORT_OPTION.YAML) { + setFormattedConfig(yaml.dump(workflowTemplate)); + } + } + }, [props.workflow, selectedOption]); + + return ( + + + { + setSelectedOption(option as EXPORT_OPTION); + }} + /> + + {props.workflow !== undefined && ( + + + {formattedConfig} + + + )} + + ); +} diff --git a/public/pages/workflow_detail/workflow_inputs/export_options/index.ts b/public/pages/workflow_detail/workflow_inputs/export_options/index.ts new file mode 100644 index 00000000..6048a6dd --- /dev/null +++ b/public/pages/workflow_detail/workflow_inputs/export_options/index.ts @@ -0,0 +1,6 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export * from './export_options'; diff --git a/public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx b/public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx index a5f3d60d..9e7d30c7 100644 --- a/public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx +++ b/public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx @@ -43,6 +43,7 @@ import { hasProvisionedIngestResources, } from '../../../utils'; import { BooleanField } from './input_fields'; +import { ExportOptions } from './export_options'; // styling import '../workspace/workspace-styles.scss'; @@ -63,6 +64,7 @@ interface WorkflowInputsProps { enum STEP { INGEST = 'Ingestion pipeline', SEARCH = 'Search pipeline', + EXPORT = 'Export', } enum INGEST_OPTION { @@ -89,6 +91,8 @@ export function WorkflowInputs(props: WorkflowInputsProps) { // maintain global states const onIngest = selectedStep === STEP.INGEST; + const onSearch = selectedStep === STEP.SEARCH; + const onExport = selectedStep === STEP.EXPORT; const ingestEnabled = values?.ingest?.enabled || false; const onIngestAndProvisioned = onIngest && ingestProvisioned; const onIngestAndUnprovisioned = onIngest && !ingestProvisioned; @@ -264,14 +268,20 @@ export function WorkflowInputs(props: WorkflowInputsProps) { steps={[ { title: STEP.INGEST, - isComplete: selectedStep === STEP.SEARCH, - isSelected: selectedStep === STEP.INGEST, + isComplete: onSearch || onExport, + isSelected: onIngest, onClick: () => {}, }, { title: STEP.SEARCH, + isComplete: onExport, + isSelected: onSearch, + onClick: () => {}, + }, + { + title: STEP.EXPORT, isComplete: false, - isSelected: selectedStep === STEP.SEARCH, + isSelected: onExport, onClick: () => {}, }, ]} @@ -321,7 +331,9 @@ export function WorkflowInputs(props: WorkflowInputsProps) { ? 'Define ingest pipeline' : onIngestAndProvisioned ? 'Edit ingest pipeline' - : 'Define search pipeline'} + : onSearch + ? 'Define search pipeline' + : 'Export project as'} @@ -339,13 +351,15 @@ export function WorkflowInputs(props: WorkflowInputsProps) { uiConfig={props.uiConfig} setUiConfig={props.setUiConfig} /> - ) : ( + ) : onSearch ? ( + ) : ( + )} @@ -407,7 +421,7 @@ export function WorkflowInputs(props: WorkflowInputsProps) { - ) : ( + ) : onSearch ? ( <> { validateAndRunQuery(); }} @@ -427,6 +441,38 @@ export function WorkflowInputs(props: WorkflowInputsProps) { Run query + + { + setSelectedStep(STEP.EXPORT); + }} + > + {`Export >`} + + + + ) : ( + <> + + setSelectedStep(STEP.SEARCH)} + > + Back + + + + { + // TODO: final UX for export flow is TBD. + }} + > + Export + + )} diff --git a/yarn.lock b/yarn.lock index f7ff8bac..d8ee619b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -283,6 +283,11 @@ resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.11.tgz#012c17cb2256ad8de78560da851ab914a7b9b40e" integrity sha512-L7A0AINMXQpVwxHJ4jxD6/XjZ4NDufaRlUJHjNIFKYUFBH1SvOW+neaqb0VTRSLW5suSrSu19ObFEFnfNcr+qg== +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + classcat@^5.0.3, classcat@^5.0.4: version "5.0.4" resolved "https://registry.yarnpkg.com/classcat/-/classcat-5.0.4.tgz#e12d1dfe6df6427f260f03b80dc63571a5107ba6" @@ -375,6 +380,13 @@ hoist-non-react-statics@^3.3.0: dependencies: react-is "^16.7.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + lodash-es@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"