@@ -114,33 +60,6 @@ exports[`renders active type MAP rather than original type REPORT_TABLE 1`] = `
exports[`renders active type REPORT_TABLE rather than original type MAP 1`] = `
-
diff --git a/src/components/Item/VisualizationItem/Visualization/plugin.js b/src/components/Item/VisualizationItem/Visualization/plugin.js
index fe19c24c2..07e677e4c 100644
--- a/src/components/Item/VisualizationItem/Visualization/plugin.js
+++ b/src/components/Item/VisualizationItem/Visualization/plugin.js
@@ -8,27 +8,71 @@ import {
} from '../../../../modules/itemTypes'
import { getVisualizationId } from '../../../../modules/item'
import getGridItemDomId from '../../../../modules/getGridItemDomId'
+import { loadExternalScript } from '../../../../modules/loadExternalScript'
//external plugins
-const itemTypeToExternalPlugin = {
+const itemTypeToGlobalVariable = {
[MAP]: 'mapPlugin',
[EVENT_REPORT]: 'eventReportPlugin',
[EVENT_CHART]: 'eventChartPlugin',
}
+
+const itemTypeToScriptPath = {
+ [MAP]: '/dhis-web-maps/map.js',
+ [EVENT_REPORT]: '/dhis-web-event-reports/eventreport.js',
+ [EVENT_CHART]: '/dhis-web-event-visualizer/eventchart.js',
+}
+
const hasIntegratedPlugin = type => [CHART, REPORT_TABLE].includes(type)
-const getPlugin = type => {
+const getPlugin = async type => {
if (hasIntegratedPlugin(type)) {
return true
}
- const pluginName = itemTypeToExternalPlugin[type]
+ const pluginName = itemTypeToGlobalVariable[type]
return global[pluginName]
}
-export const pluginIsAvailable = type => !!getPlugin(type)
+const fetchPlugin = async (type, baseUrl) => {
+ const globalName = itemTypeToGlobalVariable[type]
+ if (global[globalName]) {
+ return global[globalName] // Will be a promise if fetch is in progress
+ }
+
+ const scripts = []
+
+ if (type === EVENT_REPORT || type === EVENT_CHART) {
+ if (process.env.NODE_ENV === 'production') {
+ scripts.push('./vendor/babel-polyfill-6.26.0.min.js')
+ scripts.push('./vendor/jquery-3.3.1.min.js')
+ scripts.push('./vendor/jquery-migrate-3.0.1.min.js')
+ } else {
+ scripts.push('./vendor/babel-polyfill-6.26.0.js')
+ scripts.push('./vendor/jquery-3.3.1.js')
+ scripts.push('./vendor/jquery-migrate-3.0.1.js')
+ }
+ }
+
+ scripts.push(baseUrl + itemTypeToScriptPath[type])
+
+ const scriptsPromise = Promise.all(scripts.map(loadExternalScript)).then(
+ () => global[globalName] // At this point, has been replaced with the real thing
+ )
+ global[globalName] = scriptsPromise
+ return await scriptsPromise
+}
+
+export const pluginIsAvailable = type =>
+ hasIntegratedPlugin(type) || itemTypeToGlobalVariable[type]
+
+export const loadPlugin = async (type, config, credentials) => {
+ if (!pluginIsAvailable(type)) {
+ return
+ }
+
+ const plugin = await fetchPlugin(type, credentials.baseUrl)
-export const loadPlugin = (plugin, config, credentials) => {
if (!(plugin && plugin.load)) {
return
}
@@ -60,9 +104,7 @@ export const load = async (
}
const type = activeType || item.type
- const plugin = getPlugin(type)
-
- loadPlugin(plugin, config, credentials)
+ await loadPlugin(type, config, credentials)
}
export const resize = (id, type, isFullscreen = false) => {
diff --git a/src/modules/loadExternalScript.js b/src/modules/loadExternalScript.js
new file mode 100644
index 000000000..aa6bb1442
--- /dev/null
+++ b/src/modules/loadExternalScript.js
@@ -0,0 +1,47 @@
+const isRelative = path => path.startsWith('./')
+const normalizeRelativePath = path =>
+ [process.env.PUBLIC_URL, path.replace(/^\.\//, '')].join('/')
+
+const isScriptLoaded = src =>
+ document.querySelector('script[src="' + src + '"]') ? true : false
+
+export const loadExternalScript = src => {
+ if (isRelative(src)) {
+ src = normalizeRelativePath(src)
+ }
+
+ return new Promise((resolve, reject) => {
+ if (isScriptLoaded(src)) {
+ return resolve()
+ }
+
+ const element = document.createElement('script')
+
+ element.src = src
+ element.type = 'text/javascript'
+ element.async = false
+
+ const cleanup = () => {
+ console.log(`Dynamic Script Removed: ${src}`)
+ document.head.removeChild(element)
+ }
+
+ element.onload = () => {
+ console.log(`Dynamic Script Loaded: ${src}`)
+ try {
+ resolve()
+ } catch (e) {
+ cleanup()
+ reject()
+ }
+ }
+
+ element.onerror = () => {
+ console.error(`Dynamic Script Error: ${src}`)
+ cleanup()
+ reject()
+ }
+
+ document.head.appendChild(element)
+ })
+}