Skip to content

Commit

Permalink
Fix report for some pivot tables
Browse files Browse the repository at this point in the history
Check version to use legacy only for dhis < 39
Refactor and small Type changes
  • Loading branch information
MatiasArriola committed Dec 13, 2024
1 parent a5a5723 commit 6b9a757
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 44 deletions.
26 changes: 14 additions & 12 deletions src/data/repositories/PluginVisualizationD2Repository.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { processFieldsFilterParams } from "@eyeseetea/d2-api/api/common";
import { Id } from "../../domain/entities/Ref";
import { PluginMapVisualization, PluginVisualization } from "../../domain/entities/PluginVisualization";
import { PluginVisualization } from "../../domain/entities/PluginVisualization";
import { PluginVisualizationRepository } from "../../domain/repositories/PluginVisualizationRepository";
import { D2Api, MetadataPick } from "../../types/d2-api";
import { FutureData } from "../../domain/entities/Future";
Expand All @@ -17,35 +17,33 @@ export class PluginVisualizationD2Repository implements PluginVisualizationRepos
period: ReportPeriod;
}): FutureData<PluginVisualization> {
const params = processFieldsFilterParams({ fields: visualizationFields, filter: {} });

const model = options.dashboardItem.map
? "maps"
: options.dashboardItem.eventVisualization
? "eventVisualizations"
: "visualizations";

const model = this.getModelEndpointName(options.dashboardItem);
const res$ = apiToFuture(
this.api.get<D2PluginVisualization>(`/${model}/${options.dashboardItem.reportId}`, params)
);
return res$
.map(res => this.applyPeriodFilters(res, options.period))
.map(res => (options.orgUnitId ? this.applyOrgUnitFilters(res, options.orgUnitId) : res))
.map(res => ("mapViews" in res ? ({ ...res, type: "MAP" } as PluginMapVisualization) : res));
.map(res => (isD2Map(res) ? { ...res, type: "MAP" } : res));
}

private getModelEndpointName(dashboardItem: DashboardItem): string {
return dashboardItem.map ? "maps" : dashboardItem.eventVisualization ? "eventVisualizations" : "visualizations";
}

private applyPeriodFilters(item: D2PluginVisualization, reportPeriod: ReportPeriod) {
const itemsPeriod = generatePeriods(reportPeriod);
if (itemsPeriod.length === 0) {
return item;
}
if ("mapViews" in item) {
if (isD2Map(item)) {
return {
...item,
mapViews: item.mapViews.map((mapView: any) => ({
mapViews: item.mapViews.map((mapView: MapView) => ({
...mapView,
...this.applyPeriodToDimensionAttrs(mapView as WithDimensionAttributes, itemsPeriod),
})),
};
} as D2MapVisualization;
}
return {
...item,
Expand Down Expand Up @@ -74,6 +72,10 @@ export class PluginVisualizationD2Repository implements PluginVisualizationRepos
}
}

function isD2Map(visualization: D2PluginVisualization): visualization is D2MapVisualization {
return "mapViews" in visualization;
}

const dimensionQuery = {
dimension: true,
legendSet: {
Expand Down
36 changes: 29 additions & 7 deletions src/domain/entities/Dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ export interface DashboardItem {
id: Id;
type: string;
reportId: string;
useLegacy: boolean;
legacyReportType: LegacyReportType;
reportTitle: string;
elementId: string;
map: Map;
visualization: Visualization;
eventVisualization: Visualization;
map?: Map;
visualization?: Visualization;
eventVisualization?: Visualization;
width: number;
height: number;
}
Expand Down Expand Up @@ -72,18 +73,39 @@ export class Dashboard {
...dashboardItem,
reportTitle: this.getItemTitle(dashboardItem),
reportId: this.getItemReportId(dashboardItem),
useLegacy: this.getItemShouldUseLegacy(dashboardItem),
legacyReportType: this.getItemLegacyReportType(dashboardItem),
};
}

private getItemTitle(dashboardItem: DashboardItem): string {
/**
* @returns true when Legacy Plugin is preferred.
*/
private getItemShouldUseLegacy(dashboardItem: DashboardItem): boolean {
return (
// EVENT_CHART is not working with the new dhis-data-visualizer iframe
dashboardItem.type === "EVENT_CHART" ||
// EVENT_REPORT only works with the line-listing iframe
(dashboardItem.type === "EVENT_REPORT" && dashboardItem.eventVisualization?.type !== "LINE_LIST") ||
// VISUALIZATION type PIVOT_TABLE: dhis-data-visualizer iframe modifies dom on scroll. Prefer legacy for easy image export
(dashboardItem.type === "VISUALIZATION" && dashboardItem.visualization?.type === "PIVOT_TABLE")
);
}

private getItemData(dashboardItem: DashboardItem) {
const data = dashboardItem.map ?? dashboardItem.eventVisualization ?? dashboardItem.visualization;
return data.name.trim();
if (!data) {
throw new Error("Missing property - one of: map, eventVisualization, visualization");
}
return data;
}

private getItemTitle(dashboardItem: DashboardItem): string {
return this.getItemData(dashboardItem).name.trim();
}

private getItemReportId(dashboardItem: DashboardItem): string {
const data = dashboardItem.map ?? dashboardItem.eventVisualization ?? dashboardItem.visualization;
return data.id;
return this.getItemData(dashboardItem).id;
}

private getItemLegacyReportType(dashboardItem: DashboardItem): LegacyReportType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ export const LegacyVisualizationContents: React.FunctionComponent<LegacyVisualiz
const { visualization, dashboardItem } = props;
const pluginState = useLegacyVisualizationPlugin(dashboardItem, visualization);
return (
<div style={styles.container} id={dashboardItem.elementId} className="legacy-visualization">
<>
{pluginState.type === "loading" && <LinearProgress />}
</div>
<div style={styles.container} id={dashboardItem.elementId} className="legacy-visualization"></div>
</>
);
});

Expand Down
27 changes: 10 additions & 17 deletions src/webapp/components/visualization/Visualization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,14 @@ import { useVisualizationLoader } from "../../hooks/useVisualizationLoader";
import { DashboardItem } from "../../../domain/entities/Dashboard";
import { ReportPeriod } from "../../../domain/entities/DateMonth";
import { LegacyVisualizationContents } from "./LegacyVisualizationContents";
import { PluginVisualization } from "../../../domain/entities/PluginVisualization";
import { useAppContext } from "../../contexts/app-context";

export interface VisualizationProps {
dashboardItem: DashboardItem;
orgUnit?: Ref;
period: ReportPeriod;
}

/**
* Determines which kind of plugin to use.
* EVENT_CHART is not working with the new dhis-data-visualizer iframe
* EVENT_REPORT only works with the line-listing iframe
* VISUALIZATION type PIVOT_TABLE dhis-data-visualizer modifies dom on scroll so image export does not work
*/
function showLegacyVisualization(dashboardItem: DashboardItem, visualization: PluginVisualization): boolean {
// TODO: move this to domain - check if possible
return (
dashboardItem.type === "EVENT_CHART" ||
(dashboardItem.type === "EVENT_REPORT" && visualization.type !== "LINE_LIST") ||
(dashboardItem.type === "VISUALIZATION" && visualization.type === "PIVOT_TABLE")
);
}

export const Visualization: React.FC<VisualizationProps> = React.memo(props => {
const { dashboardItem, orgUnit, period } = props;

Expand All @@ -37,9 +22,11 @@ export const Visualization: React.FC<VisualizationProps> = React.memo(props => {
orgUnitId: orgUnit?.id,
period,
});
const onlyLegacySupported = useOnlyLegacySupported();

switch (visualizationLoader.type) {
case "loaded":
return showLegacyVisualization(dashboardItem, visualizationLoader.value) ? (
return onlyLegacySupported || dashboardItem.useLegacy ? (
<LegacyVisualizationContents visualization={visualizationLoader.value} dashboardItem={dashboardItem} />
) : (
<VisualizationContents visualization={visualizationLoader.value} dashboardItem={dashboardItem} />
Expand All @@ -50,3 +37,9 @@ export const Visualization: React.FC<VisualizationProps> = React.memo(props => {
return <div>{visualizationLoader.message}</div>;
}
});

function useOnlyLegacySupported(): boolean {
const IFRAME_PLUGIN_SUPPORT_MIN_VERSION = 239;
const { pluginVersion } = useAppContext();
return Number(pluginVersion) < IFRAME_PLUGIN_SUPPORT_MIN_VERSION;
}
4 changes: 2 additions & 2 deletions src/webapp/components/visualization/VisualizationContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { PluginVisualization } from "../../../domain/entities/PluginVisualizatio
import { useVisualizationIframeUrl } from "../../hooks/useDhis2Url";
import { DashboardItem } from "../../../domain/entities/Dashboard";

export interface VisualizationProps {
export interface VisualizationContentProps {
dashboardItem: DashboardItem;
visualization: PluginVisualization;
}

export const VisualizationContents: React.FunctionComponent<VisualizationProps> = React.memo(props => {
export const VisualizationContents: React.FunctionComponent<VisualizationContentProps> = React.memo(props => {
const { dashboardItem, visualization } = props;
const iframeRef = React.useRef<HTMLIFrameElement>(null);
const dataVisualizerPluginUrl = useVisualizationIframeUrl(visualization);
Expand Down
8 changes: 4 additions & 4 deletions src/webapp/utils/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,20 @@ export function getImagesFromDom(dashboardItems: DashboardItem[]) {
newEl.width = canvasEl.width;
newEl.height = canvasEl.height;
}
} else if (["CHART", "EVENT_CHART", "VISUALIZATION"].includes(dashboardItem.type)) {
const errorDiv = root.querySelector('[data-test="start-screen-error-container"]');
newEl.domEl = errorDiv ?? (root.querySelector("svg") as SVGElement);
} else if (
dashboardItem.type === "REPORT" ||
dashboardItem.type === "EVENT_REPORT" ||
dashboardItem.visualization.type === "PIVOT_TABLE"
dashboardItem.visualization?.type === "PIVOT_TABLE"
) {
newEl.domEl = root.querySelector("table") as HTMLTableElement;
const tableRects = newEl.domEl?.getClientRects();
if (tableRects[0]) {
newEl.width = tableRects[0].width;
newEl.height = tableRects[0].height;
}
} else if (["CHART", "EVENT_CHART", "VISUALIZATION"].includes(dashboardItem.type)) {
const errorDiv = root.querySelector('[data-test="start-screen-error-container"]');
newEl.domEl = errorDiv ?? (root.querySelector("svg") as SVGElement);
}
return newEl;
})
Expand Down

0 comments on commit 6b9a757

Please sign in to comment.