Skip to content

Commit

Permalink
[ui] add storage kind asset search result (#22097)
Browse files Browse the repository at this point in the history
## Summary

Adds a search result which takes users to the assets page, filtered by storage kind for our global search.

<img width="305" alt="Screenshot 2024-05-24 at 2 21 21 PM" src="https://github.com/dagster-io/dagster/assets/10215173/52c73254-11d2-4d56-8516-938618f63bad">


## Test Plan

Tested locally.
  • Loading branch information
benpankow authored May 28, 2024
1 parent d47c5b3 commit 2d1619e
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import close from '../icon-svgs/close.svg';
import code_location from '../icon-svgs/code_location.svg';
import collapse_arrows from '../icon-svgs/collapse_arrows.svg';
import column_lineage from '../icon-svgs/column_lineage.svg';
import compute_kind from '../icon-svgs/compute_kind.svg';
import concept_book from '../icon-svgs/concept-book.svg';
import console_icon from '../icon-svgs/console.svg';
import content_copy from '../icon-svgs/content_copy.svg';
Expand Down Expand Up @@ -153,6 +154,7 @@ import star from '../icon-svgs/star.svg';
import star_outline from '../icon-svgs/star_outline.svg';
import status from '../icon-svgs/status.svg';
import sticky_note from '../icon-svgs/sticky_note.svg';
import storage_kind from '../icon-svgs/storage_kind.svg';
import sync_alt from '../icon-svgs/sync_alt.svg';
import sync_problem from '../icon-svgs/sync_problem.svg';
import table_rows from '../icon-svgs/table_rows.svg';
Expand Down Expand Up @@ -291,6 +293,7 @@ export const Icons = {
chevron_left,
close,
code_location,
compute_kind,
console: console_icon,
content_copy,
collapse_arrows,
Expand Down Expand Up @@ -354,6 +357,7 @@ export const Icons = {
star_outline,
status,
sticky_note,
storage_kind,
sync_alt,
sync_problem,
table_view,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import {CaptionMono, Tooltip} from '@dagster-io/ui-components';
import * as React from 'react';

import {OpTags} from './OpTags';
import {DefinitionTag} from '../graphql/types';
import {DefinitionTag, buildDefinitionTag} from '../graphql/types';

export const isCanonicalStorageKindTag = (tag: DefinitionTag) => tag.key === 'dagster/storage_kind';
export const buildStorageKindTag = (storageKind: string): DefinitionTag =>
buildDefinitionTag({key: 'dagster/storage_kind', value: storageKind});

export const AssetComputeKindTag = ({
definition,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {COMMON_COLLATOR} from '../app/Util';
import {AssetTableDefinitionFragment} from '../assets/types/AssetTableFragment.types';
import {isCanonicalStorageKindTag} from '../graph/KindTags';
import {DefinitionTag} from '../graphql/types';
import {buildTagString} from '../ui/tagAsString';
import {buildRepoPathForHuman} from '../workspace/buildRepoAddress';
Expand All @@ -17,6 +18,11 @@ type CountByComputeKind = {
assetCount: number;
};

type CountByStorageKind = {
storageKind: string;
assetCount: number;
};

type CountPerTag = {
tag: DefinitionTag;
assetCount: number;
Expand All @@ -38,6 +44,7 @@ type AssetCountsResult = {
countPerTag: CountPerTag[];
countPerAssetGroup: CountPerGroupName[];
countPerCodeLocation: CountPerCodeLocation[];
countsByStorageKind: CountByStorageKind[];
};

export type GroupMetadata = {
Expand All @@ -56,6 +63,7 @@ type AssetDefinitionMetadata = {
export function buildAssetCountBySection(assets: AssetDefinitionMetadata[]): AssetCountsResult {
const assetCountByOwner: Record<string, number> = {};
const assetCountByComputeKind: Record<string, number> = {};
const assetCountByStorageKind: Record<string, number> = {};
const assetCountByGroup: Record<string, number> = {};
const assetCountByCodeLocation: Record<string, number> = {};
const assetCountByTag: Record<string, number> = {};
Expand All @@ -75,8 +83,12 @@ export function buildAssetCountBySection(assets: AssetDefinitionMetadata[]): Ass
}

assetDefinition.tags.forEach((tag) => {
const stringifiedTag = JSON.stringify(tag);
assetCountByTag[stringifiedTag] = (assetCountByTag[stringifiedTag] || 0) + 1;
if (isCanonicalStorageKindTag(tag)) {
assetCountByStorageKind[tag.value] = (assetCountByStorageKind[tag.value] || 0) + 1;
} else {
const stringifiedTag = JSON.stringify(tag);
assetCountByTag[stringifiedTag] = (assetCountByTag[stringifiedTag] || 0) + 1;
}
});

const groupName = assetDefinition.groupName;
Expand Down Expand Up @@ -112,6 +124,15 @@ export function buildAssetCountBySection(assets: AssetDefinitionMetadata[]): Ass
.sort(({computeKind: computeKindA}, {computeKind: computeKindB}) =>
COMMON_COLLATOR.compare(computeKindA, computeKindB),
);
const countsByStorageKind = Object.entries(assetCountByStorageKind)
.map(([storageKind, count]) => ({
storageKind,
assetCount: count,
}))
.sort(({storageKind: storageKindA}, {storageKind: storageKindB}) =>
COMMON_COLLATOR.compare(storageKindA, storageKindB),
);

const countPerTag = Object.entries(assetCountByTag)
.map(([tagIdentifier, count]) => ({
assetCount: count,
Expand Down Expand Up @@ -166,5 +187,6 @@ export function buildAssetCountBySection(assets: AssetDefinitionMetadata[]): Ass
countPerTag,
countPerAssetGroup,
countPerCodeLocation,
countsByStorageKind,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ const iconForType = (type: SearchResultType | AssetFilterSearchResultType): Icon
case AssetFilterSearchResultType.AssetGroup:
return 'asset_group';
case AssetFilterSearchResultType.ComputeKind:
return 'tag';
return 'compute_kind';
case AssetFilterSearchResultType.Tag:
return 'tag';
case AssetFilterSearchResultType.StorageKind:
return 'storage_kind';
default:
return 'source';
}
Expand All @@ -67,6 +69,8 @@ const assetFilterPrefixString = (type: AssetFilterSearchResultType): string => {
return 'Owner';
case AssetFilterSearchResultType.AssetGroup:
return 'Group';
case AssetFilterSearchResultType.StorageKind:
return 'Storage kind';
default:
return '';
}
Expand Down
2 changes: 2 additions & 0 deletions js_modules/dagster-ui/packages/ui-core/src/search/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export enum AssetFilterSearchResultType {
CodeLocation = 'AssetFilterSearchResultType.CodeLocation',
Owner = 'AssetFilterSearchResultType.Owner',
AssetGroup = 'AssetFilterSearchResultType.AssetGroup',
StorageKind = 'AssetFilterSearchResultType.StorageKind',
}

export function isAssetFilterSearchResultType(
Expand All @@ -31,6 +32,7 @@ export function isAssetFilterSearchResultType(
type === AssetFilterSearchResultType.AssetGroup ||
type === AssetFilterSearchResultType.CodeLocation ||
type === AssetFilterSearchResultType.ComputeKind ||
type === AssetFilterSearchResultType.StorageKind ||
type === AssetFilterSearchResultType.Owner ||
type === AssetFilterSearchResultType.Tag
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {CloudOSSContext} from '../app/CloudOSSContext';
import {PYTHON_ERROR_FRAGMENT} from '../app/PythonErrorFragment';
import {displayNameForAssetKey, isHiddenAssetGroupJob} from '../asset-graph/Utils';
import {assetDetailsPathForKey} from '../assets/assetDetailsPathForKey';
import {buildStorageKindTag} from '../graph/KindTags';
import {DefinitionTag} from '../graphql/types';
import {buildTagString} from '../ui/tagAsString';
import {buildRepoPathForHuman} from '../workspace/buildRepoAddress';
Expand All @@ -34,6 +35,12 @@ export const linkToAssetTableWithComputeKindFilter = (computeKind: string) => {
})}`;
};

export const linkToAssetTableWithStorageKindFilter = (storageKind: string) => {
return `/assets?${qs.stringify({
storageKindTags: JSON.stringify([buildStorageKindTag(storageKind)]),
})}`;
};

export const linkToAssetTableWithTagFilter = (tag: DefinitionTag) => {
return `/assets?${qs.stringify({
tags: JSON.stringify([tag]),
Expand Down Expand Up @@ -214,6 +221,15 @@ const secondaryDataToSearchResults = (
numResults: assetCount,
}),
);
const storageKindResults: SearchResult[] = countsBySection.countsByStorageKind.map(
({storageKind, assetCount}) => ({
label: storageKind,
description: '',
type: AssetFilterSearchResultType.StorageKind,
href: linkToAssetTableWithStorageKindFilter(storageKind),
numResults: assetCount,
}),
);

const tagResults: SearchResult[] = countsBySection.countPerTag.map(({tag, assetCount}) => ({
label: buildTagString(tag),
Expand Down Expand Up @@ -262,6 +278,7 @@ const secondaryDataToSearchResults = (
return [
...assets,
...computeKindResults,
...storageKindResults,
...tagResults,
...codeLocationResults,
...ownerResults,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const useComputeKindTagFilter = ({
}) => {
return useStaticSetFilter<string>({
name: 'Compute kind',
icon: 'tag',
icon: 'compute_kind',
allValues: useMemo(
() =>
allComputeKindTags.map((value) => ({
Expand All @@ -29,7 +29,7 @@ export const useComputeKindTagFilter = ({
menuWidth: '300px',
renderLabel: ({value}) => (
<Box flex={{direction: 'row', gap: 4, alignItems: 'center'}}>
<Icon name="tag" />
<Icon name="compute_kind" />
<TruncatedTextWithFullTextOnHover tooltipText={value} text={value} />
</Box>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const useStorageKindFilter = ({
const memoizedState = useMemo(() => storageKindTags?.map(buildDefinitionTag), [storageKindTags]);
return useStaticSetFilter<DefinitionTag>({
name: 'Storage kind',
icon: 'tag',
icon: 'storage_kind',
allValues: useMemo(
() =>
allAssetStorageKindTags.map((value) => ({
Expand All @@ -33,7 +33,7 @@ export const useStorageKindFilter = ({
renderLabel: ({value: tag}) => {
return (
<Box flex={{direction: 'row', gap: 4, alignItems: 'center'}}>
<Icon name="tag" />
<Icon name="storage_kind" />
<TruncatedTextWithFullTextOnHover tooltipText={tag.value} text={tag.value} />
</Box>
);
Expand Down

2 comments on commit 2d1619e

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for dagit-core-storybook ready!

✅ Preview
https://dagit-core-storybook-byknvziqw-elementl.vercel.app

Built with commit 2d1619e.
This pull request is being automatically deployed with vercel-action

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for dagit-storybook ready!

✅ Preview
https://dagit-storybook-psnxrn6xw-elementl.vercel.app

Built with commit 2d1619e.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.