gitter 1.1.5 → 1.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6bd933134f3ed6527bb09e5d111be1c5b52b35c7
4
+ data.tar.gz: 44ecdd458d9a550b067de509b170493afc2c5283
5
+ SHA512:
6
+ metadata.gz: 63880cdac97fc53c3dbf0b5a3a9d2dbe947a811912118a9b3a7f2b590e50263802dbd79ad8524e288added1f19308b020f0e7fc5d5944e1ef697b7860889973e
7
+ data.tar.gz: beb207ecac0707f69620d8c543e6ac758bc6217509777e04cfc8e32015f033f9ab49398950e04c7fafcbb7ceaa7d67f0a69168af6eb1e3a3f1aa16d3698207c2
@@ -39,7 +39,7 @@ class ArticleGrid << Gitter::Grid
39
39
  filter :topsellers, :scope => :topsellers
40
40
 
41
41
  # customized filter
42
- filter :on_stock, do |scope|
42
+ filter :on_stock do |scope|
43
43
  scope.where('stock > 0')
44
44
  end
45
45
 
@@ -73,9 +73,10 @@ class ArticleGrid << Gitter::Grid
73
73
  # make the column sortable
74
74
  column :name, :sort => true
75
75
 
76
- # customize your data cell
76
+ # Customize your data cell
77
+ # Access your model through variable 'model'
77
78
  column :price, :sort => true do
78
- "#{price/100.floor},#{price%100} USD"
79
+ "#{model.price/100.floor},#{model.price%100} USD"
79
80
  end
80
81
 
81
82
  # helpers are accessible via #h
@@ -107,12 +108,12 @@ Render you grid:
107
108
  %table
108
109
  %tr
109
110
  - @grid.headers.each do |header|
110
- %th = header
111
+ %th = header
111
112
 
112
113
  - @grid.rows.each do |row|
113
114
  %tr
114
115
  - row.each do |cell|
115
- %th = cell
116
+ %th = cell
116
117
  ```
117
118
  [More about grids](https://github.com/tracksun/gitter/wiki/Grids)
118
119
 
@@ -157,3 +158,5 @@ API inspired by [datagrid](https://github.com/bogdan/datagrid)
157
158
  # License
158
159
 
159
160
  Gitter is released under the MIT license
161
+
162
+ Copyright © 2013 Thomas Sonntag
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
6
6
  s.name = "gitter"
7
7
  s.version = Gitter::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
- s.authors = ["Thomas Sommtag"]
9
+ s.authors = ["Thomas Sonntag"]
10
10
  s.email = ["git@sonntagsbox.de"]
11
11
  s.homepage = "http://github.com/tracksun/gitter"
12
12
  s.summary = %q{Ruby gem to define searches, facets and data grids for Rails applications}
@@ -6,6 +6,7 @@ module Gitter
6
6
  autoload :Helper, 'gitter/helper'
7
7
  autoload :Controller, 'gitter/controller'
8
8
  autoload :Table, 'gitter/table'
9
+ autoload :EnumerableDriver, 'gitter/drivers/enumerable_driver'
9
10
 
10
11
  class ConfigurationError < StandardError
11
12
  end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/concern'
2
+ require 'active_support/hash_with_indifferent_access'
2
3
  require 'artdeco'
3
4
  require 'gitter/filters.rb'
4
5
  require 'gitter/facet.rb'
@@ -26,7 +27,7 @@ module Gitter
26
27
 
27
28
  @params = @decorator.params.fetch(key){{}}.symbolize_keys
28
29
 
29
- @filters, @values, @facets = {}, {}, {}
30
+ @filters, @values, @facets = {}.with_indifferent_access, {}.with_indifferent_access, {}.with_indifferent_access
30
31
  scope = opts.delete(:scope){nil}
31
32
  @options = opts.dup
32
33
 
@@ -77,7 +78,7 @@ module Gitter
77
78
  def scope &scope
78
79
  if scope
79
80
  @scope = scope
80
- else
81
+ else
81
82
  filtered_driver.scope
82
83
  end
83
84
  end
@@ -97,10 +98,15 @@ module Gitter
97
98
  if opts[:facet] && opts[:facet] != true
98
99
  opts.merge! values: opts[:facet]
99
100
  end
100
- filters = [select].flatten.map{|name| @filters[name] || scope_filter(name)}
101
+ select = [select] unless select.respond_to?(:each)
102
+ filters = select.map do |label,filter_name|
103
+ filter_name ||= label
104
+ @filters[filter_name] || scope_filter(label,filter_name,label: label)
105
+ end
101
106
  SelectFilter.new self, name, filters, opts
102
- when s = opts.delete(:scope)
103
- scope_filter( s == true ? name : s, opts )
107
+ when scope_name = opts.delete(:scope)
108
+ scope_name = name if scope_name == true
109
+ scope_filter name, scope_name
104
110
  else
105
111
  if opts[:facet] && opts[:facet] != true
106
112
  opts.merge! values: opts[:facet]
@@ -138,11 +144,11 @@ module Gitter
138
144
  create_driver(scope).less_or_equal(column, value).scope
139
145
  end
140
146
 
141
- filter name, :column => column
147
+ filter name, column: column
142
148
  end
143
149
 
144
- def scope_filter name, opts = {}
145
- BlockFilter.new(self,name, opts){|scope| create_driver(scope).named_scope(name).scope}
150
+ def scope_filter name, scope_name, opts = {}
151
+ BlockFilter.new(self, name, opts){|scope| create_driver(scope).named_scope(scope_name).scope}
146
152
  end
147
153
 
148
154
  end
@@ -16,6 +16,20 @@ module Gitter
16
16
  end
17
17
  end
18
18
 
19
+ def breadcrumbs_info
20
+ @breadcrumbs_info ||= begin
21
+ p = {}
22
+ filters.inject({}) do |memo,filter|
23
+ value = filter_value filter.name
24
+ if value.present?
25
+ p[filter.name] = value
26
+ memo[filter.name] = { label: filter.label, value: value, url: url_for(scoped_params(p)) }
27
+ end
28
+ memo
29
+ end
30
+ end
31
+ end
32
+
19
33
  def render_breadcrumbs delim = '>', params = {}
20
34
  delim_tag = h.content_tag :span, delim, {class: 'breadcrumb_delim'}
21
35
 
@@ -86,9 +86,18 @@ module Gitter
86
86
  def link label = nil, params = {}, options = {}
87
87
  label ||= headers.first.label
88
88
  if @order
89
- img = order_img_tag(options)
90
- label = grid.h.content_tag :span, img + label if ordered?
91
- grid.h.link_to label, order_params.deep_merge(params), options
89
+ #img = order_img_tag(options)
90
+ #label = grid.h.content_tag :span, img + label if ordered?
91
+ #grid.h.link_to label, order_params.deep_merge(params), options
92
+ s = ''
93
+ if !ordered? || !desc?
94
+ s += grid.h.link_to order_img_tag(false), order_params( true).deep_merge(params), options
95
+ end
96
+ if !ordered? || desc?
97
+ s += grid.h.link_to order_img_tag(true), order_params(false).deep_merge(params), options
98
+ end
99
+ s += " #{label}"
100
+ grid.h.raw s
92
101
  else
93
102
  label
94
103
  end
@@ -100,10 +109,12 @@ module Gitter
100
109
 
101
110
  private
102
111
 
103
- def order_img_tag opts = {}
104
- desc_img = opts.delete(:desc_img){'sort_desc.gif'}
105
- asc_img = opts.delete(:asc_img){'sort_asc.gif'}
106
- grid.h.image_tag( desc? ? desc_img : asc_img)
112
+ def order_img_tag desc = desc?, opts = {}
113
+ #desc_img = opts.delete(:desc_img){grid.h.image_tag 'sort_desc.gif'}
114
+ #asc_img = opts.delete(:asc_img ){grid.h.image_tag 'sort_asc.gif' }
115
+ desc_img = opts.delete(:desc_img){grid.h.fa_icon 'sort-down'}
116
+ asc_img = opts.delete(:asc_img ){grid.h.fa_icon 'sort-up' }
117
+ desc ? asc_img : desc_img
107
118
  end
108
119
 
109
120
  def to_boolean s
@@ -112,16 +123,14 @@ module Gitter
112
123
 
113
124
  # if current params contain order for this column then revert direction
114
125
  # else add order_params for this column to current params
115
- def order_params
116
- @order_params ||= begin
117
- p = grid.params.dup
118
- if ordered?
119
- p[:desc] = !desc?
120
- else
121
- p = p.merge order: name, desc: false
122
- end
123
- grid.scoped_params p
126
+ def order_params desc = !desc?
127
+ p = grid.params.dup
128
+ if ordered?
129
+ p[:desc] = desc
130
+ else
131
+ p = p.merge order: name, desc: desc
124
132
  end
133
+ grid.scoped_params p
125
134
  end
126
135
 
127
136
  def cell model
@@ -2,14 +2,21 @@ require 'active_support/concern'
2
2
  require 'gitter/column'
3
3
  require 'gitter/header'
4
4
  require 'gitter/cell'
5
+ require 'active_support/benchmarkable'
6
+ require 'logger'
5
7
 
6
8
  module Gitter
7
9
  module Columns
10
+ include ActiveSupport::Benchmarkable
8
11
  extend ActiveSupport::Concern
9
12
 
10
13
  included do
11
14
  alias_method_chain :scope, :columns
12
15
  end
16
+
17
+ def logger
18
+ @logger ||= Logger.new(STDOUT)
19
+ end
13
20
 
14
21
  def header_row
15
22
  @current_header_row = []
@@ -47,8 +54,15 @@ module Gitter
47
54
  end
48
55
 
49
56
  def rows_for model
50
- cols = columns.map{|c| [c.cells(model)].flatten }
57
+ #benchmark "---------rows_for #{model}" do
58
+ cols = nil
59
+ cols = columns.map do |c|
60
+ # benchmark "cells for #{c.name}" do
61
+ [c.cells(model)].flatten
62
+ # end
63
+ end
51
64
  max = cols.map{|col|col.size}.max
65
+
52
66
  cols.map do |col|
53
67
  nil_padded_cells = Array.new(max){|i| col[i]}
54
68
  cells = []
@@ -62,6 +76,7 @@ module Gitter
62
76
  end
63
77
  cells
64
78
  end.transpose
79
+ #end
65
80
  end
66
81
 
67
82
  def rows scope = nil
@@ -0,0 +1,74 @@
1
+ require 'gitter/drivers/abstract_driver'
2
+ module Gitter
3
+
4
+ class EnumerableDriver < AbstractDriver
5
+
6
+ def count
7
+ scope.size
8
+ end
9
+
10
+ def order attr, desc = nil
11
+ sign = case desc
12
+ when true, 'true' then 1
13
+ when false, 'false' then -1
14
+ else -1
15
+ end
16
+ new scope.sort{|a,b| sign * (a.send(attr).try(:to_s) <=> b.send(attr).try(:to_s)) }
17
+ end
18
+
19
+ def unordered
20
+ self
21
+ end
22
+
23
+ def group arg
24
+ new scope.group_by(&arg)
25
+ end
26
+
27
+ def where attr_values, opts = {}
28
+ exact = opts.fetch(:exact){true}
29
+ ignore_case = opts.fetch(:ignore_case){false}
30
+ strip_blank = opts.fetch(:strip_blank){false}
31
+
32
+ attr_texts = attr_values.map do |attr,value|
33
+ value = value.strip if strip_blank
34
+ text = exact ? value : /#{value}/
35
+ text = /#{value}/i if ignore_case
36
+ [attr,text]
37
+ end
38
+
39
+ s = scope.find_all do |item|
40
+ attr_texts.all? do |attr,text|
41
+ data = item.send(attr).try(:to_s)
42
+ text === data
43
+ end
44
+ end
45
+
46
+ new s
47
+ end
48
+
49
+ def greater_or_equal attr, value
50
+ scope.find_all{|item| item.send(:attr) >= value}
51
+ end
52
+
53
+ def less_or_equal attr, value
54
+ scope.find_all{|item| item.send(:attr) <= value}
55
+ end
56
+
57
+ def each &block
58
+ new scope.each(&block)
59
+ end
60
+
61
+ def named_scope name
62
+ raise NotImplementError
63
+ end
64
+
65
+ def distinct_values attr
66
+ group(attr).keys.uniq
67
+ end
68
+
69
+ def to_s
70
+ scope.to_s
71
+ end
72
+
73
+ end
74
+ end
@@ -30,13 +30,15 @@ module Gitter
30
30
  @label || raw_value || '-'
31
31
  end
32
32
 
33
- def link
33
+ def link opts = {}
34
34
  @link ||= begin
35
35
  p = grid.params.dup
36
36
  p.delete name
37
37
  p[name] = raw_value if raw_value.present?
38
38
  p = grid.scoped_params p
39
39
  p[:page] = 1
40
+ p[:show] = true
41
+ p = p.merge(opts)
40
42
 
41
43
  value_class = selected? ? 'facet_value_selected' : 'selected'
42
44
  value_tag = h.content_tag :span, label, class: value_class
@@ -44,7 +46,6 @@ module Gitter
44
46
 
45
47
  if selected? or not facet.selected?
46
48
  count_tag = h.content_tag :span, "(#{count})", class: 'facet_count'
47
- #count_tag = h.link_to count_tag, url_for(p.merge(show: true))
48
49
  else
49
50
  count_tag = ''
50
51
  end
@@ -1,12 +1,15 @@
1
+ module Gitter
2
+
1
3
  class AbstractFilter
2
4
 
3
- attr_reader :grid, :name, :input_options, :input_tag, :formatter, :order, :label
5
+ attr_reader :grid, :name, :input_options, :input_tag, :input_class, :formatter, :order, :label
4
6
 
5
7
  def initialize grid, name, opts = {}
6
8
  @grid, @name = grid, name
7
9
  @label = opts.delete(:label){grid.translate(:filters, name)}
8
10
  @input_options = opts.delete(:input){nil}
9
11
  @input_tag = opts.delete(:input_tag){nil}
12
+ @input_class = opts.delete(:input_class){''}
10
13
  @include_blank = opts.delete(:include_blank){false}
11
14
 
12
15
  @formatter = opts.delete(:formatter){nil}
@@ -52,7 +55,7 @@
52
55
  return '' unless input?
53
56
 
54
57
  @input_tag ||= if col = collection
55
- col = [''] + col if include_blank? && col.size > 1
58
+ #col = [''] + col if include_blank? && col.size > 1
56
59
  select_tag col
57
60
  else
58
61
  text_field_tag
@@ -60,11 +63,12 @@
60
63
  end
61
64
 
62
65
  def text_field_tag
63
- @text_field_tag ||= h.text_field_tag scoped_name, grid.params[name.intern], :class => 'grid'
66
+ @text_field_tag ||= h.text_field_tag scoped_name, grid.params[name.intern],
67
+ class: input_classes
64
68
  end
65
69
 
66
70
  def select_tag collection
67
- h.select_tag scoped_name, h.options_for_select(collection, grid.params[name.intern]), :class => 'grid'
71
+ h.select_tag scoped_name, h.options_for_select(collection, grid.params[name.intern]), include_blank: include_blank?, class: input_classes
68
72
  end
69
73
 
70
74
  def format value
@@ -91,4 +95,9 @@
91
95
  def sort_hash hash
92
96
  hash.keys.sort.inject({}){|memo,k|memo[k] = hash[k]; memo}
93
97
  end
98
+
99
+ def input_classes
100
+ "grid grid-#{name} #{input_class}"
101
+ end
102
+ end
94
103
  end
@@ -6,7 +6,7 @@ module Gitter
6
6
 
7
7
  def initialize grid, name, filters, opts = {}
8
8
  super grid, name, opts
9
- @filters = filters.inject({}){|memo,filter| memo[filter.name] = filter; memo}
9
+ @filters = filters.inject({}.with_indifferent_access){|memo,filter| memo[filter.name] = filter; memo}
10
10
  @values = opts[:values]
11
11
  if @input_options == true
12
12
  @input_options = {}
@@ -40,5 +40,9 @@ module Gitter
40
40
  end
41
41
  end
42
42
 
43
+ def input_tag name
44
+ input_tags[name]
45
+ end
46
+
43
47
  end
44
48
  end
@@ -90,12 +90,12 @@ module Gitter
90
90
  end
91
91
  end
92
92
 
93
- def html
93
+ def html opts = {}
94
94
  @html ||= begin
95
95
  h = rows.map do |row|
96
- Table.tag :tr, (row.map{|cell| cell.html} * "\n")
96
+ Table.tag :tr, (row.map{|cell| cell.html} * "\n"), (opts[:tr_html]||{})
97
97
  end * "\n"
98
- Table.tag :table, h
98
+ Table.tag :table, h, (opts[:table_html]||{})
99
99
  end
100
100
  end
101
101
 
@@ -1,3 +1,3 @@
1
1
  module Gitter
2
- VERSION = "1.1.5"
2
+ VERSION = "1.1.6"
3
3
  end
metadata CHANGED
@@ -1,75 +1,67 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
5
- prerelease:
4
+ version: 1.1.6
6
5
  platform: ruby
7
6
  authors:
8
- - Thomas Sommtag
7
+ - Thomas Sonntag
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-04-29 00:00:00.000000000 Z
11
+ date: 2014-11-11 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '3.2'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '3.2'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: activerecord
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '3.2'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: '3.2'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: artdeco
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '1.2'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '1.2'
62
- description: ! " To be used within Rails applications.\n Helps you to define
63
- searches with filters and facets \n and data tables with sortable columns and
64
- filters.\n"
55
+ description: " To be used within Rails applications.\n Helps you to define searches
56
+ with filters and facets \n and data tables with sortable columns and filters.\n"
65
57
  email:
66
58
  - git@sonntagsbox.de
67
59
  executables: []
68
60
  extensions: []
69
61
  extra_rdoc_files: []
70
62
  files:
71
- - .gitignore
72
- - .travis.yml
63
+ - ".gitignore"
64
+ - ".travis.yml"
73
65
  - Gemfile
74
66
  - Gemfile.lock
75
67
  - Guardfile
@@ -91,6 +83,7 @@ files:
91
83
  - lib/gitter/driver.rb
92
84
  - lib/gitter/drivers/abstract_driver.rb
93
85
  - lib/gitter/drivers/active_record_driver.rb
86
+ - lib/gitter/drivers/enumerable_driver.rb
94
87
  - lib/gitter/facet.rb
95
88
  - lib/gitter/filters.rb
96
89
  - lib/gitter/filters/abstract_filter.rb
@@ -126,27 +119,42 @@ files:
126
119
  - spec/support/person_grid.rb
127
120
  homepage: http://github.com/tracksun/gitter
128
121
  licenses: []
122
+ metadata: {}
129
123
  post_install_message:
130
124
  rdoc_options: []
131
125
  require_paths:
132
126
  - lib
133
127
  - assets
134
128
  required_ruby_version: !ruby/object:Gem::Requirement
135
- none: false
136
129
  requirements:
137
- - - ! '>='
130
+ - - ">="
138
131
  - !ruby/object:Gem::Version
139
132
  version: '0'
140
133
  required_rubygems_version: !ruby/object:Gem::Requirement
141
- none: false
142
134
  requirements:
143
- - - ! '>='
135
+ - - ">="
144
136
  - !ruby/object:Gem::Version
145
137
  version: '0'
146
138
  requirements: []
147
139
  rubyforge_project: gitter
148
- rubygems_version: 1.8.24
140
+ rubygems_version: 2.2.2
149
141
  signing_key:
150
- specification_version: 3
142
+ specification_version: 4
151
143
  summary: Ruby gem to define searches, facets and data grids for Rails applications
152
- test_files: []
144
+ test_files:
145
+ - spec/breadcrumbs_spec.rb
146
+ - spec/column_filter_spec.rb
147
+ - spec/column_spec.rb
148
+ - spec/facets_spec.rb
149
+ - spec/grid_spec.rb
150
+ - spec/helper_spec.rb
151
+ - spec/i18n_spec.rb
152
+ - spec/inputs_spec.rb
153
+ - spec/locales/de.yml
154
+ - spec/locales/en.yml
155
+ - spec/range_filter_spec.rb
156
+ - spec/scope_filter_spec.rb
157
+ - spec/select_filter_spec.rb
158
+ - spec/spec_helper.rb
159
+ - spec/support/database.rb
160
+ - spec/support/person_grid.rb