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,42 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
module ResourceManager
|
|
3
|
+
module Buildable
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
# @!method self.resource_class
|
|
7
|
+
# @return [Class]
|
|
8
|
+
# @!method self.resource_name
|
|
9
|
+
# @return [String]
|
|
10
|
+
# @!method self.resource_display_name
|
|
11
|
+
# @return [String]
|
|
12
|
+
class_methods do
|
|
13
|
+
def resource_class
|
|
14
|
+
@model ||= "::#{name.demodulize}".constantize
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def resource_name
|
|
18
|
+
resource_class.model_name.singular
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def resource_display_name
|
|
22
|
+
resource_class.model_name.human
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
attr_writer :model
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @param params [ActionController::Parameters]
|
|
31
|
+
# @return [ActiveRecord::Base]
|
|
32
|
+
def build(params)
|
|
33
|
+
self.class.resource_class.new(params)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @return [String]
|
|
37
|
+
def name
|
|
38
|
+
self.class.resource_class.model_name.singular
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require 'admin_core/resource_router'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceManager
|
|
5
|
+
module Convert
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
# @!method self.to_hash
|
|
9
|
+
# Implementation for ResourceManager type in flow.
|
|
10
|
+
# @see client/javascripts/src/decls.js
|
|
11
|
+
# @return [Hash]
|
|
12
|
+
# @!method self.param_name
|
|
13
|
+
# @return [Symbol]
|
|
14
|
+
# @!method self.router
|
|
15
|
+
# @return [AdminCore::ResourceRouter]
|
|
16
|
+
class_methods do
|
|
17
|
+
def to_hash
|
|
18
|
+
{
|
|
19
|
+
displayName: resource_display_name,
|
|
20
|
+
indexPath: router.index_path,
|
|
21
|
+
newPath: creatable? ? router.new_path : nil,
|
|
22
|
+
showPath: router.show_path(":#{param_name}"),
|
|
23
|
+
editPath: updatable? ? router.edit_path(":#{param_name}") : nil,
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def param_name
|
|
28
|
+
:id
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def router
|
|
32
|
+
@router ||= AdminCore::ResourceRouter.new(self)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @!method convert_for_index_page(resource)
|
|
37
|
+
# @param resource [ActiveRecord::Base]
|
|
38
|
+
# @return [Hash] Resource representation for ResourcePage$Index type
|
|
39
|
+
# @!method convert_for_new_page(resource)
|
|
40
|
+
# @param resource [ActiveRecord::Base]
|
|
41
|
+
# @return [Hash] Resource representation for ResourcePage$New type
|
|
42
|
+
# @!method convert_for_show_page(resource)
|
|
43
|
+
# @param resource [ActiveRecord::Base]
|
|
44
|
+
# @return [Hash] Resource representation for ResourcePage$Show type
|
|
45
|
+
# @!method convert_for_edit_page(resource)
|
|
46
|
+
# @param resource [ActiveRecord::Base]
|
|
47
|
+
# @return [Hash] Resource representation for ResourcePage$Edit type
|
|
48
|
+
%i[index new show edit].each do |page|
|
|
49
|
+
define_method "convert_for_#{page}_page" do |resource|
|
|
50
|
+
convert(resource, field_builders_for(page), page)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @return [Array<String>]
|
|
55
|
+
def human_attribute_names_for_index
|
|
56
|
+
self.class.field_names_for(:index).map do |name|
|
|
57
|
+
self.class.resource_class.human_attribute_name(name)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
# Implementation for Resource type in flow.
|
|
64
|
+
# @see client/javascripts/src/qiita-admin/admin-core/decls.js
|
|
65
|
+
# @param resource [ActiveRecord::Base]
|
|
66
|
+
# @param field_builders [Array<AdminCore::ResourceFieldBuilder>]
|
|
67
|
+
# @param page [Symbol]
|
|
68
|
+
# @return [Hash]
|
|
69
|
+
def convert(resource, field_builders, page)
|
|
70
|
+
{
|
|
71
|
+
displayName: display_resource(resource),
|
|
72
|
+
name: name,
|
|
73
|
+
showPath: show_path_for(resource),
|
|
74
|
+
editPath: edit_path_for(resource),
|
|
75
|
+
destroyable: self.class.destroyable?,
|
|
76
|
+
fields: build_fields(resource, field_builders, page),
|
|
77
|
+
}
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def show_path_for(resource)
|
|
81
|
+
resource.persisted? ? self.class.router.show_path(resource) : nil
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def edit_path_for(resource)
|
|
85
|
+
resource.persisted? && self.class.updatable? ? self.class.router.edit_path(resource) : nil
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def build_fields(resource, field_builders, page)
|
|
89
|
+
field_builders.map do |field_builder|
|
|
90
|
+
field_builder.build(resource, page).to_hash
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'admin_core/resource_field_builder'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourceManager
|
|
5
|
+
module HasManyFields
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
# @!method self.field_builders
|
|
9
|
+
# @return [Hash<Symbol, AdminCore::ResourceFieldBuilder>]
|
|
10
|
+
# @!method self.field_names_for(page)
|
|
11
|
+
# @param page [Symbol]
|
|
12
|
+
# @return [Array<Symbol>]
|
|
13
|
+
class_methods do
|
|
14
|
+
def field_builders
|
|
15
|
+
@field_builders ||= {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def field_names_for(page)
|
|
19
|
+
@page_fields ||= {}
|
|
20
|
+
@page_fields[page] || []
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
# @param name [Symbol]
|
|
26
|
+
# @param type [Symbol, Class] built-in type name or a resoure field class
|
|
27
|
+
# @param options [Hash]
|
|
28
|
+
def define_field(name, type, options = {})
|
|
29
|
+
field_builders[name] = AdminCore::ResourceFieldBuilder.new(name, type, options)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @param pages [Array<Symbol>]
|
|
33
|
+
# @param fields [Array<Symbol>]
|
|
34
|
+
def register_fields_for(*pages, fields)
|
|
35
|
+
@page_fields ||= {}
|
|
36
|
+
pages.each do |page|
|
|
37
|
+
@page_fields[page] = fields
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @param page [Symbol]
|
|
43
|
+
# @return [Array<Symbol>]
|
|
44
|
+
def permitted_field_names_for(page)
|
|
45
|
+
field_builders_for(page).map(&:permitted_field_name)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @param params [ActionController::Parameters]
|
|
49
|
+
# @return [Array<AdminCore::ResourceFilter::Base>]
|
|
50
|
+
def build_filters(params)
|
|
51
|
+
self.class.filter_builders.map do |filter_builder|
|
|
52
|
+
filter_builder.build(self, params[:filter] || {})
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private # rubocop:disable Lint/UselessAccessModifier
|
|
57
|
+
|
|
58
|
+
# @param page [Symbol]
|
|
59
|
+
# @return [Array<AdminCore::ResourceFieldBuilder>]
|
|
60
|
+
def field_builders_for(page)
|
|
61
|
+
self.class.field_names_for(page).map(&method(:field_builder_for))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @param name [Symbol]
|
|
65
|
+
# @return [AdminCore::ResourceFieldBuilder]
|
|
66
|
+
def field_builder_for(name)
|
|
67
|
+
self.class.field_builders[name]
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
module ResourceManager
|
|
3
|
+
module Permission
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
# @!method self.creatable?
|
|
7
|
+
# @return [Boolean]
|
|
8
|
+
# @!method self.updatable?
|
|
9
|
+
# @return [Boolean]
|
|
10
|
+
# @!method self.destroyable?
|
|
11
|
+
# @return [Boolean]
|
|
12
|
+
class_methods do
|
|
13
|
+
def creatable?
|
|
14
|
+
field_names_for(:new).present?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @return [Boolean]
|
|
18
|
+
def updatable?
|
|
19
|
+
field_names_for(:edit).present?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @return [Boolean]
|
|
23
|
+
def destroyable?
|
|
24
|
+
instance_variable_defined?(:@destroyable) ? @destroyable : true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def destroyable(value)
|
|
30
|
+
@destroyable = value
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'admin_core/resource_filter_builder'
|
|
2
|
+
require 'admin_core/resource_search'
|
|
3
|
+
|
|
4
|
+
module AdminCore
|
|
5
|
+
module ResourceManager
|
|
6
|
+
module Searchable
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
# @!method self.filter_builders
|
|
10
|
+
# @return [Array<AdminCore::ResourceFieldBuilder>]
|
|
11
|
+
# @!method self.scopes
|
|
12
|
+
# @return [Array<Symbol>]
|
|
13
|
+
class_methods do
|
|
14
|
+
def filter_builders
|
|
15
|
+
@filter_builders ||= []
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def scopes
|
|
19
|
+
@scopes || []
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
# @param values [Array<Symbol>]
|
|
25
|
+
def register_scopes(values)
|
|
26
|
+
@scopes = values
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param name [Symbol]
|
|
30
|
+
# @param type [Symbol]
|
|
31
|
+
# @param options [Hash]
|
|
32
|
+
def define_and_register_filter(name, type, options = {})
|
|
33
|
+
filter_builders.push(AdminCore::ResourceFilterBuilder.new(name, type, options))
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @!method search
|
|
38
|
+
# Delegate to {AdminCore::ResourceSearch#search}
|
|
39
|
+
included do
|
|
40
|
+
delegate :search, to: :resource_search
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @param params [ActionController::Parameters]
|
|
44
|
+
# @return [ActiveRecord::Base]
|
|
45
|
+
def find(params)
|
|
46
|
+
self.class.resource_class.find_by(self.class.param_name => params[self.class.param_name])
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private # rubocop:disable Lint/UselessAccessModifier
|
|
50
|
+
|
|
51
|
+
# @return [AdminCore::ResourceSearch]
|
|
52
|
+
def resource_search
|
|
53
|
+
AdminCore::ResourceSearch.new(self)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
module ResourcePage
|
|
3
|
+
# @abstract
|
|
4
|
+
class Base
|
|
5
|
+
# @param resource_manager [AdminCore::BaseResourceManager]
|
|
6
|
+
# @param params [ActionController::Parameters]
|
|
7
|
+
def initialize(resource_manager, params)
|
|
8
|
+
@resource_manager = resource_manager
|
|
9
|
+
@params = params
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
attr_reader :resource_manager, :params
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourcePage
|
|
5
|
+
class Edit < Base
|
|
6
|
+
# Implementation for ResourcePage$New type.
|
|
7
|
+
# @see client/javascripts/src/qiita-admin/admin-core/decls.js
|
|
8
|
+
def to_hash
|
|
9
|
+
{
|
|
10
|
+
resource: resource_manager.convert_for_edit_page(resource)
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
# @return [ActiveRecord::Base]
|
|
17
|
+
def resource
|
|
18
|
+
@resource ||= resource_manager.find(params)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourcePage
|
|
5
|
+
class Index < Base
|
|
6
|
+
# Implementation for ResourcePage$Index type.
|
|
7
|
+
# @see client/javascripts/src/qiita-admin/admin-core/decls.js
|
|
8
|
+
def to_hash
|
|
9
|
+
{
|
|
10
|
+
attributes: attributes,
|
|
11
|
+
resources: resources.map { |resource| resource_manager.convert_for_index_page(resource) },
|
|
12
|
+
filters: filters,
|
|
13
|
+
scopes: scopes,
|
|
14
|
+
pagination: {
|
|
15
|
+
current: resources.current_page,
|
|
16
|
+
total: resources.total_pages,
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def attributes
|
|
24
|
+
resource_manager.human_attribute_names_for_index
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def scopes
|
|
28
|
+
resource_manager.class.scopes.map do |scope|
|
|
29
|
+
{ name: scope, count: searched_resources.public_send(scope).count }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def searched_resources
|
|
34
|
+
@searched_resources ||= resource_manager.search(filters)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def resources
|
|
38
|
+
@resources ||= searched_resources.public_send(scope).page(params[:page])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [Array<AdminCore::ResourceFilter::Base>]
|
|
42
|
+
def filters
|
|
43
|
+
@filters ||= resource_manager.build_filters(params)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @return [Symbol]
|
|
47
|
+
def scope
|
|
48
|
+
params[:scope] || :all
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourcePage
|
|
5
|
+
class New < Base
|
|
6
|
+
# Implementation for ResourcePage$New type.
|
|
7
|
+
# @see client/javascripts/src/qiita-admin/admin-core/decls.js
|
|
8
|
+
def to_hash
|
|
9
|
+
{
|
|
10
|
+
resource: resource_manager.convert_for_new_page(resource)
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
# @return [ActiveRecord::Base]
|
|
17
|
+
def resource
|
|
18
|
+
@resource ||= resource_manager.build(permitted_params)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def permitted_params
|
|
22
|
+
params[resource_manager.name].try(:permit, resource_manager.permitted_field_names_for(:new))
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module ResourcePage
|
|
5
|
+
class Show < Base
|
|
6
|
+
# Implementation for ResourcePage$Show type.
|
|
7
|
+
# @see client/javascripts/src/qiita-admin/admin-core/decls.js
|
|
8
|
+
def to_hash
|
|
9
|
+
{
|
|
10
|
+
resource: resource_manager.convert_for_show_page(resource)
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
# @return [ActiveRecord::Base]
|
|
17
|
+
def resource
|
|
18
|
+
@resource ||= resource_manager.find(params)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'admin_core'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
class ResourceRouter
|
|
5
|
+
def self.url_helpers
|
|
6
|
+
@url_helpers ||= Rails.application.routes.url_helpers
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# @param resource_manager_class [Class]
|
|
10
|
+
def initialize(resource_manager_class)
|
|
11
|
+
@resource_manager_class = resource_manager_class
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @return [String]
|
|
15
|
+
def index_path
|
|
16
|
+
url_for(controller: controller, action: 'index', only_path: true)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [String]
|
|
20
|
+
def new_path
|
|
21
|
+
url_for(controller: controller, action: 'new', only_path: true)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param param [String, ActiveRecord::Base]
|
|
25
|
+
# @return [String]
|
|
26
|
+
def show_path(param)
|
|
27
|
+
url_for(controller: controller, action: 'show', id: strip(param), only_path: true)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @param param [String]
|
|
31
|
+
# @return [String]
|
|
32
|
+
def edit_path(param)
|
|
33
|
+
url_for(controller: controller, action: 'edit', id: strip(param), only_path: true)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
attr_reader :resource_manager_class
|
|
39
|
+
|
|
40
|
+
delegate :resource_class, to: :resource_manager_class
|
|
41
|
+
delegate :url_for, to: :url_helpers
|
|
42
|
+
|
|
43
|
+
def controller
|
|
44
|
+
"#{AdminCore.config.route_name_prefix}/#{resource_class.model_name.plural}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def url_helpers
|
|
48
|
+
self.class.url_helpers
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @param param [String, ActiveRecord::Base]
|
|
52
|
+
# @return [String]
|
|
53
|
+
def strip(param)
|
|
54
|
+
return param.public_send(resource_manager_class.param_name) if param.is_a?(ActiveRecord::Base)
|
|
55
|
+
param
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
class ResourceSearch
|
|
3
|
+
# @param resource_manager
|
|
4
|
+
def initialize(resource_manager)
|
|
5
|
+
@resource_manager = resource_manager
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# @param filters [Array<AdminCore::ResourceFilter::Base>]
|
|
9
|
+
# @return [ActiveRecord::Relation] resources for index page.
|
|
10
|
+
def search(filters)
|
|
11
|
+
resources = resource_manager.class.resource_class.all
|
|
12
|
+
filters.reject(&:empty?).each do |filter|
|
|
13
|
+
resources = filter.apply(resources)
|
|
14
|
+
end
|
|
15
|
+
resources
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
attr_reader :resource_manager
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
module RSpec
|
|
3
|
+
module Matchers
|
|
4
|
+
extend RSpec::Matchers::DSL
|
|
5
|
+
|
|
6
|
+
matcher :have_shape_of_ResourceField do |type_value: nil, value_type: nil|
|
|
7
|
+
match do |actual|
|
|
8
|
+
expect(actual).to match(
|
|
9
|
+
'displayName' => be_a(String),
|
|
10
|
+
'name' => be_a(String),
|
|
11
|
+
'type' => type_value ? type_value : be_a(String),
|
|
12
|
+
'value' => be_a(value_type ? value_type : Object)
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require_relative 'matchers'
|
|
2
|
+
|
|
3
|
+
module AdminCore
|
|
4
|
+
module RSpec
|
|
5
|
+
module ResourceFieldSpecHelper
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
include AdminCore::RSpec::Matchers
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
shared_context 'with resource field instance' do |create_resource:, name:, options:, page:|
|
|
11
|
+
let(:resource_field) do
|
|
12
|
+
described_class.new(create_resource.call, name, options, page)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
shared_examples_for 'AdminCore::ResourceField' do |create_resource:, name:, options: {}|
|
|
17
|
+
describe '.type' do
|
|
18
|
+
subject do
|
|
19
|
+
described_class.type
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it { should be_a Symbol }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe '.permitted_field_name_of' do
|
|
26
|
+
subject do
|
|
27
|
+
described_class.permitted_field_name_of(name)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it { should be_a String }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe '#to_hash' do
|
|
34
|
+
%i[index new show edit].each do |page|
|
|
35
|
+
context "when page is #{page}" do
|
|
36
|
+
include_context 'with resource field instance',
|
|
37
|
+
create_resource: create_resource,
|
|
38
|
+
name: name,
|
|
39
|
+
options: options,
|
|
40
|
+
page: page
|
|
41
|
+
|
|
42
|
+
subject do
|
|
43
|
+
resource_field.to_hash.as_json
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it { should have_shape_of_ResourceField }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
module ViewObject
|
|
3
|
+
class SidebarDropdown
|
|
4
|
+
# @param name [String]
|
|
5
|
+
# @param links [Array<SidebarLink, SidebarResourceLink>]
|
|
6
|
+
def initialize(name, links)
|
|
7
|
+
@name = name
|
|
8
|
+
@links = links
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @note Implements SidebarDropdown flow type
|
|
12
|
+
def to_hash
|
|
13
|
+
{
|
|
14
|
+
displayName: @name,
|
|
15
|
+
links: @links,
|
|
16
|
+
type: 'dropdown'
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
module ViewObject
|
|
3
|
+
class SidebarLink
|
|
4
|
+
# @param name [String]
|
|
5
|
+
# @param link [String]
|
|
6
|
+
# @param external [Boolean]
|
|
7
|
+
def initialize(name, link, external = false)
|
|
8
|
+
@name = name
|
|
9
|
+
@link = link
|
|
10
|
+
@external = external
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @note Implements SidebarLink flow type
|
|
14
|
+
def to_hash
|
|
15
|
+
{
|
|
16
|
+
displayName: @name,
|
|
17
|
+
link: @link,
|
|
18
|
+
external: @link =~ %r{://} || @external,
|
|
19
|
+
type: 'link'
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module AdminCore
|
|
2
|
+
module ViewObject
|
|
3
|
+
class SidebarResourceLink
|
|
4
|
+
# @param resource_manager [AdminCore::BaseResourceManager]
|
|
5
|
+
def initialize(resource_manager)
|
|
6
|
+
@resource_manager = resource_manager
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def to_hash
|
|
10
|
+
{
|
|
11
|
+
displayName: resource_manager_hash[:displayName],
|
|
12
|
+
link: resource_manager_hash[:indexPath],
|
|
13
|
+
external: false,
|
|
14
|
+
type: 'link'
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def resource_manager_hash
|
|
19
|
+
@resource_manager_hash ||= @resource_manager.to_hash
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|