wallaby-core 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +31 -0
- data/app/controllers/wallaby/application_controller.rb +84 -0
- data/app/controllers/wallaby/resources_controller.rb +381 -0
- data/app/controllers/wallaby/secure_controller.rb +81 -0
- data/app/security/ability.rb +13 -0
- data/config/locales/wallaby.en.yml +140 -0
- data/config/locales/wallaby_class.en.yml +30 -0
- data/config/routes.rb +39 -0
- data/lib/adaptors/wallaby/custom.rb +7 -0
- data/lib/adaptors/wallaby/custom/default_provider.rb +9 -0
- data/lib/adaptors/wallaby/custom/model_decorator.rb +71 -0
- data/lib/adaptors/wallaby/custom/model_finder.rb +13 -0
- data/lib/adaptors/wallaby/custom/model_pagination_provider.rb +14 -0
- data/lib/adaptors/wallaby/custom/model_service_provider.rb +48 -0
- data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +72 -0
- data/lib/authorizers/wallaby/default_authorization_provider.rb +58 -0
- data/lib/authorizers/wallaby/model_authorizer.rb +100 -0
- data/lib/authorizers/wallaby/pundit_authorization_provider.rb +89 -0
- data/lib/concerns/wallaby/authorizable.rb +103 -0
- data/lib/concerns/wallaby/baseable.rb +36 -0
- data/lib/concerns/wallaby/decoratable.rb +101 -0
- data/lib/concerns/wallaby/defaultable.rb +38 -0
- data/lib/concerns/wallaby/engineable.rb +61 -0
- data/lib/concerns/wallaby/fieldable.rb +78 -0
- data/lib/concerns/wallaby/paginatable.rb +72 -0
- data/lib/concerns/wallaby/rails_overridden_methods.rb +42 -0
- data/lib/concerns/wallaby/resourcable.rb +149 -0
- data/lib/concerns/wallaby/servicable.rb +68 -0
- data/lib/concerns/wallaby/shared_helpers.rb +22 -0
- data/lib/concerns/wallaby/themeable.rb +40 -0
- data/lib/decorators/wallaby/resource_decorator.rb +189 -0
- data/lib/errors/wallaby/cell_handling.rb +6 -0
- data/lib/errors/wallaby/forbidden.rb +6 -0
- data/lib/errors/wallaby/general_error.rb +6 -0
- data/lib/errors/wallaby/invalid_error.rb +6 -0
- data/lib/errors/wallaby/model_not_found.rb +11 -0
- data/lib/errors/wallaby/not_authenticated.rb +6 -0
- data/lib/errors/wallaby/not_found.rb +6 -0
- data/lib/errors/wallaby/not_implemented.rb +6 -0
- data/lib/errors/wallaby/resource_not_found.rb +11 -0
- data/lib/errors/wallaby/unprocessable_entity.rb +6 -0
- data/lib/forms/wallaby/form_builder.rb +60 -0
- data/lib/helpers/wallaby/application_helper.rb +79 -0
- data/lib/helpers/wallaby/base_helper.rb +65 -0
- data/lib/helpers/wallaby/configuration_helper.rb +18 -0
- data/lib/helpers/wallaby/form_helper.rb +62 -0
- data/lib/helpers/wallaby/index_helper.rb +84 -0
- data/lib/helpers/wallaby/links_helper.rb +213 -0
- data/lib/helpers/wallaby/resources_helper.rb +52 -0
- data/lib/helpers/wallaby/secure_helper.rb +54 -0
- data/lib/helpers/wallaby/styling_helper.rb +82 -0
- data/lib/interfaces/wallaby/mode.rb +72 -0
- data/lib/interfaces/wallaby/model_authorization_provider.rb +99 -0
- data/lib/interfaces/wallaby/model_decorator.rb +168 -0
- data/lib/interfaces/wallaby/model_finder.rb +12 -0
- data/lib/interfaces/wallaby/model_pagination_provider.rb +107 -0
- data/lib/interfaces/wallaby/model_service_provider.rb +84 -0
- data/lib/paginators/wallaby/model_paginator.rb +115 -0
- data/lib/paginators/wallaby/resource_paginator.rb +12 -0
- data/lib/parsers/wallaby/parser.rb +34 -0
- data/lib/renderers/wallaby/cell.rb +137 -0
- data/lib/renderers/wallaby/cell_resolver.rb +89 -0
- data/lib/renderers/wallaby/custom_lookup_context.rb +64 -0
- data/lib/renderers/wallaby/custom_partial_renderer.rb +33 -0
- data/lib/renderers/wallaby/custom_renderer.rb +16 -0
- data/lib/responders/wallaby/json_api_responder.rb +101 -0
- data/lib/responders/wallaby/resources_responder.rb +28 -0
- data/lib/routes/wallaby/resources_router.rb +72 -0
- data/lib/servicers/wallaby/model_servicer.rb +154 -0
- data/lib/services/wallaby/engine_name_finder.rb +22 -0
- data/lib/services/wallaby/engine_url_for.rb +46 -0
- data/lib/services/wallaby/link_options_normalizer.rb +19 -0
- data/lib/services/wallaby/map/mode_mapper.rb +27 -0
- data/lib/services/wallaby/map/model_class_collector.rb +49 -0
- data/lib/services/wallaby/map/model_class_mapper.rb +38 -0
- data/lib/services/wallaby/prefixes_builder.rb +66 -0
- data/lib/services/wallaby/sorting/hash_builder.rb +19 -0
- data/lib/services/wallaby/sorting/link_builder.rb +69 -0
- data/lib/services/wallaby/sorting/next_builder.rb +63 -0
- data/lib/services/wallaby/sorting/single_builder.rb +20 -0
- data/lib/services/wallaby/type_renderer.rb +50 -0
- data/lib/support/action_dispatch/routing/mapper.rb +75 -0
- data/lib/tree/wallaby/node.rb +25 -0
- data/lib/utils/wallaby/cell_utils.rb +34 -0
- data/lib/utils/wallaby/field_utils.rb +43 -0
- data/lib/utils/wallaby/filter_utils.rb +20 -0
- data/lib/utils/wallaby/model_utils.rb +51 -0
- data/lib/utils/wallaby/module_utils.rb +46 -0
- data/lib/utils/wallaby/params_utils.rb +14 -0
- data/lib/utils/wallaby/preload_utils.rb +44 -0
- data/lib/utils/wallaby/test_utils.rb +34 -0
- data/lib/utils/wallaby/utils.rb +27 -0
- data/lib/wallaby/configuration.rb +103 -0
- data/lib/wallaby/configuration/features.rb +24 -0
- data/lib/wallaby/configuration/mapping.rb +140 -0
- data/lib/wallaby/configuration/metadata.rb +23 -0
- data/lib/wallaby/configuration/models.rb +46 -0
- data/lib/wallaby/configuration/pagination.rb +30 -0
- data/lib/wallaby/configuration/security.rb +98 -0
- data/lib/wallaby/configuration/sorting.rb +28 -0
- data/lib/wallaby/constants.rb +45 -0
- data/lib/wallaby/core.rb +117 -0
- data/lib/wallaby/core/version.rb +7 -0
- data/lib/wallaby/engine.rb +43 -0
- data/lib/wallaby/map.rb +170 -0
- metadata +222 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
# This is the controller with only authentication logics.
|
5
|
+
class SecureController < ::Wallaby::ApplicationController
|
6
|
+
helper SecureHelper
|
7
|
+
helper_method :current_user
|
8
|
+
|
9
|
+
rescue_from NotAuthenticated, with: :unauthorized
|
10
|
+
rescue_from Forbidden, with: :forbidden
|
11
|
+
|
12
|
+
# Unauthorized page.
|
13
|
+
# @param exception [Exception] exception comes from `rescue_from`
|
14
|
+
def unauthorized(exception = nil)
|
15
|
+
error_rendering exception, __callee__
|
16
|
+
end
|
17
|
+
|
18
|
+
# Forbidden page.
|
19
|
+
# @param exception [Exception] exception comes from `rescue_from`
|
20
|
+
def forbidden(exception = nil)
|
21
|
+
error_rendering exception, __callee__
|
22
|
+
end
|
23
|
+
|
24
|
+
# @note This is a template method that can be overridden by subclasses
|
25
|
+
# This {current_user} method will try to looking up the actual implementation from the following
|
26
|
+
# places from high precedence to low:
|
27
|
+
#
|
28
|
+
# - {Wallaby::Configuration::Security#current_user}
|
29
|
+
# - `super`
|
30
|
+
# - do nothing
|
31
|
+
#
|
32
|
+
# It can be replaced completely in subclasses:
|
33
|
+
#
|
34
|
+
# ```
|
35
|
+
# def current_user
|
36
|
+
# # NOTE: please ensure `@current_user` is assigned, for instance:
|
37
|
+
# @current_user ||= User.new params.slice(:email)
|
38
|
+
# end
|
39
|
+
# ```
|
40
|
+
# @return [Object] a user object
|
41
|
+
def current_user
|
42
|
+
@current_user ||=
|
43
|
+
if security.current_user? || !defined? super
|
44
|
+
instance_exec(&security.current_user)
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @note This is a template method that can be overridden by subclasses
|
51
|
+
# This {authenticate_user!} method will try to looking up the actual implementation from the following
|
52
|
+
# places from high precedence to low:
|
53
|
+
#
|
54
|
+
# - {Wallaby::Configuration::Security#authenticate}
|
55
|
+
# - `super`
|
56
|
+
# - do nothing
|
57
|
+
#
|
58
|
+
# It can be replaced completely in subclasses:
|
59
|
+
#
|
60
|
+
# ```
|
61
|
+
# def authenticate_user!
|
62
|
+
# authenticate_or_request_with_http_basic do |username, password|
|
63
|
+
# username == 'too_simple' && password == 'too_naive'
|
64
|
+
# end
|
65
|
+
# end
|
66
|
+
# ```
|
67
|
+
# @return [true] when user is authenticated successfully
|
68
|
+
# @raise [Wallaby::NotAuthenticated] when user fails to authenticate
|
69
|
+
def authenticate_user!
|
70
|
+
authenticated =
|
71
|
+
if security.authenticate? || !defined? super
|
72
|
+
instance_exec(&security.authenticate)
|
73
|
+
else
|
74
|
+
super
|
75
|
+
end
|
76
|
+
raise NotAuthenticated unless authenticated
|
77
|
+
|
78
|
+
true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @!visibility private
|
4
|
+
# Defualt ability for wallaby
|
5
|
+
# If main app has defined `ability.rb`, this file will not be loaded/used.
|
6
|
+
class Ability
|
7
|
+
include ::CanCan::Ability
|
8
|
+
|
9
|
+
# @param _user [Object]
|
10
|
+
def initialize(_user)
|
11
|
+
can :manage, :all
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# Files in the config/locales directory are used for internationalization
|
2
|
+
# and are automatically loaded by Rails. If you want to use locales other
|
3
|
+
# than English, add the necessary files in this directory.
|
4
|
+
#
|
5
|
+
# To use the locales, use `I18n.t`:
|
6
|
+
#
|
7
|
+
# I18n.t 'hello'
|
8
|
+
#
|
9
|
+
# In views, this is aliased to just `t`:
|
10
|
+
#
|
11
|
+
# <%= t('hello') %>
|
12
|
+
#
|
13
|
+
# To use a different locale, set it with `I18n.locale`:
|
14
|
+
#
|
15
|
+
# I18n.locale = :es
|
16
|
+
#
|
17
|
+
# This would use the information in config/locales/es.yml.
|
18
|
+
#
|
19
|
+
# To learn more, please read the Rails Internationalization guide
|
20
|
+
# available at http://guides.rubyonrails.org/i18n.html.
|
21
|
+
|
22
|
+
en:
|
23
|
+
labels:
|
24
|
+
count: 'Count: '
|
25
|
+
auto_select_hint: 'Type to select...'
|
26
|
+
upload: 'Upload'
|
27
|
+
empty: 'null'
|
28
|
+
na: 'n/a'
|
29
|
+
edit: 'Edit # %{id}'
|
30
|
+
create: 'Create a %{model}'
|
31
|
+
|
32
|
+
buttons:
|
33
|
+
save: 'Save'
|
34
|
+
|
35
|
+
links:
|
36
|
+
new: 'Create %{model}'
|
37
|
+
show: 'Show'
|
38
|
+
edit: 'Edit'
|
39
|
+
delete: 'Delete'
|
40
|
+
cancel: 'Cancel'
|
41
|
+
confirm:
|
42
|
+
delete: 'Please confirm to delete'
|
43
|
+
export: 'Export as %{ext}'
|
44
|
+
|
45
|
+
http_errors:
|
46
|
+
report_error_html: 'And report the error <a href="https://github.com/reinteractive/wallaby/issues/new" target="_blank">here</a>.'
|
47
|
+
not_implemented: 'Not implemented.'
|
48
|
+
internal_server_error: 'Hope you feel better.'
|
49
|
+
bad_request: 'Your request is not supported.'
|
50
|
+
not_found: 'Not found.'
|
51
|
+
unprocessable_entity: 'Your request cannot be processed.'
|
52
|
+
unauthorized: 'You need to sign in to access this page.'
|
53
|
+
forbidden: 'You need permission to access this page.'
|
54
|
+
|
55
|
+
json_errors:
|
56
|
+
not_implemented: 'Not implemented.'
|
57
|
+
internal_server_error: 'Internal server error.'
|
58
|
+
bad_request: 'Your request is not supported.'
|
59
|
+
not_found: 'Not found.'
|
60
|
+
unprocessable_entity: 'Your request cannot be processed.'
|
61
|
+
unauthorized: 'You need to sign in to access this page.'
|
62
|
+
forbidden: 'You need permission to access this page.'
|
63
|
+
|
64
|
+
errors:
|
65
|
+
invalid:
|
66
|
+
models: '%{models} are invalid models.'
|
67
|
+
inheritance: '%{klass} does not inherit from %{parent}.'
|
68
|
+
type_required: 'Type is required for %{field_name}.'
|
69
|
+
not_found:
|
70
|
+
collection: 'Records cannot be found. Click + button to add one.'
|
71
|
+
model: 'Model %{model} cannot be found.'
|
72
|
+
resource: 'Record %{resource} cannot be found.'
|
73
|
+
unprocessable_entity:
|
74
|
+
keyword_search: 'Unable to perform keyword search when no text fields can be used.'
|
75
|
+
field_colon_search: 'Unable to perform field colon search for %{invalid_fields}.'
|
76
|
+
model: 'Unable to handle model %{model}.'
|
77
|
+
unauthorized: 'User %{user} is trying to perform %{action} on %{subject}'
|
78
|
+
pundit:
|
79
|
+
not_found:
|
80
|
+
scope_policy: 'Cannot find scope policy for %{scope}.'
|
81
|
+
attributes_for: 'Cannot find attributes for %{subject}.'
|
82
|
+
activerecord:
|
83
|
+
paginatable: '%{collection} is not paginatable.'
|
84
|
+
required: '%{subject} is required.'
|
85
|
+
not_implemented:
|
86
|
+
model_servicer: 'Custom model servicer method `%{method_name}` is not implemented'
|
87
|
+
|
88
|
+
pagination:
|
89
|
+
prev: 'Prev'
|
90
|
+
next: 'Next'
|
91
|
+
from_to: '%{from} to %{to}'
|
92
|
+
of: ' of '
|
93
|
+
total_count: '%{total}'
|
94
|
+
pers: 'Page Size'
|
95
|
+
pages: 'Page Number'
|
96
|
+
|
97
|
+
filters:
|
98
|
+
title: 'Filters'
|
99
|
+
all: 'All'
|
100
|
+
|
101
|
+
search:
|
102
|
+
hint: 'Press enter to search.'
|
103
|
+
|
104
|
+
hints:
|
105
|
+
box_html: 'Format: <code>(x1, y1), (x2, y2)</code> where <i>(x1,y1)</i> and <i>(x2,y2)</i> are any two opposite corners of the box.'
|
106
|
+
cidr_html: 'Example: <code>192.168.1.1/24</code> which holds an IPv4 or IPv6 network specification.'
|
107
|
+
circle_html: 'Format: <code><(x, y), r></code> where <i>(x,y)</i> is the center point and <i>r</i> is the radius of the circle.'
|
108
|
+
hstore_html: 'Format: <code>"Key1" => "Value1", "Key2" => "Value2"</code> is used for input and output, includes zero or more <i>key => value</i> pairs separated by commas.'
|
109
|
+
inet_html: 'Example: <code>192.168.1.1/24</code> which holds an IPv4 or IPv6 network specification.'
|
110
|
+
line_html: 'Format: <code>{ A, B, C }</code> which are represented by the linear equation <i>Ax + By + C = 0</i>.'
|
111
|
+
lseg_html: 'Format: <code>[(x1, y1), (x2, y2)]</code> where <i>(x1,y1)</i> and <i>(x2,y2)</i> are the end points of the line segment.'
|
112
|
+
ltree_html: 'Example: <code>Top.Countries.Europe.Russia</code> which is a sequence of zero or more labels separated by dots.'
|
113
|
+
macaddr_html: 'Example: <code>08:00:2b:01:02:03</code> which stores MAC addresses.'
|
114
|
+
path_html: 'Format: <code>((x1, y1) , ... , (xn, yn))</code> where the points are the end points of the line segments comprising the path.'
|
115
|
+
polygon_html: 'Format: <code>((x1, y1) , ... , (xn, yn))</code> where the points are the end points of the line segments comprising the boundary of the polygon.'
|
116
|
+
|
117
|
+
deprecation:
|
118
|
+
authorizer: "[DEPRECATION] `authorizer` will be removed from 5.3.*. Please use `current_authorizer` instead.\n(called from %{from})"
|
119
|
+
current_model_service: "[DEPRECATION] `current_model_service` will be removed from 5.3.*. Please use `current_servicer` instead.\n(called from %{from})"
|
120
|
+
find_filter_name: "[DEPRECATION] `Wallaby::Utils.find_filter_name` will be removed from 5.3.*. Please use `Wallaby::FilterUtils.filter_name_by` instead.\n(called from %{from})"
|
121
|
+
form_type_partial_render: "[DEPRECATION] `form_type_partial_render` will be removed from 5.3.*. Please use `type_render` instead.\n(called from %{from})"
|
122
|
+
index_params: "[DEPRECATION] `index_params` will be removed from 5.3.*.\n(called from %{from})"
|
123
|
+
paginator_of: "[DEPRECATION] `paginator_of` will be removed from 5.3.*. Please use `current_paginator` instead.\n(called from %{from})"
|
124
|
+
resource_paginator_inheirtance: "[DEPRECATION] `Wallaby::ResourcePaginator` will be removed from 5.3.*. Please inherit from `Wallaby::ModelPaginator` instead.\n(called from %{from})"
|
125
|
+
resource_paginator=: "[DEPRECATION] `resource_paginator=` will be removed from 5.3.*. Please use `model_paginator=` instead.\n(called from %{from})"
|
126
|
+
type_partial_render: "[DEPRECATION] `type_partial_render` will be removed from 5.3.*. Please use `type_render` instead.\n(called from %{from})"
|
127
|
+
|
128
|
+
fa:
|
129
|
+
# map fa 5's icon name to version 4
|
130
|
+
# @see this fa migration document https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4
|
131
|
+
v4:
|
132
|
+
clock: 'clock-o'
|
133
|
+
bars: 'navicon'
|
134
|
+
calendar: 'calendar-o'
|
135
|
+
check-square: 'check-square-o'
|
136
|
+
square: 'square-o'
|
137
|
+
link: 'chain'
|
138
|
+
user: 'user-o'
|
139
|
+
v5:
|
140
|
+
no-need: 'no-need'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Files in the config/locales directory are used for internationalization
|
2
|
+
# and are automatically loaded by Rails. If you want to use locales other
|
3
|
+
# than English, add the necessary files in this directory.
|
4
|
+
#
|
5
|
+
# To use the locales, use `I18n.t`:
|
6
|
+
#
|
7
|
+
# I18n.t 'hello'
|
8
|
+
#
|
9
|
+
# In views, this is aliased to just `t`:
|
10
|
+
#
|
11
|
+
# <%= t('hello') %>
|
12
|
+
#
|
13
|
+
# To use a different locale, set it with `I18n.locale`:
|
14
|
+
#
|
15
|
+
# I18n.locale = :es
|
16
|
+
#
|
17
|
+
# This would use the information in config/locales/es.yml.
|
18
|
+
#
|
19
|
+
# To learn more, please read the Rails Internationalization guide
|
20
|
+
# available at http://guides.rubyonrails.org/i18n.html.
|
21
|
+
|
22
|
+
en:
|
23
|
+
wallaby:
|
24
|
+
map:
|
25
|
+
missing_mode_for_model_class: "[WALLABY] Don't know how to handle this model %{model}."
|
26
|
+
model_class_mapper:
|
27
|
+
missing_model_class: "[WALLABY] Please define self.model_class for %{model} or set it as global.\n @see Wallaby.configuration.mapping"
|
28
|
+
|
29
|
+
mode:
|
30
|
+
inherit_required: '%{klass} must inherit from %{parent}.'
|
data/config/routes.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Wallaby::Engine.routes.draw do
|
4
|
+
# NOTE: For health check if needed
|
5
|
+
# @see Wallaby::ApplicationController#healthy
|
6
|
+
get 'status', to: 'wallaby/resources#healthy'
|
7
|
+
|
8
|
+
with_options to: Wallaby::ResourcesRouter.new do |route|
|
9
|
+
# @see `home` action for more
|
10
|
+
route.root defaults: { action: 'home' }
|
11
|
+
|
12
|
+
# To generate error pages for all supported HTTP status
|
13
|
+
Wallaby::ERRORS.each do |status|
|
14
|
+
code = Rack::Utils::SYMBOL_TO_STATUS_CODE[status]
|
15
|
+
route.get status, defaults: { action: status }
|
16
|
+
route.get code.to_s, defaults: { action: status }
|
17
|
+
end
|
18
|
+
|
19
|
+
# To generate general CRUD resourceful routes
|
20
|
+
# @see Wallaby::ResourcesRouter
|
21
|
+
scope path: ':resources' do
|
22
|
+
# @see Wallaby::ResourcesController#index
|
23
|
+
route.get '', defaults: { action: 'index' }, as: :resources
|
24
|
+
# @see Wallaby::ResourcesController#new
|
25
|
+
route.get 'new', defaults: { action: 'new' }, as: :new_resource
|
26
|
+
# @see Wallaby::ResourcesController#edit
|
27
|
+
route.get ':id/edit', defaults: { action: 'edit' }, as: :edit_resource
|
28
|
+
# @see Wallaby::ResourcesController#show
|
29
|
+
route.get ':id', defaults: { action: 'show' }, as: :resource
|
30
|
+
|
31
|
+
# @see Wallaby::ResourcesController#create
|
32
|
+
route.post '', defaults: { action: 'create' }
|
33
|
+
# @see Wallaby::ResourcesController#update
|
34
|
+
route.match ':id', via: %i(patch put), defaults: { action: 'update' }
|
35
|
+
# @see Wallaby::ResourcesController#destroy
|
36
|
+
route.delete ':id', defaults: { action: 'destroy' }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
class Custom
|
5
|
+
# Custom modal decorator
|
6
|
+
class ModelDecorator < ::Wallaby::ModelDecorator
|
7
|
+
# Assume that attributes come from the setter/getter, e.g. `name=`/`name`
|
8
|
+
# @return [ActiveSupport::HashWithIndifferentAccess] metadata
|
9
|
+
def fields
|
10
|
+
@fields ||=
|
11
|
+
::ActiveSupport::HashWithIndifferentAccess.new.tap do |hash|
|
12
|
+
methods = model_class.public_instance_methods(false).map(&:to_s)
|
13
|
+
methods
|
14
|
+
.grep(/[^=]$/)
|
15
|
+
.select { |method_id| methods.include? "#{method_id}=" }
|
16
|
+
.each { |attribute| hash[attribute] = { label: attribute.humanize, type: 'string' } }
|
17
|
+
end.freeze
|
18
|
+
end
|
19
|
+
|
20
|
+
# A copy of {#fields} for index page
|
21
|
+
# @return [ActiveSupport::HashWithIndifferentAccess] metadata
|
22
|
+
def index_fields
|
23
|
+
@index_fields ||= Utils.clone fields
|
24
|
+
end
|
25
|
+
|
26
|
+
# A copy of {#fields} for show page
|
27
|
+
# @return [ActiveSupport::HashWithIndifferentAccess] metadata
|
28
|
+
def show_fields
|
29
|
+
@show_fields ||= Utils.clone fields
|
30
|
+
end
|
31
|
+
|
32
|
+
# A copy of {#fields} for form (new/edit) page
|
33
|
+
# @return [ActiveSupport::HashWithIndifferentAccess] metadata
|
34
|
+
def form_fields
|
35
|
+
@form_fields ||= Utils.clone fields
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [Array<String>] a list of field names for index page
|
39
|
+
def index_field_names
|
40
|
+
@index_field_names ||= reposition index_fields.keys, primary_key
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Array<String>] a list of field names for show page
|
44
|
+
def show_field_names
|
45
|
+
@show_field_names ||= reposition show_fields.keys, primary_key
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Array<String>] a list of field names for form (new/edit) page
|
49
|
+
def form_field_names
|
50
|
+
@form_field_names ||= form_fields.keys - [primary_key.to_s]
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [ActiveModel::Errors]
|
54
|
+
def form_active_errors(resource)
|
55
|
+
@form_active_errors ||= ActiveModel::Errors.new resource
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [String, Symbole] primary key name
|
59
|
+
def primary_key
|
60
|
+
@primary_key ||= :id
|
61
|
+
end
|
62
|
+
|
63
|
+
# @param resource [Object]
|
64
|
+
# @return [String]
|
65
|
+
def guess_title(resource)
|
66
|
+
field_name = FieldUtils.first_field_by({ name: /name|title|subject/ }, fields)
|
67
|
+
ModuleUtils.try_to resource, field_name
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
class Custom
|
5
|
+
# Model finder
|
6
|
+
class ModelFinder < ::Wallaby::ModelFinder
|
7
|
+
# @return [Array<Class>] a list of classes
|
8
|
+
def all
|
9
|
+
Wallaby.configuration.custom_models.presence
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
class Custom
|
5
|
+
# Model pagination provider
|
6
|
+
class ModelPaginationProvider < ::Wallaby::ModelPaginationProvider
|
7
|
+
# By default, it doesn't support pagination
|
8
|
+
# @return [false]
|
9
|
+
def paginatable?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
class Custom
|
5
|
+
# Model service provider
|
6
|
+
class ModelServiceProvider < ::Wallaby::ModelServiceProvider
|
7
|
+
# @raise [Wallaby::NotImplemented]
|
8
|
+
def permit(*)
|
9
|
+
raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @raise [Wallaby::NotImplemented]
|
13
|
+
def collection(*)
|
14
|
+
raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
|
15
|
+
end
|
16
|
+
|
17
|
+
# @raise [Wallaby::NotImplemented]
|
18
|
+
def paginate(*)
|
19
|
+
raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @raise [Wallaby::NotImplemented]
|
23
|
+
def new(*)
|
24
|
+
raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @raise [Wallaby::NotImplemented]
|
28
|
+
def find(*)
|
29
|
+
raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @raise [Wallaby::NotImplemented]
|
33
|
+
def create(*)
|
34
|
+
raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @raise [Wallaby::NotImplemented]
|
38
|
+
def update(*)
|
39
|
+
raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @raise [Wallaby::NotImplemented]
|
43
|
+
def destroy(*)
|
44
|
+
raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|