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
@@ -0,0 +1,39 @@
1
+ nl:
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: "Aanmaken"
8
+ edit: "Bewerken"
9
+ delete: "Verwijderen"
10
+ save: "Opslaan"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "Weet u zeker dat u dit record wilt verwijderen?"
17
+ message: "Deze actie veroorzaakt onherstelbaar gegevensverlies."
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: "Zoeken"
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": "Nee"
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: "Onbekende veldnaam."
38
+ filter:
39
+ unknown_term: "Onbekende filterterm."
@@ -0,0 +1,39 @@
1
+ pl:
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: "Szczegóły"
7
+ create: "Utwórz"
8
+ edit: "Edytuj"
9
+ delete: "Usuń"
10
+ save: "Zapisz"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "Czy na pewno chcesz usunąć ten rekord?"
17
+ message: "Ta akcja spowoduje utratę danych, których nie będzie można odzyskać."
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: "Szukaj"
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": "Tak"
29
+ "no": "Nie"
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: "Nieznana nazwa pola."
38
+ filter:
39
+ unknown_term: "Nieznany termin filtra."
@@ -0,0 +1,39 @@
1
+ pt:
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: "Detalhe"
7
+ create: "Criar"
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: "Tem a certeza de que pretende eliminar este registo?"
17
+ message: "Esta ação irá causar uma perda de dados que não pode ser desfeita."
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: "Pesquisar"
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": "Sim"
29
+ "no": "Não"
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 de campo desconhecido."
38
+ filter:
39
+ unknown_term: "Termo de filtro desconhecido."
@@ -0,0 +1,39 @@
1
+ ro:
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: "Detaliu"
7
+ create: "Creare"
8
+ edit: "Editare"
9
+ delete: "Ștergere"
10
+ save: "Salvare"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "Sigur doriți să ștergeți această înregistrare?"
17
+ message: "Această acțiune va provoca o pierdere de date care nu poate fi anulată."
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: "Căutare"
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": "Da"
29
+ "no": "Nu"
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: "Nume de câmp necunoscut."
38
+ filter:
39
+ unknown_term: "Termen de filtrare necunoscut."
@@ -0,0 +1,39 @@
1
+ sk:
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: "Vytvoriť"
8
+ edit: "Upraviť"
9
+ delete: "Zmazať"
10
+ save: "Uložiť"
11
+
12
+ # Default confirmation dialog for the standard delete action (delete_action.rb).
13
+ confirmations:
14
+ common:
15
+ delete:
16
+ title: "Naozaj chcete zmazať tento záznam?"
17
+ message: "Táto akcia spôsobí stratu dát, ktoré už nebude možné obnoviť."
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: "Hľadať"
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": "Áno"
29
+ "no": "Nie"
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ámy názov poľa."
38
+ filter:
39
+ unknown_term: "Neznámy filtrovací výraz."
@@ -0,0 +1,39 @@
1
+ uk:
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: "Невідомий термін фільтра."
data/config/routes.rb ADDED
@@ -0,0 +1 @@
1
+ Habarico::RoutingService.instance.draw_routes
@@ -0,0 +1,27 @@
1
+ require "rails/generators"
2
+ require "rails/generators/migration"
3
+
4
+ module Habarico
5
+ module Preferences
6
+ module Generators
7
+ # Copies the habarico_user_preferences migration into the host app:
8
+ # rails g habarico:preferences:install
9
+ class InstallGenerator < Rails::Generators::Base
10
+ include Rails::Generators::Migration
11
+
12
+ source_root File.expand_path("templates", __dir__)
13
+
14
+ def self.next_migration_number(dirname)
15
+ ActiveRecord::Generators::Base.next_migration_number(dirname)
16
+ end
17
+
18
+ def create_migration_file
19
+ migration_template(
20
+ "create_habarico_user_preferences.rb.tt",
21
+ "db/migrate/create_habarico_user_preferences.rb"
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ class CreateHabaricoUserPreferences < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :habarico_user_preferences, id: :uuid do |t|
4
+ # Auth token subject (current_user.id). Stored as a scalar string - no FK, because the
5
+ # user may live in another service. Add a FK here yourself if your app has a local users table.
6
+ t.string :user_id, null: false
7
+ t.string :key, null: false
8
+ t.jsonb :value, null: false
9
+ t.datetime :updated_at, null: false
10
+ end
11
+
12
+ add_index :habarico_user_preferences, %i[user_id key], unique: true,
13
+ name: "idx_habarico_user_prefs_user_key"
14
+ end
15
+ end
@@ -0,0 +1,68 @@
1
+ module Habarico
2
+ module ActiveModel
3
+ module References
4
+ extend ::ActiveSupport::Concern
5
+ include Eluvia::ActiveModel::Attributes
6
+ include Eluvia::ActiveModel::ArrayAttribute
7
+
8
+ class_methods do
9
+
10
+ def _references
11
+ @references ||= {}
12
+ end
13
+
14
+ def references(type: nil)
15
+ result = _references.values
16
+ return result unless type
17
+ result.select { |r| r[:type] == type }
18
+ end
19
+
20
+ def reference_names(type: nil)
21
+ references(type: type).map { |r| r[:reference_name] }
22
+ end
23
+
24
+ def has_reference?(reference_name, type: nil)
25
+ find_reference(reference_name, type: type).present?
26
+ end
27
+
28
+ def find_reference(reference_name, type: nil)
29
+ result = _references.fetch(reference_name.to_sym, nil)
30
+ return result unless type
31
+ if result.nil? || result[:type] != type
32
+ nil
33
+ else
34
+ result
35
+ end
36
+ end
37
+
38
+ def has_one_reference(reference_name, class_name)
39
+ reference_name = reference_name.to_sym
40
+
41
+ string_attr reference_name # -> we need some underlying attribute to hold the data
42
+
43
+ _references[reference_name] = {
44
+ reference_name: reference_name,
45
+ type: :has_one,
46
+ class_name: class_name
47
+ }
48
+ end
49
+
50
+ def has_many_reference(reference_name, class_name)
51
+ reference_name = reference_name.to_sym
52
+
53
+ any_attr reference_name # -> we need some underlying attribute to hold the data
54
+ array_attr reference_name, type: :string # -> now we declare it as an array of strings
55
+ has_one_reference :"#{reference_name}__items", class_name # -> we need to hold metadata about the contained items
56
+
57
+ _references[reference_name] = {
58
+ reference_name: reference_name,
59
+ type: :has_many,
60
+ class_name: class_name
61
+ }
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,31 @@
1
+ module Habarico
2
+ module Authenticatable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ before_action :run_authentication
7
+ end
8
+
9
+ private
10
+
11
+ # Calls `Habarico::Config.authenticate_method` (`:authenticate_request` by default) on the
12
+ # controller. Deliberately does NOT define a fallback `authenticate_request` method itself:
13
+ # since this module is `include`d directly into `Habarico::Controller`/`Habarico::ApplicationController`,
14
+ # any method defined here would sit ahead of your ApplicationController in the ancestor chain
15
+ # (`include`d modules resolve before the superclass) and would silently shadow your override.
16
+ # Checking `respond_to?` first, instead of defining a raising default, avoids that.
17
+ #
18
+ # See https://docs.habarico.com/ruby/authentication for how to implement `authenticate_request`
19
+ # (or configure `config.authenticate_method`) in your own ApplicationController.
20
+ def run_authentication
21
+ method_name = Habarico::Config.authenticate_method
22
+ unless respond_to?(method_name, true)
23
+ raise NotImplementedError, "Habarico authentication is not configured: configure " \
24
+ "config.authenticate_method or implement ##{method_name} (and #current_user) in your " \
25
+ 'ApplicationController.'
26
+ end
27
+ send(method_name)
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,71 @@
1
+ module Habarico
2
+ module Config
3
+ mattr_accessor :resources
4
+ @@resources = []
5
+
6
+ mattr_accessor :routing_url_prefix
7
+ @@routing_url_prefix = ''
8
+
9
+ mattr_accessor :routing_scope
10
+ @@routing_scope = nil
11
+
12
+ mattr_accessor :currency
13
+ @@currency = 'CZK'
14
+
15
+ # Enables diacritics-insensitive (unaccent) fulltext search matching and highlighting by
16
+ # default. Mirrors the Python `SEARCH_UNACCENT_ENABLED` setting. Off by default; requires the
17
+ # PostgreSQL `unaccent` extension when the matcher relies on it.
18
+ mattr_accessor :search_unaccent_enabled
19
+ @@search_unaccent_enabled = false
20
+
21
+ # Parent class for Habarico's own engine controllers (schema/search endpoints). Defaults to a
22
+ # plain API controller with no authentication. Set this to your app's own `'ApplicationController'`
23
+ # to inherit its authentication before_actions instead of implementing `authenticate_method`
24
+ # again for the engine controllers.
25
+ mattr_accessor :base_controller_class
26
+ @@base_controller_class = 'ActionController::API'
27
+
28
+ # Page size of a list endpoint when the request sends no `limit`. `nil` (the default) leaves
29
+ # the decision to `set_pagination` in eluvia-base, which paginates by 20. A resource overrides
30
+ # this with `default_page_limit` in its DSL. Mirrors the Python `DEFAULT_PAGE_LIMIT` key of the
31
+ # `ADMIN_REST_FRAMEWORK` settings block (HAB-946).
32
+ mattr_accessor :default_page_limit
33
+ @@default_page_limit = nil
34
+
35
+ # Upper bound for the `limit` query parameter of a list endpoint; above it the request is
36
+ # refused with 422. `nil` (the default) leaves the decision to
37
+ # `Eluvia::Base::Config.max_page_limit` (1000), which is also the only place the bound can be
38
+ # removed altogether - a resource declares a number or nothing at all. Mirrors the Python
39
+ # `MAX_PAGE_LIMIT` key (HAB-946).
40
+ mattr_accessor :max_page_limit
41
+ @@max_page_limit = nil
42
+
43
+ # Class building the `meta.highlights` payload of a search-filtered list response, as a class
44
+ # or its name. `nil` by default - match highlighting is a paid feature, so the free gem ships
45
+ # no highlighter and simply omits the key. `habarico-enterprise` points this at its
46
+ # `SearchHighlighter` when the gem is loaded (HAB-812).
47
+ #
48
+ # Per-resource search (`search_fields`, `Search::SearchMatcher`) is free and unaffected: the
49
+ # list stays filtered, it just carries no highlighted snippets.
50
+ mattr_accessor :search_highlighter_class
51
+ @@search_highlighter_class = nil
52
+
53
+ # Name of the method Habarico calls (via `send`) as its authentication before_action, on both
54
+ # Habarico::Controller and Habarico::ApplicationController. Point this at an existing no-argument
55
+ # auth method on your ApplicationController (e.g. `:authenticate_user!`) to reuse it directly. If
56
+ # your auth method needs arguments (e.g. eluvia-auth's `authenticate(['public'])`), define a
57
+ # one-line wrapper method instead and point this at that.
58
+ mattr_accessor :authenticate_method
59
+ @@authenticate_method = :authenticate_request
60
+
61
+ # Resolves `search_highlighter_class` to a class, or nil when no highlighter is registered.
62
+ # Accepts a class or a string so the setting can be written in an initializer before the
63
+ # constant is loaded, matching how `base_controller_class` is handled.
64
+ def self.search_highlighter_class!
65
+ value = search_highlighter_class
66
+ return nil if value.nil?
67
+
68
+ value.is_a?(String) ? value.constantize : value
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,126 @@
1
+ module Habarico
2
+ class Context
3
+ include ::ActiveModel::Model
4
+
5
+ # Definition of the resource on which the action is performed
6
+ attr_accessor :definition
7
+
8
+ # Under which user is the action performed
9
+ attr_accessor :current_user
10
+
11
+ # On which record primary key is the action performed
12
+ attr_accessor :record_pk
13
+
14
+ # On which record is the action performed
15
+ attr_writer :record
16
+
17
+ # Lazy load the record
18
+ def record
19
+ @record ||= if self.record_pk
20
+ self.definition.model.find_by(self.definition.model.primary_key => self.record_pk)
21
+ end
22
+ end
23
+
24
+ # In what target is the action performed (e.g. ID of the parent record)
25
+ attr_accessor :target
26
+
27
+ # From which source the action/schema is requested (e.g. `{ "prototype/employees" => 7 }`).
28
+ # Used by context-aware schemas to resolve the originating resource/record.
29
+ attr_accessor :source
30
+
31
+ # *************************************************************************
32
+ # Authorization
33
+ # *************************************************************************
34
+
35
+ STANDARD_PERMISSIONS = %i[read create update delete].freeze
36
+
37
+ # Chooses the appropriate permission check depending on whether a record is
38
+ # available in context.
39
+ #
40
+ # When a record_pk is present (e.g. the detail schema endpoint) the full
41
+ # can_with_record? check is used so that callable permissions are evaluated
42
+ # against the actual record. When no record is present (e.g. the global or
43
+ # list schema endpoint) can_wo_record? is used instead.
44
+ def can?(permission)
45
+ record_pk.present? ? can_with_record?(permission) : can_wo_record?(permission)
46
+ end
47
+
48
+ def policy
49
+ @policy ||= if self.current_user && self.record
50
+ Pundit.policy(self.current_user, self.record)
51
+ elsif self.current_user
52
+ Pundit.policy(self.current_user, self.definition.model)
53
+ end
54
+ end
55
+
56
+ # *************************************************************************
57
+ # Reset
58
+ # *************************************************************************
59
+
60
+ def reset
61
+ @policy = nil
62
+ @record = nil
63
+ end
64
+
65
+ private
66
+
67
+ def can_with_record?(permission)
68
+ permission = :read if permission.blank?
69
+ permission = permission.to_sym
70
+ if STANDARD_PERMISSIONS.include?(permission)
71
+ value = definition.send("can_#{permission}")
72
+ if value.respond_to?(:call)
73
+ !!value.call(self)
74
+ else
75
+ !!value
76
+ end
77
+ else
78
+ value = definition.send("can")
79
+ if value.respond_to?(:call)
80
+ !!value.call(permission, self)
81
+ else
82
+ false
83
+ end
84
+ end
85
+ end
86
+
87
+ # Permission check used when generating the global or list schema, where no
88
+ # specific record is in context.
89
+ #
90
+ # Static booleans are evaluated as-is — false means the action is never
91
+ # available on this resource and should not appear in the schema at all.
92
+ #
93
+ # Callables are invoked with a nil record. Consumers commonly express
94
+ # role-based restrictions as callables that depend only on current_user
95
+ # (e.g. `can_read { |c| c.current_user.has_role?(...) }`), and these must be
96
+ # honoured already at the global/list schema level so a restricted role does
97
+ # not receive the whole resource. Pundit-based callables also resolve
98
+ # without a record — Context#policy falls back to a class-level policy.
99
+ #
100
+ # Callables that genuinely read the concrete record simply see nil here; the
101
+ # action may then be omitted from the list schema and its real, per-record
102
+ # visibility is determined later by ObjectResourceSchemaGenerator (which
103
+ # calls can? with a real record). The controller enforces the actual
104
+ # permission on every mutating request regardless of what the schema says.
105
+ def can_wo_record?(permission)
106
+ permission = :read if permission.blank?
107
+ permission = permission.to_sym
108
+ if STANDARD_PERMISSIONS.include?(permission)
109
+ value = definition.send("can_#{permission}")
110
+ if value.respond_to?(:call)
111
+ !!value.call(self)
112
+ else
113
+ !!value
114
+ end
115
+ else
116
+ value = definition.send("can")
117
+ if value.respond_to?(:call)
118
+ !!value.call(permission, self)
119
+ else
120
+ false
121
+ end
122
+ end
123
+ end
124
+
125
+ end
126
+ end
@@ -0,0 +1,40 @@
1
+ module Habarico
2
+ module Contrib
3
+ module Preferences
4
+ # Exact base preference keys -> schema (mirrors Python base.py BASE_PREFERENCES).
5
+ BASE_PREFERENCES = {
6
+ "theme" => Schemas::THEME,
7
+ "locale" => Schemas::LOCALE,
8
+ "preferences.dashboard" => Schemas::DASHBOARD,
9
+ "preferences.layout.app.pageWidth" => Schemas::APP_PAGE_WIDTH,
10
+ "preferences.layout.app.contrastMode" => Schemas::CONTRAST_MODE,
11
+ "preferences.layout.app.stripedRows" => Schemas::STRIPED_ROWS,
12
+ "preferences.layout.app.density" => Schemas::APP_DENSITY,
13
+ }.freeze
14
+
15
+ # Pattern base keys -> schema (mirrors Python base.py PATTERN_PREFERENCES).
16
+ PATTERN_PREFERENCES = {
17
+ %r{[a-zA-Z][a-zA-Z0-9_./-]*\.savedQueries} => Schemas::SAVED_QUERIES,
18
+ %r{[a-zA-Z][a-zA-Z0-9_./-]*\.columns} => Schemas::COLUMNS,
19
+ %r{[a-zA-Z][a-zA-Z0-9_./-]*\.columnWidths} => Schemas::COLUMN_WIDTHS,
20
+ }.freeze
21
+
22
+ # Registers all base preferences. A default is applied to an exact key only when present
23
+ # in Preferences.defaults; otherwise the key is registered with no default. Pattern keys
24
+ # never carry a built-in default. Mirrors Python register_base_preferences.
25
+ def self.register_base_preferences
26
+ defaults = Preferences.defaults || {}
27
+ BASE_PREFERENCES.each do |key, schema|
28
+ if defaults.key?(key)
29
+ register_preference(key, schema: schema, default: defaults[key])
30
+ else
31
+ register_preference(key, schema: schema)
32
+ end
33
+ end
34
+ PATTERN_PREFERENCES.each do |pattern, schema|
35
+ register_preference_pattern(pattern, schema: schema)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ module Habarico
2
+ module Contrib
3
+ module Preferences
4
+ # Per-key default values for base preferences, mirroring the Python
5
+ # `HABARICO_PREFERENCES["DEFAULTS"]` setting. A base key gets a default only when
6
+ # present here (see base_preferences.rb). Host apps set this in an initializer:
7
+ # Habarico::Contrib::Preferences.defaults = { "theme" => "light" }
8
+ mattr_accessor :defaults, default: {}
9
+
10
+ # Largest serialized size (bytes) one preference value may have. Looked up by the exact
11
+ # key -- or the pattern, as a Regexp or its source string -- a preference was registered
12
+ # under, falling back to "default". `nil` (for one entry or for the whole setting) means
13
+ # no limit. Mirrors the Python `HABARICO_PREFERENCES["MAX_VALUE_BYTES"]` setting.
14
+ #
15
+ # The values below sit an order of magnitude above what the frontend actually writes:
16
+ # 100 datagrid columns are ~2 KB of `columns`/`columnWidths`, a 30-widget dashboard
17
+ # ~19 KB and 20 saved queries ~11 KB at their fullest.
18
+ mattr_accessor :max_value_bytes, default: {
19
+ "default" => 16 * 1024,
20
+ "preferences.dashboard" => 32 * 1024,
21
+ %r{[a-zA-Z][a-zA-Z0-9_./-]*\.savedQueries} => 32 * 1024,
22
+ }
23
+
24
+ # Largest number of preference rows one user may hold, or `nil` for no limit. Checked only
25
+ # when a NEW key is created, so a user already past the limit can still overwrite or shrink
26
+ # what they already have. The cap is needed because the pattern keys match an unbounded set
27
+ # of names, so the per-value limit alone does not bound the per-user total.
28
+ mattr_accessor :max_keys_per_user, default: 2000
29
+ end
30
+ end
31
+ end