rbbt-rest 1.6.28 → 1.7.0

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rbbt/rest/entity.rb +71 -1
  3. data/lib/rbbt/rest/entity/render.rb +3 -2
  4. data/lib/rbbt/rest/knowledge_base.rb +81 -28
  5. data/lib/rbbt/rest/main.rb +3 -0
  6. data/lib/rbbt/rest/workflow.rb +1 -1
  7. data/lib/rbbt/rest/workflow/jobs.rb +5 -4
  8. data/share/views/compass/app.sass +21 -11
  9. data/share/views/layout/footer.haml +0 -1
  10. data/share/views/layout/header.haml +9 -6
  11. data/share/views/layout/top_menu.haml +1 -0
  12. data/share/views/partials/table.haml +7 -1
  13. data/share/views/public/js/_ajax_replace.js +2 -0
  14. data/share/views/public/js/defer.js +1 -1
  15. data/share/views/public/js/helpers.js +89 -18
  16. data/share/views/public/js/rbbt.aesthetics.js +145 -34
  17. data/share/views/public/js/rbbt.basic.js +20 -0
  18. data/share/views/public/js/rbbt.entity.js +12 -2
  19. data/share/views/public/js/rbbt.entity_list.js +51 -5
  20. data/share/views/public/js/rbbt.exception.js +9 -1
  21. data/share/views/public/js/rbbt.job.js +2 -2
  22. data/share/views/public/js/rbbt.js +5 -1
  23. data/share/views/public/js/rbbt.knowledge_base.js +40 -0
  24. data/share/views/public/js/rbbt.modal.js +82 -75
  25. data/share/views/public/js/rbbt.plots.js +276 -0
  26. data/share/views/public/js/rbbt/list.js +2 -2
  27. data/share/views/public/plugins/cola/js/cola.v3.min.js +3 -0
  28. data/share/views/public/plugins/d3js/js/d3.js +9503 -0
  29. data/share/views/public/plugins/d3js/js/d3js.min.js +5 -0
  30. data/share/views/public/plugins/mithril-node-render/js/index.js +115 -0
  31. data/share/views/public/plugins/mithril/js/mithril.js +212 -77
  32. data/share/views/public/plugins/mithril/js/mithril.min.js +2 -2
  33. data/share/views/public/plugins/mithril/js/mithril.min.js.map +1 -1
  34. data/share/views/public/plugins/nvd3/css/nv.d3.css +641 -0
  35. data/share/views/public/plugins/nvd3/js/nv.d3.js +13298 -0
  36. data/share/views/public/plugins/svg-pan-zoom/js/svg-pan-zoom.js +1861 -0
  37. data/share/views/tools/nvd3.haml +16 -0
  38. data/share/views/tools/nvd3/chart.haml +55 -0
  39. data/share/views/tools/nvd3/histogram.haml +19 -0
  40. data/share/views/tools/nvd3/pie.haml +24 -0
  41. data/share/views/tools/nvd3/scatter.haml +33 -0
  42. data/share/views/wait.haml +2 -2
  43. metadata +15 -3
  44. data/share/views/public/plugins/d3js/d3js.min.js +0 -5
@@ -10,6 +10,7 @@
10
10
  %form.collapse(action='/find' method="POST")
11
11
  %input(type="search" name="term" placeholder='Search')
12
12
 
13
+ #aesthetics.item
13
14
  - if defined? Sinatra::RbbtRESTWorkflow and Sinatra::RbbtRESTWorkflow::WORKFLOWS
14
15
  - expoted_workflows = Sinatra::RbbtRESTWorkflow::WORKFLOWS.collect do |workflow|
15
16
  - next if workflow.asynchronous_exports.empty? and workflow.synchronous_exports.empty? and workflow.exec_exports.empty?
@@ -49,7 +49,13 @@
49
49
  - list_id = "#{ Misc.humanize(table_id) }: #{header[i]} for #{row.first}" if list_links and table_id and header and AnnotatedArray === value
50
50
  - field = header ? header[i] : nil
51
51
  - val = table_value(value, field, :list_id => list_id, :unnamed => unnamed, :entity_options => entity_options, :span => span)
52
- %td= Float === val ? "%.5g" % val : val.to_s
52
+ - case val.to_s
53
+ - when 'true'
54
+ %td.true= val.to_s
55
+ - when 'false'
56
+ %td.false= val.to_s
57
+ - else
58
+ %td= Float === val ? "%.5g" % val : val.to_s
53
59
 
54
60
 
55
61
  -#{{{ TFOOT
@@ -98,6 +98,8 @@ function replace_object(object, href, embedd, complete){
98
98
  if (embedd === undefined){ embedd = false; }
99
99
  var clean_href = remove_parameter(remove_parameter(href,'_'), '_update')
100
100
 
101
+ object.find('.mithril-mount').map(function(i,obj){ m.mount(obj, null) });
102
+
101
103
  object.addClass("embedded").attr('target-href', href)
102
104
 
103
105
  $.ajax({
@@ -14,6 +14,7 @@ function defer(deps, func){
14
14
 
15
15
  function start_deferred(){
16
16
  var tmp = $.unique(deferred_execution);
17
+ deferred_execution = [];
17
18
  $(tmp).each(function(pos,func){
18
19
  if (typeof(func) == 'object'){
19
20
  require_js(func[0], func[1]);
@@ -21,7 +22,6 @@ function start_deferred(){
21
22
  rbbt.try(func).call()
22
23
  }
23
24
  })
24
- deferred_execution = [];
25
25
  return(false)
26
26
  }
27
27
 
@@ -96,32 +96,41 @@ function remove_from_array(array, elem){
96
96
  });
97
97
  }
98
98
 
99
+ function merge_hash(destination, source){
100
+ for (var property in source) {
101
+ if (source.hasOwnProperty(property)) {
102
+ destination[property] = source[property];
103
+ }
104
+ }
105
+ return destination;
106
+ }
107
+
99
108
  function array_values(hash){
100
- var tmp_arr = [], key = '';
101
- for (key in hash) {
102
- tmp_arr[tmp_arr.length] = hash[key];
103
- }
109
+ var tmp_arr = [], key = '';
110
+ for (key in hash) {
111
+ tmp_arr[tmp_arr.length] = hash[key];
112
+ }
104
113
 
105
- return tmp_arr;
114
+ return tmp_arr;
106
115
  }
107
116
 
108
117
  function clean_attr(text){
109
- return encodeURIComponent(text)
118
+ return encodeURIComponent(text)
110
119
  }
111
120
 
112
121
  function uniq(ary) {
113
- var seen = {};
114
- return ary.filter(function(elem) {
115
- var k = elem;
116
- return (seen[k] === 1) ? 0 : seen[k] = 1;
117
- })
122
+ var seen = {};
123
+ return ary.filter(function(elem) {
124
+ var k = elem;
125
+ return (seen[k] === 1) ? 0 : seen[k] = 1;
126
+ })
118
127
  }
119
128
  function uniqBy(ary, key) {
120
- var seen = {};
121
- return ary.filter(function(elem) {
122
- var k = key(elem);
123
- return (seen[k] === 1) ? 0 : seen[k] = 1;
124
- })
129
+ var seen = {};
130
+ return ary.filter(function(elem) {
131
+ var k = key(elem);
132
+ return (seen[k] === 1) ? 0 : seen[k] = 1;
133
+ })
125
134
  }
126
135
 
127
136
 
@@ -129,8 +138,8 @@ function unique(arrayName) {
129
138
  var newArray=new Array();
130
139
  label:for(var i=0; i<arrayName.length;i++ ){
131
140
  for(var j=0; j<newArray.length;j++ ){
132
- if(newArray[j]==arrayName[i])
133
- continue label;
141
+ if(newArray[j]==arrayName[i])
142
+ continue label;
134
143
  }
135
144
  newArray[newArray.length] = arrayName[i];
136
145
  }
@@ -166,3 +175,65 @@ function forArray(obj, fn, thisObj){
166
175
  }
167
176
  return forArray;
168
177
  }
178
+
179
+ function contains(a, obj) {
180
+ for (var i = 0; i < a.length; i++) {
181
+ if (a[i] === obj) {
182
+ return true;
183
+ }
184
+ }
185
+ return false;
186
+ }
187
+
188
+ function return_same(obj){ return obj }
189
+
190
+ function pvalue_score(pvalue){ if (undefined === pvalue || null == pvalue || pvalue == ""){ return pvalue }; if (pvalue < 0){ return 10 * Math.log10(-pvalue)}else{ return -10 * Math.log10(pvalue) }}
191
+
192
+ function get_gradient(values, color1, color2){
193
+ var Color = net.brehaut.Color;
194
+ var color1 = Color(color1)
195
+ var color2 = Color(color2)
196
+ var steps = values.length
197
+ var clean_values = []
198
+ forArray(values,function(v){ if (typeof v == 'number' && ! isNaN(v)) clean_values.push(v) })
199
+ var max = Math.max.apply(null,clean_values)
200
+ var min = Math.min.apply(null,clean_values)
201
+ var diff = max - min
202
+ var colors = []
203
+ forArray(values, function(value){
204
+ if (typeof value == 'number'){
205
+ var a = (value - min)/diff
206
+ colors.push(color1.blend(color2, a).toString())
207
+ }else{
208
+ colors.push(undefined)
209
+ }
210
+ })
211
+ return colors
212
+ }
213
+
214
+ function get_sign_gradient(values, color1, color0, color2){
215
+ var Color = net.brehaut.Color;
216
+ var color1 = Color(color1)
217
+ var color0 = Color(color0)
218
+ var color2 = Color(color2)
219
+ var steps = values.length
220
+ var clean_values = []
221
+ forArray(values,function(v){ if (typeof v == 'number' && ! isNaN(v)) clean_values.push(v) })
222
+ var max = Math.max.apply(null,clean_values)
223
+ var min = Math.min.apply(null,clean_values)
224
+ var colors = []
225
+ forArray(values, function(value){
226
+ if (typeof value == 'number'){
227
+ if (value > 0){
228
+ var a = value/max
229
+ colors.push(color0.blend(color1, a).toString())
230
+ }else{
231
+ var a = value/min
232
+ colors.push(color0.blend(color2, a).toString())
233
+ }
234
+ }else{
235
+ colors.push(undefined)
236
+ }
237
+ })
238
+ return colors
239
+ }
@@ -3,54 +3,165 @@ rbbt.aesthetics = {LS_key: "rbbt.aesthetics"}
3
3
  var aes_module = rbbt.aesthetics
4
4
 
5
5
  aes_module.load = function(){
6
- this.aesthetics = rbbt.LS.load(this.LS_key)
7
- if (undefined === this.aesthetics)
8
- this.aesthetics = []
9
- }
6
+ this.aesthetics = rbbt.LS.load(this.LS_key)
7
+ if (undefined === this.aesthetics)
8
+ this.aesthetics = []
9
+ }.bind(aes_module)
10
10
 
11
11
  aes_module.store = function(){
12
12
  rbbt.LS.store(this.LS_key, this.aesthetics)
13
- }
13
+ }.bind(aes_module)
14
14
 
15
- aes_module.add = function(selector, aes, value){
16
- var mod = this
17
- if (typeof selector == 'function'){
18
- return selector.then(function(_selector){
19
- mod.aesthetics.push({selector: _selector, aes: aes, value: value})
20
- })
21
- }else{
22
- this.aesthetics.push({selector: selector, aes: aes, value: value})
15
+ aes_module.map_aesthetic = function(aes, mapper, map_obj){
16
+ switch(mapper){
17
+ case false:
18
+ case undefined:
19
+ case null:
20
+ case 'direct':
21
+ return aes;
22
+ case 'gradient':
23
+ return get_gradient(aes, 'green', 'red')
24
+ case 'sign-gradient':
25
+ return get_sign_gradient(aes, 'green', 'white', 'red')
26
+ case 'map':
27
+ return aes.map(function(value){ map_obj[value] })
23
28
  }
24
29
  }
25
30
 
26
- aes_module.clear_aesthetic = function(aes){
27
- var data_key = 'data-aes-' + aesthetic.aes
31
+ aes_module.get_list_aesthetics = function(list, rules) {
32
+ var result = {}
33
+ var promises = []
34
+ var deferred = m.deferred()
35
+ var mappers = {}
28
36
 
29
- $('[' + data_key + ']').attr(data_key, 'none')
30
- }
37
+ if (undefined === rules) rules = this.aesthetics
38
+ forArray(rules, function(rule){
39
+ var aes = rule.aes
40
+ result[aes] = m.prop()
41
+ mappers[aes] = rule.mapper
42
+
43
+ var args = rule.args
44
+ var extract = rule.extract
45
+
46
+ var promise
47
+
48
+ if (rule.property){
49
+ promise = list.property(rule.property, args)
31
50
 
32
- aes_module.apply_aesthetic = function(aesthetic){
51
+ if (undefined === extract){
52
+ promises.push(promise.then(result[aes]))
53
+ }else{
54
+ promises.push(promise.then(function(v){return v.map(extract)}).then(result[aes]))
55
+ }
56
+ }
33
57
 
34
- if (typeof aesthetic.selector == "string"){
35
- targets = $(aesthetic.selector)
36
- }else{
37
- var items = aesthetic.selector
38
- if (typeof items[0] == 'object') items = $.map(items, function(i){return i.id})
39
- targets = $('.entity').filter(function(index){
40
- var id = $(this).attr('data-entity-id')
41
- return items.indexOf(id) >= 0
58
+ if (rule.workflow){
59
+ promise = rbbt.job(rule.workflow, rule.task, args,true)
60
+ if (undefined === extract){
61
+ promises.push(promise.then(result[aes]))
62
+ }else{
63
+ promises.push(m.sync([list.get(), promise]).then(function(res){
64
+ list_info = res[0]
65
+ data = res[1]
66
+ return list_info.entities.map(function(e){ return extract.call(null, data, e) })
67
+ }).then(result[aes]))
68
+ }
69
+ }
70
+
71
+ if (rule.knowledge_base){
72
+ if (rule.parents)
73
+ promise = rbbt.knowledge_base.list_parents([rule.parents, rule.knowledge_base].join("@"), list)
74
+ if (rule.children)
75
+ promise = rbbt.knowledge_base.list_children([rule.children, rule.knowledge_base].join("@"), list)
76
+
77
+ promise = promise.then(function(data){
78
+ var matches = {}
79
+ forHash(data, function(key, values){
80
+ var source = values[0]
81
+ var target = values[1]
82
+ if (matches[source] === undefined) matches[source] = {}
83
+ matches[source][target] = values.slice(2)
84
+ })
85
+ return matches
86
+ })
87
+
88
+ if (undefined === extract){
89
+ promises.push(m.sync([list.get(), promise]).then(function(res){
90
+ list_info = res[0]
91
+ data = res[1]
92
+ return list_info.entities.map(function(e){ return data[e] })
93
+ }).then(result[aes]))
94
+ }else{
95
+ promises.push(m.sync([list.get(), promise]).then(function(res){
96
+ list_info = res[0]
97
+ data = res[1]
98
+ return list_info.entities.map(function(e){ return extract.call(null, data, e) })
99
+ }).then(result[aes]))
100
+ }
101
+ }
42
102
  })
43
- }
44
103
 
45
- var data_key = 'data-aes-' + aesthetic.aes
46
- targets.attr(data_key, aesthetic.value)
104
+ var mapped_result = {}
105
+ m.sync(promises).then(function(){
106
+ forHash(result, function(aes, values){
107
+ var mapper = mappers[aes]
108
+ mapped_result[aes] = rbbt.aesthetics.map_aesthetic(values(), mapper)
109
+ })
110
+ return mapped_result
111
+ }).then(function(){ deferred.resolve(mapped_result) })
112
+
113
+ return deferred.promise
47
114
  }
48
115
 
49
- aes_module.apply = function(aesthetic){
50
- if (undefined === aesthetic)
51
- aes_module.aesthetics.map(aes_module.apply_aesthetic)
52
- else
53
- aes_module.apply_aesthetic(aesthetic)
116
+ aes_module.add = function(rule){
117
+ aes_module.aesthetics.push(rule)
118
+ aes_module.aesthetics = unique(aes_module.aesthetics)
119
+ aes_module.store()
54
120
  }
55
121
 
122
+ aes_module.apply = function(){
123
+ }
124
+
125
+ //aes_module.add = function(selector, aes, value){
126
+ // var mod = this
127
+ // if (typeof selector == 'function'){
128
+ // return selector.then(function(_selector){
129
+ // mod.aesthetics.push({selector: _selector, aes: aes, value: value})
130
+ // })
131
+ // }else{
132
+ // this.aesthetics.push({selector: selector, aes: aes, value: value})
133
+ // }
134
+ //}
135
+ //
136
+ //aes_module.clear_aesthetic = function(aes){
137
+ // var data_key = 'data-aes-' + aesthetic.aes
138
+ //
139
+ // $('[' + data_key + ']').attr(data_key, 'none')
140
+ //}
141
+ //
142
+ //aes_module.apply_aesthetic = function(aesthetic){
143
+ //
144
+ // if (typeof aesthetic.selector == "string"){
145
+ // targets = $(aesthetic.selector)
146
+ // }else{
147
+ // var items = aesthetic.selector
148
+ // if (typeof items[0] == 'object') items = $.map(items, function(i){return i.id})
149
+ // targets = $('.entity').filter(function(index){
150
+ // var id = $(this).attr('data-entity-id')
151
+ // return items.indexOf(id) >= 0
152
+ // })
153
+ // }
154
+ //
155
+ // var data_key = 'data-aes-' + aesthetic.aes
156
+ // targets.attr(data_key, aesthetic.value)
157
+ //}
158
+ //
159
+ //aes_module.apply = function(aesthetic){
160
+ // if (undefined === aesthetic)
161
+ // aes_module.aesthetics.map(aes_module.apply_aesthetic)
162
+ // else
163
+ // aes_module.apply_aesthetic(aesthetic)
164
+ //}
165
+ //
166
+
56
167
  aes_module.load()
@@ -3,11 +3,31 @@ rbbt.mlog = function(data){
3
3
  console.log(data)
4
4
  }
5
5
 
6
+ // AJAX
7
+
6
8
  rbbt.ajax = function(params){
7
9
  params.config = function(xhr, options){ xhr.setRequestHeader( "X-Requested-With", "XMLHttpRequest"); return xhr; }
10
+ if (undefined === params.method) params.method = "GET"
8
11
  return m.request(params)
9
12
  }
10
13
 
14
+ rbbt.post = function(url, data, params){
15
+ var formData = new FormData()
16
+
17
+ if (undefined === params) params = {}
18
+ if (undefined === params.method) params.method = 'POST'
19
+ if (undefined === params.url) params.url = url
20
+ if (undefined === params.serialize) params.serialize = function(formData) {return formData}
21
+
22
+
23
+ forHash(data, function(key,value){
24
+ formData.append(key, value)
25
+ })
26
+
27
+ var request_params = {url: url, method: "POST", data: formData, serialize: function(formData){return formData} }
28
+ return rbbt.ajax(request_params)
29
+ }
30
+
11
31
  rbbt.insist_request = function(params, deferred, timeout, missing){
12
32
  if (undefined === deferred) deferred = m.deferred()
13
33
  if (undefined === timeout) timeout = 1000
@@ -1,5 +1,4 @@
1
1
  var Entity = function(data){
2
- this.id = data.id
3
2
  this.code = data.code
4
3
 
5
4
  if (data.name !== undefined)
@@ -9,7 +8,11 @@ var Entity = function(data){
9
8
 
10
9
  this.type = data.type
11
10
  this.format = data.format
12
- this.info = data.info
11
+ if (undefined === data.info)
12
+ this.info = {}
13
+ else
14
+ this.info = data.info
15
+ this.info = {}
13
16
  if (this.format === undefined && this.info !== undefined) this.format = this.info['format']
14
17
 
15
18
  this.full_type = function(){
@@ -30,6 +33,13 @@ var Entity = function(data){
30
33
  url = add_parameters(url, this.link_info())
31
34
  return url
32
35
  }
36
+
37
+ this.property = function(name, args){
38
+ var url = "/entity_property/" + name + "/" + this.full_type() + "/" + this.code
39
+ url = add_parameters(url, this.link_info())
40
+ if (undefined !== args) url = add_parameter(url, "args", JSON.stringify(args))
41
+ return rbbt.insist_request({url: url})
42
+ }
33
43
  }
34
44
 
35
45
  var FavouriteEntities = function(by_type){
@@ -16,14 +16,60 @@ var EntityList = function(data){
16
16
  this.get = function(){
17
17
  var url = this.url()
18
18
  url = add_parameter(url, '_format', 'json')
19
- return m.request({url: url, method: 'GET'})
19
+ if (undefined === this.entities && ! this.loading){
20
+ list = this
21
+ this.loading = m.request({url: url, method: 'GET'}).then(this.entities).then(function(x){ list.loading = undefined; return x})
22
+ return this.loading
23
+ }else{
24
+ var deferred = m.deferred()
25
+ if (this.loading)
26
+ this.loading.then(function(x){ deferred.resolve(x)})
27
+ else
28
+ deferred.resolve(this.entities)
29
+ return deferred.promise
30
+ }
20
31
  }
21
32
 
22
- this.highlight = function(color){
23
- this.get().then(function(list){
24
- rbbt.aesthetics.apply_aesthetic({selector: list.entities, aes: 'color', value: color})
25
- })
33
+ this.get_entities = function(func){
34
+ var result = m.deferred();
35
+
36
+ this.get().then(function(list_data){
37
+ var item_values = []
38
+ forArray(list_data.entities, function(entity_code){
39
+ item_values.push(new Entity({code: entity_code, info: list_data.info}))
40
+ })
41
+ result.resolve(item_values)
42
+ })
43
+
44
+ return(result.promise)
45
+ }
46
+
47
+ this.property = function(name, args){
48
+ var url = "/entity_list_property/" + name + "/" + this.full_type() + "/" + clean_element(this.id)
49
+ if (undefined !== args)
50
+ if ('string' === typeof args)
51
+ url = add_parameter(url, "args", args)
52
+ else
53
+ url = add_parameter(url, "args", JSON.stringify(args))
54
+ return rbbt.insist_request({url: url})
55
+ }
56
+
57
+ this.children = function(knowledgebase, database){
58
+ var db_key = [database, knowledgebase].join("@")
59
+ return rbbt.knowledge_base.list_children(db_key, this)
26
60
  }
61
+
62
+ this.parents = function(knowledgebase, database){
63
+ var db_key = [database, knowledgebase].join("@")
64
+ return rbbt.knowledge_base.list_parents(db_key, this)
65
+ }
66
+
67
+ this.subset = function(knowledgebase, database){
68
+ var db_key = [database, knowledgebase].join("@")
69
+ return rbbt.knowledge_base.list_subset(db_key, this)
70
+ }
71
+
72
+
27
73
  }
28
74
 
29
75
  var FavouriteLists = function(by_type){