diff --git a/Gemfile b/Gemfile index 451be9a..cf42b47 100644 --- a/Gemfile +++ b/Gemfile @@ -36,6 +36,7 @@ gem 'sitemap_generator' gem 'activerecord-session_store' gem 'paypal-express', '0.7.1' gem 'sass-json-vars' +gem 'premailer-rails' gem 'delayed_job_active_record' gem 'redcarpet' diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index a1eb38f..c1071a6 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -1,4 +1,17 @@ (function() { + window.onerror = function(message, url, lineNumber) { + //save error and send to server for example. + var request = new XMLHttpRequest(); + request.open('POST', '/js_error', true); + request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); + request.send( + 'message=' + encodeURI(message) + + '&url=' + encodeURI(url) + + '&lineNumber=' + encodeURI(lineNumber) + + '&location=' + encodeURI(window.location.href) + ); + return false; + }; Array.prototype.forEach.call(document.querySelectorAll('.number-field,.email-field,.text-field'), function(field) { var input = field.querySelector('input'); var positionLabel = function(input) { @@ -9,6 +22,55 @@ input.addEventListener('blur', function(event) { field.classList.remove('focused'); }); input.addEventListener('focus', function(event) { field.classList.add('focused'); }); }); + var body = document.querySelector('body'); + var primaryContent = document.getElementById('primary-content'); + var overlay = document.getElementById('content-overlay'); + primaryContent.addEventListener('keydown', function(event) { + event.stopPropagation(); + return false; + //if (body.classList.contains('has-overlay')) { + // return false; + //} + }); + document.addEventListener('focus', function(event) { + if (overlay.querySelector('.dlg.open') && !overlay.querySelector('.dlg.open :focus')) { + overlay.querySelector('.dlg.open').focus(); + } + }, true); + function openDlg(dlg, link) { + body.setAttribute('style', 'width: ' + body.clientWidth + 'px'); + dlg.querySelector('.message').innerHTML = decodeURI(link.dataset.confirmation); + dlg.querySelector('.confirm').setAttribute('href', link.getAttribute('href')); + primaryContent.setAttribute('aria-hidden', 'true'); + document.getElementById('overlay').onclick = + dlg.querySelector('.delete').onclick = function() { closeDlg(dlg); }; + body.classList.add('has-overlay'); + dlg.removeAttribute('aria-hidden'); + dlg.setAttribute('role', 'alertdialog'); + dlg.setAttribute('tabindex', '0'); + dlg.focus(); + setTimeout(function() { dlg.classList.add('open'); }, 100); + } + function closeDlg(dlg) { + setTimeout(function() { + body.classList.remove('has-overlay'); + body.removeAttribute('style'); + }, 250); + primaryContent.removeAttribute('aria-hidden'); + dlg.setAttribute('aria-hidden', 'true'); + dlg.removeAttribute('tabindex'); + dlg.classList.remove('open'); + dlg.removeAttribute('role'); + } + var confirmationDlg = document.getElementById('confirmation-dlg'); + Array.prototype.forEach.call(document.querySelectorAll('a[data-confirmation]'), function(link) { + link.addEventListener('click', function(event) { + event.preventDefault(); + openDlg(confirmationDlg, link); + return false; + }); + }); + var errorField = document.querySelector('.input-field.has-error input, .input-field.has-error textarea'); if (errorField) { errorField.focus(); @@ -16,7 +78,10 @@ var htmlNode = document.documentElement; document.addEventListener('keydown', function(event) { - if (htmlNode.dataset.input != 'kb' && ["input", "select", "option"].includes("input".toLowerCase())) { + if (htmlNode.dataset.input != 'kb' && + !["input", "textarea", "select", "option"].includes(event.target.nodeName.toLowerCase()) && + !event.target.attributes.contenteditable) { + console.log() htmlNode.setAttribute('data-input', 'kb'); } }); diff --git a/app/assets/stylesheets/_application.scss b/app/assets/stylesheets/_application.scss index c49fe9d..42fcf87 100644 --- a/app/assets/stylesheets/_application.scss +++ b/app/assets/stylesheets/_application.scss @@ -90,6 +90,7 @@ table { button, .button { @include button; + vertical-align: top; #main &[type="submit"] { background-color: $colour-5; @@ -111,6 +112,7 @@ button, background-color: $colour-5; } + &.delete, #main &.delete { background-color: $colour-4; } @@ -1280,6 +1282,97 @@ $header-tilt: 8deg; } } +body { + #primary-content { + @include _(transition, 'filter 250ms ease-in-out, -webkit-filter 250ms ease-in-out'); + } + + &.has-overlay { + overflow: hidden; + + #primary-content { + -webkit-filter: blur(5px); + @include _(filter, blur(5px)); + } + + #overlay { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + cursor: pointer; + z-index: 1000; + } + } +} + +#content-overlay { + display: none; + + body.has-overlay & { + display: block; + } + + .dlg { + @include before { + content: ''; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: rgba($black, 0); + @include _(transition, background-color 250ms ease-in-out); + } + + &.open { + @include before { + background-color: rgba($black, 0.5); + } + + .dlg-content { + @include _(transform, rotateZ(0deg)); + } + } + } + + .dlg-content { + position: fixed; + right: 0; + bottom: 0; + left: 0; + max-width: 50rem; + margin: auto; + z-index: 1001; + background-color: $white; + text-align: center; + @include _(transition, transform 500ms ease-in-out); + @include _(transform, rotateX(-90deg)); + @include _(transform-origin, center 250%); + } + + .title { + padding: 0.5em; + background-color: $colour-5; + color: $white; + @include _(text-stroke, 1px rgba(0, 0, 0, 0.25)); + } + + .dlg-inner { + padding: 0 2em 2em; + } + + button, .button { + margin: 0 0.25em; + } + + .message { + font-size: 1.5em; + margin-bottom: 2em; + } +} + @include keyframes(fade-out) { to { @include _(opacity, 0.25); @@ -1296,33 +1389,6 @@ html :focus { outline: 0; } -html[data-input="kb"] { - :focus, - input[type="submit"]:focus, - .check-box-field input:focus + label, - .radio-button-field input:focus + label, - .select-field select:focus, - .workshop-link:focus .title, - #main-nav .nav a:focus .title { - outline: 0.25rem solid rgba($colour-2, 0.5); - outline-offset: 0.2rem; - z-index: 1; - } - - #main-nav .logo:focus { - outline-offset: -0.2em; - } - - /*input:focus, - textarea:focus, - select:focus, - .textarea {*/ - .workshop-link:focus, - #main-nav .nav a:focus { - outline: none; - } -} - @mixin header-colour($page, $colour) { body.#{$page} { #header-title { @@ -2259,6 +2325,29 @@ html[data-lingua-franca-example="html"] { } @include breakpoint(medium) { + html[data-input="kb"] { + :focus, + input[type="submit"]:focus, + .check-box-field input:focus + label, + .radio-button-field input:focus + label, + .select-field select:focus, + .workshop-link:focus .title, + #main-nav .nav a:focus .title { + outline: 0.25rem solid rgba($colour-2, 0.5); + outline-offset: 0.2rem; + z-index: 1; + } + + #main-nav .logo:focus { + outline-offset: -0.2em; + } + + .workshop-link:focus, + #main-nav .nav a:focus { + outline: none; + } + } + body { padding-bottom: 0; } diff --git a/app/assets/stylesheets/user-mailer.scss b/app/assets/stylesheets/user-mailer.scss index 2fc4871..4f313a2 100644 --- a/app/assets/stylesheets/user-mailer.scss +++ b/app/assets/stylesheets/user-mailer.scss @@ -4,7 +4,7 @@ body { width: 100% !important; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; - margin: 0; + margin: 1em; padding: 0; } @@ -69,12 +69,25 @@ a { } p { - margin: 1em; color: $black !important; +} + +p, blockquote { + margin: 1em; font-size: 1.5em; line-height: 1.3333em; } +blockquote { + font-style: italic; + margin-bottom: 2em; + color: #666 !important; + border: 0.1em solid #CCC; + padding: 1em; + border-style: none none solid solid; + background-color: #F8F8F8; +} + h1, h2, h3, h4, h5, h6 { color: $black !important; @@ -117,6 +130,48 @@ table#ecxbb_full_width { } } +.error-report { + width: 100%; + max-width: 100%; + border: 0.15em solid #CCC; + background-color: #EEE; + font-size: 1.25em; + margin-bottom: 2em; + + th { + background-color: #CCC; + } + + td, th { + padding: 0.25em 0.5em; + + &:last-child { + border-left: 0.15em solid #CCC; + min-width: 40em; + } + } + + td:last-child { + font-family: monospace; + word-break: break-word; + background-color: #FFF; + font-size: 0.75em; + } +} + +code { + color: #C33; + font-size: 0.9em; +} + +pre { + font-size: 1.5em; + padding: 1em; + background-color: #333; + color: antiquewhite; + word-break: break-word; +} + .diff, .ecxdiff { margin: 1em 0 5em 1em; overflow: auto; diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c427c21..b4c7817 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -8,7 +8,7 @@ class ApplicationController < LinguaFrancaApplicationController # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. - protect_from_forgery with: :exception, :except => [:do_confirm] + protect_from_forgery with: :exception, :except => [:do_confirm, :js_error] before_filter :capture_page_info @@ -100,7 +100,6 @@ class ApplicationController < LinguaFrancaApplicationController end def error_500(exception) - @page_title = 'page_titles.500.An_Error_Occurred' @main_title = 'error.500.title' params[:_original_action] = params[:action] @@ -108,6 +107,26 @@ class ApplicationController < LinguaFrancaApplicationController render 'application/500', status: 500 end + def js_error + # send and email if this is production + report = "A JavaScript error has occurred on #{params[:location]}" + if params[:location] == params[:url] + report += " on line #{params[:lineNumber]}" + else + report += " in #{params[:url]}:#{params[:lineNumber]}" + end + UserMailer.error_report( + "A JavaScript error has occurred", + report, + params[:message], + nil, + request, + params, + current_user, + ).deliver_now if Rails.env.preview? || Rails.env.production? + render json: {} + end + rescue_from ActiveRecord::RecordNotFound do |exception| do_404 end @@ -143,6 +162,7 @@ class ApplicationController < LinguaFrancaApplicationController # show the error page error_500 exception + raise exception end def generate_confirmation(user, url, expiry = nil) @@ -276,7 +296,7 @@ class ApplicationController < LinguaFrancaApplicationController # send and email if this is production UserMailer.error_report( "A missing translation found in #{Rails.env}", - "A translation for #{key} in #{locale.to_s} was found. The text that was rendered to the user was \"#{str || 'nil'}\".", + "

A translation for #{key} in #{locale.to_s} was found. The text that was rendered to the user was:

#{str || 'nil'}
", exception.to_s, exception, request, diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb index 977cbed..6f787b5 100644 --- a/app/controllers/conferences_controller.rb +++ b/app/controllers/conferences_controller.rb @@ -1002,7 +1002,7 @@ class ConferencesController < ApplicationController return redirect_to workshops_url end - return redirect_to edit_workshop_url(@this_conference.slug, @workshop.id) + return redirect_to view_workshop_url(@this_conference.slug, @workshop.id) end render 'workshops/delete' diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 58dde4f..0775905 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -161,15 +161,12 @@ module ApplicationHelper classes << 'fixed-banner' if is_header_fixed? if params[:controller] - if params[:controller] == 'application' - if params[:action] - classes << params[:action] - end - else + classes << params[:action] + unless params[:controller] == 'application' classes << params[:controller] if params[:action] - classes << params[:controller] + '-' + params[:action] + classes << "#{params[:controller]}-#{params[:action]}" end end end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index f52e6d0..6dcaef5 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -49,7 +49,7 @@ class UserMailer < ActionMailer::Base def email_confirmation(confirmation) @confirmation = confirmation @subject = _'email.subject.confirm_email','Please confirm your email address' - mail to: confirmation.user.email, subject: @subject + mail to: confirmation.user.named_email, subject: @subject end def registration_confirmation(registration) @@ -66,7 +66,7 @@ class UserMailer < ActionMailer::Base "Thank you for registering for #{@conference.title}", :vars => {:conference_title => @conference.title} ) - mail to: @user.email, subject: @subject + mail to: @user.named_email, subject: @subject end def broadcast(host, subject, content, user, conference) @@ -74,8 +74,8 @@ class UserMailer < ActionMailer::Base @content = content @banner = nil#(@host || 'http://localhost/') + (conference ? (conference.poster.preview.url || '') : image_url('logo.png')) @subject = "[#{conference ? conference.title : 'Bike!Bike!'}] #{subject}" - if user && user.email - email = user.email + if user && user.named_email + email = user.named_email mail to: email, subject: @subject end end @@ -85,14 +85,15 @@ class UserMailer < ActionMailer::Base @requester = requester addresses = [] @workshop.active_facilitators.each do |f| - addresses << f.email + addresses << f.named_email end + addresses << 'michael.allen.godwin@gmail.com' @message = message @conference = Conference.find(@workshop.conference_id) @subject = _('email.subject.workshop_facilitator_request', "Request to facilitate #{@workshop.title} from #{@requester.name}", :vars => {:workshop_title => @workshop.title, :requester_name => @requester.firstname}) - mail to: addresses, from: @requester.email, subject: @subject + mail to: addresses, reply_to: addresses + [@requester.named_email], subject: @subject end def workshop_facilitator_request_approved(workshop, user) @@ -102,7 +103,7 @@ class UserMailer < ActionMailer::Base @subject = (_'email.subject.workshop_request_approved', "You have been added as a facilitator of #{@workshop.title}", :vars => {:workshop_title => @workshop.title}) - mail to: user.email, subject: @subject + mail to: user.named_email, subject: @subject end def workshop_facilitator_request_denied(workshop, user) @@ -112,7 +113,7 @@ class UserMailer < ActionMailer::Base @subject = (_'email.subject.workshop_request_denied', "Your request to facilitate #{@workshop.title} has been denied", :vars => {:workshop_title => @workshop.title}) - mail to: user.email, subject: @subject + mail to: user.named_email, subject: @subject end def workshop_translated(workshop, data, locale, user, translator) @@ -135,7 +136,7 @@ class UserMailer < ActionMailer::Base @wrapper_id = :full_width - mail to: user.email, subject: @subject + mail to: user.named_email, subject: @subject end def workshop_original_content_changed(workshop, data, user, translator) @@ -156,7 +157,7 @@ class UserMailer < ActionMailer::Base @wrapper_id = :full_width - mail to: user.email, subject: @subject + mail to: user.named_email, subject: @subject end def error_report(subject, message, report, exception, request, params, user) diff --git a/app/models/user.rb b/app/models/user.rb index 74de4be..a87964b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -35,4 +35,10 @@ class User < ActiveRecord::Base firstname || username || email end + def named_email + name = firstname || username + return email unless name + return "#{name} <#{email}>" + end + end diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 4bd197f..78fda54 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -17,26 +17,36 @@ = yield :head %body{ class: page_style } - = render 'shared/navbar' - %main#main - - if content_for?(:side_bar) - %nav#side-bar - = yield :side_bar - -# - flash.each do |key, msg| - -# = content_tag :div, msg, :id => key - %header#banner=yield :banner - - if @submenu - =row do - = columns(medium: 12) do - %nav.sub-menu - - @submenu.each do |href,key| - %a{href: href, class: request.fullpath.start_with?(href) ? 'current' : nil}=_"menu.submenu.#{key}" - - if has_content? - #content=yield - - else - = yield - #footer - %footer= render 'shared/footer' + #primary-content + = render 'shared/navbar' + %main#main + - if content_for?(:side_bar) + %nav#side-bar + = yield :side_bar + -# - flash.each do |key, msg| + -# = content_tag :div, msg, :id => key + %header#banner=yield :banner + - if @submenu + =row do + = columns(medium: 12) do + %nav.sub-menu + - @submenu.each do |href,key| + %a{href: href, class: request.fullpath.start_with?(href) ? 'current' : nil}=_"menu.submenu.#{key}" + - if has_content? + #content=yield + - else + = yield + #footer + %footer= render 'shared/footer' + #content-overlay + #overlay + .dlg#confirmation-dlg + .dlg-content + %h2.title=_'modals.confirm' + .dlg-inner + %p.message='' + %a.button.confirm=_'modals.yes_button' + %button.delete=_'modals.no_button' = yield :footer_scripts if content_for?(:footer_scripts) - add_inline_script :main diff --git a/app/views/layouts/user_mailer.html.haml b/app/views/layouts/user_mailer.html.haml index 3e002f5..e871d8a 100644 --- a/app/views/layouts/user_mailer.html.haml +++ b/app/views/layouts/user_mailer.html.haml @@ -4,7 +4,7 @@ %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/ %meta{:content => "width=device-width, initial-scale=1.0", :name => "viewport"}/ %title=@subject - %style{type: 'text/css'}=Rails.application.assets.find_asset("user-mailer.css").to_s + = stylesheet_link_tag 'user-mailer' %body %table{:border => "0", :cellpadding => "0", :cellspacing => "0", id: @wrapper_id.present? ? "bb_#{@wrapper_id.to_s}" : 'backgroundTable'} %tr @@ -20,7 +20,7 @@ %td{colspan: 2, style: 'height: 16px'}=' '.html_safe %tr %td{style: 'width: 50%; text-align: left'} - %img.image_fix{:src => (@host + image_url('bblogo-paypal'))} + %img.image_fix{:src => ((Rails.env.development? || Rails.env.test? ? 'https://preview-en.bikebike.org/' : @host) + image_url('bblogo-paypal'))} %td{style: 'width: 50%; text-align: left'} %a{href: @host}="© Bike!Bike! #{Date.today.year}".html_safe %tr diff --git a/app/views/user_mailer/activation_needed_email.text.haml b/app/views/user_mailer/activation_needed_email.text.haml deleted file mode 100644 index 4c6b3ac..0000000 --- a/app/views/user_mailer/activation_needed_email.text.haml +++ /dev/null @@ -1,3 +0,0 @@ -UserMailer#activation_needed_email - -= @greeting + ", find me in app/views/user_mailer/activation_needed_email.text.haml" diff --git a/app/views/user_mailer/activation_success_email.text.haml b/app/views/user_mailer/activation_success_email.text.haml deleted file mode 100644 index c766aa7..0000000 --- a/app/views/user_mailer/activation_success_email.text.haml +++ /dev/null @@ -1,3 +0,0 @@ -UserMailer#activation_success_email - -= @greeting + ", find me in app/views/user_mailer/activation_success_email.text.haml" diff --git a/app/views/user_mailer/broadcast.text.haml b/app/views/user_mailer/broadcast.text.haml deleted file mode 100644 index f63bf85..0000000 --- a/app/views/user_mailer/broadcast.text.haml +++ /dev/null @@ -1 +0,0 @@ -=@content \ No newline at end of file diff --git a/app/views/user_mailer/conference_registration_confirmed_email.text.haml b/app/views/user_mailer/conference_registration_confirmed_email.text.haml deleted file mode 100644 index 50ac6ae..0000000 --- a/app/views/user_mailer/conference_registration_confirmed_email.text.haml +++ /dev/null @@ -1,9 +0,0 @@ -=_'register.email.registration_confirmed.thank_you',"Hi #{@data[:user][:username]}, thank you for completing your registration. We'll see you at Bike!Bike!" - -=_'register.email.registration_confirmed.please_pay',"If you have not already done so, we ask that you pay the registration donation as soon as you can. At your convenience please visit the link below." - -= @confirmation_url - -=_'register.email.registration_confirmed.info',"We'll have housing, loaner bikes, and food arranged for your arrival. If you have any other questions or concerns, please email bikebike2014columbus@gmail.com." - -=_'register.email.registration_confirmed.contact',"For urgent/emergency matters, you can reach our Outreach Coordinator, Reda, at 503-984-9191 or Jason at 614-364-3636." diff --git a/app/views/user_mailer/conference_registration_email.text.haml b/app/views/user_mailer/conference_registration_email.text.haml deleted file mode 100644 index 2b95786..0000000 --- a/app/views/user_mailer/conference_registration_email.text.haml +++ /dev/null @@ -1 +0,0 @@ -=_('register.email.registration.please_confirm',"Hi #{@data[:user][:username]}, please confirm your registration for #{@conference.title}", vars: {:username => @data[:user][:username]}) + ": #{@confirmation_url}" \ No newline at end of file diff --git a/app/views/user_mailer/email_confirmation.text.haml b/app/views/user_mailer/email_confirmation.text.haml deleted file mode 100644 index acc5ef1..0000000 --- a/app/views/user_mailer/email_confirmation.text.haml +++ /dev/null @@ -1,3 +0,0 @@ -=_'email.confirmation.paragraph.please_confirm','Hello! To gain access to registration and other features of Bike!Bike!, please confirm your email address by clicking on following link:' -='' -="#{@host}/confirm/#{@confirmation.token}" diff --git a/app/views/user_mailer/error_report.html.haml b/app/views/user_mailer/error_report.html.haml index 56ab09b..8c2ca0f 100644 --- a/app/views/user_mailer/error_report.html.haml +++ b/app/views/user_mailer/error_report.html.haml @@ -1,12 +1,12 @@ -%p=@message if @message.present? -%p=@report +%p=@message.html_safe if @message.present? +%pre=@report - if @exception.present? && @exception.respond_to?(:backtrace) %h1 Backtrace %pre=@exception.backtrace.join("\n") %h1 Details -%table +%table.error-report %tr %th Key %th Value @@ -30,7 +30,7 @@ %td=@request.original_url %h1 Params -%table +%table.error-report %tr %th Key %th Value @@ -40,7 +40,7 @@ %td=value.to_s %h1 Request Environment -%table +%table.error-report %tr %th Key %th Value diff --git a/app/views/user_mailer/registration_confirmation.text.haml b/app/views/user_mailer/registration_confirmation.text.haml deleted file mode 100644 index 5fc9e02..0000000 --- a/app/views/user_mailer/registration_confirmation.text.haml +++ /dev/null @@ -1,8 +0,0 @@ -=_'email.general.paragraph.thank_you', "Thank you #{@user.firstname},", :vars => {:name => @user.firstname} - -- if @conference.registration_status.to_sym == :pre - =_'email.general.paragraph.pre_registered', "You have successfully pre-registered for #{@conference.title}. We will let you know when registration is fully open and if there is any important news about the conference that you should know about. We encourage you to create or volunteer to facilitate workshops soon. You can do that, or change your registration details at any time by clicking on the pre-register link again.", :vars => {:conference_title => @conference.title} -- else - =_'email.registration.paragraph.confirmed', :vars => {:conference_title => @conference.title} - - =_'email.general.paragraph.see_you', :vars => {:conference_location => @conference.location.city} \ No newline at end of file diff --git a/app/views/user_mailer/workshop_facilitator_request.html.haml b/app/views/user_mailer/workshop_facilitator_request.html.haml index 4b16e80..b39766b 100644 --- a/app/views/user_mailer/workshop_facilitator_request.html.haml +++ b/app/views/user_mailer/workshop_facilitator_request.html.haml @@ -1,6 +1,6 @@ -%p=_'email.workshop.paragraph.request_message',"Below is a message from #{@requester.firstname}:", :vars => {:workshop_title => @workshop.title, :user_name => @requester.firstname} +%p=_'email.workshop.paragraph.request_message',"Below is a message from #{@requester.firstname}:", :vars => {:workshop_title => @workshop.title, :user_name => @requester.name} -%blockquote=markdown @message +%blockquote=CGI::escapeHTML(@message || '').gsub(/\n/, '
').html_safe %p =_'email.workshop.paragraph.request_instructions',"You can approve or deny this request on your workshop page: " diff --git a/app/views/user_mailer/workshop_facilitator_request.text.haml b/app/views/user_mailer/workshop_facilitator_request.text.haml deleted file mode 100644 index 37243e8..0000000 --- a/app/views/user_mailer/workshop_facilitator_request.text.haml +++ /dev/null @@ -1,11 +0,0 @@ -=_'email.workshop.paragraph.request_message',"Below is a message from #{@requester.firstname}:", :vars => {:workshop_title => @workshop.title, :user_name => @requester.firstname} - -=' ------------------------- ' -=@message -=' ------------------------- ' - -=_'email.workshop.paragraph.request_instructions',"You can approve or deny this request on your workshop page: " - -=@host + view_workshop_path(@conference.slug, @workshop.id) - -=_'email.workshop.paragraph.request_reply_instructions',"You can also reply directly to this email to ask follow-up questions." diff --git a/app/views/user_mailer/workshop_facilitator_request_approved.text.haml b/app/views/user_mailer/workshop_facilitator_request_approved.text.haml deleted file mode 100644 index f04fc49..0000000 --- a/app/views/user_mailer/workshop_facilitator_request_approved.text.haml +++ /dev/null @@ -1,3 +0,0 @@ -=_'email.workshop.paragraph.request_approved',"Your request to become a facilitator of #{@workshop.title} has been approved and you may now edit the workshop.", :vars => {:workshop_title => @workshop.title} - -=@host + view_workshop_path(@conference.slug, @workshop.id) diff --git a/app/views/user_mailer/workshop_facilitator_request_denied.text.haml b/app/views/user_mailer/workshop_facilitator_request_denied.text.haml deleted file mode 100644 index 16641b9..0000000 --- a/app/views/user_mailer/workshop_facilitator_request_denied.text.haml +++ /dev/null @@ -1,3 +0,0 @@ -=_'email.workshop.paragraph.request_denied',"Your request to become a facilitator of #{@workshop.title} has been denied. If you think this was in error, you may contact the current facilitators by making another request to facilitate.", :vars => {:workshop_title => @workshop.title} - -=@host + view_workshop_path(@conference.slug, @workshop.id) diff --git a/app/views/user_mailer/workshop_original_content_changed.text.haml b/app/views/user_mailer/workshop_original_content_changed.text.haml deleted file mode 100644 index a43449b..0000000 --- a/app/views/user_mailer/workshop_original_content_changed.text.haml +++ /dev/null @@ -1,25 +0,0 @@ -=_('email.translations.paragraph.workshop_translated', "#{@translator.name} has modified the #{@locale_name} translation for #{@workshop.title}.", vars: {user_name: @translator.firstname, language: @locale_name, workshop_title: @workshop.title}) - - -- @data.each do |field, values| - =(_!'** ') + (_"forms.labels.generic.#{field.to_s}") - =(_!' - ') + (_'email.translations.headings.new_value') - =(_!' ------------------------------ ') - =_!values[:new] - =(_!' ------------------------------ ') - - - =(_!' - ') + (_'email.translations.headings.old_value') - =(_!' ------------------------------ ') - =_!values[:old] - =(_!' ------------------------------ ') - - - =(_!' - ') + (_'email.translations.headings.diff') - =(_!' ------------------------------ ') - =(_!values[:diff][:text]) - =(_!' ------------------------------ ') - - -=_'email.workshop.paragraph.view_workshop',"You can view the workshop here: " -= @host + view_workshop_path(@workshop.conference.slug, @workshop.id) diff --git a/app/views/user_mailer/workshop_translated.text.haml b/app/views/user_mailer/workshop_translated.text.haml deleted file mode 100644 index 34e2ff8..0000000 --- a/app/views/user_mailer/workshop_translated.text.haml +++ /dev/null @@ -1,25 +0,0 @@ -=_('email.translations.paragraph.workshop_translated', "#{@translator.firstname} has modified the #{@locale_name} translation for #{@workshop.title}.", vars: {user_name: @translator.firstname, language: @locale_name, workshop_title: @workshop.title}) - - -- @data.each do |field, values| - =(_!'** ') + (_"forms.labels.generic.#{field.to_s}") - =(_!' - ') + (_'email.translations.headings.new_value') - =(_!' ------------------------------ ') - =_!values[:new] - =(_!' ------------------------------ ') - - - =(_!' - ') + (_'email.translations.headings.old_value') - =(_!' ------------------------------ ') - =_!values[:old] - =(_!' ------------------------------ ') - - - =(_!' - ') + (_'email.translations.headings.diff') - =(_!' ------------------------------ ') - =(_!values[:diff][:text]) - =(_!' ------------------------------ ') - - -=_'email.workshop.paragraph.view_workshop',"You can view the workshop here: " -= view_workshop_path(@workshop.conference.slug, @workshop.id) diff --git a/app/views/workshops/_show.html.haml b/app/views/workshops/_show.html.haml index adf6d1d..5c833f0 100644 --- a/app/views/workshops/_show.html.haml +++ b/app/views/workshops/_show.html.haml @@ -32,11 +32,11 @@ =(link_to (_'actions.workshops.Approve'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'approve'), :class => [:button, :modify]) =(link_to (_'actions.workshops.Deny'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'deny'), :class => [:button, :delete]) - elsif workshop.can_remove?(current_user, u) - =(link_to (_'actions.workshops.Make_Owner'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'switch_ownership'), :class => [:button, :modify]) unless f.role.to_sym == :creator || !workshop.creator?(current_user) - =(link_to (_'actions.workshops.Remove'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'remove'), :class => [:button, :delete]) + =(link_to (_'actions.workshops.Make_Owner'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'switch_ownership'), :class => [:button, :modify], data: {confirmation: CGI::escapeHTML(_'modals.workshops.facilitators.confirm_transfer_ownership', vars: { user_name: u.name})}) unless f.role.to_sym == :creator || !workshop.creator?(current_user) + =(link_to (_'actions.workshops.Remove'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'remove'), :class => [:button, :delete], data: {confirmation: CGI::escapeHTML(_'modals.workshops.facilitators.confirm_remove', vars: { user_name: u.name})}) - if f.user_id == current_user.id && workshop.requested_collaborator?(current_user) .details - =(link_to (_'actions.workshops.Remove'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'remove'), :class => [:button, :delete]) + =(link_to (_'actions.workshops.Remove'), approve_facilitate_workshop_request_path(workshop.conference.slug, workshop.id, f.user_id, 'remove'), :class => [:button, :delete], data: {confirmation: CGI::escapeHTML(_'modals.workshops.facilitators.confirm_remove_self')}) - unless preview.present? =(link_to (_'actions.workshops.Facilitate'), facilitate_workshop_path(workshop.conference.slug, workshop.id), :class => [:button, workshop.needs_facilitators ? :accented : :subdued]) unless workshop.facilitator?(current_user) - if is_facilitator diff --git a/app/views/workshops/delete.html.haml b/app/views/workshops/delete.html.haml index d6fa439..bb02d50 100644 --- a/app/views/workshops/delete.html.haml +++ b/app/views/workshops/delete.html.haml @@ -3,6 +3,7 @@ = row do = columns(medium: 12) do %h2=_'articles.workshops.headings.Delete_Workshop',"Are you sure you want to delete the workshop: #{@workshop.title}?", :vars => {:title => "#{@workshop.title}".html_safe} + %p=_'articles.workshops.paragraphs.Delete_Workshop' = form_tag delete_workshop_path(@this_conference.slug, @workshop.id), class: 'composition' do .actions = button_tag :confirm, :value => :confirm, :class => :delete diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index bfcc311..0ea88dd 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -8,4 +8,4 @@ Rails.application.config.assets.version = '1.0' # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. -Rails.application.config.assets.precompile += %w( map.js pen.js editor.js markdown.js main.js favicon.ico ) +Rails.application.config.assets.precompile += %w( user-mailer.css map.js pen.js editor.js markdown.js main.js favicon.ico ) diff --git a/config/locales/en.yml b/config/locales/en.yml index 5b5766f..1436518 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -5259,6 +5259,15 @@ en: conference: actions: Register: Register + modals: + confirm: Please Confirm + yes_button: 'Yes' + no_button: 'No' + workshops: + facilitators: + confirm_remove: Are you sure you would like to remove %{user_name} as a facilitator of this workshop? + confirm_remove_self: Are you sure you would like to remove yourself as a facilitator of this workshop? + confirm_transfer_ownership: By transferring ownership, you will lose administrative capabilities such as deletion and approving new facilitators. Are you sure you want to transfer ownership to %{user_name}? articles: policy: headings: @@ -5512,6 +5521,7 @@ en: theme: Which of the themes below best match your workshop? This will help hosts to avoid scheduling conflicts. Select other if none of the options match in any way. + Delete_Workshop: Deleting a workshop cannot be undone, are you sure that you want to proceed? new_workshop: 'Workshops in the past have tended to fit into a few broad categories: structural/organizational (how to start a shop, how to register a non-profit, consensus decision making, etc,) mechanical (how to weld two tandems to @@ -5744,6 +5754,7 @@ en: paragraph: workshop_translated: '%{user_name} has modified the %{language} translation for %{workshop_title}.' workshop_original_content_changed: '%{user_name} has modified the original content for %{workshop_title}. Translations may need to be updated.' + workshop: paragraph: request_approved: You have been added as a facilitator of %{workshop_title}. request_denied: Your request to become a facilitator of %{workshop_title} diff --git a/config/routes.rb b/config/routes.rb index 2f35a17..8d5fb17 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -50,6 +50,7 @@ BikeBike::Application.routes.draw do get '/oauth/:provider' => 'oauths#oauth', :as => :auth_at_provider post '/translator-request' => 'application#translator_request', :as => :translator_request + post '/js_error' => 'application#js_error' get '/error_403' => 'application#do_403' get '/error_404' => 'application#error_404' get '/error_500' => 'application#error_500'