tableling-rails 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/tableling-rails.rb +1 -3
- data/lib/tableling-rails/config.rb +34 -0
- data/lib/tableling-rails/errors.rb +7 -0
- data/lib/tableling-rails/ext.rb +14 -0
- data/lib/tableling-rails/field.rb +27 -9
- data/lib/tableling-rails/global.rb +11 -0
- data/lib/tableling-rails/serializer.rb +18 -0
- data/lib/tableling-rails/settings.rb +34 -0
- data/lib/tableling-rails/version.rb +1 -1
- data/lib/tableling-rails/view.rb +79 -0
- data/vendor/assets/javascripts/tableling.backbone.js +6 -4
- data/vendor/assets/javascripts/tableling.js +6 -4
- data/vendor/assets/javascripts/tableling.world.js +6 -4
- metadata +9 -7
- data/lib/tableling-rails/activerecord.rb +0 -2
- data/lib/tableling-rails/activerecord/ext.rb +0 -15
- data/lib/tableling-rails/activerecord/field.rb +0 -9
- data/lib/tableling-rails/activerecord/model.rb +0 -18
- data/lib/tableling-rails/model.rb +0 -68
data/lib/tableling-rails.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
module Tableling
|
2
2
|
end
|
3
3
|
|
4
|
-
[
|
5
|
-
require File.expand_path("../tableling-rails/#{lib}", __FILE__)
|
6
|
-
end
|
4
|
+
Dir[File.join File.dirname(__FILE__), File.basename(__FILE__, '.*'), '*.rb'].each{ |lib| require lib }
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
module Tableling
|
3
|
+
|
4
|
+
class Configuration
|
5
|
+
attr_reader :model, :settings
|
6
|
+
|
7
|
+
def initialize model, options = {}, &block
|
8
|
+
|
9
|
+
@model = model
|
10
|
+
@views = []
|
11
|
+
|
12
|
+
@settings = Settings.new Tableling.settings
|
13
|
+
extend @settings.dsl
|
14
|
+
|
15
|
+
instance_eval &block if block
|
16
|
+
@frozen = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def view name, options = {}, &block
|
20
|
+
return @views.find{ |v| v.name.to_s == name.to_s } if @frozen
|
21
|
+
@views.delete_if{ |v| v.name.to_s == name }
|
22
|
+
View.new(name, self, options, &block).tap{ |v| @views << v }
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_view options = {}, &block
|
26
|
+
view :default, options, &block
|
27
|
+
end
|
28
|
+
|
29
|
+
def process params
|
30
|
+
raise ConfigurationError, "You must specify a default view" unless view(:default)
|
31
|
+
view(:default).process params
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -3,17 +3,19 @@ module Tableling
|
|
3
3
|
|
4
4
|
class Field
|
5
5
|
attr_reader :name
|
6
|
-
# TODO: extract active record functionality
|
7
6
|
|
8
|
-
def initialize name, options = {}, &block
|
9
|
-
|
10
|
-
@
|
7
|
+
def initialize name, view, options = {}, &block
|
8
|
+
|
9
|
+
@name, @view = name.to_s, view
|
11
10
|
@value_column = options[:value].try :to_s
|
12
11
|
@includes = options[:includes]
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
|
13
|
+
if options[:order] == false
|
14
|
+
@no_order = true
|
15
|
+
elsif options[:order]
|
16
|
+
@order_column = options[:order].to_s
|
16
17
|
end
|
18
|
+
|
17
19
|
instance_eval &block if block
|
18
20
|
end
|
19
21
|
|
@@ -21,6 +23,10 @@ module Tableling
|
|
21
23
|
@order_block = block
|
22
24
|
end
|
23
25
|
|
26
|
+
def no_order
|
27
|
+
@no_order = true
|
28
|
+
end
|
29
|
+
|
24
30
|
def value &block
|
25
31
|
@value_block = block
|
26
32
|
end
|
@@ -30,10 +36,11 @@ module Tableling
|
|
30
36
|
end
|
31
37
|
|
32
38
|
def with_order query, direction
|
39
|
+
return if @no_order
|
33
40
|
if @order_block
|
34
41
|
@order_block.call query, direction
|
35
42
|
else
|
36
|
-
query.order "#{
|
43
|
+
query.order "#{model.table_name}.#{@order_column || @name} #{direction}"
|
37
44
|
end
|
38
45
|
end
|
39
46
|
|
@@ -51,8 +58,19 @@ module Tableling
|
|
51
58
|
if @value_block
|
52
59
|
@value_block.call object
|
53
60
|
else
|
54
|
-
object.send(@value_column || @name)
|
61
|
+
serialize object.send(@value_column || @name)
|
55
62
|
end
|
56
63
|
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def model
|
68
|
+
@view.config.model
|
69
|
+
end
|
70
|
+
|
71
|
+
def serialize value
|
72
|
+
serializer = @view.settings.serializers.find{ |s| s.match? value }
|
73
|
+
serializer ? serializer.serialize(value) : value
|
74
|
+
end
|
57
75
|
end
|
58
76
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
module Tableling
|
3
|
+
|
4
|
+
class Settings
|
5
|
+
|
6
|
+
def initialize parent = nil
|
7
|
+
@parent = parent
|
8
|
+
@serializers = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure &block
|
12
|
+
instance_eval &block if block
|
13
|
+
end
|
14
|
+
|
15
|
+
def serialize type, &block
|
16
|
+
@serializers << Serializer.new(type, block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def serializers
|
20
|
+
(@parent ? @parent.serializers : []) + @serializers.dup
|
21
|
+
end
|
22
|
+
|
23
|
+
def dsl
|
24
|
+
m = Module.new do
|
25
|
+
|
26
|
+
def serialize type, &block
|
27
|
+
@settings.serialize type, &block
|
28
|
+
end
|
29
|
+
end
|
30
|
+
m.instance_variable_set :@settings, self
|
31
|
+
m
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
|
2
|
+
module Tableling
|
3
|
+
|
4
|
+
class View
|
5
|
+
attr_reader :name, :config, :settings, :base_query, :base_count_query
|
6
|
+
|
7
|
+
def initialize name, config, options = {}, &block
|
8
|
+
|
9
|
+
@name, @config = name, config
|
10
|
+
@fields = []
|
11
|
+
|
12
|
+
@base_query = @config.model
|
13
|
+
@base_count_query = nil
|
14
|
+
|
15
|
+
@settings = Settings.new @config.settings
|
16
|
+
extend @settings.dsl
|
17
|
+
|
18
|
+
instance_eval &block if block
|
19
|
+
@frozen = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def field name, options = {}, &block
|
23
|
+
return @fields.find{ |f| f.name.to_s == name.to_s } if @frozen
|
24
|
+
@fields.delete_if{ |f| f.name.to_s == name.to_s }
|
25
|
+
Field.new(name, self, options, &block).tap{ |f| @fields << f }
|
26
|
+
end
|
27
|
+
|
28
|
+
def quick_search &block
|
29
|
+
@quick_search = block
|
30
|
+
end
|
31
|
+
|
32
|
+
def base base_query
|
33
|
+
@base_query = base_query
|
34
|
+
end
|
35
|
+
|
36
|
+
def base_count base_count_query
|
37
|
+
@base_count_query = base_count_query
|
38
|
+
end
|
39
|
+
|
40
|
+
def process options = {}
|
41
|
+
|
42
|
+
q = options[:base] || @base_query
|
43
|
+
cq = options[:base_count] || @base_count_query
|
44
|
+
|
45
|
+
if @quick_search and options[:quickSearch].present?
|
46
|
+
q = @quick_search.call q, options[:quickSearch].to_s
|
47
|
+
cq = @quick_search.call cq, options[:quickSearch].to_s if cq
|
48
|
+
end
|
49
|
+
|
50
|
+
total = (cq || q).count
|
51
|
+
raise BaseQueryError, "Count query must return a number" unless total.kind_of?(Fixnum)
|
52
|
+
|
53
|
+
if options[:sort].present?
|
54
|
+
options[:sort].select{ |item| item.match /\A([^ ]+)* (asc|desc)\Z/i }.each do |item|
|
55
|
+
parts = item.split ' '
|
56
|
+
f = field parts[0]
|
57
|
+
q = f.with_order q, parts[1].downcase.to_sym if f
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
@fields.each{ |f| q = f.with_includes q }
|
62
|
+
|
63
|
+
limit = options[:pageSize].to_i
|
64
|
+
limit = 10 if limit <= 0
|
65
|
+
q = q.limit limit
|
66
|
+
|
67
|
+
offset = options[:page].to_i - 1
|
68
|
+
offset = 0 if offset < 0
|
69
|
+
q = q.offset offset * limit
|
70
|
+
|
71
|
+
{
|
72
|
+
:total => total,
|
73
|
+
:data => q.all.collect{ |o|
|
74
|
+
@fields.inject({}){ |memo,f| memo[f.name] = f.extract(o); memo }
|
75
|
+
}
|
76
|
+
}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -3555,7 +3555,7 @@ _.extend(Marionette.Module, {
|
|
3555
3555
|
return Marionette;
|
3556
3556
|
})(Backbone, _, $ || window.jQuery || window.Zepto || window.ender);
|
3557
3557
|
/*!
|
3558
|
-
* Tableling v0.0.
|
3558
|
+
* Tableling v0.0.15
|
3559
3559
|
* Copyright (c) 2012-2013 Simon Oulevay (Alpha Hydrae) <hydrae.alpha@gmail.com>
|
3560
3560
|
* Distributed under MIT license
|
3561
3561
|
* https://github.com/AlphaHydrae/tableling
|
@@ -3563,7 +3563,7 @@ _.extend(Marionette.Module, {
|
|
3563
3563
|
Backbone.Tableling = Tableling = (function(Backbone, _, $){
|
3564
3564
|
|
3565
3565
|
var Tableling = {
|
3566
|
-
version : "0.0.
|
3566
|
+
version : "0.0.15"
|
3567
3567
|
};
|
3568
3568
|
|
3569
3569
|
// Tableling
|
@@ -3905,7 +3905,9 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
|
|
3905
3905
|
Tableling.Plain.TableView = Backbone.Marionette.CompositeView.extend({
|
3906
3906
|
|
3907
3907
|
events : {
|
3908
|
-
'click thead th' : 'updateSort'
|
3908
|
+
'click thead th.sorting' : 'updateSort',
|
3909
|
+
'click thead th.sorting-asc' : 'updateSort',
|
3910
|
+
'click thead th.sorting-desc' : 'updateSort'
|
3909
3911
|
},
|
3910
3912
|
|
3911
3913
|
initialize : function(options) {
|
@@ -3962,7 +3964,7 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
|
|
3962
3964
|
|
3963
3965
|
showSort : function() {
|
3964
3966
|
|
3965
|
-
this.$el.find('thead th').removeClass('sorting sorting-asc sorting-desc').addClass('sorting');
|
3967
|
+
this.$el.find('thead th.sorting, thead th.sorting-asc, thead th.sorting-desc').removeClass('sorting sorting-asc sorting-desc').addClass('sorting');
|
3966
3968
|
|
3967
3969
|
for (var i = 0; i < this.sort.length; i++) {
|
3968
3970
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* Tableling v0.0.
|
2
|
+
* Tableling v0.0.15
|
3
3
|
* Copyright (c) 2012-2013 Simon Oulevay (Alpha Hydrae) <hydrae.alpha@gmail.com>
|
4
4
|
* Distributed under MIT license
|
5
5
|
* https://github.com/AlphaHydrae/tableling
|
@@ -7,7 +7,7 @@
|
|
7
7
|
Backbone.Tableling = Tableling = (function(Backbone, _, $){
|
8
8
|
|
9
9
|
var Tableling = {
|
10
|
-
version : "0.0.
|
10
|
+
version : "0.0.15"
|
11
11
|
};
|
12
12
|
|
13
13
|
// Tableling
|
@@ -349,7 +349,9 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
|
|
349
349
|
Tableling.Plain.TableView = Backbone.Marionette.CompositeView.extend({
|
350
350
|
|
351
351
|
events : {
|
352
|
-
'click thead th' : 'updateSort'
|
352
|
+
'click thead th.sorting' : 'updateSort',
|
353
|
+
'click thead th.sorting-asc' : 'updateSort',
|
354
|
+
'click thead th.sorting-desc' : 'updateSort'
|
353
355
|
},
|
354
356
|
|
355
357
|
initialize : function(options) {
|
@@ -406,7 +408,7 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
|
|
406
408
|
|
407
409
|
showSort : function() {
|
408
410
|
|
409
|
-
this.$el.find('thead th').removeClass('sorting sorting-asc sorting-desc').addClass('sorting');
|
411
|
+
this.$el.find('thead th.sorting, thead th.sorting-asc, thead th.sorting-desc').removeClass('sorting sorting-asc sorting-desc').addClass('sorting');
|
410
412
|
|
411
413
|
for (var i = 0; i < this.sort.length; i++) {
|
412
414
|
|
@@ -14826,7 +14826,7 @@ _.extend(Marionette.Module, {
|
|
14826
14826
|
return Marionette;
|
14827
14827
|
})(Backbone, _, $ || window.jQuery || window.Zepto || window.ender);
|
14828
14828
|
/*!
|
14829
|
-
* Tableling v0.0.
|
14829
|
+
* Tableling v0.0.15
|
14830
14830
|
* Copyright (c) 2012-2013 Simon Oulevay (Alpha Hydrae) <hydrae.alpha@gmail.com>
|
14831
14831
|
* Distributed under MIT license
|
14832
14832
|
* https://github.com/AlphaHydrae/tableling
|
@@ -14834,7 +14834,7 @@ _.extend(Marionette.Module, {
|
|
14834
14834
|
Backbone.Tableling = Tableling = (function(Backbone, _, $){
|
14835
14835
|
|
14836
14836
|
var Tableling = {
|
14837
|
-
version : "0.0.
|
14837
|
+
version : "0.0.15"
|
14838
14838
|
};
|
14839
14839
|
|
14840
14840
|
// Tableling
|
@@ -15176,7 +15176,9 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
|
|
15176
15176
|
Tableling.Plain.TableView = Backbone.Marionette.CompositeView.extend({
|
15177
15177
|
|
15178
15178
|
events : {
|
15179
|
-
'click thead th' : 'updateSort'
|
15179
|
+
'click thead th.sorting' : 'updateSort',
|
15180
|
+
'click thead th.sorting-asc' : 'updateSort',
|
15181
|
+
'click thead th.sorting-desc' : 'updateSort'
|
15180
15182
|
},
|
15181
15183
|
|
15182
15184
|
initialize : function(options) {
|
@@ -15233,7 +15235,7 @@ Backbone.Tableling = Tableling = (function(Backbone, _, $){
|
|
15233
15235
|
|
15234
15236
|
showSort : function() {
|
15235
15237
|
|
15236
|
-
this.$el.find('thead th').removeClass('sorting sorting-asc sorting-desc').addClass('sorting');
|
15238
|
+
this.$el.find('thead th.sorting, thead th.sorting-asc, thead th.sorting-desc').removeClass('sorting sorting-asc sorting-desc').addClass('sorting');
|
15237
15239
|
|
15238
15240
|
for (var i = 0; i < this.sort.length; i++) {
|
15239
15241
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tableling-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -35,14 +35,16 @@ executables: []
|
|
35
35
|
extensions: []
|
36
36
|
extra_rdoc_files: []
|
37
37
|
files:
|
38
|
-
- lib/tableling-rails/
|
39
|
-
- lib/tableling-rails/activerecord/field.rb
|
40
|
-
- lib/tableling-rails/activerecord/model.rb
|
41
|
-
- lib/tableling-rails/activerecord.rb
|
38
|
+
- lib/tableling-rails/config.rb
|
42
39
|
- lib/tableling-rails/engine.rb
|
40
|
+
- lib/tableling-rails/errors.rb
|
41
|
+
- lib/tableling-rails/ext.rb
|
43
42
|
- lib/tableling-rails/field.rb
|
44
|
-
- lib/tableling-rails/
|
43
|
+
- lib/tableling-rails/global.rb
|
44
|
+
- lib/tableling-rails/serializer.rb
|
45
|
+
- lib/tableling-rails/settings.rb
|
45
46
|
- lib/tableling-rails/version.rb
|
47
|
+
- lib/tableling-rails/view.rb
|
46
48
|
- lib/tableling-rails.rb
|
47
49
|
- vendor/assets/javascripts/tableling.backbone.js
|
48
50
|
- vendor/assets/javascripts/tableling.js
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Tableling
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
|
5
|
-
module Extensions
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
def tableling options = {}, &block
|
10
|
-
@model ||= Tableling::Model.new(:modules => Tableling::ActiveRecord::Model, :model => self, &block)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Tableling
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
|
5
|
-
module Model
|
6
|
-
|
7
|
-
def initialize_model options = {}
|
8
|
-
@model = options[:model]
|
9
|
-
@field_options[:model] = @model
|
10
|
-
@field_options[:modules] = Tableling::ActiveRecord::Field
|
11
|
-
end
|
12
|
-
|
13
|
-
def base_query
|
14
|
-
@model
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
|
2
|
-
module Tableling
|
3
|
-
|
4
|
-
class Model
|
5
|
-
|
6
|
-
def initialize options = {}, &block
|
7
|
-
|
8
|
-
@fields = []
|
9
|
-
@field_options = {}
|
10
|
-
|
11
|
-
Array.wrap(options[:modules] || []).each do |mod|
|
12
|
-
extend mod
|
13
|
-
initialize_model options if respond_to? :initialize_model
|
14
|
-
end
|
15
|
-
|
16
|
-
instance_eval &block if block
|
17
|
-
end
|
18
|
-
|
19
|
-
def field name, options = {}, &block
|
20
|
-
if field = @fields.find{ |f| f.name.to_s == name.to_s }
|
21
|
-
return field
|
22
|
-
end
|
23
|
-
# TODO: do not add field if it's already there
|
24
|
-
Field.new(name, @field_options.merge(options), &block).tap{ |f| @fields << f }
|
25
|
-
end
|
26
|
-
|
27
|
-
def quick_search &block
|
28
|
-
@quick_search = block
|
29
|
-
end
|
30
|
-
|
31
|
-
def process params
|
32
|
-
|
33
|
-
q = params[:base] || base_query
|
34
|
-
|
35
|
-
if @quick_search and params[:quickSearch].present?
|
36
|
-
q = @quick_search.call q, params[:quickSearch].to_s
|
37
|
-
end
|
38
|
-
|
39
|
-
total = q.count
|
40
|
-
# TODO: allow to override count query to handle group by use cases
|
41
|
-
total = total.inject(0){ |memo,(k,v)| memo + v } if total.kind_of? Hash
|
42
|
-
|
43
|
-
if params[:sort].present?
|
44
|
-
params[:sort].select{ |item| item.match /\A([^ ]+)* (asc|desc)\Z/ }.each do |item|
|
45
|
-
parts = item.split ' '
|
46
|
-
q = field(parts[0]).with_order q, parts[1].to_sym
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
@fields.each{ |f| q = f.with_includes q }
|
51
|
-
|
52
|
-
limit = params[:pageSize].to_i
|
53
|
-
limit = 10 if limit <= 0
|
54
|
-
q = q.limit limit
|
55
|
-
|
56
|
-
offset = params[:page].to_i - 1
|
57
|
-
offset = 0 if offset < 0
|
58
|
-
q = q.offset offset * limit
|
59
|
-
|
60
|
-
{
|
61
|
-
:total => total,
|
62
|
-
:data => q.all.collect{ |o|
|
63
|
-
@fields.inject({}){ |memo,f| memo[f.name] = f.extract(o); memo }
|
64
|
-
}
|
65
|
-
}
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|