admino 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +4 -0
- data/lib/admino/query.rb +2 -0
- data/lib/admino/query/base.rb +12 -1
- data/lib/admino/query/base_presenter.rb +1 -0
- data/lib/admino/query/configuration.rb +25 -0
- data/lib/admino/query/dsl.rb +5 -0
- data/lib/admino/query/group.rb +4 -4
- data/lib/admino/query/sorting.rb +74 -0
- data/lib/admino/query/sorting_presenter.rb +41 -0
- data/lib/admino/table/head_row.rb +11 -1
- data/lib/admino/table/presenter.rb +11 -5
- data/lib/admino/version.rb +2 -1
- data/spec/admino/query/base_spec.rb +17 -0
- data/spec/admino/query/dsl_spec.rb +7 -0
- data/spec/admino/query/group_presenter_spec.rb +20 -14
- data/spec/admino/query/group_spec.rb +7 -7
- data/spec/admino/query/sorting_presenter_spec.rb +167 -0
- data/spec/admino/query/sorting_spec.rb +129 -0
- data/spec/admino/table/head_row_spec.rb +27 -2
- data/spec/admino/table/presenter_spec.rb +3 -2
- data/spec/spec_helper.rb +4 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3846d45b87e8e04505a972b8deabf753e7518ed
|
4
|
+
data.tar.gz: f5a5177a520c3e14ce1828f0158e983ae230f93e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c063c612bd312def34cccd381533613f7c13aa2ad27470065ebe1ec90671ad3abf71a49893a7986e9c1dae0aa757c5dc0f2b59285f863d610a331173a4f25fb7
|
7
|
+
data.tar.gz: dc64e3c91e279a3c631bdd1cdd7503d17b6945e8b6b3ccbc39566d9246b3007108ec09e3ba5e0588d01d4b2b2004e6ad5d1e578b340906b1812b7ee902d38707
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Admino
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/cantierecreativo/admino.png?branch=v0.0.1)](https://travis-ci.org/cantierecreativo/admino)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/cantierecreativo/admino/badge.png?branch=master)](https://coveralls.io/r/cantierecreativo/admino?branch=master)
|
5
|
+
|
3
6
|
TODO: Write a gem description
|
4
7
|
|
5
8
|
## Installation
|
@@ -27,3 +30,4 @@ TODO: Write usage instructions here
|
|
27
30
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
31
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
32
|
5. Create new Pull Request
|
33
|
+
|
data/lib/admino/query.rb
CHANGED
data/lib/admino/query/base.rb
CHANGED
@@ -15,6 +15,7 @@ module Admino
|
|
15
15
|
attr_reader :params
|
16
16
|
attr_reader :groups
|
17
17
|
attr_reader :fields
|
18
|
+
attr_reader :sorting
|
18
19
|
|
19
20
|
def self.i18n_scope
|
20
21
|
:query
|
@@ -26,6 +27,7 @@ module Admino
|
|
26
27
|
|
27
28
|
init_groups
|
28
29
|
init_fields
|
30
|
+
init_sorting
|
29
31
|
end
|
30
32
|
|
31
33
|
def scope(starting_scope = nil)
|
@@ -37,7 +39,10 @@ module Admino
|
|
37
39
|
|
38
40
|
scope_builder = starting_scope
|
39
41
|
|
40
|
-
|
42
|
+
scope_augmenters = fields + groups
|
43
|
+
scope_augmenters << sorting if sorting
|
44
|
+
|
45
|
+
scope_augmenters.each do |field|
|
41
46
|
scope_builder = field.augment_scope(scope_builder)
|
42
47
|
end
|
43
48
|
|
@@ -88,6 +93,12 @@ module Admino
|
|
88
93
|
@fields[config.name] = Field.new(config, params)
|
89
94
|
end
|
90
95
|
end
|
96
|
+
|
97
|
+
def init_sorting
|
98
|
+
if config.sorting
|
99
|
+
@sorting = Sorting.new(config.sorting, params)
|
100
|
+
end
|
101
|
+
end
|
91
102
|
end
|
92
103
|
end
|
93
104
|
end
|
@@ -27,8 +27,29 @@ module Admino
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
class Sorting
|
31
|
+
attr_reader :scopes
|
32
|
+
attr_reader :default_scope
|
33
|
+
attr_reader :default_direction
|
34
|
+
|
35
|
+
def initialize(scopes, options = {})
|
36
|
+
options.symbolize_keys!
|
37
|
+
options.assert_valid_keys(:default_scope, :default_direction)
|
38
|
+
|
39
|
+
@scopes = scopes.map(&:to_sym)
|
40
|
+
@default_scope = if options[:default_scope]
|
41
|
+
options[:default_scope].to_sym
|
42
|
+
end
|
43
|
+
|
44
|
+
@default_direction = if options[:default_direction]
|
45
|
+
options[:default_direction].to_sym
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
30
50
|
attr_reader :fields
|
31
51
|
attr_reader :groups
|
52
|
+
attr_reader :sorting
|
32
53
|
attr_accessor :starting_scope_callable
|
33
54
|
attr_accessor :ending_scope_callable
|
34
55
|
|
@@ -48,6 +69,10 @@ module Admino
|
|
48
69
|
self.groups << group
|
49
70
|
end
|
50
71
|
end
|
72
|
+
|
73
|
+
def add_sorting_scopes(scopes, options = {})
|
74
|
+
@sorting = Sorting.new(scopes, options)
|
75
|
+
end
|
51
76
|
end
|
52
77
|
end
|
53
78
|
end
|
data/lib/admino/query/dsl.rb
CHANGED
data/lib/admino/query/group.rb
CHANGED
@@ -15,14 +15,14 @@ module Admino
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def augment_scope(scope)
|
18
|
-
if
|
19
|
-
scope.send(
|
18
|
+
if active_scope
|
19
|
+
scope.send(active_scope)
|
20
20
|
else
|
21
21
|
scope
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def active_scope
|
26
26
|
if param_value && available_scopes.include?(param_value.to_sym)
|
27
27
|
param_value.to_sym
|
28
28
|
else
|
@@ -31,7 +31,7 @@ module Admino
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def is_scope_active?(scope)
|
34
|
-
|
34
|
+
active_scope == scope
|
35
35
|
end
|
36
36
|
|
37
37
|
def param_value
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'coercible'
|
2
|
+
require 'active_support/hash_with_indifferent_access'
|
3
|
+
require 'active_support/core_ext/hash'
|
4
|
+
|
5
|
+
module Admino
|
6
|
+
module Query
|
7
|
+
class Sorting
|
8
|
+
attr_reader :params
|
9
|
+
attr_reader :config
|
10
|
+
|
11
|
+
def initialize(config, params)
|
12
|
+
@config = config
|
13
|
+
@params = ActiveSupport::HashWithIndifferentAccess.new(params)
|
14
|
+
end
|
15
|
+
|
16
|
+
def augment_scope(scope)
|
17
|
+
if active_scope
|
18
|
+
scope.send(active_scope, ascending? ? :asc : :desc)
|
19
|
+
else
|
20
|
+
scope
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def is_scope_active?(scope)
|
25
|
+
active_scope == scope
|
26
|
+
end
|
27
|
+
|
28
|
+
def ascending?
|
29
|
+
if params[:sort_order] == 'desc'
|
30
|
+
false
|
31
|
+
elsif params[:sort_order].blank? && active_scope == default_scope
|
32
|
+
default_direction_is_ascending?
|
33
|
+
else
|
34
|
+
true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def active_scope
|
39
|
+
if param_value && available_scopes.include?(param_value.to_sym)
|
40
|
+
param_value.to_sym
|
41
|
+
elsif default_scope
|
42
|
+
default_scope
|
43
|
+
else
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def default_scope
|
49
|
+
config.default_scope
|
50
|
+
end
|
51
|
+
|
52
|
+
def default_direction_is_ascending?
|
53
|
+
config.default_direction != :desc
|
54
|
+
end
|
55
|
+
|
56
|
+
def param_value
|
57
|
+
params.fetch(param_name, nil)
|
58
|
+
end
|
59
|
+
|
60
|
+
def param_name
|
61
|
+
:sorting
|
62
|
+
end
|
63
|
+
|
64
|
+
def available_scopes
|
65
|
+
config.scopes
|
66
|
+
end
|
67
|
+
|
68
|
+
def scope_name
|
69
|
+
config.name
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'showcase'
|
2
|
+
|
3
|
+
module Admino
|
4
|
+
module Query
|
5
|
+
class SortingPresenter < Showcase::Presenter
|
6
|
+
def scope_link(scope, label, *args)
|
7
|
+
options = args.extract_options!
|
8
|
+
|
9
|
+
desc_class = options.delete(:desc_class) { 'is-desc' }
|
10
|
+
asc_class = options.delete(:asc_class) { 'is-asc' }
|
11
|
+
|
12
|
+
options = Showcase::Helpers::HtmlOptions.new(options)
|
13
|
+
|
14
|
+
if is_scope_active?(scope)
|
15
|
+
options.add_class!(ascending? ? asc_class : desc_class)
|
16
|
+
end
|
17
|
+
|
18
|
+
h.link_to label, scope_path(scope), options.to_h
|
19
|
+
end
|
20
|
+
|
21
|
+
def scope_path(scope)
|
22
|
+
h.request.path + "?" + scope_params(scope).to_query
|
23
|
+
end
|
24
|
+
|
25
|
+
def scope_params(scope)
|
26
|
+
params = ActiveSupport::HashWithIndifferentAccess.new(h.request.query_parameters)
|
27
|
+
|
28
|
+
if is_scope_active?(scope)
|
29
|
+
params.merge!(sorting: scope.to_s, sort_order: ascending? ? 'desc' : 'asc')
|
30
|
+
elsif default_scope == scope
|
31
|
+
params.merge!(sorting: scope.to_s, sort_order: default_direction.to_s)
|
32
|
+
else
|
33
|
+
params.merge!(sorting: scope.to_s, sort_order: 'asc')
|
34
|
+
end
|
35
|
+
|
36
|
+
params
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -5,9 +5,11 @@ module Admino
|
|
5
5
|
module Table
|
6
6
|
class HeadRow < Row
|
7
7
|
attr_reader :resource_klass
|
8
|
+
attr_reader :query
|
8
9
|
|
9
|
-
def initialize(resource_klass, view_context)
|
10
|
+
def initialize(resource_klass, query, view_context)
|
10
11
|
@resource_klass = resource_klass
|
12
|
+
@query = query
|
11
13
|
@columns = ""
|
12
14
|
|
13
15
|
super(view_context)
|
@@ -38,6 +40,14 @@ module Admino
|
|
38
40
|
default_options = column_html_options(attribute_name)
|
39
41
|
html_options = Showcase::Helpers::HtmlOptions.new(default_options)
|
40
42
|
html_options.merge_attrs!(options)
|
43
|
+
html_options = html_options.to_h
|
44
|
+
|
45
|
+
sorting_scope = html_options.delete(:sorting)
|
46
|
+
if sorting_scope
|
47
|
+
raise ArgumentError, 'query object is required' unless query
|
48
|
+
sorting_html_options = html_options.delete(:sorting_html_options) { {} }
|
49
|
+
label = query.sorting.scope_link(sorting_scope, label, sorting_html_options)
|
50
|
+
end
|
41
51
|
|
42
52
|
@columns << h.content_tag(:th, label.to_s, html_options.to_h)
|
43
53
|
end
|
@@ -6,6 +6,7 @@ module Admino
|
|
6
6
|
module Table
|
7
7
|
class Presenter < Showcase::Presenter
|
8
8
|
attr_reader :collection_klass
|
9
|
+
attr_reader :query
|
9
10
|
|
10
11
|
def self.tag_helper(name, tag, options = {})
|
11
12
|
default_options_method = :"#{name}_html_options"
|
@@ -28,8 +29,13 @@ module Admino
|
|
28
29
|
tag_helper :tbody, :tbody
|
29
30
|
tag_helper :tbody_tr, :tr, params: %w(resource index)
|
30
31
|
|
31
|
-
def initialize(
|
32
|
-
|
32
|
+
def initialize(*args)
|
33
|
+
context = args.pop
|
34
|
+
collection = args.shift
|
35
|
+
|
36
|
+
@collection_klass = args.shift
|
37
|
+
@query = args.shift
|
38
|
+
|
33
39
|
super(collection, context)
|
34
40
|
end
|
35
41
|
|
@@ -37,7 +43,7 @@ module Admino
|
|
37
43
|
table_tag(options) do
|
38
44
|
thead_tag do
|
39
45
|
thead_tr_tag do
|
40
|
-
row = head_row(collection_klass, view_context)
|
46
|
+
row = head_row(collection_klass, query, view_context)
|
41
47
|
h.capture(row, nil, &block) if block_given?
|
42
48
|
row.to_html
|
43
49
|
end
|
@@ -64,8 +70,8 @@ module Admino
|
|
64
70
|
@collection ||= present_collection(object)
|
65
71
|
end
|
66
72
|
|
67
|
-
def head_row(collection_klass, view_context)
|
68
|
-
HeadRow.new(collection_klass, view_context)
|
73
|
+
def head_row(collection_klass, query, view_context)
|
74
|
+
HeadRow.new(collection_klass, query, view_context)
|
69
75
|
end
|
70
76
|
|
71
77
|
def resource_row(resource, view_context)
|
data/lib/admino/version.rb
CHANGED
@@ -50,6 +50,23 @@ module Admino
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
context 'with a declared sorting' do
|
54
|
+
let(:config) { Configuration.new }
|
55
|
+
let(:sorting_config) do
|
56
|
+
config.add_sorting_scopes([:by_title, :by_date])
|
57
|
+
end
|
58
|
+
|
59
|
+
before do
|
60
|
+
sorting_config
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'returns a configured Sorting' do
|
64
|
+
sorting = query.sorting
|
65
|
+
expect(sorting.config).to eq sorting_config
|
66
|
+
expect(sorting.params).to eq params
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
53
70
|
describe '#scope' do
|
54
71
|
let(:config) { Configuration.new }
|
55
72
|
let(:result) { query.scope(starting_scope) }
|
@@ -18,6 +18,13 @@ module Admino
|
|
18
18
|
expect(group.scopes).to eq [:one, :two]
|
19
19
|
end
|
20
20
|
|
21
|
+
it 'allows #sortings declaration' do
|
22
|
+
sorting = config.sorting
|
23
|
+
expect(sorting.scopes).to eq [:by_title, :by_date]
|
24
|
+
expect(sorting.default_scope).to eq :by_title
|
25
|
+
expect(sorting.default_direction).to eq :desc
|
26
|
+
end
|
27
|
+
|
21
28
|
it 'allows #starting_scope block declaration' do
|
22
29
|
expect(config.starting_scope_callable.call).to eq 'start'
|
23
30
|
end
|
@@ -26,29 +26,33 @@ module Admino
|
|
26
26
|
end
|
27
27
|
|
28
28
|
describe '#scope_link' do
|
29
|
+
subject { presenter.scope_link(:foo) }
|
30
|
+
|
29
31
|
before do
|
30
|
-
group.stub(:is_scope_active?).with(:foo).and_return(
|
32
|
+
group.stub(:is_scope_active?).with(:foo).and_return(false)
|
31
33
|
end
|
32
34
|
|
33
35
|
context 'active CSS class' do
|
36
|
+
before do
|
37
|
+
group.stub(:is_scope_active?).with(:foo).and_return(true)
|
38
|
+
end
|
39
|
+
|
34
40
|
it 'adds an is-active class' do
|
35
|
-
|
41
|
+
should have_tag(:a, with: { class: 'is-active' })
|
36
42
|
end
|
37
43
|
|
38
44
|
context 'if an :active_class option is specified' do
|
45
|
+
subject { presenter.scope_link(:foo, active_class: 'active') }
|
46
|
+
|
39
47
|
it 'adds it' do
|
40
|
-
|
48
|
+
should have_tag(:a, with: { class: 'active' })
|
41
49
|
end
|
42
50
|
end
|
51
|
+
end
|
43
52
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'does not add it' do
|
50
|
-
expect(presenter.scope_link(:foo)).not_to have_tag(:a, with: { class: 'is-active' })
|
51
|
-
end
|
53
|
+
context 'else' do
|
54
|
+
it 'does not add it' do
|
55
|
+
should_not have_tag(:a, with: { class: 'is-active' })
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
@@ -58,12 +62,14 @@ module Admino
|
|
58
62
|
end
|
59
63
|
|
60
64
|
it 'uses #scope_name method' do
|
61
|
-
|
65
|
+
should have_tag(:a, text: 'scope_name')
|
62
66
|
end
|
63
67
|
|
64
68
|
context 'if a second parameter is supplied' do
|
69
|
+
subject { presenter.scope_link(:foo, 'test', active_class: 'active') }
|
70
|
+
|
65
71
|
it 'uses it' do
|
66
|
-
|
72
|
+
should have_tag(:a, text: 'test')
|
67
73
|
end
|
68
74
|
end
|
69
75
|
end
|
@@ -74,7 +80,7 @@ module Admino
|
|
74
80
|
end
|
75
81
|
|
76
82
|
it 'uses #scope_path method' do
|
77
|
-
|
83
|
+
should have_tag(:a, href: 'URL')
|
78
84
|
end
|
79
85
|
end
|
80
86
|
end
|
@@ -7,28 +7,28 @@ module Admino
|
|
7
7
|
let(:config) { Configuration::Group.new(:foo, [:bar]) }
|
8
8
|
let(:params) { {} }
|
9
9
|
|
10
|
-
describe '#
|
10
|
+
describe '#active_scope' do
|
11
11
|
context 'with no param' do
|
12
12
|
let(:params) { {} }
|
13
13
|
|
14
|
-
it 'returns
|
15
|
-
expect(group.
|
14
|
+
it 'returns nil' do
|
15
|
+
expect(group.active_scope).to be_nil
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
context 'with an invalid value' do
|
20
20
|
let(:params) { { 'foo' => 'qux' } }
|
21
21
|
|
22
|
-
it 'returns
|
23
|
-
expect(group.
|
22
|
+
it 'returns nil' do
|
23
|
+
expect(group.active_scope).to be_nil
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
context 'with a valid value' do
|
28
28
|
let(:params) { { 'foo' => 'bar' } }
|
29
29
|
|
30
|
-
it 'returns
|
31
|
-
expect(group.
|
30
|
+
it 'returns the scope name' do
|
31
|
+
expect(group.active_scope).to eq :bar
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Admino
|
4
|
+
module Query
|
5
|
+
describe SortingPresenter do
|
6
|
+
subject(:presenter) { SortingPresenter.new(sorting, view) }
|
7
|
+
let(:view) { RailsViewContext.new }
|
8
|
+
let(:sorting) { double('Sorting', default_scope: 'by_name') }
|
9
|
+
let(:request_object) do
|
10
|
+
double(
|
11
|
+
'ActionDispatch::Request',
|
12
|
+
query_parameters: { 'sorting' => 'by_date' },
|
13
|
+
path: '/'
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
view.stub(:request).and_return(request_object)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#scope_link' do
|
22
|
+
subject { presenter.scope_link(:by_title, 'Titolo') }
|
23
|
+
|
24
|
+
before do
|
25
|
+
sorting.stub(:is_scope_active?).with(:by_title).and_return(false)
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'scope is active' do
|
29
|
+
before do
|
30
|
+
sorting.stub(:is_scope_active?).with(:by_title).and_return(true)
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'ascending' do
|
34
|
+
before do
|
35
|
+
sorting.stub(:ascending?).and_return(true)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'adds an is-asc class' do
|
39
|
+
should have_tag(:a, with: { class: 'is-asc' })
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'if an :asc_class option is specified' do
|
43
|
+
subject { presenter.scope_link(:by_title, 'Titolo', asc_class: 'asc') }
|
44
|
+
|
45
|
+
it 'adds it' do
|
46
|
+
should have_tag(:a, with: { class: 'asc' })
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'descendent' do
|
52
|
+
before do
|
53
|
+
sorting.stub(:ascending?).and_return(false)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'adds an is-desc class' do
|
57
|
+
should have_tag(:a, with: { class: 'is-desc' })
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'if a :desc_class option is specified' do
|
61
|
+
subject { presenter.scope_link(:by_title, 'Titolo', desc_class: 'desc') }
|
62
|
+
|
63
|
+
it 'adds it' do
|
64
|
+
should have_tag(:a, with: { class: 'desc' })
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'else' do
|
71
|
+
it 'does not add it' do
|
72
|
+
should_not have_tag(:a, with: { class: 'is-asc' })
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'label' do
|
77
|
+
it 'uses the provided argument' do
|
78
|
+
should have_tag(:a, text: 'Titolo')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'URL' do
|
83
|
+
before do
|
84
|
+
presenter.stub(:scope_path).with(:by_title).and_return('URL')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'uses #scope_path method' do
|
88
|
+
should have_tag(:a, href: 'URL')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '#scope_params' do
|
94
|
+
subject { presenter.scope_params(:by_title) }
|
95
|
+
|
96
|
+
before do
|
97
|
+
sorting.stub(:is_scope_active?).with(:by_title).and_return(false)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'sets the sorting param as the scope' do
|
101
|
+
subject[:sorting] == 'by_title'
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'scope is active' do
|
105
|
+
before do
|
106
|
+
sorting.stub(:is_scope_active?).with(:by_title).and_return(true)
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'is currently ascending' do
|
110
|
+
before do
|
111
|
+
sorting.stub(:ascending?).and_return(true)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'sets the sorting order to descending' do
|
115
|
+
subject[:sort_order] == 'desc'
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'is currently descending' do
|
120
|
+
before do
|
121
|
+
sorting.stub(:ascending?).and_return(false)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'sets the sorting order to ascending' do
|
125
|
+
subject[:sort_order] == 'asc'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'scope is the default one' do
|
131
|
+
let(:sorting) { double('Sorting', default_scope: 'by_title') }
|
132
|
+
|
133
|
+
context 'default scope is ascending' do
|
134
|
+
before do
|
135
|
+
sorting.stub(:default_direction).and_return(:asc)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'sets the sorting order to ascending' do
|
139
|
+
subject[:sort_order] == 'asc'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'default scope is descending' do
|
144
|
+
before do
|
145
|
+
sorting.stub(:default_direction).and_return(:desc)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'sets the sorting order to descending' do
|
149
|
+
subject[:sort_order] == 'desc'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'else' do
|
155
|
+
before do
|
156
|
+
sorting.stub(:is_scope_active?).with(:by_title).and_return(false)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'sets the sorting order to ascending' do
|
160
|
+
subject[:sort_order] == 'asc'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Admino
|
4
|
+
module Query
|
5
|
+
describe Sorting do
|
6
|
+
subject(:sorting) { Sorting.new(config, params) }
|
7
|
+
let(:config) do
|
8
|
+
Configuration::Sorting.new(sorting_scopes, options)
|
9
|
+
end
|
10
|
+
let(:sorting_scopes) { [:by_title, :by_date] }
|
11
|
+
let(:options) { {} }
|
12
|
+
let(:params) { {} }
|
13
|
+
|
14
|
+
describe '#active_scope' do
|
15
|
+
context 'with no param' do
|
16
|
+
let(:params) { {} }
|
17
|
+
|
18
|
+
it 'returns false' do
|
19
|
+
expect(sorting.active_scope).to be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'if a default scope is configured' do
|
23
|
+
let(:options) { { default_scope: :by_date } }
|
24
|
+
|
25
|
+
it 'returns it' do
|
26
|
+
expect(sorting.active_scope).to eq :by_date
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with an invalid value' do
|
32
|
+
let(:params) { { 'sorting' => 'foo' } }
|
33
|
+
|
34
|
+
it 'returns false' do
|
35
|
+
expect(sorting.active_scope).to be_nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with a valid value' do
|
40
|
+
let(:params) { { 'sorting' => 'by_title' } }
|
41
|
+
|
42
|
+
it 'returns the scope name' do
|
43
|
+
expect(sorting.active_scope).to eq :by_title
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#ascending?' do
|
49
|
+
context 'with no param' do
|
50
|
+
let(:params) { {} }
|
51
|
+
|
52
|
+
it 'returns true' do
|
53
|
+
expect(sorting).to be_ascending
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'with invalid value' do
|
58
|
+
let(:params) { { 'sort_order' => 'foo' } }
|
59
|
+
|
60
|
+
it 'returns true' do
|
61
|
+
expect(sorting).to be_ascending
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'with "asc" value' do
|
66
|
+
let(:params) { { 'sort_order' => 'asc' } }
|
67
|
+
|
68
|
+
it 'returns nil' do
|
69
|
+
expect(sorting).to be_ascending
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'with "desc" value' do
|
74
|
+
let(:params) { { 'sort_order' => 'desc' } }
|
75
|
+
|
76
|
+
it 'returns the param value for the field' do
|
77
|
+
expect(sorting).not_to be_ascending
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'if a default scope and direction are set and default scope is current' do
|
82
|
+
let(:options) { { default_scope: :by_date, default_direction: :desc } }
|
83
|
+
let(:params) { { 'sorting' => 'by_date', 'sort_order' => 'desc' } }
|
84
|
+
|
85
|
+
it 'returns it' do
|
86
|
+
expect(sorting).not_to be_ascending
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#augment_scope' do
|
92
|
+
let(:result) { sorting.augment_scope(scope) }
|
93
|
+
let(:scope) { ScopeMock.new('original') }
|
94
|
+
|
95
|
+
context 'if the field has a value' do
|
96
|
+
let(:params) { { 'sorting' => 'by_title', 'sort_order' => 'desc' } }
|
97
|
+
|
98
|
+
it 'returns the original scope chained with the current scope' do
|
99
|
+
expect(result.chain).to eq [:by_title, [:desc]]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'else' do
|
104
|
+
it 'returns the original scope' do
|
105
|
+
expect(result).to eq scope
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'if a default scope is configured' do
|
110
|
+
let(:options) { { default_scope: :by_date } }
|
111
|
+
let(:params) { {} }
|
112
|
+
|
113
|
+
it 'returns the original scope chained with the default scope' do
|
114
|
+
expect(result.chain).to eq [:by_date, [:asc]]
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'if a default direction is configured' do
|
118
|
+
let(:options) { { default_scope: :by_date, default_direction: :desc } }
|
119
|
+
|
120
|
+
it 'returns the original scope chained with the default scope and default direction' do
|
121
|
+
expect(result.chain).to eq [:by_date, [:desc]]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
@@ -3,9 +3,10 @@ require 'spec_helper'
|
|
3
3
|
module Admino
|
4
4
|
module Table
|
5
5
|
describe HeadRow do
|
6
|
-
subject(:row) { HeadRow.new(klass, view) }
|
7
|
-
let(:view) { RailsViewContext.new }
|
6
|
+
subject(:row) { HeadRow.new(klass, query, view) }
|
8
7
|
let(:klass) { Post }
|
8
|
+
let(:query) { nil }
|
9
|
+
let(:view) { RailsViewContext.new }
|
9
10
|
|
10
11
|
it 'takes a class and a view context' do
|
11
12
|
expect(row.resource_klass).to eq klass
|
@@ -50,6 +51,30 @@ module Admino
|
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
54
|
+
context 'sorting' do
|
55
|
+
context 'if no query object is present' do
|
56
|
+
it 'raises an ArgumentError' do
|
57
|
+
expect { row.column(:title, sorting: :by_title) }.to raise_error ArgumentError
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'else' do
|
62
|
+
let(:query) { double('Query', sorting: sorting) }
|
63
|
+
let(:sorting) { double('Sorting') }
|
64
|
+
|
65
|
+
before do
|
66
|
+
sorting.stub(:scope_link).with(:by_title, 'Title', {}).
|
67
|
+
and_return('Link')
|
68
|
+
end
|
69
|
+
|
70
|
+
before { row.column(:title, sorting: :by_title) }
|
71
|
+
|
72
|
+
it 'generates a sorting scope link' do
|
73
|
+
should have_tag(:th, text: 'Link')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
53
78
|
context 'role' do
|
54
79
|
before { row.column(:author_name) }
|
55
80
|
|
@@ -4,8 +4,9 @@ require 'ostruct'
|
|
4
4
|
module Admino
|
5
5
|
module Table
|
6
6
|
describe Presenter do
|
7
|
-
subject(:presenter) { presenter_klass.new(collection, Post, view) }
|
7
|
+
subject(:presenter) { presenter_klass.new(collection, Post, query, view) }
|
8
8
|
let(:presenter_klass) { Presenter }
|
9
|
+
let(:query) { double('Query') }
|
9
10
|
let(:view) { RailsViewContext.new }
|
10
11
|
|
11
12
|
let(:collection) { [ first_post, second_post ] }
|
@@ -21,7 +22,7 @@ module Admino
|
|
21
22
|
PostPresenter.stub(:new).with(first_post, view).and_return(first_post_presenter)
|
22
23
|
PostPresenter.stub(:new).with(second_post, view).and_return(second_post_presenter)
|
23
24
|
|
24
|
-
HeadRow.stub(:new).with(Post, view).and_return(head_row)
|
25
|
+
HeadRow.stub(:new).with(Post, query, view).and_return(head_row)
|
25
26
|
ResourceRow.stub(:new).with(first_post_presenter, view).and_return(resource_row)
|
26
27
|
ResourceRow.stub(:new).with(second_post_presenter, view).and_return(resource_row)
|
27
28
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: admino
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefano Verna
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: showcase
|
@@ -188,6 +188,8 @@ files:
|
|
188
188
|
- lib/admino/query/field.rb
|
189
189
|
- lib/admino/query/group.rb
|
190
190
|
- lib/admino/query/group_presenter.rb
|
191
|
+
- lib/admino/query/sorting.rb
|
192
|
+
- lib/admino/query/sorting_presenter.rb
|
191
193
|
- lib/admino/table.rb
|
192
194
|
- lib/admino/table/head_row.rb
|
193
195
|
- lib/admino/table/presenter.rb
|
@@ -200,6 +202,8 @@ files:
|
|
200
202
|
- spec/admino/query/field_spec.rb
|
201
203
|
- spec/admino/query/group_presenter_spec.rb
|
202
204
|
- spec/admino/query/group_spec.rb
|
205
|
+
- spec/admino/query/sorting_presenter_spec.rb
|
206
|
+
- spec/admino/query/sorting_spec.rb
|
203
207
|
- spec/admino/table/head_row_spec.rb
|
204
208
|
- spec/admino/table/presenter_spec.rb
|
205
209
|
- spec/admino/table/resource_row_spec.rb
|
@@ -236,6 +240,8 @@ test_files:
|
|
236
240
|
- spec/admino/query/field_spec.rb
|
237
241
|
- spec/admino/query/group_presenter_spec.rb
|
238
242
|
- spec/admino/query/group_spec.rb
|
243
|
+
- spec/admino/query/sorting_presenter_spec.rb
|
244
|
+
- spec/admino/query/sorting_spec.rb
|
239
245
|
- spec/admino/table/head_row_spec.rb
|
240
246
|
- spec/admino/table/presenter_spec.rb
|
241
247
|
- spec/admino/table/resource_row_spec.rb
|