udongo 2.0.4 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/backend/application.js +1 -0
- data/app/assets/javascripts/backend/bootstrap.js +3 -3569
- data/app/assets/javascripts/backend/tree.js +106 -65
- data/app/assets/stylesheets/backend/application.scss +2 -0
- data/app/assets/stylesheets/backend/bootstrap.scss +29 -51
- data/app/assets/stylesheets/backend/components/_page_tree.scss +9 -0
- data/app/assets/stylesheets/backend/custom.scss +0 -0
- data/app/assets/stylesheets/backend/font-awesome.scss +644 -1977
- data/app/assets/stylesheets/backend/udongo.scss +1 -0
- data/app/controllers/backend/admins_controller.rb +2 -2
- data/app/controllers/{backend_controller.rb → backend/base_controller.rb} +13 -5
- data/app/controllers/backend/content/rows/columns_controller.rb +1 -1
- data/app/controllers/backend/content/rows/images_controller.rb +1 -1
- data/app/controllers/backend/content/rows/texts_controller.rb +1 -1
- data/app/controllers/backend/content/rows_controller.rb +1 -1
- data/app/controllers/backend/dashboard_controller.rb +1 -1
- data/app/controllers/backend/email_templates_controller.rb +12 -12
- data/app/controllers/backend/emails_controller.rb +1 -1
- data/app/controllers/backend/navigation/items_controller.rb +9 -11
- data/app/controllers/backend/navigations_controller.rb +1 -1
- data/app/controllers/backend/pages_controller.rb +17 -39
- data/app/controllers/backend/redirects_controller.rb +1 -1
- data/app/controllers/backend/seo_controller.rb +1 -1
- data/app/controllers/backend/sessions_controller.rb +1 -1
- data/app/controllers/backend/snippets_controller.rb +14 -13
- data/app/controllers/backend/tagbox_controller.rb +1 -1
- data/app/controllers/catch_all_controller.rb +1 -1
- data/app/controllers/concerns/backend/content_type_controller.rb +3 -1
- data/app/controllers/redirects_controller.rb +1 -1
- data/app/decorators/page_decorator.rb +1 -4
- data/app/forms/backend/email_template_translation_form.rb +1 -23
- data/app/forms/backend/navigation_item_translation_form.rb +1 -23
- data/app/forms/backend/page_translation_form.rb +13 -18
- data/app/forms/backend/snippet_translation_form.rb +1 -23
- data/app/forms/backend/translation_form.rb +22 -0
- data/app/helpers/udongo_helper.rb +0 -4
- data/app/mailers/general_mailer.rb +14 -4
- data/app/models/admin.rb +2 -2
- data/app/models/comment.rb +1 -2
- data/app/models/concerns/addressable.rb +40 -0
- data/app/models/concerns/addressable/config.rb +33 -0
- data/app/models/concerns/cacheable.rb +1 -1
- data/app/models/email.rb +2 -2
- data/app/models/email_template.rb +2 -1
- data/app/views/backend/_general_form_error.html.erb +6 -0
- data/app/views/backend/admins/_form.html.erb +3 -0
- data/app/views/backend/content/rows/columns/_dimension_fields.html.erb +3 -0
- data/app/views/backend/content/rows/columns/edit.html.erb +3 -5
- data/app/views/backend/content/rows/columns/new.html.erb +3 -5
- data/app/views/backend/content/rows/images/edit.html.erb +2 -0
- data/app/views/backend/dashboard/show.html.erb +1 -1
- data/app/views/backend/email_templates/_form.html.erb +29 -7
- data/app/views/backend/email_templates/_tabs.html.erb +1 -1
- data/app/views/backend/email_templates/edit_translation.html.erb +1 -0
- data/app/views/backend/navigation/items/_form.html.erb +4 -2
- data/app/views/backend/navigation/items/_tabs.html.erb +1 -1
- data/app/views/backend/navigation/items/edit_translation.html.erb +1 -0
- data/app/views/backend/pages/_form.html.erb +4 -2
- data/app/views/backend/pages/_tabs.html.erb +1 -1
- data/app/views/backend/pages/edit_translation.html.erb +1 -0
- data/app/views/backend/redirects/_form.html.erb +2 -0
- data/app/views/backend/snippets/_form.html.erb +3 -1
- data/app/views/backend/snippets/_tabs.html.erb +1 -1
- data/app/views/backend/snippets/edit.html.erb +1 -1
- data/app/views/backend/snippets/edit_translation.html.erb +1 -0
- data/app/views/backend/snippets/new.html.erb +1 -1
- data/app/views/layouts/backend/_top_navigation.html.erb +1 -2
- data/changelog.md +38 -0
- data/config/initializers/simple_form_bootstrap.rb +13 -9
- data/config/locales/en_backend.yml +1 -4
- data/config/locales/en_forms.yml +3 -0
- data/config/locales/nl_backend.yml +3 -4
- data/config/locales/nl_forms.yml +3 -0
- data/config/routes.rb +5 -7
- data/db/migrate/20160815100903_remove_form_models.rb +9 -0
- data/db/migrate/20161014135637_add_category_to_admin.rb +5 -0
- data/db/migrate/20161029124558_add_locale_to_admin.rb +6 -0
- data/db/migrate/20161029130557_add_bcc_and_cc_to_email_templates.rb +6 -0
- data/db/migrate/20161029171056_add_ccc_and_bcc_to_email.rb +6 -0
- data/lib/udongo/configs/flexible_content.rb +7 -0
- data/lib/udongo/configs/i18n.rb +5 -3
- data/lib/udongo/configs/i18ns/app.rb +12 -0
- data/lib/udongo/configs/i18ns/cms.rb +12 -0
- data/lib/udongo/flexible_content/column_width_calculator.rb +4 -2
- data/lib/udongo/pages/tree.rb +15 -0
- data/lib/udongo/pages/tree_node.rb +43 -0
- data/lib/udongo/version.rb +1 -1
- data/readme.md +103 -43
- data/vendor/assets/javascripts/backend/select2.min.js +3 -0
- data/vendor/assets/stylesheets/backend/jstree/default/style.scss +3 -3
- data/vendor/assets/stylesheets/backend/select2.min.scss +1 -0
- metadata +22 -30
- data/app/controllers/backend/forms/base_controller.rb +0 -14
- data/app/controllers/backend/forms/submissions_controller.rb +0 -8
- data/app/controllers/backend/forms_controller.rb +0 -7
- data/app/controllers/backend/webserver_controller.rb +0 -6
- data/app/decorators/form_decorator.rb +0 -16
- data/app/decorators/form_submission_decorator.rb +0 -3
- data/app/forms/backend/email_template_form.rb +0 -38
- data/app/forms/backend/navigation_item_form.rb +0 -23
- data/app/forms/backend/page_form.rb +0 -26
- data/app/forms/backend/snippet_form.rb +0 -35
- data/app/models/form.rb +0 -10
- data/app/models/form_field.rb +0 -15
- data/app/models/form_field_validation.rb +0 -11
- data/app/models/form_submission.rb +0 -15
- data/app/models/form_submission_data.rb +0 -5
- data/app/views/backend/_form_errors.html.erb +0 -15
- data/app/views/backend/forms/index.html.erb +0 -27
- data/app/views/backend/forms/submissions/_filter.html.erb +0 -16
- data/app/views/backend/forms/submissions/index.html.erb +0 -34
- data/lib/generators/udongo/form/form_generator.rb +0 -62
- data/lib/generators/udongo/form/templates/form.rb +0 -18
- data/lib/udongo/configs/forms.rb +0 -18
- data/lib/udongo/configs/routes.rb +0 -13
- data/lib/udongo/email_vars/form_submission.rb +0 -18
- data/lib/udongo/forms/submission_datagrid.rb +0 -27
- data/lib/udongo/forms/submission_filter.rb +0 -31
@@ -1,33 +1,11 @@
|
|
1
|
-
class Backend::EmailTemplateTranslationForm <
|
2
|
-
attr_reader :email_template, :translation
|
3
|
-
|
1
|
+
class Backend::EmailTemplateTranslationForm < Backend::TranslationForm
|
4
2
|
attribute :subject, String
|
5
3
|
attribute :plain_content, String
|
6
4
|
attribute :html_content, String
|
7
5
|
|
8
6
|
validates :subject, :plain_content, :html_content, presence: true
|
9
7
|
|
10
|
-
delegate :id, to: :email_template
|
11
|
-
|
12
|
-
def initialize(email_template, translation)
|
13
|
-
@email_template = email_template
|
14
|
-
@translation = translation
|
15
|
-
|
16
|
-
init_attribute_values(@translation)
|
17
|
-
end
|
18
|
-
|
19
8
|
def self.model_name
|
20
9
|
EmailTemplate.model_name
|
21
10
|
end
|
22
|
-
|
23
|
-
def persisted?
|
24
|
-
true
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def save_object
|
30
|
-
init_object_values(@translation)
|
31
|
-
@translation.save
|
32
|
-
end
|
33
11
|
end
|
@@ -1,30 +1,8 @@
|
|
1
|
-
class Backend::NavigationItemTranslationForm <
|
2
|
-
attr_reader :navigation_item, :translation
|
3
|
-
|
1
|
+
class Backend::NavigationItemTranslationForm < Backend::TranslationForm
|
4
2
|
attribute :label, String
|
5
3
|
attribute :path, String
|
6
4
|
|
7
|
-
delegate :id, to: :navigation_item
|
8
|
-
|
9
|
-
def initialize(navigation_item, translation)
|
10
|
-
@navigation_item = navigation_item
|
11
|
-
@translation = translation
|
12
|
-
|
13
|
-
init_attribute_values(translation)
|
14
|
-
end
|
15
|
-
|
16
5
|
def self.model_name
|
17
6
|
NavigationItem.model_name
|
18
7
|
end
|
19
|
-
|
20
|
-
def persisted?
|
21
|
-
true
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def save_object
|
27
|
-
init_object_values(@translation)
|
28
|
-
@translation.save
|
29
|
-
end
|
30
8
|
end
|
@@ -22,11 +22,9 @@ class Backend::PageTranslationForm < Udongo::Form
|
|
22
22
|
self.title = @translation.title
|
23
23
|
self.subtitle = @translation.subtitle
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
self.seo_custom = @seo.custom
|
29
|
-
self.seo_slug = @seo.slug
|
25
|
+
%w(title keywords description custom slug).each do |f|
|
26
|
+
self.send("seo_#{f}=", @seo.send(f))
|
27
|
+
end
|
30
28
|
end
|
31
29
|
|
32
30
|
def self.model_name
|
@@ -41,11 +39,9 @@ class Backend::PageTranslationForm < Udongo::Form
|
|
41
39
|
self.title = params[:title]
|
42
40
|
self.subtitle = params[:subtitle]
|
43
41
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
self.seo_custom = params[:seo_custom]
|
48
|
-
self.seo_slug = params[:seo_slug]
|
42
|
+
%w(title keywords description custom slug).each do |f|
|
43
|
+
self.send("seo_#{f}=", params["seo_#{f}".to_sym])
|
44
|
+
end
|
49
45
|
|
50
46
|
if valid?
|
51
47
|
save_object
|
@@ -60,13 +56,12 @@ class Backend::PageTranslationForm < Udongo::Form
|
|
60
56
|
def save_object
|
61
57
|
@translation.title = title
|
62
58
|
@translation.subtitle = subtitle
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
@
|
70
|
-
@seo.save
|
59
|
+
|
60
|
+
%w(title keywords description custom slug).each do |f|
|
61
|
+
@seo.send("#{f}=", send("seo_#{f}"))
|
62
|
+
end
|
63
|
+
|
64
|
+
# Saves the page, translation and SEO info all at once.
|
65
|
+
@page.save
|
71
66
|
end
|
72
67
|
end
|
@@ -1,30 +1,8 @@
|
|
1
|
-
class Backend::SnippetTranslationForm <
|
2
|
-
attr_reader :snippet, :translation
|
3
|
-
|
1
|
+
class Backend::SnippetTranslationForm < Backend::TranslationForm
|
4
2
|
attribute :title, String
|
5
3
|
attribute :content, String
|
6
4
|
|
7
|
-
delegate :id, to: :snippet
|
8
|
-
|
9
|
-
def initialize(snippet, translation)
|
10
|
-
@snippet = snippet
|
11
|
-
@translation = translation
|
12
|
-
|
13
|
-
init_attribute_values(translation)
|
14
|
-
end
|
15
|
-
|
16
5
|
def self.model_name
|
17
6
|
Snippet.model_name
|
18
7
|
end
|
19
|
-
|
20
|
-
def persisted?
|
21
|
-
true
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def save_object
|
27
|
-
init_object_values(@translation)
|
28
|
-
@translation.save
|
29
|
-
end
|
30
8
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Backend::TranslationForm < Udongo::Form
|
2
|
+
attr_reader :model, :translation
|
3
|
+
delegate :id, to: :model
|
4
|
+
|
5
|
+
def initialize(model, translation)
|
6
|
+
@model = model
|
7
|
+
@translation = translation
|
8
|
+
|
9
|
+
init_attribute_values(@translation)
|
10
|
+
end
|
11
|
+
|
12
|
+
def persisted?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def save_object
|
19
|
+
init_object_values(@translation)
|
20
|
+
@model.save
|
21
|
+
end
|
22
|
+
end
|
@@ -5,10 +5,6 @@ module UdongoHelper
|
|
5
5
|
js_asset_loader.load_js file, target
|
6
6
|
end
|
7
7
|
|
8
|
-
def restart_webserver_button
|
9
|
-
link_to I18n.t('b.restart_webserver'), backend_restart_webserver_path, class: 'btn btn-info', method: 'post'
|
10
|
-
end
|
11
|
-
|
12
8
|
# Before using: Put <%= yield(:stylesheets) %> in the <head> of your app's frontend
|
13
9
|
def stylesheet(file, media = :screen)
|
14
10
|
css_asset_loader.view = self
|
@@ -1,13 +1,23 @@
|
|
1
1
|
class GeneralMailer < ActionMailer::Base
|
2
2
|
def email(email)
|
3
|
-
|
4
|
-
to = "#{email.to_name} <#{email.to_email}>"
|
5
|
-
|
6
|
-
mail(from: from, to: to, subject: email.subject) do |format|
|
3
|
+
mail(headers(email)) do |format|
|
7
4
|
format.text { render text: email.plain_content }
|
8
5
|
format.html { render html: email.html_content.html_safe }
|
9
6
|
end
|
10
7
|
|
11
8
|
email.mark_as_sent!
|
12
9
|
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def headers(email)
|
14
|
+
from = "#{email.from_name} <#{email.from_email}>"
|
15
|
+
to = "#{email.to_name} <#{email.to_email}>"
|
16
|
+
|
17
|
+
{
|
18
|
+
from: from,
|
19
|
+
to: to,
|
20
|
+
subject: email.subject
|
21
|
+
}
|
22
|
+
end
|
13
23
|
end
|
data/app/models/admin.rb
CHANGED
@@ -2,8 +2,8 @@ class Admin < ApplicationRecord
|
|
2
2
|
include Concerns::Person
|
3
3
|
has_secure_password
|
4
4
|
|
5
|
-
validates :first_name, :last_name, presence: true
|
5
|
+
validates :locale, :first_name, :last_name, presence: true
|
6
6
|
validates :email,
|
7
7
|
uniqueness: { case_sensitive: false },
|
8
|
-
|
8
|
+
email: true
|
9
9
|
end
|
data/app/models/comment.rb
CHANGED
@@ -11,8 +11,7 @@ class Comment < ApplicationRecord
|
|
11
11
|
|
12
12
|
validates :author, :message, presence: true
|
13
13
|
validates :status, inclusion: { in: STATUSES }
|
14
|
-
validates :email, presence: true,
|
15
|
-
format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i }
|
14
|
+
validates :email, presence: true, email: true
|
16
15
|
validates :website, url: true, allow_blank: true
|
17
16
|
|
18
17
|
def published?
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Concerns
|
2
|
+
module Addressable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
has_many :addresses, dependent: :destroy
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def configure_adress(categories, default: nil)
|
11
|
+
address_config.update(categories, default: default)
|
12
|
+
end
|
13
|
+
|
14
|
+
def address_config
|
15
|
+
@address_config ||= Concerns::Addressable::Config.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def address(category = nil)
|
20
|
+
category = self.class.address_config.default unless category.present?
|
21
|
+
|
22
|
+
unless self.class.address_config.allowed?(category)
|
23
|
+
raise "You can't select the '#{category}' address because it's not an allowed category"
|
24
|
+
end
|
25
|
+
|
26
|
+
@address_collections = {} unless @address_collections
|
27
|
+
|
28
|
+
unless @address_collections[category.to_sym]
|
29
|
+
|
30
|
+
@address_collections[category.to_sym] = Address.find_or_initialize_by(
|
31
|
+
category: category,
|
32
|
+
addressable_type: self.class.name,
|
33
|
+
addressable_id: id
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
@address_collections[category.to_sym]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Concerns
|
2
|
+
module Addressable
|
3
|
+
class Config
|
4
|
+
attr_reader :fields, :default
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@fields = []
|
8
|
+
@default = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def update(categories, default: nil)
|
12
|
+
unless categories.respond_to?(:each) && categories.any?
|
13
|
+
raise 'Please provide an array with address categories'
|
14
|
+
end
|
15
|
+
|
16
|
+
@fields = categories.map(&:to_sym).uniq
|
17
|
+
@default = @fields.first
|
18
|
+
|
19
|
+
if default
|
20
|
+
unless @fields.include?(default.to_sym)
|
21
|
+
raise "You can't make '#{default.to_s}' the default address category because it's not in the list of categories"
|
22
|
+
end
|
23
|
+
|
24
|
+
@default = default.to_sym
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def allowed?(field)
|
29
|
+
@fields.include?(field.to_sym)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/app/models/email.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
class Email < ApplicationRecord
|
2
2
|
validates :from_name, :to_name, :subject, :plain_content, :html_content,
|
3
3
|
presence: true
|
4
|
-
validates :from_email, :to_email,
|
5
|
-
|
4
|
+
validates :from_email, :to_email, email: true
|
5
|
+
validates :cc, :bcc, email: true, allow_blank: true
|
6
6
|
|
7
7
|
scope :sent, -> { where('sent_at IS NOT NULL') }
|
8
8
|
scope :not_sent, -> { where('sent_at IS NULL') }
|
@@ -6,5 +6,6 @@ class EmailTemplate < ApplicationRecord
|
|
6
6
|
|
7
7
|
validates :description, :from_name, presence: true
|
8
8
|
validates :identifier, presence: true, uniqueness: { case_sensitive: false }
|
9
|
-
validates :from_email,
|
9
|
+
validates :from_email, email: true
|
10
|
+
validates :cc, :bcc, email: true, allow_blank: true
|
10
11
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
<%= render 'backend/general_form_error', object: @admin %>
|
2
|
+
|
1
3
|
<%= simple_form_for [:backend, @admin] do |f| %>
|
2
4
|
<div class="row">
|
3
5
|
<div class="col-md-6">
|
@@ -7,6 +9,7 @@
|
|
7
9
|
</div>
|
8
10
|
|
9
11
|
<div class="card-block">
|
12
|
+
<%= f.input :locale, collection: Udongo.config.i18n.cms.interface_locales, include_blank: false %>
|
10
13
|
<%= f.input :first_name %>
|
11
14
|
<%= f.input :last_name %>
|
12
15
|
<%= f.input :email, required: true %>
|
@@ -1,3 +1,5 @@
|
|
1
|
+
<%= render 'backend/general_form_error', object: @column %>
|
2
|
+
|
1
3
|
<%= simple_form_for(@column, url: backend_content_row_column_path(@row, @column)) do |f| %>
|
2
4
|
<div class="card">
|
3
5
|
<div class="card-header">
|
@@ -7,11 +9,7 @@
|
|
7
9
|
<div class="card-block">
|
8
10
|
<div class="row">
|
9
11
|
<div class="col-md-6">
|
10
|
-
<%=
|
11
|
-
<%= f.input :width_sm, as: :integer %>
|
12
|
-
<%= f.input :width_md, as: :integer %>
|
13
|
-
<%= f.input :width_lg, as: :integer %>
|
14
|
-
<%= f.input :width_xl, as: :integer %>
|
12
|
+
<%= render 'backend/content/rows/columns/dimension_fields', form: f %>
|
15
13
|
</div>
|
16
14
|
|
17
15
|
<div class="col-md-6">
|
@@ -1,3 +1,5 @@
|
|
1
|
+
<%= render 'backend/general_form_error', object: @column %>
|
2
|
+
|
1
3
|
<%= simple_form_for(@column, url: backend_content_row_columns_path(@row)) do |f| %>
|
2
4
|
<div class="card">
|
3
5
|
<div class="card-header">
|
@@ -7,11 +9,7 @@
|
|
7
9
|
<div class="card-block">
|
8
10
|
<div class="row">
|
9
11
|
<div class="col-md-6">
|
10
|
-
<%=
|
11
|
-
<%= f.input :width_sm, as: :integer %>
|
12
|
-
<%= f.input :width_md, as: :integer %>
|
13
|
-
<%= f.input :width_lg, as: :integer %>
|
14
|
-
<%= f.input :width_xl, as: :integer %>
|
12
|
+
<%= render 'backend/content/rows/columns/dimension_fields', form: f %>
|
15
13
|
</div>
|
16
14
|
|
17
15
|
<div class="col-md-6">
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
<!-- Fine me in app/views/backend/dashboard/show.html.erb -->
|
@@ -1,27 +1,49 @@
|
|
1
|
-
<%=
|
1
|
+
<%= render 'backend/general_form_error', object: @model %>
|
2
|
+
|
3
|
+
<%= simple_form_for [:backend, @model] do |f| %>
|
2
4
|
<div class="row">
|
3
|
-
<div class="col-md-
|
5
|
+
<div class="col-md-12">
|
4
6
|
<div class="card">
|
5
7
|
<div class="card-header">
|
6
8
|
<%= t 'b.general' %>
|
7
9
|
</div>
|
8
10
|
|
9
11
|
<div class="card-block">
|
10
|
-
|
11
|
-
|
12
|
+
<div class="row">
|
13
|
+
<div class="col-md-6">
|
14
|
+
<%= f.input :identifier %>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<div class="row">
|
19
|
+
<div class="col-md-12">
|
20
|
+
<%= f.input :description, as: :string %>
|
21
|
+
</div>
|
22
|
+
</div>
|
12
23
|
</div>
|
13
24
|
</div>
|
14
25
|
</div>
|
26
|
+
</div>
|
15
27
|
|
16
|
-
|
28
|
+
<div class="row">
|
29
|
+
<div class="col-md-12">
|
17
30
|
<div class="card">
|
18
31
|
<div class="card-header">
|
19
32
|
<%= t 'b.settings' %>
|
20
33
|
</div>
|
21
34
|
|
22
35
|
<div class="card-block">
|
23
|
-
|
24
|
-
|
36
|
+
<div class="row">
|
37
|
+
<div class="col-md-6">
|
38
|
+
<%= f.input :from_name %>
|
39
|
+
<%= f.input :from_email %>
|
40
|
+
</div>
|
41
|
+
|
42
|
+
<div class="col-md-6">
|
43
|
+
<%= f.input :cc %>
|
44
|
+
<%= f.input :bcc %>
|
45
|
+
</div>
|
46
|
+
</div>
|
25
47
|
</div>
|
26
48
|
</div>
|
27
49
|
</div>
|