Skip to content

Commit

Permalink
Merge branch 'main' into fix-lens-in-markdown-serverless
Browse files Browse the repository at this point in the history
  • Loading branch information
js-jankisalvi authored Sep 1, 2023
2 parents fa203b0 + 1d3af80 commit 4e94d86
Show file tree
Hide file tree
Showing 34 changed files with 581 additions and 87 deletions.
264 changes: 264 additions & 0 deletions docs/CHANGELOG.asciidoc

Large diffs are not rendered by default.

16 changes: 3 additions & 13 deletions packages/kbn-es-archiver/src/actions/empty_kibana_index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,15 @@

import type { Client } from '@elastic/elasticsearch';
import { ToolingLog } from '@kbn/tooling-log';
import { KbnClient } from '@kbn/test';

import { ALL_SAVED_OBJECT_INDICES } from '@kbn/core-saved-objects-server';
import { migrateSavedObjectIndices, createStats, cleanSavedObjectIndices } from '../lib';
import { createStats, cleanSavedObjectIndices } from '../lib';

export async function emptyKibanaIndexAction({
client,
log,
kbnClient,
}: {
client: Client;
log: ToolingLog;
kbnClient: KbnClient;
}) {
export async function emptyKibanaIndexAction({ client, log }: { client: Client; log: ToolingLog }) {
const stats = createStats('emptyKibanaIndex', log);

await cleanSavedObjectIndices({ client, stats, log });
await migrateSavedObjectIndices(kbnClient);
await client.indices.refresh({ index: ALL_SAVED_OBJECT_INDICES });
ALL_SAVED_OBJECT_INDICES.forEach((indexPattern) => stats.createdIndex(indexPattern));

return stats.toJSON();
}
4 changes: 1 addition & 3 deletions packages/kbn-es-archiver/src/es_archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,12 @@ export class EsArchiver {
}

/**
* Delete any Kibana indices, and initialize the Kibana index as Kibana would do
* on startup.
* Cleanup saved object indices, preserving the space:default saved object.
*/
async emptyKibanaIndex() {
return await emptyKibanaIndexAction({
client: this.client,
log: this.log,
kbnClient: this.kbnClient,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,27 @@ The editor also works on the expanded mode:
</Story>
</Canvas>

The editor also works on the expanded mode with the minimize button hidden:

<Canvas>
<Story
name='on expanded mode with hidden the minimize button'
args={
{
query: { esql: 'from dataview | keep field1, field2' },
isCodeEditorExpanded:true,
hideMinimizeButton: true,
'data-test-subj':'test-id',
}
}
argTypes={
{ onTextLangQueryChange: { action: 'changed' }, onTextLangQuerySubmit: { action: 'submitted' }, expandCodeEditor: { action: 'expanded' }}
}
>
{Template.bind({})}
</Story>
</Canvas>

## Component props

The component exposes the following properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,28 @@ describe('TextBasedLanguagesEditor', () => {
);
});

it('should not render the minimize button for the expanded code editor mode if the prop is set to true', async () => {
const newProps = {
...props,
isCodeEditorExpanded: true,
hideMinimizeButton: true,
};
let component: ReactWrapper;
await act(async () => {
component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps }));
});
component!.update();
await act(async () => {
expect(
component.find('[data-test-subj="TextBasedLangEditor-toggleWordWrap"]').length
).not.toBe(0);
expect(component.find('[data-test-subj="TextBasedLangEditor-minimize"]').length).toBe(0);
expect(
component.find('[data-test-subj="TextBasedLangEditor-documentation"]').length
).not.toBe(0);
});
});

it('should call the expand editor function when minimize button is clicked', async () => {
const expandCodeEditorSpy = jest.fn();
const newProps = {
Expand Down
52 changes: 28 additions & 24 deletions packages/kbn-text-based-editor/src/text_based_languages_editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export interface TextBasedLanguagesEditorProps {
isDisabled?: boolean;
isDarkMode?: boolean;
dataTestSubj?: string;
hideMinimizeButton?: boolean;
}

interface TextBasedEditorDeps {
Expand Down Expand Up @@ -118,6 +119,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({
warning,
isDisabled,
isDarkMode,
hideMinimizeButton,
dataTestSubj,
}: TextBasedLanguagesEditorProps) {
const { euiTheme } = useEuiTheme();
Expand Down Expand Up @@ -547,33 +549,35 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFlexGroup responsive={false} gutterSize="none" alignItems="center">
<EuiFlexItem grow={false} style={{ marginRight: '8px' }}>
<EuiToolTip
position="top"
content={i18n.translate(
'textBasedEditor.query.textBasedLanguagesEditor.minimizeTooltip',
{
defaultMessage: 'Compact query editor',
}
)}
>
<EuiButtonIcon
iconType="minimize"
color="text"
aria-label={i18n.translate(
'textBasedEditor.query.textBasedLanguagesEditor.MinimizeEditor',
{!Boolean(hideMinimizeButton) && (
<EuiFlexItem grow={false} style={{ marginRight: '8px' }}>
<EuiToolTip
position="top"
content={i18n.translate(
'textBasedEditor.query.textBasedLanguagesEditor.minimizeTooltip',
{
defaultMessage: 'Minimize editor',
defaultMessage: 'Compact query editor',
}
)}
data-test-subj="TextBasedLangEditor-minimize"
onClick={() => {
expandCodeEditor(false);
updateLinesFromModel = false;
}}
/>
</EuiToolTip>
</EuiFlexItem>
>
<EuiButtonIcon
iconType="minimize"
color="text"
aria-label={i18n.translate(
'textBasedEditor.query.textBasedLanguagesEditor.MinimizeEditor',
{
defaultMessage: 'Minimize editor',
}
)}
data-test-subj="TextBasedLangEditor-minimize"
onClick={() => {
expandCodeEditor(false);
updateLinesFromModel = false;
}}
/>
</EuiToolTip>
</EuiFlexItem>
)}
<EuiFlexItem grow={false}>
{documentationSections && (
<EuiFlexItem grow={false}>
Expand Down
1 change: 1 addition & 0 deletions test/examples/search/warnings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// click "see full error" button in the toast
const [openShardModalButton] = await testSubjects.findAll('openShardFailureModalBtn');
await openShardModalButton.click();
await testSubjects.exists('shardFailureModalTitle');
const modalHeader = await testSubjects.find('shardFailureModalTitle');
expect(await modalHeader.getVisibleText()).to.be('2 of 4 shards failed');
// request
Expand Down
151 changes: 150 additions & 1 deletion test/functional/apps/console/_autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const log = getService('log');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'console']);
const PageObjects = getPageObjects(['common', 'console', 'header']);
const find = getService('find');

describe('console autocomplete feature', function describeIndexTests() {
Expand Down Expand Up @@ -44,6 +44,155 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(PageObjects.console.isAutocompleteVisible()).to.be.eql(true);
});

describe('Autocomplete behavior', () => {
beforeEach(async () => {
await PageObjects.console.clearTextArea();
await PageObjects.console.pressEnter();
});

it('HTTP methods', async () => {
const suggestions = {
G: ['GET'],
P: ['PUT', 'POST'],
D: ['DELETE'],
H: ['HEAD'],
};
for (const [char, methods] of Object.entries(suggestions)) {
await PageObjects.console.sleepForDebouncePeriod();
log.debug('Key type "%s"', char);
await PageObjects.console.enterText(char);

await retry.waitFor('autocomplete to be visible', () =>
PageObjects.console.isAutocompleteVisible()
);
expect(await PageObjects.console.isAutocompleteVisible()).to.be.eql(true);

for (const [i, method] of methods.entries()) {
expect(await PageObjects.console.getAutocompleteSuggestion(i)).to.be.eql(method);
}

await PageObjects.console.pressEscape();
await PageObjects.console.pressEnter();
}
});

it('ES API endpoints', async () => {
const suggestions = {
'GET _': ['_alias', '_all'],
'PUT _': ['_all'],
'POST _': ['_aliases', '_all'],
'DELETE _': ['_all'],
'HEAD _': ['_alias', '_all'],
};
for (const [text, endpoints] of Object.entries(suggestions)) {
for (const char of text) {
await PageObjects.console.sleepForDebouncePeriod();
log.debug('Key type "%s"', char);
await PageObjects.console.enterText(char);
}

await retry.waitFor('autocomplete to be visible', () =>
PageObjects.console.isAutocompleteVisible()
);
expect(await PageObjects.console.isAutocompleteVisible()).to.be.eql(true);

for (const [i, endpoint] of endpoints.entries()) {
expect(await PageObjects.console.getAutocompleteSuggestion(i)).to.be.eql(endpoint);
}

await PageObjects.console.pressEscape();
await PageObjects.console.pressEnter();
}
});

it('JSON autocompletion with placeholder fields', async () => {
await PageObjects.console.enterText('GET _search\n{');
await PageObjects.console.pressEnter();

for (const char of '"ag') {
await PageObjects.console.sleepForDebouncePeriod();
log.debug('Key type "%s"', char);
await PageObjects.console.enterText(char);
}
await retry.waitFor('autocomplete to be visible', () =>
PageObjects.console.isAutocompleteVisible()
);
expect(await PageObjects.console.isAutocompleteVisible()).to.be.eql(true);
await PageObjects.console.pressEnter();
await PageObjects.console.sleepForDebouncePeriod();

expect(await PageObjects.console.getAllVisibleText()).to.be.eql(
`
GET _search
{
"aggs": {
"NAME": {
"AGG_TYPE": {}
}
}
}
`.replace(/\n/g, '')
);
// cursor should be located between '"' and 'N'
expect(await PageObjects.console.getCurrentLineNumber()).to.be.eql(5);

await PageObjects.console.pressDown();
await PageObjects.console.pressRight();
await PageObjects.console.pressRight();
for (let i = 0; i < 8; i++) {
await PageObjects.console.pressRight(true); // select 'AGG_TYPE'
}

for (const char of 'ter') {
await PageObjects.console.sleepForDebouncePeriod();
log.debug('Key type "%s"', char);
await PageObjects.console.enterText(char);
}
await retry.waitFor('autocomplete to be visible', () =>
PageObjects.console.isAutocompleteVisible()
);
expect(await PageObjects.console.isAutocompleteVisible()).to.be.eql(true);
await PageObjects.console.pressEnter();
await PageObjects.console.sleepForDebouncePeriod();

expect(await PageObjects.console.getAllVisibleText()).to.be.eql(
`
GET _search
{
"aggs": {
"NAME": {
"terms": {
"field": ""
}
}
}
}
`.replace(/\n/g, '')
);
});

it('Dynamic autocomplete', async () => {
await PageObjects.console.enterRequest('POST test/_doc\n{}');
await PageObjects.console.clickPlay();

await PageObjects.header.waitUntilLoadingHasFinished();
expect(await PageObjects.console.getResponseStatus()).to.be('201');

await PageObjects.console.pressEnter();
for (const char of 'POST t') {
await PageObjects.console.sleepForDebouncePeriod();
log.debug('Key type "%s"', char);
await PageObjects.console.enterText(char);
}
await retry.waitFor('autocomplete to be visible', () =>
PageObjects.console.isAutocompleteVisible()
);
expect(await PageObjects.console.isAutocompleteVisible()).to.be.eql(true);

expect(await PageObjects.console.getAutocompleteSuggestion(0)).to.be.eql('test');
});
});

// FLAKY: https://github.com/elastic/kibana/issues/164584
describe.skip('anti-regression watchdogs', () => {
beforeEach(async () => {
Expand Down
Loading

0 comments on commit 4e94d86

Please sign in to comment.