klastera 1.1.6.2 → 1.2.0
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/assets/stylesheets/klastera/clusters.css.scss +11 -0
- data/app/models/klastera/cluster_entity.rb +5 -0
- data/app/models/klastera/concerns/cluster_entity.rb +12 -0
- data/app/models/klastera/concerns/cluster_user.rb +3 -3
- data/app/models/klastera/concerns/clusterizable.rb +24 -4
- data/app/models/klastera/concerns/user.rb +13 -8
- data/app/views/layouts/klastera/_cluster_entity_fields.html.erb +10 -0
- data/app/views/layouts/klastera/_cluster_filter.html.erb +1 -1
- data/app/views/layouts/klastera/_cluster_user_fields.html.erb +2 -2
- data/app/views/layouts/klastera/_nested_cluster_entity.html.erb +41 -0
- data/app/views/layouts/klastera/_nested_cluster_user.html.erb +18 -16
- data/config/locales/es.yml +2 -0
- data/db/migrate/20200518142609_create_klastera_cluster_entities.rb +8 -0
- data/lib/klastera.rb +84 -26
- data/lib/klastera/version.rb +1 -1
- data/lib/tasks/klastera_tasks.rake +23 -0
- metadata +9 -76
- data/app/assets/stylesheets/klastera/application.css +0 -15
- data/app/assets/stylesheets/klastera/clusters.css +0 -4
- data/app/assets/stylesheets/scaffold.css +0 -56
- data/test/dummy/README.rdoc +0 -28
- data/test/dummy/Rakefile +0 -6
- data/test/dummy/app/assets/javascripts/application.js +0 -13
- data/test/dummy/app/assets/stylesheets/application.css +0 -15
- data/test/dummy/app/controllers/application_controller.rb +0 -5
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/bin/bundle +0 -3
- data/test/dummy/bin/rails +0 -4
- data/test/dummy/bin/rake +0 -4
- data/test/dummy/bin/setup +0 -29
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -26
- data/test/dummy/config/boot.rb +0 -5
- data/test/dummy/config/database.yml +0 -1
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -41
- data/test/dummy/config/environments/production.rb +0 -79
- data/test/dummy/config/environments/test.rb +0 -42
- data/test/dummy/config/initializers/assets.rb +0 -11
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
- data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/test/dummy/config/initializers/inflections.rb +0 -16
- data/test/dummy/config/initializers/mime_types.rb +0 -4
- data/test/dummy/config/initializers/session_store.rb +0 -3
- data/test/dummy/config/initializers/to_time_preserves_timezone.rb +0 -10
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -23
- data/test/dummy/config/routes.rb +0 -4
- data/test/dummy/config/secrets.yml +0 -22
- data/test/dummy/public/404.html +0 -67
- data/test/dummy/public/422.html +0 -67
- data/test/dummy/public/500.html +0 -66
- data/test/dummy/public/favicon.ico +0 -0
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: ae9963c78d2880fca43b1fd6bef6be6c7ebcdd957289dd1117d81b815fdef707
         | 
| 4 | 
            +
              data.tar.gz: 3ae1a3a37239c56675aaa9b9c82cfd65f6262777746bf6e720465c62e66af069
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: ed36fabfe91b44b8d8209a1484081021be21cb0309bfd8731cd1380aa6dcf210464f0e1e6cd5dbba218691cbae023223160ee287d6b698ce99756bc452e4c563
         | 
| 7 | 
            +
              data.tar.gz: 62ce187ce73ebf4bf07e045835a1f3c79a0c2a911c0f45c54d980938851afdf38dfe8f632641f0b6da40b5c62e82d03cf7d0286b321fed90c3873c267cce2574
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            module Klastera::Concerns::ClusterEntity
         | 
| 2 | 
            +
              extend ActiveSupport::Concern
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              included do
         | 
| 5 | 
            +
                self.table_name = 'cluster_entities'
         | 
| 6 | 
            +
                belongs_to :entity, polymorphic: true
         | 
| 7 | 
            +
                belongs_to :cluster, class_name: ::Cluster
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
              module ClassMethods
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| @@ -10,7 +10,7 @@ module Klastera::Concerns::ClusterUser | |
| 10 10 | 
             
                validates :cluster_id, presence: true
         | 
| 11 11 |  | 
| 12 12 | 
             
                scope :of, -> (user,organization) {
         | 
| 13 | 
            -
                  Rails.logger.warn("DON'T USE THIS SCOPE DIRECTLY: Use ::ClusterUser. | 
| 13 | 
            +
                  Rails.logger.warn("DON'T USE THIS SCOPE DIRECTLY: Use ::ClusterUser.clusters_from class method instead!")
         | 
| 14 14 | 
             
                  includes(:cluster).where(user_id: user, "clusters.organization_id": organization)
         | 
| 15 15 | 
             
                }
         | 
| 16 16 | 
             
              end
         | 
| @@ -20,7 +20,7 @@ module Klastera::Concerns::ClusterUser | |
| 20 20 | 
             
                ##
         | 
| 21 21 | 
             
                # Returns a hash with the users with cluster relation
         | 
| 22 22 | 
             
                #
         | 
| 23 | 
            -
                def  | 
| 23 | 
            +
                def user_clusters_from(organization)
         | 
| 24 24 | 
             
                  users_hash = {}
         | 
| 25 25 | 
             
                  organization_cluster_ids = ::Cluster.of(organization).map(&:id)
         | 
| 26 26 | 
             
                  ::ClusterUser.includes(:user).where(cluster_id: organization_cluster_ids).each do |cluster_user|
         | 
| @@ -35,7 +35,7 @@ module Klastera::Concerns::ClusterUser | |
| 35 35 | 
             
                 # Returns a Cluster::ActiveRecord_Relation
         | 
| 36 36 | 
             
                 #
         | 
| 37 37 | 
             
                 ##
         | 
| 38 | 
            -
                def  | 
| 38 | 
            +
                def clusters_from(user,organization)
         | 
| 39 39 | 
             
                  clusters = []
         | 
| 40 40 | 
             
                  unless user.can_admin_clusters?
         | 
| 41 41 | 
             
                    # We could return cu.clusters but you may quering this result and a array can't handle order, where and etc.
         | 
| @@ -4,16 +4,36 @@ module Klastera::Concerns::Clusterizable | |
| 4 4 | 
             
                attr_accessor :lonely_cluster
         | 
| 5 5 | 
             
                belongs_to :cluster
         | 
| 6 6 |  | 
| 7 | 
            -
                 | 
| 7 | 
            +
                has_many :cluster_entities, as: :entity, class_name: Klastera::ClusterEntity
         | 
| 8 | 
            +
                accepts_nested_attributes_for :cluster_entities, reject_if: :all_blank, allow_destroy: true
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                validates :cluster_id, presence: true, if: proc { self.try(:cluster_id) && self.organization.required_suborganization_mode? }
         | 
| 11 | 
            +
                validate :at_least_one_cluster_entity, if: proc { self.organization.required_suborganization_mode? }
         | 
| 8 12 |  | 
| 9 13 | 
             
                scope :related_clusters, ->() {
         | 
| 10 | 
            -
                  includes(: | 
| 14 | 
            +
                  includes(:cluster_entities).where("cluster_entities.entity_id = #{self.table_name}.id")
         | 
| 11 15 | 
             
                }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def at_least_one_cluster_entity
         | 
| 18 | 
            +
                  if cluster_entities.length == 0 || cluster_entities.reject{|cluster_entity| cluster_entity._destroy == true}.empty?
         | 
| 19 | 
            +
                    return errors.add(:cluster_entities, I18n.t('klastera.messages.at_least_one_cluster_entity'))
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def clusters_string_separated_by(separator)
         | 
| 24 | 
            +
                  self.cluster_entities.map{|ce|ce.cluster.name}.join(separator)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def has_one_cluster_entity
         | 
| 28 | 
            +
                  if cluster_entities.length > 1
         | 
| 29 | 
            +
                    return errors.add(:cluster_entities, I18n.t('klastera.messages.has_one_cluster_entity'))
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 12 32 | 
             
              end
         | 
| 13 33 |  | 
| 14 34 | 
             
              module ClassMethods
         | 
| 15 | 
            -
                def  | 
| 16 | 
            -
                  [ :cluster_id, :lonely_cluster ]
         | 
| 35 | 
            +
                def cluster_entity_params
         | 
| 36 | 
            +
                  [ :cluster_id, :lonely_cluster, { cluster_entities_attributes: [:id, :cluster_id, :_destroy] } ]
         | 
| 17 37 | 
             
                end
         | 
| 18 38 | 
             
              end
         | 
| 19 39 | 
             
            end
         | 
| @@ -33,20 +33,25 @@ module Klastera::Concerns::User | |
| 33 33 | 
             
                  self.organization.is_in_cluster_mode? && ( self.is_a_cluster_admin? || self.is_a_cluster_root? )
         | 
| 34 34 | 
             
                end
         | 
| 35 35 |  | 
| 36 | 
            +
                #
         | 
| 36 37 | 
             
                # We will try to create a cluster_user record whether
         | 
| 37 | 
            -
                # the organization is using force mode (if cluster_id isn't present,
         | 
| 38 | 
            -
                #  | 
| 39 | 
            -
                # (on  | 
| 40 | 
            -
                 | 
| 38 | 
            +
                # the organization is using force mode (if cluster_id isn't present, it will raise a validation error) 
         | 
| 39 | 
            +
                # or
         | 
| 40 | 
            +
                # cluster_id is present (on show/use mode organizations).
         | 
| 41 | 
            +
                #
         | 
| 42 | 
            +
                def try_to_clusterify!(role,cluster_ids)
         | 
| 41 43 | 
             
                  if self.try(:organization).try(:is_in_cluster_mode?)
         | 
| 42 44 | 
             
                    self.cluster_role = role
         | 
| 43 | 
            -
                    if self.try(:organization).try(:required_suborganization_mode?) ||  | 
| 44 | 
            -
                       | 
| 45 | 
            -
             | 
| 45 | 
            +
                    if self.try(:organization).try(:required_suborganization_mode?) || cluster_ids.present?
         | 
| 46 | 
            +
                      timestamp = DateTime.now.to_i
         | 
| 47 | 
            +
                      nested_attributes = {}
         | 
| 48 | 
            +
                      cluster_ids.each do |cluster_id|
         | 
| 49 | 
            +
                        nested_attributes["#{cluster_id}_#{timestamp}"] = {
         | 
| 46 50 | 
             
                          cluster_id: cluster_id,
         | 
| 47 51 | 
             
                          _destroy: false
         | 
| 48 52 | 
             
                        }
         | 
| 49 | 
            -
                       | 
| 53 | 
            +
                      end
         | 
| 54 | 
            +
                      self.cluster_users_attributes = nested_attributes
         | 
| 50 55 | 
             
                    end
         | 
| 51 56 | 
             
                  end
         | 
| 52 57 | 
             
                end
         | 
| @@ -0,0 +1,10 @@ | |
| 1 | 
            +
            <tr class="nested-fields">
         | 
| 2 | 
            +
              <td class="field">
         | 
| 3 | 
            +
                <%= f.select :cluster_id, cluster_clusters.map{|c|[c.name,c.id]}, { include_blank: true }, { class: 'form-control' } %>
         | 
| 4 | 
            +
              </td>
         | 
| 5 | 
            +
              <td class="action vertical-align-middle text-center" width="44">
         | 
| 6 | 
            +
                <%= link_to_remove_association f, class: 'btn btn-danger btn-xs text-danger' do %>
         | 
| 7 | 
            +
                  <i class="fa fa-trash"></i>
         | 
| 8 | 
            +
                <% end %>
         | 
| 9 | 
            +
              </td>
         | 
| 10 | 
            +
            </tr>
         | 
| @@ -4,7 +4,7 @@ | |
| 4 4 | 
             
                <%= button_tag(t('klastera.actions.filter'), class: 'btn btn-primary btn-sm float-right', data: { disable_with: "<i class='fa fa-spinner spin'></i>" }) %>
         | 
| 5 5 | 
             
              </div>
         | 
| 6 6 |  | 
| 7 | 
            -
              <%=yield(f)%>
         | 
| 7 | 
            +
              <%=yield(f) if block_given? %>
         | 
| 8 8 |  | 
| 9 9 | 
             
              <% if cluster_organization.is_in_cluster_mode? %>
         | 
| 10 10 | 
             
                <% cluster_collection = cluster_clusters.map{|c|[c.name,(c.id||c.nid)]} %>
         | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            <tr class="nested-fields">
         | 
| 2 2 | 
             
              <td class="field">
         | 
| 3 3 | 
             
                <%= f.select :cluster_id, @user.organization.clusters.map{|c|[c.name,c.id]}, { include_blank: true }, { class: 'form-control' } %>
         | 
| 4 | 
            -
             | 
| 5 | 
            -
              <td class="action vertical-align-middle" width="44">
         | 
| 4 | 
            +
              </td>
         | 
| 5 | 
            +
              <td class="action vertical-align-middle text-center" width="44">
         | 
| 6 6 | 
             
                <%= link_to_remove_association f, class: 'btn btn-danger btn-xs text-danger' do %>
         | 
| 7 7 | 
             
                  <i class="fa fa-trash"></i>
         | 
| 8 8 | 
             
                <% end %>
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            <% if cluster_organization.is_in_cluster_mode? %>
         | 
| 2 | 
            +
              <div class="col-xs-12">
         | 
| 3 | 
            +
                <% if hide_title||=false %>
         | 
| 4 | 
            +
                  <div class="form-group file required <%=f.object.class.name.parameterize%>_cluster_entity<%=' has-error' if f.object.errors.has_key?(:cluster_entities)%>">
         | 
| 5 | 
            +
                    <label class="text" for="<%=f.object.class.name.parameterize%>_cluster_entity">
         | 
| 6 | 
            +
                      <%=t('klastera.clusters.title')%>
         | 
| 7 | 
            +
                      <% if cluster_organization.required_suborganization_mode? %>
         | 
| 8 | 
            +
                        <abbr title="required">*</abbr>
         | 
| 9 | 
            +
                      <% end %>
         | 
| 10 | 
            +
                    </label>
         | 
| 11 | 
            +
                <% end %>
         | 
| 12 | 
            +
              
         | 
| 13 | 
            +
                  <div class="nested-cluster-entity">
         | 
| 14 | 
            +
                    <div class="panel panel-default">
         | 
| 15 | 
            +
                      <div class="panel-heading<%=' custom-required' if cluster_organization.required_suborganization_mode? %>">
         | 
| 16 | 
            +
                        <h4 class="panel-title">
         | 
| 17 | 
            +
                          <% unless hide_title||=false %>
         | 
| 18 | 
            +
                            <div class="float-left" style="line-height: 20px"><%=t('klastera.clusters.title')%></div>
         | 
| 19 | 
            +
                          <% end %>
         | 
| 20 | 
            +
                          <%= link_to_add_association f, :cluster_entities, partial: 'layouts/klastera/cluster_entity_fields', data: { 'association-insertion-node': :'tbody.cluster-entity-rows', 'association-insertion-method': :append }, class: 'btn btn-success btn-xs float-right color-white' do %>
         | 
| 21 | 
            +
                            <i class="fa fa-plus"></i>
         | 
| 22 | 
            +
                          <% end %>
         | 
| 23 | 
            +
                          <div class="clearfix"></div>
         | 
| 24 | 
            +
                        </h4>
         | 
| 25 | 
            +
                      </div>
         | 
| 26 | 
            +
                      <table id="cluster-entities" class="table table-striped">
         | 
| 27 | 
            +
                        <tbody class="cluster-entity-rows">
         | 
| 28 | 
            +
                          <%= f.fields_for :cluster_entities do |cluster_entity|%>
         | 
| 29 | 
            +
                            <%= render 'layouts/klastera/cluster_entity_fields', f: cluster_entity %>
         | 
| 30 | 
            +
                          <% end %>
         | 
| 31 | 
            +
                        </body>
         | 
| 32 | 
            +
                      </table>
         | 
| 33 | 
            +
                    </div>
         | 
| 34 | 
            +
                  </div>
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  <% if hide_title||=false %>
         | 
| 37 | 
            +
                      <div class="invalid-feedback"><%=f.object.try(:errors)&.[](:cluster_entities).try(:first)%></div>
         | 
| 38 | 
            +
                    </div>
         | 
| 39 | 
            +
                  <% end %>
         | 
| 40 | 
            +
              </div>
         | 
| 41 | 
            +
            <% end %>
         | 
| @@ -1,20 +1,22 @@ | |
| 1 1 | 
             
            <% if @user.try(:is_a_cluster_user?) %>
         | 
| 2 | 
            -
              <div class=" | 
| 3 | 
            -
                <div class="panel- | 
| 4 | 
            -
                  < | 
| 5 | 
            -
                    < | 
| 6 | 
            -
             | 
| 7 | 
            -
                       | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 2 | 
            +
              <div class="nested-cluster-user">
         | 
| 3 | 
            +
                <div class="panel panel-default">
         | 
| 4 | 
            +
                  <div class="panel-heading">
         | 
| 5 | 
            +
                    <h4 class="panel-title">
         | 
| 6 | 
            +
                      <div class="float-left" style="line-height: 20px"><%=t('klastera.clusters.title')%></div>
         | 
| 7 | 
            +
                      <%= link_to_add_association f, :cluster_users, partial: 'layouts/klastera/cluster_user_fields', data: { 'association-insertion-node': :'tbody.cluster-user-rows', 'association-insertion-method': :append }, class: 'btn btn-success btn-xs float-right color-white' do %>
         | 
| 8 | 
            +
                        <i class="fa fa-plus"></i>
         | 
| 9 | 
            +
                      <% end %>
         | 
| 10 | 
            +
                      <div class="clearfix"></div>
         | 
| 11 | 
            +
                    </h4>
         | 
| 12 | 
            +
                  </div>
         | 
| 13 | 
            +
                  <table id="cluster-users" class="table table-striped">
         | 
| 14 | 
            +
                    <tbody class="cluster-user-rows">
         | 
| 15 | 
            +
                      <%= f.fields_for :cluster_users do |cluster_user|%>
         | 
| 16 | 
            +
                        <%= render 'layouts/klastera/cluster_user_fields', f: cluster_user %>
         | 
| 17 | 
            +
                      <% end %>
         | 
| 18 | 
            +
                    </body>
         | 
| 19 | 
            +
                  </table>
         | 
| 11 20 | 
             
                </div>
         | 
| 12 | 
            -
                <table id="cluster-users" class="table">
         | 
| 13 | 
            -
                  <tbody class="cluster-user-rows">
         | 
| 14 | 
            -
                    <%= f.fields_for :cluster_users do |cluster_user|%>
         | 
| 15 | 
            -
                      <%= render 'layouts/klastera/cluster_user_fields', f: cluster_user %>
         | 
| 16 | 
            -
                    <% end %>
         | 
| 17 | 
            -
                  </body>
         | 
| 18 | 
            -
                </table>
         | 
| 19 21 | 
             
              </div>
         | 
| 20 22 | 
             
            <% end %>
         | 
    
        data/config/locales/es.yml
    CHANGED
    
    | @@ -57,6 +57,8 @@ es: | |
| 57 57 | 
             
                  created: Creado
         | 
| 58 58 | 
             
                  updated: Actualizado
         | 
| 59 59 | 
             
                messages:
         | 
| 60 | 
            +
                  has_one_cluster_entity: Está permitido agregar un sólo cluster
         | 
| 61 | 
            +
                  at_least_one_cluster_entity: Debe agregar al menos un cluster
         | 
| 60 62 | 
             
                  record_action_successfully: Registro %{a} exitosamente
         | 
| 61 63 | 
             
                  cant_delete_the_last_record_in_required_suborganization_mode: No se puede eliminar el único cluster de esta organización
         | 
| 62 64 | 
             
                  new_cluster_id:
         | 
    
        data/lib/klastera.rb
    CHANGED
    
    | @@ -3,41 +3,92 @@ require "klastera/engine" | |
| 3 3 | 
             
            module Klastera
         | 
| 4 4 | 
             
              mattr_accessor :organization_class
         | 
| 5 5 |  | 
| 6 | 
            -
              class RelatedClusterEntityComplianceError < StandardError; end
         | 
| 7 6 | 
             
              extend ActiveSupport::Concern
         | 
| 8 7 |  | 
| 9 8 | 
             
              class << self
         | 
| 10 9 |  | 
| 10 | 
            +
                #
         | 
| 11 | 
            +
                # I like to wrap methods
         | 
| 12 | 
            +
                #
         | 
| 13 | 
            +
                def cluster_scope_filtered!(scope,cluster_id,user,organization,includes=[])
         | 
| 14 | 
            +
                  self.filter_clusterized_collection_with!(
         | 
| 15 | 
            +
                    organization,
         | 
| 16 | 
            +
                    cluster_id,
         | 
| 17 | 
            +
                    self.cluster_scope!(user,organization,scope,includes)
         | 
| 18 | 
            +
                  )
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                #
         | 
| 22 | 
            +
                # In order to this works, active_record_collection argument
         | 
| 23 | 
            +
                # should be passed through cluster_scope! method before.
         | 
| 24 | 
            +
                #
         | 
| 25 | 
            +
                def filter_clusterized_collection_with!(cluster_organization,cluster_id,active_record_collection)
         | 
| 26 | 
            +
                  if cluster_organization.is_in_cluster_mode?
         | 
| 27 | 
            +
                    if cluster_id.present?
         | 
| 28 | 
            +
                      cluster_array = [cluster_id]
         | 
| 29 | 
            +
                      # Based on force/use/show definition we don't really need this validation.
         | 
| 30 | 
            +
                      # A force cluster organization won't return an entity out of a cluster, but
         | 
| 31 | 
            +
                      # we don't know if the clusterized entities are fully definition-compliant.
         | 
| 32 | 
            +
                      cluster_array << nil if cluster_organization.optional_suborganization_mode?
         | 
| 33 | 
            +
                      active_record_collection = active_record_collection.where("cluster_entities.cluster_id": cluster_array)
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                    # you may use a block only with clusterizable data
         | 
| 36 | 
            +
                    yield(active_record_collection) if block_given?
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                  active_record_collection
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                #
         | 
| 42 | 
            +
                #
         | 
| 43 | 
            +
                #
         | 
| 44 | 
            +
                def set_collection_before_group_by_entity!(cluster_organization,active_record_collection,model_class,entity_params)
         | 
| 45 | 
            +
                  entity_params_keys = [:entity_name,:entity_attribute,:entity_id,:entity_id_attribute,:unamed]
         | 
| 46 | 
            +
                  entity_params = entity_params.slice(*entity_params_keys).values
         | 
| 47 | 
            +
                  if model_class.try(:reflections).try(:keys).try(:include?,entity_params[0])
         | 
| 48 | 
            +
                    entity_params << "#{entity_params[0]}_id".to_sym
         | 
| 49 | 
            +
                    if entity_params[0] == 'cluster'
         | 
| 50 | 
            +
                      entity_params << :unclustered if cluster_organization.is_in_cluster_mode?
         | 
| 51 | 
            +
                      active_record_collection = Klastera.filter_clusterized_collection_with!(
         | 
| 52 | 
            +
                        cluster_organization,
         | 
| 53 | 
            +
                        entity_params[2],
         | 
| 54 | 
            +
                        active_record_collection
         | 
| 55 | 
            +
                      )
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
                    yield(
         | 
| 58 | 
            +
                      active_record_collection,
         | 
| 59 | 
            +
                      entity_params_keys.zip(entity_params).to_h)
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 11 63 | 
             
                ##
         | 
| 12 64 | 
             
                 # Returns a ::Cluster::ActiveRecord_Relation from a given scope
         | 
| 13 65 | 
             
                 #
         | 
| 14 66 | 
             
                def clusters_from!(user,organization,scope,includes=[])
         | 
| 15 | 
            -
                   | 
| 16 | 
            -
                  ::Cluster.where(id: _scope_result.related_clusters.map(&:cluster_id))
         | 
| 67 | 
            +
                  cluster_scope!(user,organization,scope,includes).related_clusters
         | 
| 17 68 | 
             
                end
         | 
| 18 69 |  | 
| 19 70 | 
             
                ##
         | 
| 20 | 
            -
                 # Returns a scope  | 
| 21 | 
            -
                 # the  | 
| 22 | 
            -
                 # the organization haven't active the cluster mode
         | 
| 23 | 
            -
                 #
         | 
| 71 | 
            +
                 # Returns a scope filtered by clusters or its
         | 
| 72 | 
            +
                 # organization if the cluster mode is not active.
         | 
| 24 73 | 
             
                 #
         | 
| 25 74 | 
             
                def cluster_scope!(user,organization,scope,includes=[])
         | 
| 26 | 
            -
                  scope_klass = scope_class(scope)
         | 
| 27 | 
            -
                  raise RelatedClusterEntityComplianceError, "attribute cluster_id was not found in #{scope_klass}" unless scope_klass.try(:column_names).try(:include?,'cluster_id')
         | 
| 28 | 
            -
                  scope_klass = scope_klass.includes(includes) if includes.present?
         | 
| 29 | 
            -
                  scope_klass = scope_klass.where(organization_id: organization)
         | 
| 30 | 
            -
             | 
| 75 | 
            +
                  scope_klass = scope_class(scope).where(organization_id: organization)
         | 
| 31 76 | 
             
                  session_clusters(user,organization) do |clusters|
         | 
| 32 | 
            -
                    if organization. | 
| 33 | 
            -
                      scope_klass = scope_klass. | 
| 34 | 
            -
             | 
| 35 | 
            -
                       | 
| 36 | 
            -
             | 
| 37 | 
            -
                       | 
| 77 | 
            +
                    if organization.is_in_cluster_mode?
         | 
| 78 | 
            +
                      scope_klass = scope_klass.includes(includes) if includes.present?
         | 
| 79 | 
            +
                      cluster_ids = clusters.map(&:id)
         | 
| 80 | 
            +
                      if organization.required_suborganization_mode?
         | 
| 81 | 
            +
                        scope_klass = scope_klass.joins(:cluster_entities).where( cluster_entities: { cluster_id: cluster_ids } )
         | 
| 82 | 
            +
                      else
         | 
| 83 | 
            +
                        scope_klass = scope_klass.joins("
         | 
| 84 | 
            +
                          LEFT OUTER JOIN cluster_entities
         | 
| 85 | 
            +
                            ON cluster_entities.cluster_id IN (#{cluster_ids.join(",")})
         | 
| 86 | 
            +
                            AND entity_id = #{scope.table_name}.id 
         | 
| 87 | 
            +
                            AND entity_type = '#{scope}'
         | 
| 88 | 
            +
                        ")
         | 
| 89 | 
            +
                      end
         | 
| 38 90 | 
             
                    end
         | 
| 39 91 | 
             
                  end
         | 
| 40 | 
            -
             | 
| 41 92 | 
             
                  scope_klass
         | 
| 42 93 | 
             
                end
         | 
| 43 94 |  | 
| @@ -45,6 +96,7 @@ module Klastera | |
| 45 96 | 
             
                 # TODO:
         | 
| 46 97 | 
             
                 # Implement a validation to ensure that
         | 
| 47 98 | 
             
                 # object is a ActiveRecord::Base class
         | 
| 99 | 
            +
                 # (or just try to guess how to retrieve the argument class)
         | 
| 48 100 | 
             
                 #
         | 
| 49 101 | 
             
                 ##
         | 
| 50 102 | 
             
                def scope_class(object)
         | 
| @@ -59,7 +111,7 @@ module Klastera | |
| 59 111 | 
             
                 #
         | 
| 60 112 | 
             
                 ##
         | 
| 61 113 | 
             
                def session_clusters(user,organization)
         | 
| 62 | 
            -
                  clusters = organization.is_in_cluster_mode? ? ::ClusterUser. | 
| 114 | 
            +
                  clusters = organization.is_in_cluster_mode? ? ::ClusterUser.clusters_from(user,organization) : []
         | 
| 63 115 | 
             
                  if block_given?
         | 
| 64 116 | 
             
                    clusters = clusters.reject{|c|c.id.blank?}
         | 
| 65 117 | 
             
                    yield(clusters)
         | 
| @@ -75,7 +127,7 @@ module Klastera | |
| 75 127 | 
             
                  helper_method :cluster_user
         | 
| 76 128 | 
             
                  helper_method :cluster_organization
         | 
| 77 129 | 
             
                  helper_method :cluster_clusters
         | 
| 78 | 
            -
                   | 
| 130 | 
            +
                  helper_method :cluster_scope_filtered
         | 
| 79 131 | 
             
                  helper_method :user_has_more_than_one_cluster
         | 
| 80 132 | 
             
                  helper_method :clusters_from
         | 
| 81 133 | 
             
                end
         | 
| @@ -90,8 +142,8 @@ module Klastera | |
| 90 142 | 
             
                  hide_action :cluster_organization=
         | 
| 91 143 | 
             
                  hide_action :cluster_clusters
         | 
| 92 144 | 
             
                  hide_action :cluster_clusters=
         | 
| 93 | 
            -
                   | 
| 94 | 
            -
                   | 
| 145 | 
            +
                  hide_action :cluster_scope_filtered
         | 
| 146 | 
            +
                  hide_action :cluster_scope_filtered=
         | 
| 95 147 | 
             
                  hide_action :user_has_more_than_one_cluster
         | 
| 96 148 | 
             
                  hide_action :user_has_more_than_one_cluster=
         | 
| 97 149 | 
             
                  hide_action :clusters_from
         | 
| @@ -125,9 +177,15 @@ module Klastera | |
| 125 177 | 
             
                Klastera.session_clusters(cluster_user,cluster_organization)
         | 
| 126 178 | 
             
              end
         | 
| 127 179 |  | 
| 128 | 
            -
               | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 180 | 
            +
              def cluster_scope_filtered(scope,cluster_id,includes=[])
         | 
| 181 | 
            +
                Klastera.cluster_scope_filtered!(
         | 
| 182 | 
            +
                  scope,
         | 
| 183 | 
            +
                  cluster_id,
         | 
| 184 | 
            +
                  cluster_user,
         | 
| 185 | 
            +
                  cluster_organization,
         | 
| 186 | 
            +
                  includes
         | 
| 187 | 
            +
                )
         | 
| 188 | 
            +
              end
         | 
| 131 189 |  | 
| 132 190 | 
             
              def user_has_more_than_one_cluster
         | 
| 133 191 | 
             
                @cluster_clusters ||= cluster_clusters
         |