Skip to content

Commit 82a6d39

Browse files
authored
[Discover] Modify columns and sort when switching index pattern (#74336)
* Modify columns and sort when switching index pattern * Add unit tests * Add uiSetting to allow switch to legacy behavior
1 parent 6f98372 commit 82a6d39

File tree

5 files changed

+168
-3
lines changed

5 files changed

+168
-3
lines changed

src/plugins/discover/common/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ export const FIELDS_LIMIT_SETTING = 'fields:popularLimit';
2727
export const CONTEXT_DEFAULT_SIZE_SETTING = 'context:defaultSize';
2828
export const CONTEXT_STEP_SETTING = 'context:step';
2929
export const CONTEXT_TIE_BREAKER_FIELDS_SETTING = 'context:tieBreakerFields';
30+
export const MODIFY_COLUMNS_ON_SWITCH = 'discover:modifyColumnsOnSwitch';

src/plugins/discover/public/application/angular/discover.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const {
7171
import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../helpers/breadcrumbs';
7272
import { validateTimeRange } from '../helpers/validate_time_range';
7373
import { popularizeField } from '../helpers/popularize_field';
74-
74+
import { getSwitchIndexPatternAppState } from '../helpers/get_switch_index_pattern_app_state';
7575
import { getIndexPatternId } from '../helpers/get_index_pattern_id';
7676
import { addFatalError } from '../../../../kibana_legacy/public';
7777
import {
@@ -80,6 +80,7 @@ import {
8080
SORT_DEFAULT_ORDER_SETTING,
8181
SEARCH_ON_PAGE_LOAD_SETTING,
8282
DOC_HIDE_TIME_COLUMN_SETTING,
83+
MODIFY_COLUMNS_ON_SWITCH,
8384
} from '../../../common';
8485

8586
const fetchStatuses = {
@@ -253,6 +254,11 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
253254

254255
if (!_.isEqual(newStatePartial, oldStatePartial)) {
255256
$scope.$evalAsync(async () => {
257+
if (oldStatePartial.index !== newStatePartial.index) {
258+
//in case of index switch the route has currently to be reloaded, legacy
259+
return;
260+
}
261+
256262
$scope.state = { ...newState };
257263

258264
// detect changes that should trigger fetching of new data
@@ -277,8 +283,18 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
277283
});
278284

279285
$scope.setIndexPattern = async (id) => {
280-
await replaceUrlAppState({ index: id });
281-
$route.reload();
286+
const nextIndexPattern = await indexPatterns.get(id);
287+
if (nextIndexPattern) {
288+
const nextAppState = getSwitchIndexPatternAppState(
289+
$scope.indexPattern,
290+
nextIndexPattern,
291+
$scope.state.columns,
292+
$scope.state.sort,
293+
config.get(MODIFY_COLUMNS_ON_SWITCH)
294+
);
295+
await replaceUrlAppState(nextAppState);
296+
$route.reload();
297+
}
282298
};
283299

284300
// update data source when filters update
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import { getSwitchIndexPatternAppState } from './get_switch_index_pattern_app_state';
21+
import { IIndexPatternFieldList, IndexPattern } from '../../../../data/common/index_patterns';
22+
23+
const currentIndexPattern: IndexPattern = {
24+
id: 'prev',
25+
getFieldByName(name) {
26+
return this.fields.getByName(name);
27+
},
28+
fields: {
29+
getByName: (name: string) => {
30+
const fields = [
31+
{ name: 'category', sortable: true },
32+
{ name: 'name', sortable: true },
33+
] as IIndexPatternFieldList;
34+
return fields.find((field) => field.name === name);
35+
},
36+
},
37+
} as IndexPattern;
38+
39+
const nextIndexPattern = {
40+
id: 'next',
41+
getFieldByName(name) {
42+
return this.fields.getByName(name);
43+
},
44+
fields: {
45+
getByName: (name: string) => {
46+
const fields = [{ name: 'category', sortable: true }] as IIndexPatternFieldList;
47+
return fields.find((field) => field.name === name);
48+
},
49+
},
50+
} as IndexPattern;
51+
52+
describe('Discover getSwitchIndexPatternAppState', () => {
53+
test('removing fields that are not part of the next index pattern, keeping unknown fields ', async () => {
54+
const result = getSwitchIndexPatternAppState(
55+
currentIndexPattern,
56+
nextIndexPattern,
57+
['category', 'name', 'unknown'],
58+
[['category', 'desc']]
59+
);
60+
expect(result.columns).toEqual(['category', 'unknown']);
61+
expect(result.sort).toEqual([['category', 'desc']]);
62+
});
63+
test('removing sorted by fields that are not part of the next index pattern', async () => {
64+
const result = getSwitchIndexPatternAppState(
65+
currentIndexPattern,
66+
nextIndexPattern,
67+
['name'],
68+
[
69+
['category', 'desc'],
70+
['name', 'asc'],
71+
]
72+
);
73+
expect(result.columns).toEqual(['_source']);
74+
expect(result.sort).toEqual([['category', 'desc']]);
75+
});
76+
test('removing sorted by fields that without modifying columns', async () => {
77+
const result = getSwitchIndexPatternAppState(
78+
currentIndexPattern,
79+
nextIndexPattern,
80+
['name'],
81+
[
82+
['category', 'desc'],
83+
['name', 'asc'],
84+
],
85+
false
86+
);
87+
expect(result.columns).toEqual(['name']);
88+
expect(result.sort).toEqual([['category', 'desc']]);
89+
});
90+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
import { getSortArray } from '../angular/doc_table';
20+
import { SortPairArr } from '../angular/doc_table/lib/get_sort';
21+
import { IndexPattern } from '../../kibana_services';
22+
23+
/**
24+
* Helper function to remove or adapt the currently selected columns/sort to be valid with the next
25+
* index pattern, returns a new state object
26+
*/
27+
export function getSwitchIndexPatternAppState(
28+
currentIndexPattern: IndexPattern,
29+
nextIndexPattern: IndexPattern,
30+
currentColumns: string[],
31+
currentSort: SortPairArr[],
32+
modifyColumns: boolean = true
33+
) {
34+
const nextColumns = modifyColumns
35+
? currentColumns.filter(
36+
(column) =>
37+
nextIndexPattern.fields.getByName(column) || !currentIndexPattern.fields.getByName(column)
38+
)
39+
: currentColumns;
40+
const nextSort = getSortArray(currentSort, nextIndexPattern);
41+
return {
42+
index: nextIndexPattern.id,
43+
columns: nextColumns.length ? nextColumns : ['_source'],
44+
sort: nextSort,
45+
};
46+
}

src/plugins/discover/server/ui_settings.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
CONTEXT_DEFAULT_SIZE_SETTING,
3333
CONTEXT_STEP_SETTING,
3434
CONTEXT_TIE_BREAKER_FIELDS_SETTING,
35+
MODIFY_COLUMNS_ON_SWITCH,
3536
} from '../common';
3637

3738
export const uiSettings: Record<string, UiSettingsParams> = {
@@ -163,4 +164,15 @@ export const uiSettings: Record<string, UiSettingsParams> = {
163164
category: ['discover'],
164165
schema: schema.arrayOf(schema.string()),
165166
},
167+
[MODIFY_COLUMNS_ON_SWITCH]: {
168+
name: i18n.translate('discover.advancedSettings.discover.modifyColumnsOnSwitchTitle', {
169+
defaultMessage: 'Modify columns when changing index patterns',
170+
}),
171+
value: true,
172+
description: i18n.translate('discover.advancedSettings.discover.modifyColumnsOnSwitchText', {
173+
defaultMessage: 'Remove columns that not available in the new index pattern.',
174+
}),
175+
category: ['discover'],
176+
schema: schema.boolean(),
177+
},
166178
};

0 commit comments

Comments
 (0)