Skip to content

Commit

Permalink
Merge branch 'master' into case_alerts_ui
Browse files Browse the repository at this point in the history
  • Loading branch information
kibanamachine authored Dec 9, 2020
2 parents 625b207 + f3d60c5 commit b80cc32
Show file tree
Hide file tree
Showing 143 changed files with 3,474 additions and 1,673 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@

import Chance from 'chance';

import { getUpgradeableConfigMock } from './get_upgradeable_config.test.mock';
import { SavedObjectsErrorHelpers } from '../../saved_objects';
import { savedObjectsClientMock } from '../../saved_objects/service/saved_objects_client.mock';
import { loggingSystemMock } from '../../logging/logging_system.mock';
import { getUpgradeableConfigMock } from './get_upgradeable_config.test.mock';

import { createOrUpgradeSavedConfig } from './create_or_upgrade_saved_config';

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ test('renders empty page in before initial fetch to avoid flickering', () => {
getViewUrl={() => {}}
listingLimit={1000}
hideWriteControls={false}
initialPageSize={10}
core={{ notifications: { toasts: {} }, uiSettings: { get: jest.fn(() => 10) } }}
/>
);
Expand Down
15 changes: 15 additions & 0 deletions src/plugins/data/common/search/search_source/search_source.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,21 @@ describe('SearchSource', () => {
const request = await searchSource.getSearchRequestBody();
expect(request.script_fields).toEqual({ hello: {} });
});

test('returns all scripted fields when one fields entry is *', async () => {
searchSource.setField('index', ({
...indexPattern,
getComputedFields: () => ({
storedFields: [],
scriptFields: { hello: {}, world: {} },
docvalueFields: [],
}),
} as unknown) as IndexPattern);
searchSource.setField('fields', ['timestamp', '*']);

const request = await searchSource.getSearchRequestBody();
expect(request.script_fields).toEqual({ hello: {}, world: {} });
});
});

describe('handling for when specific fields are provided', () => {
Expand Down
19 changes: 13 additions & 6 deletions src/plugins/data/common/search/search_source/search_source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,12 @@ export class SearchSource {
case 'query':
return addToRoot(key, (data[key] || []).concat(val));
case 'fields':
// uses new Fields API
// This will pass the passed in parameters to the new fields API.
// Also if will only return scripted fields that are part of the specified
// array of fields. If you specify the wildcard `*` as an array element
// the fields API will return all fields, and all scripted fields will be returned.
// NOTE: While the fields API supports wildcards within names, e.g. `user.*`
// scripted fields won't be considered for this.
return addToBody('fields', val);
case 'fieldsFromSource':
// preserves legacy behavior
Expand Down Expand Up @@ -518,11 +523,13 @@ export class SearchSource {
);
const uniqFieldNames = [...new Set([...bodyFieldNames, ...fieldsFromSource])];

// filter down script_fields to only include items specified
body.script_fields = pick(
body.script_fields,
Object.keys(body.script_fields).filter((f) => uniqFieldNames.includes(f))
);
if (!uniqFieldNames.includes('*')) {
// filter down script_fields to only include items specified
body.script_fields = pick(
body.script_fields,
Object.keys(body.script_fields).filter((f) => uniqFieldNames.includes(f))
);
}

// request the remaining fields from stored_fields just in case, since the
// fields API does not handle stored fields
Expand Down
6 changes: 4 additions & 2 deletions src/plugins/data/server/search/search_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,15 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
private readonly searchSourceService = new SearchSourceService();
private defaultSearchStrategyName: string = ES_SEARCH_STRATEGY;
private searchStrategies: StrategyMap = {};
private sessionService: ISessionService;
private coreStart?: CoreStart;
private sessionService: ISessionService = new SessionService();

constructor(
private initializerContext: PluginInitializerContext<ConfigSchema>,
private readonly logger: Logger
) {}
) {
this.sessionService = new SessionService();
}

public setup(
core: CoreSetup<{}, DataPluginStart>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import React from 'react';
import { wait } from '@testing-library/dom';
import { waitFor } from '@testing-library/dom';
import { render } from '@testing-library/react';
import {
HelloWorldEmbeddable,
Expand Down Expand Up @@ -47,7 +47,7 @@ describe('<EmbeddableRenderer/>', () => {
<EmbeddableRenderer factory={getFactory()} input={{ id: 'hello' }} />
);
expect(getByTestId('embedSpinner')).toBeInTheDocument();
await wait(() => !queryByTestId('embedSpinner')); // wait until spinner disappears
await waitFor(() => !queryByTestId('embedSpinner')); // wait until spinner disappears
expect(getByTestId('helloWorldEmbeddable')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/
import React from 'react';
import { wait, render } from '@testing-library/react';
import { waitFor, render } from '@testing-library/react';
import { ErrorEmbeddable } from './error_embeddable';
import { EmbeddableRoot } from './embeddable_root';

Expand All @@ -26,7 +26,7 @@ test('ErrorEmbeddable renders an embeddable', async () => {
const { getByTestId, getByText } = render(<EmbeddableRoot embeddable={embeddable} />);

expect(getByTestId('embeddableStackError')).toBeVisible();
await wait(() => getByTestId('errorMessageMarkdown')); // wait for lazy markdown component
await waitFor(() => getByTestId('errorMessageMarkdown')); // wait for lazy markdown component
expect(getByText(/some error occurred/i)).toBeVisible();
});

Expand All @@ -36,7 +36,7 @@ test('ErrorEmbeddable renders an embeddable with markdown message', async () =>
const { getByTestId, getByText } = render(<EmbeddableRoot embeddable={embeddable} />);

expect(getByTestId('embeddableStackError')).toBeVisible();
await wait(() => getByTestId('errorMessageMarkdown')); // wait for lazy markdown component
await waitFor(() => getByTestId('errorMessageMarkdown')); // wait for lazy markdown component
expect(getByText(/some link/i)).toMatchInlineSnapshot(`
<a
href="http://localhost:5601/takeMeThere"
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/es_ui_shared/public/request/use_request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ describe('useRequest hook', () => {
const { setupSuccessRequest, completeRequest, hookResult } = helpers;
setupSuccessRequest();
expect(hookResult.isInitialRequest).toBe(true);

hookResult.resendRequest();
act(() => {
hookResult.resendRequest();
});
await completeRequest();
expect(hookResult.isInitialRequest).toBe(false);
});
Expand Down
28 changes: 20 additions & 8 deletions src/plugins/saved_objects_tagging_oss/public/api.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
*/

import { ITagsClient } from '../common';
import { SavedObjectsTaggingApiUi, SavedObjectsTaggingApiUiComponent } from './api';
import { SavedObjectsTaggingApiUi, SavedObjectsTaggingApiUiComponent, ITagsCache } from './api';

const createClientMock = (): jest.Mocked<ITagsClient> => {
const mock = {
const createClientMock = () => {
const mock: jest.Mocked<ITagsClient> = {
create: jest.fn(),
get: jest.fn(),
getAll: jest.fn(),
Expand All @@ -32,14 +32,25 @@ const createClientMock = (): jest.Mocked<ITagsClient> => {
return mock;
};

const createCacheMock = () => {
const mock: jest.Mocked<ITagsCache> = {
getState: jest.fn(),
getState$: jest.fn(),
};

return mock;
};

interface SavedObjectsTaggingApiMock {
client: jest.Mocked<ITagsClient>;
cache: jest.Mocked<ITagsCache>;
ui: SavedObjectsTaggingApiUiMock;
}

const createApiMock = (): SavedObjectsTaggingApiMock => {
const mock = {
const mock: SavedObjectsTaggingApiMock = {
client: createClientMock(),
cache: createCacheMock(),
ui: createApiUiMock(),
};

Expand All @@ -50,8 +61,8 @@ type SavedObjectsTaggingApiUiMock = Omit<jest.Mocked<SavedObjectsTaggingApiUi>,
components: SavedObjectsTaggingApiUiComponentMock;
};

const createApiUiMock = (): SavedObjectsTaggingApiUiMock => {
const mock = {
const createApiUiMock = () => {
const mock: SavedObjectsTaggingApiUiMock = {
components: createApiUiComponentsMock(),
// TS is very picky with type guards
hasTagDecoration: jest.fn() as any,
Expand All @@ -69,8 +80,8 @@ const createApiUiMock = (): SavedObjectsTaggingApiUiMock => {

type SavedObjectsTaggingApiUiComponentMock = jest.Mocked<SavedObjectsTaggingApiUiComponent>;

const createApiUiComponentsMock = (): SavedObjectsTaggingApiUiComponentMock => {
const mock = {
const createApiUiComponentsMock = () => {
const mock: SavedObjectsTaggingApiUiComponentMock = {
TagList: jest.fn(),
TagSelector: jest.fn(),
SavedObjectSaveModalTagSelector: jest.fn(),
Expand All @@ -82,6 +93,7 @@ const createApiUiComponentsMock = (): SavedObjectsTaggingApiUiComponentMock => {
export const taggingApiMock = {
create: createApiMock,
createClient: createClientMock,
createCache: createCacheMock,
createUi: createApiUiMock,
createComponents: createApiUiComponentsMock,
};
29 changes: 28 additions & 1 deletion src/plugins/saved_objects_tagging_oss/public/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,49 @@
* under the License.
*/

import { Observable } from 'rxjs';
import { SearchFilterConfig, EuiTableFieldDataColumnType } from '@elastic/eui';
import type { FunctionComponent } from 'react';
import { SavedObject, SavedObjectReference } from '../../../core/types';
import { SavedObjectsFindOptionsReference } from '../../../core/public';
import { SavedObject as SavedObjectClass } from '../../saved_objects/public';
import { TagDecoratedSavedObject } from './decorator';
import { ITagsClient } from '../common';
import { ITagsClient, Tag } from '../common';

/**
* @public
*/
export interface SavedObjectsTaggingApi {
/**
* The client to perform tag-related operations on the server-side
*/
client: ITagsClient;
/**
* A client-side auto-refreshing cache of the existing tags. Can be used
* to synchronously access the list of tags.
*/
cache: ITagsCache;
/**
* UI API to use to add tagging capabilities to an application
*/
ui: SavedObjectsTaggingApiUi;
}

/**
* @public
*/
export interface ITagsCache {
/**
* Return the current state of the cache
*/
getState(): Tag[];

/**
* Return an observable that will emit everytime the cache's state mutates.
*/
getState$(): Observable<Tag[]>;
}

/**
* @public
*/
Expand Down
1 change: 1 addition & 0 deletions src/plugins/saved_objects_tagging_oss/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export {
SavedObjectsTaggingApi,
SavedObjectsTaggingApiUi,
SavedObjectsTaggingApiUiComponent,
ITagsCache,
TagListComponentProps,
TagSelectorComponentProps,
GetSearchBarFilterOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,27 @@ interface State {
* React component for displaying the example data associated with the Telemetry opt-in banner.
*/
export class OptInExampleFlyout extends React.PureComponent<Props, State> {
_isMounted = false;

public readonly state: State = {
data: null,
isLoading: true,
hasPrivilegeToRead: false,
};

async componentDidMount() {
this._isMounted = true;

try {
const { fetchExample } = this.props;
const clusters = await fetchExample();
this.setState({
data: Array.isArray(clusters) ? clusters : null,
isLoading: false,
hasPrivilegeToRead: true,
});
if (this._isMounted) {
this.setState({
data: Array.isArray(clusters) ? clusters : null,
isLoading: false,
hasPrivilegeToRead: true,
});
}
} catch (err) {
this.setState({
isLoading: false,
Expand All @@ -72,6 +78,10 @@ export class OptInExampleFlyout extends React.PureComponent<Props, State> {
}
}

componentWillUnmount() {
this._isMounted = false;
}

renderBody({ data, isLoading, hasPrivilegeToRead }: State) {
if (isLoading) {
return loadingSpinner;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ function DefaultEditorAggSelect({
}

const helpLink = value && aggHelpLink && (
<EuiLink href={aggHelpLink} target="_blank" rel="noopener">
<EuiText size="xs">
<EuiText size="xs">
<EuiLink href={aggHelpLink} target="_blank" rel="noopener">
<FormattedMessage
id="visDefaultEditor.aggSelect.helpLinkLabel"
defaultMessage="{aggTitle} help"
values={{ aggTitle: value ? value.title : '' }}
/>
</EuiText>
</EuiLink>
</EuiLink>
</EuiText>
);

const errors = aggError ? [aggError] : [];
Expand Down
Loading

0 comments on commit b80cc32

Please sign in to comment.