mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-02 19:48:17 +00:00
Fixes 23223: Mentions from incidents/entities not showing in Notifications (#23874)
* Fix: Notifications not showing the mentions from incident/entity * Fix: Fixed the unit test * Playwright: Added test for verifing incident manager mention notification * Fix: Addressed PR comments * Fix: fixed code smells * Playwright: Fixed the playwright tests --------- Co-authored-by: Ashish Gupta <ashish@getcollate.io>
This commit is contained in:
parent
73eca212ce
commit
c0df88f02f
@ -536,8 +536,7 @@ test.describe('Mention notifications in Notification Box', () => {
|
||||
const mentionsFeedResponse = adminPage.waitForResponse(
|
||||
(response) =>
|
||||
response.url().includes('/api/v1/feed') &&
|
||||
response.url().includes('filterType=MENTIONS') &&
|
||||
response.url().includes('type=Conversation')
|
||||
response.url().includes('filterType=MENTIONS')
|
||||
);
|
||||
|
||||
await mentionsTab.click();
|
||||
|
||||
@ -17,6 +17,7 @@ import { SidebarItem } from '../../constant/sidebar';
|
||||
import { EntityTypeEndpoint } from '../../support/entity/Entity.interface';
|
||||
import { TableClass } from '../../support/entity/TableClass';
|
||||
import { UserClass } from '../../support/user/UserClass';
|
||||
import { addMentionCommentInFeed } from '../../utils/activityFeed';
|
||||
import { performAdminLogin } from '../../utils/admin';
|
||||
import { resetTokenFromBotPage } from '../../utils/bot';
|
||||
import {
|
||||
@ -25,7 +26,7 @@ import {
|
||||
getApiContext,
|
||||
redirectToHomePage,
|
||||
} from '../../utils/common';
|
||||
import { addOwner } from '../../utils/entity';
|
||||
import { addOwner, waitForAllLoadersToDisappear } from '../../utils/entity';
|
||||
import {
|
||||
acknowledgeTask,
|
||||
assignIncident,
|
||||
@ -208,6 +209,27 @@ test.describe('Incident Manager', PLAYWRIGHT_INGESTION_TAG_OBJ, () => {
|
||||
await updateAssignee;
|
||||
});
|
||||
|
||||
await test.step(
|
||||
'Verify that notifications correctly display mentions for the incident manager',
|
||||
async () => {
|
||||
const testcaseName = await page
|
||||
.getByTestId('entity-header-name')
|
||||
.innerText();
|
||||
await addMentionCommentInFeed(page, 'admin', true);
|
||||
|
||||
await adminPage.waitForLoadState('networkidle');
|
||||
await waitForAllLoadersToDisappear(adminPage);
|
||||
await adminPage.getByRole('button', { name: 'Notifications' }).click();
|
||||
await adminPage.getByText('Mentions').click();
|
||||
await adminPage.waitForLoadState('networkidle');
|
||||
await waitForAllLoadersToDisappear(adminPage);
|
||||
|
||||
await expect(adminPage.getByLabel('Mentions')).toContainText(
|
||||
`mentioned you on the testCase ${testcaseName}`
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
await test.step(
|
||||
"Re-assign incident from test case page's header",
|
||||
async () => {
|
||||
|
||||
@ -128,14 +128,6 @@ export const addMentionCommentInFeed = async (
|
||||
|
||||
await page.waitForSelector('[data-testid="loader"]', { state: 'detached' });
|
||||
|
||||
const firstMessage = getNthFeedMessage(page, 0);
|
||||
|
||||
await expect(firstMessage).toBeVisible();
|
||||
|
||||
await firstMessage.locator('[data-testid="reply-count"]').click();
|
||||
await page.waitForSelector('.ant-drawer-content', {
|
||||
state: 'visible',
|
||||
});
|
||||
await page.getByTestId('comments-input-field').click();
|
||||
|
||||
const userSuggestionsResponse = page.waitForResponse(
|
||||
|
||||
@ -103,7 +103,7 @@ export const addOwner = async ({
|
||||
await page.getByTestId(initiatorId).click();
|
||||
if (type === 'Users') {
|
||||
const userListResponse = page.waitForResponse(
|
||||
'/api/v1/search/query?q=&index=user_search_index&*'
|
||||
'/api/v1/search/query?q=*&index=user_search_index&*'
|
||||
);
|
||||
await page.getByRole('tab', { name: type }).click();
|
||||
await userListResponse;
|
||||
|
||||
@ -52,11 +52,7 @@ import { useTourProvider } from '../../context/TourProvider/TourProvider';
|
||||
import { useWebSocketConnector } from '../../context/WebSocketProvider/WebSocketProvider';
|
||||
import { EntityTabs, EntityType } from '../../enums/entity.enum';
|
||||
import { EntityReference } from '../../generated/entity/type';
|
||||
import {
|
||||
BackgroundJob,
|
||||
EnumCleanupArgs,
|
||||
JobType,
|
||||
} from '../../generated/jobs/backgroundJob';
|
||||
import { BackgroundJob, JobType } from '../../generated/jobs/backgroundJob';
|
||||
import { useCurrentUserPreferences } from '../../hooks/currentUserStore/useCurrentUserStore';
|
||||
import { useApplicationStore } from '../../hooks/useApplicationStore';
|
||||
import useCustomLocation from '../../hooks/useCustomLocation/useCustomLocation';
|
||||
@ -248,7 +244,7 @@ const NavBar = () => {
|
||||
const { jobArgs, status, jobType } = backgroundJobData;
|
||||
|
||||
if (jobType === JobType.CustomPropertyEnumCleanup) {
|
||||
const enumCleanupArgs = jobArgs as EnumCleanupArgs;
|
||||
const enumCleanupArgs = jobArgs;
|
||||
if (!enumCleanupArgs.entityType) {
|
||||
showErrorToast(
|
||||
{
|
||||
@ -280,11 +276,11 @@ const NavBar = () => {
|
||||
icon: Logo,
|
||||
});
|
||||
notification.onclick = () => {
|
||||
const isChrome = window.navigator.userAgent.indexOf('Chrome');
|
||||
const isChrome = globalThis.navigator.userAgent.indexOf('Chrome');
|
||||
// Applying logic to open a new window onclick of browser notification from chrome
|
||||
// As it does not open the concerned tab by default.
|
||||
if (isChrome > -1) {
|
||||
window.open(path);
|
||||
globalThis.open(path);
|
||||
} else {
|
||||
navigate(path);
|
||||
}
|
||||
@ -317,7 +313,7 @@ const NavBar = () => {
|
||||
const now = Date.now();
|
||||
|
||||
if (lastFetchTime) {
|
||||
const timeSinceLastFetch = now - parseInt(lastFetchTime);
|
||||
const timeSinceLastFetch = now - Number.parseInt(lastFetchTime);
|
||||
if (timeSinceLastFetch < ONE_HOUR_MS) {
|
||||
// Less than 1 hour since last fetch, skip API call
|
||||
return;
|
||||
@ -532,6 +528,7 @@ const NavBar = () => {
|
||||
className="cursor-pointer"
|
||||
dropdownRender={() => (
|
||||
<NotificationBox
|
||||
activeTab={activeTab}
|
||||
hasMentionNotification={hasMentionNotification}
|
||||
hasTaskNotification={hasTaskNotification}
|
||||
onMarkMentionsNotificationRead={
|
||||
|
||||
@ -38,6 +38,7 @@ import { getFilters, tabsInfo } from './NotificationBox.utils';
|
||||
import NotificationFeedCard from './NotificationFeedCard.component';
|
||||
|
||||
const NotificationBox = ({
|
||||
activeTab,
|
||||
hasMentionNotification,
|
||||
hasTaskNotification,
|
||||
onMarkTaskNotificationRead,
|
||||
@ -71,9 +72,10 @@ const NotificationBox = ({
|
||||
// For mention notifications, get the actual user who made the mention from posts
|
||||
let actualUser = mainFeed.from;
|
||||
let actualTimestamp = mainFeed.postTs;
|
||||
let feedType = feed.type || ThreadType.Conversation;
|
||||
|
||||
if (
|
||||
feed.type === ThreadType.Conversation &&
|
||||
activeTab === ThreadType.Conversation &&
|
||||
feed.posts &&
|
||||
feed.posts.length > 0
|
||||
) {
|
||||
@ -85,9 +87,10 @@ const NotificationBox = ({
|
||||
)
|
||||
.sort((a, b) => (b.postTs ?? 0) - (a.postTs ?? 0))[0];
|
||||
|
||||
if (mentionPost && mentionPost.postTs !== undefined) {
|
||||
if (mentionPost?.postTs !== undefined) {
|
||||
actualUser = mentionPost.from;
|
||||
actualTimestamp = mentionPost.postTs;
|
||||
feedType = ThreadType.Conversation;
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +99,7 @@ const NotificationBox = ({
|
||||
createdBy={actualUser}
|
||||
entityFQN={entityFQN as string}
|
||||
entityType={entityType as string}
|
||||
feedType={feed.type || ThreadType.Conversation}
|
||||
feedType={feedType}
|
||||
key={`${actualUser} ${mainFeed.id}`}
|
||||
task={feed}
|
||||
timestamp={actualTimestamp}
|
||||
@ -106,8 +109,8 @@ const NotificationBox = ({
|
||||
}, [notifications]);
|
||||
|
||||
const getNotificationData = (
|
||||
threadType: ThreadType,
|
||||
feedFilter: FeedFilter
|
||||
feedFilter: FeedFilter,
|
||||
threadType?: ThreadType
|
||||
) => {
|
||||
setIsLoading(true);
|
||||
getFeedsWithFilter(currentUser?.id, feedFilter, undefined, threadType)
|
||||
@ -132,7 +135,7 @@ const NotificationBox = ({
|
||||
onTabChange(key);
|
||||
const { threadType, feedFilter } = getFilters(key as ThreadType);
|
||||
|
||||
getNotificationData(threadType, feedFilter);
|
||||
getNotificationData(feedFilter, threadType);
|
||||
|
||||
setViewAllPath(
|
||||
getUserPath(
|
||||
@ -156,7 +159,7 @@ const NotificationBox = ({
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
getNotificationData(ThreadType.Task, FeedFilter.ASSIGNED_TO);
|
||||
getNotificationData(FeedFilter.ASSIGNED_TO, ThreadType.Task);
|
||||
}, []);
|
||||
|
||||
const getTabTitle = (name: string, key: string) => {
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
export interface NotificationBoxProp {
|
||||
activeTab: string;
|
||||
hasMentionNotification: boolean;
|
||||
hasTaskNotification: boolean;
|
||||
onMarkMentionsNotificationRead: () => void;
|
||||
|
||||
@ -61,6 +61,7 @@ const mockShowErrorToast = jest.fn();
|
||||
const mockOnMarkTaskNotificationRead = jest.fn();
|
||||
|
||||
const mockProps = {
|
||||
activeTab: ThreadType.Task,
|
||||
hasMentionNotification: true,
|
||||
hasTaskNotification: true,
|
||||
onMarkMentionsNotificationRead: jest.fn(),
|
||||
|
||||
@ -47,7 +47,7 @@ export const tabsInfo = [
|
||||
];
|
||||
|
||||
export const getFilters = (activeTab: ThreadType) => ({
|
||||
threadType: activeTab,
|
||||
threadType: activeTab === ThreadType.Task ? activeTab : undefined,
|
||||
feedFilter:
|
||||
activeTab === ThreadType.Task
|
||||
? FeedFilter.ASSIGNED_TO
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user