From 386834c1819411688367c75186e39c94ca347b5d Mon Sep 17 00:00:00 2001 From: Manuel Alejandro Date: Tue, 21 Feb 2023 09:46:44 +0100 Subject: [PATCH] widget: extended loader to load from multiple sources. --- .../widgets/custom_fields/CustomFields.js | 6 +-- src/lib/forms/widgets/loader.js | 43 +++++++++++-------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/lib/forms/widgets/custom_fields/CustomFields.js b/src/lib/forms/widgets/custom_fields/CustomFields.js index 9bb1c820..d410d470 100644 --- a/src/lib/forms/widgets/custom_fields/CustomFields.js +++ b/src/lib/forms/widgets/custom_fields/CustomFields.js @@ -31,13 +31,13 @@ export class CustomFields extends Component { } async loadCustomFieldsWidgets() { - const { config, fieldPathPrefix, templateLoader } = this.props; + const { config, fieldPathPrefix, templateLoaders } = this.props; const sections = []; for (const sectionCfg of config) { // Path to end user's folder defining custom fields ui widgets const fields = await loadWidgetsFromConfig({ - templateLoader: templateLoader, + templateLoaders: templateLoaders, fieldPathPrefix: fieldPathPrefix, fields: sectionCfg.fields, }); @@ -73,7 +73,7 @@ CustomFields.propTypes = { ), }) ).isRequired, - templateLoader: PropTypes.func.isRequired, + templateLoaders: PropTypes.array.isRequired, fieldPathPrefix: PropTypes.string.isRequired, includesPaths: PropTypes.func, }; diff --git a/src/lib/forms/widgets/loader.js b/src/lib/forms/widgets/loader.js index e6fbda95..5081d6e4 100644 --- a/src/lib/forms/widgets/loader.js +++ b/src/lib/forms/widgets/loader.js @@ -8,30 +8,37 @@ import React from "react"; * dynamic import cannot rely on purely a dynamic path i.e a variable. */ export async function importWidget( - templateLoader, + templateLoaders, { ui_widget: UIWidget, fieldPath, props } ) { - let component = null; - try { - // First try import widget from user's defined templateLoader - const module = await templateLoader(UIWidget); - component = module.default ?? module[UIWidget]; - } catch (error) { + let component = undefined; + + // Try import widget from user's defined templateLoaders + for (const loader of templateLoaders) { try { - // If not then look into widgets folder for the component - const module = await import("./index"); + const module = await loader(UIWidget); component = module.default ?? module[UIWidget]; + // Component was found, stop looking. + if (component) { + break; + } } catch (error) { - console.error(`Failed to import default component ${UIWidget}.js`); + // If the component failed to load from a loader, try other loaders first. + continue; } } - if (component) { - return React.createElement(component, { - ...props, - key: fieldPath, - fieldPath: fieldPath, - }); + + // Loading failed, log it and throw an error. + if (component === undefined) { + console.error(`Failed to import default component ${UIWidget}.js`); + throw Error("Component not found in any loader"); } + + return React.createElement(component, { + ...props, + key: fieldPath, + fieldPath: fieldPath, + }); } /** @@ -62,7 +69,7 @@ export async function importWidget( * */ export async function loadWidgetsFromConfig({ - templateLoader, + templateLoaders, fieldPathPrefix, fields, }) { @@ -81,7 +88,7 @@ export async function loadWidgetsFromConfig({ return Promise.all(tplPromises); }; const _fields = await importWidgetsFromFolder( - templateLoader, + templateLoaders, fieldPathPrefix, fields );