Issue 10516 (#13297)

* fix: add description component for lineage

* fix: update lineage data

* fix: code smells

---------

Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
karanh37 2023-09-22 12:59:05 +05:30 committed by GitHub
parent 11ba94e4ea
commit 41262ecb59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 134 additions and 18 deletions

View File

@ -13,8 +13,10 @@
import { CloseOutlined } from '@ant-design/icons';
import { Col, Divider, Drawer, Row, Typography } from 'antd';
import DescriptionV1 from 'components/common/description/DescriptionV1';
import { EntityType } from 'enums/entity.enum';
import { isUndefined } from 'lodash';
import React, { useEffect, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { Node } from 'reactflow';
@ -23,7 +25,6 @@ import { getEncodedFqn } from 'utils/StringsUtils';
import { CSMode } from '../../../enums/codemirror.enum';
import { getNameFromFQN } from '../../../utils/CommonUtils';
import { getEntityLink } from '../../../utils/TableUtils';
import RichTextEditorPreviewer from '../../common/rich-text-editor/RichTextEditorPreviewer';
import Loader from '../../Loader/Loader';
import SchemaEditor from '../../schema-editor/SchemaEditor';
import {
@ -37,12 +38,21 @@ const EdgeInfoDrawer = ({
visible,
onClose,
nodes,
hasEditAccess,
onEdgeDescriptionUpdate,
}: EdgeInfoDrawerInfo) => {
const [edgeData, setEdgeData] = useState<EdgeInformationType>();
const [mysqlQuery, setMysqlQuery] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [isDescriptionEditable, setIsDescriptionEditable] =
useState<boolean>(false);
const { t } = useTranslation();
const edgeEntity = useMemo(() => {
return edge.data.edge;
}, [edge]);
const getEdgeInfo = () => {
const { source, target, data, sourceHandle, targetHandle } = edge;
let sourceData: Node | undefined, targetData: Node | undefined;
@ -101,6 +111,39 @@ const EdgeInfoDrawer = ({
setIsLoading(false);
};
const edgeDescription = useMemo(() => {
return edgeEntity?.lineageDetails?.description ?? '';
}, [edgeEntity]);
const onDescriptionUpdate = useCallback(
async (updatedHTML: string) => {
if (edgeDescription !== updatedHTML && edgeEntity) {
const lineageDetails = {
...edgeEntity.lineageDetails,
description: updatedHTML,
};
const updatedEdgeDetails = {
edge: {
fromEntity: {
id: edgeEntity.fromEntity,
type: edge.data.sourceType,
},
toEntity: {
id: edgeEntity.toEntity,
type: edge.data.sourceType,
},
lineageDetails,
},
};
await onEdgeDescriptionUpdate(updatedEdgeDetails);
setIsDescriptionEditable(false);
} else {
setIsDescriptionEditable(false);
}
},
[edgeDescription, edgeEntity, edge.data]
);
useEffect(() => {
setIsLoading(true);
getEdgeInfo();
@ -145,20 +188,17 @@ const EdgeInfoDrawer = ({
)}
<Col span={24}>
<Divider />
<Typography.Paragraph className="summary-panel-section-title">
{`${t('label.description')}:`}
</Typography.Paragraph>
{edge?.data.edge?.description?.trim() ? (
<RichTextEditorPreviewer
markdown={edge?.data.edge?.description}
/>
) : (
<Typography.Paragraph className=" m-b-0">
{t('label.no-entity', {
entity: t('label.description'),
})}
</Typography.Paragraph>
)}
<DescriptionV1
description={edgeDescription}
entityName="Edge"
entityType={EntityType.GLOSSARY}
hasEditAccess={hasEditAccess}
isEdit={isDescriptionEditable}
showCommentsIcon={false}
onCancel={() => setIsDescriptionEditable(false)}
onDescriptionEdit={() => setIsDescriptionEditable(true)}
onDescriptionUpdate={onDescriptionUpdate}
/>
</Col>
<Col span={24}>
<Divider />

View File

@ -11,6 +11,7 @@
* limitations under the License.
*/
import { AddLineage } from 'generated/api/lineage/addLineage';
import { Edge, Node } from 'reactflow';
import { SelectedNode } from '../EntityLineage/EntityLineage.interface';
@ -25,7 +26,9 @@ export interface EdgeInfoDrawerInfo {
edge: Edge;
nodes: Node[];
visible: boolean;
hasEditAccess: boolean;
onClose: () => void;
onEdgeDescriptionUpdate: (updatedEdgeDetails: AddLineage) => Promise<void>;
}
type InfoType = {
key: string;

View File

@ -65,7 +65,7 @@ import ReactFlow, {
useNodesState,
} from 'reactflow';
import { getDataModelDetails } from 'rest/dataModelsAPI';
import { getLineageByFQN } from 'rest/lineageAPI';
import { getLineageByFQN, updateLineageEdge } from 'rest/lineageAPI';
import { searchData } from 'rest/miscAPI';
import { getTableDetails } from 'rest/tableAPI';
import {
@ -106,6 +106,7 @@ import {
onNodeMouseLeave,
onNodeMouseMove,
removeLineageHandler,
updateEdgesWithLineageDetails,
} from 'utils/EntityLineageUtils';
import {
getEntityBreadcrumbs,
@ -1482,6 +1483,56 @@ const EntityLineageComponent: FunctionComponent<EntityLineageProp> = ({
}
};
const onEdgeDescriptionUpdate = useCallback(
async (updatedEdgeDetails: AddLineage) => {
try {
await updateLineageEdge(updatedEdgeDetails);
if (selectedEdgeInfo) {
const updatedSelectedEdgeInfo = {
...selectedEdgeInfo,
data: {
...selectedEdgeInfo.data,
edge: {
...selectedEdgeInfo.data.edge,
lineageDetails: updatedEdgeDetails.edge.lineageDetails,
},
},
};
const updatedEdges = edges.map((edge) =>
edge.id === selectedEdgeInfo.id ? updatedSelectedEdgeInfo : edge
);
setEdges(updatedEdges);
setSelectedEdgeInfo(updatedSelectedEdgeInfo);
setUpdatedLineageData((pre) => {
if (!pre) {
return;
}
const newData = {
...pre,
downstreamEdges: updateEdgesWithLineageDetails(
pre.downstreamEdges ?? [],
updatedEdgeDetails
),
upstreamEdges: updateEdgesWithLineageDetails(
pre.upstreamEdges ?? [],
updatedEdgeDetails
),
};
return newData;
});
}
} catch (err) {
showErrorToast(err as AxiosError);
}
},
[edges, selectedEdgeInfo, updatedLineageData, setUpdatedLineageData]
);
/**
* Handle updated lineage nodes
* Change newly added node label based on entity:EntityReference
@ -1681,12 +1732,14 @@ const EntityLineageComponent: FunctionComponent<EntityLineageProp> = ({
(selectedEdgeInfo ? (
<EdgeInfoDrawer
edge={selectedEdgeInfo}
hasEditAccess={hasEditAccess}
nodes={nodes}
visible={isDrawerOpen}
onClose={() => {
setIsDrawerOpen(false);
setSelectedEdgeInfo(undefined);
}}
onEdgeDescriptionUpdate={onEdgeDescriptionUpdate}
/>
) : (
<EntityInfoDrawer

View File

@ -32,7 +32,7 @@ export interface SelectedNode {
export interface EntityLineageProp {
entityType: EntityType;
deleted?: boolean;
hasEditAccess?: boolean;
hasEditAccess: boolean;
isFullScreen?: boolean;
entity?: SourceType;
}

View File

@ -11,6 +11,7 @@
* limitations under the License.
*/
import { AddLineage } from 'generated/api/lineage/addLineage';
import { EntityLineage } from '../generated/type/entityLineage';
import APIClient from './index';
@ -26,3 +27,9 @@ export const getLineageByFQN = async (
return response.data;
};
export const updateLineageEdge = async (edge: AddLineage) => {
const response = await APIClient.put<AddLineage>(`/lineage`, edge);
return response.data;
};

View File

@ -1372,3 +1372,16 @@ export const getSearchIndexFromNodeType = (entityType: string) => {
return SearchIndex[searchIndexKey] as ExploreSearchIndex;
};
export const updateEdgesWithLineageDetails = (
edgesArray: EntityLineageEdge[],
updatedEdgeDetails: AddLineage
) => {
const { fromEntity, toEntity, lineageDetails } = updatedEdgeDetails.edge;
return edgesArray.map((item) =>
item.toEntity === toEntity.id && item.fromEntity === fromEntity.id
? { ...item, lineageDetails: lineageDetails }
: item
);
};