Skip to content

Commit

Permalink
chore: setting up specific targets view
Browse files Browse the repository at this point in the history
  • Loading branch information
nnkogift committed Aug 9, 2024
1 parent 9ce2caa commit e40515b
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ScorecardStateProvider } from "./state/state";
import { ScorecardView } from "./components/ScorecardView";
import { ScorecardConfigProvider } from "./state/config";
import { ScorecardHeader } from "./components/ScorecardHeader";
import { ScorecardLegendsView } from "./ScorecardLegendsView";
import { ScorecardLegendsView } from "./components/ScorecardLegendsView";

export function ScorecardViewPage() {
const { setDimensions, orgUnit, periods } = useDimensions();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ArrowLegendsView } from "./components/ArrowLegendView";
import { ScorecardConfig } from "@hisptz/dhis2-analytics";
import { LegendView } from "./components/LegendView";
import { SpecificTargetLegendsView } from "./components/SpecificTargetLegendsView";

export function ScorecardLegendsView({ config }: { config: ScorecardConfig }) {
const legendDefinitions = config.legendDefinitions;
Expand All @@ -21,7 +22,15 @@ export function ScorecardLegendsView({ config }: { config: ScorecardConfig }) {
<LegendView legend={item} key={item.id} />
))}
</div>
<ArrowLegendsView />
<div>
<div
style={{ gap: 16, justifySelf: "flex-end" }}
className="row align-items-center space-between"
>
<ArrowLegendsView />
<SpecificTargetLegendsView config={config} />
</div>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IconArrowDown24, IconArrowUp24 } from "@dhis2/ui";
import i18n from "@dhis2/d2-i18n";
import { useScorecardState } from "../../state/state";
import { useScorecardState } from "../../../state/state";

export function ArrowLegendsView(props: any) {
const [state] = useScorecardState();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
import { ScorecardConfig, ScorecardLegend } from "@hisptz/dhis2-analytics";
import { getDataSourcesFromGroups } from "@scorecard/shared";
import { find, isEmpty } from "lodash";
import {
Button,
Modal,
ModalActions,
ModalContent,
ModalTitle,
} from "@dhis2/ui";
import i18n from "@dhis2/d2-i18n";
import {
OrgUnitSpecificTargetView,
PeriodSpecificTargetView,
} from "../../../../ScoreCardManagement/Components/DataConfiguration/Components/DataGroups/Components/DataSourceConfiguration/Components/TargetsArea/components/SpecificTargetView";

function LegendsView({
legends,
config,
}: {
legends: ScorecardLegend[];
config: ScorecardConfig;
}) {
const legendDefinitions = config.legendDefinitions;

return (
<div className="column gap-8">
<table>
<col width="60%" />
<col width="20%" />
<col width="20%" />
<thead>
<tr>
<th align="left">{i18n.t("Legend")}</th>
<th>{i18n.t("Min")}</th>
<th>{i18n.t("Max")}</th>
</tr>
</thead>
<tbody>
{legends?.map((legend) => {
const legendDefinition = find(legendDefinitions, {
id: legend.legendDefinitionId,
});
if (!legendDefinition) {
return <tr></tr>;
}
return (
<tr key={`${legend.id}-view`}>
<td>
<table>
<col width="20%" />
<col width="80%" />
<tbody>
<tr>
<td>
<div
style={{
height: 24,
width: 32,
background:
legendDefinition.color,
}}
/>
</td>
<td>{legendDefinition.name}</td>
</tr>
</tbody>
</table>
</td>
<td align="center">{legend?.startValue}</td>
<td align="center">{legend?.endValue}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}

export function SpecificTargetsLibrary({
config,
}: {
config: ScorecardConfig;
}) {
const specificTargetsDataSourcesByType = useMemo(() => {
const dataSourcesWithSpecificTargets = filter(
dataSources,
(ds) => ds.specificTargetsSet,
);
const data = groupBy(
filter(
dataSourcesWithSpecificTargets,
(ds) => !isEmpty(ds.specificTargets),
),
(ds) => head(ds.specificTargets)?.type,
);
data["orgUnitLevel"] = dataSourcesWithSpecificTargets.filter((ds) =>
isEmpty(ds.specificTargets),
);
return data;
}, [dataSources]);
return (
<>
<div className="column gap-16">
{!isEmpty(specificTargetsDataSourcesByType?.orgUnit) && (
<div>
<h3>{i18n.t("Organisation Units Specific targets")}</h3>
<div className="row gap-16">
{specificTargetsDataSourcesByType?.orgUnit?.map(
(dataSource) => (
<>
<OrgUnitSpecificTargetView
key={`${dataSource.id}-orgUnit-specific-target`}
specificTarget={head(
dataSource.specificTargets,
)}
dataSourceLabel={dataSource.label}
/>
<div className="page-break" />
</>
),
)}
</div>
<div className="page-break" />
</div>
)}
{!isEmpty(specificTargetsDataSourcesByType?.period) && (
<div>
<h3>{i18n.t("Period Specific targets")}</h3>
<div className="row gap-16">
{specificTargetsDataSourcesByType?.period?.map(
(dataSource) => (
<>
<PeriodSpecificTargetView
key={`${dataSource.id}-orgUnit-specific-target`}
specificTarget={head(
dataSource.specificTargets,
)}
dataSourceLabel={dataSource.label}
/>
<div className="page-break" />
</>
),
)}
</div>
<div className="page-break" />
</div>
)}
{!isEmpty(specificTargetsDataSourcesByType?.orgUnitLevell) && (
<div>
<h3>{i18n.t("Organisation unit level targets")}</h3>
<div className="column gap-16">
{specificTargetsDataSourcesByType?.orgUnitLevel?.map(
(dataSource) => (
<OrgUnitLevelSpecificTargetView
key={`${dataSource.id}-orgUnit-specific-target`}
legends={dataSource.legends}
dataSourceLabel={dataSource.label}
/>
),
)}
</div>
<div className="page-break" />
</div>
)}
</div>
</>
);
}

function SpecificTargetLegendsModal({
hide,
onClose,
}: {
hide: boolean;
onClose: () => void;
}) {
return (
<Modal>
<ModalTitle>{i18n.t("Specific targets")}</ModalTitle>
<ModalContent></ModalContent>
<ModalActions>
<Button onClick={onClose}>{i18n.t("Close")}</Button>
</ModalActions>
</Modal>
);
}

export function SpecificTargetLegendsView({
config,
}: {
config: ScorecardConfig;
}) {
const dataSources = getDataSourcesFromGroups(
config.dataSelection.dataGroups,
);
const dataSourcesWithSpecificTargets = dataSources.filter(
(dataSource) =>
!!dataSource.specificTargets || !Array.isArray(dataSource.legends),
);

if (isEmpty(dataSourcesWithSpecificTargets)) {
return null;
}

return <Button>{i18n.t("Specific Targets Library")}</Button>;
}
13 changes: 11 additions & 2 deletions packages/shared/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import { ScorecardLegend } from "../models";
import { DefaultAuthority, TableSort } from "../constants";
import { D2User } from "../state/user";
import { Sharing } from "app/src/modules/Main/components/ScorecardList/hooks/authority";
import {
ScorecardDataGroup,
ScorecardDataHolder,
ScorecardDataSource,
} from "@hisptz/dhis2-analytics";

export function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
Expand Down Expand Up @@ -94,11 +99,15 @@ export function specificTargetsSet(dataSources: any) {
);
}

export function getHoldersFromGroups(dataGroups = []) {
export function getHoldersFromGroups(
dataGroups: ScorecardDataGroup[] = [],
): ScorecardDataHolder[] {
return flattenDeep(dataGroups?.map(({ dataHolders }) => dataHolders) ?? []);
}

export function getDataSourcesFromGroups(dataGroups: any) {
export function getDataSourcesFromGroups(
dataGroups: ScorecardDataGroup[],
): ScorecardDataSource[] {
const dataHolders = compact(getHoldersFromGroups(dataGroups));
return flattenDeep(dataHolders?.map(({ dataSources }) => dataSources));
}
Expand Down

0 comments on commit e40515b

Please sign in to comment.