diff --git a/packages/kbn-text-based-editor/src/editor_footer.tsx b/packages/kbn-text-based-editor/src/editor_footer.tsx
index d31f731821bb3..6bc663713a8d0 100644
--- a/packages/kbn-text-based-editor/src/editor_footer.tsx
+++ b/packages/kbn-text-based-editor/src/editor_footer.tsx
@@ -21,6 +21,7 @@ import {
EuiDescriptionListDescription,
EuiButton,
useEuiTheme,
+ EuiLink,
} from '@elastic/eui';
import { Interpolation, Theme, css } from '@emotion/react';
import { css as classNameCss } from '@emotion/css';
@@ -29,6 +30,7 @@ import type { MonacoError } from './helpers';
const isMac = navigator.platform.toLowerCase().indexOf('mac') >= 0;
const COMMAND_KEY = isMac ? '⌘' : '^';
+const FEEDBACK_LINK = 'https://ela.st/esql-feedback';
const getConstsByType = (type: 'error' | 'warning', count: number) => {
if (type === 'error') {
@@ -56,6 +58,37 @@ const getConstsByType = (type: 'error' | 'warning', count: number) => {
}
};
+export function SubmitFeedbackComponent({ isSpaceReduced }: { isSpaceReduced?: boolean }) {
+ const { euiTheme } = useEuiTheme();
+ return (
+ <>
+
+
+
+
+
+ {isSpaceReduced
+ ? i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.feedback', {
+ defaultMessage: 'Feedback',
+ })
+ : i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.submitFeedback', {
+ defaultMessage: 'Submit feedback',
+ })}
+
+
+ >
+ );
+}
+
export function ErrorsWarningsPopover({
isPopoverOpen,
items,
@@ -198,31 +231,34 @@ export const EditorFooter = memo(function EditorFooter({
-
-
-
-
-
- {isSpaceReduced
- ? '@timestamp'
- : detectTimestamp
- ? i18n.translate(
- 'textBasedEditor.query.textBasedLanguagesEditor.timestampDetected',
- {
- defaultMessage: '@timestamp found',
- }
- )
- : i18n.translate(
- 'textBasedEditor.query.textBasedLanguagesEditor.timestampNotDetected',
- {
- defaultMessage: '@timestamp not found',
- }
- )}
-
-
-
-
-
+ {/* If there is no space and no @timestamp detected hide the information */}
+ {(detectTimestamp || !isSpaceReduced) && (
+
+
+
+
+
+ {isSpaceReduced
+ ? '@timestamp'
+ : detectTimestamp
+ ? i18n.translate(
+ 'textBasedEditor.query.textBasedLanguagesEditor.timestampDetected',
+ {
+ defaultMessage: '@timestamp found',
+ }
+ )
+ : i18n.translate(
+ 'textBasedEditor.query.textBasedLanguagesEditor.timestampNotDetected',
+ {
+ defaultMessage: '@timestamp not found',
+ }
+ )}
+
+
+
+
+
+ )}
{errors && errors.length > 0 && (
+
@@ -269,51 +306,61 @@ export const EditorFooter = memo(function EditorFooter({
)}
{Boolean(editorIsInline) && (
-
-
-
-
- {isSpaceReduced
- ? i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.run', {
- defaultMessage: 'Run',
- })
- : i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.runQuery', {
- defaultMessage: 'Run query',
- })}
-
+ <>
+
+
+
-
- {COMMAND_KEY}⏎
-
+
+
+ {isSpaceReduced
+ ? i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.run', {
+ defaultMessage: 'Run',
+ })
+ : i18n.translate(
+ 'textBasedEditor.query.textBasedLanguagesEditor.runQuery',
+ {
+ defaultMessage: 'Run query',
+ }
+ )}
+
+
+
+ {COMMAND_KEY}⏎
+
+
+
+
-
-
+
+ >
)}
);
diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx
index 173c023f8b619..0f9ed5c6cb9c5 100644
--- a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx
+++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx
@@ -69,19 +69,15 @@ describe('TextBasedLanguagesEditor', () => {
};
});
it('should render the editor component', async () => {
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...props }));
- expect(component.find('[data-test-subj="TextBasedLangEditor"]').length).not.toBe(0);
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...props }));
+ expect(component.find('[data-test-subj="TextBasedLangEditor"]').length).not.toBe(0);
});
it('should render the lines badge for the inline mode by default', async () => {
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...props }));
- expect(
- component.find('[data-test-subj="TextBasedLangEditor-inline-lines-badge"]').length
- ).not.toBe(0);
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...props }));
+ expect(
+ component.find('[data-test-subj="TextBasedLangEditor-inline-lines-badge"]').length
+ ).not.toBe(0);
});
it('should render the date info with no @timestamp found', async () => {
@@ -89,12 +85,21 @@ describe('TextBasedLanguagesEditor', () => {
...props,
isCodeEditorExpanded: true,
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- expect(
- component.find('[data-test-subj="TextBasedLangEditor-date-info"]').at(0).text()
- ).toStrictEqual('@timestamp not found');
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ expect(
+ component.find('[data-test-subj="TextBasedLangEditor-date-info"]').at(0).text()
+ ).toStrictEqual('@timestamp not found');
+ });
+
+ it('should render the feedback link', async () => {
+ const newProps = {
+ ...props,
+ isCodeEditorExpanded: true,
+ };
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ expect(component.find('[data-test-subj="TextBasedLangEditor-feedback-link"]').length).not.toBe(
+ 0
+ );
});
it('should render the date info with @timestamp found if detectTimestamp is true', async () => {
@@ -103,12 +108,10 @@ describe('TextBasedLanguagesEditor', () => {
isCodeEditorExpanded: true,
detectTimestamp: true,
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- expect(
- component.find('[data-test-subj="TextBasedLangEditor-date-info"]').at(0).text()
- ).toStrictEqual('@timestamp found');
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ expect(
+ component.find('[data-test-subj="TextBasedLangEditor-date-info"]').at(0).text()
+ ).toStrictEqual('@timestamp found');
});
it('should render the errors badge for the inline mode by default if errors are provides', async () => {
@@ -116,12 +119,10 @@ describe('TextBasedLanguagesEditor', () => {
...props,
errors: [new Error('error1')],
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- expect(
- component.find('[data-test-subj="TextBasedLangEditor-inline-errors-badge"]').length
- ).not.toBe(0);
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ expect(
+ component.find('[data-test-subj="TextBasedLangEditor-inline-errors-badge"]').length
+ ).not.toBe(0);
});
it('should render the warnings badge for the inline mode by default if warning are provides', async () => {
@@ -129,12 +130,10 @@ describe('TextBasedLanguagesEditor', () => {
...props,
warning: 'Line 1: 20: Warning',
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- expect(
- component.find('[data-test-subj="TextBasedLangEditor-inline-warning-badge"]').length
- ).not.toBe(0);
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ expect(
+ component.find('[data-test-subj="TextBasedLangEditor-inline-warning-badge"]').length
+ ).not.toBe(0);
});
it('should render the correct buttons for the inline code editor mode', async () => {
@@ -156,11 +155,9 @@ describe('TextBasedLanguagesEditor', () => {
...props,
expandCodeEditor: expandCodeEditorSpy,
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- findTestSubject(component, 'TextBasedLangEditor-expand').simulate('click');
- expect(expandCodeEditorSpy).toHaveBeenCalled();
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ findTestSubject(component, 'TextBasedLangEditor-expand').simulate('click');
+ expect(expandCodeEditorSpy).toHaveBeenCalled();
});
it('should render the correct buttons for the expanded code editor mode', async () => {
@@ -211,11 +208,9 @@ describe('TextBasedLanguagesEditor', () => {
isCodeEditorExpanded: true,
expandCodeEditor: expandCodeEditorSpy,
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- findTestSubject(component, 'TextBasedLangEditor-minimize').simulate('click');
- expect(expandCodeEditorSpy).toHaveBeenCalled();
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ findTestSubject(component, 'TextBasedLangEditor-minimize').simulate('click');
+ expect(expandCodeEditorSpy).toHaveBeenCalled();
});
it('should render the resize for the expanded code editor mode', async () => {
@@ -223,10 +218,8 @@ describe('TextBasedLanguagesEditor', () => {
...props,
isCodeEditorExpanded: true,
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- expect(component.find('[data-test-subj="TextBasedLangEditor-resize"]').length).not.toBe(0);
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ expect(component.find('[data-test-subj="TextBasedLangEditor-resize"]').length).not.toBe(0);
});
it('should render the footer for the expanded code editor mode', async () => {
@@ -234,13 +227,11 @@ describe('TextBasedLanguagesEditor', () => {
...props,
isCodeEditorExpanded: true,
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- expect(component.find('[data-test-subj="TextBasedLangEditor-footer"]').length).not.toBe(0);
- expect(
- component.find('[data-test-subj="TextBasedLangEditor-footer-lines"]').at(0).text()
- ).toBe('1 line');
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ expect(component.find('[data-test-subj="TextBasedLangEditor-footer"]').length).not.toBe(0);
+ expect(component.find('[data-test-subj="TextBasedLangEditor-footer-lines"]').at(0).text()).toBe(
+ '1 line'
+ );
});
it('should render the run query text', async () => {
@@ -248,10 +239,8 @@ describe('TextBasedLanguagesEditor', () => {
...props,
isCodeEditorExpanded: true,
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- expect(component.find('[data-test-subj="TextBasedLangEditor-run-query"]').length).not.toBe(0);
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ expect(component.find('[data-test-subj="TextBasedLangEditor-run-query"]').length).not.toBe(0);
});
it('should not render the run query text if the hideRunQueryText prop is set to true', async () => {
@@ -260,10 +249,8 @@ describe('TextBasedLanguagesEditor', () => {
isCodeEditorExpanded: true,
hideRunQueryText: true,
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- expect(component.find('[data-test-subj="TextBasedLangEditor-run-query"]').length).toBe(0);
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ expect(component.find('[data-test-subj="TextBasedLangEditor-run-query"]').length).toBe(0);
});
it('should render correctly if editorIsInline prop is set to true', async () => {
@@ -275,14 +262,12 @@ describe('TextBasedLanguagesEditor', () => {
editorIsInline: true,
onTextLangQuerySubmit,
};
- await act(async () => {
- const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
- expect(component.find('[data-test-subj="TextBasedLangEditor-run-query"]').length).toBe(0);
- expect(
- component.find('[data-test-subj="TextBasedLangEditor-run-query-button"]').length
- ).not.toBe(1);
- findTestSubject(component, 'TextBasedLangEditor-run-query-button').simulate('click');
- expect(onTextLangQuerySubmit).toHaveBeenCalled();
- });
+ const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
+ expect(component.find('[data-test-subj="TextBasedLangEditor-run-query"]').length).toBe(0);
+ expect(
+ component.find('[data-test-subj="TextBasedLangEditor-run-query-button"]').length
+ ).not.toBe(1);
+ findTestSubject(component, 'TextBasedLangEditor-run-query-button').simulate('click');
+ expect(onTextLangQuerySubmit).toHaveBeenCalled();
});
});
diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx
index 9a5eae37ed097..9d175ef86ecf0 100644
--- a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx
+++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx
@@ -119,7 +119,7 @@ const KEYCODE_ARROW_UP = 38;
const KEYCODE_ARROW_DOWN = 40;
// for editor width smaller than this value we want to start hiding some text
-const BREAKPOINT_WIDTH = 410;
+const BREAKPOINT_WIDTH = 540;
const languageId = (language: string) => {
switch (language) {