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

[Observability] [Exploratory View] add chart creation context #114784

Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
67ba076
add chart creation context
dominiqueclarke Oct 13, 2021
c54d65b
Merge branch 'master' into feature/exploratory-view-chart-creation-co…
kibanamachine Oct 14, 2021
2aa3298
add chart creation tooltip, remove outer panel, and change default ch…
dominiqueclarke Oct 15, 2021
34820f8
merge branch 'feature/exploratory-view-chart-creation-context' of htt…
dominiqueclarke Oct 15, 2021
d6b167c
adjust types
dominiqueclarke Oct 18, 2021
0dcd843
Merge branch 'master' of github.com:elastic/kibana into feature/explo…
dominiqueclarke Oct 18, 2021
ceee445
remove extra translations
dominiqueclarke Oct 18, 2021
5fc5527
add panel back
dominiqueclarke Oct 18, 2021
1359b46
Merge branch 'master' into feature/exploratory-view-chart-creation-co…
kibanamachine Oct 19, 2021
71f01f6
update chart creation time date format
dominiqueclarke Oct 19, 2021
c28b204
Merge branch 'feature/exploratory-view-chart-creation-context' of htt…
dominiqueclarke Oct 19, 2021
c0e1e64
Merge branch 'master' into feature/exploratory-view-chart-creation-co…
kibanamachine Oct 19, 2021
db95dc3
update time format
dominiqueclarke Oct 19, 2021
bc7537a
Merge branch 'feature/exploratory-view-chart-creation-context' of htt…
dominiqueclarke Oct 19, 2021
162b0b4
adjust tests
dominiqueclarke Oct 19, 2021
20ea354
Merge branch 'master' into feature/exploratory-view-chart-creation-co…
kibanamachine Oct 19, 2021
7172556
Merge branch 'master' into feature/exploratory-view-chart-creation-co…
kibanamachine Oct 20, 2021
24cf0ab
Merge branch 'master' into feature/exploratory-view-chart-creation-co…
kibanamachine Oct 20, 2021
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
1 change: 1 addition & 0 deletions src/plugins/data/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ export const UI_SETTINGS = {
FILTERS_EDITOR_SUGGEST_VALUES: 'filterEditor:suggestValues',
AUTOCOMPLETE_USE_TIMERANGE: 'autocomplete:useTimeRange',
AUTOCOMPLETE_VALUE_SUGGESTION_METHOD: 'autocomplete:valueSuggestionMethod',
DATE_FORMAT: 'dateFormat',
} as const;
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import { i18n } from '@kbn/i18n';
import React, { useEffect, useRef, useState } from 'react';
import { EuiButtonEmpty, EuiPanel, EuiResizableContainer, EuiTitle } from '@elastic/eui';
import styled from 'styled-components';
import { EuiButtonEmpty, EuiResizableContainer, EuiTitle } from '@elastic/eui';
import { PanelDirection } from '@elastic/eui/src/components/resizable_container/types';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import { ObservabilityPublicPluginsStart } from '../../../plugin';
Expand All @@ -20,6 +20,7 @@ import { useAppIndexPatternContext } from './hooks/use_app_index_pattern';
import { SeriesViews } from './views/series_views';
import { LensEmbeddable } from './lens_embeddable';
import { EmptyView } from './components/empty_view';
import type { ChartTimeRange } from './header/last_updated';

export type PanelId = 'seriesPanel' | 'chartPanel';

Expand All @@ -37,7 +38,7 @@ export function ExploratoryView({

const [height, setHeight] = useState<string>('100vh');

const [lastUpdated, setLastUpdated] = useState<number | undefined>();
const [chartTimeRangeContext, setChartTimeRangeContext] = useState<ChartTimeRange | undefined>();

const [lensAttributes, setLensAttributes] = useState<TypedLensByValueInput['attributes'] | null>(
null
Expand Down Expand Up @@ -96,7 +97,10 @@ export function ExploratoryView({
<Wrapper>
{lens ? (
<>
<ExploratoryViewHeader lensAttributes={lensAttributes} lastUpdated={lastUpdated} />
<ExploratoryViewHeader
lensAttributes={lensAttributes}
chartTimeRange={chartTimeRangeContext}
/>
<LensWrapper ref={wrapperRef} height={height}>
<EuiResizableContainer
style={{ height: '100%' }}
Expand All @@ -116,7 +120,7 @@ export function ExploratoryView({
>
{lensAttributes ? (
<LensEmbeddable
setLastUpdated={setLastUpdated}
setChartTimeRangeContext={setChartTimeRangeContext}
lensAttributes={lensAttributes}
/>
) : (
Expand Down Expand Up @@ -176,7 +180,7 @@ const LensWrapper = styled.div<{ height: string }>`
height: 100%;
}
`;
const Wrapper = styled(EuiPanel)`
const Wrapper = styled.div`
max-width: 1800px;
min-width: 800px;
margin: 0 auto;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { screen } from '@testing-library/dom';
import { render } from '../rtl_helpers';
import * as kibanaSettings from '../../../../hooks/use_kibana_ui_settings';
import { ChartCreationInfo } from './chart_creation_info';

jest.spyOn(kibanaSettings, 'useKibanaUISettings').mockReturnValue('MMM D, YYYY @ HH:mm:ss.SSS');

const info = {
to: 1634071132571,
from: 1633406400000,
lastUpdated: 1634071140788,
};

describe('ChartCreationInfo', () => {
it('renders chart creation info', async () => {
render(<ChartCreationInfo {...info} />);

expect(screen.getByText('Chart created')).toBeInTheDocument();
expect(screen.getByText('Oct 12, 2021 @ 16:39:00.788')).toBeInTheDocument();
expect(screen.getByText('Displaying from')).toBeInTheDocument();
expect(
screen.getByText('Oct 5, 2021 @ 00:00:00.000 → Oct 12, 2021 @ 16:38:52.571')
).toBeInTheDocument();
});

it('does not display info when props are falsey', async () => {
render(<ChartCreationInfo />);

expect(screen.queryByText('Oct 12, 2021 @ 16:39:00.788')).not.toBeInTheDocument();
expect(
screen.queryByText('Oct 5, 2021 @ 00:00:00.000 → Oct 12, 2021 @ 16:38:52.571')
).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import moment from 'moment';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiFlexGroup, EuiFlexItem, EuiText, EuiSpacer } from '@elastic/eui';
import { UI_SETTINGS, useKibanaUISettings } from '../../../../hooks/use_kibana_ui_settings';
import type { ChartTimeRange } from './last_updated';

export function ChartCreationInfo(props: Partial<ChartTimeRange>) {
const dateFormat = useKibanaUISettings(UI_SETTINGS.DATE_FORMAT) as string;
const from = moment(props.from).format(dateFormat);
const to = moment(props.to).format(dateFormat);
const created = moment(props.lastUpdated).format(dateFormat);

return (
<>
{props.lastUpdated && (
<>
<EuiFlexGroup>
<EuiFlexItem>
<EuiText size="xs">
<FormattedMessage
id="xpack.observability.expView.seriesBuilder.creationTime"
defaultMessage="Chart created"
/>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={2}>
<EuiText size="xs">{created}</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="xs" />
</>
)}
{props.to && props.from && (
<>
<EuiFlexGroup alignItems="center">
<EuiFlexItem>
<EuiText size="xs">
<FormattedMessage
id="xpack.observability.expView.seriesBuilder.creationContext"
defaultMessage="Displaying from"
/>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={2}>
<EuiText size="xs">
{from} &#8594; {to}
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</>
)}
</>
);
}

export const LOADING_VIEW = i18n.translate(
'xpack.observability.expView.seriesBuilder.loadingView',
{
defaultMessage: 'Loading view ...',
}
);

export const SELECT_REPORT_TYPE = i18n.translate(
'xpack.observability.expView.seriesBuilder.selectReportType',
{
defaultMessage: 'No report type selected',
}
);

export const RESET_LABEL = i18n.translate('xpack.observability.expView.seriesBuilder.reset', {
defaultMessage: 'Reset',
});

export const REPORT_TYPE_LABEL = i18n.translate(
'xpack.observability.expView.seriesBuilder.reportType',
{
defaultMessage: 'Report type',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ import { i18n } from '@kbn/i18n';
import { EuiBetaBadge, EuiButton, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
import { TypedLensByValueInput } from '../../../../../../lens/public';
import { useSeriesStorage } from '../hooks/use_series_storage';
import { LastUpdated } from './last_updated';
import { ExpViewActionMenu } from '../components/action_menu';
import { useExpViewTimeRange } from '../hooks/use_time_range';
import { LastUpdated } from './last_updated';
import type { ChartTimeRange } from './last_updated';

interface Props {
lastUpdated?: number;
chartTimeRange?: ChartTimeRange;
lensAttributes: TypedLensByValueInput['attributes'] | null;
}

export function ExploratoryViewHeader({ lensAttributes, lastUpdated }: Props) {
export function ExploratoryViewHeader({ lensAttributes, chartTimeRange }: Props) {
const { setLastRefresh } = useSeriesStorage();

const timeRange = useExpViewTimeRange();
Expand All @@ -46,7 +47,7 @@ export function ExploratoryViewHeader({ lensAttributes, lastUpdated }: Props) {
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<LastUpdated lastUpdated={lastUpdated} />
<LastUpdated chartTimeRange={chartTimeRange} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton iconType="refresh" onClick={() => setLastRefresh(Date.now())}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,24 @@
*/

import React, { useEffect, useState } from 'react';
import { EuiIcon, EuiText } from '@elastic/eui';
import moment from 'moment';
import styled from 'styled-components';
import { EuiIcon, EuiText, EuiToolTip } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { ChartCreationInfo } from './chart_creation_info';

export interface ChartTimeRange {
lastUpdated: number;
to: number;
from: number;
}

interface Props {
lastUpdated?: number;
chartTimeRange?: ChartTimeRange;
}
export function LastUpdated({ lastUpdated }: Props) {

export function LastUpdated({ chartTimeRange }: Props) {
const { lastUpdated } = chartTimeRange || {};
const [refresh, setRefresh] = useState(() => Date.now());

useEffect(() => {
Expand All @@ -39,7 +49,13 @@ export function LastUpdated({ lastUpdated }: Props) {

return (
<EuiText color={isDanger ? 'danger' : isWarning ? 'warning' : 'subdued'} size="s">
<EuiIcon type="clock" />
<StyledToolTipWrapper
as={EuiToolTip}
position="top"
content={<ChartCreationInfo {...chartTimeRange} />}
>
<EuiIcon type="iInCircle" />
</StyledToolTipWrapper>{' '}
<FormattedMessage
id="xpack.observability.expView.lastUpdated.label"
defaultMessage="Last Updated: {updatedDate}"
Expand All @@ -50,3 +66,7 @@ export function LastUpdated({ lastUpdated }: Props) {
</EuiText>
);
}

export const StyledToolTipWrapper = styled.div`
min-width: 30vw;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ import { useSeriesStorage } from './hooks/use_series_storage';
import { ObservabilityPublicPluginsStart } from '../../../plugin';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import { useExpViewTimeRange } from './hooks/use_time_range';
import { parseRelativeDate } from './components/date_range_picker';
import type { ChartTimeRange } from './header/last_updated';

interface Props {
lensAttributes: TypedLensByValueInput['attributes'];
setLastUpdated: Dispatch<SetStateAction<number | undefined>>;
setChartTimeRangeContext: Dispatch<SetStateAction<ChartTimeRange | undefined>>;
}

export function LensEmbeddable(props: Props) {
const { lensAttributes, setLastUpdated } = props;
const { lensAttributes, setChartTimeRangeContext } = props;

const {
services: { lens, notifications },
Expand All @@ -35,8 +37,12 @@ export function LensEmbeddable(props: Props) {
const timeRange = useExpViewTimeRange();

const onLensLoad = useCallback(() => {
setLastUpdated(Date.now());
}, [setLastUpdated]);
setChartTimeRangeContext({
lastUpdated: Date.now(),
to: parseRelativeDate(timeRange?.to || '').valueOf(),
from: parseRelativeDate(timeRange?.from || '').valueOf(),
});
}, [setChartTimeRangeContext, timeRange]);

const onBrushEnd = useCallback(
({ range }: { range: number[] }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function ActionMenuContent(): React.ReactElement {
allSeries: [
{
dataType: 'synthetics',
seriesType: 'area_stacked',
seriesType: 'area',
selectedMetricField: 'monitor.duration.us',
time: { from: dateRangeStart, to: dateRangeEnd },
breakdown: monitorId ? 'observer.geo.name' : 'monitor.type',
Expand Down