klastera 1.4 → 1.4.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef7788eb1826bb5f7ee15fe495ee69f181d3c028b4e51250bee6adfe8be4acbc
4
- data.tar.gz: d703b16d95ef2704ad7fcc01ed7d578f957744e362c2c968edea434eb97c167e
3
+ metadata.gz: dc8d3414d044460f33127e9eef4f0cb7cc6e6b83333697a944e5248cfe4970fd
4
+ data.tar.gz: 063dbb2a15f6b98b0219ac5af5059b40fa1da440c2e298a6140be4637ad1a504
5
5
  SHA512:
6
- metadata.gz: 3927e49fb28dceb261c9400a214f7a84a074e2330425eada935086023e235c25c8c6b530c109a46b6c934a22183200669c2afd7ac481a7090c5249b9580b55d1
7
- data.tar.gz: 8d812d8f464d26c10c4b97dfcbbcecf03d0ec62171269da18452e75aa91b88d71224300065b5b8b93a5c0c1af319ba008a9f3e600639bb881df42d4b2cb9c4f5
6
+ metadata.gz: af3e0d45ee32b14aa1f5b5bb27b246af015bfd6191b93846e52ca5e7789d245c7f068dc741afaa872a76244059dd31e71d543a8c1c8696c0346d183ac1bbb90b
7
+ data.tar.gz: 715adddc9f158ceb9c5eaa60e1318c986355d3f8a9e0c875b72903c053cc21fcf207cae038aefac9a51c4e65ffcf4a76ee13047e4a7dd70f908bcdbb0f202428
@@ -8,5 +8,11 @@ module Klastera::Concerns::ClusterEntity
8
8
  end
9
9
 
10
10
  module ClassMethods
11
+ def left_join_sources_of(scope_klass)
12
+ scope_klass_arel_table = scope_klass.arel_table
13
+ scope_klass_arel_table.join(arel_table, Arel::Nodes::OuterJoin).on(
14
+ scope_klass_arel_table[:id].eq(arel_table[:entity_id]), arel_table[:entity_type].eq(scope_klass.name)
15
+ ).join_sources
16
+ end
11
17
  end
12
18
  end
@@ -14,7 +14,7 @@ module Klastera::Concerns::ClusterUser
14
14
  #
15
15
  def clusters_of(organization,and_user=nil)
16
16
  and_user_id = and_user.present? ? { users: { id: and_user } } : {}
17
- ::Cluster.eager_load(cluster_users: :user).where({ organization_id: organization }.merge(and_user_id) )
17
+ ::Cluster.eager_load(cluster_users: :user).where({ organization_id: organization }.merge(and_user_id) ).order(order: :asc)
18
18
  end
19
19
 
20
20
  ##
@@ -1,5 +1,12 @@
1
- <% user_cluster_roles = user_cluster_roles.nil? ? User::CLUSTER_ROLES : user_cluster_roles %>
2
- <% other_visibility_reason = other_visibility_reason.nil? ? false : other_visibility_reason %>
1
+ <%
2
+ user_cluster_roles = user_cluster_roles.nil? ? User::CLUSTER_ROLES : user_cluster_roles
3
+ other_visibility_reason = other_visibility_reason.nil? ? false : other_visibility_reason
4
+ if @user.try(:organization).present?
5
+ normal_user_help = @user.try(:organization).optional_suborganization_mode? ? :optional : :required
6
+ else
7
+ normal_user_help = :new
8
+ end
9
+ %>
3
10
  <% if @user.try(:organization).try(:is_in_cluster_mode?) || other_visibility_reason %>
4
11
  <div class="form-group">
5
12
  <%= f.label t('klastera.cluster_role') %>
@@ -10,7 +17,7 @@
10
17
  data-content="<%=
11
18
  t('klastera.help.popover.content.cluster_role',
12
19
  m1: t('klastera.help.roles.description', r: t('klastera.roles.admin'), d: t('klastera.help.roles.admin')),
13
- m2: t('klastera.help.roles.description', r: t('klastera.roles.user'), d: t("klastera.help.roles.user.#{@user.organization.optional_suborganization_mode? ? :optional : :required}"))
20
+ m2: t('klastera.help.roles.description', r: t('klastera.roles.user'), d: t("klastera.help.roles.user.#{normal_user_help}"))
14
21
  )%>"
15
22
  >
16
23
  <%= fa_icon 'info-circle', class: 'btn-link' %>
@@ -79,6 +79,7 @@ es:
79
79
  root: Ve todos los clusters y no necesita asignación
80
80
  admin: Ve todos los clusters y no necesita asignación
81
81
  user:
82
+ new: Usuario al que se le puede restringir la cosas que puede ver a través de su asignación con los clusters
82
83
  required: Necesita que se le asigne uno o más clusters, de lo contrario no verá las entidades clusterizadas.
83
84
  optional: Si no tiene clusters asignados verá todas la entidades CON y SIN clusters. Si se le asigna un cluster, verá las entidades de ese cluster + las entidades SIN cluster.
84
85
  activemodel:
@@ -5,8 +5,9 @@ module Klastera
5
5
 
6
6
  extend ActiveSupport::Concern
7
7
 
8
+ UNCLUSTERED_POSITION = 9999
8
9
  UNCLUSTERED_ENTITY = 'without_cluster'.freeze
9
- KLSTR_HELPERS = %i[ cluster_user cluster_organization cluster_list cluster_scope cluster_scope_through_of user_clusters_string_list ].freeze
10
+ KLSTR_HELPERS = %i[ cluster_user cluster_organization cluster_list cluster_scope cluster_scope_through_of user_clusters_string_list cluster_scope_left_join ].freeze
10
11
 
11
12
  class << self
12
13
 
@@ -29,13 +30,15 @@ module Klastera
29
30
  if organization.is_in_cluster_mode? && user.cannot_skip_cluster_clause?
30
31
  active_record_collection = ::ClusterUser.clusters_of(organization,user)
31
32
  else
32
- active_record_collection = ::Cluster.where({ organization_id: organization })
33
+ active_record_collection = ::Cluster.where({ organization_id: organization }).order(order: :asc)
33
34
  end
34
35
 
35
36
  active_record_collection = active_record_collection.order(order: :asc)
36
37
 
37
38
  if include_unclustered && organization.optional_suborganization_mode? # For show and use modes only
38
- active_record_collection << ::Cluster.new({nid: UNCLUSTERED_ENTITY, name: I18n.t("klastera.#{UNCLUSTERED_ENTITY}")})
39
+ active_record_collection.append(
40
+ ::Cluster.new({nid: UNCLUSTERED_ENTITY, name: I18n.t("klastera.#{UNCLUSTERED_ENTITY}")}, order: UNCLUSTERED_POSITION )
41
+ )
39
42
  end
40
43
  active_record_collection
41
44
  end
@@ -85,7 +88,7 @@ module Klastera
85
88
  if cluster_filter.present?
86
89
  cluster_ids = cluster_filter.is_a?(Array) ? cluster_filter : [cluster_filter]
87
90
  elsif force_cluster_clause
88
- cluster_ids = ::ClusterUser.clusters_of(organization,user).map(&:id).sort
91
+ cluster_ids = ::ClusterUser.clusters_of(organization,user).map(&:id)
89
92
  end
90
93
  # We will avoid the query unless cluster_ids is having values OR force_cluster_clause is set (see method description)
91
94
  if cluster_ids.present? || force_cluster_clause
@@ -107,7 +110,7 @@ module Klastera
107
110
  unclusterized_scope = scope_class(scope_klass)
108
111
 
109
112
  if organization.is_in_cluster_mode? && ( force_cluster_clause || user.cannot_skip_cluster_clause? )
110
- unclusterized_scope = unclusterized_scope.joins(relation => :cluster_entities)
113
+ unclusterized_scope = unclusterized_scope.joins(relation).joins(Klastera::ClusterEntity.left_join_sources_of(cluster_entity_klass))
111
114
  end
112
115
 
113
116
  if scope_klass.respond_to?(:organization)
@@ -117,22 +120,51 @@ module Klastera
117
120
  unclusterized_scope.where("#{relation}_id" => cluster_scope!(cluster_entity_klass, user, organization, cluster_filter, force_cluster_clause))
118
121
  end
119
122
 
120
- # 
123
+ #
121
124
  # Returns an array with a clusterized scoped result and its grouped version
122
125
  #
123
126
  def group_by_cluster_scope!(scope_klass, user, organization, cluster_filter=[], scope_scopes=[])
124
127
  cluster_ids = cluster_filter.is_a?(Array) ? cluster_filter : [cluster_filter]
125
- kluster_scope = cluster_scope!(scope_klass, user, organization, cluster_ids, organization.optional_suborganization_mode? )
128
+ kluster_scope = cluster_scope!(scope_klass, user, organization, cluster_ids, organization.is_in_cluster_mode? )
129
+
126
130
  scope_scopes.each do |tuple_scope|
127
131
  scope_name, scope_arg = tuple_scope
128
132
  kluster_scope = scope_arg.present? ? kluster_scope.send(scope_name,scope_arg) : kluster_scope.send(scope_name)
129
133
  end
130
- [
131
- kluster_scope,
132
- kluster_scope.order(:cluster_id).group_by do |e|
133
- e.cluster.present? ? e.cluster.name : I18n.t("klastera.#{UNCLUSTERED_ENTITY}")
134
+
135
+ group_by_block = ->(o) {
136
+ if organization.is_in_cluster_mode?
137
+ o.cluster.present? ? o.cluster.name : UNCLUSTERED_POSITION
138
+ else
139
+ I18n.t("klastera.group_by_cluster_scope.#{scope_klass.model_name.plural}")
134
140
  end
135
- ]
141
+ }
142
+
143
+ grouped_cluster_scope = kluster_scope.group_by(&group_by_block).sort_by{|k,v|k.to_s}
144
+
145
+ grouped_cluster_scope.dup.each do |group|
146
+ if group.first == UNCLUSTERED_POSITION
147
+ grouped_cluster_scope.delete(group)
148
+ group[0] = I18n.t("klastera.#{UNCLUSTERED_ENTITY}")
149
+ grouped_cluster_scope.append(group)
150
+ end
151
+ end
152
+
153
+ [ kluster_scope, grouped_cluster_scope ]
154
+ end
155
+
156
+ #
157
+ # A helper that returns a CLUSTER SCOPE to build queries that need explicit LEFT OUTER JOIN clause,
158
+ # instead of the default INNER JOIN provide by ActiveRecord's joins method
159
+ #
160
+ def cluster_scope_left_join!(scope_klass,organization)
161
+ cluster_entities_arel_table = Klastera::ClusterEntity.arel_table
162
+ cluster_arel_table = ::Cluster.arel_table
163
+ cluster_entities_cluster = cluster_entities_arel_table.join(cluster_arel_table, Arel::Nodes::OuterJoin).on(
164
+ cluster_entities_arel_table[:cluster_id].eq(cluster_arel_table[:id]),
165
+ ).join_sources
166
+
167
+ scope_class(scope_klass).where(organization_id: organization).joins(Klastera::ClusterEntity.left_join_sources_of(scope_klass)).joins(cluster_entities_cluster)
136
168
  end
137
169
  end
138
170
 
@@ -175,6 +207,10 @@ module Klastera
175
207
  Klastera.user_clusters_string_list!(cluster_user, cluster_organization, object_entity.try(:cluster_entities), separator, attribute)
176
208
  end
177
209
 
210
+ def cluster_scope_left_join(scope_klass)
211
+ Klastera.cluster_scope_left_join!(scope_klas,cluster_organization)
212
+ end
213
+
178
214
  included do
179
215
  Klastera::KLSTR_HELPERS.each do |action|
180
216
  if respond_to?(:helper_method)
@@ -1,3 +1,3 @@
1
1
  module Klastera
2
- VERSION = "1.4"
2
+ VERSION = "1.4.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: klastera
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.4'
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gino Barahona
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-29 00:00:00.000000000 Z
11
+ date: 2020-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails