gitter 1.1.5 → 1.1.6

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