Skip to content

Commit 806ae71

Browse files
purnimagarg1esteban
authored andcommitted
feat(dataset-summary): add summary tab on dataset entities (#15238)
1 parent 3d3a9b8 commit 806ae71

File tree

11 files changed

+177
-130
lines changed

11 files changed

+177
-130
lines changed

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/types/dataset/DatasetType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ public class DatasetType
9292
SUB_TYPES_ASPECT_NAME,
9393
APPLICATION_MEMBERSHIP_ASPECT_NAME,
9494
VERSION_PROPERTIES_ASPECT_NAME,
95-
LOGICAL_PARENT_ASPECT_NAME);
95+
LOGICAL_PARENT_ASPECT_NAME,
96+
ASSET_SETTINGS_ASPECT_NAME);
9697

9798
private static final Set<String> FACET_FIELDS = ImmutableSet.of("origin", "platform");
9899
private static final String ENTITY_NAME = "dataset";

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/types/dataset/mappers/DatasetMapper.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.linkedin.datahub.graphql.generated.EntityType;
3232
import com.linkedin.datahub.graphql.generated.FabricType;
3333
import com.linkedin.datahub.graphql.types.application.ApplicationAssociationMapper;
34+
import com.linkedin.datahub.graphql.types.common.mappers.AssetSettingsMapper;
3435
import com.linkedin.datahub.graphql.types.common.mappers.BrowsePathsV2Mapper;
3536
import com.linkedin.datahub.graphql.types.common.mappers.CustomPropertiesMapper;
3637
import com.linkedin.datahub.graphql.types.common.mappers.DataPlatformInstanceAspectMapper;
@@ -65,6 +66,7 @@
6566
import com.linkedin.metadata.key.DatasetKey;
6667
import com.linkedin.schema.EditableSchemaMetadata;
6768
import com.linkedin.schema.SchemaMetadata;
69+
import com.linkedin.settings.asset.AssetSettings;
6870
import com.linkedin.structured.StructuredProperties;
6971
import java.util.Optional;
7072
import javax.annotation.Nonnull;
@@ -209,6 +211,10 @@ public Dataset apply(
209211
logicalParent ->
210212
UrnToEntityMapper.map(context, logicalParent.getDestinationUrn()))
211213
.orElse(null)));
214+
mappingHelper.mapToResult(
215+
ASSET_SETTINGS_ASPECT_NAME,
216+
((entity, dataMap) ->
217+
entity.setSettings(AssetSettingsMapper.map(new AssetSettings(dataMap)))));
212218

213219
if (context != null && !canView(context.getOperationContext(), entityUrn)) {
214220
return AuthorizationUtils.restrictEntity(mappingHelper.getResult(), Dataset.class);

datahub-graphql-core/src/main/resources/settings.graphql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,10 @@ extend type GlossaryNode {
8484
"""
8585
settings: AssetSettings
8686
}
87+
88+
extend type Dataset {
89+
"""
90+
Settings associated with this asset
91+
"""
92+
settings: AssetSettings
93+
}

datahub-web-react/src/Mocks.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ export const dataset1 = {
360360
structuredProperties: null,
361361
forms: null,
362362
activeIncidents: null,
363+
settings: null,
363364
};
364365

365366
export const dataset2 = {
@@ -460,6 +461,7 @@ export const dataset2 = {
460461
structuredProperties: null,
461462
forms: null,
462463
activeIncidents: null,
464+
settings: null,
463465
};
464466

465467
export const dataset3 = {
@@ -725,6 +727,7 @@ export const dataset3 = {
725727
upstream: null,
726728
downstream: null,
727729
versionProperties: null,
730+
settings: null,
728731
} as Dataset;
729732

730733
export const dataset3WithSchema = {

datahub-web-react/src/app/entityV2/dataset/DatasetEntity.tsx

Lines changed: 148 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { getDataForEntityType } from '@app/entityV2/shared/containers/profile/ut
4343
import EmbeddedProfile from '@app/entityV2/shared/embed/EmbeddedProfile';
4444
import SidebarNotesSection from '@app/entityV2/shared/sidebarSection/SidebarNotesSection';
4545
import SidebarStructuredProperties from '@app/entityV2/shared/sidebarSection/SidebarStructuredProperties';
46+
import { SUMMARY_TAB_ICON } from '@app/entityV2/shared/summary/HeaderComponents';
4647
import AccessManagement from '@app/entityV2/shared/tabs/Dataset/AccessManagement/AccessManagement';
4748
import QueriesTab from '@app/entityV2/shared/tabs/Dataset/Queries/QueriesTab';
4849
import { SchemaTab } from '@app/entityV2/shared/tabs/Dataset/Schema/SchemaTab';
@@ -54,12 +55,15 @@ import { EmbedTab } from '@app/entityV2/shared/tabs/Embed/EmbedTab';
5455
import { IncidentTab } from '@app/entityV2/shared/tabs/Incident/IncidentTab';
5556
import { LineageTab } from '@app/entityV2/shared/tabs/Lineage/LineageTab';
5657
import { PropertiesTab } from '@app/entityV2/shared/tabs/Properties/PropertiesTab';
58+
import { EntityTab } from '@app/entityV2/shared/types';
5759
import {
5860
SidebarTitleActionType,
5961
getDatasetLastUpdatedMs,
6062
getFirstSubType,
6163
isOutputPort,
6264
} from '@app/entityV2/shared/utils';
65+
import SummaryTab from '@app/entityV2/summary/SummaryTab';
66+
import { useShowDatasetSummaryPage } from '@app/entityV2/summary/useShowDatasetSummaryPage';
6367
import { DBT_URN } from '@app/ingest/source/builder/constants';
6468
import { MatchedFieldList } from '@app/searchV2/matches/MatchedFieldList';
6569
import { matchedFieldPathsRenderer } from '@app/searchV2/matches/matchedFieldPathsRenderer';
@@ -147,133 +151,7 @@ export class DatasetEntity implements Entity<Dataset> {
147151
subHeader={{
148152
component: DatasetStatsSummarySubHeader,
149153
}}
150-
tabs={[
151-
{
152-
name: 'Columns',
153-
component: SchemaTab,
154-
icon: LayoutOutlined,
155-
getCount: useGetColumnTabCount,
156-
},
157-
{
158-
name: 'View Definition',
159-
component: ViewDefinitionTab,
160-
icon: CodeOutlined,
161-
display: {
162-
visible: (_, dataset: GetDatasetQuery) =>
163-
!!dataset?.dataset?.viewProperties?.logic ||
164-
!!dataset?.dataset?.subTypes?.typeNames
165-
?.map((t) => t.toLocaleLowerCase())
166-
.includes(SUBTYPES.VIEW.toLocaleLowerCase()),
167-
enabled: (_, dataset: GetDatasetQuery) => !!dataset?.dataset?.viewProperties?.logic,
168-
},
169-
},
170-
{
171-
name: 'Documentation',
172-
component: DocumentationTab,
173-
icon: FileOutlined,
174-
},
175-
{
176-
name: 'Preview',
177-
component: EmbedTab,
178-
icon: EyeOutlined,
179-
display: {
180-
visible: (_, dataset: GetDatasetQuery) => !!dataset?.dataset?.embed?.renderUrl,
181-
enabled: (_, dataset: GetDatasetQuery) => !!dataset?.dataset?.embed?.renderUrl,
182-
},
183-
},
184-
{
185-
name: 'Lineage',
186-
component: LineageTab,
187-
icon: PartitionOutlined,
188-
},
189-
{
190-
name: 'Access',
191-
component: AccessManagement,
192-
icon: UnlockOutlined,
193-
display: {
194-
visible: (_, _1) => this.appconfig().config.featureFlags.showAccessManagement,
195-
enabled: (_, _2) => true,
196-
},
197-
},
198-
{
199-
name: 'Properties',
200-
component: PropertiesTab,
201-
icon: UnorderedListOutlined,
202-
getCount: (_, dataset: GetDatasetQuery) => {
203-
const customPropertiesCount = dataset?.dataset?.properties?.customProperties?.length || 0;
204-
const structuredPropertiesCount =
205-
dataset?.dataset?.structuredProperties?.properties?.length || 0;
206-
const propertiesCount = customPropertiesCount + structuredPropertiesCount;
207-
return propertiesCount;
208-
},
209-
},
210-
{
211-
name: 'Queries',
212-
component: QueriesTab,
213-
icon: ConsoleSqlOutlined,
214-
display: {
215-
visible: (_, _1) => true,
216-
enabled: (_, _2) => true,
217-
},
218-
},
219-
{
220-
name: 'Stats',
221-
component: StatsTabWrapper,
222-
icon: FundOutlined,
223-
display: {
224-
visible: (_, _1) => true,
225-
enabled: (_, dataset: GetDatasetQuery) =>
226-
(dataset?.dataset?.latestFullTableProfile?.length || 0) > 0 ||
227-
(dataset?.dataset?.latestPartitionProfile?.length || 0) > 0 ||
228-
(dataset?.dataset?.usageStats?.buckets?.length || 0) > 0 ||
229-
(dataset?.dataset?.operations?.length || 0) > 0,
230-
},
231-
},
232-
{
233-
name: QUALITY_TAB_NAME,
234-
component: AcrylValidationsTab, // Use SaaS specific Validations Tab.
235-
icon: CheckCircleOutlined,
236-
},
237-
{
238-
name: GOVERNANCE_TAB_NAME,
239-
icon: () => (
240-
<span
241-
style={{
242-
marginRight: 6,
243-
verticalAlign: '-0.2em',
244-
}}
245-
>
246-
<GovernMenuIcon width={16} height={16} fill="currentColor" />
247-
</span>
248-
),
249-
component: GovernanceTab,
250-
getCount: (_, dataset) => {
251-
const passingTests = dataset?.dataset?.testResults?.passing || [];
252-
const failingTests = dataset?.dataset?.testResults?.failing || [];
253-
return passingTests.length + failingTests.length;
254-
},
255-
},
256-
{
257-
name: 'Runs', // TODO: Rename this to DatasetRunsTab.
258-
component: OperationsTab,
259-
display: {
260-
visible: (_, dataset: GetDatasetQuery) => {
261-
return (dataset?.dataset?.runs?.total || 0) > 0;
262-
},
263-
enabled: (_, dataset: GetDatasetQuery) => {
264-
return (dataset?.dataset?.runs?.total || 0) > 0;
265-
},
266-
},
267-
},
268-
{
269-
name: 'Incidents',
270-
icon: WarningOutlined,
271-
component: IncidentTab,
272-
getCount: (_, dataset) => {
273-
return dataset?.dataset?.activeIncidents?.total;
274-
},
275-
},
276-
]}
154+
tabs={this.getProfileTabs()}
277155
sidebarSections={this.getSidebarSections()}
278156
sidebarTabs={this.getSidebarTabs()}
279157
/>
@@ -377,6 +255,149 @@ export class DatasetEntity implements Entity<Dataset> {
377255
};
378256
};
379257

258+
getProfileTabs = (): EntityTab[] => {
259+
const showSummaryTab = useShowDatasetSummaryPage();
260+
return [
261+
...(showSummaryTab
262+
? [
263+
{
264+
name: 'Summary',
265+
component: SummaryTab,
266+
icon: SUMMARY_TAB_ICON,
267+
},
268+
]
269+
: []),
270+
{
271+
name: 'Columns',
272+
component: SchemaTab,
273+
icon: LayoutOutlined,
274+
getCount: useGetColumnTabCount,
275+
},
276+
{
277+
name: 'View Definition',
278+
component: ViewDefinitionTab,
279+
icon: CodeOutlined,
280+
display: {
281+
visible: (_, dataset: GetDatasetQuery) =>
282+
!!dataset?.dataset?.viewProperties?.logic ||
283+
!!dataset?.dataset?.subTypes?.typeNames
284+
?.map((t) => t.toLocaleLowerCase())
285+
.includes(SUBTYPES.VIEW.toLocaleLowerCase()),
286+
enabled: (_, dataset: GetDatasetQuery) => !!dataset?.dataset?.viewProperties?.logic,
287+
},
288+
},
289+
...(!showSummaryTab
290+
? [
291+
{
292+
name: 'Documentation',
293+
component: DocumentationTab,
294+
icon: FileOutlined,
295+
},
296+
]
297+
: []),
298+
{
299+
name: 'Preview',
300+
component: EmbedTab,
301+
icon: EyeOutlined,
302+
display: {
303+
visible: (_, dataset: GetDatasetQuery) => !!dataset?.dataset?.embed?.renderUrl,
304+
enabled: (_, dataset: GetDatasetQuery) => !!dataset?.dataset?.embed?.renderUrl,
305+
},
306+
},
307+
{
308+
name: 'Lineage',
309+
component: LineageTab,
310+
icon: PartitionOutlined,
311+
},
312+
{
313+
name: 'Access',
314+
component: AccessManagement,
315+
icon: UnlockOutlined,
316+
display: {
317+
visible: (_, _1) => this.appconfig().config.featureFlags.showAccessManagement,
318+
enabled: (_, _2) => true,
319+
},
320+
},
321+
{
322+
name: 'Properties',
323+
component: PropertiesTab,
324+
icon: UnorderedListOutlined,
325+
getCount: (_, dataset: GetDatasetQuery) => {
326+
const customPropertiesCount = dataset?.dataset?.properties?.customProperties?.length || 0;
327+
const structuredPropertiesCount = dataset?.dataset?.structuredProperties?.properties?.length || 0;
328+
const propertiesCount = customPropertiesCount + structuredPropertiesCount;
329+
return propertiesCount;
330+
},
331+
},
332+
{
333+
name: 'Queries',
334+
component: QueriesTab,
335+
icon: ConsoleSqlOutlined,
336+
display: {
337+
visible: (_, _1) => true,
338+
enabled: (_, _2) => true,
339+
},
340+
},
341+
{
342+
name: 'Stats',
343+
component: StatsTabWrapper,
344+
icon: FundOutlined,
345+
display: {
346+
visible: (_, _1) => true,
347+
enabled: (_, dataset: GetDatasetQuery) =>
348+
(dataset?.dataset?.latestFullTableProfile?.length || 0) > 0 ||
349+
(dataset?.dataset?.latestPartitionProfile?.length || 0) > 0 ||
350+
(dataset?.dataset?.usageStats?.buckets?.length || 0) > 0 ||
351+
(dataset?.dataset?.operations?.length || 0) > 0,
352+
},
353+
},
354+
{
355+
name: QUALITY_TAB_NAME,
356+
component: AcrylValidationsTab, // Use SaaS specific Validations Tab.
357+
icon: CheckCircleOutlined,
358+
},
359+
{
360+
name: GOVERNANCE_TAB_NAME,
361+
icon: () => (
362+
<span
363+
style={{
364+
marginRight: 6,
365+
verticalAlign: '-0.2em',
366+
}}
367+
>
368+
<GovernMenuIcon width={16} height={16} fill="currentColor" />
369+
</span>
370+
),
371+
component: GovernanceTab,
372+
getCount: (_, dataset) => {
373+
const passingTests = dataset?.dataset?.testResults?.passing || [];
374+
const failingTests = dataset?.dataset?.testResults?.failing || [];
375+
return passingTests.length + failingTests.length;
376+
},
377+
},
378+
{
379+
name: 'Runs', // TODO: Rename this to DatasetRunsTab.
380+
component: OperationsTab,
381+
display: {
382+
visible: (_, dataset: GetDatasetQuery) => {
383+
return (dataset?.dataset?.runs?.total || 0) > 0;
384+
},
385+
enabled: (_, dataset: GetDatasetQuery) => {
386+
return (dataset?.dataset?.runs?.total || 0) > 0;
387+
},
388+
},
389+
},
390+
{
391+
name: 'Incidents',
392+
icon: WarningOutlined,
393+
component: IncidentTab,
394+
getCount: (_, dataset) => {
395+
return dataset?.dataset?.activeIncidents?.total;
396+
},
397+
},
398+
];
399+
};
400+
380401
renderPreview = (previewType: PreviewType, data: Dataset) => {
381402
const genericProperties = this.getGenericEntityProperties(data);
382403
const platformNames = genericProperties?.siblingPlatforms?.map(

datahub-web-react/src/app/entityV2/summary/properties/hooks/__tests__/useBasicAssetProperties.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ describe('useBasicAssetProperties', () => {
5353
});
5454

5555
it('should return an empty array for other entity types', () => {
56-
(useEntityContext as any).mockReturnValue({ entityType: EntityType.Dataset });
56+
(useEntityContext as any).mockReturnValue({ entityType: EntityType.Chart });
5757
const { result } = renderHook(() => useBasicAssetProperties());
5858
expect(result.current).toEqual([]);
5959
});

datahub-web-react/src/app/entityV2/summary/properties/hooks/useBasicAssetProperties.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export default function useBasicAssetProperties() {
2424
return [CREATED_PROPERTY, OWNERS_PROPERTY];
2525
case EntityType.DataProduct:
2626
return [CREATED_PROPERTY, OWNERS_PROPERTY, DOMAIN_PROPERTY, TAGS_PROPERTY, TERMS_PROPERTY];
27+
case EntityType.Dataset:
28+
return [CREATED_PROPERTY, OWNERS_PROPERTY, DOMAIN_PROPERTY, TAGS_PROPERTY, TERMS_PROPERTY];
2729
default:
2830
return [];
2931
}

0 commit comments

Comments
 (0)