diff --git a/packages/visual-editor/src/components/testing/screenshots/PhotoGallerySection/[desktop] version 59 with showSectionHeading false.png b/packages/visual-editor/src/components/testing/screenshots/PhotoGallerySection/[desktop] version 59 with showSectionHeading false.png index 78479fbdf2..b9bf47805f 100644 Binary files a/packages/visual-editor/src/components/testing/screenshots/PhotoGallerySection/[desktop] version 59 with showSectionHeading false.png and b/packages/visual-editor/src/components/testing/screenshots/PhotoGallerySection/[desktop] version 59 with showSectionHeading false.png differ diff --git a/packages/visual-editor/src/editor/yextEntityFieldUtils.test.ts b/packages/visual-editor/src/editor/yextEntityFieldUtils.test.ts index 5699749e05..71cbb969c9 100644 --- a/packages/visual-editor/src/editor/yextEntityFieldUtils.test.ts +++ b/packages/visual-editor/src/editor/yextEntityFieldUtils.test.ts @@ -50,7 +50,7 @@ describe("getFieldsForSelector", () => { ); }); - it("allows string descendants to satisfy rich text item source requirements", () => { + it("allows item sources when any descendant type matches", () => { const fields = getFieldsForSelector( { fields: [ @@ -82,7 +82,7 @@ describe("getFieldsForSelector", () => { }, }, { - itemSourceTypes: [["type.rich_text_v2"]], + itemSourceTypes: [["type.image"], ["type.rich_text_v2"]], } ); @@ -95,7 +95,7 @@ describe("getFieldsForSelector", () => { ); }); - it("applies rich text compatibility to mapped source descendant checks", () => { + it("hides item sources when no descendant types match", () => { const fields = getFieldsForSelector( { fields: [ @@ -127,17 +127,11 @@ describe("getFieldsForSelector", () => { }, }, { - mappedSourceTypes: [["type.rich_text_v2"]], + itemSourceTypes: [["type.image"], ["type.cta"]], } ); - expect(fields).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - name: "c_articles", - }), - ]) - ); + expect(fields).toEqual([]); }); it("merges duplicate scoped fields when one has a display name and another has nested children", () => { diff --git a/packages/visual-editor/src/editor/yextEntityFieldUtils.ts b/packages/visual-editor/src/editor/yextEntityFieldUtils.ts index 35cadf934c..3f3752c6ab 100644 --- a/packages/visual-editor/src/editor/yextEntityFieldUtils.ts +++ b/packages/visual-editor/src/editor/yextEntityFieldUtils.ts @@ -1,4 +1,5 @@ import { + type EntityFieldTypes, getFilteredEntityFields, getCompatibleEntityFieldTypes, RenderEntityFieldFilter, @@ -6,7 +7,6 @@ import { import { StreamFields, YextSchemaField } from "../types/entityFields.ts"; import { resolveField } from "../utils/resolveYextEntityField.ts"; import { type StreamDocument } from "../utils/types/StreamDocument.ts"; -import { getTopLevelLinkedEntitySourceFields } from "../utils/linkedEntityFieldUtils.ts"; import { getListSourceRootFields, type MappedSourceFieldFilter, @@ -205,16 +205,6 @@ export const getEntityFieldScopeDisplayName = ( return displayName?.split(DISPLAY_NAME_SEPARATOR).at(-1); }; -/** - * Returns whether a resolved mapped-source root is compatible with linked-item - * source selection: undefined, null, arrays, and object values are all valid. - */ -const isMappedListSourceValue = (value: unknown): boolean => - value === undefined || - value === null || - Array.isArray(value) || - (!!value && typeof value === "object"); - const hasListSourceValueInDocument = ( streamDocument: StreamDocument, fieldName: string @@ -315,9 +305,8 @@ const getScopedFieldsForSelector = ( * Returns the schema fields that should appear in an entity field selector. * * 1. Scope to a selected source item when `sourceField` is provided. - * 2. For item-source and mapped-source pickers, restrict roots to fields that - * can satisfy the required descendant type sets. `itemSourceTypes` takes - * precedence over `mappedSourceTypes` when both are present. + * 2. For item-source pickers, restrict roots to fields whose descendants can + * satisfy at least one configured type group. * 3. Filter incompatible resolved values out when a stream document is * available. * 4. Fall back to normal entity-field filtering for standard field selectors. @@ -332,8 +321,7 @@ export const getFieldsForSelector = ( return getScopedFieldsForSelector(entityFields, sourceField, filter); } - const requiredDescendantTypes = - filter.itemSourceTypes ?? filter.mappedSourceTypes; + const requiredDescendantTypes = filter.itemSourceTypes; const hasRequiredDescendants = (field: YextSchemaField): boolean => { if (!requiredDescendantTypes?.length) { @@ -347,7 +335,8 @@ export const getFieldsForSelector = ( } ); - return requiredDescendantTypes.every((requiredTypes) => + // One descendant match is enough for item-source selection. + const matchesRequiredTypes = (requiredTypes: EntityFieldTypes[]): boolean => availableFields.some( (availableField) => getFilteredEntityFields( @@ -357,8 +346,9 @@ export const getFieldsForSelector = ( types: requiredTypes.flatMap(getCompatibleEntityFieldTypes), } ).length > 0 - ) - ); + ); + + return requiredDescendantTypes.some(matchesRequiredTypes); }; if (filter.itemSourceTypes?.length) { @@ -382,46 +372,6 @@ export const getFieldsForSelector = ( ); } - if (filter.mappedSourceTypes?.length) { - const validLinkedEntityRootFields = getTopLevelLinkedEntitySourceFields( - entityFields - ) - .map((field) => ({ - ...field, - displayName: - getEntityFieldDisplayName(field.name, entityFields) ?? - field.displayName ?? - field.name, - })) - .filter(hasRequiredDescendants) - .filter((field) => - !streamDocument - ? true - : isMappedListSourceValue( - resolveField(streamDocument, field.name).value - ) - ); - const validListRootFields = getListSourceRootFields(entityFields) - .map((field) => ({ - ...field, - displayName: - getEntityFieldDisplayName(field.name, entityFields) ?? - field.displayName ?? - field.name, - })) - .filter(hasRequiredDescendants) - .filter((field) => - !streamDocument - ? true - : hasListSourceValueInDocument(streamDocument, field.name) - ); - - return sortFields([ - ...dedupeFieldsByName(validLinkedEntityRootFields), - ...dedupeFieldsByName(validListRootFields), - ]); - } - let filteredEntityFields = getFilteredEntityFields(entityFields, filter); if (filter.directChildrenOf && filteredEntityFields.length === 0) { diff --git a/packages/visual-editor/src/fields/EntityFieldSelectorField.test.tsx b/packages/visual-editor/src/fields/EntityFieldSelectorField.test.tsx index 318d601124..3b41be4efb 100644 --- a/packages/visual-editor/src/fields/EntityFieldSelectorField.test.tsx +++ b/packages/visual-editor/src/fields/EntityFieldSelectorField.test.tsx @@ -658,7 +658,7 @@ describe("EntityFieldSelectorField", () => { expect(tooltip).toBeDefined(); expect( within(tooltip).getByText( - "List elements must be able to satisfy the mapping requirements:" + "List elements should be able to satisfy the mapping requirements:" ) ).toBeDefined(); expect(within(tooltip).getByText("rich_text_v2")).toBeDefined(); diff --git a/packages/visual-editor/src/fields/EntityFieldSelectorField.tsx b/packages/visual-editor/src/fields/EntityFieldSelectorField.tsx index 02361c04f9..78b5cb4c11 100644 --- a/packages/visual-editor/src/fields/EntityFieldSelectorField.tsx +++ b/packages/visual-editor/src/fields/EntityFieldSelectorField.tsx @@ -402,7 +402,7 @@ export const ConstantValueModeToggler = ({ const locale = i18n.language; const itemSourceParentFieldTooltipTitle = pt( "itemSourceParentFieldTooltip", - "List elements must be able to satisfy the mapping requirements:" + "List elements should be able to satisfy the mapping requirements:" ); return ( diff --git a/packages/visual-editor/src/utils/cardSlots/mappedSource.ts b/packages/visual-editor/src/utils/cardSlots/mappedSource.ts index e0c5e2d80d..940646b69e 100644 --- a/packages/visual-editor/src/utils/cardSlots/mappedSource.ts +++ b/packages/visual-editor/src/utils/cardSlots/mappedSource.ts @@ -42,6 +42,4 @@ export type MappedSourceFieldFilter> = RenderEntityFieldFilter & { /** Higher-priority repeated-source constraints used by itemSource pickers. */ itemSourceTypes?: EntityFieldTypes[][]; - /** Used only when itemSourceTypes is not provided. */ - mappedSourceTypes?: EntityFieldTypes[][]; };