Skip to content

Commit

Permalink
Fix time range badges in Canvas
Browse files Browse the repository at this point in the history
  • Loading branch information
nickpeihl committed Jan 30, 2023
1 parent ae7d063 commit 10bda3c
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { canInheritTimeRange } from './can_inherit_time_range';
import {
HelloWorldContainer,
TimeRangeContainer,
TimeRangeEmbeddable,
} from '../../../../test_samples';
import { HelloWorldEmbeddable } from '../../../../../tests/fixtures';

test('canInheritTimeRange returns false if embeddable is inside container without a time range', () => {
const embeddable = new TimeRangeEmbeddable(
{ id: '1234', timeRange: { from: 'noxw-15m', to: 'now' } },
new HelloWorldContainer({ id: '123', panels: {} }, {})
);

expect(canInheritTimeRange(embeddable)).toBe(false);
});

test('canInheritTimeRange returns false if embeddable is without a time range', () => {
const embeddable = new HelloWorldEmbeddable(
{ id: '1234' },
new HelloWorldContainer({ id: '123', panels: {} }, {})
);
// @ts-ignore
expect(canInheritTimeRange(embeddable)).toBe(false);
});

test('canInheritTimeRange returns true if embeddable is inside a container with a time range', () => {
const embeddable = new TimeRangeEmbeddable(
{ id: '1234', timeRange: { from: 'noxw-15m', to: 'now' } },
new TimeRangeContainer(
{ id: '123', panels: {}, timeRange: { from: 'noxw-15m', to: 'now' } },
() => undefined
)
);
expect(canInheritTimeRange(embeddable)).toBe(true);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import type { TimeRange } from '@kbn/es-query';
import { Embeddable, IContainer, ContainerInput } from '../../../../..';
import { TimeRangeInput } from './customize_panel_action';

interface ContainerTimeRangeInput extends ContainerInput<TimeRangeInput> {
timeRange: TimeRange;
}

export function canInheritTimeRange(embeddable: Embeddable<TimeRangeInput>) {
if (!embeddable.parent) {
return false;
}

const parent = embeddable.parent as IContainer<TimeRangeInput, ContainerTimeRangeInput>;

return parent.getInput().timeRange !== undefined;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { TimeRange } from '@kbn/es-query';
import { hasTimeRange, TimeRangeInput } from './customize_panel_action';
import { doesInheritTimeRange } from './does_inherit_time_range';
import { IEmbeddable, Embeddable, EmbeddableOutput, CommonlyUsedRange } from '../../../..';
import { canInheritTimeRange } from './can_inherit_time_range';

type PanelSettings = {
title?: string;
Expand Down Expand Up @@ -67,17 +68,12 @@ function isTimeRangeCompatible(embeddable: IEmbeddable) {
const isImage = embeddable.type === 'image';

return Boolean(
embeddable &&
embeddable.parent &&
hasTimeRange(embeddable) &&
!isInputControl &&
!isMarkdown &&
!isImage
embeddable && hasTimeRange(embeddable) && !isInputControl && !isMarkdown && !isImage
);
}

export const CustomizePanelEditor = (props: CustomizePanelProps) => {
const { onClose, embeddable } = props;
const { onClose, embeddable, dateFormat } = props;
const timeRangeCompatible = isTimeRangeCompatible(embeddable);
const [hideTitle, setHideTitle] = useState(embeddable.getInput().hidePanelTitles);
const [panelDescription, setPanelDescription] = useState(
Expand Down Expand Up @@ -123,6 +119,51 @@ export const CustomizePanelEditor = (props: CustomizePanelProps) => {
onClose();
};

const renderCustomTimeRangeComponent = () => {
if (!timeRangeCompatible) return null;

return (
<>
{canInheritTimeRange(embeddable as Embeddable<TimeRangeInput>) ? (
<EuiFormRow>
<EuiSwitch
checked={!inheritTimeRange}
data-test-subj="customizePanelShowCustomTimeRange"
id="showCustomTimeRange"
label={
<FormattedMessage
defaultMessage="Apply custom time range to panel"
id="embeddableApi.customizePanel.flyout.optionsMenuForm.showCustomTimeRangeSwitch"
/>
}
onChange={(e) => setInheritTimeRange(!e.target.checked)}
/>
</EuiFormRow>
) : null}
{!inheritTimeRange ? (
<EuiFormRow
label={
<FormattedMessage
id="embeddableApi.customizePanel.flyout.optionsMenuForm.panelTimeRangeFormRowLabel"
defaultMessage="Panel time range"
/>
}
>
<EuiSuperDatePicker
start={panelTimeRange?.from ?? undefined}
end={panelTimeRange?.to ?? undefined}
onTimeChange={({ start, end }) => setPanelTimeRange({ from: start, to: end })}
showUpdateButton={false}
dateFormat={dateFormat}
commonlyUsedRanges={commonlyUsedRangesForDatePicker}
data-test-subj="customizePanelTimeRangeDatePicker"
/>
</EuiFormRow>
) : null}
</>
);
};

return (
<>
<EuiFlyoutHeader hasBorder>
Expand Down Expand Up @@ -240,50 +281,13 @@ export const CustomizePanelEditor = (props: CustomizePanelProps) => {
)}
/>
</EuiFormRow>
{timeRangeCompatible ? (
<>
<EuiFormRow>
<EuiSwitch
checked={!inheritTimeRange}
data-test-subj="customizePanelShowCustomTimeRange"
id="showCustomTimeRange"
label={
<FormattedMessage
defaultMessage="Apply custom time range to panel"
id="embeddableApi.customizePanel.flyout.optionsMenuForm.showCustomTimeRangeSwitch"
/>
}
onChange={(e) => setInheritTimeRange(!e.target.checked)}
/>
</EuiFormRow>
{!inheritTimeRange ? (
<EuiFormRow
label={
<FormattedMessage
id="embeddableApi.customizePanel.flyout.optionsMenuForm.panelTimeRangeFormRowLabel"
defaultMessage="Panel time range"
/>
}
>
<EuiSuperDatePicker
start={panelTimeRange?.from ?? undefined}
end={panelTimeRange?.to ?? undefined}
onTimeChange={({ start, end }) => setPanelTimeRange({ from: start, to: end })}
showUpdateButton={false}
dateFormat={props.dateFormat}
commonlyUsedRanges={commonlyUsedRangesForDatePicker}
data-test-subj="customizePanelTimeRangeDatePicker"
/>
</EuiFormRow>
) : null}
</>
) : null}
{renderCustomTimeRangeComponent()}
</EuiForm>
</EuiFlyoutBody>
<EuiFlyoutFooter>
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={onClose}>
<EuiButtonEmpty data-test-subj="cancelCustomizePanelButton" onClick={onClose}>
<FormattedMessage
id="embeddableApi.customizePanel.flyout.cancelButtonTitle"
defaultMessage="Cancel"
Expand Down
5 changes: 5 additions & 0 deletions test/functional/services/dashboard/panel_settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ export function DashboardCustomizePanelProvider({ getService }: FtrProviderConte
await testSubjects.click('saveCustomizePanelButton');
}

public async clickCancelButton() {
log.debug('clickCancelButton');
await testSubjects.click('cancelCustomizePanelButton');
}

public async clickToggleShowCustomTimeRange() {
log.debug('clickToggleShowCustomTimeRange');
await testSubjects.click(this.TOGGLE_TIME_RANGE_TEST_SUBJ);
Expand Down

0 comments on commit 10bda3c

Please sign in to comment.