Skip to content

Commit

Permalink
feat: add autoresizing for height
Browse files Browse the repository at this point in the history
  • Loading branch information
tomzemp committed Mar 29, 2023
1 parent 44b27c4 commit dbb6e26
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
1 change: 1 addition & 0 deletions docs/components/Plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const MyPlugin = (propsFromParent) => {
| **pluginSource** | _string_ (url) | _required_ if `pluginShortName` is not provided | The URL of the plugin. If this is not provided, `pluginShortName` must be provided. |
| **onError** | _Function_ | _optional_ | Callback function to be called when an error in the plugin triggers an error boundary. You can use this to pass an error back up to the app and create a custom handling/UX if errors occur in the plugin. In general, it is recommended that you use the plugin's built-in error boundaries |
| **showAlertsInPlugin** | _boolean_ | _optional_ | If `true`, any alerts within the plugin (defined with the `useAlert` hook) will be rendered within the iframe. By default, this is `false`. It is recommended, in general, that you do not override this and allow alerts to be hoisted up to the app level |
| **height** | _number_ | _optional_ | If a height is provided, the iframe will be fixed to the specified height. If no height is provided, the iframe will automatically resize based on its contents. |

## Plugin Props (custom props)

Expand Down
41 changes: 30 additions & 11 deletions services/plugin/src/Plugin.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AlertsManagerContext } from '@dhis2/app-service-alerts'
import { useDataQuery } from '@dhis2/app-service-data'
import postRobot from 'post-robot'
import React, { useContext, useEffect, useRef, useState } from 'react'
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react'
import PluginError from './PluginError'

const appsInfoQuery = {
Expand All @@ -27,14 +27,23 @@ const getPluginEntryPoint = ({
export const Plugin = ({
pluginSource,
pluginShortName,
...propsToPass
...propsToPassNonMemoized
}: {
pluginSource?: string
pluginShortName?: string
propsToPass: any
}): JSX.Element => {
const iframeRef = useRef<HTMLIFrameElement>(null)

// we do not know what is being sent in passed props, so for stable reference, memoize using JSON representation
const propsToPassNonMemoizedJSON = JSON.stringify(propsToPassNonMemoized)
const propsToPass = useMemo(
() => ({ ...propsToPassNonMemoized }),
// eslint-disable-next-line react-hooks/exhaustive-deps
[propsToPassNonMemoizedJSON]
)
const { height } = propsToPass

const { add: alertsAdd } = useContext(AlertsManagerContext)

const { data } = useDataQuery(appsInfoQuery)
Expand All @@ -49,12 +58,20 @@ export const Plugin = ({
useState<boolean>(false)

const [inErrorState, setInErrorState] = useState<boolean>(false)
const [pluginHeight, setPluginHeight] = useState<number>(150)

useEffect(() => {
if (height) {
setPluginHeight(height)
}
}, [height])

useEffect(() => {
if (iframeRef?.current) {
const iframeProps = {
...propsToPass,
alertsAdd,
setPluginHeight,
setInErrorState,
setCommunicationReceived,
}
Expand Down Expand Up @@ -104,15 +121,17 @@ export const Plugin = ({

if (pluginEntryPoint) {
return (
<iframe
ref={iframeRef}
src={pluginSource}
style={{
width: '100%',
height: '100%',
border: 'none',
}}
></iframe>
<div style={{ height: `${pluginHeight}px` }}>
<iframe
ref={iframeRef}
src={pluginSource}
style={{
width: '100%',
height: '100%',
border: 'none',
}}
></iframe>
</div>
)
}

Expand Down

0 comments on commit dbb6e26

Please sign in to comment.