Skip to content

Commit

Permalink
feat(ui): Adding Statistics Summary to Dataset + Dashboard Profiles (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jjoyce0510 authored Jul 19, 2022
1 parent ac61bcd commit aa7ae23
Show file tree
Hide file tree
Showing 22 changed files with 442 additions and 164 deletions.
3 changes: 3 additions & 0 deletions datahub-web-react/src/Mocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ export const dataset1 = {
assertions: null,
deprecation: null,
testResults: null,
statsSummary: null,
};

export const dataset2 = {
Expand Down Expand Up @@ -309,6 +310,7 @@ export const dataset2 = {
status: null,
deprecation: null,
testResults: null,
statsSummary: null,
};

export const dataset3 = {
Expand Down Expand Up @@ -524,6 +526,7 @@ export const dataset3 = {
writeRuns: null,
testResults: null,
siblings: null,
statsSummary: null,
} as Dataset;

export const dataset4 = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const Preview = ({
parentContainers={parentContainers}
tags={tags || undefined}
externalUrl={externalUrl}
stats={
subHeader={
(entityCount && [
<StatText>
<b>{entityCount}</b> {entityCount === 1 ? 'entity' : 'entities'}
Expand Down
11 changes: 11 additions & 0 deletions datahub-web-react/src/app/entity/dashboard/DashboardEntity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { getDataForEntityType } from '../shared/containers/profile/utils';
import { SidebarDomainSection } from '../shared/containers/profile/sidebar/Domain/SidebarDomainSection';
import { EntityMenuItems } from '../shared/EntityDropdown/EntityDropdown';
import { LineageTab } from '../shared/tabs/Lineage/LineageTab';
import { DashboardStatsSummarySubHeader } from './profile/DashboardStatsSummarySubHeader';

/**
* Definition of the DataHub Dashboard entity.
Expand Down Expand Up @@ -75,6 +76,9 @@ export class DashboardEntity implements Entity<Dashboard> {
useUpdateQuery={useUpdateDashboardMutation}
getOverrideProperties={this.getOverridePropertiesFromEntity}
headerDropdownItems={new Set([EntityMenuItems.COPY_URL, EntityMenuItems.UPDATE_DEPRECATION])}
subHeader={{
component: DashboardStatsSummarySubHeader,
}}
tabs={[
{
name: 'Documentation',
Expand Down Expand Up @@ -164,6 +168,12 @@ export class DashboardEntity implements Entity<Dashboard> {
logoUrl={data?.platform?.properties?.logoUrl}
domain={data.domain?.domain}
container={data.container}
parentContainers={data.parentContainers}
deprecation={data.deprecation}
externalUrl={data.properties?.externalUrl}
statsSummary={data.statsSummary}
lastUpdatedMs={data.properties?.lastModified?.time}
createdMs={data.properties?.created?.time}
/>
);
};
Expand All @@ -190,6 +200,7 @@ export class DashboardEntity implements Entity<Dashboard> {
externalUrl={data.properties?.externalUrl}
statsSummary={data.statsSummary}
lastUpdatedMs={data.properties?.lastModified?.time}
createdMs={data.properties?.created?.time}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import React from 'react';
import styled from 'styled-components';
import { ClockCircleOutlined, EyeOutlined, TeamOutlined } from '@ant-design/icons';
import {
AccessLevel,
Domain,
Expand All @@ -18,13 +16,7 @@ import DefaultPreviewCard from '../../../preview/DefaultPreviewCard';
import { useEntityRegistry } from '../../../useEntityRegistry';
import { capitalizeFirstLetter } from '../../../shared/textUtil';
import { IconStyleType } from '../../Entity';
import { ANTD_GRAY } from '../../shared/constants';
import { formatNumberWithoutAbbreviation } from '../../../shared/formatNumber';
import { toRelativeTimeString } from '../../../shared/time/timeUtils';

const StatText = styled.span`
color: ${ANTD_GRAY[8]};
`;
import { DashboardStatsSummary as DashboardStatsSummaryView } from '../shared/DashboardStatsSummary';

export const DashboardPreview = ({
urn,
Expand All @@ -43,6 +35,7 @@ export const DashboardPreview = ({
chartCount,
statsSummary,
lastUpdatedMs,
createdMs,
externalUrl,
parentContainers,
deprecation,
Expand All @@ -64,6 +57,7 @@ export const DashboardPreview = ({
chartCount?: number | null;
statsSummary?: DashboardStatsSummary | null;
lastUpdatedMs?: number | null;
createdMs?: number | null;
externalUrl?: string | null;
parentContainers?: ParentContainersResult | null;
}): JSX.Element => {
Expand Down Expand Up @@ -91,35 +85,15 @@ export const DashboardPreview = ({
parentContainers={parentContainers}
externalUrl={externalUrl}
topUsers={statsSummary?.topUsersLast30Days}
stats={[
(chartCount && (
<StatText>
<b>{chartCount}</b> charts
</StatText>
)) ||
undefined,
(statsSummary?.viewCount && (
<StatText>
<EyeOutlined style={{ marginRight: 8, color: ANTD_GRAY[7] }} />
<b>{formatNumberWithoutAbbreviation(statsSummary.viewCount)}</b> views
</StatText>
)) ||
undefined,
(statsSummary?.uniqueUserCountLast30Days && (
<StatText>
<TeamOutlined style={{ marginRight: 8, color: ANTD_GRAY[7] }} />
<b>{formatNumberWithoutAbbreviation(statsSummary?.uniqueUserCountLast30Days)}</b> unique users
</StatText>
)) ||
undefined,
(lastUpdatedMs && (
<StatText>
<ClockCircleOutlined style={{ marginRight: 8, color: ANTD_GRAY[7] }} />
Changed {toRelativeTimeString(lastUpdatedMs)}
</StatText>
)) ||
undefined,
].filter((stat) => stat !== undefined)}
subHeader={
<DashboardStatsSummaryView
chartCount={chartCount}
viewCount={statsSummary?.viewCount}
uniqueUserCountLast30Days={statsSummary?.uniqueUserCountLast30Days}
lastUpdatedMs={lastUpdatedMs}
createdMs={createdMs}
/>
}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { DashboardStatsSummary as DashboardStatsSummaryObj } from '../../../../types.generated';
import { useBaseEntity } from '../../shared/EntityContext';
import { GetDashboardQuery } from '../../../../graphql/dashboard.generated';
import { DashboardStatsSummary } from '../shared/DashboardStatsSummary';

export const DashboardStatsSummarySubHeader = () => {
const result = useBaseEntity<GetDashboardQuery>();
const dashboard = result?.dashboard;
const maybeStatsSummary = dashboard?.statsSummary as DashboardStatsSummaryObj;
const chartCount = dashboard?.charts?.total;
const viewCount = maybeStatsSummary?.viewCount;
const uniqueUserCountLast30Days = maybeStatsSummary?.uniqueUserCountLast30Days;
const lastUpdatedMs = dashboard?.properties?.lastModified?.time;
const createdMs = dashboard?.properties?.created?.time;

return (
<DashboardStatsSummary
chartCount={chartCount}
viewCount={viewCount}
uniqueUserCountLast30Days={uniqueUserCountLast30Days}
lastUpdatedMs={lastUpdatedMs}
createdMs={createdMs}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from 'react';
import styled from 'styled-components';
import { Popover, Tooltip } from 'antd';
import { ClockCircleOutlined, EyeOutlined, TeamOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { formatNumberWithoutAbbreviation } from '../../../shared/formatNumber';
import { ANTD_GRAY } from '../../shared/constants';
import { toLocalDateTimeString, toRelativeTimeString } from '../../../shared/time/timeUtils';
import { StatsSummary } from '../../shared/components/styled/StatsSummary';

const StatText = styled.span`
color: ${ANTD_GRAY[8]};
`;

const HelpIcon = styled(QuestionCircleOutlined)`
color: ${ANTD_GRAY[7]};
padding-left: 4px;
`;

type Props = {
chartCount?: number | null;
viewCount?: number | null;
uniqueUserCountLast30Days?: number | null;
lastUpdatedMs?: number | null;
createdMs?: number | null;
};

export const DashboardStatsSummary = ({
chartCount,
viewCount,
uniqueUserCountLast30Days,
lastUpdatedMs,
createdMs,
}: Props) => {
const statsViews = [
(!!chartCount && (
<StatText>
<b>{chartCount}</b> charts
</StatText>
)) ||
undefined,
(!!viewCount && (
<StatText>
<EyeOutlined style={{ marginRight: 8, color: ANTD_GRAY[7] }} />
<b>{formatNumberWithoutAbbreviation(viewCount)}</b> views
</StatText>
)) ||
undefined,
(!!uniqueUserCountLast30Days && (
<StatText>
<TeamOutlined style={{ marginRight: 8, color: ANTD_GRAY[7] }} />
<b>{formatNumberWithoutAbbreviation(uniqueUserCountLast30Days)}</b> unique users
</StatText>
)) ||
undefined,
(!!lastUpdatedMs && (
<Popover
content={
<>
{createdMs && <div>Created on {toLocalDateTimeString(createdMs)}.</div>}
<div>
Changed on {toLocalDateTimeString(lastUpdatedMs)}.{' '}
<Tooltip title="The time at which the dashboard was last changed in the source platform">
<HelpIcon />
</Tooltip>
</div>
</>
}
>
<StatText>
<ClockCircleOutlined style={{ marginRight: 8, color: ANTD_GRAY[7] }} />
Changed {toRelativeTimeString(lastUpdatedMs)}
</StatText>
</Popover>
)) ||
undefined,
].filter((stat) => stat !== undefined);

return <>{statsViews.length > 0 && <StatsSummary stats={statsViews} />}</>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const Preview = ({
insights={insights}
externalUrl={externalUrl}
deprecation={deprecation}
stats={
subHeader={
(jobCount && [
<StatText>
<b>{jobCount}</b> {entityRegistry.getCollectionName(EntityType.DataJob)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const Preview = ({
dataTestID="datajob-item-preview"
insights={insights}
externalUrl={externalUrl}
stats={
subHeader={
(lastRunTimeMs && [
<StatText>
<ClockCircleOutlined style={{ paddingRight: 8 }} />
Expand Down
25 changes: 10 additions & 15 deletions datahub-web-react/src/app/entity/dataset/DatasetEntity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import QueriesTab from '../shared/tabs/Dataset/Queries/QueriesTab';
import { SidebarAboutSection } from '../shared/containers/profile/sidebar/SidebarAboutSection';
import { SidebarOwnerSection } from '../shared/containers/profile/sidebar/Ownership/SidebarOwnerSection';
import { SidebarTagsSection } from '../shared/containers/profile/sidebar/SidebarTagsSection';
import { SidebarStatsSection } from '../shared/containers/profile/sidebar/Dataset/StatsSidebarSection';
import StatsTab from '../shared/tabs/Dataset/Stats/StatsTab';
import { LineageTab } from '../shared/tabs/Lineage/LineageTab';
import { capitalizeFirstLetter } from '../../shared/textUtil';
Expand All @@ -28,6 +27,7 @@ import { ValidationsTab } from '../shared/tabs/Dataset/Validations/ValidationsTa
import { OperationsTab } from './profile/OperationsTab';
import { EntityMenuItems } from '../shared/EntityDropdown/EntityDropdown';
import { SidebarSiblingsSection } from '../shared/containers/profile/sidebar/SidebarSiblingsSection';
import { DatasetStatsSummarySubHeader } from './profile/stats/stats/DatasetStatsSummarySubHeader';

const SUBTYPES = {
VIEW: 'view',
Expand Down Expand Up @@ -86,6 +86,9 @@ export class DatasetEntity implements Entity<Dataset> {
useUpdateQuery={useUpdateDatasetMutation}
getOverrideProperties={this.getOverridePropertiesFromEntity}
headerDropdownItems={new Set([EntityMenuItems.COPY_URL, EntityMenuItems.UPDATE_DEPRECATION])}
subHeader={{
component: DatasetStatsSummarySubHeader,
}}
tabs={[
{
name: 'Schema',
Expand Down Expand Up @@ -175,6 +178,12 @@ export class DatasetEntity implements Entity<Dataset> {
{
component: SidebarAboutSection,
},
{
component: SidebarOwnerSection,
properties: {
defaultOwnerType: OwnershipType.TechnicalOwner,
},
},
{
component: SidebarSiblingsSection,
display: {
Expand All @@ -189,27 +198,13 @@ export class DatasetEntity implements Entity<Dataset> {
(dataset?.dataset?.viewProperties?.logic && true) || false,
},
},
{
component: SidebarStatsSection,
display: {
visible: (_, dataset: GetDatasetQuery) =>
(dataset?.dataset?.datasetProfiles?.length || 0) > 0 ||
(dataset?.dataset?.usageStats?.buckets?.length || 0) > 0,
},
},
{
component: SidebarTagsSection,
properties: {
hasTags: true,
hasTerms: true,
},
},
{
component: SidebarOwnerSection,
properties: {
defaultOwnerType: OwnershipType.TechnicalOwner,
},
},
{
component: SidebarDomainSection,
},
Expand Down
Loading

0 comments on commit aa7ae23

Please sign in to comment.