Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support new dashboard plugin architecture #3082

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f02d622
refactor: use shared plugin wrapper component
edoardo Jun 3, 2024
2b0ec8c
chore: bump cli-app-scripts and app-runtime
edoardo Jun 3, 2024
a1c7e50
chore: use alpha of analytics for testing
edoardo Jun 6, 2024
258ac6e
chore: bump cli-app-scripts deps
edoardo Jun 7, 2024
66ec285
chore: bump app-runtime and cli-app-scripts
edoardo Jun 28, 2024
239af8c
chore: bump cli-app-scripts
edoardo Jul 1, 2024
29069dc
chore: use analytics build from d2-ci for testing
edoardo Jul 3, 2024
3a43867
chore: run deduplicate
edoardo Aug 1, 2024
881ee78
chore: bump start-server-and-test
edoardo Aug 1, 2024
39740ef
chore: use latest cli-app-scripts and app-runtime
edoardo Aug 2, 2024
0ec71f9
chore: update analytics dep
edoardo Aug 5, 2024
c99249c
fix: indicate the plugin is for dashboard
edoardo Aug 13, 2024
0526a1b
fix: use uppercase for pluginType value
edoardo Aug 15, 2024
e1d7c7e
chore: update cli-style and Cypress dependencies to work with Cypress 13
edoardo Aug 15, 2024
8fe3209
Merge remote-tracking branch 'origin/master' into refactor/use-platfo…
edoardo Aug 15, 2024
614646b
chore: run Prettier
edoardo Aug 15, 2024
0ef7ab9
Merge branch 'master' into refactor/use-platform-plugin-components
edoardo Aug 16, 2024
3b7dcf6
chore: remove resolution for @dhis2/ui
edoardo Aug 19, 2024
9d86485
Merge remote-tracking branch 'origin/master' into refactor/use-platfo…
edoardo Sep 21, 2024
ba9d5f1
Merge remote-tracking branch 'origin/master' into refactor/use-platfo…
edoardo Oct 9, 2024
8795b4c
chore: update analytics version for testing
edoardo Oct 9, 2024
21dd9ab
chore: use latest analytics for testing
edoardo Oct 10, 2024
2834847
chore: remove debug log
edoardo Oct 18, 2024
de99892
Merge remote-tracking branch 'origin/master' into refactor/use-platfo…
edoardo Oct 30, 2024
fc291f0
chore: use latest analytics build for testing
edoardo Nov 11, 2024
97a8bdb
chore: regenerate yarn.lock
edoardo Nov 11, 2024
0957a5a
Merge branch 'master' into refactor/use-platform-plugin-components
jenniferarnesen Nov 11, 2024
5911bb1
Merge remote-tracking branch 'origin/master' into refactor/use-platfo…
edoardo Nov 15, 2024
b563060
chore: use latest analytics build for testing
edoardo Nov 15, 2024
5a345d1
refactor: remove unnecessary storing of props in local state
edoardo Nov 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions d2.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const config = {

minDHIS2Version: '2.40',

pluginType: 'DASHBOARD',

direction: 'auto',

pwa: {
Expand All @@ -20,8 +22,6 @@ const config = {
app: './src/AppWrapper.js',
plugin: './src/PluginWrapper.js',
},

skipPluginLogic: true,
}

module.exports = config
14 changes: 5 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
"cy:run": "start-server-and-test 'yarn start:nobrowser' http://localhost:3000 'yarn cypress run --browser chrome headless --env networkMode=live'"
},
"devDependencies": {
"@dhis2/cli-app-scripts": "^11.3.0",
"@dhis2/cli-app-scripts": "^11.7.0",
"@dhis2/cli-style": "^10.7.3",
"@dhis2/cypress-commands": "^10.0.3",
"@dhis2/cypress-plugins": "^10.0.2",
"@dhis2/cypress-commands": "^10.0.6",
"@dhis2/cypress-plugins": "^10.0.6",
"@reportportal/agent-js-cypress": "git+https://github.com/dhis2/agent-js-cypress.git#develop",
"@reportportal/agent-js-jest": "^5.0.6",
"@semantic-release/changelog": "^6",
Expand All @@ -43,12 +43,11 @@
"typescript": "^4.8.4"
},
"dependencies": {
"@dhis2/analytics": "^26.8.7",
"@dhis2/app-runtime": "^3.10.4",
"@dhis2/analytics": "git+https://github.com/d2-ci/analytics.git#13cd471cc31e0a113fb4323a104f7b4fa70b2353",
"@dhis2/app-runtime": "^3.10.6",
"@dhis2/app-runtime-adapter-d2": "^1.1.0",
"@dhis2/app-service-datastore": "^1.0.0-beta.3",
"@dhis2/d2-i18n": "^1.1.0",
"@dhis2/ui": "^9.4.4",
"@krakenjs/post-robot": "^11.0.0",
"d2": "^31.9.1",
"decode-uri-component": "^0.2.2",
Expand All @@ -68,8 +67,5 @@
"reselect": "^4.1.7",
"styled-jsx": "^4",
"whatwg-fetch": "^3.6.2"
},
"resolutions": {
"@dhis2/ui": "^9.4.4"
}
}
127 changes: 11 additions & 116 deletions src/PluginWrapper.js
Original file line number Diff line number Diff line change
@@ -1,105 +1,14 @@
import { useCacheableSection, CacheableSection } from '@dhis2/app-runtime'
import { CssVariables, CenteredContent, CircularLoader, Layer } from '@dhis2/ui'
import postRobot from '@krakenjs/post-robot'
import { DashboardPluginWrapper } from '@dhis2/analytics'
import debounce from 'lodash-es/debounce'
import PropTypes from 'prop-types'
import React, { useEffect, useLayoutEffect, useState } from 'react'
import { VisualizationPluginWrapper } from './components/VisualizationPlugin/VisualizationPluginWrapper.js'
import { getPWAInstallationStatus } from './modules/getPWAInstallationStatus.js'
import './locales/index.js'

const LoadingMask = () => {
return (
<Layer>
<CenteredContent>
<CircularLoader />
</CenteredContent>
</Layer>
)
}

const CacheableSectionWrapper = ({
id,
children,
cacheNow,
isParentCached,
}) => {
const { startRecording, isCached, remove } = useCacheableSection(id)

useEffect(() => {
if (cacheNow) {
startRecording({ onError: console.error })
}

// NB: Adding `startRecording` to dependencies causes
// an infinite recording loop as-is (probably need to memoize it)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [cacheNow])

useEffect(() => {
const listener = postRobot.on(
'removeCachedData',
// todo: check domain too; differs based on deployment env though
{ window: window.parent },
() => remove()
)

return () => listener.cancel()
}, [remove])

useEffect(() => {
// Synchronize cache state on load or prop update
// -- a back-up to imperative `removeCachedData`
if (!isParentCached && isCached) {
remove()
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isParentCached])

return (
<CacheableSection id={id} loadingMask={LoadingMask}>
{children}
</CacheableSection>
)
}
CacheableSectionWrapper.propTypes = {
cacheNow: PropTypes.bool,
children: PropTypes.node,
id: PropTypes.string,
isParentCached: PropTypes.bool,
}

const sendInstallationStatus = (installationStatus) => {
postRobot.send(window.parent, 'installationStatus', { installationStatus })
}

const PluginWrapper = () => {
const [propsFromParent, setPropsFromParent] = useState()
const PluginWrapper = (props) => {
const [propsFromParent, setPropsFromParent] = useState(props)
const [renderId, setRenderId] = useState(null)
edoardo marked this conversation as resolved.
Show resolved Hide resolved

const receivePropsFromParent = (event) => setPropsFromParent(event.data)

useEffect(() => {
postRobot
.send(window.parent, 'getProps')
.then(receivePropsFromParent)
.catch((err) => console.error(err))

// Get & send PWA installation status now, and also prepare to send
// future updates (installing/ready)
getPWAInstallationStatus({
onStateChange: sendInstallationStatus,
}).then(sendInstallationStatus)

// Allow parent to update props
const listener = postRobot.on(
'newProps',
{ window: window.parent /* Todo: check domain */ },
receivePropsFromParent
)

return () => listener.cancel()
}, [])
useEffect(() => setPropsFromParent(props), [props])

useLayoutEffect(() => {
const updateRenderId = debounce(
Expand All @@ -115,27 +24,13 @@ const PluginWrapper = () => {
return () => window.removeEventListener('resize', updateRenderId)
}, [])

return propsFromParent ? (
<div
style={{
display: 'flex',
height: '100%',
overflow: 'hidden',
return (
<DashboardPluginWrapper {...propsFromParent}>
{(props) => {
return <VisualizationPluginWrapper id={renderId} {...props} />
}}
>
<CacheableSectionWrapper
id={propsFromParent.cacheId}
cacheNow={propsFromParent.recordOnNextLoad}
isParentCached={propsFromParent.isParentCached}
>
<VisualizationPluginWrapper
id={renderId}
{...propsFromParent}
/>
</CacheableSectionWrapper>
<CssVariables colors spacers elevations />
</div>
) : null
</DashboardPluginWrapper>
)
}

export default PluginWrapper
Loading
Loading