rbbt-views 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/rbbt/workflow/rest.rb +150 -7
- data/lib/rbbt/workflow/rest/auth.rb +4 -4
- data/lib/rbbt/workflow/rest/entity.rb +115 -17
- data/lib/rbbt/workflow/rest/helpers.rb +49 -0
- data/lib/rbbt/workflow/rest/render.rb +64 -73
- data/lib/rbbt/workflow/rest/util.rb +124 -11
- data/share/views/compass/form.sass +0 -1
- data/share/views/compass/layout.sass +93 -2
- data/share/views/edit_list.haml +39 -0
- data/share/views/entity/GenomicMutation.haml +11 -1
- data/share/views/entity/KeggPathway.haml +4 -2
- data/share/views/entity/MutatedIsoform.haml +5 -33
- data/share/views/entity/MutatedIsoform/marked_svg.haml +3 -0
- data/share/views/entity/MutatedIsoform/pdbs.haml +33 -0
- data/share/views/entity/NCIBioCartaPathway.haml +11 -0
- data/share/views/entity/NCINaturePathway.haml +11 -0
- data/share/views/entity/NCIReactomePathway.haml +11 -0
- data/share/views/entity/Protein.haml +5 -0
- data/share/views/entity_list/Default.haml +1 -10
- data/share/views/js/app.js +336 -39
- data/share/views/layout.haml +20 -1
- data/share/views/partials/_form.haml +3 -1
- data/share/views/partials/_result_table.haml +4 -1
- data/share/views/public/plugins/jquery/js/jquery.cookie.js +47 -0
- data/share/views/user_lists.haml +10 -0
- metadata +14 -10
- data/share/views/entity/NCIBioCartaPathways.haml +0 -9
- data/share/views/entity/NCINaturePathways.haml +0 -9
- data/share/views/entity/NCIReactomePathways.haml +0 -9
data/lib/rbbt/workflow/rest.rb
CHANGED
@@ -12,6 +12,7 @@ require 'rbbt/workflow/rest/render.rb'
|
|
12
12
|
require 'rbbt/workflow/rest/auth.rb'
|
13
13
|
require 'rbbt/workflow/rest/email.rb'
|
14
14
|
require 'rbbt/workflow/rest/helpers.rb'
|
15
|
+
require 'rbbt/workflow/rest/entity.rb'
|
15
16
|
|
16
17
|
module WorkflowREST
|
17
18
|
|
@@ -29,9 +30,18 @@ module WorkflowREST
|
|
29
30
|
|
30
31
|
Sinatra.module_eval do
|
31
32
|
helpers Sinatra::SinatraRbbt
|
32
|
-
enable :sessions
|
33
33
|
enable :static
|
34
34
|
|
35
|
+
# This would make random secrets that would make the server hang after reload by old cookies.
|
36
|
+
# enable :sessions
|
37
|
+
# Util fix...
|
38
|
+
use Rack::Session::Cookie, :key => 'rack.session',
|
39
|
+
:path => '/',
|
40
|
+
:expire_after => 2592000,
|
41
|
+
:secret => 'rbbt_default_secret. Please CHANGE!'
|
42
|
+
|
43
|
+
set :cache_dir, "cache"
|
44
|
+
|
35
45
|
before do
|
36
46
|
@file_cache = {}
|
37
47
|
@result_cache = {}
|
@@ -53,6 +63,7 @@ module WorkflowREST
|
|
53
63
|
request.env['REMOTE_USER'] == user || throw(:halt, [ 401, 'Authorization Required' ])
|
54
64
|
end
|
55
65
|
end
|
66
|
+
|
56
67
|
end
|
57
68
|
|
58
69
|
set :public_folder, RbbtHTMLHelpers.locate_file(nil, nil, 'public/').find
|
@@ -69,6 +80,8 @@ module WorkflowREST
|
|
69
80
|
|
70
81
|
if production?
|
71
82
|
before do
|
83
|
+
params.delete "_"
|
84
|
+
params.delete :_
|
72
85
|
cache_control :public, :must_revalidate, :max_age => 60
|
73
86
|
end
|
74
87
|
Log.severity = 0
|
@@ -78,7 +91,7 @@ module WorkflowREST
|
|
78
91
|
file = locate_file(WorkflowREST.workflows.last, nil, File.join("compass", params[:name] + '.sass'))
|
79
92
|
|
80
93
|
content_type 'text/css', :charset => 'utf-8'
|
81
|
-
cache('css', params) do
|
94
|
+
cache('css', params.merge(:cache_type => :sync)) do
|
82
95
|
renderer = Sass::Engine.new(file.read)
|
83
96
|
renderer.render
|
84
97
|
end
|
@@ -93,27 +106,155 @@ module WorkflowREST
|
|
93
106
|
type = params[:type]
|
94
107
|
|
95
108
|
visualization_parameters = get_visualization_parameters(params)
|
109
|
+
|
110
|
+
cache_type = params.delete(:_cache_type) || params.delete("_cache_type") || :sync
|
111
|
+
|
96
112
|
cache("Entity:", :params => params, :visualization_params => visualization_parameters, :user => user) do
|
97
113
|
entity_render(type, params.merge(visualization_parameters))
|
98
114
|
end
|
99
115
|
end
|
100
116
|
|
117
|
+
#{{{ entity_list
|
118
|
+
|
119
|
+
get '/entity_list/:user' do
|
120
|
+
list_user = params.delete(:user) || params.delete("user")
|
121
|
+
|
122
|
+
list_user = user if list_user.to_s == "user"
|
123
|
+
|
124
|
+
if list_user != "public"
|
125
|
+
raise "Not allowed to view entity lists for: #{ user }" unless authorized? and user.to_s == list_user
|
126
|
+
end
|
127
|
+
|
128
|
+
lists = Entity::REST.list_files(list_user)
|
129
|
+
workflow_render('user_lists', params.merge(:lists => lists))
|
130
|
+
end
|
131
|
+
|
101
132
|
get '/entity_list/:type/:id' do
|
102
133
|
type = params.delete "type"
|
103
134
|
visualization_parameters = get_visualization_parameters(params)
|
104
135
|
|
105
|
-
|
106
|
-
|
136
|
+
cache_type = params.delete(:_cache_type) || params.delete("_cache_type") || :sync
|
137
|
+
update = params.delete(:_update) || params.delete("_update") || nil
|
138
|
+
|
139
|
+
check = Entity::REST.list_file(type, params[:id], user)
|
140
|
+
check = Entity::REST.list_file(type, params[:id]) unless not check.nil? and File.exists? check
|
141
|
+
|
142
|
+
raise "List of type #{ type } not found for #{params[:id]}: #{ check.inspect }" if check.nil? or not File.exists?(check)
|
143
|
+
|
144
|
+
cache("Entity List:", :check => [check], :update => update, :cache_type => cache_type, :params => params, :type => type, :visualization_params => visualization_parameters, :user => user) do
|
145
|
+
if visualization_parameters[:_format] == 'json'
|
146
|
+
list = Entity::REST.load_list(type, params[:id], user)
|
147
|
+
list.collect{|elem| [elem.clean_annotations, elem.info]}.to_json
|
148
|
+
else
|
149
|
+
entity_list_render(type, params.merge(visualization_parameters))
|
150
|
+
end
|
107
151
|
end
|
108
152
|
end
|
109
153
|
|
154
|
+
post '/entity_list/:type/copy/:id' do
|
155
|
+
type = params.delete "type"
|
156
|
+
|
157
|
+
list = Entity::REST.load_list(type, params[:id], user)
|
158
|
+
Entity::REST.save_list(type, params[:new_id], list, user)
|
159
|
+
|
160
|
+
redirect "/entity_list/#{ type }/#{params[:new_id]}"
|
161
|
+
end
|
162
|
+
|
163
|
+
post '/entity_list/:type/add/:id' do
|
164
|
+
type = params.delete "type"
|
165
|
+
|
166
|
+
list = Entity::REST.load_list(type, params[:id], user)
|
167
|
+
other_list = Entity::REST.load_list(type, params[:other_list], user)
|
168
|
+
list.concat other_list
|
169
|
+
Entity::REST.save_list(type, params[:id], list, user)
|
170
|
+
|
171
|
+
redirect back
|
172
|
+
end
|
173
|
+
|
174
|
+
post '/entity_list/:type/remove/:id' do
|
175
|
+
type = params.delete "type"
|
176
|
+
|
177
|
+
list = Entity::REST.load_list(type, params[:id], user)
|
178
|
+
other_list = Entity::REST.load_list(type, params[:other_list], user)
|
179
|
+
Entity::REST.save_list(type, params[:id], list.remove(other_list), user)
|
180
|
+
|
181
|
+
redirect back
|
182
|
+
end
|
183
|
+
|
184
|
+
post '/entity_list/:type/subset/:id' do
|
185
|
+
type = params.delete "type"
|
186
|
+
|
187
|
+
list = Entity::REST.load_list(type, params[:id], user)
|
188
|
+
other_list = Entity::REST.load_list(type, params[:other_list], user)
|
189
|
+
Entity::REST.save_list(type, params[:id], list.subset(other_list), user)
|
190
|
+
|
191
|
+
redirect back
|
192
|
+
end
|
193
|
+
|
194
|
+
get '/entity_list/:type/edit/:id' do
|
195
|
+
type = params[:type]
|
196
|
+
visualization_parameters = get_visualization_parameters(params)
|
197
|
+
|
198
|
+
workflow = WorkflowREST.workflows.last
|
199
|
+
id = params[:id]
|
200
|
+
list = Entity::REST.load_list(type, id, user)
|
201
|
+
workflow_render('edit_list', workflow, params.merge(:list => list))
|
202
|
+
end
|
203
|
+
|
204
|
+
delete '/entity_list/:type/:id' do
|
205
|
+
Entity::REST.delete_list(params[:type], params[:id], user)
|
206
|
+
redirect '/'
|
207
|
+
end
|
208
|
+
|
209
|
+
# entities
|
210
|
+
delete '/entity_list/:type/:entity/:id' do
|
211
|
+
id = params[:id]
|
212
|
+
Log.debug "Deleting #{params[:entity] } from #{params[:id]}"
|
213
|
+
|
214
|
+
list = Entity::REST.load_list(params[:type], id, user)
|
215
|
+
|
216
|
+
list.delete params[:entity]
|
217
|
+
|
218
|
+
Entity::REST.save_list(params[:type], id, list, user)
|
219
|
+
|
220
|
+
redirect back
|
221
|
+
end
|
222
|
+
|
223
|
+
post '/entity_list/:type/:entity/:id' do
|
224
|
+
id = params.delete(:id) || params.delete("id")
|
225
|
+
entity = params.delete(:entity) || params.delete("entity")
|
226
|
+
type = params.delete(:type) || params.delete("type")
|
227
|
+
|
228
|
+
info = {}
|
229
|
+
params.each{|k,v| info[k] = begin JSON.parse(v) rescue v end}
|
230
|
+
entity = Annotated.load_tsv_values(entity, [[info.to_json]], "JSON")
|
231
|
+
|
232
|
+
list = Entity::REST.load_list(type, id, user)
|
233
|
+
|
234
|
+
|
235
|
+
different = entity.info.select{|k,v| not v.nil? and v != list_info[k]}.any?
|
236
|
+
|
237
|
+
|
238
|
+
new = list.collect{|e| e} if different
|
239
|
+
new.delete entity
|
240
|
+
new << entity
|
241
|
+
Entity::REST.save_list(type, id, new, user)
|
242
|
+
|
243
|
+
redirect back
|
244
|
+
end
|
245
|
+
|
246
|
+
#{{{ entity_action
|
247
|
+
|
110
248
|
get '/entity_action/:type/:action/:entity' do
|
111
249
|
type = params.delete "type"
|
112
250
|
action = params.delete "action"
|
113
251
|
|
114
252
|
visualization_parameters = get_visualization_parameters(params)
|
115
253
|
|
116
|
-
|
254
|
+
cache_type = params.delete(:_cache_type) || params.delete("_cache_type") || :async
|
255
|
+
update = params.delete(:_update) || params.delete("_update") || nil
|
256
|
+
|
257
|
+
cache("Entity Action [#{action}][#{ params[:entity] }]", :update => update, :cache_type => cache_type, :params => params, :type => type, :action => action, :visualization_params => visualization_parameters, :user => user) do
|
117
258
|
entity_action_render(type, action, params.merge(visualization_parameters))
|
118
259
|
end
|
119
260
|
end
|
@@ -124,7 +265,10 @@ module WorkflowREST
|
|
124
265
|
|
125
266
|
visualization_parameters = get_visualization_parameters(params)
|
126
267
|
|
127
|
-
|
268
|
+
cache_type = params.delete(:_cache_type) || params.delete("_cache_type") || :async
|
269
|
+
update = params.delete(:_update) || params.delete("_update") || nil
|
270
|
+
|
271
|
+
cache("Entity List Action [#{action}] [#{ params[:id]}]", :update => update, :cache_type => cache_type, :params => params, :type => type, :action => action, :visualization_params => visualization_parameters, :user => user) do
|
128
272
|
entity_list_action_render(type, action, params.merge(visualization_parameters))
|
129
273
|
end
|
130
274
|
end
|
@@ -518,5 +662,4 @@ module WorkflowREST
|
|
518
662
|
end
|
519
663
|
|
520
664
|
end
|
521
|
-
|
522
665
|
end
|
@@ -38,15 +38,15 @@ module Sinatra
|
|
38
38
|
end
|
39
39
|
|
40
40
|
app.post '/login' do
|
41
|
-
Log.debug "
|
42
|
-
if
|
43
|
-
Log.debug "
|
41
|
+
Log.debug "Login: #{params.inspect}"
|
42
|
+
if settings.users.include? params[:user] and settings.users[params[:user]] == params[:pass]
|
43
|
+
Log.debug "Login Successful"
|
44
44
|
session[:authorized] = true
|
45
45
|
session[:user] = params[:user]
|
46
46
|
session[:context] = nil
|
47
47
|
redirect '/'
|
48
48
|
else
|
49
|
-
Log.debug "
|
49
|
+
Log.debug "Login Failed"
|
50
50
|
session[:authorized] = false
|
51
51
|
session[:user] = nil
|
52
52
|
session[:context] = nil
|
@@ -1,7 +1,16 @@
|
|
1
1
|
module Entity
|
2
2
|
|
3
3
|
module REST
|
4
|
-
|
4
|
+
include RbbtHTMLHelpers
|
5
|
+
|
6
|
+
def rbbt_id
|
7
|
+
return "" unless self.annotations.include? :format and String === self.format
|
8
|
+
([self.format.downcase, self] * "=").gsub(/[^\w]/,'_')
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :list_repo
|
13
|
+
end
|
5
14
|
|
6
15
|
def link(text = nil, url = nil, options = {})
|
7
16
|
return nil if self.nil?
|
@@ -19,7 +28,7 @@ module Entity
|
|
19
28
|
text = self if text.nil? or text == :literal or text.to_s.strip.empty?
|
20
29
|
|
21
30
|
klass = options[:class]
|
22
|
-
klass ||= "entity " + (self.respond_to?(:format)? self.format.gsub(/\s/,'_') : annotation_types.collect{|t| t.to_s.gsub(/\s/,'_')} * " ")
|
31
|
+
klass ||= "entity " + ((self.respond_to?(:format) and not self.format.nil?) ? self.format.gsub(/\s/,'_') : annotation_types.collect{|t| t.to_s.gsub(/\s/,'_')} * " ")
|
23
32
|
|
24
33
|
klass += " " << options[:extra_classes] || "" if options.include? :extra_classes
|
25
34
|
klass += " " << html_class if self.respond_to? :html_class
|
@@ -38,31 +47,102 @@ module Entity
|
|
38
47
|
end
|
39
48
|
|
40
49
|
annotations_str = params.collect{|k,v| [k, CGI.escape(v.to_s)] * "="} * "&"
|
41
|
-
"<a class='#{klass}' href='#{url + (annotations_str.any? ? '?' + annotations_str : "")}'>#{text}</a>"
|
50
|
+
"<a class='#{klass}' #{rbbt_id} href='#{url + (annotations_str.any? ? '?' + annotations_str : "")}'>#{text}</a>"
|
42
51
|
end
|
43
52
|
end
|
44
53
|
|
45
|
-
def self.
|
46
|
-
|
54
|
+
def self.list_file(type, id, user = nil)
|
55
|
+
type = type.split(":").first if not type.nil? and type.index ':'
|
56
|
+
if production?
|
57
|
+
if user.nil?
|
58
|
+
File.join(Entity.entity_list_cache, type.to_s, id)
|
59
|
+
else
|
60
|
+
File.join(Entity.entity_list_cache, user.to_s, type.to_s, id)
|
61
|
+
end
|
62
|
+
else
|
63
|
+
nil
|
64
|
+
end
|
47
65
|
end
|
48
66
|
|
49
|
-
def self.
|
50
|
-
|
67
|
+
def self.list_files(user)
|
68
|
+
if production?
|
69
|
+
lists = {}
|
70
|
+
Dir.glob(File.join(Entity.entity_list_cache, user, '*', '*')).each do |file|
|
71
|
+
user, type, list = file.split("/")[-3..-1]
|
72
|
+
lists[type] ||= []
|
73
|
+
lists[type] << list
|
74
|
+
end
|
75
|
+
lists
|
76
|
+
else
|
77
|
+
{}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.load_list(type, id, user = nil)
|
82
|
+
if production?
|
83
|
+
path = list_file(type, id, user)
|
84
|
+
path = list_file(type, id, :public) unless File.exists? path
|
85
|
+
path = list_file(type, id) unless File.exists? path
|
86
|
+
|
87
|
+
Misc.lock path do
|
88
|
+
Annotated.load_tsv TSV.open(path)
|
89
|
+
end
|
90
|
+
else
|
91
|
+
@@list_cache ||= {}
|
92
|
+
@@list_cache[id]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.save_list(type, id, list, user = nil)
|
97
|
+
if production?
|
98
|
+
path = list_file(type, id, user)
|
99
|
+
|
100
|
+
Misc.lock path do
|
101
|
+
begin
|
102
|
+
Open.write(path, Annotated.tsv(list, :all).to_s)
|
103
|
+
rescue
|
104
|
+
FileUtils.rm path if File.exists? path
|
105
|
+
raise $!
|
106
|
+
end
|
107
|
+
end
|
108
|
+
else
|
109
|
+
@@list_cache ||= {}
|
110
|
+
@@list_cache[id] = list
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
def self.delete_list(type, id, user)
|
116
|
+
if production?
|
117
|
+
path = list_file(type, id, user)
|
118
|
+
"This list does not belong to #{ user }: #{[type, id] * ": "}" unless File.exists? path
|
119
|
+
Misc.lock path do
|
120
|
+
begin
|
121
|
+
FileUtils.rm path if File.exists? path
|
122
|
+
rescue
|
123
|
+
raise $!
|
124
|
+
end
|
125
|
+
end
|
126
|
+
else
|
127
|
+
@@list_cache.delete(id) if @@list_cache and @@list_cache.include? id
|
128
|
+
end
|
51
129
|
end
|
52
130
|
|
53
131
|
def list_link(text = nil, id = nil, options = {})
|
54
|
-
|
132
|
+
reuse = options.delete("reuse") || options.delete(:reuse)
|
133
|
+
text = self.length if text.nil? or (String === text and text.strip.empty?) or text == :length
|
55
134
|
|
56
135
|
id ||= options[:id] || Misc.digest((self * "|").inspect)
|
57
136
|
|
58
|
-
Entity::REST.save_list(id, self)
|
59
137
|
|
60
|
-
klass = self.respond_to?(:format)? self.format.gsub(/\s/,'_') : annotation_types.collect{|t| t.to_s.gsub(/\s/,'_')} * " "
|
138
|
+
klass = (self.respond_to?(:format) and not self.format.nil?) ? self.format.gsub(/\s/,'_') : annotation_types.collect{|t| t.to_s.gsub(/\s/,'_')} * " "
|
61
139
|
|
62
140
|
klass += " " << options[:extra_classes] if options.include? :extra_classes
|
63
141
|
klass += " " << html_class if self.respond_to? :html_class
|
64
142
|
|
65
|
-
type = self.respond_to?(:format)? annotation_types.last.to_s + ":" + self.format : annotation_types.last.to_s
|
143
|
+
type = (self.respond_to?(:format) and not self.format.nil?) ? annotation_types.last.to_s + ":" + self.format : annotation_types.last.to_s
|
144
|
+
|
145
|
+
Entity::REST.save_list(annotation_types.last.to_s, id, self) unless reuse
|
66
146
|
|
67
147
|
annotations_str = self.info.reject{|k,v| [:annotation_types, :format].include?(k)}.collect{|k,v| [k, CGI.escape(v.to_s)] * "="} * "&"
|
68
148
|
|
@@ -71,32 +151,50 @@ module Entity
|
|
71
151
|
|
72
152
|
def action_link(action, text = nil, inputs = {})
|
73
153
|
options = inputs.delete(:link_options) || {}
|
154
|
+
options[:extra_classes] = inputs.delete(:extra_classes) || inputs.delete("extra_class") if inputs.include?(:extra_classes) or inputs.include?("extra_classes")
|
74
155
|
clean_inputs = {}
|
75
156
|
inputs.each do |k, v|
|
76
157
|
clean_inputs[k] = Array === v ? v * "," : v
|
77
158
|
end
|
78
|
-
|
159
|
+
|
160
|
+
klass ||= "entity_action " + (self.respond_to?(:format)? self.format.gsub(/\s/,'_') : annotation_types.collect{|t| t.to_s.gsub(/\s/,'_')} * " ")
|
161
|
+
klass += " " << options[:extra_classes] if options.include? :extra_classes
|
162
|
+
klass += " " << html_class if self.respond_to? :html_class
|
163
|
+
|
164
|
+
link(text, nil, options.merge(:extra_params => clean_inputs, :action => action, :class => klass))
|
79
165
|
end
|
80
166
|
|
81
167
|
def list_action_link(action, text = nil, id = nil, options = {})
|
168
|
+
reuse = options.delete("reuse") || options.delete(:reuse)
|
169
|
+
|
82
170
|
text = self.length if text.nil? or (String === text and text.strip.empty?)
|
83
171
|
id ||= options[:id] || Misc.digest((self * "|").inspect)
|
84
172
|
|
85
173
|
text = id if text == :id
|
86
174
|
|
87
|
-
Entity::REST.save_list(id, self)
|
88
175
|
|
89
|
-
klass = self.respond_to?(:format)? self.format.gsub(/\s/,'_') : annotation_types.collect{|t| t.to_s.gsub(/\s/,'_')} * " "
|
176
|
+
klass = (self.respond_to?(:format) and not self.format.nil?) ? self.format.gsub(/\s/,'_') : annotation_types.collect{|t| t.to_s.gsub(/\s/,'_')} * " "
|
90
177
|
|
91
|
-
klass += " " << options
|
178
|
+
klass += " " << options.delete(:extra_classes) if options.include? :extra_classes
|
92
179
|
klass += " " << html_class if self.respond_to? :html_class
|
93
180
|
|
94
|
-
type = self.respond_to?(:format)? annotation_types.last.to_s + ":" + self.format : annotation_types.last.to_s
|
181
|
+
type = (self.respond_to?(:format) and not self.format.nil?)? annotation_types.last.to_s + ":" + self.format : annotation_types.last.to_s
|
95
182
|
|
96
|
-
|
183
|
+
Entity::REST.save_list(annotation_types.last.to_s, id, self) unless reuse
|
184
|
+
|
185
|
+
annotations_str = self.info.merge(options).reject{|k,v| [:annotation_types, :format].include?(k)}.collect{|k,v| [k, CGI.escape(v.to_s)] * "="} * "&"
|
97
186
|
|
98
187
|
"<a class='entity_list_action #{klass}' href='#{File.join("/entity_list_action", type, action, id) + (annotations_str.any? ? '?' + annotations_str : "")}'>#{text}</a>"
|
99
188
|
end
|
100
189
|
|
190
|
+
def html_table(fields, workflow = nil, field_names = nil)
|
191
|
+
raise "Must be an Array to produce html table: #{self.inspect}" unless Array === self
|
192
|
+
rows = self.collect{|entity|
|
193
|
+
[entity.id, entity.tsv_values(fields)]
|
194
|
+
}
|
195
|
+
|
196
|
+
workflow_partial('partials/_table', workflow = nil, :rows => rows, :header => field_names || fields)
|
197
|
+
end
|
198
|
+
|
101
199
|
end
|
102
200
|
end
|
@@ -35,4 +35,53 @@ module RbbtHTMLHelpers
|
|
35
35
|
str
|
36
36
|
end
|
37
37
|
end
|
38
|
+
|
39
|
+
def input(type, name, options = {})
|
40
|
+
id, hide, value, klass, default, description, select_options = Misc.process_options options, :id, :hide, :value, :class, :default, :description, :select_options
|
41
|
+
str = "<div class='form_input' id='#{ id }'>"
|
42
|
+
|
43
|
+
if hide
|
44
|
+
str << "<input #{"id='#{ id }'" if id} type='hidden' name='#{ name }' #{"class='#{ klass }'" if klass} #{"value='#{ value }'" if value}/>" << '</div>' << "\n"
|
45
|
+
return str
|
46
|
+
end
|
47
|
+
|
48
|
+
case type
|
49
|
+
when :select
|
50
|
+
str << "<label #{"for='#{ id }" if id}'><span class='input_name'>#{ name }</span>#{": <span class='input_description'>#{ description }</span>" if description}</label>" << "\n"
|
51
|
+
str << "<select id='input_#{id}_true' name='#{ name }'>" << "\n"
|
52
|
+
if not select_options.nil?
|
53
|
+
select_options.each do |option|
|
54
|
+
option, option_name = option if Array === option
|
55
|
+
option_name ||= option
|
56
|
+
str << "<option id='input_#{id}_option_#{option.to_s}' value='#{option.to_s}' #{option.to_s == value.to_s ? "selected=selected" : "" }>" << option_name.to_s << "</option>" << "\n"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
str << "</select>" << "\n"
|
60
|
+
str << "</div>"
|
61
|
+
str
|
62
|
+
when :boolean
|
63
|
+
not_value = ! value
|
64
|
+
str << "<label #{"for='#{ id }" if id}'><span class='input_name'>#{ name }</span>#{": <span class='input_description'>#{ description }</span>" if description}</label>" << "\n"
|
65
|
+
str << "<input type='radio' id='input_#{id}_true' name='#{ name }' value='true' #{"checked='true'" if value}>" << "\n"
|
66
|
+
str << "<label type='radio_option radio_true' for='input_#{id}_true' name='#{ name }'>true</label>" << "\n"
|
67
|
+
str << "<input type='radio' id='input_#{id}_false' name='#{ name }' value='false' #{"checked='false'" if not value}>" << "\n"
|
68
|
+
str << "<label type='radio_option radio_false' for='input_#{id}_false' name='#{ name }'>false</label>" << "\n"
|
69
|
+
str << "</div>"
|
70
|
+
str
|
71
|
+
when :string, :float, :integer
|
72
|
+
str << "<label #{"for='#{ id }" if id}'><span class='input_name'>#{ name }</span>#{": <span class='input_description'>#{ description }</span>" if description}#{": <span class='input_default'>(Default: #{ default })</span>" if default}</label>" << "\n"
|
73
|
+
str << "<input #{"class='#{klass ? klass : "#{ name } #{ type }" }'"} #{"id='#{ id }'" if id} name='#{ name }' #{"value='#{ value }'" if value}/>" << "\n"
|
74
|
+
str << "</div>"
|
75
|
+
str
|
76
|
+
when :tsv, :array, :text
|
77
|
+
str << "<label #{"for='#{ id }" if id}'><span class='input_name'>#{ name }</span>#{": <span class='input_description'>#{ description }</span>" if description}#{": <span class='input_default'>(Default: #{ default })</span>" if default}</label>" << "\n"
|
78
|
+
str << "<p>"
|
79
|
+
str << "<input type='file' #{"class='#{klass ? klass : "#{ name } #{ type }" }'"} #{"id='input_#{ id }_tsv_file'" if id} name='#{ name }_param_file' #{"value='#{ value }'" if value}/>" << "\n"
|
80
|
+
str << "<span class='tsv_textarea_note note'>(or use text area bellow)</span>"
|
81
|
+
str << "</p>"
|
82
|
+
str << "<textarea #{"class='#{klass ? klass : "#{ name } #{ type }" }'"} name='#{ name }' #{"id='input_#{ id }'" if id}></textarea>"
|
83
|
+
str << "</div>"
|
84
|
+
str
|
85
|
+
end
|
86
|
+
end
|
38
87
|
end
|