[Canvas] Expression reveal image. (#101987) (#104076)

* expression_reveal_image skeleton.

* expression_functions added.

* expression_renderers added.

* Backup of daily work.

* Fixed errors.

* Added legacy support. Added button for legacy.

* Added storybook.

* Removed revealImage from canvas.

* setState while rendering error fixed.

* tsconfig.json added.

* jest.config.js added.

* Demo doc added.

* Types fixed.

* added limits.

* Removed not used imports.

* i18n namespaces fixed.

* Fixed test suite error.

* Some errors fixed.

* Fixed eslint error.

* Removed more unused translations.

* Moved UI and elements, related to expressionRevealImage from canvas.

* Fixed unused translations errors.

* Moved type of element to types.

* Fixed types and added service for representing elements, ui and supported renderers to canvas.

* Added expression registration to canvas.

* Fixed

* Fixed mutiple call of the function.

* Removed support of a legacy lib for revealImage chart.

* Removed legacy presentation_utils plugin import.

* Doc error fixed.

* Removed useless translations and tried to fix error.

* One more fix.

* Small imports fix.

* Fixed translations.

* Made fixes based on nits.

* Removed useless params.

* fix.

* Fixed errors, related to jest and __mocks__.

* Removed useless type definition.

* Replaced RendererHandlers with IInterpreterRendererHandlers.

* fixed supported_shareable.

* Moved elements back to canvas.

* Moved views to canvas, removed expression service and imported renderer to canvas.

* Fixed translations.

* Types fix.

* Moved libs to presentation utils.

* Fixed one mistake.

* removed dataurl lib.

* Fixed jest files.

* elasticLogo removed.

* Removed elastic_outline.

* removed httpurl.

* Removed missing_asset.

* removed url.

* replaced mostly all tests.

* Fixed types.

* Fixed types and removed function_wrapper.ts

* Fixed types of test helpers.

* Changed limits of presentationUtil plugin.

* Fixed imports.

* One more fix.

* Fixed huge size of bundle.

* Reduced allow limit for presentationUtil

* Updated limits for presentationUtil.

* Fixed public API.

* fixed type errors.

* Moved css to component.

* Fixed spaces at element.

* Changed order of requiredPlugins.

* Updated limits.

* Removed unused plugin.

* Added rule for allowing import from __stories__ directory.

* removed useless comment.

* Changed readme.md

* Fixed docs error.

* A possible of smoke test.

* onResize changed to useResizeObserver.

* Remove useless events and `useEffect` block.

* Changed from passing handlers to separate functions.

* `function` moved to `server`.

* Fixed eslint error.

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Yaroslav Kuznietsov <kuznetsov.yaroslav.yk@gmail.com>
This commit is contained in:
Kibana Machine 2021-07-01 09:09:53 -04:00 committed by GitHub
parent 92991327a4
commit bdfb417a54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
159 changed files with 1311 additions and 512 deletions

View file

@ -451,6 +451,7 @@ module.exports = {
'(src|x-pack)/plugins/**/(public|server)/**/*',
'!(src|x-pack)/plugins/**/(public|server)/mocks/index.{js,mjs,ts}',
'!(src|x-pack)/plugins/**/(public|server)/(index|mocks).{js,mjs,ts,tsx}',
'!(src|x-pack)/plugins/**/__stories__/index.{js,mjs,ts,tsx}',
],
allowSameFolder: true,
errorMessage: 'Plugins may only import from top-level public and server modules.',

View file

@ -16,6 +16,7 @@
"esUi": "src/plugins/es_ui_shared",
"devTools": "src/plugins/dev_tools",
"expressions": "src/plugins/expressions",
"expressionRevealImage": "src/plugins/expression_reveal_image",
"inputControl": "src/plugins/input_control_vis",
"inspector": "src/plugins/inspector",
"inspectorViews": "src/legacy/core_plugins/inspector_views",

View file

@ -70,6 +70,10 @@ This API doesn't support angular, for registering angular dev tools, bootstrap a
|WARNING: Missing README.
|{kib-repo}blob/{branch}/src/plugins/expression_reveal_image/README.md[expressionRevealImage]
|Expression Reveal Image plugin adds a revealImage function to the expression plugin and an associated renderer. The renderer will display the given percentage of a given image.
|<<kibana-expressions-plugin>>
|Expression pipeline is a chain of functions that *pipe* its output to the
input of the next function. Functions can be configured using arguments provided

View file

@ -99,7 +99,7 @@ pageLoadAssetSize:
watcher: 43742
runtimeFields: 41752
stackAlerts: 29684
presentationUtil: 49767
presentationUtil: 94301
spacesOss: 18817
indexPatternFieldEditor: 90489
osquery: 107090
@ -110,4 +110,5 @@ pageLoadAssetSize:
timelines: 230410
screenshotMode: 17856
visTypePie: 35583
expressionRevealImage: 25675
cases: 144442

View file

@ -17,6 +17,7 @@ export const storybookAliases = {
dashboard_enhanced: 'x-pack/plugins/dashboard_enhanced/.storybook',
data_enhanced: 'x-pack/plugins/data_enhanced/.storybook',
embeddable: 'src/plugins/embeddable/.storybook',
expression_reveal_image: 'src/plugins/expression_reveal_image/.storybook',
infra: 'x-pack/plugins/infra/.storybook',
security_solution: 'x-pack/plugins/security_solution/.storybook',
ui_actions_enhanced: 'x-pack/plugins/ui_actions_enhanced/.storybook',

View file

@ -0,0 +1,7 @@
{
"prefix": "expressionRevealImage",
"paths": {
"expressionRevealImage": "."
},
"translations": ["translations/ja-JP.json"]
}

View file

@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
// eslint-disable-next-line import/no-commonjs
module.exports = require('@kbn/storybook').defaultConfig;

View file

@ -0,0 +1,9 @@
# expressionRevealImage
Expression Reveal Image plugin adds a `revealImage` function to the expression plugin and an associated renderer. The renderer will display the given percentage of a given image.
---
## Development
See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions setting up your development environment.

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export const PLUGIN_ID = 'expressionRevealImage';
export const PLUGIN_NAME = 'expressionRevealImage';

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { revealImageFunction } from './reveal_image_function';
export const functions = [revealImageFunction];
export { revealImageFunction };

View file

@ -0,0 +1,168 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import {
functionWrapper,
elasticOutline,
elasticLogo,
} from '../../../presentation_util/common/lib';
import { getFunctionErrors } from '../i18n';
import { revealImageFunction } from './reveal_image_function';
import { Origin } from '../types';
import { ExecutionContext } from 'src/plugins/expressions';
const errors = getFunctionErrors().revealImage;
describe('revealImageFunction', () => {
const fn = functionWrapper(revealImageFunction);
it('returns a render as revealImage', () => {
const result = fn(
0.5,
{
image: null,
emptyImage: null,
origin: Origin.BOTTOM,
},
{} as ExecutionContext
);
expect(result).toHaveProperty('type', 'render');
expect(result).toHaveProperty('as', 'revealImage');
});
describe('context', () => {
it('throws when context is not a number between 0 and 1', () => {
expect(() => {
fn(
10,
{
image: elasticLogo,
emptyImage: elasticOutline,
origin: Origin.TOP,
},
{} as ExecutionContext
);
}).toThrow(new RegExp(errors.invalidPercent(10).message));
expect(() => {
fn(
-0.1,
{
image: elasticLogo,
emptyImage: elasticOutline,
origin: Origin.TOP,
},
{} as ExecutionContext
);
}).toThrow(new RegExp(errors.invalidPercent(-0.1).message));
});
});
describe('args', () => {
describe('image', () => {
it('sets the image', () => {
const result = fn(
0.89,
{
emptyImage: null,
origin: Origin.TOP,
image: elasticLogo,
},
{} as ExecutionContext
).value;
expect(result).toHaveProperty('image', elasticLogo);
});
it('defaults to the Elastic outline logo', () => {
const result = fn(
0.89,
{
emptyImage: null,
origin: Origin.TOP,
image: null,
},
{} as ExecutionContext
).value;
expect(result).toHaveProperty('image', elasticOutline);
});
});
describe('emptyImage', () => {
it('sets the background image', () => {
const result = fn(
0,
{
emptyImage: elasticLogo,
origin: Origin.TOP,
image: null,
},
{} as ExecutionContext
).value;
expect(result).toHaveProperty('emptyImage', elasticLogo);
});
it('sets emptyImage to null', () => {
const result = fn(
0,
{
emptyImage: null,
origin: Origin.TOP,
image: null,
},
{} as ExecutionContext
).value;
expect(result).toHaveProperty('emptyImage', null);
});
});
describe('origin', () => {
it('sets which side to start the reveal from', () => {
let result = fn(
1,
{
emptyImage: null,
origin: Origin.TOP,
image: null,
},
{} as ExecutionContext
).value;
expect(result).toHaveProperty('origin', 'top');
result = fn(
1,
{
emptyImage: null,
origin: Origin.LEFT,
image: null,
},
{} as ExecutionContext
).value;
expect(result).toHaveProperty('origin', 'left');
result = fn(
1,
{
emptyImage: null,
origin: Origin.BOTTOM,
image: null,
},
{} as ExecutionContext
).value;
expect(result).toHaveProperty('origin', 'bottom');
result = fn(
1,
{
emptyImage: null,
origin: Origin.RIGHT,
image: null,
},
{} as ExecutionContext
).value;
expect(result).toHaveProperty('origin', 'right');
});
});
});
});

View file

@ -1,41 +1,16 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { ExpressionFunctionDefinition, ExpressionValueRender } from 'src/plugins/expressions';
import { resolveWithMissingImage } from '../../../common/lib/resolve_dataurl';
import { elasticOutline } from '../../lib/elastic_outline';
import { getFunctionHelp, getFunctionErrors } from '../../../i18n';
import { resolveWithMissingImage, elasticOutline } from '../../../presentation_util/common/lib';
import { getFunctionHelp, getFunctionErrors } from '../i18n';
import { ExpressionRevealImageFunction, Origin } from '../types';
export enum Origin {
TOP = 'top',
LEFT = 'left',
BOTTOM = 'bottom',
RIGHT = 'right',
}
interface Arguments {
image: string | null;
emptyImage: string | null;
origin: Origin;
}
export interface Output {
image: string;
emptyImage: string;
origin: Origin;
percent: number;
}
export function revealImage(): ExpressionFunctionDefinition<
'revealImage',
number,
Arguments,
ExpressionValueRender<Output>
> {
export const revealImageFunction: ExpressionRevealImageFunction = () => {
const { help, args: argHelp } = getFunctionHelp().revealImage;
const errors = getFunctionErrors().revealImage;
@ -80,4 +55,4 @@ export function revealImage(): ExpressionFunctionDefinition<
};
},
};
}
};

View file

@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export const BASE64 = '`base64`';
export const URL = 'URL';

View file

@ -1,23 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { i18n } from '@kbn/i18n';
import { revealImage } from '../../../canvas_plugin_src/functions/common/revealImage';
import { FunctionHelp } from '../function_help';
import { FunctionFactory } from '../../../types';
import { Position } from '../../../types';
import { BASE64, URL } from '../../constants';
export const help: FunctionHelp<FunctionFactory<typeof revealImage>> = {
help: i18n.translate('xpack.canvas.functions.revealImageHelpText', {
export const help = {
help: i18n.translate('expressionRevealImage.functions.revealImageHelpText', {
defaultMessage: 'Configures an image reveal element.',
}),
args: {
image: i18n.translate('xpack.canvas.functions.revealImage.args.imageHelpText', {
image: i18n.translate('expressionRevealImage.functions.revealImage.args.imageHelpText', {
defaultMessage:
'The image to reveal. Provide an image asset as a {BASE64} data {URL}, ' +
'or pass in a sub-expression.',
@ -26,16 +24,19 @@ export const help: FunctionHelp<FunctionFactory<typeof revealImage>> = {
URL,
},
}),
emptyImage: i18n.translate('xpack.canvas.functions.revealImage.args.emptyImageHelpText', {
defaultMessage:
'An optional background image to reveal over. ' +
'Provide an image asset as a `{BASE64}` data {URL}, or pass in a sub-expression.',
values: {
BASE64,
URL,
},
}),
origin: i18n.translate('xpack.canvas.functions.revealImage.args.originHelpText', {
emptyImage: i18n.translate(
'expressionRevealImage.functions.revealImage.args.emptyImageHelpText',
{
defaultMessage:
'An optional background image to reveal over. ' +
'Provide an image asset as a `{BASE64}` data {URL}, or pass in a sub-expression.',
values: {
BASE64,
URL,
},
}
),
origin: i18n.translate('expressionRevealImage.functions.revealImage.args.originHelpText', {
defaultMessage: 'The position to start the image fill. For example, {list}, or {end}.',
values: {
list: Object.values(Position)
@ -50,7 +51,7 @@ export const help: FunctionHelp<FunctionFactory<typeof revealImage>> = {
export const errors = {
invalidPercent: (percent: number) =>
new Error(
i18n.translate('xpack.canvas.functions.revealImage.invalidPercentErrorMessage', {
i18n.translate('expressionRevealImage.functions.revealImage.invalidPercentErrorMessage', {
defaultMessage: "Invalid value: '{percent}'. Percentage must be between 0 and 1",
values: {
percent,

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { errors as revealImage } from './dict/reveal_image';
export const getFunctionErrors = () => ({
revealImage,
});

View file

@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { help as revealImage } from './dict/reveal_image';
/**
* Help text for Canvas Functions should be properly localized. This function will
* return a dictionary of help strings, organized by `ExpressionFunctionDefinition`
* specification and then by available arguments within each `ExpressionFunctionDefinition`.
*
* This a function, rather than an object, to future-proof string initialization,
* if ever necessary.
*/
export const getFunctionHelp = () => ({
revealImage,
});

View file

@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './function_help';
export * from './function_errors';

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export { strings as revealImage } from './reveal_image';

View file

@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { i18n } from '@kbn/i18n';
export const strings = {
getDisplayName: () =>
i18n.translate('expressionRevealImage.renderer.revealImage.displayName', {
defaultMessage: 'Image reveal',
}),
getHelpDescription: () =>
i18n.translate('expressionRevealImage.renderer.revealImage.helpDescription', {
defaultMessage: 'Reveal a percentage of an image to make a custom gauge-style chart',
}),
};

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './renderer_strings';

View file

@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { revealImage } from './dict';
/**
* Help text for Canvas Functions should be properly localized. This function will
* return a dictionary of help strings, organized by `ExpressionFunctionDefinition`
* specification and then by available arguments within each `ExpressionFunctionDefinition`.
*
* This a function, rather than an object, to future-proof string initialization,
* if ever necessary.
*/
export const getRendererStrings = () => ({
revealImage,
});

View file

@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './expression_functions';
export * from './expression_renderers';

View file

@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './constants';
export * from './expression_functions';

View file

@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { ExpressionFunctionDefinition, ExpressionValueRender } from 'src/plugins/expressions';
export enum Origin {
TOP = 'top',
LEFT = 'left',
BOTTOM = 'bottom',
RIGHT = 'right',
}
interface Arguments {
image: string | null;
emptyImage: string | null;
origin: Origin;
}
export interface Output {
image: string;
emptyImage: string;
origin: Origin;
percent: number;
}
export type ExpressionRevealImageFunction = () => ExpressionFunctionDefinition<
'revealImage',
number,
Arguments,
ExpressionValueRender<Output>
>;
export enum Position {
TOP = 'top',
BOTTOM = 'bottom',
LEFT = 'left',
RIGHT = 'right',
}

View file

@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export type OriginString = 'bottom' | 'left' | 'top' | 'right';
export interface RevealImageRendererConfig {
percent: number;
origin?: OriginString;
image?: string;
emptyImage?: string;
}
export interface NodeDimensions {
width: number;
height: number;
}

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './expression_functions';
export * from './expression_renderers';

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
preset: '@kbn/test',
rootDir: '../../..',
roots: ['<rootDir>/src/plugins/expression_reveal_image'],
};

View file

@ -0,0 +1,10 @@
{
"id": "expressionRevealImage",
"version": "1.0.0",
"kibanaVersion": "kibana",
"server": true,
"ui": true,
"requiredPlugins": ["expressions", "presentationUtil"],
"optionalPlugins": [],
"requiredBundles": []
}

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './reveal_image_component';

View file

@ -0,0 +1,136 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { useRef, useState, useEffect, useCallback } from 'react';
import { useResizeObserver } from '@elastic/eui';
import { IInterpreterRenderHandlers } from 'src/plugins/expressions';
import { NodeDimensions, RevealImageRendererConfig, OriginString } from '../../common/types';
import { isValidUrl, elasticOutline } from '../../../presentation_util/public';
import './reveal_image.scss';
interface RevealImageComponentProps extends RevealImageRendererConfig {
onLoaded: IInterpreterRenderHandlers['done'];
parentNode: HTMLElement;
}
interface ImageStyles {
width?: string;
height?: string;
clipPath?: string;
}
interface AlignerStyles {
backgroundImage?: string;
}
function RevealImageComponent({
onLoaded,
parentNode,
percent,
origin,
image,
emptyImage,
}: RevealImageComponentProps) {
const [loaded, setLoaded] = useState(false);
const [dimensions, setDimensions] = useState<NodeDimensions>({
width: 1,
height: 1,
});
const imgRef = useRef<HTMLImageElement>(null);
const parentNodeDimensions = useResizeObserver(parentNode);
// modify the top-level container class
parentNode.className = 'revealImage';
// set up the overlay image
const updateImageView = useCallback(() => {
if (imgRef.current) {
setDimensions({
height: imgRef.current.naturalHeight,
width: imgRef.current.naturalWidth,
});
setLoaded(true);
onLoaded();
}
}, [imgRef, onLoaded]);
useEffect(() => {
updateImageView();
}, [parentNodeDimensions, updateImageView]);
function getClipPath(percentParam: number, originParam: OriginString = 'bottom') {
const directions: Record<OriginString, number> = { bottom: 0, left: 1, top: 2, right: 3 };
const values: Array<number | string> = [0, 0, 0, 0];
values[directions[originParam]] = `${100 - percentParam * 100}%`;
return `inset(${values.join(' ')})`;
}
function getImageSizeStyle() {
const imgStyles: ImageStyles = {};
const imgDimensions = {
height: dimensions.height,
width: dimensions.width,
ratio: dimensions.height / dimensions.width,
};
const domNodeDimensions = {
width: parentNode.clientWidth,
height: parentNode.clientHeight,
ratio: parentNode.clientHeight / parentNode.clientWidth,
};
if (imgDimensions.ratio > domNodeDimensions.ratio) {
imgStyles.height = `${domNodeDimensions.height}px`;
imgStyles.width = 'initial';
} else {
imgStyles.width = `${domNodeDimensions.width}px`;
imgStyles.height = 'initial';
}
return imgStyles;
}
const imgSrc = isValidUrl(image ?? '') ? image : elasticOutline;
const alignerStyles: AlignerStyles = {};
if (isValidUrl(emptyImage ?? '')) {
// only use empty image if one is provided
alignerStyles.backgroundImage = `url(${emptyImage})`;
}
let imgStyles: ImageStyles = {};
if (imgRef.current && loaded) imgStyles = getImageSizeStyle();
imgStyles.clipPath = getClipPath(percent, origin);
if (imgRef.current && loaded) {
imgRef.current.style.setProperty('-webkit-clip-path', getClipPath(percent, origin));
}
return (
<div className="revealImageAligner" style={alignerStyles}>
<img
ref={imgRef}
onLoad={updateImageView}
className="revealImage__image"
src={imgSrc ?? ''}
alt=""
role="presentation"
style={imgStyles}
/>
</div>
);
}
// default export required for React.Lazy
// eslint-disable-next-line import/no-default-export
export { RevealImageComponent as default };

View file

@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React from 'react';
import { storiesOf } from '@storybook/react';
import { revealImageRenderer } from '../';
import { elasticOutline, elasticLogo } from '../../../../presentation_util/public';
import { Render } from '../../../../presentation_util/public/__stories__';
import { Origin } from '../../../common/types/expression_functions';
storiesOf('renderers/revealImage', module).add('default', () => {
const config = {
image: elasticLogo,
emptyImage: elasticOutline,
origin: Origin.LEFT,
percent: 0.45,
};
return <Render renderer={revealImageRenderer} config={config} />;
});

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { revealImageRenderer } from './reveal_image_renderer';
export const renderers = [revealImageRenderer];
export { revealImageRenderer };

View file

@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { lazy } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { I18nProvider } from '@kbn/i18n/react';
import { ExpressionRenderDefinition, IInterpreterRenderHandlers } from 'src/plugins/expressions';
import { withSuspense } from '../../../presentation_util/public';
import { getRendererStrings } from '../../common/i18n';
import { RevealImageRendererConfig } from '../../common/types';
const { revealImage: revealImageStrings } = getRendererStrings();
const LazyRevealImageComponent = lazy(() => import('../components/reveal_image_component'));
const RevealImageComponent = withSuspense(LazyRevealImageComponent, null);
export const revealImageRenderer = (): ExpressionRenderDefinition<RevealImageRendererConfig> => ({
name: 'revealImage',
displayName: revealImageStrings.getDisplayName(),
help: revealImageStrings.getHelpDescription(),
reuseDomNode: true,
render: async (
domNode: HTMLElement,
config: RevealImageRendererConfig,
handlers: IInterpreterRenderHandlers
) => {
handlers.onDestroy(() => {
unmountComponentAtNode(domNode);
});
render(
<I18nProvider>
<RevealImageComponent {...config} parentNode={domNode} onLoaded={handlers.done} />
</I18nProvider>,
domNode
);
},
});

View file

@ -0,0 +1,17 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { ExpressionRevealImagePlugin } from './plugin';
export type { ExpressionRevealImagePluginSetup, ExpressionRevealImagePluginStart } from './plugin';
export function plugin() {
return new ExpressionRevealImagePlugin();
}
export * from './expression_renderers';

View file

@ -0,0 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { CoreSetup, CoreStart, Plugin } from '../../../core/public';
import { ExpressionsStart, ExpressionsSetup } from '../../expressions/public';
import { revealImageRenderer } from './expression_renderers';
interface SetupDeps {
expressions: ExpressionsSetup;
}
interface StartDeps {
expression: ExpressionsStart;
}
export type ExpressionRevealImagePluginSetup = void;
export type ExpressionRevealImagePluginStart = void;
export class ExpressionRevealImagePlugin
implements
Plugin<
ExpressionRevealImagePluginSetup,
ExpressionRevealImagePluginStart,
SetupDeps,
StartDeps
> {
public setup(core: CoreSetup, { expressions }: SetupDeps): ExpressionRevealImagePluginSetup {
expressions.registerRenderer(revealImageRenderer);
}
public start(core: CoreStart): ExpressionRevealImagePluginStart {}
public stop() {}
}

View file

@ -0,0 +1,15 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { ExpressionRevealImagePlugin } from './plugin';
export type { ExpressionRevealImagePluginSetup, ExpressionRevealImagePluginStart } from './plugin';
export function plugin() {
return new ExpressionRevealImagePlugin();
}

View file

@ -0,0 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { CoreSetup, CoreStart, Plugin } from '../../../core/public';
import { ExpressionsServerStart, ExpressionsServerSetup } from '../../expressions/server';
import { revealImageFunction } from '../common';
interface SetupDeps {
expressions: ExpressionsServerSetup;
}
interface StartDeps {
expression: ExpressionsServerStart;
}
export type ExpressionRevealImagePluginSetup = void;
export type ExpressionRevealImagePluginStart = void;
export class ExpressionRevealImagePlugin
implements
Plugin<
ExpressionRevealImagePluginSetup,
ExpressionRevealImagePluginStart,
SetupDeps,
StartDeps
> {
public setup(core: CoreSetup, { expressions }: SetupDeps): ExpressionRevealImagePluginSetup {
expressions.registerFunction(revealImageFunction);
}
public start(core: CoreStart): ExpressionRevealImagePluginStart {}
public stop() {}
}

View file

@ -0,0 +1,21 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
"emitDeclarationOnly": true,
"declaration": true,
"declarationMap": true,
"isolatedModules": true
},
"include": [
"common/**/*",
"public/**/*",
"server/**/*",
],
"references": [
{ "path": "../../core/tsconfig.json" },
{ "path": "../presentation_util/tsconfig.json" },
{ "path": "../expressions/tsconfig.json" },
]
}

View file

@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './utils';
export * from './test_helpers';

View file

@ -0,0 +1,27 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { mapValues } from 'lodash';
import {
ExpressionValueBoxed,
typeSpecs,
ExpressionFunctionDefinition,
} from '../../../../expressions/common';
type FnType = () => typeof typeSpecs[number] &
ExpressionFunctionDefinition<string, any, Record<string, any>, ExpressionValueBoxed<any, any>>;
// It takes a function spec and passes in default args into the spec fn
export const functionWrapper = (fnSpec: FnType): ReturnType<FnType>['fn'] => {
const spec = fnSpec();
const defaultArgs = mapValues(spec.args, (argSpec) => {
return argSpec.default;
});
return (context, args, handlers) => spec.fn(context, { ...defaultArgs, ...args }, handlers);
};

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './function_wrapper';

View file

@ -1,8 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { isValidDataUrl, parseDataUrl } from './dataurl';

View file

@ -1,8 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { fromByteArray } from 'base64-js';

View file

@ -1,8 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export const elasticLogo =

File diff suppressed because one or more lines are too long

View file

@ -1,8 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { isValidHttpUrl } from './httpurl';

View file

@ -1,8 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
// A cheap regex to distinguish an HTTP URL string from a data URL string

View file

@ -0,0 +1,15 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './dataurl';
export * from './elastic_logo';
export * from './elastic_outline';
export * from './httpurl';
export * from './missing_asset';
export * from './resolve_dataurl';
export * from './url';

View file

@ -0,0 +1,11 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
// CC0, source: https://pixabay.com/en/question-mark-confirmation-question-838656/
export const missingImage =
'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAzMSAzMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcz48ZmlsdGVyIGlkPSJiIiB4PSItLjM2IiB5PSItLjM2IiB3aWR0aD0iMS43MiIgaGVpZ2h0PSIxLjcyIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjIuNDY0Ii8+PC9maWx0ZXI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMTU5LjM0IiB4Mj0iMTg0LjQ4IiB5MT0iNzI3LjM2IiB5Mj0iNzQ5Ljg5IiBncmFkaWVudFRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMTEuNTMgLTU0OS42OCkgc2NhbGUoLjc3MDAyKSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiNlYmYwZWQiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNmYWZhZmEiIG9mZnNldD0iMSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0xNS40MzcgMi42OTVsMTQuNTA2IDI0LjQ3NkgxLjI4N2wxNC4xNS0yNC40NzZ6IiBmaWxsPSJ1cmwoI2EpIiBzdHJva2U9InJlZCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIi8+PHBhdGggdHJhbnNmb3JtPSJtYXRyaXgoLjgzMTk3IDAgMCAuNTU0NjYgLTc4LjU4MyAtMzgzLjUxKSIgZD0iTTExMS4zMSA3MzEuMmMtMy4yODMtMy45MjUtMy41OTUtNi4xNDgtMi4wMjQtMTAuNDM4IDMuMzM2LTYuMTQ1IDQuNDk2LTguMDY4IDUuNDEtOS40MDUgMS45MDEgNS4xNjIgMi4xMjYgMTkuMTQtMy4zODYgMTkuODQzeiIgZmlsbD0iI2ZmZiIgZmlsbC1vcGFjaXR5PSIuODc2IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGZpbHRlcj0idXJsKCNiKSIvPjxnIGZpbGwtb3BhY2l0eT0iLjgyIj48cGF0aCBkPSJNMTUuMDQ2IDIwLjIyN2gtLjQxNWMtLjAxMy0uNzQ4LjAyLTEuMzA4LjEwMS0xLjY3OC4wODgtLjM3MS4zMDctLjg4LjY1OC0xLjUyOC4zNTctLjY1NC41OS0xLjE3Ni42OTctMS41NjcuMTE1LS4zOTguMTcyLS44ODcuMTcyLTEuNDY3IDAtLjg5Ni0uMTc1LTEuNTU3LS41MjYtMS45ODItLjM1LS40MjUtLjc2NS0uNjM3LTEuMjQ0LS42MzctLjM2NCAwLS42Ny4wOTgtLjkyLjI5My0uMTg5LjE0OS0uMjgzLjMwNC0uMjgzLjQ2NiAwIC4xMDcuMDY0LjI3Ni4xOTIuNTA1LjI5LjUyLjQzNS45NjEuNDM1IDEuMzI1IDAgLjMzLS4xMTUuNjA3LS4zNDQuODNhMS4xMzggMS4xMzggMCAwIDEtLjg0LjMzM2MtLjM3NyAwLS42OTQtLjEzMS0uOTUtLjM5NC0uMjU2LS4yNy0uMzg0LS42MjQtLjM4NC0xLjA2MiAwLS43OTYuMzQ0LTEuNDk0IDEuMDMxLTIuMDk0LjY4OC0uNiAxLjY0OS0uOSAyLjg4My0uOSAxLjMwOCAwIDIuMzAyLjMxNCAyLjk4My45NC42ODguNjIxIDEuMDMyIDEuMzczIDEuMDMyIDIuMjU2IDAgLjY0LS4xNzYgMS4yMzQtLjUyNiAxLjc4LS4zNTEuNTQtMS4wMjkgMS4xNC0yLjAzMyAxLjgtLjY3NC40NDUtMS4xMi44NDMtMS4zMzUgMS4xOTQtLjIxLjM0My0uMzM3Ljg3My0uMzg0IDEuNTg3bS0uMTEyIDEuNDc3Yy40NTIgMCAuODM2LjE1OCAxLjE1My40NzUuMzE3LjMxNy40NzYuNzAxLjQ3NiAxLjE1MyAwIC40NTItLjE1OS44NC0uNDc2IDEuMTYzYTEuNTcgMS41NyAwIDAgMS0xLjE1My40NzUgMS41NyAxLjU3IDAgMCAxLTEuMTUzLS40NzUgMS42MDQgMS42MDQgMCAwIDEtLjQ3NS0xLjE2M2MwLS40NTIuMTU5LS44MzYuNDc1LTEuMTUzYTEuNTcgMS41NyAwIDAgMSAxLjE1My0uNDc1IiBmaWxsPSIjZmZmIiBmaWxsLW9wYWNpdHk9Ii40ODYiLz48cGF0aCBkPSJNMTUuMzI3IDIwLjUwOGgtLjQxNWMtLjAxMy0uNzQ4LjAyLTEuMzA4LjEwMS0xLjY3OC4wODgtLjM3MS4zMDctLjg4LjY1OC0xLjUyOC4zNTctLjY1NC41OS0xLjE3Ni42OTctMS41NjcuMTE1LS4zOTguMTcyLS44ODcuMTcyLTEuNDY2IDAtLjg5Ny0uMTc1LTEuNTU4LS41MjYtMS45ODMtLjM1LS40MjQtLjc2NS0uNjM3LTEuMjQzLS42MzctLjM2NSAwLS42NzEuMDk4LS45Mi4yOTMtLjE5LjE0OS0uMjg0LjMwNC0uMjg0LjQ2NiAwIC4xMDguMDY0LjI3Ni4xOTIuNTA1LjI5LjUyLjQzNS45NjEuNDM1IDEuMzI1IDAgLjMzLS4xMTUuNjA3LS4zNDQuODNhMS4xMzggMS4xMzggMCAwIDEtLjg0LjMzM2MtLjM3NyAwLS42OTQtLjEzMS0uOTUtLjM5NC0uMjU2LS4yNy0uMzg0LS42MjQtLjM4NC0xLjA2MiAwLS43OTYuMzQ0LTEuNDkzIDEuMDMxLTIuMDk0LjY4OC0uNiAxLjY0OS0uOSAyLjg4My0uOSAxLjMwOCAwIDIuMzAyLjMxNCAyLjk4My45NC42ODguNjIxIDEuMDMyIDEuMzczIDEuMDMyIDIuMjU2IDAgLjY0LS4xNzYgMS4yMzQtLjUyNiAxLjc4LS4zNS41NC0xLjAyOCAxLjE0LTIuMDMzIDEuOC0uNjc0LjQ0NS0uODUzLjg0My0xLjA2OCAxLjE5NC0uMjEuMzQzLS4zMzcuODczLS4zODUgMS41ODdtLS4zNzggMS40NzdjLjQ1MiAwIC44MzYuMTU4IDEuMTUzLjQ3NS4zMTcuMzE3LjQ3Ni43MDEuNDc2IDEuMTUzIDAgLjQ1Mi0uMTU5Ljg0LS40NzYgMS4xNjNhMS41NyAxLjU3IDAgMCAxLTEuMTUzLjQ3NiAxLjU3IDEuNTcgMCAwIDEtMS4xNTMtLjQ3NiAxLjYwNCAxLjYwNCAwIDAgMS0uNDc1LTEuMTYzYzAtLjQ1Mi4xNTktLjgzNi40NzUtMS4xNTNhMS41NyAxLjU3IDAgMCAxIDEuMTUzLS40NzUiIGZpbGwtb3BhY2l0eT0iLjgyIi8+PC9nPjwvc3ZnPg==';

View file

@ -1,11 +1,12 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { missingImage } from '../../common/lib/missing_asset';
import { missingImage } from './missing_asset';
import { resolveFromArgs, resolveWithMissingImage } from './resolve_dataurl';
describe('resolve_dataurl', () => {

View file

@ -1,13 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { get } from 'lodash';
import { isValidUrl } from '../../common/lib/url';
import { missingImage } from '../../common/lib/missing_asset';
import { isValidUrl } from './url';
import { missingImage } from './missing_asset';
/*
* NOTE: args.dataurl can come as an expression here.

View file

@ -1,11 +1,12 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { missingImage } from '../../common/lib/missing_asset';
import { missingImage } from './missing_asset';
import { isValidUrl } from './url';
describe('resolve_dataurl', () => {

View file

@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { isValidDataUrl } from './dataurl';
import { isValidHttpUrl } from './httpurl';
export function isValidUrl(url: string) {
return isValidDataUrl(url) || isValidHttpUrl(url);
}

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
preset: '@kbn/test',
rootDir: '../../..',
roots: ['<rootDir>/src/plugins/presentation_util'],
};

View file

@ -4,6 +4,9 @@
"kibanaVersion": "kibana",
"server": true,
"ui": true,
"extraPublicDirs": [
"common/lib"
],
"requiredPlugins": [
"savedObjects"
],

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './render';

View file

@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { action } from '@storybook/addon-actions';
import React, { useRef, useEffect } from 'react';
import { ExpressionRenderDefinition, IInterpreterRenderHandlers } from 'src/plugins/expressions';
export const defaultHandlers: IInterpreterRenderHandlers = {
getRenderMode: () => 'display',
isSyncColorsEnabled: () => false,
done: action('done'),
onDestroy: action('onDestroy'),
reload: action('reload'),
update: action('update'),
event: action('event'),
};
/*
Uses a RenderDefinitionFactory and Config to render into an element.
Intended to be used for stories for RenderDefinitionFactory
*/
interface RenderAdditionalProps {
height?: string;
width?: string;
handlers?: IInterpreterRenderHandlers;
}
export const Render = <Renderer,>({
renderer,
config,
...rest
}: Renderer extends () => ExpressionRenderDefinition<infer Config>
? { renderer: Renderer; config: Config } & RenderAdditionalProps
: { renderer: undefined; config: undefined } & RenderAdditionalProps) => {
const { height, width, handlers } = {
height: '200px',
width: '200px',
handlers: defaultHandlers,
...rest,
};
const containerRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
if (renderer && containerRef.current !== null) {
renderer().render(containerRef.current, config, handlers);
}
}, [renderer, config, handlers]);
return (
<div style={{ width, height }} ref={containerRef}>
{' '}
</div>
);
};

View file

@ -28,6 +28,7 @@ export {
export { PresentationUtilPluginSetup, PresentationUtilPluginStart } from './types';
export { SaveModalDashboardProps } from './components/types';
export { projectIDs, ProjectID, Project } from '../common/labs';
export * from '../common/lib';
export {
LazyLabsBeakerButton,

View file

@ -7,6 +7,9 @@
"declaration": true,
"declarationMap": true
},
"extraPublicDirs": [
"common"
],
"include": [
"common/**/*",
"public/**/*",

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import _ from 'lodash';
import { debounce } from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
@ -116,7 +116,7 @@ class SavedObjectFinderUi extends React.Component<
private isComponentMounted: boolean = false;
private debouncedFetch = _.debounce(async (query: string) => {
private debouncedFetch = debounce(async (query: string) => {
const metaDataMap = this.getSavedObjectMetaDataMap();
const fields = Object.values(metaDataMap)

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import _ from 'lodash';
import { cloneDeep, defaults, forOwn, assign } from 'lodash';
import { EsResponse, SavedObject, SavedObjectConfig, SavedObjectKibanaServices } from '../../types';
import { SavedObjectNotFound } from '../../../../kibana_utils/public';
import {
@ -28,7 +28,7 @@ export async function applyESResp(
) {
const mapping = expandShorthand(config.mapping ?? {});
const savedObjectType = config.type || '';
savedObject._source = _.cloneDeep(resp._source);
savedObject._source = cloneDeep(resp._source);
if (typeof resp.found === 'boolean' && !resp.found) {
throw new SavedObjectNotFound(savedObjectType, savedObject.id || '');
}
@ -42,10 +42,10 @@ export async function applyESResp(
}
// assign the defaults to the response
_.defaults(savedObject._source, savedObject.defaults);
defaults(savedObject._source, savedObject.defaults);
// transform the source using _deserializers
_.forOwn(mapping, (fieldMapping, fieldName) => {
forOwn(mapping, (fieldMapping, fieldName) => {
if (fieldMapping._deserialize && typeof fieldName === 'string') {
savedObject._source[fieldName] = fieldMapping._deserialize(
savedObject._source[fieldName] as string
@ -54,7 +54,7 @@ export async function applyESResp(
});
// Give obj all of the values in _source.fields
_.assign(savedObject, savedObject._source);
assign(savedObject, savedObject._source);
savedObject.lastSavedTitle = savedObject.title;
if (meta.searchSourceJSON) {

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import _ from 'lodash';
import { get } from 'lodash';
import { i18n } from '@kbn/i18n';
import { SavedObjectAttributes } from 'kibana/public';
import { SavedObject, SavedObjectKibanaServices } from '../../types';
@ -40,7 +40,7 @@ export async function createSource(
return await savedObjectsClient.create(esType, source, options);
} catch (err) {
// record exists, confirm overwriting
if (_.get(err, 'res.status') === 409) {
if (get(err, 'res.status') === 409) {
const confirmMessage = i18n.translate(
'savedObjects.confirmModal.overwriteConfirmationMessage',
{

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import _ from 'lodash';
import { cloneDeep, assign } from 'lodash';
import { SavedObjectsClientContract } from 'kibana/public';
import { SavedObject, SavedObjectConfig } from '../../types';
@ -24,7 +24,7 @@ export async function intializeSavedObject(
if (!savedObject.id) {
// just assign the defaults and be done
_.assign(savedObject, savedObject.defaults);
assign(savedObject, savedObject.defaults);
await savedObject.hydrateIndexPattern!();
if (typeof config.afterESResp === 'function') {
savedObject = await config.afterESResp(savedObject);
@ -36,7 +36,7 @@ export async function intializeSavedObject(
const respMapped = {
_id: resp.id,
_type: resp.type,
_source: _.cloneDeep(resp.attributes),
_source: cloneDeep(resp.attributes),
references: resp.references,
found: !!resp._version,
};

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import _ from 'lodash';
import { forOwn } from 'lodash';
import { SavedObject, SavedObjectConfig } from '../../types';
import { extractSearchSourceReferences } from '../../../../data/public';
import { expandShorthand } from './field_mapping';
@ -17,7 +17,7 @@ export function serializeSavedObject(savedObject: SavedObject, config: SavedObje
const attributes = {} as Record<string, any>;
const references = [];
_.forOwn(mapping, (fieldMapping, fieldName) => {
forOwn(mapping, (fieldMapping, fieldName) => {
if (typeof fieldName !== 'string') {
return;
}

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { testTable } from '../common/__fixtures__/test_tables';
import { fontStyle } from '../common/__fixtures__/test_styles';
import { markdown } from './markdown';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { elasticLogo } from '../../../lib/elastic_logo';
import { elasticLogo } from '../../../../../../../src/plugins/presentation_util/common/lib';
export const fontStyle = {
type: 'style',

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { all } from './all';
describe('all', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { getFunctionErrors } from '../../../i18n';
import { emptyTable, testTable } from './__fixtures__/test_tables';
import { alterColumn } from './alterColumn';

View file

@ -4,8 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { any } from './any';
describe('any', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { asFn } from './as';
describe('as', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { getFunctionErrors } from '../../../i18n';
import { testTable } from './__fixtures__/test_tables';
import { axisConfig } from './axisConfig';

View file

@ -7,7 +7,7 @@
import { of } from 'rxjs';
import { TestScheduler } from 'rxjs/testing';
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { caseFn } from './case';
describe('case', () => {

View file

@ -4,8 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { testTable } from './__fixtures__/test_tables';
import { clear } from './clear';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { emptyTable, testTable } from './__fixtures__/test_tables';
import { columns } from './columns';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { getFunctionErrors } from '../../../i18n';
import { compare } from './compare';

View file

@ -8,7 +8,7 @@
import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
import { ContainerStyle, Overflow, BackgroundRepeat, BackgroundSize } from '../../../types';
import { getFunctionHelp, getFunctionErrors } from '../../../i18n';
import { isValidUrl } from '../../../common/lib/url';
import { isValidUrl } from '../../../../../../src/plugins/presentation_util/common/lib';
interface Output extends ContainerStyle {
type: 'containerStyle';

View file

@ -5,8 +5,10 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { elasticLogo } from '../../lib/elastic_logo';
import {
elasticLogo,
functionWrapper,
} from '../../../../../../src/plugins/presentation_util/common/lib';
import { getFunctionErrors } from '../../../i18n';
import { containerStyle } from './containerStyle';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { testTable, emptyTable } from './__fixtures__/test_tables';
import { context } from './context';

View file

@ -5,11 +5,11 @@
* 2.0.
*/
// @ts-expect-error untyped lib
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { getFunctionErrors } from '../../../i18n';
import { csv } from './csv';
import { Datatable } from 'src/plugins/expressions';
import { Datatable, ExecutionContext, SerializableState } from 'src/plugins/expressions';
import { Adapters } from 'src/plugins/inspector';
const errors = getFunctionErrors().csv;
@ -30,43 +30,59 @@ describe('csv', () => {
it('should return a datatable', () => {
expect(
fn(null, {
data: `name,number
fn(
null,
{
data: `name,number
one,1
two,2
fourty two,42`,
})
},
{} as ExecutionContext<Adapters, SerializableState>
)
).toEqual(expected);
});
it('should allow custom delimiter', () => {
expect(
fn(null, {
data: `name\tnumber
fn(
null,
{
data: `name\tnumber
one\t1
two\t2
fourty two\t42`,
delimiter: '\t',
})
delimiter: '\t',
},
{} as ExecutionContext<Adapters, SerializableState>
)
).toEqual(expected);
expect(
fn(null, {
data: `name%SPLIT%number
fn(
null,
{
data: `name%SPLIT%number
one%SPLIT%1
two%SPLIT%2
fourty two%SPLIT%42`,
delimiter: '%SPLIT%',
})
delimiter: '%SPLIT%',
},
{} as ExecutionContext<Adapters, SerializableState>
)
).toEqual(expected);
});
it('should allow custom newline', () => {
expect(
fn(null, {
data: `name,number\rone,1\rtwo,2\rfourty two,42`,
newline: '\r',
})
fn(
null,
{
data: `name,number\rone,1\rtwo,2\rfourty two,42`,
newline: '\r',
},
{} as ExecutionContext<Adapters, SerializableState>
)
).toEqual(expected);
});
@ -83,10 +99,14 @@ fourty two%SPLIT%42`,
};
expect(
fn(null, {
data: `foo," bar ", baz, " buz "
fn(
null,
{
data: `foo," bar ", baz, " buz "
1,2,3,4`,
})
},
{} as ExecutionContext<Adapters, SerializableState>
)
).toEqual(expectedResult);
});
@ -106,22 +126,30 @@ fourty two%SPLIT%42`,
};
expect(
fn(null, {
data: `foo," bar ", baz, " buz "
fn(
null,
{
data: `foo," bar ", baz, " buz "
1," best ",3, " ok"
" good", bad, better , " worst " `,
})
},
{} as ExecutionContext<Adapters, SerializableState>
)
).toEqual(expectedResult);
});
it('throws when given invalid csv', () => {
expect(() => {
fn(null, {
data: `name,number
fn(
null,
{
data: `name,number
one|1
two.2
fourty two,42`,
});
},
{} as ExecutionContext<Adapters, SerializableState>
);
}).toThrow(new RegExp(errors.invalidInputCSV().message));
});
});

View file

@ -6,7 +6,7 @@
*/
import sinon from 'sinon';
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { getFunctionErrors } from '../../../i18n';
import { date } from './date';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { doFn } from './do';
describe('do', () => {

View file

@ -5,23 +5,30 @@
* 2.0.
*/
// @ts-expect-error untyped local
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { testTable, relationalTable } from './__fixtures__/test_tables';
import { dropdownControl } from './dropdownControl';
import { ExecutionContext, SerializableState } from 'src/plugins/expressions';
import { Adapters } from 'src/plugins/inspector';
describe('dropdownControl', () => {
const fn = functionWrapper(dropdownControl);
it('returns a render as dropdown_filter', () => {
expect(fn(testTable, { filterColumn: 'name', valueColumn: 'name' })).toHaveProperty(
'type',
'render'
);
expect(fn(testTable, { filterColumn: 'name', valueColumn: 'name' })).toHaveProperty(
'as',
'dropdown_filter'
);
expect(
fn(
testTable,
{ filterColumn: 'name', valueColumn: 'name' },
{} as ExecutionContext<Adapters, SerializableState>
)
).toHaveProperty('type', 'render');
expect(
fn(
testTable,
{ filterColumn: 'name', valueColumn: 'name' },
{} as ExecutionContext<Adapters, SerializableState>
)
).toHaveProperty('as', 'dropdown_filter');
});
describe('args', () => {
@ -32,12 +39,24 @@ describe('dropdownControl', () => {
unique.find(([value, label]) => value === name) ? unique : [...unique, [name, name]],
[]
);
expect(fn(testTable, { valueColumn: 'name' }).value.choices).toEqual(uniqueNames);
expect(
fn(
testTable,
{ valueColumn: 'name' },
{} as ExecutionContext<Adapters, SerializableState>
)?.value?.choices
).toEqual(uniqueNames);
});
it('returns an empty array when provided an invalid column', () => {
expect(fn(testTable, { valueColumn: 'foo' }).value.choices).toEqual([]);
expect(fn(testTable, { valueColumn: '' }).value.choices).toEqual([]);
expect(
fn(testTable, { valueColumn: 'foo' }, {} as ExecutionContext<Adapters, SerializableState>)
?.value?.choices
).toEqual([]);
expect(
fn(testTable, { valueColumn: '' }, {} as ExecutionContext<Adapters, SerializableState>)
?.value?.choices
).toEqual([]);
});
});
@ -45,7 +64,11 @@ describe('dropdownControl', () => {
it('populates dropdown choices with labels from label column', () => {
const expectedChoices = relationalTable.rows.map((row) => [row.id, row.name]);
expect(
fn(relationalTable, { valueColumn: 'id', labelColumn: 'name' }).value.choices
fn(
relationalTable,
{ valueColumn: 'id', labelColumn: 'name' },
{} as ExecutionContext<Adapters, SerializableState>
)?.value?.choices
).toEqual(expectedChoices);
});
});
@ -53,19 +76,30 @@ describe('dropdownControl', () => {
describe('filterColumn', () => {
it('sets which column the filter is applied to', () => {
expect(fn(testTable, { filterColumn: 'name' }).value).toHaveProperty('column', 'name');
expect(fn(testTable, { filterColumn: 'name', valueColumn: 'price' }).value).toHaveProperty(
'column',
'name'
);
expect(
fn(testTable, { filterColumn: 'name' }, {} as ExecutionContext<Adapters, SerializableState>)
?.value
).toHaveProperty('column', 'name');
expect(
fn(
testTable,
{ filterColumn: 'name', valueColumn: 'price' },
{} as ExecutionContext<Adapters, SerializableState>
)?.value
).toHaveProperty('column', 'name');
});
it('defaults to valueColumn if not provided', () => {
expect(fn(testTable, { valueColumn: 'price' }).value).toHaveProperty('column', 'price');
expect(
fn(testTable, { valueColumn: 'price' }, {} as ExecutionContext<Adapters, SerializableState>)
?.value
).toHaveProperty('column', 'price');
});
it('sets column to undefined if no args are provided', () => {
expect(fn(testTable).value).toHaveProperty('column', undefined);
expect(
fn(testTable, {}, {} as ExecutionContext<Adapters, SerializableState>)?.value
).toHaveProperty('column', undefined);
});
});
});

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { eq } from './eq';
describe('eq', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { emptyFilter } from './__fixtures__/test_filters';
import { exactly } from './exactly';

View file

@ -7,7 +7,7 @@
import { of } from 'rxjs';
import { TestScheduler } from 'rxjs/testing';
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { testTable } from './__fixtures__/test_tables';
import { filterrows } from './filterrows';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { formatdate } from './formatdate';
describe('formatdate', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { formatnumber } from './formatnumber';
describe('formatnumber', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { getFunctionErrors } from '../../../i18n';
import { emptyTable, testTable } from './__fixtures__/test_tables';
import { getCell } from './getCell';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { gt } from './gt';
describe('gt', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { gte } from './gte';
describe('gte', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { emptyTable, testTable } from './__fixtures__/test_tables';
import { head } from './head';

View file

@ -7,7 +7,7 @@
import { of } from 'rxjs';
import { TestScheduler } from 'rxjs/testing';
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { ifFn } from './if';
describe('if', () => {

View file

@ -6,14 +6,14 @@
*/
import expect from '@kbn/expect';
// import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { elasticLogo } from '../../lib/elastic_logo';
import { elasticOutline } from '../../lib/elastic_outline';
import {
elasticLogo,
elasticOutline,
} from '../../../../../../src/plugins/presentation_util/common/lib';
// import { image } from './image';
// TODO: the test was not running and is not up to date
describe.skip('image', () => {
// const fn = functionWrapper(image);
const fn = jest.fn();
it('returns an image object using a dataUrl', () => {

View file

@ -7,9 +7,10 @@
import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
import { getFunctionHelp, getFunctionErrors } from '../../../i18n';
import { resolveWithMissingImage } from '../../../common/lib/resolve_dataurl';
import { elasticLogo } from '../../lib/elastic_logo';
import {
elasticLogo,
resolveWithMissingImage,
} from '../../../../../../src/plugins/presentation_util/common/lib';
export enum ImageMode {
CONTAIN = 'contain',

View file

@ -43,7 +43,6 @@ import { replace } from './replace';
import { rounddate } from './rounddate';
import { rowCount } from './rowCount';
import { repeatImage } from './repeat_image';
import { revealImage } from './revealImage';
import { seriesStyle } from './seriesStyle';
import { shape } from './shape';
import { sort } from './sort';
@ -94,7 +93,6 @@ export const functions = [
render,
repeatImage,
replace,
revealImage,
rounddate,
rowCount,
seriesStyle,

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { getFunctionErrors } from '../../../i18n';
import { testTable } from './__fixtures__/test_tables';
import { joinRows } from './join_rows';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { lt } from './lt';
describe('lt', () => {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { functionWrapper } from '../../../test_helpers/function_wrapper';
import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib';
import { lte } from './lte';
describe('lte', () => {

Some files were not shown because too many files have changed in this diff Show more