agile_rails 0.0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +285 -0
  5. data/Rakefile +39 -0
  6. data/agile_rails.gemspec +36 -0
  7. data/app/assets/fonts/ibm-plex-sans-300.woff2 +0 -0
  8. data/app/assets/fonts/ibm-plex-sans-400.woff2 +0 -0
  9. data/app/assets/fonts/ibm-plex-sans-500.woff2 +0 -0
  10. data/app/assets/fonts/ibm-plex-sans-600.woff2 +0 -0
  11. data/app/assets/fonts/ibm-plex-sans-700.woff2 +0 -0
  12. data/app/assets/fonts/ibm-plex-sans-italic.woff2 +0 -0
  13. data/app/assets/images/32px.png +0 -0
  14. data/app/assets/images/throbber.gif +0 -0
  15. data/app/assets/javascripts/agile/agile.js +1489 -0
  16. data/app/assets/javascripts/agile/jquery-migrate.js +702 -0
  17. data/app/assets/javascripts/agile/jquery.bpopup.js +372 -0
  18. data/app/assets/javascripts/agile/jquery.datetimepicker.js +1353 -0
  19. data/app/assets/javascripts/agile/jstree.min.js +6 -0
  20. data/app/assets/javascripts/agile/select-multiple.js +459 -0
  21. data/app/assets/javascripts/agile/some_scripts.js +33 -0
  22. data/app/assets/javascripts/agile.js +22 -0
  23. data/app/assets/javascripts/agile_application.js +22 -0
  24. data/app/assets/javascripts/agile_editor.js +22 -0
  25. data/app/assets/stylesheets/agile/agile.css +1882 -0
  26. data/app/assets/stylesheets/agile/agile_apps.css +149 -0
  27. data/app/assets/stylesheets/agile/jquery.datetimepicker.css +304 -0
  28. data/app/assets/stylesheets/agile/jstree.css +1107 -0
  29. data/app/assets/stylesheets/agile/select-multiple.css +110 -0
  30. data/app/assets/stylesheets/agile/th-bg.png +0 -0
  31. data/app/assets/stylesheets/agile/theme.css +49 -0
  32. data/app/assets/stylesheets/agile.css +21 -0
  33. data/app/assets/stylesheets/agile_application.css +20 -0
  34. data/app/assets/stylesheets/agile_editor.css +19 -0
  35. data/app/controllers/agile_application_controller.rb +735 -0
  36. data/app/controllers/agile_common_controller.rb +345 -0
  37. data/app/controllers/agile_controller.rb +977 -0
  38. data/app/controllers/agile_main_controller.rb +36 -0
  39. data/app/controls/agile_control.rb +120 -0
  40. data/app/controls/agile_report.rb +364 -0
  41. data/app/controls/ar_category_control.rb +39 -0
  42. data/app/controls/ar_help_control.rb +139 -0
  43. data/app/controls/ar_image_control.rb +180 -0
  44. data/app/controls/ar_journal_control.rb +47 -0
  45. data/app/controls/ar_menu_item_control.rb +55 -0
  46. data/app/controls/ar_page_control.rb +64 -0
  47. data/app/controls/ar_poll_result_control.rb +84 -0
  48. data/app/controls/ar_setup_control.rb +62 -0
  49. data/app/controls/belongs_to_control.rb +61 -0
  50. data/app/controls/browse_models_control.rb +98 -0
  51. data/app/controls/settings_form_control.rb +137 -0
  52. data/app/forms/agile_help.yml +112 -0
  53. data/app/forms/agile_menu.yml +140 -0
  54. data/app/forms/agile_report_defaults.yml +39 -0
  55. data/app/forms/all_options.yml +810 -0
  56. data/app/forms/ar_ad.yml +121 -0
  57. data/app/forms/ar_big_table.yml +60 -0
  58. data/app/forms/ar_big_table_value.yml +52 -0
  59. data/app/forms/ar_browse_fields.yml +35 -0
  60. data/app/forms/ar_browse_models.yml +48 -0
  61. data/app/forms/ar_category.yml +73 -0
  62. data/app/forms/ar_category_as_tree.yml +31 -0
  63. data/app/forms/ar_design.yml +75 -0
  64. data/app/forms/ar_filter.yml +52 -0
  65. data/app/forms/ar_folder_permission.yml +56 -0
  66. data/app/forms/ar_folder_rule.yml +48 -0
  67. data/app/forms/ar_gallery.yml +55 -0
  68. data/app/forms/ar_image.yml +126 -0
  69. data/app/forms/ar_image_search.yml +83 -0
  70. data/app/forms/ar_journal.yml +76 -0
  71. data/app/forms/ar_json_ld.yml +56 -0
  72. data/app/forms/ar_key_value.yml +33 -0
  73. data/app/forms/ar_key_value_store.yml +33 -0
  74. data/app/forms/ar_link.yml +60 -0
  75. data/app/forms/ar_menu.yml +67 -0
  76. data/app/forms/ar_menu_item.yml +141 -0
  77. data/app/forms/ar_page.yml +187 -0
  78. data/app/forms/ar_part.yml +91 -0
  79. data/app/forms/ar_permission.yml +52 -0
  80. data/app/forms/ar_permission_rule.yml +40 -0
  81. data/app/forms/ar_piece.yml +106 -0
  82. data/app/forms/ar_policy.yml +64 -0
  83. data/app/forms/ar_policy_rule.yml +42 -0
  84. data/app/forms/ar_policy_rule_nocms.yml +40 -0
  85. data/app/forms/ar_poll.yml +118 -0
  86. data/app/forms/ar_poll_item.yml +78 -0
  87. data/app/forms/ar_poll_result.yml +88 -0
  88. data/app/forms/ar_poll_result_export.yml +35 -0
  89. data/app/forms/ar_removed_url.yml +41 -0
  90. data/app/forms/ar_role.yml +43 -0
  91. data/app/forms/ar_seo.yml +32 -0
  92. data/app/forms/ar_setup.yml +45 -0
  93. data/app/forms/ar_site.yml +149 -0
  94. data/app/forms/ar_steps_template.yml +51 -0
  95. data/app/forms/ar_user.yml +140 -0
  96. data/app/forms/ar_user_role.yml +57 -0
  97. data/app/forms/help/dc_category_as_tree.en +4 -0
  98. data/app/forms/help/dc_category_as_tree.sl +5 -0
  99. data/app/forms/json_ld_schema.yml +168 -0
  100. data/app/helpers/agile_application_helper.rb +1162 -0
  101. data/app/helpers/agile_category_helper.rb +128 -0
  102. data/app/helpers/agile_common_helper.rb +308 -0
  103. data/app/helpers/agile_edit_helper.rb +645 -0
  104. data/app/helpers/agile_helper.rb +509 -0
  105. data/app/helpers/agile_index_helper.rb +677 -0
  106. data/app/helpers/ar_image_helper.rb +128 -0
  107. data/app/models/agile_form_fields/action.rb +61 -0
  108. data/app/models/agile_form_fields/agile_form_field.rb +322 -0
  109. data/app/models/agile_form_fields/belongs_to.rb +112 -0
  110. data/app/models/agile_form_fields/check_box.rb +73 -0
  111. data/app/models/agile_form_fields/comment.rb +62 -0
  112. data/app/models/agile_form_fields/date_picker.rb +104 -0
  113. data/app/models/agile_form_fields/date_select.rb +68 -0
  114. data/app/models/agile_form_fields/datetime_picker.rb +88 -0
  115. data/app/models/agile_form_fields/datetime_select.rb +73 -0
  116. data/app/models/agile_form_fields/file_field.rb +52 -0
  117. data/app/models/agile_form_fields/file_select.rb +69 -0
  118. data/app/models/agile_form_fields/hidden_field.rb +51 -0
  119. data/app/models/agile_form_fields/html_field.rb +69 -0
  120. data/app/models/agile_form_fields/journal_diff.rb +62 -0
  121. data/app/models/agile_form_fields/link_to.rb +69 -0
  122. data/app/models/agile_form_fields/method.rb +66 -0
  123. data/app/models/agile_form_fields/multitext_autocomplete.rb +215 -0
  124. data/app/models/agile_form_fields/number_field.rb +92 -0
  125. data/app/models/agile_form_fields/password_field.rb +63 -0
  126. data/app/models/agile_form_fields/radio_button.rb +95 -0
  127. data/app/models/agile_form_fields/readonly.rb +77 -0
  128. data/app/models/agile_form_fields/select.rb +281 -0
  129. data/app/models/agile_form_fields/submit_tag.rb +58 -0
  130. data/app/models/agile_form_fields/text_area.rb +61 -0
  131. data/app/models/agile_form_fields/text_autocomplete.rb +171 -0
  132. data/app/models/agile_form_fields/text_field.rb +55 -0
  133. data/app/models/agile_form_fields/text_with_select.rb +94 -0
  134. data/app/models/agile_form_fields/tree_select.rb +170 -0
  135. data/app/models/ar_big_table.rb +82 -0
  136. data/app/models/ar_big_table_value.rb +53 -0
  137. data/app/models/ar_category.rb +109 -0
  138. data/app/models/ar_design.rb +116 -0
  139. data/app/models/ar_filter.rb +200 -0
  140. data/app/models/ar_folder_permission.rb +50 -0
  141. data/app/models/ar_folder_rule.rb +47 -0
  142. data/app/models/ar_gallery.rb +53 -0
  143. data/app/models/ar_image.rb +198 -0
  144. data/app/models/ar_internals.rb +60 -0
  145. data/app/models/ar_journal.rb +46 -0
  146. data/app/models/ar_json_ld.rb +131 -0
  147. data/app/models/ar_key_value_store.rb +128 -0
  148. data/app/models/ar_link.rb +48 -0
  149. data/app/models/ar_memory.rb +172 -0
  150. data/app/models/ar_menu.rb +144 -0
  151. data/app/models/ar_menu_item.rb +106 -0
  152. data/app/models/ar_page.rb +74 -0
  153. data/app/models/ar_part.rb +66 -0
  154. data/app/models/ar_permission.rb +180 -0
  155. data/app/models/ar_permission_rule.rb +65 -0
  156. data/app/models/ar_policy.rb +78 -0
  157. data/app/models/ar_policy_rule.rb +65 -0
  158. data/app/models/ar_poll.rb +74 -0
  159. data/app/models/ar_poll_item.rb +47 -0
  160. data/app/models/ar_poll_result.rb +38 -0
  161. data/app/models/ar_removed_url.rb +42 -0
  162. data/app/models/ar_role.rb +84 -0
  163. data/app/models/ar_setup.rb +115 -0
  164. data/app/models/ar_site.rb +68 -0
  165. data/app/models/ar_temp.rb +150 -0
  166. data/app/models/ar_user.rb +72 -0
  167. data/app/models/ar_user_group.rb +38 -0
  168. data/app/models/ar_user_role.rb +54 -0
  169. data/app/models/ar_visit.rb +41 -0
  170. data/app/models/concerns/ar_page_concern.rb +128 -0
  171. data/app/models/concerns/ar_part_concern.rb +48 -0
  172. data/app/models/concerns/ar_piece_concern.rb +48 -0
  173. data/app/models/concerns/ar_policy_rule_concern.rb +87 -0
  174. data/app/models/concerns/ar_seo_concern.rb +66 -0
  175. data/app/models/concerns/ar_site_concern.rb +103 -0
  176. data/app/models/concerns/ar_user_concern.rb +195 -0
  177. data/app/renderers/agile_common_renderer.rb +93 -0
  178. data/app/renderers/agile_renderer.rb +59 -0
  179. data/app/renderers/ar_ad_renderer.rb +219 -0
  180. data/app/renderers/ar_captcha_renderer.rb +113 -0
  181. data/app/renderers/ar_common_renderer.rb +90 -0
  182. data/app/renderers/ar_gallery_renderer.rb +107 -0
  183. data/app/renderers/ar_menu_renderer.rb +195 -0
  184. data/app/renderers/ar_page_renderer.rb +147 -0
  185. data/app/renderers/ar_part_renderer.rb +235 -0
  186. data/app/renderers/ar_piece_renderer.rb +119 -0
  187. data/app/renderers/ar_poll_renderer.rb +272 -0
  188. data/app/views/agile/_edit_stuff.html.erb +57 -0
  189. data/app/views/agile/_form.html.erb +24 -0
  190. data/app/views/agile/_result.html.erb +28 -0
  191. data/app/views/agile/edit.html.erb +13 -0
  192. data/app/views/agile/error.html.erb +2 -0
  193. data/app/views/agile/index.html.erb +14 -0
  194. data/app/views/agile/login.html.erb +19 -0
  195. data/app/views/agile/new.html.erb +12 -0
  196. data/app/views/agile_common/_help.html.erb +18 -0
  197. data/app/views/agile_common/_iframe_edit.html.erb +2 -0
  198. data/app/views/agile_common/paste_clipboard.html.erb +17 -0
  199. data/app/views/layouts/agile.html.erb +17 -0
  200. data/app/views/layouts/content.html.erb +20 -0
  201. data/app/views/models/dump_models.html.erb +47 -0
  202. data/config/initializers/kaminari_patch.rb +56 -0
  203. data/config/locales/agile_de.yml +138 -0
  204. data/config/locales/agile_en.yml +162 -0
  205. data/config/locales/agile_sl.yml +163 -0
  206. data/config/locales/datetimepicker.yml +19 -0
  207. data/config/locales/de.yml +231 -0
  208. data/config/locales/en.yml +13 -0
  209. data/config/locales/kaminari.yml +26 -0
  210. data/config/locales/models_en.yml +1032 -0
  211. data/config/locales/models_sl.yml +1065 -0
  212. data/config/locales/sl.yml +211 -0
  213. data/db/migrate/20240120160001_add_sessions_table.rb +12 -0
  214. data/db/migrate/20240120160002_ar_big_table.rb +17 -0
  215. data/db/migrate/20240120160003_ar_big_table_value.rb +18 -0
  216. data/db/migrate/20240120160004_ar_category.rb +22 -0
  217. data/db/migrate/20240120160005_ar_design.rb +20 -0
  218. data/db/migrate/20240120160006_ar_filter.rb +17 -0
  219. data/db/migrate/20240120160007_ar_gallery.rb +21 -0
  220. data/db/migrate/20240120160008_ar_journal.rb +19 -0
  221. data/db/migrate/20240120160009_ar_key_value_store.rb +11 -0
  222. data/db/migrate/20240120160010_ar_link.rb +19 -0
  223. data/db/migrate/20240120160011_ar_memory.rb +8 -0
  224. data/db/migrate/20240120160012_ar_menu.rb +21 -0
  225. data/db/migrate/20240120160013_ar_menu_item.rb +28 -0
  226. data/db/migrate/20240120160014_ar_page.rb +50 -0
  227. data/db/migrate/20240120160015_ar_part.rb +33 -0
  228. data/db/migrate/20240120160016_ar_permission.rb +16 -0
  229. data/db/migrate/20240120160017_ar_permission_rule.rb +17 -0
  230. data/db/migrate/20240120160018_ar_piece.rb +28 -0
  231. data/db/migrate/20240120160019_ar_policy.rb +21 -0
  232. data/db/migrate/20240120160020_ar_policy_rule.rb +18 -0
  233. data/db/migrate/20240120160021_ar_poll.rb +27 -0
  234. data/db/migrate/20240120160022_ar_poll_item.rb +23 -0
  235. data/db/migrate/20240120160023_ar_poll_result.rb +14 -0
  236. data/db/migrate/20240120160024_ar_removed_url.rb +16 -0
  237. data/db/migrate/20240120160025_ar_role.rb +17 -0
  238. data/db/migrate/20240120160026_ar_site.rb +37 -0
  239. data/db/migrate/20240120160027_ar_temp.rb +11 -0
  240. data/db/migrate/20240120160028_ar_user.rb +42 -0
  241. data/db/migrate/20240120160029_ar_user_group.rb +12 -0
  242. data/db/migrate/20240120160030_ar_user_role.rb +18 -0
  243. data/db/migrate/20240120160031_ar_visit.rb +15 -0
  244. data/db/migrate/20240703016001_ar_setup.rb +16 -0
  245. data/db/migrate/20240703016002_ar_folder_permission.rb +15 -0
  246. data/db/migrate/20240703016003_ar_folder_rule.rb +14 -0
  247. data/db/migrate/20250115000001_ar_image.rb +25 -0
  248. data/lib/agile/configuration.rb +43 -0
  249. data/lib/agile/engine.rb +29 -0
  250. data/lib/agile/version.rb +27 -0
  251. data/lib/agile.rb +282 -0
  252. data/lib/agile_rails.rb +1 -0
  253. data/lib/generators/agile/USAGE +11 -0
  254. data/lib/generators/agile/new_form_generator.rb +369 -0
  255. data/lib/generators/convert_to_ar/convert_to_ar_generator.rb +158 -0
  256. data/lib/tasks/agile_db_clone.rake +132 -0
  257. data/lib/tasks/agile_db_export_to_yaml.rake +37 -0
  258. data/lib/tasks/agile_db_migrate.rake +35 -0
  259. metadata +414 -0
@@ -0,0 +1,109 @@
1
+ #--
2
+ # Copyright (c) 2024+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #+
23
+
24
+ #####################################################################
25
+ # == Schema information
26
+ #
27
+ # Table name: ar_category : Categories
28
+ #
29
+ # id Integer id
30
+ # created_at Time created_at
31
+ # updated_at Time Last update
32
+ # name String Category name
33
+ # description String Additional description of category
34
+ # ctype Integer Category type. Could be used for grouping categories.
35
+ # parent Integer Parent category. Leave blank if this is top level category.
36
+ # active Boolean Category is active.
37
+ # order Integer Additional order, which can be used for sorting.
38
+ # created_by Integer created_by
39
+ # updated_by Integer updated_by
40
+ #
41
+ # Categories are used on ArPage documents for grouping documents. Categorization
42
+ # is most useful for grouping news, blog entries ...
43
+ #####################################################################
44
+ class ArCategory < ApplicationRecord
45
+
46
+ validates :name, presence: true
47
+
48
+ before_destroy :can_destroy?
49
+
50
+ private
51
+
52
+ #########################################################################
53
+ # Can't delete if category document has children documents
54
+ #########################################################################
55
+ def can_destroy?
56
+ if ArCategory.where(parent: id).count > 0
57
+ errors.add(:base, I18n.t('agile.category_has_subs'))
58
+ throw :abort
59
+ end
60
+ end
61
+
62
+ #########################################################################
63
+ # Returns all values for use as parent select field.
64
+ #########################################################################
65
+ def self.values_for_parent(site_id = nil) #:nodoc:
66
+ qry = where(active: true)
67
+ qry = qry.and(ar_site_id: site_id.id) if site_id
68
+ parents = {} # cache parent names to minimize database usage
69
+ qry.inject([]) do |r, v|
70
+ if parents[v.parent].nil?
71
+ name = ''
72
+ parent = v.parent
73
+ until parent.nil?
74
+ doc = find(parent)
75
+ name = "#{doc.name} / #{name}"
76
+ parent = doc.parent
77
+ end
78
+ parents[v.parent] = name
79
+ end
80
+ name = v.parent ? parents[v.parent] + v.name : v.name
81
+ r << [name, v.id]
82
+ end.sort { |a, b| a.first <=> b.first }
83
+ end
84
+
85
+ #########################################################################
86
+ # Returns values for category type. Values should be defined in BigTable
87
+ # on the site level all overall.
88
+ #########################################################################
89
+ # @param [Integer] site_id : Return only values for specified site
90
+ #########################################################################
91
+ def self.choices_for_ctype(site_id = nil)
92
+ site_id = site_id.id if site_id&.class != Integer
93
+ ArBigTable.choices_for('ar_category_type', site_id)
94
+ end
95
+
96
+ #########################################################################
97
+ # Returns choices for all categories, prepared for tree_select input field
98
+ #########################################################################
99
+ def self.choices_for_categories(site_id = nil)
100
+ qry = where(active: true)
101
+ ar = [nil]
102
+ if site_id
103
+ ar << (site_id.instance_of?(Integer) ? site_id : site_id.id)
104
+ end
105
+ qry = qry.in(ar_site_id: ar)
106
+ qry.map { |category| [category.name, category.id, category.parent, category.order] }
107
+ end
108
+
109
+ end
@@ -0,0 +1,116 @@
1
+ #--
2
+ # Copyright (c) 2024+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #+
23
+
24
+ ########################################################################
25
+ # == Schema information
26
+ #
27
+ # Table name: ar_design : Designs
28
+ #
29
+ # id Integer id
30
+ # created_at Time created_at
31
+ # updated_at Time updated_at
32
+ # description String Short description of design
33
+ # body String Body of design which will be rendered like any Rails view
34
+ # params String Parameters used by design
35
+ # css String CSS for design
36
+ # rails_view String Rails view (file) name which will be used to render design
37
+ # code String Ruby code evaluated when processing page
38
+ # author String Creater if design
39
+ # active Boolean Is the design active
40
+ # created_by Integer created_by
41
+ # updated_by Integer Last updated by
42
+ # site_id Integer Select site name if this design belongs to singe site
43
+ #
44
+ # Designs are essential parts of AgileRails. Every ArPage document must have its design document defined.
45
+ # If ArPage documents are anchors for url addresses, ArDesign documents define how
46
+ # will page data be rendered in browser.
47
+ #
48
+ # ArDesign documents define what would normally be written into Rails view file. The code
49
+ # is saved in the body field of ArDesign document. If you prefere Rails way, enter view
50
+ # file name into rails_view field and put your code into file into views directory
51
+ # (ex. designs/home_page for ../views/designs/home_page.html.erb file).
52
+ #
53
+ # If you choose to save code to Rails view file you must add one top and bottom line to every source file.
54
+ # Top line will provide CMS edit menu, bottom line will provide additional CSS and javascript code
55
+ # scooped when renderers are called.
56
+ #
57
+ # Example (as written in body of ar_design):
58
+ # <div id="site">
59
+ # <div id="site-top-bg">
60
+ # <div id="site-top"><div id="logo"><%= agile_render(:ar_piece, name: 'site-top') %></div>
61
+ # <div id="login"><%= agile_render(:common, method: 'login') %></div>
62
+ # </div>
63
+ # <%= agile_render(:ar_menu, name: 'test-menu') %>
64
+ # </div>
65
+ #
66
+ # <div id="page"><%= agile_render(:ar_page) %></div>
67
+ # </div>
68
+ # <div id="site-bottom"><%= agile_render(:ar_piece, name: 'site-bottom') %></div>
69
+ #
70
+ # Example (as written in Rails view file):
71
+ #
72
+ # <!-- Pay attention on lines added at the top and bottom of file -->
73
+ # <%= render partial: 'ra/edit_stuff' if session[:edit_mode] > 0 %>
74
+ #
75
+ # <div id="site">
76
+ # <div id="site-top-bg">
77
+ # <div id="site-top"><div id="logo"><%= agile_render(:ar_piece, name: 'site-top') %></div>
78
+ # <div id="login"><%= agile_render(:common, method: 'login') %></div>
79
+ # </div>
80
+ # <%= agile_render(:ar_menu, name: 'test-menu') %>
81
+ # </div>
82
+ #
83
+ # <div id="page"><%= agile_render(:ar_page) %></div>
84
+ # </div>
85
+ # <div id="site-bottom"><%= agile_render(:ar_piece, name: 'site-bottom') %></div>
86
+ #
87
+ # <style type="text/css"><%= @css.html_safe %></style><%= javascript_tag @js %>
88
+ ########################################################################
89
+ class ArDesign < ApplicationRecord
90
+
91
+ validates_length_of :description, minimum: 5
92
+
93
+ after_save :cache_clear
94
+ after_destroy :cache_clear
95
+
96
+ ####################################################################
97
+ # Clear cache if cache is configured
98
+ ####################################################################
99
+ def cache_clear
100
+ Agile.cache_clear(:ar_design)
101
+ end
102
+
103
+ ########################################################################
104
+ # Return choices for select for design_id.
105
+ #
106
+ # If site is passed as parameter, only designs which belong to site or do not
107
+ # have site assigned will be selected. Too much designs to select often confuses
108
+ # end user.
109
+ ########################################################################
110
+ def self.choices_for_designs(site = nil)
111
+ site.nil? ? where(active: true) : where(site_id: [nil, site.id], active: true)
112
+ .sort { |w1, w2| w1.description.casecmp(w2.description) }
113
+ .map { |design| [design.description, design.id] }
114
+ end
115
+
116
+ end
@@ -0,0 +1,200 @@
1
+ #--
2
+ # Copyright (c) 2024+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #+
23
+
24
+ ##########################################################################
25
+ # Model and collection for filtering and sorting data.
26
+ # For now it is just an idea. Not yet implemented although data filtering implementation
27
+ # code is here, but should probably be moved into some helper.
28
+ ##########################################################################
29
+ class ArFilter < ApplicationRecord
30
+
31
+ # field :ar_user_id, type: Integer
32
+ # field :table, type: String
33
+ # field :description, type: String
34
+ # field 'filter', type: String, default: ''
35
+ # field :public, type: Boolean
36
+ # field :active, type: Boolean, default: true
37
+
38
+ validates :description, presence: true
39
+ before_save :do_before_save
40
+
41
+ ######################################################################
42
+ # Implementation of before_save callback.
43
+ ######################################################################
44
+ def do_before_save
45
+ self.ar_user_id = nil if self.public
46
+ end
47
+
48
+ ######################################################################
49
+ # Will return model with filter query set
50
+ ######################################################################
51
+ def self.get_filter(table_filter)
52
+ return if table_filter.nil?
53
+
54
+ filter = table_filter[:filter]
55
+ return if filter.nil? || filter[:table].nil?
56
+
57
+ model = filter[:table].classify.constantize
58
+ field = filter[:field]
59
+ # evaluate
60
+ if filter[:operation] == 'eval'
61
+ return eval(filter[:value]) if filter.dig(:value).to_s != '#NIL' # evaluated as string
62
+ return model.send(field) if model.respond_to?(field) # defined as scope or method in the model
63
+ end
64
+ # empty
65
+ return model.where(field => [nil, '']) if filter[:operation] == 'empty'
66
+
67
+ value = case filter[:value].to_s
68
+ when '#NIL' then return # #NIL. Filter is not active
69
+ when 'true' then true # boolean true
70
+ when 'false' then false # boolean false
71
+ else # is it a date or time. This can be improved
72
+ if filter[:value].to_s.split(/[\.|\/|\-]/).size < 3
73
+ filter[:value]
74
+ else
75
+ (Date.parse(filter[:value]) rescue nil) || filter[:value]
76
+ end
77
+ end
78
+
79
+ case filter[:operation]
80
+ when 'like'
81
+ #TODO get_like_clause(field, value)
82
+ value = sanitize_sql(value)
83
+ model.where("lower(#{field}) like ?", "%#{value.downcase}%")
84
+ when 'gt'
85
+ model.where("#{field} > ?", value)
86
+ when 'lt'
87
+ model.where("#{field} < ?", value)
88
+ when 'eq'
89
+ model.where("#{field} = ?", value)
90
+ end
91
+ end
92
+
93
+ ############################################################################
94
+ # Return filter input field for entering filter data on index action
95
+ ############################################################################
96
+ def self.get_filter_input_field(env)
97
+ form = env.form
98
+ filter = env.session.dig(:filters, form['table'], :filter)
99
+ return '' if filter.nil? || filter[:operation] == 'eval'
100
+
101
+ field = AgileHelper.get_field_form_definition(filter[:field], form)
102
+ return '' if field.nil? && filter[:input].nil?
103
+
104
+ saved_readonly = form['readonly']
105
+ form['readonly'] = false # must be
106
+ field ||= {}
107
+ # If field has choices available in labels, use them. This is most likely select input field.
108
+ if field['name']
109
+ choices = env.t('helpers.label.' + form['table'] + '.choices_for_' + field['name'] )
110
+ unless choices.match(/translation missing/i) || choices.match('helpers.label')
111
+ field['choices'] = choices
112
+ end
113
+ end
114
+ # field redefined with input keyword. Name must start with _
115
+ field['name'] = '_filter_field'
116
+ field['type'] = filter[:input] if filter[:input].to_s.size > 5
117
+ field['type'] ||= 'text_field'
118
+ field['readonly'] = false # must be
119
+ # let text fields size be no more then 20
120
+ field['size'] = 20 if field['type'].match('text') && field['size'].to_i > 20
121
+ field['html'] ||= {}
122
+ # Start with last entered value
123
+ field['html']['value'] = filter[:value] unless filter[:value] == '#NIL'
124
+ field['html']['selected'] = field['html']['value'] # for select field
125
+ # url for filter ON action
126
+ field['html']['data-url'] = env.url_for(controller: :agile, action: :run, control: 'agile.filter_on',
127
+ t: AgileHelper.table_param(env.params), f: AgileHelper.form_param(env.params))
128
+ url = field['html']['data-url']
129
+ # remove if present
130
+ field['with_new'] = nil if field['with_new']
131
+ # create input field
132
+ html = ''
133
+ klass_string = field['type'].camelize
134
+ klass = AgileFormFields::const_get(klass_string) rescue nil
135
+ if klass
136
+ if (agile_field = klass.new(env, nil, field).render rescue nil)
137
+ js = agile_field.js.blank? ? '' : env.javascript_tag(agile_field.js)
138
+ html = %(<li class="no-background">
139
+ <span class="filter_field" data-url="#{url}">#{agile_field.html}
140
+ #{env.mi_icon('search', class: 'record_filter_field_icon')}
141
+ #{js}</span></li>)
142
+ else
143
+ # Error. Forget filter
144
+ env.session[:filters][form['table']][:filter] = nil
145
+ end
146
+ end
147
+ form['readonly'] = saved_readonly
148
+ html.html_safe
149
+ end
150
+
151
+ ######################################################################
152
+ # Create popup menu for filter options.
153
+ ######################################################################
154
+ def self.filter_menu(env)
155
+ html = '<div><ul class="menu-filter">'
156
+ table = env.form['table']
157
+ documents = self.where(table: table, active: true).to_a
158
+ documents.each do |document|
159
+ description = document.description.match('.') ? I18n.t(document.description) : document.description
160
+ html += "<li data-filter=\"#{document.id}\">#{description}</li>"
161
+ end
162
+
163
+ # add filters defined in model
164
+ model = table.classify.constantize
165
+ filters = model.agile_filters if model.respond_to?(:agile_filters)
166
+ if filters
167
+ # only single defined. Convert to array.
168
+ filters = [filters] if filters.class == Hash
169
+ filters.each do |filter|
170
+ url = env.url_for(controller: :agile, action: :run, t: table, f: AgileHelper.form_param(env.params),
171
+ control: 'agile.filter_on',
172
+ filter_field: filter[:field],
173
+ filter_oper: filter[:operation],
174
+ filter_value: filter[:value])
175
+ html += %(<li class="ar-link-ajax in-menu" data-url="#{url}">#{filter[:title]}</li>)
176
+ end
177
+ end
178
+ # divide standard and custom filter options
179
+ html += '<hr>' if html.size > 30 #
180
+ html += %(<li class="ar-link in-menu" id="open_ar_filter">#{I18n.t('agile.filter_set')}</li></ul></div>)
181
+ html.html_safe
182
+ end
183
+
184
+ ######################################################################
185
+ # Creates title for turn filter off, which consists of displaying curently
186
+ # active filter and text to turn it off.
187
+ ######################################################################
188
+ def self.title_for_filter_off(filter_data)
189
+ filter = filter_data&.dig(:filter)
190
+ return '' if filter.nil?
191
+ return I18n.t('agile.filter_off') if filter[:operation] == 'eval'
192
+
193
+ operations = I18n.t('agile.choices_for_filter_operators').split(',').map { _1.split(':') }
194
+ operation = operations.find { _1.last == filter[:operation] }.first
195
+
196
+ '[ ' + I18n.t("helpers.label.#{filter[:table]}.#{filter[:field]}") +
197
+ " ] #{operation} [ #{filter[:value]} ] : #{I18n.t('agile.filter_off')}"
198
+ end
199
+
200
+ end
@@ -0,0 +1,50 @@
1
+ #--
2
+ # Copyright (c) 2024+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #+
23
+
24
+ #########################################################################
25
+ # == Schema information
26
+ #
27
+ # Table name: ar_folder_permissions : Folder permissions
28
+ #
29
+ # id Integer id
30
+ # created_at Time created_at
31
+ # updated_at Time updated_at
32
+ # name String Folder name
33
+ # inherited Boolean Inherit permissions from parent
34
+ # active Boolean Permission is valid
35
+ # ar_policy_rules Embedded: ArPolicyRule Policy rules
36
+ #
37
+ # Similar to ArPermission ArDirPermission model defines documents
38
+ # for accessing file system. Permissions defined on a parent folder automatically
39
+ # apply to all folders below unless folder on lower level has its own permission document.
40
+ #
41
+ # At least one document must exist for file manager to work.
42
+ #########################################################################
43
+ class ArFolderPermission < ApplicationRecord
44
+
45
+ has_many :ar_folder_rules
46
+
47
+ validates :folder_name, presence: true
48
+ validates :folder_name, uniqueness: true
49
+
50
+ end
@@ -0,0 +1,47 @@
1
+ #--
2
+ # Copyright (c) 2024+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #+
23
+
24
+ #########################################################################
25
+ # == Schema information
26
+ #
27
+ # Table name: ar_Folder_rules : Access policy rules for file system folders
28
+ #
29
+ # id Integer id
30
+ # created_at Time created_at
31
+ # updated_at Time updated_at
32
+ # ar_role_id Object User role access defined by this rule
33
+ # permission Integer Access permission
34
+ #
35
+ # ArFolderRule records define rules for accessing folders in the file system.
36
+ #########################################################################
37
+ class ArFolderRule < ApplicationRecord
38
+
39
+ belongs_to :ar_folder_permission
40
+
41
+ validate do
42
+ if new_record? && ArFolderRule.find_by(ar_folder_permission: ar_folder_permission, ar_role_id: ar_role_id).present?
43
+ errors.add('ar_role_id', I18n.t('agile.already_defined'))
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,53 @@
1
+ #--
2
+ # Copyright (c) 2024+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #+
23
+
24
+ #########################################################################
25
+ # ArGallery model holds data for picture galleries for various types of documents.
26
+ # Picture Gallery can be added to any document, provided that it has two parameters:
27
+ # doc_id and doc_type.
28
+ #########################################################################
29
+ # == Schema information
30
+ #
31
+ # Table name: ar_gallery : Pictures gallery
32
+ #
33
+ # id Integer id
34
+ # doc_id Integer Parent document id where this gallery lies
35
+ # doc_type String Parent document table name
36
+ # title String Title name for picture
37
+ # description String Short description
38
+ # picture String Picture filename
39
+ # thumbnail String Picture thumbnail
40
+ # order Integer Order of picture in a gallery
41
+ #
42
+ # active Boolean Picture is active
43
+ # created_by Integer created_by
44
+ # updated_by Integer updated_by
45
+ # created_at Time created_at
46
+ # updated_at Time updated_at
47
+ #
48
+ #########################################################################
49
+ class ArGallery < ApplicationRecord
50
+ validates :picture, presence: true
51
+ validates :doc_id, presence: true
52
+ validates :doc_type, presence: true
53
+ end