Objective Enable project Notifications on Modern UI (bell logo on top right). Summary 1. Enable Push on project Notifications 2. Modify File $NIKU_HOME/META-INF/nmc/pmd/notificationPMD.xml 3. Create a New Notification Template in Folder $NIKU_HOME\META-INF\uif\wars\js\core\layout\notification 4. Modify JS File $NIKU_HOME\META-INF\uif\wars\js\ppm-core-app-%.js 5. Persist Changes in War File $NIKU_HOME\META-INF\uif\wars\ppm-ux.war Detail --1. Enable Push on project Notifications begin update cmn_notification_def_objects d set d.is_push_enabled = 1 where d.object_type_code = 'project' and d.is_push_enabled = 0; commit; end; --2. Modify File $NIKU_HOME/META-INF/nmc/pmd/notificationPMD.xml Statement nmc.getUnreadNotificationsByUserName returns the Correct Total. Statement nmc.markAllPushNotificationsAsRead marks the Correct Notifications. Modify Statement nmc.getPushedNotifications to add where clause l.lookup_code = 'NOTIFICATION_CONVERSATIONS' on Conversation Notification. Add SQL Select to add New Notification Type project. Add Dynamic Parameter . SELECT n.id id , c.id conversation_id , c.top_parent_id conv_top_parent_id , c.message , n.localized_subject subject , n.is_visited , c.resource_name originating_area , c.resource_id originating_object_id , ( CASE WHEN c.resource_name = 'teams' THEN ( SELECT prprojectid FROM prteam WHERE prid = c.resource_id ) WHEN c.resource_name = 'tasks' THEN ( SELECT prprojectid FROM prtask WHERE prid = c.resource_id ) WHEN c.resource_name in ('risks', 'issues', 'changes') THEN ( SELECT pk_id FROM rim_risks_and_issues WHERE id = c.resource_id ) WHEN c.resource_name = 'costPlans' THEN ( SELECT object_id FROM fin_plans WHERE id = c.resource_id ) WHEN c.resource_name = 'costPlanDetails' THEN ( SELECT plan_id FROM fin_cost_plan_details WHERE id = c.resource_id ) ELSE -1 END ) originating_parent_id , ( CASE WHEN c.resource_name = 'teams' THEN ( SELECT odf_object_code @+@ 's' FROM inv_investments where id = (SELECT prprojectid FROM prteam WHERE prid = c.resource_id )) WHEN c.resource_name = 'tasks' THEN ( SELECT odf_object_code @+@ 's' FROM inv_investments where id = (SELECT prprojectid FROM prtask WHERE prid = c.resource_id )) WHEN c.resource_name in ('risks', 'issues', 'changes') THEN ( SELECT odf_object_code @+@ 's' FROM inv_investments where id = ( SELECT pk_id FROM rim_risks_and_issues WHERE id = c.resource_id )) WHEN c.resource_name = 'costPlans' THEN ( SELECT api_alias from ODF_OBJECTS WHERE code = ( SELECT odf_object_code FROM inv_investments where id = ( SELECT object_id FROM fin_plans WHERE id = c.resource_id ))) WHEN c.resource_name = 'costPlanDetails' THEN ( SELECT plan_type_code FROM fin_plans where id = ( SELECT plan_id FROM fin_cost_plan_details WHERE id = c.resource_id )) ELSE '' END ) originating_parent_area , ( CASE WHEN c.resource_name = 'costPlans' THEN ( SELECT name FROM INV_INVESTMENTS WHERE id = ( SELECT object_id FROM fin_plans WHERE id = c.resource_id ) ) WHEN c.resource_name = 'costPlanDetails' THEN ( SELECT name FROM fin_plans WHERE id = ( SELECT plan_id FROM fin_cost_plan_details WHERE id = c.resource_id ) ) ELSE '' END ) originating_parent_name , ( CASE WHEN c.resource_name = 'costPlanDetails' THEN ( SELECT object_id FROM fin_plans WHERE id = ( SELECT plan_id FROM fin_cost_plan_details WHERE id = c.resource_id ) ) ELSE -1 END ) originating_grand_parent_id , ( CASE WHEN c.resource_name = 'costPlanDetails' THEN ( SELECT api_alias from ODF_OBJECTS WHERE code = ( SELECT odf_object_code FROM inv_investments where id = ( SELECT object_id FROM fin_plans WHERE id = ( SELECT plan_id FROM fin_cost_plan_details WHERE id = c.resource_id ) ) ) ) ELSE '' END ) originating_grand_parent_area , ( CASE WHEN c.resource_name = 'costPlanDetails' THEN ( SELECT name FROM INV_INVESTMENTS WHERE id = ( SELECT object_id FROM fin_plans WHERE id = ( SELECT plan_id FROM fin_cost_plan_details WHERE id = c.resource_id ) ) ) ELSE '' END ) originating_grand_parent_name , r.id sender_resource_id , r.first_name sender_first_name , r.last_name sender_last_name , r.full_name sender_full_name , n.created_date notification_creation_time , 'conversation' notification_type FROM clb_notifications n LEFT OUTER JOIN nmc_conversations c ON n.originating_object_instance_id = c.id , cmn_sec_users u, srm_resources r, cmn_lookups l, cmn_notification_def_objects d WHERE u.id = n.receiver_id AND n.sender_id = r.user_id AND n.event_type = l.lookup_code AND l.lookup_type = 'NOTIFICATION_TYPE' and l.lookup_code = 'NOTIFICATION_CONVERSATIONS' AND d.is_push_enabled = 1 AND d.functional_area_id = l.id AND n.receiver_id = ? union all select n.id id, -1 conversation_id, -1 conv_top_parent_id, n.localized_message message, n.localized_subject subject, n.is_visited, '' originating_area, -1 originating_object_id, -1 originating_parent_id, '' originating_parent_area, '' originating_parent_name, -1 originating_grand_parent_id, '' originating_grand_parent_area, '' originating_grand_parent_name, r.id sender_resource_id, r.first_name sender_first_name, r.last_name sender_last_name, r.full_name sender_full_name, n.created_date notification_creation_time, 'project' notification_type from clb_notifications n inner join cmn_sec_users u on u.id = n.receiver_id inner join srm_resources r on r.user_id = n.sender_id inner join cmn_lookups l on l.lookup_code = n.event_type and l.lookup_type = 'NOTIFICATION_TYPE' inner join cmn_notification_def_objects d on d.functional_area_id = l.id where d.object_type_code = 'project' and d.is_push_enabled = 1 and n.receiver_id = ? union all SELECT c.id id, -1 conversation_id, -1 conv_top_parent_id ,r.output_path message, r.status_code subject ,c.is_visited, '' originating_area, -1 originating_object_id, -1 originating_parent_id, '' originating_parent_area, '' originating_parent_name, -1 originating_grand_parent_id, '' originating_grand_parent_name, '' originating_grand_parent_name , -1 sender_resource_id, '' sender_first_name, '' sender_last_name, '' sender_full_name ,r.end_date notification_creation_time, 'csv_export' notification_type FROM clb_notifications c, cmn_sch_job_definitions d, cmn_sch_job_runs r WHERE d.job_code = 'CSV_EXPORT_ITEMS' AND c.event_type = 'SCHEDULER_TYPE' AND c.originating_object_instance_id = d.id AND c.receiver_id = ? AND TRIM(SUBSTR(SUBSTR(c.localized_message, INSTR(c.localized_message, ':', INSTR(c.localized_message, '<br>', 1, 3)) + 1), 2, INSTR(SUBSTR(c.localized_message, INSTR(c.localized_message, ':', INSTR(c.localized_message, '<br>', 1, 3) + 1)), '<br>') - 4)) = TO_CHAR(r.id) AND SUBSTRING(SUBSTRING(localized_message, CHARINDEX(':', localized_message, CHARINDEX('<br>', localized_message, CHARINDEX('<br>', localized_message, CHARINDEX('<br>', localized_message) + 1) + 1)) + 2, LEN(localized_message)), 1, CHARINDEX('<br>',SUBSTRING(localized_message, CHARINDEX(':', localized_message, CHARINDEX('<br>', localized_message, CHARINDEX('<br>', localized_message, CHARINDEX('<br>', localized_message) + 1) + 1)) + 2, LEN(localized_message))) - 3) = CONVERT(varchar, r.id) AND SUBSTRING(SUBSTRING(c.localized_message FROM '<br>..(?:[^<br>]*<br>)'), '\d+') = r.id::text AND r.status_code in ('COMPLETED', 'FAILED') ORDER BY notification_creation_time desc --3. Create a New Notification Template in Folder $NIKU_HOME\META-INF\uif\wars\js\core\layout\notification File Name : project-notification-item.tpl.html I removed the Avatar dynamically set with Notification Sender. I kept only Subject and Message with the Delete Action.
PPM
{{notificationItem.subject}}
--4. Modify JS File $NIKU_HOME\META-INF\uif\wars\js\ppm-core-app-%.js Identify the Function populateNotificationList. Add a case in the switch : the Notification Type must be the same as the Alias notification_type in the SQL Statement. Set the correct template html snippet project-notification-item.tpl.html. Note : It seems that the REST API function NotificationService.getNotifications $URL/ppm/rest/v1/private/pullNotifications does not return Notification Subject :( As a workaround, I added a part to split Message with the key word :: case "project": { notificationDetails.isVisited = notification.isVisited; notificationDetails.template = "js/core/layout/notification/project-notification-item.tpl.html"; notificationDetails.notificationId = notification.id; notificationDetails.notificationType = notification.notificationType; var v_array = notification.message.split("::"); if (v_array.length > 0) { notificationDetails.subject = v_array[0]; notificationDetails.message = v_array[1]; } else { notificationDetails.subject = "Notification"; notificationDetails.message = notification.message; } break; } --5. Persist Changes in War File $NIKU_HOME\META-INF\uif\wars\ppm-ux.war Redeploy app Services after copy-paste file on target server.