klastera 1.2.4.2 → 1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8780a6928f5249deb34be42cac1f52a226113865b9f29ddb12e1a36f018141ed
4
- data.tar.gz: 1d99b709cea49a08533192ad8a1df621d78ea4d4ee59e1c266f06e952e6d8063
3
+ metadata.gz: ef7788eb1826bb5f7ee15fe495ee69f181d3c028b4e51250bee6adfe8be4acbc
4
+ data.tar.gz: d703b16d95ef2704ad7fcc01ed7d578f957744e362c2c968edea434eb97c167e
5
5
  SHA512:
6
- metadata.gz: 62c72441e00d9edb6c17525453cde71d864389c9342dbe54df3538609814aef0cdcbc3f7c49f49134d526e2da1f99ff1cc258b750cd024a7031afd3a80977d2d
7
- data.tar.gz: 806978a3fae34b0a2ddda331ce37b90de2e66f9c77bd707859b721ac7c83980f706b5eb432a00875db8b26b4c8901b11307ef62ab063952d013eef30eca69772
6
+ metadata.gz: 3927e49fb28dceb261c9400a214f7a84a074e2330425eada935086023e235c25c8c6b530c109a46b6c934a22183200669c2afd7ac481a7090c5249b9580b55d1
7
+ data.tar.gz: 8d812d8f464d26c10c4b97dfcbbcecf03d0ec62171269da18452e75aa91b88d71224300065b5b8b93a5c0c1af319ba008a9f3e600639bb881df42d4b2cb9c4f5
@@ -8,4 +8,39 @@
8
8
  background: none;
9
9
  }
10
10
  }
11
- }
11
+ }
12
+
13
+ #cluster-remote-table {
14
+ .cluster-id { width: 70px; }
15
+ .cluster-order { width: 70px; }
16
+ .cluster-color { width: 70px; }
17
+ .odd .colorless { color: #F9F9F9 }
18
+ .even .colorless { color: #FFF }
19
+ tr:hover .colorless { color: #444; opacity: 0.2;}
20
+ }
21
+
22
+ #cluster-remote-form {
23
+ h4.blank-modal-title {
24
+ margin: 0;
25
+ line-height: 28px;
26
+ letter-spacing: 0.05rem;
27
+ font-size: 21px;
28
+ font-weight: 400;
29
+ color: #666;
30
+ }
31
+ }
32
+
33
+
34
+ ul.klastera-option-help {
35
+ padding-left: 20px;
36
+ list-style-type: disc;
37
+ }
38
+
39
+ ul.klastera-option-help li {
40
+ margin-bottom: 10px;
41
+ padding-bottom: 5px;
42
+ border-bottom: 1px solid #DDD;
43
+ }
44
+
45
+ ul.klastera-option-help li b { color: #8A8A8A; font-weight: 400; }
46
+ ul.klastera-option-help li b:first-child { color: #2E5F9B; font-weight: bold; }
@@ -33,13 +33,11 @@ module Klastera
33
33
 
34
34
  def destroy
35
35
  new_cluster_id = params.require(:transfer).permit(:new_cluster_id).values.first rescue nil
36
- @transfer = Transfer.new(
37
- current_cluster: @cluster,
38
- new_cluster_id: new_cluster_id
39
- )
36
+ @transfer = Transfer.new( current_cluster: @cluster, new_cluster_id: new_cluster_id )
40
37
  if @transfer.valid?
41
- @transfer.to!(::Cluster.related_entities.map{|re|re.constantize})
42
- @cluster.destroy
38
+ if @transfer.apply!
39
+ @cluster.destroy
40
+ end
43
41
  set_clusters
44
42
  end
45
43
  end
@@ -8,9 +8,13 @@ module Klastera::Concerns::Cluster
8
8
 
9
9
  attr_reader :last_record
10
10
 
11
- MODES = [ :required_suborganization, :optional_suborganization, :optional_filter ].freeze
11
+ REQUIRED_MODE = :required_suborganization.freeze
12
+ OPTIONAL_MODE = :optional_suborganization.freeze
13
+ MODES = [ REQUIRED_MODE, OPTIONAL_MODE ].freeze
12
14
 
13
15
  belongs_to :organization, class_name: Klastera.organization_class
16
+ has_many :cluster_users
17
+ has_many :cluster_entities, dependent: :destroy
14
18
 
15
19
  scope :of, -> (organization,except_ids=[]) {
16
20
  _scope = where(organization: organization)
@@ -41,7 +45,7 @@ module Klastera::Concerns::Cluster
41
45
  end
42
46
 
43
47
  def has_related_entities_using_it?
44
- ::Cluster.total_records_assign_to(self) > 0
48
+ self.cluster_entities.size > 0
45
49
  end
46
50
 
47
51
  def can_transfer_and_destroy?
@@ -54,29 +58,10 @@ module Klastera::Concerns::Cluster
54
58
  end
55
59
 
56
60
  def display_name_nid
57
- "#{name} (#{nid})"
61
+ "#{name} (#{nid==Klastera::UNCLUSTERED_ENTITY ? I18n.t("klastera.#{ Klastera::UNCLUSTERED_ENTITY}") : nid})"
58
62
  end
59
63
  end
60
64
 
61
65
  module ClassMethods
62
- def related_entities(attr_needed: :class_name, macro: :has_many)
63
- ::Cluster.reflections.map do |association_name, reflection|
64
- reflection.send(attr_needed) if reflection.macro == macro
65
- end.compact
66
- end
67
-
68
- def total_records_assign_to(cluster_instance)
69
- related_entities(attr_needed: :name).inject(0) do |total, association_name|
70
- entity = cluster_instance.send(association_name)
71
- if entity.respond_to?(:cluster_id)
72
- total+=entity.where(cluster_id: cluster_instance.id).count
73
- end
74
- total
75
- end
76
- end
77
-
78
- def modes_as_strings
79
- ::Cluster::MODES.map{|m|m.to_s}
80
- end
81
66
  end
82
67
  end
@@ -4,11 +4,8 @@ module Klastera::Concerns::ClusterFilter
4
4
  included do
5
5
  include ActiveModel::Model
6
6
  include ActiveModel::Validations::Callbacks
7
- attr_accessor :cluster_id
8
7
 
9
- def kcluster_id
10
- self.cluster_id == 'without_cluster' ? nil : self.cluster_id
11
- end
8
+ attr_accessor :cluster_id
12
9
  end
13
10
 
14
11
  module ClassMethods
@@ -3,55 +3,39 @@ module Klastera::Concerns::ClusterUser
3
3
 
4
4
  included do
5
5
  self.table_name = 'cluster_users'
6
-
7
6
  belongs_to :user
8
7
  belongs_to :cluster
9
-
10
8
  validates :cluster_id, presence: true
11
-
12
- scope :of, -> (user,organization) {
13
- Rails.logger.warn("DON'T USE THIS SCOPE DIRECTLY: Use ::ClusterUser.clusters_from class method instead!")
14
- includes(:cluster).where(user_id: user, "clusters.organization_id": organization)
15
- }
16
9
  end
17
10
 
18
11
  module ClassMethods
12
+ ##
13
+ # Return a Cluster::ActiveRecord_Relation of organization (and) user
14
+ #
15
+ def clusters_of(organization,and_user=nil)
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) )
18
+ end
19
19
 
20
20
  ##
21
- # Returns a hash with the users with cluster relation
22
- #
23
- def user_clusters_from(organization)
24
- users_hash = {}
25
- organization_cluster_ids = ::Cluster.of(organization).map(&:id)
26
- ::ClusterUser.includes(:user).where(cluster_id: organization_cluster_ids).each do |cluster_user|
27
- user_id = cluster_user.user_id || :uncluster
28
- users_hash[user_id] ||= []
29
- users_hash[user_id] << cluster_user.cluster_id
30
- end
31
- users_hash
21
+ # Return a User::ActiveRecord_Relation of organization (and) user
22
+ #
23
+ def users_of(organization)
24
+ ::User.eager_load(:cluster_users).where(users: { organization_id: organization } )
32
25
  end
33
26
 
34
27
  ##
35
- # Returns a Cluster::ActiveRecord_Relation
28
+ # Return a hash of users and its clusters
36
29
  #
37
- ##
38
- def clusters_from(user,organization)
39
- clusters = []
40
- unless user.can_admin_clusters?
41
- # We could return cu.clusters but you may quering this result and a array can't handle order, where and etc.
42
- # So we take only the cluster_ids and perfome a new search in order to get a Cluster::ActiveRecord_Relation
43
- # like the else block.
44
- # TODO: resolve it without quering twice
45
- clusters_id = ::ClusterUser.of(user,organization).map(&:cluster_id)
46
- clusters = ::Cluster.where(id: clusters_id)
47
- # Add a empty cluster instance to handle models without a cluster assignation. Only for use and show modes
48
- if organization.optional_mode?
49
- clusters << ::Cluster.new({nid: :without_cluster, name: I18n.t('klastera.without_cluster')})
50
- end
51
- else
52
- clusters = ::Cluster.of(organization)
30
+ def users_hash_of(organization)
31
+ users = {}
32
+ rows = self.users_of(organization).pluck("users.id AS user_id","cluster_users.cluster_id").uniq
33
+ rows.each do |row|
34
+ user_id = row.first
35
+ users[user_id] ||= []
36
+ users[user_id] << row.last
53
37
  end
54
- clusters
38
+ users
55
39
  end
56
40
  end
57
41
  end
@@ -1,7 +1,6 @@
1
1
  module Klastera::Concerns::Clusterizable
2
2
  extend ActiveSupport::Concern
3
3
  included do
4
- attr_accessor :lonely_cluster
5
4
  belongs_to :cluster
6
5
 
7
6
  has_many :cluster_entities, as: :entity, class_name: Klastera::ClusterEntity
@@ -11,9 +10,7 @@ module Klastera::Concerns::Clusterizable
11
10
  validate :at_least_one_cluster_entity, if: proc { self.organization.required_suborganization_mode? }
12
11
  validate :uniqueness_of_cluster_entity_record
13
12
 
14
- scope :related_clusters, ->() {
15
- joins(:cluster_entities).where("cluster_entities.entity_id = #{self.table_name}.id")
16
- }
13
+ scope :includes_cluster, -> { includes(cluster_entities: :cluster) }
17
14
 
18
15
  def at_least_one_cluster_entity
19
16
  if cluster_entities.length == 0 || cluster_entities.reject{|cluster_entity| cluster_entity._destroy == true}.empty?
@@ -47,7 +44,7 @@ module Klastera::Concerns::Clusterizable
47
44
 
48
45
  module ClassMethods
49
46
  def cluster_entity_params
50
- [ :cluster_id, :lonely_cluster, { cluster_entities_attributes: [:id, :cluster_id, :_destroy] } ]
47
+ [ :cluster_id, { cluster_entities_attributes: [:id, :cluster_id, :_destroy] } ]
51
48
  end
52
49
  end
53
50
  end
@@ -4,7 +4,7 @@ module Klastera::Concerns::Organization
4
4
 
5
5
  has_many :clusters
6
6
 
7
- validates :use_cluster_as, inclusion: { in: ::Cluster.modes_as_strings , message: I18n.t('klastera.clusters.wrong_option') }, if: proc{ use_cluster_as.present? }
7
+ validates :use_cluster_as, inclusion: { in: ::Cluster::MODES.map{|m|m.to_s}, message: I18n.t('klastera.clusters.wrong_option') }, if: proc{ use_cluster_as.present? }
8
8
 
9
9
  # Return a symbol version of use_cluster_as value
10
10
  def cluster_mode
@@ -22,19 +22,11 @@ module Klastera::Concerns::Organization
22
22
  end
23
23
 
24
24
  def required_suborganization_mode?
25
- cluster_mode == ::Cluster::MODES.first
25
+ cluster_mode == ::Cluster::REQUIRED_MODE
26
26
  end
27
27
 
28
28
  def optional_suborganization_mode?
29
- cluster_mode == ::Cluster::MODES.second
30
- end
31
-
32
- def optional_filter_mode?
33
- cluster_mode == ::Cluster::MODES.third
34
- end
35
-
36
- def optional_mode?
37
- optional_suborganization_mode? || optional_filter_mode?
29
+ cluster_mode == ::Cluster::OPTIONAL_MODE
38
30
  end
39
31
  end
40
32
 
@@ -7,20 +7,14 @@ module Klastera::Concerns::Transfer
7
7
  include ActiveModel::Model
8
8
  include ActiveModel::Validations::Callbacks
9
9
 
10
- attr_accessor :current_cluster, :new_cluster_id, :entities_transfered
10
+ attr_accessor :current_cluster, :new_cluster_id
11
11
 
12
12
  validates :current_cluster, presence: true
13
13
  validates :new_cluster_id, presence: true, if: proc { self.required_transfer? }
14
14
 
15
15
  validate do
16
16
  new_cluster = ::Cluster.find(self.new_cluster_id.to_i) rescue nil
17
- #
18
- # In my time, to_a? didnt work
19
- # current_cluster.class returned:
20
- # Cluster(id: integer, name: string, nid: text, organization_id: integer, created_at: datetime, updated_at: datetime, color: string)
21
- #
22
- # If you see this, please fixe it. Thanks
23
- #
17
+
24
18
  if current_cluster.class.name != 'Cluster' || current_cluster.try(:is_the_last_record_in_required_suborganization_mode?)
25
19
  errors.add(:current_cluster, I18n.t('klastera.messages.current_cluster.cant_transfer'))
26
20
  elsif self.required_transfer? && new_cluster_id.present? && new_cluster.nil?
@@ -33,22 +27,19 @@ module Klastera::Concerns::Transfer
33
27
  end
34
28
  end
35
29
 
36
- ##
37
- #
38
- #
39
- def to!(related_entities)
40
- self.entities_transfered = 0
41
- related_entities.each do |entity|
42
- if entity.is_a?(Class) && entity.respond_to?(:cluster_id)
43
- self.entities_transfered += entity.where(
44
- cluster_id: self.current_cluster.id
45
- ).update_all(cluster_id: self.new_cluster_id)
46
- end
47
- end
48
- end
49
-
50
30
  def required_transfer?
51
31
  self.current_cluster.required_transfer? && self.current_cluster.has_related_entities_using_it?
52
32
  end
33
+
34
+ ##
35
+ # A returned boolean is expected. It should always be true even nothing is
36
+ # transfered, and it only will return false if creation fails.
37
+ #
38
+ def apply!
39
+ Klastera::ClusterEntity.create(current_cluster.cluster_entities.map{ |relation|
40
+ next if self.new_cluster_id.blank?
41
+ { cluster_id: self.new_cluster_id, entity_id: relation.entity_id, entity_type: relation.entity_type }
42
+ }.compact)
43
+ end
53
44
  end
54
45
  end
@@ -21,10 +21,6 @@ module Klastera::Concerns::User
21
21
  def is_a_cluster_admin?; self.cluster_role == CLUSTER_ADMIN; end
22
22
  def is_a_cluster_user?; self.cluster_role == CLUSTER_USER; end
23
23
 
24
- def is_not_a_cluster_root?; ! self.is_a_cluster_root?; end
25
- def is_not_a_cluster_admin?; ! self.is_a_cluster_admin?; end
26
- def is_not_a_cluster_user?; ! self.is_a_cluster_user?; end
27
-
28
24
  def need_cluster_assignation?
29
25
  self.try(:organization).try(:required_suborganization_mode?) && self.is_a_cluster_user?
30
26
  end
@@ -33,6 +29,13 @@ module Klastera::Concerns::User
33
29
  self.organization.is_in_cluster_mode? && ( self.is_a_cluster_admin? || self.is_a_cluster_root? )
34
30
  end
35
31
 
32
+ #
33
+ # It tells if this user should see what they cluster role or organization dictates
34
+ # Adminers and users from show cluster modes skip cluster clause
35
+ def cannot_skip_cluster_clause?
36
+ ! ( self.is_a_cluster_admin? || self.is_a_cluster_root? || ( self.organization.optional_suborganization_mode? && self.cluster_users.blank? ) )
37
+ end
38
+
36
39
  #
37
40
  # We will try to create a cluster_user record whether
38
41
  # the organization is using force mode (if cluster_id isn't present, it will raise a validation error)
@@ -3,16 +3,16 @@
3
3
 
4
4
  <div class="<%=classes_for_remote_modal_body()%>">
5
5
  <div class="row">
6
- <div class="col-xs-12">
6
+ <div class="col-xs-6">
7
7
  <%= f.input :name, as: :string, label: t('klastera.cluster_name') %>
8
8
  </div>
9
- <div class="col-xs-12">
9
+ <div class="col-xs-6">
10
10
  <%= f.input :nid, as: :string, label: t('klastera.cluster_nid') %>
11
11
  </div>
12
- <div class="col-xs-12">
12
+ <div class="col-xs-6">
13
13
  <%= f.input :color, as: :string, label: t('klastera.cluster_color'), input_html: { class: 'color-picker'} %>
14
14
  </div>
15
- <div class="col-xs-12">
15
+ <div class="col-xs-6">
16
16
  <%= f.input :order, as: :string, label: t('klastera.cluster_order') %>
17
17
  </div>
18
18
  </div>
@@ -2,8 +2,8 @@
2
2
  <%= simple_form_for( @transfer, url: cluster_path(@cluster), method: :delete, remote: true, html: { autocomplete: :off, class: 'destroy-form slim-form-field' } ) do |f| %>
3
3
  <%=render 'layouts/remote_form/header', o: @cluster, title: title, fa: :qrcode %>
4
4
  <div class="<%=classes_for_remote_modal_body()%>">
5
- <h4 class="text-center">Esta acción es irreversible.<br/>¿Está seguro?</h4>
6
- <% if ::Cluster.total_records_assign_to(@cluster) > 0 %>
5
+ <h4 class="blank-modal-title text-center">Esta acción es irreversible<br/>¿Está seguro?</h4>
6
+ <% if @cluster.cluster_entities.size > 0 %>
7
7
  <br />
8
8
  <div class="row">
9
9
  <% if can_transfer_and_destroy %>
@@ -1,4 +1,4 @@
1
- <table class="table table-striped table-hover table-condensed table-bordered datatable">
1
+ <table class="table table-striped table-hover table-condensed table-bordered datatable table">
2
2
  <thead>
3
3
  <tr>
4
4
  <th class="text-center cluster-id"><%=t('klastera.cluster_id')%></th>
@@ -6,7 +6,7 @@
6
6
  <th class="text-center cluster-color"><%=t('klastera.cluster_color')%></th>
7
7
  <th class="text-center cluster-name"><%=t('klastera.cluster_name')%></th>
8
8
  <th class="text-center cluster-nid"><%=t('klastera.cluster_nid')%></th>
9
- <th class="cogs-actions four-icons"><span class="fa fa-cogs"></span></th>
9
+ <th class="cogs-actions two-icons"><span class="fa fa-cogs"></span></th>
10
10
  </tr>
11
11
  </thead>
12
12
  <tbody>
@@ -19,7 +19,7 @@
19
19
  </td>
20
20
  <td class="text-center cluster-name"><%= cluster.name %></td>
21
21
  <td class="text-center cluster-nid"><%= cluster.nid %></td>
22
- <td class="cogs-actions four-icons">
22
+ <td class="cogs-actions two-icons">
23
23
  <%= link_to edit_cluster_path(cluster), class:'btn btn-primary btn-xs', title: t('shared.actions.edit'), "data-toggle": "modal", "data-target": "#remote-modal-block" do %>
24
24
  <span class="fa fa-pencil-square-o"></span>
25
25
  <% end %>
@@ -30,12 +30,4 @@
30
30
  </tr>
31
31
  <% end %>
32
32
  </tbody>
33
- </table>
34
- <style type="text/css">
35
- .cluster-id { width: 70px; }
36
- .cluster-order { width: 70px; }
37
- .cluster-color { width: 70px; }
38
- .odd .colorless { color: #F9F9F9 }
39
- .even .colorless { color: #FFF }
40
- tr:hover .colorless { color: #F5F5F5 }
41
- </style>
33
+ </table>
@@ -18,4 +18,4 @@
18
18
 
19
19
  </div>
20
20
 
21
- <%= render 'layouts/remote_form/modal'%>
21
+ <%= render 'layouts/remote_form/modal', width: 'md' %>
@@ -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, @clusters_session.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,4 @@
1
- <%= simple_form_for(@filter, url: url, remote: true) do |f| %>
1
+ <%= simple_form_for(@cluster_filter, url: url, remote: true) do |f| %>
2
2
 
3
3
  <div class="inline-buttons-block top">
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>" }) %>
@@ -7,7 +7,7 @@
7
7
  <%=yield(f) if block_given? %>
8
8
 
9
9
  <% if cluster_organization.is_in_cluster_mode? %>
10
- <% cluster_collection = cluster_clusters.map{|c|[c.name,(c.id||c.nid)]} %>
10
+ <% cluster_collection = cluster_list.map{|c|[c.name,(c.id||c.nid)]} %>
11
11
  <% if cluster_collection.size > 1 %>
12
12
  <div class="inline-label-control-block">
13
13
  <%= f.input :cluster_id, collection: cluster_collection, prompt: t('klastera.clusters.all'), label: false, wrapper: false %>
@@ -3,6 +3,18 @@
3
3
  <% if @user.try(:organization).try(:is_in_cluster_mode?) || other_visibility_reason %>
4
4
  <div class="form-group">
5
5
  <%= f.label t('klastera.cluster_role') %>
6
+ <span
7
+ class="klastera-user-cluster-rol"
8
+ data-title="<%= t('klastera.help.popover.title')%>"
9
+ data-toggle="popover"
10
+ data-content="<%=
11
+ t('klastera.help.popover.content.cluster_role',
12
+ 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}"))
14
+ )%>"
15
+ >
16
+ <%= fa_icon 'info-circle', class: 'btn-link' %>
17
+ </span>
6
18
  <%= f.select :cluster_role, user_cluster_roles.map{|r|[t("klastera.roles.#{r}"),r]}, { include_blank: true }, { class: 'form-control' } %>
7
19
  </div>
8
20
 
@@ -23,5 +35,7 @@
23
35
  });
24
36
  }
25
37
  });
38
+ var popoverTemplate = '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
39
+ $('.klastera-user-cluster-rol').popover({ template: popoverTemplate, html: true, trigger: 'click', });
26
40
  </script>
27
41
  <% end %>
@@ -4,26 +4,18 @@
4
4
  %>
5
5
  <% if cluster_organization.is_in_cluster_mode? || other_visibility_reason %>
6
6
  <%
7
- cluster_collection = @cluster_clusters || cluster_clusters
7
+ cluster_collection = @clusters_session || cluster_list
8
8
  label = t('klastera.cluster.title')
9
9
  %>
10
10
  <% if f.nil? %>
11
11
  <%= label_tag(:cluster_id, label, class: 'control-label') %>
12
12
  <%= select_tag(:cluster_id, options_from_collection_for_select(cluster_collection, 'id', 'display_name_nid'), class: 'form-control', prompt: 'Seleccione') %>
13
13
  <% elsif f.is_a?(SimpleForm::FormBuilder) %>
14
- <% if cluster_collection.size == 1 %>
15
- <%= f.input :lonely_cluster, as: :hidden, html_input: { value: true } %>
16
- <% else %>
17
- <%= f.input :cluster_id, collection: cluster_collection.map{|c|[c.name,c.id]}, label: label %>
18
- <% end %>
14
+ <%= f.input :cluster_id, collection: cluster_collection.map{|c|[c.name,c.id]}, label: label %>
19
15
  <% else %>
20
- <% if cluster_collection.size == 1 %>
21
- <%= f.hidden_field :lonely_cluster, value: true %>
22
- <% else %>
23
- <div class="form-group">
24
- <%= f.label label %>
25
- <%= f.select :cluster_id, cluster_collection.map{|c|[c.name,c.id]}, { include_blank: true }, { class: 'form-control' } %>
26
- </div>
27
- <% end %>
16
+ <div class="form-group">
17
+ <%= f.label label %>
18
+ <%= f.select :cluster_id, cluster_collection.map{|c|[c.name,c.id]}, { include_blank: true }, { class: 'form-control' } %>
19
+ </div>
28
20
  <% end %>
29
21
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <% if cluster_organization.is_in_cluster_mode? %>
2
- <% @cluster_clusters = cluster_clusters %>
2
+ <% @clusters_session = cluster_list(false) %>
3
3
  <div class="col-xs-12">
4
4
  <% if hide_title||=false %>
5
5
  <div class="form-group file required <%=f.object.class.name.parameterize%>_cluster_entity<%=' has-error' if f.object.errors.has_key?(:cluster_entities)%>">
@@ -27,7 +27,7 @@
27
27
  <table id="cluster-entities" class="table table-striped">
28
28
  <tbody class="cluster-entity-rows">
29
29
  <%= f.fields_for :cluster_entities do |cluster_entity|%>
30
- <% next unless @cluster_clusters.map(&:id).include?(cluster_entity.try(:object).try(:cluster_id)) %>
30
+ <% next unless @clusters_session.map(&:id).include?(cluster_entity.try(:object).try(:cluster_id)) %>
31
31
  <%= render 'layouts/klastera/cluster_entity_fields', f: cluster_entity %>
32
32
  <% end %>
33
33
  </body>
@@ -5,10 +5,9 @@
5
5
  data-title="<%= t('klastera.help.popover.title')%>"
6
6
  data-toggle="popover"
7
7
  data-content="<%=
8
- t('klastera.help.popover.content',
8
+ t('klastera.help.popover.content.user_as_cluster_as',
9
9
  m1:t('klastera.help.required_suborganization', t: t('klastera.required_suborganization'), e: t('klastera.clusters.entities')),
10
- m2:t('klastera.help.optional_suborganization', t: t('klastera.optional_suborganization'), e: t('klastera.clusters.entities')),
11
- m3:t('klastera.help.optional_filter', t: t('klastera.optional_filter'), e: t('klastera.clusters.entities'))
10
+ m2:t('klastera.help.optional_suborganization', t: t('klastera.optional_suborganization'), e: t('klastera.clusters.entities'))
12
11
  )%>"
13
12
  >
14
13
  <%= fa_icon 'info-circle', class: 'btn-link' %>
@@ -19,20 +18,4 @@
19
18
  <script type="text/javascript">
20
19
  var popoverTemplate = '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
21
20
  $('.klastera-cluster-option').popover({ template: popoverTemplate, html: true, trigger: 'click', });
22
- </script>
23
-
24
- <style type="text/css">
25
- ul.klastera-option-help {
26
- padding-left: 20px;
27
- list-style-type: disc;
28
- }
29
-
30
- ul.klastera-option-help li {
31
- margin-bottom: 10px;
32
- padding-bottom: 5px;
33
- border-bottom: 1px solid #DDD;
34
- }
35
-
36
- ul.klastera-option-help li b { color: #8A8A8A; font-weight: 400; }
37
- ul.klastera-option-help li b:first-child { color: #2E5F9B; font-weight: bold; }
38
- </style>
21
+ </script>
@@ -9,24 +9,23 @@ es:
9
9
  you_need_add_at_least_one_cluster: Esta organización usa clusters en modo obligatorio. Asigne un cluster al usuario por favor.
10
10
  assign_cluster_role: Asignar role
11
11
  cluster_root_asignation:
12
- title: Asignación Routing Super Admin
13
- text: Este rol es sólo para usuarios Routing
12
+ title: Asignación Super Admin
13
+ text: Este rol es sólo para usuarios super admin
14
14
  roles:
15
- root: Routing Super Admin
16
- admin: Admin Cliente [ Ignora asignación, ve todos los clusters ]
17
- user: Usuario normal [ Ve sólo los clusters asignados ]
15
+ root: Super Admin
16
+ admin: Admin Cluster
17
+ user: Usuario Cluster
18
18
  using_cluster_as: Usando cluster como
19
19
  cluster_order: Orden
20
20
  cluster_id: ID
21
- cluster_role: Cluster rol
21
+ cluster_role: Rol de clusters
22
22
  cluster_name: Nombre
23
23
  cluster_nid: Código
24
24
  cluster_color: Color
25
25
  organization_name: Organización
26
- use_cluster_as: Activar y usar cluster como
27
- required_suborganization: Sub-organización Obligatorio
28
- optional_suborganization: Sub-organización Opcional
29
- optional_filter: Filtro opcional
26
+ use_cluster_as: Activar y usar cluster en modo
27
+ required_suborganization: Obligatorio
28
+ optional_suborganization: Opcional
30
29
  clusters:
31
30
  all: Todos
32
31
  title: Clusters
@@ -71,10 +70,17 @@ es:
71
70
  help:
72
71
  popover:
73
72
  title: Descripción de cada opción
74
- content: "<ul class='klastera-option-help'><li>%{m1}</li><li>%{m2}</li><li>%{m3}</li></ul>"
75
- required_suborganization: "<b>%{t}</b>: Obliga definir un cluster en las entidades %{e} ."
76
- optional_suborganization: "<b>%{t}</b>: Permite definir un cluster en las entidades %{e}."
77
- optional_filter: "<b>%{t}</b>: Permite definir un cluster en las entidades %{e} de forma opcional."
73
+ content:
74
+ user_as_cluster_as: "<ul class='klastera-option-help'><li>%{m1}</li><li>%{m2}</li></ul>"
75
+ required_suborganization: "<b>%{t}</b>: Obliga asignar un cluster a las entidades %{e} ."
76
+ optional_suborganization: "<b>%{t}</b>: Permite asociar un cluster a las entidades %{e}."
77
+ roles:
78
+ description: "<b>%{r}</b>: %{d}."
79
+ root: Ve todos los clusters y no necesita asignación
80
+ admin: Ve todos los clusters y no necesita asignación
81
+ user:
82
+ required: Necesita que se le asigne uno o más clusters, de lo contrario no verá las entidades clusterizadas.
83
+ 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.
78
84
  activemodel:
79
85
  attributes:
80
86
  'klastera/transfer':
@@ -5,140 +5,11 @@ 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 set_collection_before_group_by_entity
12
- ]
8
+ 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
13
10
 
14
11
  class << self
15
12
 
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
-
38
- #
39
- # In cases you don't have the active_record_collection object to filter, this method helps you
40
- # calling cluster_scope! before and pass the collction to filter_clusterized_collection_with!,
41
- # but at the end of the day, I just like to wrap methods.
42
- #
43
- def cluster_scope_filtered!(scope,cluster_id,user,organization)
44
- self.filter_clusterized_collection_with!(
45
- cluster_id,
46
- self.cluster_scope!(scope,user,organization),
47
- organization
48
- )
49
- end
50
-
51
- #
52
- # In order to this works, active_record_collection argument
53
- # should be passed through cluster_scope! method before.
54
- #
55
- def filter_clusterized_collection_with!(cluster_id,active_record_collection,cluster_organization)
56
- if cluster_organization.is_in_cluster_mode?
57
-
58
- # IMPORTANT
59
- # The next block was commented on because cluster_scope! method is not returning
60
- # the cluster_entities within the scope anymore and it doesn't make any sense trying
61
- # to filter based on force/use/show logic. Nevertheless, someday we will need it again.
62
-
63
- # # If cluster_id is nil we will try to filter including unclustered entities active_record_collection wsas
64
- # unless cluster_id.present?
65
- # # Based on force/use/show definition we don't really need this validation. A force cluster organization won't return an entity that
66
- # # doesn't belong to a cluster. Nevertheless we don't know if active_record_collection argument is fully definition-compliant.
67
- # if cluster_organization.optional_suborganization_mode?
68
- # cluster_array << nil
69
- # end
70
- # end
71
-
72
- if cluster_id.present?
73
- cluster_array = [cluster_id] unless cluster_id.is_a?(Array)
74
- # The ActiveRecordCollection argument should have previously eager-loaded the cluster entities, thus the join statement is unnecessary.
75
- active_record_collection = active_record_collection.joins(:cluster_entities).where("cluster_entities.cluster_id": cluster_array)
76
- end
77
-
78
- # You should use a block with clusterable data only
79
- yield(active_record_collection) if block_given?
80
- end
81
- active_record_collection
82
- end
83
-
84
- ##
85
- #
86
- #
87
- ##
88
- def set_collection_before_group_by_entity!(active_record_collection,entity_params,cluster_organization)
89
- entity_params_keys = [:entity_name,:entity_attribute,:entity_id,:entity_id_attribute,:unamed]
90
- entity_params[:entity_id] ||= nil #Ensures the entity_id attribute presence even if there is no filter
91
- entity_params = entity_params.slice(*entity_params_keys).values
92
- model_class = active_record_collection.model.base_class
93
- model_relations = model_class.reflections.keys
94
- if model_relations.include?(entity_params[0])
95
- entity_params << "#{entity_params[0]}_id".to_sym
96
- if entity_params[0] == 'cluster'
97
- entity_params << :unclustered if cluster_organization.is_in_cluster_mode?
98
- active_record_collection = Klastera.filter_clusterized_collection_with!(
99
- entity_params[2],
100
- active_record_collection,
101
- cluster_organization
102
- )
103
- end
104
- yield( active_record_collection, entity_params_keys.zip(entity_params).to_h )
105
- end
106
- end
107
-
108
- ##
109
- # Returns a ::Cluster::ActiveRecord_Relation from a given scope
110
- #
111
- def clusters_from!(scope,user,organization)
112
- cluster_scope!(scope,user,organization).related_clusters
113
- end
114
-
115
- ##
116
- # Returns a scope filtered by clusters or its
117
- # organization if the cluster mode is not active.
118
- #
119
- def cluster_scope!(scope,user,organization)
120
- scope_klass = scope_class(scope).where(organization_id: organization)
121
- session_clusters(user,organization) do |clusters|
122
- if organization.is_in_cluster_mode?
123
- scope_klass = scope_klass.select("DISTINCT ON (#{scope.table_name}.id) #{scope.table_name}.id, #{scope.table_name}.*")
124
- cluster_ids = clusters.map(&:id)
125
- if organization.required_suborganization_mode?
126
- scope_klass = scope_klass.joins(:cluster_entities).where( cluster_entities: { cluster_id: cluster_ids } )
127
- else
128
- or_these_cluster_ids = cluster_ids.present? ? " OR cluster_entities.cluster_id IN (#{cluster_ids.join(",")})" : ""
129
- scope_klass = scope_klass.joins("
130
- LEFT OUTER JOIN cluster_entities
131
- ON entity_id = #{scope.table_name}.id
132
- AND entity_type = '#{scope}'
133
- ").where("cluster_entities.id IS NULL#{or_these_cluster_ids}")
134
- end
135
- # Provisional fix to avoid SQL clashes due to DISTINCT ON clause
136
- scope_klass = scope_class(scope).eager_load(:cluster_entities).where(id: scope_klass.map(&:id), organization_id: organization)
137
- end
138
- end
139
- scope_klass
140
- end
141
-
142
13
  ##
143
14
  # TODO:
144
15
  # Implement a validation to ensure that
@@ -151,19 +22,22 @@ module Klastera
151
22
  end
152
23
 
153
24
  ##
154
- # Returns a cluster array if organization is using the cluster mode
155
- #
156
- # Use this only to get current_user/organization clusters
157
- # understanding this wont be useful out of a cluster mode context.
25
+ # Returns which clusters a user can see avoiding unnecessary queries if the cluster restraint doesn't apply
158
26
  #
159
- ##
160
- def session_clusters(user,organization)
161
- clusters = organization.is_in_cluster_mode? ? ::ClusterUser.clusters_from(user,organization) : []
162
- if block_given?
163
- clusters = clusters.reject{|c|c.id.blank?}
164
- yield(clusters)
27
+ def cluster_list!(organization,user,include_unclustered=true)
28
+ # Only the cluster mode on and the mandatory user-cluster relation will use a join clause to get the clusters list
29
+ if organization.is_in_cluster_mode? && user.cannot_skip_cluster_clause?
30
+ active_record_collection = ::ClusterUser.clusters_of(organization,user)
31
+ else
32
+ active_record_collection = ::Cluster.where({ organization_id: organization })
165
33
  end
166
- clusters
34
+
35
+ active_record_collection = active_record_collection.order(order: :asc)
36
+
37
+ 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
+ end
40
+ active_record_collection
167
41
  end
168
42
 
169
43
  ##
@@ -181,88 +55,124 @@ module Klastera
181
55
  end
182
56
 
183
57
  ##
184
- # cluster_clusters needs the logged user and its organization
185
- # that why, we perfomed this logic here
58
+ # cluster_list! needs a user and a organization. that why we perfomed this logic here
186
59
  #
187
60
  def user_clusters_string_list!(user,organization,cluster_entities,separator,attribute=:name)
188
- @_session_clusters ||= self.session_clusters(user,organization)
189
- self.entity_clusters_string_list!(cluster_entities, separator, attribute, @_session_clusters.map(&:id))
61
+ @clusters_session ||= Klastera.cluster_list!(organization,user)
62
+ self.entity_clusters_string_list!(cluster_entities, separator, attribute, @clusters_session.map(&:id))
190
63
  end
191
- end
192
64
 
193
- def cluster_user
194
- current_user
195
- end
65
+ #
66
+ # We will try to avoid cluster clause except when:
67
+ # 1.- cluster mode is active
68
+ # AND
69
+ # 2a.- cluster_filter is present (someone wants to filter by cluster)
70
+ # OR
71
+ # 2b.- the current user has some limitations and must checks they cluster relation
72
+ # - User is having clusters in optional_suborganization mode
73
+ # - User IS NOT having clusters in required_suborganization mode
74
+ #
75
+ # For the other hand, with force_cluster_clause we can skip the previous logic if
76
+ # cluster_filter_id is present when the optional_suborganization mode is on. BUT!
77
+ # Be aware that if the cluster_filter is not present, the value of force_cluster_clause
78
+ # will be overridden by the returned value of cannot_skip_cluster_clause? method.
79
+ #
80
+ def cluster_scope!(scope_klass, user, organization, cluster_filter=nil, force_cluster_clause=false)
81
+ scope_klass = scope_class(scope_klass)
82
+ if organization.is_in_cluster_mode? && ( cluster_filter.present? || force_cluster_clause = user.cannot_skip_cluster_clause? ) # yes, this is an assignation
83
+ cluster_ids = []
84
+ # Set another variable as array to get the cluster id(s)
85
+ if cluster_filter.present?
86
+ cluster_ids = cluster_filter.is_a?(Array) ? cluster_filter : [cluster_filter]
87
+ elsif force_cluster_clause
88
+ cluster_ids = ::ClusterUser.clusters_of(organization,user).map(&:id).sort
89
+ end
90
+ # We will avoid the query unless cluster_ids is having values OR force_cluster_clause is set (see method description)
91
+ if cluster_ids.present? || force_cluster_clause
92
+ scope_klass = scope_klass.eager_load(:organization,cluster_entities: :cluster)
93
+ # We add the unclustered if the value of cluster_filter have the special without_cluster string or as method description says
94
+ if cluster_ids.delete(UNCLUSTERED_ENTITY) || ( force_cluster_clause && organization.optional_suborganization_mode? )
95
+ cluster_ids << nil
96
+ end
97
+ scope_klass = scope_klass.where( cluster_entities: { cluster_id: cluster_ids } )
98
+ end
99
+ end
100
+ scope_klass.where(organization_id: organization)
101
+ end
196
102
 
197
- def cluster_organization
198
- current_organization
199
- end
103
+
104
+ # Filter non-clustered entity through a clusterized one
105
+ #
106
+ def cluster_scope_through_of!(relation, cluster_entity_klass, scope_klass, user, organization, cluster_filter=nil, force_cluster_clause=false)
107
+ unclusterized_scope = scope_class(scope_klass)
200
108
 
201
- def user_has_more_than_one_cluster
202
- @cluster_clusters ||= cluster_clusters
203
- @cluster_clusters.size > 1
204
- end
109
+ if organization.is_in_cluster_mode? && ( force_cluster_clause || user.cannot_skip_cluster_clause? )
110
+ unclusterized_scope = unclusterized_scope.joins(relation => :cluster_entities)
111
+ end
112
+
113
+ if scope_klass.respond_to?(:organization)
114
+ unclusterized_scope = unclusterized_scope.where(organization_id: organization)
115
+ end
205
116
 
206
- def set_the_lonely_cluster
207
- form_model = @form_record ? model_name_from_record_or_class(@form_record).param_key : params[:controller].singularize
208
- parameters = params.require( form_model ) rescue nil
209
- lonely_cluster = parameters.blank? ? false : parameters.permit( :lonely_cluster ).present?
210
- if lonely_cluster
211
- params[form_model][:cluster_id] = cluster_clusters.first.try(:id)
117
+ unclusterized_scope.where("#{relation}_id" => cluster_scope!(cluster_entity_klass, user, organization, cluster_filter, force_cluster_clause))
212
118
  end
213
- end
214
119
 
215
- def set_cluster_filter
216
- @filter = ::ClusterFilter.new(cluster_filter_params)
120
+
121
+ # Returns an array with a clusterized scoped result and its grouped version
122
+ #
123
+ def group_by_cluster_scope!(scope_klass, user, organization, cluster_filter=[], scope_scopes=[])
124
+ 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? )
126
+ scope_scopes.each do |tuple_scope|
127
+ scope_name, scope_arg = tuple_scope
128
+ kluster_scope = scope_arg.present? ? kluster_scope.send(scope_name,scope_arg) : kluster_scope.send(scope_name)
129
+ 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
+ end
135
+ ]
136
+ end
217
137
  end
218
138
 
219
- def cluster_filter_params
220
- parameters = params.require(:cluster_filter) rescue nil
221
- return {} if parameters.blank?
222
- parameters.permit(*cluster_filter_permit_params)
223
- end
139
+ ##################################################################################################################################################
224
140
 
225
- def cluster_filter_permit_params
226
- [ :cluster_id ].concat( ::ClusterFilter.attributes )
141
+ def cluster_user
142
+ current_user
227
143
  end
228
144
 
229
- def filter_clusterized_collection_with(cluster_id,active_record_collection)
230
- Klastera.filter_clusterized_collection_with!(cluster_id,active_record_collection,cluster_organization)
145
+ def cluster_organization
146
+ current_organization
231
147
  end
232
148
 
233
- def cluster_scope(scope)
234
- Klastera.cluster_scope!(scope,cluster_user,cluster_organization)
149
+ def set_cluster_filter
150
+ cluster_filter_params = params.require(:cluster_filter) rescue {}
151
+ @cluster_filter = ::ClusterFilter.new(
152
+ cluster_filter_params.present? ? cluster_filter_params.permit(
153
+ [ :cluster_id ].concat( ::ClusterFilter.attributes )
154
+ ) : {}
155
+ )
235
156
  end
236
157
 
237
- def cluster_clusters
238
- Klastera.session_clusters(cluster_user,cluster_organization)
158
+ def cluster_list(include_unclustered=true)
159
+ Klastera.cluster_list!(cluster_organization, cluster_user, include_unclustered)
239
160
  end
240
161
 
241
- def cluster_scope_filtered(scope,cluster_id)
242
- Klastera.cluster_scope_filtered!(
243
- scope,
244
- cluster_id,
245
- cluster_user,
246
- cluster_organization
247
- )
162
+ def cluster_scope(scope_klass, cluster_filter=nil, force_cluster_clause=false)
163
+ Klastera.cluster_scope!(scope_klass, cluster_user, cluster_organization, cluster_filter, force_cluster_clause)
248
164
  end
249
165
 
250
- def clusters_from(scope)
251
- Klastera.clusters_from!(scope,cluster_user,cluster_organization)
166
+ def cluster_scope_through_of(relation, cluster_entity_klass, scope_klass, cluster_filter=nil, force_cluster_clause=false)
167
+ Klastera.cluster_scope_through_of!(relation, cluster_entity_klass, scope_klass, cluster_user, cluster_organization, cluster_filter, force_cluster_clause)
252
168
  end
253
169
 
254
- def user_clusters_string_list(object_entity,separator,attribute=:name)
255
- Klastera.user_clusters_string_list!(
256
- cluster_user,
257
- cluster_organization,
258
- object_entity.try(:cluster_entities),
259
- separator,
260
- attribute
261
- )
170
+ def group_by_cluster_scope(scope_klass, cluster_filter=[], scope_scopes=[])
171
+ Klastera.group_by_cluster_scope!(scope_klass, cluster_user, cluster_organization, cluster_filter, scope_scopes)
262
172
  end
263
173
 
264
- def set_collection_before_group_by_entity(active_record_collection,entity_params,&block)
265
- Klastera.set_collection_before_group_by_entity!(active_record_collection,params,cluster_organization,&block)
174
+ def user_clusters_string_list(object_entity, separator, attribute=:name)
175
+ Klastera.user_clusters_string_list!(cluster_user, cluster_organization, object_entity.try(:cluster_entities), separator, attribute)
266
176
  end
267
177
 
268
178
  included do
@@ -275,6 +185,5 @@ module Klastera
275
185
  hide_action("#{helper}=")
276
186
  end
277
187
  end
278
- before_action :set_the_lonely_cluster, only: %i[ create update ]
279
188
  end
280
189
  end
@@ -1,3 +1,3 @@
1
1
  module Klastera
2
- VERSION = "1.2.4.2"
2
+ VERSION = "1.4"
3
3
  end
@@ -13,6 +13,11 @@ namespace :klastera do
13
13
  klass = args.entity.constantize
14
14
  ActiveRecord::Base.transaction do
15
15
  klass.where.not(cluster_id: nil).each do |entity|
16
+ if entity.cluster.blank?
17
+ puts "Cluster ID #{entity.cluster_id} was not found!"
18
+ puts "skip..."
19
+ next
20
+ end
16
21
  Klastera::ClusterEntity.create(entity: entity, cluster: entity.cluster)
17
22
  end
18
23
  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.2
4
+ version: '1.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-06-15 00:00:00.000000000 Z
11
+ date: 2020-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails