Skip to content

Commit

Permalink
Merge branch 'master' into liza-update/update-percy-client
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticmachine authored Apr 1, 2020
2 parents dbf3e9e + 7975765 commit 5ed4295
Show file tree
Hide file tree
Showing 28 changed files with 631 additions and 352 deletions.
3 changes: 2 additions & 1 deletion test/functional/apps/context/_discover_navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export default function({ getService, getPageObjects }) {
const filterBar = getService('filterBar');
const PageObjects = getPageObjects(['common', 'discover', 'timePicker']);

describe('context link in discover', function contextSize() {
// FLAKY: https://github.com/elastic/kibana/issues/53308
describe.skip('context link in discover', function contextSize() {
this.tags('smoke');
before(async function() {
await PageObjects.common.navigateToApp('discover');
Expand Down
3 changes: 2 additions & 1 deletion test/functional/apps/discover/_field_visualize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
defaultIndex: 'logstash-*',
};

describe('discover field visualize button', () => {
// FLAKY: https://github.com/elastic/kibana/issues/61714
describe.skip('discover field visualize button', () => {
before(async function() {
log.debug('load kibana index with default index pattern');
await esArchiver.load('discover');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ export function ServiceMap({ serviceName }: ServiceMapProps) {
const license = useLicense();
const { urlParams } = useUrlParams();

const { data } = useFetcher(() => {
const { data = { elements: [] } } = useFetcher(() => {
// When we don't have a license or a valid license, don't make the request.
if (!license || !isValidPlatinumLicense(license)) {
return;
}

const { start, end, environment } = urlParams;
if (start && end) {
return callApmApi({
Expand All @@ -48,7 +53,7 @@ export function ServiceMap({ serviceName }: ServiceMapProps) {
}
});
}
}, [serviceName, urlParams]);
}, [license, serviceName, urlParams]);

const { ref, height, width } = useRefDimensions();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export const FiltersSection = ({
</EuiFlexItem>
<EuiFlexItem>
<EuiFieldText
data-test-subj={`value-${idx}`}
data-test-subj={`${key}.value`}
fullWidth
placeholder={i18n.translate(
'xpack.apm.settings.customizeUI.customLink.flyOut.filters.defaultOption.value',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import {
CustomLink,
Filter
} from '../../../../../../../../../../plugins/apm/common/custom_link/custom_link_types';
import { Filter } from '../../../../../../../../../../plugins/apm/common/custom_link/custom_link_types';
import { useApmPluginContext } from '../../../../../../hooks/useApmPluginContext';
import { FiltersSection } from './FiltersSection';
import { FlyoutFooter } from './FlyoutFooter';
Expand All @@ -28,27 +25,32 @@ import { Documentation } from './Documentation';

interface Props {
onClose: () => void;
customLinkSelected?: CustomLink;
onSave: () => void;
onDelete: () => void;
defaults?: {
url?: string;
label?: string;
filters?: Filter[];
};
customLinkId?: string;
}

const filtersEmptyState: Filter[] = [{ key: '', value: '' }];

export const CustomLinkFlyout = ({
onClose,
customLinkSelected,
onSave,
onDelete
onDelete,
defaults,
customLinkId
}: Props) => {
const { toasts } = useApmPluginContext().core.notifications;
const [isSaving, setIsSaving] = useState(false);

const [label, setLabel] = useState(customLinkSelected?.label || '');
const [url, setUrl] = useState(customLinkSelected?.url || '');
const selectedFilters = customLinkSelected?.filters;
const [label, setLabel] = useState(defaults?.label || '');
const [url, setUrl] = useState(defaults?.url || '');
const [filters, setFilters] = useState(
selectedFilters?.length
? selectedFilters
: ([{ key: '', value: '' }] as Filter[])
defaults?.filters?.length ? defaults.filters : filtersEmptyState
);

const isFormValid = !!label && !!url;
Expand All @@ -61,7 +63,7 @@ export const CustomLinkFlyout = ({
event.preventDefault();
setIsSaving(true);
await saveCustomLink({
id: customLinkSelected?.id,
id: customLinkId,
label,
url,
filters,
Expand Down Expand Up @@ -131,7 +133,7 @@ export const CustomLinkFlyout = ({
onClose={onClose}
isSaving={isSaving}
onDelete={onDelete}
customLinkId={customLinkSelected?.id}
customLinkId={customLinkId}
/>
</EuiFlyout>
</form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ export const CustomLinkOverview = () => {
{isFlyoutOpen && (
<CustomLinkFlyout
onClose={onCloseFlyout}
customLinkSelected={customLinkSelected}
defaults={customLinkSelected}
customLinkId={customLinkSelected?.id}
onSave={() => {
onCloseFlyout();
refetch();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
import { EuiButtonEmpty } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { FunctionComponent, useMemo, useState } from 'react';
import {
CustomLink as CustomLinkType,
Filter
} from '../../../../../../../plugins/apm/common/custom_link/custom_link_types';
import { Filter } from '../../../../../../../plugins/apm/common/custom_link/custom_link_types';
import { Transaction } from '../../../../../../../plugins/apm/typings/es_schemas/ui/transaction';
import {
ActionMenu,
Expand Down Expand Up @@ -68,7 +65,7 @@ export const TransactionActionMenu: FunctionComponent<Props> = ({
{ key: 'service.environment', value: transaction?.service.environment },
{ key: 'transaction.name', value: transaction?.transaction.name },
{ key: 'transaction.type', value: transaction?.transaction.type }
] as Filter[],
].filter((filter): filter is Filter => typeof filter.value === 'string'),
[transaction]
);

Expand Down Expand Up @@ -100,7 +97,7 @@ export const TransactionActionMenu: FunctionComponent<Props> = ({
<>
{isCustomLinkFlyoutOpen && (
<CustomLinkFlyout
customLinkSelected={{ filters: { ...filters } } as CustomLinkType}
defaults={{ filters }}
onClose={toggleCustomLinkFlyout}
onSave={() => {
toggleCustomLinkFlyout();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import * as hooks from '../../../../hooks/useFetcher';
import { LicenseContext } from '../../../../context/LicenseContext';
import { License } from '../../../../../../../../plugins/licensing/common/license';
import { MockApmPluginContextWrapper } from '../../../../context/ApmPluginContext/MockApmPluginContext';
import * as apmApi from '../../../../services/rest/createCallApmApi';

const renderTransaction = async (transaction: Record<string, any>) => {
const rendered = render(
Expand Down Expand Up @@ -142,6 +143,12 @@ describe('TransactionActionMenu component', () => {
});

describe('Custom links', () => {
beforeAll(() => {
spyOn(apmApi, 'callApmApi').and.returnValue({});
});
afterAll(() => {
jest.resetAllMocks();
});
it('doesnt show custom links when license is not valid', () => {
const license = new License({
signature: 'test signature',
Expand Down Expand Up @@ -250,5 +257,53 @@ describe('TransactionActionMenu component', () => {
});
expectTextsInDocument(component, ['Custom Links']);
});
it('opens flyout with filters prefilled', () => {
const license = new License({
signature: 'test signature',
license: {
expiryDateInMillis: 0,
mode: 'gold',
status: 'active',
type: 'gold',
uid: '1'
}
});
const component = render(
<LicenseContext.Provider value={license}>
<MockApmPluginContextWrapper>
<TransactionActionMenu
transaction={
Transactions.transactionWithMinimalData as Transaction
}
/>
</MockApmPluginContextWrapper>
</LicenseContext.Provider>
);
act(() => {
fireEvent.click(component.getByText('Actions'));
});
expectTextsInDocument(component, ['Custom Links']);
act(() => {
fireEvent.click(component.getByText('Create custom link'));
});
expectTextsInDocument(component, ['Create link']);
const getFilterKeyValue = (key: string) => {
return {
[(component.getAllByText(key)[0] as HTMLOptionElement)
.text]: (component.getAllByTestId(
`${key}.value`
)[0] as HTMLInputElement).value
};
};
expect(getFilterKeyValue('service.name')).toEqual({
'service.name': 'opbeans-go'
});
expect(getFilterKeyValue('transaction.name')).toEqual({
'transaction.name': 'GET /api/products/:id/customers'
});
expect(getFilterKeyValue('transaction.type')).toEqual({
'transaction.type': 'request'
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ export const EmbeddedMap = React.memo(({ upPoints, downPoints }: EmbeddedMapProp

return (
<EmbeddedPanel>
<div className="embPanel__content" ref={embeddableRoot} />
<div
data-test-subj="xpack.uptime.locationMap.embeddedPanel"
className="embPanel__content"
ref={embeddableRoot}
/>
</EmbeddedPanel>
);
});
Expand Down
12 changes: 9 additions & 3 deletions x-pack/legacy/plugins/uptime/public/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ interface RouterProps {
export const PageRouter: FC<RouterProps> = ({ autocomplete }) => (
<Switch>
<Route path={MONITOR_ROUTE}>
<MonitorPage />
<div data-test-subj="uptimeMonitorPage">
<MonitorPage />
</div>
</Route>
<Route path={SETTINGS_ROUTE}>
<SettingsPage />
<div data-test-subj="uptimeSettingsPage">
<SettingsPage />
</div>
</Route>
<Route path={OVERVIEW_ROUTE}>
<OverviewPage autocomplete={autocomplete} />
<div data-test-subj="uptimeOverviewPage">
<OverviewPage autocomplete={autocomplete} />
</div>
</Route>
<Route component={NotFoundPage} />
</Switch>
Expand Down
14 changes: 10 additions & 4 deletions x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
getTotalLoaded,
} from '../../../../../src/plugins/data/server';
import { IEnhancedEsSearchRequest } from '../../common';
import { shimHitsTotal } from './shim_hits_total';

export interface AsyncSearchResponse<T> {
id: string;
Expand Down Expand Up @@ -56,22 +57,27 @@ async function asyncSearch(
request: IEnhancedEsSearchRequest,
options?: ISearchOptions
) {
const { body = undefined, index = undefined, ...params } = request.id ? {} : request.params;
const { timeout = undefined, restTotalHitsAsInt = undefined, ...params } = {
trackTotalHits: true, // Get the exact count of hits
...request.params,
};

// If we have an ID, then just poll for that ID, otherwise send the entire request body
const { body = undefined, index = undefined, ...queryParams } = request.id ? {} : params;

const method = request.id ? 'GET' : 'POST';
const path = encodeURI(request.id ? `_async_search/${request.id}` : `${index}/_async_search`);

// Wait up to 1s for the response to return
const query = toSnakeCase({ waitForCompletionTimeout: '1s', ...params });
const query = toSnakeCase({ waitForCompletionTimeout: '1s', ...queryParams });

const { response: rawResponse, id } = (await caller(
const { response, id } = (await caller(
'transport.request',
{ method, path, body, query },
options
)) as AsyncSearchResponse<any>;

return { id, rawResponse, ...getTotalLoaded(rawResponse._shards) };
return { id, rawResponse: shimHitsTotal(response), ...getTotalLoaded(response._shards) };
}

async function rollupSearch(
Expand Down
56 changes: 56 additions & 0 deletions x-pack/plugins/data_enhanced/server/search/shim_hits_total.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { shimHitsTotal } from './shim_hits_total';

describe('shimHitsTotal', () => {
test('returns the total if it is already numeric', () => {
const result = shimHitsTotal({
hits: {
total: 5,
},
} as any);
expect(result).toEqual({
hits: {
total: 5,
},
});
});

test('returns the total if it is inside `value`', () => {
const result = shimHitsTotal({
hits: {
total: {
value: 5,
},
},
} as any);
expect(result).toEqual({
hits: {
total: 5,
},
});
});

test('returns other properties from the response', () => {
const result = shimHitsTotal({
_shards: {},
hits: {
hits: [],
total: {
value: 5,
},
},
} as any);
expect(result).toEqual({
_shards: {},
hits: {
hits: [],
total: 5,
},
});
});
});
18 changes: 18 additions & 0 deletions x-pack/plugins/data_enhanced/server/search/shim_hits_total.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { SearchResponse } from 'elasticsearch';

/**
* Temporary workaround until https://github.com/elastic/kibana/issues/26356 is addressed.
* Since we are setting `track_total_hits` in the request, `hits.total` will be an object
* containing the `value`.
*/
export function shimHitsTotal(response: SearchResponse<any>) {
const total = (response.hits?.total as any)?.value ?? response.hits?.total;
const hits = { ...response.hits, total };
return { ...response, hits };
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const removeServerGeneratedProperties = (
created_at,
updated_at,
id,
last_failure_at,
last_failure_message,
last_success_at,
last_success_message,
status,
Expand Down
Loading

0 comments on commit 5ed4295

Please sign in to comment.