diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/AddPipeLineModal.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/AddPipeLineModal.tsx deleted file mode 100644 index caf8b14b07b..00000000000 --- a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/AddPipeLineModal.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2022 Collate. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Button, Modal, Select } from 'antd'; -import { t } from 'i18next'; -import { isUndefined } from 'lodash'; -import React from 'react'; -import { EntityReference } from '../../../generated/entity/type'; -import { getEntityName } from '../../../utils/EntityUtils'; - -interface AddPipeLineModalType { - showAddEdgeModal: boolean; - edgeSearchValue: string; - selectedEdgeId: string | undefined; - edgeOptions: EntityReference[]; - onModalCancel: () => void; - onSave: () => void; - onClear: () => void; - onRemoveEdgeClick: (evt: React.MouseEvent) => void; - onSearch: (value: string) => void; - onSelect: (value: string) => void; -} - -const AddPipeLineModal = ({ - showAddEdgeModal, - edgeOptions, - edgeSearchValue, - selectedEdgeId, - onRemoveEdgeClick, - onModalCancel, - onSave, - onClear, - onSearch, - onSelect, -}: AddPipeLineModalType) => { - return ( - - {t('label.remove-entity', { - entity: t('label.edge-lowercase'), - })} - , - , - ]} - maskClosable={false} - open={showAddEdgeModal} - title={t(`label.${isUndefined(selectedEdgeId) ? 'add' : 'edit'}-entity`, { - entity: t('label.edge'), - })} - onCancel={onModalCancel}> - onSearch(e.target.value)} + /> + +
+ {edgeOptions.map((item) => { + const icon = getEntityIcon(item.type); + const breadcrumb = Fqn.split(item.fullyQualifiedName).join('/'); + + return ( +
onSelect(item.id)}> +
{icon}
+
+
+ {breadcrumb} +
+
+ + {getEntityName(item)} + +
+
+
+ ); + })} + + {errorPlaceholderEdge} +
+
+ ); +}; + +export default AddPipeLineModal; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/AppPipelineModel/add-pipeline-modal.less b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/AppPipelineModel/add-pipeline-modal.less new file mode 100644 index 00000000000..f4780ece4c4 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/AppPipelineModel/add-pipeline-modal.less @@ -0,0 +1,47 @@ +/* + * Copyright 2023 Collate. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@import (reference) url('../../../../styles/variables.less'); + +.edge-option-container { + margin-top: 6px; + width: 100%; + height: 310px; + overflow: scroll; + + .edge-option-item { + display: flex; + align-items: center; + margin: 8px 0; + padding: 8px; + border-radius: 4px; + cursor: pointer; + + &.active { + background: @primary-color-hover; + + &:hover { + background: @primary-color-hover; + } + } + + &:hover { + background: @body-dark-bg-color; + } + + .breadcrumb { + color: @text-grey-muted; + font-size: 10px; + } + } +} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/EntityLineage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/EntityLineage.component.tsx index 0b6ebf5fb6a..ddb541b0410 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/EntityLineage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/EntityLineage.component.tsx @@ -118,7 +118,7 @@ import Loader from '../../Loader/Loader'; import { useTourProvider } from '../../TourProvider/TourProvider'; import EdgeInfoDrawer from '../EntityInfoDrawer/EdgeInfoDrawer.component'; import EntityInfoDrawer from '../EntityInfoDrawer/EntityInfoDrawer.component'; -import AddPipeLineModal from './AddPipeLineModal'; +import AddPipeLineModal from './AppPipelineModel/AddPipeLineModal'; import CustomControlsComponent from './CustomControls.component'; import './entity-lineage.style.less'; import { @@ -398,6 +398,13 @@ const EntityLineageComponent: FunctionComponent = ({ } }; + const handleModalCancel = () => { + setSelectedEdgeId(undefined); + setShowAddEdgeModal(false); + setSelectedEdge({} as SelectedEdge); + setEdgeOptions([]); + }; + /** * * @param data selected edge @@ -440,6 +447,7 @@ const EntityLineageComponent: FunctionComponent = ({ resetSelectedData(); setConfirmDelete(false); + handleModalCancel(); } }; @@ -999,18 +1007,6 @@ const EntityLineageComponent: FunctionComponent = ({ setSelectedEdgeId(value); }; - const handleModalCancel = () => { - setSelectedEdgeId(undefined); - setShowAddEdgeModal(false); - setSelectedEdge({} as SelectedEdge); - setEdgeOptions([]); - }; - - const onEdgeSelectionClear = () => { - setSelectedEdgeId(undefined); - setEdgeSearchValue(''); - }; - const handleModalSave = () => { if (selectedEdge.data && updatedLineageData) { setStatus('waiting'); @@ -1031,7 +1027,8 @@ const EntityLineageComponent: FunctionComponent = ({ selectedEdgeValue, selectedEdgeId, selectedEdge.data, - (edgeDetails?.type as EntityType) ?? EntityType.PIPELINE + (edgeDetails?.type as EntityType) ?? EntityType.PIPELINE, + edgeDetails ); addLineageHandler(newEdge) @@ -1417,14 +1414,29 @@ const EntityLineageComponent: FunctionComponent = ({ SearchIndex.PIPELINE, SearchIndex.STORED_PROCEDURE, ]); - setEdgeOptions( - data.data.hits.hits.map((hit) => - getEntityReferenceFromEntity( - hit._source, - hit._source.entityType as EntityType - ) + + const selectedPipeline = selectedEdge.data?.pipeline; + + const edgeOptions = data.data.hits.hits.map((hit) => + getEntityReferenceFromEntity( + hit._source, + hit._source.entityType as EntityType ) ); + + const optionContainItem = edgeOptions.find( + (item) => item.id === selectedEdgeId + ); + + setEdgeOptions([ + ...(selectedPipeline && + isEmpty(optionContainItem) && + isEmpty(edgeSearchValue) && + selectedPipeline.id === selectedEdgeId + ? [selectedPipeline] + : []), + ...edgeOptions, + ]); } catch (error) { showErrorToast( error as AxiosError, @@ -1630,10 +1642,10 @@ const EntityLineageComponent: FunctionComponent = ({ }, [selectedEdge, confirmDelete]); useEffect(() => { - if (edgeSearchValue) { + if (showAddEdgeModal) { getSearchResults(edgeSearchValue); } - }, [edgeSearchValue]); + }, [edgeSearchValue, showAddEdgeModal]); useEffect(() => { edgesRef.current = edges; @@ -1775,7 +1787,6 @@ const EntityLineageComponent: FunctionComponent = ({ edgeSearchValue={edgeSearchValue} selectedEdgeId={selectedEdgeId} showAddEdgeModal={showAddEdgeModal} - onClear={onEdgeSelectionClear} onModalCancel={handleModalCancel} onRemoveEdgeClick={handleRemoveEdgeClick} onSave={handleModalSave} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.tsx index f95eb52defc..c2921d35e22 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Tag/TagsContainerV2/TagsContainerV2.tsx @@ -410,10 +410,12 @@ const TagsContainerV2 = ({ {header} {tagBody} - - {showBottomEditButton && !showInlineEditButton && editTagButton} - {children} - + {(children || showBottomEditButton) && ( + + {showBottomEditButton && !showInlineEditButton && editTagButton} + {children} + + )} ); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/EntityLineageUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/EntityLineageUtils.tsx index 37b1a861570..64e7480b45a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/EntityLineageUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/EntityLineageUtils.tsx @@ -824,7 +824,8 @@ export const getNewLineageConnectionDetails = ( selectedEdgeValue: EntityLineageEdge | undefined, selectedPipelineId: string | undefined, customEdgeData: CustomEdgeData, - type: EntityType + type: EntityType, + edgeDetails?: EntityReference ) => { const { source, sourceType, target, targetType } = customEdgeData; const updatedLineageDetails: LineageDetails = { @@ -836,6 +837,7 @@ export const getNewLineageConnectionDetails = ( : { id: selectedPipelineId, type, + fullyQualifiedName: edgeDetails?.fullyQualifiedName ?? '', }, };