Skip to content

Commit 85b19c9

Browse files
committed
fix(VB-1541): hide field extension and comment icons on update-restricted fields
Gate CommentIcon and FieldLocationIcon in FieldToolbar by disableFieldActions (driven by isFieldDisabled, which already covers field updateRestrict, entry update permission, workflow stage permission, and variant permissions). Adds unit tests covering visibility in disabled and non-disabled states. Ticket: https://contentstack.atlassian.net/browse/VB-1541
1 parent 94a4e47 commit 85b19c9

2 files changed

Lines changed: 96 additions & 12 deletions

File tree

src/visualBuilder/components/FieldToolbar.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ function FieldToolbarComponent(
563563
{isModalEditable ? editButton : null}
564564
{isReplaceAllowed ? replaceButton : null}
565565
{formButton}
566-
{fieldSchema ? (
566+
{fieldSchema && !disableFieldActions ? (
567567
<CommentIcon
568568
fieldMetadata={fieldMetadata}
569569
fieldSchema={fieldSchema}
@@ -575,16 +575,18 @@ function FieldToolbarComponent(
575575
</>
576576
)}
577577

578-
<FieldLocationIcon
579-
fieldLocationData={fieldLocationData}
580-
multipleFieldToolbarButtonClasses={
581-
multipleFieldToolbarButtonClasses
582-
}
583-
handleMoreIconClick={handleMoreIconClick}
584-
moreButtonRef={moreButtonRef}
585-
toolbarRef={toolbarRef}
586-
domEditStack={domEditStack}
587-
/>
578+
{!disableFieldActions && (
579+
<FieldLocationIcon
580+
fieldLocationData={fieldLocationData}
581+
multipleFieldToolbarButtonClasses={
582+
multipleFieldToolbarButtonClasses
583+
}
584+
handleMoreIconClick={handleMoreIconClick}
585+
moreButtonRef={moreButtonRef}
586+
toolbarRef={toolbarRef}
587+
domEditStack={domEditStack}
588+
/>
589+
)}
588590
</>
589591
</div>
590592
</div>

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

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ vi.mock("../../utils/instanceHandlers", () => ({
3333

3434
//CommentIcon testcases are covered seperatly
3535
vi.mock("../CommentIcon", () => ({
36-
default: vi.fn(() => <div>Comment Icon</div>),
36+
default: vi.fn(() => <div data-testid="vb-comment-icon">Comment Icon</div>),
37+
}));
38+
39+
vi.mock("../FieldLocationIcon", () => ({
40+
FieldLocationIcon: vi.fn(() => (
41+
<div data-testid="vb-field-location-icon">Field Location Icon</div>
42+
)),
3743
}));
3844

3945
vi.mock("../../utils/visualBuilderPostMessage", () => {
@@ -273,6 +279,82 @@ describe("FieldToolbarComponent", () => {
273279
expect(icon).toBeInTheDocument();
274280
});
275281

282+
describe("CommentIcon and FieldLocationIcon visibility on restricted fields", () => {
283+
const wholeMultiMetadata: CslpData = {
284+
...mockMultipleFieldMetadata,
285+
fieldPathWithIndex: "group.link",
286+
instance: { fieldPathWithIndex: "group.link" },
287+
};
288+
289+
test("renders CommentIcon and FieldLocationIcon when field is not disabled", async () => {
290+
vi.mocked(isFieldDisabled).mockReturnValue({
291+
isDisabled: false,
292+
reason: "" as any,
293+
});
294+
295+
const { container } = render(
296+
<FieldToolbarComponent
297+
eventDetails={{
298+
...mockEventDetails,
299+
fieldMetadata: wholeMultiMetadata,
300+
}}
301+
hideOverlay={vi.fn()}
302+
/>
303+
);
304+
305+
await act(async () => {
306+
await new Promise((r) => setTimeout(r, 0));
307+
});
308+
309+
expect(
310+
await findByTestId(
311+
container,
312+
"vb-comment-icon",
313+
{},
314+
{ timeout: 1000 }
315+
)
316+
).toBeInTheDocument();
317+
expect(
318+
container.querySelector('[data-testid="vb-field-location-icon"]')
319+
).toBeInTheDocument();
320+
});
321+
322+
test("hides CommentIcon and FieldLocationIcon when field is disabled (update restrict)", async () => {
323+
vi.mocked(isFieldDisabled).mockReturnValue({
324+
isDisabled: true,
325+
reason: "You have only read access to this field" as any,
326+
});
327+
328+
const { container } = render(
329+
<FieldToolbarComponent
330+
eventDetails={{
331+
...mockEventDetails,
332+
fieldMetadata: wholeMultiMetadata,
333+
}}
334+
hideOverlay={vi.fn()}
335+
/>
336+
);
337+
338+
await act(async () => {
339+
await new Promise((r) => setTimeout(r, 0));
340+
});
341+
342+
await findByTestId(
343+
container,
344+
"visual-builder__focused-toolbar__multiple-field-toolbar",
345+
{},
346+
{ timeout: 1000 }
347+
);
348+
349+
expect(
350+
container.querySelector('[data-testid="vb-comment-icon"]')
351+
).not.toBeInTheDocument();
352+
expect(
353+
container.querySelector('[data-testid="vb-field-location-icon"]')
354+
).not.toBeInTheDocument();
355+
});
356+
});
357+
276358
describe("'Replace button' visibility for multiple file fields", () => {
277359
beforeEach(() => {
278360
// Override the mock for this describe block - resolve immediately

0 commit comments

Comments
 (0)