@openmrs/esm-extensions
Version:
Coordinates extensions and extension points in the OpenMRS Frontend
63 lines (62 loc) • 2.63 kB
JavaScript
/** @module @category Extension */ import { mountRootParcel } from "single-spa";
import { getExtensionNameFromId, getExtensionRegistration } from "./extensions.js";
import { checkStatus } from "./helpers.js";
import { updateInternalExtensionStore } from "./store.js";
let parcelCount = 0;
/**
* Mounts into a DOM node (representing an extension slot)
* a lazy-loaded component from *any* frontend module
* that registered an extension component for this slot.
*/ export async function renderExtension(domElement, extensionSlotName, extensionSlotModuleName, extensionId, renderFunction = (x)=>x, additionalProps = {}) {
const extensionName = getExtensionNameFromId(extensionId);
const extensionRegistration = getExtensionRegistration(extensionId);
let parcel = null;
if (domElement) {
if (!extensionRegistration) {
throw Error(`Couldn't find extension '${extensionName}' to attach to '${extensionSlotName}'`);
}
const { meta, moduleName, online, offline, load } = extensionRegistration;
if (checkStatus(online, offline)) {
updateInternalExtensionStore((state)=>{
const instance = {
domElement,
id: extensionId,
slotName: extensionSlotName,
slotModuleName: extensionSlotModuleName
};
return {
...state,
extensions: {
...state.extensions,
[extensionName]: {
...state.extensions[extensionName],
instances: [
...state.extensions[extensionName].instances,
instance
]
}
}
};
});
const lifecycle = await load();
const id = parcelCount++;
parcel = mountRootParcel(renderFunction({
...lifecycle,
name: `${extensionSlotName}/${extensionName}-${id}`
}), {
...additionalProps,
_meta: meta,
_extensionContext: {
extensionId,
extensionSlotName,
extensionSlotModuleName,
extensionModuleName: moduleName
},
domElement
});
}
} else {
console.warn(`Tried to render ${extensionId} into ${extensionSlotName} but no DOM element was available.`);
}
return parcel;
}