Skip to content

Commit

Permalink
refactor: iframe plugin support (#2110)
Browse files Browse the repository at this point in the history
* chore: convert to functional component

* feat: enable EVENT_VISUALIZATION dashboard item types

* feat: allow iframe plugin overrides for dev/test

* feat: render LL plugin in iframe

* chore: add dependency for post-robot

* chore: update pot file

* fix: lookup in installed apps for the plugin URL to use in the iframe

* chore: remove TODO comment

* chore: update pot file

* chore: add handy deduplicate yarn command

* fix: fix ui dependency

* chore: run prettier

* refactor: rewrite condition for better readability

* fix: remove Suspense which might interfere with the iframe

* fix: ensure the selector content fits in the container

This is a ui issue: dhis2/ui#1152.

* refactor: use Layer + Popper to avoid bottom double border

* fix: remove redundant overflow rule, fixed in ui

This reverts commit a36ab37.

* chore: deduplicate yarn.lock

* refactor: preserve height/width if provided, update props passed

* refactor: use iframe for DV plugin

* chore: remove unused import

* feat: add recording props to plugin (#2125)

* fix(pwa): make cache filters more specifc

* feat(plugins): add `record` prop to iframe plugins when caching dashboard

* feat: remove cached plugin data with dashboard

* chore: run Prettier

* test: fix failing tests

* chore: remove unused code

* chore: run Prettier

* fix: pass correct prop for display property

Also do not pass the whole userSettings object, not used in the plugins
where the only thing really needed is the displayProperty for the
analytics request.

* chore: deduplicate yarn.lock

* fix: add more paths to omit from cache

Replaced deprecated config key with new one.

* fix: show error when iframe src is not available

Also avoid adding postRobot handlers when the iframeRef is not
available, this removes some extra errors.

* fix: do not pass filtered AO to LL plugin

Filters don't work in LL without modifications.
For now just disable filtering for LL items.

* fix: set error when pluginLaunchUrl is not available

The app could be installed and the entry in apps api returned, but the
plugin launch URL can be missing, in that case the plugin cannot be
loaded in the iframe.

* refactor: use specific reducer selector

* fix: remove View As in context menu for LL items

* fix: clear selected from Redux when editing a new dashboard

* feat: add tags on item header, used for filters in LL

For LL items we don't apply filters.
Show a tag in the item header to indicate this to the user.

* feat: add overlay on LL items to inform about not applied filters

* refactor: move the overlay handling to the parent component

In this way both the tag in the item header and the overlay in the item
content can be controlled at the same time allowing for toggling the tag
depending on whether the overlay is shown or not.

* test: update snapshots

* fix: remove tag icon and fix styles

Approved by Joe.

* chore: update pot file

* fix: remove context menu when plugin is not installed

* fetch schema for eventVisualizations, required by the interpretations
  component

* fix: rename Event visualizations to Line lists

This appears as section title in the dashboard item search.

* feat: add custom message for when the plugin is not installed

More friendly than the generic error message.
In this case there isn't any problem with the dashboard item, but the
plugin for rendering the item is not installed.
We inform the user about it and suggest to install the missing app from
the app hub.

* refactor: propagate d2 needed to check installed apps

* feat: use iframe for Map items

* chore: update d2-ui-interpretations component

* fix: update iframe src and props when using View As

* chore: fix linting issue

* fix: fix re-render of visualizations when interpretations panel toggles (#2199)

* fix: add app id for DV when fetched from installed apps

* fix: detect plugin availability via plugin launch URL

* fix: add fallback to bundled plugin path for core apps

This addresses the case of core apps plugins which are always served
from the bundled app's path, instead of from api/apps.

For core (bundled) apps:
* first we look at the api/apps, if there is an entry there for the
  app it means it has been manually installed from the app hub
  overriding the bundled version.
  The plugin URL in this case is not in the format api/apps but
  dhis-web-*.
* if no entry is returned from api/apps we use the "hardcoded" path (as
  before) thus using the bundled version of the plugin.

This should work for situations where a new version of a core app is
installed or uninstalled from the app hub.

* chore: remove accidentally committed temp files

* fix: use base url without api version

This should solve the issue of bundled apps plugin not working in
iframes.

* fix: deduplicate yarn.lock

* fix: attempt at fixing the sizing issue in DV iframe content

* feat: map plugin (#2229)

---------

Co-authored-by: Kai Vandivier <[email protected]>
Co-authored-by: Jen Jones Arnesen <[email protected]>
  • Loading branch information
3 people authored Mar 3, 2023
1 parent 3901e2d commit 7f3eb17
Show file tree
Hide file tree
Showing 34 changed files with 930 additions and 424 deletions.
17 changes: 11 additions & 6 deletions d2.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ const config = {
pwa: {
enabled: true,
caching: {
patternsToOmit: [
'dashboards/[a-zA-Z0-9]*',
'visualizations',
'analytics',
'geoFeatures',
'cartodb-basemaps-a.global.ssl.fastly.net',
patternsToOmitFromAppShell: [
// Make these specific as possible --
// unspecific ones have caused errors on instances with
// 'analytics' in the name, for example
/\/api\/(\d+\/)?dashboards\/[a-zA-Z0-9]*/,
/\/api\/(\d+\/)?maps/,
/\/api\/(\d+\/)?eventVisualizations/,
/\/api\/(\d+\/)?visualizations/,
/\/api\/(\d+\/)?analytics/,
/\/api\/(\d+\/)?geoFeatures/,
/cartodb-basemaps-[a-c]\.global\.ssl\.fastly\.net/,
],
},
},
Expand Down
35 changes: 31 additions & 4 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2023-02-10T10:21:06.817Z\n"
"PO-Revision-Date: 2023-02-10T10:21:06.817Z\n"
"POT-Creation-Date: 2023-02-14T12:38:49.529Z\n"
"PO-Revision-Date: 2023-02-14T12:38:49.529Z\n"

msgid "Untitled dashboard"
msgstr "Untitled dashboard"
Expand Down Expand Up @@ -62,6 +62,12 @@ msgstr "Text item"
msgid "Add text here"
msgstr "Add text here"

msgid "Filters are not applied to line list dashboard items"
msgstr "Filters are not applied to line list dashboard items"

msgid "Filters not applied"
msgstr "Filters not applied"

msgid "There was a problem loading this dashboard item"
msgstr "There was a problem loading this dashboard item"

Expand Down Expand Up @@ -98,12 +104,30 @@ msgstr "There was a problem loading interpretations for this item"
msgid "Maps with Earth Engine layers cannot be displayed when offline"
msgstr "Maps with Earth Engine layers cannot be displayed when offline"

msgid "Unable to load the plugin for this item"
msgstr "Unable to load the plugin for this item"
msgid "The plugin for rendering this item is not available"
msgstr "The plugin for rendering this item is not available"

msgid "Install the {{appName}} app from the App Hub"
msgstr "Install the {{appName}} app from the App Hub"

msgid "The plugin for rendering this item is not available"
msgstr "The plugin for rendering this item is not available"

msgid "Install the {{appName}} app from the App Hub"
msgstr "Install the {{appName}} app from the App Hub"

msgid "No data to display"
msgstr "No data to display"

msgid "Filters are not applied to line list dashboard items."
msgstr "Filters are not applied to line list dashboard items."

msgid "Show without filters"
msgstr "Show without filters"

msgid "Unable to load the plugin for this item"
msgstr "Unable to load the plugin for this item"

msgid "There was an error loading data for this item"
msgstr "There was an error loading data for this item"

Expand Down Expand Up @@ -131,6 +155,9 @@ msgstr "Event reports"
msgid "Event charts"
msgstr "Event charts"

msgid "Line lists"
msgstr "Line lists"

msgid "Apps"
msgstr "Apps"

Expand Down
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
"@dhis2/app-runtime": "^3.7.0",
"@dhis2/app-runtime-adapter-d2": "^1.1.0",
"@dhis2/d2-i18n": "^1.1.1",
"@dhis2/d2-ui-core": "^7.3.3",
"@dhis2/d2-ui-interpretations": "^7.4.0",
"@dhis2/d2-ui-mentions-wrapper": "^7.3.3",
"@dhis2/d2-ui-rich-text": "^7.3.3",
"@dhis2/d2-ui-core": "^7.4.1",
"@dhis2/d2-ui-interpretations": "^7.4.1",
"@dhis2/d2-ui-mentions-wrapper": "^7.4.1",
"@dhis2/d2-ui-rich-text": "^7.4.1",
"@dhis2/data-visualizer-plugin": "^39.2.10",
"@dhis2/ui": "^8.11.2",
"@krakenjs/post-robot": "^11.0.0",
"classnames": "^2.3.2",
"d2": "^31.10.0",
"d2-utilizr": "^0.2.16",
Expand All @@ -33,6 +34,7 @@
"styled-jsx": "^4.0.1"
},
"scripts": {
"deduplicate": "d2-app-scripts deduplicate",
"start": "d2-app-scripts start",
"coverage": "npm test -- --coverage",
"lint": "d2-style check",
Expand Down
1 change: 1 addition & 0 deletions src/AppWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const d2Config = {
'report',
'eventChart',
'eventReport',
'eventVisualization',
'dashboard',
'organisationUnit',
'userGroup',
Expand Down
3 changes: 3 additions & 0 deletions src/api/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ export const getFavoritesFields = () => [
`map[${getFavoriteFields({ withDimensions: false }).join(',')}]`,
`eventReport[${getFavoriteFields({ withDimensions: false }).join(',')}]`,
`eventChart[${getFavoriteFields({ withDimensions: false }).join(',')}]`,
`eventVisualization[${getFavoriteFields({ withDimensions: false }).join(
','
)}]`,
]

// List item
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ exports[`renders a valid App item in view mode 1`] = `
>
Scorecard
</p>
<div
class="itemHeaderRightWrap"
/>
</div>
<div
class="ui-Divider"
Expand All @@ -33,11 +36,15 @@ exports[`renders a valid App item with filter in edit mode 1`] = `
Scorecard
</p>
<div
class="itemActionsWrap"
class="itemHeaderRightWrap"
>
<div
class="DeleteItemButton"
/>
class="itemActionsWrap"
>
<div
class="DeleteItemButton"
/>
</div>
</div>
</div>
<div
Expand All @@ -61,6 +68,9 @@ exports[`renders a valid App item with filter in view mode 1`] = `
>
Scorecard
</p>
<div
class="itemHeaderRightWrap"
/>
</div>
<div
class="ui-Divider"
Expand All @@ -84,11 +94,15 @@ exports[`renders a valid App item with title in edit mode irrespective of app se
No Title
</p>
<div
class="itemActionsWrap"
class="itemHeaderRightWrap"
>
<div
class="DeleteItemButton"
/>
class="itemActionsWrap"
>
<div
class="DeleteItemButton"
/>
</div>
</div>
</div>
<div
Expand Down Expand Up @@ -122,6 +136,9 @@ exports[`renders an invalid App item 1`] = `
>
unknownApp app not found
</p>
<div
class="itemHeaderRightWrap"
/>
</div>
<div
class="ui-Divider"
Expand Down
7 changes: 6 additions & 1 deletion src/components/Item/Item.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useD2 } from '@dhis2/app-runtime-adapter-d2'
import PropTypes from 'prop-types'
import React from 'react'
import {
Expand All @@ -8,6 +9,7 @@ import {
MAP,
EVENT_CHART,
EVENT_REPORT,
EVENT_VISUALIZATION,
MESSAGES,
REPORTS,
RESOURCES,
Expand Down Expand Up @@ -35,6 +37,7 @@ const getGridItem = (type) => {
case MAP:
case EVENT_CHART:
case EVENT_REPORT:
case EVENT_VISUALIZATION:
return VisualizationItem
case MESSAGES:
return MessagesItem
Expand All @@ -58,9 +61,11 @@ const getGridItem = (type) => {
}

export const Item = (props) => {
const { d2 } = useD2()

const GridItem = getGridItem(props.item.type)

return <GridItem {...props} />
return <GridItem d2={d2} {...props} />
}

Item.propTypes = {
Expand Down
9 changes: 7 additions & 2 deletions src/components/Item/ItemHeader/ItemHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import EditItemActions from './EditItemActions.js'
import PrintItemInfo from './PrintItemInfo.js'
import classes from './styles/ItemHeader.module.css'
import ViewItemActions from './ViewItemActions.js'
import ViewItemTags from './ViewItemTags.js'

const getItemActionsMap = (isShortened) => {
return {
Expand All @@ -16,12 +17,15 @@ const getItemActionsMap = (isShortened) => {
}

const ItemHeader = React.forwardRef(
({ dashboardMode, title, isShortened, ...rest }, ref) => {
({ dashboardMode, title, isShortened, tags, ...rest }, ref) => {
const Actions = getItemActionsMap(isShortened)[dashboardMode]
return (
<div className={classes.itemHeaderWrap} ref={ref}>
<p className={classes.itemTitle}>{title}</p>
{Actions ? <Actions {...rest} /> : null}
<div className={classes.itemHeaderRightWrap}>
{tags ? <ViewItemTags tags={tags} /> : null}
{Actions ? <Actions {...rest} /> : null}
</div>
</div>
)
}
Expand All @@ -32,6 +36,7 @@ ItemHeader.displayName = 'ItemHeader'
ItemHeader.propTypes = {
dashboardMode: PropTypes.string,
isShortened: PropTypes.bool,
tags: PropTypes.node,
title: PropTypes.string,
}

Expand Down
12 changes: 12 additions & 0 deletions src/components/Item/ItemHeader/ViewItemTags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import PropTypes from 'prop-types'
import React from 'react'
import classes from './styles/ItemHeader.module.css'

const ViewItemTags = ({ tags }) =>
tags ? <div className={classes.itemTagsWrap}>{tags}</div> : null

ViewItemTags.propTypes = {
tags: PropTypes.node,
}

export default ViewItemTags
7 changes: 5 additions & 2 deletions src/components/Item/ItemHeader/styles/ItemHeader.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
align-self: center;
}

.itemActionsWrap {
margin-left: auto;
.itemHeaderRightWrap {
display: flex;
flex-shrink: 0;
align-items: center;
margin-left: auto;
}

.itemActionsWrap button {
margin-left: var(--spacers-dp8);
}
Loading

0 comments on commit 7f3eb17

Please sign in to comment.