From dbd7cb8c60695a4869b239104cae4320d41f1f1b Mon Sep 17 00:00:00 2001 From: Jen Jones Arnesen Date: Wed, 22 Mar 2023 13:10:56 +0100 Subject: [PATCH] fix: prevent re-rendering/flashing of maps and charts [DHIS2-14979] [v40] (#2266) * fix: unwanted re-rendering of dashboard items (#2247) * fix: solve most unwanted re-renders of dashboard items This is basically reverting a change I added to solve a DV Highchart's cutoff issue. I think I found another approach for that issue which does not require to pass style to the plugin, which is a problem because of course it changes any time the dashboard item container changes size (window resize, resize of other dashboard items, interpretation panel toggle, etc...). * chore: bump cli-app-scripts to solve no-service-worker issue * fix: avoid sending props twice when using View as and plugin changes (#2248) * fix: use chrome in e2e tests --------- Co-authored-by: Edoardo Sabadelli --- .github/workflows/verify.yml | 10 +++-- .../Visualization/IframePlugin.js | 42 ++++++++++--------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 768d3843a..378fc913c 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -108,6 +108,9 @@ jobs: runs-on: ubuntu-latest needs: install if: "!contains(github.event.head_commit.message, '[skip ci]')" + container: + image: cypress/browsers:node16.17.0-chrome106 + options: --user 1001 strategy: matrix: @@ -115,9 +118,9 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v3 with: node-version: 14.x @@ -131,13 +134,14 @@ jobs: run: yarn cypress install - name: End-to-End tests - uses: cypress-io/github-action@v2 + uses: cypress-io/github-action@v5 with: record: true parallel: true start: ${{ env.SERVER_START_CMD }} wait-on: ${{ env.SERVER_URL }} wait-on-timeout: 300 + browser: chrome cache-key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} group: 'e2e' tag: ${{ github.event_name }} diff --git a/src/components/Item/VisualizationItem/Visualization/IframePlugin.js b/src/components/Item/VisualizationItem/Visualization/IframePlugin.js index 580c6e74d..f6d8590f6 100644 --- a/src/components/Item/VisualizationItem/Visualization/IframePlugin.js +++ b/src/components/Item/VisualizationItem/Visualization/IframePlugin.js @@ -35,6 +35,7 @@ const IframePlugin = ({ // When this mounts, check if the dashboard is recording const { isCached, recordingState } = useCacheableSection(dashboardId) + const [communicationReceived, setCommunicationReceived] = useState(false) const [recordOnNextLoad, setRecordOnNextLoad] = useState( recordingState === 'recording' ) @@ -47,7 +48,6 @@ const IframePlugin = ({ forDashboard: true, displayProperty: userSettings.displayProperty, visualization, - style, onError, // For caching: --- @@ -65,7 +65,6 @@ const IframePlugin = ({ itemId, isCached, recordOnNextLoad, - style, ] ) @@ -88,34 +87,37 @@ const IframePlugin = ({ useEffect(() => { if (iframeRef?.current) { - const listener = postRobot.on( - 'getProps', - // listen for messages coming only from the iframe rendered by this component - { window: iframeRef.current.contentWindow }, - () => { - if (recordOnNextLoad) { - // Avoid recording unnecessarily, - // e.g. if plugin re-requests props for some reason - setRecordOnNextLoad(false) + // if iframe has not sent initial request, set up a listener + if (!communicationReceived) { + const listener = postRobot.on( + 'getProps', + // listen for messages coming only from the iframe rendered by this component + { window: iframeRef.current.contentWindow }, + () => { + setCommunicationReceived(true) + + if (recordOnNextLoad) { + // Avoid recording unnecessarily, + // e.g. if plugin re-requests props for some reason + setRecordOnNextLoad(false) + } + + return pluginProps } + ) - return pluginProps - } - ) - - return () => listener.cancel() + return () => listener.cancel() + } } - }, [recordOnNextLoad, pluginProps]) - useEffect(() => { - if (iframeRef.current?.contentWindow) { + if (communicationReceived && iframeRef.current?.contentWindow) { postRobot.send( iframeRef.current.contentWindow, 'newProps', pluginProps ) } - }, [pluginProps]) + }, [communicationReceived, recordOnNextLoad, pluginProps]) useEffect(() => { setError(null)