From 2547f267bd86aba9801aac03d6675c6d9196db09 Mon Sep 17 00:00:00 2001 From: kishor82 Date: Sat, 8 Apr 2023 14:53:45 +0530 Subject: [PATCH 01/15] feat: Add export functionality for dev tool queries Signed-off-by: kishor82 --- .../containers/main/get_top_nav.ts | 21 ++++++++++++++++++- .../application/containers/main/main.tsx | 14 +++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/plugins/console/public/application/containers/main/get_top_nav.ts b/src/plugins/console/public/application/containers/main/get_top_nav.ts index e7eba5c580ac..b1e3511c9b2f 100644 --- a/src/plugins/console/public/application/containers/main/get_top_nav.ts +++ b/src/plugins/console/public/application/containers/main/get_top_nav.ts @@ -34,9 +34,15 @@ interface Props { onClickHistory: () => void; onClickSettings: () => void; onClickHelp: () => void; + onClickExport: () => void; } -export function getTopNavConfig({ onClickHistory, onClickSettings, onClickHelp }: Props) { +export function getTopNavConfig({ + onClickHistory, + onClickSettings, + onClickHelp, + onClickExport, +}: Props) { return [ { id: 'history', @@ -77,5 +83,18 @@ export function getTopNavConfig({ onClickHistory, onClickSettings, onClickHelp } }, testId: 'consoleHelpButton', }, + { + id: 'export', + label: i18n.translate('console.topNav.exportTabLabel', { + defaultMessage: 'Export', + }), + description: i18n.translate('console.topNav.exportTabDescription', { + defaultMessage: 'Export', + }), + onClick: () => { + onClickExport(); + }, + testId: 'consoleExportButton', + }, ]; } diff --git a/src/plugins/console/public/application/containers/main/main.tsx b/src/plugins/console/public/application/containers/main/main.tsx index 1967c14615bb..154d81e08b48 100644 --- a/src/plugins/console/public/application/containers/main/main.tsx +++ b/src/plugins/console/public/application/containers/main/main.tsx @@ -28,8 +28,10 @@ * under the License. */ -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import { i18n } from '@osd/i18n'; +// @ts-expect-error +import { saveAs } from '@elastic/filesaver'; import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiPageContent } from '@elastic/eui'; import { ConsoleHistory } from '../console_history'; import { Editor } from '../editor'; @@ -54,7 +56,7 @@ interface MainProps { export function Main({ dataSourceId }: MainProps) { const { - services: { storage }, + services: { storage, objectStorageClient }, } = useServicesContext(); const { ready: editorsReady } = useEditorReadContext(); @@ -72,6 +74,13 @@ export function Main({ dataSourceId }: MainProps) { const [showSettings, setShowSettings] = useState(false); const [showHelp, setShowHelp] = useState(false); + const onExport = async () => { + const results = await objectStorageClient.text.findAll(); + const senseData = results.sort((a, b) => a.createdAt - b.createdAt)[0]; + const blob = new Blob([JSON.stringify(senseData || {})], { type: 'application/json' }); + saveAs(blob, 'sense.json'); + }; + const renderConsoleHistory = () => { return editorsReady ? setShowHistory(false)} /> : null; }; @@ -111,6 +120,7 @@ export function Main({ dataSourceId }: MainProps) { onClickHistory: () => setShowHistory(!showingHistory), onClickSettings: () => setShowSettings(true), onClickHelp: () => setShowHelp(!showHelp), + onClickExport: () => onExport(), })} /> From 9322883a5d79778aadab4557d69b7748ebc6e382 Mon Sep 17 00:00:00 2001 From: kishor82 Date: Sat, 8 Apr 2023 22:18:18 +0530 Subject: [PATCH 02/15] feat: Add import functionality for dev tool queries Signed-off-by: kishor82 --- .../application/components/import_flyout.tsx | 313 ++++++++++++++++++ .../components/import_mode_control.tsx | 100 ++++++ .../public/application/components/index.ts | 1 + .../components/overwrite_modal.tsx | 66 ++++ .../containers/main/get_top_nav.ts | 15 + .../application/containers/main/main.tsx | 7 + .../application/contexts/services_context.tsx | 3 +- .../console/public/application/index.tsx | 5 +- src/plugins/console/public/plugin.ts | 2 + 9 files changed, 510 insertions(+), 2 deletions(-) create mode 100644 src/plugins/console/public/application/components/import_flyout.tsx create mode 100644 src/plugins/console/public/application/components/import_mode_control.tsx create mode 100644 src/plugins/console/public/application/components/overwrite_modal.tsx diff --git a/src/plugins/console/public/application/components/import_flyout.tsx b/src/plugins/console/public/application/components/import_flyout.tsx new file mode 100644 index 000000000000..4914f69cc811 --- /dev/null +++ b/src/plugins/console/public/application/components/import_flyout.tsx @@ -0,0 +1,313 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Any modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + EuiFlyout, + EuiFlyoutHeader, + EuiTitle, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiCallOut, + EuiSpacer, + EuiFilePicker, + EuiFlexGroup, + EuiFlexItem, + EuiForm, + EuiFormRow, + EuiLoadingSpinner, + EuiText, + EuiButton, + EuiButtonEmpty, +} from '@elastic/eui'; +import moment from 'moment'; +import { i18n } from '@osd/i18n'; +import { FormattedMessage } from '@osd/i18n/react'; +import React, { Fragment, useState } from 'react'; +import { ImportMode, ImportModeControl } from './import_mode_control'; +import { useEditorReadContext, useServicesContext } from '../contexts'; +import { TextObject } from '../../../common/text_object'; +import { OverwriteModal } from './overwrite_modal'; + +const OVERWRITE_ALL_DEFAULT = false; + +interface ImportFlyoutProps { + close: () => void; + refresh: () => void; +} + +const getErrorMessage = () => { + return i18n.translate('console.ImpoerFlyout.importFileErrorMessage', { + defaultMessage: 'The file could not be processed due to error.', + }); +}; + +export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { + const [error, setError] = useState(); + const [status, setStatus] = useState('idle'); + const [loadingMessage, setLoadingMessage] = useState(); + const [file, setFile] = useState(); + const [jsonData, setJsonData] = useState(); + const [showOverwriteModal, setShowOverwriteModal] = useState(false); + const [importMode, setImportMode] = useState({ + overwrite: OVERWRITE_ALL_DEFAULT, + }); + + const { + services: { + objectStorageClient, + uiSettings, + notifications: { toasts }, + }, + } = useServicesContext(); + const { currentTextObject } = useEditorReadContext(); + + const dateFormat = uiSettings.get('dateFormat'); + + const setImportFile = (files: FileList | null) => { + if (!files || !files[0]) { + setFile(undefined); + return; + } + const fileContent = files[0]; + const reader = new FileReader(); + + reader.onload = (event) => { + const fileData = event.target?.result; + if (typeof fileData === 'string') { + const parsedData = JSON.parse(fileData); + setJsonData(parsedData); + } + }; + + reader.readAsText(fileContent); + setFile(fileContent); + setStatus('idle'); + }; + + const renderError = () => { + if (status !== 'error') { + return null; + } + + return ( + + + } + color="danger" + > +

{error}

+
+ +
+ ); + }; + + const renderBody = () => { + if (status === 'loading') { + return ( + + + + + +

{loadingMessage}

+
+
+
+ ); + } + + return ( + + + } + > + + } + onChange={setImportFile} + /> + + + setImportMode(newValues)} + /> + + + ); + }; + + const importFile = async (isOverwriteConfirmed?: boolean) => { + setStatus('loading'); + setError(undefined); + try { + if (jsonData && jsonData.text) { + if (importMode.overwrite) { + if (!isOverwriteConfirmed) { + setShowOverwriteModal(true); + return; + } else { + setLoadingMessage('Importing queries and overwriting existing ones...'); + const newObject = { + createdAt: Date.now(), + updatedAt: Date.now(), + text: jsonData.text, + }; + if (currentTextObject) { + await objectStorageClient.text.update({ + ...currentTextObject, + ...newObject, + }); + } else { + await objectStorageClient.text.create({ + ...newObject, + }); + } + } + toasts.addSuccess('Queries overwritten.'); + } else { + setLoadingMessage('Importing queries and merging with existing ones...'); + if (currentTextObject) { + await objectStorageClient.text.update({ + ...currentTextObject, + createdAt: Date.now(), + updatedAt: Date.now(), + text: currentTextObject.text.concat( + `\n#Imported on ${moment(Date.now()).format(dateFormat)}\n\n${jsonData.text}` + ), + }); + toasts.addSuccess('Queries merged.'); + } + } + } else { + setStatus('error'); + setError( + i18n.translate('console.ImpoerFlyout.importFileErrorMessage', { + defaultMessage: 'The selected file is not valid. Please select a valid JSON file.', + }) + ); + } + refresh(); + setLoadingMessage(undefined); + setStatus('idle'); + close(); + } catch (e) { + setStatus('error'); + setError(getErrorMessage(e)); + return; + } + }; + + const onConfirm = () => { + setShowOverwriteModal(false); + importFile(true); + }; + + const onSkip = () => { + setShowOverwriteModal(false); + setStatus('idle'); + }; + + const renderFooter = () => { + return ( + + + + + + + + importFile(false)} + size="s" + fill + isLoading={status === 'loading'} + > + + + + + ); + }; + + return ( + + + +

+ +

+
+
+ + + {renderError()} + {renderBody()} + + + {renderFooter()} + {showOverwriteModal && } +
+ ); +}; diff --git a/src/plugins/console/public/application/components/import_mode_control.tsx b/src/plugins/console/public/application/components/import_mode_control.tsx new file mode 100644 index 000000000000..48f37694bd8b --- /dev/null +++ b/src/plugins/console/public/application/components/import_mode_control.tsx @@ -0,0 +1,100 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Any modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useState } from 'react'; +import { EuiFormFieldset, EuiTitle, EuiRadioGroup } from '@elastic/eui'; +import { i18n } from '@osd/i18n'; + +export interface ImportModeControlProps { + initialValues: ImportMode; + isLegacyFile: boolean; + updateSelection: (result: ImportMode) => void; +} + +export interface ImportMode { + overwrite: boolean; +} + +const overwriteEnabled = { + id: 'overwriteEnabled', + label: i18n.translate('console.importModeControl.overwrite.enabledLabel', { + defaultMessage: 'Overwrite existing queries', + }), +}; +const overwriteDisabled = { + id: 'overwriteDisabled', + label: i18n.translate('console.importModeControl.overwrite.disabledLabel', { + defaultMessage: 'Merge with existing queries', + }), +}; +const importOptionsTitle = i18n.translate('console.importModeControl.importOptionsTitle', { + defaultMessage: 'Import options', +}); + +export const ImportModeControl = ({ + initialValues, + isLegacyFile, + updateSelection, +}: ImportModeControlProps) => { + const [overwrite, setOverwrite] = useState(initialValues.overwrite); + + const onChange = (partial: Partial) => { + if (partial.overwrite !== undefined) { + setOverwrite(partial.overwrite); + } + updateSelection({ overwrite, ...partial }); + }; + + const overwriteRadio = ( + onChange({ overwrite: id === overwriteEnabled.id })} + /> + ); + + if (isLegacyFile) { + return overwriteRadio; + } + + return ( + + {importOptionsTitle} + + ), + }} + > + {overwriteRadio} + + ); +}; diff --git a/src/plugins/console/public/application/components/index.ts b/src/plugins/console/public/application/components/index.ts index d6cceb7c7ca8..dca2bb72d211 100644 --- a/src/plugins/console/public/application/components/index.ts +++ b/src/plugins/console/public/application/components/index.ts @@ -36,3 +36,4 @@ export { WelcomePanel } from './welcome_panel'; export { AutocompleteOptions, DevToolsSettingsModal } from './settings_modal'; export { HelpPanel } from './help_panel'; export { EditorContentSpinner } from './editor_content_spinner'; +export { ImportFlyout } from './import_flyout'; diff --git a/src/plugins/console/public/application/components/overwrite_modal.tsx b/src/plugins/console/public/application/components/overwrite_modal.tsx new file mode 100644 index 000000000000..180a930034f0 --- /dev/null +++ b/src/plugins/console/public/application/components/overwrite_modal.tsx @@ -0,0 +1,66 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Any modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { i18n } from '@osd/i18n'; +import { EUI_MODAL_CONFIRM_BUTTON, EuiConfirmModal } from '@elastic/eui'; + +export interface OverwriteModalProps { + onSkip: () => void; + onConfirm: () => void; +} +export const OverwriteModal = ({ onSkip, onConfirm }: OverwriteModalProps) => { + return ( + +

+ {i18n.translate('console.overwriteModal.body.conflict', { + defaultMessage: + 'Are you sure you want to overwrite the existing queries? This action cannot be undone. All existing queries will be deleted and replaced with the imported queries. If you are unsure, please choose the "{option}" option instead', + values: { option: 'Merge with existing queries' }, + })} +

+
+ ); +}; diff --git a/src/plugins/console/public/application/containers/main/get_top_nav.ts b/src/plugins/console/public/application/containers/main/get_top_nav.ts index b1e3511c9b2f..cd21321993bb 100644 --- a/src/plugins/console/public/application/containers/main/get_top_nav.ts +++ b/src/plugins/console/public/application/containers/main/get_top_nav.ts @@ -35,6 +35,7 @@ interface Props { onClickSettings: () => void; onClickHelp: () => void; onClickExport: () => void; + onClickImport: () => void; } export function getTopNavConfig({ @@ -42,6 +43,7 @@ export function getTopNavConfig({ onClickSettings, onClickHelp, onClickExport, + onClickImport, }: Props) { return [ { @@ -96,5 +98,18 @@ export function getTopNavConfig({ }, testId: 'consoleExportButton', }, + { + id: 'import', + label: i18n.translate('console.topNav.importTabLabel', { + defaultMessage: 'Import', + }), + description: i18n.translate('console.topNav.importTabDescription', { + defaultMessage: 'Import', + }), + onClick: () => { + onClickImport(); + }, + testId: 'consoleImportButton', + }, ]; } diff --git a/src/plugins/console/public/application/containers/main/main.tsx b/src/plugins/console/public/application/containers/main/main.tsx index 154d81e08b48..bbe5bd9856eb 100644 --- a/src/plugins/console/public/application/containers/main/main.tsx +++ b/src/plugins/console/public/application/containers/main/main.tsx @@ -43,6 +43,7 @@ import { HelpPanel, SomethingWentWrongCallout, NetworkRequestStatusBar, + ImportFlyout, } from '../../components'; import { useServicesContext, useEditorReadContext, useRequestReadContext } from '../../contexts'; @@ -73,6 +74,7 @@ export function Main({ dataSourceId }: MainProps) { const [showingHistory, setShowHistory] = useState(false); const [showSettings, setShowSettings] = useState(false); const [showHelp, setShowHelp] = useState(false); + const [showImportFlyout, setShowImportFlyout] = useState(false); const onExport = async () => { const results = await objectStorageClient.text.findAll(); @@ -121,6 +123,7 @@ export function Main({ dataSourceId }: MainProps) { onClickSettings: () => setShowSettings(true), onClickHelp: () => setShowHelp(!showHelp), onClickExport: () => onExport(), + onClickImport: () => setShowImportFlyout(!showImportFlyout), })} /> @@ -162,6 +165,10 @@ export function Main({ dataSourceId }: MainProps) { ) : null} {showHelp ? setShowHelp(false)} /> : null} + + {showImportFlyout ? ( + setShowImportFlyout(false)} /> + ) : null} ); } diff --git a/src/plugins/console/public/application/contexts/services_context.tsx b/src/plugins/console/public/application/contexts/services_context.tsx index fc9ab157f783..0e8398ea8b83 100644 --- a/src/plugins/console/public/application/contexts/services_context.tsx +++ b/src/plugins/console/public/application/contexts/services_context.tsx @@ -29,7 +29,7 @@ */ import React, { createContext, useContext, useEffect } from 'react'; -import { HttpSetup, NotificationsSetup } from 'opensearch-dashboards/public'; +import { HttpSetup, IUiSettingsClient, NotificationsSetup } from 'opensearch-dashboards/public'; import { History, Settings, Storage } from '../../services'; import { ObjectStorageClient } from '../../../common/types'; import { MetricsTracker } from '../../types'; @@ -44,6 +44,7 @@ interface ContextServices { trackUiMetric: MetricsTracker; opensearchHostService: OpenSearchHostService; http: HttpSetup; + uiSettings: IUiSettingsClient; } export interface ContextValue { diff --git a/src/plugins/console/public/application/index.tsx b/src/plugins/console/public/application/index.tsx index c1a107ac500a..ac32909735b2 100644 --- a/src/plugins/console/public/application/index.tsx +++ b/src/plugins/console/public/application/index.tsx @@ -30,7 +30,7 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; -import { HttpSetup, NotificationsSetup } from 'src/core/public'; +import { HttpSetup, IUiSettingsClient, NotificationsSetup } from 'src/core/public'; import { ServicesContextProvider, EditorContextProvider, RequestContextProvider } from './contexts'; import { Main } from './containers'; import { createStorage, createHistory, createSettings } from '../services'; @@ -47,6 +47,7 @@ export interface BootDependencies { usageCollection?: UsageCollectionSetup; element: HTMLElement; dataSourceId?: string; + uiSettings: IUiSettingsClient; } export function renderApp({ @@ -57,6 +58,7 @@ export function renderApp({ element, http, dataSourceId, + uiSettings, }: BootDependencies) { const trackUiMetric = createUsageTracker(usageCollection); trackUiMetric.load('opened_app'); @@ -85,6 +87,7 @@ export function renderApp({ trackUiMetric, objectStorageClient, http, + uiSettings, }, }} > diff --git a/src/plugins/console/public/plugin.ts b/src/plugins/console/public/plugin.ts index 5e1478875ec6..300d57d4b75d 100644 --- a/src/plugins/console/public/plugin.ts +++ b/src/plugins/console/public/plugin.ts @@ -68,6 +68,7 @@ export class ConsoleUIPlugin implements Plugin Date: Mon, 10 Apr 2023 12:54:45 +0530 Subject: [PATCH 03/15] update: changelog. Signed-off-by: kishor82 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9998f316974c..1095899636ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -326,6 +326,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [VisBuilder] Add metric to metric, bucket to bucket aggregation persistence ([#3495](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3495)) - [VisBuilder] Add UI actions handler ([#3732](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3732)) - [VisBuilder] Add persistence to visualizations inner state ([#3751](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3751)) +- [Console] Add support for exporting and restoring commands in Dev Tools ([#3810](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3810)) ### 🐛 Bug Fixes From b329a00f5c223c4e20aba307cb98d53d571dcc81 Mon Sep 17 00:00:00 2001 From: kishor82 Date: Sat, 6 May 2023 03:07:00 +0530 Subject: [PATCH 04/15] feat: updated license headers for new file. Signed-off-by: kishor82 --- .../application/components/import_flyout.tsx | 29 ++----------------- .../components/import_mode_control.tsx | 27 +---------------- .../components/overwrite_modal.tsx | 27 +---------------- 3 files changed, 4 insertions(+), 79 deletions(-) diff --git a/src/plugins/console/public/application/components/import_flyout.tsx b/src/plugins/console/public/application/components/import_flyout.tsx index 4914f69cc811..775b808601c8 100644 --- a/src/plugins/console/public/application/components/import_flyout.tsx +++ b/src/plugins/console/public/application/components/import_flyout.tsx @@ -1,31 +1,6 @@ /* + * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Any modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. */ import { @@ -239,7 +214,7 @@ export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { close(); } catch (e) { setStatus('error'); - setError(getErrorMessage(e)); + setError(getErrorMessage()); return; } }; diff --git a/src/plugins/console/public/application/components/import_mode_control.tsx b/src/plugins/console/public/application/components/import_mode_control.tsx index 48f37694bd8b..34d3fe716416 100644 --- a/src/plugins/console/public/application/components/import_mode_control.tsx +++ b/src/plugins/console/public/application/components/import_mode_control.tsx @@ -1,31 +1,6 @@ /* + * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Any modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. */ import React, { useState } from 'react'; diff --git a/src/plugins/console/public/application/components/overwrite_modal.tsx b/src/plugins/console/public/application/components/overwrite_modal.tsx index 180a930034f0..5432a0fc86c2 100644 --- a/src/plugins/console/public/application/components/overwrite_modal.tsx +++ b/src/plugins/console/public/application/components/overwrite_modal.tsx @@ -1,31 +1,6 @@ /* + * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - * Any modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. */ import React from 'react'; From 38fe2261a7ca7ee3d8d6bf9ed7163edf812ac55d Mon Sep 17 00:00:00 2001 From: kishor82 Date: Thu, 18 May 2023 04:34:43 +0530 Subject: [PATCH 05/15] fix: typo:ImportFlyout and removed ImportModeControl prop (isLegacyFile) Signed-off-by: kishor82 --- .../public/application/components/import_flyout.tsx | 5 ++--- .../application/components/import_mode_control.tsx | 11 +---------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/plugins/console/public/application/components/import_flyout.tsx b/src/plugins/console/public/application/components/import_flyout.tsx index 775b808601c8..d3d686b6d6aa 100644 --- a/src/plugins/console/public/application/components/import_flyout.tsx +++ b/src/plugins/console/public/application/components/import_flyout.tsx @@ -38,7 +38,7 @@ interface ImportFlyoutProps { } const getErrorMessage = () => { - return i18n.translate('console.ImpoerFlyout.importFileErrorMessage', { + return i18n.translate('console.ImportFlyout.importFileErrorMessage', { defaultMessage: 'The file could not be processed due to error.', }); }; @@ -150,7 +150,6 @@ export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { setImportMode(newValues)} /> @@ -203,7 +202,7 @@ export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { } else { setStatus('error'); setError( - i18n.translate('console.ImpoerFlyout.importFileErrorMessage', { + i18n.translate('console.ImportFlyout.importFileErrorMessage', { defaultMessage: 'The selected file is not valid. Please select a valid JSON file.', }) ); diff --git a/src/plugins/console/public/application/components/import_mode_control.tsx b/src/plugins/console/public/application/components/import_mode_control.tsx index 34d3fe716416..0b543a9c593c 100644 --- a/src/plugins/console/public/application/components/import_mode_control.tsx +++ b/src/plugins/console/public/application/components/import_mode_control.tsx @@ -9,7 +9,6 @@ import { i18n } from '@osd/i18n'; export interface ImportModeControlProps { initialValues: ImportMode; - isLegacyFile: boolean; updateSelection: (result: ImportMode) => void; } @@ -33,11 +32,7 @@ const importOptionsTitle = i18n.translate('console.importModeControl.importOptio defaultMessage: 'Import options', }); -export const ImportModeControl = ({ - initialValues, - isLegacyFile, - updateSelection, -}: ImportModeControlProps) => { +export const ImportModeControl = ({ initialValues, updateSelection }: ImportModeControlProps) => { const [overwrite, setOverwrite] = useState(initialValues.overwrite); const onChange = (partial: Partial) => { @@ -55,10 +50,6 @@ export const ImportModeControl = ({ /> ); - if (isLegacyFile) { - return overwriteRadio; - } - return ( Date: Thu, 18 May 2023 04:36:13 +0530 Subject: [PATCH 06/15] fix: default query export Signed-off-by: kishor82 --- .../containers/editor/legacy/console_editor/editor.tsx | 2 +- .../public/application/hooks/use_data_init/use_data_init.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx index 1c47cc41e920..7d0d323edab5 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx @@ -68,7 +68,7 @@ const abs: CSSProperties = { right: '0', }; -const DEFAULT_INPUT_VALUE = `GET _search +export const DEFAULT_INPUT_VALUE = `GET _search { "query": { "match_all": {} diff --git a/src/plugins/console/public/application/hooks/use_data_init/use_data_init.ts b/src/plugins/console/public/application/hooks/use_data_init/use_data_init.ts index b9be1c56d912..e82584c8adda 100644 --- a/src/plugins/console/public/application/hooks/use_data_init/use_data_init.ts +++ b/src/plugins/console/public/application/hooks/use_data_init/use_data_init.ts @@ -31,6 +31,7 @@ import { useCallback, useEffect, useState } from 'react'; import { migrateToTextObjects } from './data_migration'; import { useEditorActionContext, useServicesContext } from '../../contexts'; +import { DEFAULT_INPUT_VALUE } from '../../containers/editor/legacy/console_editor/editor'; export const useDataInit = () => { const [error, setError] = useState(null); @@ -58,7 +59,7 @@ export const useDataInit = () => { const newObject = await objectStorageClient.text.create({ createdAt: Date.now(), updatedAt: Date.now(), - text: '', + text: DEFAULT_INPUT_VALUE, }); dispatch({ type: 'setCurrentTextObject', payload: newObject }); } else { From 1994c8670c50ddbc57e8e4d1c56d0227b2c01056 Mon Sep 17 00:00:00 2001 From: kishor82 Date: Sat, 20 May 2023 05:10:32 +0530 Subject: [PATCH 07/15] fix: added basic text validation for imported file. Signed-off-by: kishor82 --- .../public/application/components/import_flyout.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/console/public/application/components/import_flyout.tsx b/src/plugins/console/public/application/components/import_flyout.tsx index d3d686b6d6aa..373adf63aa3d 100644 --- a/src/plugins/console/public/application/components/import_flyout.tsx +++ b/src/plugins/console/public/application/components/import_flyout.tsx @@ -199,6 +199,10 @@ export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { toasts.addSuccess('Queries merged.'); } } + refresh(); + setLoadingMessage(undefined); + setStatus('idle'); + close(); } else { setStatus('error'); setError( @@ -206,11 +210,8 @@ export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { defaultMessage: 'The selected file is not valid. Please select a valid JSON file.', }) ); + return; } - refresh(); - setLoadingMessage(undefined); - setStatus('idle'); - close(); } catch (e) { setStatus('error'); setError(getErrorMessage()); From cecaf679de64f8895b03a4340e7f507933041316 Mon Sep 17 00:00:00 2001 From: kishor82 Date: Fri, 30 Jun 2023 15:25:02 +0530 Subject: [PATCH 08/15] update: removed legacy variable export. Signed-off-by: kishor82 --- .../application/components/import_flyout.tsx | 29 +++++++++++-------- .../editor/legacy/console_editor/editor.tsx | 2 +- .../hooks/use_data_init/use_data_init.ts | 8 ++++- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/plugins/console/public/application/components/import_flyout.tsx b/src/plugins/console/public/application/components/import_flyout.tsx index 373adf63aa3d..fef6e5da267c 100644 --- a/src/plugins/console/public/application/components/import_flyout.tsx +++ b/src/plugins/console/public/application/components/import_flyout.tsx @@ -26,7 +26,7 @@ import { i18n } from '@osd/i18n'; import { FormattedMessage } from '@osd/i18n/react'; import React, { Fragment, useState } from 'react'; import { ImportMode, ImportModeControl } from './import_mode_control'; -import { useEditorReadContext, useServicesContext } from '../contexts'; +import { useServicesContext } from '../contexts'; import { TextObject } from '../../../common/text_object'; import { OverwriteModal } from './overwrite_modal'; @@ -37,9 +37,14 @@ interface ImportFlyoutProps { refresh: () => void; } -const getErrorMessage = () => { +const getErrorMessage = (e: any) => { + const errorMessage = + e.body?.error && e.body?.message ? `${e.body.error}: ${e.body.message}` : e.message; return i18n.translate('console.ImportFlyout.importFileErrorMessage', { - defaultMessage: 'The file could not be processed due to error.', + defaultMessage: 'The file could not be processed due to error: "{error}"', + values: { + error: errorMessage, + }, }); }; @@ -61,7 +66,6 @@ export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { notifications: { toasts }, }, } = useServicesContext(); - const { currentTextObject } = useEditorReadContext(); const dateFormat = uiSettings.get('dateFormat'); @@ -161,6 +165,8 @@ export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { setStatus('loading'); setError(undefined); try { + const results = await objectStorageClient.text.findAll(); + const currentText = results.sort((a, b) => a.createdAt - b.createdAt)[0]; if (jsonData && jsonData.text) { if (importMode.overwrite) { if (!isOverwriteConfirmed) { @@ -173,9 +179,9 @@ export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { updatedAt: Date.now(), text: jsonData.text, }; - if (currentTextObject) { + if (results.length) { await objectStorageClient.text.update({ - ...currentTextObject, + ...currentText, ...newObject, }); } else { @@ -187,13 +193,13 @@ export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { toasts.addSuccess('Queries overwritten.'); } else { setLoadingMessage('Importing queries and merging with existing ones...'); - if (currentTextObject) { + if (results.length) { await objectStorageClient.text.update({ - ...currentTextObject, + ...currentText, createdAt: Date.now(), updatedAt: Date.now(), - text: currentTextObject.text.concat( - `\n#Imported on ${moment(Date.now()).format(dateFormat)}\n\n${jsonData.text}` + text: currentText.text.concat( + `\n\n#Imported on ${moment(Date.now()).format(dateFormat)}\n\n${jsonData.text}` ), }); toasts.addSuccess('Queries merged.'); @@ -214,8 +220,7 @@ export const ImportFlyout = ({ close, refresh }: ImportFlyoutProps) => { } } catch (e) { setStatus('error'); - setError(getErrorMessage()); - return; + setError(getErrorMessage(e)); } }; diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx index 7d0d323edab5..1c47cc41e920 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx @@ -68,7 +68,7 @@ const abs: CSSProperties = { right: '0', }; -export const DEFAULT_INPUT_VALUE = `GET _search +const DEFAULT_INPUT_VALUE = `GET _search { "query": { "match_all": {} diff --git a/src/plugins/console/public/application/hooks/use_data_init/use_data_init.ts b/src/plugins/console/public/application/hooks/use_data_init/use_data_init.ts index e82584c8adda..9c6ee873806e 100644 --- a/src/plugins/console/public/application/hooks/use_data_init/use_data_init.ts +++ b/src/plugins/console/public/application/hooks/use_data_init/use_data_init.ts @@ -31,7 +31,13 @@ import { useCallback, useEffect, useState } from 'react'; import { migrateToTextObjects } from './data_migration'; import { useEditorActionContext, useServicesContext } from '../../contexts'; -import { DEFAULT_INPUT_VALUE } from '../../containers/editor/legacy/console_editor/editor'; + +const DEFAULT_INPUT_VALUE = `GET _search +{ + "query": { + "match_all": {} + } +}`; export const useDataInit = () => { const [error, setError] = useState(null); From 9b4bc14aa43c624d48e8ac18fdfa8a9471d7aaf0 Mon Sep 17 00:00:00 2001 From: kishor82 Date: Tue, 1 Aug 2023 23:57:01 +0530 Subject: [PATCH 09/15] test: Add unit tests for OverwriteModal component Signed-off-by: kishor82 --- .../overwrite_modal.test.tsx.snap | 18 +++++ .../components/overwrite_modal.test.tsx | 71 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/plugins/console/public/application/components/__snapshots__/overwrite_modal.test.tsx.snap create mode 100644 src/plugins/console/public/application/components/overwrite_modal.test.tsx diff --git a/src/plugins/console/public/application/components/__snapshots__/overwrite_modal.test.tsx.snap b/src/plugins/console/public/application/components/__snapshots__/overwrite_modal.test.tsx.snap new file mode 100644 index 000000000000..27228e29674e --- /dev/null +++ b/src/plugins/console/public/application/components/__snapshots__/overwrite_modal.test.tsx.snap @@ -0,0 +1,18 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`OverwriteModal Component should render correclty 1`] = ` + +

+ Are you sure you want to overwrite the existing queries? This action cannot be undone. All existing queries will be deleted and replaced with the imported queries. If you are unsure, please choose the "Merge with existing queries" option instead +

+
+`; diff --git a/src/plugins/console/public/application/components/overwrite_modal.test.tsx b/src/plugins/console/public/application/components/overwrite_modal.test.tsx new file mode 100644 index 000000000000..94c66bda2fbd --- /dev/null +++ b/src/plugins/console/public/application/components/overwrite_modal.test.tsx @@ -0,0 +1,71 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { shallowWithIntl } from 'test_utils/enzyme_helpers'; +import { OverwriteModal } from './overwrite_modal'; +import { act } from '@testing-library/react-hooks'; +import { ShallowWrapper } from 'enzyme'; + +const confirmModalIdentifier = 'EuiConfirmModal'; + +describe('OverwriteModal Component', () => { + let component: ShallowWrapper, React.Component<{}, {}, any>>; + const mockOnConfirm = jest.fn(); + const mockOnSkip = jest.fn(); + + beforeEach(async () => { + jest.clearAllMocks(); + await act(async () => { + component = await shallowWithIntl( + + ); + }); + component.update(); + }); + + it('should render correclty', () => { + expect(component).toMatchSnapshot(); + }); + + it('should call onConfirm when clicking the "Overwrite" button', async () => { + await act(async () => { + // @ts-ignore + await component.find(confirmModalIdentifier).first().props().onConfirm(); + }); + + component.update(); + + // Expect that the onConfirm function has been called + expect(mockOnConfirm).toHaveBeenCalled(); + }); + + it('should call onSkip when clicking the "Skip" button', async () => { + await act(async () => { + // @ts-ignore + await component.find(confirmModalIdentifier).first().props().onCancel(); + }); + + component.update(); + + // Expect that the onSkip function has been called + expect(mockOnSkip).toHaveBeenCalled(); + }); + + it('should display the correct title and body text', () => { + // Find the title and body text elements + const componentProps = component.find(confirmModalIdentifier).first().props(); + // Find the

element inside the component + const paragraphElement = component.find('p'); + + // Expect the correct translations for title and body text + expect(componentProps.title).toBe('Confirm Overwrite'); + + // Check the text content of the

element + const expectedText = + 'Are you sure you want to overwrite the existing queries? This action cannot be undone. All existing queries will be deleted and replaced with the imported queries. If you are unsure, please choose the "Merge with existing queries" option instead'; + expect(paragraphElement.text()).toEqual(expectedText); + }); +}); From 7079533baaeead0f169128571c349d081dcd7121 Mon Sep 17 00:00:00 2001 From: kishor82 Date: Wed, 2 Aug 2023 01:06:35 +0530 Subject: [PATCH 10/15] test: Add unit tests for ImportModeControl component Signed-off-by: kishor82 --- .../import_mode_control.test.tsx.snap | 34 +++++++++ .../components/import_mode_control.test.tsx | 74 +++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 src/plugins/console/public/application/components/__snapshots__/import_mode_control.test.tsx.snap create mode 100644 src/plugins/console/public/application/components/import_mode_control.test.tsx diff --git a/src/plugins/console/public/application/components/__snapshots__/import_mode_control.test.tsx.snap b/src/plugins/console/public/application/components/__snapshots__/import_mode_control.test.tsx.snap new file mode 100644 index 000000000000..343c6b351229 --- /dev/null +++ b/src/plugins/console/public/application/components/__snapshots__/import_mode_control.test.tsx.snap @@ -0,0 +1,34 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ImportModeControl Component should render correclty 1`] = ` + + + Import options + + , + } + } +> + + +`; diff --git a/src/plugins/console/public/application/components/import_mode_control.test.tsx b/src/plugins/console/public/application/components/import_mode_control.test.tsx new file mode 100644 index 000000000000..f0b09fb10b46 --- /dev/null +++ b/src/plugins/console/public/application/components/import_mode_control.test.tsx @@ -0,0 +1,74 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { act } from '@testing-library/react-hooks'; +import { ShallowWrapper, shallow } from 'enzyme'; +import { shallowWithIntl } from 'test_utils/enzyme_helpers'; +import { ImportModeControl } from './import_mode_control'; +import { EuiFormLegendProps, EuiRadioGroupProps } from '@elastic/eui'; +import { ReactElement } from 'react'; + +const radioGroupIdentifier = 'EuiRadioGroup'; + +describe('ImportModeControl Component', () => { + let component: ShallowWrapper, React.Component<{}, {}, any>>; + const mockUpdateSelection = jest.fn(); + + beforeEach(async () => { + jest.clearAllMocks(); + await act(async () => { + component = await shallowWithIntl( + + ); + }); + component.update(); + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render correclty', () => { + expect(component).toMatchSnapshot(); + }); + + it('should render the correct title in the fieldset legend', () => { + const legendText = 'Import options'; + const legend: EuiFormLegendProps = component.find('EuiFormFieldset').prop('legend'); + const legendTitle = shallow(legend?.children as ReactElement); + + expect(legendTitle.text()).toBe(legendText); + }); + + it('should display the correct labels for radio options', () => { + const componentProps = (component + .find(radioGroupIdentifier) + .props() as unknown) as EuiRadioGroupProps; + + // Check if the labels for radio options are displayed correctly + const radioOptions = componentProps.options; + expect(radioOptions[0].label).toBe('Merge with existing queries'); + expect(radioOptions[1].label).toBe('Overwrite existing queries'); + + // Check the initial selection (overwrite is false, so Merge with existing queries should be selected) + const selectedOptionId = component.find(radioGroupIdentifier).prop('idSelected'); + expect(selectedOptionId).toBe('overwriteDisabled'); + }); + + it('should call updateSelection when the selection is changed', async () => { + await act(async () => { + // @ts-ignore + await component.find(radioGroupIdentifier).first().props().onChange('overwriteEnabled'); + }); + component.update(); + + // Expect that the updateSelection function has been called with the correct parameters + expect(mockUpdateSelection).toHaveBeenCalledWith({ overwrite: true }); + }); +}); From 301f16a460f823d699cfc7bbb0f9f4d415b0e9fe Mon Sep 17 00:00:00 2001 From: kishor82 Date: Wed, 2 Aug 2023 02:14:36 +0530 Subject: [PATCH 11/15] test: Add unit tests for ImportFlyout component Signed-off-by: kishor82 --- .../__snapshots__/import_flyout.test.tsx.snap | 482 ++++++++++++++++++ .../components/import_flyout.test.tsx | 41 ++ .../contexts/services_context.mock.ts | 4 +- 3 files changed, 526 insertions(+), 1 deletion(-) create mode 100644 src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap create mode 100644 src/plugins/console/public/application/components/import_flyout.test.tsx diff --git a/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap b/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap new file mode 100644 index 000000000000..0d84582cb9fb --- /dev/null +++ b/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap @@ -0,0 +1,482 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ImportFlyout Component renders correctly 1`] = ` + + + +

+ + +
+ + +
+ + + + + +
+
+ + + + + + +
+ +`; diff --git a/src/plugins/console/public/application/components/import_flyout.test.tsx b/src/plugins/console/public/application/components/import_flyout.test.tsx new file mode 100644 index 000000000000..aef44c1a8464 --- /dev/null +++ b/src/plugins/console/public/application/components/import_flyout.test.tsx @@ -0,0 +1,41 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { act } from 'react-dom/test-utils'; +import { ImportFlyout } from './import_flyout'; +import { ContextValue, ServicesContextProvider } from '../contexts'; +import { serviceContextMock } from '../contexts/services_context.mock'; +import { wrapWithIntl } from 'test_utils/enzyme_helpers'; +import { ReactWrapper, mount } from 'enzyme'; + +describe('ImportFlyout Component', () => { + let mockedAppContextValue: ContextValue; + const mockClose = jest.fn(); + const mockRefresh = jest.fn(); + let component: ReactWrapper, React.Component<{}, {}, any>>; + + beforeEach(async () => { + jest.clearAllMocks(); + + await act(async () => { + mockedAppContextValue = serviceContextMock.create(); + component = await mount( + wrapWithIntl(), + { + wrappingComponent: ServicesContextProvider, + wrappingComponentProps: { + value: mockedAppContextValue, + }, + } + ); + }); + component.update(); + }); + + it('renders correctly', () => { + expect(component).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/console/public/application/contexts/services_context.mock.ts b/src/plugins/console/public/application/contexts/services_context.mock.ts index 5e39565aca8a..5a3de45568de 100644 --- a/src/plugins/console/public/application/contexts/services_context.mock.ts +++ b/src/plugins/console/public/application/contexts/services_context.mock.ts @@ -28,7 +28,7 @@ * under the License. */ -import { notificationServiceMock } from '../../../../../core/public/mocks'; +import { notificationServiceMock, uiSettingsServiceMock } from '../../../../../core/public/mocks'; import { httpServiceMock } from '../../../../../core/public/mocks'; import { HistoryMock } from '../../services/history.mock'; @@ -53,7 +53,9 @@ export const serviceContextMock = { settings: new SettingsMock(storage), history: new HistoryMock(storage), notifications: notificationServiceMock.createSetupContract(), + uiSettings: uiSettingsServiceMock.createSetupContract(), objectStorageClient: {} as any, + http, }, docLinkVersion: 'NA', }; From 9274d87c02f40e37353e7d40c4d329b71caadeac Mon Sep 17 00:00:00 2001 From: kishor82 Date: Sat, 5 Aug 2023 02:04:32 +0530 Subject: [PATCH 12/15] test: updated unit tests for ImportFlyout component Signed-off-by: kishor82 --- .../__snapshots__/import_flyout.test.tsx.snap | 9 +- .../components/import_flyout.test.tsx | 178 +++++++++++++++++- .../application/components/import_flyout.tsx | 13 +- .../contexts/services_context.mock.ts | 7 +- 4 files changed, 190 insertions(+), 17 deletions(-) diff --git a/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap b/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap index 0d84582cb9fb..bac6be2733fd 100644 --- a/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap +++ b/src/plugins/console/public/application/components/__snapshots__/import_flyout.test.tsx.snap @@ -111,6 +111,7 @@ exports[`ImportFlyout Component renders correctly 1`] = ` } + name="queryFileImport" onBlur={[Function]} onChange={[Function]} onFocus={[Function]} @@ -150,7 +152,9 @@ exports[`ImportFlyout Component renders correctly 1`] = ` accept=".ndjson, .json" aria-describedby="generated-id-filePicker__prompt" className="euiFilePicker__input" + data-test-subj="queryFilePicker" id="generated-id" + name="queryFileImport" onBlur={[Function]} onChange={[Function]} onDragLeave={[Function]} @@ -410,14 +414,16 @@ exports[`ImportFlyout Component renders correctly 1`] = ` className="euiFlexItem euiFlexItem--flexGrowZero" >