@shopgate/pwa-common
Version:
Common library for the Shopgate Connect PWA.
155 lines (144 loc) • 4.52 kB
JavaScript
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import isEqual from 'lodash/isEqual';
import { withThemeWidgets } from '@shopgate/engage/core/hocs';
import WidgetGrid from "./components/WidgetGrid";
import shouldShowWidget from "./helpers/shouldShowWidget";
import { jsx as _jsx } from "react/jsx-runtime";
const WIDGET_GRID_TYPE = '@shopgate/commerce-widgets/widget-grid';
const GRID_COLUMNS = 12; // One grid row has 12 columns. // TODO: is it deprecated since css grid?
/**
* Creates a grid wrapper for widget(s).
* @param {string} key The unique key.
* @param {Array} config Array of widgets to be placed in the grid.
* @param {Array} components The component definitions for the widgets.
* @returns {JSX} The wrapper.
*/
const createGridWrapper = (key, config, components) => (/*#__PURE__*/React.createElement(WidgetGrid, {
key,
config,
components
}));
/**
* The widgets component.
*/
let Widgets = /*#__PURE__*/function (_Component) {
/**
* @param {Object} props The component props.
*/
function Widgets(props) {
var _this;
_this = _Component.call(this, props) || this;
if (_this.hasSchedulableWidgets()) {
_this.startAutoRerender();
}
return _this;
}
/**
* @param {Object} nextProps The next component props.
* @return {JSX}
*/
_inheritsLoose(Widgets, _Component);
var _proto = Widgets.prototype;
_proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps) {
if (!isEqual(this.props.themeWidgets, nextProps.themeWidgets)) {
return true;
}
if (!isEqual(this.props.widgets, nextProps.widgets)) {
return true;
}
return false;
}
/**
* Component will unmount lifecycle method.
*/;
_proto.componentWillUnmount = function componentWillUnmount() {
this.stopAutoRerender();
}
/**
* Checks if any widget is schedulable.
* @param {Array} widgets Array of widgets.
* @returns {boolean}
*/;
_proto.hasSchedulableWidgets = function hasSchedulableWidgets() {
return (this.props.widgets || []).some(widget => widget.settings.plan);
}
/**
* Sets auto re-render.
*/;
_proto.startAutoRerender = function startAutoRerender() {
const minutesToRoundedHour = 60 - new Date().getMinutes();
const nextRerenderIn = minutesToRoundedHour * 60000;
this.autoReloadTimeout = setTimeout(() => this.doAutoRerender(), nextRerenderIn);
}
/**
* Stops auto re-render. Must be called before component is unmounted to avoid
* memory leak.
*/;
_proto.stopAutoRerender = function stopAutoRerender() {
clearTimeout(this.autoReloadTimeout);
}
/**
* Forces re-render and sets another timeout for next cycle.
*/;
_proto.doAutoRerender = function doAutoRerender() {
this.forceUpdate();
this.startAutoRerender();
}
/**
* Create array of elements from widget configuration.
* @returns {Array} Array of JSX elements.
*/;
_proto.createArrayOfElements = function createArrayOfElements() {
const {
widgets = [],
themeWidgets: components
} = this.props;
return widgets.filter(widget => shouldShowWidget(widget.settings)).map((widget, index) => {
if (!components[widget.type] && widget.type !== WIDGET_GRID_TYPE) {
return null;
}
const key = `w${widget?.id || index}`;
if (widget.type === WIDGET_GRID_TYPE) {
// If it's a grid just create it and pass the child widgets.
return createGridWrapper(key, widget.settings.widgets, components);
}
if (widget.height) {
// If it has a definite height wrap the widget in a grid.
return createGridWrapper(key, [{
...widget,
col: 0,
row: 0,
width: GRID_COLUMNS
}], components);
}
// In all other cases just create and return the widget component.
return /*#__PURE__*/React.createElement(components[widget.type], {
...widget,
key
});
});
}
/**
* @return {JSX}
*/;
_proto.render = function render() {
const {
widgets,
themeWidgets: components
} = this.props;
if (!widgets) {
return null;
}
return /*#__PURE__*/_jsx("div", {
className: "common__widgets",
children: this.createArrayOfElements(widgets, components)
});
};
return Widgets;
}(Component);
Widgets.defaultProps = {
widgets: null
};
export default withThemeWidgets(Widgets);