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,128 @@
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
+ ####################################################################
26
+ # Helpers needed by some form fields on ar_image form
27
+ ####################################################################
28
+ module ArImageHelper
29
+
30
+ ############################################################################
31
+ # Will return code for previewing image on top of ar_image entry form
32
+ ############################################################################
33
+ def ar_image_preview(document, *parms)
34
+ src = "/#{agile_get_site.params.dig('ar_image', 'location')}/#{document.first_available_image}"
35
+ %(<span class="ar-image-preview ar-image-preview-1"><img src="#{src}"></img></span>).html_safe
36
+ end
37
+
38
+ ############################################################################
39
+ # Will return code for previewing resized images on ar_image entry form
40
+ ############################################################################
41
+ def ar_image_preview_resized(document, yaml, ignore)
42
+ size = yaml['name'].last
43
+ return '' if document["size_#{size}"].blank?
44
+
45
+ src = "/#{agile_get_site.params.dig('ar_image', 'location')}/#{document.id}-#{size}.#{document.img_type}?#{Time.now.to_i}"
46
+ %(<span class="ar-image-preview"><img src="#{src}"></img></span><div id="ar-image-preview"></div>).html_safe
47
+ end
48
+
49
+ ############################################################################
50
+ # Will return choices for preset image sizes
51
+ ############################################################################
52
+ def ar_image_choices_for_image_size
53
+ sizes = agile_get_site.params.dig('ar_image', 'sizes')
54
+ return ['300x200'] if sizes.blank?
55
+
56
+ sizes.split(",").map(&:strip)
57
+ end
58
+
59
+ ############################################################################
60
+ # Will return code for invoking ar_image_search form to select image select on an AgileRails Form.
61
+ #
62
+ # @param [String] field_name : Field name to which selected image value will be saved.
63
+ ###########################################################################
64
+ def ar_image_invoke(field_name)
65
+ return '' unless agile_get_site.params.dig('ar_image', 'location')
66
+
67
+ url = url_for(controller: :cmsedit, form_name: :ar_image_search, table: :ar_image, field_name: field_name)
68
+ %(<span class="ar-window-open" data-url="#{url}" title="#{t('agile.ar_image.invoke')}">#{mi_icon('image-o')}</span>).html_safe
69
+ end
70
+
71
+ ############################################################################
72
+ # Will return code for previewing image on top of ar_image entry form
73
+ ############################################################################
74
+ def first_ar_image(document, *parms)
75
+ src = "/#{agile_get_site.params.dig('ar_image', 'location')}/#{document.first_available_image}"
76
+ %(<span class="ar-image-preview"><img src="#{src}"></img></span><span id="ar-image-preview">).html_safe
77
+ end
78
+
79
+ ######################################################################
80
+ # Will format qry result as html code for selecting image
81
+ ######################################################################
82
+ def select_links_for_ar_image(doc, *parms)
83
+ %w[o s m l].map { |size| ar_image_link_for_select(doc, size) }.join.html_safe
84
+ end
85
+
86
+ ######################################################################
87
+ # Will return HTML code for selecting image
88
+ ######################################################################
89
+ def ar_image_link_for_select(doc, what)
90
+ field = "size_#{what}"
91
+ value = doc.send(field)
92
+ return '' if value.blank?
93
+
94
+ value = value.split(/\+/).first
95
+ src = "/#{agile_get_site.params.dig('ar_image', 'location')}/#{doc.id}-#{what}.#{doc.img_type}"
96
+ %(
97
+ <div class="img-link"><div>
98
+ #{value}<br>
99
+ <i class="mi-o mi-preview" onclick="ar_image_preview('#{src}');" title="#{t('agile.ar_image.preview')}"></i>
100
+ <i class="mi-o mi-check_circle" onclick="ar_image_select('#{src}');" title="#{t('agile.ar_image.select')}"></i>
101
+ </div></div>)
102
+ end
103
+
104
+ ######################################################################
105
+ # Will return image file for requested size.
106
+ #
107
+ # @param [String] file_name : Image file name
108
+ # @param [String] size : Preferred image size
109
+ #
110
+ # @return [String] : Image file name if requested size is found. Otherwise first available image.
111
+ ######################################################################
112
+ def ar_image_get_by_size(file_name, size)
113
+ id = file_name[file_name.rindex('/') + 1, 24]
114
+ return 'error: ID not valid' unless BSON::ObjectId.legal?(id)
115
+
116
+ image = ArImage.find(id)
117
+ return 'error: ID not found' unless image
118
+
119
+ what = %w[o s m l].inject('l') do |r, e|
120
+ field_name = "size_#{e}".to_sym
121
+ break e if doc.send(field_name) == size
122
+
123
+ e
124
+ end
125
+ "/#{agile_get_site.params.dig('ar_image', 'location')}/#{doc.id}-#{what}.#{doc.img_type}"
126
+ end
127
+
128
+ end
@@ -0,0 +1,61 @@
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
+ module AgileFormFields
24
+
25
+ ###########################################################################
26
+ # Implementation of action AgileRails form field. Actions can also be inserted on
27
+ # the form like just like on action pane.
28
+ #
29
+ # ===Form options:
30
+ # * +type:+ action (required)
31
+ # * +action_type:+ link, submit or ajax action (default link)
32
+ # * +caption:+ Caption for action
33
+ # * +icon:+ Action icon
34
+ # * +url:+ direct url link
35
+ # * +controller:+ controller name
36
+ # * +action:+ action name
37
+ # * +html:+ html options which apply to link_to (optional)
38
+ #
39
+ # Form example:
40
+ # 30:
41
+ # type: action
42
+ # action_type: popup
43
+ # caption: Some action
44
+ # icon: cogs
45
+ # controller: my_controller
46
+ # action: my_action
47
+ # id: id # will be replaced by record.id
48
+ ###########################################################################
49
+ class Action < AgileFormField
50
+
51
+ ###########################################################################
52
+ # Render link_to field html code
53
+ ###########################################################################
54
+ def render
55
+ @yaml['type'] = @yaml['action_type'] || 'link'
56
+ @html += '<ul class="action">' + @env.agile_link_ajax_window_submit_action(@yaml, @record) + '</ul>'
57
+ self
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,322 @@
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
+ # AgileFormFields module contains definitions of classes used for
26
+ # rendering data entry fields on AgileRails forms.
27
+ #
28
+ # Every data entry field type written in lowercase in form must have its class
29
+ # defined in CamelCase in AgileFormFields module.
30
+ #
31
+ # Each class must have at least render method implemented. All classes can
32
+ # inherit from AgileFormField class which acts as abstract template class and implements
33
+ # most of surrounding code for creating custom AgileRails form field.
34
+ #
35
+ # Render method must create html and javascript code which must be
36
+ # saved to internal @html and @js variables. Field code is then retrived by accessing
37
+ # these two internal variables.
38
+ #
39
+ # Example. How the field code is generated in form renderer:
40
+ # klas_string = yaml['type'].camelize
41
+ # if AgileFormFields.const_defined?(klas_string) # check if field type class is defined
42
+ # klas = AgileFormFields.const_get(klas_string)
43
+ # field = klas.new(self, @record, options).render
44
+ # javascript += field.js
45
+ # html += field.html
46
+ # end
47
+ #
48
+ # Example. How to mix AgileRails field code in Rails views:
49
+ # <div>User:
50
+ # <%=
51
+ # opts = {'name' => 'user', 'choices' => "eval agile_choices_for('ar_user','name')", 'include_blank' => true }
52
+ # dt = AgileFormFields::Select.new(self, {}, opts).render
53
+ # (dt.html + javascript_tag(dt.js)).html_safe
54
+ # %></div>
55
+ ###########################################################################
56
+ module AgileFormFields
57
+
58
+ ###########################################################################
59
+ # Template method for AgileRails form field definition. This is abstract class with
60
+ # most of the common code for custom form field already implemented.
61
+ ###########################################################################
62
+ class AgileFormField
63
+ attr_reader :js
64
+ attr_reader :css
65
+
66
+ ####################################################################
67
+ # AgileFormField initialization code.
68
+ #
69
+ # Parameters:
70
+ # [env] Controller object. Controller object from where object is created. Usually self is send.
71
+ # [record] Document object. Document object which holds fields data.
72
+ # [yaml] Hash. Hash object holding field definition data.
73
+ #
74
+ # Returns:
75
+ # Self
76
+ ####################################################################
77
+ def initialize( env, record, yaml )
78
+ @env = env
79
+ @record = record
80
+ @yaml = yaml
81
+ @form = env.form
82
+ @yaml['html'] ||= {}
83
+ # set readonly field
84
+ #@readonly = (@yaml and @yaml['readonly']) || (@form and @form['readonly'])
85
+ @readonly = @yaml&.dig('readonly') || @form&.dig('readonly')
86
+ @yaml['html']['readonly'] = true if @readonly
87
+ # assign size to html element if not already there
88
+ @yaml['html']['size'] ||= @yaml['size'] if @yaml['size']
89
+
90
+ @html = ''
91
+ @js = ''
92
+ @css = set_css_code @yaml['css']
93
+ self
94
+ end
95
+
96
+ ####################################################################
97
+ # Returns html code together with CSS code.
98
+ ####################################################################
99
+ def html
100
+ @html
101
+ end
102
+
103
+ ####################################################################
104
+ # Wrapper for i18 t method, with some spice added. If translation is not found English
105
+ # translation value will be returned. And if still not found default value will be returned if passed.
106
+ #
107
+ # Parameters:
108
+ # [key] String. String to be translated into locale.
109
+ # [default] String. Value returned if translation is not found.
110
+ #
111
+ # Example:
112
+ # t('translate.this','Enter text for ....')
113
+ #
114
+ # Returns:
115
+ # String. Translated text.
116
+ ####################################################################
117
+ def t(key, default = '')
118
+ c = I18n.t(key)
119
+ if c.match(/translation missing/i)
120
+ c = I18n.t(key, locale: 'en')
121
+ # Still not found. Return default if set
122
+ c = default unless default.blank?
123
+ end
124
+ c
125
+ end
126
+
127
+ ####################################################################
128
+ # Standard code for returning readonly field.
129
+ ####################################################################
130
+ def ro_standard(value = nil)
131
+ if value.nil?
132
+ value = if @yaml['html']['value']
133
+ @yaml['html']['value']
134
+ else
135
+ @record.respond_to?(@yaml['name']) ? @record.send(@yaml['name']) : nil
136
+ end
137
+ end
138
+ @html += %(<div id="#{@yaml['name']}" class="ar-readonly">#{value}</div>)
139
+ self
140
+ end
141
+
142
+ ####################################################################
143
+ # Set initial value of the field when initial value is set in url parameters..
144
+ #
145
+ # Example: Form has field named picture. Field can be initialized by
146
+ # setting value of param p_picture.
147
+ # params['p_picture'] = '/path/to_picture'
148
+ #
149
+ # When multiple initial values are assigned it is more convinient to assign them
150
+ # through flash object.
151
+ # flash[:record] = {}
152
+ # flash[:record]['picture'] = '/path/to_picture'
153
+ ####################################################################
154
+ def set_initial_value(opt1 = 'html', opt2 = 'value')
155
+ @yaml['html'] ||= {}
156
+ value_send_as = 'p_' + @yaml['name']
157
+ if @env.params[value_send_as]
158
+ @yaml[opt1][opt2] = @env.params[value_send_as]
159
+ elsif @env.flash[:record] and @env.flash[:record][@yaml['name']]
160
+ @yaml[opt1][opt2] = @env.flash[:record][@yaml['name']]
161
+ end
162
+ set_default_value(opt1, opt2) if @yaml['default']
163
+ end
164
+
165
+ ####################################################################
166
+ # Will set default value for field on a AgileRails form.
167
+ ####################################################################
168
+ def set_default_value(opt1, opt2)
169
+ return if @yaml[opt1][opt2].present?
170
+ return if @record&.send(@yaml['name']).present?
171
+
172
+ @yaml[opt1][opt2] = if @yaml['default'].class.to_s == 'Hash'
173
+ evaluate = @yaml['default']['eval']
174
+ return if evaluate.blank?
175
+ # add @env if it's a method call and @env is not present
176
+ if evaluate[0] != evaluate[0].upcase && !evaluate.match('@env')
177
+ evaluate.prepend('@env.')
178
+ end
179
+ eval(evaluate)
180
+ else
181
+ @yaml['default']
182
+ end
183
+ end
184
+
185
+ ####################################################################
186
+ # Returns style html code for AgileRails Form object if style directive is present in field definition.
187
+ # Otherwise returns empty string.
188
+ #
189
+ # Style may be defined like:
190
+ # style:
191
+ # height: 400px
192
+ # width: 800px
193
+ # padding: 10px 20px
194
+ #
195
+ # or
196
+ #
197
+ # style: "height:400px; width:800px; padding: 10px 20px;"
198
+ #
199
+ # Style directive may also be defined under html directive.
200
+ # html:
201
+ # style:
202
+ # height: 400px
203
+ # width: 800px
204
+ #
205
+ #
206
+ ####################################################################
207
+ def set_style
208
+ style = @yaml['html']['style'] || @yaml['style']
209
+ case style.class
210
+ when String then "style=\"#{style}\""
211
+ when Hash then
212
+ value = style.to_a.map { "#{_1}: #{_2}" }.join(';')
213
+ "style=\"#{value}\""
214
+ else ''
215
+ end
216
+ end
217
+
218
+ ####################################################################
219
+ # Sets css code for the field if specified. It replaces all occurences of '# '
220
+ # with field name id, as defined on form.
221
+ ####################################################################
222
+ def set_css_code(css)
223
+ return '' if css.blank?
224
+
225
+ css.gsub!('# ', "#td_record_#{@yaml['name']} ") if css.match('# ')
226
+ css
227
+ end
228
+
229
+ ####################################################################
230
+ # Will return ruby hash formated as javascript string which can be used
231
+ # for passing parameters in javascript code.
232
+ #
233
+ # Parameters:
234
+ # [Hash] Hash. Ruby hash parameters.
235
+ #
236
+ # Form example: As used in forms
237
+ # options:
238
+ # height: 400
239
+ # width: 800
240
+ # toolbar: "basic"
241
+ #
242
+ # => "height:400, width:800, toolbar: 'basic'"
243
+ #
244
+ # Return:
245
+ # String: Options formated as javascript options.
246
+ #
247
+ ####################################################################
248
+ def hash_to_options(options)
249
+ options.inject('') do |r, element|
250
+ key, option = element
251
+
252
+ r += "#{key} : "
253
+ r += case
254
+ when option.to_s.match(/function/i) then option
255
+ when option.class == String then "\"#{option}\""
256
+ else option.to_s
257
+ end
258
+ r += ",\n"
259
+ end
260
+ end
261
+
262
+ ####################################################################
263
+ # Options may be defined on form as hash or as string. This method will
264
+ # ensure conversion of options into hash.
265
+ #
266
+ # Parameters:
267
+ # [String or Hash] : Form options
268
+ #
269
+ # Form example: As used in forms
270
+ # options:
271
+ # height: 400
272
+ # width: 800
273
+ # toolbar: "'basic'"
274
+ # or
275
+ #
276
+ # options: "height:400, width:800, toolbar:'basic'"
277
+ #
278
+ # Return:
279
+ # Hash: Options as Hash
280
+ ####################################################################
281
+ def options_to_hash(options)
282
+ return {} if options.blank?
283
+ return options unless options.class == String
284
+
285
+ options.chomp.split(',').inject({}) do |r, e|
286
+ key, value = e.chomp.split(':')
287
+ value.strip!
288
+ value = value[1..value.size - 2] if value[0] =~ /\'|\"/
289
+ r[key.strip] = value
290
+ r
291
+ end
292
+ end
293
+
294
+ ####################################################################
295
+ # Checks if field name exists in document and alters record parameters if necesary.
296
+ # Method was added after fields that do not belong to current edited record
297
+ # were added to forms. Valid form only field name must start with underscore (_) letter.
298
+ #
299
+ # Return:
300
+ # String: 'record' or '_record' when valid nonexisting field is used
301
+ ####################################################################
302
+ def record_text_for(name)
303
+ (!@record.respond_to?(name) && name[0] == '_') ? '_record' : 'record'
304
+ end
305
+
306
+
307
+ ###########################################################################
308
+ # Default get_data method for retrieving data from form. If data that will be written to
309
+ # database must be recalculated, then AgileRails field class definition will define it's own get_data method.
310
+ #
311
+ # Parameters:
312
+ # [params] Controllers params object.
313
+ # [name] Field name
314
+ #
315
+ # Most of classes will use this default method which simply returns params['record'][name].
316
+ ###########################################################################
317
+ def self.get_data(params, name)
318
+ params['record'][name]
319
+ end
320
+
321
+ end
322
+ end
@@ -0,0 +1,112 @@
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
+ module AgileFormFields
24
+
25
+ ###########################################################################
26
+ # Implementation of belongs_to AgileRails form field.
27
+ # belongs_to form field is used to edit records that are related to currently edited record.
28
+ #
29
+ # Related records are edited inside iframe.
30
+ #
31
+ # ===Form options:
32
+ # * +name:+ field name (required)
33
+ # * +type:+ belongs_to (required)
34
+ # * +form_name:+ name of form which will be used for editing
35
+ # * +load:+ when is embedded iframe loaded. default=on form load, delay=on tab select, always=every time tab is selected)
36
+ # * +belongs_to:+ optionaly define name of model, to which edited table is related
37
+ # * +html:+ html options (optional)
38
+ # * +height:+ height of embedded object in pixels (1000)
39
+ # * +width:+ width of embedded object in pixels (500)
40
+ #
41
+ # Form example:
42
+ # 10:
43
+ # name: ar_parts
44
+ # type: belongs_to
45
+ # form_name: ar_part
46
+ # refresh: delay
47
+ # belongs_to: ar_page
48
+ # html:
49
+ # height: 1000
50
+ ###########################################################################
51
+ class BelongsTo < AgileFormField
52
+
53
+ ###########################################################################
54
+ # Render belongs_to AgileRails form field code
55
+ ###########################################################################
56
+ def render
57
+ # some HTML5 defaults
58
+ @yaml['html'] ||= {}
59
+ @yaml['html']['width'] ||= '99%'
60
+
61
+ @yaml['action'] ||= 'index'
62
+ # defaults both way
63
+ @yaml['table'] ||= @yaml['form_name'] if @yaml['form_name']
64
+ @yaml['form_name'] ||= @yaml['table'] if @yaml['table']
65
+
66
+ if @yaml['name'] == @yaml['table'] || @yaml['table'] == 'ar_memory'
67
+ tables = @yaml['table']
68
+ ids = @record.id
69
+ else
70
+ tables = @env.tables.inject('') { |r, v| r += "#{v[1]};" } + @yaml['table']
71
+ ids = (@env.ids.present? ? @env.ids.join(';') + ';' : '') + @record.id.to_s
72
+ end
73
+ # message when new record
74
+ if @record.new_record? && tables != 'ar_temp'
75
+ @yaml['html']['srcdoc'] = %(
76
+ <div style='font-family: helvetica; font-size: 1.7rem; font-weight: bold; color: #ddd; padding: 1rem'>
77
+ #{I18n.t('agile.iframe_save_to_view')}
78
+ </div>)
79
+ end
80
+ html5 = @yaml['html'].map{ |k, v| %(#{k}="#{v}") }.join(' ')
81
+
82
+ # edit enabled belong_to form on a readonly form
83
+ readonly = AgileHelper.dont?(@yaml['readonly']) ? nil : @readonly
84
+ opts = { controller: :agile, action: @yaml['action'],
85
+ ids: ids, table: tables, form_name: @yaml['form_name'],
86
+ field_name: @yaml['name'], iframe: "if_#{@yaml['name']}", readonly: readonly }
87
+ # additional parameters if specified
88
+ @yaml['params'].each { |k, v| opts[k] = @env.agile_value_for_parameter(v) } if @yaml['params']
89
+
90
+ @html += "<iframe class='iframe_embedded' id='if_#{@yaml['name']}' name='if_#{@yaml['name']}' #{html5}></iframe>"
91
+ return self if @record.new_record? && tables != 'ar_temp'
92
+
93
+ url = @env.url_for(opts)
94
+ attributes = case @yaml['load']
95
+ when nil?, 'default'
96
+ "'src', '#{url}'"
97
+ when 'delay'
98
+ "'data-src-#{@yaml['load']}', '#{url}'"
99
+ else
100
+ "{'data-src-#{@yaml['load']}': '#{url}', src: '#{url}'}"
101
+ end
102
+ @js += %(
103
+ $(document).ready( function() {
104
+ $('#if_#{@yaml['name']}').attr(#{attributes});
105
+ });)
106
+
107
+ self
108
+ end
109
+
110
+ end
111
+
112
+ end