mirror of
https://github.com/datahub-project/datahub.git
synced 2025-11-02 11:49:23 +00:00
feat(ui): Changes to allow editable dataset name (#10608)
Co-authored-by: Jay Kadambi <jayasimhan_venkatadri@optum.com>
This commit is contained in:
parent
aa07e2a937
commit
3a38415d6b
@ -21,5 +21,6 @@ public class FeatureFlags {
|
||||
private boolean schemaFieldEntityFetchEnabled = false;
|
||||
private boolean businessAttributeEntityEnabled = false;
|
||||
private boolean dataContractsEnabled = false;
|
||||
private boolean editableDatasetNameEnabled = false;
|
||||
private boolean showSeparateSiblings = false;
|
||||
}
|
||||
|
@ -186,6 +186,7 @@ public class AppConfigResolver implements DataFetcher<CompletableFuture<AppConfi
|
||||
.setNestedDomainsEnabled(_featureFlags.isNestedDomainsEnabled())
|
||||
.setPlatformBrowseV2(_featureFlags.isPlatformBrowseV2())
|
||||
.setDataContractsEnabled(_featureFlags.isDataContractsEnabled())
|
||||
.setEditableDatasetNameEnabled(_featureFlags.isEditableDatasetNameEnabled())
|
||||
.setShowSeparateSiblings(_featureFlags.isShowSeparateSiblings())
|
||||
.build();
|
||||
|
||||
|
@ -4,9 +4,11 @@ import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.bindArgument;
|
||||
import static com.linkedin.datahub.graphql.resolvers.mutate.MutationUtils.persistAspect;
|
||||
|
||||
import com.linkedin.businessattribute.BusinessAttributeInfo;
|
||||
import com.linkedin.common.AuditStamp;
|
||||
import com.linkedin.common.urn.CorpuserUrn;
|
||||
import com.linkedin.common.urn.Urn;
|
||||
import com.linkedin.common.urn.UrnUtils;
|
||||
import com.linkedin.data.template.SetMode;
|
||||
import com.linkedin.datahub.graphql.QueryContext;
|
||||
import com.linkedin.datahub.graphql.authorization.AuthorizationUtils;
|
||||
import com.linkedin.datahub.graphql.concurrency.GraphQLConcurrencyUtils;
|
||||
@ -20,6 +22,7 @@ import com.linkedin.datahub.graphql.resolvers.mutate.util.BusinessAttributeUtils
|
||||
import com.linkedin.datahub.graphql.resolvers.mutate.util.DomainUtils;
|
||||
import com.linkedin.datahub.graphql.resolvers.mutate.util.GlossaryUtils;
|
||||
import com.linkedin.dataproduct.DataProductProperties;
|
||||
import com.linkedin.dataset.EditableDatasetProperties;
|
||||
import com.linkedin.domain.DomainProperties;
|
||||
import com.linkedin.domain.Domains;
|
||||
import com.linkedin.entity.client.EntityClient;
|
||||
@ -70,6 +73,8 @@ public class UpdateNameResolver implements DataFetcher<CompletableFuture<Boolean
|
||||
return updateDataProductName(targetUrn, input, context);
|
||||
case Constants.BUSINESS_ATTRIBUTE_ENTITY_NAME:
|
||||
return updateBusinessAttributeName(targetUrn, input, environment.getContext());
|
||||
case Constants.DATASET_ENTITY_NAME:
|
||||
return updateDatasetName(targetUrn, input, environment.getContext());
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
String.format(
|
||||
@ -236,6 +241,37 @@ public class UpdateNameResolver implements DataFetcher<CompletableFuture<Boolean
|
||||
"Unauthorized to perform this action. Please contact your DataHub administrator.");
|
||||
}
|
||||
|
||||
// udpates editable dataset properties aspect's name field
|
||||
private Boolean updateDatasetName(Urn targetUrn, UpdateNameInput input, QueryContext context) {
|
||||
if (AuthorizationUtils.canEditProperties(targetUrn, context)) {
|
||||
try {
|
||||
if (input.getName() != null) {
|
||||
final EditableDatasetProperties editableDatasetProperties =
|
||||
new EditableDatasetProperties();
|
||||
editableDatasetProperties.setName(input.getName());
|
||||
final AuditStamp auditStamp = new AuditStamp();
|
||||
Urn actor = UrnUtils.getUrn(context.getActorUrn());
|
||||
auditStamp.setActor(actor, SetMode.IGNORE_NULL);
|
||||
auditStamp.setTime(System.currentTimeMillis());
|
||||
editableDatasetProperties.setLastModified(auditStamp);
|
||||
persistAspect(
|
||||
context.getOperationContext(),
|
||||
targetUrn,
|
||||
Constants.EDITABLE_DATASET_PROPERTIES_ASPECT_NAME,
|
||||
editableDatasetProperties,
|
||||
actor,
|
||||
_entityService);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
String.format("Failed to perform update against input %s", input), e);
|
||||
}
|
||||
}
|
||||
throw new AuthorizationException(
|
||||
"Unauthorized to perform this action. Please contact your DataHub administrator.");
|
||||
}
|
||||
|
||||
private Boolean updateDataProductName(
|
||||
Urn targetUrn, UpdateNameInput input, QueryContext context) {
|
||||
try {
|
||||
|
@ -222,6 +222,7 @@ public class DatasetMapper implements ModelMapper<EntityResponse, Dataset> {
|
||||
properties.setQualifiedName(gmsProperties.getQualifiedName());
|
||||
dataset.setProperties(properties);
|
||||
dataset.setDescription(properties.getDescription());
|
||||
dataset.setName(properties.getName());
|
||||
if (gmsProperties.getUri() != null) {
|
||||
dataset.setUri(gmsProperties.getUri().toString());
|
||||
}
|
||||
@ -248,6 +249,9 @@ public class DatasetMapper implements ModelMapper<EntityResponse, Dataset> {
|
||||
new EditableDatasetProperties(dataMap);
|
||||
final DatasetEditableProperties editableProperties = new DatasetEditableProperties();
|
||||
editableProperties.setDescription(editableDatasetProperties.getDescription());
|
||||
if (editableDatasetProperties.getName() != null) {
|
||||
editableProperties.setName(editableDatasetProperties.getName());
|
||||
}
|
||||
dataset.setEditableProperties(editableProperties);
|
||||
}
|
||||
|
||||
|
@ -111,8 +111,13 @@ public class DatasetUpdateInputMapper
|
||||
|
||||
if (datasetUpdateInput.getEditableProperties() != null) {
|
||||
final EditableDatasetProperties editableDatasetProperties = new EditableDatasetProperties();
|
||||
editableDatasetProperties.setDescription(
|
||||
datasetUpdateInput.getEditableProperties().getDescription());
|
||||
if (datasetUpdateInput.getEditableProperties().getDescription() != null) {
|
||||
editableDatasetProperties.setDescription(
|
||||
datasetUpdateInput.getEditableProperties().getDescription());
|
||||
}
|
||||
if (datasetUpdateInput.getEditableProperties().getName() != null) {
|
||||
editableDatasetProperties.setName(datasetUpdateInput.getEditableProperties().getName());
|
||||
}
|
||||
editableDatasetProperties.setLastModified(auditStamp);
|
||||
editableDatasetProperties.setCreated(auditStamp);
|
||||
proposals.add(
|
||||
|
@ -508,6 +508,11 @@ type FeatureFlagsConfig {
|
||||
"""
|
||||
dataContractsEnabled: Boolean!
|
||||
|
||||
"""
|
||||
Whether dataset names are editable
|
||||
"""
|
||||
editableDatasetNameEnabled: Boolean!
|
||||
|
||||
"""
|
||||
If turned on, all siblings will be separated with no way to get to a "combined" sibling view
|
||||
"""
|
||||
|
@ -3482,6 +3482,11 @@ type DatasetEditableProperties {
|
||||
Description of the Dataset
|
||||
"""
|
||||
description: String
|
||||
|
||||
"""
|
||||
Editable name of the Dataset
|
||||
"""
|
||||
name: String
|
||||
}
|
||||
|
||||
"""
|
||||
@ -4850,6 +4855,10 @@ input DatasetEditablePropertiesUpdate {
|
||||
Writable description aka documentation for a Dataset
|
||||
"""
|
||||
description: String!
|
||||
"""
|
||||
Editable name of the Dataset
|
||||
"""
|
||||
name: String
|
||||
}
|
||||
|
||||
"""
|
||||
|
@ -220,6 +220,7 @@ export class DatasetEntity implements Entity<Dataset> {
|
||||
},
|
||||
]}
|
||||
sidebarSections={this.getSidebarSections()}
|
||||
isNameEditable
|
||||
/>
|
||||
);
|
||||
|
||||
@ -283,7 +284,7 @@ export class DatasetEntity implements Entity<Dataset> {
|
||||
return (
|
||||
<Preview
|
||||
urn={data.urn}
|
||||
name={data.properties?.name || data.name}
|
||||
name={data.editableProperties?.name || data.properties?.name || data.name}
|
||||
origin={data.origin}
|
||||
subtype={data.subTypes?.typeNames?.[0]}
|
||||
description={data.editableProperties?.description || data.properties?.description}
|
||||
@ -311,7 +312,7 @@ export class DatasetEntity implements Entity<Dataset> {
|
||||
return (
|
||||
<Preview
|
||||
urn={data.urn}
|
||||
name={data.properties?.name || data.name}
|
||||
name={data.editableProperties?.name || data.properties?.name || data.name}
|
||||
origin={data.origin}
|
||||
description={data.editableProperties?.description || data.properties?.description}
|
||||
platformName={
|
||||
@ -361,7 +362,7 @@ export class DatasetEntity implements Entity<Dataset> {
|
||||
};
|
||||
|
||||
displayName = (data: Dataset) => {
|
||||
return data?.properties?.name || data.name || data.urn;
|
||||
return data?.editableProperties?.name || data?.properties?.name || data.name || data.urn;
|
||||
};
|
||||
|
||||
platformLogoUrl = (data: Dataset) => {
|
||||
|
@ -17,6 +17,7 @@ import { capitalizeFirstLetterOnly } from '../../../../../shared/textUtil';
|
||||
import { useUserContext } from '../../../../../context/useUserContext';
|
||||
import { useEntityRegistry } from '../../../../../useEntityRegistry';
|
||||
import EntityHeaderLoadingSection from './EntityHeaderLoadingSection';
|
||||
import { useIsEditableDatasetNameEnabled } from '../../../../../useAppConfig';
|
||||
|
||||
const TitleWrapper = styled.div`
|
||||
display: flex;
|
||||
@ -71,6 +72,8 @@ export function getCanEditName(
|
||||
return true; // TODO: add permissions for data products
|
||||
case EntityType.BusinessAttribute:
|
||||
return privileges?.manageBusinessAttributes;
|
||||
case EntityType.Dataset:
|
||||
return entityData?.privileges?.canEditProperties;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -94,8 +97,11 @@ export const EntityHeader = ({ headerDropdownItems, headerActionItems, isNameEdi
|
||||
const entityName = entityData?.name;
|
||||
const subType = capitalizeFirstLetterOnly(entityData?.subTypes?.typeNames?.[0]) || undefined;
|
||||
|
||||
const isEditableDatasetNameEnabled = useIsEditableDatasetNameEnabled();
|
||||
const canEditName =
|
||||
isNameEditable && getCanEditName(entityType, entityData, me?.platformPrivileges as PlatformPrivileges);
|
||||
isEditableDatasetNameEnabled &&
|
||||
isNameEditable &&
|
||||
getCanEditName(entityType, entityData, me?.platformPrivileges as PlatformPrivileges);
|
||||
const entityRegistry = useEntityRegistry();
|
||||
|
||||
return (
|
||||
@ -106,7 +112,7 @@ export const EntityHeader = ({ headerDropdownItems, headerActionItems, isNameEdi
|
||||
<>
|
||||
<PlatformContent />
|
||||
<TitleWrapper>
|
||||
<EntityName isNameEditable={canEditName} />
|
||||
<EntityName isNameEditable={canEditName || false} />
|
||||
{entityData?.deprecation?.deprecated && (
|
||||
<DeprecationPill
|
||||
urn={urn}
|
||||
|
@ -28,6 +28,11 @@ export function useIsAppConfigContextLoaded() {
|
||||
return appConfig.loaded;
|
||||
}
|
||||
|
||||
export function useIsEditableDatasetNameEnabled() {
|
||||
const appConfig = useAppConfig();
|
||||
return appConfig.config.featureFlags.editableDatasetNameEnabled;
|
||||
}
|
||||
|
||||
export function useIsShowSeparateSiblingsEnabled() {
|
||||
const appConfig = useAppConfig();
|
||||
return appConfig.config.featureFlags.showSeparateSiblings;
|
||||
|
@ -54,6 +54,7 @@ export const DEFAULT_APP_CONFIG = {
|
||||
platformBrowseV2: false,
|
||||
businessAttributeEntityEnabled: false,
|
||||
dataContractsEnabled: false,
|
||||
editableDatasetNameEnabled: false,
|
||||
showSeparateSiblings: false,
|
||||
},
|
||||
};
|
||||
|
@ -69,6 +69,7 @@ query appConfig {
|
||||
platformBrowseV2
|
||||
businessAttributeEntityEnabled
|
||||
dataContractsEnabled
|
||||
editableDatasetNameEnabled
|
||||
showSeparateSiblings
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ query getBrowseResults($input: BrowseInput!) {
|
||||
description
|
||||
}
|
||||
editableProperties {
|
||||
name
|
||||
description
|
||||
}
|
||||
platform {
|
||||
|
@ -251,6 +251,7 @@ fragment nonRecursiveDatasetFields on Dataset {
|
||||
}
|
||||
}
|
||||
editableProperties {
|
||||
name
|
||||
description
|
||||
}
|
||||
ownership {
|
||||
|
@ -9,6 +9,7 @@ fragment entityPreview on Entity {
|
||||
...platformFields
|
||||
}
|
||||
editableProperties {
|
||||
name
|
||||
description
|
||||
}
|
||||
platformNativeType
|
||||
|
@ -335,6 +335,7 @@ fragment nonSiblingsDatasetSearchFields on Dataset {
|
||||
...dataPlatformInstanceFields
|
||||
}
|
||||
editableProperties {
|
||||
name
|
||||
description
|
||||
}
|
||||
access {
|
||||
|
@ -19,4 +19,13 @@ record EditableDatasetProperties includes ChangeAuditStamps {
|
||||
"fieldName": "editedDescription",
|
||||
}
|
||||
description: optional string
|
||||
|
||||
/**
|
||||
* Editable display name of the Dataset
|
||||
*/
|
||||
@Searchable = {
|
||||
"fieldType": "TEXT_PARTIAL",
|
||||
"fieldName": "editedName",
|
||||
}
|
||||
name: optional string
|
||||
}
|
||||
|
@ -2328,6 +2328,15 @@
|
||||
"fieldName" : "editedDescription",
|
||||
"fieldType" : "TEXT"
|
||||
}
|
||||
}, {
|
||||
"name" : "name",
|
||||
"type" : "string",
|
||||
"doc" : "Editable display name of the Dataset",
|
||||
"optional" : true,
|
||||
"Searchable" : {
|
||||
"fieldName" : "editedName",
|
||||
"fieldType" : "TEXT_PARTIAL"
|
||||
}
|
||||
} ],
|
||||
"Aspect" : {
|
||||
"name" : "editableDatasetProperties"
|
||||
|
@ -2328,6 +2328,15 @@
|
||||
"fieldName" : "editedDescription",
|
||||
"fieldType" : "TEXT"
|
||||
}
|
||||
}, {
|
||||
"name" : "name",
|
||||
"type" : "string",
|
||||
"doc" : "Editable display name of the Dataset",
|
||||
"optional" : true,
|
||||
"Searchable" : {
|
||||
"fieldName" : "editedName",
|
||||
"fieldType" : "TEXT_PARTIAL"
|
||||
}
|
||||
} ],
|
||||
"Aspect" : {
|
||||
"name" : "editableDatasetProperties"
|
||||
|
Loading…
x
Reference in New Issue
Block a user