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,1162 @@
|
|
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
|
+
# AgileApplicationHelper defines common helper methods for using with AgileRails.
|
27
|
+
#
|
28
|
+
###########################################################################
|
29
|
+
module AgileApplicationHelper
|
30
|
+
# page document
|
31
|
+
attr_reader :page
|
32
|
+
# design document
|
33
|
+
attr_reader :design
|
34
|
+
# site document
|
35
|
+
attr_reader :site
|
36
|
+
# menu document
|
37
|
+
attr_reader :menu
|
38
|
+
# selected menu_item document
|
39
|
+
attr_reader :menu_item
|
40
|
+
# tables url parameter
|
41
|
+
attr_reader :tables
|
42
|
+
# ids url parameter
|
43
|
+
attr_reader :ids
|
44
|
+
# form object
|
45
|
+
attr_reader :form
|
46
|
+
# options object
|
47
|
+
attr_reader :options
|
48
|
+
# part
|
49
|
+
attr_reader :part
|
50
|
+
|
51
|
+
# page title
|
52
|
+
attr_accessor :page_title
|
53
|
+
# all parts read from page, design, ...
|
54
|
+
attr_accessor :parts
|
55
|
+
#
|
56
|
+
attr_accessor :record
|
57
|
+
#
|
58
|
+
attr_accessor :footer_record
|
59
|
+
# json_ld
|
60
|
+
attr_reader :json_ld
|
61
|
+
|
62
|
+
############################################################################
|
63
|
+
# When @env is present then helper methods are called from @env object otherwise
|
64
|
+
# from self.
|
65
|
+
############################################################################
|
66
|
+
def _origin #:nodoc:
|
67
|
+
@env || self
|
68
|
+
end
|
69
|
+
|
70
|
+
############################################################################
|
71
|
+
# Writes out deprication msg. It also adds site_name to message, so it is easier to
|
72
|
+
# find where the message is comming from.
|
73
|
+
############################################################################
|
74
|
+
def agile_deprecate(msg)
|
75
|
+
ActiveSupport::Deprecation.warn("#{agile_get_site.name}: #{msg}")
|
76
|
+
end
|
77
|
+
|
78
|
+
############################################################################
|
79
|
+
# This is main method used for render parts of design into final HTML document.
|
80
|
+
#
|
81
|
+
# Parameters:
|
82
|
+
# [renderer] String or Symbol. Class name (in lowercase) that will be used to render final HTML code.
|
83
|
+
# If class name is provided without '_renderer' suffix it will be added automatically.
|
84
|
+
#
|
85
|
+
# When renderer has value :part, it is a shortcut for agile_render_part method which
|
86
|
+
# is used to draw parts of layout on design.
|
87
|
+
#
|
88
|
+
# [opts] Hash. Additional options that are passed to method. Options are merged with
|
89
|
+
# options set on site, design, page and passed to renderer object.
|
90
|
+
#
|
91
|
+
# Example:
|
92
|
+
# <%= agile_render(:ar_page, method: 'view', category: 'news') %>
|
93
|
+
############################################################################
|
94
|
+
def agile_render(renderer, opts = {})
|
95
|
+
return agile_render_part(renderer[:part]) if renderer.instance_of?(Hash)
|
96
|
+
|
97
|
+
opts[:edit_mode] = session[:edit_mode]
|
98
|
+
opts[:edit_params] = {}
|
99
|
+
|
100
|
+
opts = @options.merge(opts) # merge options with parameters passed on site, page, design ...
|
101
|
+
opts.symbolize_keys! # this makes lots of things easier
|
102
|
+
# Create renderer object
|
103
|
+
klass = renderer.to_s.downcase
|
104
|
+
klass += '_renderer' unless klass.match('_renderer')
|
105
|
+
begin
|
106
|
+
renderer_object = Kernel.const_get(klass.classify, Class.new).new(self, opts)
|
107
|
+
rescue Exception => e
|
108
|
+
Agile.dump_exception(e)
|
109
|
+
# obj = nil
|
110
|
+
end
|
111
|
+
|
112
|
+
if renderer_object
|
113
|
+
html = renderer_object.render_html.to_s
|
114
|
+
@css += renderer_object.render_css.to_s
|
115
|
+
html.html_safe
|
116
|
+
else
|
117
|
+
I18n.t 'agile.no_class', class: klass
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
########################################################################
|
122
|
+
# Used for designs with lots of common code and one (or more) part which differs.
|
123
|
+
# Point is to define design once and replace some parts of design dynamically.
|
124
|
+
# Design may be defined in site and design doc defines only parts that vary
|
125
|
+
# from page to page.
|
126
|
+
#
|
127
|
+
# Example: As used in design.
|
128
|
+
# <%= agile_render_part(@main) %>
|
129
|
+
#
|
130
|
+
# main variable is defined in design body for example:
|
131
|
+
#
|
132
|
+
# @main = Proc.new { render partial: 'parts/home' }
|
133
|
+
########################################################################
|
134
|
+
def agile_render_part(part)
|
135
|
+
case
|
136
|
+
when part.nil?
|
137
|
+
logger.error('ERROR agile_render_part! part is NIL !'); ''
|
138
|
+
# Send as array. Part may be defined with options on page. First element has
|
139
|
+
# name of element which defines what to do. If not defined default behaviour is
|
140
|
+
# called. That is what is defined in second part of array.
|
141
|
+
when part.instance_of?(Array)
|
142
|
+
if @options.dig(:settings, part.first)
|
143
|
+
#TODO to be defined
|
144
|
+
else
|
145
|
+
result = part.last.call
|
146
|
+
result.instance_of?(Array) ? result.first : result
|
147
|
+
end
|
148
|
+
when part.instance_of?(Proc)
|
149
|
+
result = part.call
|
150
|
+
result.instance_of?(Array) ? result.first : result
|
151
|
+
# Send as string. Evaluate content of string
|
152
|
+
when part.instance_of?(String)
|
153
|
+
eval part
|
154
|
+
# For future maybe. Just call objects to_s method.
|
155
|
+
else
|
156
|
+
part.to_s
|
157
|
+
end.html_safe
|
158
|
+
end
|
159
|
+
|
160
|
+
########################################################################
|
161
|
+
# Helper for rendering top CMS menu when in editing mode
|
162
|
+
########################################################################
|
163
|
+
def agile_page_top
|
164
|
+
# Evaluate some code if defined in design
|
165
|
+
eval(@design.code) if @design&.code.present?
|
166
|
+
|
167
|
+
session[:edit_mode] > 0 ? render(partial: 'agile/edit_stuff') : ''
|
168
|
+
end
|
169
|
+
|
170
|
+
########################################################################
|
171
|
+
# Helper for adding additional css and javascript code added by documents
|
172
|
+
# and renderers during page rendering.
|
173
|
+
########################################################################
|
174
|
+
def agile_page_bottom
|
175
|
+
%(<style>#{@css}</style>#{javascript_tag @js}).html_safe
|
176
|
+
end
|
177
|
+
|
178
|
+
############################################################################
|
179
|
+
# Creates title div for AgileRails dialogs. Title may also contain pagination section on right side if
|
180
|
+
# data_set is provided as parameter.
|
181
|
+
#
|
182
|
+
# Parameters:
|
183
|
+
# [text] String. Title caption.
|
184
|
+
# [data_set=nil] Document collection. If data_set is passed pagination links will be created.
|
185
|
+
|
186
|
+
# Returns:
|
187
|
+
# String. HTML code for title.
|
188
|
+
############################################################################
|
189
|
+
def agile_dialog_title(text, data_set = nil)
|
190
|
+
c = %(<div class="ar-title">#{text})
|
191
|
+
c += agile_help_button(data_set)
|
192
|
+
|
193
|
+
if data_set&.respond_to?(:current_page)
|
194
|
+
c += %(<div class="ar-paginate">#{paginate(data_set, params: { action: 'index', clear: 'no', filter: nil })}</div>)
|
195
|
+
end
|
196
|
+
c += '<div style="clear: both;"></div></div>'
|
197
|
+
c.html_safe
|
198
|
+
end
|
199
|
+
|
200
|
+
############################################################################
|
201
|
+
# Creates title for AgileRails forms edit dialog
|
202
|
+
#
|
203
|
+
# Returns:
|
204
|
+
# String. HTML code for title.
|
205
|
+
############################################################################
|
206
|
+
def agile_edit_title
|
207
|
+
session[:form_processing] = 'form:title:'
|
208
|
+
title = @form['form']['title']
|
209
|
+
# defined as form:title:edit
|
210
|
+
if title && title['edit'] && !@form['readonly']
|
211
|
+
t( title['edit'], title['edit'] )
|
212
|
+
elsif title && title['show'] && @form['readonly']
|
213
|
+
t( title['show'], title['show'] )
|
214
|
+
else
|
215
|
+
# concatenate title
|
216
|
+
c = "#{@form['readonly'] ? t('agile.show') : t('agile.edit')} : "
|
217
|
+
c += (@form['title'].instance_of?(String) ? t( @form['title'], @form['title'] ) : t_table_name(@form['table']))
|
218
|
+
title = title.try('field')
|
219
|
+
|
220
|
+
c += "#{@record[title]}" if title && @record.respond_to?(title)
|
221
|
+
c
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
############################################################################
|
226
|
+
# Creates title for AgileRails new dialog
|
227
|
+
#
|
228
|
+
# Returns:
|
229
|
+
# String. HTML code for title.
|
230
|
+
############################################################################
|
231
|
+
def agile_new_title
|
232
|
+
session[:form_processing] = 'form:title:'
|
233
|
+
title = @form.dig('form', 'title')
|
234
|
+
if title.is_a?(String) # defined as form:title
|
235
|
+
t(title, title)
|
236
|
+
elsif title&.dig('new') # defined as form:title:new
|
237
|
+
t(title['new'], title['new'])
|
238
|
+
else
|
239
|
+
# in memory structures
|
240
|
+
if @form['table'] == 'agile_memory'
|
241
|
+
return t( @form['title'], @form['title'] ) if @form['title']
|
242
|
+
|
243
|
+
t("#{@form['i18n_prefix']}.table_title", '')
|
244
|
+
else
|
245
|
+
"#{t('agile.new')} : #{t_table_name(@form['table'])}"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
############################################################################
|
251
|
+
# Similar to rails submit_tag, but also takes care of link icon, translation, ...
|
252
|
+
############################################################################
|
253
|
+
def agile_submit_tag(caption, icon, parms, rest = {})
|
254
|
+
icon_image = agile_icon_for_link(icon, nil)
|
255
|
+
%(<button type="submit" class="ar-submit" name="commit" value="#{t(caption, caption)}">#{icon_image} #{t(caption, caption)}</button>).html_safe
|
256
|
+
end
|
257
|
+
|
258
|
+
############################################################################
|
259
|
+
# Returns icon code if icon is specified
|
260
|
+
############################################################################
|
261
|
+
def agile_icon_for_link(icon, clas = 'ar-link-img')
|
262
|
+
return '' if icon.blank?
|
263
|
+
|
264
|
+
if icon.match(/\./)
|
265
|
+
_origin.image_tag(icon, class: clas)
|
266
|
+
elsif icon.match('<i')
|
267
|
+
icon
|
268
|
+
else
|
269
|
+
_origin.mi_icon(icon)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
############################################################################
|
274
|
+
# Similar to rails link_to, but also takes care of link icon, translation, ...
|
275
|
+
#
|
276
|
+
# Parameters:
|
277
|
+
# [String] caption : Caption or text created on link
|
278
|
+
# [String] icon : Icon used with the caption
|
279
|
+
# [Hash] parms : Standard parameters for link_to method (controller, action, id, table, form_name, ...)
|
280
|
+
# [Hash] rest : Standard rest parameters for link_to method (target, class, confirm ...)
|
281
|
+
############################################################################
|
282
|
+
def agile_link_to(caption, icon, parms, rest = {})
|
283
|
+
url, body, parms, rest = _agile_link_to(caption, icon, parms, rest)
|
284
|
+
url ? _origin.link_to(body, url, rest) : _origin.link_to(body, parms, rest)
|
285
|
+
end
|
286
|
+
|
287
|
+
############################################################################
|
288
|
+
# Creates link that will respond to json data returned by invoked action
|
289
|
+
#
|
290
|
+
# Parameters:
|
291
|
+
# [String] caption : Caption or text created on link
|
292
|
+
# [String] icon : Icon used with the caption
|
293
|
+
# [Hash] parms : Standard parameters for link_to method (controller, action, id, table, form_name, ...)
|
294
|
+
# [Hash] rest : Standard rest parameters for link_to method (target, class, confirm ...)
|
295
|
+
############################################################################
|
296
|
+
def agile_ajax_link_to(caption, icon, parms, rest = {})
|
297
|
+
url, body, parms, rest = _agile_link_to(caption, icon, parms, rest)
|
298
|
+
url ||= _origin.url_for(parms)
|
299
|
+
clas = "ar-link-ajax #{rest.delete('class')}"
|
300
|
+
rest['data-confirm'] ||= rest.delete('confirm')
|
301
|
+
rest_data = rest.map { "#{_1}=\"#{_2}\"" }.join(', ')
|
302
|
+
|
303
|
+
%(<span class="#{clas}" data-url="#{url}" #{rest_data}>#{body}</span>).html_safe
|
304
|
+
end
|
305
|
+
|
306
|
+
############################################################################
|
307
|
+
# Will use some default values and return data for previous link_to methods
|
308
|
+
############################################################################
|
309
|
+
def _agile_link_to(caption, icon, parms, rest) # :nodoc:
|
310
|
+
icon_pos = 'first'
|
311
|
+
if parms.instance_of?(Hash)
|
312
|
+
parms.stringify_keys!
|
313
|
+
rest.stringify_keys!
|
314
|
+
url = parms.delete('url')
|
315
|
+
rest['target'] ||= parms.delete('target')
|
316
|
+
parms['controller'] ||= 'agile'
|
317
|
+
icon_pos = parms.delete('icon_pos') || 'first'
|
318
|
+
end
|
319
|
+
|
320
|
+
icon_image = agile_icon_for_link(icon)
|
321
|
+
if caption
|
322
|
+
caption = t(caption, caption)
|
323
|
+
icon_image += ' ' if icon_image
|
324
|
+
end
|
325
|
+
body = (%w[first left].include?(icon_pos) ? "#{icon_image}#{caption}" : "#{caption} #{icon_image}").html_safe
|
326
|
+
[url, body, parms, rest]
|
327
|
+
end
|
328
|
+
|
329
|
+
####################################################################
|
330
|
+
# Returns flash messages formatted for display on message div.
|
331
|
+
#
|
332
|
+
# Returns:
|
333
|
+
# String. HTML code formatted for display.
|
334
|
+
####################################################################
|
335
|
+
def agile_flash_messages()
|
336
|
+
err = _origin.flash[:error]
|
337
|
+
war = _origin.flash[:warning]
|
338
|
+
inf = _origin.flash[:info]
|
339
|
+
note = _origin.flash[:note]
|
340
|
+
html = ''
|
341
|
+
unless err.nil? and war.nil? and inf.nil? and note.nil?
|
342
|
+
html += "<div class=\"ar-form-error\">#{err}</div>" if err
|
343
|
+
html += "<div class=\"ar-form-warning\">#{war}</div>" if war
|
344
|
+
html += "<div class=\"ar-form-info\">#{inf}</div>" if inf
|
345
|
+
html += note if note
|
346
|
+
_origin.flash[:error] = nil
|
347
|
+
_origin.flash[:warning] = nil
|
348
|
+
_origin.flash[:info] = nil
|
349
|
+
_origin.flash[:note] = nil
|
350
|
+
end
|
351
|
+
# Update fields on the form
|
352
|
+
if _origin.flash[:update]
|
353
|
+
html += "<div class=\"ar-form-updates\">\n"
|
354
|
+
_origin.flash[:update].each do |field, value|
|
355
|
+
html += %(<div data-field="#{field}" data-value="#{value}"></div>\n)
|
356
|
+
end
|
357
|
+
html += '</div>'
|
358
|
+
_origin.flash[:update] = nil
|
359
|
+
end
|
360
|
+
html.html_safe
|
361
|
+
end
|
362
|
+
|
363
|
+
########################################################################
|
364
|
+
# Decamelizes string. This probably doesn't work very good with non ascii chars.
|
365
|
+
# Therefore it is very unwise to use non ascii chars for table (table) names.
|
366
|
+
#
|
367
|
+
# Parameters:
|
368
|
+
# [Object] model_string. String or model to be converted into decamelized string.
|
369
|
+
#
|
370
|
+
# Returns:
|
371
|
+
# String. Decamelized string.
|
372
|
+
########################################################################
|
373
|
+
def decamelize_type(model_string)
|
374
|
+
model_string&.to_s&.underscore
|
375
|
+
end
|
376
|
+
|
377
|
+
####################################################################
|
378
|
+
# Returns validation error messages for the document (record) formatted for
|
379
|
+
# display on message div.
|
380
|
+
#
|
381
|
+
# Parameters:
|
382
|
+
# [doc] Document. Document record which will be checked for errors.
|
383
|
+
#
|
384
|
+
# Returns:
|
385
|
+
# String. HTML code formatted for display.
|
386
|
+
####################################################################
|
387
|
+
def agile_error_messages_for(doc)
|
388
|
+
return '' unless doc&.errors.any?
|
389
|
+
|
390
|
+
msgs = doc.errors.inject('') do |r, error|
|
391
|
+
label = t("helpers.label.#{decamelize_type(doc.class)}.#{error.attribute}", error.attribute)
|
392
|
+
r + "<li>#{label} : #{error.message}</li>"
|
393
|
+
end
|
394
|
+
|
395
|
+
%(
|
396
|
+
<div class="ar-form-error">
|
397
|
+
<h2>#{t('agile.errors_no')} #{doc.errors.size}</h2>
|
398
|
+
<ul>#{msgs}</ul>
|
399
|
+
</div>).html_safe
|
400
|
+
end
|
401
|
+
|
402
|
+
####################################################################
|
403
|
+
# Returns warning messages if any set in a model.
|
404
|
+
#
|
405
|
+
# When warnings array is added to model its content can be written on top of the form.
|
406
|
+
#
|
407
|
+
# Parameters:
|
408
|
+
# [doc] Document. Document record which will be checked for errors.
|
409
|
+
#
|
410
|
+
# Returns:
|
411
|
+
# String. HTML code formatted for display.
|
412
|
+
####################################################################
|
413
|
+
def agile_warning_messages_for(doc)
|
414
|
+
return '' # NOT WORKING
|
415
|
+
return '' unless doc&.respond_to?(:warnings)
|
416
|
+
|
417
|
+
msgs = doc.warnings.inject('') do |r, error|
|
418
|
+
label = t("helpers.label.#{decamelize_type(doc.class)}.#{error.attribute}", error.attribute)
|
419
|
+
r + "<li>#{label} : #{error.message}</li>"
|
420
|
+
end
|
421
|
+
|
422
|
+
%(
|
423
|
+
<div class="ar-form-warning">
|
424
|
+
<h2>#{t('agile.warnings_no')} #{doc.warnings.size}</h2>
|
425
|
+
<ul>#{msgs}</ul>
|
426
|
+
</div>).html_safe
|
427
|
+
end
|
428
|
+
|
429
|
+
####################################################################
|
430
|
+
# Checks if CMS is in edit mode (CMS menu bar is visible).
|
431
|
+
#
|
432
|
+
# Returns:
|
433
|
+
# Boolean. True if in edit mode
|
434
|
+
####################################################################
|
435
|
+
def agile_edit_mode?
|
436
|
+
_origin.session[:edit_mode] > 1
|
437
|
+
end
|
438
|
+
|
439
|
+
####################################################################
|
440
|
+
# Will create HTML code required to create new document.
|
441
|
+
#
|
442
|
+
# Parameters:
|
443
|
+
# [opts] Hash. Optional parameters for url_for helper. These options must provide at least table and form_name
|
444
|
+
# parameters.
|
445
|
+
#
|
446
|
+
# Example:
|
447
|
+
# if @opts[:edit_mode] > 1
|
448
|
+
# opts = {table: 'agile_page;agile_part', form_name: 'agile_part', ids: @doc.id }
|
449
|
+
# html += agile_link_for_create( opts.merge!({title: 'Add new part', 'agile_part.name' => 'initial name', 'agile_part.order' => 10}) )
|
450
|
+
# end
|
451
|
+
#
|
452
|
+
# Returns:
|
453
|
+
# String. HTML code which includes add image and javascript to invoke new document create action.
|
454
|
+
####################################################################
|
455
|
+
def agile_link_for_create(opts)
|
456
|
+
opts.stringify_keys!
|
457
|
+
title = opts.delete('title') #
|
458
|
+
title = t(title, title) if title
|
459
|
+
target = opts.delete('target') || 'iframe_cms'
|
460
|
+
opts['form_name'] ||= opts['table'].to_s.split(';').last
|
461
|
+
opts['action'] = :new
|
462
|
+
opts['controller'] ||= :agile
|
463
|
+
url_forward_params(opts)
|
464
|
+
js = "$('##{target}').attr('src', '#{_origin.url_for(opts)}'); return false;"
|
465
|
+
agile_link_to(nil, _origin.mi_icon('plus-circle'), '#',
|
466
|
+
{ onclick: js, title: title, alt: 'Create', class: 'ar-inline-link'}).html_safe
|
467
|
+
end
|
468
|
+
|
469
|
+
####################################################################
|
470
|
+
# Will create HTML code required to edit document.
|
471
|
+
#
|
472
|
+
# Parameters:
|
473
|
+
# [opts] Hash. Optional parameters for url_for helper. These options must provide
|
474
|
+
# at least table, form_name and id parameters. Optional title, target and icon parameters
|
475
|
+
# can be set.
|
476
|
+
#
|
477
|
+
# Example:
|
478
|
+
# html += agile_link_for_edit( @options ) if @opts[:edit_mode] > 1
|
479
|
+
#
|
480
|
+
# Returns:
|
481
|
+
# String. HTML code which includes edit image and javascript to invoke edit document action.
|
482
|
+
####################################################################
|
483
|
+
def agile_link_for_edit(opts)
|
484
|
+
opts.stringify_keys!
|
485
|
+
title = opts.delete('title') #
|
486
|
+
title = t(title)
|
487
|
+
target = opts.delete('target') || 'iframe_cms'
|
488
|
+
icon = opts.delete('icon') || 'edit-o'
|
489
|
+
opts['controller'] ||= :agile
|
490
|
+
opts['action'] ||= 'edit'
|
491
|
+
opts['form_name'] ||= opts['table'].to_s.split(';').last
|
492
|
+
|
493
|
+
js = "$('##{target}').attr('src', '#{_origin.url_for(opts)}'); return false;"
|
494
|
+
agile_link_to(nil, _origin.mi_icon(icon), '#',
|
495
|
+
{ onclick: js, title: title, class: 'ar-inline-link', alt: 'Edit'})
|
496
|
+
end
|
497
|
+
|
498
|
+
####################################################################
|
499
|
+
# Create edit link with edit picture. Subroutine of agile_page_edit_menu.
|
500
|
+
####################################################################
|
501
|
+
def agile_link_menu_tag(title) #:nodoc:
|
502
|
+
html = %(
|
503
|
+
<dl>
|
504
|
+
<dt><div class='ar_popmenu ar-inline-link' href="#">
|
505
|
+
#{_origin.mi_icon('file-text-o', title: title)}
|
506
|
+
</div></dt>
|
507
|
+
<dd>
|
508
|
+
<ul class=' div-hidden ar_popmenu_class'>
|
509
|
+
)
|
510
|
+
|
511
|
+
yield html
|
512
|
+
html + '</ul></dd></dl>'
|
513
|
+
end
|
514
|
+
|
515
|
+
####################################################################
|
516
|
+
# Create one option in page edit link. Subroutine of agile_page_edit_menu.
|
517
|
+
####################################################################
|
518
|
+
def agile_link_for_edit1(opts, link_text) #:nodoc:
|
519
|
+
icon = opts.delete('icon')
|
520
|
+
url = _origin.url_for(opts)
|
521
|
+
"<li><div class='ar_popmenu_item' style='cursor: pointer;' data-url='#{url}'>
|
522
|
+
#{_origin.mi_icon(icon)} #{link_text}</div></li>\n"
|
523
|
+
end
|
524
|
+
|
525
|
+
########################################################################
|
526
|
+
# Create edit menu for editing existing or creating new agile_page documents. Edit menu
|
527
|
+
# consists of for options.
|
528
|
+
# * Edit content. Will edit only body part od document.
|
529
|
+
# * Edit advanced. Will create edit form for editing all document fields.
|
530
|
+
# * New page. Will create new document and pass some initial data to it. Initial data is saved to cookie.
|
531
|
+
# * New part. Will create new part of document.
|
532
|
+
#
|
533
|
+
# Parameters:
|
534
|
+
# [opts] Hash. Optional parameters for url_for helper. These options must provide at least table and form_name
|
535
|
+
# and id parameters.
|
536
|
+
#
|
537
|
+
# Example:
|
538
|
+
# html += agile_page_edit_menu() if @opts[:edit_mode] > 1
|
539
|
+
#
|
540
|
+
# Returns:
|
541
|
+
# String. HTML code required for manipulation of currently processed document.
|
542
|
+
########################################################################
|
543
|
+
def agile_page_edit_menu(opts = @opts)
|
544
|
+
opts[:edit_mode] ||= _origin.session[:edit_mode]
|
545
|
+
return '' if opts[:edit_mode] < 2
|
546
|
+
|
547
|
+
# save some data to cookie. This can not go to session.
|
548
|
+
page = opts[:page] || @page
|
549
|
+
table = _origin.site.page_class.underscore
|
550
|
+
kukis = { "#{table}.ar_design_id" => page.ar_design_id,
|
551
|
+
# "#{table}.menu_id" => page.menu_id,
|
552
|
+
# "#{table}.kats" => page.kats,
|
553
|
+
"#{table}.page_id" => page.id,
|
554
|
+
"#{table}.ar_site_id" => _origin.site.id
|
555
|
+
}
|
556
|
+
_origin.cookies[:record] = Marshal.dump(kukis)
|
557
|
+
title = "#{t('agile.edit')}: #{page.subject}"
|
558
|
+
opts[:edit_params] ||= {}
|
559
|
+
agile_link_menu_tag(title) do |html|
|
560
|
+
opts[:edit_params].merge!( controller: :agile, action: 'edit', 'icon' => 'edit-o' )
|
561
|
+
opts[:edit_params].merge!( id: page.id, table: _origin.site.page_class.underscore, form_name: opts[:form_name], edit_only: 'body' )
|
562
|
+
html += agile_link_for_edit1( opts[:edit_params], t('agile.edit_content') )
|
563
|
+
|
564
|
+
opts[:edit_params].merge!( edit_only: nil, 'icon' => 'edit-o' )
|
565
|
+
html += agile_link_for_edit1( opts[:edit_params], t('agile.edit_advanced') )
|
566
|
+
|
567
|
+
opts[:edit_params].merge!( action: 'new', 'icon' => 'plus' )
|
568
|
+
html += agile_link_for_edit1( opts[:edit_params], t('agile.edit_new_page') )
|
569
|
+
|
570
|
+
opts[:edit_params].merge!(ids: page.id, form_name: 'agile_part', 'icon' => 'plus',
|
571
|
+
table: "#{_origin.site.page_class.underscore};agile_part" )
|
572
|
+
html + agile_link_for_edit1( opts[:edit_params], t('agile.edit_new_part') )
|
573
|
+
end.html_safe
|
574
|
+
end
|
575
|
+
|
576
|
+
########################################################################
|
577
|
+
# Return page class model defined in site document page_class field.
|
578
|
+
#
|
579
|
+
# Used in forms, when method must be called from page model and model is overwritten by
|
580
|
+
# user's own model.
|
581
|
+
#
|
582
|
+
# Example as used on form:
|
583
|
+
# 30:
|
584
|
+
# name: link
|
585
|
+
# type: text_with_select
|
586
|
+
# eval: 'agile_page_class.all_pages_for_site(@env.agile_get_site)'
|
587
|
+
########################################################################
|
588
|
+
def agile_page_class
|
589
|
+
agile_get_site.page_klass
|
590
|
+
end
|
591
|
+
|
592
|
+
########################################################################
|
593
|
+
# Return menu class model defined in site document menu_class field.
|
594
|
+
#
|
595
|
+
# Used in forms for providing menus class to the forms object.
|
596
|
+
#
|
597
|
+
# Example as used on form:
|
598
|
+
# 30:
|
599
|
+
# name: menu_id
|
600
|
+
# type: tree_view
|
601
|
+
# eval: 'agile_menu_class.all_menus_for_site(@env.agile_get_site)'
|
602
|
+
########################################################################
|
603
|
+
def agile_menu_class
|
604
|
+
agile_get_site.menu_class.classify.constantize
|
605
|
+
end
|
606
|
+
|
607
|
+
####################################################################
|
608
|
+
# Parse site name from url and return ar_site document. Site document will be cached in
|
609
|
+
# @site variable.
|
610
|
+
#
|
611
|
+
# If not in production environment and site document is not found
|
612
|
+
# method will search for 'test' document and return ar_site document found in alias_for field.
|
613
|
+
#
|
614
|
+
# Returns:
|
615
|
+
# ArSite. Site document.
|
616
|
+
####################################################################
|
617
|
+
def agile_get_site
|
618
|
+
return @site if @site # already cached
|
619
|
+
|
620
|
+
reqst = _origin.request.url # different when called from renderer
|
621
|
+
uri = URI.parse(reqst)
|
622
|
+
@site = ArSite.find_by(name: uri.host)
|
623
|
+
# Site can be aliased
|
624
|
+
@site = ArSite.find_by(name: @site.alias_for) if @site&.alias_for.present?
|
625
|
+
# Development. If site with name test exists use alias_for field as pointer to real site data
|
626
|
+
if @site.nil? && ENV['RAILS_ENV'] != 'production'
|
627
|
+
@site = ArSite.find_by(name: 'development')
|
628
|
+
@site = ArSite.find_by(name: @site.alias_for) if @site
|
629
|
+
end
|
630
|
+
@site = nil unless @site&.active # might be disabled
|
631
|
+
@site
|
632
|
+
end
|
633
|
+
|
634
|
+
############################################################################
|
635
|
+
# Return array of policies defined in a site document formated to be used
|
636
|
+
# as choices for select field. Method is used for selecting site policy where
|
637
|
+
# policy for displaying data is required.
|
638
|
+
#
|
639
|
+
# Example (as used in forms):
|
640
|
+
# name: policy_id
|
641
|
+
# type: select
|
642
|
+
# eval: agile_choices_for_site_policies
|
643
|
+
# include_blank: true
|
644
|
+
############################################################################
|
645
|
+
def agile_choices_for_site_policies
|
646
|
+
agile_get_site.site_policies.map { |policy| [policy.name, policy.id] }
|
647
|
+
end
|
648
|
+
|
649
|
+
############################################################################
|
650
|
+
# Returns list of all collections (tables) as array of choices for usage in select fields.
|
651
|
+
# List is collected from agile_menu.yml files and may not include all collections used in application.
|
652
|
+
# Currently list is only used for helping defining collection names on agile_permission form.
|
653
|
+
#
|
654
|
+
# Example (as used in forms):
|
655
|
+
# form:
|
656
|
+
# fields:
|
657
|
+
# 10:
|
658
|
+
# name: table_name
|
659
|
+
# type: text_with_select
|
660
|
+
# eval: agile_choices_for_all_tables
|
661
|
+
############################################################################
|
662
|
+
def agile_choices_for_all_tables
|
663
|
+
choices = {}
|
664
|
+
Agile.paths(:forms).reverse.each do |path|
|
665
|
+
filename = "#{path}/agile_menu.yml"
|
666
|
+
next unless File.exist?(filename)
|
667
|
+
|
668
|
+
menu = YAML.load_file(filename) rescue nil # load menu
|
669
|
+
next unless menu['menu'] # not menu or error
|
670
|
+
|
671
|
+
menu['menu'].each do |section|
|
672
|
+
next unless section.last['items'] # next if no items
|
673
|
+
|
674
|
+
section.last['items'].each_value do |v|
|
675
|
+
key = v['table']
|
676
|
+
choices[key] ||= "#{key} - #{t(v['caption'], v['caption'])}"
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
680
|
+
choices.invert.to_a.sort # hash has to be inverted for values to be returned right
|
681
|
+
end
|
682
|
+
|
683
|
+
##########################################################################
|
684
|
+
# html code for AgileRails application menu
|
685
|
+
##########################################################################
|
686
|
+
def agile_application_menu
|
687
|
+
menus = {}
|
688
|
+
Agile.paths(:forms).reverse.each do |path|
|
689
|
+
filename = "#{path}/agile_menu.yml"
|
690
|
+
next unless File.exist?(filename)
|
691
|
+
|
692
|
+
menu = YAML.load_file(filename) rescue nil # load menu file
|
693
|
+
next unless menu['menu']
|
694
|
+
|
695
|
+
menus = AgileHelper.forms_merge(menu['menu'], menus) # ignore top level
|
696
|
+
end
|
697
|
+
|
698
|
+
html = '<ul>'
|
699
|
+
menus.to_a.sort.each do |index, menu| # sort menu numbers
|
700
|
+
next unless menu['caption']
|
701
|
+
|
702
|
+
icon = menu['icon'].match('/') ? image_tag(menu['icon']) : mi_icon(menu['icon']) #external or fa- image
|
703
|
+
html += %(<li class="agile-top-level-menu"><div>#{icon}#{t(menu['caption'])}</div><ul>)
|
704
|
+
menu['items'].to_a.sort.each do |index1, option| # sort by menu items
|
705
|
+
html += if option['link']
|
706
|
+
opts = { target: option['target'] || 'iframe_cms' }
|
707
|
+
"<li>#{agile_link_to(t(option['caption']), option['icon'], option['link'], opts)}</li>"
|
708
|
+
else
|
709
|
+
opts = { controller: option['controller'],
|
710
|
+
action: option['action'],
|
711
|
+
table: option['table'],
|
712
|
+
form_name: option['form_name'] || option['table'],
|
713
|
+
target: option['target'] || 'iframe_cms',
|
714
|
+
}
|
715
|
+
"<li>#{agile_link_to(t(option['caption']), option['icon'], opts)}</li>"
|
716
|
+
end
|
717
|
+
end
|
718
|
+
html += '</ul></li>'
|
719
|
+
end
|
720
|
+
html.html_safe
|
721
|
+
end
|
722
|
+
|
723
|
+
############################################################################
|
724
|
+
# Returns list of directories as array of choices for use in select field
|
725
|
+
# on folder permission form. Directory root is determined from ar_site.files_directory field.
|
726
|
+
############################################################################
|
727
|
+
def agile_choices_for_folders
|
728
|
+
public = File.join(Rails.root,'public')
|
729
|
+
home = File.join(public, agile_get_site.files_directory)
|
730
|
+
choices = Dir.glob("#{home}/**/*/").select { |fn| File.directory?(fn) }
|
731
|
+
choices << home # add home
|
732
|
+
choices.map { _1.gsub(public, '') }.sort # remove public part
|
733
|
+
end
|
734
|
+
|
735
|
+
############################################################################
|
736
|
+
# Returns choices for select input field when choices are generated from
|
737
|
+
# all documents in collection.
|
738
|
+
#
|
739
|
+
# Parameters:
|
740
|
+
# [model] String. Collection (table) name in lowercase format.
|
741
|
+
# [name] String. Field name containing description text.
|
742
|
+
# [id] String. Field name containing id field. Default is '_id'
|
743
|
+
# [options] Hash. Various options. Currently site: (:only, :with_nil, :all) is used.
|
744
|
+
# Will return only documents belonging to current site, also with site not defined,
|
745
|
+
# or all documents.
|
746
|
+
#
|
747
|
+
# Example (as used in forms):
|
748
|
+
# 50:
|
749
|
+
# name: agile_poll_id
|
750
|
+
# type: select
|
751
|
+
# eval: agile_choices_for('agile_poll','name','_id')
|
752
|
+
############################################################################
|
753
|
+
def agile_choices_for(model, name, id = 'id', options = {})
|
754
|
+
model = model.classify.constantize
|
755
|
+
qry = model.select(id, name)
|
756
|
+
if (param = options[:site])
|
757
|
+
sites = [agile_get_site.id] unless param == :all
|
758
|
+
sites << nil if param == :with_nil
|
759
|
+
qry = qry.where(ar_site_id: sites) if sites
|
760
|
+
end
|
761
|
+
qry = qry.where(active: true) if model.has_attribute?(:active)
|
762
|
+
qry.order(name => :asc).map { [_1[name], _1[id]] }
|
763
|
+
end
|
764
|
+
|
765
|
+
############################################################################
|
766
|
+
# Returns list of choices for selection top level menu on agile_page form. Used for defining which
|
767
|
+
# top level menu will be highlited when page is displayed.
|
768
|
+
#
|
769
|
+
# Example (as used in forms):
|
770
|
+
# 20:
|
771
|
+
# name: menu_id
|
772
|
+
# type: select
|
773
|
+
# eval: agile_choices_for_menu
|
774
|
+
############################################################################
|
775
|
+
def agile_choices_for_menu
|
776
|
+
menu_class = agile_get_site.menu_class
|
777
|
+
menu_class = 'ArMenu' if menu_class.blank?
|
778
|
+
klass = menu_class.classify.constantize
|
779
|
+
klass.choices_for_menu(agile_get_site)
|
780
|
+
end
|
781
|
+
|
782
|
+
############################################################################
|
783
|
+
# Will add data to record cookie. Record cookie is used to preload some
|
784
|
+
# data on next create action. Create action will look for cookies[:record] and
|
785
|
+
# if found initialize fields on form with matching name to value found in cookie data.
|
786
|
+
#
|
787
|
+
# Example:
|
788
|
+
# kukis = {'agile_page.ar_design_id' => @page.ar_design_id,
|
789
|
+
# 'agile_page.agile_menu_id' => @page.menu_id)
|
790
|
+
# agile_add2_record_cookie(kukis)
|
791
|
+
############################################################################
|
792
|
+
def agile_add2_record_cookie(hash)
|
793
|
+
kukis = if @env.cookies[:record]&.present?
|
794
|
+
Marshal.load(@env.cookies[:record])
|
795
|
+
else
|
796
|
+
{}
|
797
|
+
end
|
798
|
+
hash.each { |k, v| kukis[k] = v }
|
799
|
+
@env.cookies[:record] = Marshal.dump(kukis)
|
800
|
+
end
|
801
|
+
|
802
|
+
############################################################################
|
803
|
+
# Will check if user roles allow user to view data in document with defined access_policy.
|
804
|
+
#
|
805
|
+
# Parameters:
|
806
|
+
# [ctrl] Controller object or object which holds methods to access environment. For example @env
|
807
|
+
# when called from renderer.
|
808
|
+
# [policy_id] Document or documents policy_id field value required to view data. Method will automatically
|
809
|
+
# check if parameter send has policy_id field defined and use value of that field.
|
810
|
+
#
|
811
|
+
# Example:
|
812
|
+
# can_view, message = agile_user_can_view(@env, @page)
|
813
|
+
# # or
|
814
|
+
# can_view, message = agile_user_can_view(@env, @page.policy_id)
|
815
|
+
# return message unless can_view
|
816
|
+
#
|
817
|
+
# Returns:
|
818
|
+
# True if access_policy allows user to view data.
|
819
|
+
# False and message from policy that is blocking view if access is not allowed.
|
820
|
+
############################################################################
|
821
|
+
def agile_user_can_view(ctrl, policy_id)
|
822
|
+
@can_view_cache ||= {}
|
823
|
+
policy_id = policy_id.policy_id if policy_id&.respond_to?(:policy_id)
|
824
|
+
# Eventualy object without policy_id will be checked. This is to prevent error
|
825
|
+
policy_id = nil unless policy_id.instance_of?(Integer)
|
826
|
+
return @can_view_cache[policy_id] if @can_view_cache[policy_id]
|
827
|
+
|
828
|
+
# get site policies
|
829
|
+
site = ctrl.site
|
830
|
+
policies = (site.inherit_policy.blank? ? site : ArSite.find(site.inherit_policy)).site_policies.to_a
|
831
|
+
# get default policy
|
832
|
+
default_policy = policies.find(&:is_default)
|
833
|
+
return cache_can_view(policy_id, false, 'Default access policy not found for the site!') unless default_policy
|
834
|
+
|
835
|
+
permissions = {}
|
836
|
+
default_policy.ar_policy_rules.each { |v| permissions[v.ar_role_id] = v.permission }
|
837
|
+
# update permissions with defined policy
|
838
|
+
part_policy = nil
|
839
|
+
if policy_id
|
840
|
+
part_policy = policies.find { |policy| policy.id == policy_id }
|
841
|
+
return cache_can_view(policy_id, false, 'Access policy not found for part!') unless part_policy
|
842
|
+
|
843
|
+
part_policy.ar_policy_rules.each { |v| permissions[v.ar_role_id] = v.permission }
|
844
|
+
end
|
845
|
+
# apply guest role if no roles defined
|
846
|
+
if ctrl.session[:user_roles].nil?
|
847
|
+
guest_role = ArRole.get_role('guest')
|
848
|
+
return cache_can_view(policy_id, false, 'System guest role not defined!') unless guest_role
|
849
|
+
|
850
|
+
ctrl.session[:user_roles] = [guest_role.id]
|
851
|
+
end
|
852
|
+
# Check if user has any role that allows him to view part
|
853
|
+
can_view = ctrl.session[:user_roles].find{ |role| permissions[role]&.to_i > 0 }
|
854
|
+
msg = ''
|
855
|
+
unless can_view
|
856
|
+
msg = part_policy ? t(part_policy.message, part_policy.message) : t(default_policy.message, default_policy.message)
|
857
|
+
# message may have variable content
|
858
|
+
msg = _origin.render(inline: msg, layout: nil) if msg.match('<%=')
|
859
|
+
end
|
860
|
+
cache_can_view(policy_id, can_view, msg)
|
861
|
+
end
|
862
|
+
|
863
|
+
####################################################################
|
864
|
+
# Check if user has required role assigned to its user profile. If role is passed as
|
865
|
+
# string method will check roles for name and system name.
|
866
|
+
#
|
867
|
+
# Parameters:
|
868
|
+
# [role] ArRole/String. Required role. If passed as string role will be searched in agile_policy_roles collection.
|
869
|
+
# [user] User id. Defaults to session[:user_id].
|
870
|
+
# [roles] Array of roles that will be searched. Default session[:user_roles].
|
871
|
+
#
|
872
|
+
# Example:
|
873
|
+
# if agile_user_has_role?('decision_maker', session[:user_id), session[:user_roles])
|
874
|
+
# do_something_important
|
875
|
+
# end
|
876
|
+
#
|
877
|
+
# Returns:
|
878
|
+
# Boolean. True if user has required role.
|
879
|
+
####################################################################
|
880
|
+
def agile_user_has_role?( role, user = nil, roles = nil )
|
881
|
+
roles = _origin.session[:user_roles] if roles.nil?
|
882
|
+
user = _origin.session[:user_id] if user.nil?
|
883
|
+
return false if user.nil? || roles.nil?
|
884
|
+
|
885
|
+
role = ArRole.get_role(role)
|
886
|
+
return false if role.nil?
|
887
|
+
|
888
|
+
# role is included in roles array
|
889
|
+
roles.include?(role.id)
|
890
|
+
end
|
891
|
+
|
892
|
+
####################################################################
|
893
|
+
# Returns true if parameter has value of 0, false, no, none or -.
|
894
|
+
# Returns value of default if parameter has nil value.
|
895
|
+
#
|
896
|
+
# Parameters:
|
897
|
+
# [what] String/boolean/Integer.
|
898
|
+
# [default] Default value when what has value of nil. False by default.
|
899
|
+
#
|
900
|
+
# Example:
|
901
|
+
# agile_dont?('none') # => true
|
902
|
+
# agile_dont?('-') # => true
|
903
|
+
# agile_dont?(1) # => false
|
904
|
+
# agile_dont?(nil, true) # => true
|
905
|
+
####################################################################
|
906
|
+
def agile_dont?(what, default = false)
|
907
|
+
AgileHelper.dont?(what, default)
|
908
|
+
end
|
909
|
+
|
910
|
+
############################################################################
|
911
|
+
# Truncates string length maximal to the size required and takes care, that words are not broken in middle.
|
912
|
+
# Used for output text summary with texts that can be longer then allowed space.
|
913
|
+
#
|
914
|
+
# Parameters:
|
915
|
+
# [string] String of any size.
|
916
|
+
# [size] Maximal size of the string to be returned.
|
917
|
+
#
|
918
|
+
# Example:
|
919
|
+
# agile_limit_string(description, 100)
|
920
|
+
#
|
921
|
+
# Returns:
|
922
|
+
# String, truncated to required size. If string is truncated '...' will be added to the end.
|
923
|
+
############################################################################
|
924
|
+
def agile_limit_string(string, size)
|
925
|
+
return string if string.size <= size
|
926
|
+
|
927
|
+
string = string[0, size]
|
928
|
+
string.chop! until string[-1, 1] == ' ' || string == ''
|
929
|
+
"#{string}..."
|
930
|
+
end
|
931
|
+
|
932
|
+
############################################################################
|
933
|
+
# Returns key defined in ArBigTable as array of choices for use in select fields.
|
934
|
+
# ArBigTable can be used like a key/value store for all kind of predefined values
|
935
|
+
# which can be linked to site and or locale.
|
936
|
+
#
|
937
|
+
# Parameters:
|
938
|
+
# [key] String. Key name to be searched in agile_big_tables documents.
|
939
|
+
#
|
940
|
+
# Example:
|
941
|
+
# 10:
|
942
|
+
# name: category
|
943
|
+
# type: select
|
944
|
+
# eval: agile_big_table_choices 'categories_for_page' # as used on form
|
945
|
+
#
|
946
|
+
# Returns:
|
947
|
+
# Array of choices ready for select field.
|
948
|
+
############################################################################
|
949
|
+
def agile_big_table_choices(key)
|
950
|
+
ret = []
|
951
|
+
bt = ArBigTable.find_by(key: key, site_id: agile_get_site.id, active: true) ||
|
952
|
+
ArBigTable.find_by(key: key, site_id: nil, active: true)
|
953
|
+
return ret if bt.nil?
|
954
|
+
|
955
|
+
bt.ar_big_table_values.order(description: 'asc').each do |ar_value| # iterate values
|
956
|
+
next unless ar_value.active
|
957
|
+
|
958
|
+
desc = ar_value.get_localized_description
|
959
|
+
ret << [desc, ar_value.value]
|
960
|
+
end
|
961
|
+
ret
|
962
|
+
end
|
963
|
+
|
964
|
+
########################################################################
|
965
|
+
# Will return html code required for load AgileRails form into iframe. If parameters
|
966
|
+
# are passed to method iframe url will have initial value and thus enabling automatic form
|
967
|
+
# load on page display.
|
968
|
+
#
|
969
|
+
# Parameters:
|
970
|
+
# [table] String: Collection (table) name used to load initial form.
|
971
|
+
# [opts] Hash: Optional parameters which define url for loading AgileRails form.
|
972
|
+
# These parameters are :action, :oper, :table, :form_name, :id, :readonly
|
973
|
+
#
|
974
|
+
# Example:
|
975
|
+
# # just iframe code
|
976
|
+
# <%= agile_edit_frame(nil) %>
|
977
|
+
# # load note form for note collection into iframe with name iframe_name
|
978
|
+
# <%= agile_edit_frame('note', iframe: 'iframe_name') %>
|
979
|
+
# # on register collection use reg_adresses form_name to display data with id @register.id
|
980
|
+
# <%= agile_edit_frame('register', action: :show, form_name: 'reg_adresses', readonly: 1, id: @register.id ) %>
|
981
|
+
#
|
982
|
+
# Returns:
|
983
|
+
# Html code for edit iframe
|
984
|
+
########################################################################
|
985
|
+
def agile_edit_frame(table, opts = {})
|
986
|
+
iframe_name = opts[:iframe] || 'iframe_edit'
|
987
|
+
if params.to_unsafe_h.size > 2 && table # controller, action, path is minimal
|
988
|
+
params[:controller] = :agile
|
989
|
+
params[:action] = params[:oper] == 'edit' ? 'edit' : 'index'
|
990
|
+
params[:action] = opts[:action] unless params[:oper]
|
991
|
+
params[:table] ||= table
|
992
|
+
params[:form_name] ||= opts[:form_name] || table
|
993
|
+
params[:id] ||= params[:idp] || opts[:id]
|
994
|
+
params[:readonly] ||= opts[:readonly]
|
995
|
+
params[:path] = nil
|
996
|
+
params.permit! # rails 5 request
|
997
|
+
"<iframe id='#{iframe_name}' name='#{iframe_name}' src='#{url_for params}'></iframe>"
|
998
|
+
else
|
999
|
+
"<iframe id='#{iframe_name}' name='#{iframe_name}'></iframe>"
|
1000
|
+
end.html_safe
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
########################################################################
|
1004
|
+
# Will return value from Rails and AgileRails environment objects.
|
1005
|
+
# This objects can be params, session, record, site, page
|
1006
|
+
#
|
1007
|
+
# Parameters:
|
1008
|
+
# [object] String: Internal object holding variable. Possible values are session, params, record, site, page, class
|
1009
|
+
# [var_name] String[symbol]: Variable name (:user_name, 'user_id', ...)
|
1010
|
+
# [current_record] Object: If passed and object is 'record' then current active record it will be used for retrieving data.
|
1011
|
+
#
|
1012
|
+
# Example:
|
1013
|
+
# # called when constructing iframe for display
|
1014
|
+
# agile_internal_var('session', :user_id)
|
1015
|
+
# agile_internal_var('params', :some_external_parameter)
|
1016
|
+
# agile_internal_var('site', :name)
|
1017
|
+
# # or even
|
1018
|
+
# agile_internal_var('class', 'ClassName.class_method_name')
|
1019
|
+
#
|
1020
|
+
#
|
1021
|
+
# Returns:
|
1022
|
+
# Value of variable or error when not found
|
1023
|
+
########################################################################
|
1024
|
+
def agile_internal_var(object, var_name, current_record = nil)
|
1025
|
+
begin
|
1026
|
+
case object.to_s
|
1027
|
+
when 'session' then _origin.session[var_name]
|
1028
|
+
when 'params' then _origin.params[var_name]
|
1029
|
+
when 'site' then _origin.agile_get_site.send(var_name)
|
1030
|
+
when 'page' then _origin.page.send(var_name)
|
1031
|
+
when 'record'
|
1032
|
+
current_record ? current_record.send(var_name) : _origin.record.send(var_name)
|
1033
|
+
when 'class'
|
1034
|
+
clas, method_name = var_name.split('.')
|
1035
|
+
klas = clas.classify.constantize
|
1036
|
+
# call method. Error will be caught below.
|
1037
|
+
klas.send(method_name)
|
1038
|
+
else
|
1039
|
+
'VARIABLE: UNKNOWN OBJECT'
|
1040
|
+
end
|
1041
|
+
rescue Exception => e
|
1042
|
+
Rails.logger.debug "\nagile_internal_var. Runtime error. #{e.message}\n"
|
1043
|
+
Rails.logger.debug(e.backtrace.join($/)) if Rails.env.development?
|
1044
|
+
'VARIABLE: ERROR'
|
1045
|
+
end
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
########################################################################
|
1049
|
+
# Will return formated code for embedding json+ld data into page
|
1050
|
+
#
|
1051
|
+
# Returns:
|
1052
|
+
# HTML data to be embedded into page header
|
1053
|
+
#######################################################################
|
1054
|
+
def agile_get_json_ld
|
1055
|
+
return '' if @json_ld.nil? || @json_ld.size == 0
|
1056
|
+
|
1057
|
+
%(
|
1058
|
+
<script type="application/ld+json">
|
1059
|
+
#{JSON.pretty_generate({ '@context' => 'http://schema.org', '@graph' => @json_ld })}
|
1060
|
+
</script>
|
1061
|
+
).html_safe
|
1062
|
+
end
|
1063
|
+
|
1064
|
+
########################################################################
|
1065
|
+
# Will add new element to json_ld structure
|
1066
|
+
#
|
1067
|
+
# Parameters:
|
1068
|
+
# [element] Hash or Array of hashes: json+ld element
|
1069
|
+
#######################################################################
|
1070
|
+
def agile_add_json_ld(element)
|
1071
|
+
@json_ld ||= []
|
1072
|
+
if element.instance_of?(Array)
|
1073
|
+
@json_ld << element
|
1074
|
+
else
|
1075
|
+
@json_ld << element
|
1076
|
+
end
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
########################################################################
|
1080
|
+
# Will return meta data for SEO optimizations
|
1081
|
+
#
|
1082
|
+
# Returns:
|
1083
|
+
# HTML data to be embedded into page header
|
1084
|
+
#######################################################################
|
1085
|
+
def agile_get_seo_meta_tags
|
1086
|
+
html = ''
|
1087
|
+
html += %(<link rel="canonical" href="#{@page.canonical_link}">\n ) unless @page&.canonical_link.blank?
|
1088
|
+
if @meta_tags
|
1089
|
+
html += @meta_tags.inject('') do |r, hash|
|
1090
|
+
r + %(<meta #{hash.first} content="#{hash.last}">\n )
|
1091
|
+
end
|
1092
|
+
end
|
1093
|
+
html.html_safe
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
########################################################################
|
1097
|
+
# Will add a meta tag to internal hash structure. If meta tag already exists it
|
1098
|
+
# will be overwritten.
|
1099
|
+
#
|
1100
|
+
# Parameters:
|
1101
|
+
# [name] String: meta name
|
1102
|
+
# [content] String: meta content
|
1103
|
+
########################################################################
|
1104
|
+
def agile_add_meta_tag(type, name, content)
|
1105
|
+
return if content.blank?
|
1106
|
+
|
1107
|
+
@meta_tags ||= {}
|
1108
|
+
key = "#{type}=\"#{name}\""
|
1109
|
+
@meta_tags[key] = content
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
#######################################################################
|
1113
|
+
# Will return alt image option when text is provided. When text is blank
|
1114
|
+
# it will extract alt name from picture file_name. This method returns
|
1115
|
+
# together with alt="image-tag" tag.
|
1116
|
+
#
|
1117
|
+
# Parameters:
|
1118
|
+
# [file_name] String: Filename of a picture
|
1119
|
+
# [text] String: Alt text name
|
1120
|
+
#
|
1121
|
+
# Returns:
|
1122
|
+
# [String] alt="image-tag"
|
1123
|
+
#######################################################################
|
1124
|
+
def agile_img_alt_tag(file_name, text = nil)
|
1125
|
+
%( alt="#{agile_img_alt(file_name, text)}" ).html_safe
|
1126
|
+
end
|
1127
|
+
|
1128
|
+
#######################################################################
|
1129
|
+
# Will return alt image option when text is provided. When text is blank
|
1130
|
+
# it will extract alt name from picture file_name. This method returns just
|
1131
|
+
# alt name.
|
1132
|
+
#
|
1133
|
+
# Parameters:
|
1134
|
+
# [file_name] String: Filename of a picture
|
1135
|
+
# [text] String: Alt text name
|
1136
|
+
#
|
1137
|
+
# Returns:
|
1138
|
+
# [String] alt_image_name
|
1139
|
+
#######################################################################
|
1140
|
+
def agile_img_alt(file_name, text = nil)
|
1141
|
+
return text if text.present?
|
1142
|
+
|
1143
|
+
name = File.basename(file_name.to_s)
|
1144
|
+
name[0, name.index('.')].downcase rescue name
|
1145
|
+
end
|
1146
|
+
|
1147
|
+
########################################################################
|
1148
|
+
# Will return name for value defined in ar_big_table
|
1149
|
+
########################################################################
|
1150
|
+
def agile_big_table_name_for_value(key, value)
|
1151
|
+
agile_big_table_choices(key).each { |k, val| return k if val.to_s == value.to_s}
|
1152
|
+
'???'
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
private
|
1156
|
+
|
1157
|
+
# will cache agile_user_can_view response
|
1158
|
+
def cache_can_view(id, can_view, msg)
|
1159
|
+
@can_view_cache[id] = [can_view, msg]
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
end
|