Skip to content

Commit

Permalink
fix: use hooks to exert finer control on setting dashboard [DHIS2-950…
Browse files Browse the repository at this point in the history
…8] (#1067)

Redux actions were being executed multiple times unnecessarily because of changes in props that had nothing to do with whether the dashboard needed to be set.

Implementation is a switch to using useEffect rather than class componentDidMount and componentDidUpdate.

Additional change includes moving print constants to a single file
  • Loading branch information
jenniferarnesen authored Sep 15, 2020
1 parent a0a7365 commit 96f50f2
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 113 deletions.
2 changes: 1 addition & 1 deletion src/actions/printDashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const acAddPrintDashboardItem = item => {
const yPos = item.yPos || 0
shape = getPageBreakItemShape(yPos, item.isStatic)
} else {
shape = getPrintTitlePageItemShape()
shape = getPrintTitlePageItemShape(item.isOneItemPerPage)
}

return {
Expand Down
143 changes: 74 additions & 69 deletions src/components/Dashboard/Dashboard.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Component } from 'react'
import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import isEmpty from 'lodash/isEmpty'
Expand Down Expand Up @@ -34,6 +34,15 @@ import {
isPrintMode,
} from './dashboardModes'

const setHeaderbarVisibility = mode => {
const header = document.getElementsByTagName('header')[0]
if (isPrintMode(mode)) {
header.classList.add('hidden')
} else {
header.classList.remove('hidden')
}
}

const dashboardMap = {
[VIEW]: <ViewDashboard />,
[EDIT]: <EditDashboard />,
Expand All @@ -42,101 +51,97 @@ const dashboardMap = {
[PRINT_LAYOUT]: <PrintLayoutDashboard />,
}

export class Dashboard extends Component {
setDashboard = () => {
if (this.props.dashboardsLoaded) {
const id = this.props.match.params.dashboardId || null || null

this.props.selectDashboard(id)
export const Dashboard = ({
id,
mode,
dashboardsLoaded,
dashboardsIsEmpty,
routeId,
selectDashboard,
setWindowHeight,
}) => {
useEffect(() => {
setHeaderbarVisibility(mode)
}, [mode])

useEffect(() => {
if (dashboardsLoaded && !dashboardsIsEmpty) {
selectDashboard(routeId)
}
}, [dashboardsLoaded, dashboardsIsEmpty, routeId])

this.setHeaderbarVisibility()
useEffect(() => {
const onResize = debounce(
() => setWindowHeight(window.innerHeight),
300
)
window.addEventListener('resize', onResize)
return () => {
window.removeEventListener('resize', onResize)
}
}, [])

if (!dashboardsLoaded || id === null) {
return (
<Layer translucent>
<CenteredContent>
<CircularLoader />
</CenteredContent>
</Layer>
)
}

setHeaderbarVisibility = () => {
const header = document.getElementsByTagName('header')[0]
if (isPrintMode(this.props.mode)) {
header.classList.add('hidden')
} else {
header.classList.remove('hidden')
}
if (mode === NEW) {
return dashboardMap[mode]
}

componentDidMount() {
window.onresize = debounce(
() => this.props.setWindowHeight(window.innerHeight),
300
if (dashboardsIsEmpty) {
return (
<>
<DashboardsBar />
<DashboardVerticalOffset />
<NoContentMessage
text={i18n.t(
'No dashboards found. Use the + button to create a new dashboard.'
)}
/>
</>
)
this.setDashboard()
}

componentDidUpdate() {
this.setDashboard()
if (id === NON_EXISTING_DASHBOARD_ID) {
return (
<>
<DashboardsBar />
<DashboardVerticalOffset />
<NoContentMessage
text={i18n.t('Requested dashboard not found')}
/>
</>
)
}

render() {
const { id, mode, dashboardsLoaded, dashboardsIsEmpty } = this.props

if (!dashboardsLoaded || id === null) {
return (
<Layer translucent>
<CenteredContent>
<CircularLoader />
</CenteredContent>
</Layer>
)
}

if (mode === NEW) {
return dashboardMap[mode]
}

if (dashboardsIsEmpty) {
return (
<>
<DashboardsBar />
<DashboardVerticalOffset />
<NoContentMessage
text={i18n.t(
'No dashboards found. Use the + button to create a new dashboard.'
)}
/>
</>
)
}

if (id === NON_EXISTING_DASHBOARD_ID) {
return (
<>
<DashboardsBar />
<DashboardVerticalOffset />
<NoContentMessage
text={i18n.t('Requested dashboard not found')}
/>
</>
)
}

return dashboardMap[mode]
}
return dashboardMap[mode]
}

Dashboard.propTypes = {
dashboardsIsEmpty: PropTypes.bool,
dashboardsLoaded: PropTypes.bool,
id: PropTypes.string,
match: PropTypes.object,
match: PropTypes.object, // provided by the react-router-dom
mode: PropTypes.string,
routeId: PropTypes.string,
selectDashboard: PropTypes.func,
setWindowHeight: PropTypes.func,
}

const mapStateToProps = state => {
const mapStateToProps = (state, ownProps) => {
const dashboards = sGetAllDashboards(state)
return {
dashboardsIsEmpty: isEmpty(dashboards),
dashboardsLoaded: !sDashboardsIsFetching(state),
id: sGetSelectedId(state),
routeId: ownProps.match?.params?.dashboardId || null,
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/Dashboard/PrintActionsBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import i18n from '@dhis2/d2-i18n'
import { Button } from '@dhis2/ui'
import { Link } from 'react-router-dom'
import LessHorizontalIcon from '../../icons/LessHorizontal'
import { a4LandscapeWidthPx } from '../../modules/printUtils'
import { a4LandscapeWidthPx } from '../ItemGrid/gridUtil'

import classes from './styles/PrintActionsBar.module.css'

Expand Down
24 changes: 22 additions & 2 deletions src/components/Dashboard/PrintDashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
acSetPrintDashboard,
acAddPrintDashboardItem,
acRemovePrintDashboardItem,
acUpdatePrintDashboardItem,
} from '../../actions/printDashboard'
import { sGetSelectedId } from '../../reducers/selected'
import { sGetWindowHeight } from '../../reducers/windowHeight'
Expand All @@ -18,7 +19,11 @@ import {
sGetDashboardItems,
} from '../../reducers/dashboards'
import { PAGEBREAK, PRINT_TITLE_PAGE, SPACER } from '../../modules/itemTypes'
import { a4LandscapeWidthPx } from '../../modules/printUtils'
import {
a4LandscapeWidthPx,
MAX_ITEM_GRID_HEIGHT_OIPP,
MAX_ITEM_GRID_WIDTH_OIPP,
} from '../ItemGrid/gridUtil'
import { PRINT_ACTIONS_BAR_HEIGHT } from './PrintActionsBar'

import classes from './styles/PrintDashboard.module.css'
Expand Down Expand Up @@ -49,6 +54,16 @@ export class PrintDashboard extends Component {
}
})

// Resize the items to the full page size
this.props.items.forEach(item => {
this.props.updateDashboardItem(
Object.assign({}, item, {
w: MAX_ITEM_GRID_WIDTH_OIPP,
h: MAX_ITEM_GRID_HEIGHT_OIPP,
})
)
})

// insert page breaks into the document flow to create the "pages"
// when previewing the print
for (
Expand All @@ -63,7 +78,10 @@ export class PrintDashboard extends Component {
})
}

this.props.addDashboardItem({ type: PRINT_TITLE_PAGE })
this.props.addDashboardItem({
type: PRINT_TITLE_PAGE,
isOneItemPerPage: true,
})
}
}

Expand Down Expand Up @@ -103,6 +121,7 @@ PrintDashboard.propTypes = {
items: PropTypes.array,
removeDashboardItem: PropTypes.func,
setPrintDashboard: PropTypes.func,
updateDashboardItem: PropTypes.func,
windowHeight: PropTypes.number,
}

Expand All @@ -122,4 +141,5 @@ export default connect(mapStateToProps, {
setPrintDashboard: acSetPrintDashboard,
addDashboardItem: acAddPrintDashboardItem,
removeDashboardItem: acRemovePrintDashboardItem,
updateDashboardItem: acUpdatePrintDashboardItem,
})(PrintDashboard)
2 changes: 1 addition & 1 deletion src/components/Dashboard/PrintInfo.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import i18n from '@dhis2/d2-i18n'
import { a4LandscapeWidthPx } from '../../modules/printUtils'
import { a4LandscapeWidthPx } from '../ItemGrid/gridUtil'

import classes from './styles/PrintInfo.module.css'

Expand Down
10 changes: 5 additions & 5 deletions src/components/Dashboard/PrintLayoutDashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ import {
sGetDashboardItems,
} from '../../reducers/dashboards'
import { PAGEBREAK, PRINT_TITLE_PAGE } from '../../modules/itemTypes'
import {
a4LandscapeWidthPx,
MAX_ITEM_GRID_HEIGHT,
} from '../../modules/printUtils'
import { a4LandscapeWidthPx, MAX_ITEM_GRID_HEIGHT } from '../ItemGrid/gridUtil'
import {
getControlBarHeight,
HEADERBAR_HEIGHT,
Expand Down Expand Up @@ -106,7 +103,10 @@ export class PrintLayoutDashboard extends Component {

addPageBreaks(this.props)

this.props.addDashboardItem({ type: PRINT_TITLE_PAGE })
this.props.addDashboardItem({
type: PRINT_TITLE_PAGE,
isOneItemPerPage: false,
})
}
}

Expand Down
27 changes: 7 additions & 20 deletions src/components/ItemGrid/PrintItemGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'
import i18n from '@dhis2/d2-i18n'
import ReactGridLayout from 'react-grid-layout'
import { Layer, CenteredContent, CircularLoader } from '@dhis2/ui'
import cx from 'classnames'

import { Item } from '../Item/Item'
import NoContentMessage from '../../widgets/NoContentMessage'
Expand All @@ -21,34 +22,20 @@ import {
MARGIN,
getGridColumns,
hasShape,
a4LandscapeWidthPx,
} from './gridUtil'
import { a4LandscapeWidthPx } from '../../modules/printUtils'
import { orArray } from '../../modules/util'
import { PAGEBREAK } from '../../modules/itemTypes'

import 'react-grid-layout/css/styles.css'

import './ItemGrid.css'

export class PrintItemGrid extends Component {
getItemComponent = item => {
const itemClassNames = [item.type, 'print', 'oipp'].join(' ')

// TODO: this mutates the redux store
item.w = 56

if (item.type === PAGEBREAK) {
item.h = 3
} else {
item.h = 35
}

return (
<div key={item.i} className={itemClassNames}>
<Item item={item} dashboardMode={PRINT} />
</div>
)
}
getItemComponent = item => (
<div key={item.i} className={cx(item.type, 'print', 'oipp')}>
<Item item={item} dashboardMode={PRINT} />
</div>
)

getItemComponents = items => items.map(item => this.getItemComponent(item))

Expand Down
2 changes: 1 addition & 1 deletion src/components/ItemGrid/PrintLayoutItemGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ import {
MARGIN,
getGridColumns,
hasShape,
a4LandscapeWidthPx,
} from './gridUtil'
import {
a4LandscapeWidthPx,
getDomGridItemsSortedByYPos,
getTransformYPx,
} from '../../modules/printUtils'
Expand Down
Loading

0 comments on commit 96f50f2

Please sign in to comment.