diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeader.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeader.test.tsx index 8cd5f17fac9f..55d73282b8d1 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeader.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeader.test.tsx @@ -11,130 +11,108 @@ * limitations under the License. */ -import { - findByTestId, - findByText, - queryByTestId, - render, -} from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; import { Thread, ThreadType } from '../../../../generated/entity/feed/thread'; import FeedCardHeader from './FeedCardHeader'; -const FQN = 'service.database.schema.table'; -const type = 'table'; -const expectedDisplayName = 'database.schema.table'; +const mockProps1 = { + createdBy: 'username', + entityFQN: 'service.database.schema.table', + entityField: 'entityField', + entityType: 'table', + isEntityFeed: true, + timeStamp: 1647322547179, + feedType: ThreadType.Conversation, + task: {} as Thread, +}; + +const mockProps2 = { + ...mockProps1, + isEntityFeed: false, +}; -jest.mock('../../../../rest/userAPI', () => ({ - getUserByName: jest.fn().mockReturnValue({}), +jest.mock('../../../../constants/constants', () => ({ + getUserPath: jest.fn().mockReturnValue('user-profile-path'), })); -jest.mock('../../../../utils/CommonUtils', () => ({ - getPartialNameFromFQN: jest.fn().mockReturnValue('feedcard'), - getNonDeletedTeams: jest.fn().mockReturnValue([]), - getEntityName: jest.fn().mockReturnValue('entityname'), - getPartialNameFromTableFQN: jest.fn().mockImplementation(() => { - return expectedDisplayName; - }), - getEntityDetailLink: jest.fn().mockImplementation(() => expectedDisplayName), +jest.mock('../../../../hooks/user-profile/useUserProfile', () => ({ + useUserProfile: jest.fn().mockReturnValue([]), })); -jest.mock('../../../../utils/TableUtils', () => ({ - getTierTags: jest.fn(), - getTagsWithoutTier: jest.fn(), +jest.mock('../../../../utils/date-time/DateTimeUtils', () => ({ + formatDateTime: jest.fn().mockImplementation((date) => date), + getRelativeTime: jest.fn().mockImplementation((date) => date), })); -jest.mock('../../../common/ProfilePicture/ProfilePicture', () => { - return jest.fn().mockReturnValue(

ProfilePicture

); -}); +jest.mock('../../../../utils/EntityUtils', () => ({ + getEntityName: jest.fn().mockReturnValue('username'), +})); -const mockFeedHeaderProps = { - createdBy: 'xyz', - entityFQN: 'x.y.v.z', - entityField: 'z', - entityType: 'y', - isEntityFeed: true, - timeStamp: 1647322547179, - feedType: ThreadType.Conversation, - task: {} as Thread, -}; +jest.mock('../../../../utils/FeedUtils', () => ({ + entityDisplayName: jest.fn().mockReturnValue('database.schema.table'), + getEntityFieldDisplay: jest + .fn() + .mockImplementation((entityField) => entityField), + prepareFeedLink: jest.fn().mockReturnValue('entity-link'), +})); + +jest.mock('../../../../utils/TasksUtils', () => ({ + getTaskDetailPath: jest.fn().mockReturnValue('task detail path'), +})); + +jest.mock('../../../common/PopOverCard/EntityPopOverCard', () => + jest.fn().mockImplementation(({ children }) => ( + <> + EntityPopOverCard +
{children}
+ + )) +); + +jest.mock('../../../common/PopOverCard/UserPopOverCard', () => + jest.fn().mockImplementation(({ children }) => ( + <> + UserPopOverCard +
{children}
+ + )) +); describe('Test FeedHeader Component', () => { - it('Checks if the FeedHeader component has isEntityFeed as true', async () => { - const { container } = render(, { + it('should contain all necessary elements, when isEntityFeed true', () => { + render(, { wrapper: MemoryRouter, }); - const createdBy = await findByText(container, /xyz/i); - - const headerElement = await findByTestId(container, 'headerText'); - const entityFieldElement = await findByTestId( - container, - 'headerText-entityField' - ); - const entityTypeElement = queryByTestId(container, 'entityType'); - const entityLinkElement = queryByTestId(container, 'entitylink'); - const timeStampElement = await findByTestId(container, 'timestamp'); - - expect(createdBy).toBeInTheDocument(); - - expect(headerElement).toBeInTheDocument(); - expect(entityFieldElement).toBeInTheDocument(); - expect(entityTypeElement).not.toBeInTheDocument(); - expect(entityLinkElement).not.toBeInTheDocument(); - expect(timeStampElement).toBeInTheDocument(); - expect(timeStampElement).toHaveTextContent('1 year ago'); - }); - it('Checks if the FeedHeader component has isEntityFeed as false', async () => { - const { container } = render( - , - { - wrapper: MemoryRouter, - } - ); - const createdBy = await findByText(container, /xyz/i); - - const headerElement = await findByTestId(container, 'headerText'); - const entityFieldElement = queryByTestId( - container, - 'headerText-entityField' - ); - const entityTypeElement = await findByTestId(container, 'entityType'); - const entityLinkElement = await findByTestId(container, 'entitylink'); - const timeStampElement = await findByTestId(container, 'timestamp'); - - expect(createdBy).toBeInTheDocument(); - - expect(headerElement).toBeInTheDocument(); - expect(entityFieldElement).not.toBeInTheDocument(); - expect(entityTypeElement).toBeInTheDocument(); - expect(entityLinkElement).toBeInTheDocument(); - expect(timeStampElement).toBeInTheDocument(); - expect(timeStampElement).toHaveTextContent('1 year ago'); + expect(screen.getByText('UserPopOverCard')).toBeInTheDocument(); + expect(screen.getByText('username')).toBeInTheDocument(); + + expect(screen.getByTestId('headerText-entityField')).toBeInTheDocument(); + + expect(screen.getByTestId('timestamp')).toBeInTheDocument(); + + expect(screen.queryByTestId('table')).not.toBeInTheDocument(); + expect(screen.queryByTestId('entitylink')).not.toBeInTheDocument(); }); - it('Should show link text as `database.schema.table` if entity type is table', async () => { - const { container } = render( - , - { - wrapper: MemoryRouter, - } - ); + it('should contain all necessary elements, when isEntityFeed false', () => { + render(, { + wrapper: MemoryRouter, + }); - const entityTypeElement = await findByTestId(container, 'entityType'); - const entityLinkElement = await findByTestId(container, 'entitylink'); + expect(screen.getByText('UserPopOverCard')).toBeInTheDocument(); + expect(screen.getByText('username')).toBeInTheDocument(); - expect(entityTypeElement).toBeInTheDocument(); - expect(entityLinkElement).toBeInTheDocument(); + expect(screen.getByText('table')).toBeInTheDocument(); + expect(screen.getByText('database.schema.table')).toBeInTheDocument(); + expect(screen.getByTestId('entitylink')).toBeInTheDocument(); - expect(entityTypeElement).toHaveTextContent(type); + expect(screen.getByTestId('timestamp')).toBeInTheDocument(); - expect(entityLinkElement).toHaveTextContent(expectedDisplayName); + expect( + screen.queryByTestId('headerText-entityField') + ).not.toBeInTheDocument(); }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeader.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeader.tsx index 91e86bc9f303..b744129fa9ea 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeader.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeader.tsx @@ -17,11 +17,14 @@ import { isUndefined } from 'lodash'; import React, { FC } from 'react'; import { useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; +import { getUserPath } from '../../../../constants/constants'; import { ThreadType } from '../../../../generated/entity/feed/thread'; +import { useUserProfile } from '../../../../hooks/user-profile/useUserProfile'; import { formatDateTime, getRelativeTime, } from '../../../../utils/date-time/DateTimeUtils'; +import { getEntityName } from '../../../../utils/EntityUtils'; import { entityDisplayName, getEntityFieldDisplay, @@ -31,6 +34,7 @@ import { getTaskDetailPath } from '../../../../utils/TasksUtils'; import EntityPopOverCard from '../../../common/PopOverCard/EntityPopOverCard'; import UserPopOverCard from '../../../common/PopOverCard/UserPopOverCard'; import { FeedHeaderProp } from '../ActivityFeedCard.interface'; +import './feed-card-header-v1.style.less'; const FeedCardHeader: FC = ({ className, @@ -43,6 +47,11 @@ const FeedCardHeader: FC = ({ feedType, task, }) => { + const [, , user] = useUserProfile({ + permission: true, + name: createdBy ?? '', + }); + const { t } = useTranslation(); const { task: taskDetails } = task; @@ -119,8 +128,12 @@ const FeedCardHeader: FC = ({ ); return ( -
- {createdBy} +
+ + + {getEntityName(user)} + + {feedType === ThreadType.Conversation && getFeedLinkElement} {feedType === ThreadType.Task && getTaskLinkElement} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeaderV1.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeaderV1.tsx index 63e0959bbeb7..b9c4be99c01a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeaderV1.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/FeedCardHeaderV1.tsx @@ -17,10 +17,13 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; import EntityPopOverCard from '../../../../components/common/PopOverCard/EntityPopOverCard'; +import { getUserPath } from '../../../../constants/constants'; +import { useUserProfile } from '../../../../hooks/user-profile/useUserProfile'; import { formatDateTime, getRelativeTime, } from '../../../../utils/date-time/DateTimeUtils'; +import { getEntityName } from '../../../../utils/EntityUtils'; import { entityDisplayName, getEntityField, @@ -49,6 +52,11 @@ const FeedCardHeaderV1 = ({ className = '', isEntityFeed = false, }: FeedCardHeaderV1Props) => { + const [, , user] = useUserProfile({ + permission: true, + name: createdBy ?? '', + }); + const { t } = useTranslation(); const entityType = getEntityType(entityLink) ?? ''; @@ -59,7 +67,7 @@ const FeedCardHeaderV1 = ({ const getFeedLinkElement = entityCheck && ( - {t('label.posted-on-lowercase')} + {t('label.posted-on-lowercase')} {isEntityFeed ? ( {getEntityFieldDisplay(entityField)} @@ -96,20 +104,25 @@ const FeedCardHeaderV1 = ({ return (
- - {getFeedLinkElement} + - {timeStamp && ( - - - {getRelativeTime(timeStamp)} - - - )} +

+ + + {getEntityName(user)} + + + + {getFeedLinkElement} + + {timeStamp && ( + + + {getRelativeTime(timeStamp)} + + + )} +

); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/feed-card-header-v1.style.less b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/feed-card-header-v1.style.less index ffbc504f575e..c53978993c6c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/feed-card-header-v1.style.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCard/FeedCardHeader/feed-card-header-v1.style.less @@ -15,7 +15,7 @@ .feed-header { display: flex; - align-items: center; + align-items: flex-start; .thread-author { font-weight: 600; @@ -31,9 +31,6 @@ } .feed-header-content { line-height: 20px; - display: inline-flex; - align-items: center; - flex-wrap: wrap; } } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/MyData/RightSidebar/announcements-widget.less b/openmetadata-ui/src/main/resources/ui/src/components/MyData/RightSidebar/announcements-widget.less index 31b8a11529ce..805869056fa0 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/MyData/RightSidebar/announcements-widget.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/MyData/RightSidebar/announcements-widget.less @@ -20,8 +20,5 @@ overflow-y: scroll; overflow-x: hidden; max-height: 90%; - .feed-card-body { - padding: 0; - } } }