wallaby-core 0.1.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +60 -13
- data/app/controllers/wallaby/resources_controller.rb +15 -374
- data/app/security/ability.rb +1 -1
- data/config/locales/wallaby.en.yml +92 -128
- data/config/locales/wallaby_class.en.yml +2 -23
- data/lib/adaptors/wallaby/custom/default_provider.rb +1 -1
- data/lib/adaptors/wallaby/custom/model_decorator.rb +8 -7
- data/lib/adaptors/wallaby/custom/model_finder.rb +3 -2
- data/lib/adaptors/wallaby/custom/model_pagination_provider.rb +1 -1
- data/lib/adaptors/wallaby/custom/model_service_provider.rb +1 -40
- data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +30 -24
- data/lib/authorizers/wallaby/default_authorization_provider.rb +6 -13
- data/lib/authorizers/wallaby/model_authorizer.rb +43 -67
- data/lib/authorizers/wallaby/pundit_authorization_provider.rb +21 -30
- data/lib/concerns/wallaby/application_concern.rb +110 -0
- data/lib/concerns/wallaby/authentication_concern.rb +162 -0
- data/lib/concerns/wallaby/authorizable.rb +8 -14
- data/lib/concerns/wallaby/baseable.rb +91 -10
- data/lib/concerns/wallaby/decoratable.rb +3 -3
- data/lib/concerns/wallaby/engineable.rb +1 -1
- data/lib/concerns/wallaby/fieldable.rb +4 -4
- data/lib/concerns/wallaby/paginatable.rb +3 -3
- data/lib/concerns/wallaby/prefixable.rb +21 -0
- data/lib/concerns/wallaby/resourcable.rb +4 -35
- data/lib/concerns/wallaby/resources_concern.rb +434 -0
- data/lib/concerns/wallaby/servicable.rb +4 -10
- data/lib/decorators/wallaby/resource_decorator.rb +53 -80
- data/lib/errors/wallaby/{cell_handling.rb → class_not_found.rb} +1 -1
- data/lib/errors/wallaby/model_not_found.rb +3 -1
- data/lib/errors/wallaby/resource_not_found.rb +1 -1
- data/lib/helpers/wallaby/application_helper.rb +6 -9
- data/lib/helpers/wallaby/form_helper.rb +2 -9
- data/lib/helpers/wallaby/index_helper.rb +2 -14
- data/lib/helpers/wallaby/links_helper.rb +5 -5
- data/lib/helpers/wallaby/resources_helper.rb +3 -7
- data/lib/helpers/wallaby/secure_helper.rb +3 -3
- data/lib/helpers/wallaby/styling_helper.rb +17 -3
- data/lib/interfaces/wallaby/mode.rb +5 -5
- data/lib/interfaces/wallaby/model_authorization_provider.rb +15 -13
- data/lib/interfaces/wallaby/model_decorator.rb +15 -3
- data/lib/paginators/wallaby/model_paginator.rb +14 -45
- data/lib/parsers/wallaby/parser.rb +49 -14
- data/lib/routes/wallaby/resources_router.rb +1 -1
- data/lib/servicers/wallaby/model_servicer.rb +32 -62
- data/lib/services/wallaby/map/mode_mapper.rb +14 -14
- data/lib/services/wallaby/map/model_class_collector.rb +2 -2
- data/lib/services/wallaby/map/model_class_mapper.rb +7 -26
- data/lib/services/wallaby/prefixes_builder.rb +15 -49
- data/lib/services/wallaby/type_renderer.rb +3 -13
- data/lib/utils/wallaby/locale.rb +53 -0
- data/lib/utils/wallaby/model_utils.rb +4 -3
- data/lib/utils/wallaby/module_utils.rb +1 -1
- data/lib/utils/wallaby/utils.rb +10 -15
- data/lib/wallaby/class_array.rb +75 -0
- data/lib/wallaby/class_hash.rb +94 -0
- data/lib/wallaby/classifier.rb +29 -0
- data/lib/wallaby/configuration/mapping.rb +33 -27
- data/lib/wallaby/configuration/metadata.rb +1 -1
- data/lib/wallaby/configuration/models.rb +5 -9
- data/lib/wallaby/configuration/security.rb +6 -3
- data/lib/wallaby/configuration/sorting.rb +1 -1
- data/lib/wallaby/configuration.rb +31 -2
- data/lib/wallaby/constants.rb +10 -8
- data/lib/wallaby/core/version.rb +1 -1
- data/lib/wallaby/core.rb +21 -16
- data/lib/wallaby/engine.rb +9 -20
- data/lib/wallaby/logger.rb +35 -0
- data/lib/wallaby/map.rb +20 -17
- data/lib/wallaby/preloader.rb +77 -0
- metadata +48 -22
- data/app/controllers/wallaby/application_controller.rb +0 -84
- data/app/controllers/wallaby/secure_controller.rb +0 -81
- data/lib/concerns/wallaby/rails_overridden_methods.rb +0 -42
- data/lib/concerns/wallaby/themeable.rb +0 -40
- data/lib/paginators/wallaby/resource_paginator.rb +0 -12
- data/lib/renderers/wallaby/cell.rb +0 -137
- data/lib/renderers/wallaby/cell_resolver.rb +0 -89
- data/lib/renderers/wallaby/custom_lookup_context.rb +0 -64
- data/lib/renderers/wallaby/custom_partial_renderer.rb +0 -33
- data/lib/renderers/wallaby/custom_renderer.rb +0 -16
- data/lib/utils/wallaby/cell_utils.rb +0 -34
- data/lib/utils/wallaby/preload_utils.rb +0 -44
@@ -12,15 +12,6 @@ module Wallaby
|
|
12
12
|
# @see Wallaby::ModuleUtils.try_to
|
13
13
|
delegate :try_to, to: ModuleUtils
|
14
14
|
|
15
|
-
# Override the origin view_renderer to support {Wallaby::Cell} rendering
|
16
|
-
# @!attribute [r] view_renderer
|
17
|
-
# @see Wallaby::CustomRenderer
|
18
|
-
def view_renderer
|
19
|
-
return @view_renderer if @view_renderer.is_a? CustomRenderer
|
20
|
-
|
21
|
-
@view_renderer = CustomRenderer.new @view_renderer.lookup_context
|
22
|
-
end
|
23
|
-
|
24
15
|
# Override origin method to handle URL for Wallaby engine.
|
25
16
|
#
|
26
17
|
# As Wallaby's routes are declared in a
|
@@ -75,5 +66,11 @@ module Wallaby
|
|
75
66
|
options = default_options.merge!(sources.extract_options!.stringify_keys)
|
76
67
|
super(*sources, options)
|
77
68
|
end
|
69
|
+
|
70
|
+
# @param key
|
71
|
+
# @param options [Hash]
|
72
|
+
def wt(key, options = {})
|
73
|
+
Locale.t key, { translator: method(:t) }.merge(options)
|
74
|
+
end
|
78
75
|
end
|
79
76
|
end
|
@@ -3,12 +3,6 @@
|
|
3
3
|
module Wallaby
|
4
4
|
# Form helper
|
5
5
|
module FormHelper
|
6
|
-
# @deprecated Use {Wallaby::ResourcesHelper#type_render} instead. It will be removed from 5.3.*
|
7
|
-
def form_type_partial_render(options = {}, locals = {}, &block)
|
8
|
-
Utils.deprecate 'deprecation.form_type_partial_render', caller: caller
|
9
|
-
type_render options, locals, &block
|
10
|
-
end
|
11
|
-
|
12
6
|
# To generate remote URL for auto select plugin.
|
13
7
|
# @see https://github.com/reinteractive/wallaby/blob/master/app/assets/javascripts/wallaby/auto_select.js
|
14
8
|
# auto_select.js
|
@@ -52,9 +46,8 @@ module Wallaby
|
|
52
46
|
type = metadata[:type]
|
53
47
|
hint = metadata[:hint]
|
54
48
|
# @see http://guides.rubyonrails.org/i18n.html#using-safe-html-translations
|
55
|
-
hint ||= type &&
|
56
|
-
|
57
|
-
return unless hint
|
49
|
+
hint ||= type && wt("hints.#{type}_html", default: [:"hints.#{type}", ''])
|
50
|
+
return if hint.blank?
|
58
51
|
|
59
52
|
content_tag :p, hint, class: 'help-block'
|
60
53
|
end
|
@@ -3,22 +3,10 @@
|
|
3
3
|
module Wallaby
|
4
4
|
# Helper methods for index action
|
5
5
|
module IndexHelper
|
6
|
-
# @deprecated This method is no longer in use. It will be removed from 5.3.*
|
7
|
-
def index_params(parameters = params)
|
8
|
-
Utils.deprecate 'deprecation.index_params', caller: caller
|
9
|
-
parameters
|
10
|
-
end
|
11
|
-
|
12
|
-
# @deprecated Use {Wallaby::Paginatable#current_paginator} instead. It will be removed from 5.3.*
|
13
|
-
def paginator_of(_model_class, _collection, _params)
|
14
|
-
Utils.deprecate 'deprecation.paginator_of', caller: caller
|
15
|
-
current_paginator
|
16
|
-
end
|
17
|
-
|
18
6
|
# Just a label
|
19
7
|
# @return [String]
|
20
8
|
def all_label
|
21
|
-
|
9
|
+
wt 'filters.all'
|
22
10
|
end
|
23
11
|
|
24
12
|
# If `:fields` parameter is given, only display fields that is in `index_field_names`
|
@@ -70,7 +58,7 @@ module Wallaby
|
|
70
58
|
# @return [String] Export link for the given model_class.
|
71
59
|
def export_link(model_class, url_params: {})
|
72
60
|
index_link(model_class, url_params: { format: 'csv', page: nil, per: nil, with_query: true }.merge(url_params)) do
|
73
|
-
|
61
|
+
wt 'links.export', ext: 'CSV'
|
74
62
|
end
|
75
63
|
end
|
76
64
|
|
@@ -44,7 +44,7 @@ module Wallaby
|
|
44
44
|
html_options, block = LinkOptionsNormalizer.normalize(
|
45
45
|
html_options, block,
|
46
46
|
class: 'resource__create',
|
47
|
-
block: -> {
|
47
|
+
block: -> { wt 'links.new', model: to_model_label(model_class) }
|
48
48
|
)
|
49
49
|
|
50
50
|
url = options[:url] || new_path(model_class, url_params: url_params)
|
@@ -97,7 +97,7 @@ module Wallaby
|
|
97
97
|
html_options, block = LinkOptionsNormalizer.normalize(
|
98
98
|
html_options, block,
|
99
99
|
class: 'resource__update',
|
100
|
-
block: -> { "#{
|
100
|
+
block: -> { "#{wt 'links.edit'} #{decorate(resource).to_label}" }
|
101
101
|
)
|
102
102
|
|
103
103
|
default = options[:readonly] && block.call || nil
|
@@ -123,11 +123,11 @@ module Wallaby
|
|
123
123
|
return if unauthorized? :destroy, extract(resource)
|
124
124
|
|
125
125
|
html_options, block = LinkOptionsNormalizer.normalize(
|
126
|
-
html_options, block, class: 'resource__destroy', block: -> {
|
126
|
+
html_options, block, class: 'resource__destroy', block: -> { wt 'links.delete' }
|
127
127
|
)
|
128
128
|
|
129
129
|
html_options[:method] ||= :delete
|
130
|
-
(html_options[:data] ||= {})[:confirm] ||=
|
130
|
+
(html_options[:data] ||= {})[:confirm] ||= wt 'links.confirm.delete'
|
131
131
|
|
132
132
|
url = options[:url] || show_path(resource, is_resource: options[:is_resource], url_params: url_params)
|
133
133
|
link_to url, html_options, &block
|
@@ -140,7 +140,7 @@ module Wallaby
|
|
140
140
|
# @yield block to return the link label
|
141
141
|
# @return [String] anchor link of cancel action
|
142
142
|
def cancel_link(html_options: {}, &block)
|
143
|
-
block ||= -> {
|
143
|
+
block ||= -> { wt 'links.cancel' }
|
144
144
|
link_to 'javascript:history.back()', html_options, &block
|
145
145
|
end
|
146
146
|
|
@@ -3,6 +3,9 @@
|
|
3
3
|
module Wallaby
|
4
4
|
# Resources helper
|
5
5
|
module ResourcesHelper
|
6
|
+
include ApplicationHelper
|
7
|
+
include SecureHelper
|
8
|
+
|
6
9
|
include BaseHelper
|
7
10
|
include FormHelper
|
8
11
|
include IndexHelper
|
@@ -12,13 +15,6 @@ module Wallaby
|
|
12
15
|
include Paginatable
|
13
16
|
include Resourcable
|
14
17
|
include Servicable
|
15
|
-
include Themeable
|
16
|
-
|
17
|
-
# @deprecated Use {#type_render} instead. It will be removed from 5.3.*
|
18
|
-
def type_partial_render(options = {}, locals = {}, &block)
|
19
|
-
Utils.deprecate 'deprecation.type_partial_render', caller: caller
|
20
|
-
type_render options, locals, &block
|
21
|
-
end
|
22
18
|
|
23
19
|
# Render type cell/partial
|
24
20
|
# @param partial_name [String]
|
@@ -9,7 +9,7 @@ module Wallaby
|
|
9
9
|
# - otherwise, an user icon will be returned
|
10
10
|
# @param user [Object]
|
11
11
|
# @return [String] IMG or I element
|
12
|
-
def user_portrait(user =
|
12
|
+
def user_portrait(user = wallaby_user)
|
13
13
|
email_method = security.email_method || :email
|
14
14
|
email = try_to user, email_method
|
15
15
|
if email.present?
|
@@ -27,7 +27,7 @@ module Wallaby
|
|
27
27
|
# @param user [Object]
|
28
28
|
# @param app [Object]
|
29
29
|
# @return [String] URL to log out
|
30
|
-
def logout_path(user =
|
30
|
+
def logout_path(user = wallaby_user, app = main_app)
|
31
31
|
path = security.logout_path
|
32
32
|
path ||=
|
33
33
|
if defined? ::Devise
|
@@ -41,7 +41,7 @@ module Wallaby
|
|
41
41
|
# @see Wallaby::Configuration::Security#logout_method
|
42
42
|
# @param user [Object]
|
43
43
|
# @return [String, Symbol] http method to log out
|
44
|
-
def logout_method(user =
|
44
|
+
def logout_method(user = wallaby_user)
|
45
45
|
http_method = security.logout_method
|
46
46
|
http_method ||
|
47
47
|
if defined? ::Devise
|
@@ -3,6 +3,20 @@
|
|
3
3
|
module Wallaby
|
4
4
|
# Helper methods to build custom elements
|
5
5
|
module StylingHelper
|
6
|
+
# backforward compatible with FontAwesome 4
|
7
|
+
# @see this fa migration document https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4
|
8
|
+
FONT_AWESOME_MAPPING = {
|
9
|
+
4 => {
|
10
|
+
clock: 'clock-o',
|
11
|
+
bars: 'navicon',
|
12
|
+
calendar: 'calendar-o',
|
13
|
+
'check-square': 'check-square-o',
|
14
|
+
square: 'square-o',
|
15
|
+
link: 'chain',
|
16
|
+
user: 'user-o'
|
17
|
+
}
|
18
|
+
}.with_indifferent_access.freeze
|
19
|
+
|
6
20
|
# Shortcut to build up the HTML options as keyword arguments
|
7
21
|
# @param string_or_array [String, Array<String>]
|
8
22
|
# @param options [Hash]
|
@@ -54,12 +68,12 @@ module Wallaby
|
|
54
68
|
|
55
69
|
# @return [String] grey null
|
56
70
|
def null
|
57
|
-
muted
|
71
|
+
muted wt 'labels.empty'
|
58
72
|
end
|
59
73
|
|
60
74
|
# @return [String] grey N/A
|
61
75
|
def na
|
62
|
-
muted
|
76
|
+
muted wt 'labels.na'
|
63
77
|
end
|
64
78
|
|
65
79
|
# Grey text
|
@@ -74,7 +88,7 @@ module Wallaby
|
|
74
88
|
def fa_map(name, major = nil)
|
75
89
|
@map ||= begin
|
76
90
|
major ||= Gem.loaded_specs['font-awesome-sass'].try(:version).try(:segments).try(:first)
|
77
|
-
|
91
|
+
FONT_AWESOME_MAPPING[major] || {}
|
78
92
|
end
|
79
93
|
@map[name] || name
|
80
94
|
end
|
@@ -24,14 +24,14 @@ module Wallaby
|
|
24
24
|
|
25
25
|
# @see Wallaby::ModelPaginationProvider
|
26
26
|
# @return [Class] pagination provider for the mode
|
27
|
-
# @since 5.2.0
|
27
|
+
# @since wallaby-5.2.0
|
28
28
|
def model_pagination_provider
|
29
29
|
check_and_constantize __callee__
|
30
30
|
end
|
31
31
|
|
32
32
|
# @see Wallaby::ModelPaginationProvider
|
33
33
|
# @return [Class] pagination provider for the mode
|
34
|
-
# @since 5.2.0
|
34
|
+
# @since wallaby-5.2.0
|
35
35
|
def default_authorization_provider
|
36
36
|
check_and_constantize __callee__
|
37
37
|
end
|
@@ -39,7 +39,7 @@ module Wallaby
|
|
39
39
|
# Return a list of authorization providers for authorizer to detect which one to use.
|
40
40
|
# @see Wallaby::ModelAuthorizationProvider
|
41
41
|
# @return [ActiveSupport::HashWithIndifferentAccess<String, Class>] authorization provider hash
|
42
|
-
# @since 5.2.0
|
42
|
+
# @since wallaby-5.2.0
|
43
43
|
def model_authorization_providers(classes = ModelAuthorizationProvider.descendants)
|
44
44
|
# NOTE: make sure default provider always comes last
|
45
45
|
@model_authorization_providers ||=
|
@@ -61,10 +61,10 @@ module Wallaby
|
|
61
61
|
class_name.constantize.tap do |klass|
|
62
62
|
next if klass < parent_class
|
63
63
|
|
64
|
-
raise InvalidError,
|
64
|
+
raise InvalidError, Locale.t('mode.inherit_required', klass: klass, parent: parent_class)
|
65
65
|
end
|
66
66
|
rescue NameError => e
|
67
|
-
|
67
|
+
Logger.error e
|
68
68
|
raise NotImplemented, class_name
|
69
69
|
end
|
70
70
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Wallaby
|
4
4
|
# Model Authorizer interface.
|
5
|
-
# @since 5.2.0
|
5
|
+
# @since wallaby-5.2.0
|
6
6
|
class ModelAuthorizationProvider
|
7
7
|
class << self
|
8
8
|
# @!attribute [w] provider_name
|
@@ -13,34 +13,36 @@ module Wallaby
|
|
13
13
|
# @see Wallaby::ModelAuthorizer.provider_name
|
14
14
|
# @return [String/Symbol] provider name
|
15
15
|
def provider_name
|
16
|
-
@provider_name
|
16
|
+
@provider_name ||= name.demodulize.gsub(/(Authorization)?Provider/, EMPTY_STRING).underscore
|
17
17
|
end
|
18
18
|
|
19
19
|
# @note Template method to check and see if current provider is in used.
|
20
|
-
# @param _context [ActionController::Base]
|
20
|
+
# @param _context [ActionController::Base, ActionView::Base]
|
21
21
|
# @raise [Wallaby::NotImplemented]
|
22
22
|
def available?(_context)
|
23
23
|
raise NotImplemented
|
24
24
|
end
|
25
|
-
|
26
|
-
# @note Template method to pull out the args required for contruction from context.
|
27
|
-
# @param _context [ActionController::Base]
|
28
|
-
# @raise [Wallaby::NotImplemented]
|
29
|
-
def args_from(_context)
|
30
|
-
raise NotImplemented
|
31
|
-
end
|
32
25
|
end
|
33
26
|
|
34
27
|
# @!attribute [r] context
|
35
|
-
# @return [ActionController::Base]
|
28
|
+
# @return [ActionController::Base, ActionView::Base]
|
36
29
|
attr_reader :context
|
37
30
|
|
38
31
|
# @!attribute [r] user
|
39
32
|
# @return [Object]
|
40
33
|
attr_reader :user
|
41
34
|
|
42
|
-
#
|
43
|
-
|
35
|
+
# @!attribute [r] options
|
36
|
+
# @return [Hash]
|
37
|
+
attr_reader :options
|
38
|
+
|
39
|
+
# @param context [ActionController::Base, ActionView::Base]
|
40
|
+
# @param options [Hash]
|
41
|
+
def initialize(context, **options)
|
42
|
+
@context = context
|
43
|
+
@options = options
|
44
|
+
@user = context.try :wallaby_user
|
45
|
+
end
|
44
46
|
|
45
47
|
# @note It can be overridden in subclasses for customization purpose.
|
46
48
|
# This is the template method to check user's permission for given action on given subject.
|
@@ -157,12 +157,24 @@ module Wallaby
|
|
157
157
|
field_names.unshift(primary_key.to_s).uniq
|
158
158
|
end
|
159
159
|
|
160
|
-
#
|
160
|
+
# Ensure the type is present for given field name
|
161
161
|
# @param type [String, Symbol, nil]
|
162
162
|
# @return [String, Symbol] type
|
163
163
|
# @raise [ArgumentError] when type is nil
|
164
|
-
def
|
165
|
-
type || raise(::ArgumentError,
|
164
|
+
def ensure_type_is_present(field_name, type, metadata_prefix = '')
|
165
|
+
type || raise(::ArgumentError, <<~INSTRUCTION
|
166
|
+
The type for field `#{field_name}` is missing in metadata `#{metadata_prefix}_fields`.
|
167
|
+
The possible causes are:
|
168
|
+
|
169
|
+
1. Check type's value from metadata `#{metadata_prefix}_fields[:#{field_name}][:type]`.
|
170
|
+
If it is missing, specify the type as below:
|
171
|
+
|
172
|
+
#{metadata_prefix}field_name[:#{field_name}][:type] = 'string'
|
173
|
+
|
174
|
+
2. If metadata `#{metadata_prefix}_fields` is blank, maybe table hasn't be created yet
|
175
|
+
or there is some error in the decorator class declaration.
|
176
|
+
INSTRUCTION
|
177
|
+
)
|
166
178
|
end
|
167
179
|
end
|
168
180
|
end
|
@@ -1,72 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Wallaby
|
4
|
-
#
|
4
|
+
# This is the base paginator class to provider pagination for given collection.
|
5
|
+
#
|
6
|
+
# For best practice, please create an application paginator class (see example)
|
7
|
+
# to better control the functions shared between different model paginators.
|
8
|
+
# @example Create an application class for Admin Interface usage
|
9
|
+
# class Admin::ApplicationPaginator < Wallaby::ModelPaginator
|
10
|
+
# base_class!
|
11
|
+
# end
|
5
12
|
class ModelPaginator
|
6
13
|
extend Baseable::ClassMethods
|
7
|
-
|
8
|
-
class << self
|
9
|
-
# @!attribute [w] model_class
|
10
|
-
attr_writer :model_class
|
11
|
-
|
12
|
-
# @!attribute [r] model_class
|
13
|
-
# Return associated model class, e.g. return **Product** for **ProductPaginator**.
|
14
|
-
#
|
15
|
-
# If Wallaby can't recognise the model class for Paginator, it's required to be configured as below example:
|
16
|
-
# @example To configure model class
|
17
|
-
# class Admin::ProductPaginator < Admin::ApplicationPaginator
|
18
|
-
# self.model_class = Product
|
19
|
-
# end
|
20
|
-
# @example To configure model class for version below 5.2.0
|
21
|
-
# class Admin::ProductPaginator < Admin::ApplicationPaginator
|
22
|
-
# def self.model_class
|
23
|
-
# Product
|
24
|
-
# end
|
25
|
-
# end
|
26
|
-
# @return [Class] assoicated model class
|
27
|
-
# @return [nil] if current class is marked as base class
|
28
|
-
# @return [nil] if current class is the same as the value of {Wallaby::Configuration::Mapping#model_paginator}
|
29
|
-
# @return [nil] if current class is {Wallaby::ModelPaginator}
|
30
|
-
# @return [nil] if assoicated model class is not found
|
31
|
-
def model_class
|
32
|
-
return unless self < ModelPaginator
|
33
|
-
return if base_class? || self == Wallaby.configuration.mapping.model_paginator
|
34
|
-
|
35
|
-
@model_class ||= Map.model_class_map(name.gsub(/(^#{namespace}::)|(Paginator$)/, EMPTY_STRING))
|
36
|
-
end
|
37
|
-
|
38
|
-
# @!attribute provider_class
|
39
|
-
# @return [Class] pagination provider class
|
40
|
-
# @since 5.2.0
|
41
|
-
attr_accessor :provider_class
|
42
|
-
end
|
14
|
+
base_class!
|
43
15
|
|
44
16
|
# @!attribute [r] model_class
|
45
17
|
# @return [Class]
|
46
18
|
attr_reader :model_class
|
47
19
|
|
48
20
|
# @!attribute [r] provider
|
49
|
-
# @return [Wallaby::
|
50
|
-
# @since 5.2.0
|
21
|
+
# @return [Wallaby::ModelPaginationProvider] the instance that does the job
|
22
|
+
# @since wallaby-5.2.0
|
51
23
|
attr_reader :provider
|
52
24
|
|
53
|
-
# During initialization, Wallaby will assign a pagination provider for this paginator
|
54
|
-
# to carry out the actual execution.
|
55
|
-
#
|
56
|
-
# Therefore, all its actions can be completely replaced by user's own implemnetation.
|
57
25
|
# @param model_class [Class]
|
58
26
|
# @param collection [#to_a] a collection of the resources
|
59
27
|
# @param params [ActionController::Parameters]
|
60
28
|
def initialize(model_class, collection, params)
|
61
29
|
@model_class = self.class.model_class || model_class
|
62
|
-
raise ArgumentError,
|
30
|
+
raise ArgumentError, 'Please provide a `model_class`.' unless @model_class
|
63
31
|
|
64
32
|
@collection = collection
|
65
33
|
@params = params
|
66
34
|
@provider = Map.pagination_provider_map(@model_class).new(@collection, @params)
|
67
35
|
end
|
68
36
|
|
69
|
-
delegate(*ModelPaginationProvider.instance_methods(false), to: :provider)
|
70
37
|
# @!method paginatable?
|
71
38
|
# (see Wallaby::ModelPaginationProvider#paginatable?)
|
72
39
|
|
@@ -111,5 +78,7 @@ module Wallaby
|
|
111
78
|
|
112
79
|
# @!method number_of_pages
|
113
80
|
# (see Wallaby::ModelPaginationProvider#number_of_pages)
|
81
|
+
|
82
|
+
delegate(*ModelPaginationProvider.instance_methods(false), to: :provider)
|
114
83
|
end
|
115
84
|
end
|
@@ -1,34 +1,69 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Wallaby
|
4
|
-
#
|
4
|
+
# A parser to parse colon query string and return a hash for transformer
|
5
|
+
# to consume
|
5
6
|
class Parser < Parslet::Parser
|
7
|
+
# @!method parse(str)
|
8
|
+
# Parse string into Abstract Syntax Tree for transformer to consume
|
9
|
+
# @param str [String]
|
10
|
+
# @return [Hash] Abstract Syntax Tree
|
11
|
+
|
12
|
+
# Case insensitive string match
|
13
|
+
# @param str [String]
|
14
|
+
def stri(str)
|
15
|
+
str.chars.map! { |c| match["#{c.upcase}#{c.downcase}"] }.reduce :>>
|
16
|
+
end
|
17
|
+
|
6
18
|
root(:statement)
|
7
|
-
rule(:statement) { expression >> (
|
8
|
-
rule(:expression) { colon_query |
|
19
|
+
rule(:statement) { expression >> (spaces >> expression).repeat }
|
20
|
+
rule(:expression) { colon_query | quoted_string | string | any.repeat(0).as(:null) }
|
9
21
|
rule(:colon_query) do
|
10
|
-
name.as(:left) >> operator.as(:op) >>
|
22
|
+
name.as(:left) >> operator.as(:op) >> values.as(:right)
|
23
|
+
end
|
24
|
+
|
25
|
+
# colon query
|
26
|
+
begin
|
27
|
+
# name starts with letter
|
28
|
+
rule(:name) { letter >> ((colon | spaces).absent? >> any).repeat }
|
29
|
+
|
30
|
+
# operator starts with colon
|
31
|
+
rule(:operator) do
|
32
|
+
colon >> (
|
33
|
+
(colon | spaces | quote | comma | digit | letter).absent? >> any
|
34
|
+
).repeat(0, 3)
|
35
|
+
end
|
36
|
+
|
37
|
+
# values separated by comma
|
38
|
+
rule(:values) { value >> (comma >> value).repeat }
|
39
|
+
rule(:value) { quoted_string | data }
|
40
|
+
rule(:data) do
|
41
|
+
null.as(:null) | boolean.as(:boolean) |
|
42
|
+
(spaces.absent? >> comma.absent? >> any).repeat.as(:string)
|
43
|
+
end
|
11
44
|
end
|
12
|
-
rule(:name) { (space.absent? >> colon.absent? >> any).repeat(1) }
|
13
|
-
rule(:operator) { colon >> match('[^\s\'\"\:\,0-9a-zA-Z]').repeat(0, 3) }
|
14
|
-
rule(:keywords) { general_keyword >> (comma >> general_keyword).repeat }
|
15
|
-
rule(:general_keyword) { quoted_keyword | keyword }
|
16
45
|
|
17
46
|
# basic elements
|
18
|
-
rule(:
|
47
|
+
rule(:quoted_string) do
|
19
48
|
open_quote >>
|
20
|
-
(close_quote.absent? >> any).repeat.as(:
|
49
|
+
(close_quote.absent? >> any).repeat.as(:string) >>
|
21
50
|
close_quote
|
22
51
|
end
|
23
|
-
rule(:
|
52
|
+
rule(:string) { (spaces.absent? >> any).repeat(1).as(:string) }
|
24
53
|
|
25
54
|
# atomic entities
|
55
|
+
rule(:null) { stri('nil') | stri('null') }
|
56
|
+
rule(:boolean) { stri('true') | stri('false') }
|
57
|
+
rule(:letter) { match['a-zA-Z'] }
|
58
|
+
rule(:digit) { match['0-9'] }
|
59
|
+
rule(:dot) { str('.') }
|
26
60
|
rule(:comma) { str(',') }
|
27
|
-
rule(:
|
61
|
+
rule(:spaces) { match['\s'].repeat(1) }
|
28
62
|
rule(:colon) { str(':') }
|
63
|
+
rule(:quote) { match['\'\"'] }
|
29
64
|
|
30
65
|
# open-close elements
|
31
|
-
rule(:open_quote) {
|
32
|
-
rule(:close_quote) { dynamic { |_src, ctx| str(ctx.captures[:
|
66
|
+
rule(:open_quote) { quote.capture(:quoting) }
|
67
|
+
rule(:close_quote) { dynamic { |_src, ctx| str(ctx.captures[:quoting]) } }
|
33
68
|
end
|
34
69
|
end
|
@@ -53,7 +53,7 @@ module Wallaby
|
|
53
53
|
return model_class unless MODEL_ACTIONS.include? params[:action].to_sym
|
54
54
|
raise ModelNotFound, params[:resources] unless model_class
|
55
55
|
unless Map.mode_map[model_class]
|
56
|
-
raise UnprocessableEntity,
|
56
|
+
raise UnprocessableEntity, Locale.t('errors.unprocessable_entity.model', model: model_class)
|
57
57
|
end
|
58
58
|
|
59
59
|
model_class
|