Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
c6cbf61
feat: show preferred or default dashboard without accessing dashboard…
jenniferarnesen Feb 18, 2025
d1bd466
feat: star and unstar a dashboard moved to selected
jenniferarnesen Feb 18, 2025
2cdaf23
chore: fetch 1 dashboard to make sure that at least one exists
jenniferarnesen Feb 18, 2025
8e2552d
feat: no longer have access to the dashboard name since not fetching …
jenniferarnesen Feb 18, 2025
ca758e0
feat: component NavigationMenu now works with filter
jenniferarnesen Feb 21, 2025
26d67a0
feat: restore no dashboards message
jenniferarnesen Feb 21, 2025
7fcc846
chore: move latest component code to existing file
jenniferarnesen Feb 21, 2025
4eccd94
Merge branch 'master' into feat/limit-dashboard-preloading-DHIS2-10624
jenniferarnesen Feb 21, 2025
d62929e
Merge branch 'feat/limit-dashboard-preloading-DHIS2-10624' of github.…
jenniferarnesen Feb 21, 2025
97c7051
chore: test changes
jenniferarnesen Feb 21, 2025
f403795
chore: test fixes
jenniferarnesen Feb 21, 2025
8aeecc3
fix: handle case where preferred id is invalid
jenniferarnesen Feb 24, 2025
879db0f
chore: reorder
jenniferarnesen Feb 26, 2025
91968df
chore: reorder more
jenniferarnesen Feb 26, 2025
6fc83c6
chore: use hooks instead of connect from react-redux
jenniferarnesen Feb 26, 2025
94c013f
fix: handle when routeId not found
jenniferarnesen Feb 26, 2025
6ccce38
chore: cleanup
jenniferarnesen Feb 26, 2025
45f161f
chore: remove code smells
jenniferarnesen Feb 26, 2025
0f93299
chore: fix code smell
jenniferarnesen Feb 26, 2025
5092eb1
fix: re set hasDashboards when filter text is removed
jenniferarnesen Feb 26, 2025
2ac1c89
Merge branch 'master' into feat/limit-dashboard-preloading-DHIS2-10624
jenniferarnesen Feb 27, 2025
98ec059
chore: remove console.log
jenniferarnesen Feb 27, 2025
1afe262
fix: state to keep track of whether there are any dashboards at all
jenniferarnesen Feb 27, 2025
d5adb45
fix: filtering and paging together now works
jenniferarnesen Feb 28, 2025
db37e29
Merge branch 'feat/limit-dashboard-preloading-DHIS2-10624' of github.…
jenniferarnesen Feb 28, 2025
358d7f2
chore: temporarily change min height of nav menu
jenniferarnesen Feb 28, 2025
8d21685
fix: avoid duplicate requests when filtering
jenniferarnesen Mar 4, 2025
9714f0b
fix: add hasDashboards prop
jenniferarnesen Mar 4, 2025
a96826c
feat: debounce filtering to 300ms
jenniferarnesen Mar 4, 2025
08d7b87
chore: consolidate filterText and page to single state var
jenniferarnesen Mar 4, 2025
898930f
Merge branch 'master' into feat/limit-dashboard-preloading-DHIS2-10624
jenniferarnesen Mar 4, 2025
9500ca4
chore: a little cleanup
jenniferarnesen Mar 4, 2025
60777d7
chore: fix tests
jenniferarnesen Mar 4, 2025
d916157
Merge branch 'feat/limit-dashboard-preloading-DHIS2-10624' of github.…
jenniferarnesen Mar 4, 2025
67b02f4
test: moving and changing cypress tests
jenniferarnesen Mar 5, 2025
a9ae078
fix: prevent temporary flash of the offline message when switching da…
jenniferarnesen Mar 5, 2025
de4e1bc
fix: reset hasDashboards to true if there are dashboards and add more…
jenniferarnesen Mar 5, 2025
50cf754
test: convert more tests related to nav menu
jenniferarnesen Mar 5, 2025
501b702
chore: lint
jenniferarnesen Mar 5, 2025
799001c
fix: restore original nav menu size
jenniferarnesen Mar 5, 2025
576b489
chore: share query object and dont bother removing preferred id
jenniferarnesen Mar 5, 2025
eefbf3f
chore: lint
jenniferarnesen Mar 5, 2025
4cb5d2d
chore: clean up
jenniferarnesen Mar 7, 2025
9db88c8
chore: small refactor of fetch dashboard code
jenniferarnesen Mar 7, 2025
e2c4e26
chore: lint
jenniferarnesen Mar 7, 2025
e80cae2
Merge branch 'master' into feat/limit-dashboard-preloading-DHIS2-10624
jenniferarnesen Mar 7, 2025
4b06fa1
fix: need to set hasDashboards
jenniferarnesen Mar 7, 2025
4a4b29c
chore: make logic more logical :P
jenniferarnesen Mar 7, 2025
3b75b25
chore: look what is in cachedSections
jenniferarnesen Mar 10, 2025
2d9393c
Merge branch 'master' into feat/limit-dashboard-preloading-DHIS2-10624
jenniferarnesen Mar 21, 2025
468ae0b
fix: dont fetch dashboards
jenniferarnesen Mar 21, 2025
a1eed8c
Merge branch 'master' into feat/limit-dashboard-preloading-DHIS2-10624
jenniferarnesen Mar 21, 2025
17617d2
Merge branch 'master' into feat/limit-dashboard-preloading-DHIS2-10624
jenniferarnesen Oct 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cypress/support/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const EXTENDED_TIMEOUT = { timeout: 25000 }
export const EXTENDED_TIMEOUT = { timeout: 15000 }

export const getApiBaseUrl = () => {
const baseUrl = Cypress.env('dhis2BaseUrl') || ''
Expand Down
6 changes: 3 additions & 3 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -679,12 +679,12 @@ msgstr "Create a new dashboard with the + button."
msgid "Your most viewed dashboards"
msgstr "Your most viewed dashboards"

msgid "No dashboards found. Use the + button to create a new dashboard."
msgstr "No dashboards found. Use the + button to create a new dashboard."

msgid "Requested dashboard not found"
msgstr "Requested dashboard not found"

msgid "No dashboards found. Use the + button to create a new dashboard."
msgstr "No dashboards found. Use the + button to create a new dashboard."

msgid "No description"
msgstr "No description"

Expand Down
33 changes: 0 additions & 33 deletions src/actions/dashboards.js

This file was deleted.

15 changes: 0 additions & 15 deletions src/actions/dashboardsFilter.js

This file was deleted.

4 changes: 0 additions & 4 deletions src/actions/editDashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
sGetItemConfigInsertPosition,
RECEIVED_CODE,
} from '../reducers/editDashboard.js'
import { tFetchDashboards } from './dashboards.js'

// actions

Expand Down Expand Up @@ -183,8 +182,5 @@ export const tSaveDashboard = () => async (dispatch, getState, dataEngine) => {
? await updateDashboard(dataEngine, dashboardToSave)
: await postDashboard(dataEngine, dashboardToSave)

// update the dashboard list
await dispatch(tFetchDashboards())

return Promise.resolve(dashboardId)
}
15 changes: 15 additions & 0 deletions src/actions/offlineDashboards.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {
SET_OFFLINE_DASHBOARDS,
STAR_OFFLINE_DASHBOARD,
} from '../reducers/offlineDashboards.js'

// Action creators
export const acSetOfflineDashboards = (dashboards) => ({
type: SET_OFFLINE_DASHBOARDS,
dashboards,
})

export const acSetOfflineDashboardStarred = (value) => ({
type: STAR_OFFLINE_DASHBOARD,
value,
})
16 changes: 6 additions & 10 deletions src/actions/selected.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { storePreferredDashboardId } from '../modules/localStorage.js'
import {
SET_SELECTED,
CLEAR_SELECTED,
SET_SELECTED_STARRED,
sGetSelectedId,
} from '../reducers/selected.js'
import { acAppendDashboards } from './dashboards.js'
import { acClearItemActiveTypes } from './itemActiveTypes.js'
import { acClearItemFilters } from './itemFilters.js'
import { acClearVisualizations } from './visualizations.js'
Expand All @@ -24,21 +24,17 @@ export const acClearSelected = () => ({
type: CLEAR_SELECTED,
})

export const acSetSelectedStarred = (isStarred) => ({
type: SET_SELECTED_STARRED,
value: isStarred,
})

// thunks
export const tSetSelectedDashboardById =
(id, username) => async (dispatch, getState, dataEngine) => {
const dashboard = await apiFetchDashboard(dataEngine, id, {
mode: VIEW,
})
dispatch(
acAppendDashboards([
{
id: dashboard.id,
displayName: dashboard.displayName,
starred: dashboard.starred,
},
])
)

if (username) {
storePreferredDashboardId(username, id)
Expand Down
35 changes: 35 additions & 0 deletions src/api/fetchDashboards.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export const firstDashboardQuery = {
dashboards: {
resource: 'dashboards',
params: {
fields: 'id,displayName',
order: 'favorite:desc,displayName:asc',
paging: true,
pageSize: 1,
},
},
}

export const requestedDashboardQuery = {
dashboard: {
resource: 'dashboards',
id: ({ id }) => id,
params: {
fields: ['id', 'displayName'],
},
},
}

export const dashboardsByIdsQuery = {
dashboards: {
resource: 'dashboards',
params: ({ ids }) => {
return {
fields: 'id,displayName,favorite~rename(starred)',
order: 'favorite:desc,displayName:asc',
filter: ids ? `id:in:[${ids.join(',')}]` : undefined,
paging: false,
}
},
},
}
22 changes: 4 additions & 18 deletions src/components/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import { Redirect, HashRouter as Router, Route, Switch } from 'react-router-dom'
import { acClearActiveModalDimension } from '../actions/activeModalDimension.js'
import { tFetchDashboards } from '../actions/dashboards.js'
import { acClearDashboardsFilter } from '../actions/dashboardsFilter.js'
import { acClearEditDashboard } from '../actions/editDashboard.js'
import { acClearItemActiveTypes } from '../actions/itemActiveTypes.js'
import { acClearItemFilters } from '../actions/itemFilters.js'
Expand All @@ -26,14 +24,13 @@ import 'react-grid-layout/css/styles.css'
import 'react-resizable/css/styles.css'
import './styles/ItemGrid.css'

const App = ({ fetchDashboards, setShowDescription, resetState }) => {
const App = ({ setShowDescription, resetState }) => {
const systemSettings = useSystemSettings()
const currentUser = useCurrentUser()

useEffect(() => {
fetchDashboards()
setShowDescription()
}, [fetchDashboards, setShowDescription])
}, [setShowDescription])

return (
systemSettings && (
Expand All @@ -48,10 +45,7 @@ const App = ({ fetchDashboards, setShowDescription, resetState }) => {
systemSettings.startModuleEnableLightweight ? (
<Redirect to={ROUTE_START_PATH} />
) : (
<ViewDashboard
{...props}
username={currentUser.username}
/>
<ViewDashboard {...props} />
)
}
/>
Expand All @@ -73,12 +67,7 @@ const App = ({ fetchDashboards, setShowDescription, resetState }) => {
<Route
exact
path="/:dashboardId"
render={(props) => (
<ViewDashboard
{...props}
username={currentUser.username}
/>
)}
render={(props) => <ViewDashboard {...props} />}
/>
<Route
exact
Expand All @@ -105,17 +94,14 @@ const App = ({ fetchDashboards, setShowDescription, resetState }) => {
}

App.propTypes = {
fetchDashboards: PropTypes.func,
resetState: PropTypes.func,
setShowDescription: PropTypes.func,
}

const mapDispatchToProps = {
fetchDashboards: tFetchDashboards,
setShowDescription: tSetShowDescription,
resetState: () => (dispatch) => {
dispatch(acSetSelected({}))
dispatch(acClearDashboardsFilter())
dispatch(acClearVisualizations())
dispatch(acClearEditDashboard())
dispatch(acClearPrintDashboard())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import {
} from '@dhis2/ui'
import PropTypes from 'prop-types'
import React, { useCallback, useState } from 'react'
import { useDispatch } from 'react-redux'
import { useHistory } from 'react-router-dom'
import { tFetchDashboards } from '../../../actions/dashboards.js'
import { parseSupersetDashboardFieldValues } from '../../../modules/parseSupersetDashboardFieldValues.js'
import { useSupersetDashboardFieldsState } from '../../../modules/useSupersetDashboardFieldsState.js'
import styles from './styles/SupersetDashboardModal.module.css'
Expand All @@ -29,7 +27,6 @@ export const CreateSupersetDashboardModal = ({
backToChooseDashboardModal,
closeModal,
}) => {
const dispatch = useDispatch()
const history = useHistory()
const [loading, setLoading] = useState(false)
const [postDashboard, { error }] = useDataMutation(postDashboardQuery, {
Expand All @@ -49,12 +46,11 @@ export const CreateSupersetDashboardModal = ({
event.preventDefault()
setLoading(true)
const { response } = await postDashboard({ values })
await dispatch(tFetchDashboards())
setLoading(false)
closeModal()
history.push(`/${response.uid}`)
},
[values, postDashboard, closeModal, dispatch, history]
[values, postDashboard, closeModal, history]
)

return (
Expand Down
56 changes: 15 additions & 41 deletions src/components/DashboardsBar/InformationBlock/InformationBlock.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { useAlert, useDataEngine } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'
import React, { useCallback } from 'react'
import { connect } from 'react-redux'
import { acSetDashboardStarred } from '../../../actions/dashboards.js'
import { useDispatch, useSelector } from 'react-redux'
import { acSetOfflineDashboardStarred } from '../../../actions/offlineDashboards.js'
import { acSetSelectedStarred } from '../../../actions/selected.js'
import { isSmallScreen } from '../../../modules/smallScreen.js'
import { sGetDashboardStarred } from '../../../reducers/dashboards.js'
import {
sGetSelected,
sGetSelectedIsEmbedded,
} from '../../../reducers/selected.js'
import { sGetSelected } from '../../../reducers/selected.js'
import { useWindowDimensions } from '../../WindowDimensionsProvider.jsx'
import ActionsBar from './ActionsBar.jsx'
import { apiStarDashboard } from './apiStarDashboard.js'
Expand All @@ -18,14 +14,12 @@ import LastUpdatedTag from './LastUpdatedTag.jsx'
import StarDashboardButton from './StarDashboardButton.jsx'
import classes from './styles/InformationBlock.module.css'

const InformationBlock = ({
id,
isEmbeddedDashboard,
displayName,
starred,
setDashboardStarred,
}) => {
const InformationBlock = () => {
const dataEngine = useDataEngine()
const dispatch = useDispatch()
const { id, displayName, starred, embedded } = useSelector(sGetSelected)
const isEmbeddedDashboard = !!embedded

const { show: showAlert } = useAlert(
({ msg }) => msg,
({ isCritical }) =>
Expand All @@ -35,15 +29,18 @@ const InformationBlock = ({
() =>
apiStarDashboard(dataEngine, id, !starred)
.then(() => {
setDashboardStarred(id, !starred)
dispatch(acSetSelectedStarred(!starred))
dispatch(
acSetOfflineDashboardStarred({ id, starred: !starred })
)
})
.catch(() => {
const msg = starred
? i18n.t('Failed to unstar the dashboard')
: i18n.t('Failed to star the dashboard')
showAlert({ msg, isCritical: false })
}),
[dataEngine, id, setDashboardStarred, showAlert, starred]
[dataEngine, id, showAlert, starred, dispatch]
)

const { width } = useWindowDimensions()
Expand Down Expand Up @@ -76,27 +73,4 @@ const InformationBlock = ({
)
}

InformationBlock.propTypes = {
displayName: PropTypes.string,
id: PropTypes.string,
isEmbeddedDashboard: PropTypes.bool,
setDashboardStarred: PropTypes.func,
starred: PropTypes.bool,
}

const mapStateToProps = (state) => {
const dashboard = sGetSelected(state)

return {
displayName: dashboard.displayName,
id: dashboard.id,
starred: dashboard.id
? sGetDashboardStarred(state, dashboard.id)
: false,
isEmbeddedDashboard: sGetSelectedIsEmbedded(state),
}
}

export default connect(mapStateToProps, {
setDashboardStarred: acSetDashboardStarred,
})(InformationBlock)
export default InformationBlock
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { IntersectionDetector } from '@dhis2-ui/intersection-detector'
import PropTypes from 'prop-types'
import React from 'react'
import styles from './styles/EndIntersectionDetector.module.css'

export const EndIntersectionDetector = ({ rootRef, onEndReached }) => {
return (
<div className={styles.container}>
<IntersectionDetector
rootRef={rootRef}
onChange={({ isIntersecting }) =>
isIntersecting && onEndReached()
}
/>
</div>
)
}

EndIntersectionDetector.propTypes = {
rootRef: PropTypes.shape({
current: PropTypes.instanceOf(HTMLElement),
}).isRequired,
onEndReached: PropTypes.func.isRequired,
}
Loading
Loading