diff --git a/js_modules/dagster-ui/packages/ui-components/src/components/Icon.tsx b/js_modules/dagster-ui/packages/ui-components/src/components/Icon.tsx index b5c3de86354b9..c0cb72f672231 100644 --- a/js_modules/dagster-ui/packages/ui-components/src/components/Icon.tsx +++ b/js_modules/dagster-ui/packages/ui-components/src/components/Icon.tsx @@ -44,6 +44,10 @@ import collapse_arrows from '../icon-svgs/collapse_arrows.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'; +import datatype_array from '../icon-svgs/datatype_array.svg'; +import datatype_bool from '../icon-svgs/datatype_bool.svg'; +import datatype_number from '../icon-svgs/datatype_number.svg'; +import datatype_string from '../icon-svgs/datatype_string.svg'; import date from '../icon-svgs/date.svg'; import deleteSVG from '../icon-svgs/delete.svg'; import done from '../icon-svgs/done.svg'; @@ -176,6 +180,10 @@ export const Icons = { backfill, badge, date, + datatype_array, + datatype_bool, + datatype_string, + datatype_number, expectation, execute, materialization, diff --git a/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_array.svg b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_array.svg new file mode 100644 index 0000000000000..9aedc9d5de883 --- /dev/null +++ b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_array.svg @@ -0,0 +1,3 @@ + + + diff --git a/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_bool.svg b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_bool.svg new file mode 100644 index 0000000000000..f5fb9e6c75852 --- /dev/null +++ b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_bool.svg @@ -0,0 +1,3 @@ + + + diff --git a/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_number.svg b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_number.svg new file mode 100644 index 0000000000000..226fc45e2c46a --- /dev/null +++ b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_number.svg @@ -0,0 +1,3 @@ + + + diff --git a/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_string.svg b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_string.svg new file mode 100644 index 0000000000000..55530819ca2d0 --- /dev/null +++ b/js_modules/dagster-ui/packages/ui-components/src/icon-svgs/datatype_string.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/js_modules/dagster-ui/packages/ui-core/src/assets/AssetNodeOverview.tsx b/js_modules/dagster-ui/packages/ui-core/src/assets/AssetNodeOverview.tsx index 9fbcef4ba4b7a..1172e7ef98b0a 100644 --- a/js_modules/dagster-ui/packages/ui-core/src/assets/AssetNodeOverview.tsx +++ b/js_modules/dagster-ui/packages/ui-core/src/assets/AssetNodeOverview.tsx @@ -95,15 +95,19 @@ export const AssetNodeOverview = ({ const visibleJobNames = assetNode.jobNames.filter((jobName) => !isHiddenAssetGroupJob(jobName)); const assetNodeLoadTimestamp = location ? location.updatedTimestamp * 1000 : undefined; - const latestPartitionEvents = useLatestPartitionEvents( + + const {materialization, observation} = useLatestPartitionEvents( assetNode, assetNodeLoadTimestamp, liveData, ); - const tableSchema = [...(latestPartitionEvents.materialization?.metadataEntries || [])].find( - isCanonicalTableSchemaEntry, - ); + let tableSchema = materialization?.metadataEntries.find(isCanonicalTableSchemaEntry); + let tableSchemaLoadTimestamp = materialization ? Number(materialization.timestamp) : undefined; + if (!tableSchema) { + tableSchema = assetNode?.metadataEntries.find(isCanonicalTableSchemaEntry); + tableSchemaLoadTimestamp = assetNodeLoadTimestamp; + } return ( ) : ( No table schema @@ -155,16 +159,10 @@ export const AssetNodeOverview = ({ showTimestamps showFilter hideTableSchema - observations={ - latestPartitionEvents.observation && latestPartitionEvents.materialization - ? [latestPartitionEvents.observation] - : [] - } + observations={observation && materialization ? [observation] : []} definitionMetadata={assetMetadata} definitionLoadTimestamp={assetNodeLoadTimestamp} - event={ - latestPartitionEvents.materialization || latestPartitionEvents.observation || null - } + event={materialization || observation || null} /> - + {schemaLoadTimestamp && ( - - Updated - + + Updated + )} {multiColumnConstraints.length > 0 && ( @@ -75,7 +85,7 @@ export const TableSchema = ({ {column.name} - + {!column.constraints.nullable && NonNullableTag} {column.constraints.unique && UniqueTag} {column.constraints.other.map((constraint, i) => ( @@ -98,7 +108,34 @@ export const TableSchema = ({ ); }; -const TypeTag = ({type}: {type: string}) => {type}; +const iconForType = (type: string): IconName | null => { + const lower = type.toLowerCase(); + if (lower.includes('bool')) { + return 'datatype_bool'; + } + if (['char', 'str', 'text', 'uuid'].some((term) => lower.includes(term))) { + return 'datatype_string'; + } + if (lower.includes('arr') || lower.includes('[]')) { + return 'datatype_array'; + } + if (['int', 'float', 'double', 'num', 'decimal'].some((term) => lower.includes(term))) { + return 'datatype_number'; + } + if (lower.includes('time') || lower.includes('date')) { + return 'schedule'; + } + return null; +}; + +const TypeTag = ({type, icon}: {type: string; icon: IconName | null}) => ( + + + {icon ? : } + {type} + + +); const NonNullableTag = non-nullable;