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

[Discover] Add "Hide chart" / "Show chart" persistence #88603

Merged
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
22 changes: 13 additions & 9 deletions src/plugins/discover/public/application/angular/discover.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ function discoverController($route, $scope, Promise) {
(prop) => !_.isEqual(newStatePartial[prop], oldStatePartial[prop])
);

if (oldStatePartial.hideChart && !newStatePartial.hideChart) {
// in case the histogram is hidden, no data is requested
// so when changing this state data needs to be fetched
changes.push(true);
}

if (changes.length) {
refetch$.next();
}
Expand Down Expand Up @@ -313,6 +319,8 @@ function discoverController($route, $scope, Promise) {
setAppState,
data,
stateContainer,
searchSessionManager,
refetch$,
};

const inspectorAdapters = ($scope.opts.inspectorAdapters = {
Expand Down Expand Up @@ -412,6 +420,9 @@ function discoverController($route, $scope, Promise) {
if (savedSearch.grid) {
defaultState.grid = savedSearch.grid;
}
if (savedSearch.hideChart) {
defaultState.hideChart = savedSearch.hideChart;
}

return defaultState;
}
Expand Down Expand Up @@ -562,13 +573,6 @@ function discoverController($route, $scope, Promise) {
});
};

$scope.handleRefresh = function (_payload, isUpdate) {
if (isUpdate === false) {
searchSessionManager.removeSearchSessionIdFromURL({ replace: false });
refetch$.next();
}
};

function getDimensions(aggs, timeRange) {
const [metric, agg] = aggs;
agg.params.timeRange = timeRange;
Expand Down Expand Up @@ -601,7 +605,7 @@ function discoverController($route, $scope, Promise) {
function onResults(resp) {
inspectorRequest.stats(getResponseInspectorStats(resp, $scope.searchSource)).ok({ json: resp });

if (getTimeField()) {
if (getTimeField() && !$scope.state.hideChart) {
const tabifiedData = tabifyAggResponse($scope.opts.chartAggConfigs, resp);
$scope.searchSource.rawResponse = resp;
$scope.histogramData = discoverResponseHandler(
Expand Down Expand Up @@ -704,7 +708,7 @@ function discoverController($route, $scope, Promise) {

async function setupVisualization() {
// If no timefield has been specified we don't create a histogram of messages
if (!getTimeField()) return;
if (!getTimeField() || $scope.state.hideChart) return;
const { interval: histogramInterval } = $scope.state;

const visStateAggs = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
state="state"
time-range="timeRange"
top-nav-menu="topNavMenu"
update-query="handleRefresh"
use-new-fields-api="useNewFieldsApi"
unmapped-fields-config="unmappedFieldsConfig"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ export interface AppState {
* Data Grid related state
*/
grid?: DiscoverGridSettings;
/**
* Hide chart
*/
hideChart?: boolean;
/**
* id of the used index pattern
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import { indexPatternWithTimefieldMock } from '../../__mocks__/index_pattern_wit
import { calcFieldCounts } from '../helpers/calc_field_counts';
import { DiscoverProps } from './types';
import { RequestAdapter } from '../../../../inspector/common';
import { Subject } from 'rxjs';
import { DiscoverSearchSessionManager } from '../angular/discover_search_session';

const mockNavigation = navigationPluginMock.createStartContract();

Expand Down Expand Up @@ -73,8 +75,10 @@ function getProps(indexPattern: IndexPattern): DiscoverProps {
indexPatternList: (indexPattern as unknown) as Array<SavedObject<IndexPatternAttributes>>,
inspectorAdapters: { requests: {} as RequestAdapter },
navigateTo: jest.fn(),
refetch$: {} as Subject<undefined>,
sampleSize: 10,
savedSearch: savedSearchMock,
searchSessionManager: {} as DiscoverSearchSessionManager,
setHeaderActionMenu: jest.fn(),
timefield: indexPattern.timeFieldName || '',
setAppState: jest.fn(),
Expand All @@ -86,7 +90,6 @@ function getProps(indexPattern: IndexPattern): DiscoverProps {
rows: esHits,
searchSource: searchSourceMock,
state: { columns: [] },
updateQuery: jest.fn(),
};
}

Expand Down
32 changes: 22 additions & 10 deletions src/plugins/discover/public/application/components/discover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import './discover.scss';
import React, { useCallback, useMemo, useRef, useState } from 'react';
import React, { useState, useRef, useMemo, useCallback } from 'react';
import {
EuiButtonEmpty,
EuiButtonIcon,
Expand Down Expand Up @@ -66,7 +66,6 @@ export function Discover({
searchSource,
state,
timeRange,
updateQuery,
unmappedFieldsConfig,
}: DiscoverProps) {
const [expandedDoc, setExpandedDoc] = useState<ElasticSearchHit | undefined>(undefined);
Expand All @@ -76,8 +75,11 @@ export function Discover({
// collapse icon isn't displayed in mobile view, use it to detect which view is displayed
return collapseIcon && !collapseIcon.current;
};

const [toggleOn, toggleChart] = useState(true);
const toggleHideChart = useCallback(() => {
const newState = { ...state, hideChart: !state.hideChart };
opts.stateContainer.setAppState(newState);
}, [state, opts]);
const hideChart = useMemo(() => state.hideChart, [state]);
const { savedSearch, indexPatternList, config, services, data, setAppState } = opts;
const { trackUiMetric, capabilities, indexPatterns } = services;
const [isSidebarClosed, setIsSidebarClosed] = useState(false);
Expand All @@ -89,6 +91,15 @@ export function Discover({
const contentCentered = resultState === 'uninitialized';
const isLegacy = services.uiSettings.get('doc_table:legacy');
const useNewFieldsApi = !services.uiSettings.get(SEARCH_FIELDS_FROM_SOURCE);
const updateQuery = useCallback(
(_payload, isUpdate?: boolean) => {
if (isUpdate === false) {
opts.searchSessionManager.removeSearchSessionIdFromURL({ replace: false });
opts.refetch$.next();
}
},
[opts]
);

const { onAddColumn, onRemoveColumn, onMoveColumn, onSetColumns } = useMemo(
() =>
Expand Down Expand Up @@ -192,7 +203,8 @@ export function Discover({
indexPattern={indexPattern}
opts={opts}
onOpenInspector={onOpenInspector}
state={state}
query={state.query}
savedQuery={state.savedQuery}
updateQuery={updateQuery}
/>
<EuiPageBody className="dscPageBody" aria-describedby="savedSearchTitle">
Expand Down Expand Up @@ -277,7 +289,7 @@ export function Discover({
onResetQuery={resetQuery}
/>
</EuiFlexItem>
{toggleOn && (
{!hideChart && (
<EuiFlexItem className="dscResultCount__actions">
<TimechartHeader
dateFormat={opts.config.get('dateFormat')}
Expand All @@ -293,13 +305,13 @@ export function Discover({
<EuiFlexItem className="dscResultCount__toggle" grow={false}>
<EuiButtonEmpty
size="xs"
iconType={toggleOn ? 'eyeClosed' : 'eye'}
iconType={!hideChart ? 'eyeClosed' : 'eye'}
onClick={() => {
toggleChart(!toggleOn);
toggleHideChart();
}}
data-test-subj="discoverChartToggle"
>
{toggleOn
{!hideChart
? i18n.translate('discover.hideChart', {
defaultMessage: 'Hide chart',
})
Expand All @@ -312,7 +324,7 @@ export function Discover({
</EuiFlexGroup>
{isLegacy && <SkipBottomButton onClick={onSkipBottomButtonClick} />}
</EuiFlexItem>
{toggleOn && opts.timefield && (
{!hideChart && opts.timefield && (
<EuiFlexItem grow={false}>
<section
aria-label={i18n.translate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import React from 'react';
import { mountWithIntl } from '@kbn/test/jest';
import { indexPatternMock } from '../../__mocks__/index_pattern';
import { DiscoverServices } from '../../build_services';
import { AppState, GetStateReturn } from '../angular/discover_state';
import { GetStateReturn } from '../angular/discover_state';
import { savedSearchMock } from '../../__mocks__/saved_search';
import { dataPluginMock } from '../../../../data/public/mocks';
import { createFilterManagerMock } from '../../../../data/public/query/filter_manager/filter_manager.mock';
Expand All @@ -20,9 +20,11 @@ import { SavedObject } from '../../../../../core/types';
import { DiscoverTopNav, DiscoverTopNavProps } from './discover_topnav';
import { RequestAdapter } from '../../../../inspector/common/adapters/request';
import { TopNavMenu } from '../../../../navigation/public';
import { Query } from '../../../../data/common';
import { DiscoverSearchSessionManager } from '../angular/discover_search_session';
import { Subject } from 'rxjs';

function getProps(): DiscoverTopNavProps {
const state = ({} as unknown) as AppState;
const services = ({
navigation: {
ui: { TopNavMenu },
Expand All @@ -45,15 +47,18 @@ function getProps(): DiscoverTopNavProps {
indexPatternList: (indexPattern as unknown) as Array<SavedObject<IndexPatternAttributes>>,
inspectorAdapters: { requests: {} as RequestAdapter },
navigateTo: jest.fn(),
refetch$: {} as Subject<undefined>,
sampleSize: 10,
savedSearch: savedSearchMock,
searchSessionManager: {} as DiscoverSearchSessionManager,
services,
setAppState: jest.fn(),
setHeaderActionMenu: jest.fn(),
stateContainer: {} as GetStateReturn,
timefield: indexPattern.timeFieldName || '',
},
state,
query: {} as Query,
savedQuery: '',
updateQuery: jest.fn(),
onOpenInspector: jest.fn(),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,21 @@
import React, { useMemo } from 'react';
import { DiscoverProps } from './types';
import { getTopNavLinks } from './top_nav/get_top_nav_links';
import { Query, TimeRange } from '../../../../data/common/query';

export type DiscoverTopNavProps = Pick<
DiscoverProps,
'indexPattern' | 'updateQuery' | 'state' | 'opts'
> & { onOpenInspector: () => void };
export type DiscoverTopNavProps = Pick<DiscoverProps, 'indexPattern' | 'opts'> & {
onOpenInspector: () => void;
query?: Query;
savedQuery?: string;
updateQuery: (payload: { dateRange: TimeRange; query?: Query }, isUpdate?: boolean) => void;
};

export const DiscoverTopNav = ({
indexPattern,
opts,
onOpenInspector,
state,
query,
savedQuery,
updateQuery,
}: DiscoverTopNavProps) => {
const showDatePicker = useMemo(() => indexPattern.isTimeBased(), [indexPattern]);
Expand Down Expand Up @@ -58,9 +62,9 @@ export const DiscoverTopNav = ({
indexPatterns={[indexPattern]}
onQuerySubmit={updateQuery}
onSavedQueryIdChange={updateSavedQueryId}
query={state.query}
query={query}
setMenuMountPoint={opts.setHeaderActionMenu}
savedQueryId={state.savedQuery}
savedQueryId={savedQuery}
screenTitle={opts.savedSearch.title}
showDatePicker={showDatePicker}
showSaveQuery={!!opts.services.capabilities.discover.saveQuery}
Expand Down
24 changes: 14 additions & 10 deletions src/plugins/discover/public/application/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { IUiSettingsClient, MountPoint, SavedObject } from 'kibana/public';
import { Subject } from 'rxjs';
import { Chart } from '../angular/helpers/point_series';
import { IndexPattern } from '../../../../data/common/index_patterns/index_patterns';
import { ElasticSearchHit } from '../doc_views/doc_views_types';
Expand All @@ -17,13 +18,12 @@ import {
FilterManager,
IndexPatternAttributes,
ISearchSource,
Query,
TimeRange,
} from '../../../../data/public';
import { SavedSearch } from '../../saved_searches';
import { AppState, GetStateReturn } from '../angular/discover_state';
import { RequestAdapter } from '../../../../inspector/common';
import { DiscoverServices } from '../../build_services';
import { DiscoverSearchSessionManager } from '../angular/discover_search_session';

export interface DiscoverProps {
/**
Expand Down Expand Up @@ -97,10 +97,18 @@ export interface DiscoverProps {
* List of available index patterns
*/
indexPatternList: Array<SavedObject<IndexPatternAttributes>>;
/**
* Refetch observable
*/
refetch$: Subject<undefined>;
/**
* Kibana core services used by discover
*/
services: DiscoverServices;
/**
* Helps with state management of search session
*/
searchSessionManager: DiscoverSearchSessionManager;
/**
* The number of documents that can be displayed in the table/grid
*/
Expand All @@ -113,10 +121,6 @@ export interface DiscoverProps {
* Function to set the header menu
*/
setHeaderActionMenu: (menuMount: MountPoint | undefined) => void;
/**
* Functions for retrieving/mutating state
*/
stateContainer: GetStateReturn;
/**
* Timefield of the currently used index pattern
*/
Expand All @@ -125,6 +129,10 @@ export interface DiscoverProps {
* Function to set the current state
*/
setAppState: (state: Partial<AppState>) => void;
/**
* State container providing globalState, appState and functions
*/
stateContainer: GetStateReturn;
};
/**
* Function to reset the current query
Expand All @@ -150,10 +158,6 @@ export interface DiscoverProps {
* Currently selected time range
*/
timeRange?: { from: string; to: string };
/**
* Function to update the actual query
*/
updateQuery: (payload: { dateRange: TimeRange; query?: Query }, isUpdate?: boolean) => void;
/**
* An object containing properties for proper handling of unmapped fields in the UI
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export async function persistSavedSearch(
if (state.grid) {
savedSearch.grid = state.grid;
}
if (state.hideChart) {
savedSearch.hideChart = state.hideChart;
}

try {
const id = await savedSearch.save(saveOptions);
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/discover/public/saved_searches/_saved_search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export function createSavedSearchClass(savedObjects: SavedObjectsStart) {
public static mapping = {
title: 'text',
description: 'text',
hideChart: 'boolean',
hits: 'integer',
columns: 'keyword',
grid: 'object',
Expand All @@ -35,6 +36,7 @@ export function createSavedSearchClass(savedObjects: SavedObjectsStart) {
mapping: {
title: 'text',
description: 'text',
hideChart: 'boolean',
hits: 'integer',
columns: 'keyword',
grid: 'object',
Expand Down
1 change: 1 addition & 0 deletions src/plugins/discover/public/saved_searches/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface SavedSearch {
lastSavedTitle?: string;
copyOnSave?: boolean;
pre712?: boolean;
hideChart?: boolean;
}
export interface SavedSearchLoader {
get: (id: string) => Promise<SavedSearch>;
Expand Down
Loading