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.
Files changed (173) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +2 -0
  3. data/.gitignore +53 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +27 -0
  6. data/CHANGELOG.md +15 -0
  7. data/Gemfile +3 -0
  8. data/README.md +48 -0
  9. data/Rakefile +31 -0
  10. data/admin_core.gemspec +32 -0
  11. data/client/.babelrc +19 -0
  12. data/client/.eslintignore +3 -0
  13. data/client/.eslintrc.yml +20 -0
  14. data/client/.flowconfig +7 -0
  15. data/client/.gitignore +64 -0
  16. data/client/README.md +3 -0
  17. data/client/admin-core.scss +8 -0
  18. data/client/flow-typed/npm/axios_v0.16.x.js +120 -0
  19. data/client/flow-typed/npm/classnames_v2.x.x.js +16 -0
  20. data/client/flow-typed/npm/lodash_v4.x.x.js +514 -0
  21. data/client/flow-typed/npm/react-router-dom_v4.x.x.js +166 -0
  22. data/client/flow-typed/npm/reactstrap_vx.x.x.js +536 -0
  23. data/client/package.json +60 -0
  24. data/client/src/.eslintrc.yml +23 -0
  25. data/client/src/AdminCore.jsx +44 -0
  26. data/client/src/components/Breadcrumb.jsx +18 -0
  27. data/client/src/components/Header.jsx +45 -0
  28. data/client/src/components/Pagination.jsx +72 -0
  29. data/client/src/components/ResourceFilters.jsx +87 -0
  30. data/client/src/components/ResourceForm.jsx +103 -0
  31. data/client/src/components/ResourcesCollection.jsx +41 -0
  32. data/client/src/components/Sidebar.jsx +90 -0
  33. data/client/src/decls.js +119 -0
  34. data/client/src/http-client.js +18 -0
  35. data/client/src/main.js +9 -0
  36. data/client/src/resource-field/BelongsTo.jsx +26 -0
  37. data/client/src/resource-field/Boolean.jsx +43 -0
  38. data/client/src/resource-field/Date.jsx +29 -0
  39. data/client/src/resource-field/DateTime.jsx +29 -0
  40. data/client/src/resource-field/Enum.jsx +34 -0
  41. data/client/src/resource-field/Number.jsx +28 -0
  42. data/client/src/resource-field/String.jsx +28 -0
  43. data/client/src/resource-field/Text.jsx +27 -0
  44. data/client/src/resource-field-renderer.js +45 -0
  45. data/client/src/resource-filter/Boolean.jsx +22 -0
  46. data/client/src/resource-filter/Number.jsx +45 -0
  47. data/client/src/resource-filter/String.jsx +46 -0
  48. data/client/src/resource-filter-renderer.js +17 -0
  49. data/client/src/resource-page/Base.js +36 -0
  50. data/client/src/resource-page/Edit.jsx +48 -0
  51. data/client/src/resource-page/Index.jsx +141 -0
  52. data/client/src/resource-page/New.jsx +48 -0
  53. data/client/src/resource-page/Show.jsx +116 -0
  54. data/client/webpack.config.js +26 -0
  55. data/client/yarn.lock +3816 -0
  56. data/lib/admin_core/base_controller.rb +114 -0
  57. data/lib/admin_core/base_resource_manager.rb +24 -0
  58. data/lib/admin_core/configuration.rb +20 -0
  59. data/lib/admin_core/engine.rb +6 -0
  60. data/lib/admin_core/errors.rb +17 -0
  61. data/lib/admin_core/resource_field/base.rb +69 -0
  62. data/lib/admin_core/resource_field/belongs_to.rb +38 -0
  63. data/lib/admin_core/resource_field/boolean.rb +18 -0
  64. data/lib/admin_core/resource_field/date.rb +18 -0
  65. data/lib/admin_core/resource_field/date_time.rb +18 -0
  66. data/lib/admin_core/resource_field/enum.rb +26 -0
  67. data/lib/admin_core/resource_field/number.rb +18 -0
  68. data/lib/admin_core/resource_field/string.rb +18 -0
  69. data/lib/admin_core/resource_field/text.rb +23 -0
  70. data/lib/admin_core/resource_field_builder.rb +48 -0
  71. data/lib/admin_core/resource_filter/base.rb +63 -0
  72. data/lib/admin_core/resource_filter/boolean.rb +17 -0
  73. data/lib/admin_core/resource_filter/number.rb +25 -0
  74. data/lib/admin_core/resource_filter/string.rb +27 -0
  75. data/lib/admin_core/resource_filter_builder.rb +37 -0
  76. data/lib/admin_core/resource_manager/buildable.rb +42 -0
  77. data/lib/admin_core/resource_manager/convert.rb +95 -0
  78. data/lib/admin_core/resource_manager/has_many_fields.rb +71 -0
  79. data/lib/admin_core/resource_manager/permission.rb +35 -0
  80. data/lib/admin_core/resource_manager/searchable.rb +57 -0
  81. data/lib/admin_core/resource_page/base.rb +17 -0
  82. data/lib/admin_core/resource_page/edit.rb +22 -0
  83. data/lib/admin_core/resource_page/index.rb +52 -0
  84. data/lib/admin_core/resource_page/new.rb +26 -0
  85. data/lib/admin_core/resource_page/show.rb +22 -0
  86. data/lib/admin_core/resource_router.rb +58 -0
  87. data/lib/admin_core/resource_search.rb +22 -0
  88. data/lib/admin_core/rspec/matchers.rb +18 -0
  89. data/lib/admin_core/rspec/resource_field_spec_helper.rb +54 -0
  90. data/lib/admin_core/version.rb +11 -0
  91. data/lib/admin_core/view_object/sidebar_dropdown.rb +21 -0
  92. data/lib/admin_core/view_object/sidebar_link.rb +24 -0
  93. data/lib/admin_core/view_object/sidebar_resource_link.rb +23 -0
  94. data/lib/admin_core/view_object/sidebar_title.rb +18 -0
  95. data/lib/admin_core.rb +69 -0
  96. data/lib/generators/admin_core/install_generator.rb +39 -0
  97. data/lib/generators/admin_core/resource_manager_generator.rb +166 -0
  98. data/lib/generators/admin_core/templates/admin-core.css +1 -0
  99. data/lib/generators/admin_core/templates/admin-core.js +38196 -0
  100. data/lib/generators/admin_core/templates/controller.rb.erb +4 -0
  101. data/lib/generators/admin_core/templates/initializer.rb.erb +3 -0
  102. data/lib/generators/admin_core/templates/resource_manager.rb.erb +33 -0
  103. data/lib/generators/admin_core/templates/view.html.erb +58 -0
  104. data/sample/.gitignore +21 -0
  105. data/sample/Gemfile +35 -0
  106. data/sample/Gemfile.lock +147 -0
  107. data/sample/README.md +24 -0
  108. data/sample/Rakefile +6 -0
  109. data/sample/app/assets/config/manifest.js +2 -0
  110. data/sample/app/assets/images/.keep +0 -0
  111. data/sample/app/assets/stylesheets/application.css +15 -0
  112. data/sample/app/controllers/admin/application_controller.rb +4 -0
  113. data/sample/app/controllers/admin/tweets_controller.rb +4 -0
  114. data/sample/app/controllers/admin/users_controller.rb +4 -0
  115. data/sample/app/controllers/application_controller.rb +3 -0
  116. data/sample/app/controllers/concerns/.keep +0 -0
  117. data/sample/app/helpers/application_helper.rb +2 -0
  118. data/sample/app/jobs/application_job.rb +2 -0
  119. data/sample/app/models/admin/tweet.rb +35 -0
  120. data/sample/app/models/admin/user.rb +41 -0
  121. data/sample/app/models/application_record.rb +3 -0
  122. data/sample/app/models/concerns/.keep +0 -0
  123. data/sample/app/models/tweet.rb +3 -0
  124. data/sample/app/models/user.rb +3 -0
  125. data/sample/app/views/admin/application.html.erb +64 -0
  126. data/sample/app/views/layouts/application.html.erb +13 -0
  127. data/sample/bin/bundle +3 -0
  128. data/sample/bin/rails +4 -0
  129. data/sample/bin/rake +4 -0
  130. data/sample/bin/setup +34 -0
  131. data/sample/bin/update +29 -0
  132. data/sample/config/application.rb +25 -0
  133. data/sample/config/boot.rb +3 -0
  134. data/sample/config/database.yml +25 -0
  135. data/sample/config/environment.rb +5 -0
  136. data/sample/config/environments/development.rb +42 -0
  137. data/sample/config/environments/production.rb +69 -0
  138. data/sample/config/environments/test.rb +36 -0
  139. data/sample/config/initializers/admin_core.rb +8 -0
  140. data/sample/config/initializers/application_controller_renderer.rb +6 -0
  141. data/sample/config/initializers/backtrace_silencers.rb +7 -0
  142. data/sample/config/initializers/cookies_serializer.rb +5 -0
  143. data/sample/config/initializers/filter_parameter_logging.rb +4 -0
  144. data/sample/config/initializers/inflections.rb +16 -0
  145. data/sample/config/initializers/mime_types.rb +4 -0
  146. data/sample/config/initializers/new_framework_defaults.rb +24 -0
  147. data/sample/config/initializers/session_store.rb +3 -0
  148. data/sample/config/initializers/wrap_parameters.rb +14 -0
  149. data/sample/config/locales/en.yml +23 -0
  150. data/sample/config/routes.rb +6 -0
  151. data/sample/config/secrets.yml +22 -0
  152. data/sample/config.ru +5 -0
  153. data/sample/db/migrate/20170417055257_create_users.rb +10 -0
  154. data/sample/db/migrate/20170417055412_create_tweets.rb +9 -0
  155. data/sample/db/schema.rb +31 -0
  156. data/sample/db/seeds.rb +7 -0
  157. data/sample/lib/assets/.keep +0 -0
  158. data/sample/lib/tasks/.keep +0 -0
  159. data/sample/log/.keep +0 -0
  160. data/sample/public/404.html +67 -0
  161. data/sample/public/422.html +67 -0
  162. data/sample/public/500.html +66 -0
  163. data/sample/public/apple-touch-icon-precomposed.png +0 -0
  164. data/sample/public/apple-touch-icon.png +0 -0
  165. data/sample/public/bundle.min.js +27 -0
  166. data/sample/public/bundle.min.js.map +1 -0
  167. data/sample/public/favicon.ico +0 -0
  168. data/sample/public/javascripts/admin-core.js +38196 -0
  169. data/sample/public/robots.txt +5 -0
  170. data/sample/public/stylesheets/admin-core.css +1 -0
  171. data/sample/tmp/.keep +0 -0
  172. data/sample/vendor/assets/stylesheets/.keep +0 -0
  173. 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,11 @@
1
+ module AdminCore
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ PATCH = 1
6
+
7
+ def self.to_s
8
+ [MAJOR, MINOR, PATCH].join('.')
9
+ end
10
+ end
11
+ 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