Skip to content

Commit

Permalink
Add 717 Alerts cards in dashboards
Browse files Browse the repository at this point in the history
  • Loading branch information
anagperal committed Dec 27, 2024
1 parent c715317 commit 718631e
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 91 deletions.
158 changes: 89 additions & 69 deletions src/data/repositories/PerformanceOverviewD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -606,86 +606,106 @@ export class PerformanceOverviewD2Repository implements PerformanceOverviewRepos
.value();
}

getDashboard717Performance(): FutureData<PerformanceMetrics717[]> {
return this.datastore
.getObject<PerformanceMetrics717[]>(PERFORMANCE_717_PROGRAM_INDICATORS_DATASTORE_KEY)
.flatMap(nullable717PerformanceProgramIndicators => {
return assertOrError(
nullable717PerformanceProgramIndicators,
PERFORMANCE_717_PROGRAM_INDICATORS_DATASTORE_KEY
).flatMap(performance717ProgramIndicators => {
const dashboard717PerformanceIndicator = performance717ProgramIndicators.filter(
indicator => indicator.key === "dashboard"
getNational717Performance(): FutureData<PerformanceMetrics717[]> {
return this.getAll717PerformanceIndicators().flatMap(performance717ProgramIndicators => {
const dashboard717PerformanceIndicator = performance717ProgramIndicators.filter(
indicator => indicator.key === "national"
);
return apiToFuture(
this.api.analytics.get({
dimension: [
`dx:${dashboard717PerformanceIndicator.map(({ id }) => id).join(";")}`,
],
startDate: DEFAULT_START_DATE,
endDate: DEFAULT_END_DATE,
includeMetadataDetails: true,
})
).map(res => {
return this.mapIndicatorsTo717PerformanceMetrics(
res.rows,
dashboard717PerformanceIndicator
);
});
});
}

getAlerts717Performance(): FutureData<PerformanceMetrics717[]> {
return this.getAll717PerformanceIndicators().flatMap(performance717ProgramIndicators => {
const dashboard717PerformanceIndicator = performance717ProgramIndicators.filter(
indicator => indicator.key === "alerts"
);

return apiToFuture(
this.api.analytics.get({
dimension: [
`dx:${dashboard717PerformanceIndicator.map(({ id }) => id).join(";")}`,
],
startDate: DEFAULT_START_DATE,
endDate: DEFAULT_END_DATE,
includeMetadataDetails: true,
})
).map(res => {
return this.mapIndicatorsTo717PerformanceMetrics(
res.rows,
dashboard717PerformanceIndicator
);
});
});
}

getEvent717Performance(diseaseOutbreakEventId: Id): FutureData<PerformanceMetrics717[]> {
return this.getAll717PerformanceIndicators().flatMap(performance717ProgramIndicators => {
const eventTracker717PerformanceIndicator = performance717ProgramIndicators.filter(
indicator => indicator.key === "event"
);
return apiToFuture(
this.api.analytics.getEnrollmentsQuery({
programId: RTSL_ZEBRA_PROGRAM_ID,
dimension: [...eventTracker717PerformanceIndicator.map(({ id }) => id)],
startDate: DEFAULT_START_DATE,
endDate: DEFAULT_END_DATE,
})
).flatMap(response => {
const filteredRow = filterAnalyticsEnrollmentDataByDiseaseOutbreakEvent(
diseaseOutbreakEventId,
response.rows,
response.headers
);

if (!filteredRow)
return Future.error(
new Error("No data found for event tracker 7-1-7 performance")
);
return apiToFuture(
this.api.analytics.get({
dimension: [
`dx:${dashboard717PerformanceIndicator
.map(({ id }) => id)
.join(";")}`,
],
startDate: DEFAULT_START_DATE,
endDate: DEFAULT_END_DATE,
includeMetadataDetails: true,
})
).map(res => {
return this.mapIndicatorsTo717PerformanceMetrics(
res.rows,
dashboard717PerformanceIndicator
);
});
});

const mappedIndicatorsToRows: string[][] = eventTracker717PerformanceIndicator.map(
({ id }) => {
return [
id,
filteredRow[response.headers.findIndex(header => header.name === id)] ||
"",
];
}
);

return Future.success(
this.mapIndicatorsTo717PerformanceMetrics(
mappedIndicatorsToRows,
eventTracker717PerformanceIndicator
)
);
});
});
}

getEventTracker717Performance(diseaseOutbreakEventId: Id): FutureData<PerformanceMetrics717[]> {
private getAll717PerformanceIndicators(): FutureData<PerformanceMetrics717[]> {
return this.datastore
.getObject<PerformanceMetrics717[]>(PERFORMANCE_717_PROGRAM_INDICATORS_DATASTORE_KEY)
.flatMap(nullable717PerformanceProgramIndicators => {
return assertOrError(
nullable717PerformanceProgramIndicators,
PERFORMANCE_717_PROGRAM_INDICATORS_DATASTORE_KEY
).flatMap(performance717ProgramIndicators => {
const eventTracker717PerformanceIndicator =
performance717ProgramIndicators.filter(
indicator => indicator.key === "event_tracker"
);
return apiToFuture(
this.api.analytics.getEnrollmentsQuery({
programId: RTSL_ZEBRA_PROGRAM_ID,
dimension: [...eventTracker717PerformanceIndicator.map(({ id }) => id)],
startDate: DEFAULT_START_DATE,
endDate: DEFAULT_END_DATE,
})
).flatMap(response => {
const filteredRow = filterAnalyticsEnrollmentDataByDiseaseOutbreakEvent(
diseaseOutbreakEventId,
response.rows,
response.headers
);

if (!filteredRow)
return Future.error(
new Error("No data found for event tracker 7-1-7 performance")
);

const mappedIndicatorsToRows: string[][] =
eventTracker717PerformanceIndicator.map(({ id }) => {
return [
id,
filteredRow[
response.headers.findIndex(header => header.name === id)
] || "",
];
});

return Future.success(
this.mapIndicatorsTo717PerformanceMetrics(
mappedIndicatorsToRows,
eventTracker717PerformanceIndicator
)
);
});
return Future.success(performance717ProgramIndicators);
});
});
}
Expand Down
10 changes: 6 additions & 4 deletions src/data/repositories/test/PerformanceOverviewTestRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import { PerformanceOverviewRepository } from "../../../domain/repositories/Perf
import { FutureData } from "../../api-futures";

export class PerformanceOverviewTestRepository implements PerformanceOverviewRepository {
getEventTracker717Performance(
_diseaseOutbreakEventId: Id
): FutureData<PerformanceMetrics717[]> {
getEvent717Performance(_diseaseOutbreakEventId: Id): FutureData<PerformanceMetrics717[]> {
return Future.success([]);
}
getEventTrackerOverviewMetrics(): FutureData<OverviewCard[]> {
Expand All @@ -17,7 +15,11 @@ export class PerformanceOverviewTestRepository implements PerformanceOverviewRep
getTotalCardCounts(): FutureData<any> {
return Future.success(0);
}
getDashboard717Performance(): FutureData<any> {
getNational717Performance(): FutureData<any> {
return Future.success(0);
}

getAlerts717Performance(): FutureData<any> {
return Future.success(0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,5 @@ export type PerformanceMetrics717 = {
name: string;
type: "primary" | "secondary";
value?: number | "Inc";
key: "dashboard" | "event_tracker";
key: "national" | "event" | "alerts";
};
5 changes: 3 additions & 2 deletions src/domain/repositories/PerformanceOverviewRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ export interface PerformanceOverviewRepository {
multiSelectFilters?: Record<string, string[]>,
dateRangeFilter?: string[]
): FutureData<TotalCardCounts[]>;
getDashboard717Performance(): FutureData<PerformanceMetrics717[]>;
getEventTracker717Performance(diseaseOutbreakEventId: Id): FutureData<PerformanceMetrics717[]>;
getNational717Performance(): FutureData<PerformanceMetrics717[]>;
getEvent717Performance(diseaseOutbreakEventId: Id): FutureData<PerformanceMetrics717[]>;
getAlerts717Performance(): FutureData<PerformanceMetrics717[]>;
getEventTrackerOverviewMetrics(
type: string,
casesDataSource: CasesDataSource
Expand Down
12 changes: 7 additions & 5 deletions src/domain/usecases/Get717PerformanceUseCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ export class Get717PerformanceUseCase {
) {}

public execute(
type: "dashboard" | "event_tracker",
type: "national" | "event" | "alerts",
diseaseOutbreakEventId: Id | undefined
): FutureData<PerformanceMetrics717[]> {
if (type === "event_tracker" && diseaseOutbreakEventId) {
return this.options.performanceOverviewRepository.getEventTracker717Performance(
if (type === "event" && diseaseOutbreakEventId) {
return this.options.performanceOverviewRepository.getEvent717Performance(
diseaseOutbreakEventId
);
} else if (type === "dashboard") {
return this.options.performanceOverviewRepository.getDashboard717Performance();
} else if (type === "national") {
return this.options.performanceOverviewRepository.getNational717Performance();
} else if (type === "alerts") {
return this.options.performanceOverviewRepository.getAlerts717Performance();
} else throw new Error(`Unknown 717 type: ${type} `);
}
}
30 changes: 27 additions & 3 deletions src/webapp/pages/dashboard/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,14 @@ export const DashboardPage: React.FC = React.memo(() => {
isLoading: performanceOverviewLoading,
} = usePerformanceOverview();

const { performanceMetrics717, isLoading: _717CardsLoading } = use717Performance("dashboard");
const {
performanceMetrics717: nationalPerformanceMetrics717,
isLoading: national717CardsLoading,
} = use717Performance("national");

const { performanceMetrics717: alertsPerformanceMetrics717, isLoading: alerts717CardsLoading } =
use717Performance("alerts");

const { cardCounts, isLoading: cardCountsLoading } = useCardCounts(
singleSelectFilters,
multiSelectFilters,
Expand All @@ -55,7 +62,7 @@ export const DashboardPage: React.FC = React.memo(() => {
resetCurrentEventTrackerId();
}, [resetCurrentEventTrackerId]);

return performanceOverviewLoading || _717CardsLoading ? (
return performanceOverviewLoading || national717CardsLoading || alerts717CardsLoading ? (
<Loader />
) : (
<Layout
Expand Down Expand Up @@ -125,9 +132,26 @@ export const DashboardPage: React.FC = React.memo(() => {
dateRangeFilter={dateRangeFilter.value}
/>
</Section>
<Section title={i18n.t("Alerts 7-1-7 performance")}>
<GridWrapper>
{alertsPerformanceMetrics717.map(
(perfMetric717: PerformanceMetric717, index: number) => (
<StatsCard
key={index}
stat={`${perfMetric717.primaryValue}`}
title={perfMetric717.title}
pretitle={`${perfMetric717.secondaryValue} ${i18n.t("events")}`}
color={perfMetric717.color}
fillParent
isPercentage
/>
)
)}
</GridWrapper>
</Section>
<Section title={i18n.t("7-1-7 performance")}>
<GridWrapper>
{performanceMetrics717.map(
{nationalPerformanceMetrics717.map(
(perfMetric717: PerformanceMetric717, index: number) => (
<StatsCard
key={index}
Expand Down
6 changes: 3 additions & 3 deletions src/webapp/pages/dashboard/use717Performance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export type PerformanceMetric717State = {
export type Order = { name: string; direction: "asc" | "desc" };

export function use717Performance(
type: "dashboard" | "event_tracker",
type: "national" | "event" | "alerts",
diseaseOutbreakEventId?: Id
): PerformanceMetric717State {
const { compositionRoot } = useAppContext();
Expand All @@ -34,8 +34,8 @@ export function use717Performance(
const [isLoading, setIsLoading] = useState(false);

const getColor = useCallback(
(key: string, value: number | "Inc", type: "dashboard" | "event_tracker"): CardColors => {
if (type === "dashboard") {
(key: string, value: number | "Inc", type: "national" | "event" | "alerts"): CardColors => {
if (type === "national") {
switch (key) {
case "allTargets":
return "grey";
Expand Down
5 changes: 1 addition & 4 deletions src/webapp/pages/event-tracker/EventTrackerPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,7 @@ export const EventTrackerPage: React.FC = React.memo(() => {
});
}, [goTo]);

const { performanceMetrics717, isLoading: _717CardsLoading } = use717Performance(
"event_tracker",
id
);
const { performanceMetrics717, isLoading: _717CardsLoading } = use717Performance("event", id);

useEffect(() => {
if (eventTrackerDetails) {
Expand Down

0 comments on commit 718631e

Please sign in to comment.