diff --git a/ckanext-hdx_package/ckanext/hdx_package/helpers/analytics.py b/ckanext-hdx_package/ckanext/hdx_package/helpers/analytics.py index ecb9127af3..68bb4755c2 100644 --- a/ckanext-hdx_package/ckanext/hdx_package/helpers/analytics.py +++ b/ckanext-hdx_package/ckanext/hdx_package/helpers/analytics.py @@ -5,6 +5,9 @@ from ckanext.hdx_package.helpers.constants import COD_ENHANCED, COD_STANDARD from ckanext.hdx_theme.util.analytics import AbstractAnalyticsSender +from ckanext.hdx_users.helpers.notification_platform import check_notifications_enabled_for_dataset + +from typing import Any, Dict, Optional import ckan.lib.helpers as h import ckan.model as model @@ -63,6 +66,22 @@ def dataset_availability(pkg_dict): return level +def came_from(request_args: Dict[str, str]) -> Optional[str]: + source_mapping = { + 'notification_platform_email': 'notification platform email', + } + + came_from_arg = request_args.get('came_from') + + return source_mapping.get(came_from_arg, '') + + +def supports_notifications(pkg_dict: dict[str, Any]) -> str: + dataset_supports_notifications = check_notifications_enabled_for_dataset(pkg_dict['id']) + + return str(dataset_supports_notifications).lower() + + def extract_locations(pkg_dict): locations = pkg_dict.get('groups', []) location_names = [] @@ -121,6 +140,8 @@ def generate_analytics_data(dataset_dict): analytics_dict['isArchived'] = is_archived(dataset_dict) analytics_dict['groupNames'], analytics_dict['groupIds'] = extract_locations_in_json(dataset_dict) analytics_dict['datasetAvailability'] = dataset_availability(dataset_dict) + analytics_dict['cameFrom'] = '' + analytics_dict['supportsNotifications'] = supports_notifications(dataset_dict) else: analytics_dict['datasetId'] = '' analytics_dict['datasetName'] = '' @@ -132,6 +153,8 @@ def generate_analytics_data(dataset_dict): analytics_dict['groupNames'] = '[]' analytics_dict['groupIds'] = '[]' analytics_dict['datasetAvailability'] = None + analytics_dict['cameFrom'] = '' + analytics_dict['supportsNotifications'] = 'false' return analytics_dict diff --git a/ckanext-hdx_package/ckanext/hdx_package/views/dataset.py b/ckanext-hdx_package/ckanext/hdx_package/views/dataset.py index cefa06063f..eea2c269de 100644 --- a/ckanext-hdx_package/ckanext/hdx_package/views/dataset.py +++ b/ckanext-hdx_package/ckanext/hdx_package/views/dataset.py @@ -137,6 +137,8 @@ def read(id): analytics_is_archived = analytics.is_archived(pkg_dict) analytics_group_names, analytics_group_ids = analytics.extract_locations_in_json(pkg_dict) analytics_dataset_availability = analytics.dataset_availability(pkg_dict) + analytics_came_from = analytics.came_from(request.args) + analytics_supports_notifications = analytics.supports_notifications(pkg_dict) # changes done for indicator act_data_dict = {'id': pkg_dict['id'], 'limit': 7} @@ -189,7 +191,7 @@ def read(id): unsubscribe_token = request.args.get('unsubscribe_token', None) if unsubscribe_token: try: - token_obj = verify_unsubscribe_token(unsubscribe_token, inactivate=False) + unsubscribe_token = verify_unsubscribe_token(unsubscribe_token, inactivate=False) except Exception as e: unsubscribe_token = None h.flash_error('Your token is invalid or has expired.') @@ -208,6 +210,8 @@ def read(id): 'analytics_group_names': analytics_group_names, 'analytics_group_ids': analytics_group_ids, 'analytics_dataset_availability': analytics_dataset_availability, + 'analytics_came_from': analytics_came_from, + 'analytics_supports_notifications': analytics_supports_notifications, 'stats_downloads_last_weeks': stats_downloads_last_weeks, 'user_survey_url': user_survey_url, 'logo_config': logo_config, diff --git a/ckanext-hdx_package/ckanext/hdx_package/views/light_dataset.py b/ckanext-hdx_package/ckanext/hdx_package/views/light_dataset.py index ab22b59d64..bc53638d96 100644 --- a/ckanext-hdx_package/ckanext/hdx_package/views/light_dataset.py +++ b/ckanext-hdx_package/ckanext/hdx_package/views/light_dataset.py @@ -4,6 +4,7 @@ import ckan.plugins.toolkit as tk from ckan.common import g +from ckan.types import DataDict, Request import ckan.logic as logic import ckanext.hdx_package.helpers.analytics as analytics @@ -66,7 +67,7 @@ def read(id): org_info_dict = _get_org_extras(org_id) user_survey_url = org_info_dict.get('user_survey_url') if dataset_dict.get('type') == 'dataset': - analytics_dict = _compute_analytics(dataset_dict) + analytics_dict = _compute_analytics(dataset_dict, tk.request) dataset_dict['page_list'] = cp_h.hdx_get_page_list_for_dataset(context, dataset_dict) dataset_dict['link_list'] = get_action('hdx_package_links_by_id_list')(context, {'id': dataset_dict.get('name')}) @@ -122,13 +123,17 @@ def generic_search(html_template): return render(html_template, data_dict) -def _compute_analytics(dataset_dict): - result = {} - result['is_cod'] = analytics.is_cod(dataset_dict) - result['is_indicator'] = analytics.is_indicator(dataset_dict) - result['is_archived'] = analytics.is_archived(dataset_dict) - result['analytics_group_names'], result['analytics_group_ids'] = analytics.extract_locations_in_json(dataset_dict) - result['analytics_dataset_availability'] = analytics.dataset_availability(dataset_dict) +def _compute_analytics(dataset_dict: DataDict, request: Request): + result = { + 'is_cod': analytics.is_cod(dataset_dict), + 'is_indicator': analytics.is_indicator(dataset_dict), + 'is_archived': analytics.is_archived(dataset_dict), + 'analytics_group_names': (analytics.extract_locations_in_json(dataset_dict))[0], + 'analytics_group_ids': (analytics.extract_locations_in_json(dataset_dict))[1], + 'analytics_dataset_availability': analytics.dataset_availability(dataset_dict), + 'analytics_came_from': analytics.came_from(request.args), + 'analytics_supports_notifications': analytics.supports_notifications(dataset_dict), + } return result diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/base/hdx-util-lib.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/base/hdx-util-lib.js index 51ebe79f33..fdc1781062 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/base/hdx-util-lib.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/base/hdx-util-lib.js @@ -190,6 +190,7 @@ var randomIndex = Math.floor(Math.random() * NOTIFICATION_OPTIN_OPTIONS.length); optinLocation = NOTIFICATION_OPTIN_OPTIONS[randomIndex]; localStorage.setItem(NOTIFICATION_OPTIN_KEY, optinLocation); + hdxUtil.analytics.sendABTestingEvent('notification platform', optinLocation.replace('_', ' ')); } return optinLocation; diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/bem.blocks/floating_button.css b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/bem.blocks/floating_button.css index 826c6ca088..9573d9eff3 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/bem.blocks/floating_button.css +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/bem.blocks/floating_button.css @@ -21,7 +21,8 @@ .floating-button__paragraph { font-size: 18px; color: #FFF; - max-width: 250px; + max-width: 300px; padding-left: 10px; padding-right: 10px; + line-height: 1.05; } diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/datasets/dataset.css b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/datasets/dataset.css index c0d1e9afaa..dd726e8555 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/datasets/dataset.css +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/datasets/dataset.css @@ -121,13 +121,30 @@ .wrapper-secondary .form-check .form-check-input { box-shadow: none; } -.notification-platform-opt-in-action-menu i { +.notification-platform-opt-in-action-menu { + cursor: pointer; background-color: #007CE1; - color: #fff; - width: 22px; - height: 22px; - line-height: 22px; - border-radius: 11px; - font-size: 10px; + display: inline-block; + padding: 7px; + border-radius: 22px; + margin-top: -25px; + margin-bottom: 15px; +} +.notification-platform-opt-in-action-menu .icon { + width: 30px; + height: 30px; + line-height: 30px; + border-radius: 15px; text-align: center; + font-size: 18px; + color: #007CE1; + background-color: #fff; +} +.notification-platform-opt-in-action-menu .paragraph { + font-size: 14px; + color: #fff; + max-width: 240px; + padding-left: 10px; + padding-right: 10px; + line-height: 1.05; } diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/datasets/notification_platform.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/datasets/notification_platform.js index 45f4804198..887ed5720d 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/datasets/notification_platform.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/datasets/notification_platform.js @@ -1,41 +1,70 @@ var $notificationsSignupModal = $('#notificationsSignupBemModal'); var notificationsSignupModal = bootstrap.Modal.getOrCreateInstance($notificationsSignupModal.get(0)); +var $signupSubmitButton = $notificationsSignupModal.find('button[type="submit"]'); +var $signupDangerAlert = $notificationsSignupModal.find('.alert-danger'); +var $signupForm = $notificationsSignupModal.find('#notification-platform-form'); +var $signupFormPopupSourceInput = $signupForm.find('input[name="popup_source"]'); + +var $verificationModal = $('#notificationsVerificationBemModal'); +var verificationModal = bootstrap.Modal.getOrCreateInstance($verificationModal.get(0)); + +var $unsubscribeModal = $('#notificationsUnsubscribeBemModal'); +var unsubscribeModal = bootstrap.Modal.getOrCreateInstance($unsubscribeModal.get(0)); + +var $unsubscribedModal = $('#notificationsUnsubscribedBemModal'); +var unsubscribedModal = bootstrap.Modal.getOrCreateInstance($unsubscribedModal.get(0)); + +var $unsubscribeSubmitButton = $unsubscribeModal.find('button[type="submit"]'); +var $unsubscribeDangerAlert = $unsubscribeModal.find('.alert-danger'); + +var $actionMenuButton = $('.notification-platform-opt-in-action-menu'); +var $floatingButton = $('.notification-platform-opt-in-floating-button'); + +var $unsubscribeToken = $('#unsubscribe_token'); +var unsubscribeToken = null; +if($unsubscribeToken.length > 0 && $unsubscribeToken.data('token').toLowerCase() !== 'none') { + unsubscribeToken = $unsubscribeToken.data('token'); +} $(document).ready(function () { - var $verificationModal = $('#notificationsVerificationBemModal'); - var verificationModal = bootstrap.Modal.getOrCreateInstance($verificationModal.get(0)); - var $unsubscribeModal = $('#notificationsUnsubscribeBemModal'); - var unsubscribeModal = bootstrap.Modal.getOrCreateInstance($unsubscribeModal.get(0)); - var $unsubscribedModal = $('#notificationsUnsubscribedBemModal'); - var unsubscribedModal = bootstrap.Modal.getOrCreateInstance($unsubscribedModal.get(0)); - - var $signupForm = $notificationsSignupModal.find('#notification-platform-form'); - var $signupSubmitButton = $notificationsSignupModal.find('button[type="submit"]'); - var $signupDangerAlert = $notificationsSignupModal.find('.alert-danger'); - - var $unsubscribeSubmitButton = $unsubscribeModal.find('button[type="submit"]'); - var $unsubscribeDangerAlert = $unsubscribeModal.find('.alert-danger'); - - var $unsubscribeToken = $('#unsubscribe_token'); - var unsubscribeToken = null; - if($unsubscribeToken.length > 0 && $unsubscribeToken.data('token').toLowerCase() !== 'none') { - unsubscribeToken = $unsubscribeToken.data('token'); - } var onSignupSubmit = function (e) { e.preventDefault(); + var formDataArray = $signupForm.serializeArray(), formData = {}; + $(formDataArray).each(function (i, field) { + formData[field.name] = field.value; + }); + + var datasetId = formData.dataset_id; + var email = formData.email; + $.ajax({ url: '/notifications/subscription-confirmation', method: 'POST', headers: hdxUtil.net.getCsrfTokenAsObject(), - data: $signupForm.serialize(), + data: { + 'email': email, + 'dataset_id': datasetId, + 'g-recaptcha-response': formData['g-recaptcha-response'], + }, success: function (data) { grecaptcha.reset(); if (data.success) { hideAlert($signupDangerAlert); - hideNotificationsSignupModal(); + notificationsSignupModal.hide(); + verificationModal.show(); + + hdxUtil.analytics.sendNotificationPlatformPopupInteractionEvent( + 'confirm popup', + 'subscribe to notifications', + formData.popup_source, + datasetId, + formData.dataset_name, + hdxUtil.compute.strHash(email, 'notification_platform') + ); + } else { showAlert($signupDangerAlert, data.error.message); @@ -53,6 +82,10 @@ $(document).ready(function () { var onUnsubscribeSubmit = function (e) { e.preventDefault(); + var unsubscribeToken = $unsubscribeModal.data('token'); + var email = $unsubscribeModal.data('email'); + var datasetId = $unsubscribeModal.data('dataset-id'); + var datasetName = $unsubscribeModal.data('dataset-name'); $.ajax({ url: '/notifications/unsubscribe-confirmation', method: 'POST', @@ -65,6 +98,15 @@ $(document).ready(function () { hideAlert($unsubscribeDangerAlert); unsubscribeModal.hide(); unsubscribedModal.show(); + + hdxUtil.analytics.sendNotificationPlatformPopupInteractionEvent( + 'confirm popup', + 'unsubscribe from notifications', + null, + datasetId, + datasetName, + hdxUtil.compute.strHash(email, 'notification_platform') + ); } else { showAlert($unsubscribeDangerAlert, data.error.message); @@ -90,10 +132,10 @@ $(document).ready(function () { var optinLocation = hdxUtil.net.getNotificationOptinLocation(); if (optinLocation === 'action_menu') { - $('.notification-platform-opt-in-action-menu').removeClass('d-none'); + $actionMenuButton.removeClass('d-none'); } else if (optinLocation === 'floating_button') { - $('.notification-platform-opt-in-floating-button').removeClass('d-none'); + $floatingButton.removeClass('d-none'); } }; @@ -102,26 +144,64 @@ $(document).ready(function () { $unsubscribeSubmitButton.on('click', onUnsubscribeSubmit); + $actionMenuButton.on('click', function(e) { + e.preventDefault(); + var datasetId = $(this).data('dataset-id'); + var datasetName = $(this).data('dataset-name'); + showNotificationsSignupModal('action menu', datasetId, datasetName); + return false; + }); + + $floatingButton.on('click', function(e) { + e.preventDefault(); + var datasetId = $(this).data('dataset-id'); + var datasetName = $(this).data('dataset-name'); + showNotificationsSignupModal('floating button', datasetId, datasetName); + return false; + }); + if(unsubscribeToken) { unsubscribeModal.show(); + var datasetId = $unsubscribeModal.data('dataset-id'); + var datasetName = $unsubscribeModal.data('dataset-name'); + + hdxUtil.analytics.sendNotificationPlatformPopupInteractionEvent( + 'show popup', + 'unsubscribe from notifications', + null, + datasetId, + datasetName, + null + ); } else { displayNotificationOptinOption(); } }); -var showNotificationsSignupModal = function (datasetId) { +var showNotificationsSignupModal = function (popupSource, datasetId, datasetName) { var modalShownData = hdxUtil.net.getNotificationModalData() || {}; - if (!modalShownData[datasetId]) { + if (!modalShownData[datasetId] || popupSource !== 'download') { notificationsSignupModal.show(); - - var newData = {}; - newData[datasetId] = true; - hdxUtil.net.updateNotificationModalData(newData); + $signupFormPopupSourceInput.val(popupSource); + hdxUtil.analytics.sendNotificationPlatformPopupInteractionEvent( + 'show popup', + 'subscribe to notifications', + popupSource, + datasetId, + datasetName, + null + ); + + if(popupSource === 'download') { + var newData = {}; + newData[datasetId] = true; + hdxUtil.net.updateNotificationModalData(newData); + } } }; -var hideNotificationsSignupModal = function () { - notificationsSignupModal.hide(); -}; +$notificationsSignupModal.on('hide.bs.modal', function () { + $signupFormPopupSourceInput.val(''); +}); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/google-analytics.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/google-analytics.js index cf424f838d..a7d04d1b64 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/google-analytics.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/google-analytics.js @@ -288,7 +288,9 @@ $( "is cod": analyticsInfo.isCod, "is indicator": analyticsInfo.isIndicator, "is archived": analyticsInfo.isArchived, - "authenticated": analyticsInfo.authenticated + "authenticated": analyticsInfo.authenticated, + "came from": analyticsInfo.cameFrom, // notification platform email + "supports notifications": analyticsInfo.supportsNotifications, // true / false }); }); @@ -716,6 +718,53 @@ $( } hdxUtil.analytics.sendSurveyEvent = sendSurveyEvent; + + /** + * Sends events related to notification platform popup interaction + * @param interactionType {string} + * @param popupTitle {string} + * @param popupSource {string} + * @param datasetId {string} + * @param datasetName {string} + * @param emailHash {string} + */ + function sendNotificationPlatformPopupInteractionEvent(interactionType, popupTitle, popupSource, datasetId, datasetName, emailHash) { + var mixpanelData = { + "eventName": "popup interaction", + "eventMeta": { + "interaction type": interactionType, // show popup / confirm popup + "popup type": "notification platform", + "popup title": popupTitle, // subscribe to notifications / unsubscribe from notifications + "popup source": popupSource, // download / action menu / floating button (for subscribe) + "dataset id": datasetId, + "dataset name": datasetName, + "email hash": emailHash, + } + }; + return sendAnalyticsEventsAsync(mixpanelData); + } + + hdxUtil.analytics.sendNotificationPlatformPopupInteractionEvent = sendNotificationPlatformPopupInteractionEvent; + + + /** + * Sends events related to A/B testing + * @param testingType {string} + * @param testingOption {string} + */ + function sendABTestingEvent(testingType, testingOption) { + var mixpanelData = { + "eventName": "ab testing", + "eventMeta": { + "type": testingType, // notification platform + "option": testingOption, // action menu / floating button + } + }; + return sendAnalyticsEventsAsync(mixpanelData); + } + + hdxUtil.analytics.sendABTestingEvent = sendABTestingEvent; + /** * This function will send the analytics events to the server async and will return a promise * which is fulfilled when the events are successfully sent OR when "timeout" seconds have passed diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/_header-light.css b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/_header-light.css index d01d84a7a1..29207f7a2b 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/_header-light.css +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/_header-light.css @@ -333,3 +333,6 @@ width: 40px; } } +.flash-messages { + background-color: unset; +} diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/dataset/dataset-light.css b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/dataset/dataset-light.css index 80ca76ae95..879fa34515 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/dataset/dataset-light.css +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/dataset/dataset-light.css @@ -121,15 +121,32 @@ .wrapper-secondary .form-check .form-check-input { box-shadow: none; } -.notification-platform-opt-in-action-menu i { +.notification-platform-opt-in-action-menu { + cursor: pointer; background-color: #007CE1; - color: #fff; - width: 22px; - height: 22px; - line-height: 22px; - border-radius: 11px; - font-size: 10px; + display: inline-block; + padding: 7px; + border-radius: 22px; + margin-top: -25px; + margin-bottom: 15px; +} +.notification-platform-opt-in-action-menu .icon { + width: 30px; + height: 30px; + line-height: 30px; + border-radius: 15px; text-align: center; + font-size: 18px; + color: #007CE1; + background-color: #fff; +} +.notification-platform-opt-in-action-menu .paragraph { + font-size: 14px; + color: #fff; + max-width: 240px; + padding-left: 10px; + padding-right: 10px; + line-height: 1.05; } .dataset-light .nav-tabs { margin: 0 -15px; @@ -247,16 +264,7 @@ margin-left: 0; } .dataset-light .notification-platform-opt-in-action-menu { - display: block; - margin-bottom: 1rem; -} -.dataset-light .notification-platform-opt-in-action-menu i { - width: 18px; - height: 18px; - line-height: 18px; - border-radius: 9px; - font-size: 10px; - margin-right: 3px; + margin-top: 5px; } @media (max-width: 375px) { .dataset-light .nav-tabs .hdx-tab-button { diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/page-light.css b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/page-light.css index e2622d6305..e538afbc1d 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/page-light.css +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/light/page-light.css @@ -4257,6 +4257,9 @@ label.terms-of-service:after { width: 40px; } } +.flash-messages { + background-color: unset; +} .mobile-carousel { display: none; } diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/resource-list.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/resource-list.js index ec3a80d2b3..da89af052e 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/resource-list.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/resource-list.js @@ -26,7 +26,7 @@ function showDataCheck(url){ iframe.focus(); } var DATA_USE_SURVEY_LOAD_COUNT; -function showDataUseSurveyPopup(resId, datasetId, userSurveyUrl) { +function showDataUseSurveyPopup(resId, datasetId, datasetName, datasetSupportsNotifications, userSurveyUrl) { const orgName = $("#dataUseSurveyOrgName").text(); const SURVEY_KEY = "/organization:" + "hdx-data-use-survey-popup-" + orgName; @@ -68,17 +68,19 @@ function showDataUseSurveyPopup(resId, datasetId, userSurveyUrl) { iframe.hide(); $("#dataUseSurveyPopup").show(); } - else { - showNotificationsSignupModal(datasetId); + else if(datasetSupportsNotifications.toString() === 'true') { + showNotificationsSignupModal('download', datasetId, datasetName); } } $('.resource-download-button').on('click', function (event) { var resId = $(this).data('resource-id'); var datasetId = $(this).data('dataset-id'); + var datasetName = $(this).data('dataset-name'); + var datasetSupportsNotifications = $(this).data('dataset-supports-notifications'); var userSurveyUrl = $(this).data('user-survey-url'); - showDataUseSurveyPopup(resId, datasetId, userSurveyUrl); + showDataUseSurveyPopup(resId, datasetId, datasetName, datasetSupportsNotifications, userSurveyUrl); return true; }); diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/bem.blocks/floating_button.less b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/bem.blocks/floating_button.less index 057569c4ef..315b8d0227 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/bem.blocks/floating_button.less +++ b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/bem.blocks/floating_button.less @@ -23,8 +23,9 @@ &__paragraph { font-size: 18px; color: @white-color; - max-width: 250px; + max-width: 300px; padding-left: 10px; padding-right: 10px; + line-height: 1.05; } } diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/datasets/dataset.less b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/datasets/dataset.less index fa726b5edb..7c1dad96ca 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/datasets/dataset.less +++ b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/datasets/dataset.less @@ -153,14 +153,30 @@ } .notification-platform-opt-in-action-menu { - i { - background-color: #007CE1; - color: #fff; - width: 22px; - height: 22px; - line-height: 22px; - border-radius: 11px; - font-size: 10px; + cursor: pointer; + background-color: #007CE1; + display: inline-block; + padding: 7px; + border-radius: 22px; + margin-top: -25px; + margin-bottom: 15px; + + .icon { + width: 30px; + height: 30px; + line-height: 30px; + border-radius: 15px; text-align: center; + font-size: 18px; + color: #007CE1; + background-color: #fff; + } + .paragraph { + font-size: 14px; + color: #fff; + max-width: 240px; + padding-left: 10px; + padding-right: 10px; + line-height: 1.05; } } diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/light/_header-light.less b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/light/_header-light.less index 62f5bf5f4f..4c6b1c81e9 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/light/_header-light.less +++ b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/light/_header-light.less @@ -36,3 +36,6 @@ } } +.flash-messages { + background-color: unset; +} diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/light/dataset/dataset-light.less b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/light/dataset/dataset-light.less index 3bb4ad3266..fb81c1a5c3 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/light/dataset/dataset-light.less +++ b/ckanext-hdx_theme/ckanext/hdx_theme/hdx-styles/src/common/less/light/dataset/dataset-light.less @@ -140,16 +140,7 @@ margin-left: 0; } .notification-platform-opt-in-action-menu { - display: block; - margin-bottom: 1rem; - i { - width: 18px; - height: 18px; - line-height: 18px; - border-radius: 9px; - font-size: 10px; - margin-right: 3px; - } + margin-top: 5px; } } diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/helpers.py b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/helpers.py index 154547f81d..29fb2b3c18 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/helpers.py +++ b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/helpers.py @@ -23,6 +23,7 @@ from ckanext.hdx_package.helpers.freshness_calculator import UPDATE_FREQ_INFO from ckanext.hdx_package.helpers.p_code_filters_helper import are_new_p_code_filters_enabled from ckanext.hdx_theme.util.light_redirect import switch_url_path +from ckanext.hdx_users.helpers.notification_platform import check_notifications_enabled_for_dataset _ = toolkit._ request = toolkit.request @@ -1029,3 +1030,8 @@ def hdx_generate_basemap_config_string() -> str: 'token': config.get('hdx.mapbox.baselayer.token'), } return json.dumps(conf_dict) + + +def hdx_dataset_supports_notifications(pkg_id: str) -> str: + supports_notifications = check_notifications_enabled_for_dataset(pkg_id) + return str(supports_notifications).lower() diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/notification_platform/__init__.py b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/notification_platform/__init__.py index 0bfc395983..26e1d38131 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/notification_platform/__init__.py +++ b/ckanext-hdx_theme/ckanext/hdx_theme/helpers/ui_constants/notification_platform/__init__.py @@ -1,6 +1,5 @@ CONSTANTS = { - 'OPT_IN_TEXT_ACTION_MENU': '''Subscribe to email notifications''', - 'OPT_IN_TEXT_FLOATING_BUTTON': '''Sign up to receive alerts when this dataset is updated''', + 'OPT_IN_TEXT': '''Sign up to receive email notifications when this dataset is updated''', 'SIGNUP_MODAL_TITLE': '''Do you want to receive email notifications when this dataset is updated?''', 'SIGNUP_MODAL_INTRO_TEXT': '''Would you like to receive email notifications when resources (files) in this diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/plugin.py b/ckanext-hdx_theme/ckanext/hdx_theme/plugin.py index be7b060e6e..1223e7fba4 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/plugin.py +++ b/ckanext-hdx_theme/ckanext/hdx_theme/plugin.py @@ -264,6 +264,7 @@ def get_helpers(self): 'hdx_generate_basemap_config_string': hdx_helpers.hdx_generate_basemap_config_string, 'hdx_location_dict': hdx_helpers.hdx_location_dict, 'hdx_user_orgs_dict': hdx_helpers.hdx_user_orgs_dict, + 'hdx_dataset_supports_notifications': hdx_helpers.hdx_dataset_supports_notifications, 'HDX_CONST': const, } diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/base.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/base.html index 1cd3cbdace..98fc0d0324 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/base.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/base.html @@ -30,6 +30,8 @@ 'datasetId': '{% block analytics_dataset_id %}None{% endblock %}', 'pageTitle': '{% if self.subtitle()|trim %}{{ self.subtitle()|trim }}{% else %} {{ 'None' }} {% endif -%}', 'datasetAvailability': '{% block analytics_dataset_availability %}None{% endblock %}', + 'cameFrom': '{% block analytics_came_from %}{% endblock %}', + 'supportsNotifications': {% block analytics_supports_notifications %}null{% endblock %}, 'authenticated': '{{ "true" if c.userobj else "false" }}' }; @@ -170,7 +172,7 @@ {% endblock %} - + {# render all assets included in styles block #} {{ h.render_assets('style') }} {%- block custom_styles %} diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/bem.blocks/floating_button.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/bem.blocks/floating_button.html index 885a0d38f9..62ce577ca2 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/bem.blocks/floating_button.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/bem.blocks/floating_button.html @@ -1,7 +1,9 @@