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.
- checksums.yaml +4 -4
- data/app/channels/glib/channel/is_typing_channel.rb +34 -34
- data/app/channels/glib/channel/online_channel.rb +36 -36
- data/app/controllers/concerns/glib/analytics/funnel.rb +61 -61
- data/app/controllers/concerns/glib/auth/policy.rb +148 -148
- data/app/controllers/concerns/glib/json/dynamic_text.rb +126 -126
- data/app/controllers/concerns/glib/json/libs.rb +149 -149
- data/app/controllers/concerns/glib/json/new_dynamic_text.rb +122 -122
- data/app/controllers/concerns/glib/json/transformation.rb +11 -11
- data/app/controllers/concerns/glib/json/traversal.rb +92 -92
- data/app/controllers/concerns/glib/json/ui.rb +88 -88
- data/app/controllers/concerns/glib/json/validation.rb +13 -13
- data/app/controllers/glib/home_controller.rb +54 -54
- data/app/helpers/glib/app_feature_support_helper.rb +16 -16
- data/app/helpers/glib/dynamic_images_helper.rb +55 -55
- data/app/helpers/glib/dynamic_texts_helper.rb +42 -42
- data/app/helpers/glib/enum_helper.rb +18 -8
- data/app/helpers/glib/forms_helper.rb +15 -15
- data/app/helpers/glib/json_ui/abstract_builder.rb +309 -309
- data/app/helpers/glib/json_ui/action_builder.rb +140 -140
- data/app/helpers/glib/json_ui/action_builder/dialogs.rb +58 -58
- data/app/helpers/glib/json_ui/action_builder/http.rb +39 -39
- data/app/helpers/glib/json_ui/action_builder/panels.rb +14 -14
- data/app/helpers/glib/json_ui/action_builder/sheets.rb +15 -15
- data/app/helpers/glib/json_ui/action_builder/snackbars.rb +41 -41
- data/app/helpers/glib/json_ui/action_builder/windows.rb +33 -33
- data/app/helpers/glib/json_ui/analytics_helper.rb +17 -17
- data/app/helpers/glib/json_ui/dynamic_field_builders.rb +25 -25
- data/app/helpers/glib/json_ui/generic_builders.rb +28 -28
- data/app/helpers/glib/json_ui/list_builders.rb +110 -110
- data/app/helpers/glib/json_ui/menu_builder.rb +94 -94
- data/app/helpers/glib/json_ui/page_helper.rb +221 -221
- data/app/helpers/glib/json_ui/response_helper.rb +25 -25
- data/app/helpers/glib/json_ui/split_builders.rb +32 -32
- data/app/helpers/glib/json_ui/styling_helper.rb +55 -55
- data/app/helpers/glib/json_ui/table_builders.rb +74 -74
- data/app/helpers/glib/json_ui/view_builder.rb +240 -240
- data/app/helpers/glib/json_ui/view_builder/banners.rb +26 -26
- data/app/helpers/glib/json_ui/view_builder/charts.rb +33 -33
- data/app/helpers/glib/json_ui/view_builder/fields.rb +278 -279
- data/app/helpers/glib/json_ui/view_builder/panels.rb +256 -256
- data/app/helpers/glib/urls_helper.rb +12 -12
- data/app/models/glib/active_storage/attachment.rb +9 -9
- data/app/models/glib/active_storage/blob.rb +9 -9
- data/app/models/glib/application_record.rb +18 -18
- data/app/models/glib/dynamic_text_record.rb +9 -9
- data/app/models/glib/text.rb +95 -95
- data/app/policies/glib/application_policy.rb +161 -161
- data/app/validators/email_typo_validator.rb +38 -38
- data/app/validators/email_validator.rb +7 -7
- data/app/validators/url_validator.rb +20 -20
- data/app/views/json_ui/garage/_nav_menu.json.jbuilder +70 -70
- data/app/views/json_ui/garage/actions/_dialogs.json.jbuilder +104 -104
- data/app/views/json_ui/garage/actions/_http.json.jbuilder +24 -24
- data/app/views/json_ui/garage/actions/_panels.json.jbuilder +18 -18
- data/app/views/json_ui/garage/actions/_reload.json.jbuilder +17 -17
- data/app/views/json_ui/garage/actions/_sheets.json.jbuilder +18 -18
- data/app/views/json_ui/garage/actions/_snackbars.json.jbuilder +33 -33
- data/app/views/json_ui/garage/actions/_timeouts.json.jbuilder +24 -24
- data/app/views/json_ui/garage/actions/_windows.json.jbuilder +24 -24
- data/app/views/json_ui/garage/actions/dialogs_oauth_post.json.jbuilder +6 -6
- data/app/views/json_ui/garage/actions/index.json.jbuilder +24 -24
- data/app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder +6 -6
- data/app/views/json_ui/garage/forms/basic.json.jbuilder +21 -21
- data/app/views/json_ui/garage/forms/basic_post.json.jbuilder +8 -8
- data/app/views/json_ui/garage/forms/checkboxes.json.jbuilder +43 -43
- data/app/views/json_ui/garage/forms/conditional_value.json.jbuilder +36 -36
- data/app/views/json_ui/garage/forms/dynamic_group.json.jbuilder +39 -39
- data/app/views/json_ui/garage/forms/dynamic_select.json.jbuilder +24 -22
- data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +38 -38
- data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +32 -37
- data/app/views/json_ui/garage/forms/floating_submit.json.jbuilder +19 -19
- data/app/views/json_ui/garage/forms/generic_post.json.jbuilder +3 -3
- data/app/views/json_ui/garage/forms/get_request.json.jbuilder +27 -27
- data/app/views/json_ui/garage/forms/index.json.jbuilder +113 -113
- data/app/views/json_ui/garage/forms/new_rich_text.json.jbuilder +39 -39
- data/app/views/json_ui/garage/forms/online_participant1.json.jbuilder +25 -25
- data/app/views/json_ui/garage/forms/online_participant2.json.jbuilder +25 -25
- data/app/views/json_ui/garage/forms/pickers.json.jbuilder +81 -81
- data/app/views/json_ui/garage/forms/ratings.json.jbuilder +49 -49
- data/app/views/json_ui/garage/forms/rich_text.json.jbuilder +40 -40
- data/app/views/json_ui/garage/forms/selects.json.jbuilder +91 -84
- data/app/views/json_ui/garage/forms/show_hide.json.jbuilder +130 -130
- data/app/views/json_ui/garage/forms/styled_boxes.json.jbuilder +35 -35
- data/app/views/json_ui/garage/forms/submission_flow.json.jbuilder +17 -17
- data/app/views/json_ui/garage/forms/submission_flow_post.json.jbuilder +26 -26
- data/app/views/json_ui/garage/forms/submission_indicator.json.jbuilder +63 -63
- data/app/views/json_ui/garage/forms/submission_indicator_post.json.jbuilder +25 -25
- data/app/views/json_ui/garage/forms/text_validation.json.jbuilder +81 -81
- data/app/views/json_ui/garage/forms/timers.json.jbuilder +120 -120
- data/app/views/json_ui/garage/home/blank.json.jbuilder +10 -10
- data/app/views/json_ui/garage/home/index.json.jbuilder +36 -36
- data/app/views/json_ui/garage/home/slow.json.jbuilder +11 -11
- data/app/views/json_ui/garage/lists/_autoload_section.json.jbuilder +28 -28
- data/app/views/json_ui/garage/lists/autoload_all.json.jbuilder +32 -32
- data/app/views/json_ui/garage/lists/autoload_as_needed.json.jbuilder +35 -35
- data/app/views/json_ui/garage/lists/chat_ui.json.jbuilder +94 -94
- data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +62 -62
- data/app/views/json_ui/garage/lists/fab.json.jbuilder +12 -12
- data/app/views/json_ui/garage/lists/index.json.jbuilder +38 -38
- data/app/views/json_ui/garage/lists/reordering.json.jbuilder +34 -34
- data/app/views/json_ui/garage/lists/templating.json.jbuilder +35 -35
- data/app/views/json_ui/garage/notifications/action_cable.json.jbuilder +114 -114
- data/app/views/json_ui/garage/notifications/android_post.json.jbuilder +48 -48
- data/app/views/json_ui/garage/notifications/index.json.jbuilder +36 -36
- data/app/views/json_ui/garage/notifications/web_socket.json.jbuilder +60 -60
- data/app/views/json_ui/garage/pages/flat_centered.json.jbuilder +29 -29
- data/app/views/json_ui/garage/pages/full_width.json.jbuilder +29 -29
- data/app/views/json_ui/garage/pages/full_width_height.json.jbuilder +16 -16
- data/app/views/json_ui/garage/pages/index.json.jbuilder +62 -62
- data/app/views/json_ui/garage/pages/layout.json.jbuilder +18 -18
- data/app/views/json_ui/garage/pages/lifecycle_hooks.json.jbuilder +13 -13
- data/app/views/json_ui/garage/pages/loading_indicator.json.jbuilder +10 -10
- data/app/views/json_ui/garage/pages/nav_buttons.json.jbuilder +21 -21
- data/app/views/json_ui/garage/pages/nested_scroll.json.jbuilder +40 -40
- data/app/views/json_ui/garage/pages/tab_bar.json.jbuilder +31 -31
- data/app/views/json_ui/garage/panels/_styled.json.jbuilder +78 -78
- data/app/views/json_ui/garage/panels/card.json.jbuilder +4 -4
- data/app/views/json_ui/garage/panels/carousel.json.jbuilder +37 -37
- data/app/views/json_ui/garage/panels/custom.json.jbuilder +17 -17
- data/app/views/json_ui/garage/panels/flow.json.jbuilder +59 -59
- data/app/views/json_ui/garage/panels/horizontal.json.jbuilder +91 -91
- data/app/views/json_ui/garage/panels/index.json.jbuilder +138 -134
- data/app/views/json_ui/garage/panels/outlined.json.jbuilder +4 -4
- data/app/views/json_ui/garage/panels/responsive.json.jbuilder +98 -98
- data/app/views/json_ui/garage/panels/split.json.jbuilder +182 -182
- data/app/views/json_ui/garage/panels/ul.json.jbuilder +33 -0
- data/app/views/json_ui/garage/panels/vertical.json.jbuilder +55 -55
- data/app/views/json_ui/garage/panels/web.json.jbuilder +15 -15
- data/app/views/json_ui/garage/services/dynamic_text.json.jbuilder +13 -13
- data/app/views/json_ui/garage/services/image.json.jbuilder +47 -47
- data/app/views/json_ui/garage/services/index.json.jbuilder +17 -17
- data/app/views/json_ui/garage/tables/_autoload_section.json.jbuilder +16 -16
- data/app/views/json_ui/garage/tables/autoload_all.json.jbuilder +43 -43
- data/app/views/json_ui/garage/tables/autoload_as_needed.json.jbuilder +50 -50
- data/app/views/json_ui/garage/tables/export_import.json.jbuilder +29 -29
- data/app/views/json_ui/garage/tables/horizontal_scroll.json.jbuilder +26 -26
- data/app/views/json_ui/garage/tables/index.json.jbuilder +25 -25
- data/app/views/json_ui/garage/tables/layout.json.jbuilder +40 -40
- data/app/views/json_ui/garage/views/_chart_data.json.jbuilder +17 -17
- data/app/views/json_ui/garage/views/banners.json.jbuilder +63 -63
- data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +30 -30
- data/app/views/json_ui/garage/views/charts.json.jbuilder +115 -115
- data/app/views/json_ui/garage/views/controls.json.jbuilder +37 -37
- data/app/views/json_ui/garage/views/icon_names.json.jbuilder +1450 -1450
- data/app/views/json_ui/garage/views/icons.json.jbuilder +15 -14
- data/app/views/json_ui/garage/views/images.json.jbuilder +89 -89
- data/app/views/json_ui/garage/views/index.json.jbuilder +67 -67
- data/app/views/json_ui/garage/views/links.json.jbuilder +70 -70
- data/app/views/json_ui/garage/views/map_cluster_data.json.jbuilder +41 -41
- data/app/views/json_ui/garage/views/map_data.json.jbuilder +51 -51
- data/app/views/json_ui/garage/views/maps.json.jbuilder +31 -31
- data/app/views/json_ui/garage/views/markdowns.json.jbuilder +41 -41
- data/app/views/json_ui/garage/views/misc.json.jbuilder +34 -34
- data/app/views/json_ui/garage/views/texts.json.jbuilder +35 -35
- data/app/views/layouts/json_ui/renderer.html.erb +35 -35
- data/config/routes.rb +7 -7
- data/lib/generators/glib/install_generator.rb +24 -24
- data/lib/generators/templates/20191017062519_create_texts.rb +12 -12
- data/lib/generators/templates/20191024063257_add_scope_to_texts.rb +7 -7
- data/lib/generators/templates/20191112095018_add_lang_to_texts.rb +7 -7
- data/lib/generators/templates/20191126071051_create_active_storage_tables.active_storage.rb +27 -27
- data/lib/generators/templates/database.yml +107 -107
- data/lib/generators/templates/dynamic_text.rb +2 -2
- data/lib/glib-web.rb +9 -9
- data/lib/glib/crypt/utils.rb +26 -26
- data/lib/glib/dynamic_text/config.rb +21 -21
- data/lib/glib/engine.rb +7 -7
- data/lib/glib/json_crawler.rb +11 -11
- data/lib/glib/json_crawler/action_crawler.rb +23 -23
- data/lib/glib/json_crawler/action_crawlers/action_http.rb +11 -11
- data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +48 -48
- data/lib/glib/json_crawler/action_crawlers/menu.rb +12 -12
- data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +19 -19
- data/lib/glib/json_crawler/action_crawlers/run_multiple.rb +13 -13
- data/lib/glib/json_crawler/action_crawlers/windows_open.rb +33 -33
- data/lib/glib/json_crawler/coverage.rb +20 -20
- data/lib/glib/json_crawler/http.rb +120 -120
- data/lib/glib/json_crawler/router.rb +98 -98
- data/lib/glib/mailer_tester.rb +36 -36
- data/lib/glib/test_helpers.rb +52 -52
- data/lib/glib/value.rb +7 -7
- data/lib/glib/version.rb +5 -5
- data/lib/tasks/db.rake +95 -95
- 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
|
data/app/models/glib/text.rb
CHANGED
|
@@ -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
|