UNPKG

@openmrs/esm-extensions

Version:

Coordinates extensions and extension points in the OpenMRS Frontend

63 lines (62 loc) 2.63 kB
/** @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; }