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.