mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Drilldowns] Fix back button by removing panels from url in dashboard in view mode (#62415) (#63923)
* remove panels from url * review nits Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
13222a547b
commit
2c2a95d859
5 changed files with 82 additions and 4 deletions
|
@ -34,6 +34,7 @@ import { FilterUtils } from './lib/filter_utils';
|
|||
import {
|
||||
DashboardAppState,
|
||||
DashboardAppStateDefaults,
|
||||
DashboardAppStateInUrl,
|
||||
DashboardAppStateTransitions,
|
||||
SavedDashboardPanel,
|
||||
} from '../types';
|
||||
|
@ -165,11 +166,12 @@ export class DashboardStateManager {
|
|||
});
|
||||
|
||||
// setup state syncing utils. state container will be synced with url into `this.STATE_STORAGE_KEY` query param
|
||||
this.stateSyncRef = syncState<DashboardAppState>({
|
||||
this.stateSyncRef = syncState<DashboardAppStateInUrl>({
|
||||
storageKey: this.STATE_STORAGE_KEY,
|
||||
stateContainer: {
|
||||
...this.stateContainer,
|
||||
set: (state: DashboardAppState | null) => {
|
||||
get: () => this.toUrlState(this.stateContainer.get()),
|
||||
set: (state: DashboardAppStateInUrl | null) => {
|
||||
// sync state required state container to be able to handle null
|
||||
// overriding set() so it could handle null coming from url
|
||||
if (state) {
|
||||
|
@ -558,9 +560,9 @@ export class DashboardStateManager {
|
|||
*/
|
||||
private saveState({ replace }: { replace: boolean }): boolean {
|
||||
// schedules setting current state to url
|
||||
this.kbnUrlStateStorage.set<DashboardAppState>(
|
||||
this.kbnUrlStateStorage.set<DashboardAppStateInUrl>(
|
||||
this.STATE_STORAGE_KEY,
|
||||
this.stateContainer.get()
|
||||
this.toUrlState(this.stateContainer.get())
|
||||
);
|
||||
// immediately forces scheduled updates and changes location
|
||||
return this.kbnUrlStateStorage.flush({ replace });
|
||||
|
@ -620,4 +622,13 @@ export class DashboardStateManager {
|
|||
const current = _.omit(this.stateContainer.get(), propsToIgnore);
|
||||
return !_.isEqual(initial, current);
|
||||
}
|
||||
|
||||
private toUrlState(state: DashboardAppState): DashboardAppStateInUrl {
|
||||
if (state.viewMode === ViewMode.VIEW) {
|
||||
const { panels, ...stateWithoutPanels } = state;
|
||||
return stateWithoutPanels;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,6 +152,14 @@ export type DashboardAppStateDefaults = DashboardAppState & {
|
|||
description?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* In URL panels are optional,
|
||||
* Panels are not added to the URL when in "view" mode
|
||||
*/
|
||||
export type DashboardAppStateInUrl = Omit<DashboardAppState, 'panels'> & {
|
||||
panels?: SavedDashboardPanel[];
|
||||
};
|
||||
|
||||
export interface DashboardAppStateTransitions {
|
||||
set: (
|
||||
state: DashboardAppState
|
||||
|
|
47
test/functional/apps/dashboard/dashboard_back_button.ts
Normal file
47
test/functional/apps/dashboard/dashboard_back_button.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const PageObjects = getPageObjects(['dashboard', 'header', 'common', 'visualize', 'timePicker']);
|
||||
const browser = getService('browser');
|
||||
|
||||
describe('dashboard back button', () => {
|
||||
before(async () => {
|
||||
await esArchiver.loadIfNeeded('dashboard/current/kibana');
|
||||
await kibanaServer.uiSettings.replace({
|
||||
defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c',
|
||||
});
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.preserveCrossAppState();
|
||||
});
|
||||
|
||||
it('after navigation from listing page to dashboard back button works', async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.loadSavedDashboard('dashboard with everything');
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await browser.goBack();
|
||||
expect(await PageObjects.dashboard.onDashboardLandingPage()).to.be(true);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -55,6 +55,7 @@ export default function({ getService, loadTestFile }) {
|
|||
loadTestFile(require.resolve('./dashboard_options'));
|
||||
loadTestFile(require.resolve('./data_shared_attributes'));
|
||||
loadTestFile(require.resolve('./embed_mode'));
|
||||
loadTestFile(require.resolve('./dashboard_back_button'));
|
||||
|
||||
// Note: This one must be last because it unloads some data for one of its tests!
|
||||
// No, this isn't ideal, but loading/unloading takes so much time and these are all bunched
|
||||
|
|
|
@ -13,6 +13,7 @@ export default function({ getPageObjects, getService }) {
|
|||
const dashboardPanelActions = getService('dashboardPanelActions');
|
||||
const inspector = getService('inspector');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const browser = getService('browser');
|
||||
|
||||
describe('embed in dashboard', () => {
|
||||
before(async () => {
|
||||
|
@ -111,5 +112,15 @@ export default function({ getPageObjects, getService }) {
|
|||
const afterRefreshTimerTimestamp = await getRequestTimestamp();
|
||||
expect(beforeRefreshTimerTimestamp).not.to.equal(afterRefreshTimerTimestamp);
|
||||
});
|
||||
|
||||
// see https://github.com/elastic/kibana/issues/61596 on why it is specific to maps
|
||||
it("dashboard's back button should navigate to previous page", async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.preserveCrossAppState();
|
||||
await PageObjects.dashboard.loadSavedDashboard('map embeddable example');
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await browser.goBack();
|
||||
expect(await PageObjects.dashboard.onDashboardLandingPage()).to.be(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue