@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
127 lines (125 loc) • 4.75 kB
JavaScript
/*
* 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;