Skip to content

Commit

Permalink
update per pr feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
clairelin135 committed Mar 7, 2024
1 parent fa3f320 commit 9f8c949
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ interface Props {
rightIcon?: React.ReactNode;
label?: React.ReactNode;
tooltipText?: string;
fontSize?: string;
}

const BaseTagTooltipStyle: React.CSSProperties = {
Expand All @@ -38,15 +37,9 @@ export const BaseTag = (props: Props) => {
rightIcon,
label,
tooltipText,
fontSize = '12px',
} = props;
return (
<StyledTag
$fillColor={fillColor}
$interactive={interactive}
$textColor={textColor}
$fontSize={fontSize}
>
<StyledTag $fillColor={fillColor} $interactive={interactive} $textColor={textColor}>
{icon || null}
{label !== undefined && label !== null ? (
<span
Expand All @@ -69,7 +62,6 @@ interface StyledTagProps {
$fillColor: string;
$interactive: boolean;
$textColor: string;
$fontSize: string;
}

export const StyledTag = styled.div<StyledTagProps>`
Expand All @@ -79,7 +71,7 @@ export const StyledTag = styled.div<StyledTagProps>`
cursor: ${({$interactive}) => ($interactive ? 'pointer' : 'inherit')};
display: inline-flex;
flex-direction: row;
font-size: ${({$fontSize}) => $fontSize};
font-size: 12px;
line-height: 16px;
align-items: center;
padding: 4px 8px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import {BreadcrumbProps, Breadcrumbs} from '@blueprintjs/core';
import {
Box,
Button,
Colors,
Heading,
Icon,
Expand All @@ -16,6 +15,7 @@ import styled from 'styled-components';

import {showSharedToaster} from '../app/DomUtils';
import {useCopyToClipboard} from '../app/browser';
import {AnchorButton} from '../ui/AnchorButton';

type Props = {assetKey: {path: string[]}} & Partial<React.ComponentProps<typeof PageHeader>>;

Expand Down Expand Up @@ -118,11 +118,9 @@ export const AssetGlobalLineageLink = () => (
);

export const AssetGlobalLineageButton = () => (
<Link to="/asset-groups">
<Button intent="primary" icon={<Icon name="schema" />}>
View global asset lineage
</Button>
</Link>
<AnchorButton intent="primary" icon={<Icon name="schema" />} to="/asset-groups">
View global asset lineage
</AnchorButton>
);

const BreadcrumbsWithSlashes = styled(Breadcrumbs)`
Expand Down
162 changes: 81 additions & 81 deletions js_modules/dagster-ui/packages/ui-core/src/assets/AssetsOverview.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {useQuery} from '@apollo/client';
import {Box, Colors, Heading, Icon, Page, Spinner, TextInput} from '@dagster-io/ui-components';
import qs from 'qs';
import {useContext} from 'react';
import {Link, useParams} from 'react-router-dom';
import styled from 'styled-components';

Expand All @@ -11,19 +13,17 @@ import {
AssetCatalogTableQueryVariables,
} from './types/AssetsCatalogTable.types';
import {useTrackPageView} from '../app/analytics';
import {TimeContext} from '../app/time/TimeContext';
import {browserTimezone} from '../app/time/browserTimezone';
import {TagIcon} from '../graph/OpTags';
import {useDocumentTitle} from '../hooks/useDocumentTitle';
import {useLaunchPadHooks} from '../launchpad/LaunchpadHooksContext';
import {ReloadAllButton} from '../workspace/ReloadAllButton';
import {buildRepoPathForHuman} from '../workspace/buildRepoAddress';
import {repoAddressAsHumanString, repoAddressAsURLString} from '../workspace/repoAddressAsString';
import {repoAddressFromPath} from '../workspace/repoAddressFromPath';
import {RepoAddress} from '../workspace/types';

const ViewAllAssetsLink = () => (
<Link to="/assets">
<Box flex={{gap: 4}}>View all</Box>
</Link>
);

type AssetCountsResult = {
countsByOwner: Record<string, number>;
countsByComputeKind: Record<string, number>;
Expand Down Expand Up @@ -53,21 +53,23 @@ function buildAssetCountBySection(assets: AssetTableFragment[]): AssetCountsResu
const assetCountByGroup: Record<string, number> = {};
const assetCountByCodeLocation: Record<string, number> = {};

assets.forEach((asset) => {
if (asset.definition) {
asset.definition.owners.forEach((owner) => {
assets
.filter((asset) => asset.definition)
.forEach((asset) => {
const assetDefinition = asset.definition!;
assetDefinition.owners.forEach((owner) => {
const ownerKey = owner.__typename === 'UserAssetOwner' ? owner.email : owner.team;
assetCountByOwner[ownerKey] = (assetCountByOwner[ownerKey] || 0) + 1;
});

const computeKind = asset.definition.computeKind;
const computeKind = assetDefinition.computeKind;
if (computeKind) {
assetCountByComputeKind[computeKind] = (assetCountByComputeKind[computeKind] || 0) + 1;
}

const groupName = asset.definition.groupName;
const locationName = asset.definition.repository.location.name;
const repositoryName = asset.definition.repository.name;
const groupName = assetDefinition.groupName;
const locationName = assetDefinition.repository.location.name;
const repositoryName = assetDefinition.repository.name;

if (groupName) {
const metadata: GroupMetadata = {
Expand All @@ -79,33 +81,23 @@ function buildAssetCountBySection(assets: AssetTableFragment[]): AssetCountsResu
assetCountByGroup[groupIdentifier] = (assetCountByGroup[groupIdentifier] || 0) + 1;
}

const stringifiedCodeLocation = JSON.stringify({
name: repositoryName,
location: locationName,
});
const stringifiedCodeLocation = buildRepoPathForHuman(repositoryName, locationName);
assetCountByCodeLocation[stringifiedCodeLocation] =
(assetCountByCodeLocation[stringifiedCodeLocation] || 0) + 1;
}
});

const countPerAssetGroup: CountPerGroupName[] = [];
Object.entries(assetCountByGroup).forEach(([groupIdentifier, count]) => {
const metadata: GroupMetadata = JSON.parse(groupIdentifier);
countPerAssetGroup.push({
assetCount: count,
groupMetadata: metadata,
});
});

const countPerAssetGroup = Object.entries(assetCountByGroup).map(([groupIdentifier, count]) => ({
assetCount: count,
groupMetadata: JSON.parse(groupIdentifier),
}));

return {
countsByOwner: assetCountByOwner,
countsByComputeKind: assetCountByComputeKind,
countPerAssetGroup,
countPerCodeLocation: Object.entries(assetCountByCodeLocation).reduce(
(a, [stringifiedRepoLocation, count]) =>
a.concat({repoAddress: JSON.parse(stringifiedRepoLocation), assetCount: count}),
[] as CountPerCodeLocation[],
),
countPerCodeLocation: Object.entries(assetCountByCodeLocation).map(([key, count]) => {
return {repoAddress: repoAddressFromPath(key)!, assetCount: count};
}),
};
}

Expand All @@ -114,8 +106,14 @@ interface AssetOverviewCategoryProps {
assetsCount: number;
}

function getGreeting() {
const hour = new Date().getHours();
function getGreeting(timezone: string) {
const hour = Number(
new Date().toLocaleTimeString('en-US', {
hour: '2-digit',
hourCycle: 'h23',
timeZone: timezone === 'Automatic' ? browserTimezone() : timezone,
}),
);
if (hour < 12) {
return 'Good morning';
} else if (hour < 18) {
Expand All @@ -131,10 +129,8 @@ const CountForAssetType = ({children, assetsCount}: AssetOverviewCategoryProps)
flex={{direction: 'row', justifyContent: 'space-between'}}
style={{width: 'calc(33% - 16px)'}}
>
<Box>{children}</Box>
<Box>
<AssetCount>{assetsCount} assets</AssetCount>
</Box>
<div>{children}</div>
<AssetCount>{assetsCount} assets</AssetCount>
</Box>
);
};
Expand All @@ -144,10 +140,7 @@ const SectionHeader = ({sectionName}: {sectionName: string}) => {
<Box
flex={{alignItems: 'center', justifyContent: 'space-between'}}
padding={{horizontal: 24, vertical: 8}}
style={{
borderBottom: `1px solid ${Colors.backgroundGray()}`,
borderTop: `1px solid ${Colors.backgroundGray()}`,
}}
border="top-and-bottom"
>
<SectionName>{sectionName}</SectionName>
</Box>
Expand All @@ -166,15 +159,17 @@ const SectionBody = ({children}: {children: React.ReactNode}) => {
);
};

const LinkToAssetGraphGroup = (groupMetadata: GroupMetadata) => {
return `/asset-groups?groups=[${encodeURIComponent(JSON.stringify(groupMetadata))}]`;
const linkToAssetGraphGroup = (groupMetadata: GroupMetadata) => {
return `/asset-groups?${qs.stringify({groups: JSON.stringify([groupMetadata])})}`;
};

const LinkToAssetGraphComputeKind = (computeKind: string) => {
return `/asset-groups?computeKindTags=${encodeURIComponent(JSON.stringify([computeKind]))}`;
const linkToAssetGraphComputeKind = (computeKind: string) => {
return `/asset-groups?${qs.stringify({
computeKindTags: JSON.stringify([computeKind]),
})}`;
};

const LinkToCodeLocation = (repoAddress: RepoAddress) => {
const linkToCodeLocation = (repoAddress: RepoAddress) => {
return `/locations/${repoAddressAsURLString(repoAddress)}/assets`;
};

Expand All @@ -201,6 +196,9 @@ export const AssetsOverview = ({viewerName}: {viewerName?: string}) => {
: [],
);
const {UserDisplay} = useLaunchPadHooks();
const {
timezone: [timezone],
} = useContext(TimeContext);

if (assetsQuery.loading) {
return (
Expand Down Expand Up @@ -234,11 +232,11 @@ export const AssetsOverview = ({viewerName}: {viewerName?: string}) => {
<Box style={{width: '60%'}} flex={{direction: 'column', gap: 16}}>
<Box flex={{direction: 'row', alignItems: 'center', justifyContent: 'space-between'}}>
<Heading>
{getGreeting()}
{getGreeting(timezone)}
{viewerName ? `, ${viewerName}` : ''}
</Heading>
<Box flex={{direction: 'row', gap: 12, alignItems: 'center'}}>
<ViewAllAssetsLink />
<Box flex={{direction: 'row', gap: 16, alignItems: 'center'}}>
<Link to="/assets">View all</Link>
<AssetGlobalLineageButton />
</Box>
</Box>
Expand All @@ -250,9 +248,9 @@ export const AssetsOverview = ({viewerName}: {viewerName?: string}) => {
<>
<SectionHeader sectionName="Owner" />
<SectionBody>
{Object.entries(assetCountBySection.countsByOwner).map(([label, count], idx) => (
<CountForAssetType key={idx} assetsCount={count}>
<UserDisplay key={idx} email={label} size="normal" />
{Object.entries(assetCountBySection.countsByOwner).map(([label, count]) => (
<CountForAssetType key={label} assetsCount={count}>
<UserDisplay email={label} />
</CountForAssetType>
))}
</SectionBody>
Expand All @@ -262,50 +260,52 @@ export const AssetsOverview = ({viewerName}: {viewerName?: string}) => {
<>
<SectionHeader sectionName="Compute kind" />
<SectionBody>
{Object.entries(assetCountBySection.countsByComputeKind).map(
([label, count], idx) => (
<CountForAssetType key={idx} assetsCount={count}>
<Box flex={{direction: 'row', gap: 4, alignItems: 'center'}}>
<TagIcon tag_label={label} />
<Link to={LinkToAssetGraphComputeKind(label)}>{label}</Link>
</Box>
</CountForAssetType>
),
)}
{Object.entries(assetCountBySection.countsByComputeKind).map(([label, count]) => (
<CountForAssetType key={label} assetsCount={count}>
<Box flex={{direction: 'row', gap: 4, alignItems: 'center'}}>
<TagIcon label={label} />
<Link to={linkToAssetGraphComputeKind(label)}>{label}</Link>
</Box>
</CountForAssetType>
))}
</SectionBody>
</>
)}
{assetCountBySection.countPerAssetGroup.length > 0 && (
<>
<SectionHeader sectionName="Asset groups" />
<SectionBody>
{assetCountBySection.countPerAssetGroup.map(
(assetGroupCount: CountPerGroupName, idx) => (
<CountForAssetType key={idx} assetsCount={assetGroupCount.assetCount}>
<Box flex={{direction: 'row', gap: 4, alignItems: 'center'}}>
<Icon name="asset_group" />
<Link to={LinkToAssetGraphGroup(assetGroupCount.groupMetadata)}>
{assetGroupCount.groupMetadata.groupName}
</Link>
<span style={{color: Colors.textLighter()}}>
{assetGroupCount.groupMetadata.repositoryLocationName}
</span>
</Box>
</CountForAssetType>
),
)}
{assetCountBySection.countPerAssetGroup.map((assetGroupCount) => (
<CountForAssetType
key={JSON.stringify(assetGroupCount.groupMetadata)}
assetsCount={assetGroupCount.assetCount}
>
<Box flex={{direction: 'row', gap: 4, alignItems: 'center'}}>
<Icon name="asset_group" />
<Link to={linkToAssetGraphGroup(assetGroupCount.groupMetadata)}>
{assetGroupCount.groupMetadata.groupName}
</Link>
<span style={{color: Colors.textLighter()}}>
{assetGroupCount.groupMetadata.repositoryLocationName}
</span>
</Box>
</CountForAssetType>
))}
</SectionBody>
</>
)}
{assetCountBySection.countPerCodeLocation.length > 0 && (
<>
<SectionHeader sectionName="Code locations" />
<SectionBody>
{assetCountBySection.countPerCodeLocation.map((countPerCodeLocation, idx) => (
<CountForAssetType key={idx} assetsCount={countPerCodeLocation.assetCount}>
{assetCountBySection.countPerCodeLocation.map((countPerCodeLocation) => (
<CountForAssetType
key={repoAddressAsHumanString(countPerCodeLocation.repoAddress)}
assetsCount={countPerCodeLocation.assetCount}
>
<Box flex={{direction: 'row', gap: 4, alignItems: 'center'}}>
<Icon name="folder" />
<Link to={LinkToCodeLocation(countPerCodeLocation.repoAddress)}>
<Link to={linkToCodeLocation(countPerCodeLocation.repoAddress)}>
{repoAddressAsHumanString(countPerCodeLocation.repoAddress)}
</Link>
</Box>
Expand Down
6 changes: 3 additions & 3 deletions js_modules/dagster-ui/packages/ui-core/src/graph/OpTags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,8 @@ export const OpTags = React.memo(({tags, style, reduceColor, reduceText}: OpTags
);
});

export const TagIcon = React.memo(({tag_label}: {tag_label: string}) => {
const known = KNOWN_TAGS[coerceToStandardLabel(tag_label) as keyof typeof KNOWN_TAGS];
export const TagIcon = React.memo(({label}: {label: string}) => {
const known = KNOWN_TAGS[coerceToStandardLabel(label) as keyof typeof KNOWN_TAGS];
const color = known?.color || null;
const reversed = known && 'reversed' in known ? known.reversed : false;
if (known && 'icon' in known) {
Expand All @@ -628,7 +628,7 @@ export const TagIcon = React.memo(({tag_label}: {tag_label: string}) => {
$img={known.icon.src}
$color={reversed ? Colors.accentPrimary() : color}
$rotation={null}
aria-label={tag_label}
aria-label={label}
/>
);
}
Expand Down
Loading

0 comments on commit 9f8c949

Please sign in to comment.