From 7495a9b27df25b251345e61409db6310505b130d Mon Sep 17 00:00:00 2001 From: Maksym Mykhailenko Date: Sat, 6 Jan 2018 19:07:44 +0800 Subject: [PATCH 1/2] Issue #1554 - User in notifications are listed with @handle instead of their name --- config/constants/dev.js | 4 +- .../notifications/constants/notifications.js | 290 ++++++++++++------ .../notifications/helpers/notifications.js | 13 +- 3 files changed, 211 insertions(+), 96 deletions(-) diff --git a/config/constants/dev.js b/config/constants/dev.js index c73d681ac..365c98db7 100644 --- a/config/constants/dev.js +++ b/config/constants/dev.js @@ -12,7 +12,7 @@ module.exports = { AUTH0_CLIENT_ID : process.env.AUTH0_CLIENT_ID_DEV, domain : 'topcoder-dev.com', DOMAIN : 'topcoder-dev.com', - CONNECT_MESSAGE_API_URL: process.env.CONNECT_MESSAGE_API_URL, + CONNECT_MESSAGE_API_URL: process.env.CONNECT_MESSAGE_API_URL, ENV : 'DEV', PROJECTS_API_URL : 'https://api.topcoder-dev.com', @@ -44,5 +44,5 @@ module.exports = { IBM_COGNITIVE_PROGRAM_ID : 3449, HEAP_ANALYTICS_APP_ID : '4153837120', - TC_NOTIFICATION_URL: 'https://api.topcoder-dev.com' + TC_NOTIFICATION_URL: 'http://localhost:4000' } diff --git a/src/routes/notifications/constants/notifications.js b/src/routes/notifications/constants/notifications.js index c6ca3094d..3817fd2d4 100644 --- a/src/routes/notifications/constants/notifications.js +++ b/src/routes/notifications/constants/notifications.js @@ -12,190 +12,300 @@ const GOTO = { FILE_LIST: '/projects/[projectId]/specification#appDefinition-files' } +// each notification can be displayed differently depend on WHO see them +// that's why each notification can have several rules to display which describe user roles +// NOTE for each version of notification have to repeat ALL rules, even if some rules are not changed export const NOTIFICATIONS = [ // Outside project { eventType: 'notifications.connect.project.created', type: NOTIFICATION_TYPE.NEW_PROJECT, - text: 'Your Project was created successfully', - projectRoles: [PROJECT_ROLE_OWNER], - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: 'Your Project was created successfully', + projectRoles: [PROJECT_ROLE_OWNER], + goTo: GOTO.PROJECT_DASHBOARD + }] }, { eventType: 'notifications.connect.project.submittedForReview', type: NOTIFICATION_TYPE.REVIEW_PENDING, - text: 'Your project is now in review', - projectRoles: [PROJECT_ROLE_OWNER] - }, - { - eventType: 'notifications.connect.project.submittedForReview', - type: NOTIFICATION_TYPE.REVIEW_PENDING, - text: 'Project is available for review', - topcoderRoles: [ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR], - goTo: GOTO.PROJECT_SPECIFICATION + rules: [{ + text: 'Your project is now in review', + projectRoles: [PROJECT_ROLE_OWNER] + }, { + text: 'Project is available for review', + topcoderRoles: [ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR], + goTo: GOTO.PROJECT_SPECIFICATION + }] }, { eventType: 'notifications.connect.project.approved', type: NOTIFICATION_TYPE.UPDATES, - text: 'Your project was approved, work would soon start', - projectRoles: [PROJECT_ROLE_OWNER] - }, - { - eventType: 'notifications.connect.project.approved', - type: NOTIFICATION_TYPE.UPDATES, - text: 'Project is available for pickup', - topcoderRoles: [ROLE_CONNECT_COPILOT, ROLE_ADMINISTRATOR], - goTo: GOTO.PROJECT_DASHBOARD - }, - { - eventType: 'notifications.connect.project.approved', - type: NOTIFICATION_TYPE.UPDATES, - text: 'Project was approved', - projectRoles: [PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: 'Your project was approved, work would soon start', + projectRoles: [PROJECT_ROLE_OWNER] + }, { + text: 'Project is available for pickup', + topcoderRoles: [ROLE_CONNECT_COPILOT, ROLE_ADMINISTRATOR], + goTo: GOTO.PROJECT_DASHBOARD + }, { + text: 'Project was approved', + projectRoles: [PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], + goTo: GOTO.PROJECT_DASHBOARD + }] }, { eventType: 'notifications.connect.project.paused', type: NOTIFICATION_TYPE.REVIEW_PENDING, - text: 'Your project was paused', - projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], - goTo: GOTO.PROJECT_DASHBOARD - }, - { - eventType: 'notifications.connect.project.paused', - type: NOTIFICATION_TYPE.REVIEW_PENDING, - text: 'A project was paused', - topcoderRoles: [ROLE_ADMINISTRATOR], - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: 'Your project was paused', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], + goTo: GOTO.PROJECT_DASHBOARD + }, { + text: 'A project was paused', + topcoderRoles: [ROLE_ADMINISTRATOR], + goTo: GOTO.PROJECT_DASHBOARD + }] }, { eventType: 'notifications.connect.project.completed', type: NOTIFICATION_TYPE.UPDATES, - text: 'Your project completed successfully!', - projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], - goTo: GOTO.PROJECT_DASHBOARD - }, - { - eventType: 'notifications.connect.project.completed', - type: NOTIFICATION_TYPE.UPDATES, - text: 'A project was completed', - topcoderRoles: [ROLE_ADMINISTRATOR], - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: 'Your project completed successfully!', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.PROJECT_DASHBOARD + }, { + text: 'A project was completed', + topcoderRoles: [ROLE_ADMINISTRATOR], + goTo: GOTO.PROJECT_DASHBOARD + }] }, { eventType: 'notifications.connect.project.canceled', type: NOTIFICATION_TYPE.WARNING, - text: 'Your project was canceled. If you think that was a mistake...', - projectRoles: [PROJECT_ROLE_OWNER], - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: 'Your project was canceled. If you think that was a mistake...', + projectRoles: [PROJECT_ROLE_OWNER], + goTo: GOTO.PROJECT_DASHBOARD + }] }, // User management { eventType: 'notifications.connect.project.member.joined', type: NOTIFICATION_TYPE.MEMBER_ADDED, - text: 'A new team member joined your project', - projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: 'A new team member joined your project', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], + goTo: GOTO.PROJECT_DASHBOARD + }] }, { eventType: 'notifications.connect.project.member.left', type: NOTIFICATION_TYPE.WARNING, - text: '[userHandle] left a project', - projectRoles: [PROJECT_ROLE_MANAGER] + rules: [{ + text: '[userHandle] left a project', + projectRoles: [PROJECT_ROLE_MANAGER] + }] + }, { + version: 2, + eventType: 'notifications.connect.project.member.left', + type: NOTIFICATION_TYPE.WARNING, + rules: [{ + text: '[userFullName] left a project', + projectRoles: [PROJECT_ROLE_MANAGER] + }] }, { eventType: 'notifications.connect.project.member.removed', type: NOTIFICATION_TYPE.WARNING, - text: '[userHandle] was removed from project', - projectRoles: [PROJECT_ROLE_MANAGER] + rules: [{ + text: '[userHandle] was removed from project', + projectRoles: [PROJECT_ROLE_MANAGER] + }, { + text: 'You were removed from a project', + toUserHandle: true + }] }, { + version: 2, eventType: 'notifications.connect.project.member.removed', type: NOTIFICATION_TYPE.WARNING, - text: 'You were removed from a project', - toUserHandle: true + rules: [{ + text: '[userFullName] was removed from project', + projectRoles: [PROJECT_ROLE_MANAGER] + }, { + text: 'You were removed from a project', + toUserHandle: true + }] }, { eventType: 'notifications.connect.project.member.assignedAsOwner', type: NOTIFICATION_TYPE.MEMBER_ADDED, - text: 'You are now the owner of project', - toUserHandle: true, - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: 'You are now the owner of project', + toUserHandle: true, + goTo: GOTO.PROJECT_DASHBOARD + }, { + text: 'Project owner was changed to [userHandle]', + projectRoles: [PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], + goTo: GOTO.PROJECT_DASHBOARD + }] }, { + version: 2, eventType: 'notifications.connect.project.member.assignedAsOwner', type: NOTIFICATION_TYPE.MEMBER_ADDED, - text: 'Project owner was changed to [userHandle]', - projectRoles: [PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: 'You are now the owner of project', + toUserHandle: true, + goTo: GOTO.PROJECT_DASHBOARD + }, { + text: 'Project owner was changed to [userFullName]', + projectRoles: [PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], + goTo: GOTO.PROJECT_DASHBOARD + }] }, { eventType: 'notifications.connect.project.member.copilotJoined', type: NOTIFICATION_TYPE.MEMBER_ADDED, - text: 'A copilot joined your project team', - projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: 'A copilot joined your project team', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], + goTo: GOTO.PROJECT_DASHBOARD + }] }, { eventType: 'notifications.connect.project.member.managerJoined', type: NOTIFICATION_TYPE.MEMBER_ADDED, - text: 'A manager joined your project team', - projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: 'A manager joined your project team', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER], + goTo: GOTO.PROJECT_DASHBOARD + }] }, { eventType: 'notifications.connect.project.topic.created', type: NOTIFICATION_TYPE.NEW_POSTS, - text: '[userHandle] created a new post ', - projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], - goTo: GOTO.TOPIC + rules: [{ + text: '[userHandle] created a new post ', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.TOPIC + }] + }, { + version: 2, + eventType: 'notifications.connect.project.topic.created', + type: NOTIFICATION_TYPE.NEW_POSTS, + rules: [{ + text: '[userFullName] created a new post ', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.TOPIC + }] }, { eventType: 'notifications.connect.project.post.created', type: NOTIFICATION_TYPE.NEW_POSTS, - text: '[userHandle] responded to your post', - toTopicStarter: true, - goTo: GOTO.POST + rules: [{ + text: '[userHandle] responded to your post', + toTopicStarter: true, + goTo: GOTO.POST + }, { + text: '[userHandle] responded to a post', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.POST + }] }, { + version: 2, eventType: 'notifications.connect.project.post.created', type: NOTIFICATION_TYPE.NEW_POSTS, - text: '[userHandle] responded to a post', - projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], - goTo: GOTO.POST + rules: [{ + text: '[userFullName] responded to your post', + toTopicStarter: true, + goTo: GOTO.POST + }, { + text: '[userFullName] responded to a post', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.POST + }] }, { eventType: 'notifications.connect.project.linkCreated', type: NOTIFICATION_TYPE.NEW_POSTS, - text: '[userHandle] added to your project', - projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], - goTo: GOTO.PROJECT_DASHBOARD + rules: [{ + text: '[userHandle] added to your project', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.PROJECT_DASHBOARD + }] + }, { + version: 2, + eventType: 'notifications.connect.project.linkCreated', + type: NOTIFICATION_TYPE.NEW_POSTS, + rules: [{ + text: '[userFullName] added to your project', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.PROJECT_DASHBOARD + }] }, { eventType: 'notifications.connect.project.fileUploaded', type: NOTIFICATION_TYPE.NEW_POSTS, - text: '[userHandle] added a new file', - projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], - goTo: GOTO.FILE_LIST + rules: [{ + text: '[userHandle] added a new file', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.FILE_LIST + }] + }, { + version: 2, + eventType: 'notifications.connect.project.fileUploaded', + type: NOTIFICATION_TYPE.NEW_POSTS, + rules: [{ + text: '[userFullName] added a new file', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.FILE_LIST + }] }, { eventType: 'notifications.connect.project.specificationModified', type: NOTIFICATION_TYPE.UPDATES, - text: '[userHandle] updated the project specification', - projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], - goTo: GOTO.PROJECT_SPECIFICATION + rules: [{ + text: '[userHandle] updated the project specification', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.PROJECT_SPECIFICATION + }] + }, { + version: 2, + eventType: 'notifications.connect.project.specificationModified', + type: NOTIFICATION_TYPE.UPDATES, + rules: [{ + text: '[userFullName] updated the project specification', + projectRoles: [PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, PROJECT_ROLE_MEMBER], + goTo: GOTO.PROJECT_SPECIFICATION + }] } ] + +// create a flat list of all possible notifications (expand notification rules) +export const NOTIFICATION_RULES = (() => { + const notificationRules = [] + + NOTIFICATIONS.forEach((notification) => { + notification.rules.forEach((notificationRule) => { + notificationRules.push({ ...notification, ...notificationRule }) + }) + }) + + return notificationRules +})() diff --git a/src/routes/notifications/helpers/notifications.js b/src/routes/notifications/helpers/notifications.js index 2907cb44a..5f55b66a9 100644 --- a/src/routes/notifications/helpers/notifications.js +++ b/src/routes/notifications/helpers/notifications.js @@ -3,7 +3,7 @@ */ import _ from 'lodash' import { OLD_NOTIFICATION_TIME } from '../../../config/constants' -import { NOTIFICATIONS } from '../constants/notifications' +import { NOTIFICATION_RULES } from '../constants/notifications' // how many milliseconds in one minute const MILLISECONDS_IN_MINUTE = 60000 @@ -133,9 +133,13 @@ const renderTemplate = (templateStr, values) => { * @return {Object} notification rule */ const getNotificationRule = (notification) => { - const notificationRule = _.find(NOTIFICATIONS, (_notificationRule) => { + const notificationRule = _.find(NOTIFICATION_RULES, (_notificationRule) => { let match = _notificationRule.eventType === notification.eventType + if (notification.version) { + match = match && _notificationRule.version === notification.version + } + if (notification.contents.toTopicStarter) { match = match && _notificationRule.toTopicStarter } @@ -156,7 +160,7 @@ const getNotificationRule = (notification) => { }) if (!notificationRule) { - throw new Error(`Cannot find notification rule for eventType ${notification.eventType}.`) + throw new Error(`Cannot find notification rule for eventType '${notification.eventType}' version '${notification.version}'.`) } return notificationRule @@ -178,7 +182,8 @@ export const prepareNotifications = (rowNotifications) => { date: rowNotification.createdAt, isRead: rowNotification.read, isOld: new Date().getTime() - OLD_NOTIFICATION_TIME * MILLISECONDS_IN_MINUTE > new Date(rowNotification.createdAt).getTime(), - contents: rowNotification.contents + contents: rowNotification.contents, + version: rowNotification.version })).map((notification) => { const notificationRule = getNotificationRule(notification) From ff6a46f0debe92cf59a230f38417951c1811f1a1 Mon Sep 17 00:00:00 2001 From: Maksym Mykhailenko Date: Sat, 6 Jan 2018 19:23:12 +0800 Subject: [PATCH 2/2] Revert development config for notification API URL --- config/constants/dev.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/constants/dev.js b/config/constants/dev.js index 365c98db7..ec672937d 100644 --- a/config/constants/dev.js +++ b/config/constants/dev.js @@ -44,5 +44,5 @@ module.exports = { IBM_COGNITIVE_PROGRAM_ID : 3449, HEAP_ANALYTICS_APP_ID : '4153837120', - TC_NOTIFICATION_URL: 'http://localhost:4000' + TC_NOTIFICATION_URL: 'https://api.topcoder-dev.com' }