Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prod into dev #6464

Merged
merged 9 commits into from
Oct 29, 2024
23 changes: 23 additions & 0 deletions ckanext-hdx_package/ckanext/hdx_package/helpers/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = []
Expand Down Expand Up @@ -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'] = ''
Expand All @@ -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


Expand Down
6 changes: 5 additions & 1 deletion ckanext-hdx_package/ckanext/hdx_package/views/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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.')
Expand All @@ -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,
Expand Down
21 changes: 13 additions & 8 deletions ckanext-hdx_package/ckanext/hdx_package/views/light_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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')})

Expand Down Expand Up @@ -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


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
31 changes: 24 additions & 7 deletions ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/datasets/dataset.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -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',
Expand All @@ -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);
Expand All @@ -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');
}
};

Expand All @@ -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('');
});
Loading
Loading