4 Notification Bubble for Connection Requests and Tasks - V3 (Rock v18+) Shared by Brent Pirolli, CedarCreek Church 9 days ago 18.1 Administration / Finance, CMS, Connection, Web, General, Operations Beginner Notification Bubble for Staff One of the worst things to hear was how someone tried to get connected at church and never heard back from the staff or volunteers. Oof! Rock goes a long way to helping with this, but we wanted to leverage what people are used to seeing every day (notification bubbles) to make sure items awaiting their attention were not overlooked, tucked away on a page they may not visit daily. Let's put these notifications into a format that people are used to seeing as "needing attention" and give them a red bubble with a notifications count in it. (Yes, I'm aware some monsters out there have 24,563 unread messages in their gmail app with an atrociously ignored notification bubble... you know who you are... this won't help you... call a therapist). Prerequisite: Rock v18+ This is where light/dark modes and the new "RockNextGen" Theme came into play. If you are on a previous version of Rock, consider V2 of this recipe here: https://community.rockrms.com/recipes/413/notification-bubble-for-connection-requests-and-tasks-v2-up-to-rock-v17 Let's Build! 1) We're going to start by adding a new block to the Header Zone, that is visible across the entire Site. On the left, choose "Admin Tools" and "Settings" to enter the Settings area. From there, choose "CMS" and "Pages". Choose "Internal Homepage" and then change the zone to "Header" in the dropdown box. 2) Click the "Add Block to Zone" button and enter "Action Required Notifications" as the name. Type should be HTML Content, and then choose "Site (Rock RMS)" as the "Add To" option to ensure this shows across the entire internal Rock site and not only this page. Click "Save" when done. 3) Optionally drag the three lines on the left of that item to the top of the stack if you want the icon to be the far right (closest to the user's name at the top right). If you want it on the left (closest to the search box), you can skip this. 4) Now click the edit HTML button and copy and paste the following code (this box scrolls down) into the code editor view of this block (you should see line numbers on the left, if you don't press the code editor button to the left of the "Bold" text button) and press Save. {% assign personId = CurrentPerson.Id %} {% assign userTimeZone = CurrentPerson | Attribute:'TimeZone' | Default:'Eastern Standard Time' %} {% sql %} DECLARE @UserTimeZone NVARCHAR(50) = '{{ userTimeZone }}'; DECLARE @Today DATE = CAST(SYSDATETIMEOFFSET() AT TIME ZONE @UserTimeZone AS DATE); DECLARE @PersonId INT = {{ personId }}; -- Ensure the outer SELECT always returns a single row with non-null integers SELECT COALESCE(SUM(CASE WHEN Source = 'Connection' THEN Cnt ELSE 0 END), 0) AS ConnectionCount, COALESCE(SUM(CASE WHEN Source = 'Task' THEN Cnt ELSE 0 END), 0) AS TaskCount FROM ( -- Connection Requests SELECT 'Connection' AS Source, COUNT(*) AS Cnt FROM [ConnectionRequest] cr INNER JOIN [PersonAlias] pa ON pa.[Id] = cr.[ConnectorPersonAliasId] WHERE pa.[PersonId] = @PersonId AND ( cr.[ConnectionState] = 0 OR (cr.[ConnectionState] = 2 AND cr.[FollowUpDate] <= @Today) ) UNION ALL -- Workflow Tasks (activation checks on Workflow and WorkflowActivity) SELECT 'Task', COUNT(*) FROM WorkflowActivity LEFT JOIN PersonAlias ON WorkflowActivity.AssignedPersonAliasId = PersonAlias.Id AND PersonAlias.PersonId = @PersonId LEFT JOIN ( SELECT * FROM GroupMember WHERE PersonId = @PersonId AND GroupMemberStatus = 1 AND ArchivedDateTime IS NULL AND InactiveDateTime IS NULL ) AS GM ON GM.GroupId = WorkflowActivity.AssignedGroupId INNER JOIN Workflow ON WorkflowActivity.WorkflowId = Workflow.Id INNER JOIN WorkflowAction ON WorkflowActivity.Id = WorkflowAction.ActivityId INNER JOIN WorkflowActionType ON WorkflowAction.ActionTypeId = WorkflowActionType.Id INNER JOIN WorkflowActivityType ON WorkflowActionType.ActivityTypeId = WorkflowActivityType.Id INNER JOIN WorkflowType ON WorkflowActivityType.WorkflowTypeId = WorkflowType.Id WHERE -- Activated WorkflowActivity.ActivatedDateTime IS NOT NULL AND Workflow.ActivatedDateTime IS NOT NULL -- Open/incomplete only AND WorkflowAction.CompletedDateTime IS NULL AND WorkflowActivity.CompletedDateTime IS NULL AND Workflow.CompletedDateTime IS NULL -- Only active types AND WorkflowActivityType.IsActive != 0 AND WorkflowType.IsActive != 0 -- Assigned to the person or their active groups AND (GM.Id IS NOT NULL OR PersonAlias.Id IS NOT NULL) -- Only actions with a form AND WorkflowActionType.WorkflowFormId IS NOT NULL ) AS Counts; {% endsql %} {% assign connectionCount = 0 %} {% assign taskCount = 0 %} {% if results and results.size > 0 %} {% assign connectionCount = results[0].ConnectionCount | Default: 0 | AsInteger %} {% assign taskCount = results[0].TaskCount | Default: 0 | AsInteger %} {% endif %} {% assign totalCount = connectionCount | Plus: taskCount %} {% assign tooltip = 'Connections: ' | Append: connectionCount | Append: ' Tasks: ' | Append: taskCount %} {% if totalCount > 0 %} {% endif %} 5) Next we need to allow some security permissions for this block to run the SQL and Entity Commands and assign it a CSS Class so it will format and appear properly for mobile devices. Click on the "Block Properties" icon, enable "Rock Entity" and "SQL" lava commands in the first tab, then click on the "Advanced Settings" tab and give it a CSS class of "notifications-bubble" and press Save. End Result If all has gone as expected, you should now see NOTHING! Well... unless you have any Tasks or Connection Requests assigned to you. If you do, then you'll see something like the photos below (desktop and mobile menu). If you click it, you'll be taken to your "My Connections" page where you should see a matching number of items awaiting your attention. Desktop View (shown in both light and dark modes): Mobile View: NOTE: By default, this notification will always appear in the top bar, even on narrow screens (mobile devices). While we prefer this to make sure staff see it without opening the menu, I understand you may not. If you want to NOT have that on the top bar on mobile devices and you want it to only show when the menu is opened (similar to the other two round icons), you can edit the HTML of the block and replace: /* Display top bar alerts/notifications on small screens */ .rock-top-header .navbar-zone-header .zone-content .smart-search { flex: 1 1; max-width: 340px; } .rock-top-header .navbar-zone-header .zone-content > .notifications-bubble { display: block; } @media (max-width: 767px) { .navbar-side-open .zone-content > .notifications-bubble { position: inherit; } } with: /* Display menu alerts/notifications on small screens */ @media (max-width: 767px) { .navbar-side-open .zone-content > .notifications-bubble { position: fixed; display: block !important; top: 60px; right: 84px; } } V1 - Thanks to Courtney Cooksey and David Axelson for help with some of the original code! V2 - This code has bene completely re-written to: - use more efficient SQL (one call instad of two) - use the users's local timezone when determining which tasks are due (defaults to EST if not specified, so feel free to adjust line 26 as needed if you aren't EST) - add a tooltip on the notification now that shows a breakdown of "Connections: # and Tasks: #" with a dynamic width V3 - Rebuilt for V18+ with style and format adapted to NextGen theming: - converted from fontawesome to tabler icon - added light/dark modes support - removed "ul" and "li" elements for displaying the badge - give options on where to display the badge on mobile devices (narrow screens)