admin_core 0.0.1
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/.gitattributes +2 -0
- data/.gitignore +53 -0
- data/.rspec +2 -0
- data/.rubocop.yml +27 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +3 -0
- data/README.md +48 -0
- data/Rakefile +31 -0
- data/admin_core.gemspec +32 -0
- data/client/.babelrc +19 -0
- data/client/.eslintignore +3 -0
- data/client/.eslintrc.yml +20 -0
- data/client/.flowconfig +7 -0
- data/client/.gitignore +64 -0
- data/client/README.md +3 -0
- data/client/admin-core.scss +8 -0
- data/client/flow-typed/npm/axios_v0.16.x.js +120 -0
- data/client/flow-typed/npm/classnames_v2.x.x.js +16 -0
- data/client/flow-typed/npm/lodash_v4.x.x.js +514 -0
- data/client/flow-typed/npm/react-router-dom_v4.x.x.js +166 -0
- data/client/flow-typed/npm/reactstrap_vx.x.x.js +536 -0
- data/client/package.json +60 -0
- data/client/src/.eslintrc.yml +23 -0
- data/client/src/AdminCore.jsx +44 -0
- data/client/src/components/Breadcrumb.jsx +18 -0
- data/client/src/components/Header.jsx +45 -0
- data/client/src/components/Pagination.jsx +72 -0
- data/client/src/components/ResourceFilters.jsx +87 -0
- data/client/src/components/ResourceForm.jsx +103 -0
- data/client/src/components/ResourcesCollection.jsx +41 -0
- data/client/src/components/Sidebar.jsx +90 -0
- data/client/src/decls.js +119 -0
- data/client/src/http-client.js +18 -0
- data/client/src/main.js +9 -0
- data/client/src/resource-field/BelongsTo.jsx +26 -0
- data/client/src/resource-field/Boolean.jsx +43 -0
- data/client/src/resource-field/Date.jsx +29 -0
- data/client/src/resource-field/DateTime.jsx +29 -0
- data/client/src/resource-field/Enum.jsx +34 -0
- data/client/src/resource-field/Number.jsx +28 -0
- data/client/src/resource-field/String.jsx +28 -0
- data/client/src/resource-field/Text.jsx +27 -0
- data/client/src/resource-field-renderer.js +45 -0
- data/client/src/resource-filter/Boolean.jsx +22 -0
- data/client/src/resource-filter/Number.jsx +45 -0
- data/client/src/resource-filter/String.jsx +46 -0
- data/client/src/resource-filter-renderer.js +17 -0
- data/client/src/resource-page/Base.js +36 -0
- data/client/src/resource-page/Edit.jsx +48 -0
- data/client/src/resource-page/Index.jsx +141 -0
- data/client/src/resource-page/New.jsx +48 -0
- data/client/src/resource-page/Show.jsx +116 -0
- data/client/webpack.config.js +26 -0
- data/client/yarn.lock +3816 -0
- data/lib/admin_core/base_controller.rb +114 -0
- data/lib/admin_core/base_resource_manager.rb +24 -0
- data/lib/admin_core/configuration.rb +20 -0
- data/lib/admin_core/engine.rb +6 -0
- data/lib/admin_core/errors.rb +17 -0
- data/lib/admin_core/resource_field/base.rb +69 -0
- data/lib/admin_core/resource_field/belongs_to.rb +38 -0
- data/lib/admin_core/resource_field/boolean.rb +18 -0
- data/lib/admin_core/resource_field/date.rb +18 -0
- data/lib/admin_core/resource_field/date_time.rb +18 -0
- data/lib/admin_core/resource_field/enum.rb +26 -0
- data/lib/admin_core/resource_field/number.rb +18 -0
- data/lib/admin_core/resource_field/string.rb +18 -0
- data/lib/admin_core/resource_field/text.rb +23 -0
- data/lib/admin_core/resource_field_builder.rb +48 -0
- data/lib/admin_core/resource_filter/base.rb +63 -0
- data/lib/admin_core/resource_filter/boolean.rb +17 -0
- data/lib/admin_core/resource_filter/number.rb +25 -0
- data/lib/admin_core/resource_filter/string.rb +27 -0
- data/lib/admin_core/resource_filter_builder.rb +37 -0
- data/lib/admin_core/resource_manager/buildable.rb +42 -0
- data/lib/admin_core/resource_manager/convert.rb +95 -0
- data/lib/admin_core/resource_manager/has_many_fields.rb +71 -0
- data/lib/admin_core/resource_manager/permission.rb +35 -0
- data/lib/admin_core/resource_manager/searchable.rb +57 -0
- data/lib/admin_core/resource_page/base.rb +17 -0
- data/lib/admin_core/resource_page/edit.rb +22 -0
- data/lib/admin_core/resource_page/index.rb +52 -0
- data/lib/admin_core/resource_page/new.rb +26 -0
- data/lib/admin_core/resource_page/show.rb +22 -0
- data/lib/admin_core/resource_router.rb +58 -0
- data/lib/admin_core/resource_search.rb +22 -0
- data/lib/admin_core/rspec/matchers.rb +18 -0
- data/lib/admin_core/rspec/resource_field_spec_helper.rb +54 -0
- data/lib/admin_core/version.rb +11 -0
- data/lib/admin_core/view_object/sidebar_dropdown.rb +21 -0
- data/lib/admin_core/view_object/sidebar_link.rb +24 -0
- data/lib/admin_core/view_object/sidebar_resource_link.rb +23 -0
- data/lib/admin_core/view_object/sidebar_title.rb +18 -0
- data/lib/admin_core.rb +69 -0
- data/lib/generators/admin_core/install_generator.rb +39 -0
- data/lib/generators/admin_core/resource_manager_generator.rb +166 -0
- data/lib/generators/admin_core/templates/admin-core.css +1 -0
- data/lib/generators/admin_core/templates/admin-core.js +38196 -0
- data/lib/generators/admin_core/templates/controller.rb.erb +4 -0
- data/lib/generators/admin_core/templates/initializer.rb.erb +3 -0
- data/lib/generators/admin_core/templates/resource_manager.rb.erb +33 -0
- data/lib/generators/admin_core/templates/view.html.erb +58 -0
- data/sample/.gitignore +21 -0
- data/sample/Gemfile +35 -0
- data/sample/Gemfile.lock +147 -0
- data/sample/README.md +24 -0
- data/sample/Rakefile +6 -0
- data/sample/app/assets/config/manifest.js +2 -0
- data/sample/app/assets/images/.keep +0 -0
- data/sample/app/assets/stylesheets/application.css +15 -0
- data/sample/app/controllers/admin/application_controller.rb +4 -0
- data/sample/app/controllers/admin/tweets_controller.rb +4 -0
- data/sample/app/controllers/admin/users_controller.rb +4 -0
- data/sample/app/controllers/application_controller.rb +3 -0
- data/sample/app/controllers/concerns/.keep +0 -0
- data/sample/app/helpers/application_helper.rb +2 -0
- data/sample/app/jobs/application_job.rb +2 -0
- data/sample/app/models/admin/tweet.rb +35 -0
- data/sample/app/models/admin/user.rb +41 -0
- data/sample/app/models/application_record.rb +3 -0
- data/sample/app/models/concerns/.keep +0 -0
- data/sample/app/models/tweet.rb +3 -0
- data/sample/app/models/user.rb +3 -0
- data/sample/app/views/admin/application.html.erb +64 -0
- data/sample/app/views/layouts/application.html.erb +13 -0
- data/sample/bin/bundle +3 -0
- data/sample/bin/rails +4 -0
- data/sample/bin/rake +4 -0
- data/sample/bin/setup +34 -0
- data/sample/bin/update +29 -0
- data/sample/config/application.rb +25 -0
- data/sample/config/boot.rb +3 -0
- data/sample/config/database.yml +25 -0
- data/sample/config/environment.rb +5 -0
- data/sample/config/environments/development.rb +42 -0
- data/sample/config/environments/production.rb +69 -0
- data/sample/config/environments/test.rb +36 -0
- data/sample/config/initializers/admin_core.rb +8 -0
- data/sample/config/initializers/application_controller_renderer.rb +6 -0
- data/sample/config/initializers/backtrace_silencers.rb +7 -0
- data/sample/config/initializers/cookies_serializer.rb +5 -0
- data/sample/config/initializers/filter_parameter_logging.rb +4 -0
- data/sample/config/initializers/inflections.rb +16 -0
- data/sample/config/initializers/mime_types.rb +4 -0
- data/sample/config/initializers/new_framework_defaults.rb +24 -0
- data/sample/config/initializers/session_store.rb +3 -0
- data/sample/config/initializers/wrap_parameters.rb +14 -0
- data/sample/config/locales/en.yml +23 -0
- data/sample/config/routes.rb +6 -0
- data/sample/config/secrets.yml +22 -0
- data/sample/config.ru +5 -0
- data/sample/db/migrate/20170417055257_create_users.rb +10 -0
- data/sample/db/migrate/20170417055412_create_tweets.rb +9 -0
- data/sample/db/schema.rb +31 -0
- data/sample/db/seeds.rb +7 -0
- data/sample/lib/assets/.keep +0 -0
- data/sample/lib/tasks/.keep +0 -0
- data/sample/log/.keep +0 -0
- data/sample/public/404.html +67 -0
- data/sample/public/422.html +67 -0
- data/sample/public/500.html +66 -0
- data/sample/public/apple-touch-icon-precomposed.png +0 -0
- data/sample/public/apple-touch-icon.png +0 -0
- data/sample/public/bundle.min.js +27 -0
- data/sample/public/bundle.min.js.map +1 -0
- data/sample/public/favicon.ico +0 -0
- data/sample/public/javascripts/admin-core.js +38196 -0
- data/sample/public/robots.txt +5 -0
- data/sample/public/stylesheets/admin-core.css +1 -0
- data/sample/tmp/.keep +0 -0
- data/sample/vendor/assets/stylesheets/.keep +0 -0
- metadata +368 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require 'action_controller'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
# @abstract
|
|
5
|
+
class BaseController < ActionController::Base
|
|
6
|
+
def index
|
|
7
|
+
respond_to do |format|
|
|
8
|
+
format.html do
|
|
9
|
+
render template: AdminCore.config.template
|
|
10
|
+
end
|
|
11
|
+
format.json do
|
|
12
|
+
render json: { page: AdminCore::ResourcePage::Index.new(resource_manager, params) }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def new
|
|
18
|
+
respond_to do |format|
|
|
19
|
+
format.html do
|
|
20
|
+
render template: AdminCore.config.template
|
|
21
|
+
end
|
|
22
|
+
format.json do
|
|
23
|
+
render json: { page: AdminCore::ResourcePage::New.new(resource_manager, params) }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def create
|
|
29
|
+
resource = resource_manager.build(params_for_create)
|
|
30
|
+
if resource.save
|
|
31
|
+
render json: { redirectTo: resource_router.show_path(resource) }
|
|
32
|
+
else
|
|
33
|
+
render_errors(resource)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def show
|
|
38
|
+
respond_to do |format|
|
|
39
|
+
format.html do
|
|
40
|
+
render template: AdminCore.config.template
|
|
41
|
+
end
|
|
42
|
+
format.json do
|
|
43
|
+
render json: { page: AdminCore::ResourcePage::Show.new(resource_manager, params) }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def edit
|
|
49
|
+
respond_to do |format|
|
|
50
|
+
format.html do
|
|
51
|
+
render template: AdminCore.config.template
|
|
52
|
+
end
|
|
53
|
+
format.json do
|
|
54
|
+
render json: { page: AdminCore::ResourcePage::Edit.new(resource_manager, params) }
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def update
|
|
60
|
+
resource = resource_manager.find(params)
|
|
61
|
+
if resource.update(params_for_update)
|
|
62
|
+
render json: { redirectTo: resource_router.show_path(resource) }
|
|
63
|
+
else
|
|
64
|
+
render_errors(resource)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def destroy
|
|
69
|
+
resource = resource_manager.find(params)
|
|
70
|
+
if resource.destroy
|
|
71
|
+
render json: { redirectTo: resource_router.index_path }
|
|
72
|
+
else
|
|
73
|
+
render_errors(resource)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
# @param resource [ActiveRecord::Base]
|
|
80
|
+
def render_errors(resource)
|
|
81
|
+
errors = {}
|
|
82
|
+
resource.errors.messages.keys.each do |key|
|
|
83
|
+
errors[key] = resource.errors.full_messages_for(key)
|
|
84
|
+
end
|
|
85
|
+
render json: { errors: errors }, status: :unprocessable_entity
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @return [AdminCore::BaseResourceManager]
|
|
89
|
+
def resource_manager
|
|
90
|
+
@resource_manager ||= resource_manager_class.new
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# @return [AdminCore::ResourceRouter]
|
|
94
|
+
def resource_router
|
|
95
|
+
resource_manager_class.router
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# @return [Class]
|
|
99
|
+
def resource_manager_class
|
|
100
|
+
resource_name = controller_path.singularize.split('/')[-1]
|
|
101
|
+
"#{AdminCore.config.module_name}::#{resource_name.camelize}".constantize
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @return [ActionController::Parameters]
|
|
105
|
+
def params_for_create
|
|
106
|
+
params.require(resource_manager.name).permit(resource_manager.permitted_field_names_for(:new))
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @return [ActionController::Parameters]
|
|
110
|
+
def params_for_update
|
|
111
|
+
params.require(resource_manager.name).permit(resource_manager.permitted_field_names_for(:edit))
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative 'resource_manager/buildable'
|
|
2
|
+
require_relative 'resource_manager/convert'
|
|
3
|
+
require_relative 'resource_manager/has_many_fields'
|
|
4
|
+
require_relative 'resource_manager/permission'
|
|
5
|
+
require_relative 'resource_manager/searchable'
|
|
6
|
+
|
|
7
|
+
module AdminCore
|
|
8
|
+
# @abstract
|
|
9
|
+
class BaseResourceManager
|
|
10
|
+
include AdminCore::ResourceManager::Buildable
|
|
11
|
+
include AdminCore::ResourceManager::Convert
|
|
12
|
+
include AdminCore::ResourceManager::HasManyFields
|
|
13
|
+
include AdminCore::ResourceManager::Searchable
|
|
14
|
+
include AdminCore::ResourceManager::Permission
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
# @param resource [ActiveRecord::Base]
|
|
19
|
+
# @return [String]
|
|
20
|
+
def display_resource(resource)
|
|
21
|
+
"#{resource.class} ##{resource.id}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
# Stores AdminCore configuration information.
|
|
3
|
+
class Configuration
|
|
4
|
+
DEFAULT_MODULE_NAME = 'Admin'.freeze
|
|
5
|
+
|
|
6
|
+
attr_accessor :route_name_prefix, :module_name, :template
|
|
7
|
+
|
|
8
|
+
def module_name
|
|
9
|
+
@module_name ||= DEFAULT_MODULE_NAME
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def route_name_prefix
|
|
13
|
+
@route_name_prefix ||= module_name.underscore
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def template
|
|
17
|
+
@template ||= "#{route_name_prefix}/application"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
# Base of any errors raised by AdminCore.
|
|
3
|
+
class Error < StandardError
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
class ResourceManagerAlreadyRegistered < Error
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class ResourceFieldAlreadyRegistered < Error
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class ResourceFieldNotFound < Error
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class InvalidResourceFieldDefinition < Error
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'admin_core/resource_field_builder'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceField
|
|
5
|
+
# @abstract Subclass and override {#field_value} to implement a custom resource field class.
|
|
6
|
+
class Base
|
|
7
|
+
# @return [Symbol]
|
|
8
|
+
def self.type
|
|
9
|
+
name.demodulize.underscore.to_sym
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @param name [Symbol]
|
|
13
|
+
# @return [Symbol]
|
|
14
|
+
def self.permitted_field_name_of(name)
|
|
15
|
+
name
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.register
|
|
19
|
+
AdminCore::ResourceFieldBuilder.register(type, self)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param resource [ActiveRecord::Base]
|
|
23
|
+
# @param name [Symbol]
|
|
24
|
+
# @param options [Hash]
|
|
25
|
+
# @param page [Symbol] :index, :new, :show or :edit
|
|
26
|
+
# @raise [AdminCore::InvalidFieldDefinition]
|
|
27
|
+
def initialize(resource, name, options, page)
|
|
28
|
+
@resource = resource
|
|
29
|
+
@name = name
|
|
30
|
+
@options = options
|
|
31
|
+
@page = page
|
|
32
|
+
validate
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Representation of ResourceField type.
|
|
36
|
+
#
|
|
37
|
+
# @return [Hash]
|
|
38
|
+
def to_hash
|
|
39
|
+
{
|
|
40
|
+
type: self.class.type,
|
|
41
|
+
name: name,
|
|
42
|
+
displayName: human_attribute_name,
|
|
43
|
+
value: field_value,
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
attr_reader :resource, :name, :options, :page
|
|
50
|
+
|
|
51
|
+
def field_value
|
|
52
|
+
raise NotImplementedError
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Override this method to validate field definition.
|
|
56
|
+
#
|
|
57
|
+
# @raise [AdminCore::InvalidFieldDefinition]
|
|
58
|
+
def validate; end
|
|
59
|
+
|
|
60
|
+
def data
|
|
61
|
+
resource.public_send(name)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def human_attribute_name
|
|
65
|
+
resource.class.human_attribute_name(name)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
require_relative '../errors'
|
|
3
|
+
|
|
4
|
+
module AdminCore
|
|
5
|
+
module ResourceField
|
|
6
|
+
class BelongsTo < Base
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def field_value
|
|
10
|
+
{
|
|
11
|
+
# Remove fields to avoid infinite field dependency loop
|
|
12
|
+
resource: associated_resource_manager.convert_for_index_page(associated_resource).merge(fields: []),
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def validate
|
|
17
|
+
return if associated_resource_manager_class
|
|
18
|
+
raise AdminCore::InvalidResourceFieldDefinition, 'resource_manager_class option is required'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def associated_resource
|
|
22
|
+
data || associated_resource_manager.build({})
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def associated_resource_manager
|
|
26
|
+
@associated_resource_manager ||= associated_resource_manager_class.new
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def associated_resource_manager_class
|
|
30
|
+
options[:resource_manager_class] || AdminCore.resource_managers.find do |manager_class|
|
|
31
|
+
manager_class.resource_name.to_sym == name
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
AdminCore.register_resource_field(BelongsTo)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceField
|
|
5
|
+
# @!attribute [r] data
|
|
6
|
+
# @return [Boolean]
|
|
7
|
+
class Boolean < Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# @note Implementation for {QiitaAdmin::ResourceField::Base#field_value}
|
|
11
|
+
def field_value
|
|
12
|
+
data
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
AdminCore.register_resource_field(Boolean)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceField
|
|
5
|
+
# @!attribute [r] data
|
|
6
|
+
# @return [ActiveSupport::TimeWithZone]
|
|
7
|
+
class Date < Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# @note Implementation for {QiitaAdmin::ResourceField::Base#field_value}
|
|
11
|
+
def field_value
|
|
12
|
+
data.to_s
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
AdminCore.register_resource_field(Date)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceField
|
|
5
|
+
# @!attribute [r] data
|
|
6
|
+
# @return [ActiveSupport::TimeWithZone]
|
|
7
|
+
class DateTime < Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# @note Implementation for {QiitaAdmin::ResourceField::Base#field_value}
|
|
11
|
+
def field_value
|
|
12
|
+
data.to_s
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
AdminCore.register_resource_field(DateTime)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceField
|
|
5
|
+
# @!attribute [r] data
|
|
6
|
+
# @return [String]
|
|
7
|
+
class Enum < Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# @note Implementation for {QiitaAdmin::ResourceField::Base#field_value}
|
|
11
|
+
def field_value
|
|
12
|
+
{
|
|
13
|
+
value: data,
|
|
14
|
+
values: values,
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [Array<String>]
|
|
19
|
+
def values
|
|
20
|
+
options.fetch(:values, [])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
AdminCore.register_resource_field(Enum)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceField
|
|
5
|
+
# @!attribute [r] data
|
|
6
|
+
# @return [Integer, Float]
|
|
7
|
+
class Number < Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# @note Implementation for {QiitaAdmin::ResourceField::Base#field_value}
|
|
11
|
+
def field_value
|
|
12
|
+
data
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
AdminCore.register_resource_field(Number)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceField
|
|
5
|
+
# @!attribute [r] data
|
|
6
|
+
# @return [String]
|
|
7
|
+
class String < Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# @note Implementation for {QiitaAdmin::ResourceField::Base#field_value}
|
|
11
|
+
def field_value
|
|
12
|
+
data
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
AdminCore.register_resource_field(String)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceField
|
|
5
|
+
# @!attribute [r] data
|
|
6
|
+
# @return [String]
|
|
7
|
+
class Text < Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# @note Implementation for {QiitaAdmin::ResourceField::Base#field_value}
|
|
11
|
+
def field_value
|
|
12
|
+
data.to_s[0...truncate_length]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [Integer]
|
|
16
|
+
def truncate_length
|
|
17
|
+
options.fetch(:truncate, 50)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
AdminCore.register_resource_field(Text)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
require 'admin_core/errors'
|
|
3
|
+
|
|
4
|
+
module AdminCore
|
|
5
|
+
class ResourceFieldBuilder
|
|
6
|
+
# @param type [Symbol]
|
|
7
|
+
# @return [Class]
|
|
8
|
+
# @raise [AdminCore::FieldNotFound]
|
|
9
|
+
def self.resolve(type)
|
|
10
|
+
unless AdminCore.resource_field_map.key?(type)
|
|
11
|
+
raise AdminCore::FieldNotFound, "Unknown field: #{type}"
|
|
12
|
+
end
|
|
13
|
+
AdminCore.resource_field_map[type]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @param name [Symbol]
|
|
17
|
+
# @param type [Symbol, Class]
|
|
18
|
+
# @param options [Symbol]
|
|
19
|
+
def initialize(name, type, options)
|
|
20
|
+
@name = name
|
|
21
|
+
@type = type
|
|
22
|
+
@options = options
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @param resource [ActiveRecord::Base]
|
|
26
|
+
# @param page [Symbol]
|
|
27
|
+
# @return [AdminCore::ResourceField::Base]
|
|
28
|
+
# @raise [AdminCore::FieldNotFound]
|
|
29
|
+
def build(resource, page)
|
|
30
|
+
resource_field_class.new(resource, name, options, page)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @return [Symbol]
|
|
34
|
+
# @raise [AdminCore::FieldNotFound]
|
|
35
|
+
def permitted_field_name
|
|
36
|
+
resource_field_class.permitted_field_name_of(name)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
attr_reader :name, :type, :options
|
|
42
|
+
|
|
43
|
+
# @return [Class]
|
|
44
|
+
def resource_field_class
|
|
45
|
+
@resource_field_class ||= self.class.resolve(type)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
module ResourceFilter
|
|
3
|
+
class Base
|
|
4
|
+
# @return [String]
|
|
5
|
+
def self.default_query_operator
|
|
6
|
+
'is'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# @return [String]
|
|
10
|
+
def self.type
|
|
11
|
+
name.demodulize.underscore.to_sym
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @param resource_manager [AdminCore::BaseResourceManager]
|
|
15
|
+
# @param name [Symbol]
|
|
16
|
+
# @param options [Hash]
|
|
17
|
+
# @param query_operator [String]
|
|
18
|
+
# @param query_value [String]
|
|
19
|
+
def initialize(resource_manager, name, options, query_operator, query_value)
|
|
20
|
+
@resource_manager = resource_manager
|
|
21
|
+
@name = name
|
|
22
|
+
@options = options
|
|
23
|
+
@query_operator = query_operator
|
|
24
|
+
@query_value = query_value
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def empty?
|
|
28
|
+
query_value ? query_value.empty? : true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def to_hash
|
|
32
|
+
{
|
|
33
|
+
type: self.class.type,
|
|
34
|
+
name: name,
|
|
35
|
+
displayName: display_name,
|
|
36
|
+
query: {
|
|
37
|
+
operator: query_operator,
|
|
38
|
+
value: query_value,
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @param relation [ActiveRecord::Relation]
|
|
44
|
+
# @return [ActiveRecord::Relation]
|
|
45
|
+
def apply(relation) # rubocop:disable Lint/UnusedMethodArgument
|
|
46
|
+
raise NotImplementedError
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
attr_reader :resource_manager, :name, :options, :query_value
|
|
52
|
+
|
|
53
|
+
# @return [String]
|
|
54
|
+
def display_name
|
|
55
|
+
resource_manager.class.resource_class.human_attribute_name(name)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def query_operator
|
|
59
|
+
@query_operator || self.class.default_query_operator
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceFilter
|
|
5
|
+
class Boolean < Base
|
|
6
|
+
# @note Implementation for {AdminCore::ResourceFilter::Base#apply}
|
|
7
|
+
def apply(relation)
|
|
8
|
+
case query_operator
|
|
9
|
+
when 'is'
|
|
10
|
+
relation.where(name => %w[true yes on 1].include?(query_value))
|
|
11
|
+
else
|
|
12
|
+
raise NotImplementedError
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceFilter
|
|
5
|
+
class Number < Base
|
|
6
|
+
def self.default_query_operator
|
|
7
|
+
'equals'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# @note Implementation for {AdminCore::ResourceFilter::Base#apply}
|
|
11
|
+
def apply(relation) # rubocop:disable Metrics/AbcSize
|
|
12
|
+
case query_operator
|
|
13
|
+
when 'equals'
|
|
14
|
+
relation.where(name => query_value)
|
|
15
|
+
when 'greater_than'
|
|
16
|
+
relation.where(relation.arel_table[name].gt(query_value))
|
|
17
|
+
when 'less_than'
|
|
18
|
+
relation.where(relation.arel_table[name].lt(query_value))
|
|
19
|
+
else
|
|
20
|
+
raise NotImplementedError
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceFilter
|
|
5
|
+
class String < Base
|
|
6
|
+
def self.default_query_operator
|
|
7
|
+
'equals'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# @note Implementation for {AdminCore::ResourceFilter::Base#apply}
|
|
11
|
+
def apply(relation) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
12
|
+
case query_operator
|
|
13
|
+
when 'contains'
|
|
14
|
+
relation.where(relation.arel_table[name].matches("%#{query_value}%"))
|
|
15
|
+
when 'equals'
|
|
16
|
+
relation.where(name => query_value)
|
|
17
|
+
when 'starts_with'
|
|
18
|
+
relation.where(relation.arel_table[name].matches("#{query_value}%"))
|
|
19
|
+
when 'ends_with'
|
|
20
|
+
relation.where(relation.arel_table[name].matches("%#{query_value}"))
|
|
21
|
+
else
|
|
22
|
+
raise NotImplementedError, query_operator
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
# @!attribute name
|
|
3
|
+
# @return [Symbol]
|
|
4
|
+
# @!attribute type
|
|
5
|
+
# @return [Symbol]
|
|
6
|
+
# @!attribute options
|
|
7
|
+
# @return [Symbol]
|
|
8
|
+
ResourceFilterBuilder = Struct.new(:name, :type, :options) do
|
|
9
|
+
# @param resource_manager [AdminCore::BaseResourceManager]
|
|
10
|
+
# @param params [ActionController::Parameters]
|
|
11
|
+
# @return [AdminCore::ResourceFilter::Base]
|
|
12
|
+
def build(resource_manager, params)
|
|
13
|
+
query_operator, query_value = parse(params)
|
|
14
|
+
resource_filter_class.new(resource_manager, name, options, query_operator, query_value)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
# @return [Class]
|
|
20
|
+
def resource_filter_class
|
|
21
|
+
@resource_filter_class ||= "AdminCore::ResourceFilter::#{type.to_s.camelize}".constantize
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def regexp
|
|
25
|
+
@regexp = /\A#{name}(?::(\w+))?\z/
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def parse(params)
|
|
29
|
+
params.keys.each do |key|
|
|
30
|
+
if (match = regexp.match(key))
|
|
31
|
+
return [match[1] || resource_filter_class.default_query_operator, params[key]]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
[]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|