UNPKG

@craftercms/studio-ui

Version:

Services, components, models & utils to build CrafterCMS authoring extensions.

127 lines (125 loc) 4.75 kB
/* * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ import React, { memo } from 'react'; import NonReactWidget from '../NonReactWidget/NonReactWidget'; import { importPlugin } from '../../services/plugin'; import { components } from '../../utils/constants'; import EmptyState from '../EmptyState/EmptyState'; import { defineMessages, useIntl } from 'react-intl'; import ErrorState from '../ErrorState'; import { isValidElementType } from 'react-is'; const messages = defineMessages({ componentNotFoundTitle: { id: 'widgetComponent.componentNotFoundTitle', defaultMessage: 'Component {id} not found.' }, componentNotFoundSubtitle: { id: 'widgetComponent.componentNotFoundSubtitle', defaultMessage: "Check ui config & make sure you've installed the plugins that contain the desired components." }, pluginLoadFailedMessageTitle: { id: 'widgetComponent.pluginLoadFailedMessageTitle', defaultMessage: 'Plugin load failed' }, pluginLoadFailedMessageBody: { id: 'widgetComponent.pluginLoadFailedMessageBody', defaultMessage: 'With {info} & component id "{id}".' } }); const Widget = memo(function (props) { const { id, plugin, configuration } = props; const record = components.get(id); const { formatMessage } = useIntl(); if (record) { if (isValidElementType(record)) { const Component = record; return React.createElement( Component, Object.assign( {}, Object.assign(Object.assign(Object.assign({}, props.defaultProps), configuration), props.overrideProps) ) ); } else { return React.createElement(NonReactWidget, { widget: record, configuration: Object.assign( Object.assign(Object.assign({}, props.defaultProps), configuration), props.overrideProps ) }); } } else if (!plugin) { return React.createElement(EmptyState, { title: formatMessage(messages.componentNotFoundTitle, { id }), subtitle: formatMessage(messages.componentNotFoundSubtitle), styles: { image: { width: 100 } } }); } else { const Component = React.lazy(() => importPlugin(plugin).then( () => ({ default: function (props) { if (components.has(id)) { return React.createElement(Widget, Object.assign({}, props)); } else { return React.createElement(EmptyState, { title: formatMessage(messages.componentNotFoundTitle, { id }), subtitle: formatMessage(messages.componentNotFoundSubtitle), styles: { image: { width: 100 } } }); } } }), (error) => { console.error(error); return { default: function ({ id, plugin }) { return React.createElement(ErrorState, { styles: { image: { width: 100 } }, title: formatMessage(messages.pluginLoadFailedMessageTitle), message: formatMessage(messages.pluginLoadFailedMessageBody, { id, info: Object.entries(plugin) .map(([key, value]) => `${key} "${value}"`) .join(', ') }) }); } }; } ) ); return React.createElement(Component, Object.assign({}, props)); } }); export { Widget }; export default Widget;