diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx index cd94e9c904b..4242efa9903 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx @@ -261,7 +261,9 @@ const DashboardDetails = ({ : dashboardDetails.tags; const updatedDashboardDetails = { ...dashboardDetails, - owner: newOwner ? newOwner : dashboardDetails.owner, + owner: newOwner + ? { ...dashboardDetails.owner, ...newOwner } + : dashboardDetails.owner, tags: tierTag, }; @@ -678,7 +680,7 @@ const DashboardDetails = ({ = ({ = ({ currentTier = '', - currentUser = '', + currentUser, hideTier = false, hideOwner = false, onSave, @@ -67,10 +67,6 @@ const ManageTab: FunctionComponent = ({ const [owner, setOwner] = useState(currentUser); const [isLoadingTierData, setIsLoadingTierData] = useState(false); - const getOwnerById = (): string => { - return listOwners.find((item) => item.value === owner)?.name || ''; - }; - const setInitialOwnerLoadingState = () => { setStatusOwner('initial'); }; @@ -79,24 +75,20 @@ const ManageTab: FunctionComponent = ({ setStatusTier('initial'); }; - const prepareOwner = (updatedOwner: string) => { - return updatedOwner !== currentUser - ? { - id: updatedOwner, - type: listOwners.find((item) => item.value === updatedOwner)?.type as - | 'user' - | 'team', - } - : undefined; + const prepareOwner = (updatedOwner?: EntityReference) => { + return !isEqual(updatedOwner, currentUser) ? updatedOwner : undefined; }; const prepareTier = (updatedTier: string) => { return updatedTier !== currentTier ? updatedTier : undefined; }; - const handleOwnerSave = (updatedOwner: string, updatedTier: string) => { + const handleOwnerSave = ( + updatedOwner: EntityReference, + updatedTier: string + ) => { setStatusOwner('waiting'); - const newOwner: TableDetail['owner'] = prepareOwner(updatedOwner); + const newOwner = prepareOwner(updatedOwner); if (hideTier) { if (newOwner || !isUndefined(teamJoinable)) { onSave?.(newOwner, '', Boolean(teamJoinable)).catch(() => { @@ -115,7 +107,7 @@ const ManageTab: FunctionComponent = ({ const handleTierSave = (updatedTier: string) => { setStatusTier('waiting'); - const newOwner: TableDetail['owner'] = prepareOwner(currentUser); + const newOwner = prepareOwner(currentUser); if (hideTier) { if (newOwner || !isUndefined(teamJoinable)) { onSave?.(newOwner, '', Boolean(teamJoinable)).catch(() => { @@ -139,8 +131,9 @@ const ManageTab: FunctionComponent = ({ if (value) { const newOwner = listOwners.find((item) => item.value === value); if (newOwner) { - setOwner(newOwner.value); - handleOwnerSave(newOwner.value, activeTier); + const { value: id, type } = newOwner; + setOwner({ id, type }); + handleOwnerSave({ id, type }, activeTier); } } setListVisible(false); @@ -223,7 +216,6 @@ const ManageTab: FunctionComponent = ({ ); }; - const ownerName = getOwnerById(); const getTierData = () => { setIsLoadingTierData(true); getCategory('Tier') @@ -322,8 +314,8 @@ const ManageTab: FunctionComponent = ({ isJoinableActionAllowed={isJoinableActionAllowed()} listOwners={listOwners} listVisible={listVisible} - owner={owner} - ownerName={ownerName} + owner={owner || ({} as EntityReference)} + ownerName={currentUser?.displayName || currentUser?.name || ''} statusOwner={statusOwner} teamJoinable={teamJoinable} /> diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ManageTab/ManageTab.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/ManageTab/ManageTab.interface.ts index 75b93c029fa..4b4342582d5 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ManageTab/ManageTab.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/ManageTab/ManageTab.interface.ts @@ -12,18 +12,19 @@ */ import { TableDetail } from 'Models'; +import { EntityReference } from '../../generated/type/entityReference'; export interface ManageProps { currentTier?: string; - currentUser?: string; + currentUser?: EntityReference; manageSectionType?: string; hideTier?: boolean; hideOwner?: boolean; isJoinable?: boolean; allowSoftDelete?: boolean; onSave?: ( - owner: TableDetail['owner'], - tier: TableDetail['tier'], + owner?: EntityReference, + tier?: TableDetail['tier'], isJoinable?: boolean ) => Promise; handleIsJoinable?: (bool: boolean) => void; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx index d0a65dcf47c..95f1bdd4265 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/PipelineDetails/PipelineDetails.component.tsx @@ -270,7 +270,9 @@ const PipelineDetails = ({ : pipelineDetails.tags; const updatedPipelineDetails = { ...pipelineDetails, - owner: newOwner ? newOwner : pipelineDetails.owner, + owner: newOwner + ? { ...pipelineDetails.owner, ...newOwner } + : pipelineDetails.owner, tags: tierTag, }; @@ -596,7 +598,7 @@ const PipelineDetails = ({ { + const handleManageSave = (owner?: EntityReference) => { if (currentTeam) { const updatedData: Team = { ...currentTeam, - owner: owner, + owner: !isUndefined(owner) ? owner : currentTeam.owner, }; return updateTeamHandler(updatedData); @@ -626,7 +627,7 @@ const TeamDetails = ({ hideTier afterDeleteAction={afterDeleteAction} allowTeamOwner={false} - currentUser={currentTeam.owner?.id} + currentUser={currentTeam.owner} entityId={currentTeam.id} entityName={currentTeam.displayName || currentTeam.name} entityType="team" diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx index 13ea415ae80..428887587f0 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TopicDetails/TopicDetails.component.tsx @@ -465,7 +465,7 @@ const TopicDetails: React.FC = ({ )} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/dropdown/DropDownList.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/dropdown/DropDownList.test.tsx index a8be751e0c4..583993cad17 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/dropdown/DropDownList.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/dropdown/DropDownList.test.tsx @@ -15,6 +15,7 @@ import { fireEvent, getAllByTestId, getByTestId, + queryByTestId, render, } from '@testing-library/react'; import React from 'react'; @@ -82,4 +83,51 @@ describe('Test DropDownList Component', () => { expect(MockOnSelect).toBeCalledTimes(1); }); + + it('On search, show no result placeholder', () => { + const { container } = render( + + ); + const searchbar = getByTestId(container, 'searchInputText'); + + fireEvent.change(searchbar, { + target: { + value: 'test X', + }, + }); + + const noMatchElement = getByTestId(container, 'empty-list'); + + expect(noMatchElement).toBeInTheDocument(); + }); + + it('On search, do not show dropdown if no result matched', () => { + const { container } = render( + + ); + const searchbar = getByTestId(container, 'searchInputText'); + + fireEvent.change(searchbar, { + target: { + value: 'test X', + }, + }); + + const dropdownElement = queryByTestId(container, 'dropdown-list'); + + expect(dropdownElement).not.toBeInTheDocument(); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/dropdown/DropDownList.tsx b/openmetadata-ui/src/main/resources/ui/src/components/dropdown/DropDownList.tsx index 2155791a122..a714fc04c0b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/dropdown/DropDownList.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/dropdown/DropDownList.tsx @@ -27,6 +27,7 @@ const DropDownList: FunctionComponent = ({ horzPosRight, searchString = '', showSearchBar = false, + showEmptyList = false, value, onSelect, groupType = 'label', @@ -62,6 +63,18 @@ const DropDownList: FunctionComponent = ({ setSearchText(text || ''); }; + const getEmptyTextElement = (): JSX.Element => { + return ( +
+

+ {searchText ? 'No match found' : 'No data available'} +

+
+ ); + }; + const getSearchedListByGroup = ( groupName?: string ): Array => { @@ -95,6 +108,77 @@ const DropDownList: FunctionComponent = ({ ); }; + const getListElements = (): JSX.Element => { + const results = getSearchedListByGroup(); + + if (!results.length && showEmptyList && !listGroups.length) { + return getEmptyTextElement(); + } + + return ( + <> + {results.map((item: DropDownListItem, index: number) => + getDropDownElement(item, index) + )} + + ); + }; + + const getListElementsByLabels = (groupName: string) => { + const results = getSearchedListByGroup(groupName); + const groupLabel = ( + +
+ {groupName}{' '} +
+
+ ); + + if (!results.length && showEmptyList) { + return ( + <> + {groupLabel} + {getEmptyTextElement()} + + ); + } + + return ( + <> + {results.length > 0 && groupLabel} + {results.map((item: DropDownListItem, index: number) => + getDropDownElement(item, index) + )} + + ); + }; + + const getListElementsByTab = (groupTab: string) => { + const results = getSearchedListByGroup(groupTab); + + if (!results.length && showEmptyList) { + return getEmptyTextElement(); + } + + return ( + <> + {results.map((item: DropDownListItem, index: number) => + getDropDownElement(item, index) + )} + + ); + }; + + const getListElementsByGroup = () => { + if (groupType === 'label') { + return listGroups.map((grp, index) => { + return
{getListElementsByLabels(grp)}
; + }); + } else { + return getListElementsByTab(listGroups[activeTab - 1]); + } + }; + useEffect(() => { setSearchText(searchString); }, [searchString]); @@ -138,7 +222,7 @@ const DropDownList: FunctionComponent = ({ return ( <> - {searchedList.length > 0 && ( + {(searchedList.length > 0 || showEmptyList) && ( <>