rocketjob_mission_control 5.0.1 → 6.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/assets/config/manifest.js +3 -0
- data/app/assets/javascripts/rocket_job_mission_control/application.js +1 -1
- data/app/assets/javascripts/rocket_job_mission_control/nested_fields.js +112 -0
- data/app/assets/stylesheets/rocket_job_mission_control/{application.scss → application.css} +9 -8
- data/app/assets/stylesheets/rocket_job_mission_control/base.css +420 -0
- data/app/assets/stylesheets/rocket_job_mission_control/{callout.scss → callout.css} +50 -52
- data/app/assets/stylesheets/rocket_job_mission_control/jobs.css +57 -0
- data/app/assets/stylesheets/rocket_job_mission_control/worker_processes.css +7 -0
- data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +20 -20
- data/app/controllers/rocket_job_mission_control/jobs_controller.rb +44 -4
- data/app/datatables/rocket_job_mission_control/jobs_datatable.rb +1 -1
- data/app/helpers/rocket_job_mission_control/application_helper.rb +43 -26
- data/app/helpers/rocket_job_mission_control/dirmon_entries_helper.rb +8 -0
- data/app/helpers/rocket_job_mission_control/jobs_helper.rb +76 -8
- data/app/models/rocket_job_mission_control/dirmon_sanitizer.rb +68 -0
- data/app/models/rocket_job_mission_control/job_sanitizer.rb +35 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_form.html.erb +78 -42
- data/app/views/rocket_job_mission_control/dirmon_entries/_input_categories.html.erb +59 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_input_category_fields.html.erb +56 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_output_categories.html.erb +44 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_output_category_fields.html.erb +36 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.erb +22 -16
- data/app/views/rocket_job_mission_control/dirmon_entries/copy.html.erb +1 -1
- data/app/views/rocket_job_mission_control/dirmon_entries/edit.html.erb +7 -3
- data/app/views/rocket_job_mission_control/dirmon_entries/show.html.erb +2 -3
- data/app/views/rocket_job_mission_control/jobs/_attributes.html.erb +89 -0
- data/app/views/rocket_job_mission_control/jobs/_dates.html.erb +39 -0
- data/app/views/rocket_job_mission_control/jobs/_details.html.erb +86 -0
- data/app/views/rocket_job_mission_control/jobs/_exception.html.erb +33 -0
- data/app/views/rocket_job_mission_control/jobs/_input_categories.html.erb +126 -0
- data/app/views/rocket_job_mission_control/jobs/_input_category_fields.html.erb +56 -0
- data/app/views/rocket_job_mission_control/jobs/_output_categories.html.erb +60 -0
- data/app/views/rocket_job_mission_control/jobs/_output_category_fields.html.erb +36 -0
- data/app/views/rocket_job_mission_control/jobs/_retryable.html.erb +27 -0
- data/app/views/rocket_job_mission_control/jobs/_status.html.erb +21 -49
- data/app/views/rocket_job_mission_control/jobs/edit.html.erb +28 -0
- data/app/views/rocket_job_mission_control/jobs/exception.html.erb +1 -1
- data/app/views/rocket_job_mission_control/jobs/index.html.erb +24 -18
- data/app/views/rocket_job_mission_control/jobs/show.html.erb +32 -58
- data/app/views/rocket_job_mission_control/jobs/view_slice.html.erb +4 -4
- data/config/initializers/assets.rb +3 -4
- data/lib/rocket_job_mission_control/engine.rb +0 -1
- data/lib/rocket_job_mission_control/version.rb +1 -1
- data/test/controllers/rocket_job_mission_control/jobs_controller_test.rb +2 -1
- data/test/models/rocket_job_mission_control/dirmon_sanitizer_test.rb +146 -0
- data/test/test_helper.rb +5 -11
- data/vendor/assets/fonts/glyphicons-halflings-regular.eot +0 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.svg +288 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.woff +0 -0
- data/vendor/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/vendor/assets/stylesheets/bootstrap.min.css.erb +6 -0
- metadata +37 -29
- data/app/assets/stylesheets/rocket_job_mission_control/base.scss +0 -436
- data/app/assets/stylesheets/rocket_job_mission_control/bootstrap_and_overrides.scss +0 -488
- data/app/assets/stylesheets/rocket_job_mission_control/jobs.scss +0 -72
- data/app/assets/stylesheets/rocket_job_mission_control/worker_processes.scss +0 -9
- data/vendor/assets/stylesheets/bootstrap.min.css +0 -6
@@ -4,74 +4,72 @@
|
|
4
4
|
border-left-width: 0.5em;
|
5
5
|
}
|
6
6
|
.callout-queued {
|
7
|
-
border-left-color: #
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
border-left-color: #a29f00;
|
8
|
+
}
|
9
|
+
.callout-queued a {
|
10
|
+
color: #a29f00;
|
11
11
|
}
|
12
12
|
.callout-running {
|
13
13
|
border-left-color: #337ab7;
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
}
|
15
|
+
.callout-running a {
|
16
|
+
color: #337ab7;
|
17
17
|
}
|
18
18
|
.callout-sleeping {
|
19
19
|
border-left-color: darkcyan;
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
}
|
21
|
+
.callout-sleeping a {
|
22
|
+
color: darkcyan;
|
23
23
|
}
|
24
24
|
.callout-scheduled {
|
25
|
-
border-left-color:
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
border-left-color: purple;
|
26
|
+
}
|
27
|
+
.callout-scheduled a {
|
28
|
+
color: purple;
|
29
29
|
}
|
30
30
|
.callout-completed {
|
31
31
|
border-left-color: green;
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
}
|
33
|
+
.callout-completed a {
|
34
|
+
color: green;
|
35
35
|
}
|
36
36
|
.callout-paused {
|
37
37
|
border-left-color: orange;
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
}
|
39
|
+
.callout-paused a {
|
40
|
+
color: orange;
|
41
41
|
}
|
42
42
|
.callout-failed {
|
43
43
|
border-left-color: red;
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
}
|
45
|
+
.callout-failed a {
|
46
|
+
color: red;
|
47
47
|
}
|
48
48
|
.callout-aborted {
|
49
49
|
border-left-color: darkorange;
|
50
|
-
a {
|
51
|
-
color: darkorange;
|
52
|
-
}
|
53
50
|
}
|
54
|
-
|
51
|
+
.callout-aborted a {
|
52
|
+
color: darkorange;
|
53
|
+
}
|
55
54
|
/* Used by Dirmon Entries */
|
56
55
|
.callout-pending {
|
57
56
|
border-color: orange;
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
}
|
58
|
+
.callout-pending a {
|
59
|
+
color: orange;
|
61
60
|
}
|
62
61
|
.callout-enabled {
|
63
62
|
border-left-color: green;
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
}
|
64
|
+
.callout-enabled a {
|
65
|
+
color: green;
|
67
66
|
}
|
68
67
|
.callout-disabled {
|
69
68
|
border-left-color: grey;
|
70
|
-
a {
|
71
|
-
color: grey;
|
72
|
-
}
|
73
69
|
}
|
74
|
-
|
70
|
+
.callout-disabled a {
|
71
|
+
color: grey;
|
72
|
+
}
|
75
73
|
/* Used by Servers */
|
76
74
|
.callout-top {
|
77
75
|
border: 1px solid #eee;
|
@@ -79,31 +77,31 @@
|
|
79
77
|
}
|
80
78
|
.callout-info {
|
81
79
|
border-left-color: #1b809e;
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
}
|
81
|
+
.callout-info .title {
|
82
|
+
color: #1b809e;
|
85
83
|
}
|
86
84
|
.callout-success {
|
87
85
|
border-left-color: #3c763d;
|
88
|
-
|
89
|
-
|
90
|
-
|
86
|
+
}
|
87
|
+
.callout-success .title {
|
88
|
+
color: #3c763d;
|
91
89
|
}
|
92
90
|
.callout-warning {
|
93
91
|
border-left-color: #aa6708;
|
94
|
-
|
95
|
-
|
96
|
-
|
92
|
+
}
|
93
|
+
.callout-warning .title {
|
94
|
+
color: #aa6708;
|
97
95
|
}
|
98
96
|
.callout-alert {
|
99
97
|
border-left-color: #ce4844;
|
100
|
-
|
101
|
-
|
102
|
-
|
98
|
+
}
|
99
|
+
.callout-alert .title {
|
100
|
+
color: #ce4844;
|
103
101
|
}
|
104
102
|
.callout-zombie {
|
105
103
|
border-left-color: darkred;
|
106
|
-
|
107
|
-
|
108
|
-
|
104
|
+
}
|
105
|
+
.callout-zombie .title {
|
106
|
+
color: darkred;
|
109
107
|
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
.job-list {
|
2
|
+
/*padding: 1px 1px 1px 1px;
|
3
|
+
*/
|
4
|
+
}
|
5
|
+
.job-list .breadcrumb {
|
6
|
+
margin-bottom: 0px;
|
7
|
+
}
|
8
|
+
.job-list .breadcrumb {
|
9
|
+
padding: 2px;
|
10
|
+
}
|
11
|
+
.job-list .breadcrumb > li {
|
12
|
+
margin: 5px 0 0 5px;
|
13
|
+
}
|
14
|
+
.job-list .list .progress {
|
15
|
+
width: 10em;
|
16
|
+
height: 1em;
|
17
|
+
margin: 5px 0px 0px 10px;
|
18
|
+
display: inline-block;
|
19
|
+
-webkit-border-radius: 0 !important;
|
20
|
+
-moz-border-radius: 0 !important;
|
21
|
+
border-radius: 0 !important;
|
22
|
+
}
|
23
|
+
.job-list .list .progress-bar {
|
24
|
+
min-width: 0em;
|
25
|
+
}
|
26
|
+
.error pre {
|
27
|
+
margin: 0px 0px 0px 0px;
|
28
|
+
border-bottom: 0;
|
29
|
+
border-radius: 0;
|
30
|
+
word-wrap: normal;
|
31
|
+
}
|
32
|
+
.error pre:last-child {
|
33
|
+
border: 1px solid #ccc;
|
34
|
+
}
|
35
|
+
.pagination {
|
36
|
+
margin-top: 1em;
|
37
|
+
}
|
38
|
+
.pagination .btn {
|
39
|
+
border-radius: 0;
|
40
|
+
}
|
41
|
+
.input_slices {
|
42
|
+
font-size: 14px;
|
43
|
+
line-height: 2;
|
44
|
+
resize: none;
|
45
|
+
width: 100%;
|
46
|
+
height: 20em;
|
47
|
+
padding-top: 5px;
|
48
|
+
padding-bottom: 5px;
|
49
|
+
margin-bottom: 4px;
|
50
|
+
}
|
51
|
+
.edit_button {
|
52
|
+
float: right;
|
53
|
+
margin-left: 3px;
|
54
|
+
}
|
55
|
+
.edit_input {
|
56
|
+
margin-left: 80px;
|
57
|
+
}
|
@@ -1,18 +1,11 @@
|
|
1
1
|
module RocketJobMissionControl
|
2
2
|
class DirmonEntriesController < RocketJobMissionControl::ApplicationController
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
before_filter :show_sidebar
|
7
|
-
else
|
8
|
-
before_action :find_entry_or_redirect, except: %i[index disabled enabled failed pending new create]
|
9
|
-
before_action :authorize_read, only: %i[index disabled enabled failed pending]
|
10
|
-
before_action :show_sidebar
|
11
|
-
end
|
3
|
+
before_action :find_entry_or_redirect, except: %i[index disabled enabled failed pending new create]
|
4
|
+
before_action :authorize_read, only: %i[index disabled enabled failed pending]
|
5
|
+
before_action :show_sidebar
|
12
6
|
|
13
7
|
rescue_from AccessGranted::AccessDenied do |exception|
|
14
8
|
raise exception if Rails.env.development? || Rails.env.test?
|
15
|
-
|
16
9
|
redirect_to :back, alert: "Access not authorized."
|
17
10
|
end
|
18
11
|
|
@@ -56,6 +49,7 @@ module RocketJobMissionControl
|
|
56
49
|
def create
|
57
50
|
authorize! :create, RocketJob::DirmonEntry
|
58
51
|
@dirmon_entry = RocketJob::DirmonEntry.new(dirmon_params)
|
52
|
+
|
59
53
|
if properties = params[:rocket_job_dirmon_entry][:properties]
|
60
54
|
@dirmon_entry.properties = JobSanitizer.sanitize(properties, @dirmon_entry.job_class, @dirmon_entry, false)
|
61
55
|
end
|
@@ -76,19 +70,23 @@ module RocketJobMissionControl
|
|
76
70
|
def edit
|
77
71
|
authorize! :edit, @dirmon_entry
|
78
72
|
end
|
79
|
-
|
73
|
+
|
74
|
+
# When you click on the Copy button,
|
80
75
|
# the copy method loads the Dirmon Entity attributes in Copy Dirmon Entry Page
|
81
76
|
def copy
|
82
77
|
authorize! :copy, @dirmon_entry
|
83
78
|
end
|
79
|
+
|
84
80
|
# When you click on the replicate button,
|
85
81
|
# the replicate method clones the existing Dirmon Entity
|
86
82
|
def replicate
|
87
83
|
authorize! :replicate, @dirmon_entry
|
88
84
|
dirmon_entry_replicate = RocketJob::DirmonEntry.new(@dirmon_entry.dup.attributes.except("id"))
|
85
|
+
|
89
86
|
if properties = params[:rocket_job_dirmon_entry][:properties]
|
90
|
-
dirmon_entry_replicate.properties = JobSanitizer.sanitize(properties, dirmon_entry_replicate.job_class,
|
87
|
+
dirmon_entry_replicate.properties = JobSanitizer.sanitize(properties, dirmon_entry_replicate.job_class, @dirmon_entry, false)
|
91
88
|
end
|
89
|
+
|
92
90
|
if dirmon_entry_replicate.errors.empty? && dirmon_entry_replicate.valid? && dirmon_entry_replicate.update_attributes(dirmon_params)
|
93
91
|
redirect_to(rocket_job_mission_control.dirmon_entry_path(dirmon_entry_replicate))
|
94
92
|
else
|
@@ -98,10 +96,12 @@ module RocketJobMissionControl
|
|
98
96
|
|
99
97
|
def update
|
100
98
|
authorize! :update, @dirmon_entry
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
99
|
+
sanitized_params = DirmonSanitizer.sanitize(params[:rocket_job_dirmon_entry], @dirmon_entry.job_class, @dirmon_entry)
|
100
|
+
properties = DirmonSanitizer.diff_properties(sanitized_params[:properties], @dirmon_entry)
|
101
|
+
|
102
|
+
sanitized_params[:properties] = properties
|
103
|
+
|
104
|
+
if @dirmon_entry.errors.empty? && @dirmon_entry.valid? && @dirmon_entry.update_attributes(sanitized_params)
|
105
105
|
redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
|
106
106
|
else
|
107
107
|
render :edit
|
@@ -110,6 +110,7 @@ module RocketJobMissionControl
|
|
110
110
|
|
111
111
|
def enable
|
112
112
|
authorize! :enable, @dirmon_entry
|
113
|
+
|
113
114
|
if @dirmon_entry.may_enable?
|
114
115
|
@dirmon_entry.enable!
|
115
116
|
redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
|
@@ -121,6 +122,7 @@ module RocketJobMissionControl
|
|
121
122
|
|
122
123
|
def disable
|
123
124
|
authorize! :disable, @dirmon_entry
|
125
|
+
|
124
126
|
if @dirmon_entry.may_disable?
|
125
127
|
@dirmon_entry.disable!
|
126
128
|
redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
|
@@ -148,15 +150,12 @@ module RocketJobMissionControl
|
|
148
150
|
def find_entry_or_redirect
|
149
151
|
unless @dirmon_entry = RocketJob::DirmonEntry.where(id: params[:id]).first
|
150
152
|
flash[:alert] = t(:failure, scope: %i[dirmon_entry find], id: params[:id])
|
151
|
-
|
152
153
|
redirect_to(dirmon_entries_path)
|
153
154
|
end
|
154
155
|
end
|
155
156
|
|
156
157
|
def dirmon_params
|
157
|
-
params.
|
158
|
-
fetch(:rocket_job_dirmon_entry, {}).
|
159
|
-
permit(:name, :archive_directory, :pattern, :job_class_name)
|
158
|
+
params.fetch(:rocket_job_dirmon_entry, {}).permit(:name, :archive_directory, :pattern, :job_class_name, :properties)
|
160
159
|
end
|
161
160
|
|
162
161
|
def render_datatable(entries, description)
|
@@ -165,6 +164,7 @@ module RocketJobMissionControl
|
|
165
164
|
@description = description
|
166
165
|
render :index
|
167
166
|
end
|
167
|
+
|
168
168
|
format.json do
|
169
169
|
query = RocketJobMissionControl::Query.new(entries, name: :asc)
|
170
170
|
query.search_columns = %i[job_class_name name pattern]
|
@@ -74,8 +74,11 @@ module RocketJobMissionControl
|
|
74
74
|
|
75
75
|
def update
|
76
76
|
authorize! :update, @job
|
77
|
-
permitted_params = JobSanitizer.sanitize(
|
78
|
-
|
77
|
+
permitted_params = JobSanitizer.sanitize(job_params, @job.class, @job)
|
78
|
+
|
79
|
+
assign_job_values(@job, permitted_params)
|
80
|
+
|
81
|
+
if @job.errors.empty? && @job.valid? && @job.save
|
79
82
|
redirect_to job_path(@job)
|
80
83
|
else
|
81
84
|
render :edit
|
@@ -247,6 +250,24 @@ module RocketJobMissionControl
|
|
247
250
|
|
248
251
|
private
|
249
252
|
|
253
|
+
def assign_job_values(target, hash)
|
254
|
+
hash.each_pair do |attribute, value|
|
255
|
+
if attribute == :input_categories
|
256
|
+
value.each do |category_hash|
|
257
|
+
h = category_hash.dup
|
258
|
+
assign_job_values(target.input_category(h.delete(:name)), h)
|
259
|
+
end
|
260
|
+
elsif attribute == :output_categories
|
261
|
+
value.each do |category_hash|
|
262
|
+
h = category_hash.dup
|
263
|
+
assign_job_values(target.output_category(h.delete(:name)), h)
|
264
|
+
end
|
265
|
+
elsif attribute != :id
|
266
|
+
target.send("#{attribute}=", value)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
250
271
|
def authorize_read
|
251
272
|
authorize! :read, RocketJob::Job
|
252
273
|
end
|
@@ -264,7 +285,26 @@ module RocketJobMissionControl
|
|
264
285
|
end
|
265
286
|
|
266
287
|
def job_params
|
267
|
-
params.require(:job).permit(
|
288
|
+
params.require(:job).permit(
|
289
|
+
@job.class.user_editable_fields,
|
290
|
+
input_categories_attributes: [
|
291
|
+
:id,
|
292
|
+
:name,
|
293
|
+
:format,
|
294
|
+
:format_options,
|
295
|
+
:mode,
|
296
|
+
:skip_unknown,
|
297
|
+
:slice_size,
|
298
|
+
columns: []
|
299
|
+
],
|
300
|
+
output_categories_attributes: [
|
301
|
+
:id,
|
302
|
+
:name,
|
303
|
+
:format,
|
304
|
+
:format_options,
|
305
|
+
columns: []
|
306
|
+
]
|
307
|
+
)
|
268
308
|
end
|
269
309
|
|
270
310
|
def error_occurred(exception)
|
@@ -308,7 +348,7 @@ module RocketJobMissionControl
|
|
308
348
|
h = {data: index.to_s}
|
309
349
|
h[:width] = column[:width] if column.key?(:width)
|
310
350
|
h[:orderable] = column[:orderable] if column.key?(:orderable)
|
311
|
-
index
|
351
|
+
index += 1
|
312
352
|
h
|
313
353
|
end
|
314
354
|
end
|
@@ -47,7 +47,7 @@ module RocketJobMissionControl
|
|
47
47
|
{display: "Started", value: :started, field: "started_at"},
|
48
48
|
{display: "Actions", value: :action_buttons, orderable: false}
|
49
49
|
].freeze
|
50
|
-
RUNNING_FIELDS = (COMMON_FIELDS + %i[record_count
|
50
|
+
RUNNING_FIELDS = (COMMON_FIELDS + %i[record_count input_categories output_categories priority sub_state percent_complete]).freeze
|
51
51
|
|
52
52
|
SCHEDULED_COLUMNS = [
|
53
53
|
{display: "Class", value: :class_with_link, field: "_type"},
|
@@ -57,7 +57,7 @@ module RocketJobMissionControl
|
|
57
57
|
end
|
58
58
|
|
59
59
|
# Returns the editable field as html for use in editing dynamic fields from a Job class.
|
60
|
-
def editable_field_html(klass, field_name, value, f
|
60
|
+
def editable_field_html(klass, field_name, value, f)
|
61
61
|
# When editing a job the values are of the correct type.
|
62
62
|
# When editing a dirmon entry values are strings.
|
63
63
|
field = klass.fields[field_name.to_s]
|
@@ -67,44 +67,61 @@ module RocketJobMissionControl
|
|
67
67
|
placeholder = nil if placeholder.is_a?(Proc)
|
68
68
|
|
69
69
|
case field.type.name
|
70
|
-
when "
|
70
|
+
when "Integer"
|
71
|
+
options = extract_inclusion_values(klass, field_name)
|
72
|
+
f.number_field(field_name, in: options, include_blank: false, value: value, class: "form-control", placeholder: placeholder)
|
73
|
+
when "String", "Symbol", "Mongoid::StringifiedSymbol"
|
71
74
|
options = extract_inclusion_values(klass, field_name)
|
72
|
-
str = "[#{field.type.name}]\n".html_safe
|
73
75
|
if options
|
74
|
-
|
76
|
+
f.select(field_name, options, {include_blank: options.include?(nil), selected: value}, {class: "selectize form-control"})
|
75
77
|
else
|
76
|
-
|
77
|
-
str + f.number_field(field_name, value: value, class: "form-control", placeholder: placeholder)
|
78
|
-
else
|
79
|
-
str + f.text_field(field_name, value: value, class: "form-control", placeholder: placeholder)
|
80
|
-
end
|
78
|
+
f.text_field(field_name, value: value, class: "form-control", placeholder: placeholder)
|
81
79
|
end
|
80
|
+
when "Boolean", "Mongoid::Boolean"
|
81
|
+
options = extract_inclusion_values(klass, field_name) || [nil, "true", "false"]
|
82
|
+
f.select(field_name, options, {include_blank: options.include?(nil), selected: value}, {class: "selectize form-control"})
|
82
83
|
when "Hash"
|
83
84
|
"[JSON Hash]\n".html_safe +
|
84
85
|
f.text_field(field_name, value: value ? value.to_json : "", class: "form-control", placeholder: '{"key1":"value1", "key2":"value2", "key3":"value3"}')
|
85
86
|
when "Array"
|
86
87
|
options = Array(value)
|
87
|
-
"
|
88
|
-
f.select(field_name, options_for_select(options, options), {include_hidden: false}, {class: "selectize form-control", multiple: true})
|
89
|
-
when "Mongoid::Boolean"
|
90
|
-
name = "#{field_name}_true".to_sym
|
91
|
-
value = value.to_s
|
92
|
-
str = '<div class="radio-buttons">'.html_safe
|
93
|
-
str << f.radio_button(field_name, "true", checked: value == "true")
|
94
|
-
str << " ".html_safe + f.label(name, "true")
|
95
|
-
str << " ".html_safe + f.radio_button(field_name, "false", checked: value == "false")
|
96
|
-
str << " ".html_safe + f.label(name, "false")
|
97
|
-
# Allow this field to be unset (nil).
|
98
|
-
if include_nil_selectors
|
99
|
-
str << " ".html_safe + f.radio_button(field_name, "", checked: value == "")
|
100
|
-
str << " ".html_safe + f.label(name, "nil")
|
101
|
-
end
|
102
|
-
|
103
|
-
str << "</div>".html_safe
|
88
|
+
f.select(field_name, options_for_select(options, options), {include_hidden: false}, {class: "selectize form-control", multiple: true})
|
104
89
|
else
|
105
90
|
"[#{field.type.name}]".html_safe +
|
106
91
|
f.text_field(field_name, value: value, class: "form-control", placeholder: placeholder)
|
107
92
|
end
|
108
93
|
end
|
94
|
+
|
95
|
+
# This method creates a link with `data-id` `data-fields` attributes. These attributes are used to create new instances of the nested fields through Javascript.
|
96
|
+
def link_to_add_fields(name, f, association, option)
|
97
|
+
# Takes an object (@job) and creates a new instance of its associated model (:properties)
|
98
|
+
new_object = f.object.send(association).klass.new
|
99
|
+
|
100
|
+
# Saves the unique ID of the object into a variable.
|
101
|
+
# This is needed to ensure the key of the associated array is unique. This is makes parsing the content in the `data-fields` attribute easier through Javascript.
|
102
|
+
# We could use another method to achive this.
|
103
|
+
id = new_object.object_id
|
104
|
+
|
105
|
+
# https://api.rubyonrails.org/ fields_for(record_name, record_object = nil, fields_options = {}, &block)
|
106
|
+
# record_name = :addresses
|
107
|
+
# record_object = new_object
|
108
|
+
# fields_options = { child_index: id }
|
109
|
+
# child_index` is used to ensure the key of the associated array is unique, and that it matched the value in the `data-id` attribute.
|
110
|
+
# `person[addresses_attributes][child_index_value][_destroy]`
|
111
|
+
fields = f.fields_for(association, new_object, child_index: id) do |builder|
|
112
|
+
# `association.to_s.singularize + "_fields"` ends up evaluating to `address_fields`
|
113
|
+
# The render function will then look for `views/people/_address_fields.html.erb`
|
114
|
+
# The render function also needs to be passed the value of 'builder', because `views/dirmon_entries/_input_categories.html.erb` needs this to render the form tags.
|
115
|
+
render(association.to_s.singularize + "_fields", f: builder)
|
116
|
+
end
|
117
|
+
|
118
|
+
# This renders a simple link, but passes information into `data` attributes.
|
119
|
+
# This info can be named anything we want, but in this case we chose `data-id:` and `data-fields:`.
|
120
|
+
# The `id:` is from `new_object.object_id`.
|
121
|
+
# The `fields:` are rendered from the `fields` blocks.
|
122
|
+
# We use `gsub("\n", "")` to remove anywhite space from the rendered partial.
|
123
|
+
# The `id:` value needs to match the value used in `child_index: id`.
|
124
|
+
link_to(name, '#', class: "add_fields btn btn-#{option}", data: { id: id, fields: fields.gsub("\n", "") })
|
125
|
+
end
|
109
126
|
end
|
110
127
|
end
|