2021-06-09 09:39:17 +00:00
|
|
|
import React from "react";
|
|
|
|
|
|
|
|
|
|
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
|
|
|
|
import { WidgetType, WidgetTypes } from "constants/WidgetConstants";
|
|
|
|
|
import IframeComponent from "components/designSystems/blueprint/IframeComponent";
|
2021-07-26 05:50:46 +00:00
|
|
|
import { ValidationTypes } from "constants/WidgetValidation";
|
2021-06-09 09:39:17 +00:00
|
|
|
import * as Sentry from "@sentry/react";
|
2021-06-10 05:29:52 +00:00
|
|
|
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
2021-06-09 09:39:17 +00:00
|
|
|
|
|
|
|
|
class IframeWidget extends BaseWidget<IframeWidgetProps, WidgetState> {
|
|
|
|
|
static getPropertyPaneConfig() {
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
sectionName: "General",
|
|
|
|
|
children: [
|
|
|
|
|
{
|
|
|
|
|
propertyName: "source",
|
|
|
|
|
helpText: "The URL of the page to embed",
|
|
|
|
|
label: "Source",
|
|
|
|
|
controlType: "INPUT_TEXT",
|
|
|
|
|
placeholderText: "Enter the URL of the page to embed",
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
2021-07-26 05:50:46 +00:00
|
|
|
validation: {
|
|
|
|
|
type: ValidationTypes.TEXT,
|
|
|
|
|
params: {
|
|
|
|
|
regex: /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/,
|
|
|
|
|
expected: {
|
|
|
|
|
type: "URL",
|
|
|
|
|
example: "https://www.wikipedia.org",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
2021-06-09 09:39:17 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
propertyName: "title",
|
|
|
|
|
helpText: "Label the content of the page to embed",
|
|
|
|
|
label: "Title",
|
|
|
|
|
controlType: "INPUT_TEXT",
|
|
|
|
|
placeholderText: "Enter the title of the page to embed",
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
2021-07-26 05:50:46 +00:00
|
|
|
validation: { type: ValidationTypes.TEXT },
|
2021-06-09 09:39:17 +00:00
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
sectionName: "Actions",
|
|
|
|
|
children: [
|
|
|
|
|
{
|
2021-06-21 10:48:00 +00:00
|
|
|
helpText: "Triggers an action when the source URL is changed",
|
2021-06-09 09:39:17 +00:00
|
|
|
propertyName: "onURLChanged",
|
|
|
|
|
label: "onURLChanged",
|
|
|
|
|
controlType: "ACTION_SELECTOR",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
helpText: "Triggers an action when a message event is received",
|
|
|
|
|
propertyName: "onMessageReceived",
|
|
|
|
|
label: "onMessageReceived",
|
|
|
|
|
controlType: "ACTION_SELECTOR",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: true,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
sectionName: "Styles",
|
|
|
|
|
children: [
|
|
|
|
|
{
|
|
|
|
|
propertyName: "borderColor",
|
|
|
|
|
label: "Border Color",
|
|
|
|
|
controlType: "COLOR_PICKER",
|
|
|
|
|
isBindProperty: false,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
propertyName: "borderOpacity",
|
|
|
|
|
label: "Border Opacity (%)",
|
|
|
|
|
controlType: "INPUT_TEXT",
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
inputType: "NUMBER",
|
2021-07-26 05:50:46 +00:00
|
|
|
validation: {
|
|
|
|
|
type: ValidationTypes.NUMBER,
|
|
|
|
|
params: { min: 0, max: 100, default: 100 },
|
|
|
|
|
},
|
2021-06-09 09:39:17 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
propertyName: "borderWidth",
|
|
|
|
|
label: "Border Width (px)",
|
|
|
|
|
controlType: "INPUT_TEXT",
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
inputType: "NUMBER",
|
2021-07-26 05:50:46 +00:00
|
|
|
validation: {
|
|
|
|
|
type: ValidationTypes.NUMBER,
|
|
|
|
|
params: { min: 0, default: 1 },
|
|
|
|
|
},
|
2021-06-09 09:39:17 +00:00
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
urlChangedHandler = (url: string) => {
|
2021-06-10 05:29:52 +00:00
|
|
|
if (url && this.props.onURLChanged) {
|
|
|
|
|
super.executeAction({
|
|
|
|
|
triggerPropertyName: "onURLChanged",
|
|
|
|
|
dynamicString: this.props.onURLChanged,
|
|
|
|
|
event: {
|
|
|
|
|
type: EventType.ON_IFRAME_URL_CHANGED,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-06-09 09:39:17 +00:00
|
|
|
};
|
|
|
|
|
|
2021-06-10 08:17:33 +00:00
|
|
|
messageReceivedHandler = (event: MessageEvent) => {
|
|
|
|
|
// Accept messages only from the current iframe
|
2021-06-11 13:16:29 +00:00
|
|
|
if (!this.props.source?.includes(event.origin)) {
|
2021-06-10 08:17:33 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (this.props.onMessageReceived) {
|
2021-06-10 05:29:52 +00:00
|
|
|
super.executeAction({
|
|
|
|
|
triggerPropertyName: "onMessageReceived",
|
|
|
|
|
dynamicString: this.props.onMessageReceived,
|
|
|
|
|
event: {
|
|
|
|
|
type: EventType.ON_IFRAME_MESSAGE_RECEIVED,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-06-09 09:39:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
getPageView() {
|
2021-06-12 16:08:10 +00:00
|
|
|
const {
|
|
|
|
|
borderColor,
|
|
|
|
|
borderOpacity,
|
|
|
|
|
borderWidth,
|
|
|
|
|
source,
|
|
|
|
|
title,
|
|
|
|
|
widgetId,
|
|
|
|
|
} = this.props;
|
2021-06-09 09:39:17 +00:00
|
|
|
return (
|
|
|
|
|
<IframeComponent
|
2021-06-12 16:08:10 +00:00
|
|
|
borderColor={borderColor}
|
|
|
|
|
borderOpacity={borderOpacity}
|
|
|
|
|
borderWidth={borderWidth}
|
2021-06-09 09:39:17 +00:00
|
|
|
onMessageReceived={this.messageReceivedHandler}
|
|
|
|
|
onURLChanged={this.urlChangedHandler}
|
2021-06-12 16:08:10 +00:00
|
|
|
source={source}
|
|
|
|
|
title={title}
|
|
|
|
|
widgetId={widgetId}
|
2021-06-09 09:39:17 +00:00
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getWidgetType(): WidgetType {
|
|
|
|
|
return WidgetTypes.IFRAME_WIDGET;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-12 16:08:10 +00:00
|
|
|
export interface IframeWidgetProps extends WidgetProps {
|
2021-06-09 09:39:17 +00:00
|
|
|
source: string;
|
|
|
|
|
title?: string;
|
|
|
|
|
onURLChanged?: string;
|
|
|
|
|
onMessageReceived?: string;
|
|
|
|
|
borderColor?: string;
|
|
|
|
|
borderOpacity?: number;
|
|
|
|
|
borderWidth?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default IframeWidget;
|
2021-06-12 16:08:10 +00:00
|
|
|
export const ProfiledIframeWidget = Sentry.withProfiler(IframeWidget);
|