Skip to content

Commit

Permalink
Extract/inject references for by-value embeddables in embeddable func…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
cqliu1 committed Oct 15, 2021
1 parent 74e168b commit fc41b40
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
* 2.0.
*/

import { embeddable } from './embeddable';
import { embeddableFunctionFactory } from './embeddable';
import { getQueryFilters } from '../../../common/lib/build_embeddable_filters';
import { ExpressionValueFilter } from '../../../types';
import { encode } from '../../../common/lib/embeddable_dataurl';
import { InitializeArguments } from '.';

const filterContext: ExpressionValueFilter = {
type: 'filter',
Expand All @@ -32,7 +33,7 @@ const filterContext: ExpressionValueFilter = {
};

describe('embeddable', () => {
const fn = embeddable().fn;
const fn = embeddableFunctionFactory({} as InitializeArguments)().fn;
const config = {
id: 'some-id',
timerange: { from: '15m', to: 'now' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { getFunctionHelp } from '../../../i18n';
import { SavedObjectReference } from '../../../../../../src/core/types';
import { getQueryFilters } from '../../../common/lib/build_embeddable_filters';
import { decode, encode } from '../../../common/lib/embeddable_dataurl';
import { InitializeArguments } from '.';

interface Arguments {
config: string;
Expand All @@ -31,77 +32,112 @@ const baseEmbeddableInput = {

type Return = EmbeddableExpression<EmbeddableInput>;

export function embeddable(): ExpressionFunctionDefinition<
type EmbeddableFunction = ExpressionFunctionDefinition<
'embeddable',
ExpressionValueFilter | null,
Arguments,
Return
> {
const { help, args: argHelp } = getFunctionHelp().embeddable;

return {
name: 'embeddable',
help,
args: {
config: {
aliases: ['_'],
types: ['string'],
required: true,
help: argHelp.config,
},
type: {
types: ['string'],
required: true,
help: argHelp.type,
},
},
context: {
types: ['filter'],
},
type: EmbeddableExpressionType,
fn: (input, args) => {
const filters = input ? input.and : [];

const embeddableInput = decode(args.config) as EmbeddableInput;

return {
type: EmbeddableExpressionType,
input: {
...baseEmbeddableInput,
...embeddableInput,
filters: getQueryFilters(filters),
>;

export function embeddableFunctionFactory({
embeddablePersistableStateService,
}: InitializeArguments): () => EmbeddableFunction {
return function embeddable(): EmbeddableFunction {
const { help, args: argHelp } = getFunctionHelp().embeddable;

return {
name: 'embeddable',
help,
args: {
config: {
aliases: ['_'],
types: ['string'],
required: true,
help: argHelp.config,
},
generatedAt: Date.now(),
embeddableType: args.type,
};
},

extract(state) {
const input = decode(state.config[0] as string);
const refName = 'embeddable.id';

const references: SavedObjectReference[] = [
{
name: refName,
type: state.type[0] as string,
id: input.savedObjectId as string,
type: {
types: ['string'],
required: true,
help: argHelp.type,
},
];
},
context: {
types: ['filter'],
},
type: EmbeddableExpressionType,
fn: (input, args) => {
const filters = input ? input.and : [];

const embeddableInput = decode(args.config) as EmbeddableInput;

return {
state,
references,
};
},
return {
type: EmbeddableExpressionType,
input: {
...baseEmbeddableInput,
...embeddableInput,
filters: getQueryFilters(filters),
},
generatedAt: Date.now(),
embeddableType: args.type,
};
},

inject(state, references) {
const reference = references.find((ref) => ref.name === 'embeddable.id');
if (reference) {
extract(state) {
const input = decode(state.config[0] as string);
input.savedObjectId = reference.id;
state.config[0] = encode(input);
}
return state;
},

// extracts references for by-reference embeddables
if (input.savedObjectId) {
const refName = 'embeddable.savedObjectId';

const references: SavedObjectReference[] = [
{
name: refName,
type: state.type[0] as string,
id: input.savedObjectId as string,
},
];

return {
state,
references,
};
}

// extracts references for by-value embeddables
const { state: extractedState, references: extractedReferences } =
embeddablePersistableStateService.extract({
...input,
type: state.type[0],
});

const { type, ...extractedInput } = extractedState;

return {
state: { ...state, config: [encode(extractedInput)], type: [type] },
references: extractedReferences,
};
},

inject(state, references) {
const input = decode(state.config[0] as string);
const savedObjectReference = references.find((ref) => ref.name === 'embeddable.id');

// injects saved object id for by-references embeddable
if (savedObjectReference) {
input.savedObjectId = savedObjectReference.id;
state.config[0] = encode(input);
state.type[0] = savedObjectReference.type;
} else {
// injects references for by-value embeddables
const { type, ...injectedInput } = embeddablePersistableStateService.inject(
input,
references
);
state.config[0] = encode(injectedInput);
state.type[0] = type;
}
return state;
},
};
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@
* 2.0.
*/

import { EmbeddableStart } from 'src/plugins/embeddable/public';
import { embeddableFunctionFactory } from './embeddable';
import { savedLens } from './saved_lens';
import { savedMap } from './saved_map';
import { savedSearch } from './saved_search';
import { savedVisualization } from './saved_visualization';
import { embeddable } from './embeddable';

export const functions = [embeddable, savedLens, savedMap, savedSearch, savedVisualization];
export interface InitializeArguments {
embeddablePersistableStateService: {
extract: EmbeddableStart['extract'];
inject: EmbeddableStart['inject'];
};
}

export function initFunctions(initialize: InitializeArguments) {
return [
embeddableFunctionFactory(initialize),
savedLens,
savedMap,
savedSearch,
savedVisualization,
];
}
4 changes: 2 additions & 2 deletions x-pack/plugins/canvas/i18n/functions/dict/embeddable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
*/

import { i18n } from '@kbn/i18n';
import { embeddable } from '../../../canvas_plugin_src/functions/external/embeddable';
import { embeddableFunctionFactory } from '../../../canvas_plugin_src/functions/external/embeddable';
import { FunctionHelp } from '../function_help';
import { FunctionFactory } from '../../../types';

export const help: FunctionHelp<FunctionFactory<typeof embeddable>> = {
export const help: FunctionHelp<FunctionFactory<ReturnType<typeof embeddableFunctionFactory>>> = {
help: i18n.translate('xpack.canvas.functions.embeddableHelpText', {
defaultMessage: `Returns an embeddable with the provided configuration`,
}),
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/canvas/public/application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export const initializeCanvas = async (
prependBasePath: coreStart.http.basePath.prepend,
types: setupPlugins.expressions.getTypes(),
paletteService: await setupPlugins.charts.palettes.getPalettes(),
embeddablesService: startPlugins.embeddable,
});

for (const fn of canvasFunctions) {
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/canvas/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class CanvasPlugin implements Plugin {
const globalConfig = this.initializerContext.config.legacy.get();
registerCanvasUsageCollector(plugins.usageCollection, globalConfig.kibana.index);

setupInterpreter(expressionsFork);
setupInterpreter(expressionsFork, { embeddablesService: plugins.embeddable });

coreSetup.getStartServices().then(([_, depsStart]) => {
const strategy = essqlSearchStrategyProvider();
Expand Down
12 changes: 10 additions & 2 deletions x-pack/plugins/canvas/server/setup_interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,18 @@
*/

import { ExpressionsServerSetup } from 'src/plugins/expressions/server';
import { EmbeddableSetup } from 'src/plugins/embeddable/server';
import { functions } from '../canvas_plugin_src/functions/server';
import { functions as externalFunctions } from '../canvas_plugin_src/functions/external';
import { initFunctions as initExternalFunctions } from '../canvas_plugin_src/functions/external';

export function setupInterpreter(expressions: ExpressionsServerSetup) {
interface InterpreterDependencies {
embeddablesService: EmbeddableSetup;
}

export function setupInterpreter(
expressions: ExpressionsServerSetup,
dependencies: InterpreterDependencies
) {
functions.forEach((f) => expressions.registerFunction(f));
externalFunctions.forEach((f) => expressions.registerFunction(f));
}

0 comments on commit fc41b40

Please sign in to comment.