mirror of
https://github.com/datahub-project/datahub.git
synced 2025-11-10 16:32:26 +00:00
feat(ui): Edit glossary term descriptions via UI (#4156)
This commit is contained in:
parent
e3599c521c
commit
da74943485
@ -46,6 +46,7 @@ public class GlossaryTermType implements SearchableEntityType<GlossaryTerm>, Bro
|
||||
GLOSSARY_TERM_KEY_ASPECT_NAME,
|
||||
GLOSSARY_TERM_INFO_ASPECT_NAME,
|
||||
GLOSSARY_RELATED_TERM_ASPECT_NAME,
|
||||
INSTITUTIONAL_MEMORY_ASPECT_NAME,
|
||||
OWNERSHIP_ASPECT_NAME,
|
||||
STATUS_ASPECT_NAME,
|
||||
BROWSE_PATHS_ASPECT_NAME,
|
||||
@ -76,7 +77,7 @@ public class GlossaryTermType implements SearchableEntityType<GlossaryTerm>, Bro
|
||||
|
||||
try {
|
||||
final Map<Urn, EntityResponse> glossaryTermMap = _entityClient.batchGetV2(GLOSSARY_TERM_ENTITY_NAME,
|
||||
new HashSet<>(glossaryTermUrns), null, context.getAuthentication());
|
||||
new HashSet<>(glossaryTermUrns), ASPECTS_TO_RESOLVE, context.getAuthentication());
|
||||
|
||||
final List<EntityResponse> gmsResults = new ArrayList<>();
|
||||
for (Urn urn : glossaryTermUrns) {
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
package com.linkedin.datahub.graphql.types.glossary.mappers;
|
||||
|
||||
import com.linkedin.common.Deprecation;
|
||||
import com.linkedin.common.InstitutionalMemory;
|
||||
import com.linkedin.common.Ownership;
|
||||
import com.linkedin.data.DataMap;
|
||||
import com.linkedin.data.template.RecordTemplate;
|
||||
import com.linkedin.datahub.graphql.generated.EntityType;
|
||||
import com.linkedin.datahub.graphql.generated.GlossaryTerm;
|
||||
import com.linkedin.datahub.graphql.types.common.mappers.DeprecationMapper;
|
||||
import com.linkedin.datahub.graphql.types.common.mappers.InstitutionalMemoryMapper;
|
||||
import com.linkedin.datahub.graphql.types.common.mappers.OwnershipMapper;
|
||||
import com.linkedin.datahub.graphql.types.common.mappers.util.MappingHelper;
|
||||
import com.linkedin.datahub.graphql.types.glossary.GlossaryTermUtils;
|
||||
@ -30,31 +32,43 @@ public class GlossaryTermMapper implements ModelMapper<EntityResponse, GlossaryT
|
||||
public static final GlossaryTermMapper INSTANCE = new GlossaryTermMapper();
|
||||
|
||||
public static GlossaryTerm map(@Nonnull final EntityResponse entityResponse) {
|
||||
return INSTANCE.apply(entityResponse);
|
||||
return INSTANCE.apply(entityResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlossaryTerm apply(@Nonnull final EntityResponse entityResponse) {
|
||||
GlossaryTerm result = new GlossaryTerm();
|
||||
result.setUrn(entityResponse.getUrn().toString());
|
||||
result.setType(EntityType.GLOSSARY_TERM);
|
||||
GlossaryTerm result = new GlossaryTerm();
|
||||
result.setUrn(entityResponse.getUrn().toString());
|
||||
result.setType(EntityType.GLOSSARY_TERM);
|
||||
final String legacyName = GlossaryTermUtils.getGlossaryTermName(entityResponse.getUrn().getId());
|
||||
|
||||
EnvelopedAspectMap aspectMap = entityResponse.getAspects();
|
||||
MappingHelper<GlossaryTerm> mappingHelper = new MappingHelper<>(aspectMap, result);
|
||||
mappingHelper.mapToResult(GLOSSARY_TERM_KEY_ASPECT_NAME, this::mapGlossaryTermKey);
|
||||
mappingHelper.mapToResult(GLOSSARY_TERM_INFO_ASPECT_NAME, (glossaryTerm, dataMap) ->
|
||||
glossaryTerm.setGlossaryTermInfo(GlossaryTermInfoMapper.map(new GlossaryTermInfo(dataMap))));
|
||||
mappingHelper.mapToResult(OWNERSHIP_ASPECT_NAME, (glossaryTerm, dataMap) ->
|
||||
glossaryTerm.setOwnership(OwnershipMapper.map(new Ownership(dataMap))));
|
||||
EnvelopedAspectMap aspectMap = entityResponse.getAspects();
|
||||
MappingHelper<GlossaryTerm> mappingHelper = new MappingHelper<>(aspectMap, result);
|
||||
mappingHelper.mapToResult(GLOSSARY_TERM_KEY_ASPECT_NAME, this::mapGlossaryTermKey);
|
||||
mappingHelper.mapToResult(GLOSSARY_TERM_INFO_ASPECT_NAME, (glossaryTerm, dataMap) ->
|
||||
glossaryTerm.setGlossaryTermInfo(GlossaryTermInfoMapper.map(new GlossaryTermInfo(dataMap))));
|
||||
mappingHelper.mapToResult(GLOSSARY_TERM_INFO_ASPECT_NAME, (glossaryTerm, dataMap) ->
|
||||
glossaryTerm.setProperties(GlossaryTermPropertiesMapper.map(new GlossaryTermInfo(dataMap))));
|
||||
mappingHelper.mapToResult(OWNERSHIP_ASPECT_NAME, (glossaryTerm, dataMap) ->
|
||||
glossaryTerm.setOwnership(OwnershipMapper.map(new Ownership(dataMap))));
|
||||
mappingHelper.mapToResult(DEPRECATION_ASPECT_NAME, (glossaryTerm, dataMap) ->
|
||||
glossaryTerm.setDeprecation(DeprecationMapper.map(new Deprecation(dataMap))));
|
||||
glossaryTerm.setDeprecation(DeprecationMapper.map(new Deprecation(dataMap))));
|
||||
mappingHelper.mapToResult(INSTITUTIONAL_MEMORY_ASPECT_NAME, (dataset, dataMap) ->
|
||||
dataset.setInstitutionalMemory(InstitutionalMemoryMapper.map(new InstitutionalMemory(dataMap))));
|
||||
|
||||
return mappingHelper.getResult();
|
||||
// If there's no name property, resort to the legacy name computation.
|
||||
if (result.getGlossaryTermInfo() != null && result.getGlossaryTermInfo().getName() == null) {
|
||||
result.getGlossaryTermInfo().setName(legacyName);
|
||||
}
|
||||
if (result.getProperties() != null && result.getProperties().getName() == null) {
|
||||
result.getProperties().setName(legacyName);
|
||||
}
|
||||
return mappingHelper.getResult();
|
||||
}
|
||||
|
||||
private void mapGlossaryTermKey(@Nonnull GlossaryTerm glossaryTerm, @Nonnull DataMap dataMap) {
|
||||
GlossaryTermKey glossaryTermKey = new GlossaryTermKey(dataMap);
|
||||
glossaryTerm.setName(GlossaryTermUtils.getGlossaryTermName(glossaryTermKey.getName()));
|
||||
glossaryTerm.setHierarchicalName(glossaryTermKey.getName());
|
||||
GlossaryTermKey glossaryTermKey = new GlossaryTermKey(dataMap);
|
||||
glossaryTerm.setName(GlossaryTermUtils.getGlossaryTermName(glossaryTermKey.getName()));
|
||||
glossaryTerm.setHierarchicalName(glossaryTermKey.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,14 +36,21 @@ public class TagMapper implements ModelMapper<EntityResponse, Tag> {
|
||||
final Tag result = new Tag();
|
||||
result.setUrn(entityResponse.getUrn().toString());
|
||||
result.setType(EntityType.TAG);
|
||||
|
||||
final String legacyName = entityResponse.getUrn().getId();
|
||||
result.setName(legacyName);
|
||||
|
||||
EnvelopedAspectMap aspectMap = entityResponse.getAspects();
|
||||
MappingHelper<Tag> mappingHelper = new MappingHelper<>(aspectMap, result);
|
||||
mappingHelper.mapToResult(TAG_KEY_ASPECT_NAME, this::mapTagKey);
|
||||
mappingHelper.mapToResult(TAG_PROPERTIES_ASPECT_NAME, (tag, dataMap) ->
|
||||
tag.setDescription(new TagProperties(dataMap).getDescription()));
|
||||
mappingHelper.mapToResult(TAG_PROPERTIES_ASPECT_NAME, this::mapTagProperties);
|
||||
mappingHelper.mapToResult(OWNERSHIP_ASPECT_NAME, (tag, dataMap) ->
|
||||
tag.setOwnership(OwnershipMapper.map(new Ownership(dataMap))));
|
||||
|
||||
if (result.getProperties() != null && result.getProperties().getName() == null) {
|
||||
result.getProperties().setName(legacyName);
|
||||
}
|
||||
|
||||
return mappingHelper.getResult();
|
||||
}
|
||||
|
||||
|
||||
@ -802,6 +802,11 @@ type GlossaryTerm implements Entity {
|
||||
"""
|
||||
ownership: Ownership
|
||||
|
||||
"""
|
||||
References to internal resources related to the Glossary Term
|
||||
"""
|
||||
institutionalMemory: InstitutionalMemory
|
||||
|
||||
"""
|
||||
A standard Entity Type
|
||||
"""
|
||||
@ -818,7 +823,7 @@ type GlossaryTerm implements Entity {
|
||||
hierarchicalName: String!
|
||||
|
||||
"""
|
||||
Additional read only properties associated with the Glossary Term
|
||||
Additional properties associated with the Glossary Term
|
||||
"""
|
||||
properties: GlossaryTermProperties
|
||||
|
||||
@ -858,7 +863,7 @@ type GlossaryTermInfo {
|
||||
"""
|
||||
Description of the glossary term
|
||||
"""
|
||||
description: String!
|
||||
description: String
|
||||
|
||||
"""
|
||||
Definition of the glossary term. Deprecated - Use 'description' instead.
|
||||
@ -898,12 +903,12 @@ type GlossaryTermProperties {
|
||||
"""
|
||||
The name of the Glossary Term
|
||||
"""
|
||||
name: String
|
||||
name: String!
|
||||
|
||||
"""
|
||||
Description of the glossary term
|
||||
"""
|
||||
description: String!
|
||||
description: String
|
||||
|
||||
"""
|
||||
Definition of the glossary term. Deprecated - Use 'description' instead.
|
||||
@ -2579,7 +2584,7 @@ type TagProperties {
|
||||
"""
|
||||
A display name for the Tag
|
||||
"""
|
||||
name: String
|
||||
name: String!
|
||||
|
||||
"""
|
||||
A description of the Tag
|
||||
|
||||
@ -839,12 +839,16 @@ const glossaryTerm3 = {
|
||||
hasRelatedTerms: [
|
||||
{
|
||||
urn: 'urn:li:glossaryTerm:example.glossaryterm3',
|
||||
name: 'glossaryterm3',
|
||||
properties: {
|
||||
name: 'glossaryterm3',
|
||||
},
|
||||
__typename: 'GlossaryTerm',
|
||||
},
|
||||
{
|
||||
urn: 'urn:li:glossaryTerm:example.glossaryterm4',
|
||||
name: 'glossaryterm4',
|
||||
properties: {
|
||||
name: 'glossaryterm4',
|
||||
},
|
||||
__typename: 'GlossaryTerm',
|
||||
},
|
||||
],
|
||||
|
||||
@ -121,8 +121,8 @@ export const sampleSchemaWithTags: Schema = {
|
||||
{
|
||||
term: {
|
||||
type: EntityType.GlossaryTerm,
|
||||
urn: 'urn:li:glossaryTerm:sample-glossary-term',
|
||||
name: 'sample-glossary-term',
|
||||
urn: 'urn:li:glossaryTerm:sample-glossary-term',
|
||||
hierarchicalName: 'example.sample-glossary-term',
|
||||
properties: {
|
||||
name: 'sample-glossary-term',
|
||||
|
||||
@ -11,8 +11,9 @@ import { SchemaTab } from '../shared/tabs/Dataset/Schema/SchemaTab';
|
||||
import GlossaryRelatedEntity from './profile/GlossaryRelatedEntity';
|
||||
import GlossayRelatedTerms from './profile/GlossaryRelatedTerms';
|
||||
import { SidebarOwnerSection } from '../shared/containers/profile/sidebar/Ownership/SidebarOwnerSection';
|
||||
import GlossarySidebarAboutSection from './profile/GlossarySidebarAboutSection';
|
||||
import { PropertiesTab } from '../shared/tabs/Properties/PropertiesTab';
|
||||
import { DocumentationTab } from '../shared/tabs/Documentation/DocumentationTab';
|
||||
import { SidebarAboutSection } from '../shared/containers/profile/sidebar/SidebarAboutSection';
|
||||
|
||||
/**
|
||||
* Definition of the DataHub Dataset entity.
|
||||
@ -64,6 +65,10 @@ export class GlossaryTermEntity implements Entity<GlossaryTerm> {
|
||||
name: 'Related Entities',
|
||||
component: GlossaryRelatedEntity,
|
||||
},
|
||||
{
|
||||
name: 'Documentation',
|
||||
component: DocumentationTab,
|
||||
},
|
||||
{
|
||||
name: 'Schema',
|
||||
component: SchemaTab,
|
||||
@ -88,7 +93,7 @@ export class GlossaryTermEntity implements Entity<GlossaryTerm> {
|
||||
]}
|
||||
sidebarSections={[
|
||||
{
|
||||
component: GlossarySidebarAboutSection,
|
||||
component: SidebarAboutSection,
|
||||
},
|
||||
{
|
||||
component: SidebarOwnerSection,
|
||||
@ -102,7 +107,7 @@ export class GlossaryTermEntity implements Entity<GlossaryTerm> {
|
||||
getOverridePropertiesFromEntity = (glossaryTerm?: GlossaryTerm | null): GenericEntityProperties => {
|
||||
// if dataset has subTypes filled out, pick the most specific subtype and return it
|
||||
return {
|
||||
customProperties: glossaryTerm?.glossaryTermInfo?.customProperties,
|
||||
customProperties: glossaryTerm?.properties?.customProperties,
|
||||
};
|
||||
};
|
||||
|
||||
@ -114,15 +119,15 @@ export class GlossaryTermEntity implements Entity<GlossaryTerm> {
|
||||
return (
|
||||
<Preview
|
||||
urn={data?.urn}
|
||||
name={data?.name}
|
||||
definition={data?.glossaryTermInfo?.definition}
|
||||
name={this.displayName(data)}
|
||||
description={data?.properties?.description || ''}
|
||||
owners={data?.ownership?.owners}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
displayName = (data: GlossaryTerm) => {
|
||||
return data.name;
|
||||
return data.properties?.name || data.name || data.urn;
|
||||
};
|
||||
|
||||
platformLogoUrl = (_: GlossaryTerm) => {
|
||||
|
||||
@ -7,12 +7,12 @@ import { useEntityRegistry } from '../../../useEntityRegistry';
|
||||
export const Preview = ({
|
||||
urn,
|
||||
name,
|
||||
definition,
|
||||
description,
|
||||
owners,
|
||||
}: {
|
||||
urn: string;
|
||||
name: string;
|
||||
definition?: string | null;
|
||||
description?: string | null;
|
||||
owners?: Array<Owner> | null;
|
||||
}): JSX.Element => {
|
||||
const entityRegistry = useEntityRegistry();
|
||||
@ -20,7 +20,7 @@ export const Preview = ({
|
||||
<DefaultPreviewCard
|
||||
url={entityRegistry.getEntityUrl(EntityType.GlossaryTerm, urn)}
|
||||
name={name || ''}
|
||||
description={definition || ''}
|
||||
description={description || ''}
|
||||
owners={owners}
|
||||
logoComponent={<BookOutlined style={{ fontSize: '20px' }} />}
|
||||
type="Glossary Term"
|
||||
|
||||
@ -13,7 +13,7 @@ describe('Preview', () => {
|
||||
<Preview
|
||||
urn="urn:li:glossaryTerm:instruments.FinancialInstrument_v1"
|
||||
name="name"
|
||||
definition="definition"
|
||||
description="definition"
|
||||
owners={null}
|
||||
/>
|
||||
</TestPageContainer>
|
||||
|
||||
@ -68,7 +68,7 @@ export class TagEntity implements Entity<Tag> {
|
||||
};
|
||||
|
||||
displayName = (data: Tag) => {
|
||||
return data.name;
|
||||
return data.properties?.name || data.name || data.urn;
|
||||
};
|
||||
|
||||
getGenericEntityProperties = (tag: Tag) => {
|
||||
|
||||
@ -160,7 +160,7 @@ export default function TagTermGroup({
|
||||
<TagLink to={entityRegistry.getEntityUrl(EntityType.GlossaryTerm, term.term.urn)} key={term.term.urn}>
|
||||
<Tag closable={false}>
|
||||
<BookOutlined style={{ marginRight: '3%' }} />
|
||||
{term.term.name}
|
||||
{entityRegistry.getDisplayName(EntityType.GlossaryTerm, term.term)}
|
||||
</Tag>
|
||||
</TagLink>
|
||||
))}
|
||||
@ -174,7 +174,7 @@ export default function TagTermGroup({
|
||||
}}
|
||||
>
|
||||
<BookOutlined style={{ marginRight: '3%' }} />
|
||||
{term.term.name}
|
||||
{entityRegistry.getDisplayName(EntityType.GlossaryTerm, term.term)}
|
||||
</Tag>
|
||||
</TagLink>
|
||||
))}
|
||||
@ -185,7 +185,7 @@ export default function TagTermGroup({
|
||||
return (
|
||||
<TagLink to={entityRegistry.getEntityUrl(EntityType.Tag, tag.tag.urn)} key={tag.tag.urn}>
|
||||
<StyledTag $colorHash={tag.tag.urn} closable={false}>
|
||||
{tag.tag.name}
|
||||
{entityRegistry.getDisplayName(EntityType.Tag, tag.tag)}
|
||||
</StyledTag>
|
||||
</TagLink>
|
||||
);
|
||||
|
||||
@ -71,11 +71,12 @@ query getBrowseResults($input: BrowseInput!) {
|
||||
}
|
||||
}
|
||||
... on GlossaryTerm {
|
||||
name
|
||||
ownership {
|
||||
...ownershipFields
|
||||
}
|
||||
glossaryTermInfo {
|
||||
properties {
|
||||
name
|
||||
description
|
||||
definition
|
||||
termSource
|
||||
sourceRef
|
||||
|
||||
@ -32,5 +32,8 @@ query getContainer($urn: String!) {
|
||||
container {
|
||||
...entityContainer
|
||||
}
|
||||
domain {
|
||||
...entityDomain
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,9 @@ fragment glossaryTerms on GlossaryTerms {
|
||||
term {
|
||||
urn
|
||||
name
|
||||
properties {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,8 +31,12 @@ query getGlossaryTerm($urn: String!, $start: Int, $count: Int) {
|
||||
ownership {
|
||||
...ownershipFields
|
||||
}
|
||||
glossaryTermInfo {
|
||||
definition
|
||||
institutionalMemory {
|
||||
...institutionalMemoryFields
|
||||
}
|
||||
properties {
|
||||
name
|
||||
description
|
||||
termSource
|
||||
sourceRef
|
||||
sourceUrl
|
||||
@ -42,10 +46,8 @@ query getGlossaryTerm($urn: String!, $start: Int, $count: Int) {
|
||||
value
|
||||
}
|
||||
}
|
||||
schemaMetadata(version: 0) {
|
||||
schemaMetadata(version: 0) {
|
||||
...schemaMetadataFields
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -186,11 +186,13 @@ fragment entityPreview on Entity {
|
||||
... on GlossaryTerm {
|
||||
name
|
||||
hierarchicalName
|
||||
glossaryTermInfo {
|
||||
definition
|
||||
properties {
|
||||
name
|
||||
description
|
||||
termSource
|
||||
sourceRef
|
||||
sourceUrl
|
||||
rawSchema
|
||||
customProperties {
|
||||
key
|
||||
value
|
||||
|
||||
@ -219,11 +219,13 @@ fragment searchResults on SearchResults {
|
||||
... on GlossaryTerm {
|
||||
name
|
||||
hierarchicalName
|
||||
glossaryTermInfo {
|
||||
definition
|
||||
properties {
|
||||
name
|
||||
description
|
||||
termSource
|
||||
sourceRef
|
||||
sourceUrl
|
||||
rawSchema
|
||||
customProperties {
|
||||
key
|
||||
value
|
||||
@ -345,7 +347,9 @@ fragment searchResults on SearchResults {
|
||||
description
|
||||
}
|
||||
... on GlossaryTerm {
|
||||
name
|
||||
properties {
|
||||
name
|
||||
}
|
||||
}
|
||||
... on DataPlatform {
|
||||
...platformFields
|
||||
|
||||
@ -76,6 +76,7 @@ entities:
|
||||
keyAspect: glossaryTermKey
|
||||
aspects:
|
||||
- glossaryTermInfo
|
||||
- institutionalMemory
|
||||
- schemaMetadata
|
||||
- ownership
|
||||
- deprecation
|
||||
|
||||
@ -32,5 +32,5 @@ dependencies {
|
||||
because("previous versions are vulnerable to CVE-2021-45105")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -134,7 +134,7 @@ public class Constants {
|
||||
// Policy
|
||||
public static final String DATAHUB_POLICY_INFO_ASPECT_NAME = "dataHubPolicyInfo";
|
||||
|
||||
//Tag
|
||||
// Tag
|
||||
public static final String TAG_KEY_ASPECT_NAME = "tagKey";
|
||||
public static final String TAG_PROPERTIES_ASPECT_NAME = "tagProperties";
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user