tableling-rails 0.0.11 → 0.0.12

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.
@@ -1,6 +1,4 @@
1
1
  module Tableling
2
2
  end
3
3
 
4
- [ :engine, :model, :field, :version, :activerecord ].each do |lib|
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
@@ -0,0 +1,7 @@
1
+
2
+ module Tableling
3
+
4
+ class Error < StandardError; end
5
+ class BaseQueryError < Error; end
6
+ class ConfigurationError < Error; end
7
+ end
@@ -0,0 +1,14 @@
1
+
2
+ module Tableling
3
+
4
+ module Model
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+
9
+ def tableling options = {}, &block
10
+ @tableling ||= Tableling::Configuration.new(self, options, &block)
11
+ end
12
+ end
13
+ end
14
+ 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
- @name = name.to_s
10
- @order_column = options[:order].try :to_s
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
- @model = options[:model]
14
- Array.wrap(options[:modules] || []).each do |mod|
15
- extend mod
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 "#{@model.table_name}.#{@order_column || @name} #{direction}"
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).to_s
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,11 @@
1
+
2
+ module Tableling
3
+
4
+ def self.settings
5
+ @settings ||= Settings.new
6
+ end
7
+
8
+ def self.global &block
9
+ settings.configure &block
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+
2
+ module Tableling
3
+
4
+ class Serializer
5
+
6
+ def initialize type, block
7
+ @type, @block = type, block
8
+ end
9
+
10
+ def match? value
11
+ value.kind_of? @type
12
+ end
13
+
14
+ def serialize value
15
+ @block.call value
16
+ end
17
+ end
18
+ 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
@@ -1,3 +1,3 @@
1
1
  module Tableling
2
- VERSION = "0.0.11"
2
+ VERSION = "0.0.12"
3
3
  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.14
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.14"
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.14
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.14"
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.14
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.14"
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.11
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 00:00:00.000000000 Z
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/activerecord/ext.rb
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/model.rb
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,2 +0,0 @@
1
- Dir[File.join File.dirname(__FILE__), File.basename(__FILE__, '.*'), '*.rb'].each{ |lib| require lib }
2
- ActiveRecord::Base.send :include, Tableling::ActiveRecord::Extensions
@@ -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,9 +0,0 @@
1
-
2
- module Tableling
3
-
4
- module ActiveRecord
5
-
6
- module Field
7
- end
8
- end
9
- 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