Skip to content

Commit

Permalink
Merge pull request #2741 from Gizra/issue-2740
Browse files Browse the repository at this point in the history
Dashbords page - fix performance issue for large HCs
  • Loading branch information
anvmn authored Aug 27, 2021
2 parents b9aef7a + cdb89d2 commit 8191199
Show file tree
Hide file tree
Showing 18 changed files with 705 additions and 484 deletions.
3 changes: 2 additions & 1 deletion client/src/elm/App/Fetch.elm
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ fetch model =
List.map MsgIndexedDb Pages.Device.Fetch.fetch

PinCodePage ->
List.map MsgIndexedDb Pages.PinCode.Fetch.fetch
Pages.PinCode.Fetch.fetch model.healthCenterId
|> List.map MsgIndexedDb

PageNotFound _ ->
[]
Expand Down
6 changes: 1 addition & 5 deletions client/src/elm/App/Update.elm
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ update msg model =
MsgPageDashboard subPage subMsg ->
let
( subModel, subCmd, appMsgs ) =
Pages.Dashboard.Update.update subMsg subPage data.dashboardPage
Pages.Dashboard.Update.update currentDate model.healthCenterId subPage model.indexedDb subMsg data.dashboardPage
in
( { data | dashboardPage = subModel }
, Cmd.map (MsgLoggedIn << MsgPageDashboard subPage) subCmd
Expand Down Expand Up @@ -893,10 +893,6 @@ update msg model =
( modelUpdated, cmd ) =
case urlRequest of
Browser.Internal url ->
let
activePage =
activePageByUrl url
in
( model, Nav.pushUrl model.navigationKey (Url.toString url) )

-- As we use a tag in multiple places in HTML and CSS,
Expand Down
8 changes: 4 additions & 4 deletions client/src/elm/Backend/Dashboard/Decoder.elm
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ decodeCaseNutrition =

decodeNutritionValueDict : Decoder (Dict Int NutritionValue)
decodeNutritionValueDict =
dict decodeNutritionValue
dict (decodeWithFallback (NutritionValue Neutral "X") decodeNutritionValue)
|> andThen
(\dict ->
LegacyDict.toList dict
Expand All @@ -114,8 +114,8 @@ decodeNutritionValueDict =
decodeNutritionValue : Decoder NutritionValue
decodeNutritionValue =
succeed NutritionValue
|> required "class" decodeNutritionStatus
|> required "value" string
|> required "c" decodeNutritionStatus
|> required "v" string


decodeNutritionStatus : Decoder NutritionStatus
Expand Down Expand Up @@ -325,7 +325,7 @@ decodeAcuteIllnessEncounterDataItem : Decoder AcuteIllnessEncounterDataItem
decodeAcuteIllnessEncounterDataItem =
succeed AcuteIllnessEncounterDataItem
|> required "start_date" decodeYYYYMMDD
|> required "sequence_number" decodeInt
|> required "sequence_number" (decodeWithFallback 1 decodeInt)
|> required "diagnosis" decodeAcuteIllnessDiagnosis
|> required "fever" bool
|> required "isolation" (decodeEverySet (decodeWithFallback NoIsolationSigns decodeIsolationSign))
Expand Down
4 changes: 2 additions & 2 deletions client/src/elm/Backend/Dashboard/Encoder.elm
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ dictToLegacyDict dict =

encodeNutritionValue : NutritionValue -> List ( String, Value )
encodeNutritionValue value =
[ ( "class", encodeNutritionStatus value.class )
, ( "value", string value.value )
[ ( "c", encodeNutritionStatus value.class )
, ( "v", string value.value )
]


Expand Down
10 changes: 10 additions & 0 deletions client/src/elm/Backend/Dashboard/Model.elm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ type alias AssembledData =
, acuteIllnessData : List AcuteIllnessDataItem
, prenatalData : List PrenatalDataItem
, caseManagementData : Maybe FollowUpMeasurements
, nutritionPageData : NutritionPageData
}


type alias NutritionPageData =
{ caseNutritionTotalsLastYear : List CaseNutritionTotal
, caseNutritionTotalsThisYear : List CaseNutritionTotal
, totalEncounters : Periods
, newCasesGraphData : Dict Int TotalBeneficiaries
, totalsGraphData : Dict Int TotalBeneficiaries
}


Expand Down
13 changes: 12 additions & 1 deletion client/src/elm/Backend/Endpoints.elm
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,20 @@ encodeRelationshipParams params =
]


computedDashboardEndpoint : ReadOnlyEndPoint Error HealthCenterId DashboardStatsRaw ()
computedDashboardEndpoint : ReadOnlyEndPoint Error HealthCenterId DashboardStatsRaw ComputedDashboardParams
computedDashboardEndpoint =
swEndpoint "statistics" decodeDashboardStatsRaw
|> withParamsEncoder encodeComputedDashboardParams


type alias ComputedDashboardParams =
{ healthCenter : HealthCenterId
}


encodeComputedDashboardParams : ComputedDashboardParams -> List ( String, String )
encodeComputedDashboardParams params =
[ ( "healthCenter", fromEntityUuid params.healthCenter ) ]


healthCenterEndpoint : ReadOnlyEndPoint Error HealthCenterId HealthCenter ()
Expand Down
2 changes: 1 addition & 1 deletion client/src/elm/Backend/Fetch.elm
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ shouldFetch currentTime model msg =
False

else
Dict.member healthCenterId model.computedDashboard
Dict.member healthCenterId model.computedDashboards
|> not

FetchChildrenMeasurements ids ->
Expand Down
32 changes: 29 additions & 3 deletions client/src/elm/Backend/Model.elm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Backend.Model exposing (ModelIndexedDb, MsgIndexedDb(..), Revision(..), emptyModelIndexedDb)
module Backend.Model exposing (ComputedDashboard, ModelIndexedDb, MsgIndexedDb(..), Revision(..), emptyModelIndexedDb)

{-| The `Backend` hierarchy is for code that represents entities from the
backend. It is reponsible for fetching them, saving them, etc.
Expand Down Expand Up @@ -36,6 +36,7 @@ import Backend.PrenatalEncounter.Model exposing (PrenatalEncounter, PrenatalEnco
import Backend.Relationship.Model exposing (MyRelationship, Relationship)
import Backend.Session.Model exposing (EditableSession, ExpectedParticipants, OfflineSession, Session)
import Backend.Village.Model exposing (Village)
import Pages.Dashboard.Model
import RemoteData exposing (RemoteData(..), WebData)
import Time

Expand Down Expand Up @@ -134,7 +135,7 @@ type alias ModelIndexedDb =
, postHomeVisitEncounter : Dict IndividualEncounterParticipantId (WebData ( HomeVisitEncounterId, HomeVisitEncounter ))

-- Dashboard Statistics.
, computedDashboard : Dict HealthCenterId DashboardStatsRaw
, computedDashboards : Dict HealthCenterId ComputedDashboard
, computedDashboardLastFetched : Time.Posix
}

Expand Down Expand Up @@ -187,11 +188,33 @@ emptyModelIndexedDb =
, sessions = Dict.empty
, sessionsByClinic = Dict.empty
, followUpMeasurements = Dict.empty
, computedDashboard = Dict.empty
, computedDashboards = Dict.empty
, computedDashboardLastFetched = Time.millisToPosix 0
}


{-| This is the data type we store for single health center statistics.
It consist of raw statistics that we get from the backend, and a dictionary
of assembeled data permutations we may need.
We need this to avoid making heavy calculations (repeated every few seconds),
that are need to present the dashboards page.
We have different options for displaying data on page:
- Overall Statistics
- Statistics for single group type (FBF, PMTCT, ...)
- Statistics for selected village.
To support this, each permutation of assembeled data is combination of
selected program type and village (optional). This combinations serves
as key of assembled data permutations dictionary).
-}
type alias ComputedDashboard =
{ statsRaw : Backend.Dashboard.Model.DashboardStatsRaw
, assembledPermutations : Dict ( Pages.Dashboard.Model.FilterProgramType, Maybe VillageId ) Backend.Dashboard.Model.AssembledData
}


type MsgIndexedDb
= -- Messages which fetch various kinds of data.
FetchAcuteIllnessEncounter AcuteIllnessEncounterId
Expand All @@ -201,6 +224,9 @@ type MsgIndexedDb
| FetchChildrenMeasurements (List PersonId)
| FetchClinics
| FetchComputedDashboard HealthCenterId
-- Request to generate assembled daya needed to display Dashboards
-- page for selected program type and village (optional).
| FetchComputedDashboardAssembledPermutation HealthCenterId Pages.Dashboard.Model.FilterProgramType (Maybe VillageId)
-- For `FetchEditableSession`, you'll also need to send the messages
-- you get from `Backend.Session.Fetch.fetchEditableSession`
| FetchEditableSession SessionId (List MsgIndexedDb)
Expand Down
Loading

0 comments on commit 8191199

Please sign in to comment.