mirror of
https://github.com/datahub-project/datahub.git
synced 2025-08-15 12:46:53 +00:00
feat(ui) Allow a configurable default tab for domain entity profile page (#8316)
This commit is contained in:
parent
b97e9b5b53
commit
18c1f12436
@ -7,6 +7,8 @@ import com.linkedin.datahub.graphql.featureflags.FeatureFlags;
|
||||
import com.linkedin.datahub.graphql.generated.AnalyticsConfig;
|
||||
import com.linkedin.datahub.graphql.generated.AppConfig;
|
||||
import com.linkedin.datahub.graphql.generated.AuthConfig;
|
||||
import com.linkedin.datahub.graphql.generated.EntityProfileConfig;
|
||||
import com.linkedin.datahub.graphql.generated.EntityProfilesConfig;
|
||||
import com.linkedin.datahub.graphql.generated.EntityType;
|
||||
import com.linkedin.datahub.graphql.generated.FeatureFlagsConfig;
|
||||
import com.linkedin.datahub.graphql.generated.IdentityManagementConfig;
|
||||
@ -133,6 +135,15 @@ public class AppConfigResolver implements DataFetcher<CompletableFuture<AppConfi
|
||||
queriesTabConfig.setQueriesTabResultSize(_visualConfiguration.getQueriesTab().getQueriesTabResultSize());
|
||||
visualConfig.setQueriesTab(queriesTabConfig);
|
||||
}
|
||||
if (_visualConfiguration != null && _visualConfiguration.getEntityProfile() != null) {
|
||||
EntityProfilesConfig entityProfilesConfig = new EntityProfilesConfig();
|
||||
if (_visualConfiguration.getEntityProfile().getDomainDefaultTab() != null) {
|
||||
EntityProfileConfig profileConfig = new EntityProfileConfig();
|
||||
profileConfig.setDefaultTab(_visualConfiguration.getEntityProfile().getDomainDefaultTab());
|
||||
entityProfilesConfig.setDomain(profileConfig);
|
||||
}
|
||||
visualConfig.setEntityProfiles(entityProfilesConfig);
|
||||
}
|
||||
appConfig.setVisualConfig(visualConfig);
|
||||
|
||||
final TelemetryConfig telemetryConfig = new TelemetryConfig();
|
||||
|
@ -211,6 +211,11 @@ type VisualConfig {
|
||||
Configuration for the queries tab
|
||||
"""
|
||||
queriesTab: QueriesTabConfig
|
||||
|
||||
"""
|
||||
Configuration for the queries tab
|
||||
"""
|
||||
entityProfiles: EntityProfilesConfig
|
||||
}
|
||||
|
||||
"""
|
||||
@ -223,6 +228,28 @@ type QueriesTabConfig {
|
||||
queriesTabResultSize: Int
|
||||
}
|
||||
|
||||
|
||||
"""
|
||||
Configuration for different entity profiles
|
||||
"""
|
||||
type EntityProfilesConfig {
|
||||
"""
|
||||
The configurations for a Domain entity profile
|
||||
"""
|
||||
domain: EntityProfileConfig
|
||||
}
|
||||
|
||||
"""
|
||||
Configuration for an entity profile
|
||||
"""
|
||||
type EntityProfileConfig {
|
||||
"""
|
||||
The enum value from EntityProfileTab for which tab should be showed by default on
|
||||
entity profile pages. If null, rely on default sorting from React code.
|
||||
"""
|
||||
defaultTab: String
|
||||
}
|
||||
|
||||
"""
|
||||
Configurations related to tracking users in the app
|
||||
"""
|
||||
|
@ -13,6 +13,7 @@ import { DomainEntitiesTab } from './DomainEntitiesTab';
|
||||
import { EntityMenuItems } from '../shared/EntityDropdown/EntityDropdown';
|
||||
import { EntityActionItem } from '../shared/entity/EntityActions';
|
||||
import DataProductsTab from './DataProductsTab/DataProductsTab';
|
||||
import { EntityProfileTab } from '../shared/constants';
|
||||
// import { EntityActionItem } from '../shared/entity/EntityActions';
|
||||
|
||||
/**
|
||||
@ -72,14 +73,17 @@ export class DomainEntity implements Entity<Domain> {
|
||||
isNameEditable
|
||||
tabs={[
|
||||
{
|
||||
id: EntityProfileTab.DOMAIN_ENTITIES_TAB,
|
||||
name: 'Entities',
|
||||
component: DomainEntitiesTab,
|
||||
},
|
||||
{
|
||||
id: EntityProfileTab.DOCUMENTATION_TAB,
|
||||
name: 'Documentation',
|
||||
component: DocumentationTab,
|
||||
},
|
||||
{
|
||||
id: EntityProfileTab.DATA_PRODUCTS_TAB,
|
||||
name: 'Data Products',
|
||||
component: DataProductsTab,
|
||||
},
|
||||
|
@ -93,3 +93,10 @@ export const GLOSSARY_ENTITY_TYPES = [EntityType.GlossaryTerm, EntityType.Glossa
|
||||
export const DEFAULT_SYSTEM_ACTOR_URNS = ['urn:li:corpuser:__datahub_system', 'urn:li:corpuser:unknown'];
|
||||
|
||||
export const VIEW_ENTITY_PAGE = 'VIEW_ENTITY_PAGE';
|
||||
|
||||
// only values for Domain Entity for custom configurable default tab
|
||||
export enum EntityProfileTab {
|
||||
DOMAIN_ENTITIES_TAB = 'DOMAIN_ENTITIES_TAB',
|
||||
DOCUMENTATION_TAB = 'DOCUMENTATION_TAB',
|
||||
DATA_PRODUCTS_TAB = 'DATA_PRODUCTS_TAB',
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import { Message } from '../../../../shared/Message';
|
||||
import {
|
||||
getEntityPath,
|
||||
getOnboardingStepIdsForEntityType,
|
||||
sortEntityProfileTabs,
|
||||
useRoutedTab,
|
||||
useUpdateGlossaryEntityDataOnChange,
|
||||
} from './utils';
|
||||
@ -43,6 +44,7 @@ import {
|
||||
LINEAGE_GRAPH_INTRO_ID,
|
||||
LINEAGE_GRAPH_TIME_FILTER_ID,
|
||||
} from '../../../../onboarding/config/LineageGraphOnboardingConfig';
|
||||
import { useAppConfig } from '../../../../useAppConfig';
|
||||
|
||||
type Props<T, U> = {
|
||||
urn: string;
|
||||
@ -168,8 +170,10 @@ export const EntityProfile = <T, U>({
|
||||
const isHideSiblingMode = useIsSeparateSiblingsMode();
|
||||
const entityRegistry = useEntityRegistry();
|
||||
const history = useHistory();
|
||||
const appConfig = useAppConfig();
|
||||
const isCompact = React.useContext(CompactContext);
|
||||
const tabsWithDefaults = tabs.map((tab) => ({ ...tab, display: { ...defaultTabDisplayConfig, ...tab.display } }));
|
||||
const sortedTabs = sortEntityProfileTabs(appConfig.config, entityType, tabsWithDefaults);
|
||||
const sideBarSectionsWithDefaults = sidebarSections.map((sidebarSection) => ({
|
||||
...sidebarSection,
|
||||
display: { ...defaultSidebarSection, ...sidebarSection.display },
|
||||
@ -235,7 +239,7 @@ export const EntityProfile = <T, U>({
|
||||
},
|
||||
})) || [];
|
||||
|
||||
const visibleTabs = [...tabsWithDefaults, ...autoRenderTabs].filter((tab) =>
|
||||
const visibleTabs = [...sortedTabs, ...autoRenderTabs].filter((tab) =>
|
||||
tab.display?.visible(entityData, dataPossiblyCombinedWithSiblings),
|
||||
);
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { useEffect } from 'react';
|
||||
import { useLocation } from 'react-router';
|
||||
import queryString from 'query-string';
|
||||
import { isEqual } from 'lodash';
|
||||
import { EntityType } from '../../../../../types.generated';
|
||||
import { AppConfig, EntityType } from '../../../../../types.generated';
|
||||
import useIsLineageMode from '../../../../lineage/utils/useIsLineageMode';
|
||||
import { useEntityRegistry } from '../../../../useEntityRegistry';
|
||||
import EntityRegistry from '../../../EntityRegistry';
|
||||
@ -202,3 +202,22 @@ export function getOnboardingStepIdsForEntityType(entityType: EntityType): strin
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function sortTabsWithDefaultTabId(tabs: EntityTab[], defaultTabId: string) {
|
||||
return tabs.sort((tabA, tabB) => {
|
||||
if (tabA.id === defaultTabId) return -1;
|
||||
if (tabB.id === defaultTabId) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
export function sortEntityProfileTabs(appConfig: AppConfig, entityType: EntityType, tabs: EntityTab[]) {
|
||||
const sortedTabs = [...tabs];
|
||||
|
||||
if (entityType === EntityType.Domain && appConfig.visualConfig.entityProfiles?.domain?.defaultTab) {
|
||||
const defaultTabId = appConfig.visualConfig.entityProfiles?.domain.defaultTab;
|
||||
sortTabsWithDefaultTabId(sortedTabs, defaultTabId);
|
||||
}
|
||||
|
||||
return sortedTabs;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ export type EntityTab = {
|
||||
enabled: (GenericEntityProperties, T) => boolean; // Whether the tab is enabled on the UI. Defaults to true.
|
||||
};
|
||||
properties?: any;
|
||||
id?: string;
|
||||
};
|
||||
|
||||
export type EntitySidebarSection = {
|
||||
|
@ -24,6 +24,9 @@ export const DEFAULT_APP_CONFIG = {
|
||||
queriesTab: {
|
||||
queriesTabResultSize: 5,
|
||||
},
|
||||
entityProfile: {
|
||||
domainDefaultTab: null,
|
||||
},
|
||||
},
|
||||
authConfig: {
|
||||
tokenAuthEnabled: false,
|
||||
|
@ -40,6 +40,11 @@ query appConfig {
|
||||
queriesTab {
|
||||
queriesTabResultSize
|
||||
}
|
||||
entityProfiles {
|
||||
domain {
|
||||
defaultTab
|
||||
}
|
||||
}
|
||||
}
|
||||
telemetryConfig {
|
||||
enableThirdPartyLogging
|
||||
|
@ -0,0 +1,12 @@
|
||||
package com.linkedin.metadata.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class EntityProfileConfig {
|
||||
/**
|
||||
* The default tab to show first on a Domain entity profile. Defaults to React code sorting if not present.
|
||||
*/
|
||||
public String domainDefaultTab;
|
||||
}
|
@ -17,4 +17,9 @@ public class VisualConfiguration {
|
||||
* Queries tab related configurations
|
||||
*/
|
||||
public QueriesTabConfig queriesTab;
|
||||
|
||||
/**
|
||||
* Queries tab related configurations
|
||||
*/
|
||||
public EntityProfileConfig entityProfile;
|
||||
}
|
||||
|
@ -108,6 +108,9 @@ visualConfig:
|
||||
assets:
|
||||
logoUrl: ${REACT_APP_LOGO_URL:/assets/platforms/datahublogo.png}
|
||||
faviconUrl: ${REACT_APP_FAVICON_URL:/assets/favicon.ico}
|
||||
entityProfile:
|
||||
# we only support default tab for domains right now. In order to implement for other entities, update React code
|
||||
domainDefaultTab: ${DOMAIN_DEFAULT_TAB:} # set to DOCUMENTATION_TAB to show documentation tab first
|
||||
|
||||
# Storage Layer
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user