Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/plugins/vis_type_script/public/expression/fn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,15 @@ export const createScriptVisFn = (): ScriptVisExpressionFunctionDefinition => ({
defaultMessage: 'Visualization script',
}),
},
dependencyUrls: {
scriptDependencyUrls: {
types: ['string'],
multi: true,
required: true,
help: i18n.translate('visTypeScript.function.markdown.help', {
defaultMessage: 'List of script dependencies',
}),
},
styleDependencyUrls: {
types: ['string'],
multi: true,
required: true,
Expand All @@ -51,7 +59,8 @@ export const createScriptVisFn = (): ScriptVisExpressionFunctionDefinition => ({
visType: 'script',
visParams: {
script: args.script,
dependencyUrls: args.dependencyUrls,
scriptDependencyUrls: args.scriptDependencyUrls,
styleDependencyUrls: args.styleDependencyUrls,
},
visSearchContext: {
timeRange: input?.timeRange,
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/vis_type_script/public/expression/renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ export const scriptVisRenderer: (
<VisualizationContainer className="scriptVis" handlers={handlers}>
<ScriptRenderer
script={visParams.script}
dependencyUrls={visParams.dependencyUrls}
scriptDependencyUrls={visParams.scriptDependencyUrls}
styleDependencyUrls={visParams.styleDependencyUrls}
kibanaApi={visTypeScriptKibanaApi}
validateUrl={deps.validateUrl}
nonce={deps.nonce}
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/vis_type_script/public/expression/to_ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ type ScriptVisExpressionFunctionDefinition = ExpressionFunctionDefinition<
export const toExpressionAst: VisToExpressionAst<VisParams> = (vis) => {
const scriptVis = buildExpressionFunction<ScriptVisExpressionFunctionDefinition>('scriptVis', {
script: vis.params.script,
dependencyUrls: vis.params.dependencyUrls,
scriptDependencyUrls: vis.params.scriptDependencyUrls,
styleDependencyUrls: vis.params.styleDependencyUrls,
});

const ast = buildExpression([scriptVis]);
Expand Down
47 changes: 34 additions & 13 deletions src/plugins/vis_type_script/public/renderer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import React, { useEffect, useState, useMemo } from 'react';
import React, { useEffect, useState, useMemo, useCallback } from 'react';
import { createEndpoint, fromIframe } from '@remote-ui/rpc';

import './index.scss';
Expand All @@ -23,13 +23,19 @@ import {

export const KIBANA_API_CONSTANT_NAME = 'KIBANA';

const getSandboxDocument = (script: string, dependencies: string[], nonce: string) => {
const getSandboxDocument = (
script: string,
scriptDependencies: string[],
styleDependencies: string[],
nonce: string
) => {
return `
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-security-policy" content="default-src none; script-src 'nonce-${nonce}'">
${dependencies
<meta http-equiv="content-security-policy" content="default-src none; script-src 'nonce-${nonce}'; style-src 'nonce-${nonce}'">
${styleDependencies.map((dep) => `<style nonce=${nonce}>${dep}</style>`).join('')}
${scriptDependencies
.map((dependency) => `<script nonce="${nonce}">${dependency}</script>`)
.join('')}
<script nonce="${nonce}" type="module">
Expand Down Expand Up @@ -81,19 +87,22 @@ const loadDependencies = (urls: string[]) => {

export const ScriptRenderer: React.FunctionComponent<{
script: string;
dependencyUrls: string[];
scriptDependencyUrls: string[];
styleDependencyUrls: string[];
kibanaApi: VisTypeScriptKibanaApi;
validateUrl: IExternalUrl['validateUrl'];
nonce: string;
}> = ({
script: visualizationScript,
dependencyUrls,
scriptDependencyUrls,
styleDependencyUrls,
kibanaApi,
validateUrl,
nonce,
}: {
script: string;
dependencyUrls: string[];
scriptDependencyUrls: string[];
styleDependencyUrls: string[];
kibanaApi: VisTypeScriptKibanaApi;
validateUrl: IExternalUrl['validateUrl'];
nonce: string;
Expand Down Expand Up @@ -125,17 +134,29 @@ export const ScriptRenderer: React.FunctionComponent<{
};
}, [kibanaApi]);

const [dependencies, setDependencies] = useState<string[]>([]);
const onlyValidUrls = useCallback(
(urls: string[]) => urls.filter((url) => validateUrl(url) !== null),
[validateUrl]
);

const [scriptDependencies, setScriptDependencies] = useState<string[]>([]);
const [styleDependencies, setStyleDependencies] = useState<string[]>([]);

useEffect(() => {
loadDependencies(onlyValidUrls(scriptDependencyUrls)).then((deps: string[]) =>
setScriptDependencies(deps)
);
}, [scriptDependencyUrls, onlyValidUrls, validateUrl]);

useEffect(() => {
loadDependencies(dependencyUrls.filter((url) => validateUrl(url) !== null)).then(
(deps: string[]) => setDependencies(deps)
loadDependencies(onlyValidUrls(styleDependencyUrls)).then((deps: string[]) =>
setStyleDependencies(deps)
);
}, [dependencyUrls, validateUrl]);
}, [scriptDependencyUrls, onlyValidUrls, validateUrl, styleDependencyUrls]);

const sandboxDocument = useMemo(
() => getSandboxDocument(visualizationScript, dependencies, nonce),
[visualizationScript, dependencies, nonce]
() => getSandboxDocument(visualizationScript, scriptDependencies, styleDependencies, nonce),
[visualizationScript, scriptDependencies, styleDependencies, nonce]
);

return (
Expand Down
6 changes: 4 additions & 2 deletions src/plugins/vis_type_script/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import { TimeRange } from '@kbn/data-plugin/common';

export interface Arguments {
script: string;
dependencyUrls: string[];
scriptDependencyUrls: string[];
styleDependencyUrls: string[];
}

export interface VisParams {
script: Arguments['script'];
dependencyUrls: Arguments['dependencyUrls'];
scriptDependencyUrls: Arguments['scriptDependencyUrls'];
styleDependencyUrls: Arguments['styleDependencyUrls'];
}

export interface VisSearchContext {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,42 @@ const DependencyUrl = ({
};

function SettingsOptions({
stateParams: { dependencyUrls },
stateParams: { scriptDependencyUrls, styleDependencyUrls },
setValue,
validateUrl,
}: VisEditorOptionsProps<VisParams> & { validateUrl: IExternalUrl['validateUrl'] }) {
const setDependencyUrls = (newDependencyUrls: string[]) =>
setValue('dependencyUrls', newDependencyUrls);
return (
<EuiPanel paddingSize="s">
<EuiTitle size="xs">
<h2>Script Dependencies</h2>
</EuiTitle>
<DependencyUrlList
dependencyUrls={scriptDependencyUrls}
validateUrl={validateUrl}
setDependencyUrls={(urls) => setValue('scriptDependencyUrls', urls)}
/>
<EuiSpacer size="l" />
<EuiTitle size="xs">
<h2>Style Dependencies</h2>
</EuiTitle>
<DependencyUrlList
dependencyUrls={styleDependencyUrls}
validateUrl={validateUrl}
setDependencyUrls={(urls) => setValue('styleDependencyUrls', urls)}
/>
</EuiPanel>
);
}

function DependencyUrlList({
dependencyUrls,
setDependencyUrls,
validateUrl,
}: {
dependencyUrls: string[];
setDependencyUrls: (deps: string[]) => void;
validateUrl: IExternalUrl['validateUrl'];
}) {
const updateNthDependency = (n: number, newValue: string) => {
const newDependencies = [...dependencyUrls];
newDependencies[n] = newValue;
Expand All @@ -94,10 +123,7 @@ function SettingsOptions({
};

return (
<EuiPanel paddingSize="s">
<EuiTitle size="xs">
<h2>Dependencies</h2>
</EuiTitle>
<>
<EuiForm component="form">
{dependencyUrls.map((url: string, index: number) => (
<DependencyUrl
Expand All @@ -112,7 +138,7 @@ function SettingsOptions({
<EuiButton size="s" fullWidth iconType="listAdd" onClick={addDependency}>
Add dependency
</EuiButton>
</EuiPanel>
</>
);
}

Expand Down
3 changes: 2 additions & 1 deletion src/plugins/vis_type_script/public/vis_definition/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export const getScriptVisDefinition: (
visConfig: {
defaults: {
script: DEFAULT_VIS,
dependencyUrls: ['https://unpkg.com/d3@3.4.0/d3.min.js'],
scriptDependencyUrls: ['https://unpkg.com/d3@3.4.0/d3.min.js'],
styleDependencyUrls: [],
},
},
editorConfig: {
Expand Down