Skip to content

Commit af6cefa

Browse files
authored
Merge pull request #346 from contentstack/VE-4043-configure-start-edit-retry-2
feat(VE-4043): add start editing button configuration for builder mode
2 parents 6cfe76f + 66fee50 commit af6cefa

7 files changed

Lines changed: 129 additions & 9 deletions

File tree

src/configManager/config.default.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ export function getUserInitData(): IInitData {
1616
position: "top",
1717
includeByQueryParameter: true,
1818
},
19+
editButtonBuilder: {
20+
enable: true,
21+
position: "bottom-right"
22+
},
1923

2024
mode: "preview",
2125

@@ -50,6 +54,10 @@ export function getDefaultConfig(): IConfig {
5054
position: "top",
5155
includeByQueryParameter: true,
5256
},
57+
editButtonBuilder: {
58+
enable: true,
59+
position: "bottom-right"
60+
},
5361

5462
hash: "",
5563
mode: 1,

src/configManager/handleUserConfig.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ export const handleInitData = (initData: Partial<IInitData>): void => {
108108
config.editButton.includeByQueryParameter ??
109109
true,
110110
});
111+
112+
Config.set("editButtonBuilder", {
113+
enable:
114+
initData.editButtonBuilder?.enable ??
115+
stackSdk.live_preview?.editButtonBuilder?.enable ??
116+
config.editButtonBuilder.enable,
117+
position:
118+
initData.editButtonBuilder?.position ??
119+
stackSdk.live_preview?.position ??
120+
config.editButtonBuilder.position ??
121+
"bottom-right",
122+
})
111123

112124
// client URL params
113125
handleClientUrlParams(

src/types/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,23 @@ export declare interface IConfig {
7979
windowType: ILivePreviewWindowType;
8080
hash: string;
8181
editButton: IConfigEditButton;
82+
editButtonBuilder: IConfigEditButtonBuilder;
8283
mode: ILivePreviewModeConfig;
8384
elements: {
8485
highlightedElement: HTMLElement | null;
8586
};
8687
}
8788

89+
export declare interface IConfigEditButtonBuilder {
90+
enable: boolean;
91+
position?:
92+
| "top-left"
93+
| "top-right"
94+
| "bottom-left"
95+
| "bottom-right"
96+
}
97+
98+
8899
export declare interface IConfigEditButton {
89100
enable: boolean;
90101
exclude?: ("insideLivePreviewPortal" | "outsideLivePreviewPortal")[];
@@ -115,6 +126,7 @@ export declare interface IInitData {
115126
clientUrlParams: Partial<Omit<IClientUrlParams, "url">>;
116127
stackSdk: IStackSdk;
117128
editButton: IConfigEditButton;
129+
editButtonBuilder: IConfigEditButtonBuilder;
118130
mode: ILivePreviewMode;
119131
}
120132

src/visualBuilder/__test__/index.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ describe("Visual builder", () => {
194194
expect(h1).toHaveAttribute("contenteditable");
195195
expect(h1).toHaveAttribute("data-cslp-field-type", "singleline");
196196
})
197-
}, { timeout: 20 * 1000 });
197+
}, { timeout: 40 * 1000 });
198198

199199
test("multi line should be contenteditable", async () => {
200200
h1.setAttribute(
@@ -207,7 +207,7 @@ describe("Visual builder", () => {
207207
expect(h1).toHaveAttribute("contenteditable");
208208
expect(h1).toHaveAttribute("data-cslp-field-type", "multiline");
209209
})
210-
}, { timeout: 20 * 1000 });
210+
}, { timeout: 40 * 1000 });
211211

212212
});
213213
});

src/visualBuilder/components/__test__/startEditingButton.test.tsx

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { render, fireEvent, screen } from "@testing-library/preact";
2-
import StartEditingButtonComponent from "../startEditingButton";
2+
import StartEditingButtonComponent, { getEditButtonPosition } from "../startEditingButton";
33
import Config from "../../../configManager/configManager";
44
import { asyncRender } from "../../../__test__/utils";
55

@@ -45,4 +45,52 @@ describe("StartEditingButtonComponent", () => {
4545
"https://app.contentstack.com/#!/stack/bltapikey/visual-builder?branch=main&environment=bltenvironment&target-url=http%3A%2F%2Flocalhost%3A3000%2F&locale=en-us"
4646
);
4747
});
48+
49+
test("should not render when enable is false", async () => {
50+
Config.set("editButtonBuilder.enable", false);
51+
const { container } = await asyncRender(<StartEditingButtonComponent />);
52+
expect(container).toBeEmptyDOMElement();
53+
});
54+
55+
test("should render when enable is true", async () => {
56+
Config.set("editButtonBuilder.enable", true);
57+
const { getByTestId } = await asyncRender(<StartEditingButtonComponent />);
58+
const button = getByTestId("vcms-start-editing-btn");
59+
expect(button).toBeInTheDocument();
60+
});
61+
62+
test.each([
63+
'bottom-right',
64+
'bottom-left',
65+
'top-left',
66+
'top-right'
67+
])('should return valid position %s', (position) => {
68+
expect(getEditButtonPosition(position)).toBe(position);
69+
});
70+
71+
test.each([
72+
'invalid-position',
73+
'center',
74+
'',
75+
undefined,
76+
null,
77+
123,
78+
{},
79+
[],
80+
false,
81+
])('should return bottom-right for invalid input: %s', (invalidPosition) => {
82+
expect(getEditButtonPosition(invalidPosition)).toBe('bottom-right');
83+
});
84+
85+
test("should render with default values when editButtonBuilder config is missing", async () => {
86+
Config.reset();
87+
Config.set("stackDetails.apiKey", "bltapikey");
88+
Config.set("stackDetails.environment", "bltenvironment");
89+
90+
const { getByTestId } = await asyncRender(<StartEditingButtonComponent />);
91+
const button = getByTestId("vcms-start-editing-btn");
92+
93+
expect(Config.get().editButtonBuilder.position).toBe("bottom-right")
94+
expect(button).toBeInTheDocument();
95+
});
4896
});

src/visualBuilder/components/startEditingButton.tsx

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,40 @@ import getVisualBuilderRedirectionUrl from "../utils/getVisualBuilderRedirection
33
import { EditIcon } from "./icons";
44
import { visualBuilderStyles } from "../visualBuilder.style";
55
import React from "preact/compat";
6+
import Config from "../../configManager/configManager";
7+
import { IConfigEditButtonBuilder } from "../../types/types";
68

7-
function StartEditingButtonComponent(): JSX.Element {
8-
return (
9+
10+
type Position = NonNullable<IConfigEditButtonBuilder['position']>;
11+
12+
const positionStyles: Record<Position, string> = {
13+
"bottom-right": visualBuilderStyles()['visual-builder__start-editing-btn__bottom-right'],
14+
"bottom-left": visualBuilderStyles()['visual-builder__start-editing-btn__bottom-left'],
15+
"top-left": visualBuilderStyles()['visual-builder__start-editing-btn__top-left'],
16+
"top-right": visualBuilderStyles()['visual-builder__start-editing-btn__top-right'],
17+
}
18+
19+
export function getEditButtonPosition(position: any): Position {
20+
const validPositions: Position[] = ['bottom-left', 'bottom-right', 'top-left', 'top-right']
21+
if(validPositions.includes(position)){
22+
return position
23+
} else {
24+
return "bottom-right"
25+
}
26+
}
27+
28+
function StartEditingButtonComponent(): JSX.Element | null {
29+
const config = Config.get()
30+
const enable = config.editButtonBuilder.enable;
31+
const position = config.editButtonBuilder.position || "bottom-right";
32+
33+
return enable ? (
934
<a
1035
href={getVisualBuilderRedirectionUrl().toString()}
1136
className={classNames(
1237
"visual-builder__start-editing-btn",
13-
visualBuilderStyles()["visual-builder__start-editing-btn"]
38+
visualBuilderStyles()["visual-builder__start-editing-btn"],
39+
positionStyles[getEditButtonPosition(position)]
1440
)}
1541
data-testid="vcms-start-editing-btn"
1642
onClick={(e) => {
@@ -24,7 +50,7 @@ function StartEditingButtonComponent(): JSX.Element {
2450
<EditIcon />
2551
<span>Start Editing</span>
2652
</a>
27-
);
53+
) : null;
2854
}
2955

3056
export default StartEditingButtonComponent;

src/visualBuilder/visualBuilder.style.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,6 @@ export function visualBuilderStyles() {
152152
z-index: 1000;
153153
text-decoration: none;
154154
position: fixed;
155-
bottom: 30px;
156-
right: 30px;
157155
box-shadow:
158156
0px 4px 15px 0px rgba(108, 92, 231, 0.2),
159157
0px 3px 14px 3px rgba(0, 0, 0, 0.12),
@@ -201,6 +199,22 @@ export function visualBuilderStyles() {
201199
text-transform: capitalize;
202200
}
203201
`,
202+
"visual-builder__start-editing-btn__bottom-right": css`
203+
bottom: 30px;
204+
right: 30px;
205+
`,
206+
"visual-builder__start-editing-btn__bottom-left": css`
207+
bottom: 30px;
208+
left: 30px;
209+
`,
210+
"visual-builder__start-editing-btn__top-right": css`
211+
top: 30px;
212+
right: 30px;
213+
`,
214+
"visual-builder__start-editing-btn__top-left": css`
215+
top: 30px;
216+
left: 30px;
217+
`,
204218
"visual-builder__cursor-icon": css`
205219
height: 40px;
206220
width: 40px;

0 commit comments

Comments
 (0)