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.
@@ -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