Skip to content

Commit

Permalink
[Lens] Make date histogram interval more customizable (#49217) (#49654)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisdavies authored Oct 29, 2019
1 parent 150e822 commit f90855e
Show file tree
Hide file tree
Showing 17 changed files with 463 additions and 239 deletions.
2 changes: 1 addition & 1 deletion src/legacy/ui/public/agg_types/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function isValidJson(value: string): boolean {
}
}

function isValidInterval(value: string, baseInterval: string) {
function isValidInterval(value: string, baseInterval?: string) {
if (baseInterval) {
return _parseWithBase(value, baseInterval);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -807,30 +807,38 @@ describe('editor_frame', () => {
await waitForPromises();

expect(mockDatasource.getPublicAPI).toHaveBeenCalledWith(
datasource1State,
expect.anything(),
'first'
expect.objectContaining({
state: datasource1State,
setState: expect.anything(),
layerId: 'first',
})
);
expect(mockDatasource2.getPublicAPI).toHaveBeenCalledWith(
datasource2State,
expect.anything(),
'second'
expect.objectContaining({
state: datasource2State,
setState: expect.anything(),
layerId: 'second',
})
);
expect(mockDatasource2.getPublicAPI).toHaveBeenCalledWith(
datasource2State,
expect.anything(),
'third'
expect.objectContaining({
state: datasource2State,
setState: expect.anything(),
layerId: 'third',
})
);
});

it('should give access to the datasource state in the datasource factory function', async () => {
const datasourceState = {};
const dateRange = { fromDate: 'now-1w', toDate: 'now' };
mockDatasource.initialize.mockResolvedValue(datasourceState);
mockDatasource.getLayers.mockReturnValue(['first']);

mount(
<EditorFrame
{...getDefaultProps()}
dateRange={dateRange}
visualizationMap={{
testVis: mockVisualization,
}}
Expand All @@ -845,11 +853,12 @@ describe('editor_frame', () => {

await waitForPromises();

expect(mockDatasource.getPublicAPI).toHaveBeenCalledWith(
datasourceState,
expect.any(Function),
'first'
);
expect(mockDatasource.getPublicAPI).toHaveBeenCalledWith({
dateRange,
state: datasourceState,
setState: expect.any(Function),
layerId: 'first',
});
});

it('should re-create the public api after state has been set', async () => {
Expand All @@ -872,15 +881,17 @@ describe('editor_frame', () => {
await waitForPromises();

const updatedState = {};
const setDatasourceState = mockDatasource.getPublicAPI.mock.calls[0][1];
const setDatasourceState = mockDatasource.getPublicAPI.mock.calls[0][0].setState;
act(() => {
setDatasourceState(updatedState);
});

expect(mockDatasource.getPublicAPI).toHaveBeenLastCalledWith(
updatedState,
expect.any(Function),
'first'
expect.objectContaining({
state: updatedState,
setState: expect.any(Function),
layerId: 'first',
})
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,19 @@ export function EditorFrame(props: EditorFrameProps) {

const layers = datasource.getLayers(datasourceState);
layers.forEach(layer => {
const publicAPI = props.datasourceMap[id].getPublicAPI(
datasourceState,
(newState: unknown) => {
const publicAPI = props.datasourceMap[id].getPublicAPI({
state: datasourceState,
setState: (newState: unknown) => {
dispatch({
type: 'UPDATE_DATASOURCE_STATE',
datasourceId: id,
updater: newState,
clearStagedPreview: true,
});
},
layer
);
layerId: layer,
dateRange: props.dateRange,
});

datasourceLayers[layer] = publicAPI;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,12 @@ function getPreviewExpression(
const changedLayers = datasource.getLayers(visualizableState.datasourceState);
changedLayers.forEach(layerId => {
if (updatedLayerApis[layerId]) {
updatedLayerApis[layerId] = datasource.getPublicAPI(datasourceState, () => {}, layerId);
updatedLayerApis[layerId] = datasource.getPublicAPI({
layerId,
dateRange: frame.dateRange,
state: datasourceState,
setState: () => {},
});
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function createMockDatasource(): DatasourceMock {
getDatasourceSuggestionsForField: jest.fn((_state, item) => []),
getDatasourceSuggestionsFromCurrentState: jest.fn(_state => []),
getPersistableState: jest.fn(),
getPublicAPI: jest.fn((_state, _setState, _layerId) => publicAPIMock),
getPublicAPI: jest.fn().mockReturnValue(publicAPIMock),
initialize: jest.fn((_state?) => Promise.resolve()),
renderDataPanel: jest.fn(),
toExpression: jest.fn((_frame, _state) => null),
Expand Down
29 changes: 21 additions & 8 deletions x-pack/legacy/plugins/lens/public/indexpattern_plugin/auto_date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,38 @@ import {
ExpressionFunction,
KibanaContext,
} from '../../../../../../src/plugins/expressions/common';
import { DateRange } from '../../common';

interface LensAutoDateProps {
aggConfigs: string;
}

export function getAutoInterval(ctx?: KibanaContext | null) {
if (!ctx || !ctx.timeRange) {
return;
export function autoIntervalFromDateRange(dateRange?: DateRange, defaultValue: string = '1h') {
if (!dateRange) {
return defaultValue;
}

const { timeRange } = ctx;
const buckets = new TimeBuckets();
buckets.setInterval('auto');
buckets.setBounds({
min: dateMath.parse(timeRange.from),
max: dateMath.parse(timeRange.to, { roundUp: true }),
min: dateMath.parse(dateRange.fromDate),
max: dateMath.parse(dateRange.toDate, { roundUp: true }),
});

return buckets.getInterval();
return buckets.getInterval().expression;
}

function autoIntervalFromContext(ctx?: KibanaContext | null) {
if (!ctx || !ctx.timeRange) {
return;
}

const { timeRange } = ctx;

return autoIntervalFromDateRange({
fromDate: timeRange.from,
toDate: timeRange.to,
});
}

/**
Expand Down Expand Up @@ -56,7 +69,7 @@ export const autoDate: ExpressionFunction<
},
},
fn(ctx: KibanaContext, args: LensAutoDateProps) {
const interval = getAutoInterval(ctx);
const interval = autoIntervalFromContext(ctx);

if (!interval) {
return args.aggConfigs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ describe('IndexPatternDimensionPanel', () => {
dragDropContext,
state,
setState,
dateRange: { fromDate: 'now-1d', toDate: 'now' },
columnId: 'col1',
layerId: 'first',
uniqueLabel: 'stuff',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { changeColumn, deleteColumn } from '../state_helpers';
import { isDraggedField, hasField } from '../utils';
import { IndexPatternPrivateState, IndexPatternField } from '../types';
import { trackUiEvent } from '../../lens_ui_telemetry';
import { DateRange } from '../../../common';

export type IndexPatternDimensionPanelProps = DatasourceDimensionPanelProps & {
state: IndexPatternPrivateState;
Expand All @@ -34,6 +35,7 @@ export type IndexPatternDimensionPanelProps = DatasourceDimensionPanelProps & {
layerId: string;
http: HttpServiceBase;
uniqueLabel: string;
dateRange: DateRange;
};

export interface OperationFieldSupportMatrix {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ export function PopoverEditor(props: PopoverEditorProps) {
savedObjectsClient={props.savedObjectsClient}
layerId={layerId}
http={props.http}
dateRange={props.dateRange}
/>
<EuiSpacer size="m" />
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,15 @@ describe('IndexPattern Data Source', () => {

beforeEach(async () => {
const initialState = stateFromPersistedState(persistedState);
publicAPI = indexPatternDatasource.getPublicAPI(initialState, () => {}, 'first');
publicAPI = indexPatternDatasource.getPublicAPI({
state: initialState,
setState: () => {},
layerId: 'first',
dateRange: {
fromDate: 'now-30d',
toDate: 'now',
},
});
});

describe('getTableSpec', () => {
Expand Down Expand Up @@ -453,8 +461,8 @@ describe('IndexPattern Data Source', () => {
suggestedPriority: 2,
},
};
const api = indexPatternDatasource.getPublicAPI(
{
const api = indexPatternDatasource.getPublicAPI({
state: {
...initialState,
layers: {
first: {
Expand All @@ -465,8 +473,12 @@ describe('IndexPattern Data Source', () => {
},
},
setState,
'first'
);
layerId: 'first',
dateRange: {
fromDate: 'now-1y',
toDate: 'now',
},
});

api.removeColumnInTableSpec('b');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
DatasourceDataPanelProps,
Operation,
DatasourceLayerPanelProps,
PublicAPIProps,
} from '../types';
import { loadInitialState, changeIndexPattern, changeLayerIndexPattern } from './loader';
import { toExpression } from './to_expression';
Expand Down Expand Up @@ -196,11 +197,12 @@ export function getIndexPatternDatasource({
);
},

getPublicAPI(
state: IndexPatternPrivateState,
setState: StateSetter<IndexPatternPrivateState>,
layerId: string
) {
getPublicAPI({
state,
setState,
layerId,
dateRange,
}: PublicAPIProps<IndexPatternPrivateState>) {
const columnLabelMap = uniqueLabels(state.layers);

return {
Expand Down Expand Up @@ -237,6 +239,7 @@ export function getIndexPatternDatasource({
layerId={props.layerId}
http={core.http}
uniqueLabel={columnLabelMap[props.columnId]}
dateRange={dateRange}
{...props}
/>
</KibanaContextProvider>
Expand Down
Loading

0 comments on commit f90855e

Please sign in to comment.