Skip to content

Commit

Permalink
fix: display message on unloaded items when offline and not cached
Browse files Browse the repository at this point in the history
  • Loading branch information
jenniferarnesen committed Dec 11, 2024
1 parent 347e520 commit df0fda2
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 14 deletions.
5 changes: 3 additions & 2 deletions src/components/Item/ItemHeader/ItemHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ const getItemActionsMap = (isShortened) => {
}

const ItemHeader = React.forwardRef(
({ dashboardMode, title, isShortened, tags, ...rest }, ref) => {
({ dashboardMode, title, isShortened, style, tags, ...rest }, ref) => {
const Actions = getItemActionsMap(isShortened)[dashboardMode]
return (
<div className={classes.itemHeaderWrap} ref={ref}>
<div className={classes.itemHeaderWrap} ref={ref} style={style}>
<p className={classes.itemTitle}>{title}</p>
<div className={classes.itemHeaderRightWrap}>
{tags ? <ViewItemTags tags={tags} /> : null}
Expand All @@ -36,6 +36,7 @@ ItemHeader.displayName = 'ItemHeader'
ItemHeader.propTypes = {
dashboardMode: PropTypes.string,
isShortened: PropTypes.bool,
style: PropTypes.object,
tags: PropTypes.node,
title: PropTypes.string,
}
Expand Down
101 changes: 93 additions & 8 deletions src/components/ProgressiveLoadingContainer.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,69 @@
import i18n from '@dhis2/d2-i18n'
import { Divider, spacers, CenteredContent } from '@dhis2/ui'
import debounce from 'lodash/debounce.js'
import pick from 'lodash/pick.js'
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { getVisualizationName } from '../modules/item.js'
import {
APP,
MESSAGES,
RESOURCES,
REPORTS,
isVisualizationType,
} from '../modules/itemTypes.js'
import ItemHeader from './Item/ItemHeader/ItemHeader.js'

const defaultDebounceMs = 100
const defaultBufferFactor = 0.25
const observerConfig = { attributes: true, childList: false, subtree: false }

const getItemHeader = ({ item, apps }) => {
if (isVisualizationType(item)) {
const title = getVisualizationName(item)
return <ItemHeader title={title} style={{ minHeight: '31px' }} />
}

let title
if ([MESSAGES, RESOURCES, REPORTS].includes(item.type)) {
const titleMap = {
[MESSAGES]: i18n.t('Messages'),
[RESOURCES]: i18n.t('Resources'),
[REPORTS]: i18n.t('Reports'),
}
title = titleMap[item.type]
} else if (item.type === APP) {
let appDetails
const appKey = item.appKey

if (appKey) {
appDetails = apps.find((app) => app.key === appKey)
}

const hideTitle = appDetails?.settings?.dashboardWidget?.hideTitle
title = hideTitle ? null : appDetails.name
}

return !title ? null : (
<>
<ItemHeader title={title} />
<Divider margin={`0 0 ${spacers.dp4} 0`} />
</>
)
}

class ProgressiveLoadingContainer extends Component {
static propTypes = {
children: PropTypes.node.isRequired,
item: PropTypes.object.isRequired,
apps: PropTypes.array,
bufferFactor: PropTypes.number,
className: PropTypes.string,
dashboardIsCached: PropTypes.bool,
debounceMs: PropTypes.number,
forceLoad: PropTypes.bool,
fullsreenView: PropTypes.bool,
itemId: PropTypes.string,
isOffline: PropTypes.bool,
style: PropTypes.object,
}
static defaultProps = {
Expand All @@ -32,6 +80,7 @@ class ProgressiveLoadingContainer extends Component {
debouncedCheckShouldLoad = null
handlerOptions = { passive: true }
observer = null
isObserving = null

checkShouldLoad() {
if (!this.containerRef) {
Expand All @@ -41,7 +90,9 @@ class ProgressiveLoadingContainer extends Component {
// force load item regardless of its position
if (this.forceLoad && !this.state.shouldLoad) {
this.setState({ shouldLoad: true })
this.removeHandler()
if (!this.props.isOffline || this.props.dashboardIsCached) {
this.removeHandler()
}
return
}

Expand All @@ -60,7 +111,9 @@ class ProgressiveLoadingContainer extends Component {
rect.top < window.innerHeight + bufferPx
) {
this.setState({ shouldLoad: true })
this.removeHandler()
if (!this.props.isOffline || this.props.dashboardIsCached) {
this.removeHandler()
}
}
}

Expand Down Expand Up @@ -92,6 +145,7 @@ class ProgressiveLoadingContainer extends Component {

this.observer = new MutationObserver(mutationCallback)
this.observer.observe(this.containerRef, observerConfig)
this.isObserving = true
}

removeHandler() {
Expand All @@ -106,6 +160,7 @@ class ProgressiveLoadingContainer extends Component {
})

this.observer.disconnect()
this.isObserving = false
}

componentDidMount() {
Expand All @@ -124,9 +179,16 @@ class ProgressiveLoadingContainer extends Component {
}

render() {
const { children, className, style, ...props } = this.props

const shouldLoad = this.state.shouldLoad || props.forceLoad
const {
children,
className,
style,
apps,
item,
dashboardIsCached,
isOffline,
...props
} = this.props

const eventProps = pick(props, [
'onMouseDown',
Expand All @@ -135,15 +197,38 @@ class ProgressiveLoadingContainer extends Component {
'onTouchEnd',
])

const renderContent = this.state.shouldLoad || props.forceLoad

const getContent = () => {
if (isOffline && !dashboardIsCached && this.isObserving !== false) {
return !renderContent ? null : (
<div
style={{
display: 'flex',
flexDirection: 'column',
height: '100%',
}}
>
{getItemHeader({ item, apps })}
<CenteredContent>
<div>{i18n.t('Not available offline')}</div>
</CenteredContent>
</div>
)
} else {
return renderContent && children
}
}

return (
<div
ref={(ref) => (this.containerRef = ref)}
style={style}
className={className}
data-test={`dashboarditem-${props.itemId}`}
data-test={`dashboarditem-${item.id}`}
{...eventProps}
>
{shouldLoad && children}
{getContent()}
</div>
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/edit/ItemGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const EditItemGrid = ({
'edit',
getGridItemDomElementClassName(item.id)
)}
itemId={item.id}
item={item}
>
<Item
item={item}
Expand Down
16 changes: 14 additions & 2 deletions src/pages/view/ItemGrid.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { useCachedDataQuery } from '@dhis2/analytics'
import { useDhis2ConnectionStatus } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import cx from 'classnames'
import PropTypes from 'prop-types'
import React, { useState, useEffect, useRef } from 'react'
import { Responsive as ResponsiveReactGridLayout } from 'react-grid-layout'
import { useSelector } from 'react-redux'
Expand Down Expand Up @@ -35,16 +38,18 @@ import useSlideshow from './useSlideshow.js'
const EXPANDED_HEIGHT = 19
const EXPANDED_HEIGHT_SM = 15

const ResponsiveItemGrid = () => {
const ResponsiveItemGrid = ({ dashboardIsCached }) => {
const dashboardId = useSelector(sGetSelectedId)
const dashboardItems = useSelector(sGetSelectedDashboardItems)
const { width } = useWindowDimensions()
const { apps } = useCachedDataQuery()
const [expandedItems, setExpandedItems] = useState({})
const [displayItems, setDisplayItems] = useState(dashboardItems)
const [layoutSm, setLayoutSm] = useState([])
const [gridWidth, setGridWidth] = useState(0)
const [forceLoad, setForceLoad] = useState(false)
const { recordingState } = useCacheableSection(dashboardId)
const { isDisconnected: isOffline } = useDhis2ConnectionStatus()
const firstOfTypes = getFirstOfTypes(dashboardItems)
const slideshowElementRef = useRef(null)

Expand Down Expand Up @@ -142,11 +147,14 @@ const ResponsiveItemGrid = () => {
[classes.enteringFullscreen]: isEnteringSlideshow,
}
)}
itemId={item.id}
item={item}
forceLoad={
forceLoad || itemIsFullscreen || itemIsNextPrevFullscreen
}
fullscreenView={isSlideshowView}
isOffline={isOffline}
dashboardIsCached={dashboardIsCached}
apps={apps}
>
<Item
item={item}
Expand Down Expand Up @@ -218,4 +226,8 @@ const ResponsiveItemGrid = () => {
)
}

ResponsiveItemGrid.propTypes = {
dashboardIsCached: PropTypes.bool,
}

export default ResponsiveItemGrid
2 changes: 1 addition & 1 deletion src/pages/view/ViewDashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ const ViewDashboard = (props) => {
<>
<TitleBar />
<FilterBar />
<ItemGrid />
<ItemGrid dashboardIsCached={isCached} />
</>
)
}
Expand Down

0 comments on commit df0fda2

Please sign in to comment.