Skip to content

Commit

Permalink
[Lens] Add more in-editor Advanced documentation (#86821)
Browse files Browse the repository at this point in the history
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Wylie Conlon <wylieconlon@gmail.com>
Co-authored-by: Michael Marcialis <michael.marcialis@elastic.co>
  • Loading branch information
4 people authored Jan 20, 2021
1 parent ef40806 commit 86789da
Show file tree
Hide file tree
Showing 17 changed files with 578 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ search: {
siblingPipelineType: string;
termsAggFilter: string[];
toAbsoluteDates: typeof toAbsoluteDates;
boundsDescendingRaw: ({
bound: number;
interval: import("moment").Duration;
boundLabel: string;
intervalLabel: string;
} | {
bound: import("moment").Duration;
interval: import("moment").Duration;
boundLabel: string;
intervalLabel: string;
})[];
};
getRequestInspectorStats: typeof getRequestInspectorStats;
getResponseInspectorStats: typeof getResponseInspectorStats;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,75 +6,205 @@
* Public License, v 1.
*/

import { i18n } from '@kbn/i18n';
import moment from 'moment';

const boundsDescending = [
export const boundsDescendingRaw = [
{
bound: Infinity,
interval: Number(moment.duration(1, 'year')),
interval: moment.duration(1, 'year'),
boundLabel: i18n.translate('data.search.timeBuckets.infinityLabel', {
defaultMessage: 'More than a year',
}),
intervalLabel: i18n.translate('data.search.timeBuckets.yearLabel', {
defaultMessage: 'a year',
}),
},
{
bound: Number(moment.duration(1, 'year')),
interval: Number(moment.duration(1, 'month')),
bound: moment.duration(1, 'year'),
interval: moment.duration(1, 'month'),
boundLabel: i18n.translate('data.search.timeBuckets.yearLabel', {
defaultMessage: 'a year',
}),
intervalLabel: i18n.translate('data.search.timeBuckets.monthLabel', {
defaultMessage: 'a month',
}),
},
{
bound: Number(moment.duration(3, 'week')),
interval: Number(moment.duration(1, 'week')),
bound: moment.duration(3, 'week'),
interval: moment.duration(1, 'week'),
boundLabel: i18n.translate('data.search.timeBuckets.dayLabel', {
defaultMessage: '{amount, plural, one {a day} other {# days}}',
values: { amount: 21 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.dayLabel', {
defaultMessage: '{amount, plural, one {a day} other {# days}}',
values: { amount: 7 },
}),
},
{
bound: Number(moment.duration(1, 'week')),
interval: Number(moment.duration(1, 'd')),
bound: moment.duration(1, 'week'),
interval: moment.duration(1, 'd'),
boundLabel: i18n.translate('data.search.timeBuckets.dayLabel', {
defaultMessage: '{amount, plural, one {a day} other {# days}}',
values: { amount: 7 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.dayLabel', {
defaultMessage: '{amount, plural, one {a day} other {# days}}',
values: { amount: 1 },
}),
},
{
bound: Number(moment.duration(24, 'hour')),
interval: Number(moment.duration(12, 'hour')),
bound: moment.duration(24, 'hour'),
interval: moment.duration(12, 'hour'),
boundLabel: i18n.translate('data.search.timeBuckets.dayLabel', {
defaultMessage: '{amount, plural, one {a day} other {# days}}',
values: { amount: 1 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.hourLabel', {
defaultMessage: '{amount, plural, one {an hour} other {# hours}}',
values: { amount: 12 },
}),
},
{
bound: Number(moment.duration(6, 'hour')),
interval: Number(moment.duration(3, 'hour')),
bound: moment.duration(6, 'hour'),
interval: moment.duration(3, 'hour'),
boundLabel: i18n.translate('data.search.timeBuckets.hourLabel', {
defaultMessage: '{amount, plural, one {an hour} other {# hours}}',
values: { amount: 6 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.hourLabel', {
defaultMessage: '{amount, plural, one {an hour} other {# hours}}',
values: { amount: 3 },
}),
},
{
bound: Number(moment.duration(2, 'hour')),
interval: Number(moment.duration(1, 'hour')),
bound: moment.duration(2, 'hour'),
interval: moment.duration(1, 'hour'),
boundLabel: i18n.translate('data.search.timeBuckets.hourLabel', {
defaultMessage: '{amount, plural, one {an hour} other {# hours}}',
values: { amount: 2 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.hourLabel', {
defaultMessage: '{amount, plural, one {an hour} other {# hours}}',
values: { amount: 1 },
}),
},
{
bound: Number(moment.duration(45, 'minute')),
interval: Number(moment.duration(30, 'minute')),
bound: moment.duration(45, 'minute'),
interval: moment.duration(30, 'minute'),
boundLabel: i18n.translate('data.search.timeBuckets.minuteLabel', {
defaultMessage: '{amount, plural, one {a minute} other {# minutes}}',
values: { amount: 45 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.minuteLabel', {
defaultMessage: '{amount, plural, one {a minute} other {# minutes}}',
values: { amount: 30 },
}),
},
{
bound: Number(moment.duration(20, 'minute')),
interval: Number(moment.duration(10, 'minute')),
bound: moment.duration(20, 'minute'),
interval: moment.duration(10, 'minute'),
boundLabel: i18n.translate('data.search.timeBuckets.minuteLabel', {
defaultMessage: '{amount, plural, one {a minute} other {# minutes}}',
values: { amount: 20 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.minuteLabel', {
defaultMessage: '{amount, plural, one {a minute} other {# minutes}}',
values: { amount: 10 },
}),
},
{
bound: Number(moment.duration(9, 'minute')),
interval: Number(moment.duration(5, 'minute')),
bound: moment.duration(9, 'minute'),
interval: moment.duration(5, 'minute'),
boundLabel: i18n.translate('data.search.timeBuckets.minuteLabel', {
defaultMessage: '{amount, plural, one {a minute} other {# minutes}}',
values: { amount: 9 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.minuteLabel', {
defaultMessage: '{amount, plural, one {a minute} other {# minutes}}',
values: { amount: 5 },
}),
},
{
bound: Number(moment.duration(3, 'minute')),
interval: Number(moment.duration(1, 'minute')),
bound: moment.duration(3, 'minute'),
interval: moment.duration(1, 'minute'),
boundLabel: i18n.translate('data.search.timeBuckets.minuteLabel', {
defaultMessage: '{amount, plural, one {a minute} other {# minutes}}',
values: { amount: 3 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.minuteLabel', {
defaultMessage: '{amount, plural, one {a minute} other {# minutes}}',
values: { amount: 1 },
}),
},
{
bound: Number(moment.duration(45, 'second')),
interval: Number(moment.duration(30, 'second')),
bound: moment.duration(45, 'second'),
interval: moment.duration(30, 'second'),
boundLabel: i18n.translate('data.search.timeBuckets.secondLabel', {
defaultMessage: '{amount, plural, one {a second} other {# seconds}}',
values: { amount: 45 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.secondLabel', {
defaultMessage: '{amount, plural, one {a second} other {# seconds}}',
values: { amount: 30 },
}),
},
{
bound: Number(moment.duration(15, 'second')),
interval: Number(moment.duration(10, 'second')),
bound: moment.duration(15, 'second'),
interval: moment.duration(10, 'second'),
boundLabel: i18n.translate('data.search.timeBuckets.secondLabel', {
defaultMessage: '{amount, plural, one {a second} other {# seconds}}',
values: { amount: 15 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.secondLabel', {
defaultMessage: '{amount, plural, one {a second} other {# seconds}}',
values: { amount: 10 },
}),
},
{
bound: Number(moment.duration(7.5, 'second')),
interval: Number(moment.duration(5, 'second')),
bound: moment.duration(7.5, 'second'),
interval: moment.duration(5, 'second'),
boundLabel: i18n.translate('data.search.timeBuckets.secondLabel', {
defaultMessage: '{amount, plural, one {a second} other {# seconds}}',
values: { amount: 7.5 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.secondLabel', {
defaultMessage: '{amount, plural, one {a second} other {# seconds}}',
values: { amount: 5 },
}),
},
{
bound: Number(moment.duration(5, 'second')),
interval: Number(moment.duration(1, 'second')),
bound: moment.duration(5, 'second'),
interval: moment.duration(1, 'second'),
boundLabel: i18n.translate('data.search.timeBuckets.secondLabel', {
defaultMessage: '{amount, plural, one {a second} other {# seconds}}',
values: { amount: 5 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.secondLabel', {
defaultMessage: '{amount, plural, one {a second} other {# seconds}}',
values: { amount: 1 },
}),
},
{
bound: Number(moment.duration(500, 'ms')),
interval: Number(moment.duration(100, 'ms')),
bound: moment.duration(500, 'ms'),
interval: moment.duration(100, 'ms'),
boundLabel: i18n.translate('data.search.timeBuckets.millisecondLabel', {
defaultMessage: '{amount, plural, one {a millisecond} other {# milliseconds}}',
values: { amount: 500 },
}),
intervalLabel: i18n.translate('data.search.timeBuckets.millisecondLabel', {
defaultMessage: '{amount, plural, one {a millisecond} other {# milliseconds}}',
values: { amount: 100 },
}),
},
];

const boundsDescending = boundsDescendingRaw.map(({ bound, interval }) => ({
bound: Number(bound),
interval: Number(interval),
}));

function getPerBucketMs(count: number, duration: number) {
const ms = duration / count;
return isFinite(ms) ? ms : NaN;
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/data/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ import {
parseEsInterval,
parseInterval,
toAbsoluteDates,
boundsDescendingRaw,
// expressions utils
getRequestInspectorStats,
getResponseInspectorStats,
Expand Down Expand Up @@ -416,6 +417,7 @@ export const search = {
siblingPipelineType,
termsAggFilter,
toAbsoluteDates,
boundsDescendingRaw,
},
getRequestInspectorStats,
getResponseInspectorStats,
Expand Down
41 changes: 26 additions & 15 deletions src/plugins/data/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2205,6 +2205,17 @@ export const search: {
siblingPipelineType: string;
termsAggFilter: string[];
toAbsoluteDates: typeof toAbsoluteDates;
boundsDescendingRaw: ({
bound: number;
interval: import("moment").Duration;
boundLabel: string;
intervalLabel: string;
} | {
bound: import("moment").Duration;
interval: import("moment").Duration;
boundLabel: string;
intervalLabel: string;
})[];
};
getRequestInspectorStats: typeof getRequestInspectorStats;
getResponseInspectorStats: typeof getResponseInspectorStats;
Expand Down Expand Up @@ -2608,21 +2619,21 @@ export const UI_SETTINGS: {
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "validateIndexPattern" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:398:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:398:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:398:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:398:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:410:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:413:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:417:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:418:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:421:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:422:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:425:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:399:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:399:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:399:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:399:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:402:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:413:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:414:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:418:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:419:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:422:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:423:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:426:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:34:5 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/search/session/session_service.ts:41:5 - (ae-forgotten-export) The symbol "UrlGeneratorStateMapping" needs to be exported by the entry point index.d.ts

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,17 @@ export function DimensionEditor(props: DimensionEditorProps) {
}
);

// Need to workout early on the error to decide whether to show this or an help text
const fieldErrorMessage =
(selectedOperationDefinition?.input !== 'fullReference' ||
(incompleteOperation && operationDefinitionMap[incompleteOperation].input === 'field')) &&
getErrorMessage(
selectedColumn,
Boolean(incompleteOperation),
selectedOperationDefinition?.input,
currentFieldIsInvalid
);

return (
<div id={columnId}>
<div className="lnsIndexPatternDimensionEditor__section lnsIndexPatternDimensionEditor__section--shaded">
Expand Down Expand Up @@ -342,6 +353,11 @@ export function DimensionEditor(props: DimensionEditorProps) {
existingFields={state.existingFields}
selectionStyle={selectedOperationDefinition.selectionStyle}
dateRange={dateRange}
labelAppend={selectedOperationDefinition?.getHelpMessage?.({
data: props.data,
uiSettings: props.uiSettings,
currentColumn: state.layers[layerId].columns[columnId],
})}
{...services}
/>
);
Expand All @@ -360,12 +376,15 @@ export function DimensionEditor(props: DimensionEditorProps) {
})}
fullWidth
isInvalid={Boolean(incompleteOperation || currentFieldIsInvalid)}
error={getErrorMessage(
selectedColumn,
Boolean(incompleteOperation),
selectedOperationDefinition?.input,
currentFieldIsInvalid
)}
error={fieldErrorMessage}
labelAppend={
!fieldErrorMessage &&
selectedOperationDefinition?.getHelpMessage?.({
data: props.data,
uiSettings: props.uiSettings,
currentColumn: state.layers[layerId].columns[columnId],
})
}
>
<FieldSelect
fieldIsInvalid={currentFieldIsInvalid}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ describe('IndexPatternDimensionEditorPanel', () => {
id: 'bytes',
title: 'Bytes',
}),
deserialize: jest.fn().mockReturnValue({
convert: () => 'formatted',
}),
} as unknown) as DataPublicPluginStart['fieldFormats'],
} as unknown) as DataPublicPluginStart,
core: {} as CoreSetup,
Expand Down
Loading

0 comments on commit 86789da

Please sign in to comment.