From e9b1124efceb4e5e67d17bf0ca5cbb5925d454b0 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Tue, 24 Sep 2024 16:59:02 +0200 Subject: [PATCH 1/9] Fix linter issues --- .../application/components/help_popover.tsx | 193 +++++++++--------- .../containers/history/history.tsx | 4 +- 2 files changed, 98 insertions(+), 99 deletions(-) diff --git a/src/plugins/console/public/application/components/help_popover.tsx b/src/plugins/console/public/application/components/help_popover.tsx index 16e9465d4d388..614a132b770e6 100644 --- a/src/plugins/console/public/application/components/help_popover.tsx +++ b/src/plugins/console/public/application/components/help_popover.tsx @@ -7,17 +7,10 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import React from 'react'; +import React, { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { - EuiPopover, - EuiTitle, - EuiText, - EuiFlexGroup, - EuiFlexItem, - EuiButtonIcon, - EuiSpacer, -} from '@elastic/eui'; +import { EuiPopover, EuiTitle, EuiText, EuiPanel, EuiSpacer, EuiListGroup } from '@elastic/eui'; +import { css } from '@emotion/react'; import { useServicesContext } from '../contexts'; interface HelpPopoverProps { @@ -27,9 +20,81 @@ interface HelpPopoverProps { resetTour: () => void; } +const styles = { + // Hide the external svg icon for the link given that we have a custom icon for it. + // Also remove the the hover effect on the action icon since it's a bit distracting. + listItem: css` + .euiListGroupItem__button { + > svg { + display: none; + } + } + + .euiButtonIcon:hover { + background: transparent; + } + `, +}; + export const HelpPopover = ({ button, isOpen, closePopover, resetTour }: HelpPopoverProps) => { const { docLinks } = useServicesContext(); + const listItems = useMemo( + () => [ + { + label: i18n.translate('console.helpPopover.aboutConsoleLabel', { + defaultMessage: 'About Console', + }), + href: docLinks.console.guide, + target: '_blank', + css: styles.listItem, + extraAction: { + iconType: 'popout', + href: docLinks.console.guide, + target: '_blank', + alwaysShow: true, + 'aria-label': i18n.translate('console.helpPopover.aboutConsoleButtonAriaLabel', { + defaultMessage: 'About Console link', + }), + }, + }, + { + label: i18n.translate('console.helpPopover.aboutQueryDSLLabel', { + defaultMessage: 'About Query DSL', + }), + href: docLinks.query.queryDsl, + target: '_blank', + css: styles.listItem, + extraAction: { + iconType: 'popout', + href: docLinks.query.queryDsl, + target: '_blank', + alwaysShow: true, + 'aria-label': i18n.translate('console.helpPopover.aboutQueryDSLButtonAriaLabel', { + defaultMessage: 'About QueryDSL link', + }), + }, + }, + { + label: i18n.translate('console.helpPopover.rerunTourLabel', { + defaultMessage: 'Re-run feature tour', + }), + css: styles.listItem, + onClick: resetTour, + extraAction: { + iconType: 'refresh', + alwaysShow: true, + onClick: resetTour, + 'data-test-subj': 'consoleRerunTourButton', + 'aria-label': i18n.translate('console.helpPopover.rerunTourButtonAriaLabel', { + defaultMessage: 'Re-run feature tour button', + }), + }, + }, + ], + [docLinks, resetTour] + ); + return ( - -

- {i18n.translate('console.helpPopover.title', { - defaultMessage: 'Elastic Console', - })} -

-
- - - - -

- {i18n.translate('console.helpPopover.description', { - defaultMessage: - 'Console is an interactive UI for calling Elasticsearch and Kibana APIs and viewing their responses. Search your data, manage settings, and more, using Query DSL and REST API syntax.', - })} -

-
- - + + +

+ {i18n.translate('console.helpPopover.title', { + defaultMessage: 'Elastic Console', + })} +

+
- - - - -

- {i18n.translate('console.helpPopover.aboutConsoleLabel', { - defaultMessage: 'About Console', - })} -

-
- - - -
-
+ - - - -

- {i18n.translate('console.helpPopover.aboutQueryDSLLabel', { - defaultMessage: 'About Query DSL', - })} -

-
- - - -
-
+ +

+ {i18n.translate('console.helpPopover.description', { + defaultMessage: + 'Console is an interactive UI for calling Elasticsearch and Kibana APIs and viewing their responses. Search your data, manage settings, and more, using Query DSL and REST API syntax.', + })} +

+
+
- - - -

- {i18n.translate('console.helpPopover.rerunTourLabel', { - defaultMessage: 'Re-run feature tour', - })} -

-
- - - -
-
- +
); }; diff --git a/src/plugins/console/public/application/containers/history/history.tsx b/src/plugins/console/public/application/containers/history/history.tsx index 93777a364356e..c9488a48aca48 100644 --- a/src/plugins/console/public/application/containers/history/history.tsx +++ b/src/plugins/console/public/application/containers/history/history.tsx @@ -65,7 +65,9 @@ const CheckeableCardLabel = ({ historyItem }: { historyItem: HistoryProps }) => - {historyItem.endpoint} + + {historyItem.method} - {historyItem.endpoint} + From 10a93a186b65a44dbc09fc6d065c3dee7eb01448 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Tue, 24 Sep 2024 17:03:11 +0200 Subject: [PATCH 2/9] commit with @elastic email From 35592d6511a96b9fbcaf225f602563fe92c48b9d Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Wed, 25 Sep 2024 09:21:16 +0200 Subject: [PATCH 3/9] Remove string mask --- .../console/public/application/containers/history/history.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/console/public/application/containers/history/history.tsx b/src/plugins/console/public/application/containers/history/history.tsx index e5f871163fae0..384503e5df084 100644 --- a/src/plugins/console/public/application/containers/history/history.tsx +++ b/src/plugins/console/public/application/containers/history/history.tsx @@ -67,7 +67,7 @@ const CheckeableCardLabel = ({ historyItem }: { historyItem: HistoryProps }) => - {historyItem.method} - {historyItem.endpoint} + {historyItem.method} {historyItem.endpoint} From 9f3965f7114ddd950b315d43c3dbbcf34b225cab Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Wed, 25 Sep 2024 10:15:06 +0200 Subject: [PATCH 4/9] Clear decorations when editor loses focus and when its initialized --- .../monaco_editor_output_actions_provider.ts | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts b/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts index fe20af6a1bcb4..38adbfc738b6f 100644 --- a/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts +++ b/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts @@ -30,30 +30,47 @@ export class MonacoEditorOutputActionsProvider { private setEditorActionsCss: (css: CSSProperties) => void ) { this.highlightedLines = this.editor.createDecorationsCollection(); - this.editor.focus(); const debouncedHighlightRequests = debounce( - () => this.highlightRequests(), + async () => { + if (editor.hasTextFocus()) { + await this.highlightRequests(); + } else { + this.clearEditorDecorations(); + } + }, DEBOUNCE_HIGHLIGHT_WAIT_MS, { leading: true, } ); - debouncedHighlightRequests(); // init all listeners - editor.onDidChangeCursorPosition(async (event) => { + editor.onDidChangeCursorPosition(async () => { await debouncedHighlightRequests(); }); - editor.onDidScrollChange(async (event) => { + editor.onDidScrollChange(async () => { await debouncedHighlightRequests(); }); - editor.onDidChangeCursorSelection(async (event) => { + editor.onDidChangeCursorSelection(async () => { await debouncedHighlightRequests(); }); - editor.onDidContentSizeChange(async (event) => { + editor.onDidContentSizeChange(async () => { await debouncedHighlightRequests(); }); + + editor.onDidBlurEditorText(() => + this.clearEditorDecorations() + ); + } + + private clearEditorDecorations() { + // remove the highlighted lines + this.highlightedLines.clear(); + // hide action buttons + this.setEditorActionsCss({ + visibility: 'hidden', + }); } private updateEditorActions(lineNumber?: number) { From f63fefcaaf32278bc1eb81c0005438669ba7b2a9 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Wed, 25 Sep 2024 10:19:48 +0200 Subject: [PATCH 5/9] Fix linter issue --- .../editor/monaco_editor_output_actions_provider.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts b/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts index 38adbfc738b6f..6ed988217cd1e 100644 --- a/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts +++ b/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts @@ -59,9 +59,7 @@ export class MonacoEditorOutputActionsProvider { await debouncedHighlightRequests(); }); - editor.onDidBlurEditorText(() => - this.clearEditorDecorations() - ); + editor.onDidBlurEditorText(() => this.clearEditorDecorations()); } private clearEditorDecorations() { From c8e3f99cfeee0d696a07975c81c0286eb94c7ded Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Wed, 25 Sep 2024 11:23:18 +0200 Subject: [PATCH 6/9] Dont initially highlight requests as the editor doesnt have focus --- .../editor/monaco_editor_actions_provider.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts b/src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts index 8c66d31b2b57e..0a37d258e9f47 100644 --- a/src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts +++ b/src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts @@ -66,13 +66,18 @@ export class MonacoEditorActionsProvider { this.highlightedLines = this.editor.createDecorationsCollection(); const debouncedHighlightRequests = debounce( - () => this.highlightRequests(), + async () => { + if (editor.hasTextFocus()) { + await this.highlightRequests(); + } else { + this.clearEditorDecorations(); + } + }, DEBOUNCE_HIGHLIGHT_WAIT_MS, { leading: true, } ); - debouncedHighlightRequests(); const debouncedTriggerSuggestions = debounce( () => { @@ -110,6 +115,15 @@ export class MonacoEditorActionsProvider { }); } + private clearEditorDecorations() { + // remove the highlighted lines + this.highlightedLines.clear(); + // hide action buttons + this.setEditorActionsCss({ + visibility: 'hidden', + }); + } + private updateEditorActions(lineNumber?: number) { // if no request is currently selected, hide the actions buttons if (!lineNumber) { From c5145b3678f28454fa43715dccdc5782dc8fa562 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Wed, 25 Sep 2024 13:13:06 +0200 Subject: [PATCH 7/9] Fix fn test --- test/functional/apps/console/_text_input.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/apps/console/_text_input.ts b/test/functional/apps/console/_text_input.ts index 640a31bd19edf..31c832990042b 100644 --- a/test/functional/apps/console/_text_input.ts +++ b/test/functional/apps/console/_text_input.ts @@ -84,7 +84,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.try(async () => { const history = await PageObjects.console.getHistoryEntries(); - expect(history).to.eql(['/_search?pretty\na few seconds ago']); + expect(history).to.eql(['GET /_search?pretty\na few seconds ago']); }); await PageObjects.console.clickClearHistory(); From 9e295c3e885a0e2bd779a92b0533f63d2f332f61 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Thu, 26 Sep 2024 09:25:34 +0200 Subject: [PATCH 8/9] Fix small bug with copy output menu --- .../editor/monaco_editor_output_actions_provider.ts | 9 ++++++++- test/functional/apps/console/_output_panel.ts | 1 + test/functional/page_objects/console_page.ts | 7 +++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts b/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts index 6ed988217cd1e..bd9d0c9e73490 100644 --- a/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts +++ b/src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts @@ -59,7 +59,14 @@ export class MonacoEditorOutputActionsProvider { await debouncedHighlightRequests(); }); - editor.onDidBlurEditorText(() => this.clearEditorDecorations()); + editor.onDidBlurEditorText(() => { + // Since the actions buttons are placed outside of the editor, we need to delay + // the clearing of the editor decorations to ensure that the actions buttons + // are not hidden. + setTimeout(() => { + this.clearEditorDecorations(); + }, 100); + }); } private clearEditorDecorations() { diff --git a/test/functional/apps/console/_output_panel.ts b/test/functional/apps/console/_output_panel.ts index 49c41ae7a6ccc..1da032328493b 100644 --- a/test/functional/apps/console/_output_panel.ts +++ b/test/functional/apps/console/_output_panel.ts @@ -47,6 +47,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should be able to copy the response of a request', async () => { await sendRequest('GET /_search?pretty'); + await PageObjects.console.focusOutputEditor(); await PageObjects.console.clickCopyOutput(); const resultToast = await toasts.getElementByIndex(1); diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts index 080167c995ccb..29b88787e7ec2 100644 --- a/test/functional/page_objects/console_page.ts +++ b/test/functional/page_objects/console_page.ts @@ -51,6 +51,13 @@ export class ConsolePageObject extends FtrService { await textArea.clearValueWithKeyboard(); } + public async focusOutputEditor() { + const outputEditor = await this.testSubjects.find('consoleMonacoOutput'); + // Simply clicking on the output editor doesn't focus it, so we need to click + // on the margin view overlays + await (await outputEditor.findByClassName('margin-view-overlays')).click(); + } + public async getOutputText() { const outputPanel = await this.testSubjects.find('consoleMonacoOutput'); const outputViewDiv = await outputPanel.findByClassName('monaco-scrollable-element'); From 1e228b09b1bbf944d038e451f2e9859799c08aa0 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Fri, 27 Sep 2024 09:41:11 +0200 Subject: [PATCH 9/9] Autofocus editor when mounted --- .../containers/editor/monaco_editor_actions_provider.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts b/src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts index 0a37d258e9f47..8fe6a33332379 100644 --- a/src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts +++ b/src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts @@ -62,6 +62,7 @@ export class MonacoEditorActionsProvider { private setEditorActionsCss: (css: CSSProperties) => void, private isDevMode: boolean ) { + this.editor.focus(); this.parsedRequestsProvider = getParsedRequestsProvider(this.editor.getModel()); this.highlightedLines = this.editor.createDecorationsCollection();