mirror of
https://github.com/datahub-project/datahub.git
synced 2025-12-17 13:04:04 +00:00
fix(ui): make data process instance visible in container in V2& fix model/modelgroup names (#12513)
This commit is contained in:
parent
d2b0e57528
commit
469cc4f8fa
@ -143,7 +143,8 @@ export class MLModelEntity implements Entity<MlModel> {
|
|||||||
getLineageVizConfig = (entity: MlModel) => {
|
getLineageVizConfig = (entity: MlModel) => {
|
||||||
return {
|
return {
|
||||||
urn: entity.urn,
|
urn: entity.urn,
|
||||||
name: entity.name,
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
||||||
|
name: entity.properties?.['propertiesName'] || entity.name,
|
||||||
type: EntityType.Mlmodel,
|
type: EntityType.Mlmodel,
|
||||||
icon: entity.platform?.properties?.logoUrl || undefined,
|
icon: entity.platform?.properties?.logoUrl || undefined,
|
||||||
platform: entity.platform,
|
platform: entity.platform,
|
||||||
|
|||||||
@ -24,7 +24,11 @@ export default function MLModelGroupsTab() {
|
|||||||
title: 'Group',
|
title: 'Group',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
render: (name, record) => {
|
render: (name, record) => {
|
||||||
return <Link href={entityRegistry.getEntityUrl(EntityType.MlmodelGroup, record.urn)}>{name}</Link>;
|
return (
|
||||||
|
<Link href={entityRegistry.getEntityUrl(EntityType.MlmodelGroup, record.urn)}>
|
||||||
|
{record.properties?.name || name}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -131,7 +131,8 @@ export class MLModelGroupEntity implements Entity<MlModelGroup> {
|
|||||||
getLineageVizConfig = (entity: MlModelGroup) => {
|
getLineageVizConfig = (entity: MlModelGroup) => {
|
||||||
return {
|
return {
|
||||||
urn: entity.urn,
|
urn: entity.urn,
|
||||||
name: entity.name,
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
||||||
|
name: entity.properties?.['propertiesName'] || entity.name,
|
||||||
type: EntityType.MlmodelGroup,
|
type: EntityType.MlmodelGroup,
|
||||||
icon: entity.platform?.properties?.logoUrl || undefined,
|
icon: entity.platform?.properties?.logoUrl || undefined,
|
||||||
platform: entity.platform,
|
platform: entity.platform,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { GenericEntityProperties } from '@app/entity/shared/types';
|
import { GenericEntityProperties } from '@app/entity/shared/types';
|
||||||
|
import { Entity as GraphQLEntity } from '@types';
|
||||||
import { globalEntityRegistryV2 } from '@app/EntityRegistryProvider';
|
import { globalEntityRegistryV2 } from '@app/EntityRegistryProvider';
|
||||||
import { Entity, EntityCapabilityType, IconStyleType, PreviewType } from '@app/entityV2/Entity';
|
import { Entity, EntityCapabilityType, IconStyleType, PreviewType } from '@app/entityV2/Entity';
|
||||||
import { EntityProfile } from '@app/entityV2/shared/containers/profile/EntityProfile';
|
import { EntityProfile } from '@app/entityV2/shared/containers/profile/EntityProfile';
|
||||||
@ -11,24 +12,21 @@ import { getDataProduct } from '@app/entityV2/shared/utils';
|
|||||||
import { GetDataProcessInstanceQuery, useGetDataProcessInstanceQuery } from '@graphql/dataProcessInstance.generated';
|
import { GetDataProcessInstanceQuery, useGetDataProcessInstanceQuery } from '@graphql/dataProcessInstance.generated';
|
||||||
import { ArrowsClockwise } from 'phosphor-react';
|
import { ArrowsClockwise } from 'phosphor-react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DataProcessInstance, Entity as GeneratedEntity, EntityType, SearchResult } from '../../../types.generated';
|
import { DataProcessInstance, EntityType, SearchResult } from '../../../types.generated';
|
||||||
import Preview from './preview/Preview';
|
import Preview from './preview/Preview';
|
||||||
|
import DataProcessInstanceSummary from './profile/DataProcessInstanceSummary';
|
||||||
|
|
||||||
const getParentEntities = (data: DataProcessInstance): GeneratedEntity[] => {
|
const getParentEntities = (data: DataProcessInstance): GraphQLEntity[] => {
|
||||||
const parentEntity = data?.relationships?.relationships?.find(
|
const parentEntity = data?.relationships?.relationships?.find(
|
||||||
(rel) => rel.type === 'InstanceOf' && rel.entity?.type === EntityType.DataJob,
|
(rel) => rel.type === 'InstanceOf' && rel.entity?.type === EntityType.DataJob,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!parentEntity?.entity) return [];
|
if (!parentEntity || !parentEntity.entity) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
// Convert to GeneratedEntity
|
// First cast to unknown, then to Entity with proper type
|
||||||
return [
|
return [parentEntity.entity];
|
||||||
{
|
|
||||||
type: parentEntity.entity.type,
|
|
||||||
urn: (parentEntity.entity as any).urn, // Make sure urn exists
|
|
||||||
relationships: (parentEntity.entity as any).relationships,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,6 +83,10 @@ export class DataProcessInstanceEntity implements Entity<DataProcessInstance> {
|
|||||||
new Set([EntityMenuItems.UPDATE_DEPRECATION, EntityMenuItems.RAISE_INCIDENT, EntityMenuItems.SHARE])
|
new Set([EntityMenuItems.UPDATE_DEPRECATION, EntityMenuItems.RAISE_INCIDENT, EntityMenuItems.SHARE])
|
||||||
}
|
}
|
||||||
tabs={[
|
tabs={[
|
||||||
|
{
|
||||||
|
name: 'Summary',
|
||||||
|
component: DataProcessInstanceSummary,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Lineage',
|
name: 'Lineage',
|
||||||
component: LineageTab,
|
component: LineageTab,
|
||||||
|
|||||||
@ -0,0 +1,102 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { Space, Table, Typography } from 'antd';
|
||||||
|
import { formatDetailedDuration } from '@src/app/shared/time/timeUtils';
|
||||||
|
import { capitalize } from 'lodash';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { MlHyperParam, MlMetric, DataProcessInstanceRunResultType } from '../../../../types.generated';
|
||||||
|
import { useBaseEntity } from '../../../entity/shared/EntityContext';
|
||||||
|
import { InfoItem } from '../../shared/components/styled/InfoItem';
|
||||||
|
import { GetDataProcessInstanceQuery } from '../../../../graphql/dataProcessInstance.generated';
|
||||||
|
import { Pill } from '../../../../alchemy-components/components/Pills';
|
||||||
|
|
||||||
|
const TabContent = styled.div`
|
||||||
|
padding: 16px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const InfoItemContainer = styled.div<{ justifyContent }>`
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
justify-content: ${(props) => props.justifyContent};
|
||||||
|
padding: 0px 2px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const InfoItemContent = styled.div`
|
||||||
|
padding-top: 8px;
|
||||||
|
width: 100px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const propertyTableColumns = [
|
||||||
|
{
|
||||||
|
title: 'Name',
|
||||||
|
dataIndex: 'name',
|
||||||
|
width: 450,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Value',
|
||||||
|
dataIndex: 'value',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function DataProcessInstanceSummary() {
|
||||||
|
const baseEntity = useBaseEntity<GetDataProcessInstanceQuery>();
|
||||||
|
const dpi = baseEntity?.dataProcessInstance;
|
||||||
|
|
||||||
|
const formatStatus = (state) => {
|
||||||
|
if (!state || state.length === 0) return '-';
|
||||||
|
const result = state[0]?.result?.resultType;
|
||||||
|
const statusColor = result === DataProcessInstanceRunResultType.Success ? 'green' : 'red';
|
||||||
|
return <Pill label={capitalize(result)} colorScheme={statusColor} clickable={false} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatDuration = (state) => {
|
||||||
|
if (!state || state.length === 0) return '-';
|
||||||
|
return formatDetailedDuration(state[0]?.durationMillis);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TabContent>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }} size="large">
|
||||||
|
<Typography.Title level={3}>Details</Typography.Title>
|
||||||
|
<InfoItemContainer justifyContent="left">
|
||||||
|
<InfoItem title="Created At">
|
||||||
|
<InfoItemContent>
|
||||||
|
{dpi?.properties?.created?.time
|
||||||
|
? moment(dpi.properties.created.time).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
: '-'}
|
||||||
|
</InfoItemContent>
|
||||||
|
</InfoItem>
|
||||||
|
<InfoItem title="Status">
|
||||||
|
<InfoItemContent>{formatStatus(dpi?.state)}</InfoItemContent>
|
||||||
|
</InfoItem>
|
||||||
|
<InfoItem title="Duration">
|
||||||
|
<InfoItemContent>{formatDuration(dpi?.state)}</InfoItemContent>
|
||||||
|
</InfoItem>
|
||||||
|
<InfoItem title="Run ID">
|
||||||
|
<InfoItemContent>{dpi?.mlTrainingRunProperties?.id}</InfoItemContent>
|
||||||
|
</InfoItem>
|
||||||
|
<InfoItem title="Created By">
|
||||||
|
<InfoItemContent>{dpi?.properties?.created?.actor}</InfoItemContent>
|
||||||
|
</InfoItem>
|
||||||
|
</InfoItemContainer>
|
||||||
|
<InfoItemContainer justifyContent="left">
|
||||||
|
<InfoItem title="Artifacts Location">
|
||||||
|
<InfoItemContent>{dpi?.mlTrainingRunProperties?.outputUrls}</InfoItemContent>
|
||||||
|
</InfoItem>
|
||||||
|
</InfoItemContainer>
|
||||||
|
<Typography.Title level={3}>Training Metrics</Typography.Title>
|
||||||
|
<Table
|
||||||
|
pagination={false}
|
||||||
|
columns={propertyTableColumns}
|
||||||
|
dataSource={dpi?.mlTrainingRunProperties?.trainingMetrics as MlMetric[]}
|
||||||
|
/>
|
||||||
|
<Typography.Title level={3}>Hyper Parameters</Typography.Title>
|
||||||
|
<Table
|
||||||
|
pagination={false}
|
||||||
|
columns={propertyTableColumns}
|
||||||
|
dataSource={dpi?.mlTrainingRunProperties?.hyperParams as MlHyperParam[]}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</TabContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -192,7 +192,8 @@ export class MLModelEntity implements Entity<MlModel> {
|
|||||||
getLineageVizConfig = (entity: MlModel) => {
|
getLineageVizConfig = (entity: MlModel) => {
|
||||||
return {
|
return {
|
||||||
urn: entity.urn,
|
urn: entity.urn,
|
||||||
name: entity.name,
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
||||||
|
name: entity.properties?.['propertiesName'] || entity.name,
|
||||||
type: EntityType.Mlmodel,
|
type: EntityType.Mlmodel,
|
||||||
icon: entity.platform?.properties?.logoUrl || undefined,
|
icon: entity.platform?.properties?.logoUrl || undefined,
|
||||||
platform: entity.platform,
|
platform: entity.platform,
|
||||||
@ -201,7 +202,7 @@ export class MLModelEntity implements Entity<MlModel> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
displayName = (data: MlModel) => {
|
displayName = (data: MlModel) => {
|
||||||
return data.name || data.urn;
|
return data.properties?.name || data.name || data.urn;
|
||||||
};
|
};
|
||||||
|
|
||||||
getGenericEntityProperties = (mlModel: MlModel) => {
|
getGenericEntityProperties = (mlModel: MlModel) => {
|
||||||
|
|||||||
@ -31,7 +31,8 @@ export const Preview = ({
|
|||||||
return (
|
return (
|
||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.Mlmodel, model.urn)}
|
url={entityRegistry.getEntityUrl(EntityType.Mlmodel, model.urn)}
|
||||||
name={model.name || ''}
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
||||||
|
name={model?.properties?.['propertiesName'] || model?.name || ''}
|
||||||
urn={model.urn}
|
urn={model.urn}
|
||||||
data={data}
|
data={data}
|
||||||
description={model.description || ''}
|
description={model.description || ''}
|
||||||
|
|||||||
@ -24,7 +24,11 @@ export default function MLModelGroupsTab() {
|
|||||||
title: 'Group',
|
title: 'Group',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
render: (name, record) => {
|
render: (name, record) => {
|
||||||
return <Link href={entityRegistry.getEntityUrl(EntityType.MlmodelGroup, record.urn)}>{name}</Link>;
|
return (
|
||||||
|
<Link href={entityRegistry.getEntityUrl(EntityType.MlmodelGroup, record.urn)}>
|
||||||
|
{record.properties?.name || name}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -175,7 +175,8 @@ export class MLModelGroupEntity implements Entity<MlModelGroup> {
|
|||||||
getLineageVizConfig = (entity: MlModelGroup) => {
|
getLineageVizConfig = (entity: MlModelGroup) => {
|
||||||
return {
|
return {
|
||||||
urn: entity.urn,
|
urn: entity.urn,
|
||||||
name: entity.name,
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
||||||
|
name: entity.properties?.['propertiesName'] || entity.name,
|
||||||
type: EntityType.MlmodelGroup,
|
type: EntityType.MlmodelGroup,
|
||||||
icon: entity.platform?.properties?.logoUrl || undefined,
|
icon: entity.platform?.properties?.logoUrl || undefined,
|
||||||
platform: entity.platform,
|
platform: entity.platform,
|
||||||
@ -184,7 +185,7 @@ export class MLModelGroupEntity implements Entity<MlModelGroup> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
displayName = (data: MlModelGroup) => {
|
displayName = (data: MlModelGroup) => {
|
||||||
return data.name || data.urn;
|
return data.properties?.name || data.name || data.urn;
|
||||||
};
|
};
|
||||||
|
|
||||||
getGenericEntityProperties = (mlModelGroup: MlModelGroup) => {
|
getGenericEntityProperties = (mlModelGroup: MlModelGroup) => {
|
||||||
|
|||||||
@ -30,7 +30,8 @@ export const Preview = ({
|
|||||||
return (
|
return (
|
||||||
<DefaultPreviewCard
|
<DefaultPreviewCard
|
||||||
url={entityRegistry.getEntityUrl(EntityType.MlmodelGroup, group.urn)}
|
url={entityRegistry.getEntityUrl(EntityType.MlmodelGroup, group.urn)}
|
||||||
name={group?.name || ''}
|
// eslint-disable-next-line @typescript-eslint/dot-notation
|
||||||
|
name={group?.properties?.['propertiesName'] || group?.name || ''}
|
||||||
urn={group.urn}
|
urn={group.urn}
|
||||||
data={data}
|
data={data}
|
||||||
platformInstanceId={group.dataPlatformInstance?.instanceId}
|
platformInstanceId={group.dataPlatformInstance?.instanceId}
|
||||||
|
|||||||
@ -1054,6 +1054,9 @@ fragment nonRecursiveMLModel on MLModel {
|
|||||||
urn
|
urn
|
||||||
name
|
name
|
||||||
description
|
description
|
||||||
|
properties {
|
||||||
|
name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
customProperties {
|
customProperties {
|
||||||
key
|
key
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user