klastera 1.2.0 → 1.2.4
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/models/klastera/concerns/clusterizable.rb +16 -2
- data/app/views/layouts/klastera/_cluster_entity_fields.html.erb +1 -1
- data/app/views/layouts/klastera/_nested_cluster_entity.html.erb +2 -0
- data/config/locales/es.yml +1 -0
- data/lib/klastera.rb +99 -54
- data/lib/klastera/version.rb +2 -2
- metadata +2 -3
- data/app/helpers/klastera/clusters_helper.rb +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5cc4bc5d29598040f68599863b41983f415778050bc988fb0c35b67e7d9e264b
|
|
4
|
+
data.tar.gz: d96dd17be603a6683084bc34c9c040c51e4cb9422af7a2956c97860f812299ae
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad8633404c203750947c1566d4c1d883bd7c33c1eae58982bb0489d62e769255caad49d75277244ad4b50f79fd95ef361c37408078d5ff657a7da7324d3bf75a
|
|
7
|
+
data.tar.gz: a4c6e14fafdd2eaa1c7664901a1590800d89006a257412b04b483c313fcdc61a1797340028ffe0e9c0bd9a15d38c3783d823bba4d665cd194dd8790d2369e971
|
|
@@ -9,6 +9,7 @@ module Klastera::Concerns::Clusterizable
|
|
|
9
9
|
|
|
10
10
|
validates :cluster_id, presence: true, if: proc { self.try(:cluster_id) && self.organization.required_suborganization_mode? }
|
|
11
11
|
validate :at_least_one_cluster_entity, if: proc { self.organization.required_suborganization_mode? }
|
|
12
|
+
validate :uniqueness_of_cluster_entity_record
|
|
12
13
|
|
|
13
14
|
scope :related_clusters, ->() {
|
|
14
15
|
includes(:cluster_entities).where("cluster_entities.entity_id = #{self.table_name}.id")
|
|
@@ -20,8 +21,15 @@ module Klastera::Concerns::Clusterizable
|
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
##
|
|
25
|
+
# This is a legacy method and we don't recommend using it.
|
|
26
|
+
# Implement directly Klastera.entity_clusters_string_list instead of this method.
|
|
27
|
+
# TODO: In order to deprecate it, you will need to perform some changes in the main app
|
|
28
|
+
##
|
|
29
|
+
def clusters_string_separated_by(separator,attribute=:name)
|
|
30
|
+
Klastera.entity_clusters_string_list!(
|
|
31
|
+
self.cluster_entities, separator, attribute
|
|
32
|
+
)
|
|
25
33
|
end
|
|
26
34
|
|
|
27
35
|
def has_one_cluster_entity
|
|
@@ -29,6 +37,12 @@ module Klastera::Concerns::Clusterizable
|
|
|
29
37
|
return errors.add(:cluster_entities, I18n.t('klastera.messages.has_one_cluster_entity'))
|
|
30
38
|
end
|
|
31
39
|
end
|
|
40
|
+
|
|
41
|
+
def uniqueness_of_cluster_entity_record
|
|
42
|
+
if cluster_entities.map(&:cluster_id).uniq.size != cluster_entities.size
|
|
43
|
+
return errors.add(:cluster_entities, I18n.t('klastera.messages.duplicated_cluster_entity') )
|
|
44
|
+
end
|
|
45
|
+
end
|
|
32
46
|
end
|
|
33
47
|
|
|
34
48
|
module ClassMethods
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<tr class="nested-fields">
|
|
2
2
|
<td class="field">
|
|
3
|
-
<%= f.select :cluster_id, cluster_clusters.map{|c|[c.name,c.id]}, { include_blank: true }, { class: 'form-control' } %>
|
|
3
|
+
<%= f.select :cluster_id, @cluster_clusters.map{|c|[c.name,c.id]}, { include_blank: true }, { class: 'form-control' } %>
|
|
4
4
|
</td>
|
|
5
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 %>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<% if cluster_organization.is_in_cluster_mode? %>
|
|
2
|
+
<% @cluster_clusters = cluster_clusters %>
|
|
2
3
|
<div class="col-xs-12">
|
|
3
4
|
<% if hide_title||=false %>
|
|
4
5
|
<div class="form-group file required <%=f.object.class.name.parameterize%>_cluster_entity<%=' has-error' if f.object.errors.has_key?(:cluster_entities)%>">
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
<table id="cluster-entities" class="table table-striped">
|
|
27
28
|
<tbody class="cluster-entity-rows">
|
|
28
29
|
<%= f.fields_for :cluster_entities do |cluster_entity|%>
|
|
30
|
+
<% next unless @cluster_clusters.map(&:id).include?(cluster_entity.try(:object).try(:cluster_id)) %>
|
|
29
31
|
<%= render 'layouts/klastera/cluster_entity_fields', f: cluster_entity %>
|
|
30
32
|
<% end %>
|
|
31
33
|
</body>
|
data/config/locales/es.yml
CHANGED
|
@@ -61,6 +61,7 @@ es:
|
|
|
61
61
|
at_least_one_cluster_entity: Debe agregar al menos un cluster
|
|
62
62
|
record_action_successfully: Registro %{a} exitosamente
|
|
63
63
|
cant_delete_the_last_record_in_required_suborganization_mode: No se puede eliminar el único cluster de esta organización
|
|
64
|
+
duplicated_cluster_entity: Hay un cluster duplicado
|
|
64
65
|
new_cluster_id:
|
|
65
66
|
nil: Cluster no existe
|
|
66
67
|
same: Cluster no puede ser el mismo
|
data/lib/klastera.rb
CHANGED
|
@@ -5,8 +5,36 @@ module Klastera
|
|
|
5
5
|
|
|
6
6
|
extend ActiveSupport::Concern
|
|
7
7
|
|
|
8
|
+
KLSTR_HELPERS = %i[
|
|
9
|
+
cluster_user cluster_organization user_has_more_than_one_cluster
|
|
10
|
+
cluster_scope cluster_clusters cluster_scope_filtered clusters_from
|
|
11
|
+
user_clusters_string_list
|
|
12
|
+
]
|
|
13
|
+
|
|
8
14
|
class << self
|
|
9
15
|
|
|
16
|
+
def set_cluster_entities_attributes!(entity,array_cluster_ids)
|
|
17
|
+
cluster_entities_attributes = {}
|
|
18
|
+
entity_cluster_entities = entity.try(:cluster_entities) || []
|
|
19
|
+
entity_clusters = entity_cluster_entities.map(&:cluster_id).sort
|
|
20
|
+
array_cluster_ids = array_cluster_ids.map(&:id).sort
|
|
21
|
+
if array_cluster_ids != entity_clusters
|
|
22
|
+
now = DateTime.now
|
|
23
|
+
entity_cluster_entities.each_with_index do |ec,index|
|
|
24
|
+
remove_cluster = true
|
|
25
|
+
if array_cluster_ids.include?(ec.cluster_id)
|
|
26
|
+
remove_cluster = false
|
|
27
|
+
array_cluster_ids.delete(ec.cluster_id)
|
|
28
|
+
end
|
|
29
|
+
cluster_entities_attributes[index] = { id: ec.id, cluster_id: ec.cluster_id, _destroy: remove_cluster }
|
|
30
|
+
end
|
|
31
|
+
array_cluster_ids.each_with_index do |cluster_id,index|
|
|
32
|
+
cluster_entities_attributes[now.to_i+index] = { cluster_id: cluster_id, _destroy: false }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
cluster_entities_attributes
|
|
36
|
+
end
|
|
37
|
+
|
|
10
38
|
#
|
|
11
39
|
# I like to wrap methods
|
|
12
40
|
#
|
|
@@ -30,7 +58,7 @@ module Klastera
|
|
|
30
58
|
# A force cluster organization won't return an entity out of a cluster, but
|
|
31
59
|
# we don't know if the clusterized entities are fully definition-compliant.
|
|
32
60
|
cluster_array << nil if cluster_organization.optional_suborganization_mode?
|
|
33
|
-
active_record_collection = active_record_collection.where("cluster_entities.cluster_id": cluster_array)
|
|
61
|
+
active_record_collection = active_record_collection.joins(:cluster_entities).where("cluster_entities.cluster_id": cluster_array)
|
|
34
62
|
end
|
|
35
63
|
# you may use a block only with clusterizable data
|
|
36
64
|
yield(active_record_collection) if block_given?
|
|
@@ -75,18 +103,21 @@ module Klastera
|
|
|
75
103
|
scope_klass = scope_class(scope).where(organization_id: organization)
|
|
76
104
|
session_clusters(user,organization) do |clusters|
|
|
77
105
|
if organization.is_in_cluster_mode?
|
|
106
|
+
scope_klass = scope_klass.select("DISTINCT ON (#{scope.table_name}.id) #{scope.table_name}.id, #{scope.table_name}.*")
|
|
78
107
|
scope_klass = scope_klass.includes(includes) if includes.present?
|
|
79
108
|
cluster_ids = clusters.map(&:id)
|
|
80
109
|
if organization.required_suborganization_mode?
|
|
81
110
|
scope_klass = scope_klass.joins(:cluster_entities).where( cluster_entities: { cluster_id: cluster_ids } )
|
|
82
111
|
else
|
|
112
|
+
or_these_cluster_ids = cluster_ids.present? ? " OR cluster_entities.cluster_id IN (#{cluster_ids.join(",")})" : ""
|
|
83
113
|
scope_klass = scope_klass.joins("
|
|
84
114
|
LEFT OUTER JOIN cluster_entities
|
|
85
|
-
ON
|
|
86
|
-
AND entity_id = #{scope.table_name}.id
|
|
115
|
+
ON entity_id = #{scope.table_name}.id
|
|
87
116
|
AND entity_type = '#{scope}'
|
|
88
|
-
")
|
|
117
|
+
").where("cluster_entities.id IS NULL#{or_these_cluster_ids}")
|
|
89
118
|
end
|
|
119
|
+
# Provisional fix to avoid SQL clashes due to DISTINCT ON clause
|
|
120
|
+
scope_klass = scope_class(scope).where(organization_id: organization).where(id: scope_klass.map(&:id))
|
|
90
121
|
end
|
|
91
122
|
end
|
|
92
123
|
scope_klass
|
|
@@ -118,38 +149,42 @@ module Klastera
|
|
|
118
149
|
end
|
|
119
150
|
clusters
|
|
120
151
|
end
|
|
121
|
-
end
|
|
122
152
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
153
|
+
##
|
|
154
|
+
# Return a string with cluster attribute separated by separator argument
|
|
155
|
+
# A array of cluster ids can be passed fo filter the result
|
|
156
|
+
#
|
|
157
|
+
def entity_clusters_string_list!(cluster_entities,separator,attribute=:name,allowed_cluster_ids=nil)
|
|
158
|
+
_cluster_entities = cluster_entities.reject(&:nil?)
|
|
159
|
+
if allowed_cluster_ids.is_a?(Array)
|
|
160
|
+
_cluster_entities.select!{|ce| allowed_cluster_ids.include?(ce.cluster_id)}
|
|
161
|
+
end
|
|
162
|
+
_cluster_entities.map do |ce|
|
|
163
|
+
ce.cluster.try(attribute)
|
|
164
|
+
end.compact.join(separator)
|
|
133
165
|
end
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
hide_action :cluster_organization=
|
|
143
|
-
hide_action :cluster_clusters
|
|
144
|
-
hide_action :cluster_clusters=
|
|
145
|
-
hide_action :cluster_scope_filtered
|
|
146
|
-
hide_action :cluster_scope_filtered=
|
|
147
|
-
hide_action :user_has_more_than_one_cluster
|
|
148
|
-
hide_action :user_has_more_than_one_cluster=
|
|
149
|
-
hide_action :clusters_from
|
|
150
|
-
hide_action :clusters_from=
|
|
166
|
+
|
|
167
|
+
##
|
|
168
|
+
# cluster_clusters needs the logged user and its organization
|
|
169
|
+
# that why, we perfomed this logic here
|
|
170
|
+
#
|
|
171
|
+
def user_clusters_string_list!(user,organization,cluster_entities,separator,attribute=:name)
|
|
172
|
+
@_session_clusters ||= self.session_clusters(user,organization)
|
|
173
|
+
self.entity_clusters_string_list!(cluster_entities, separator, attribute, @_session_clusters.map(&:id))
|
|
151
174
|
end
|
|
152
|
-
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def cluster_user
|
|
178
|
+
current_user
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def cluster_organization
|
|
182
|
+
current_organization
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def user_has_more_than_one_cluster
|
|
186
|
+
@cluster_clusters ||= cluster_clusters
|
|
187
|
+
@cluster_clusters.size > 1
|
|
153
188
|
end
|
|
154
189
|
|
|
155
190
|
def set_the_lonely_cluster
|
|
@@ -161,16 +196,22 @@ module Klastera
|
|
|
161
196
|
end
|
|
162
197
|
end
|
|
163
198
|
|
|
164
|
-
def
|
|
165
|
-
|
|
199
|
+
def set_cluster_filter
|
|
200
|
+
@filter = ::ClusterFilter.new(cluster_filter_params)
|
|
166
201
|
end
|
|
167
202
|
|
|
168
|
-
def
|
|
169
|
-
|
|
203
|
+
def cluster_filter_params
|
|
204
|
+
parameters = params.require(:cluster_filter) rescue nil
|
|
205
|
+
return {} if parameters.blank?
|
|
206
|
+
parameters.permit(*cluster_filter_permit_params)
|
|
170
207
|
end
|
|
171
208
|
|
|
172
|
-
def
|
|
173
|
-
|
|
209
|
+
def cluster_filter_permit_params
|
|
210
|
+
[ :cluster_id ].concat( ::ClusterFilter.attributes )
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def cluster_scope(scope,includes=[])
|
|
214
|
+
Klastera.cluster_scope!(cluster_user,cluster_organization,scope,includes)
|
|
174
215
|
end
|
|
175
216
|
|
|
176
217
|
def cluster_clusters
|
|
@@ -187,26 +228,30 @@ module Klastera
|
|
|
187
228
|
)
|
|
188
229
|
end
|
|
189
230
|
|
|
190
|
-
def user_has_more_than_one_cluster
|
|
191
|
-
@cluster_clusters ||= cluster_clusters
|
|
192
|
-
@cluster_clusters.size > 1
|
|
193
|
-
end
|
|
194
|
-
|
|
195
231
|
def clusters_from(scope,includes=[])
|
|
196
232
|
Klastera.clusters_from!(cluster_user,cluster_organization,scope,includes)
|
|
197
233
|
end
|
|
198
234
|
|
|
199
|
-
def
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
235
|
+
def user_clusters_string_list(object_entity,separator,attribute=:name)
|
|
236
|
+
Klastera.user_clusters_string_list!(
|
|
237
|
+
cluster_user,
|
|
238
|
+
cluster_organization,
|
|
239
|
+
object_entity.try(:cluster_entities),
|
|
240
|
+
separator,
|
|
241
|
+
attribute
|
|
242
|
+
)
|
|
207
243
|
end
|
|
208
244
|
|
|
209
|
-
|
|
210
|
-
|
|
245
|
+
included do
|
|
246
|
+
Klastera::KLSTR_HELPERS.each do |action|
|
|
247
|
+
if respond_to?(:helper_method)
|
|
248
|
+
helper_method(action)
|
|
249
|
+
end
|
|
250
|
+
if respond_to?(:hide_action)
|
|
251
|
+
hide_action(helper)
|
|
252
|
+
hide_action("#{helper}=")
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
before_action :set_the_lonely_cluster, only: %i[ create update ]
|
|
211
256
|
end
|
|
212
257
|
end
|
data/lib/klastera/version.rb
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
module Klastera
|
|
2
|
-
VERSION = "1.2.
|
|
3
|
-
end
|
|
2
|
+
VERSION = "1.2.4"
|
|
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.2.
|
|
4
|
+
version: 1.2.4
|
|
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-
|
|
11
|
+
date: 2020-06-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -54,7 +54,6 @@ files:
|
|
|
54
54
|
- app/controllers/klastera/application_controller.rb
|
|
55
55
|
- app/controllers/klastera/clusters_controller.rb
|
|
56
56
|
- app/helpers/klastera/application_helper.rb
|
|
57
|
-
- app/helpers/klastera/clusters_helper.rb
|
|
58
57
|
- app/models/klastera/cluster.rb
|
|
59
58
|
- app/models/klastera/cluster_entity.rb
|
|
60
59
|
- app/models/klastera/cluster_filter.rb
|