Skip to content

Commit b213daa

Browse files
committed
fix(custom-chart-web): send real layout/config to playground and drop dead style
1 parent f48e916 commit b213daa

3 files changed

Lines changed: 90 additions & 38 deletions

File tree

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1+
const base = require("@mendix/pluggable-widgets-tools/test-config/jest.config.js");
2+
13
module.exports = {
2-
...require("@mendix/pluggable-widgets-tools/test-config/jest.config.js"),
3-
testEnvironment: "@happy-dom/jest-environment"
4+
...base,
5+
testEnvironment: "@happy-dom/jest-environment",
6+
moduleNameMapper: {
7+
...base.moduleNameMapper,
8+
// Source uses baseUrl-relative imports (e.g. `from "src/controllers/..."`); map them to rootDir.
9+
"^src/(.*)$": "<rootDir>/$1"
10+
}
411
};
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { render, renderHook, screen, waitFor } from "@testing-library/react";
2+
import { observer } from "mobx-react-lite";
3+
import { createElement, ReactElement } from "react";
4+
import { PlaygroundDataV2 } from "@mendix/shared-charts/main";
5+
import { CustomChartContainerProps } from "../../../typings/CustomChartProps";
6+
import { useCustomChart } from "../useCustomChart";
7+
8+
function props(overrides: Partial<CustomChartContainerProps> = {}): CustomChartContainerProps {
9+
return {
10+
name: "chart",
11+
class: "",
12+
tabIndex: 0,
13+
dataStatic: "[]",
14+
sampleData: "",
15+
showPlaygroundSlot: true,
16+
layoutStatic: "{}",
17+
sampleLayout: "",
18+
configurationOptions: "{}",
19+
widthUnit: "percentage",
20+
width: 100,
21+
heightUnit: "percentageOfWidth",
22+
height: 75,
23+
minHeightUnit: "none",
24+
minHeight: 0,
25+
maxHeightUnit: "none",
26+
maxHeight: 0,
27+
OverflowY: "auto",
28+
...overrides
29+
} as CustomChartContainerProps;
30+
}
31+
32+
describe("useCustomChart", () => {
33+
it("passes the adapter's parsed layout and config into playgroundData (not empty objects)", () => {
34+
const { result } = renderHook(() =>
35+
useCustomChart(
36+
props({
37+
layoutStatic: JSON.stringify({ title: "X" }),
38+
configurationOptions: JSON.stringify({ displaylogo: true })
39+
})
40+
)
41+
);
42+
43+
const data = result.current.playgroundData as PlaygroundDataV2;
44+
45+
expect(data.layoutOptions).toMatchObject({ title: "X" });
46+
expect(data.configOptions).toMatchObject({ displaylogo: true });
47+
});
48+
49+
it("returns only playgroundData and ref (no dead containerStyle)", () => {
50+
const { result } = renderHook(() => useCustomChart(props()));
51+
52+
expect(Object.keys(result.current).sort()).toEqual(["playgroundData", "ref"]);
53+
});
54+
55+
it("stays reactive to the store's parsed traces when rendered inside an observer", async () => {
56+
// Mirrors CustomChart.tsx: the hook is consumed by an observer component, which
57+
// re-renders once the store's setup autorun loads the parsed data.
58+
const Probe = observer(function Probe(p: CustomChartContainerProps): ReactElement {
59+
const { playgroundData } = useCustomChart(p);
60+
const data = playgroundData as PlaygroundDataV2;
61+
return createElement("output", {}, JSON.stringify({ type: data.type, plotData: data.plotData }));
62+
});
63+
64+
render(createElement(Probe, props({ dataStatic: JSON.stringify([{ type: "bar", x: [1], y: [2] }]) })));
65+
66+
await waitFor(() => {
67+
const parsed = JSON.parse(screen.getByRole("status").textContent ?? "{}");
68+
expect(parsed.type).toBe("editor.data.v2");
69+
expect(parsed.plotData).toEqual([{ type: "bar", x: [1], y: [2] }]);
70+
});
71+
});
72+
});

packages/pluggableWidgets/custom-chart-web/src/hooks/useCustomChart.ts

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { computed } from "mobx";
2-
import { CSSProperties, Ref, RefCallback, useEffect } from "react";
1+
import { Ref, RefCallback, useEffect } from "react";
32
import { CustomChartControllerHost } from "src/controllers/CustomChartControllerHost";
43
import { mergeRefs } from "src/utils/mergeRefs";
54
import { PlaygroundData } from "@mendix/shared-charts/main";
@@ -9,30 +8,7 @@ import { useSetup } from "@mendix/widget-plugin-mobx-kit/react/useSetup";
98
import { CustomChartContainerProps } from "../../typings/CustomChartProps";
109
import { ControllerProps } from "../controllers/typings";
1110

12-
// TODO: replace with get-dimensions from widget-plugin-platform
13-
function getContainerStyle(
14-
width: number,
15-
widthUnit: CustomChartContainerProps["widthUnit"],
16-
height: number,
17-
heightUnit: CustomChartContainerProps["heightUnit"]
18-
): CSSProperties {
19-
const style: CSSProperties = {
20-
width: widthUnit === "percentage" ? `${width}%` : `${width}px`
21-
};
22-
23-
if (heightUnit === "percentageOfWidth") {
24-
style.paddingBottom = widthUnit === "percentage" ? `${height}%` : `${width / 2}px`;
25-
} else if (heightUnit === "pixels") {
26-
style.height = `${height}px`;
27-
} else if (heightUnit === "percentageOfParent") {
28-
style.height = `${height}%`;
29-
}
30-
31-
return style;
32-
}
33-
3411
interface UseCustomChartReturn {
35-
containerStyle: CSSProperties;
3612
playgroundData: PlaygroundData;
3713
ref: Ref<HTMLDivElement> | RefCallback<HTMLDivElement> | undefined;
3814
}
@@ -42,6 +18,7 @@ export function useCustomChart(props: CustomChartContainerProps): UseCustomChart
4218

4319
const {
4420
store,
21+
adapter,
4522
chartViewModel,
4623
resizeCtrl: resizeController
4724
} = useSetup(() => new CustomChartControllerHost(gateProvider.gate));
@@ -50,19 +27,15 @@ export function useCustomChart(props: CustomChartContainerProps): UseCustomChart
5027
gateProvider.setProps(props);
5128
});
5229

53-
const containerStyle = getContainerStyle(props.width, props.widthUnit, props.height, props.heightUnit);
54-
const playgroundData = computed(
55-
(): PlaygroundData => ({
56-
type: "editor.data.v2",
57-
store,
58-
plotData: store.data,
59-
layoutOptions: {},
60-
configOptions: {}
61-
})
62-
).get();
30+
const playgroundData: PlaygroundData = {
31+
type: "editor.data.v2",
32+
store,
33+
plotData: store.data,
34+
layoutOptions: adapter.layout,
35+
configOptions: adapter.config
36+
};
6337

6438
return {
65-
containerStyle,
6639
playgroundData,
6740
ref: mergeRefs<HTMLDivElement>(resizeController.setTarget, chartViewModel.setChart)
6841
};

0 commit comments

Comments
 (0)