diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index e9eeffae..219ded23 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -126,6 +126,15 @@ $(function() { $(this).children('input[type="submit"]').attr('disabled', 'disabled'); }); + // The autocomplete attribute is used for both autocompletion and storing + // for passwords, it's nice to store it when editing one's own profile, + // but never autocomplete. Only implemented for passwords. + $('input[type="password"][autocomplete="off"][data-store="on"]').each(function() { + $(this).on('change', function() { + $(this).removeAttr('autocomplete'); + }); + }); + // Use bootstrap datepicker for dateinput $('.datepicker').datepicker({format: 'yyyy-mm-dd', language: I18n.locale}); diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9c77fe48..dcc0f298 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -4,7 +4,7 @@ class ApplicationController < ActionController::Base helper_method :available_locales protect_from_forgery - before_filter :select_foodcoop, :authenticate, :store_controller, :items_per_page, :set_redirect_to + before_filter :select_foodcoop, :authenticate, :store_controller, :items_per_page after_filter :remove_controller @@ -80,8 +80,8 @@ class ApplicationController < ActionController::Base # checks if the current_user is member of given group. # if fails the user will redirected to startpage - def authenticate_membership_or_admin - @group = Group.find(params[:id]) + def authenticate_membership_or_admin(group_id = params[:id]) + @group = Group.find(group_id) unless @group.member?(@current_user) or @current_user.role_admin? redirect_to root_path, alert: I18n.t('application.controller.error_members_only') end @@ -128,18 +128,6 @@ class ApplicationController < ActionController::Base end end - def set_redirect_to - session[:redirect_to] = params[:redirect_to] if params[:redirect_to] - end - - def back_or_default_path(default = root_path) - if session[:redirect_to].present? - default = session[:redirect_to] - session[:redirect_to] = nil - end - default - end - # Always stay in foodcoop url scope def default_url_options(options = {}) {foodcoop: FoodsoftConfig.scope} diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index f301156a..553e4398 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -1,20 +1,20 @@ class InvitesController < ApplicationController - before_filter :authenticate_membership_or_admin, :only => [:new] - #TODO: authorize also for create action. + before_filter :authenticate_membership_or_admin_for_invites def new @invite = Invite.new(:user => @current_user, :group => @group) end def create + authenticate_membership_or_admin params[:invite][:group_id] @invite = Invite.new(params[:invite]) if @invite.save Mailer.invite(@invite).deliver respond_to do |format| format.html do - redirect_to back_or_default_path, notice: I18n.t('invites.success') + redirect_to root_path, notice: I18n.t('invites.success') end format.js { render layout: false } end @@ -23,4 +23,10 @@ class InvitesController < ApplicationController render action: :new end end + + protected + + def authenticate_membership_or_admin_for_invites + authenticate_membership_or_admin((params[:invite][:group_id] rescue params[:id])) + end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index ef516a67..52ec9256 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -203,5 +203,5 @@ module ApplicationHelper :title => I18n.t('helpers.application.write_message') end end - + end diff --git a/app/helpers/shared_helper.rb b/app/helpers/shared_helper.rb new file mode 100644 index 00000000..befd61c4 --- /dev/null +++ b/app/helpers/shared_helper.rb @@ -0,0 +1,13 @@ +module SharedHelper + + # provide input_html for password autocompletion + def autocomplete_flag_to_password_html(password_autocomplete) + case password_autocomplete + when true then {autocomplete: 'on'} + when false then {autocomplete: 'off'} + when 'store-only' then {autocomplete: 'off', data: {store: 'on'}} + else {} + end + end + +end diff --git a/app/models/user.rb b/app/models/user.rb index 19ea452c..f04d2714 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -73,8 +73,15 @@ class User < ActiveRecord::Base # search by (nick)name def self.natural_search(q) - # we always use both nick and name, to make sure a user is found - where("CONCAT(first_name, CONCAT(' ', last_name)) LIKE :q OR nick LIKE :q", q: "%#{q}%") + q = q.strip + users = User.arel_table + # full string as nickname + match_nick = users[:nick].matches("%#{q}%") + # or each word matches either first or last name + match_name = q.split.map do |a| + users[:first_name].matches("%#{a}%").or users[:last_name].matches("%#{a}%") + end.reduce(:and) + User.where(match_nick.or match_name) end def locale diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index eeb70abf..4fb28547 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -1,5 +1,5 @@ = simple_form_for([:admin, @user]) do |f| - = render 'shared/user_form_fields', f: f + = render 'shared/user_form_fields', f: f, password_autocomplete: false .form-actions = f.submit = link_to t('ui.or_cancel'), :back diff --git a/app/views/finance/invoices/_form.html.haml b/app/views/finance/invoices/_form.html.haml index 8f8ce228..d2c6d144 100644 --- a/app/views/finance/invoices/_form.html.haml +++ b/app/views/finance/invoices/_form.html.haml @@ -5,7 +5,7 @@ - if @invoice.delivery %p= t('finance.invoices.linked', what_link: link_to(t('finance.invoices.linked_delivery'), [@invoice.supplier,@invoice.delivery])).html_safe - if @invoice.order - %p= t('finance.invoices.linked', what_link: link_to(t('finance.invoices.linked_order'), @invoice.order)).html_safe + %p= t('finance.invoices.linked', what_link: link_to(t('finance.invoices.linked_order'), new_finance_order_path(order_id: @invoice.order.id))).html_safe = f.association :supplier, hint: false = f.input :number diff --git a/app/views/home/profile.html.haml b/app/views/home/profile.html.haml index 0b0364a1..31fa9ee9 100644 --- a/app/views/home/profile.html.haml +++ b/app/views/home/profile.html.haml @@ -6,7 +6,7 @@ = h(t('.user.title', user: show_user)) %small= t '.user.since', when: distance_of_time_in_words(Time.now, @current_user.created_on) = simple_form_for(@current_user, :url => update_profile_path) do |f| - = render :partial => 'shared/user_form_fields', :locals => {:f => f} + = render :partial => 'shared/user_form_fields', :locals => {:f => f, :password_autocomplete => 'store-only'} .form-actions = submit_tag t('ui.save'), class: 'btn' .span5 diff --git a/app/views/messages/new.haml b/app/views/messages/new.haml index 5d3e0c89..577eef16 100644 --- a/app/views/messages/new.haml +++ b/app/views/messages/new.haml @@ -25,15 +25,15 @@ - if FoodsoftConfig[:mailing_list].blank? = f.input :sent_to_all, :as => :boolean - else - %b= t '.list.desc', list: mail_to(FoodsoftConfig[:mailing_list]) + %b= t('.list.desc', list: mail_to(FoodsoftConfig[:mailing_list])).html_safe %br/ %small{:style => "color:grey"} = t '.list.subscribe_msg' %br/ - if FoodsoftConfig[:mailing_list_subscribe].blank? - = t '.list.subscribe', link: link_to(t('.list.wiki'), wiki_page_path('MailingListe')) + = t('.list.subscribe', link: link_to(t('.list.wiki'), wiki_page_path('MailingListe'))).html_safe - else - = t '.list.mail', email: mail_to(FoodsoftConfig[:mailing_list_subscribe]) + = t('.list.mail', email: mail_to(FoodsoftConfig[:mailing_list_subscribe])).html_safe #recipients = f.input :recipient_tokens, :input_html => { 'data-pre' => User.find_all_by_id(@message.recipients_ids).map(&:token_attributes).to_json } diff --git a/app/views/shared/_user_form_fields.html.haml b/app/views/shared/_user_form_fields.html.haml index 56701874..a0afffd6 100644 --- a/app/views/shared/_user_form_fields.html.haml +++ b/app/views/shared/_user_form_fields.html.haml @@ -1,12 +1,16 @@ -- if FoodsoftConfig[:use_nick] - -# use_nil option to user model validators break required mark - = f.input :nick, required: true = f.input :first_name = f.input :last_name = f.input :email +-# need :required because :use_nil option on user model validators break the required mark += f.input :nick, required: true if FoodsoftConfig[:use_nick] +-# You can control password autocompletion by passing `password_autocomplete` to this partial. +-# Possible values: undefined/nil, true, false, 'store-only' +-# see also https://github.com/foodcoops/foodsoft/wiki/Form-autocompletion +- password_autocomplete = nil unless defined?(:password_autocomplete) +- password_html = autocomplete_flag_to_password_html(password_autocomplete) += f.input :password, :required => f.object.new_record?, input_html: password_html += f.input :password_confirmation, :required => f.object.new_record?, input_html: password_html = f.input :phone -= f.input :password, :required => f.object.new_record? -= f.input :password_confirmation = f.simple_fields_for :settings_attributes do |s| = s.simple_fields_for :profile, defaults: { inline_label: true } do |profile| diff --git a/config/locales/de.yml b/config/locales/de.yml index 146a827f..112e6f7a 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -27,6 +27,11 @@ de: article_category: description: Beschreibung name: Name + article_price: + deposit: Pfand + price: Nettopreis + tax: MwSt + unit_quantity: Gebindegröße delivery: delivered_on: Lieferdatum note: Notiz @@ -1167,6 +1172,7 @@ de: title_list: Seiten-Liste body: title_toc: Inhalt + wikicloth_exception: "Entschuldigung, ein Fehler ist beim Anzeigen der Wikiseite aufgetreten: »%{msg}«. Bearbeiten der Seite kann helfen, diesen Fehler zu beseitigen." create: notice: Seite wurde angelegt cshow: @@ -1360,6 +1366,8 @@ de: title: Lagerartikel kopieren create: notice: Neuer Lagerartikel »%{name}« gespeichert. + derive: + title: Lagerartikel aus Vorlage erstellen destroy: notice: Artikel %{name} gelöscht. edit: diff --git a/config/locales/en.yml b/config/locales/en.yml index 089f78fe..230aab46 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -27,6 +27,11 @@ en: article_category: description: Description name: Name + article_price: + deposit: Deposit + price: Price (net) + tax: VAT + unit_quantity: Unit quantity delivery: delivered_on: Delivery date note: Note @@ -1178,6 +1183,7 @@ en: title_list: List of pages body: title_toc: Content + wikicloth_exception: "I'm sorry to report that an error occured when interpreting the wiki page: %{msg}. Please try to fix it, and save the page again." create: notice: Page was created cshow: @@ -1371,6 +1377,8 @@ en: title: Copy stock article create: notice: New stock article "%{name}" was created. + derive: + title: Add stock article using template destroy: notice: Article %{name} was deleted. edit: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index eb40b75b..e73a720b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -27,6 +27,11 @@ fr: article_category: description: Description name: Nom + article_price: + deposit: Consigne + price: Prix net + tax: TVA + unit_quantity: Unités par lot delivery: delivered_on: Date de réapprovisionnement note: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 65c63213..e11dfebc 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -27,6 +27,11 @@ nl: article_category: description: Omschrijving name: Naam + article_price: + deposit: Statiegeld + price: Netto prijs + tax: BTW + unit_quantity: Groothandelseenheid delivery: delivered_on: Leverdatum note: Notitie diff --git a/lib/foodsoft_wiki/app/helpers/pages_helper.rb b/lib/foodsoft_wiki/app/helpers/pages_helper.rb index 552791f3..cfc8ea7b 100644 --- a/lib/foodsoft_wiki/app/helpers/pages_helper.rb +++ b/lib/foodsoft_wiki/app/helpers/pages_helper.rb @@ -4,6 +4,8 @@ module PagesHelper def wikified_body(body, title = nil) render_opts = {:locale => I18n.locale} # workaround for wikicloth 0.8.0 https://github.com/nricciar/wikicloth/pull/59 WikiCloth.new({:data => body+"\n", :link_handler => Wikilink.new, :params => {:referer => title}}).to_html(render_opts).html_safe + rescue => e + "#{t('.wikicloth_exception', :msg => e)}".html_safe # try the following with line breaks: === one === == two == = three = end def link_to_wikipage(page, text = nil)