Skip to content

Commit

Permalink
fix: only request dimensions when needed (#1654)
Browse files Browse the repository at this point in the history
This fix decreases the initial api requests being made when the dashboard first loads. There's no need to request dimensions unless they are needed for filtering the dashboard or setting filter settings while editing a dashboard.
  • Loading branch information
jenniferarnesen authored Mar 17, 2021
1 parent b31124a commit 36eec71
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 53 deletions.
28 changes: 0 additions & 28 deletions src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,14 @@ import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { CssVariables } from '@dhis2/ui'
import { useD2 } from '@dhis2/app-runtime-adapter-d2'
import { apiFetchDimensions } from '@dhis2/analytics'
import { useDataEngine } from '@dhis2/app-runtime'

import Dashboard from './Dashboard/Dashboard'
import AlertBar from './AlertBar/AlertBar'
import { useUserSettings } from './UserSettingsProvider'

import { acReceivedUser } from '../actions/user'
import { tFetchDashboards } from '../actions/dashboards'
import { tSetControlBarRows } from '../actions/controlBar'
import { tSetShowDescription } from '../actions/selected'
import { acSetDimensions } from '../actions/dimensions'
import getFilteredDimensions from '../modules/getFilteredDimensions'

import {
EDIT,
Expand All @@ -30,8 +25,6 @@ import './App.css'

const App = props => {
const { d2 } = useD2()
const dataEngine = useDataEngine()
const { userSettings } = useUserSettings()

useEffect(() => {
props.setCurrentUser(d2.currentUser)
Expand All @@ -50,25 +43,6 @@ const App = props => {
)
}, [])

useEffect(() => {
const fetchDimensions = async () => {
try {
const dimensions = await apiFetchDimensions(
dataEngine,
userSettings.keyAnalysisDisplayProperty
)

props.setDimensions(getFilteredDimensions(dimensions))
} catch (e) {
console.error(e)
}
}

if (userSettings.keyAnalysisDisplayProperty) {
fetchDimensions()
}
}, [userSettings])

return (
<>
<CssVariables colors spacers />
Expand Down Expand Up @@ -117,15 +91,13 @@ App.propTypes = {
fetchDashboards: PropTypes.func.isRequired,
setControlBarRows: PropTypes.func.isRequired,
setCurrentUser: PropTypes.func.isRequired,
setDimensions: PropTypes.func.isRequired,
setShowDescription: PropTypes.func.isRequired,
}

const mapDispatchToProps = {
fetchDashboards: tFetchDashboards,
setControlBarRows: tSetControlBarRows,
setCurrentUser: acReceivedUser,
setDimensions: acSetDimensions,
setShowDescription: tSetShowDescription,
}

Expand Down
4 changes: 0 additions & 4 deletions src/components/ControlBar/EditBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
} from '../../actions/editDashboard'
import { acClearPrintDashboard } from '../../actions/printDashboard'
import { tDeleteDashboard } from '../../actions/dashboards'
import { sGetDimensions } from '../../reducers/dimensions'
import {
sGetEditDashboardRoot,
sGetIsNewDashboard,
Expand Down Expand Up @@ -152,7 +151,6 @@ const EditBar = props => {
const filterSettingsDialog = () =>
dashboard || props.newDashboard ? (
<FilterSettingsDialog
dimensions={props.dimensions}
restrictFilters={props.restrictFilters}
initiallySelectedItems={props.allowedFilters}
onClose={toggleFilterSettingsDialog}
Expand Down Expand Up @@ -222,7 +220,6 @@ EditBar.propTypes = {
dashboardId: PropTypes.string,
dashboardName: PropTypes.string,
deleteAccess: PropTypes.bool,
dimensions: PropTypes.array,
isPrintPreviewView: PropTypes.bool,
newDashboard: PropTypes.bool,
restrictFilters: PropTypes.bool,
Expand Down Expand Up @@ -254,7 +251,6 @@ const mapStateToProps = state => {
dashboardId: dashboard.id,
dashboardName: dashboard.name,
deleteAccess,
dimensions: sGetDimensions(state),
newDashboard,
restrictFilters: dashboard.restrictFilters,
isPrintPreviewView: sGetIsPrintPreviewView(state),
Expand Down
8 changes: 8 additions & 0 deletions src/components/ControlBar/__tests__/EditBar.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ jest.mock('@dhis2/app-runtime-adapter-d2')
jest.mock('@dhis2/app-runtime')
jest.mock('../../../api/fetchDashboard')

jest.mock(
'../../ItemFilter/FilterSettingsDialog',
() =>
function MockFilterSettingsDialog() {
return <div className="mock-filter-settings-dialog" />
}
)

jest.mock(
'@dhis2/d2-ui-translation-dialog',
() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ exports[`renders Save and Discard buttons but no dialogs when no dashboard id 1`
</button>
</div>
</div>
<div
class="mock-filter-settings-dialog"
/>
</div>
`;

Expand Down
15 changes: 6 additions & 9 deletions src/components/ItemFilter/FilterSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,24 @@ import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown'
import isEmpty from 'lodash/isEmpty'

import i18n from '@dhis2/d2-i18n'
import { DimensionsPanel } from '@dhis2/analytics'

import { Button, Popover } from '@dhis2/ui'
import FilterDialog from './FilterDialog'

import { sGetActiveModalDimension } from '../../reducers/activeModalDimension'
import { sGetDimensions } from '../../reducers/dimensions'
import { sGetItemFiltersRoot } from '../../reducers/itemFilters'
import {
acClearActiveModalDimension,
acSetActiveModalDimension,
} from '../../actions/activeModalDimension'
import useDimensions from '../../modules/useDimensions'

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

const FilterSelector = props => {
const [showPopover, setShowPopover] = useState(false)
const dimensions = useDimensions(showPopover)

const ref = useRef(null)

Expand All @@ -33,21 +32,21 @@ const FilterSelector = props => {

const selectDimension = id => {
props.setActiveModalDimension(
props.dimensions.find(dimension => dimension.id === id)
dimensions.find(dimension => dimension.id === id)
)
}

const filterDimensions = () => {
if (!props.restrictFilters) {
return props.dimensions
return dimensions
} else {
return props.dimensions.filter(d =>
return dimensions.filter(d =>
[...props.allowedFilters].includes(d.id)
)
}
}

return isEmpty(filterDimensions()) ? null : (
return props.restrictFilters && !props.allowedFilters ? null : (
<>
<span className={classes.buttonContainer} ref={ref}>
<Button onClick={() => setShowPopover(true)}>
Expand Down Expand Up @@ -87,15 +86,13 @@ const FilterSelector = props => {

const mapStateToProps = state => ({
dimension: sGetActiveModalDimension(state),
dimensions: sGetDimensions(state),
initiallySelectedItems: sGetItemFiltersRoot(state),
})

FilterSelector.propTypes = {
allowedFilters: PropTypes.array,
clearActiveModalDimension: PropTypes.func,
dimension: PropTypes.object,
dimensions: PropTypes.array,
initiallySelectedItems: PropTypes.object,
restrictFilters: PropTypes.bool,
setActiveModalDimension: PropTypes.func,
Expand Down
4 changes: 2 additions & 2 deletions src/components/ItemFilter/FilterSettingsDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
Radio,
Transfer,
} from '@dhis2/ui'
import useDimensions from '../../modules/useDimensions'

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

Expand Down Expand Up @@ -57,7 +58,6 @@ RadioOptions.propTypes = {
}

const FilterSettingsDialog = ({
dimensions,
restrictFilters,
initiallySelectedItems,
onClose,
Expand All @@ -66,6 +66,7 @@ const FilterSettingsDialog = ({
}) => {
const [selected, setSelected] = useState(initiallySelectedItems)
const [filtersSelectable, setFiltersSelectable] = useState(restrictFilters)
const dimensions = useDimensions(open)

const updateFilterDimensionRestrictability = val => {
if (val) {
Expand Down Expand Up @@ -186,7 +187,6 @@ const FilterSettingsDialog = ({
}

FilterSettingsDialog.propTypes = {
dimensions: PropTypes.array,
initiallySelectedItems: PropTypes.array,
open: PropTypes.bool,
restrictFilters: PropTypes.bool,
Expand Down
18 changes: 11 additions & 7 deletions src/components/ItemFilter/__tests__/FilterSettingsDialog.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@ import { shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import FilterSettingsDialog from '../FilterSettingsDialog'

const mockDimensions = [
{ id: 'kl', name: 'kvikk lunsj' },
{ id: 'ss', name: 'salt sild' },
{ id: 'sm', name: 'seigmenn' },
]
jest.mock('../../../modules/useDimensions', () => ({
__esModule: true,
default: () => {
return [
{ id: 'kl', name: 'kvikk lunsj' },
{ id: 'ss', name: 'salt sild' },
{ id: 'sm', name: 'seigmenn' },
]
},
}))

const mockSelectedItems = ['kl']

it('renders correctly when filters are not restricted', () => {
const container = shallow(
<FilterSettingsDialog
dimensions={mockDimensions}
restrictFilters={false}
initiallySelectedItems={[]}
open={true}
Expand All @@ -25,7 +30,6 @@ it('renders correctly when filters are not restricted', () => {
it('renders correctly when filters are restricted', () => {
const container = shallow(
<FilterSettingsDialog
dimensions={mockDimensions}
restrictFilters={true}
initiallySelectedItems={mockSelectedItems}
open={true}
Expand Down
44 changes: 44 additions & 0 deletions src/modules/useDimensions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { acSetDimensions } from '../actions/dimensions'
import { apiFetchDimensions } from '@dhis2/analytics'
import { useDataEngine } from '@dhis2/app-runtime'

import getFilteredDimensions from './getFilteredDimensions'
import { useUserSettings } from '../components/UserSettingsProvider'

const useDimensions = doFetch => {
const dataEngine = useDataEngine()
const { userSettings } = useUserSettings()
const dimensions = useSelector(state => state.dimensions)
const dispatch = useDispatch()

useEffect(() => {
const fetchDimensions = async () => {
try {
const unfilteredDimensions = await apiFetchDimensions(
dataEngine,
userSettings.keyAnalysisDisplayProperty
)

dispatch(
acSetDimensions(getFilteredDimensions(unfilteredDimensions))
)
} catch (e) {
console.error(e)
}
}

if (
!dimensions.length &&
doFetch &&
userSettings.keyAnalysisDisplayProperty
) {
fetchDimensions()
}
}, [dimensions, doFetch, userSettings.keyAnalysisDisplayProperty])

return dimensions
}

export default useDimensions
8 changes: 5 additions & 3 deletions src/reducers/dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import {
} from '@dhis2/analytics'

export const SET_DIMENSIONS = 'SET_DIMENSIONS'
export const DEFAULT_DIMENSIONS = [
const PE_OU_DIMENSIONS = [
getDimensionById(DIMENSION_ID_PERIOD),
getDimensionById(DIMENSION_ID_ORGUNIT),
]

export default (state = DEFAULT_DIMENSIONS, action) => {
const INITIAL_DIMENSIONS = []

export default (state = INITIAL_DIMENSIONS, action) => {
switch (action.type) {
case SET_DIMENSIONS: {
return [...DEFAULT_DIMENSIONS, ...action.value]
return [...PE_OU_DIMENSIONS, ...action.value]
}
default:
return state
Expand Down

0 comments on commit 36eec71

Please sign in to comment.