Skip to content

Commit

Permalink
feat: cases, deaths and risk history charts
Browse files Browse the repository at this point in the history
  • Loading branch information
9sneha-n committed Oct 6, 2024
1 parent f779051 commit 642773b
Show file tree
Hide file tree
Showing 11 changed files with 383 additions and 206 deletions.
10 changes: 10 additions & 0 deletions src/CompositionRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ import { AlertSyncDataStoreTestRepository } from "./data/repositories/test/Alert
import { AlertSyncRepository } from "./domain/repositories/AlertSyncRepository";
import { DataStoreClient } from "./data/DataStoreClient";
import { GetTotalCardCountsUseCase } from "./domain/usecases/GetTotalCardCountsUseCase";
import { ChartConfigRepository } from "./domain/repositories/ChartConfigRepository";
import { GetChartConfigByTypeUseCase } from "./domain/usecases/GetChartConfigByTypeUseCase";
import { ChartConfigTestRepository } from "./data/repositories/test/ChartConfigTestRepository";
import { ChartConfigD2Repository } from "./data/repositories/ChartConfigD2Repository";

export type CompositionRoot = ReturnType<typeof getCompositionRoot>;

Expand All @@ -56,6 +60,7 @@ type Repositories = {
riskAssessmentRepository: RiskAssessmentRepository;
mapConfigRepository: MapConfigRepository;
performanceOverviewRepository: PerformanceOverviewRepository;
chartConfigRepository: ChartConfigRepository;
};

function getCompositionRoot(repositories: Repositories) {
Expand Down Expand Up @@ -91,6 +96,9 @@ function getCompositionRoot(repositories: Repositories) {
getAll: new GetAllOrgUnitsUseCase(repositories.orgUnitRepository),
getProvinces: new GetProvincesOrgUnits(repositories.orgUnitRepository),
},
charts: {
getCases: new GetChartConfigByTypeUseCase(repositories.chartConfigRepository),
},
};
}

Expand All @@ -107,6 +115,7 @@ export function getWebappCompositionRoot(api: D2Api) {
riskAssessmentRepository: new RiskAssessmentD2Repository(api),
mapConfigRepository: new MapConfigD2Repository(api),
performanceOverviewRepository: new PerformanceOverviewD2Repository(api, dataStoreClient),
chartConfigRepository: new ChartConfigD2Repository(dataStoreClient),
};

return getCompositionRoot(repositories);
Expand All @@ -124,6 +133,7 @@ export function getTestCompositionRoot() {
riskAssessmentRepository: new RiskAssessmentTestRepository(),
mapConfigRepository: new MapConfigTestRepository(),
performanceOverviewRepository: new PerformanceOverviewTestRepository(),
chartConfigRepository: new ChartConfigTestRepository(),
};

return getCompositionRoot(repositories);
Expand Down
53 changes: 53 additions & 0 deletions src/data/repositories/ChartConfigD2Repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { DataStoreClient } from "../DataStoreClient";
import { FutureData } from "../api-futures";
import { ChartConfigRepository } from "../../domain/repositories/ChartConfigRepository";
import { Id } from "../../domain/entities/Ref";

type ChartConfig = {
key: string;
casesId: Id;
deathsId: Id;
riskAssessmentHistoryId: Id;
};

const chartConfigDatastoreKey = "charts-config";

export class ChartConfigD2Repository implements ChartConfigRepository {
constructor(private dataStoreClient: DataStoreClient) {}

public getCases(chartKey: string): FutureData<string> {
return this.dataStoreClient
.getObject<ChartConfig[]>(chartConfigDatastoreKey)
.map(chartConfigs => {
const currentChart = chartConfigs?.find(
chartConfig => chartConfig.key === chartKey
);
if (currentChart) return currentChart.casesId;
else throw new Error(`Chart id not found for ${chartKey}`);
});
}

public getDeaths(chartKey: string): FutureData<string> {
return this.dataStoreClient
.getObject<ChartConfig[]>(chartConfigDatastoreKey)
.map(chartConfigs => {
const currentChart = chartConfigs?.find(
chartConfig => chartConfig.key === chartKey
);
if (currentChart) return currentChart.deathsId;
else throw new Error(`Chart id not found for ${chartKey}`);
});
}

public getRiskAssessmentHistory(chartKey: string): FutureData<string> {
return this.dataStoreClient
.getObject<ChartConfig[]>(chartConfigDatastoreKey)
.map(chartConfigs => {
const currentChart = chartConfigs?.find(
chartConfig => chartConfig.key === chartKey
);
if (currentChart) return currentChart.riskAssessmentHistoryId;
else throw new Error(`Chart id not found for ${chartKey}`);
});
}
}
15 changes: 15 additions & 0 deletions src/data/repositories/test/ChartConfigTestRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Future } from "../../../domain/entities/generic/Future";
import { ChartConfigRepository } from "../../../domain/repositories/ChartConfigRepository";
import { FutureData } from "../../api-futures";

export class ChartConfigTestRepository implements ChartConfigRepository {
getRiskAssessmentHistory(_chartKey: string): FutureData<string> {
return Future.success("1");
}
getCases(_chartkey: string): FutureData<string> {
return Future.success("1");
}
getDeaths(_chartKey: string): FutureData<string> {
return Future.success("1");
}
}
7 changes: 7 additions & 0 deletions src/domain/repositories/ChartConfigRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { FutureData } from "../../data/api-futures";

export interface ChartConfigRepository {
getCases(chartkey: string): FutureData<string>;
getDeaths(chartKey: string): FutureData<string>;
getRiskAssessmentHistory(chartKey: string): FutureData<string>;
}
19 changes: 19 additions & 0 deletions src/domain/usecases/GetChartConfigByTypeUseCase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FutureData } from "../../data/api-futures";
import { ChartConfigRepository } from "../repositories/ChartConfigRepository";

export type ChartType = "deaths" | "cases" | "risk-assessment-history";
export class GetChartConfigByTypeUseCase {
constructor(private chartConfigRepository: ChartConfigRepository) {}

public execute(chartType: ChartType, chartKey: string): FutureData<string> {
if (chartType === "deaths") {
return this.chartConfigRepository.getDeaths(chartKey);
} else if (chartType === "cases") {
return this.chartConfigRepository.getCases(chartKey);
} else if (chartType === "risk-assessment-history") {
return this.chartConfigRepository.getRiskAssessmentHistory(chartKey);
} else {
throw new Error(`Invalid chart type: ${chartType}`);
}
}
}
40 changes: 40 additions & 0 deletions src/webapp/components/chart/Chart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from "react";
import { Section } from "../section/Section";
import { Visualisation } from "../visualisation/Visualisation";
import { useAppContext } from "../../contexts/app-context";
import { useChart } from "./useChart";
import { Maybe } from "../../../utils/ts-utils";
import LoaderContainer from "../loader/LoaderContainer";
import { ChartType } from "../../../domain/usecases/GetChartConfigByTypeUseCase";

type ChartProps = {
title: string;
chartType: ChartType;
chartKey: Maybe<string>;
hasSeparator?: boolean;
lastUpdated?: string;
};
export const Chart: React.FC<ChartProps> = React.memo(props => {
const { api } = useAppContext();
const { title, hasSeparator, lastUpdated, chartType, chartKey } = props;

const { id } = useChart(chartType, chartKey);

const chartUrl =
chartType === "risk-assessment-history"
? `${api.baseUrl}/dhis-web-event-visualizer/?id=${id}`
: `${api.baseUrl}/dhis-web-data-visualizer/#/${id}`;

return (
<LoaderContainer loading={!id}>
<Section
title={title}
hasSeparator={hasSeparator}
titleVariant="secondary"
lastUpdated={lastUpdated}
>
<Visualisation type="chart" srcUrl={chartUrl} />
</Section>
</LoaderContainer>
);
});
25 changes: 25 additions & 0 deletions src/webapp/components/chart/useChart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useEffect, useState } from "react";
import { useAppContext } from "../../contexts/app-context";
import { Maybe } from "../../../utils/ts-utils";
import { ChartType } from "../../../domain/usecases/GetChartConfigByTypeUseCase";

export function useChart(chartType: ChartType, chartKey: Maybe<string>) {
const { compositionRoot } = useAppContext();
const [id, setId] = useState<string>();

useEffect(() => {
if (!chartKey) {
return;
}
compositionRoot.charts.getCases.execute(chartType, chartKey).run(
chartId => {
setId(chartId);
},
error => {
console.error(error);
}
);
}, [chartKey, chartType, compositionRoot.charts.getCases]);

return { id };
}
140 changes: 0 additions & 140 deletions src/webapp/components/map/Map.tsx

This file was deleted.

Loading

0 comments on commit 642773b

Please sign in to comment.