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

[Lens] Add more in-editor Advanced documentation #86821

Merged
merged 45 commits into from
Jan 20, 2021
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
64c09f0
:speech_balloon: Add granularity advanced doc
dej611 Dec 22, 2020
b52749a
:wrench: Make advanced setting parametric
dej611 Dec 22, 2020
78266ac
:speech_balloon: Add auto date histogram popup
dej611 Dec 22, 2020
94f8b53
:speech_balloon: Add Missing values/Fitting help tooltip
dej611 Dec 22, 2020
fd54795
:ok_hand: Use the duration formatter from data plugin
dej611 Dec 23, 2020
ff02be9
:white_check_mark: Fix unit tests
dej611 Dec 23, 2020
03fd855
:hammer: Document data plugin API changes
dej611 Dec 23, 2020
6f87fdd
:wrench: Fix i18n checks
dej611 Dec 23, 2020
a2d5de9
Merge remote-tracking branch 'upstream/master' into doc/lens/popups
dej611 Dec 23, 2020
5189137
:fire: Remove unused translations
dej611 Dec 23, 2020
ffa15db
:ok_hand: Reworked based on feedback
dej611 Dec 23, 2020
0f14c6b
:baloon_speech: Add moving average popover
dej611 Dec 23, 2020
bef3487
:pencil2: Missed one label
dej611 Dec 23, 2020
a51ee89
Merge branch 'master' into doc/lens/popups
kibanamachine Dec 28, 2020
23797c0
:lipstick: Fix short table problem
dej611 Dec 28, 2020
c417160
Merge branch 'doc/lens/popups' of github.com:dej611/kibana into doc/l…
dej611 Dec 28, 2020
51e4b5a
Merge remote-tracking branch 'origin/master' into HEAD
wylieconlon Dec 28, 2020
f691ea6
Use Kibana translations instead of moment
wylieconlon Dec 28, 2020
34cbb44
Revert "Use Kibana translations instead of moment"
wylieconlon Dec 28, 2020
4786a6d
Use Kibana translations instead of moment
wylieconlon Dec 28, 2020
75e11ea
Remove unused code
wylieconlon Dec 28, 2020
81917e1
Merge pull request #3 from wylieconlon/lens/advanced-docs-fork
dej611 Dec 29, 2020
5d840da
:speech_balloon: Revisit some interval labels
dej611 Dec 29, 2020
e955849
:ok_hand: Fix api doc changes
dej611 Dec 29, 2020
4ebc327
:speech_balloon: Improve moving_avg doc with example
dej611 Dec 29, 2020
167a76d
update class name; remove problematic styles
MichaelMarcialis Dec 29, 2020
a5b3d18
eui scroll on proper element; max width; rm icon
MichaelMarcialis Dec 29, 2020
e02de31
add help icon to button for consistency
MichaelMarcialis Dec 29, 2020
a4e77f9
created new HelpPopover component
MichaelMarcialis Dec 29, 2020
4e6cf4a
change all to use new HelpPopover component
MichaelMarcialis Dec 29, 2020
c15d0f1
moved popover btns to labelAppend for consistency
MichaelMarcialis Dec 29, 2020
69e88f9
Merge pull request #4 from MichaelMarcialis/doc/lens/popups-design
dej611 Dec 30, 2020
4b4db87
Merge remote-tracking branch 'upstream/master' into doc/lens/popups
dej611 Dec 30, 2020
cec6ff8
:bug: Fix stale help popup on operation change
dej611 Dec 30, 2020
0ef1b9d
:lipstick: Integrated tooltip suggestion
dej611 Dec 30, 2020
6592790
Merge branch 'master' into doc/lens/popups
kibanamachine Jan 4, 2021
933b52c
Merge branch 'master' into doc/lens/popups
kibanamachine Jan 11, 2021
3be0e5e
:speech_balloon: Rework some copy
dej611 Jan 11, 2021
49524fe
Merge branch 'master' into doc/lens/popups
kibanamachine Jan 14, 2021
012297a
:ok_hand: Integrate new feedback
dej611 Jan 14, 2021
180b4af
:speech_balloon: Changed copy as last feedback
dej611 Jan 15, 2021
5feadf0
Merge branch 'master' into doc/lens/popups
kibanamachine Jan 18, 2021
3ed6381
Merge remote-tracking branch 'upstream/master' into doc/lens/popups
dej611 Jan 20, 2021
b94bccf
Merge branch 'doc/lens/popups' of github.com:dej611/kibana into doc/l…
dej611 Jan 20, 2021
782530b
:bug: Fix api changes with rebuild
dej611 Jan 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
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 @@ -17,75 +17,205 @@
* under the License.
*/

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 @@ -318,6 +318,7 @@ import {
parseEsInterval,
parseInterval,
toAbsoluteDates,
boundsDescendingRaw,
// expressions utils
getRequestInspectorStats,
getResponseInspectorStats,
Expand Down Expand Up @@ -427,6 +428,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 @@ -2201,6 +2201,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 @@ -2604,21 +2615,21 @@ export const UI_SETTINGS: {
// src/plugins/data/public/index.ts:245:27 - (ae-forgotten-export) The symbol "validateIndexPattern" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:245:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:245:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:409:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:409:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:409:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:409:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:421:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:422:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:423:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:424:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:428:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:429:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:432:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:433:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:436:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:410:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:410:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:410:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:410:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:413:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:422:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:423:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:424:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:425:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:429:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:430:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:433:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:434:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:437: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:45: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:50: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 @@ -291,6 +291,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 @@ -334,6 +345,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 @@ -352,12 +368,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