add foodcoop configuration screen
This commit is contained in:
parent
dd3ac0971c
commit
7b000c39eb
20 changed files with 562 additions and 12 deletions
|
|
@ -140,6 +140,23 @@ table {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
// Navigation with embedded tabs
|
||||
.nav-tabs-with-heading {
|
||||
> li {
|
||||
line-height: 40px;
|
||||
margin-top: 16.5px;
|
||||
a { padding-bottom: 9px; }
|
||||
}
|
||||
> li.heading {
|
||||
> h1, > h2, > h3 {
|
||||
font-size: 31.5px;
|
||||
line-height: 40px;
|
||||
margin: 0;
|
||||
}
|
||||
margin: 10px 1em 5px 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Tasks ..
|
||||
.accepted {
|
||||
color: #468847;
|
||||
|
|
@ -324,6 +341,15 @@ table.table {
|
|||
}
|
||||
}
|
||||
|
||||
// inline (boolean) position after/before heading
|
||||
label {
|
||||
h1, h2, h3, h4 {
|
||||
input[type=checkbox] {
|
||||
margin: auto 0.3em auto 0.3em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// it's a bit distracting
|
||||
.icon-asterisk {
|
||||
font-size: 80%;
|
||||
|
|
|
|||
39
app/controllers/admin/configs_controller.rb
Normal file
39
app/controllers/admin/configs_controller.rb
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
class Admin::ConfigsController < Admin::BaseController
|
||||
|
||||
before_action :get_tabs, only: [:show, :list]
|
||||
|
||||
def show
|
||||
@current_tab = @tabs.include?(params[:tab]) ? params[:tab] : @tabs.first
|
||||
@cfg = FoodsoftConfig
|
||||
end
|
||||
|
||||
def list
|
||||
@current_tab = 'list'
|
||||
@cfg = FoodsoftConfig
|
||||
@dfl = FoodsoftConfig.config
|
||||
@keys = FoodsoftConfig.keys.select {|k| FoodsoftConfig.allowed_key?(k)}.sort
|
||||
end
|
||||
|
||||
def update
|
||||
ActiveRecord::Base.transaction do
|
||||
# TODO support nested configuration keys
|
||||
params[:config].each do |key, val|
|
||||
FoodsoftConfig[key] = val
|
||||
end
|
||||
end
|
||||
flash[:notice] = I18n.t('admin.configs.update.notice')
|
||||
redirect_to action: 'show'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Set configuration tab names as `@tabs`
|
||||
def get_tabs
|
||||
@tabs = %w(foodcoop payment tasks messages layout language others)
|
||||
# allow engines to modify this list
|
||||
engines = Rails::Engine.subclasses.map(&:instance).select { |e| e.respond_to?(:configuration) }
|
||||
engines.each { |e| e.configuration(@tabs, self) }
|
||||
@tabs.uniq!
|
||||
end
|
||||
|
||||
end
|
||||
117
app/helpers/admin/configs_helper.rb
Normal file
117
app/helpers/admin/configs_helper.rb
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
module Admin::ConfigsHelper
|
||||
# Returns form input for configuration key.
|
||||
# For configuration keys that contain a {Hash}, {ActiveView::Helpers::FormBuilder#fields_for fields_for} can be used.
|
||||
# @param form [ActionView::Helpers::FormBuilder] Form object.
|
||||
# @param key [Symbol, String] Configuration key.
|
||||
# @param options [Hash] Options passed to the form builder.
|
||||
# @option options [Boolean] :required Wether field is shown as required (default not).
|
||||
# @return [String] Form input for configuration key.
|
||||
def config_input(form, key, options = {}, &block)
|
||||
options[:label] = config_input_label(form, key)
|
||||
options[:required] ||= false
|
||||
options[:input_html] ||= {}
|
||||
config_input_field_options form, key, options[:input_html]
|
||||
config_input_tooltip_options form, key, options[:input_html]
|
||||
if options[:as] == :boolean
|
||||
options[:input_html][:checked] = 'checked' if options[:input_html].delete(:value)
|
||||
options[:checked_value] = true
|
||||
options[:unchecked_value] = false
|
||||
elsif options[:collection] or options[:as] == :select
|
||||
options[:selected] = options[:input_html].delete(:value)
|
||||
return form.input key, options, &block
|
||||
end
|
||||
form.input key, options, &block
|
||||
end
|
||||
|
||||
# @return [String] Label name in form for configuration key.
|
||||
# @param form [ActionView::Helpers::FormBuilder] Form object.
|
||||
# @param key [Symbol, String] Configuration key.
|
||||
# @see #config_input
|
||||
def config_input_label(form, key)
|
||||
cfg_path = form.lookup_model_names[1..-1] + [key]
|
||||
I18n.t("config.keys.#{cfg_path.map(&:to_s).join('.')}")
|
||||
end
|
||||
|
||||
# @return [String] Form input field for configuration key.
|
||||
# @see config_input
|
||||
# @todo find out how to pass +checked_value+ and +unchecked_value+ to +input_field+
|
||||
def config_input_field(form, key, options = {})
|
||||
config_input_field_options form, key, options
|
||||
config_input_tooltip_options form, key, options
|
||||
if options[:as] == :boolean
|
||||
options[:checked] = 'checked' if options.delete(:value)
|
||||
form.hidden_field(key, value: false, as: :hidden) + form.check_box(key, options, true, false)
|
||||
else
|
||||
form.input_field key, options
|
||||
end
|
||||
end
|
||||
|
||||
# @return [String] Form heading with checkbox with block passed in expandable +fieldset+.
|
||||
# @param form [ActionView::Helpers::FormBuilder] Form object.
|
||||
# @param key [Symbol, String] Configuration key of a boolean (e.g. +use_messages+).
|
||||
# @option options [String] :label Label to show
|
||||
def config_use_heading(form, key, options = {})
|
||||
head = content_tag :label do
|
||||
lbl = options[:label] || config_input_label(form, key)
|
||||
field = config_input_field(form, key, as: :boolean, boolean_style: :inline,
|
||||
data: {toggle: 'collapse', target: "##{key}-fields"})
|
||||
content_tag :h4 do
|
||||
# put in span to keep space for tooltip at right
|
||||
content_tag :span, (lbl + field).html_safe, config_input_tooltip_options(form, key, {})
|
||||
end
|
||||
end
|
||||
fields = content_tag(:fieldset, id: "#{key}-fields", class: "collapse#{' in' if @cfg[key]}") do
|
||||
yield
|
||||
end
|
||||
head + fields
|
||||
end
|
||||
|
||||
# Returns configuration value suitable for rendering in HTML.
|
||||
# Makes keys different from +app_config.yml+ configuration bold,
|
||||
# protects sensitive values like keys and passwords, and makes
|
||||
# links from URLs.
|
||||
# @param key [String] Configuration key
|
||||
# @param value [String] Configuration value
|
||||
# @return [String] Configuration value suitable for rendering in HTML.
|
||||
def show_config_value(key, value)
|
||||
if key =~ /passw|secr|key/
|
||||
'(protected)'
|
||||
elsif value.is_a? Hash
|
||||
content_tag :ul do
|
||||
value.map do |k,v|
|
||||
content_tag :li, content_tag(:tt, "#{k}: ") + show_config_value(k, v).to_s
|
||||
end.join.html_safe
|
||||
end
|
||||
elsif value.is_a? Enumerable
|
||||
content_tag :ul, value.map {|v| content_tag :li, h(v)}.join.html_safe
|
||||
elsif key =~ /url|website|www|homepage/
|
||||
link_to(value, value).html_safe
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def config_input_tooltip_options(form, key, options)
|
||||
# tooltip with help info to the right
|
||||
cfg_path = form.lookup_model_names[1..-1] + [key]
|
||||
tooltip = I18n.t("config.hints.#{cfg_path.map(&:to_s).join('.')}", default: '')
|
||||
unless tooltip.blank?
|
||||
options[:data] ||= {}
|
||||
options[:data][:toggle] ||= 'tooltip'
|
||||
options[:data][:placement] ||= 'right'
|
||||
options[:title] ||= tooltip
|
||||
end
|
||||
options
|
||||
end
|
||||
|
||||
def config_input_field_options(form, key, options)
|
||||
cfg_path = form.lookup_model_names[1..-1] + [key]
|
||||
# set current value
|
||||
value = @cfg
|
||||
cfg_path.each {|n| value = value[n] unless value.nil? }
|
||||
options[:value] ||= value
|
||||
options
|
||||
end
|
||||
end
|
||||
10
app/views/admin/configs/_tab_foodcoop.html.haml
Normal file
10
app/views/admin/configs/_tab_foodcoop.html.haml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
= config_input form, :name, required: true, input_html: {class: 'input-xlarge'}
|
||||
= form.fields_for :contact do |c|
|
||||
= config_input c, :street, input_html: {class: 'input-xlarge'}
|
||||
.fold-line
|
||||
= config_input c, :zip_code, input_html: {class: 'input-mini'}
|
||||
= config_input c, :city, input_html: {class: 'input-medium'}
|
||||
= config_input c, :country, as: :string, input_html: {class: 'input-xlarge'}
|
||||
= config_input c, :email, required: true, input_html: {class: 'input-xlarge'}
|
||||
= config_input c, :phone, input_html: {class: 'input-medium'}
|
||||
= config_input form, :homepage, required: true, as: :url, input_html: {class: 'input-xlarge'}
|
||||
3
app/views/admin/configs/_tab_language.html.haml
Normal file
3
app/views/admin/configs/_tab_language.html.haml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
= config_input form, :default_locale,
|
||||
collection: I18n.available_locales.map {|l| [t("simple_form.options.settings.profile.language.#{l}"), l]}
|
||||
= config_input form, :ignore_browser_locale, as: :boolean
|
||||
7
app/views/admin/configs/_tab_layout.html.haml
Normal file
7
app/views/admin/configs/_tab_layout.html.haml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
= config_input form, :page_footer, as: :text, input_html: {class: 'input-xxlarge', rows: 2, placeholder: "#{link_to(FoodsoftConfig[:name], FoodsoftConfig[:homepage])}"}
|
||||
|
||||
%h4= t '.pdf_title'
|
||||
.fold-line
|
||||
= config_input form, :pdf_font_size, as: :integer, input_html: {class: 'input-mini'}
|
||||
= config_input form, :pdf_page_size, input_html: {class: 'input-medium'}
|
||||
= config_input form, :pdf_add_page_breaks, as: :boolean
|
||||
7
app/views/admin/configs/_tab_messages.html.haml
Normal file
7
app/views/admin/configs/_tab_messages.html.haml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
%fieldset
|
||||
%label
|
||||
%h4= t '.emails_title'
|
||||
= config_input form, :email_from, as: :string, input_html: {class: 'input-xlarge', placeholder: "#{@cfg[:name]} <#{@cfg[:contact][:email]}>"}
|
||||
= config_input form, :email_replyto, as: :string, input_html: {class: 'input-xlarge'}
|
||||
-# sender is better configured by server administrator, since it affects SPF records
|
||||
-#= config_input form, :email_sender, as: :string, input_html: {class: 'input-xlarge'}
|
||||
5
app/views/admin/configs/_tab_others.html.haml
Normal file
5
app/views/admin/configs/_tab_others.html.haml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
- if defined? FoodsoftWiki # avoid requiring deface here (the single exception)
|
||||
= config_input form, :use_wiki, as: :boolean
|
||||
= config_input form, :use_nick, as: :boolean
|
||||
= config_input form, :tolerance_is_costly, as: :boolean
|
||||
= config_input form, :help_url, as: :url, input_html: {class: 'input-xlarge'}
|
||||
12
app/views/admin/configs/_tab_payment.html.haml
Normal file
12
app/views/admin/configs/_tab_payment.html.haml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
= config_input form, :price_markup do
|
||||
.input-append
|
||||
= config_input_field form, :price_markup, as: :decimal, class: 'input-mini'
|
||||
%span.add-on %
|
||||
= config_input form, :tax_default do
|
||||
.input-append
|
||||
= config_input_field form, :tax_default, as: :decimal, class: 'input-mini'
|
||||
%span.add-on %
|
||||
= config_input form, :minimum_balance do
|
||||
.input-prepend
|
||||
%span.add-on= t 'number.currency.format.unit'
|
||||
= config_input_field form, :minimum_balance, as: :decimal, class: 'input-small'
|
||||
3
app/views/admin/configs/_tab_tasks.html.haml
Normal file
3
app/views/admin/configs/_tab_tasks.html.haml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
-#= config_use_heading form, :use_tasks do
|
||||
= config_use_heading form, :use_apple_points do
|
||||
= config_input form, :stop_ordering_under, as: :numeric, input_html: {class: 'input-small'}
|
||||
11
app/views/admin/configs/_tabs.html.haml
Normal file
11
app/views/admin/configs/_tabs.html.haml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
%ul.nav.nav-tabs.nav-tabs-with-heading
|
||||
%li.heading
|
||||
%h1= t '.title'
|
||||
|
||||
- for tab in @tabs
|
||||
- url = action_name == 'show' ? nil : admin_config_path(tab: tab)
|
||||
%li{class: ('active' if @current_tab==tab)}= link_to t("config.tabs.#{tab}"), "#{url}#tab-#{tab}", data: ({toggle: 'tab'} unless url)
|
||||
|
||||
-# make this a button to give some indicator that navigation away might lose changes
|
||||
%li.pull-right{class: ('active' if @current_tab=='list')}
|
||||
= link_to t('config.tabs.list'), list_admin_config_path, class: ('btn' unless @current_tab=='list')
|
||||
16
app/views/admin/configs/list.html.haml
Normal file
16
app/views/admin/configs/list.html.haml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
- title t('.title'), false
|
||||
|
||||
= render 'tabs'
|
||||
|
||||
%table.table
|
||||
%thead
|
||||
%tr
|
||||
%th= t '.key'
|
||||
%th= t '.value'
|
||||
%tbody
|
||||
- @keys.each do |key|
|
||||
%tr
|
||||
%td
|
||||
%tt= key
|
||||
%td{style: if @cfg[key] != @dfl[key] then 'font-weight: bold' end}
|
||||
= show_config_value key, @cfg[key]
|
||||
13
app/views/admin/configs/show.html.haml
Normal file
13
app/views/admin/configs/show.html.haml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
- title t('admin.configs.tabs.title'), false
|
||||
|
||||
= simple_form_for :config, method: :patch do |f|
|
||||
|
||||
= render 'tabs', url: nil
|
||||
|
||||
.tab-content
|
||||
- for tab in @tabs
|
||||
.tab-pane{class: ('active' if @current_tab==tab), id: "tab-#{tab}"}= render "tab_#{tab}", form: f
|
||||
|
||||
.form-actions
|
||||
= f.submit t('.submit'), class: 'btn btn-primary'
|
||||
|
||||
|
|
@ -10,9 +10,9 @@
|
|||
%li= link_to t('.profile'), my_profile_path
|
||||
%li= link_to t('.ordergroup'), my_ordergroup_path
|
||||
%li= link_to t('.logout'), logout_path
|
||||
%li{class: ('disabled' if FoodsoftConfig.config[:homepage].blank?)}
|
||||
= link_to FoodsoftConfig.config[:name], FoodsoftConfig.config[:homepage]
|
||||
%li= link_to t('.help'), FoodsoftConfig.config[:help_url]
|
||||
%li{class: ('disabled' if FoodsoftConfig[:homepage].blank?)}
|
||||
= link_to FoodsoftConfig[:name], FoodsoftConfig[:homepage]
|
||||
%li= link_to t('.help'), FoodsoftConfig[:help_url]
|
||||
%li= link_to t('.feedback.title'), new_feedback_path, title: t('.feedback.desc')
|
||||
.clearfix
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue