habarico 7.2.0.pre.beta.5

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 (221) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +82 -0
  4. data/Rakefile +15 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/habarico/action_schema_controller.rb +41 -0
  7. data/app/controllers/habarico/application_controller.rb +15 -0
  8. data/app/controllers/habarico/contrib/preferences/user_preferences_controller.rb +105 -0
  9. data/app/controllers/habarico/global_schema_controller.rb +11 -0
  10. data/app/controllers/habarico/local_schema_controller.rb +35 -0
  11. data/app/helpers/habarico/application_helper.rb +4 -0
  12. data/app/models/habarico/application_record.rb +5 -0
  13. data/app/views/layouts/habarico/application.html.erb +17 -0
  14. data/config/locales/cs.yml +39 -0
  15. data/config/locales/de.yml +39 -0
  16. data/config/locales/en.yml +39 -0
  17. data/config/locales/es.yml +39 -0
  18. data/config/locales/fr.yml +39 -0
  19. data/config/locales/it.yml +39 -0
  20. data/config/locales/ja.yml +39 -0
  21. data/config/locales/nl.yml +39 -0
  22. data/config/locales/pl.yml +39 -0
  23. data/config/locales/pt.yml +39 -0
  24. data/config/locales/ro.yml +39 -0
  25. data/config/locales/sk.yml +39 -0
  26. data/config/locales/uk.yml +39 -0
  27. data/config/routes.rb +1 -0
  28. data/lib/generators/habarico/preferences/install_generator.rb +27 -0
  29. data/lib/generators/habarico/preferences/templates/create_habarico_user_preferences.rb.tt +15 -0
  30. data/lib/habarico/active_model/references.rb +68 -0
  31. data/lib/habarico/authenticatable.rb +31 -0
  32. data/lib/habarico/config.rb +71 -0
  33. data/lib/habarico/context.rb +126 -0
  34. data/lib/habarico/contrib/preferences/base_preferences.rb +40 -0
  35. data/lib/habarico/contrib/preferences/config.rb +31 -0
  36. data/lib/habarico/contrib/preferences/errors.rb +79 -0
  37. data/lib/habarico/contrib/preferences/locales/cs.yml +8 -0
  38. data/lib/habarico/contrib/preferences/locales/de.yml +8 -0
  39. data/lib/habarico/contrib/preferences/locales/en.yml +8 -0
  40. data/lib/habarico/contrib/preferences/locales/es.yml +8 -0
  41. data/lib/habarico/contrib/preferences/locales/fr.yml +8 -0
  42. data/lib/habarico/contrib/preferences/locales/it.yml +8 -0
  43. data/lib/habarico/contrib/preferences/locales/ja.yml +8 -0
  44. data/lib/habarico/contrib/preferences/locales/nl.yml +8 -0
  45. data/lib/habarico/contrib/preferences/locales/pl.yml +8 -0
  46. data/lib/habarico/contrib/preferences/locales/pt.yml +8 -0
  47. data/lib/habarico/contrib/preferences/locales/ro.yml +8 -0
  48. data/lib/habarico/contrib/preferences/locales/sk.yml +8 -0
  49. data/lib/habarico/contrib/preferences/locales/uk.yml +8 -0
  50. data/lib/habarico/contrib/preferences/registry.rb +293 -0
  51. data/lib/habarico/contrib/preferences/routes.rb +17 -0
  52. data/lib/habarico/contrib/preferences/schemas.rb +129 -0
  53. data/lib/habarico/contrib/preferences/serializer.rb +19 -0
  54. data/lib/habarico/contrib/preferences/user_preference.rb +16 -0
  55. data/lib/habarico/contrib/preferences.rb +32 -0
  56. data/lib/habarico/controller.rb +584 -0
  57. data/lib/habarico/definition/action_reference.rb +18 -0
  58. data/lib/habarico/definition/actions/action.rb +14 -0
  59. data/lib/habarico/definition/actions/create_action.rb +18 -0
  60. data/lib/habarico/definition/actions/delete_action.rb +20 -0
  61. data/lib/habarico/definition/actions/edit_action.rb +18 -0
  62. data/lib/habarico/definition/actions/link_action.rb +11 -0
  63. data/lib/habarico/definition/actions/resource_action.rb +12 -0
  64. data/lib/habarico/definition/actions/save_action.rb +14 -0
  65. data/lib/habarico/definition/actions/show_action.rb +18 -0
  66. data/lib/habarico/definition/actions/upload_images_action.rb +11 -0
  67. data/lib/habarico/definition/actions/view_action.rb +11 -0
  68. data/lib/habarico/definition/boxes/array_box.rb +10 -0
  69. data/lib/habarico/definition/boxes/box.rb +32 -0
  70. data/lib/habarico/definition/boxes/gallery_box.rb +10 -0
  71. data/lib/habarico/definition/boxes/grid_box.rb +10 -0
  72. data/lib/habarico/definition/boxes/grid_item_box.rb +10 -0
  73. data/lib/habarico/definition/boxes/list_box.rb +10 -0
  74. data/lib/habarico/definition/boxes/object_box.rb +10 -0
  75. data/lib/habarico/definition/boxes/tab_box.rb +10 -0
  76. data/lib/habarico/definition/boxes/tab_item_box.rb +10 -0
  77. data/lib/habarico/definition/boxes/wizard_box.rb +10 -0
  78. data/lib/habarico/definition/concerns/definition_model.rb +38 -0
  79. data/lib/habarico/definition/definition.rb +206 -0
  80. data/lib/habarico/definition/field_reference.rb +9 -0
  81. data/lib/habarico/definition/filter_reference.rb +7 -0
  82. data/lib/habarico/definition/menu/link_menu_item.rb +12 -0
  83. data/lib/habarico/definition/menu/menu_item.rb +9 -0
  84. data/lib/habarico/definition/menu/text_menu_item.rb +12 -0
  85. data/lib/habarico/definition/menu/view_menu_item.rb +13 -0
  86. data/lib/habarico/definition/response.rb +13 -0
  87. data/lib/habarico/definition/views/action_view.rb +11 -0
  88. data/lib/habarico/definition/views/create_view.rb +15 -0
  89. data/lib/habarico/definition/views/edit_view.rb +15 -0
  90. data/lib/habarico/definition/views/list_view.rb +17 -0
  91. data/lib/habarico/definition/views/show_view.rb +15 -0
  92. data/lib/habarico/definition/views/view.rb +10 -0
  93. data/lib/habarico/engine.rb +6 -0
  94. data/lib/habarico/file_validations.rb +119 -0
  95. data/lib/habarico/generators/abstract_generator.rb +21 -0
  96. data/lib/habarico/generators/action/action_schema_generator.rb +111 -0
  97. data/lib/habarico/generators/action/confirm_dialog_properties_generator.rb +30 -0
  98. data/lib/habarico/generators/action/global_resource_action_schema_generator.rb +46 -0
  99. data/lib/habarico/generators/action/link_action_parameters_generator.rb +31 -0
  100. data/lib/habarico/generators/action/resource_action_endpoint_parameters_generator.rb +70 -0
  101. data/lib/habarico/generators/action/resource_action_parameters_generator.rb +40 -0
  102. data/lib/habarico/generators/action/resource_action_schema_generator.rb +51 -0
  103. data/lib/habarico/generators/action/save_action_parameters_generator.rb +26 -0
  104. data/lib/habarico/generators/action/upload_images_action_parameters_generator.rb +41 -0
  105. data/lib/habarico/generators/action/view_action_endpoint_parameters_generator.rb +37 -0
  106. data/lib/habarico/generators/action/view_action_parameters_generator.rb +56 -0
  107. data/lib/habarico/generators/endpoint/dynamic_render_options_generator.rb +26 -0
  108. data/lib/habarico/generators/endpoint/endpoints_schema_generator.rb +61 -0
  109. data/lib/habarico/generators/endpoint/enum_type_generator.rb +45 -0
  110. data/lib/habarico/generators/endpoint/field_options_generator.rb +179 -0
  111. data/lib/habarico/generators/endpoint/field_schema_generator.rb +381 -0
  112. data/lib/habarico/generators/endpoint/fields_schema_generator.rb +35 -0
  113. data/lib/habarico/generators/endpoint/filter_schema_generator.rb +201 -0
  114. data/lib/habarico/generators/endpoint/filters_schema_generator.rb +25 -0
  115. data/lib/habarico/generators/endpoint/method_schema_generator.rb +34 -0
  116. data/lib/habarico/generators/endpoint/number_field_options_generator.rb +45 -0
  117. data/lib/habarico/generators/endpoint/phone_field_options_generator.rb +29 -0
  118. data/lib/habarico/generators/endpoint/relation_field_options_generator.rb +90 -0
  119. data/lib/habarico/generators/endpoint/search_filter_schema_generator.rb +44 -0
  120. data/lib/habarico/generators/menu/menu_group_schema_generator.rb +63 -0
  121. data/lib/habarico/generators/menu/menu_link_parameters_generator.rb +31 -0
  122. data/lib/habarico/generators/menu/menu_schema_generator.rb +105 -0
  123. data/lib/habarico/generators/menu/menu_view_endpoint_parameters_generator.rb +44 -0
  124. data/lib/habarico/generators/menu/menu_view_parameters_generator.rb +50 -0
  125. data/lib/habarico/generators/resource/action_resource_schema_generator.rb +84 -0
  126. data/lib/habarico/generators/resource/global_resource_schema_generator.rb +70 -0
  127. data/lib/habarico/generators/resource/local_resource_schema_generator.rb +111 -0
  128. data/lib/habarico/generators/resource/object_resource_schema_generator.rb +49 -0
  129. data/lib/habarico/generators/resource/resource_schema_generator.rb +31 -0
  130. data/lib/habarico/generators/view/action_descriptor_generator.rb +88 -0
  131. data/lib/habarico/generators/view/array_box_parameters_generator.rb +34 -0
  132. data/lib/habarico/generators/view/box_options_generator.rb +23 -0
  133. data/lib/habarico/generators/view/box_schema_generator.rb +194 -0
  134. data/lib/habarico/generators/view/detail_view_parameters_generator.rb +57 -0
  135. data/lib/habarico/generators/view/field_descriptor_generator.rb +107 -0
  136. data/lib/habarico/generators/view/filter_descriptor_generator.rb +75 -0
  137. data/lib/habarico/generators/view/gallery_box_parameters_generator.rb +71 -0
  138. data/lib/habarico/generators/view/global_view_schema_generator.rb +59 -0
  139. data/lib/habarico/generators/view/grid_item_box_parameters_generator.rb +44 -0
  140. data/lib/habarico/generators/view/list_box_parameters_generator.rb +124 -0
  141. data/lib/habarico/generators/view/list_view_parameters_generator.rb +120 -0
  142. data/lib/habarico/generators/view/object_box_parameters_generator.rb +26 -0
  143. data/lib/habarico/generators/view/sort_descriptor_generator.rb +30 -0
  144. data/lib/habarico/generators/view/tab_box_parameters_generator.rb +26 -0
  145. data/lib/habarico/generators/view/view_endpoint_parameters_generator.rb +71 -0
  146. data/lib/habarico/generators/view/view_schema_generator.rb +87 -0
  147. data/lib/habarico/generators/view/wizard_box_parameters_generator.rb +32 -0
  148. data/lib/habarico/helpers/action_helper.rb +9 -0
  149. data/lib/habarico/helpers/attributes_helper.rb +67 -0
  150. data/lib/habarico/helpers/box_helper.rb +19 -0
  151. data/lib/habarico/helpers/callable_helper.rb +15 -0
  152. data/lib/habarico/helpers/filter_params_helper.rb +49 -0
  153. data/lib/habarico/helpers/order_by_helper.rb +56 -0
  154. data/lib/habarico/helpers/reflection_helper.rb +61 -0
  155. data/lib/habarico/helpers/sorting_helper.rb +136 -0
  156. data/lib/habarico/schema/action/action_schema.rb +46 -0
  157. data/lib/habarico/schema/action/confirm_dialog_properties.rb +13 -0
  158. data/lib/habarico/schema/action/global_resource_action_schema.rb +29 -0
  159. data/lib/habarico/schema/action/link_action_parameters.rb +15 -0
  160. data/lib/habarico/schema/action/resource_action_endpoint_parameters.rb +24 -0
  161. data/lib/habarico/schema/action/resource_action_parameters.rb +17 -0
  162. data/lib/habarico/schema/action/resource_action_schema.rb +14 -0
  163. data/lib/habarico/schema/action/save_action_parameters.rb +10 -0
  164. data/lib/habarico/schema/action/upload_images_action_parameters.rb +23 -0
  165. data/lib/habarico/schema/action/view_action_endpoint_parameters.rb +16 -0
  166. data/lib/habarico/schema/action/view_action_parameters.rb +27 -0
  167. data/lib/habarico/schema/endpoint/ai_field_options.rb +10 -0
  168. data/lib/habarico/schema/endpoint/box_options.rb +10 -0
  169. data/lib/habarico/schema/endpoint/choices_field_options.rb +10 -0
  170. data/lib/habarico/schema/endpoint/dynamic_render_options.rb +14 -0
  171. data/lib/habarico/schema/endpoint/endpoints_schema.rb +22 -0
  172. data/lib/habarico/schema/endpoint/enum_type.rb +21 -0
  173. data/lib/habarico/schema/endpoint/field_options.rb +56 -0
  174. data/lib/habarico/schema/endpoint/field_schema.rb +65 -0
  175. data/lib/habarico/schema/endpoint/filter_schema.rb +44 -0
  176. data/lib/habarico/schema/endpoint/image_field_options.rb +13 -0
  177. data/lib/habarico/schema/endpoint/key_value.rb +13 -0
  178. data/lib/habarico/schema/endpoint/method_schema.rb +13 -0
  179. data/lib/habarico/schema/endpoint/number_field_options.rb +24 -0
  180. data/lib/habarico/schema/endpoint/phone_field_options.rb +13 -0
  181. data/lib/habarico/schema/endpoint/relation_field_options.rb +39 -0
  182. data/lib/habarico/schema/extensible_enum.rb +20 -0
  183. data/lib/habarico/schema/menu/action_view_choice.rb +13 -0
  184. data/lib/habarico/schema/menu/menu_group_schema.rb +26 -0
  185. data/lib/habarico/schema/menu/menu_schema.rb +36 -0
  186. data/lib/habarico/schema/resource/global_resource_schema.rb +14 -0
  187. data/lib/habarico/schema/resource/local_resource_schema.rb +14 -0
  188. data/lib/habarico/schema/resource/object_resource_schema.rb +8 -0
  189. data/lib/habarico/schema/resource/resource_schema.rb +16 -0
  190. data/lib/habarico/schema/types.rb +102 -0
  191. data/lib/habarico/schema/view/action_descriptor.rb +30 -0
  192. data/lib/habarico/schema/view/array_box_parameters.rb +13 -0
  193. data/lib/habarico/schema/view/box_schema.rb +67 -0
  194. data/lib/habarico/schema/view/detail_view_parameters.rb +16 -0
  195. data/lib/habarico/schema/view/field_descriptor.rb +50 -0
  196. data/lib/habarico/schema/view/field_wrapper_properties.rb +13 -0
  197. data/lib/habarico/schema/view/filter_descriptor.rb +24 -0
  198. data/lib/habarico/schema/view/gallery_box_parameters.rb +31 -0
  199. data/lib/habarico/schema/view/global_view_schema.rb +25 -0
  200. data/lib/habarico/schema/view/grid_item_box_parameters.rb +13 -0
  201. data/lib/habarico/schema/view/list_box_parameters.rb +44 -0
  202. data/lib/habarico/schema/view/list_view_parameters.rb +31 -0
  203. data/lib/habarico/schema/view/object_box_parameters.rb +10 -0
  204. data/lib/habarico/schema/view/sort_descriptor.rb +15 -0
  205. data/lib/habarico/schema/view/sortable_parameters.rb +13 -0
  206. data/lib/habarico/schema/view/tab_box_parameters.rb +10 -0
  207. data/lib/habarico/schema/view/view_action_descriptor_parameters.rb +21 -0
  208. data/lib/habarico/schema/view/view_endpoint_parameters.rb +22 -0
  209. data/lib/habarico/schema/view/view_schema.rb +33 -0
  210. data/lib/habarico/schema/view/wizard_box_parameters.rb +13 -0
  211. data/lib/habarico/search/field_resolver.rb +138 -0
  212. data/lib/habarico/search/search_matcher.rb +152 -0
  213. data/lib/habarico/serializers/meta_serializer.rb +42 -0
  214. data/lib/habarico/serializers/record_serializer.rb +33 -0
  215. data/lib/habarico/serializers/serializer.rb +61 -0
  216. data/lib/habarico/services/resource_service.rb +69 -0
  217. data/lib/habarico/services/routing_service.rb +160 -0
  218. data/lib/habarico/services/schema_service.rb +72 -0
  219. data/lib/habarico/version.rb +5 -0
  220. data/lib/habarico.rb +262 -0
  221. metadata +324 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1f8b6c198a99af28029879ffde809fdd78c4cfd3809798f2d4624040ccdf0614
4
+ data.tar.gz: b0ec882cb2c571cd9350d5b4a6a01706970661f5b52900789a7215c4ac523c6a
5
+ SHA512:
6
+ metadata.gz: a8ab25a7e0b5c74f63a2d4b8203cd2bb797c1324a60c744a7e2db019a5dbdd7571fe252a21de1b3bb35ef821c31fcafc1305c7320e792f2c572d28277cf047fd
7
+ data.tar.gz: 3d8a9df73a2bcce948c33a21273f09d2864e81002bf56ed24cebd8be7862038874443c3c4edd3ace9a0f6b22301785cbbf7273f39fd21d9206431a7db02a1906
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Eluvia.land s.r.o.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # habarico
2
+
3
+ Habarico is a schema-driven admin library for Rails. The gem is an engine that turns Rails models
4
+ into a complete admin API: REST endpoints plus JSON schemas describing resources, fields, views and
5
+ actions. The [React frontend](https://docs.habarico.com/node/intro) renders the whole admin UI from
6
+ those schemas — no screen is written per resource.
7
+
8
+ ## Installation
9
+
10
+ The gem is published to the internal server, not to rubygems.org. Add it to your `Gemfile`:
11
+
12
+ ```ruby
13
+ gem 'habarico'
14
+ ```
15
+
16
+ ```bash
17
+ bundle install
18
+ ```
19
+
20
+ Then configure the engine in `config/initializers/habarico.rb`:
21
+
22
+ ```ruby
23
+ Habarico.setup do |config|
24
+ config.resources = [{ admin: [:products, :orders] }]
25
+ config.routing_url_prefix = ENV.fetch('URL_PREFIX') { '' }
26
+ config.routing_scope = 'apps'
27
+ config.currency = 'CZK'
28
+ end
29
+ ```
30
+
31
+ ## Quick start
32
+
33
+ A resource is a controller that includes the concern and describes itself through the DSL:
34
+
35
+ ```ruby
36
+ class Apps::Admin::ProductsController < ApplicationController
37
+ include Habarico::Controller
38
+
39
+ model Product
40
+ default_sorting 'created_at:desc'
41
+
42
+ can_read true
43
+ can_create { |c| c.policy.create? }
44
+ can_update { |c| c.policy.update? }
45
+
46
+ fields [:id, :name, :sku, :status, :category, :price, :stock, :created_at]
47
+ read_only_fields [:id, :created_at]
48
+ filters [:name, :status, :category]
49
+ sorting_fields [:name, :price, :created_at]
50
+
51
+ views [:list, :show, :create, :edit]
52
+ actions [:show, :create, :edit, :delete]
53
+ end
54
+ ```
55
+
56
+ Routes are drawn from the configured resources — `config/routes.rb` only calls
57
+ `Habarico::RoutingService.instance.draw_routes`.
58
+
59
+ ## Documentation
60
+
61
+ Full documentation is at **[docs.habarico.com/ruby](https://docs.habarico.com/ruby/intro)** — this
62
+ file is only a quick start.
63
+
64
+ | Section | What it covers |
65
+ | --- | --- |
66
+ | [Installation](https://docs.habarico.com/ruby/installation) and [configuration](https://docs.habarico.com/ruby/configuration) | The initializer and its options |
67
+ | [Basic usage](https://docs.habarico.com/ruby/basic-usage/) | Controllers, permissions, data loading, views, global search, aggregation, response field selection |
68
+ | [Schema & field customization](https://docs.habarico.com/ruby/schema-and-field-customization/) | Shaping the list, detail and form views, custom actions, box types |
69
+ | [Field types](https://docs.habarico.com/ruby/field-types) | The types a field can take and how they are inferred |
70
+ | [Filtering and searching](https://docs.habarico.com/ruby/filtering-and-searching) | Filters, sorting and fulltext search |
71
+ | [Change history](https://docs.habarico.com/ruby/change-history-paper-trail) | PaperTrail versions surfaced in the admin |
72
+ | [Cross-service references](https://docs.habarico.com/ruby/cross-service-references) | Fields pointing at another service's records |
73
+ | [User preferences](https://docs.habarico.com/ruby/user-preferences) | The per-user preference store the frontend syncs to |
74
+ | [Complete example](https://docs.habarico.com/ruby/complete-example) | One resource wired up end to end |
75
+
76
+ The frontend consuming these schemas is documented at
77
+ [docs.habarico.com/node](https://docs.habarico.com/node/intro), and the contract between them is
78
+ the [API reference](https://docs.habarico.com/api).
79
+
80
+ ## License
81
+
82
+ [MIT](LICENSE)
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ load "rails/tasks/statistics.rake"
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << "test"
9
+ t.test_files = FileList["test/unit/**/*_test.rb"] +
10
+ FileList["test/integration/**/*_test.rb"] +
11
+ FileList["test/contrib/**/*_test.rb"]
12
+ t.verbose = true
13
+ end
14
+
15
+ task default: :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 7.2.0-beta.5
@@ -0,0 +1,41 @@
1
+ module Habarico
2
+ class ActionSchemaController < ApplicationController
3
+
4
+ def index
5
+ # Path is something like this: /xxx/:resource_name/:action_name/schema
6
+ resource_name = request.path.split('/')[-3]
7
+ action_name = request.path.split('/')[-2]
8
+ raise Eluvia::Errors::BadRequest.new("Missing resource name in the request path.") unless resource_name
9
+ raise Eluvia::Errors::BadRequest.new("Missing action name in the request path.") unless action_name
10
+
11
+ # Prepare context and generate schema
12
+ context = Habarico::Context.new(
13
+ current_user: current_user,
14
+ target: (JSON.parse(params['_target']) rescue {}).symbolize_keys
15
+ )
16
+ render json: Habarico::SchemaService.instance.get_action_schema(resource_name, action_name, context)
17
+ .as_json
18
+ .deep_compact(compactable: [nil, {}].freeze)
19
+ end
20
+
21
+ def show
22
+ # Path is something like this: /xxx/:resource_name/:id/:action_name/schema
23
+ resource_name = request.path.split('/')[-4]
24
+ action_name = request.path.split('/')[-2]
25
+ raise Eluvia::Errors::BadRequest.new("Missing resource name in the request path.") unless resource_name
26
+ raise Eluvia::Errors::BadRequest.new("Missing record PK in the request path.") unless params[:id]
27
+ raise Eluvia::Errors::BadRequest.new("Missing action name in the request path.") unless action_name
28
+
29
+ # Prepare context and generate schema
30
+ context = Habarico::Context.new(
31
+ current_user: current_user,
32
+ record_pk: params[:id],
33
+ target: (JSON.parse(params['_target']) rescue {}).symbolize_keys
34
+ )
35
+ render json: Habarico::SchemaService.instance.get_action_schema(resource_name, action_name, context)
36
+ .as_json
37
+ .deep_compact(compactable: [nil, {}].freeze)
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ module Habarico
2
+ class ApplicationController < Habarico::Config.base_controller_class.constantize
3
+ include Eluvia::ErrorHandler
4
+ include Habarico::Authenticatable
5
+
6
+ # ***************************************************************************
7
+ # JSON as default format
8
+ # ***************************************************************************
9
+
10
+ before_action do
11
+ request.format = :json if %w[text/html */*].include?(request.format.to_s)
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,105 @@
1
+ module Habarico
2
+ module Contrib
3
+ module Preferences
4
+ # REST endpoints for the per-user preference store. Auth (`authenticate(['public'])`)
5
+ # and `current_user` come from Habarico::ApplicationController. Behavior mirrors the
6
+ # Python UserPreferenceViewSet 1:1 (status codes match doc/openapi.yaml: 200 / 204 /
7
+ # 404 unregistered-or-empty / 422 schema-invalid / 400 malformed body).
8
+ class UserPreferencesController < Habarico::ApplicationController
9
+ # GET user-preferences
10
+ def index
11
+ items = Habarico::Contrib::Preferences.get_values(user_scope).map { |resolved| Serializer.item(resolved) }
12
+ render json: items
13
+ end
14
+
15
+ # GET user-preferences/:key
16
+ def show
17
+ resolved = Habarico::Contrib::Preferences.get_value(user_scope, params[:key])
18
+ raise Eluvia::Errors::NotFound.new(not_found_message) if resolved.nil?
19
+
20
+ render json: Serializer.item(resolved)
21
+ rescue Habarico::Contrib::Preferences::PreferenceNotRegistered
22
+ raise Eluvia::Errors::NotFound.new(not_found_message)
23
+ end
24
+
25
+ # PUT user-preferences/:key
26
+ def update
27
+ resolved = Habarico::Contrib::Preferences.set_value(user_scope, params[:key], value_param)
28
+ render json: Serializer.item(resolved)
29
+ rescue Habarico::Contrib::Preferences::PreferenceNotRegistered
30
+ raise Eluvia::Errors::NotFound.new(not_found_message)
31
+ rescue Habarico::Contrib::Preferences::PreferenceValueTooLarge
32
+ raise Eluvia::Errors::UnprocessableEntity.new({ "value" => value_too_large_message })
33
+ rescue Habarico::Contrib::Preferences::TooManyPreferences
34
+ raise Eluvia::Errors::UnprocessableEntity.new({ "value" => too_many_preferences_message })
35
+ rescue Habarico::Contrib::Preferences::PreferenceValidationError
36
+ raise Eluvia::Errors::UnprocessableEntity.new({ "value" => invalid_value_message })
37
+ end
38
+
39
+ # DELETE user-preferences/:key
40
+ def destroy
41
+ Habarico::Contrib::Preferences.delete_value(user_scope, params[:key])
42
+ head :no_content
43
+ rescue Habarico::Contrib::Preferences::PreferenceNotRegistered
44
+ raise Eluvia::Errors::NotFound.new(not_found_message)
45
+ end
46
+
47
+ # DELETE user-preferences
48
+ def destroy_all
49
+ Habarico::Contrib::Preferences.delete_values(user_scope)
50
+ head :no_content
51
+ end
52
+
53
+ private
54
+
55
+ # The auth token subject, stored as a scalar (no DB foreign key).
56
+ def user_scope
57
+ current_user.id.to_s
58
+ end
59
+
60
+ # The raw request body IS the preference value (any JSON type: object, array or scalar),
61
+ # mirroring DRF's `request.data`. A malformed body is a 400 (matches openapi BadRequest).
62
+ def value_param
63
+ raw = request.raw_post
64
+ ensure_size_allowed!(raw)
65
+ return nil if raw.nil? || raw.empty?
66
+
67
+ JSON.parse(raw)
68
+ rescue JSON::ParserError
69
+ raise Eluvia::Errors::BadRequest.new("Malformed request body.")
70
+ end
71
+
72
+ # Refuses an oversized body before it is parsed - the key is in the URL, so its limit is
73
+ # known without looking at the body at all. The registry checks the parsed value as well;
74
+ # this only saves the parse of a body already known to be too big. Raises
75
+ # PreferenceNotRegistered for an unknown key, which `update` turns into the usual 404.
76
+ def ensure_size_allowed!(raw)
77
+ limit = Habarico::Contrib::Preferences.max_bytes_for(params[:key])
78
+ return if limit.nil? || raw.nil?
79
+
80
+ size = raw.bytesize
81
+ return if size <= limit
82
+
83
+ raise Habarico::Contrib::Preferences::PreferenceValueTooLarge.new(params[:key], limit, size)
84
+ end
85
+
86
+ def not_found_message
87
+ I18n.t("habarico.contrib.preferences.not_found", default: "Preference not found.")
88
+ end
89
+
90
+ def invalid_value_message
91
+ I18n.t("habarico.contrib.preferences.invalid_value", default: "Invalid value for preference.")
92
+ end
93
+
94
+ def value_too_large_message
95
+ I18n.t("habarico.contrib.preferences.value_too_large", default: "Preference value is too large.")
96
+ end
97
+
98
+ def too_many_preferences_message
99
+ I18n.t("habarico.contrib.preferences.too_many_preferences",
100
+ default: "Too many preferences are stored for this user.")
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,11 @@
1
+ module Habarico
2
+ class GlobalSchemaController < ApplicationController
3
+
4
+ def index
5
+ # Prepare context and generate schema
6
+ context = Habarico::Context.new(current_user: current_user)
7
+ render json: Habarico::SchemaService.instance.get_global_schema(context).as_json.deep_compact(compactable: [nil, {}].freeze)
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ module Habarico
2
+ class LocalSchemaController < ApplicationController
3
+
4
+ def index
5
+ # Path is something like this: /xxx/:resource_name/schema
6
+ resource_name = request.path.split('/')[-2]
7
+ raise Eluvia::Errors::BadRequest.new("Missing resource name in the request path.") unless resource_name
8
+
9
+ # Prepare context and generate schema
10
+ context = Habarico::Context.new(
11
+ current_user: current_user,
12
+ target: (JSON.parse(params['_target']) rescue {}).symbolize_keys,
13
+ source: (JSON.parse(params['_source']) rescue {}).symbolize_keys
14
+ )
15
+ render json: Habarico::SchemaService.instance.get_local_schema(resource_name, context).as_json.deep_compact(compactable: [nil, {}].freeze)
16
+ end
17
+
18
+ def show
19
+ # Path is something like this: /xxx/:resource_name/:id/schema
20
+ resource_name = request.path.split('/')[-3]
21
+ raise Eluvia::Errors::BadRequest.new("Missing resource name in the request path.") unless resource_name
22
+ raise Eluvia::Errors::BadRequest.new("Missing record PK in the request path.") unless params[:id]
23
+
24
+ # Prepare context and generate schema
25
+ context = Habarico::Context.new(
26
+ current_user: current_user,
27
+ record_pk: params[:id],
28
+ target: (JSON.parse(params['_target']) rescue {}).symbolize_keys,
29
+ source: (JSON.parse(params['_source']) rescue {}).symbolize_keys
30
+ )
31
+ render json: Habarico::SchemaService.instance.get_local_schema(resource_name, context).as_json.deep_compact(compactable: [nil, {}].freeze)
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,4 @@
1
+ module Habarico
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module Habarico
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Habarico</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= yield :head %>
9
+
10
+ <%= stylesheet_link_tag "habarico/application", media: "all" %>
11
+ </head>
12
+ <body>
13
+
14
+ <%= yield %>
15
+
16
+ </body>
17
+ </html>
@@ -0,0 +1,39 @@
1
+ cs:
2
+ # Default labels for Habarico's standard actions. Host apps override any key in
3
+ # their own config/locales (per-resource via `actions.<resource_path>.<action>`).
4
+ actions:
5
+ common:
6
+ show: "Detail"
7
+ create: "Vytvořit"
8
+ edit: "Upravit"
9
+ delete: "Smazat"
10
+ save: "Uložit"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "Opravdu chcete smazat záznam?"
17
+ message: "Tato akce způsobí ztrátu dat, které již nebude možné obnovit."
18
+
19
+ # Default label for the generic full-text search filter (search_filter_schema_generator.rb).
20
+ # Override per model via `activerecord.attributes.<model>.search`.
21
+ filters:
22
+ common:
23
+ search: "Hledat"
24
+
25
+ # Human-readable boolean labels used by the search highlighter (search_highlighter.rb) when a
26
+ # matched search field is a boolean column.
27
+ search:
28
+ "yes": "Ano"
29
+ "no": "Ne"
30
+
31
+ # Validation error messages for the order_by and filter query params (controller.rb). The
32
+ # `order_by` notation itself is validated by eluvia-base, which ships its own translations
33
+ # under `eluvia.errors.ordering` (HAB-915).
34
+ habarico:
35
+ errors:
36
+ order_by:
37
+ unknown_field: "Neznámý název pole."
38
+ filter:
39
+ unknown_term: "Neznámý filtrovací termín."
@@ -0,0 +1,39 @@
1
+ de:
2
+ # Default labels for Habarico's standard actions. Host apps override any key in
3
+ # their own config/locales (per-resource via `actions.<resource_path>.<action>`).
4
+ actions:
5
+ common:
6
+ show: "Detail"
7
+ create: "Erstellen"
8
+ edit: "Bearbeiten"
9
+ delete: "Löschen"
10
+ save: "Speichern"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "Sind Sie sicher, dass Sie diesen Datensatz löschen möchten?"
17
+ message: "Diese Aktion führt zu einem Datenverlust, der nicht rückgängig gemacht werden kann."
18
+
19
+ # Default label for the generic full-text search filter (search_filter_schema_generator.rb).
20
+ # Override per model via `activerecord.attributes.<model>.search`.
21
+ filters:
22
+ common:
23
+ search: "Suchen"
24
+
25
+ # Human-readable boolean labels used by the search highlighter (search_highlighter.rb) when a
26
+ # matched search field is a boolean column.
27
+ search:
28
+ "yes": "Ja"
29
+ "no": "Nein"
30
+
31
+ # Validation error messages for the order_by and filter query params (controller.rb). The
32
+ # `order_by` notation itself is validated by eluvia-base, which ships its own translations
33
+ # under `eluvia.errors.ordering` (HAB-915).
34
+ habarico:
35
+ errors:
36
+ order_by:
37
+ unknown_field: "Unbekannter Feldname."
38
+ filter:
39
+ unknown_term: "Unbekannter Filterbegriff."
@@ -0,0 +1,39 @@
1
+ en:
2
+ # Default labels for Habarico's standard actions. Host apps override any key in
3
+ # their own config/locales (per-resource via `actions.<resource_path>.<action>`).
4
+ actions:
5
+ common:
6
+ show: "Detail"
7
+ create: "Create"
8
+ edit: "Edit"
9
+ delete: "Delete"
10
+ save: "Save"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "Are you sure you want to delete this record?"
17
+ message: "This action will cause data loss that cannot be undone."
18
+
19
+ # Default label for the generic full-text search filter (search_filter_schema_generator.rb).
20
+ # Override per model via `activerecord.attributes.<model>.search`.
21
+ filters:
22
+ common:
23
+ search: "Search"
24
+
25
+ # Human-readable boolean labels used by the search highlighter (search_highlighter.rb) when a
26
+ # matched search field is a boolean column.
27
+ search:
28
+ "yes": "Yes"
29
+ "no": "No"
30
+
31
+ # Validation error messages for the order_by and filter query params (controller.rb). The
32
+ # `order_by` notation itself is validated by eluvia-base, which ships its own translations
33
+ # under `eluvia.errors.ordering` (HAB-915).
34
+ habarico:
35
+ errors:
36
+ order_by:
37
+ unknown_field: "Unknown field name."
38
+ filter:
39
+ unknown_term: "Unknown filter term."
@@ -0,0 +1,39 @@
1
+ es:
2
+ # Default labels for Habarico's standard actions. Host apps override any key in
3
+ # their own config/locales (per-resource via `actions.<resource_path>.<action>`).
4
+ actions:
5
+ common:
6
+ show: "Detalle"
7
+ create: "Crear"
8
+ edit: "Editar"
9
+ delete: "Eliminar"
10
+ save: "Guardar"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "¿Está seguro de que desea eliminar este registro?"
17
+ message: "Esta acción provocará una pérdida de datos que no se podrá deshacer."
18
+
19
+ # Default label for the generic full-text search filter (search_filter_schema_generator.rb).
20
+ # Override per model via `activerecord.attributes.<model>.search`.
21
+ filters:
22
+ common:
23
+ search: "Buscar"
24
+
25
+ # Human-readable boolean labels used by the search highlighter (search_highlighter.rb) when a
26
+ # matched search field is a boolean column.
27
+ search:
28
+ "yes": "Sí"
29
+ "no": "No"
30
+
31
+ # Validation error messages for the order_by and filter query params (controller.rb). The
32
+ # `order_by` notation itself is validated by eluvia-base, which ships its own translations
33
+ # under `eluvia.errors.ordering` (HAB-915).
34
+ habarico:
35
+ errors:
36
+ order_by:
37
+ unknown_field: "Nombre de campo desconocido."
38
+ filter:
39
+ unknown_term: "Término de filtro desconocido."
@@ -0,0 +1,39 @@
1
+ fr:
2
+ # Default labels for Habarico's standard actions. Host apps override any key in
3
+ # their own config/locales (per-resource via `actions.<resource_path>.<action>`).
4
+ actions:
5
+ common:
6
+ show: "Détail"
7
+ create: "Créer"
8
+ edit: "Modifier"
9
+ delete: "Supprimer"
10
+ save: "Enregistrer"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "Êtes-vous sûr de vouloir supprimer cet enregistrement ?"
17
+ message: "Cette action entraînera une perte de données irréversible."
18
+
19
+ # Default label for the generic full-text search filter (search_filter_schema_generator.rb).
20
+ # Override per model via `activerecord.attributes.<model>.search`.
21
+ filters:
22
+ common:
23
+ search: "Rechercher"
24
+
25
+ # Human-readable boolean labels used by the search highlighter (search_highlighter.rb) when a
26
+ # matched search field is a boolean column.
27
+ search:
28
+ "yes": "Oui"
29
+ "no": "Non"
30
+
31
+ # Validation error messages for the order_by and filter query params (controller.rb). The
32
+ # `order_by` notation itself is validated by eluvia-base, which ships its own translations
33
+ # under `eluvia.errors.ordering` (HAB-915).
34
+ habarico:
35
+ errors:
36
+ order_by:
37
+ unknown_field: "Nom de champ inconnu."
38
+ filter:
39
+ unknown_term: "Terme de filtre inconnu."
@@ -0,0 +1,39 @@
1
+ it:
2
+ # Default labels for Habarico's standard actions. Host apps override any key in
3
+ # their own config/locales (per-resource via `actions.<resource_path>.<action>`).
4
+ actions:
5
+ common:
6
+ show: "Dettaglio"
7
+ create: "Crea"
8
+ edit: "Modifica"
9
+ delete: "Elimina"
10
+ save: "Salva"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "Sei sicuro di voler eliminare questo record?"
17
+ message: "Questa azione causerà una perdita di dati che non potrà essere annullata."
18
+
19
+ # Default label for the generic full-text search filter (search_filter_schema_generator.rb).
20
+ # Override per model via `activerecord.attributes.<model>.search`.
21
+ filters:
22
+ common:
23
+ search: "Cerca"
24
+
25
+ # Human-readable boolean labels used by the search highlighter (search_highlighter.rb) when a
26
+ # matched search field is a boolean column.
27
+ search:
28
+ "yes": "Sì"
29
+ "no": "No"
30
+
31
+ # Validation error messages for the order_by and filter query params (controller.rb). The
32
+ # `order_by` notation itself is validated by eluvia-base, which ships its own translations
33
+ # under `eluvia.errors.ordering` (HAB-915).
34
+ habarico:
35
+ errors:
36
+ order_by:
37
+ unknown_field: "Nome campo sconosciuto."
38
+ filter:
39
+ unknown_term: "Termine di filtro sconosciuto."
@@ -0,0 +1,39 @@
1
+ ja:
2
+ # Default labels for Habarico's standard actions. Host apps override any key in
3
+ # their own config/locales (per-resource via `actions.<resource_path>.<action>`).
4
+ actions:
5
+ common:
6
+ show: "詳細"
7
+ create: "作成"
8
+ edit: "編集"
9
+ delete: "削除"
10
+ save: "保存"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "このレコードを削除してもよろしいですか?"
17
+ message: "この操作を行うと、元に戻せないデータ損失が発生します。"
18
+
19
+ # Default label for the generic full-text search filter (search_filter_schema_generator.rb).
20
+ # Override per model via `activerecord.attributes.<model>.search`.
21
+ filters:
22
+ common:
23
+ search: "検索"
24
+
25
+ # Human-readable boolean labels used by the search highlighter (search_highlighter.rb) when a
26
+ # matched search field is a boolean column.
27
+ search:
28
+ "yes": "はい"
29
+ "no": "いいえ"
30
+
31
+ # Validation error messages for the order_by and filter query params (controller.rb). The
32
+ # `order_by` notation itself is validated by eluvia-base, which ships its own translations
33
+ # under `eluvia.errors.ordering` (HAB-915).
34
+ habarico:
35
+ errors:
36
+ order_by:
37
+ unknown_field: "不明なフィールド名です。"
38
+ filter:
39
+ unknown_term: "不明なフィルター項目です。"