gestart-admino 1.0.0
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.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +29 -0
- data/.gitignore +20 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +91 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +716 -0
- data/Rakefile +6 -0
- data/gestart-admino.gemspec +36 -0
- data/lib/admino/action_view_extension.rb +35 -0
- data/lib/admino/query/base.rb +124 -0
- data/lib/admino/query/base_presenter.rb +27 -0
- data/lib/admino/query/builder.rb +24 -0
- data/lib/admino/query/configuration.rb +100 -0
- data/lib/admino/query/dsl.rb +38 -0
- data/lib/admino/query/filter_group.rb +73 -0
- data/lib/admino/query/filter_group_presenter.rb +85 -0
- data/lib/admino/query/scope_presenter.rb +17 -0
- data/lib/admino/query/search_field.rb +43 -0
- data/lib/admino/query/sorting.rb +74 -0
- data/lib/admino/query/sorting_presenter.rb +60 -0
- data/lib/admino/query.rb +15 -0
- data/lib/admino/table/head_row.rb +86 -0
- data/lib/admino/table/presenter.rb +122 -0
- data/lib/admino/table/resource_row.rb +145 -0
- data/lib/admino/table/row.rb +56 -0
- data/lib/admino/table.rb +7 -0
- data/lib/admino/version.rb +3 -0
- data/lib/admino.rb +14 -0
- data/lib/gestart-admino.rb +1 -0
- data/spec/admino/integration_spec.rb +63 -0
- data/spec/admino/query/base_presenter_spec.rb +59 -0
- data/spec/admino/query/base_spec.rb +192 -0
- data/spec/admino/query/dsl_spec.rb +52 -0
- data/spec/admino/query/filter_group_presenter_spec.rb +182 -0
- data/spec/admino/query/filter_group_spec.rb +133 -0
- data/spec/admino/query/search_field_spec.rb +66 -0
- data/spec/admino/query/sorting_presenter_spec.rb +206 -0
- data/spec/admino/query/sorting_spec.rb +137 -0
- data/spec/admino/table/head_row_spec.rb +158 -0
- data/spec/admino/table/presenter_spec.rb +180 -0
- data/spec/admino/table/resource_row_spec.rb +225 -0
- data/spec/admino/table/row_spec.rb +76 -0
- data/spec/spec_helper.rb +93 -0
- metadata +267 -0
data/Rakefile
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'admino/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = 'gestart-admino'
|
|
8
|
+
spec.version = Admino::VERSION
|
|
9
|
+
spec.authors = ['Gestart Cloud S.r.l.', 'Stefano Verna']
|
|
10
|
+
spec.email = ['dev@gestart.net']
|
|
11
|
+
spec.description = %q{Fork Gestart di admino 0.0.22, potato di ciò che Gestart non usa}
|
|
12
|
+
spec.summary = %q{Fork Gestart di admino: query object e tabelle delle pagine indice}
|
|
13
|
+
spec.homepage = 'https://github.com/gestartcloudsrl/gestart-admino'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ['lib']
|
|
20
|
+
|
|
21
|
+
spec.required_ruby_version = '>= 3.1'
|
|
22
|
+
|
|
23
|
+
spec.add_dependency 'showcase', '~> 0.2.5'
|
|
24
|
+
spec.add_dependency 'activesupport'
|
|
25
|
+
spec.add_dependency 'activemodel'
|
|
26
|
+
|
|
27
|
+
spec.add_development_dependency 'bundler'
|
|
28
|
+
spec.add_development_dependency 'rake'
|
|
29
|
+
spec.add_development_dependency 'rspec'
|
|
30
|
+
spec.add_development_dependency 'i18n'
|
|
31
|
+
spec.add_development_dependency 'rspec-html-matchers'
|
|
32
|
+
spec.add_development_dependency 'actionpack'
|
|
33
|
+
spec.add_development_dependency 'railties'
|
|
34
|
+
spec.add_development_dependency 'simple_form'
|
|
35
|
+
spec.add_development_dependency 'ostruct'
|
|
36
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'active_support/core_ext/hash'
|
|
2
|
+
require 'admino/table/presenter'
|
|
3
|
+
require 'admino/query/base_presenter'
|
|
4
|
+
|
|
5
|
+
module Admino
|
|
6
|
+
module ActionViewExtension
|
|
7
|
+
module Internals
|
|
8
|
+
def self.present_query(query, context, options, key = :presenter)
|
|
9
|
+
presenter_klass = options.fetch(key, Admino::Query::BasePresenter)
|
|
10
|
+
presenter_klass.new(query, context)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def table_for(collection, options = {}, &block)
|
|
15
|
+
options.symbolize_keys!
|
|
16
|
+
options.assert_valid_keys(:presenter, :class, :query, :html)
|
|
17
|
+
presenter_klass = options.fetch(:presenter, Admino::Table::Presenter)
|
|
18
|
+
query = if options[:query]
|
|
19
|
+
Internals.present_query(options[:query], self, options, :query_presenter)
|
|
20
|
+
else
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
presenter = presenter_klass.new(collection, options[:class], query, self)
|
|
24
|
+
html_options = options.fetch(:html, {})
|
|
25
|
+
presenter.to_html(html_options, &block)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def simple_search_form_for(query, options = {}, &block)
|
|
29
|
+
options.symbolize_keys!
|
|
30
|
+
Internals.present_query(query, self, options.slice(:presenter)).
|
|
31
|
+
simple_form(options, &block)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
require 'active_support/concern'
|
|
2
|
+
require 'active_model/naming'
|
|
3
|
+
require 'active_model/translation'
|
|
4
|
+
require 'active_model/conversion'
|
|
5
|
+
require 'active_support/hash_with_indifferent_access'
|
|
6
|
+
require 'active_support/core_ext/hash'
|
|
7
|
+
require 'active_support/core_ext/class/attribute'
|
|
8
|
+
|
|
9
|
+
require 'admino/query/dsl'
|
|
10
|
+
require 'admino/query/builder'
|
|
11
|
+
|
|
12
|
+
module Admino
|
|
13
|
+
module Query
|
|
14
|
+
class Base
|
|
15
|
+
extend ActiveModel::Naming
|
|
16
|
+
extend ActiveModel::Translation
|
|
17
|
+
include ActiveModel::Conversion
|
|
18
|
+
extend Dsl
|
|
19
|
+
|
|
20
|
+
attr_reader :params
|
|
21
|
+
attr_reader :context
|
|
22
|
+
attr_reader :filter_groups
|
|
23
|
+
attr_reader :search_fields
|
|
24
|
+
attr_reader :sorting
|
|
25
|
+
|
|
26
|
+
def self.i18n_scope
|
|
27
|
+
:query
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def initialize(params = nil, context = {}, config = nil)
|
|
31
|
+
@params =
|
|
32
|
+
if params.respond_to?(:to_unsafe_h)
|
|
33
|
+
ActiveSupport::HashWithIndifferentAccess.new(params.to_unsafe_h)
|
|
34
|
+
else
|
|
35
|
+
ActiveSupport::HashWithIndifferentAccess.new(params)
|
|
36
|
+
end
|
|
37
|
+
@config = config
|
|
38
|
+
@context = context
|
|
39
|
+
|
|
40
|
+
init_filter_groups
|
|
41
|
+
init_search_fields
|
|
42
|
+
init_sorting
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def scope(starting_scope = nil)
|
|
46
|
+
starting_scope ||= if config.starting_scope_callable
|
|
47
|
+
config.starting_scope_callable.call(self)
|
|
48
|
+
else
|
|
49
|
+
raise ArgumentError, 'no starting scope provided'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
scope = augment_scope(Builder.new(self, starting_scope)).scope
|
|
53
|
+
|
|
54
|
+
if config.ending_scope_callable
|
|
55
|
+
scope.instance_exec(self, &config.ending_scope_callable)
|
|
56
|
+
else
|
|
57
|
+
scope
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def persisted?
|
|
62
|
+
false
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def config
|
|
66
|
+
@config || self.class.config
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def filter_groups
|
|
70
|
+
@filter_groups.values
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def filter_group_by_name(name)
|
|
74
|
+
@filter_groups[name]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def search_fields
|
|
78
|
+
@search_fields.values
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def search_field_by_name(name)
|
|
82
|
+
@search_fields[name]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def augment_scope(query_builder)
|
|
88
|
+
scope_augmenters.each do |augmenter|
|
|
89
|
+
query_builder = augmenter.augment_scope(query_builder)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
query_builder
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def scope_augmenters
|
|
96
|
+
scope_augmenters = search_fields + filter_groups
|
|
97
|
+
scope_augmenters << sorting if sorting
|
|
98
|
+
scope_augmenters
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def init_filter_groups
|
|
102
|
+
@filter_groups = {}
|
|
103
|
+
i18n_key = self.class.model_name.i18n_key
|
|
104
|
+
config.filter_groups.each do |config|
|
|
105
|
+
@filter_groups[config.name] = FilterGroup.new(config, params, i18n_key)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def init_search_fields
|
|
110
|
+
@search_fields = {}
|
|
111
|
+
config.search_fields.each do |config|
|
|
112
|
+
@search_fields[config.name] = SearchField.new(config, params)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def init_sorting
|
|
117
|
+
if config.sorting
|
|
118
|
+
i18n_key = self.class.model_name.i18n_key
|
|
119
|
+
@sorting = Sorting.new(config.sorting, params, i18n_key)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'showcase'
|
|
2
|
+
|
|
3
|
+
module Admino
|
|
4
|
+
module Query
|
|
5
|
+
class BasePresenter < Showcase::Presenter
|
|
6
|
+
presents_collection :filter_groups
|
|
7
|
+
presents :sorting
|
|
8
|
+
|
|
9
|
+
def simple_form(options = {}, &block)
|
|
10
|
+
h.simple_form_for(
|
|
11
|
+
self,
|
|
12
|
+
options.reverse_merge(default_form_options),
|
|
13
|
+
&block
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def default_form_options
|
|
18
|
+
{
|
|
19
|
+
as: :query,
|
|
20
|
+
method: :get,
|
|
21
|
+
url: h.request.fullpath
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Admino
|
|
2
|
+
module Query
|
|
3
|
+
class Builder
|
|
4
|
+
attr_accessor :scope
|
|
5
|
+
attr_reader :context
|
|
6
|
+
|
|
7
|
+
def initialize(context, scope)
|
|
8
|
+
@context = context
|
|
9
|
+
@scope = scope
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def method_missing(method, *args)
|
|
15
|
+
context_method = "#{method}_scope"
|
|
16
|
+
if context.respond_to?(context_method)
|
|
17
|
+
Builder.new(context, context.send(context_method, scope, *args))
|
|
18
|
+
else
|
|
19
|
+
Builder.new(context, scope.send(method, *args))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
module Admino
|
|
2
|
+
module Query
|
|
3
|
+
class Configuration
|
|
4
|
+
class SearchField
|
|
5
|
+
attr_reader :name
|
|
6
|
+
attr_reader :options
|
|
7
|
+
|
|
8
|
+
def initialize(name, options = {})
|
|
9
|
+
options.symbolize_keys!
|
|
10
|
+
options.assert_valid_keys(
|
|
11
|
+
:default
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
@name = name.to_sym
|
|
15
|
+
@options = options
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def default_value
|
|
19
|
+
options[:default]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class FilterGroup
|
|
24
|
+
attr_reader :name
|
|
25
|
+
attr_reader :scopes
|
|
26
|
+
attr_reader :options
|
|
27
|
+
|
|
28
|
+
def initialize(name, scopes, options = {})
|
|
29
|
+
options.symbolize_keys!
|
|
30
|
+
options.assert_valid_keys(
|
|
31
|
+
:include_empty_scope,
|
|
32
|
+
:default
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
@name = name.to_sym
|
|
36
|
+
@scopes = scopes.map(&:to_sym)
|
|
37
|
+
@options = options
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def include_empty_scope?
|
|
41
|
+
@options.fetch(:include_empty_scope) { false }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def default_scope
|
|
45
|
+
if options[:default]
|
|
46
|
+
options[:default].to_sym
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class Sorting
|
|
52
|
+
attr_reader :scopes
|
|
53
|
+
attr_reader :default_scope
|
|
54
|
+
attr_reader :default_direction
|
|
55
|
+
|
|
56
|
+
def initialize(scopes, options = {})
|
|
57
|
+
options.symbolize_keys!
|
|
58
|
+
options.assert_valid_keys(:default_scope, :default_direction)
|
|
59
|
+
|
|
60
|
+
@scopes = scopes.map(&:to_sym)
|
|
61
|
+
@default_scope = if options[:default_scope]
|
|
62
|
+
options[:default_scope].to_sym
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
@default_direction = if options[:default_direction]
|
|
66
|
+
options[:default_direction].to_sym
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
attr_reader :search_fields
|
|
72
|
+
attr_reader :filter_groups
|
|
73
|
+
attr_reader :sorting
|
|
74
|
+
attr_accessor :starting_scope_callable
|
|
75
|
+
attr_accessor :ending_scope_callable
|
|
76
|
+
|
|
77
|
+
def initialize
|
|
78
|
+
@search_fields = []
|
|
79
|
+
@filter_groups = []
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def add_search_field(name, options = {})
|
|
83
|
+
SearchField.new(name, options).tap do |search_field|
|
|
84
|
+
self.search_fields << search_field
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def add_filter_group(name, scopes, options = {})
|
|
89
|
+
FilterGroup.new(name, scopes, options).tap do |filter_group|
|
|
90
|
+
self.filter_groups << filter_group
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def add_sorting_scopes(scopes, options = {})
|
|
95
|
+
@sorting = Sorting.new(scopes, options)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Admino
|
|
2
|
+
module Query
|
|
3
|
+
module Dsl
|
|
4
|
+
def config
|
|
5
|
+
@config ||= Admino::Query::Configuration.new
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def search_field(name, options = {})
|
|
9
|
+
config.add_search_field(name, options)
|
|
10
|
+
|
|
11
|
+
define_method name do
|
|
12
|
+
search_field_by_name(name).value
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def filter_by(name, scopes, options = {})
|
|
17
|
+
config.add_filter_group(name, scopes, options)
|
|
18
|
+
|
|
19
|
+
define_method name do
|
|
20
|
+
filter_group_by_name(name).value.to_s
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def sorting(*args)
|
|
25
|
+
options = args.extract_options!
|
|
26
|
+
config.add_sorting_scopes(args, options)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def starting_scope(&block)
|
|
30
|
+
config.starting_scope_callable = block
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def ending_scope(&block)
|
|
34
|
+
config.ending_scope_callable = block
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'active_support/hash_with_indifferent_access'
|
|
2
|
+
require 'active_support/core_ext/hash'
|
|
3
|
+
|
|
4
|
+
module Admino
|
|
5
|
+
module Query
|
|
6
|
+
class FilterGroup
|
|
7
|
+
attr_reader :params
|
|
8
|
+
attr_reader :config
|
|
9
|
+
attr_reader :query_i18n_key
|
|
10
|
+
|
|
11
|
+
def initialize(config, params, query_i18n_key = nil)
|
|
12
|
+
@config = config
|
|
13
|
+
@params = ActiveSupport::HashWithIndifferentAccess.new(params)
|
|
14
|
+
@query_i18n_key = query_i18n_key
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def augment_scope(scope)
|
|
18
|
+
if active_scope && active_scope != :empty
|
|
19
|
+
scope.send(active_scope)
|
|
20
|
+
else
|
|
21
|
+
scope
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def active_scope
|
|
26
|
+
if value && scopes.include?(value)
|
|
27
|
+
value
|
|
28
|
+
else
|
|
29
|
+
nil
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def is_scope_active?(scope)
|
|
34
|
+
active_scope == scope.to_sym
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def value
|
|
38
|
+
value = params.fetch(:query, {}).fetch(param_name, default_value)
|
|
39
|
+
if value
|
|
40
|
+
value.to_sym
|
|
41
|
+
else
|
|
42
|
+
nil
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def default_value
|
|
47
|
+
if config.default_scope
|
|
48
|
+
config.default_scope
|
|
49
|
+
elsif config.include_empty_scope?
|
|
50
|
+
:empty
|
|
51
|
+
else
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def param_name
|
|
57
|
+
config.name
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def scopes
|
|
61
|
+
@scopes ||= config.scopes.dup.tap do |scopes|
|
|
62
|
+
if config.include_empty_scope?
|
|
63
|
+
scopes.unshift :empty
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def i18n_key
|
|
69
|
+
config.name
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'i18n'
|
|
2
|
+
require 'showcase'
|
|
3
|
+
require 'showcase/helpers/html_options'
|
|
4
|
+
require 'active_support/core_ext/object/deep_dup'
|
|
5
|
+
require 'active_support/core_ext/array/extract_options'
|
|
6
|
+
require 'active_support/hash_with_indifferent_access'
|
|
7
|
+
require 'active_support/core_ext/hash'
|
|
8
|
+
|
|
9
|
+
module Admino
|
|
10
|
+
module Query
|
|
11
|
+
class FilterGroupPresenter < Showcase::Presenter
|
|
12
|
+
def scope_link(scope, *args)
|
|
13
|
+
options = args.extract_options!
|
|
14
|
+
|
|
15
|
+
label = args.first || scope_name(scope)
|
|
16
|
+
|
|
17
|
+
active_class = options.delete(:active_class) { 'is-active' }
|
|
18
|
+
options = Showcase::Helpers::HtmlOptions.new(options)
|
|
19
|
+
|
|
20
|
+
if is_scope_active?(scope)
|
|
21
|
+
options.add_class!(active_class)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
h.link_to label, scope_path(scope), options.to_h
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def scopes
|
|
28
|
+
@scopes ||= super.map do |scope|
|
|
29
|
+
ScopePresenter.new(scope, self, view_context)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def each_scope(&block)
|
|
34
|
+
scopes.each(&block)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def scope_path(scope)
|
|
38
|
+
h.request.path + "?" + scope_params(scope).to_query
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def scope_params(scope)
|
|
42
|
+
params = ActiveSupport::HashWithIndifferentAccess.new(
|
|
43
|
+
h.request.query_parameters.deep_dup
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
params[:query] ||= {}
|
|
47
|
+
|
|
48
|
+
if is_scope_active?(scope)
|
|
49
|
+
params[:query].delete(param_name)
|
|
50
|
+
else
|
|
51
|
+
params[:query].merge!(param_name => scope.to_s)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
if params[:query].empty?
|
|
55
|
+
params.delete(:query)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
params
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def scope_name(scope)
|
|
62
|
+
I18n.t(
|
|
63
|
+
:"#{query_i18n_key}.#{i18n_key}.scopes.#{scope}",
|
|
64
|
+
scope: 'query.filter_groups',
|
|
65
|
+
default: [
|
|
66
|
+
:"#{i18n_key}.scopes.#{scope}",
|
|
67
|
+
scope.to_s.titleize
|
|
68
|
+
]
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def name
|
|
73
|
+
I18n.t(
|
|
74
|
+
:"#{query_i18n_key}.#{i18n_key}.name",
|
|
75
|
+
scope: 'query.filter_groups',
|
|
76
|
+
default: [
|
|
77
|
+
:"#{i18n_key}.name",
|
|
78
|
+
i18n_key.to_s.titleize.capitalize
|
|
79
|
+
]
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'showcase'
|
|
2
|
+
|
|
3
|
+
module Admino
|
|
4
|
+
module Query
|
|
5
|
+
class ScopePresenter < Showcase::Presenter
|
|
6
|
+
def initialize(object, parent, view_context)
|
|
7
|
+
super(object, view_context)
|
|
8
|
+
@parent = parent
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def link(*args)
|
|
12
|
+
@parent.scope_link(object, *args)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'active_support/hash_with_indifferent_access'
|
|
2
|
+
require 'active_support/core_ext/hash'
|
|
3
|
+
|
|
4
|
+
module Admino
|
|
5
|
+
module Query
|
|
6
|
+
class SearchField
|
|
7
|
+
attr_reader :params
|
|
8
|
+
attr_reader :config
|
|
9
|
+
|
|
10
|
+
def initialize(config, params)
|
|
11
|
+
@config = config
|
|
12
|
+
@params = ActiveSupport::HashWithIndifferentAccess.new(params)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def augment_scope(scope)
|
|
16
|
+
if present?
|
|
17
|
+
scope.send(scope_name, value)
|
|
18
|
+
else
|
|
19
|
+
scope
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def value
|
|
24
|
+
value = params.fetch(:query, {}).fetch(param_name, nil)
|
|
25
|
+
|
|
26
|
+
value || config.default_value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def present?
|
|
30
|
+
value.present?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def param_name
|
|
34
|
+
config.name
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def scope_name
|
|
38
|
+
config.name
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'active_support/hash_with_indifferent_access'
|
|
2
|
+
require 'active_support/core_ext/hash'
|
|
3
|
+
|
|
4
|
+
module Admino
|
|
5
|
+
module Query
|
|
6
|
+
class Sorting
|
|
7
|
+
attr_reader :params
|
|
8
|
+
attr_reader :config
|
|
9
|
+
attr_reader :query_i18n_key
|
|
10
|
+
|
|
11
|
+
def initialize(config, params, query_i18n_key = nil)
|
|
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.to_sym
|
|
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 && 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
|
|
53
|
+
config.default_direction
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def default_direction_is_ascending?
|
|
57
|
+
default_direction != :desc
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def param_value
|
|
61
|
+
params.fetch(param_name, nil)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def param_name
|
|
65
|
+
:sorting
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def scopes
|
|
69
|
+
config.scopes
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|