Skip to content

Commit

Permalink
[Discover] Make share links and search session info shorter for ad-ho…
Browse files Browse the repository at this point in the history
…c data views (elastic#161180)

- Closes elastic#160993

## Summary

This PR introduces `dataView.toMinimalSpec()` which is used now in 3
cases:
- when constructing an alert link
- when constructing a share URL for ad-hoc data views
- when constructing search session info for ad-hoc data views

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
2 people authored and Devon Thomson committed Aug 1, 2023
1 parent 1ff765b commit 6221b06
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 50 deletions.
1 change: 1 addition & 0 deletions packages/kbn-discover-utils/src/__mocks__/data_view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export const buildDataViewMock = ({
isTimeNanosBased: () => false,
isPersisted: () => true,
toSpec: () => ({}),
toMinimalSpec: () => ({}),
getTimeField: () => {
return dataViewFields.find((field) => field.name === timeFieldName);
},
Expand Down

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

107 changes: 107 additions & 0 deletions src/plugins/data_views/common/data_views/data_view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,4 +478,111 @@ describe('IndexPattern', () => {
expect(dataView1.sourceFilters).not.toBe(dataView2.sourceFilters);
});
});

describe('toMinimalSpec', () => {
test('can exclude fields', () => {
expect(indexPattern.toMinimalSpec()).toMatchSnapshot();
});

test('can omit counts', () => {
const fieldsMap = {
test1: {
name: 'test1',
type: 'keyword',
aggregatable: true,
searchable: true,
readFromDocValues: false,
},
test2: {
name: 'test2',
type: 'keyword',
aggregatable: true,
searchable: true,
readFromDocValues: false,
},
test3: {
name: 'test3',
type: 'keyword',
aggregatable: true,
searchable: true,
readFromDocValues: false,
},
};
expect(
create('test', {
id: 'test',
title: 'test*',
fields: fieldsMap,
fieldAttrs: undefined,
}).toMinimalSpec().fieldAttrs
).toBeUndefined();
expect(
create('test', {
id: 'test',
title: 'test*',
fields: fieldsMap,
fieldAttrs: {
test1: {
count: 11,
},
test2: {
count: 12,
},
},
}).toMinimalSpec().fieldAttrs
).toBeUndefined();

expect(
create('test', {
id: 'test',
title: 'test*',
fields: fieldsMap,
fieldAttrs: {
test1: {
count: 11,
customLabel: 'test11',
},
test2: {
count: 12,
},
},
}).toMinimalSpec().fieldAttrs
).toMatchInlineSnapshot(`
Object {
"test1": Object {
"customLabel": "test11",
},
}
`);

expect(
create('test', {
id: 'test',
title: 'test*',
fields: fieldsMap,
fieldAttrs: {
test1: {
count: 11,
customLabel: 'test11',
},
test2: {
customLabel: 'test12',
},
test3: {
count: 30,
},
},
}).toMinimalSpec().fieldAttrs
).toMatchInlineSnapshot(`
Object {
"test1": Object {
"customLabel": "test11",
},
"test2": Object {
"customLabel": "test12",
},
}
`);
});
});
});
24 changes: 23 additions & 1 deletion src/plugins/data_views/common/data_views/data_view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type {
} from '@kbn/field-formats-plugin/common';
import { castEsToKbnFieldTypeName, ES_FIELD_TYPES, KBN_FIELD_TYPES } from '@kbn/field-types';
import { CharacterNotAllowedInField } from '@kbn/kibana-utils-plugin/common';
import { cloneDeep, each, reject } from 'lodash';
import { cloneDeep, each, mapValues, omit, pickBy, reject } from 'lodash';
import type { DataViewAttributes, FieldAttrs, FieldAttrSet } from '..';
import type { DataViewField, IIndexPatternFieldList } from '../fields';
import { fieldList } from '../fields';
Expand Down Expand Up @@ -332,6 +332,28 @@ export class DataView implements DataViewBase {
return Object.fromEntries(Object.entries(spec).filter(([, v]) => typeof v !== 'undefined'));
}

/**
* Creates a minimal static representation of the data view. Fields and popularity scores will be omitted.
*/
public toMinimalSpec(): Omit<DataViewSpec, 'fields'> {
// removes `fields`
const dataViewSpec = this.toSpec(false);

if (dataViewSpec.fieldAttrs) {
// removes `count` props (popularity scores) from `fieldAttrs`
dataViewSpec.fieldAttrs = pickBy(
mapValues(dataViewSpec.fieldAttrs, (fieldAttrs) => omit(fieldAttrs, 'count')),
(trimmedFieldAttrs) => Object.keys(trimmedFieldAttrs).length > 0
);

if (Object.keys(dataViewSpec.fieldAttrs).length === 0) {
dataViewSpec.fieldAttrs = undefined;
}
}

return dataViewSpec;
}

/**
* Get the source filtering configuration for that index.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export const getTopNavLinks = ({
...(savedSearch.id ? { savedSearchId: savedSearch.id } : {}),
...(dataView?.isPersisted()
? { dataViewId: dataView?.id }
: { dataViewSpec: dataView?.toSpec() }),
: { dataViewSpec: dataView?.toMinimalSpec() }),
filters,
timeRange,
refreshInterval,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ describe('Test discover state actions', () => {
timeFieldName: 'mock-time-field-name',
};
const dataViewsCreateMock = discoverServiceMock.dataViews.create as jest.Mock;
dataViewsCreateMock.mockImplementation(() => ({
dataViewsCreateMock.mockImplementationOnce(() => ({
...dataViewMock,
...dataViewSpecMock,
isPersisted: () => false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,6 @@ function createUrlGeneratorState({
viewMode: appState.viewMode,
hideAggregatedPreview: appState.hideAggregatedPreview,
breakdownField: appState.breakdownField,
dataViewSpec: !dataView?.isPersisted() ? dataView?.toSpec(false) : undefined,
dataViewSpec: !dataView?.isPersisted() ? dataView?.toMinimalSpec() : undefined,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* 2.0.
*/

import { omit, pickBy, mapValues } from 'lodash';
import { buildRangeFilter, Filter } from '@kbn/es-query';
import {
DataView,
Expand Down Expand Up @@ -221,19 +220,5 @@ function updateFilterReferences(filters: Filter[], fromDataView: string, toDataV
export function getSmallerDataViewSpec(
dataView: DataView
): DiscoverAppLocatorParams['dataViewSpec'] {
const dataViewSpec = dataView.toSpec(false);

if (dataViewSpec.fieldAttrs) {
// remove `count` props
dataViewSpec.fieldAttrs = pickBy(
mapValues(dataViewSpec.fieldAttrs, (fieldAttrs) => omit(fieldAttrs, 'count')),
(trimmedFieldAttrs) => Object.keys(trimmedFieldAttrs).length > 0
);

if (Object.keys(dataViewSpec.fieldAttrs).length === 0) {
dataViewSpec.fieldAttrs = undefined;
}
}

return dataViewSpec;
return dataView.toMinimalSpec();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
AlertInstanceMock,
} from '@kbn/alerting-plugin/server/mocks';
import { loggingSystemMock } from '@kbn/core/server/mocks';
import type { DataViewSpec } from '@kbn/data-views-plugin/common';
import { createStubDataView } from '@kbn/data-views-plugin/common/data_view.stub';
import { getRuleType } from './rule_type';
import { EsQueryRuleParams, EsQueryRuleState } from './rule_type_params';
import { ActionContext } from './action_context';
Expand Down Expand Up @@ -512,32 +514,31 @@ describe('ruleType', () => {
});

describe('search source query', () => {
const dataViewMock = {
id: 'test-id',
title: 'test-title',
timeFieldName: 'time-field',
fields: [
{
name: 'message',
type: 'string',
displayName: 'message',
scripted: false,
filterable: false,
aggregatable: false,
},
{
name: 'timestamp',
type: 'date',
displayName: 'timestamp',
scripted: false,
filterable: false,
aggregatable: false,
const dataViewMock = createStubDataView({
spec: {
id: 'test-id',
title: 'test-title',
timeFieldName: 'time-field',
fields: {
message: {
name: 'message',
type: 'string',
scripted: false,
searchable: false,
aggregatable: false,
readFromDocValues: false,
},
timestamp: {
name: 'timestamp',
type: 'date',
scripted: false,
searchable: true,
aggregatable: false,
readFromDocValues: false,
},
},
],
toSpec: () => {
return { id: 'test-id', title: 'test-title', timeFieldName: 'time-field' };
},
};
});
const defaultParams: OnlySearchSourceRuleParams = {
size: 100,
timeWindowSize: 5,
Expand Down Expand Up @@ -583,9 +584,9 @@ describe('ruleType', () => {
const searchResult: ESSearchResponse<unknown, {}> = generateResults([]);
const ruleServices: RuleExecutorServicesMock = alertsMock.createRuleExecutorServices();

(ruleServices.dataViews.create as jest.Mock).mockResolvedValueOnce({
toSpec: () => dataViewMock.toSpec(),
});
(ruleServices.dataViews.create as jest.Mock).mockImplementationOnce((spec: DataViewSpec) =>
createStubDataView({ spec })
);
(searchSourceInstanceMock.getField as jest.Mock).mockImplementation((name: string) => {
if (name === 'index') {
return dataViewMock;
Expand Down Expand Up @@ -620,9 +621,9 @@ describe('ruleType', () => {
const params = { ...defaultParams, thresholdComparator: Comparator.GT_OR_EQ, threshold: [3] };
const ruleServices: RuleExecutorServicesMock = alertsMock.createRuleExecutorServices();

(ruleServices.dataViews.create as jest.Mock).mockResolvedValueOnce({
toSpec: () => dataViewMock.toSpec(),
});
(ruleServices.dataViews.create as jest.Mock).mockImplementationOnce((spec: DataViewSpec) =>
createStubDataView({ spec })
);
(searchSourceInstanceMock.getField as jest.Mock).mockImplementation((name: string) => {
if (name === 'index') {
return dataViewMock;
Expand Down

0 comments on commit 6221b06

Please sign in to comment.