fix(summary-tab): fix structured property value type issue (#14644)

Co-authored-by: Chris Collins <chriscollins3456@gmail.com>
This commit is contained in:
purnimagarg1 2025-09-04 23:33:04 +05:30 committed by GitHub
parent 4341e64732
commit 03bca391d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 56 additions and 62 deletions

View File

@ -10,12 +10,12 @@ import EditStructuredPropertyModal from '@app/entity/shared/tabs/Properties/Edit
import { Icon, Input as InputComponent, Text, colors } from '@src/alchemy-components';
import { useUserContext } from '@src/app/context/useUserContext';
import { REDESIGN_COLORS } from '@src/app/entityV2/shared/constants';
import { getEntityTypesPropertyFilter, getNotHiddenPropertyFilter } from '@src/app/govern/structuredProperties/utils';
import { getStructuredPropertiesSearchInputs } from '@src/app/govern/structuredProperties/utils';
import { useEntityRegistry } from '@src/app/useEntityRegistry';
import { useIsThemeV2 } from '@src/app/useIsThemeV2';
import { PageRoutes } from '@src/conf/Global';
import { useGetSearchResultsForMultipleQuery } from '@src/graphql/search.generated';
import { EntityType, Maybe, StructuredProperties, StructuredPropertyEntity } from '@src/types.generated';
import { Maybe, StructuredProperties, StructuredPropertyEntity } from '@src/types.generated';
const AddButton = styled.div<{ isThemeV2: boolean; isV1Drawer?: boolean }>`
border-radius: 200px;
@ -87,26 +87,10 @@ const AddPropertyButton = ({ fieldUrn, refetch, fieldProperties, isV1Drawer }: P
const entityRegistry = useEntityRegistry();
const [isEditModalVisible, setIsEditModalVisible] = useState(false);
const inputs = {
types: [EntityType.StructuredProperty],
query: '',
start: 0,
count: 100,
searchFlags: { skipCache: true },
orFilters: [
{
and: [
getEntityTypesPropertyFilter(entityRegistry, !!fieldUrn, entityType),
getNotHiddenPropertyFilter(),
],
},
],
};
// Execute search
const { data, loading } = useGetSearchResultsForMultipleQuery({
variables: {
input: inputs,
input: getStructuredPropertiesSearchInputs(entityRegistry, entityType, fieldUrn, searchQuery),
},
fetchPolicy: 'cache-first',
});
@ -157,9 +141,6 @@ const AddPropertyButton = ({ fieldUrn, refetch, fieldProperties, isV1Drawer }: P
if (!canEditProperties) return null;
// Filter items based on search query
const filteredItems = properties?.filter((prop) => prop.name?.toLowerCase().includes(searchQuery.toLowerCase()));
const noDataText =
properties?.length === 0 ? (
<>
@ -177,7 +158,7 @@ const AddPropertyButton = ({ fieldUrn, refetch, fieldProperties, isV1Drawer }: P
<>
<Dropdown
trigger={['click']}
menu={{ items: filteredItems }}
menu={{ items: properties }}
dropdownRender={(menuNode) => (
<DropdownContainer>
<SearchContainer>
@ -195,7 +176,7 @@ const AddPropertyButton = ({ fieldUrn, refetch, fieldProperties, isV1Drawer }: P
</LoadingContainer>
) : (
<>
{filteredItems?.length === 0 && (
{properties?.length === 0 && (
<EmptyContainer>
<Text color="gray" weight="medium">
No results found

View File

@ -20,6 +20,7 @@ vi.mock('@app/govern/structuredProperties/utils', async () => {
getNotHiddenPropertyFilter: vi.fn(),
getValueTypeFilter: vi.fn(),
getDisplayNameFilter: vi.fn(),
getStructuredPropertiesSearchInputs: vi.fn(),
};
});
@ -33,6 +34,9 @@ const mockSearchResults = {
urn: 'urn1',
definition: {
displayName: 'First Property',
valueType: {
urn: 'urn:li:dataType:datahub.string',
},
},
},
},
@ -43,6 +47,22 @@ const mockSearchResults = {
urn: 'urn2',
definition: {
displayName: 'Second Property',
valueType: {
urn: 'urn:li:dataType:datahub.string',
},
},
},
},
{
entity: {
__typename: 'StructuredProperty',
type: EntityType.StructuredProperty,
urn: 'urn3',
definition: {
displayName: 'Rich Text Property',
valueType: {
urn: 'urn:li:dataType:datahub.rich_text', // should get filtered out
},
},
},
},
@ -66,6 +86,7 @@ describe('useStructuredProperties', () => {
(governUtils.getNotHiddenPropertyFilter as any).mockReturnValue({ field: 'test', values: [] });
(governUtils.getValueTypeFilter as any).mockReturnValue({ field: 'test', values: [] });
(governUtils.getDisplayNameFilter as any).mockReturnValue({ field: 'test', values: [] });
(governUtils.getStructuredPropertiesSearchInputs as any).mockReturnValue({ field: 'test', values: [] });
});
it('should correctly map search results to AssetProperty', () => {
@ -83,12 +104,6 @@ describe('useStructuredProperties', () => {
expect(firstProperty.structuredProperty?.definition.displayName).toBe('First Property');
});
it('should call getDisplayNameFilter when a query is provided', () => {
(useGetSearchResultsForMultipleQuery as any).mockReturnValue({ data: null, loading: false });
renderHook(() => useStructuredProperties('test query'));
expect(governUtils.getDisplayNameFilter).toHaveBeenCalledWith('test query');
});
it('should not call getDisplayNameFilter when query is empty', () => {
(useGetSearchResultsForMultipleQuery as any).mockReturnValue({ data: null, loading: false });
renderHook(() => useStructuredProperties(''));

View File

@ -3,19 +3,11 @@ import { useMemo } from 'react';
import { useEntityData } from '@app/entity/shared/EntityContext';
import { SUPPORTED_STRUCTURED_PROPERTY_VALUE_TYPES } from '@app/entityV2/summary/properties/constants';
import { AssetProperty } from '@app/entityV2/summary/properties/types';
import {
getDisplayNameFilter,
getEntityTypesPropertyFilter,
getNotHiddenPropertyFilter,
getValueTypeFilter,
isStructuredProperty,
} from '@app/govern/structuredProperties/utils';
import { getStructuredPropertiesSearchInputs, isStructuredProperty } from '@app/govern/structuredProperties/utils';
import { useEntityRegistry } from '@app/useEntityRegistry';
import { useGetSearchResultsForMultipleQuery } from '@graphql/search.generated';
import { EntityType, SummaryElementType } from '@types';
const MAX_PROPERTIES = 20;
import { SummaryElementType } from '@types';
export default function useStructuredProperties(query: string | undefined) {
const { entityType } = useEntityData();
@ -59,27 +51,9 @@ export default function useStructuredProperties(query: string | undefined) {
// SEARCH API
const inputs = {
types: [EntityType.StructuredProperty],
query: '*',
start: 0,
count: MAX_PROPERTIES,
searchFlags: { skipCache: true },
orFilters: [
{
and: [
getEntityTypesPropertyFilter(entityRegistry, false, entityType),
getNotHiddenPropertyFilter(),
getValueTypeFilter(SUPPORTED_STRUCTURED_PROPERTY_VALUE_TYPES),
...(preprocessedQuery ? [getDisplayNameFilter(preprocessedQuery)] : []),
],
},
],
};
const { data, loading } = useGetSearchResultsForMultipleQuery({
variables: {
input: inputs,
input: getStructuredPropertiesSearchInputs(entityRegistry, entityType, '', preprocessedQuery),
},
fetchPolicy: 'cache-first',
});
@ -89,6 +63,9 @@ export default function useStructuredProperties(query: string | undefined) {
((data?.searchAcrossEntities?.searchResults ?? [])
.map((result) => result.entity)
.filter(isStructuredProperty)
.filter((property) =>
SUPPORTED_STRUCTURED_PROPERTY_VALUE_TYPES.includes(property.definition.valueType.urn),
)
?.map((structuredProperty) => ({
key: structuredProperty.urn,
name: structuredProperty.definition.displayName ?? '',

View File

@ -283,3 +283,27 @@ export const getDisplayNameFilter = (displayNameQuery: string) => {
export function isStructuredProperty(entity?: Entity | null | undefined): entity is StructuredPropertyEntity {
return !!entity && entity.type === EntityType.StructuredProperty;
}
export function getStructuredPropertiesSearchInputs(
entityRegistry: EntityRegistry,
entityType: EntityType,
fieldUrn?: string,
nameQuery?: string,
) {
return {
types: [EntityType.StructuredProperty],
query: '*',
start: 0,
count: 100,
searchFlags: { skipCache: true },
orFilters: [
{
and: [
getEntityTypesPropertyFilter(entityRegistry, !!fieldUrn, entityType),
getNotHiddenPropertyFilter(),
...(nameQuery ? [getDisplayNameFilter(nameQuery)] : []),
],
},
],
};
}

View File

@ -24,9 +24,6 @@ record StructuredPropertyDefinition {
* The value type of the property. Must be a dataType.
* e.g. To indicate that the property is of type DATE, use urn:li:dataType:datahub.date
*/
@Searchable = {
"fieldType": "URN"
}
@UrnValidation = {
"exist": true,
"strict": true,