glib-web 0.5.71 → 0.5.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/app/channels/glib/channel/is_typing_channel.rb +34 -34
  3. data/app/channels/glib/channel/online_channel.rb +36 -36
  4. data/app/controllers/concerns/glib/analytics/funnel.rb +61 -61
  5. data/app/controllers/concerns/glib/auth/policy.rb +148 -148
  6. data/app/controllers/concerns/glib/json/dynamic_text.rb +126 -126
  7. data/app/controllers/concerns/glib/json/libs.rb +149 -149
  8. data/app/controllers/concerns/glib/json/new_dynamic_text.rb +122 -122
  9. data/app/controllers/concerns/glib/json/transformation.rb +11 -11
  10. data/app/controllers/concerns/glib/json/traversal.rb +92 -92
  11. data/app/controllers/concerns/glib/json/ui.rb +88 -88
  12. data/app/controllers/concerns/glib/json/validation.rb +13 -13
  13. data/app/controllers/glib/home_controller.rb +54 -54
  14. data/app/helpers/glib/app_feature_support_helper.rb +16 -16
  15. data/app/helpers/glib/dynamic_images_helper.rb +55 -55
  16. data/app/helpers/glib/dynamic_texts_helper.rb +42 -42
  17. data/app/helpers/glib/enum_helper.rb +18 -8
  18. data/app/helpers/glib/forms_helper.rb +15 -15
  19. data/app/helpers/glib/json_ui/abstract_builder.rb +309 -309
  20. data/app/helpers/glib/json_ui/action_builder.rb +140 -140
  21. data/app/helpers/glib/json_ui/action_builder/dialogs.rb +58 -58
  22. data/app/helpers/glib/json_ui/action_builder/http.rb +39 -39
  23. data/app/helpers/glib/json_ui/action_builder/panels.rb +14 -14
  24. data/app/helpers/glib/json_ui/action_builder/sheets.rb +15 -15
  25. data/app/helpers/glib/json_ui/action_builder/snackbars.rb +41 -41
  26. data/app/helpers/glib/json_ui/action_builder/windows.rb +33 -33
  27. data/app/helpers/glib/json_ui/analytics_helper.rb +17 -17
  28. data/app/helpers/glib/json_ui/dynamic_field_builders.rb +25 -25
  29. data/app/helpers/glib/json_ui/generic_builders.rb +28 -28
  30. data/app/helpers/glib/json_ui/list_builders.rb +110 -110
  31. data/app/helpers/glib/json_ui/menu_builder.rb +94 -94
  32. data/app/helpers/glib/json_ui/page_helper.rb +221 -221
  33. data/app/helpers/glib/json_ui/response_helper.rb +25 -25
  34. data/app/helpers/glib/json_ui/split_builders.rb +32 -32
  35. data/app/helpers/glib/json_ui/styling_helper.rb +55 -55
  36. data/app/helpers/glib/json_ui/table_builders.rb +74 -74
  37. data/app/helpers/glib/json_ui/view_builder.rb +240 -240
  38. data/app/helpers/glib/json_ui/view_builder/banners.rb +26 -26
  39. data/app/helpers/glib/json_ui/view_builder/charts.rb +33 -33
  40. data/app/helpers/glib/json_ui/view_builder/fields.rb +278 -279
  41. data/app/helpers/glib/json_ui/view_builder/panels.rb +256 -256
  42. data/app/helpers/glib/urls_helper.rb +12 -12
  43. data/app/models/glib/active_storage/attachment.rb +9 -9
  44. data/app/models/glib/active_storage/blob.rb +9 -9
  45. data/app/models/glib/application_record.rb +18 -18
  46. data/app/models/glib/dynamic_text_record.rb +9 -9
  47. data/app/models/glib/text.rb +95 -95
  48. data/app/policies/glib/application_policy.rb +161 -161
  49. data/app/validators/email_typo_validator.rb +38 -38
  50. data/app/validators/email_validator.rb +7 -7
  51. data/app/validators/url_validator.rb +20 -20
  52. data/app/views/json_ui/garage/_nav_menu.json.jbuilder +70 -70
  53. data/app/views/json_ui/garage/actions/_dialogs.json.jbuilder +104 -104
  54. data/app/views/json_ui/garage/actions/_http.json.jbuilder +24 -24
  55. data/app/views/json_ui/garage/actions/_panels.json.jbuilder +18 -18
  56. data/app/views/json_ui/garage/actions/_reload.json.jbuilder +17 -17
  57. data/app/views/json_ui/garage/actions/_sheets.json.jbuilder +18 -18
  58. data/app/views/json_ui/garage/actions/_snackbars.json.jbuilder +33 -33
  59. data/app/views/json_ui/garage/actions/_timeouts.json.jbuilder +24 -24
  60. data/app/views/json_ui/garage/actions/_windows.json.jbuilder +24 -24
  61. data/app/views/json_ui/garage/actions/dialogs_oauth_post.json.jbuilder +6 -6
  62. data/app/views/json_ui/garage/actions/index.json.jbuilder +24 -24
  63. data/app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder +6 -6
  64. data/app/views/json_ui/garage/forms/basic.json.jbuilder +21 -21
  65. data/app/views/json_ui/garage/forms/basic_post.json.jbuilder +8 -8
  66. data/app/views/json_ui/garage/forms/checkboxes.json.jbuilder +43 -43
  67. data/app/views/json_ui/garage/forms/conditional_value.json.jbuilder +36 -36
  68. data/app/views/json_ui/garage/forms/dynamic_group.json.jbuilder +39 -39
  69. data/app/views/json_ui/garage/forms/dynamic_select.json.jbuilder +24 -22
  70. data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +38 -38
  71. data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +32 -37
  72. data/app/views/json_ui/garage/forms/floating_submit.json.jbuilder +19 -19
  73. data/app/views/json_ui/garage/forms/generic_post.json.jbuilder +3 -3
  74. data/app/views/json_ui/garage/forms/get_request.json.jbuilder +27 -27
  75. data/app/views/json_ui/garage/forms/index.json.jbuilder +113 -113
  76. data/app/views/json_ui/garage/forms/new_rich_text.json.jbuilder +39 -39
  77. data/app/views/json_ui/garage/forms/online_participant1.json.jbuilder +25 -25
  78. data/app/views/json_ui/garage/forms/online_participant2.json.jbuilder +25 -25
  79. data/app/views/json_ui/garage/forms/pickers.json.jbuilder +81 -81
  80. data/app/views/json_ui/garage/forms/ratings.json.jbuilder +49 -49
  81. data/app/views/json_ui/garage/forms/rich_text.json.jbuilder +40 -40
  82. data/app/views/json_ui/garage/forms/selects.json.jbuilder +91 -84
  83. data/app/views/json_ui/garage/forms/show_hide.json.jbuilder +130 -130
  84. data/app/views/json_ui/garage/forms/styled_boxes.json.jbuilder +35 -35
  85. data/app/views/json_ui/garage/forms/submission_flow.json.jbuilder +17 -17
  86. data/app/views/json_ui/garage/forms/submission_flow_post.json.jbuilder +26 -26
  87. data/app/views/json_ui/garage/forms/submission_indicator.json.jbuilder +63 -63
  88. data/app/views/json_ui/garage/forms/submission_indicator_post.json.jbuilder +25 -25
  89. data/app/views/json_ui/garage/forms/text_validation.json.jbuilder +81 -81
  90. data/app/views/json_ui/garage/forms/timers.json.jbuilder +120 -120
  91. data/app/views/json_ui/garage/home/blank.json.jbuilder +10 -10
  92. data/app/views/json_ui/garage/home/index.json.jbuilder +36 -36
  93. data/app/views/json_ui/garage/home/slow.json.jbuilder +11 -11
  94. data/app/views/json_ui/garage/lists/_autoload_section.json.jbuilder +28 -28
  95. data/app/views/json_ui/garage/lists/autoload_all.json.jbuilder +32 -32
  96. data/app/views/json_ui/garage/lists/autoload_as_needed.json.jbuilder +35 -35
  97. data/app/views/json_ui/garage/lists/chat_ui.json.jbuilder +94 -94
  98. data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +62 -62
  99. data/app/views/json_ui/garage/lists/fab.json.jbuilder +12 -12
  100. data/app/views/json_ui/garage/lists/index.json.jbuilder +38 -38
  101. data/app/views/json_ui/garage/lists/reordering.json.jbuilder +34 -34
  102. data/app/views/json_ui/garage/lists/templating.json.jbuilder +35 -35
  103. data/app/views/json_ui/garage/notifications/action_cable.json.jbuilder +114 -114
  104. data/app/views/json_ui/garage/notifications/android_post.json.jbuilder +48 -48
  105. data/app/views/json_ui/garage/notifications/index.json.jbuilder +36 -36
  106. data/app/views/json_ui/garage/notifications/web_socket.json.jbuilder +60 -60
  107. data/app/views/json_ui/garage/pages/flat_centered.json.jbuilder +29 -29
  108. data/app/views/json_ui/garage/pages/full_width.json.jbuilder +29 -29
  109. data/app/views/json_ui/garage/pages/full_width_height.json.jbuilder +16 -16
  110. data/app/views/json_ui/garage/pages/index.json.jbuilder +62 -62
  111. data/app/views/json_ui/garage/pages/layout.json.jbuilder +18 -18
  112. data/app/views/json_ui/garage/pages/lifecycle_hooks.json.jbuilder +13 -13
  113. data/app/views/json_ui/garage/pages/loading_indicator.json.jbuilder +10 -10
  114. data/app/views/json_ui/garage/pages/nav_buttons.json.jbuilder +21 -21
  115. data/app/views/json_ui/garage/pages/nested_scroll.json.jbuilder +40 -40
  116. data/app/views/json_ui/garage/pages/tab_bar.json.jbuilder +31 -31
  117. data/app/views/json_ui/garage/panels/_styled.json.jbuilder +78 -78
  118. data/app/views/json_ui/garage/panels/card.json.jbuilder +4 -4
  119. data/app/views/json_ui/garage/panels/carousel.json.jbuilder +37 -37
  120. data/app/views/json_ui/garage/panels/custom.json.jbuilder +17 -17
  121. data/app/views/json_ui/garage/panels/flow.json.jbuilder +59 -59
  122. data/app/views/json_ui/garage/panels/horizontal.json.jbuilder +91 -91
  123. data/app/views/json_ui/garage/panels/index.json.jbuilder +138 -134
  124. data/app/views/json_ui/garage/panels/outlined.json.jbuilder +4 -4
  125. data/app/views/json_ui/garage/panels/responsive.json.jbuilder +98 -98
  126. data/app/views/json_ui/garage/panels/split.json.jbuilder +182 -182
  127. data/app/views/json_ui/garage/panels/ul.json.jbuilder +33 -0
  128. data/app/views/json_ui/garage/panels/vertical.json.jbuilder +55 -55
  129. data/app/views/json_ui/garage/panels/web.json.jbuilder +15 -15
  130. data/app/views/json_ui/garage/services/dynamic_text.json.jbuilder +13 -13
  131. data/app/views/json_ui/garage/services/image.json.jbuilder +47 -47
  132. data/app/views/json_ui/garage/services/index.json.jbuilder +17 -17
  133. data/app/views/json_ui/garage/tables/_autoload_section.json.jbuilder +16 -16
  134. data/app/views/json_ui/garage/tables/autoload_all.json.jbuilder +43 -43
  135. data/app/views/json_ui/garage/tables/autoload_as_needed.json.jbuilder +50 -50
  136. data/app/views/json_ui/garage/tables/export_import.json.jbuilder +29 -29
  137. data/app/views/json_ui/garage/tables/horizontal_scroll.json.jbuilder +26 -26
  138. data/app/views/json_ui/garage/tables/index.json.jbuilder +25 -25
  139. data/app/views/json_ui/garage/tables/layout.json.jbuilder +40 -40
  140. data/app/views/json_ui/garage/views/_chart_data.json.jbuilder +17 -17
  141. data/app/views/json_ui/garage/views/banners.json.jbuilder +63 -63
  142. data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +30 -30
  143. data/app/views/json_ui/garage/views/charts.json.jbuilder +115 -115
  144. data/app/views/json_ui/garage/views/controls.json.jbuilder +37 -37
  145. data/app/views/json_ui/garage/views/icon_names.json.jbuilder +1450 -1450
  146. data/app/views/json_ui/garage/views/icons.json.jbuilder +15 -14
  147. data/app/views/json_ui/garage/views/images.json.jbuilder +89 -89
  148. data/app/views/json_ui/garage/views/index.json.jbuilder +67 -67
  149. data/app/views/json_ui/garage/views/links.json.jbuilder +70 -70
  150. data/app/views/json_ui/garage/views/map_cluster_data.json.jbuilder +41 -41
  151. data/app/views/json_ui/garage/views/map_data.json.jbuilder +51 -51
  152. data/app/views/json_ui/garage/views/maps.json.jbuilder +31 -31
  153. data/app/views/json_ui/garage/views/markdowns.json.jbuilder +41 -41
  154. data/app/views/json_ui/garage/views/misc.json.jbuilder +34 -34
  155. data/app/views/json_ui/garage/views/texts.json.jbuilder +35 -35
  156. data/app/views/layouts/json_ui/renderer.html.erb +35 -35
  157. data/config/routes.rb +7 -7
  158. data/lib/generators/glib/install_generator.rb +24 -24
  159. data/lib/generators/templates/20191017062519_create_texts.rb +12 -12
  160. data/lib/generators/templates/20191024063257_add_scope_to_texts.rb +7 -7
  161. data/lib/generators/templates/20191112095018_add_lang_to_texts.rb +7 -7
  162. data/lib/generators/templates/20191126071051_create_active_storage_tables.active_storage.rb +27 -27
  163. data/lib/generators/templates/database.yml +107 -107
  164. data/lib/generators/templates/dynamic_text.rb +2 -2
  165. data/lib/glib-web.rb +9 -9
  166. data/lib/glib/crypt/utils.rb +26 -26
  167. data/lib/glib/dynamic_text/config.rb +21 -21
  168. data/lib/glib/engine.rb +7 -7
  169. data/lib/glib/json_crawler.rb +11 -11
  170. data/lib/glib/json_crawler/action_crawler.rb +23 -23
  171. data/lib/glib/json_crawler/action_crawlers/action_http.rb +11 -11
  172. data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +48 -48
  173. data/lib/glib/json_crawler/action_crawlers/menu.rb +12 -12
  174. data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +19 -19
  175. data/lib/glib/json_crawler/action_crawlers/run_multiple.rb +13 -13
  176. data/lib/glib/json_crawler/action_crawlers/windows_open.rb +33 -33
  177. data/lib/glib/json_crawler/coverage.rb +20 -20
  178. data/lib/glib/json_crawler/http.rb +120 -120
  179. data/lib/glib/json_crawler/router.rb +98 -98
  180. data/lib/glib/mailer_tester.rb +36 -36
  181. data/lib/glib/test_helpers.rb +52 -52
  182. data/lib/glib/value.rb +7 -7
  183. data/lib/glib/version.rb +5 -5
  184. data/lib/tasks/db.rake +95 -95
  185. metadata +3 -3
@@ -1,12 +1,12 @@
1
- module Glib
2
- module UrlsHelper
3
- def glib_url_current(new_params)
4
- url_for(params.to_unsafe_h.merge(new_params.merge(only_path: false)))
5
- end
6
-
7
- def glib_url_equals_current?(url)
8
- route = Rails.application.routes.recognize_path(url)
9
- route[:controller] == controller_name && route[:action] == action_name
10
- end
11
- end
12
- end
1
+ module Glib
2
+ module UrlsHelper
3
+ def glib_url_current(new_params)
4
+ url_for(params.to_unsafe_h.merge(new_params.merge(only_path: false)))
5
+ end
6
+
7
+ def glib_url_equals_current?(url)
8
+ route = Rails.application.routes.recognize_path(url)
9
+ route[:controller] == controller_name && route[:action] == action_name
10
+ end
11
+ end
12
+ end
@@ -1,9 +1,9 @@
1
- module Glib
2
- module ActiveStorage
3
- class Attachment < ::ActiveStorage::Attachment
4
- if Glib::DynamicText::Config.database_url.present?
5
- connects_to database: { writing: :dynamic_text, reading: :dynamic_text }
6
- end
7
- end
8
- end
9
- end
1
+ module Glib
2
+ module ActiveStorage
3
+ class Attachment < ::ActiveStorage::Attachment
4
+ if Glib::DynamicText::Config.database_url.present?
5
+ connects_to database: { writing: :dynamic_text, reading: :dynamic_text }
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,9 +1,9 @@
1
- module Glib
2
- module ActiveStorage
3
- class Blob < ::ActiveStorage::Blob
4
- if Glib::DynamicText::Config.database_url.present?
5
- connects_to database: { writing: :dynamic_text, reading: :dynamic_text }
6
- end
7
- end
8
- end
9
- end
1
+ module Glib
2
+ module ActiveStorage
3
+ class Blob < ::ActiveStorage::Blob
4
+ if Glib::DynamicText::Config.database_url.present?
5
+ connects_to database: { writing: :dynamic_text, reading: :dynamic_text }
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,18 +1,18 @@
1
- module Glib
2
- class ApplicationRecord < ActiveRecord::Base
3
- self.abstract_class = true
4
-
5
- scope :created_asc, -> { order(created_at: :asc) }
6
- scope :created_desc, -> { order(created_at: :desc) }
7
-
8
- def glib_enum_humanize(enum_name, default_value = nil)
9
- self.class.glib_enum_humanize(enum_name, send(enum_name), default_value)
10
- end
11
-
12
- def self.glib_enum_humanize(enum_name, enum_value, default_value = nil)
13
- if enum_value
14
- I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{enum_value}", default: default_value)
15
- end
16
- end
17
- end
18
- end
1
+ module Glib
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+
5
+ scope :created_asc, -> { order(created_at: :asc) }
6
+ scope :created_desc, -> { order(created_at: :desc) }
7
+
8
+ def glib_enum_humanize(enum_name, default_value = nil)
9
+ self.class.glib_enum_humanize(enum_name, send(enum_name), default_value)
10
+ end
11
+
12
+ def self.glib_enum_humanize(enum_name, enum_value, default_value = nil)
13
+ if enum_value
14
+ I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{enum_value}", default: default_value)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,9 +1,9 @@
1
- module Glib
2
- class DynamicTextRecord < ActiveRecord::Base
3
- self.abstract_class = true
4
-
5
- if Glib::DynamicText::Config.database_url.present?
6
- connects_to database: { writing: :dynamic_text, reading: :dynamic_text }
7
- end
8
- end
9
- end
1
+ module Glib
2
+ class DynamicTextRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+
5
+ if Glib::DynamicText::Config.database_url.present?
6
+ connects_to database: { writing: :dynamic_text, reading: :dynamic_text }
7
+ end
8
+ end
9
+ end
@@ -1,96 +1,96 @@
1
- module Glib
2
- class Text < Glib::DynamicTextRecord
3
- class << self
4
- def dt_has_many_attached(name, dependent: :purge_later)
5
- generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
6
- def #{name}
7
- @active_storage_attached_#{name} ||= ::ActiveStorage::Attached::Many.new("#{name}", self)
8
- end
9
-
10
- def #{name}=(attachables)
11
- if ActiveStorage.replace_on_assign_to_many
12
- attachment_changes["#{name}"] =
13
- if Array(attachables).none?
14
- ::ActiveStorage::Attached::Changes::DeleteMany.new("#{name}", self)
15
- else
16
- ::ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables)
17
- end
18
- else
19
- if Array(attachables).any?
20
- attachment_changes["#{name}"] =
21
- ::ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, #{name}.blobs + attachables)
22
- end
23
- end
24
- end
25
- CODE
26
-
27
- has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "Glib::ActiveStorage::Attachment", inverse_of: :record, dependent: :destroy do
28
- def purge
29
- each(&:purge)
30
- reset
31
- end
32
-
33
- def purge_later
34
- each(&:purge_later)
35
- reset
36
- end
37
- end
38
- has_many :"#{name}_blobs", through: :"#{name}_attachments", class_name: "Glib::ActiveStorage::Blob", source: :blob
39
-
40
- scope :"with_attached_#{name}", -> { includes("#{name}_attachments": :blob) }
41
-
42
- after_save { attachment_changes[name.to_s]&.save }
43
-
44
- after_commit(on: %i[ create update ]) { attachment_changes.delete(name.to_s).try(:upload) }
45
-
46
- ActiveRecord::Reflection.add_attachment_reflection(
47
- self,
48
- name,
49
- ActiveRecord::Reflection.create(:has_many_attached, name, nil, { dependent: dependent }, self)
50
- )
51
- end
52
- end
53
-
54
- dt_has_many_attached :images
55
-
56
- validates :scope, presence: true
57
- validates :lang, presence: true
58
- validates :key, presence: true, uniqueness: { scope: [:scope, :lang] }
59
- validates :content, presence: true
60
-
61
- after_save :update_to_redis
62
-
63
- def self.redis
64
- Glib::DynamicText::Config.redis
65
- end
66
-
67
- def self.get_content(key, default_value, options:)
68
- scope_key = "#{options[:scope]}.#{options[:lang]}.#{key}"
69
-
70
- content = redis.get(scope_key)
71
- text = find_by(scope: options[:scope], lang: options[:lang], key: key)
72
-
73
- if !(content && text)
74
- if text = find_by(scope: options[:scope], lang: options[:lang], key: key)
75
- update_content(scope_key, text.content)
76
- content = text.content
77
- else
78
- text = create(scope: options[:scope], lang: options[:lang], key: key, content: default_value)
79
- update_content(scope_key, default_value)
80
- content = default_value
81
- end
82
- end
83
-
84
- [content, text]
85
- end
86
-
87
- private
88
- def self.update_content(scope_key, content)
89
- redis.set(scope_key, content)
90
- end
91
-
92
- def update_to_redis
93
- Glib::Text.update_content("#{scope}.#{lang}.#{key}", content)
94
- end
95
- end
1
+ module Glib
2
+ class Text < Glib::DynamicTextRecord
3
+ class << self
4
+ def dt_has_many_attached(name, dependent: :purge_later)
5
+ generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
6
+ def #{name}
7
+ @active_storage_attached_#{name} ||= ::ActiveStorage::Attached::Many.new("#{name}", self)
8
+ end
9
+
10
+ def #{name}=(attachables)
11
+ if ActiveStorage.replace_on_assign_to_many
12
+ attachment_changes["#{name}"] =
13
+ if Array(attachables).none?
14
+ ::ActiveStorage::Attached::Changes::DeleteMany.new("#{name}", self)
15
+ else
16
+ ::ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables)
17
+ end
18
+ else
19
+ if Array(attachables).any?
20
+ attachment_changes["#{name}"] =
21
+ ::ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, #{name}.blobs + attachables)
22
+ end
23
+ end
24
+ end
25
+ CODE
26
+
27
+ has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "Glib::ActiveStorage::Attachment", inverse_of: :record, dependent: :destroy do
28
+ def purge
29
+ each(&:purge)
30
+ reset
31
+ end
32
+
33
+ def purge_later
34
+ each(&:purge_later)
35
+ reset
36
+ end
37
+ end
38
+ has_many :"#{name}_blobs", through: :"#{name}_attachments", class_name: "Glib::ActiveStorage::Blob", source: :blob
39
+
40
+ scope :"with_attached_#{name}", -> { includes("#{name}_attachments": :blob) }
41
+
42
+ after_save { attachment_changes[name.to_s]&.save }
43
+
44
+ after_commit(on: %i[ create update ]) { attachment_changes.delete(name.to_s).try(:upload) }
45
+
46
+ ActiveRecord::Reflection.add_attachment_reflection(
47
+ self,
48
+ name,
49
+ ActiveRecord::Reflection.create(:has_many_attached, name, nil, { dependent: dependent }, self)
50
+ )
51
+ end
52
+ end
53
+
54
+ dt_has_many_attached :images
55
+
56
+ validates :scope, presence: true
57
+ validates :lang, presence: true
58
+ validates :key, presence: true, uniqueness: { scope: [:scope, :lang] }
59
+ validates :content, presence: true
60
+
61
+ after_save :update_to_redis
62
+
63
+ def self.redis
64
+ Glib::DynamicText::Config.redis
65
+ end
66
+
67
+ def self.get_content(key, default_value, options:)
68
+ scope_key = "#{options[:scope]}.#{options[:lang]}.#{key}"
69
+
70
+ content = redis.get(scope_key)
71
+ text = find_by(scope: options[:scope], lang: options[:lang], key: key)
72
+
73
+ if !(content && text)
74
+ if text = find_by(scope: options[:scope], lang: options[:lang], key: key)
75
+ update_content(scope_key, text.content)
76
+ content = text.content
77
+ else
78
+ text = create(scope: options[:scope], lang: options[:lang], key: key, content: default_value)
79
+ update_content(scope_key, default_value)
80
+ content = default_value
81
+ end
82
+ end
83
+
84
+ [content, text]
85
+ end
86
+
87
+ private
88
+ def self.update_content(scope_key, content)
89
+ redis.set(scope_key, content)
90
+ end
91
+
92
+ def update_to_redis
93
+ Glib::Text.update_content("#{scope}.#{lang}.#{key}", content)
94
+ end
95
+ end
96
96
  end
@@ -1,161 +1,161 @@
1
- # The main purpose of this is for security. If it is important to display useful error message or to provide a "banana", then
2
- # it's better to perform an explicit check (e.g. as a validation in the model or using a before_action).
3
- module Glib
4
- class ApplicationPolicy
5
- attr_reader :user, :record, :policy_name, :controller, :request, :params
6
-
7
- private
8
- def initialize(user, record, policy_name, controller, request, params)
9
- @user = user
10
- @record = record
11
- @controller = controller
12
- @request = request
13
- # Don't get params from request because we might not have a proper request object. This might execute in Sidekiq.
14
- # See Presenter::Model::inside_mock_controller()
15
- @params = params
16
- @policy_name = policy_name
17
- end
18
-
19
- class << self
20
- attr_reader :catch_all
21
-
22
- # This is to define the authorization logic for an action (or a group of actions). It's different from controller's
23
- # authorize().
24
- private # Used by child
25
- def authorize(*actions, &block)
26
- actions.each do |action|
27
- if action == :glib_all
28
- # Serve as a catch-all to all actions that have not been specified in the policy.
29
- @catch_all = block
30
- else
31
- method_name = "#{action}?"
32
- # Avoid accidentally redefining multiple times from child policies. But it's okay if the child policy
33
- # wants to override the parent's authorization method.
34
- raise "Action authorization has been declared: #{action}" if instance_methods(false).include?(method_name.to_sym)
35
- define_method method_name, &block
36
- end
37
- end
38
- end
39
- end
40
-
41
- private
42
- def catch_all
43
- self.class.catch_all
44
- end
45
-
46
- private
47
- # To ensure the block is called on the policy's instance instead class.
48
- def call_catch_all
49
- instance_eval(&catch_all)
50
- end
51
-
52
- authorize :index do
53
- # We need this line because in `index` action, this method will be called instead of method_missing().
54
- # Having this line ensures that the catch_all behaviour works according to the priority below:
55
- # - child_policy#index?
56
- # - child_policy#manage? -- catch_all
57
- # - application_policy@index?
58
- return call_catch_all if catch_all
59
-
60
- false
61
- end
62
-
63
- authorize :show do
64
- return call_catch_all if catch_all
65
-
66
- scope.where(id: record.id).exists?
67
- end
68
-
69
- authorize :create do
70
- return call_catch_all if catch_all
71
-
72
- false
73
- end
74
-
75
- authorize :new do
76
- return call_catch_all if catch_all
77
-
78
- create?
79
- end
80
-
81
- authorize :update do
82
- return call_catch_all if catch_all
83
-
84
- false
85
- end
86
-
87
- authorize :edit do
88
- return call_catch_all if catch_all
89
-
90
- update?
91
- end
92
-
93
- authorize :destroy do
94
- return call_catch_all if catch_all
95
-
96
- false
97
- end
98
-
99
- public
100
- def method_missing(name, *args, &block)
101
- if name.to_s.end_with?('?') && catch_all
102
- call_catch_all
103
- else
104
- super
105
- end
106
- end
107
-
108
- public
109
- def scope
110
- policy_scope_class = Pundit::PolicyFinder.new(@policy_name).scope
111
- return unless policy_scope_class
112
-
113
- controller.policy_scope(record.class, policy_scope_class: policy_scope_class)
114
- end
115
-
116
- public
117
- def self.args_builder
118
- Proc.new { |controller| [] }
119
- end
120
-
121
- # TODO: Remove. Deprecated
122
- # private # Used by child
123
- # def public?
124
- # true
125
- # end
126
-
127
- class Scope
128
- attr_reader :user, :scope
129
-
130
- def initialize(user, scope)
131
- @user = user
132
- @scope = scope
133
- end
134
-
135
- # def current_user
136
- # user
137
- # end
138
-
139
- # To be overridden
140
- def resolve
141
- scope.none
142
- end
143
- end
144
-
145
- private # Used by child
146
- def everyone
147
- true
148
- end
149
-
150
- # def current_user
151
- # user
152
- # end
153
-
154
- # TODO: Bad pattern. Implement explicit policy parameter instead.
155
- # - E.g. can? :destroy, :service_subscription_auto_renewal, { service_subscription: @service_subscription }
156
- # - E.g. super class: :service_subscription_auto_renewal, { service_subscription: @service_subscription }
157
- def controller_var(name)
158
- controller.instance_variable_get(:"@#{name}")
159
- end
160
- end
161
- end
1
+ # The main purpose of this is for security. If it is important to display useful error message or to provide a "banana", then
2
+ # it's better to perform an explicit check (e.g. as a validation in the model or using a before_action).
3
+ module Glib
4
+ class ApplicationPolicy
5
+ attr_reader :user, :record, :policy_name, :controller, :request, :params
6
+
7
+ private
8
+ def initialize(user, record, policy_name, controller, request, params)
9
+ @user = user
10
+ @record = record
11
+ @controller = controller
12
+ @request = request
13
+ # Don't get params from request because we might not have a proper request object. This might execute in Sidekiq.
14
+ # See Presenter::Model::inside_mock_controller()
15
+ @params = params
16
+ @policy_name = policy_name
17
+ end
18
+
19
+ class << self
20
+ attr_reader :catch_all
21
+
22
+ # This is to define the authorization logic for an action (or a group of actions). It's different from controller's
23
+ # authorize().
24
+ private # Used by child
25
+ def authorize(*actions, &block)
26
+ actions.each do |action|
27
+ if action == :glib_all
28
+ # Serve as a catch-all to all actions that have not been specified in the policy.
29
+ @catch_all = block
30
+ else
31
+ method_name = "#{action}?"
32
+ # Avoid accidentally redefining multiple times from child policies. But it's okay if the child policy
33
+ # wants to override the parent's authorization method.
34
+ raise "Action authorization has been declared: #{action}" if instance_methods(false).include?(method_name.to_sym)
35
+ define_method method_name, &block
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ private
42
+ def catch_all
43
+ self.class.catch_all
44
+ end
45
+
46
+ private
47
+ # To ensure the block is called on the policy's instance instead class.
48
+ def call_catch_all
49
+ instance_eval(&catch_all)
50
+ end
51
+
52
+ authorize :index do
53
+ # We need this line because in `index` action, this method will be called instead of method_missing().
54
+ # Having this line ensures that the catch_all behaviour works according to the priority below:
55
+ # - child_policy#index?
56
+ # - child_policy#manage? -- catch_all
57
+ # - application_policy@index?
58
+ return call_catch_all if catch_all
59
+
60
+ false
61
+ end
62
+
63
+ authorize :show do
64
+ return call_catch_all if catch_all
65
+
66
+ scope.where(id: record.id).exists?
67
+ end
68
+
69
+ authorize :create do
70
+ return call_catch_all if catch_all
71
+
72
+ false
73
+ end
74
+
75
+ authorize :new do
76
+ return call_catch_all if catch_all
77
+
78
+ create?
79
+ end
80
+
81
+ authorize :update do
82
+ return call_catch_all if catch_all
83
+
84
+ false
85
+ end
86
+
87
+ authorize :edit do
88
+ return call_catch_all if catch_all
89
+
90
+ update?
91
+ end
92
+
93
+ authorize :destroy do
94
+ return call_catch_all if catch_all
95
+
96
+ false
97
+ end
98
+
99
+ public
100
+ def method_missing(name, *args, &block)
101
+ if name.to_s.end_with?('?') && catch_all
102
+ call_catch_all
103
+ else
104
+ super
105
+ end
106
+ end
107
+
108
+ public
109
+ def scope
110
+ policy_scope_class = Pundit::PolicyFinder.new(@policy_name).scope
111
+ return unless policy_scope_class
112
+
113
+ controller.policy_scope(record.class, policy_scope_class: policy_scope_class)
114
+ end
115
+
116
+ public
117
+ def self.args_builder
118
+ Proc.new { |controller| [] }
119
+ end
120
+
121
+ # TODO: Remove. Deprecated
122
+ # private # Used by child
123
+ # def public?
124
+ # true
125
+ # end
126
+
127
+ class Scope
128
+ attr_reader :user, :scope
129
+
130
+ def initialize(user, scope)
131
+ @user = user
132
+ @scope = scope
133
+ end
134
+
135
+ # def current_user
136
+ # user
137
+ # end
138
+
139
+ # To be overridden
140
+ def resolve
141
+ scope.none
142
+ end
143
+ end
144
+
145
+ private # Used by child
146
+ def everyone
147
+ true
148
+ end
149
+
150
+ # def current_user
151
+ # user
152
+ # end
153
+
154
+ # TODO: Bad pattern. Implement explicit policy parameter instead.
155
+ # - E.g. can? :destroy, :service_subscription_auto_renewal, { service_subscription: @service_subscription }
156
+ # - E.g. super class: :service_subscription_auto_renewal, { service_subscription: @service_subscription }
157
+ def controller_var(name)
158
+ controller.instance_variable_get(:"@#{name}")
159
+ end
160
+ end
161
+ end