diff --git a/shell/src/PluginLoader.js b/shell/src/PluginLoader.js
index 109fe0b2..ee7c900e 100644
--- a/shell/src/PluginLoader.js
+++ b/shell/src/PluginLoader.js
@@ -2,7 +2,74 @@ import AppAdapter from '@dhis2/app-adapter'
import { Layer, layers, CenteredContent, CircularLoader } from '@dhis2/ui'
import postRobot from 'post-robot'
import PropTypes from 'prop-types'
-import React, { useCallback, useEffect, useState } from 'react'
+import React, { useCallback, useEffect, useRef, useState } from 'react'
+
+const PluginInner = ({
+ D2App,
+ config,
+ propsFromParent,
+ resizePluginHeight,
+ resizePluginWidth,
+}) => {
+ const divRef = useRef()
+ const innerDivRef = useRef()
+ useEffect(() => {
+ if (divRef && divRef.current && resizePluginHeight) {
+ const resizeObserver = new ResizeObserver(() => {
+ // the additional pixels currently account for possible horizontal scroll bar
+ if (resizePluginHeight) {
+ resizePluginHeight(divRef.current.offsetHeight + 20)
+ }
+ })
+ resizeObserver.observe(divRef.current)
+ }
+ }, [resizePluginHeight])
+
+ const previousWidth = useRef()
+
+ const resetWidth = useCallback(() => {
+ const currentWidth = innerDivRef.current?.scrollWidth
+ if (resizePluginWidth && currentWidth) {
+ if (
+ previousWidth.current &&
+ Math.abs(currentWidth - previousWidth.current) > 20
+ ) {
+ resizePluginWidth(currentWidth + 20)
+ }
+ previousWidth.current = currentWidth
+ }
+ requestAnimationFrame(resetWidth)
+ }, [resizePluginWidth])
+
+ useEffect(() => {
+ if (resizePluginWidth) {
+ requestAnimationFrame(resetWidth)
+ }
+ }, [resetWidth, resizePluginWidth])
+
+ // inner div disables margin collapsing which would prevent computing correct height
+ return (
+
+ )
+}
+
+PluginInner.propTypes = {
+ D2App: PropTypes.object,
+ config: PropTypes.object,
+ propsFromParent: PropTypes.array,
+ resizePluginHeight: PropTypes.func,
+ resizePluginWidth: PropTypes.func,
+}
export const PluginLoader = ({ config, requiredProps, D2App }) => {
const [propsFromParent, setPropsFromParent] = useState({})
@@ -11,6 +78,8 @@ export const PluginLoader = ({ config, requiredProps, D2App }) => {
const [showAlertsInPlugin, setShowAlertsInPlugin] = useState(false)
const [onPluginError, setOnPluginError] = useState(() => () => {})
const [clearPluginError, setClearPluginError] = useState(() => () => {})
+ const [resizePluginHeight, setResizePluginHeight] = useState(null)
+ const [resizePluginWidth, setResizePluginWidth] = useState(null)
const receivePropsFromParent = useCallback(
(event) => {
@@ -20,6 +89,10 @@ export const PluginLoader = ({ config, requiredProps, D2App }) => {
setCommunicationReceived,
alertsAdd,
showAlertsInPlugin,
+ height,
+ setPluginHeight,
+ width,
+ setPluginWidth,
onError,
...explicitlyPassedProps
} = receivedProps
@@ -61,6 +134,14 @@ export const PluginLoader = ({ config, requiredProps, D2App }) => {
if (showAlertsInPlugin) {
setShowAlertsInPlugin(Boolean(showAlertsInPlugin))
}
+
+ if (!height && setPluginHeight) {
+ setResizePluginHeight(() => (height) => setPluginHeight(height))
+ }
+
+ if (!width && setPluginWidth) {
+ setResizePluginWidth(() => (width) => setPluginWidth(width))
+ }
},
[
requiredProps,
@@ -68,6 +149,8 @@ export const PluginLoader = ({ config, requiredProps, D2App }) => {
setClearPluginError,
setParentAlertsAdd,
setShowAlertsInPlugin,
+ setResizePluginHeight,
+ setResizePluginWidth,
]
)
@@ -120,7 +203,13 @@ export const PluginLoader = ({ config, requiredProps, D2App }) => {
}
>
-
+
)