Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dashboard De-Angular] Fix filter and query related functional tests in functional test group 3 #4495

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const DashboardEditor = () => {
savedDashboardInstance
);

const { dashboardContainer } = useDashboardContainer(
const { dashboardContainer, indexPatterns } = useDashboardContainer(
services,
isChromeVisible,
eventEmitter,
Expand Down Expand Up @@ -93,6 +93,7 @@ export const DashboardEditor = () => {
console.log('isDirty', dashboard.isDirty);
}
console.log('dashboardContainer', dashboardContainer);
console.log('indexPatterns', indexPatterns);

return (
<div>
Expand All @@ -109,6 +110,7 @@ export const DashboardEditor = () => {
dashboard={dashboard}
currentAppState={currentAppState}
isEmbeddableRendered={isEmbeddableRendered}
indexPatterns={indexPatterns}
dashboardContainer={dashboardContainer}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { uniqBy } from 'lodash';
import React, { memo, useState, useEffect } from 'react';
import { Filter, IndexPattern } from 'src/plugins/data/public';
import { useCallback } from 'react';
Expand All @@ -13,7 +12,6 @@ import { getTopNavConfig } from '../top_nav/get_top_nav_config';
import { DashboardAppStateContainer, DashboardAppState, DashboardServices } from '../../types';
import { getNavActions } from '../utils/get_nav_actions';
import { DashboardContainer } from '../embeddable';
import { isErrorEmbeddable } from '../../embeddable_plugin';
import { Dashboard } from '../../dashboard';

interface DashboardTopNavProps {
Expand All @@ -23,6 +21,7 @@ interface DashboardTopNavProps {
dashboard: Dashboard;
currentAppState: DashboardAppState;
isEmbeddableRendered: boolean;
indexPatterns: IndexPattern[];
dashboardContainer?: DashboardContainer;
}

Expand All @@ -42,16 +41,14 @@ const TopNav = ({
currentAppState,
isEmbeddableRendered,
dashboardContainer,
indexPatterns,
}: DashboardTopNavProps) => {
const [filters, setFilters] = useState<Filter[]>([]);
const [topNavMenu, setTopNavMenu] = useState<any>();
const [isFullScreenMode, setIsFullScreenMode] = useState<any>();
const [indexPatterns, setIndexPatterns] = useState<IndexPattern[]>();

const { services } = useOpenSearchDashboards<DashboardServices>();
const { TopNavMenu } = services.navigation.ui;
const { data, dashboardConfig, setHeaderActionMenu } = services;
const { query: queryService } = data;
const { dashboardConfig, setHeaderActionMenu } = services;

const location = useLocation();
const queryParameters = new URLSearchParams(location.search);
Expand All @@ -76,10 +73,6 @@ const TopNav = ({
const shouldShowNavBarComponent = (forceShow: boolean): boolean =>
(forceShow || isChromeVisible) && !currentAppState?.fullScreenMode;

useEffect(() => {
setFilters(queryService.filterManager.getFilters());
}, [services, queryService]);

useEffect(() => {
if (isEmbeddableRendered) {
const navActions = getNavActions(
Expand Down Expand Up @@ -112,33 +105,6 @@ const TopNav = ({
setIsFullScreenMode(currentAppState?.fullScreenMode);
}, [currentAppState, services]);

useEffect(() => {
const asyncSetIndexPattern = async () => {
if (dashboardContainer) {
let panelIndexPatterns: IndexPattern[] = [];
dashboardContainer.getChildIds().forEach((id) => {
const embeddableInstance = dashboardContainer.getChild(id);
if (isErrorEmbeddable(embeddableInstance)) return;
const embeddableIndexPatterns = (embeddableInstance.getOutput() as any).indexPatterns;
if (!embeddableIndexPatterns) return;
panelIndexPatterns.push(...embeddableIndexPatterns);
});
panelIndexPatterns = uniqBy(panelIndexPatterns, 'id');

if (panelIndexPatterns.length > 0) {
setIndexPatterns(panelIndexPatterns);
} else {
const defaultIndex = await services.data.indexPatterns.getDefault();
if (defaultIndex) {
setIndexPatterns([defaultIndex]);
}
}
}
};

asyncSetIndexPattern();
}, [dashboardContainer, stateContainer, currentAppState, services.data.indexPatterns]);

const shouldShowFilterBar = (forceHide: boolean): boolean =>
!forceHide && (currentAppState.filters!.length > 0 || !currentAppState?.fullScreenMode);

Expand All @@ -156,7 +122,6 @@ const TopNav = ({
return (
<TopNavMenu
appName={'dashboard'}
savedQueryId={currentAppState?.savedQuery}
config={showTopNavMenu ? topNavMenu : undefined}
className={isFullScreenMode ? 'osdTopNavMenu-isFullScreen' : undefined}
screenTitle={currentAppState.title}
Expand All @@ -169,7 +134,10 @@ const TopNav = ({
indexPatterns={indexPatterns}
showSaveQuery={services.dashboardCapabilities.saveQuery as boolean}
savedQuery={undefined}
onSavedQueryIdChange={() => {}}
onSavedQueryIdChange={(savedQueryId?: string) => {
stateContainer.transitions.set('savedQuery', savedQueryId);
}}
savedQueryId={currentAppState?.savedQuery}
onQuerySubmit={handleRefresh}
setMenuMountPoint={isEmbeddedExternally ? undefined : setHeaderActionMenu}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { SavedObjectSaveOpts } from 'src/plugins/saved_objects/public';
import { updateSavedDashboard } from './update_saved_dashboard';

import { DashboardAppStateContainer } from '../../types';
import { Dashboard } from '../../dashboard';

/**
* Saves the dashboard.
Expand All @@ -43,11 +44,12 @@ export function saveDashboard(
timeFilter: TimefilterContract,
stateContainer: DashboardAppStateContainer,
savedDashboard: any,
saveOptions: SavedObjectSaveOpts
saveOptions: SavedObjectSaveOpts,
dashboard: Dashboard
): Promise<string> {
const appState = stateContainer.getState();

updateSavedDashboard(savedDashboard, appState, timeFilter);
updateSavedDashboard(savedDashboard, appState, timeFilter, dashboard);

return savedDashboard.save(saveOptions).then((id: string) => {
if (id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,37 @@ import { FilterUtils } from './filter_utils';
import { SavedObjectDashboard } from '../../saved_dashboards';
import { DashboardAppState } from '../../types';
import { opensearchFilters } from '../../../../data/public';
import { Dashboard } from '../../dashboard';

export function updateSavedDashboard(
savedDashboard: SavedObjectDashboard,
appState: DashboardAppState,
timeFilter: TimefilterContract
timeFilter: TimefilterContract,
dashboard: Dashboard
) {
savedDashboard.title = appState.title;
savedDashboard.description = appState.description;
savedDashboard.timeRestore = appState.timeRestore;
savedDashboard.panelsJSON = JSON.stringify(appState.panels);
savedDashboard.optionsJSON = JSON.stringify(appState.options);

savedDashboard.timeFrom = savedDashboard.timeRestore
const timeFrom = savedDashboard.timeRestore
? FilterUtils.convertTimeToUTCString(timeFilter.getTime().from)
: undefined;
savedDashboard.timeTo = savedDashboard.timeRestore
const timeTo = savedDashboard.timeRestore
? FilterUtils.convertTimeToUTCString(timeFilter.getTime().to)
: undefined;

const timeRestoreObj: RefreshInterval = _.pick(timeFilter.getRefreshInterval(), [
'display',
'pause',
'section',
'value',
]) as RefreshInterval;
savedDashboard.refreshInterval = savedDashboard.timeRestore ? timeRestoreObj : undefined;
const refreshInterval = savedDashboard.timeRestore ? timeRestoreObj : undefined;
savedDashboard.timeFrom = timeFrom;
savedDashboard.timeTo = timeTo;
savedDashboard.refreshInterval = refreshInterval;

// save only unpinned filters
const unpinnedFilters = appState.filters.filter(
Expand All @@ -68,4 +74,17 @@ export function updateSavedDashboard(

// save the queries
savedDashboard.searchSource.setField('query', appState.query as Query);

dashboard.setState({
title: appState.title,
description: appState.description,
timeRestore: appState.timeRestore,
panels: appState.panels,
options: appState.options,
timeFrom,
timeTo,
refreshInterval,
query: appState.query as Query,
filters: unpinnedFilters,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,13 @@ export const getNavActions = (
async function save(saveOptions: SavedObjectSaveOpts) {
const timefilter = queryService.timefilter.timefilter;
try {
const id = await saveDashboard(timefilter, stateContainer, savedDashboard, saveOptions);
const id = await saveDashboard(
timefilter,
stateContainer,
savedDashboard,
saveOptions,
dashboard
);

if (id) {
notifications.toasts.addSuccess({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import React, { useState } from 'react';
import { cloneDeep, isEqual } from 'lodash';
import { cloneDeep, isEqual, uniqBy } from 'lodash';
import { EMPTY, Observable, Subscription, merge, of, pipe } from 'rxjs';
import {
catchError,
Expand Down Expand Up @@ -62,6 +62,7 @@ export const useDashboardContainer = (
appState?: DashboardAppStateContainer
) => {
const [dashboardContainer, setDashboardContainer] = useState<DashboardContainer>();
const [indexPatterns, setIndexPatterns] = useState<IndexPattern[]>([]);

useEffect(() => {
const getDashboardContainer = async () => {
Expand All @@ -71,7 +72,8 @@ export const useDashboardContainer = (
savedDashboardInstance,
services,
appState,
dashboard
dashboard,
setIndexPatterns
);

setDashboardContainer(dashboardContainerEmbeddable);
Expand Down Expand Up @@ -105,14 +107,15 @@ export const useDashboardContainer = (
}
}, [dashboardContainer, services]);

return { dashboardContainer };
return { dashboardContainer, indexPatterns };
};

const createDashboardEmbeddable = (
savedDash: any,
dashboardServices: DashboardServices,
appState: DashboardAppStateContainer,
dashboard: Dashboard
dashboard: Dashboard,
setIndexPatterns: React.Dispatch<React.SetStateAction<IndexPattern[]>>
) => {
let dashboardContainer: DashboardContainer;
let inputSubscription: Subscription | undefined;
Expand Down Expand Up @@ -240,6 +243,45 @@ const createDashboardEmbeddable = (
expandedPanelId: appStateData.expandedPanelId,
};
};
const setCurrentIndexPatterns = () => {
let panelIndexPatterns: IndexPattern[] = [];
dashboardContainer.getChildIds().forEach((id) => {
const embeddableInstance = dashboardContainer.getChild(id);
if (isErrorEmbeddable(embeddableInstance)) return;
const embeddableIndexPatterns = (embeddableInstance.getOutput() as any).indexPatterns;
if (!embeddableIndexPatterns) return;
panelIndexPatterns.push(...embeddableIndexPatterns);
});
panelIndexPatterns = uniqBy(panelIndexPatterns, 'id');
return panelIndexPatterns;
};

const updateIndexPatternsOperator = pipe(
filter((container: DashboardContainer) => !!container && !isErrorEmbeddable(container)),
map(setCurrentIndexPatterns),
distinctUntilChanged((a, b) =>
deepEqual(
a.map((ip) => ip.id),
b.map((ip) => ip.id)
)
),
// using switchMap for previous task cancellation
switchMap((panelIndexPatterns: IndexPattern[]) => {
return new Observable((observer) => {
if (panelIndexPatterns && panelIndexPatterns.length > 0) {
if (observer.closed) return;
setIndexPatterns(panelIndexPatterns);
observer.complete();
} else {
data.indexPatterns.getDefault().then((defaultIndexPattern) => {
if (observer.closed) return;
setIndexPatterns([defaultIndexPattern as IndexPattern]);
observer.complete();
});
}
});
})
);

if (dashboardFactory) {
return dashboardFactory
Expand Down Expand Up @@ -321,7 +363,8 @@ const createDashboardEmbeddable = (
)
.pipe(
mapTo(dashboardContainer),
startWith(dashboardContainer) // to trigger initial index pattern update
startWith(dashboardContainer), // to trigger initial index pattern update
updateIndexPatternsOperator
)
.subscribe();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ export const useEditorUpdates = (
if (changes) {
dashboardContainer.updateInput(changes);

if (changes.filters || changes.query || changes.timeRange || changes.refreshConfig) {
if (changes.timeRange || changes.refreshConfig) {
if (dashboardInstance.timeRestore) {
dashboard.isDirty = true;
}
}

if (changes.filters || changes.query) {
dashboard.isDirty = true;
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/plugins/dashboard/public/dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class Dashboard<TDashboardParams = DashboardParams> {
this.filters = cloneDeep(dashboardState.filters);
}

async setState(state: PartialDashboardState) {
setState(state: PartialDashboardState) {
if (state.id) {
this.id = state.id;
}
Expand Down Expand Up @@ -109,12 +109,12 @@ export class Dashboard<TDashboardParams = DashboardParams> {
if (state.searchSource) {
this.searchSource = state.searchSource;
}
// if (state.query) {
// this.query = this.getQuery(state.query);
// }
// if (state.filters) {
// this.filters = this.getFilters(state.filters);
// }
if (state.query) {
this.query = state.query;
}
if (state.filters) {
this.filters = state.filters;
}
}

public setIsDirty(value: boolean) {
Expand Down
Loading