diff --git a/src/visualBuilder/components/__test__/addInstanceButton.test.tsx b/src/visualBuilder/components/__test__/addInstanceButton.test.tsx
index 92fc7364..066d33b7 100644
--- a/src/visualBuilder/components/__test__/addInstanceButton.test.tsx
+++ b/src/visualBuilder/components/__test__/addInstanceButton.test.tsx
@@ -1,3 +1,4 @@
+import React from "preact/compat";
import {
act,
cleanup,
@@ -7,6 +8,21 @@ import {
} from "@testing-library/preact";
import { singleLineFieldSchema } from "../../../__test__/data/fields";
import AddInstanceButtonComponent from "../addInstanceButton";
+import visualBuilderPostMessageActual from "../../utils/visualBuilderPostMessage";
+import { getDiscussionIdByFieldMetaData } from "../../utils/getDiscussionIdByFieldMetaData";
+
+const visualBuilderPostMessage = vi.mocked(visualBuilderPostMessageActual);
+
+vi.mock("../../utils/visualBuilderPostMessage", async () => {
+ return {
+ default: {
+ send: vi.fn().mockImplementation((_eventName: string) => {
+ return Promise.resolve({});
+ }),
+ on: vi.fn(),
+ },
+ };
+});
describe("AddInstanceButtonComponent", () => {
afterEach(cleanup);
@@ -18,10 +34,16 @@ describe("AddInstanceButtonComponent", () => {
);
- })
+ });
const buttonElement = getByTestId(
document.body,
"visual-builder-add-instance-button"
@@ -33,22 +55,63 @@ describe("AddInstanceButtonComponent", () => {
expect(buttonElement.querySelector("path")).toBeTruthy();
});
- test("calls onClickCallback when button is clicked", async () => {
+ test("sends add-instance message when clicked", async () => {
const onClickCallback = vi.fn();
await act(() => {
render(
);
- })
+ });
const buttonElement = getByTestId(
document.body,
"visual-builder-add-instance-button"
);
- fireEvent.click(buttonElement);
+ await act(() => {
+ fireEvent.click(buttonElement);
+ });
+ expect(visualBuilderPostMessage?.send).toHaveBeenCalledWith(
+ "add-instance",
+ {
+ fieldMetadata: {},
+ index: 0,
+ }
+ );
+ });
+
+ test("calls onClick callback when clicked", async () => {
+ const onClickCallback = vi.fn();
+ await act(() => {
+ render(
+
+ );
+ });
+ const buttonElement = getByTestId(
+ document.body,
+ "visual-builder-add-instance-button"
+ );
+ await act(() => {
+ fireEvent.click(buttonElement);
+ });
expect(onClickCallback).toHaveBeenCalled();
});
});
diff --git a/src/visualBuilder/components/addInstanceButton.tsx b/src/visualBuilder/components/addInstanceButton.tsx
index 036644fe..650341a3 100644
--- a/src/visualBuilder/components/addInstanceButton.tsx
+++ b/src/visualBuilder/components/addInstanceButton.tsx
@@ -3,44 +3,82 @@ import classNames from "classnames";
import { visualBuilderStyles } from "../visualBuilder.style";
import { PlusIcon } from "./icons";
import { ISchemaFieldMap } from "../utils/types/index.types";
+import { CslpData } from "../../cslp/types/cslp.types";
+import visualBuilderPostMessage from "../utils/visualBuilderPostMessage";
+import { VisualBuilderPostMessageEvents } from "../utils/types/postMessage.types";
+import { Signal } from "@preact/signals";
interface AddInstanceButtonProps {
value: any;
onClick: (event: MouseEvent) => void;
label?: string | undefined;
fieldSchema: ISchemaFieldMap | undefined;
+ fieldMetadata: CslpData;
+ index: number;
+ loading: Signal;
}
function AddInstanceButtonComponent(
props: AddInstanceButtonProps
): JSX.Element {
const fieldSchema = props.fieldSchema;
- const disabled =
- fieldSchema && "max_instance" in fieldSchema && fieldSchema.max_instance
- ? props.value.length >= fieldSchema.max_instance
- : false;
+ const fieldMetadata = props.fieldMetadata;
+ const index = props.index;
+ const loading = props.loading;
+
+ const onClick = async (event: MouseEvent) => {
+ loading.value = true;
+ try {
+ await visualBuilderPostMessage?.send(
+ VisualBuilderPostMessageEvents.ADD_INSTANCE,
+ {
+ fieldMetadata,
+ index,
+ }
+ );
+ } catch (error) {
+ console.error("Visual Builder: Failed to add instance", error);
+ }
+ loading.value = false;
+ props.onClick(event);
+ };
+
+ const buttonClassName = classNames(
+ "visual-builder__add-button",
+ visualBuilderStyles()["visual-builder__add-button"],
+ {
+ "visual-builder__add-button--with-label": props.label,
+ },
+ {
+ [visualBuilderStyles()["visual-builder__add-button--loading"]]:
+ loading.value,
+ },
+ visualBuilderStyles()["visual-builder__tooltip"]
+ );
+
+ const maxInstances =
+ fieldSchema && fieldSchema.data_type !== "block"
+ ? fieldSchema.max_instance
+ : undefined;
+ const isMaxInstances = maxInstances
+ ? props.value.length >= maxInstances
+ : false;
+ const disabled = loading.value || isMaxInstances;
return (