diff --git a/app/assets/javascripts/projects/introdutory_popup.js b/app/assets/javascripts/projects/introdutory_popup.js
deleted file mode 100644
index 95b11a1cc..000000000
--- a/app/assets/javascripts/projects/introdutory_popup.js
+++ /dev/null
@@ -1,10 +0,0 @@
-(function(){
- // display introductory modal
- if( Cookies.get('popup-release-shown') !== 'yes'){
- $("#introductory-popup-modal").modal('show',{
- backdrop: true,
- keyboard: false,
- });
- Cookies.set('popup-release-shown', 'yes', { expires: 7300 });
- }
-})();
diff --git a/app/assets/javascripts/users/settings/preferences.js b/app/assets/javascripts/users/settings/preferences.js
index ef4f31a14..88de044f6 100644
--- a/app/assets/javascripts/users/settings/preferences.js
+++ b/app/assets/javascripts/users/settings/preferences.js
@@ -95,28 +95,53 @@
// Setup notification checkbox buttons
function notificationsSettings() {
- var recent_notification = $('[name="recent_notification"]');
- recent_notification
- .checkboxpicker({
- onActiveCls: 'btn-primary'
- });
+ var notification_settings = [ "recent_notification",
+ "assignments_notification" ]
- if ( recent_notification.attr('value') === 'true' ) {
- recent_notification.prop('checked', true);
- } else {
- recent_notification.prop('checked', false);
+ for (var i = 0; i < notification_settings.length; i++ ) {
+ var setting = $('[name="' + notification_settings[i] + '"]');
+ var dependant = $('[name="' + notification_settings[i] + '_email"]');
+ setting
+ .checkboxpicker({
+ onActiveCls: 'btn-primary'
+ }).change(function() {
+ if ( $(this).prop('checked') ) {
+ enableDependant($('[name="' + $(this).attr('name') + '_email"]'));
+ } else {
+ disableDependant($('[name="' + $(this).attr('name') + '_email"]'));
+ }
+ });
+
+ if ( setting.attr('value') === 'true' ) {
+ setting.prop('checked', true);
+ } else {
+ setting.prop('checked', false);
+ disableDependant(dependant);
+ }
+
+ setEmailSwitch(dependant);
}
- var assignments_notification = $('[name="assignments_notification"]');
- assignments_notification
- .checkboxpicker({
- onActiveCls: 'btn-primary'
- });
+ function setEmailSwitch(setting) {
+ setting
+ .checkboxpicker({
+ onActiveCls: 'btn-primary'
+ });
+ if ( setting.attr('value') === 'true' ) {
+ setting.prop('checked', true);
+ enableDependant(setting);
+ } else {
+ setting.prop('checked', false);
+ }
+ }
- if ( assignments_notification.attr('value') === 'true' ) {
- assignments_notification.prop('checked', true);
- } else {
- assignments_notification.prop('checked', false);
+ function disableDependant(dependant) {
+ dependant.checkboxpicker().prop('disabled', true);
+ dependant.checkboxpicker().prop('checked', false);
+ }
+
+ function enableDependant(dependant) {
+ dependant.checkboxpicker().prop('disabled', false);
}
var system_message_notification = $('[name="system_message_notification"]');
diff --git a/app/controllers/users/settings_controller.rb b/app/controllers/users/settings_controller.rb
index bd89daef8..7e8f13c3c 100644
--- a/app/controllers/users/settings_controller.rb
+++ b/app/controllers/users/settings_controller.rb
@@ -458,8 +458,13 @@ class Users::SettingsController < ApplicationController
end
def notifications_settings
- @user.assignments_notification = params[:assignments_notification]
- @user.recent_notification = params[:recent_notification]
+ @user.assignments_notification =
+ params[:assignments_notification] ? true : false
+ @user.recent_notification = params[:recent_notification] ? true : false
+ @user.recent_notification_email =
+ params[:recent_notification_email] ? true : false
+ @user.assignments_notification_email =
+ params[:assignments_notification_email] ? true : false
if @user.save
respond_to do |format|
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
index 19364cd8d..e1f3eb61c 100644
--- a/app/helpers/notifications_helper.rb
+++ b/app/helpers/notifications_helper.rb
@@ -13,4 +13,8 @@ module NotificationsHelper
notification.save!
end
end
+
+ def send_email_notification(user, notification)
+ AppMailer.delay.notification(user, notification)
+ end
end
diff --git a/app/mailers/app_mailer.rb b/app/mailers/app_mailer.rb
index fcee5ca57..d72873ea2 100644
--- a/app/mailers/app_mailer.rb
+++ b/app/mailers/app_mailer.rb
@@ -12,4 +12,14 @@ class AppMailer < Devise::Mailer
headers = { to: @user.email, subject: (I18n.t('mailer.invitation_to_organization.subject')) }.merge(opts)
mail(headers)
end
-end
\ No newline at end of file
+
+ def notification(user, notification)
+ @user = user
+ @notification = notification
+ headers = {
+ to: @user.email,
+ subject: I18n.t('notifications.email_title')
+ }
+ mail(headers)
+ end
+end
diff --git a/app/models/user_notification.rb b/app/models/user_notification.rb
index a99b05895..d56cb3998 100644
--- a/app/models/user_notification.rb
+++ b/app/models/user_notification.rb
@@ -1,7 +1,11 @@
class UserNotification < ActiveRecord::Base
+ include NotificationsHelper
+
belongs_to :user
belongs_to :notification
+ after_save :send_email
+
def self.last_notifications(user, last_notification_id = nil, per_page = 10)
last_notification_id = 999999999999999999999999 if last_notification_id < 1
Notification.joins(:user_notifications)
@@ -25,4 +29,21 @@ class UserNotification < ActiveRecord::Base
def self.seen_by_user(user)
where(user: user).where(checked: false).update_all(checked: true)
end
+
+ def send_email
+ case notification.type_of
+ when 'system_message'
+ send_email_notification(user, notification)
+ when 'assignment'
+ send_email_notification(
+ user,
+ notification
+ ) if user.assignments_notification_email
+ when 'recent_changes'
+ send_email_notification(
+ user,
+ notification
+ ) if user.recent_notification_email
+ end
+ end
end
diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb
index e102948ab..cf0129a2c 100644
--- a/app/views/projects/index.html.erb
+++ b/app/views/projects/index.html.erb
@@ -132,10 +132,6 @@
<% end %>
-
-<%= render partial: 'projects/index/introductory_popup' %>
-<%= javascript_include_tag 'projects/introdutory_popup' %>
-
<% if @projects_by_orgs.length > 0 %>
<% @projects_by_orgs.each do |org, projects| %>
<%= render partial: "projects/index/org_projects", locals: {org: org, projects: projects} %>
diff --git a/app/views/projects/index/_introductory_popup.html.erb b/app/views/projects/index/_introductory_popup.html.erb
deleted file mode 100644
index 6498e0848..000000000
--- a/app/views/projects/index/_introductory_popup.html.erb
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
diff --git a/app/views/steps/_step.html.erb b/app/views/steps/_step.html.erb
index 00ae5e601..ba6ed12a8 100644
--- a/app/views/steps/_step.html.erb
+++ b/app/views/steps/_step.html.erb
@@ -31,8 +31,6 @@
- <% if @protocol.in_module? %>
-
<% if step.description.blank? %>
<%= t("protocols.steps.no_description") %>
@@ -126,8 +124,6 @@
<% end %>
-
- <% end %>
diff --git a/app/views/users/mailer/notification.html.erb b/app/views/users/mailer/notification.html.erb
new file mode 100644
index 000000000..f8ad84d77
--- /dev/null
+++ b/app/views/users/mailer/notification.html.erb
@@ -0,0 +1,9 @@
+Hello <%= @user.name %>!
+
+<%= I18n.t("notifications.email_title") %>
+
+Type: <%= I18n.t("notifications.types.#{@notification.type_of}") %>
+
+<%= @notification.title.html_safe %>
+
+<%= @notification.message.html_safe %>
diff --git a/app/views/users/settings/preferences.html.erb b/app/views/users/settings/preferences.html.erb
index 9540ebfad..e5bfe2b6b 100644
--- a/app/views/users/settings/preferences.html.erb
+++ b/app/views/users/settings/preferences.html.erb
@@ -63,6 +63,13 @@
<%= f.label t('notifications.form.system_message'), class: 'visible-sm visible-xs' %>
<%= check_box_tag :system_message_notification %>
+
+
<%= t('notifications.form.email_settings') %>
+ <%= f.label t('notifications.form.recent_notification'), class: 'visible-sm visible-xs'%>
+ <%= check_box_tag :recent_notification_email, @user.recent_notification_email %>
+ <%= f.label t('notifications.form.assignments'), class: 'visible-sm visible-xs' %>
+ <%= check_box_tag :assignments_notification_email, @user.assignments_notification_email %>
+
<% end %>
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index 11ad88bd0..f1a105b3b 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -58,7 +58,6 @@ Rails.application.config.assets.precompile += %w(jszip.min.js)
Rails.application.config.assets.precompile += %w(assets.js)
Rails.application.config.assets.precompile += %w(comments.js)
Rails.application.config.assets.precompile += %w(projects/show.js)
-Rails.application.config.assets.precompile += %w(projects/introdutory_popup.js)
Rails.application.config.assets.precompile += %w(notifications.js)
# Libraries needed for Handsontable formulas
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 133d7f6e0..411592bcf 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1498,29 +1498,21 @@ en:
archive_project_html: "Archive Demo project - qPCR by clicking on the down arrow . You can always access the Archive by clicking the icon on the top right side of the Dashboard and restore any item you have archived."
goodbye_message: "To repeat the tutorial, go to your Settings and open My preferences tab. Click on the Repeat tutorial button and watch the tutorial as many times needed."
- introductory:
- popup-title: "Release notes - sciNote version 1.3"
- sentence_one_html: "For this sciNote version we focused on improving Tables in Protocol steps and Results. Tables now support basic math operations (addition, subtraction, multiplication, division) just like Excel spreadsheets do. "
- sentence_two_html: "You can also use the functions listed below:
- SUM that adds together a supplied set of numbers and returns the sum of these values;
- AVERAGE that returns the arithmetic mean of a list of supplied numbers;
- MEDIAN that returns the statistical median (the middle value) of a list of supplied numbers;
- MAX that returns the largest value from a supplied set of numeric values;
- MIN that returns the smallest value from a supplied set of numeric values;
- SLOPE that calculates the slope of the linear regression line through a supplied set of x- and y- values;
- IF that tests a supplied condition and returns one result if the condition evaluates to TRUE, and another result if the condition evaluates to FALSE;
- SQRT that calculates the positive square root of a supplied number;
- POWER that calculates a given number, raised to a supplied power;
- LOG that calculates the logarithm of a given number, to a supplied base;
- LN that calculates the natural logarithm of a given number;
- LOG10 that calculates the base 10 logarithm of a given number.
Some other improvements have been made in sciNote as well. Let’s take a look at them."
- sentence_three_html: "Extended length of text field
You can now write names of Experiments and Protocol steps with limitation of 255 characters and descriptions with 10,000 characters."
- sentence_four_html: "Redesigned Navigation pane
We have added the connecting line of Experiments in the Navigation pane, where you can expand or collapse the Experiments and get a better overview."
- sentence_five_html: "Reorder of Comments and Messages
The Comments section in Protocols steps and Results has been moved bellow the description (it’s not in a separate tab any more). Also the order of Messages in the Project and Task cards has been changed. The most recent Messages are now seen at the end of the correspondence."
- sentence_six_html: "Deleting Results
You can now delete Results. First you archive them, then you go to the Archive and delete them. This way you have a \"safety net\" against deleting Results by accident."
- sentence_seven_html: "Info tab
In the upper right corner of the Dashboard you can now access the Info button, where you can find links to support on how to use sciNote features (e.g., Tutorials, FAQ) or how to change your current sciNote Plan (e.g., Professional support and customization, Plans). In case you have some other questions or suggestions, click on the Contact us link."
- confim: "OK, got it"
-
notifications:
title: "Notifications"
form:
assignments: "Assignments notifications"
recent_notification: "Change notifications"
- system_message: "Update notifications"
- filter: "Filter"
+ email_settings: "E-mail notifications"
show_all: "Show all notifications"
show_more: "Show more notifications"
no_notifications: "No notifications."
no_recent: "No recent notifications."
-
+ types:
+ assignment: "Assignment"
+ recent_changes: "Recent changes"
+ system_message: "sciNote system message"
+ email_title: "You've received a sciNote notification!"
# This section contains general words that can be used in any parts of
# application.
diff --git a/db/migrate/20161006065203_add_email_notification_settings_to_user.rb b/db/migrate/20161006065203_add_email_notification_settings_to_user.rb
new file mode 100644
index 000000000..31f9e8bad
--- /dev/null
+++ b/db/migrate/20161006065203_add_email_notification_settings_to_user.rb
@@ -0,0 +1,14 @@
+class AddEmailNotificationSettingsToUser < ActiveRecord::Migration
+ def up
+ add_column :users, :assignments_notification_email, :boolean, default: false
+ add_column :users, :recent_notification_email, :boolean, default: false
+
+ User.update_all(assignments_notification_email: false,
+ recent_notification_email: false)
+ end
+
+ def down
+ remove_column :users, :assignments_notification_email
+ remove_column :users, :recent_notification_email
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4a0b0e388..02905cd39 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20161004074754) do
+ActiveRecord::Schema.define(version: 20161006065203) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -628,20 +628,20 @@ ActiveRecord::Schema.define(version: 20161004074754) do
add_index "user_projects", ["user_id"], name: "index_user_projects_on_user_id", using: :btree
create_table "users", force: :cascade do |t|
- t.string "full_name", null: false
- t.string "initials", null: false
- t.string "email", default: "", null: false
- t.string "encrypted_password", default: "", null: false
+ t.string "full_name", null: false
+ t.string "initials", null: false
+ t.string "email", default: "", null: false
+ t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
- t.integer "sign_in_count", default: 0, null: false
+ t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
@@ -650,7 +650,7 @@ ActiveRecord::Schema.define(version: 20161004074754) do
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
- t.string "time_zone", default: "UTC"
+ t.string "time_zone", default: "UTC"
t.string "invitation_token"
t.datetime "invitation_created_at"
t.datetime "invitation_sent_at"
@@ -658,10 +658,12 @@ ActiveRecord::Schema.define(version: 20161004074754) do
t.integer "invitation_limit"
t.integer "invited_by_id"
t.string "invited_by_type"
- t.integer "invitations_count", default: 0
- t.integer "tutorial_status", default: 0, null: false
- t.boolean "assignments_notification", default: true
- t.boolean "recent_notification", default: true
+ t.integer "invitations_count", default: 0
+ t.integer "tutorial_status", default: 0, null: false
+ t.boolean "assignments_notification", default: true
+ t.boolean "recent_notification", default: true
+ t.boolean "assignments_notification_email", default: false
+ t.boolean "recent_notification_email", default: false
end
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
diff --git a/public/images/introductory_popup/image1a.png b/public/images/introductory_popup/image1a.png
deleted file mode 100644
index 30abdba18..000000000
Binary files a/public/images/introductory_popup/image1a.png and /dev/null differ
diff --git a/public/images/introductory_popup/image2a.png b/public/images/introductory_popup/image2a.png
deleted file mode 100644
index 9ecf63324..000000000
Binary files a/public/images/introductory_popup/image2a.png and /dev/null differ
diff --git a/public/images/introductory_popup/image3a.png b/public/images/introductory_popup/image3a.png
deleted file mode 100644
index 4a2f0c44e..000000000
Binary files a/public/images/introductory_popup/image3a.png and /dev/null differ
diff --git a/public/images/introductory_popup/image4a.png b/public/images/introductory_popup/image4a.png
deleted file mode 100644
index 446678a47..000000000
Binary files a/public/images/introductory_popup/image4a.png and /dev/null differ