From e18ebbe1fcefc4135af35af699fd9559d887230f Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 1 Oct 2020 18:12:57 +0200 Subject: [PATCH] table poc --- .../public/lib/url_drilldown.tsx | 9 ++++- .../public/lib/url_drilldown_scope.test.ts | 38 +++++++++---------- .../public/lib/url_drilldown_scope.ts | 28 +++++++++++--- .../drilldowns/url_drilldown/url_template.ts | 8 +++- .../url_drilldown/url_validation.ts | 5 ++- 5 files changed, 57 insertions(+), 31 deletions(-) diff --git a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx index 85e92d0827daa..08b35d078df23 100644 --- a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx +++ b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx @@ -90,14 +90,19 @@ export class UrlDrilldown implements Drilldown { - const { isValid } = urlDrilldownValidateUrlTemplate(config.url, this.buildEditorScope(context)); + const { isValid } = urlDrilldownValidateUrlTemplate( + config.url, + this.buildEditorScope(context), + { validateVariables: false } + ); return isValid; }; public readonly isCompatible = async (config: Config, context: ActionContext) => { const { isValid, error } = urlDrilldownValidateUrlTemplate( config.url, - await this.buildRuntimeScope(context) + await this.buildRuntimeScope(context), + { validateVariables: true } ); if (!isValid) { diff --git a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.test.ts b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.test.ts index bb1baf5b96428..884ee4602cbd4 100644 --- a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.test.ts +++ b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.test.ts @@ -84,25 +84,25 @@ describe('VALUE_CLICK_TRIGGER', () => { ]) as ValueClickTriggerEventScope; expect(mockEventScope.points.length).toBeGreaterThan(3); expect(mockEventScope.points).toMatchInlineSnapshot(` - Array [ - Object { - "key": "event.points.0.key", - "value": "event.points.0.value", - }, - Object { - "key": "event.points.1.key", - "value": "event.points.1.value", - }, - Object { - "key": "event.points.2.key", - "value": "event.points.2.value", - }, - Object { - "key": "event.points.3.key", - "value": "event.points.3.value", - }, - ] - `); + Array [ + Object { + "key": "event.points.[0].key", + "value": "event.points.[0].value", + }, + Object { + "key": "event.points.[1].key", + "value": "event.points.[1].value", + }, + Object { + "key": "event.points.[2].key", + "value": "event.points.[2].value", + }, + Object { + "key": "event.points.[3].key", + "value": "event.points.[3].value", + }, + ] + `); }); }); diff --git a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.ts b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.ts index 15a9a3ba77d88..80b27d1f90346 100644 --- a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.ts +++ b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.ts @@ -108,6 +108,7 @@ export interface ValueClickTriggerEventScope { value: Primitive; negate: boolean; points: Array<{ key?: string; value: Primitive }>; + row: Primitive[]; } export interface RangeSelectTriggerEventScope { key: string; @@ -131,7 +132,7 @@ function getEventScopeFromRangeSelectTriggerContext( const { table, column: columnIndex, range } = eventScopeInput.data; const column = table.columns[columnIndex]; return cleanEmptyKeys({ - key: toPrimitiveOrUndefined(column?.meta?.aggConfigParams?.field) as string, + key: toPrimitiveOrUndefined(column?.meta?.aggConfigParams?.field ?? column?.name) as string, from: toPrimitiveOrUndefined(range[0]) as string | number | undefined, to: toPrimitiveOrUndefined(range[range.length - 1]) as string | number | undefined, }); @@ -141,19 +142,29 @@ function getEventScopeFromValueClickTriggerContext( eventScopeInput: ValueClickContext ): ValueClickTriggerEventScope { const negate = eventScopeInput.data.negate ?? false; + const points = eventScopeInput.data.data.map(({ table, value, column: columnIndex }) => { const column = table.columns[columnIndex]; return { value: toPrimitiveOrUndefined(value) as Primitive, - key: toPrimitiveOrUndefined(column?.meta?.aggConfigParams?.field) as string | undefined, + key: toPrimitiveOrUndefined(column?.meta?.aggConfigParams?.field ?? column?.name) as + | string + | undefined, }; }); + const dataPoint = eventScopeInput.data.data[0]; + + const row = dataPoint.table.columns.map( + ({ id }) => dataPoint.table.rows[dataPoint.row][id] + ) as Primitive[]; + return cleanEmptyKeys({ key: points[0]?.key, value: points[0]?.value, negate, points, + row, }); } @@ -174,14 +185,19 @@ export function getMockEventScope([trigger]: UrlTrigger[]): UrlDrilldownEventSco // should be larger or equal of any possible data points length emitted by VALUE_CLICK_TRIGGER const nPoints = 4; const points = new Array(nPoints).fill(0).map((_, index) => ({ - key: `event.points.${index}.key`, - value: `event.points.${index}.value`, + key: `event.points.[${index}].key`, + value: `event.points.[${index}].value`, })); + + // number of mock columns to generate + const nColumns = 4; + const row = new Array(nColumns).fill(0).map((_, index) => `event.row.[${index}]`); return { - key: `event.key`, - value: `event.value`, + key: points[0].key, + value: points[0].value, negate: false, points, + row, }; } } diff --git a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_template.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_template.ts index 2c3537636b9da..243d32e8438b0 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_template.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_template.ts @@ -69,7 +69,11 @@ handlebars.registerHelper('date', (...args) => { return format ? momentDate.format(format) : momentDate.toISOString(); }); -export function compile(url: string, context: object): string { - const template = handlebars.compile(url, { strict: true, noEscape: true }); +export function compile( + url: string, + context: object, + { strict = true }: { strict: boolean } = { strict: true } +): string { + const template = handlebars.compile(url, { strict, noEscape: true }); return encodeURI(template(context)); } diff --git a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_validation.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_validation.ts index b32f5d84c6775..bb3f896210bc0 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_validation.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_validation.ts @@ -51,7 +51,8 @@ export function validateUrl(url: string): { isValid: boolean; error?: string } { export function validateUrlTemplate( urlTemplate: UrlDrilldownConfig['url'], - scope: UrlDrilldownScope + scope: UrlDrilldownScope, + { validateVariables = true }: { validateVariables: boolean } = { validateVariables: true } ): { isValid: boolean; error?: string } { if (!urlTemplate.template) return { @@ -60,7 +61,7 @@ export function validateUrlTemplate( }; try { - const compiledUrl = compile(urlTemplate.template, scope); + const compiledUrl = compile(urlTemplate.template, scope, { strict: validateVariables }); return validateUrl(compiledUrl); } catch (e) { return {