Add iframe and markup legacy plugin (#6741)

* Add iframe plugin

* Use lazy load and add description

* remove unintended files

* Add markup

* minor adjustment
This commit is contained in:
Krist Wongsuphasawat 2019-01-23 10:21:57 -08:00 committed by GitHub
parent 954e42bafe
commit 3ae7d32caa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 260 additions and 80 deletions

View File

@ -2228,7 +2228,7 @@
"dependencies": {
"whatwg-fetch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
"resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
"integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng=="
}
}

View File

@ -0,0 +1,58 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import Mustache from 'mustache';
import React from 'react';
import PropTypes from 'prop-types';
const propTypes = {
className: PropTypes.string,
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
url: PropTypes.string,
};
const defaultProps = {
className: '',
};
class Iframe extends React.PureComponent {
render() {
const { className, url, width, height } = this.props;
const completeUrl = Mustache.render(url, {
width,
height,
});
return (
<iframe
className={className}
title="superset-iframe"
src={completeUrl}
style={{
width: '100%',
height,
}}
/>
);
}
}
Iframe.propTypes = propTypes;
Iframe.defaultProps = defaultProps;
export default Iframe;

View File

@ -0,0 +1,38 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t } from '@superset-ui/translation';
import { ChartMetadata, ChartPlugin } from '@superset-ui/chart';
import thumbnail from './images/thumbnail.png';
import transformProps from './transformProps';
const metadata = new ChartMetadata({
name: t('IFrame'),
description: 'HTML Inline Frame',
thumbnail,
});
export default class IframeChartPlugin extends ChartPlugin {
constructor() {
super({
metadata,
loadChart: () => import('./Iframe.jsx'),
transformProps,
});
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -16,23 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
import Mustache from 'mustache';
export default function iframeWidget(slice) {
const { selector, formData } = slice;
export default function transformProps(chartProps) {
const { width, height, formData } = chartProps;
const { url } = formData;
const width = slice.width();
const height = slice.height();
const container = document.querySelector(selector);
const completedUrl = Mustache.render(url, {
return {
width,
height,
});
const iframe = document.createElement('iframe');
iframe.style.width = '100%';
iframe.style.height = height;
iframe.setAttribute('src', completedUrl);
container.appendChild(iframe);
url,
};
}

View File

@ -17,16 +17,16 @@
* under the License.
*/
.markup.slice_container {
margin: 10px;
margin: 10px;
}
.separator {
background-color: transparent !important;
background-color: transparent !important;
}
.separator hr {
border: 0;
height: 1px;
background-image: linear-gradient(to right, rgba(0, 0, 0, 1), rgba(0, 0, 0, 1), rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
border: 0;
height: 1px;
background-image: linear-gradient(to right, rgba(0, 0, 0, 1), rgba(0, 0, 0, 1), rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
}
.separator .chart-header {
border: none !important;
border: none !important;
}

View File

@ -0,0 +1,76 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import './Markup.css';
const propTypes = {
className: PropTypes.string,
height: PropTypes.number.isRequired,
isSeparator: PropTypes.bool,
html: PropTypes.string,
cssFiles: PropTypes.arrayOf(PropTypes.string),
};
const defaultProps = {
className: '',
isSeparator: false,
html: '',
};
const CONTAINER_STYLE = {
position: 'relative',
overflow: 'auto',
};
class Markup extends React.PureComponent {
render() {
const { className, height, isSeparator, html, cssFiles } = this.props;
return (
<div
className={className}
style={CONTAINER_STYLE}
>
<iframe
title="superset-markup"
frameBorder={0}
height={isSeparator ? height - 20 : height}
sandbox="allow-forms allow-popups allow-same-origin allow-scripts allow-top-navigation"
srcDoc={`
<html>
<head>
${cssFiles.map(
href => `<link rel="stylesheet" type="text/css" href="${href}" />`,
)}
</head>
<body style="background-color: transparent;">
${html}
</body>
</html>`
}
/>
</div>
);
}
}
Markup.propTypes = propTypes;
Markup.defaultProps = defaultProps;
export default Markup;

View File

@ -0,0 +1,38 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t } from '@superset-ui/translation';
import { ChartMetadata, ChartPlugin } from '@superset-ui/chart';
import thumbnail from './images/thumbnail.png';
import transformProps from './transformProps';
const metadata = new ChartMetadata({
name: t('Markup'),
description: 'HTML Markup',
thumbnail,
});
export default class IframeChartPlugin extends ChartPlugin {
constructor() {
super({
metadata,
loadChart: () => import('./Markup.jsx'),
transformProps,
});
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,33 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export default function transformProps(chartProps) {
const { height, payload, formData } = chartProps;
const { vizType } = formData;
const {
theme_css: cssFiles,
html,
} = payload.data;
return {
height,
cssFiles,
html,
isSeparator: vizType === 'separator',
};
}

View File

@ -1,58 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import srcdoc from 'srcdoc-polyfill';
import './markup.css';
function markupWidget(slice, payload) {
const { selector } = slice;
const height = slice.height();
const headerHeight = slice.headerHeight();
const vizType = slice.props.vizType;
const { data } = payload;
const container = document.querySelector(selector);
container.style.overflow = 'auto';
// markup height is slice height - (marginTop + marginBottom)
const iframeHeight = vizType === 'separator'
? height - 20
: height + headerHeight;
const html = `
<html>
<head>
${data.theme_css.map(
href => `<link rel="stylesheet" type="text/css" href="${href}" />`,
)}
</head>
<body style="background-color: transparent;">
${data.html}
</body>
</html>`;
const iframe = document.createElement('iframe');
iframe.setAttribute('frameborder', 0);
iframe.setAttribute('height', iframeHeight);
iframe.setAttribute('sandbox', 'allow-forms allow-popups allow-same-origin allow-scripts allow-top-navigation');
container.appendChild(iframe);
srcdoc.set(iframe, html);
}
export default markupWidget;

View File

@ -30,7 +30,9 @@ import EventFlowChartPlugin from '../EventFlow/EventFlowChartPlugin';
import ForceDirectedChartPlugin from '../ForceDirected/ForceDirectedChartPlugin';
import HeatmapChartPlugin from '../Heatmap/HeatmapChartPlugin';
import HorizonChartPlugin from '../Horizon/HorizonChartPlugin';
import IframeChartPlugin from '../Iframe/IframeChartPlugin';
import LineMultiChartPlugin from '../nvd3/LineMulti/LineMultiChartPlugin';
import MarkupChartPlugin from '../Markup/MarkupChartPlugin';
import PairedTTestChartPlugin from '../PairedTTest/PairedTTestChartPlugin';
import ParallelCoordinatesChartPlugin from '../ParallelCoordinates/ParallelCoordinatesChartPlugin';
import RoseChartPlugin from '../Rose/RoseChartPlugin';
@ -57,7 +59,10 @@ export default class LegacyChartPreset extends Preset {
new ForceDirectedChartPlugin().configure({ key: 'directed_force' }),
new HeatmapChartPlugin().configure({ key: 'heatmap' }),
new HorizonChartPlugin().configure({ key: 'horizon' }),
new IframeChartPlugin().configure({ key: 'iframe' }),
new LineMultiChartPlugin().configure({ key: 'line_multi' }),
new MarkupChartPlugin().configure({ key: 'markup' }),
new MarkupChartPlugin().configure({ key: 'separator' }),
new PairedTTestChartPlugin().configure({ key: 'paired_ttest' }),
new ParallelCoordinatesChartPlugin().configure({ key: 'para' }),
new RoseChartPlugin().configure({ key: 'rose' }),