From 8834a3b2fcf667ce5805d60e1b96eb0251f1ed81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Verg=C3=A9s?= Date: Mon, 2 Dec 2024 14:57:04 +0100 Subject: [PATCH] add an organization memoizer for helpers --- Gemfile.lock | 2 +- .../proposal_l_cell_override.rb | 23 ++++++++++ .../decidim_awesome/needs_awesome_config.rb | 2 - lib/decidim/decidim_awesome/awesome.rb | 2 + .../decidim_awesome/awesome_helpers.rb | 46 +++++++++++++------ lib/decidim/decidim_awesome/engine.rb | 6 +-- .../decidim_awesome/organization_memoizer.rb | 21 +++++++++ 7 files changed, 82 insertions(+), 20 deletions(-) create mode 100644 app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb create mode 100644 lib/decidim/decidim_awesome/organization_memoizer.rb diff --git a/Gemfile.lock b/Gemfile.lock index 0770ea9f5..48951696f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -845,7 +845,7 @@ DEPENDENCIES web-console RUBY VERSION - ruby 3.0.6p216 + ruby 3.0.7p220 BUNDLED WITH 2.4.22 diff --git a/app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb b/app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb new file mode 100644 index 000000000..7d85bd460 --- /dev/null +++ b/app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Decidim + module DecidimAwesome + module ProposalLCellOverride + extend ActiveSupport::Concern + + included do + private + + alias_method :decidim_original_cache_hash, :cache_hash + + def metadata_cell + @metadata_cell ||= awesome_voting_manifest_for(resource&.component)&.proposal_metadata_cell.presence || "decidim/proposals/proposal_metadata" + end + + def cache_hash + @cache_hash ||= "#{decidim_original_cache_hash}#{Decidim.cache_key_separator}#{model.extra_fields&.vote_weight_totals}" + end + end + end + end +end diff --git a/app/controllers/concerns/decidim/decidim_awesome/needs_awesome_config.rb b/app/controllers/concerns/decidim/decidim_awesome/needs_awesome_config.rb index d61f2177b..59bd0df2e 100644 --- a/app/controllers/concerns/decidim/decidim_awesome/needs_awesome_config.rb +++ b/app/controllers/concerns/decidim/decidim_awesome/needs_awesome_config.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "decidim/decidim_awesome/awesome_helpers" - module Decidim module DecidimAwesome module NeedsAwesomeConfig diff --git a/lib/decidim/decidim_awesome/awesome.rb b/lib/decidim/decidim_awesome/awesome.rb index 9f5de8679..dc1b506c5 100644 --- a/lib/decidim/decidim_awesome/awesome.rb +++ b/lib/decidim/decidim_awesome/awesome.rb @@ -4,6 +4,8 @@ module Decidim module DecidimAwesome include ActiveSupport::Configurable + autoload :AwesomeHelpers, "decidim/decidim_awesome/awesome_helpers" + autoload :OrganizationMemoizer, "decidim/decidim_awesome/organization_memoizer" autoload :Config, "decidim/decidim_awesome/config" autoload :SystemChecker, "decidim/decidim_awesome/system_checker" autoload :ContextAnalyzers, "decidim/decidim_awesome/context_analyzers" diff --git a/lib/decidim/decidim_awesome/awesome_helpers.rb b/lib/decidim/decidim_awesome/awesome_helpers.rb index 0022d2c6c..24fd20ce6 100644 --- a/lib/decidim/decidim_awesome/awesome_helpers.rb +++ b/lib/decidim/decidim_awesome/awesome_helpers.rb @@ -6,6 +6,8 @@ module Decidim # add a global helper with awesome configuration module DecidimAwesome module AwesomeHelpers + include OrganizationMemoizer + # Returns the normalized config for an Organization and the current url def awesome_config_instance return @awesome_config_instance if @awesome_config_instance @@ -20,12 +22,16 @@ def awesome_config_instance end def awesome_config - @awesome_config ||= awesome_config_instance.config + memoize("awesome_config") do + awesome_config_instance.config + end end def javascript_config_vars - awesome_config.slice(:allow_images_in_proposals, :allow_images_in_small_editor, :allow_images_in_full_editor, :allow_images_in_markdown_editor, :use_markdown_editor, - :auto_save_forms).to_json.html_safe + memoize("javascript_config_vars") do + awesome_config.slice(:allow_images_in_proposals, :allow_images_in_small_editor, :allow_images_in_full_editor, :allow_images_in_markdown_editor, :use_markdown_editor, + :auto_save_forms).to_json.html_safe + end end def show_public_intergram? @@ -36,11 +42,15 @@ def show_public_intergram? end def unfiltered_awesome_config - @unfiltered_awesome_config ||= awesome_config_instance.unfiltered_config + memoize("unfiltered_awesome_config") do + awesome_config_instance.unfiltered_config + end end def organization_awesome_config - @organization_awesome_config ||= awesome_config_instance.organization_config + memoize("organization_awesome_config") do + awesome_config_instance.organization_config + end end def awesome_version @@ -49,33 +59,43 @@ def awesome_version # Collects all CSS that is applied in the current URL context def awesome_scoped_styles - @awesome_scoped_styles ||= awesome_config_instance.collect_sub_configs_values("scoped_style") + memoize("awesome_scoped_styles") do + awesome_config_instance.collect_sub_configs_values("scoped_style") + end end # Collects all CSS that is applied in the current URL context def awesome_scoped_admin_styles - @awesome_scoped_admin_styles ||= awesome_config_instance.collect_sub_configs_values("scoped_admin_style") + memoize("awesome_scoped_admin_styles") do + awesome_config_instance.collect_sub_configs_values("scoped_admin_style") + end end # Collects all proposal custom fields that is applied in the current URL context def awesome_scoped_admins - @awesome_scoped_admins ||= awesome_config_instance.collect_sub_configs_values("scoped_admin") + memoize("awesome_scoped_admins") do + awesome_config_instance.collect_sub_configs_values("scoped_admin") + end end # Collects all proposal custom fields that is applied in the current URL context def awesome_proposal_custom_fields - @awesome_proposal_custom_fields ||= awesome_config_instance.collect_sub_configs_values("proposal_custom_field") + memoize("awesome_proposal_custom_fields") do + awesome_config_instance.collect_sub_configs_values("proposal_custom_field") + end end def awesome_proposal_private_custom_fields - @awesome_proposal_private_custom_fields ||= awesome_config_instance.collect_sub_configs_values("proposal_private_custom_field") + memoize("awesome_proposal_private_custom_fields") do + awesome_config_instance.collect_sub_configs_values("proposal_private_custom_field") + end end # this will check if the current component has been configured to use a custom voting manifest def awesome_voting_manifest_for(component) - return nil unless component.settings.respond_to? :awesome_voting_manifest - - DecidimAwesome.voting_registry.find(component.settings.awesome_voting_manifest) + memoize("awesome_voting_manifest_for_#{component.id}") do + DecidimAwesome.voting_registry.find(component.settings.try(:awesome_voting_manifest)) + end end # Retrives all the "admins_available_authorizations" for the user along with other possible authorizations diff --git a/lib/decidim/decidim_awesome/engine.rb b/lib/decidim/decidim_awesome/engine.rb index b11dc4eb9..007c158de 100644 --- a/lib/decidim/decidim_awesome/engine.rb +++ b/lib/decidim/decidim_awesome/engine.rb @@ -25,11 +25,9 @@ class Engine < ::Rails::Engine config.to_prepare do # activate Decidim LayoutHelper for the overriden views ActiveSupport.on_load :action_controller do - helper Decidim::LayoutHelper if respond_to?(:helper) + helper Decidim::DecidimAwesome::AwesomeHelpers end - # Include additional helpers globally - ActiveSupport.on_load(:action_view) { include Decidim::DecidimAwesome::AwesomeHelpers } - # Also for cells + # # Also for cells Decidim::ViewModel.include(Decidim::DecidimAwesome::AwesomeHelpers) # Override EtiquetteValidator diff --git a/lib/decidim/decidim_awesome/organization_memoizer.rb b/lib/decidim/decidim_awesome/organization_memoizer.rb new file mode 100644 index 000000000..f3f56fba0 --- /dev/null +++ b/lib/decidim/decidim_awesome/organization_memoizer.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Decidim + # add a global helper with awesome configuration + module DecidimAwesome + module OrganizationMemoizer + def self.memoize(key) + @memoized ||= {} + @memoized[key] ||= yield + end + + # memoize a piece of code in the class instead of the instance (helper are initialized for each view) + # only works if request.env["decidim.current_organization"] is defined + def memoize(key, &block) + return yield unless request.env["decidim.current_organization"]&.id + + OrganizationMemoizer.memoize("#{request.env["decidim.current_organization"].id}-#{key}", &block) + end + end + end +end