admin_core 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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