fluentd-ui 0.3.11 → 0.3.12
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd-ui might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ChangeLog +11 -0
- data/Gemfile.lock +1 -1
- data/app/assets/stylesheets/common.css.scss +4 -0
- data/app/controllers/application_controller.rb +25 -15
- data/app/controllers/concerns/setting_history_concern.rb +28 -0
- data/app/controllers/fluentd/agents_controller.rb +13 -15
- data/app/controllers/fluentd/settings/histories_controller.rb +3 -13
- data/app/controllers/fluentd/settings/notes_controller.rb +16 -0
- data/app/controllers/fluentd/settings/running_backup_controller.rb +2 -12
- data/app/controllers/fluentd/settings_controller.rb +2 -2
- data/app/controllers/misc_controller.rb +27 -18
- data/app/controllers/polling_controller.rb +10 -13
- data/app/helpers/settings_helper.rb +67 -29
- data/app/models/{fluentd/setting/backup_file.rb → concerns/fluentd/setting_archive/archivable.rb} +11 -11
- data/app/models/fluent_gem.rb +1 -1
- data/app/models/fluentd/agent/fluentd_gem.rb +7 -3
- data/app/models/fluentd/agent/local_common.rb +44 -9
- data/app/models/fluentd/agent/td_agent/macosx.rb +5 -2
- data/app/models/fluentd/agent/td_agent/unix.rb +4 -0
- data/app/models/fluentd/setting/out_s3.rb +3 -3
- data/app/models/fluentd/setting_archive/backup_file.rb +20 -0
- data/app/models/fluentd/setting_archive/note.rb +28 -0
- data/app/models/plugin.rb +12 -6
- data/app/views/fluentd/settings/histories/_list.html.haml +17 -6
- data/app/views/fluentd/settings/histories/show.html.haml +12 -2
- data/app/views/fluentd/settings/running_backup/show.html.haml +8 -3
- data/app/views/layouts/application.html.erb +1 -1
- data/app/views/plugins/updated.html.haml +21 -19
- data/app/views/shared/_flash.html.haml +3 -0
- data/config/locales/translation_en.yml +5 -0
- data/config/locales/translation_ja.yml +5 -0
- data/config/routes.rb +4 -0
- data/lib/file_reverse_reader.rb +38 -13
- data/lib/fluentd-ui/version.rb +1 -1
- data/spec/controllers/application_controller_spec.rb +88 -0
- data/spec/controllers/fluentd/agents_controller_spec.rb +45 -0
- data/spec/controllers/misc_controller_spec.rb +68 -0
- data/spec/controllers/polling_controller_spec.rb +34 -0
- data/spec/features/fluentd/setting/histories_spec.rb +87 -0
- data/spec/features/fluentd/setting/notes_spec.rb +27 -0
- data/spec/features/fluentd/setting/out_forward_spec.rb +40 -0
- data/spec/features/fluentd/setting/{ranning_backup_spec.rb → running_backup_spec.rb} +36 -0
- data/spec/features/setting_spec.rb +2 -2
- data/spec/models/fluentd/agent_spec.rb +49 -0
- data/spec/support/fixtures/error3.log +7 -0
- data/spec/support/fluentd_agent_common_behavior.rb +14 -0
- metadata +23 -13
- data/app/helpers/miscs_helper.rb +0 -2
- data/db/seeds.rb +0 -7
- data/spec/controllers/plugins_controller_spec.rb +0 -5
- data/spec/controllers/tutorials_controller_spec.rb +0 -5
- data/spec/features/fluentd/setting/hisotries_spec.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1234cfcd1d5b0b9b3516e222f0636a525c6bbc7
|
4
|
+
data.tar.gz: 1cda1dadc1c7ccaf68ad646a218e41179ab8f6d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c9556dca73540fad194055497813912481af121c40303a15c378ca02cb5c88e6f05d92780cfe801870ff67a517d0e3897f5f86cc16d3a11043fb332d1bc6d65
|
7
|
+
data.tar.gz: 9b92d7c3774bab9acf5f73b86f04aa39122c0112ff322af3c2ab4ba28482a711d27c61fb1d2c348c8c1523029623ab3de67e38e5b9eecc40e9530f51e8418409
|
data/ChangeLog
CHANGED
@@ -1,11 +1,22 @@
|
|
1
|
+
Release 0.3.12 - 2015/01/16
|
2
|
+
* [maintenance] #126-#131, #135, #138,#139 #CodeClimate score is now 4.0! special thanks to @rthbound for many pull-requests.
|
3
|
+
* [fixed] #133 Incompatible config generated on out_s3 version 0.5.x or newer.
|
4
|
+
* [fixed] #140 Fluentd::Agent#logged_errors methods returned wrong errors.
|
5
|
+
* [fixed] #136 Caused error on gem list fetching on some environments.
|
6
|
+
* [improve] #124 Enable to note config history.
|
7
|
+
* [improve] #137 Add "config test" button to config histories. You can check config before reuse that.
|
8
|
+
|
9
|
+
|
1
10
|
Release 0.3.11 - 2014/12/19
|
2
11
|
* [improve] Save config history. Now any saved config files can be restored to the current.
|
3
12
|
|
13
|
+
|
4
14
|
Release 0.3.10 - 2014/12/17
|
5
15
|
* [maintenance] Update components.
|
6
16
|
* [improve] Add fluentd default plugin settings.
|
7
17
|
* [fixed] Fix #121. Change to allow utf-8 string instead of ascii.
|
8
18
|
|
19
|
+
|
9
20
|
Release 0.3.9 - 2014/12/01
|
10
21
|
|
11
22
|
* [improve] Display current setting for each section.
|
data/Gemfile.lock
CHANGED
@@ -75,28 +75,38 @@ class ApplicationController < ActionController::Base
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def set_locale
|
78
|
-
|
79
|
-
|
78
|
+
I18n.locale = locale_from_params || locale_from_session || locale_from_http_accept_lang || I18n.default_locale
|
79
|
+
end
|
80
|
+
|
81
|
+
def locale_from_params
|
82
|
+
if params[:lang] && available_locales.include?(params[:lang])
|
80
83
|
session[:prefer_lang] = params[:lang]
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
if session[:prefer_lang]
|
85
|
-
I18n.locale = session[:prefer_lang]
|
86
|
-
return
|
84
|
+
params[:lang]
|
85
|
+
else
|
86
|
+
nil
|
87
87
|
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def locale_from_session
|
91
|
+
session[:prefer_lang]
|
92
|
+
end
|
88
93
|
|
94
|
+
def locale_from_http_accept_lang
|
89
95
|
# NOTE: ignoring q=xxx in request header for now
|
90
|
-
return if request.env["HTTP_ACCEPT_LANGUAGE"].blank?
|
96
|
+
return nil if request.env["HTTP_ACCEPT_LANGUAGE"].blank?
|
97
|
+
|
91
98
|
langs = request.env["HTTP_ACCEPT_LANGUAGE"].gsub(/q=[0-9.]+/, "").gsub(";","").split(",")
|
92
|
-
prefer = langs.find {|lang|
|
99
|
+
prefer = langs.find { |lang| available_locales.include?(lang) }
|
100
|
+
|
93
101
|
unless prefer
|
94
|
-
if langs.find{|lang| lang.match(/^en/)}
|
95
|
-
I18n.locale = :en
|
96
|
-
return
|
97
|
-
end
|
102
|
+
prefer = :en if langs.find{ |lang| lang.match(/^en/) }
|
98
103
|
end
|
99
|
-
|
104
|
+
|
105
|
+
prefer
|
106
|
+
end
|
107
|
+
|
108
|
+
def available_locales
|
109
|
+
@available_locales ||= I18n.available_locales.map(&:to_s)
|
100
110
|
end
|
101
111
|
|
102
112
|
def file_tail(path, limit = 10)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SettingHistoryConcern
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
before_action :login_required
|
6
|
+
before_action :find_fluentd
|
7
|
+
before_action :find_backup_file, only: [:show, :reuse, :configtest]
|
8
|
+
end
|
9
|
+
|
10
|
+
def show
|
11
|
+
end
|
12
|
+
|
13
|
+
def reuse
|
14
|
+
@fluentd.agent.config_write @backup_file.content
|
15
|
+
redirect_to daemon_setting_path, flash: { success: t('messages.config_successfully_copied', brand: fluentd_ui_brand) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def configtest
|
19
|
+
@fluentd.config_file = @backup_file.file_path
|
20
|
+
if @fluentd.agent.dryrun
|
21
|
+
flash = { success: t('messages.dryrun_is_passed') }
|
22
|
+
else
|
23
|
+
flash = { danger: @fluentd.agent.log_tail(1).first }
|
24
|
+
end
|
25
|
+
redirect_to :back, flash: flash
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -2,29 +2,17 @@ class Fluentd::AgentsController < ApplicationController
|
|
2
2
|
before_action :find_fluentd
|
3
3
|
|
4
4
|
def start
|
5
|
-
|
6
|
-
flash[:success] = t("messages.fluentd_start_stop_delay_notice", action: t('fluentd.common.start'))
|
7
|
-
else
|
8
|
-
flash[:error] = t("messages.fluentd_start_failed", brand: fluentd_ui_title) + @fluentd.agent.log_tail(1).first
|
9
|
-
end
|
5
|
+
run_action(__method__) { @fluentd.agent.log_tail(1).first }
|
10
6
|
redirect_to daemon_path(@fluentd), status: 303 # 303 is change HTTP Verb GET
|
11
7
|
end
|
12
8
|
|
13
9
|
def stop
|
14
|
-
|
15
|
-
flash[:success] = t("messages.fluentd_start_stop_delay_notice", action: t('fluentd.common.stop'))
|
16
|
-
else
|
17
|
-
flash[:error] = t("messages.fluentd_stop_failed", brand: fluentd_ui_title)
|
18
|
-
end
|
10
|
+
run_action(__method__)
|
19
11
|
redirect_to daemon_path(@fluentd), status: 303 # 303 is change HTTP Verb GET
|
20
12
|
end
|
21
13
|
|
22
14
|
def restart
|
23
|
-
|
24
|
-
flash[:success] = t("messages.fluentd_start_stop_delay_notice", action: t('fluentd.common.restart'))
|
25
|
-
else
|
26
|
-
flash[:error] = t("messages.fluentd_restart_failed", brand: fluentd_ui_title) + @fluentd.agent.log_tail(1).first
|
27
|
-
end
|
15
|
+
run_action(__method__) { @fluentd.agent.log_tail(1).first }
|
28
16
|
redirect_to daemon_path(@fluentd), status: 303 # 303 is change HTTP Verb GET
|
29
17
|
end
|
30
18
|
|
@@ -32,4 +20,14 @@ class Fluentd::AgentsController < ApplicationController
|
|
32
20
|
@logs = @fluentd.agent.log_tail(params[:limit]).reverse if @fluentd
|
33
21
|
render json: @logs
|
34
22
|
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def run_action(action)
|
26
|
+
if @fluentd.agent.public_send(action)
|
27
|
+
flash[:success] = t("messages.fluentd_start_stop_delay_notice", action: t("fluentd.common.#{action}"))
|
28
|
+
else
|
29
|
+
flash[:error] = t("messages.fluentd_#{action}_failed", brand: fluentd_ui_title)
|
30
|
+
flash[:error] += yield if block_given?
|
31
|
+
end
|
32
|
+
end
|
35
33
|
end
|
@@ -1,26 +1,16 @@
|
|
1
1
|
class Fluentd::Settings::HistoriesController < ApplicationController
|
2
|
-
|
3
|
-
before_action :find_fluentd
|
4
|
-
before_action :find_backup_file, only: [:show, :reuse]
|
2
|
+
include SettingHistoryConcern
|
5
3
|
|
6
4
|
def index
|
7
5
|
@backup_files = @fluentd.agent.backup_files_in_new_order.map do |file_path|
|
8
|
-
Fluentd::
|
6
|
+
Fluentd::SettingArchive::BackupFile.new(file_path)
|
9
7
|
end
|
10
8
|
end
|
11
9
|
|
12
|
-
def show
|
13
|
-
end
|
14
|
-
|
15
|
-
def reuse
|
16
|
-
@fluentd.agent.config_write @backup_file.content
|
17
|
-
redirect_to daemon_setting_path, flash: { success: t('messages.config_successfully_copied', brand: fluentd_ui_brand) }
|
18
|
-
end
|
19
|
-
|
20
10
|
private
|
21
11
|
|
22
12
|
def find_backup_file
|
23
13
|
#Do not use BackupFile.new(params[:id]) because params[:id] can be any path.
|
24
|
-
@backup_file = Fluentd::
|
14
|
+
@backup_file = Fluentd::SettingArchive::BackupFile.find_by_file_id(@fluentd.agent.config_backup_dir, params[:id])
|
25
15
|
end
|
26
16
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Fluentd::Settings::NotesController < ApplicationController
|
2
|
+
before_action :login_required
|
3
|
+
before_action :find_fluentd
|
4
|
+
before_action :find_note, only: [:update]
|
5
|
+
|
6
|
+
def update
|
7
|
+
@note.update!(params[:note][:content])
|
8
|
+
redirect_to daemon_setting_path, flash: { success: t('messages.note_updating_success') }
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def find_note
|
14
|
+
@note = Fluentd::SettingArchive::Note.find_by_file_id(@fluentd.agent.config_backup_dir, params[:id])
|
15
|
+
end
|
16
|
+
end
|
@@ -1,19 +1,9 @@
|
|
1
1
|
class Fluentd::Settings::RunningBackupController < ApplicationController
|
2
|
-
|
3
|
-
before_action :find_fluentd
|
4
|
-
before_action :find_backup_file, only: [:show, :reuse]
|
5
|
-
|
6
|
-
def show
|
7
|
-
end
|
8
|
-
|
9
|
-
def reuse
|
10
|
-
@fluentd.agent.config_write @backup_file.content
|
11
|
-
redirect_to daemon_setting_path, flash: { success: t('messages.config_successfully_copied', brand: fluentd_ui_brand) }
|
12
|
-
end
|
2
|
+
include SettingHistoryConcern
|
13
3
|
|
14
4
|
private
|
15
5
|
|
16
6
|
def find_backup_file
|
17
|
-
@backup_file = Fluentd::
|
7
|
+
@backup_file = Fluentd::SettingArchive::BackupFile.new(@fluentd.agent.running_config_backup_file)
|
18
8
|
end
|
19
9
|
end
|
@@ -7,10 +7,10 @@ class Fluentd::SettingsController < ApplicationController
|
|
7
7
|
|
8
8
|
def show
|
9
9
|
@backup_files = @fluentd.agent.backup_files_in_new_order.first(Settings.histories_count_in_preview).map do |file_path|
|
10
|
-
Fluentd::
|
10
|
+
Fluentd::SettingArchive::BackupFile.new(file_path)
|
11
11
|
end
|
12
12
|
|
13
|
-
@running_backedup_file = Fluentd::
|
13
|
+
@running_backedup_file = Fluentd::SettingArchive::BackupFile.new(@fluentd.agent.running_config_backup_file)
|
14
14
|
end
|
15
15
|
|
16
16
|
def edit
|
@@ -39,30 +39,39 @@ class MiscController < ApplicationController
|
|
39
39
|
|
40
40
|
Zip::File.open(path, Zip::File::CREATE) do |zip|
|
41
41
|
zip.get_output_stream('fluentd.log') {|f| f.puts fluentd.agent.log }
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
zip.get_output_stream('env.txt') do |f|
|
48
|
-
ENV.to_a.each do |(key, value)|
|
49
|
-
f.puts "#{key}=#{value}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
zip.get_output_stream('versions.txt') do |f|
|
53
|
-
f.puts "ruby: #{RUBY_DESCRIPTION}"
|
54
|
-
f.puts "fluentd: #{FluentdUI.fluentd_version}"
|
55
|
-
f.puts "fluentd-ui: #{FluentdUI::VERSION}"
|
56
|
-
f.puts
|
57
|
-
f.puts "# OS Information"
|
58
|
-
f.puts "uname -a: #{`uname -a`.strip}"
|
59
|
-
end
|
42
|
+
zip.add("fluentd-ui.log", log_path)
|
43
|
+
|
44
|
+
add_env_file_to(zip)
|
45
|
+
add_version_file_to(zip)
|
60
46
|
end
|
61
47
|
send_file path
|
62
48
|
end
|
63
49
|
|
64
50
|
private
|
65
51
|
|
52
|
+
def log_path
|
53
|
+
ENV["FLUENTD_UI_LOG_PATH"] || Rails.root.join("log/#{Rails.env}.log")
|
54
|
+
end
|
55
|
+
|
56
|
+
def add_env_file_to(zip)
|
57
|
+
zip.get_output_stream('env.txt') do |f|
|
58
|
+
ENV.to_a.each do |(key, value)|
|
59
|
+
f.puts "#{key}=#{value}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def add_version_file_to(zip)
|
65
|
+
zip.get_output_stream('versions.txt') do |f|
|
66
|
+
f.puts "ruby: #{RUBY_DESCRIPTION}"
|
67
|
+
f.puts "fluentd: #{FluentdUI.fluentd_version}"
|
68
|
+
f.puts "fluentd-ui: #{FluentdUI::VERSION}"
|
69
|
+
f.puts
|
70
|
+
f.puts "# OS Information"
|
71
|
+
f.puts "uname -a: #{`uname -a`.strip}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
66
75
|
def update!
|
67
76
|
FluentdUiRestart.new.async.perform
|
68
77
|
end
|
@@ -1,20 +1,17 @@
|
|
1
1
|
class PollingController < ApplicationController
|
2
2
|
def alerts
|
3
3
|
alerts = []
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
target << "(#{plugin.version})" if plugin.version
|
14
|
-
alerts << {
|
15
|
-
text: I18n.t('terms.uninstalling', target: target)
|
16
|
-
}
|
4
|
+
|
5
|
+
%w{ installing uninstalling }.each do |action|
|
6
|
+
send("#{action}_gems").each do |plugin|
|
7
|
+
target = plugin.gem_name.dup
|
8
|
+
target << "(#{plugin.version})" if plugin.version
|
9
|
+
alerts << {
|
10
|
+
text: I18n.t("terms.#{action}", target: target)
|
11
|
+
}
|
12
|
+
end
|
17
13
|
end
|
14
|
+
|
18
15
|
render json: alerts
|
19
16
|
end
|
20
17
|
end
|
@@ -2,42 +2,80 @@ module SettingsHelper
|
|
2
2
|
def field(form, key, opts = {})
|
3
3
|
html = '<div class="form-group">'
|
4
4
|
|
5
|
-
|
5
|
+
field_resolver(form.object.column_type(key), html, form, key, opts)
|
6
|
+
|
7
|
+
html << "</div>"
|
8
|
+
html.html_safe
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def field_resolver(type, html, form, key, opts)
|
13
|
+
case type
|
6
14
|
when :hidden
|
7
|
-
|
15
|
+
html << form.hidden_field(key)
|
8
16
|
when :boolean, :flag
|
9
|
-
html
|
10
|
-
html << " " # NOTE: Adding space for padding
|
11
|
-
html << h(form.label(key))
|
17
|
+
boolean_field(html, form, key, opts)
|
12
18
|
when :choice
|
13
|
-
html
|
14
|
-
html << " " # NOTE: Adding space for padding
|
15
|
-
html << form.select(key, form.object.values_of(key), opts)
|
19
|
+
choice_field(html, form, key, opts)
|
16
20
|
when :nested
|
17
|
-
|
18
|
-
klass = child_data[:class]
|
19
|
-
options = child_data[:options]
|
20
|
-
children = form.object.send(key) || {"0" => {}}
|
21
|
-
children.each_pair do |index, child|
|
22
|
-
html << %Q!<div class="js-nested-column #{options[:multiple] ? "js-multiple" : ""} well well-sm">!
|
23
|
-
if options[:multiple]
|
24
|
-
html << %Q!<a class="btn btn-xs btn-default js-append">#{icon('fa-plus')}</a> !
|
25
|
-
html << %Q!<a class="btn btn-xs btn-default js-remove" style="display:none">#{icon('fa-minus')}</a> !
|
26
|
-
end
|
27
|
-
html << h(form.label(key))
|
28
|
-
form.fields_for("#{key}[#{index}]", klass.new(child)) do |ff|
|
29
|
-
klass::KEYS.each do |k|
|
30
|
-
html << field(ff, k)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
html << "</div>"
|
34
|
-
end
|
21
|
+
nested_field(html, form, key, opts)
|
35
22
|
else
|
23
|
+
other_field(html, form, key, opts)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def nested_field(html, form, key, opts = {})
|
28
|
+
klass = child_data(form, key)[:class]
|
29
|
+
options = child_data(form, key)[:options]
|
30
|
+
children = form.object.send(key) || {"0" => {}}
|
31
|
+
|
32
|
+
children.each_pair do |index, child|
|
33
|
+
html << open_nested_div(options[:multiple])
|
34
|
+
html << append_and_remove_links if options[:multiple]
|
36
35
|
html << h(form.label(key))
|
37
|
-
html << form
|
36
|
+
html << nested_fields(form, key, index, klass, child)
|
37
|
+
html << "</div>"
|
38
38
|
end
|
39
|
+
end
|
39
40
|
|
40
|
-
|
41
|
-
|
41
|
+
def open_nested_div(multiple)
|
42
|
+
%Q!<div class="js-nested-column #{ multiple ? "js-multiple" : "" } well well-sm">!
|
43
|
+
end
|
44
|
+
|
45
|
+
def nested_fields(form, key, index, klass, child)
|
46
|
+
nested_html = ""
|
47
|
+
form.fields_for("#{key}[#{index}]", klass.new(child)) do |ff|
|
48
|
+
klass::KEYS.each do |k|
|
49
|
+
nested_html << field(ff, k)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
nested_html
|
54
|
+
end
|
55
|
+
|
56
|
+
def append_and_remove_links
|
57
|
+
%Q!<a class="btn btn-xs btn-default js-append">icon('fa-plus')}</a> ! +
|
58
|
+
%Q!<a class="btn btn-xs btn-default js-remove" style="display:none">icon('fa-minus')}</a> !
|
59
|
+
end
|
60
|
+
|
61
|
+
def child_data(form, key)
|
62
|
+
form.object.class.children[key]
|
63
|
+
end
|
64
|
+
|
65
|
+
def choice_field(html, form, key, opts = {})
|
66
|
+
html << h(form.label(key))
|
67
|
+
html << " " # NOTE: Adding space for padding
|
68
|
+
html << form.select(key, form.object.values_of(key), opts)
|
69
|
+
end
|
70
|
+
|
71
|
+
def boolean_field(html, form, key, opts = {})
|
72
|
+
html << form.check_box(key, {}, "true", "false")
|
73
|
+
html << " " # NOTE: Adding space for padding
|
74
|
+
html << h(form.label(key))
|
75
|
+
end
|
76
|
+
|
77
|
+
def other_field(html, form, key, opts = {})
|
78
|
+
html << h(form.label(key))
|
79
|
+
html << form.text_field(key, class: "form-control")
|
42
80
|
end
|
43
81
|
end
|