rbbt-rest 1.1.0 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rbbt/rest/common/cache.rb +3 -1
- data/lib/rbbt/rest/common/misc.rb +14 -7
- data/lib/rbbt/rest/common/resources.rb +0 -1
- data/lib/rbbt/rest/common/table.rb +46 -5
- data/lib/rbbt/rest/entity.rb +7 -0
- data/lib/rbbt/rest/entity/helpers.rb +3 -2
- data/lib/rbbt/rest/main.rb +3 -1
- data/lib/rbbt/rest/web_tool.rb +8 -0
- data/lib/rbbt/rest/workflow.rb +2 -1
- data/lib/rbbt/rest/workflow/jobs.rb +2 -0
- data/share/views/compass/_foundation_setup.sass +1 -6
- data/share/views/compass/actions.sass +1 -3
- data/share/views/compass/app.sass +8 -6
- data/share/views/compass/dom.sass +0 -10
- data/share/views/compass/form.sass +2 -0
- data/share/views/compass/list_container.sass +4 -2
- data/share/views/compass/offcanvas.sass +2 -2
- data/share/views/compass/style.sass +5 -17
- data/share/views/compass/style_mixins.sass +19 -1
- data/share/views/compass/table.sass +3 -0
- data/share/views/compass/tabs.sass +9 -16
- data/share/views/job_result.haml +4 -0
- data/share/views/job_result/integer.haml +1 -0
- data/share/views/job_result/text.haml +1 -0
- data/share/views/layout.haml +5 -2
- data/share/views/partials/table.haml +10 -0
- data/share/views/public/js/helpers.js +14 -0
- data/share/views/public/js/lists.js +16 -2
- data/share/views/public/js/offcanvas.js +2 -0
- data/share/views/public/js/tables.js +89 -27
- data/share/views/public/js/workflow.js +29 -0
- data/share/views/public/plugins/jquery/js/jquery-1.9.1.js +9597 -0
- data/share/views/public/plugins/jquery/js/jquery-2.0.0.js +8755 -0
- metadata +8 -2
@@ -39,7 +39,9 @@ module RbbtRESTHelpers
|
|
39
39
|
content_type "text/tab-separated-values"
|
40
40
|
send_file fragment_file
|
41
41
|
when "table"
|
42
|
-
tsv2html
|
42
|
+
halt 200, tsv2html(fragment_file)
|
43
|
+
when "json"
|
44
|
+
halt 200, tsv_process(TSV.open(fragment_file)).to_json
|
43
45
|
when "excel"
|
44
46
|
require 'rbbt/tsv/excel'
|
45
47
|
tsv = TSV.open(Open.open(fragment_file))
|
@@ -52,8 +52,10 @@ module RbbtRESTHelpers
|
|
52
52
|
@splat = consume_parameter :splat
|
53
53
|
@captures = consume_parameter :captures
|
54
54
|
|
55
|
-
#
|
55
|
+
# TSV table pagination, filtering, and slicing
|
56
56
|
@page = consume_parameter :_page
|
57
|
+
@filter = consume_parameter :_filter
|
58
|
+
@column = consume_parameter :_column
|
57
59
|
|
58
60
|
# Fix boolean inputs sumbitted using checkboxes
|
59
61
|
params.keys.each do |param|
|
@@ -106,14 +108,19 @@ module RbbtRESTHelpers
|
|
106
108
|
value
|
107
109
|
end
|
108
110
|
|
109
|
-
|
111
|
+
case
|
112
|
+
when Array === text
|
110
113
|
text
|
111
|
-
|
112
|
-
|
114
|
+
when text =~ /^list:([^:]+):(.+)$/
|
115
|
+
Entity::List.load_list($1, $2, user)
|
116
|
+
when text =~ /\[.*\]/
|
113
117
|
JSON.parse(text)
|
114
|
-
|
115
|
-
|
116
|
-
|
118
|
+
when text =~ /\n/
|
119
|
+
text.split(/\r?\n/).collect{|l| l.strip}
|
120
|
+
when text =~ /\|/
|
121
|
+
text.split(/\|/).collect{|l| l.strip}
|
122
|
+
else
|
123
|
+
text.split(/,/).collect{|l| l.strip}
|
117
124
|
end
|
118
125
|
|
119
126
|
when :tsv
|
@@ -49,7 +49,6 @@ module RbbtRESTHelpers
|
|
49
49
|
} * "\n"
|
50
50
|
|
51
51
|
FileUtils.mkdir_p File.dirname(filename) unless File.exists? File.dirname(filename)
|
52
|
-
#Open.write(filename, YUI::JavaScriptCompressor.new(:munge => false).compress(text))
|
53
52
|
Open.write(filename, Uglifier.compile(text))
|
54
53
|
end
|
55
54
|
|
@@ -94,7 +94,31 @@ module RbbtRESTHelpers
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
-
def
|
97
|
+
def tsv_process(tsv, filter = nil, column = nil)
|
98
|
+
filter = @filter if filter.nil?
|
99
|
+
column = @column if column.nil?
|
100
|
+
|
101
|
+
if filter and filter.to_s != "false"
|
102
|
+
filter.split("|").each do |f|
|
103
|
+
key, value = f.split("~")
|
104
|
+
case
|
105
|
+
when value =~ /^([<>]=?)(.*)/
|
106
|
+
tsv = tsv.select(key){|k| k.send($1, $2)}
|
107
|
+
when value =~ /^\/.*\/$/
|
108
|
+
tsv = tsv.select(key => Regexp.new(value))
|
109
|
+
else
|
110
|
+
tsv = tsv.select(key => value)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
tsv = tsv.column(column) if column and not column.empty?
|
116
|
+
|
117
|
+
tsv
|
118
|
+
end
|
119
|
+
|
120
|
+
def tsv_rows(tsv, page = nil, filter = nil, column = nil)
|
121
|
+
tsv = tsv_process(tsv, filter, column)
|
98
122
|
page = @page if page.nil?
|
99
123
|
if page.nil? or page.to_s == "false"
|
100
124
|
tsv_rows_full(tsv)
|
@@ -122,6 +146,11 @@ module RbbtRESTHelpers
|
|
122
146
|
@table_headers[field] = [entity_type, entity_options]
|
123
147
|
end
|
124
148
|
|
149
|
+
def filter(field, type = :string)
|
150
|
+
@table_filters ||= {}
|
151
|
+
@table_filters[field] = type
|
152
|
+
end
|
153
|
+
|
125
154
|
def table(options = {})
|
126
155
|
options = {} if options.nil?
|
127
156
|
|
@@ -146,24 +175,36 @@ module RbbtRESTHelpers
|
|
146
175
|
@table_headers = {}
|
147
176
|
end
|
148
177
|
|
178
|
+
if @table_filters and @table_filters.any?
|
179
|
+
options[:filters] = @table_filters
|
180
|
+
@table_filters = {}
|
181
|
+
end
|
182
|
+
|
149
183
|
Open.write table_file, tsv.to_s
|
150
184
|
Open.write table_file + '.table_options', options.to_yaml if defined? options.any?
|
151
185
|
|
152
186
|
total_size = tsv.size
|
153
187
|
if options[:page].nil? and total_size > PAGE_SIZE * 1.2
|
154
|
-
page = "1"
|
188
|
+
@page = "1"
|
155
189
|
end
|
156
190
|
|
157
|
-
|
191
|
+
tsv2html(table_file)
|
192
|
+
end
|
193
|
+
|
194
|
+
def load_tsv(file)
|
195
|
+
tsv
|
158
196
|
end
|
159
197
|
|
160
198
|
def tsv2html(file)
|
161
199
|
tsv = TSV.open(Open.open(file))
|
162
|
-
|
200
|
+
|
201
|
+
table_options = File.exists?(file + '.table_options') ? YAML.load_file(file + '.table_options') : {}
|
163
202
|
tsv.entity_options = table_options[:tsv_entity_options]
|
164
203
|
headers = table_options[:headers]
|
204
|
+
filters = table_options[:filters]
|
165
205
|
headers.each{|field,p| tsv.entity_templates[field] = Misc.prepare_entity("TEMPLATE", p.first, p.last) } unless headers.nil?
|
206
|
+
|
166
207
|
content_type "text/html"
|
167
|
-
|
208
|
+
partial_render('partials/table', {:filters => filters, :total_size => tsv.size, :rows => tsv_rows(tsv), :header => tsv.all_fields, :table_options => table_options})
|
168
209
|
end
|
169
210
|
end
|
data/lib/rbbt/rest/entity.rb
CHANGED
@@ -110,6 +110,13 @@ module Sinatra
|
|
110
110
|
send_file global_file if File.exists? global_file
|
111
111
|
|
112
112
|
raise "List file not found: #{ list_id }"
|
113
|
+
when :json
|
114
|
+
list = Entity::List.load_list(entity_type.split(":").first, list_id, user)
|
115
|
+
list_info = {:entities => list, :info => list.info}
|
116
|
+
halt 200, list_info.to_json
|
117
|
+
when :info
|
118
|
+
list = Entity::List.load_list(entity_type.split(":").first, list_id, user)
|
119
|
+
halt 200, list.info.to_json
|
113
120
|
when :list
|
114
121
|
list = Entity::List.load_list(entity_type.split(":").first, list_id, user)
|
115
122
|
|
@@ -14,7 +14,7 @@ module EntityRESTHelpers
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def action_parameters(values = nil, &block)
|
17
|
+
def action_parameters(values = nil, action_options = {}, form_options = {}, &block)
|
18
18
|
o = Object.new
|
19
19
|
o.extend AnnotatedModule
|
20
20
|
|
@@ -46,8 +46,9 @@ module EntityRESTHelpers
|
|
46
46
|
locals[:action] = @ajax_url
|
47
47
|
locals[:klass] = 'action_parameter_form'
|
48
48
|
locals[:info] = info
|
49
|
+
locals = locals.merge(form_options)
|
49
50
|
|
50
|
-
html_tag :div, partial_render('partials/form', locals), :class => 'action_parameters'
|
51
|
+
html_tag :div, partial_render('partials/form', locals), {:class => 'action_parameters'}.merge(action_options)
|
51
52
|
end
|
52
53
|
|
53
54
|
def page_type(path = nil)
|
data/lib/rbbt/rest/main.rb
CHANGED
@@ -17,6 +17,8 @@ module Sinatra
|
|
17
17
|
helpers RbbtRESTHelpers
|
18
18
|
register Sinatra::RbbtAuth
|
19
19
|
|
20
|
+
add_sass_load_path Rbbt.share.views.compass.find(:lib)
|
21
|
+
|
20
22
|
set :cache_dir, Rbbt.var.sinatra.cache.find unless settings.respond_to? :cache_dir and settings.cache_dir != nil
|
21
23
|
set :file_dir, Rbbt.var.sinatra.files.find unless settings.respond_to? :file_dir and settings.file_dir != nil
|
22
24
|
|
@@ -32,7 +34,7 @@ module Sinatra
|
|
32
34
|
end
|
33
35
|
|
34
36
|
before do
|
35
|
-
Log.debug("IP #{request.ip}: " << request.path_info << ". Params: " << params.inspect)
|
37
|
+
Log.debug("IP #{request.ip}: " << request.path_info << ". Params: " << Misc.remove_long_items(params).inspect)
|
36
38
|
process_common_parameters
|
37
39
|
|
38
40
|
if profile
|
data/lib/rbbt/rest/workflow.rb
CHANGED
@@ -26,6 +26,7 @@ module Sinatra
|
|
26
26
|
add_sass_load_path views_dir.compass if views_dir.compass.exists?
|
27
27
|
|
28
28
|
RbbtRESTHelpers.javascript_resources.unshift views_dir.public.js if views_dir.public.js.exists?
|
29
|
+
RbbtRESTHelpers.sass_resources.unshift views_dir.compass if views_dir.compass.exists?
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
@@ -36,7 +37,7 @@ module Sinatra
|
|
36
37
|
|
37
38
|
Log.debug("Adding #{ workflow } to REST server")
|
38
39
|
|
39
|
-
|
40
|
+
self.instance_eval workflow.libdir.lib['sinatra.rb'].read if File.exists? workflow.libdir.lib['sinatra.rb']
|
40
41
|
|
41
42
|
get "/#{workflow.to_s}" do
|
42
43
|
case format
|
@@ -129,12 +129,14 @@ module WorkflowRESTHelpers
|
|
129
129
|
job.clean if update == :reload
|
130
130
|
job.run
|
131
131
|
job_url = to(File.join("/", workflow.to_s, task, job.name))
|
132
|
+
job_url += "?_format=#{@format}" if @format
|
132
133
|
halt 200, job.name if format === :jobname
|
133
134
|
redirect job_url
|
134
135
|
when :asynchronous, :async, nil
|
135
136
|
job.clean if update == :reload
|
136
137
|
job.fork
|
137
138
|
job_url = to(File.join("/", workflow.to_s, task, job.name))
|
139
|
+
job_url += "?_format=#{@format}" if @format
|
138
140
|
halt 200, job.name if format === :jobname
|
139
141
|
redirect job_url
|
140
142
|
else
|
@@ -1,14 +1,10 @@
|
|
1
|
-
// Make sure the charset is set appropriately
|
2
1
|
@charset "UTF-8"
|
3
2
|
|
4
|
-
// This includes all of the foundation global elements that are needed to work with any of the other files.
|
5
|
-
//
|
6
|
-
// RENAME THIS TO _foundation-global.scss ONCE ALL THE OLD VARIABLES ARE OUT OF THE FILE.
|
7
|
-
|
8
3
|
@import "normalize"
|
9
4
|
@import "foundation/_variables"
|
10
5
|
@import "foundation/components/global"
|
11
6
|
@import "colors"
|
7
|
+
|
12
8
|
$breakpoint: 1050px
|
13
9
|
|
14
10
|
$small-screen: emCalc($breakpoint)
|
@@ -40,7 +36,6 @@ $indent: 15px
|
|
40
36
|
$vindent: 22px
|
41
37
|
$white: #EEEEEE
|
42
38
|
|
43
|
-
|
44
39
|
// Foundation Components
|
45
40
|
@import foundation/components/grid
|
46
41
|
@import foundation/components/visibility
|
@@ -1,18 +1,20 @@
|
|
1
1
|
@import _foundation_setup
|
2
|
+
@import lists
|
3
|
+
@import list_container
|
4
|
+
@import dom
|
5
|
+
@import form
|
6
|
+
@import table
|
7
|
+
@import tabs
|
8
|
+
|
2
9
|
@import style_mixins
|
10
|
+
|
3
11
|
@import topbar
|
4
12
|
@import favourites
|
5
13
|
@import footer
|
6
14
|
@import entity_card
|
7
15
|
@import actions
|
8
|
-
@import lists
|
9
|
-
@import list_container
|
10
|
-
@import form
|
11
|
-
@import dom
|
12
|
-
@import table
|
13
16
|
@import offcanvas
|
14
17
|
@import fragment
|
15
|
-
@import tabs
|
16
18
|
@import workflow
|
17
19
|
@import style
|
18
20
|
|
@@ -11,9 +11,6 @@
|
|
11
11
|
display: inline-block
|
12
12
|
padding: 0px 10px
|
13
13
|
|
14
|
-
.embedded
|
15
|
-
// @include transition(1.25s height ease-in)
|
16
|
-
|
17
14
|
.hide
|
18
15
|
display: none
|
19
16
|
|
@@ -30,13 +27,6 @@ dl.float
|
|
30
27
|
dt dd
|
31
28
|
float: left
|
32
29
|
|
33
|
-
//dl.meta
|
34
|
-
dt, dd
|
35
|
-
font-size: 0.7em
|
36
|
-
display: inline
|
37
|
-
dd
|
38
|
-
margin-right: 1em
|
39
|
-
|
40
30
|
i[class*="foundicon-"]
|
41
31
|
display: inline-block
|
42
32
|
|
@@ -24,9 +24,11 @@ dl.list_container
|
|
24
24
|
a.entity_list
|
25
25
|
display: block
|
26
26
|
z-index: 15
|
27
|
-
margin-right:
|
27
|
+
margin-right: 1em
|
28
28
|
color: $primary-color
|
29
29
|
width: 1.5em
|
30
30
|
float: left
|
31
|
-
padding:
|
31
|
+
padding-top: 0.2em
|
32
|
+
padding-bottom: 0px
|
33
|
+
padding-right: 20px
|
32
34
|
|
@@ -1,9 +1,10 @@
|
|
1
1
|
@import "colors"
|
2
2
|
@import url(http://fonts.googleapis.com/css?family=Noticia+Text)
|
3
|
+
@import url(http://fonts.googleapis.com/css?family=Open+Sans)
|
3
4
|
|
4
5
|
body, p, h1, h2, h3, h4, h5, h6
|
5
|
-
font-family: Arial,Liberation Sans,DejaVu Sans,sans-serif
|
6
|
-
font-family: "Noticia Text", Verdana, Arial, "Helvetica Neue", Helvetica, sans-serif
|
6
|
+
//font-family: Arial, Liberation Sans,DejaVu Sans,sans-serif
|
7
|
+
font-family: "Open Sans", "Trebuchet MS", "Noticia Text", Verdana, Arial, "Helvetica Neue", Helvetica, sans-serif
|
7
8
|
line-height: 1.4em
|
8
9
|
|
9
10
|
body
|
@@ -26,21 +27,8 @@ footer
|
|
26
27
|
background-color: darken($primary-color, 30%)
|
27
28
|
|
28
29
|
ul.controls, ul.actions
|
29
|
-
|
30
|
-
|
31
|
-
margin-bottom: 5px
|
32
|
-
li
|
33
|
-
margin: 0 2px 0 0
|
34
|
-
|
35
|
-
a
|
36
|
-
@include button-base
|
37
|
-
@include button-size
|
38
|
-
@include button-style
|
39
|
-
@include radius
|
40
|
-
@include single-transition
|
41
|
-
margin-bottom: 2px
|
42
|
-
font-size: 0.8em
|
43
|
-
|
30
|
+
@extend .button-group-list
|
31
|
+
|
44
32
|
ul.controls
|
45
33
|
li.parameters:not(.active), li.reload:not(.active)
|
46
34
|
a
|
@@ -1,3 +1,4 @@
|
|
1
|
+
@import foundation/components/inline-lists
|
1
2
|
=dl_indented()
|
2
3
|
dt
|
3
4
|
font-weight: bold
|
@@ -9,4 +10,21 @@
|
|
9
10
|
//border: solid 1px darken($white, 10%)
|
10
11
|
@extend .panel
|
11
12
|
|
12
|
-
|
13
|
+
.button-group-list
|
14
|
+
@include inline-list()
|
15
|
+
@include button-group-container()
|
16
|
+
margin: 0
|
17
|
+
margin-top: 5px
|
18
|
+
margin-bottom: 5px
|
19
|
+
li
|
20
|
+
margin: 0 2px 0 0
|
21
|
+
|
22
|
+
a
|
23
|
+
@include button-base
|
24
|
+
@include button-size
|
25
|
+
@include button-style
|
26
|
+
@include radius
|
27
|
+
@include single-transition
|
28
|
+
margin-bottom: 2px
|
29
|
+
font-size: 0.8em
|
30
|
+
|
@@ -1,8 +1,12 @@
|
|
1
1
|
dl.tabs
|
2
2
|
position: relative
|
3
|
-
dd:not(.selected)
|
4
|
-
|
5
|
-
|
3
|
+
& > dd:not(.selected)
|
4
|
+
visibility: hidden
|
5
|
+
height: 0px
|
6
|
+
margin: 0px
|
7
|
+
padding: 0px
|
8
|
+
border: none
|
9
|
+
& > dt
|
6
10
|
margin: 0px
|
7
11
|
padding: 5px
|
8
12
|
padding-bottom: 2px
|
@@ -14,21 +18,10 @@ dl.tabs
|
|
14
18
|
background: $tab-active-color-bg
|
15
19
|
|
16
20
|
&:not(.selected)
|
21
|
+
cursor: pointer
|
17
22
|
border: none
|
18
23
|
background: $tab-color-bg
|
19
|
-
|
20
|
-
//
|
21
|
-
float: left
|
22
|
-
line-height: 2
|
23
|
-
height: 2em
|
24
|
-
border-bottom: 0
|
25
|
-
padding: 0 1em
|
26
|
-
position: relative
|
27
|
-
left: 35px
|
28
|
-
margin-right: 1px
|
29
|
-
cursor: pointer
|
30
|
-
|
31
|
-
dd
|
24
|
+
& > dd
|
32
25
|
float: right
|
33
26
|
width: 100%
|
34
27
|
padding: 5px
|