Skip to content

Commit

Permalink
fix: decrease dashboard request response load size (#1596)
Browse files Browse the repository at this point in the history
Request load improvements:
* Limit the request that fetches all dashboards (for the dashboard bar) to only getting id, displayName, favorite~rename(starred). This reduces the response size from 3.9kb to 1.1kb on the SL database. Feels like a drop in the bucket, but that will have a bigger impact on instances with a lot of dashboards
* Create separate requests getting a single dashboard for viewing and editing. In view, there are several fields that aren't used. In edit, we need all the fields if we are going to PUT changes.

Refactor:
* move getCustomDashboards to own module file
* split up api requests for dashboards into separate files
  • Loading branch information
jenniferarnesen authored Mar 4, 2021
1 parent 827f643 commit 9ac201f
Show file tree
Hide file tree
Showing 16 changed files with 172 additions and 182 deletions.
11 changes: 6 additions & 5 deletions src/actions/dashboards.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@ import {
SET_DASHBOARD_STARRED,
SET_DASHBOARD_DISPLAY_NAME,
SET_DASHBOARD_ITEMS,
getCustomDashboards,
sGetDashboardById,
sGetDashboardsSortedByStarred,
} from '../reducers/dashboards'
import { NON_EXISTING_DASHBOARD_ID } from '../reducers/selected'
import { sGetUserUsername } from '../reducers/user'
import { tSetSelectedDashboardById, acSetSelectedId } from './selected'
import { apiFetchDashboards, apiDeleteDashboard } from '../api/dashboards'
import { apiFetchDashboards } from '../api/fetchAllDashboards'
import { apiDeleteDashboard } from '../api/deleteDashboard'
import { getPreferredDashboardId } from '../api/localStorage'
import { arrayToIdMap } from '../modules/util'
import { getCustomDashboards } from '../modules/getCustomDashboards'

// actions

export const acSetDashboards = dashboards => ({
type: SET_DASHBOARDS,
value: arrayToIdMap(getCustomDashboards(dashboards)),
value: arrayToIdMap(dashboards),
})

export const acAppendDashboards = dashboards => ({
Expand Down Expand Up @@ -55,7 +56,7 @@ export const tFetchDashboards = () => async (
dispatch(acSetDashboards(dashboards))
}

export const tSelectDashboard = id => async (dispatch, getState) => {
export const tSelectDashboard = (id, mode) => async (dispatch, getState) => {
try {
const state = getState()

Expand All @@ -72,7 +73,7 @@ export const tSelectDashboard = id => async (dispatch, getState) => {
}

if (dashboardToSelect) {
dispatch(tSetSelectedDashboardById(dashboardToSelect.id))
dispatch(tSetSelectedDashboardById(dashboardToSelect.id, mode))
} else {
dispatch(acSetSelectedId(NON_EXISTING_DASHBOARD_ID))
}
Expand Down
9 changes: 5 additions & 4 deletions src/actions/selected.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import i18n from '@dhis2/d2-i18n'
import { getCustomDashboards, sGetDashboardById } from '../reducers/dashboards'
import { sGetDashboardById } from '../reducers/dashboards'
import {
SET_SELECTED_ID,
SET_SELECTED_ISLOADING,
Expand All @@ -16,12 +16,13 @@ import { acClearItemFilters } from './itemFilters'
import { tGetMessages } from '../components/Item/MessagesItem/actions'
import { acSetAlertMessage, acClearAlertMessage } from './alert'
import { acAddVisualization, acClearVisualizations } from './visualizations'
import { apiFetchDashboard } from '../api/dashboards'
import { apiFetchDashboard } from '../api/fetchDashboard'
import { storePreferredDashboardId } from '../api/localStorage'
import { apiGetShowDescription } from '../api/description'

import { withShape } from '../modules/gridUtil'
import { getVisualizationFromItem } from '../modules/item'
import { getCustomDashboards } from '../modules/getCustomDashboards'

import {
REPORT_TABLE,
Expand Down Expand Up @@ -64,7 +65,7 @@ export const acClearSelectedItemActiveTypes = () => ({
})

// thunks
export const tSetSelectedDashboardById = id => async (
export const tSetSelectedDashboardById = (id, mode) => async (
dispatch,
getState,
dataEngine
Expand Down Expand Up @@ -127,7 +128,7 @@ export const tSetSelectedDashboardById = id => async (
}

try {
const dashboard = await apiFetchDashboard(dataEngine, id)
const dashboard = await apiFetchDashboard(dataEngine, id, mode)

return onSuccess(dashboard)
} catch (err) {
Expand Down
68 changes: 0 additions & 68 deletions src/api/dashboards.js

This file was deleted.

13 changes: 13 additions & 0 deletions src/api/deleteDashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const deleteDashboardMutation = {
type: 'delete',
resource: 'dashboards',
id: ({ id }) => id,
}

export const apiDeleteDashboard = async (dataEngine, id) => {
try {
await dataEngine.mutate(deleteDashboardMutation, { variables: { id } })
} catch (error) {
console.log('Error: ', error)
}
}
5 changes: 3 additions & 2 deletions src/api/editDashboard.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { apiFetchDashboard } from './dashboards'
import { apiFetchDashboard } from './fetchDashboard'
import { EDIT } from '../components/Dashboard/dashboardModes'

export const createDashboardMutation = {
resource: 'dashboards',
Expand Down Expand Up @@ -29,7 +30,7 @@ const generatePayload = (dashboard = {}, data) => {
}

export const updateDashboard = async (dataEngine, data) => {
const dashboard = await apiFetchDashboard(dataEngine, data.id)
const dashboard = await apiFetchDashboard(dataEngine, data.id, EDIT)

const { response } = await dataEngine.mutate(updateDashboardMutation, {
variables: {
Expand Down
19 changes: 19 additions & 0 deletions src/api/fetchAllDashboards.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const dashboardsQuery = {
resource: 'dashboards',
params: {
fields: ['id', 'displayName', 'favorite~rename(starred)'],
paging: false,
},
}

export const apiFetchDashboards = async dataEngine => {
try {
const dashboardsData = await dataEngine.query({
dashboards: dashboardsQuery,
})

return dashboardsData.dashboards.dashboards
} catch (error) {
console.log('Error: ', error)
}
}
77 changes: 77 additions & 0 deletions src/api/fetchDashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import arrayClean from 'd2-utilizr/lib/arrayClean'
import {
getIdNameFields,
getListItemFields,
getFavoritesFields,
} from './metadata'
import { isViewMode } from '../components/Dashboard/dashboardModes'

const getDashboardItemsFields = () =>
arrayClean([
'id',
'type',
'shape',
'x',
'y',
'width~rename(w)',
'height~rename(h)',
'messages',
'text',
'appKey',
`${getListItemFields().join(',')}`,
`${getFavoritesFields().join(',')}`,
])

const baseDashboardFields = arrayClean([
'id',
'displayName',
'displayDescription',
'favorite~rename(starred)',
'access',
'restrictFilters',
'allowedFilters',
`dashboardItems[${getDashboardItemsFields().join(',')}]`,
])

export const viewDashboardQuery = {
resource: 'dashboards',
id: ({ id }) => id,
params: {
fields: baseDashboardFields,
},
}

export const editDashboardQuery = {
resource: 'dashboards',
id: ({ id }) => id,
params: {
fields: arrayClean([
...baseDashboardFields,
`user[${getIdNameFields({ rename: true }).join(',')}]`,
'name',
'description',
'created',
'lastUpdated',
'href', // needed for d2-ui-translations-dialog
]),
},
}

// Get more info about selected dashboard
export const apiFetchDashboard = async (dataEngine, id, mode) => {
const query = isViewMode(mode) ? viewDashboardQuery : editDashboardQuery
try {
const dashboardData = await dataEngine.query(
{ dashboard: query },
{
variables: {
id,
},
}
)

return dashboardData.dashboard
} catch (error) {
console.log('Error: ', error)
}
}
52 changes: 0 additions & 52 deletions src/api/index.js

This file was deleted.

14 changes: 8 additions & 6 deletions src/api/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,14 @@ export const getFavoriteFields = ({ withDimensions, withOptions }) => {
])
}

export const getFavoritesFields = ({ withDimensions }) => [
`reportTable[${getFavoriteFields({ withDimensions }).join(',')}]`,
`chart[${['type', ...getFavoriteFields({ withDimensions })].join(',')}]`,
`map[${getFavoriteFields({ withDimensions }).join(',')}]`,
`eventReport[${getFavoriteFields({ withDimensions }).join(',')}]`,
`eventChart[${getFavoriteFields({ withDimensions }).join(',')}]`,
export const getFavoritesFields = () => [
`reportTable[${getFavoriteFields({ withDimensions: false }).join(',')}]`,
`chart[${['type', ...getFavoriteFields({ withDimensions: false })].join(
','
)}]`,
`map[${getFavoriteFields({ withDimensions: false }).join(',')}]`,
`eventReport[${getFavoriteFields({ withDimensions: false }).join(',')}]`,
`eventChart[${getFavoriteFields({ withDimensions: false }).join(',')}]`,
]

// List item
Expand Down
11 changes: 7 additions & 4 deletions src/components/ControlBar/EditBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import {
sGetIsNewDashboard,
sGetIsPrintPreviewView,
} from '../../reducers/editDashboard'
import { apiFetchDashboard } from '../../api/dashboards'
import { apiFetchDashboard } from '../../api/fetchDashboard'
import { EDIT } from '../Dashboard/dashboardModes'

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

Expand All @@ -53,9 +54,11 @@ const EditBar = props => {

useEffect(() => {
if (props.dashboardId && !dashboard) {
apiFetchDashboard(dataEngine, props.dashboardId).then(dboard =>
setDashboard(dboard)
)
apiFetchDashboard(
dataEngine,
props.dashboardId,
EDIT
).then(dboard => setDashboard(dboard))
}
}, [props.dashboardId, dashboard])

Expand Down
4 changes: 2 additions & 2 deletions src/components/ControlBar/__tests__/EditBar.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import { useDataEngine } from '@dhis2/app-runtime'
import { Router } from 'react-router-dom'
import { createMemoryHistory } from 'history'
import EditBar from '../EditBar'
import { apiFetchDashboard } from '../../../api/dashboards'
import { apiFetchDashboard } from '../../../api/fetchDashboard'
import { acClearEditDashboard } from '../../../actions/editDashboard'

const mockStore = configureMockStore()

jest.mock('@dhis2/app-runtime-adapter-d2')
jest.mock('@dhis2/app-runtime')
jest.mock('../../../api/dashboards')
jest.mock('../../../api/fetchDashboard')

jest.mock(
'@dhis2/d2-ui-translation-dialog',
Expand Down
Loading

0 comments on commit 9ac201f

Please sign in to comment.