2020-10-06 09:01:51 +00:00
|
|
|
import React from "react";
|
|
|
|
|
import BaseWidget, { WidgetProps } from "./BaseWidget";
|
|
|
|
|
import _ from "lodash";
|
|
|
|
|
import { EditorContext } from "../components/editorComponents/EditorContextProvider";
|
2021-01-04 10:16:08 +00:00
|
|
|
import { clearEvalPropertyCache } from "sagas/EvaluationsSaga";
|
2020-10-06 16:47:16 +00:00
|
|
|
import { ExecuteActionPayload } from "../constants/ActionConstants";
|
|
|
|
|
|
|
|
|
|
type DebouncedExecuteActionPayload = Omit<
|
|
|
|
|
ExecuteActionPayload,
|
|
|
|
|
"dynamicString"
|
2020-10-21 04:25:32 +00:00
|
|
|
> & {
|
|
|
|
|
dynamicString?: string;
|
|
|
|
|
};
|
2020-10-06 09:01:51 +00:00
|
|
|
|
|
|
|
|
export interface WithMeta {
|
2020-10-06 16:47:16 +00:00
|
|
|
updateWidgetMetaProperty: (
|
|
|
|
|
propertyName: string,
|
|
|
|
|
propertyValue: any,
|
|
|
|
|
actionExecution?: DebouncedExecuteActionPayload,
|
|
|
|
|
) => void;
|
2020-10-06 09:01:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const withMeta = (WrappedWidget: typeof BaseWidget) => {
|
|
|
|
|
return class MetaHOC extends React.Component<WidgetProps, any> {
|
|
|
|
|
static contextType = EditorContext;
|
|
|
|
|
updatedProperties = new Map<string, true>();
|
2020-10-06 16:47:16 +00:00
|
|
|
propertyTriggers = new Map<string, DebouncedExecuteActionPayload>();
|
2020-10-06 09:01:51 +00:00
|
|
|
|
|
|
|
|
debouncedHandleUpdateWidgetMetaProperty = _.debounce(
|
|
|
|
|
this.handleUpdateWidgetMetaProperty.bind(this),
|
|
|
|
|
200,
|
|
|
|
|
{
|
|
|
|
|
leading: true,
|
|
|
|
|
trailing: true,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
constructor(props: any) {
|
|
|
|
|
super(props);
|
|
|
|
|
const metaProperties = WrappedWidget.getMetaPropertiesMap();
|
|
|
|
|
this.state = _.fromPairs(
|
2020-12-24 04:32:25 +00:00
|
|
|
Object.keys(metaProperties).map((metaProperty) => {
|
2020-10-06 09:01:51 +00:00
|
|
|
return [metaProperty, this.props[metaProperty]];
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
componentDidUpdate(prevProps: WidgetProps) {
|
|
|
|
|
const metaProperties = WrappedWidget.getMetaPropertiesMap();
|
|
|
|
|
const defaultProperties = WrappedWidget.getDefaultPropertiesMap();
|
2020-12-24 04:32:25 +00:00
|
|
|
Object.keys(metaProperties).forEach((metaProperty) => {
|
2020-10-06 09:01:51 +00:00
|
|
|
const defaultProperty = defaultProperties[metaProperty];
|
|
|
|
|
if (
|
2020-11-03 05:19:27 +00:00
|
|
|
!_.isEqual(prevProps[metaProperty], this.props[metaProperty]) &&
|
|
|
|
|
_.isEqual(this.props[defaultProperty], this.props[metaProperty])
|
2020-10-06 09:01:51 +00:00
|
|
|
) {
|
|
|
|
|
this.setState({ [metaProperty]: this.props[metaProperty] });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateWidgetMetaProperty = (
|
|
|
|
|
propertyName: string,
|
|
|
|
|
propertyValue: any,
|
2020-10-06 16:47:16 +00:00
|
|
|
actionExecution?: DebouncedExecuteActionPayload,
|
2020-10-06 09:01:51 +00:00
|
|
|
): void => {
|
|
|
|
|
this.updatedProperties.set(propertyName, true);
|
2020-10-06 16:47:16 +00:00
|
|
|
if (actionExecution) {
|
|
|
|
|
this.propertyTriggers.set(propertyName, actionExecution);
|
|
|
|
|
}
|
|
|
|
|
this.setState(
|
|
|
|
|
{
|
|
|
|
|
[propertyName]: propertyValue,
|
|
|
|
|
},
|
|
|
|
|
() => {
|
|
|
|
|
this.debouncedHandleUpdateWidgetMetaProperty();
|
|
|
|
|
},
|
|
|
|
|
);
|
2020-10-06 09:01:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
handleUpdateWidgetMetaProperty() {
|
2020-10-06 16:47:16 +00:00
|
|
|
const { updateWidgetMetaProperty, executeAction } = this.context;
|
2020-10-06 09:01:51 +00:00
|
|
|
const { widgetId, widgetName } = this.props;
|
|
|
|
|
// We have kept a map of all updated properties. After debouncing we will
|
|
|
|
|
// go through these properties and update with the final value. This way
|
|
|
|
|
// we will only update a certain property once per debounce interval.
|
2020-10-06 16:47:16 +00:00
|
|
|
// Then we will execute any action associated with the trigger of
|
|
|
|
|
// that value changing
|
2020-12-24 04:32:25 +00:00
|
|
|
[...this.updatedProperties.keys()].forEach((propertyName) => {
|
2020-10-06 09:01:51 +00:00
|
|
|
if (updateWidgetMetaProperty) {
|
|
|
|
|
const propertyValue = this.state[propertyName];
|
2020-10-21 04:25:32 +00:00
|
|
|
clearEvalPropertyCache(`${widgetName}.${propertyName}`);
|
2020-10-06 09:01:51 +00:00
|
|
|
updateWidgetMetaProperty(widgetId, propertyName, propertyValue);
|
|
|
|
|
this.updatedProperties.delete(propertyName);
|
|
|
|
|
}
|
2020-10-06 16:47:16 +00:00
|
|
|
const debouncedPayload = this.propertyTriggers.get(propertyName);
|
|
|
|
|
if (
|
|
|
|
|
debouncedPayload &&
|
|
|
|
|
debouncedPayload.dynamicString &&
|
|
|
|
|
executeAction
|
|
|
|
|
) {
|
|
|
|
|
executeAction(debouncedPayload);
|
|
|
|
|
this.propertyTriggers.delete(propertyName);
|
|
|
|
|
}
|
2020-10-06 09:01:51 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updatedProps = () => {
|
|
|
|
|
return {
|
|
|
|
|
...this.props,
|
|
|
|
|
...this.state,
|
|
|
|
|
updateWidgetMetaProperty: this.updateWidgetMetaProperty,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
render() {
|
|
|
|
|
return <WrappedWidget {...this.updatedProps()} />;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default withMeta;
|