Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/visualBuilder/__test__/click/fields/multi-line.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,18 @@ describe("When an element is clicked in visual builder mode", () => {
"all_fields.bltapikey.en-us.single_line":
"Single Line",
});
} else if (
eventName ===
VisualBuilderPostMessageEvents.GET_WORKFLOW_STAGE_DETAILS
) {
return Promise.resolve({
stage: { name: "Example Stage" },
permissions: {
entry: {
update: true,
},
},
});
}
return Promise.resolve({});
}
Expand Down Expand Up @@ -197,6 +209,18 @@ describe("When an element is clicked in visual builder mode", () => {
return Promise.resolve({
fieldData: values[args.entryPath],
});
} else if (
eventName ===
VisualBuilderPostMessageEvents.GET_WORKFLOW_STAGE_DETAILS
) {
return Promise.resolve({
stage: { name: "Example Stage" },
permissions: {
entry: {
update: true,
},
},
});
}
return Promise.resolve({});
}
Expand Down
24 changes: 24 additions & 0 deletions src/visualBuilder/__test__/click/fields/number.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ describe("When an element is clicked in visual builder mode", () => {
return Promise.resolve({
"all_fields.bltapikey.en-us.number": "Number",
});
} else if (
eventName ===
VisualBuilderPostMessageEvents.GET_WORKFLOW_STAGE_DETAILS
) {
return Promise.resolve({
stage: { name: "Example Stage" },
permissions: {
entry: {
update: true,
},
},
});
}
return Promise.resolve({});
}
Expand Down Expand Up @@ -196,6 +208,18 @@ describe("When an element is clicked in visual builder mode", () => {
return Promise.resolve({
fieldData: values[args.entryPath],
});
} else if (
eventName ===
VisualBuilderPostMessageEvents.GET_WORKFLOW_STAGE_DETAILS
) {
return Promise.resolve({
stage: { name: "Example Stage" },
permissions: {
entry: {
update: true,
},
},
});
}
return Promise.resolve({});
}
Expand Down
24 changes: 24 additions & 0 deletions src/visualBuilder/__test__/click/fields/single-line.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@ describe("When an element is clicked in visual builder mode", () => {
"all_fields.bltapikey.en-us.single_line":
"Single Line",
});
} else if (
eventName ===
VisualBuilderPostMessageEvents.GET_WORKFLOW_STAGE_DETAILS
) {
return Promise.resolve({
stage: { name: "Example Stage" },
permissions: {
entry: {
update: true,
},
},
});
}
return Promise.resolve({});
}
Expand Down Expand Up @@ -217,6 +229,18 @@ describe("When an element is clicked in visual builder mode", () => {
return Promise.resolve({
fieldData: values[args.entryPath],
});
} else if (
eventName ===
VisualBuilderPostMessageEvents.GET_WORKFLOW_STAGE_DETAILS
) {
return Promise.resolve({
stage: { name: "Example Stage" },
permissions: {
entry: {
update: true,
},
},
});
}
return Promise.resolve({});
}
Expand Down
15 changes: 6 additions & 9 deletions src/visualBuilder/components/FieldToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import getChildrenDirection from "../utils/getChildrenDirection";
import {
ALLOWED_MODAL_EDITABLE_FIELD,
ALLOWED_REPLACE_FIELDS,
DEFAULT_MULTIPLE_FIELDS,
} from "../utils/constants";
import { getFieldType } from "../utils/getFieldType";
import {
Expand All @@ -20,7 +19,6 @@ import {
MoveLeftIcon,
MoveRightIcon,
ReplaceAssetIcon,
MoreIcon,
} from "./icons";
import { fieldIcons } from "./icons/fields";
import classNames from "classnames";
Expand All @@ -42,10 +40,9 @@ import {
} from "./FieldRevert/FieldRevertComponent";
import { LoadingIcon } from "./icons/loading";
import { EntryPermissions } from "../utils/getEntryPermissions";
import { EmptyAppIcon } from "./icons/EmptyAppIcon";
import { FieldLocationAppList } from "./FieldLocationAppList";
import { FieldLocationIcon } from "./FieldLocationIcon";

import { WorkflowStageDetails } from "../utils/getWorkflowStageDetails";

export type FieldDetails = Pick<
VisualBuilderCslpEventDetails,
Expand All @@ -58,7 +55,8 @@ interface MultipleFieldToolbarProps {
eventDetails: VisualBuilderCslpEventDetails;
hideOverlay: () => void;
isVariant?: boolean;
entryPermissions?: EntryPermissions;
entryPermissions?: EntryPermissions | undefined;
entryWorkflowStageDetails?: WorkflowStageDetails | undefined;
}

function handleReplaceAsset(fieldMetadata: CslpData) {
Expand Down Expand Up @@ -118,6 +116,7 @@ function FieldToolbarComponent(
eventDetails,
isVariant: isVariantOrParentOfVariant,
entryPermissions,
entryWorkflowStageDetails,
} = props;
const { fieldMetadata, editableElement: targetElement } = eventDetails;
const [isFormLoading, setIsFormLoading] = useState(false);
Expand Down Expand Up @@ -158,12 +157,12 @@ function FieldToolbarComponent(
editableElement: targetElement,
fieldMetadata,
},
entryPermissions
entryPermissions,
entryWorkflowStageDetails
);
disableFieldActions = isDisabled;

fieldType = getFieldType(fieldSchema);


Icon = fieldIcons[fieldType];

Expand Down Expand Up @@ -394,8 +393,6 @@ function FieldToolbarComponent(
};
}, []);



useEffect(() => {
const fetchFieldLocationData = async () => {
try {
Expand Down
66 changes: 40 additions & 26 deletions src/visualBuilder/components/__test__/fieldLabelWrapper.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { singleLineFieldSchema } from "../../../__test__/data/fields";
import { asyncRender } from "../../../__test__/utils";
import { isFieldDisabled } from "../../utils/isFieldDisabled";
import { FieldSchemaMap } from "../../utils/fieldSchemaMap";
import { getEntryPermissionsCached } from "../../utils/getEntryPermissionsCached";
import visualBuilderPostMessage from "../../utils/visualBuilderPostMessage";
import React from "preact/compat";

Expand Down Expand Up @@ -81,21 +80,33 @@ vi.mock("../../utils/isFieldDisabled", () => ({

vi.mock("../../../cslp", () => ({
extractDetailsFromCslp: vi.fn().mockImplementation((path) => {
return {
content_type_uid: "mockContentTypeUid",
return {
content_type_uid: "mockContentTypeUid",
fieldPath: path,
cslpValue: path
cslpValue: path,
};
}),
}));

vi.mock("../../utils/getEntryPermissionsCached", () => ({
getEntryPermissionsCached: vi.fn().mockResolvedValue({
create: true,
read: true,
update: true,
delete: true,
publish: true,
vi.mock("../../utils/fetchEntryPermissionsAndStageDetails", () => ({
fetchEntryPermissionsAndStageDetails: async () => ({
acl: {
update: {
create: true,
read: true,
update: true,
delete: true,
publish: true,
},
},
workflowStage: {
stage: undefined,
permissions: {
entry: {
update: true,
},
},
},
}),
}));

Expand Down Expand Up @@ -128,11 +139,10 @@ const PARENT_PATHS = [
`${pathPrefix}.parentPath3`,
];

describe("FieldLabelWrapperComponent", () => {
describe.sequential("FieldLabelWrapperComponent", () => {
beforeEach(() => {
vi.mocked(isFieldDisabled).mockReturnValue({
isDisabled: false,
// @ts-expect-error - reason is an unexported literal
reason: "",
});

Expand Down Expand Up @@ -237,7 +247,6 @@ describe("FieldLabelWrapperComponent", () => {
test("renders with correct class when field is disabled", async () => {
vi.mocked(isFieldDisabled).mockReturnValue({
isDisabled: true,
// @ts-expect-error - reason is an unexported literal
reason: "You have only read access to this field",
});
const { findByTestId } = await asyncRender(
Expand All @@ -262,20 +271,10 @@ describe("FieldLabelWrapperComponent", () => {

test("calls isFieldDisabled with correct arguments", async () => {
const mockFieldSchema = { ...singleLineFieldSchema };
const mockEntryPermissions = {
create: true,
read: true,
update: false,
delete: true,
publish: true,
};

vi.mocked(FieldSchemaMap.getFieldSchema).mockResolvedValue(
mockFieldSchema
);
vi.mocked(getEntryPermissionsCached).mockResolvedValue(
mockEntryPermissions
);

await asyncRender(
<FieldLabelWrapperComponent
Expand All @@ -298,7 +297,23 @@ describe("FieldLabelWrapperComponent", () => {
expect(isFieldDisabled).toHaveBeenCalledWith(
mockFieldSchema,
mockEventDetails,
mockEntryPermissions
{
update: {
create: true,
read: true,
update: true,
delete: true,
publish: true,
},
},
{
stage: undefined,
permissions: {
entry: {
update: true,
},
},
}
);
});

Expand Down Expand Up @@ -351,7 +366,6 @@ describe("FieldLabelWrapperComponent", () => {
expect(fieldLabelWrapper).toHaveAttribute("data-hovered-cslp", mockFieldMetadata.cslpValue);
});


test("does not render ContentTypeIcon when loading", async () => {
// Mock the display names to never resolve to simulate loading state
vi.mocked(visualBuilderPostMessage!.send).mockImplementation(() => {
Expand Down
18 changes: 10 additions & 8 deletions src/visualBuilder/components/fieldLabelWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import { visualBuilderStyles } from "../visualBuilder.style";
import { CslpError } from "./CslpError";
import { hasPostMessageError } from "../utils/errorHandling";
import { VisualBuilderPostMessageEvents } from "../utils/types/postMessage.types";
import { getEntryPermissionsCached } from "../utils/getEntryPermissionsCached";
import { ContentTypeIcon } from "./icons";
import { ToolbarTooltip } from "./Tooltip";
import { fetchEntryPermissionsAndStageDetails } from "../utils/fetchEntryPermissionsAndStageDetails";

interface ReferenceParentMap {
[entryUid: string]: {
Expand Down Expand Up @@ -55,7 +55,6 @@ async function getReferenceParentMap() {
console.warn("[getFieldLabelWrapper] Error getting reference parent map", e);
return {};
}

}

interface FieldLabelWrapperProps {
Expand Down Expand Up @@ -157,15 +156,18 @@ function FieldLabelWrapperComponent(
return;
}

const entryPermissions = await getEntryPermissionsCached({
entryUid: props.fieldMetadata.entry_uid,
contentTypeUid: props.fieldMetadata.content_type_uid,
locale: props.fieldMetadata.locale,
});
const { acl: entryAcl, workflowStage: entryWorkflowStageDetails } =
await fetchEntryPermissionsAndStageDetails({
entryUid: props.fieldMetadata.entry_uid,
contentTypeUid: props.fieldMetadata.content_type_uid,
locale: props.fieldMetadata.locale,
variantUid: props.fieldMetadata.variant,
});
const { isDisabled: fieldDisabled, reason } = isFieldDisabled(
fieldSchema,
eventDetails,
entryPermissions
entryAcl,
entryWorkflowStageDetails
);

const currentFieldDisplayName =
Expand Down
23 changes: 22 additions & 1 deletion src/visualBuilder/generators/__test__/generateToolbar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { appendFieldPathDropdown } from "../generateToolbar";
import visualBuilderPostMessage from "../../utils/visualBuilderPostMessage";
import { VisualBuilderPostMessageEvents } from "../../utils/types/postMessage.types";
import { singleLineFieldSchema } from "../../../__test__/data/fields";
import { sleep } from "../../../__test__/utils";

const MOCK_CSLP = "all_fields.bltapikey.en-us.single_line";

Expand All @@ -17,6 +16,28 @@ global.ResizeObserver = vi.fn().mockImplementation(() => ({
disconnect: vi.fn(),
}));

vi.mock("../../utils/fetchEntryPermissionsAndStageDetails", () => ({
fetchEntryPermissionsAndStageDetails: async () => ({
acl: {
update: {
create: true,
read: true,
update: true,
delete: true,
publish: true,
},
},
workflowStage: {
stage: undefined,
permissions: {
entry: {
update: true,
},
},
},
}),
}));

describe("appendFieldPathDropdown", () => {
let singleLineField: HTMLParagraphElement;
let focusedToolbar: HTMLDivElement;
Expand Down
Loading
Loading