Skip to content

Commit

Permalink
[Canvas] Misc NP Stuff (elastic#63703)
Browse files Browse the repository at this point in the history
* Timelion function -> np

* embeddable renderer -> np i18n context

* ui_metric -> np

* Fix timelion issue

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
Corey Robertson and elasticmachine committed Apr 24, 2020
1 parent 19c2a2a commit 049572c
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import React from 'react';
import ReactDOM from 'react-dom';
import { I18nContext } from 'ui/i18n';
import { CoreStart } from '../../../../../../../src/core/public';
import { StartDeps } from '../../plugin';
import {
Expand All @@ -30,6 +29,8 @@ const embeddablesRegistry: {
} = {};

const renderEmbeddableFactory = (core: CoreStart, plugins: StartDeps) => {
const I18nContext = core.i18n.Context;

return (embeddableObject: IEmbeddable, domNode: HTMLElement) => {
return (
<div
Expand Down
4 changes: 2 additions & 2 deletions x-pack/legacy/plugins/canvas/i18n/functions/dict/timelion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
*/

import { i18n } from '@kbn/i18n';
import { timelion } from '../../../public/functions/timelion';
import { timelionFunctionFactory } from '../../../public/functions/timelion';
import { FunctionHelp } from '../function_help';
import { FunctionFactory } from '../../../types';
import { ELASTICSEARCH, DATEMATH, MOMENTJS_TIMEZONE_URL } from '../../constants';

export const help: FunctionHelp<FunctionFactory<typeof timelion>> = {
export const help: FunctionHelp<FunctionFactory<ReturnType<typeof timelionFunctionFactory>>> = {
help: i18n.translate('xpack.canvas.functions.timelionHelpText', {
defaultMessage: 'Use Timelion to extract one or more timeseries from many sources.',
}),
Expand Down
5 changes: 5 additions & 0 deletions x-pack/legacy/plugins/canvas/public/application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { VALUE_CLICK_TRIGGER, ActionByType } from '../../../../../src/plugins/ui
/* eslint-disable */
import { ACTION_VALUE_CLICK } from '../../../../../src/plugins/data/public/actions/value_click_action';
/* eslint-enable */
import { init as initStatsReporter } from './lib/ui_metric';

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

if (setupPlugins.usageCollection) {
initStatsReporter(setupPlugins.usageCollection.reportUiStats);
}

return canvasStore;
};

Expand Down
15 changes: 11 additions & 4 deletions x-pack/legacy/plugins/canvas/public/functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { ExpressionsSetup } from 'src/plugins/expressions/public';
import { asset } from './asset';
import { filtersFunctionFactory } from './filters';
import { timelion } from './timelion';
import { timelionFunctionFactory } from './timelion';
import { toFunctionFactory } from './to';
import { CanvasSetupDeps, CoreSetup } from '../plugin';

export interface InitializeArguments {
typesRegistry: ExpressionsSetup['__LEGACY']['types'];
prependBasePath: CoreSetup['http']['basePath']['prepend'];
typesRegistry: CanvasSetupDeps['expressions']['__LEGACY']['types'];
timefilter: CanvasSetupDeps['data']['query']['timefilter']['timefilter'];
}

export function initFunctions(initialize: InitializeArguments) {
return [asset, filtersFunctionFactory(initialize), timelion, toFunctionFactory(initialize)];
return [
asset,
filtersFunctionFactory(initialize),
timelionFunctionFactory(initialize),
toFunctionFactory(initialize),
];
}
173 changes: 90 additions & 83 deletions x-pack/legacy/plugins/canvas/public/functions/timelion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@

import { flatten } from 'lodash';
import moment from 'moment-timezone';
import chrome from 'ui/chrome';
import { npStart } from 'ui/new_platform';
import { TimeRange } from 'src/plugins/data/common';
import { ExpressionFunctionDefinition, DatatableRow } from 'src/plugins/expressions/public';
import { fetch } from '../../common/lib/fetch';
// @ts-ignore untyped local
import { buildBoolArray } from '../../server/lib/build_bool_array';
import { Datatable, Filter } from '../../types';
import { getFunctionHelp } from '../../i18n';
import { InitializeArguments } from './';

interface Arguments {
query: string;
Expand All @@ -30,110 +29,118 @@ interface Arguments {
* @param timeRange time range to parse
* @param timeZone time zone to do the parsing in
*/
function parseDateMath(timeRange: TimeRange, timeZone: string) {
function parseDateMath(
timeRange: TimeRange,
timeZone: string,
timefilter: InitializeArguments['timefilter']
) {
// the datemath plugin always parses dates by using the current default moment time zone.
// to use the configured time zone, we are switching just for the bounds calculation.
const defaultTimezone = moment().zoneName();
moment.tz.setDefault(timeZone);

const parsedRange = npStart.plugins.data.query.timefilter.timefilter.calculateBounds(timeRange);
const parsedRange = timefilter.calculateBounds(timeRange);

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

return parsedRange;
}

export function timelion(): ExpressionFunctionDefinition<
type TimelionFunction = ExpressionFunctionDefinition<
'timelion',
Filter,
Arguments,
Promise<Datatable>
> {
const { help, args: argHelp } = getFunctionHelp().timelion;
>;

return {
name: 'timelion',
type: 'datatable',
inputTypes: ['filter'],
help,
args: {
query: {
types: ['string'],
aliases: ['_', 'q'],
help: argHelp.query,
default: '".es(*)"',
},
interval: {
types: ['string'],
help: argHelp.interval,
default: 'auto',
},
from: {
types: ['string'],
help: argHelp.from,
default: 'now-1y',
},
to: {
types: ['string'],
help: argHelp.to,
default: 'now',
},
timezone: {
types: ['string'],
help: argHelp.timezone,
default: 'UTC',
export function timelionFunctionFactory(initialize: InitializeArguments): () => TimelionFunction {
return () => {
const { help, args: argHelp } = getFunctionHelp().timelion;

return {
name: 'timelion',
type: 'datatable',
inputTypes: ['filter'],
help,
args: {
query: {
types: ['string'],
aliases: ['_', 'q'],
help: argHelp.query,
default: '".es(*)"',
},
interval: {
types: ['string'],
help: argHelp.interval,
default: 'auto',
},
from: {
types: ['string'],
help: argHelp.from,
default: 'now-1y',
},
to: {
types: ['string'],
help: argHelp.to,
default: 'now',
},
timezone: {
types: ['string'],
help: argHelp.timezone,
default: 'UTC',
},
},
},
fn: (input, args): Promise<Datatable> => {
// Timelion requires a time range. Use the time range from the timefilter element in the
// workpad, if it exists. Otherwise fall back on the function args.
const timeFilter = input.and.find(and => and.type === 'time');
const range = timeFilter
? { min: timeFilter.from, max: timeFilter.to }
: parseDateMath({ from: args.from, to: args.to }, args.timezone);
fn: (input, args): Promise<Datatable> => {
// Timelion requires a time range. Use the time range from the timefilter element in the
// workpad, if it exists. Otherwise fall back on the function args.
const timeFilter = input.and.find(and => and.type === 'time');
const range = timeFilter
? { min: timeFilter.from, max: timeFilter.to }
: parseDateMath({ from: args.from, to: args.to }, args.timezone, initialize.timefilter);

const body = {
extended: {
es: {
filter: {
bool: {
must: buildBoolArray(input.and),
const body = {
extended: {
es: {
filter: {
bool: {
must: buildBoolArray(input.and),
},
},
},
},
},
sheet: [args.query],
time: {
from: range.min,
to: range.max,
interval: args.interval,
timezone: args.timezone,
},
};
sheet: [args.query],
time: {
from: range.min,
to: range.max,
interval: args.interval,
timezone: args.timezone,
},
};

return fetch(chrome.addBasePath(`/api/timelion/run`), {
method: 'POST',
responseType: 'json',
data: body,
}).then(resp => {
const seriesList = resp.data.sheet[0].list;
const rows = flatten(
seriesList.map((series: { data: any[]; label: string }) =>
series.data.map(row => ({ '@timestamp': row[0], value: row[1], label: series.label }))
)
) as DatatableRow[];
return fetch(initialize.prependBasePath(`/api/timelion/run`), {
method: 'POST',
responseType: 'json',
data: body,
}).then(resp => {
const seriesList = resp.data.sheet[0].list;
const rows = flatten(
seriesList.map((series: { data: any[]; label: string }) =>
series.data.map(row => ({ '@timestamp': row[0], value: row[1], label: series.label }))
)
) as DatatableRow[];

return {
type: 'datatable',
columns: [
{ name: '@timestamp', type: 'date' },
{ name: 'value', type: 'number' },
{ name: 'label', type: 'string' },
],
rows,
};
});
},
return {
type: 'datatable',
columns: [
{ name: '@timestamp', type: 'date' },
{ name: 'value', type: 'number' },
{ name: 'label', type: 'string' },
],
rows,
};
});
},
};
};
}
2 changes: 2 additions & 0 deletions x-pack/legacy/plugins/canvas/public/legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ const shimCoreStart = {
};

const shimSetupPlugins: CanvasSetupDeps = {
data: npSetup.plugins.data,
expressions: npSetup.plugins.expressions,
home: npSetup.plugins.home,
usageCollection: npSetup.plugins.usageCollection,
};
const shimStartPlugins: CanvasStartDeps = {
...npStart.plugins,
Expand Down
21 changes: 16 additions & 5 deletions x-pack/legacy/plugins/canvas/public/lib/ui_metric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@
* you may not use this file except in compliance with the Elastic License.
*/

import {
createUiStatsReporter,
METRIC_TYPE,
} from '../../../../../../src/legacy/core_plugins/ui_metric/public';
import { UiStatsMetricType, METRIC_TYPE } from '@kbn/analytics';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/public';

export const trackCanvasUiMetric = createUiStatsReporter('canvas');
export { METRIC_TYPE };

export let reportUiStats: UsageCollectionSetup['reportUiStats'] | undefined;

export function init(_reportUiStats: UsageCollectionSetup['reportUiStats']): void {
reportUiStats = _reportUiStats;
}

export function trackCanvasUiMetric(metricType: UiStatsMetricType, name: string | string[]) {
if (!reportUiStats) {
return;
}

reportUiStats('canvas', metricType, name);
}
15 changes: 13 additions & 2 deletions x-pack/legacy/plugins/canvas/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public';
import { initLoadingIndicator } from './lib/loading_indicator';
import { featureCatalogueEntry } from './feature_catalogue_entry';
import { ExpressionsSetup, ExpressionsStart } from '../../../../../src/plugins/expressions/public';
import { DataPublicPluginSetup } from '../../../../../src/plugins/data/public';
import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public';
import { EmbeddableStart } from '../../../../../src/plugins/embeddable/public';
import { UsageCollectionSetup } from '../../../../../src/plugins/usage_collection/public';
import { Start as InspectorStart } from '../../../../../src/plugins/inspector/public';
// @ts-ignore untyped local
import { argTypeSpecs } from './expression_types/arg_types';
Expand All @@ -20,22 +22,25 @@ import { legacyRegistries } from './legacy_plugin_support';
import { getPluginApi, CanvasApi } from './plugin_api';
import { initFunctions } from './functions';
import { CanvasSrcPlugin } from '../canvas_plugin_src/plugin';
export { CoreStart };
export { CoreStart, CoreSetup };

/**
* These are the private interfaces for the services your plugin depends on.
* @internal
*/
// This interface will be built out as we require other plugins for setup
export interface CanvasSetupDeps {
data: DataPublicPluginSetup;
expressions: ExpressionsSetup;
home: HomePublicPluginSetup;
usageCollection?: UsageCollectionSetup;
}

export interface CanvasStartDeps {
embeddable: EmbeddableStart;
expressions: ExpressionsStart;
inspector: InspectorStart;

uiActions: UiActionsStart;
__LEGACY: {
absoluteToParsedUrl: (url: string, basePath: string) => any;
Expand Down Expand Up @@ -94,7 +99,13 @@ export class CanvasPlugin
canvasApi.addTypes(legacyRegistries.types.getOriginalFns());

// Register core canvas stuff
canvasApi.addFunctions(initFunctions({ typesRegistry: plugins.expressions.__LEGACY.types }));
canvasApi.addFunctions(
initFunctions({
timefilter: plugins.data.query.timefilter.timefilter,
prependBasePath: core.http.basePath.prepend,
typesRegistry: plugins.expressions.__LEGACY.types,
})
);
canvasApi.addArgumentUIs(argTypeSpecs);
canvasApi.addTransitions(transitions);

Expand Down

0 comments on commit 049572c

Please sign in to comment.