Fixed login, new_password and invitation views.
This commit is contained in:
parent
f20ae890dd
commit
1708df3f6c
18 changed files with 200 additions and 122 deletions
|
@ -10,8 +10,10 @@ class InvitesController < ApplicationController
|
||||||
def create
|
def create
|
||||||
@invite = Invite.new(params[:invite])
|
@invite = Invite.new(params[:invite])
|
||||||
if @invite.save
|
if @invite.save
|
||||||
|
Mailer.delay.invite(FoodsoftConfig.scope, @invite.id)
|
||||||
redirect_to back_or_default_path, notice: "Benutzerin wurde erfolgreich eingeladen."
|
redirect_to back_or_default_path, notice: "Benutzerin wurde erfolgreich eingeladen."
|
||||||
else
|
else
|
||||||
|
logger.debug "[debug] errors: #{@invite.errors.messages}"
|
||||||
render action: :new
|
render action: :new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
class LoginController < ApplicationController
|
class LoginController < ApplicationController
|
||||||
skip_before_filter :authenticate # no authentication since this is the login page
|
skip_before_filter :authenticate # no authentication since this is the login page
|
||||||
before_filter :validate_token, :only => [:password, :update_password]
|
before_filter :validate_token, :only => [:new_password, :update_password]
|
||||||
|
|
||||||
# Display the form to enter an email address requesting a token to set a new password.
|
# Display the form to enter an email address requesting a token to set a new password.
|
||||||
def forgot_password
|
def forgot_password
|
||||||
|
@ -14,7 +14,7 @@ class LoginController < ApplicationController
|
||||||
user.reset_password_token = user.new_random_password(16)
|
user.reset_password_token = user.new_random_password(16)
|
||||||
user.reset_password_expires = Time.now.advance(:days => 2)
|
user.reset_password_expires = Time.now.advance(:days => 2)
|
||||||
if user.save
|
if user.save
|
||||||
email = Mailer.reset_password(user).deliver
|
Mailer.delay.reset_password(FoodsoftConfig.scope, user.id)
|
||||||
logger.debug("Sent password reset email to #{user.email}.")
|
logger.debug("Sent password reset email to #{user.email}.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -23,7 +23,7 @@ class LoginController < ApplicationController
|
||||||
|
|
||||||
# Set a new password with a token from the password reminder email.
|
# Set a new password with a token from the password reminder email.
|
||||||
# Called with params :id => User.id and :token => User.reset_password_token to specify a new password.
|
# Called with params :id => User.id and :token => User.reset_password_token to specify a new password.
|
||||||
def password
|
def new_password
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets a new password.
|
# Sets a new password.
|
||||||
|
@ -36,13 +36,13 @@ class LoginController < ApplicationController
|
||||||
@user.save
|
@user.save
|
||||||
redirect_to login_url, :notice => "Dein Passwort wurde aktualisiert. Du kannst Dich jetzt anmelden."
|
redirect_to login_url, :notice => "Dein Passwort wurde aktualisiert. Du kannst Dich jetzt anmelden."
|
||||||
else
|
else
|
||||||
render :action => 'password'
|
render :new_password
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Invited users.
|
# For invited users.
|
||||||
def invite
|
def accept_invitation
|
||||||
@invite = Invite.find_by_token(params[:id])
|
@invite = Invite.find_by_token(params[:token])
|
||||||
if (@invite.nil? || @invite.expires_at < Time.now)
|
if (@invite.nil? || @invite.expires_at < Time.now)
|
||||||
flash[:error] = "Deine Einladung ist nicht (mehr) gültig."
|
flash[:error] = "Deine Einladung ist nicht (mehr) gültig."
|
||||||
render :action => 'login'
|
render :action => 'login'
|
||||||
|
@ -71,7 +71,7 @@ class LoginController < ApplicationController
|
||||||
def validate_token
|
def validate_token
|
||||||
@user = User.find_by_id_and_reset_password_token(params[:id], params[:token])
|
@user = User.find_by_id_and_reset_password_token(params[:id], params[:token])
|
||||||
if (@user.nil? || @user.reset_password_expires < Time.now)
|
if (@user.nil? || @user.reset_password_expires < Time.now)
|
||||||
flash[:error] = "Ungültiger oder abgelaufener Token. Bitte versuch es erneut."
|
flash.now.error = "Ungültiger oder abgelaufener Token. Bitte versuch es erneut."
|
||||||
render :action => 'forgot_password'
|
render :action => 'forgot_password'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -130,4 +130,17 @@ module ApplicationHelper
|
||||||
:target => "_blank"
|
:target => "_blank"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bootstrap_flash
|
||||||
|
flash_messages = []
|
||||||
|
flash.each do |type, message|
|
||||||
|
type = :success if type == :notice
|
||||||
|
type = :error if type == :alert
|
||||||
|
text = content_tag(:div,
|
||||||
|
content_tag(:button, raw("×"), :class => "close", "data-dismiss" => "alert") +
|
||||||
|
message, :class => "alert fade in alert-#{type}")
|
||||||
|
flash_messages << text if message
|
||||||
|
end
|
||||||
|
flash_messages.join("\n").html_safe
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,20 +19,22 @@ class Mailer < ActionMailer::Base
|
||||||
|
|
||||||
# Sends an email with instructions on how to reset the password.
|
# Sends an email with instructions on how to reset the password.
|
||||||
# Assumes user.setResetPasswordToken has been successfully called already.
|
# Assumes user.setResetPasswordToken has been successfully called already.
|
||||||
def reset_password(user)
|
def reset_password(foodcoop, user_id)
|
||||||
@user = user
|
set_foodcoop_scope(foodcoop)
|
||||||
@link = url_for(:controller => "login", :action => "password", :id => user.id, :token => user.reset_password_token)
|
@user = User.find(user_id)
|
||||||
|
@link = new_password_url(id: @user.id, token: @user.reset_password_token)
|
||||||
|
|
||||||
mail :to => user.email,
|
mail :to => @user.email,
|
||||||
:subject => "[#{FoodsoftConfig[:name]}] Neues Passwort für/ New password for #{user.nick}"
|
:subject => "[#{FoodsoftConfig[:name]}] Neues Passwort für/ New password for #{@user.nick}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends an invite email.
|
# Sends an invite email.
|
||||||
def invite(invite)
|
def invite(foodcoop, invite_id)
|
||||||
@invite = invite
|
set_foodcoop_scope(foodcoop)
|
||||||
@link = url_for(:controller => "login", :action => "invite", :id => invite.token)
|
@invite = Invite.find(invite_id)
|
||||||
|
@link = accept_invitation_url(token: @invite.token)
|
||||||
|
|
||||||
mail :to => invite.email,
|
mail :to => @invite.email,
|
||||||
:subject => "Einladung in die Foodcoop #{FoodsoftConfig[:name]} - Invitation to the Foodcoop"
|
:subject => "Einladung in die Foodcoop #{FoodsoftConfig[:name]} - Invitation to the Foodcoop"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -81,5 +83,11 @@ class Mailer < ActionMailer::Base
|
||||||
mail :to => user.email,
|
mail :to => user.email,
|
||||||
:subject => "[#{FoodsoftConfig[:name]}] \"#{task.name}\" braucht noch Leute!"
|
:subject => "[#{FoodsoftConfig[:name]}] \"#{task.name}\" braucht noch Leute!"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_foodcoop_scope(foodcoop)
|
||||||
|
ActionMailer::Base.default_url_options[:foodcoop] = foodcoop
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,20 +12,16 @@ class Invite < ActiveRecord::Base
|
||||||
validates_presence_of :expires_at
|
validates_presence_of :expires_at
|
||||||
validate :email_not_already_registered, :on => :create
|
validate :email_not_already_registered, :on => :create
|
||||||
|
|
||||||
|
before_validation :set_token_and_expires_at
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# Before validation, set token and expires_at.
|
# Before validation, set token and expires_at.
|
||||||
def before_validation
|
def set_token_and_expires_at
|
||||||
self.token = Digest::SHA1.hexdigest(Time.now.to_s + rand(100).to_s)
|
self.token = Digest::SHA1.hexdigest(Time.now.to_s + rand(100).to_s)
|
||||||
self.expires_at = Time.now.advance(:days => 7)
|
self.expires_at = Time.now.advance(:days => 7)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends an email to the invited user.
|
|
||||||
def after_create
|
|
||||||
Mailer.invite(self).deliver
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Custom validation: check that email does not already belong to a registered user.
|
# Custom validation: check that email does not already belong to a registered user.
|
||||||
|
|
29
app/views/layouts/_header.html.haml
Normal file
29
app/views/layouts/_header.html.haml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
!!! 5
|
||||||
|
%html(lang="en")
|
||||||
|
%head
|
||||||
|
%meta(charset="utf-8")
|
||||||
|
%meta(http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1")
|
||||||
|
%meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||||
|
%title= content_for?(:title) ? yield(:title) : "Foodsoft"
|
||||||
|
= csrf_meta_tags
|
||||||
|
/ Le HTML5 shim, for IE6-8 support of HTML elements
|
||||||
|
/[if lt IE 9]
|
||||||
|
= javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js"
|
||||||
|
= stylesheet_link_tag "application", :media => "all"
|
||||||
|
%link(href="images/apple-touch-icon-144x144.png" rel="apple-touch-icon-precomposed" sizes="144x144")
|
||||||
|
%link(href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon-precomposed" sizes="114x114")
|
||||||
|
%link(href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72")
|
||||||
|
%link(href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed")
|
||||||
|
//%link(href="images/favicon.ico" rel="shortcut icon")
|
||||||
|
|
||||||
|
= yield(:head)
|
||||||
|
|
||||||
|
%body
|
||||||
|
= yield
|
||||||
|
|
||||||
|
/
|
||||||
|
Javascripts
|
||||||
|
\==================================================
|
||||||
|
/ Placed at the end of the document so the pages load faster
|
||||||
|
= javascript_include_tag "application"
|
||||||
|
= yield(:javascript)
|
|
@ -1,58 +1,35 @@
|
||||||
!!! 5
|
= render layout: 'layouts/header' do
|
||||||
%html(lang="en")
|
.row-fluid
|
||||||
%head
|
|
||||||
%meta(charset="utf-8")
|
|
||||||
%meta(http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1")
|
|
||||||
%meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
|
||||||
%title= content_for?(:title) ? yield(:title) : "Foodsoft"
|
|
||||||
= csrf_meta_tags
|
|
||||||
/ Le HTML5 shim, for IE6-8 support of HTML elements
|
|
||||||
/[if lt IE 9]
|
|
||||||
= javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js"
|
|
||||||
= stylesheet_link_tag "application", :media => "all"
|
|
||||||
%link(href="images/apple-touch-icon-144x144.png" rel="apple-touch-icon-precomposed" sizes="144x144")
|
|
||||||
%link(href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon-precomposed" sizes="114x114")
|
|
||||||
%link(href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72")
|
|
||||||
%link(href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed")
|
|
||||||
%link(href="images/favicon.ico" rel="shortcut icon")
|
|
||||||
|
|
||||||
|
.navbar.navbar-fixed-top
|
||||||
|
.navbar-inner
|
||||||
|
.container-fluid
|
||||||
|
%a.btn.btn-navbar(data-target=".nav-collapse" data-toggle="collapse")
|
||||||
|
%span.icon-bar
|
||||||
|
%span.icon-bar
|
||||||
|
%span.icon-bar
|
||||||
|
= link_to 'Foodsoft', root_path(anchor: ''), class: 'brand'
|
||||||
|
.container.nav-collapse
|
||||||
|
= render_navigation expand_all: true, renderer: :bootstrap
|
||||||
|
|
||||||
%body
|
.container-fluid
|
||||||
.row-fluid
|
.row-fluid
|
||||||
|
- if content_for?(:sidebar)
|
||||||
.navbar.navbar-fixed-top
|
.span2
|
||||||
.navbar-inner
|
= yield(:sidebar)
|
||||||
.container-fluid
|
.span10
|
||||||
%a.btn.btn-navbar(data-target=".nav-collapse" data-toggle="collapse")
|
= bootstrap_flash
|
||||||
%span.icon-bar
|
|
||||||
%span.icon-bar
|
|
||||||
%span.icon-bar
|
|
||||||
= link_to 'Foodsoft', root_path(anchor: ''), class: 'brand'
|
|
||||||
.container.nav-collapse
|
|
||||||
= render_navigation expand_all: true, renderer: :bootstrap
|
|
||||||
|
|
||||||
.container-fluid
|
|
||||||
.row-fluid
|
|
||||||
- if content_for?(:sidebar)
|
|
||||||
.span2
|
|
||||||
= yield(:sidebar)
|
|
||||||
.span10
|
|
||||||
- if show_title?
|
|
||||||
.page-header
|
|
||||||
%h1= yield(:title)
|
|
||||||
= yield
|
|
||||||
- else
|
|
||||||
- if show_title?
|
- if show_title?
|
||||||
.page-header
|
.page-header
|
||||||
%h1= yield(:title)
|
%h1= yield(:title)
|
||||||
= yield
|
= yield
|
||||||
|
- else
|
||||||
%footer
|
= bootstrap_flash
|
||||||
%p
|
- if show_title?
|
||||||
Foodsoft, open source software to manage a non-profit food coop.
|
.page-header
|
||||||
|
%h1= yield(:title)
|
||||||
|
= yield
|
||||||
|
|
||||||
/
|
%footer
|
||||||
Javascripts
|
%p
|
||||||
\==================================================
|
Foodsoft, open source software to manage a non-profit food coop.
|
||||||
/ Placed at the end of the document so the pages load faster
|
|
||||||
= javascript_include_tag "application"
|
|
||||||
|
|
|
@ -1,19 +1,13 @@
|
||||||
!!!
|
= render layout: 'layouts/header' do
|
||||||
%html
|
.container
|
||||||
%head
|
.row
|
||||||
%meta{"http-equiv" => "content-type", :content => "text/html;charset=UTF-8"}
|
.span6.offset3
|
||||||
%title= "FoodSoft - " + (yield(:title) or controller.controller_name)
|
= bootstrap_flash
|
||||||
= stylesheet_link_tag 'application'
|
- if show_title?
|
||||||
= javascript_include_tag 'application'
|
.page-header
|
||||||
= csrf_meta_tags
|
%h1= yield(:title)
|
||||||
= yield(:head)
|
= yield
|
||||||
%body
|
|
||||||
#login
|
%footer
|
||||||
- if yield(:title)
|
%p
|
||||||
%h1= yield(:title)
|
Foodsoft, open source software to manage a non-profit food coop.
|
||||||
- flash.each do |name, msg|
|
|
||||||
= content_tag :div, msg, :class => "flash #{name}"
|
|
||||||
= yield
|
|
||||||
#meta
|
|
||||||
Foodcoop
|
|
||||||
= link_to_if FoodsoftConfig[:homepage], FoodsoftConfig[:name], FoodsoftConfig[:homepage]
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
- content_for :javascript do
|
||||||
|
:javascript
|
||||||
|
$('user_nick').focus();
|
||||||
|
|
||||||
- title "Einladung in die #{FoodsoftConfig[:name]}"
|
- title "Einladung in die #{FoodsoftConfig[:name]}"
|
||||||
%p
|
%p
|
||||||
Du bist eingeladen worden als Mitglied der Gruppe
|
Du bist eingeladen worden als Mitglied der Gruppe
|
||||||
|
@ -12,7 +16,8 @@
|
||||||
Gründen, weitergeben. Du kannst auch entscheiden, wieviel deiner persönlichen
|
Gründen, weitergeben. Du kannst auch entscheiden, wieviel deiner persönlichen
|
||||||
Daten für alle einsehbar sein sollen. 'Alle' bedeutet hier alle Foodcoop-Mitglieder.
|
Daten für alle einsehbar sein sollen. 'Alle' bedeutet hier alle Foodcoop-Mitglieder.
|
||||||
Die Administratoren haben aber jederzeit Zugriff auf deine Daten.
|
Die Administratoren haben aber jederzeit Zugriff auf deine Daten.
|
||||||
= simple_form_for @user, url: {action: 'invite'} do |form|
|
= simple_form_for @user, url: accept_invitation_path do |form|
|
||||||
= render partial: 'shared/user_form_fields', locals: {f: form}
|
= render partial: 'shared/user_form_fields', locals: {f: form}
|
||||||
= submit_tag "Absenden"
|
.form-actions
|
||||||
= javascript_tag("$('user_nick').focus()")
|
= submit_tag "Foodsoft Account erstellen", class: 'btn'
|
||||||
|
|
|
@ -7,5 +7,6 @@
|
||||||
|
|
||||||
= simple_form_for User.new, url: {action: 'reset_password'} do |form|
|
= simple_form_for User.new, url: {action: 'reset_password'} do |form|
|
||||||
= form.input :email
|
= form.input :email
|
||||||
= form.submit "Neues Passwort anfordern"
|
.form-actions
|
||||||
= link_to "Abbrechen", :back
|
= form.submit "Neues Passwort anfordern", class: 'btn'
|
||||||
|
= link_to "oder abbrechen", :back
|
|
@ -3,4 +3,5 @@
|
||||||
= simple_form_for @user, :url => {:action => 'update_password', :id => @user.id, :token => @user.reset_password_token} do |form|
|
= simple_form_for @user, :url => {:action => 'update_password', :id => @user.id, :token => @user.reset_password_token} do |form|
|
||||||
= form.input :password
|
= form.input :password
|
||||||
= form.input :password_confirmation
|
= form.input :password_confirmation
|
||||||
= form.submit
|
.form-actions
|
||||||
|
= form.submit 'Neues Passwort speichern', class: 'btn'
|
|
@ -1,7 +1,7 @@
|
||||||
Hallo <%= @user.nick %>,
|
Hallo <%= @user.nick %>,
|
||||||
|
|
||||||
du (oder jemand anderes) hat auf der FoodSoft-Website ein neues Passwort angefordert.
|
du (oder jemand anderes) hat auf der FoodSoft-Website ein neues Passwort angefordert.
|
||||||
Um ein neues Passwort einzugeben, gehe zu: <%= @link %>
|
Um ein neues Passwort einzugeben, gehe zu: <%= raw @link %>
|
||||||
Dieser Link kann nur einmal aufgerufen werden und läuft am <%= I18n.l @user.reset_password_expires %> ab.
|
Dieser Link kann nur einmal aufgerufen werden und läuft am <%= I18n.l @user.reset_password_expires %> ab.
|
||||||
Wenn du das Passwort nicht ändern möchtest oder diese Email nicht ausgelöst hast, brauchst du nichts zu tun. Dein bisheriges Passwort wurde nicht geändert.
|
Wenn du das Passwort nicht ändern möchtest oder diese Email nicht ausgelöst hast, brauchst du nichts zu tun. Dein bisheriges Passwort wurde nicht geändert.
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ Grüße sendet die Foodsoft! :)
|
||||||
|
|
||||||
Hi <%= @user.nick %>,
|
Hi <%= @user.nick %>,
|
||||||
you have (or someone else has) requested a new password.
|
you have (or someone else has) requested a new password.
|
||||||
In order to choose a new password follow this link: <%= @link %>
|
In order to choose a new password follow this link: <%= raw @link %>
|
||||||
This link works only once and expires on <%= I18n.l @user.reset_password_expires, locale: :en %>.
|
This link works only once and expires on <%= I18n.l @user.reset_password_expires, locale: :en %>.
|
||||||
If you don't want to change your password, just ignore this message. Your password hasn't been changed yet.
|
If you don't want to change your password, just ignore this message. Your password hasn't been changed yet.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
- content_for :head do
|
- content_for :javascript do
|
||||||
:javascript
|
:javascript
|
||||||
$(function() {
|
$(function() {
|
||||||
$('#nick').focus();
|
$('#nick').focus();
|
||||||
|
@ -7,21 +7,23 @@
|
||||||
- title "FoodSoft login"
|
- title "FoodSoft login"
|
||||||
|
|
||||||
%noscript
|
%noscript
|
||||||
#javascript-warn.error(style="font-size:1.5em")
|
.alert.alert-error
|
||||||
Achtung, Cookies und Javascript müssen aktiviert sein!
|
Achtung, Cookies und Javascript müssen aktiviert sein!
|
||||||
= link_to "NoScript", "http://noscript.net/"
|
= link_to "NoScript", "http://noscript.net/"
|
||||||
bitte abschalten.
|
bitte abschalten.
|
||||||
|
|
||||||
#login-form.edit_form(style="width:25em")
|
= form_tag sessions_path, class: 'form-horizontal' do
|
||||||
= form_tag sessions_path do
|
.control-group
|
||||||
%p
|
%label(for='nick' class='control-label') Benutzerin
|
||||||
%label{:for => 'user'} Benutzerin
|
.controls
|
||||||
%br/
|
|
||||||
= text_field_tag 'nick'
|
= text_field_tag 'nick'
|
||||||
%p
|
|
||||||
%label{:for => 'password'} Passwort
|
.control-group
|
||||||
%br/
|
%label(for='password' class='control-label') Passwort
|
||||||
|
.controls
|
||||||
= password_field_tag 'password'
|
= password_field_tag 'password'
|
||||||
= submit_tag "Anmelden"
|
|
||||||
|
|
.control-group
|
||||||
= link_to "Passwort vergessen?", :controller => 'login', :action => 'forgot_password'
|
.controls
|
||||||
|
= submit_tag "Anmelden", class: 'btn'
|
||||||
|
= link_to "Passwort vergessen?", :controller => 'login', :action => 'forgot_password'
|
|
@ -3,11 +3,12 @@
|
||||||
= f.input :last_name
|
= f.input :last_name
|
||||||
= f.input :email
|
= f.input :email
|
||||||
= f.input :phone
|
= f.input :phone
|
||||||
= f.input :password, :required => @user.new_record?
|
= f.input :password, :required => f.object.new_record?
|
||||||
= f.input :password_confirmation
|
= f.input :password_confirmation
|
||||||
- for setting in User::setting_keys.keys
|
.control-group
|
||||||
.input.boolean
|
.controls
|
||||||
= check_box_tag "user[setting_attributes][#{setting}]",
|
- for setting in User::setting_keys.keys
|
||||||
'1', @user.settings[setting] == '1' || @user.settings_default(setting),
|
%label.checkbox{:for => "user[setting_attributes][#{setting}]"}
|
||||||
:class => 'boolean'
|
= check_box_tag "user[setting_attributes][#{setting}]", '1',
|
||||||
%label.boolean{:for => "user[setting_attributes][#{setting}]"}= h User::setting_keys[setting]
|
f.object.settings[setting] == '1' || f.object.settings_default(setting)
|
||||||
|
= User::setting_keys[setting]
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
Delayed::Worker.max_attempts = 5
|
Delayed::Worker.max_attempts = 5
|
||||||
Delayed::Worker.delay_jobs = !Rails.env.test?
|
Delayed::Worker.delay_jobs = !Rails.env.test?
|
||||||
|
Delayed::Worker.destroy_failed_jobs = false
|
||||||
|
|
|
@ -98,7 +98,7 @@ SimpleForm.setup do |config|
|
||||||
config.label_class = 'control-label'
|
config.label_class = 'control-label'
|
||||||
|
|
||||||
# You can define the class to use on all forms. Default is simple_form.
|
# You can define the class to use on all forms. Default is simple_form.
|
||||||
# config.form_class = :simple_form
|
config.form_class = 'form-horizontal'
|
||||||
|
|
||||||
# You can define which elements should obtain additional classes
|
# You can define which elements should obtain additional classes
|
||||||
# config.generate_additional_classes_for = [:wrapper, :label, :input]
|
# config.generate_additional_classes_for = [:wrapper, :label, :input]
|
||||||
|
@ -108,7 +108,7 @@ SimpleForm.setup do |config|
|
||||||
|
|
||||||
# Tell browsers whether to use default HTML5 validations (novalidate option).
|
# Tell browsers whether to use default HTML5 validations (novalidate option).
|
||||||
# Default is enabled.
|
# Default is enabled.
|
||||||
config.browser_validations = false
|
config.browser_validations = true
|
||||||
|
|
||||||
# Collection of methods to detect if a file type was given.
|
# Collection of methods to detect if a file type was given.
|
||||||
# config.file_methods = [ :mounted_as, :file?, :public_filename ]
|
# config.file_methods = [ :mounted_as, :file?, :public_filename ]
|
||||||
|
|
45
config/initializers/simple_form_bootstrap.rb
Normal file
45
config/initializers/simple_form_bootstrap.rb
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# Use this setup block to configure all options available in SimpleForm.
|
||||||
|
SimpleForm.setup do |config|
|
||||||
|
config.wrappers :bootstrap, :tag => 'div', :class => 'control-group', :error_class => 'error' do |b|
|
||||||
|
b.use :html5
|
||||||
|
b.use :placeholder
|
||||||
|
b.use :label
|
||||||
|
b.wrapper :tag => 'div', :class => 'controls' do |ba|
|
||||||
|
ba.use :input
|
||||||
|
ba.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
|
||||||
|
ba.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
config.wrappers :prepend, :tag => 'div', :class => "control-group", :error_class => 'error' do |b|
|
||||||
|
b.use :html5
|
||||||
|
b.use :placeholder
|
||||||
|
b.use :label
|
||||||
|
b.wrapper :tag => 'div', :class => 'controls' do |input|
|
||||||
|
input.wrapper :tag => 'div', :class => 'input-prepend' do |prepend|
|
||||||
|
prepend.use :input
|
||||||
|
end
|
||||||
|
input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' }
|
||||||
|
input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
config.wrappers :append, :tag => 'div', :class => "control-group", :error_class => 'error' do |b|
|
||||||
|
b.use :html5
|
||||||
|
b.use :placeholder
|
||||||
|
b.use :label
|
||||||
|
b.wrapper :tag => 'div', :class => 'controls' do |input|
|
||||||
|
input.wrapper :tag => 'div', :class => 'input-append' do |append|
|
||||||
|
append.use :input
|
||||||
|
end
|
||||||
|
input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' }
|
||||||
|
input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Wrappers for forms and inputs using the Twitter Bootstrap toolkit.
|
||||||
|
# Check the Bootstrap docs (http://twitter.github.com/bootstrap)
|
||||||
|
# to learn about the different styles for forms and inputs,
|
||||||
|
# buttons and other elements.
|
||||||
|
config.default_wrapper = :bootstrap
|
||||||
|
end
|
|
@ -17,6 +17,8 @@ Foodsoft::Application.routes.draw do
|
||||||
|
|
||||||
match '/login' => 'sessions#new', :as => 'login'
|
match '/login' => 'sessions#new', :as => 'login'
|
||||||
match '/logout' => 'sessions#destroy', :as => 'logout'
|
match '/logout' => 'sessions#destroy', :as => 'logout'
|
||||||
|
get '/login/new_password' => 'login#new_password', as: :new_password
|
||||||
|
match '/login/accept_invitation/:token' => 'login#accept_invitation', as: :accept_invitation
|
||||||
resources :sessions, :only => [:new, :create, :destroy]
|
resources :sessions, :only => [:new, :create, :destroy]
|
||||||
|
|
||||||
########### User specific
|
########### User specific
|
||||||
|
@ -174,6 +176,7 @@ Foodsoft::Application.routes.draw do
|
||||||
|
|
||||||
resources :users, :only => [:index]
|
resources :users, :only => [:index]
|
||||||
|
|
||||||
|
# TODO: This is very error prone. Better deactivate this catch all route
|
||||||
match ':controller(/:action(/:id))(.:format)'
|
match ':controller(/:action(/:id))(.:format)'
|
||||||
|
|
||||||
end # End of /:foodcoop scope
|
end # End of /:foodcoop scope
|
||||||
|
|
Loading…
Add table
Reference in a new issue