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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/MIT-LICENSE +20 -0
- data/README.md +285 -0
- data/Rakefile +39 -0
- data/agile_rails.gemspec +36 -0
- data/app/assets/fonts/ibm-plex-sans-300.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-400.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-500.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-600.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-700.woff2 +0 -0
- data/app/assets/fonts/ibm-plex-sans-italic.woff2 +0 -0
- data/app/assets/images/32px.png +0 -0
- data/app/assets/images/throbber.gif +0 -0
- data/app/assets/javascripts/agile/agile.js +1489 -0
- data/app/assets/javascripts/agile/jquery-migrate.js +702 -0
- data/app/assets/javascripts/agile/jquery.bpopup.js +372 -0
- data/app/assets/javascripts/agile/jquery.datetimepicker.js +1353 -0
- data/app/assets/javascripts/agile/jstree.min.js +6 -0
- data/app/assets/javascripts/agile/select-multiple.js +459 -0
- data/app/assets/javascripts/agile/some_scripts.js +33 -0
- data/app/assets/javascripts/agile.js +22 -0
- data/app/assets/javascripts/agile_application.js +22 -0
- data/app/assets/javascripts/agile_editor.js +22 -0
- data/app/assets/stylesheets/agile/agile.css +1882 -0
- data/app/assets/stylesheets/agile/agile_apps.css +149 -0
- data/app/assets/stylesheets/agile/jquery.datetimepicker.css +304 -0
- data/app/assets/stylesheets/agile/jstree.css +1107 -0
- data/app/assets/stylesheets/agile/select-multiple.css +110 -0
- data/app/assets/stylesheets/agile/th-bg.png +0 -0
- data/app/assets/stylesheets/agile/theme.css +49 -0
- data/app/assets/stylesheets/agile.css +21 -0
- data/app/assets/stylesheets/agile_application.css +20 -0
- data/app/assets/stylesheets/agile_editor.css +19 -0
- data/app/controllers/agile_application_controller.rb +735 -0
- data/app/controllers/agile_common_controller.rb +345 -0
- data/app/controllers/agile_controller.rb +977 -0
- data/app/controllers/agile_main_controller.rb +36 -0
- data/app/controls/agile_control.rb +120 -0
- data/app/controls/agile_report.rb +364 -0
- data/app/controls/ar_category_control.rb +39 -0
- data/app/controls/ar_help_control.rb +139 -0
- data/app/controls/ar_image_control.rb +180 -0
- data/app/controls/ar_journal_control.rb +47 -0
- data/app/controls/ar_menu_item_control.rb +55 -0
- data/app/controls/ar_page_control.rb +64 -0
- data/app/controls/ar_poll_result_control.rb +84 -0
- data/app/controls/ar_setup_control.rb +62 -0
- data/app/controls/belongs_to_control.rb +61 -0
- data/app/controls/browse_models_control.rb +98 -0
- data/app/controls/settings_form_control.rb +137 -0
- data/app/forms/agile_help.yml +112 -0
- data/app/forms/agile_menu.yml +140 -0
- data/app/forms/agile_report_defaults.yml +39 -0
- data/app/forms/all_options.yml +810 -0
- data/app/forms/ar_ad.yml +121 -0
- data/app/forms/ar_big_table.yml +60 -0
- data/app/forms/ar_big_table_value.yml +52 -0
- data/app/forms/ar_browse_fields.yml +35 -0
- data/app/forms/ar_browse_models.yml +48 -0
- data/app/forms/ar_category.yml +73 -0
- data/app/forms/ar_category_as_tree.yml +31 -0
- data/app/forms/ar_design.yml +75 -0
- data/app/forms/ar_filter.yml +52 -0
- data/app/forms/ar_folder_permission.yml +56 -0
- data/app/forms/ar_folder_rule.yml +48 -0
- data/app/forms/ar_gallery.yml +55 -0
- data/app/forms/ar_image.yml +126 -0
- data/app/forms/ar_image_search.yml +83 -0
- data/app/forms/ar_journal.yml +76 -0
- data/app/forms/ar_json_ld.yml +56 -0
- data/app/forms/ar_key_value.yml +33 -0
- data/app/forms/ar_key_value_store.yml +33 -0
- data/app/forms/ar_link.yml +60 -0
- data/app/forms/ar_menu.yml +67 -0
- data/app/forms/ar_menu_item.yml +141 -0
- data/app/forms/ar_page.yml +187 -0
- data/app/forms/ar_part.yml +91 -0
- data/app/forms/ar_permission.yml +52 -0
- data/app/forms/ar_permission_rule.yml +40 -0
- data/app/forms/ar_piece.yml +106 -0
- data/app/forms/ar_policy.yml +64 -0
- data/app/forms/ar_policy_rule.yml +42 -0
- data/app/forms/ar_policy_rule_nocms.yml +40 -0
- data/app/forms/ar_poll.yml +118 -0
- data/app/forms/ar_poll_item.yml +78 -0
- data/app/forms/ar_poll_result.yml +88 -0
- data/app/forms/ar_poll_result_export.yml +35 -0
- data/app/forms/ar_removed_url.yml +41 -0
- data/app/forms/ar_role.yml +43 -0
- data/app/forms/ar_seo.yml +32 -0
- data/app/forms/ar_setup.yml +45 -0
- data/app/forms/ar_site.yml +149 -0
- data/app/forms/ar_steps_template.yml +51 -0
- data/app/forms/ar_user.yml +140 -0
- data/app/forms/ar_user_role.yml +57 -0
- data/app/forms/help/dc_category_as_tree.en +4 -0
- data/app/forms/help/dc_category_as_tree.sl +5 -0
- data/app/forms/json_ld_schema.yml +168 -0
- data/app/helpers/agile_application_helper.rb +1162 -0
- data/app/helpers/agile_category_helper.rb +128 -0
- data/app/helpers/agile_common_helper.rb +308 -0
- data/app/helpers/agile_edit_helper.rb +645 -0
- data/app/helpers/agile_helper.rb +509 -0
- data/app/helpers/agile_index_helper.rb +677 -0
- data/app/helpers/ar_image_helper.rb +128 -0
- data/app/models/agile_form_fields/action.rb +61 -0
- data/app/models/agile_form_fields/agile_form_field.rb +322 -0
- data/app/models/agile_form_fields/belongs_to.rb +112 -0
- data/app/models/agile_form_fields/check_box.rb +73 -0
- data/app/models/agile_form_fields/comment.rb +62 -0
- data/app/models/agile_form_fields/date_picker.rb +104 -0
- data/app/models/agile_form_fields/date_select.rb +68 -0
- data/app/models/agile_form_fields/datetime_picker.rb +88 -0
- data/app/models/agile_form_fields/datetime_select.rb +73 -0
- data/app/models/agile_form_fields/file_field.rb +52 -0
- data/app/models/agile_form_fields/file_select.rb +69 -0
- data/app/models/agile_form_fields/hidden_field.rb +51 -0
- data/app/models/agile_form_fields/html_field.rb +69 -0
- data/app/models/agile_form_fields/journal_diff.rb +62 -0
- data/app/models/agile_form_fields/link_to.rb +69 -0
- data/app/models/agile_form_fields/method.rb +66 -0
- data/app/models/agile_form_fields/multitext_autocomplete.rb +215 -0
- data/app/models/agile_form_fields/number_field.rb +92 -0
- data/app/models/agile_form_fields/password_field.rb +63 -0
- data/app/models/agile_form_fields/radio_button.rb +95 -0
- data/app/models/agile_form_fields/readonly.rb +77 -0
- data/app/models/agile_form_fields/select.rb +281 -0
- data/app/models/agile_form_fields/submit_tag.rb +58 -0
- data/app/models/agile_form_fields/text_area.rb +61 -0
- data/app/models/agile_form_fields/text_autocomplete.rb +171 -0
- data/app/models/agile_form_fields/text_field.rb +55 -0
- data/app/models/agile_form_fields/text_with_select.rb +94 -0
- data/app/models/agile_form_fields/tree_select.rb +170 -0
- data/app/models/ar_big_table.rb +82 -0
- data/app/models/ar_big_table_value.rb +53 -0
- data/app/models/ar_category.rb +109 -0
- data/app/models/ar_design.rb +116 -0
- data/app/models/ar_filter.rb +200 -0
- data/app/models/ar_folder_permission.rb +50 -0
- data/app/models/ar_folder_rule.rb +47 -0
- data/app/models/ar_gallery.rb +53 -0
- data/app/models/ar_image.rb +198 -0
- data/app/models/ar_internals.rb +60 -0
- data/app/models/ar_journal.rb +46 -0
- data/app/models/ar_json_ld.rb +131 -0
- data/app/models/ar_key_value_store.rb +128 -0
- data/app/models/ar_link.rb +48 -0
- data/app/models/ar_memory.rb +172 -0
- data/app/models/ar_menu.rb +144 -0
- data/app/models/ar_menu_item.rb +106 -0
- data/app/models/ar_page.rb +74 -0
- data/app/models/ar_part.rb +66 -0
- data/app/models/ar_permission.rb +180 -0
- data/app/models/ar_permission_rule.rb +65 -0
- data/app/models/ar_policy.rb +78 -0
- data/app/models/ar_policy_rule.rb +65 -0
- data/app/models/ar_poll.rb +74 -0
- data/app/models/ar_poll_item.rb +47 -0
- data/app/models/ar_poll_result.rb +38 -0
- data/app/models/ar_removed_url.rb +42 -0
- data/app/models/ar_role.rb +84 -0
- data/app/models/ar_setup.rb +115 -0
- data/app/models/ar_site.rb +68 -0
- data/app/models/ar_temp.rb +150 -0
- data/app/models/ar_user.rb +72 -0
- data/app/models/ar_user_group.rb +38 -0
- data/app/models/ar_user_role.rb +54 -0
- data/app/models/ar_visit.rb +41 -0
- data/app/models/concerns/ar_page_concern.rb +128 -0
- data/app/models/concerns/ar_part_concern.rb +48 -0
- data/app/models/concerns/ar_piece_concern.rb +48 -0
- data/app/models/concerns/ar_policy_rule_concern.rb +87 -0
- data/app/models/concerns/ar_seo_concern.rb +66 -0
- data/app/models/concerns/ar_site_concern.rb +103 -0
- data/app/models/concerns/ar_user_concern.rb +195 -0
- data/app/renderers/agile_common_renderer.rb +93 -0
- data/app/renderers/agile_renderer.rb +59 -0
- data/app/renderers/ar_ad_renderer.rb +219 -0
- data/app/renderers/ar_captcha_renderer.rb +113 -0
- data/app/renderers/ar_common_renderer.rb +90 -0
- data/app/renderers/ar_gallery_renderer.rb +107 -0
- data/app/renderers/ar_menu_renderer.rb +195 -0
- data/app/renderers/ar_page_renderer.rb +147 -0
- data/app/renderers/ar_part_renderer.rb +235 -0
- data/app/renderers/ar_piece_renderer.rb +119 -0
- data/app/renderers/ar_poll_renderer.rb +272 -0
- data/app/views/agile/_edit_stuff.html.erb +57 -0
- data/app/views/agile/_form.html.erb +24 -0
- data/app/views/agile/_result.html.erb +28 -0
- data/app/views/agile/edit.html.erb +13 -0
- data/app/views/agile/error.html.erb +2 -0
- data/app/views/agile/index.html.erb +14 -0
- data/app/views/agile/login.html.erb +19 -0
- data/app/views/agile/new.html.erb +12 -0
- data/app/views/agile_common/_help.html.erb +18 -0
- data/app/views/agile_common/_iframe_edit.html.erb +2 -0
- data/app/views/agile_common/paste_clipboard.html.erb +17 -0
- data/app/views/layouts/agile.html.erb +17 -0
- data/app/views/layouts/content.html.erb +20 -0
- data/app/views/models/dump_models.html.erb +47 -0
- data/config/initializers/kaminari_patch.rb +56 -0
- data/config/locales/agile_de.yml +138 -0
- data/config/locales/agile_en.yml +162 -0
- data/config/locales/agile_sl.yml +163 -0
- data/config/locales/datetimepicker.yml +19 -0
- data/config/locales/de.yml +231 -0
- data/config/locales/en.yml +13 -0
- data/config/locales/kaminari.yml +26 -0
- data/config/locales/models_en.yml +1032 -0
- data/config/locales/models_sl.yml +1065 -0
- data/config/locales/sl.yml +211 -0
- data/db/migrate/20240120160001_add_sessions_table.rb +12 -0
- data/db/migrate/20240120160002_ar_big_table.rb +17 -0
- data/db/migrate/20240120160003_ar_big_table_value.rb +18 -0
- data/db/migrate/20240120160004_ar_category.rb +22 -0
- data/db/migrate/20240120160005_ar_design.rb +20 -0
- data/db/migrate/20240120160006_ar_filter.rb +17 -0
- data/db/migrate/20240120160007_ar_gallery.rb +21 -0
- data/db/migrate/20240120160008_ar_journal.rb +19 -0
- data/db/migrate/20240120160009_ar_key_value_store.rb +11 -0
- data/db/migrate/20240120160010_ar_link.rb +19 -0
- data/db/migrate/20240120160011_ar_memory.rb +8 -0
- data/db/migrate/20240120160012_ar_menu.rb +21 -0
- data/db/migrate/20240120160013_ar_menu_item.rb +28 -0
- data/db/migrate/20240120160014_ar_page.rb +50 -0
- data/db/migrate/20240120160015_ar_part.rb +33 -0
- data/db/migrate/20240120160016_ar_permission.rb +16 -0
- data/db/migrate/20240120160017_ar_permission_rule.rb +17 -0
- data/db/migrate/20240120160018_ar_piece.rb +28 -0
- data/db/migrate/20240120160019_ar_policy.rb +21 -0
- data/db/migrate/20240120160020_ar_policy_rule.rb +18 -0
- data/db/migrate/20240120160021_ar_poll.rb +27 -0
- data/db/migrate/20240120160022_ar_poll_item.rb +23 -0
- data/db/migrate/20240120160023_ar_poll_result.rb +14 -0
- data/db/migrate/20240120160024_ar_removed_url.rb +16 -0
- data/db/migrate/20240120160025_ar_role.rb +17 -0
- data/db/migrate/20240120160026_ar_site.rb +37 -0
- data/db/migrate/20240120160027_ar_temp.rb +11 -0
- data/db/migrate/20240120160028_ar_user.rb +42 -0
- data/db/migrate/20240120160029_ar_user_group.rb +12 -0
- data/db/migrate/20240120160030_ar_user_role.rb +18 -0
- data/db/migrate/20240120160031_ar_visit.rb +15 -0
- data/db/migrate/20240703016001_ar_setup.rb +16 -0
- data/db/migrate/20240703016002_ar_folder_permission.rb +15 -0
- data/db/migrate/20240703016003_ar_folder_rule.rb +14 -0
- data/db/migrate/20250115000001_ar_image.rb +25 -0
- data/lib/agile/configuration.rb +43 -0
- data/lib/agile/engine.rb +29 -0
- data/lib/agile/version.rb +27 -0
- data/lib/agile.rb +282 -0
- data/lib/agile_rails.rb +1 -0
- data/lib/generators/agile/USAGE +11 -0
- data/lib/generators/agile/new_form_generator.rb +369 -0
- data/lib/generators/convert_to_ar/convert_to_ar_generator.rb +158 -0
- data/lib/tasks/agile_db_clone.rake +132 -0
- data/lib/tasks/agile_db_export_to_yaml.rake +37 -0
- data/lib/tasks/agile_db_migrate.rake +35 -0
- metadata +414 -0
@@ -0,0 +1,645 @@
|
|
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
|
+
# AgileEditHelper module defines helper methods used by AgileRails form edit action. Output is controlled by
|
27
|
+
# data found in 3 major sections of AgileRails form: index, data_set and form sections.
|
28
|
+
#
|
29
|
+
###########################################################################
|
30
|
+
module AgileEditHelper
|
31
|
+
|
32
|
+
############################################################################
|
33
|
+
# Will return value when internal or additional parameters are defined in action
|
34
|
+
# Subroutine of agile_actions_for_form.
|
35
|
+
############################################################################
|
36
|
+
def agile_value_for_parameter(param, current_document = nil)#:nodoc:
|
37
|
+
if param.class == Hash
|
38
|
+
agile_internal_var(param['object'] ||= 'record', param['method'], current_document)
|
39
|
+
elsif param.to_s.match(/record|document/)
|
40
|
+
current_document ? current_document : @record
|
41
|
+
else
|
42
|
+
param
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
############################################################################
|
47
|
+
# Creates actions div for edit form.
|
48
|
+
#
|
49
|
+
# Displaying readonly form turned out to be challenge. For now when readonly parameter
|
50
|
+
# has value 2, back link will force readonly form. Value 1 or not set will result in
|
51
|
+
# normal link.
|
52
|
+
############################################################################
|
53
|
+
def agile_is_action_active?(options)
|
54
|
+
return true unless options['active']
|
55
|
+
|
56
|
+
# alias record and document so both can be used in eval
|
57
|
+
record = document = @record
|
58
|
+
option = options['active']
|
59
|
+
case
|
60
|
+
# usually only for test
|
61
|
+
when option.class == TrueClass || option['eval'].class == TrueClass then true
|
62
|
+
|
63
|
+
when option.class == String then
|
64
|
+
if option.match(/new_record/i)
|
65
|
+
(@record.new_record? && option == 'new_record') || (!@record.new_record? && option == 'not_new_record')
|
66
|
+
elsif option.match(/\./)
|
67
|
+
# shortcut for method and eval option
|
68
|
+
agile_process_eval(option, self)
|
69
|
+
else
|
70
|
+
eval(option['eval'])
|
71
|
+
end
|
72
|
+
|
73
|
+
# direct evaluate expression
|
74
|
+
when option['eval'] then
|
75
|
+
eval(option['eval'])
|
76
|
+
|
77
|
+
# if record present send record otherwise send self as parameter
|
78
|
+
when option['method'] then
|
79
|
+
agile_process_eval(option['method'], self)
|
80
|
+
|
81
|
+
else
|
82
|
+
false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
############################################################################
|
87
|
+
# Creates actions div for edit form.
|
88
|
+
#
|
89
|
+
# Displaying readonly form turned out to be challenge. For now when readonly parameter
|
90
|
+
# has value 2, back link will force readonly form. Value 1 or not set will result in
|
91
|
+
# normal link.
|
92
|
+
############################################################################
|
93
|
+
def agile_actions_for_form(position)
|
94
|
+
actions_pos = agile_check_and_default(@form['form']['actions_position'], Agile.config(:default_actions_position), %w[top bottom both])
|
95
|
+
return '' if actions_pos != 'both' && (position != actions_pos)# == 'bottom') || (position == 'bottom' && actions_pos == 'top')
|
96
|
+
|
97
|
+
# create standard actions
|
98
|
+
actions = @form['form']['actions'] || {}
|
99
|
+
std_actions = Agile.config(:form_standard_actions)
|
100
|
+
std_actions = { 1 => 'back' } if @form['readonly'] # readonly
|
101
|
+
if actions.class == String
|
102
|
+
actions = process_standard_actions(actions, std_actions)
|
103
|
+
elsif actions['standard']
|
104
|
+
actions.merge!(std_actions)
|
105
|
+
actions.delete('standard')
|
106
|
+
end
|
107
|
+
|
108
|
+
# some actions have meaning only when editing
|
109
|
+
if @record.try(:id).nil?
|
110
|
+
actions_remove_action(actions, 'new', 'enable', 'refresh')
|
111
|
+
# enable disable if active field is present
|
112
|
+
elsif @record.has_attribute?(:active)
|
113
|
+
index = actions.find { |k, v| v.is_a?(String) && v == 'enable' }
|
114
|
+
actions[index.first] = (@record.active ? 'disable' : 'enable') if index
|
115
|
+
else
|
116
|
+
actions_remove_action(actions, 'enable')
|
117
|
+
end
|
118
|
+
# Actions are strictly forbidden
|
119
|
+
if @form['form']['actions'] && agile_dont?(@form['form']['actions'])
|
120
|
+
actions = []
|
121
|
+
end
|
122
|
+
|
123
|
+
# request for close window button present
|
124
|
+
if actions.kind_of?(Hash) && params[:window_close].present?
|
125
|
+
case params[:window_close].to_i
|
126
|
+
when 0
|
127
|
+
actions[1] = 'close'
|
128
|
+
actions_remove_action(actions, 'new')
|
129
|
+
|
130
|
+
when 1, 2
|
131
|
+
actions = { 1 => 'close' }
|
132
|
+
end
|
133
|
+
# if save & back present with close action change it to save
|
134
|
+
index = actions.find { |k, v| v.is_a?(String) && v == 'save&back' }
|
135
|
+
actions[index.first] = 'save' if index
|
136
|
+
end
|
137
|
+
|
138
|
+
# select only integer keys and sort
|
139
|
+
actions = actions.to_a.select{ _1.first.is_a?(Integer) }.sort{ |x, y| x[0] <=> y[0] }
|
140
|
+
# Add spinner to the beginning
|
141
|
+
html = %(<span class="ar-spinner">#{mi_icon('settings-o spin')}</span><ul class="ar-edit-menu #{position}">)
|
142
|
+
|
143
|
+
actions.each do |key, options|
|
144
|
+
session[:form_processing] = "form:actions: #{key} #{options}"
|
145
|
+
next if options.nil? # yes it happens
|
146
|
+
|
147
|
+
parms = @form_params.clone
|
148
|
+
if options.class == String
|
149
|
+
next if @form['readonly'] && !options.match(/back|close/)
|
150
|
+
|
151
|
+
partial =
|
152
|
+
case options
|
153
|
+
|
154
|
+
when 'save&back', 'save'
|
155
|
+
html += form_submit_action(options) # already comes with li tags
|
156
|
+
next
|
157
|
+
|
158
|
+
when 'back', 'cancel'
|
159
|
+
# If return_to is present link directly to URL
|
160
|
+
if parms['xreturn_to'] # disabled for now
|
161
|
+
agile_link_to( 'agile.back', 'arrow_back', parms['return_to'], class: 'ar-link' )
|
162
|
+
else
|
163
|
+
parms['action'] = 'index'
|
164
|
+
parms['readonly'] = parms['readonly'].to_s.to_i < 2 ? nil : 1
|
165
|
+
|
166
|
+
agile_link_to( 'agile.back', 'arrow_back', parms, class: 'ar-link' )
|
167
|
+
end
|
168
|
+
|
169
|
+
when 'new'
|
170
|
+
parms['action'] = options
|
171
|
+
agile_link_to( 'agile.new', 'add', parms, class: 'ar-link')
|
172
|
+
|
173
|
+
when 'enable', 'disable'
|
174
|
+
parms['operation'] = options
|
175
|
+
parms['id'] = @record.id
|
176
|
+
icon = (options == 'enable' ? 'check_box-o' : 'check_box_outline_blank')
|
177
|
+
agile_link_to( "agile.#{options}",icon, parms, method: :delete, class: 'ar-link' )
|
178
|
+
|
179
|
+
when 'refresh'
|
180
|
+
%(<div class="ar-link refresh">#{mi_icon('refresh')} #{t('agile.refresh')}</div>)
|
181
|
+
|
182
|
+
when 'close'
|
183
|
+
close = params[:window_close].to_i
|
184
|
+
if close < 2
|
185
|
+
%(<div class="ar-link close">#{mi_icon('close')} #{t('agile.close')}</div>)
|
186
|
+
else
|
187
|
+
%(<div class="ar-link back">#{mi_icon('close')} #{t('agile.close')}</div>)
|
188
|
+
end
|
189
|
+
|
190
|
+
else
|
191
|
+
"err1 #{key}=>#{options}"
|
192
|
+
end
|
193
|
+
html += "<li>#{partial}</li>"
|
194
|
+
|
195
|
+
# non standard actions
|
196
|
+
else
|
197
|
+
# action will be displayed when show: always or readonly option is declared and form is readonly
|
198
|
+
next if @form['readonly'] && !%w[readonly always].include?(options['show'].to_s)
|
199
|
+
|
200
|
+
options['title'] = t("#{options['title'].downcase}", options['title']) if options['title']
|
201
|
+
html +=
|
202
|
+
case
|
203
|
+
# submit button
|
204
|
+
when options['type'] == 'submit'
|
205
|
+
form_submit_action(options)
|
206
|
+
|
207
|
+
# ajax or link button
|
208
|
+
when %w(ajax link window popup).include?(options['type'])
|
209
|
+
agile_link_ajax_window_submit_action(options, @record)
|
210
|
+
|
211
|
+
# Javascript action
|
212
|
+
when options['type'] == 'script'
|
213
|
+
agile_script_action(options)
|
214
|
+
else
|
215
|
+
'<li>err2</li>'
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
(html += '</ul>').html_safe
|
221
|
+
end
|
222
|
+
|
223
|
+
############################################################################
|
224
|
+
# Create background div and table definitions for dataset.
|
225
|
+
############################################################################
|
226
|
+
def agile_background_for_dataset(start)
|
227
|
+
if start == :start
|
228
|
+
style = @form.dig('index', 'data_set', 'table_style')
|
229
|
+
html = '<div class="ar-result-div" '
|
230
|
+
html += (style ? 'style="overflow-x: scroll;" >' : '>')
|
231
|
+
|
232
|
+
html += "\n<div class=\"ar-result #{@form['index']['data_set']['table_class']}\" "
|
233
|
+
html += ( style ? "style=\"#{style}\" >" : '>')
|
234
|
+
else
|
235
|
+
html = '</div></div>'
|
236
|
+
end
|
237
|
+
html.html_safe
|
238
|
+
end
|
239
|
+
|
240
|
+
############################################################################
|
241
|
+
# Checks if value is defined and sets default. If values are sent it also checks
|
242
|
+
# if value is found in values. If not it will report error and set value to default.
|
243
|
+
# Subroutine of agile_fields_for_tab.
|
244
|
+
############################################################################
|
245
|
+
def agile_check_and_default(value, default, values = nil) #:nodoc:
|
246
|
+
return default if value.nil?
|
247
|
+
# check if value is within allowed values
|
248
|
+
if values
|
249
|
+
if !values.index(value)
|
250
|
+
# parameters should be in downcase. Check downcase version.
|
251
|
+
if n = values.index(value.downcase)
|
252
|
+
return values[n]
|
253
|
+
else
|
254
|
+
logger.error("AgileRails Forms: Value #{value} not within values [#{values.join(',')}]. Default #{default} used!")
|
255
|
+
return default
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
value
|
260
|
+
end
|
261
|
+
|
262
|
+
############################################################################
|
263
|
+
# Creates input fields defined in form options
|
264
|
+
############################################################################
|
265
|
+
def agile_fields_for_form
|
266
|
+
html = "<div id='data_fields' " + (@form['form']['height'] ? "style=\"height: #{@form['form']['height']}px;\">" : '>')
|
267
|
+
@js ||= ''
|
268
|
+
@css ||= ''
|
269
|
+
# fields
|
270
|
+
if (form_fields = @form['form']['fields'])
|
271
|
+
html += agile_input_form(form_fields) + '</div>'
|
272
|
+
elsif @form['form']['tabs'] #tabs
|
273
|
+
html = agile_tabs_form()
|
274
|
+
end
|
275
|
+
# add last_updated_at hidden field so controller can check if record was updated in db during editing
|
276
|
+
html += hidden_field(nil, :last_updated_at, value: @record.updated_at.to_i) if @record.respond_to?(:updated_at)
|
277
|
+
# add form time stamp to prevent double form submit
|
278
|
+
html += hidden_field(nil, :form_time_stamp, value: Time.now.to_i)
|
279
|
+
# add javascript code if defined by form
|
280
|
+
@js += "\n#{@form['script']} #{@form['js']}"
|
281
|
+
@css += "\n#{@form['css']}\n#{@form['form']['css']}"
|
282
|
+
html.html_safe
|
283
|
+
end
|
284
|
+
|
285
|
+
############################################################################
|
286
|
+
# Creates head form div. Head form div is used to display header data useful
|
287
|
+
# to be seen even when tabs are switched.
|
288
|
+
############################################################################
|
289
|
+
def agile_head_for_form
|
290
|
+
@css ||= ''
|
291
|
+
head = @form['form']['head']
|
292
|
+
return '' if head.nil?
|
293
|
+
|
294
|
+
html = %(<div class="ar-head #{head['class']}">\n<div class="ar-row">)
|
295
|
+
split = head['split'] || 4
|
296
|
+
percent = 100/split
|
297
|
+
current = 0
|
298
|
+
head_fields = head.select {|field| field.class == Integer }
|
299
|
+
head_fields.to_a.sort.each do |number, options|
|
300
|
+
session[:form_processing] = "form: head: #{number}=#{options}"
|
301
|
+
# Label
|
302
|
+
caption = options['caption']
|
303
|
+
span = options['span'] || 1
|
304
|
+
@css += "\n#{options['css']}" unless options['css'].blank?
|
305
|
+
label = if caption.blank?
|
306
|
+
''
|
307
|
+
elsif options['name'] == caption
|
308
|
+
t_label_for_field(options['name'], options['name'].capitalize.gsub('_',' ') )
|
309
|
+
else
|
310
|
+
t(caption, caption)
|
311
|
+
end
|
312
|
+
# Field value
|
313
|
+
begin
|
314
|
+
field = if options['eval']
|
315
|
+
agile_process_column_eval(options, @record)
|
316
|
+
else
|
317
|
+
@record.send(options['name'])
|
318
|
+
end
|
319
|
+
rescue Exception => e
|
320
|
+
agile_log_exception(e, 'agile_head_for_form')
|
321
|
+
field = '!!!Error'
|
322
|
+
end
|
323
|
+
#
|
324
|
+
klass = agile_style_or_class(nil, options['class'], field, @record)
|
325
|
+
style = agile_style_or_class(nil, options['style'], field, @record)
|
326
|
+
html += %(<div class="ar-column #{klass}" style="width:#{percent*span}%;#{style}">
|
327
|
+
#{label.blank? ? '' : "<span class=\"label\">#{label}</span>"}
|
328
|
+
<span id="head-#{options['name']}" class="field">#{field}</span>
|
329
|
+
</div>)
|
330
|
+
current += span
|
331
|
+
if current == split
|
332
|
+
html += %(</div>\n<div class="ar-row">)
|
333
|
+
current = 0
|
334
|
+
end
|
335
|
+
end
|
336
|
+
html += '</div></div>'
|
337
|
+
html.html_safe
|
338
|
+
end
|
339
|
+
|
340
|
+
############################################################################
|
341
|
+
# Returns username for id. Subroutine of agile_document_statistics
|
342
|
+
###########################################################################
|
343
|
+
def agile_document_user_for(field_name) #:nodoc:
|
344
|
+
return if @record[field_name].nil?
|
345
|
+
|
346
|
+
user = ArUser.find(@record[field_name])
|
347
|
+
user ? user.name : @record[field_name]
|
348
|
+
end
|
349
|
+
|
350
|
+
############################################################################
|
351
|
+
# Creates current document statistics div (created_by, created_at, ....) at the bottom of edit form.
|
352
|
+
# + lots of more. At the moment also adds icon for dumping current record as json text.
|
353
|
+
############################################################################
|
354
|
+
def agile_document_statistics
|
355
|
+
return '' if @record.id.nil? || agile_dont?(@form['form']['info'])
|
356
|
+
|
357
|
+
html = %(<div id="ar-document-info">#{mi_icon('info md-18')}</div> <div id="ar-document-info-popup" class="div-hidden">)
|
358
|
+
u = agile_document_user_for('created_by')
|
359
|
+
html += %(<div><span>#{t('agile.created_by', 'Created by')}: </span><span>#{u}</span></div>) if u
|
360
|
+
u = agile_document_user_for('updated_by')
|
361
|
+
html += %(<div><span>#{t('agile.updated_by', 'Updated by')}: </span><span>#{u}</span></div>) if u
|
362
|
+
|
363
|
+
html += %(<div><span>#{t('agile.created_at', 'Created at')}: </span><span>#{agile_format_value(@record.created_at)}</span></div>) if @record['created_at']
|
364
|
+
html += %(<div><span>#{t('agile.updated_at', 'Updated at')}: </span><span>#{agile_format_value(@record.updated_at)}</span></div>) if @record['updated_at']
|
365
|
+
# copy to clipboard icon
|
366
|
+
parms = params.clone
|
367
|
+
parms[:controller] = :agile_common
|
368
|
+
parms[:action] = :copy_clipboard
|
369
|
+
url = url_for(parms.permit!)
|
370
|
+
html += '<div>'
|
371
|
+
html += mi_icon('content_copy-o md-18', class: 'ar-link-img ar-link-ajax',
|
372
|
+
'data-url' => url, 'data-request' => 'get', title: t('agile.copy_clipboard') )
|
373
|
+
|
374
|
+
url = url_for(controller: :agile, action: :run, table: 'ar_journal', control: 'agile.filter_on',
|
375
|
+
filter_oper: 'eq', filter_field: 'id', filter_value: "#{@form['table']};#{@record.id}")
|
376
|
+
|
377
|
+
html += mi_icon('history md-18', class: 'ar-link-img ar-window-open',
|
378
|
+
'data-url' => url, title: t('helpers.label.ar_journal.table_title') )
|
379
|
+
html += %(<span>ID: </span>
|
380
|
+
<span id="record-id" class="hover" onclick="agile_copy_to_clipboard('record-id');" title="Copy document ID to clipboard">#{@record.id}
|
381
|
+
</span>)
|
382
|
+
|
383
|
+
(html += '</div></div>').html_safe
|
384
|
+
end
|
385
|
+
|
386
|
+
############################################################################
|
387
|
+
# Updates form prior to processing form
|
388
|
+
############################################################################
|
389
|
+
def agile_update_form
|
390
|
+
# update form for steps options
|
391
|
+
if @form.dig('form', 'steps')
|
392
|
+
agile_update_form_steps
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
############################################################################
|
397
|
+
# If form is divided into two parts, this method gathers html to be painted
|
398
|
+
# on right side of the form pane.
|
399
|
+
############################################################################
|
400
|
+
def agile_form_left
|
401
|
+
yaml = @form.dig('form', 'form_left')
|
402
|
+
return '' unless yaml
|
403
|
+
|
404
|
+
html = ''
|
405
|
+
html += agile_process_eval(yaml['eval'], self) if yaml['eval']
|
406
|
+
|
407
|
+
html.html_safe
|
408
|
+
end
|
409
|
+
|
410
|
+
private
|
411
|
+
|
412
|
+
############################################################################
|
413
|
+
# Creates top or bottom horizontal line on form.
|
414
|
+
#
|
415
|
+
# @param [String] location (top or bottom)
|
416
|
+
# @param [Object] options yaml field definition
|
417
|
+
#
|
418
|
+
# @return [String] html code for drawing a line
|
419
|
+
############################################################################
|
420
|
+
def agile_top_bottom_line(location, options)
|
421
|
+
if options["#{location}-line"] || options['line'].to_s == location.to_s
|
422
|
+
'</div><div class="ar-form-section"><div class="ar-separator"></div>'
|
423
|
+
else
|
424
|
+
''
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
############################################################################
|
429
|
+
# Creates submit action on form. Subroutine of agile_actions_for_form.
|
430
|
+
############################################################################
|
431
|
+
def form_submit_action(options) #:nodoc:
|
432
|
+
if options.is_a?(String)
|
433
|
+
options = { 'type' => 'submit', 'caption' => t("agile.#{options}"), 'params' => {} }
|
434
|
+
end
|
435
|
+
caption = options['caption'] || 'agile.save'
|
436
|
+
icon = options['icon'] || 'save'
|
437
|
+
parameters = {}
|
438
|
+
options['params'].each { |k, v| parameters[k] = agile_value_for_parameter(v) } if options['params']
|
439
|
+
if agile_is_action_active?(options)
|
440
|
+
'<li>' +
|
441
|
+
agile_submit_tag(caption, icon, { data: parameters, title: options['title'] }) +
|
442
|
+
'</li>'
|
443
|
+
else
|
444
|
+
%(<li><div class="ar-link-no">#{mi_icon(icon)} #{caption}</div></li>)
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
############################################################################
|
449
|
+
# Creates input fields for one tab. Subroutine of agile_fields_for_form.
|
450
|
+
############################################################################
|
451
|
+
def agile_input_form(fields_on_tab) #:nodoc:
|
452
|
+
html = '<div class="ar-form"><div class="ar-form-section">'
|
453
|
+
labels_pos = agile_check_and_default(@form['form']['labels_position'], Agile.config(:default_labels_position), %w[top left])
|
454
|
+
hidden_fields = ''
|
455
|
+
group_option, group_count = 0, 0
|
456
|
+
# Select form fields and sort them by key
|
457
|
+
form_fields = fields_on_tab.select { |field| field.is_a?(Integer) }
|
458
|
+
form_fields.to_a.sort.each do |number, options|
|
459
|
+
session[:form_processing] = "form:fields: #{number}=#{options}"
|
460
|
+
# ignore if edit_only singe field is required
|
461
|
+
next if params[:edit_only] && params[:edit_only] != options['name']
|
462
|
+
next if options.nil?
|
463
|
+
|
464
|
+
# hidden_fields. Add them at the end
|
465
|
+
if options['type'] == 'hidden_field'
|
466
|
+
hidden_fields << AgileFormFields::HiddenField.new(self, @record, options).render
|
467
|
+
next
|
468
|
+
end
|
469
|
+
# label
|
470
|
+
field_html, label, help = agile_field_label_help(options)
|
471
|
+
label = nil if agile_dont?(options['caption'])
|
472
|
+
# Line separator
|
473
|
+
html += agile_top_bottom_line(:top, options)
|
474
|
+
# Beginning of new row
|
475
|
+
if group_count == 0
|
476
|
+
html += '<div class="row-div">'
|
477
|
+
group_count = options['group'] || 1
|
478
|
+
group_option = options['group'] || 1
|
479
|
+
end
|
480
|
+
html += if labels_pos == 'top'
|
481
|
+
data_width = case group_option
|
482
|
+
when 2 then (group_count == 2 ? 40 : 70)
|
483
|
+
when 3 then [30, 30, 40][group_count - 1]
|
484
|
+
else 100
|
485
|
+
end
|
486
|
+
label = label.nil? ? '' : %(<label for="record_#{options['name']}">#{label} </label>)
|
487
|
+
%(
|
488
|
+
<div class="ar-form-label-top ar-align-left ar-width-#{data_width}" title="#{help}">
|
489
|
+
#{label}
|
490
|
+
<div id="td_record_#{options['name']}">#{field_html}</div>
|
491
|
+
</div> )
|
492
|
+
else
|
493
|
+
# no label
|
494
|
+
if label.nil?
|
495
|
+
label = ''
|
496
|
+
label_width = 0
|
497
|
+
data_width = 100
|
498
|
+
elsif group_option > 1
|
499
|
+
label_width = group_option != group_count ? 10 : 14
|
500
|
+
data_width = 21
|
501
|
+
else
|
502
|
+
label_width = 14
|
503
|
+
data_width = 85
|
504
|
+
end
|
505
|
+
help.gsub!('<br>',"\n") if help.present?
|
506
|
+
%(
|
507
|
+
<div class="ar-form-label ar-align-right ar-width-#{label_width}" title="#{help}">
|
508
|
+
<label for="record_#{options['name']}">#{label} </label>
|
509
|
+
</div>
|
510
|
+
<div id="td_record_#{options['name']}" class="ar-form-field ar-width-#{data_width}">#{field_html}</div>
|
511
|
+
)
|
512
|
+
end
|
513
|
+
# check if group end
|
514
|
+
if (group_count -= 1) == 0
|
515
|
+
html += '</div>'
|
516
|
+
# insert dummy div when only two fields in group
|
517
|
+
html += '<div></div>' if group_option == 2
|
518
|
+
end
|
519
|
+
|
520
|
+
html += agile_top_bottom_line(:bottom, options)
|
521
|
+
end
|
522
|
+
html += '</div></div>' + hidden_fields
|
523
|
+
end
|
524
|
+
|
525
|
+
############################################################################
|
526
|
+
# Will create html code required for input form with steps defined
|
527
|
+
############################################################################
|
528
|
+
def agile_steps_one_element(element, tab_name = nil)
|
529
|
+
def add_one_step(key, tab_name, key_number)
|
530
|
+
fields = tab_name ? @form['form']['tabs'][tab_name] : @form['form']['fields']
|
531
|
+
{ key_number => fields[key] }
|
532
|
+
end
|
533
|
+
|
534
|
+
key_number, fields = 0, {}
|
535
|
+
element.to_s.split(',').each do |particle|
|
536
|
+
if particle.match('-')
|
537
|
+
tabs_fields = tab_name ? @form['form']['tabs'][tab_name] : @form['form']['fields']
|
538
|
+
next if tabs_fields.nil?
|
539
|
+
|
540
|
+
start, to_end = particle.split('-').map(&:to_i)
|
541
|
+
tabs_fields.each_key { |key| fields.merge!(add_one_step(key, tab_name, key_number += 10)) if (start..to_end).include?(key) }
|
542
|
+
else
|
543
|
+
fields.merge!(add_one_step(particle.to_i, tab_name, key_number += 10))
|
544
|
+
end
|
545
|
+
end
|
546
|
+
fields
|
547
|
+
end
|
548
|
+
|
549
|
+
############################################################################
|
550
|
+
# Will create html code required for input form with steps defined and update
|
551
|
+
# actions.
|
552
|
+
############################################################################
|
553
|
+
def agile_update_form_steps
|
554
|
+
def add_step_to_form(index, step, next_step)
|
555
|
+
@form['form']['actions'][index]['params']['step'] = step
|
556
|
+
@form['form']['actions'][index]['params']['next_step'] = next_step
|
557
|
+
end
|
558
|
+
|
559
|
+
form = {}
|
560
|
+
step = params[:step].to_i
|
561
|
+
step_data = @form['form']['steps'].to_a[step - 1]
|
562
|
+
|
563
|
+
step_data.last.each do |element|
|
564
|
+
if element.first == 'fields'
|
565
|
+
form.merge!(agile_steps_one_element(element.second))
|
566
|
+
elsif element.first == 'tabs'
|
567
|
+
element.last.each do |tab_name, data|
|
568
|
+
form.merge!(agile_steps_one_element(data, tab_name))
|
569
|
+
end
|
570
|
+
end
|
571
|
+
end
|
572
|
+
# fraction updates of newly created form
|
573
|
+
form.deep_merge!(step_data.last['update']) if step_data.last['update']
|
574
|
+
# update steps data on form
|
575
|
+
add_step_to_form(10, step, step - 1)
|
576
|
+
add_step_to_form(20, step, step + 1)
|
577
|
+
add_step_to_form(100, step, step + 1)
|
578
|
+
# remove not needed steps
|
579
|
+
if step < 2
|
580
|
+
@form['form']['actions'].delete(10)
|
581
|
+
elsif step == @form['form']['steps'].size
|
582
|
+
@form['form']['actions'].delete(20)
|
583
|
+
end
|
584
|
+
@form['form']['actions'].delete(100) unless step == @form['form']['steps'].size
|
585
|
+
# update form_name and control name if defined
|
586
|
+
%w[1 10 20 100].each do |i|
|
587
|
+
next unless @form['form']['actions'][i.to_i]
|
588
|
+
|
589
|
+
@form['form']['actions'][i.to_i]['form_name'] = AgileHelper.form_param(params)
|
590
|
+
control = @form['control'] ? @form['control'] : @form['table']
|
591
|
+
@form['form']['actions'][i.to_i]['control'].sub!('x.', "#{control}.")
|
592
|
+
end
|
593
|
+
|
594
|
+
@form['form']['form_left'] ||= { 'eval' => 'agile_steps_menu_get'}
|
595
|
+
@form['form']['fields'] = form
|
596
|
+
end
|
597
|
+
|
598
|
+
############################################################################
|
599
|
+
# Will create html code required for input form with tabs
|
600
|
+
############################################################################
|
601
|
+
def agile_tabs_form
|
602
|
+
html, tabs, tab_data = '', [], ''
|
603
|
+
first_tab = true # first tab
|
604
|
+
tab_type = @form['form']['type'] || 'default'
|
605
|
+
tab_class = @form['form']['class'] || ''
|
606
|
+
tab_style = @form['form']['style'] || ''
|
607
|
+
|
608
|
+
@form['form']['tabs'].keys.sort.each do |tab_name|
|
609
|
+
next if tab_name.match('options')
|
610
|
+
|
611
|
+
# Tricky when editing single field. If field is not present on the tab skip to next tab
|
612
|
+
if params[:edit_only]
|
613
|
+
is_on_tab = false
|
614
|
+
@form['form']['tabs'][tab_name].each_value { |v| is_on_tab = true if params[:edit_only] == v['name'] }
|
615
|
+
next unless is_on_tab
|
616
|
+
end
|
617
|
+
tab_index = tab_name.delete("\s\n")
|
618
|
+
tab_label, tab_title = agile_tab_label_help(tab_name)
|
619
|
+
tabs << [tab_name, tab_label, tab_title, tab_index]
|
620
|
+
|
621
|
+
klass = "#{tab_type == 'accordion' ? 'ar-accordion' : ''} ar-form-accordion #{first_tab ? 'open' : ''} #{tab_class}"
|
622
|
+
tab_data += %(<div id="acc_#{tab_index}" class="#{klass}" title="#{tab_title}">#{tab_label}</div>)
|
623
|
+
tab_data += %(<div id="data_#{tab_index}")
|
624
|
+
tab_data += ' class="div-hidden"' unless first_tab
|
625
|
+
tab_data += (@form['form']['style'] ? %( style="#{tab_style};">) : '>')
|
626
|
+
tab_data += "#{agile_input_form(@form['form']['tabs'][tab_name])}</div>"
|
627
|
+
first_tab = false
|
628
|
+
end
|
629
|
+
|
630
|
+
if tab_type != 'accordion' #
|
631
|
+
# make it all work together
|
632
|
+
html += '<ul class="ar-form-ul" >'
|
633
|
+
first = true # first tab must be selected
|
634
|
+
tabs.each do |tab_name, tab_label, tab_title, tab_index|
|
635
|
+
html += %(<li id="li_#{tab_index}" data-div="#{tab_index}" title="#{tab_title}" class="ar-form-li)
|
636
|
+
html += ' ar-form-li-selected' if first
|
637
|
+
html += "\">#{tab_label}</li>"
|
638
|
+
first = false
|
639
|
+
end
|
640
|
+
html += '</ul>'
|
641
|
+
end
|
642
|
+
html + tab_data
|
643
|
+
end
|
644
|
+
|
645
|
+
end
|