Skip to content

Commit dfddcdd

Browse files
Corey Robertsonelasticmachine
andauthored
[Canvas] Misc NP Stuff (#63703)
* Timelion function -> np * embeddable renderer -> np i18n context * ui_metric -> np * Fix timelion issue Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
1 parent 103a3cd commit dfddcdd

File tree

8 files changed

+141
-97
lines changed

8 files changed

+141
-97
lines changed

x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import React from 'react';
88
import ReactDOM from 'react-dom';
9-
import { I18nContext } from 'ui/i18n';
109
import { CoreStart } from '../../../../../../../src/core/public';
1110
import { StartDeps } from '../../plugin';
1211
import {
@@ -30,6 +29,8 @@ const embeddablesRegistry: {
3029
} = {};
3130

3231
const renderEmbeddableFactory = (core: CoreStart, plugins: StartDeps) => {
32+
const I18nContext = core.i18n.Context;
33+
3334
return (embeddableObject: IEmbeddable, domNode: HTMLElement) => {
3435
return (
3536
<div

x-pack/legacy/plugins/canvas/i18n/functions/dict/timelion.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
*/
66

77
import { i18n } from '@kbn/i18n';
8-
import { timelion } from '../../../public/functions/timelion';
8+
import { timelionFunctionFactory } from '../../../public/functions/timelion';
99
import { FunctionHelp } from '../function_help';
1010
import { FunctionFactory } from '../../../types';
1111
import { ELASTICSEARCH, DATEMATH, MOMENTJS_TIMEZONE_URL } from '../../constants';
1212

13-
export const help: FunctionHelp<FunctionFactory<typeof timelion>> = {
13+
export const help: FunctionHelp<FunctionFactory<ReturnType<typeof timelionFunctionFactory>>> = {
1414
help: i18n.translate('xpack.canvas.functions.timelionHelpText', {
1515
defaultMessage: 'Use Timelion to extract one or more timeseries from many sources.',
1616
}),

x-pack/legacy/plugins/canvas/public/application.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { VALUE_CLICK_TRIGGER, ActionByType } from '../../../../../src/plugins/ui
3030
/* eslint-disable */
3131
import { ACTION_VALUE_CLICK } from '../../../../../src/plugins/data/public/actions/value_click_action';
3232
/* eslint-enable */
33+
import { init as initStatsReporter } from './lib/ui_metric';
3334

3435
import { CapabilitiesStrings } from '../i18n';
3536
const { ReadOnlyBadge: strings } = CapabilitiesStrings;
@@ -121,6 +122,10 @@ export const initializeCanvas = async (
121122
startPlugins.uiActions.attachAction(VALUE_CLICK_TRIGGER, emptyAction);
122123
}
123124

125+
if (setupPlugins.usageCollection) {
126+
initStatsReporter(setupPlugins.usageCollection.reportUiStats);
127+
}
128+
124129
return canvasStore;
125130
};
126131

x-pack/legacy/plugins/canvas/public/functions/index.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,23 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { ExpressionsSetup } from 'src/plugins/expressions/public';
87
import { asset } from './asset';
98
import { filtersFunctionFactory } from './filters';
10-
import { timelion } from './timelion';
9+
import { timelionFunctionFactory } from './timelion';
1110
import { toFunctionFactory } from './to';
11+
import { CanvasSetupDeps, CoreSetup } from '../plugin';
1212

1313
export interface InitializeArguments {
14-
typesRegistry: ExpressionsSetup['__LEGACY']['types'];
14+
prependBasePath: CoreSetup['http']['basePath']['prepend'];
15+
typesRegistry: CanvasSetupDeps['expressions']['__LEGACY']['types'];
16+
timefilter: CanvasSetupDeps['data']['query']['timefilter']['timefilter'];
1517
}
1618

1719
export function initFunctions(initialize: InitializeArguments) {
18-
return [asset, filtersFunctionFactory(initialize), timelion, toFunctionFactory(initialize)];
20+
return [
21+
asset,
22+
filtersFunctionFactory(initialize),
23+
timelionFunctionFactory(initialize),
24+
toFunctionFactory(initialize),
25+
];
1926
}

x-pack/legacy/plugins/canvas/public/functions/timelion.ts

Lines changed: 90 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66

77
import { flatten } from 'lodash';
88
import moment from 'moment-timezone';
9-
import chrome from 'ui/chrome';
10-
import { npStart } from 'ui/new_platform';
119
import { TimeRange } from 'src/plugins/data/common';
1210
import { ExpressionFunctionDefinition, DatatableRow } from 'src/plugins/expressions/public';
1311
import { fetch } from '../../common/lib/fetch';
1412
// @ts-ignore untyped local
1513
import { buildBoolArray } from '../../server/lib/build_bool_array';
1614
import { Datatable, Filter } from '../../types';
1715
import { getFunctionHelp } from '../../i18n';
16+
import { InitializeArguments } from './';
1817

1918
interface Arguments {
2019
query: string;
@@ -30,110 +29,118 @@ interface Arguments {
3029
* @param timeRange time range to parse
3130
* @param timeZone time zone to do the parsing in
3231
*/
33-
function parseDateMath(timeRange: TimeRange, timeZone: string) {
32+
function parseDateMath(
33+
timeRange: TimeRange,
34+
timeZone: string,
35+
timefilter: InitializeArguments['timefilter']
36+
) {
3437
// the datemath plugin always parses dates by using the current default moment time zone.
3538
// to use the configured time zone, we are switching just for the bounds calculation.
3639
const defaultTimezone = moment().zoneName();
3740
moment.tz.setDefault(timeZone);
3841

39-
const parsedRange = npStart.plugins.data.query.timefilter.timefilter.calculateBounds(timeRange);
42+
const parsedRange = timefilter.calculateBounds(timeRange);
4043

4144
// reset default moment timezone
4245
moment.tz.setDefault(defaultTimezone);
4346

4447
return parsedRange;
4548
}
4649

47-
export function timelion(): ExpressionFunctionDefinition<
50+
type TimelionFunction = ExpressionFunctionDefinition<
4851
'timelion',
4952
Filter,
5053
Arguments,
5154
Promise<Datatable>
52-
> {
53-
const { help, args: argHelp } = getFunctionHelp().timelion;
55+
>;
5456

55-
return {
56-
name: 'timelion',
57-
type: 'datatable',
58-
inputTypes: ['filter'],
59-
help,
60-
args: {
61-
query: {
62-
types: ['string'],
63-
aliases: ['_', 'q'],
64-
help: argHelp.query,
65-
default: '".es(*)"',
66-
},
67-
interval: {
68-
types: ['string'],
69-
help: argHelp.interval,
70-
default: 'auto',
71-
},
72-
from: {
73-
types: ['string'],
74-
help: argHelp.from,
75-
default: 'now-1y',
76-
},
77-
to: {
78-
types: ['string'],
79-
help: argHelp.to,
80-
default: 'now',
81-
},
82-
timezone: {
83-
types: ['string'],
84-
help: argHelp.timezone,
85-
default: 'UTC',
57+
export function timelionFunctionFactory(initialize: InitializeArguments): () => TimelionFunction {
58+
return () => {
59+
const { help, args: argHelp } = getFunctionHelp().timelion;
60+
61+
return {
62+
name: 'timelion',
63+
type: 'datatable',
64+
inputTypes: ['filter'],
65+
help,
66+
args: {
67+
query: {
68+
types: ['string'],
69+
aliases: ['_', 'q'],
70+
help: argHelp.query,
71+
default: '".es(*)"',
72+
},
73+
interval: {
74+
types: ['string'],
75+
help: argHelp.interval,
76+
default: 'auto',
77+
},
78+
from: {
79+
types: ['string'],
80+
help: argHelp.from,
81+
default: 'now-1y',
82+
},
83+
to: {
84+
types: ['string'],
85+
help: argHelp.to,
86+
default: 'now',
87+
},
88+
timezone: {
89+
types: ['string'],
90+
help: argHelp.timezone,
91+
default: 'UTC',
92+
},
8693
},
87-
},
88-
fn: (input, args): Promise<Datatable> => {
89-
// Timelion requires a time range. Use the time range from the timefilter element in the
90-
// workpad, if it exists. Otherwise fall back on the function args.
91-
const timeFilter = input.and.find(and => and.type === 'time');
92-
const range = timeFilter
93-
? { min: timeFilter.from, max: timeFilter.to }
94-
: parseDateMath({ from: args.from, to: args.to }, args.timezone);
94+
fn: (input, args): Promise<Datatable> => {
95+
// Timelion requires a time range. Use the time range from the timefilter element in the
96+
// workpad, if it exists. Otherwise fall back on the function args.
97+
const timeFilter = input.and.find(and => and.type === 'time');
98+
const range = timeFilter
99+
? { min: timeFilter.from, max: timeFilter.to }
100+
: parseDateMath({ from: args.from, to: args.to }, args.timezone, initialize.timefilter);
95101

96-
const body = {
97-
extended: {
98-
es: {
99-
filter: {
100-
bool: {
101-
must: buildBoolArray(input.and),
102+
const body = {
103+
extended: {
104+
es: {
105+
filter: {
106+
bool: {
107+
must: buildBoolArray(input.and),
108+
},
102109
},
103110
},
104111
},
105-
},
106-
sheet: [args.query],
107-
time: {
108-
from: range.min,
109-
to: range.max,
110-
interval: args.interval,
111-
timezone: args.timezone,
112-
},
113-
};
112+
sheet: [args.query],
113+
time: {
114+
from: range.min,
115+
to: range.max,
116+
interval: args.interval,
117+
timezone: args.timezone,
118+
},
119+
};
114120

115-
return fetch(chrome.addBasePath(`/api/timelion/run`), {
116-
method: 'POST',
117-
responseType: 'json',
118-
data: body,
119-
}).then(resp => {
120-
const seriesList = resp.data.sheet[0].list;
121-
const rows = flatten(
122-
seriesList.map((series: { data: any[]; label: string }) =>
123-
series.data.map(row => ({ '@timestamp': row[0], value: row[1], label: series.label }))
124-
)
125-
) as DatatableRow[];
121+
return fetch(initialize.prependBasePath(`/api/timelion/run`), {
122+
method: 'POST',
123+
responseType: 'json',
124+
data: body,
125+
}).then(resp => {
126+
const seriesList = resp.data.sheet[0].list;
127+
const rows = flatten(
128+
seriesList.map((series: { data: any[]; label: string }) =>
129+
series.data.map(row => ({ '@timestamp': row[0], value: row[1], label: series.label }))
130+
)
131+
) as DatatableRow[];
126132

127-
return {
128-
type: 'datatable',
129-
columns: [
130-
{ name: '@timestamp', type: 'date' },
131-
{ name: 'value', type: 'number' },
132-
{ name: 'label', type: 'string' },
133-
],
134-
rows,
135-
};
136-
});
137-
},
133+
return {
134+
type: 'datatable',
135+
columns: [
136+
{ name: '@timestamp', type: 'date' },
137+
{ name: 'value', type: 'number' },
138+
{ name: 'label', type: 'string' },
139+
],
140+
rows,
141+
};
142+
});
143+
},
144+
};
138145
};
139146
}

x-pack/legacy/plugins/canvas/public/legacy.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ const shimCoreStart = {
2121
};
2222

2323
const shimSetupPlugins: CanvasSetupDeps = {
24+
data: npSetup.plugins.data,
2425
expressions: npSetup.plugins.expressions,
2526
home: npSetup.plugins.home,
27+
usageCollection: npSetup.plugins.usageCollection,
2628
};
2729
const shimStartPlugins: CanvasStartDeps = {
2830
...npStart.plugins,

x-pack/legacy/plugins/canvas/public/lib/ui_metric.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,21 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import {
8-
createUiStatsReporter,
9-
METRIC_TYPE,
10-
} from '../../../../../../src/legacy/core_plugins/ui_metric/public';
7+
import { UiStatsMetricType, METRIC_TYPE } from '@kbn/analytics';
8+
import { UsageCollectionSetup } from 'src/plugins/usage_collection/public';
119

12-
export const trackCanvasUiMetric = createUiStatsReporter('canvas');
1310
export { METRIC_TYPE };
11+
12+
export let reportUiStats: UsageCollectionSetup['reportUiStats'] | undefined;
13+
14+
export function init(_reportUiStats: UsageCollectionSetup['reportUiStats']): void {
15+
reportUiStats = _reportUiStats;
16+
}
17+
18+
export function trackCanvasUiMetric(metricType: UiStatsMetricType, name: string | string[]) {
19+
if (!reportUiStats) {
20+
return;
21+
}
22+
23+
reportUiStats('canvas', metricType, name);
24+
}

x-pack/legacy/plugins/canvas/public/plugin.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public';
1010
import { initLoadingIndicator } from './lib/loading_indicator';
1111
import { featureCatalogueEntry } from './feature_catalogue_entry';
1212
import { ExpressionsSetup, ExpressionsStart } from '../../../../../src/plugins/expressions/public';
13+
import { DataPublicPluginSetup } from '../../../../../src/plugins/data/public';
1314
import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public';
1415
import { EmbeddableStart } from '../../../../../src/plugins/embeddable/public';
16+
import { UsageCollectionSetup } from '../../../../../src/plugins/usage_collection/public';
1517
import { Start as InspectorStart } from '../../../../../src/plugins/inspector/public';
1618
// @ts-ignore untyped local
1719
import { argTypeSpecs } from './expression_types/arg_types';
@@ -20,22 +22,25 @@ import { legacyRegistries } from './legacy_plugin_support';
2022
import { getPluginApi, CanvasApi } from './plugin_api';
2123
import { initFunctions } from './functions';
2224
import { CanvasSrcPlugin } from '../canvas_plugin_src/plugin';
23-
export { CoreStart };
25+
export { CoreStart, CoreSetup };
2426

2527
/**
2628
* These are the private interfaces for the services your plugin depends on.
2729
* @internal
2830
*/
2931
// This interface will be built out as we require other plugins for setup
3032
export interface CanvasSetupDeps {
33+
data: DataPublicPluginSetup;
3134
expressions: ExpressionsSetup;
3235
home: HomePublicPluginSetup;
36+
usageCollection?: UsageCollectionSetup;
3337
}
3438

3539
export interface CanvasStartDeps {
3640
embeddable: EmbeddableStart;
3741
expressions: ExpressionsStart;
3842
inspector: InspectorStart;
43+
3944
uiActions: UiActionsStart;
4045
__LEGACY: {
4146
absoluteToParsedUrl: (url: string, basePath: string) => any;
@@ -94,7 +99,13 @@ export class CanvasPlugin
9499
canvasApi.addTypes(legacyRegistries.types.getOriginalFns());
95100

96101
// Register core canvas stuff
97-
canvasApi.addFunctions(initFunctions({ typesRegistry: plugins.expressions.__LEGACY.types }));
102+
canvasApi.addFunctions(
103+
initFunctions({
104+
timefilter: plugins.data.query.timefilter.timefilter,
105+
prependBasePath: core.http.basePath.prepend,
106+
typesRegistry: plugins.expressions.__LEGACY.types,
107+
})
108+
);
98109
canvasApi.addArgumentUIs(argTypeSpecs);
99110
canvasApi.addTransitions(transitions);
100111

0 commit comments

Comments
 (0)