klastera 1.5.3 → 1.5.5

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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/javascripts/klastera/application.js +13 -0
  6. data/app/assets/javascripts/klastera/clusters.js +2 -0
  7. data/app/assets/stylesheets/klastera/clusters.scss +46 -0
  8. data/app/controllers/klastera/application_controller.rb +29 -0
  9. data/app/controllers/klastera/clusters_controller.rb +60 -0
  10. data/app/helpers/klastera/application_helper.rb +40 -0
  11. data/app/models/klastera/cluster.rb +5 -0
  12. data/app/models/klastera/cluster_entity.rb +5 -0
  13. data/app/models/klastera/cluster_filter.rb +5 -0
  14. data/app/models/klastera/cluster_user.rb +5 -0
  15. data/app/models/klastera/concerns/cluster.rb +67 -0
  16. data/app/models/klastera/concerns/cluster_entity.rb +18 -0
  17. data/app/models/klastera/concerns/cluster_filter.rb +22 -0
  18. data/app/models/klastera/concerns/cluster_user.rb +41 -0
  19. data/app/models/klastera/concerns/clusterizable.rb +115 -0
  20. data/app/models/klastera/concerns/organization.rb +49 -0
  21. data/app/models/klastera/concerns/transfer.rb +45 -0
  22. data/app/models/klastera/concerns/user.rb +77 -0
  23. data/app/models/klastera/transfer.rb +5 -0
  24. data/app/views/klastera/clusters/_filter.html.erb +0 -0
  25. data/app/views/klastera/clusters/_form.html.erb +22 -0
  26. data/app/views/klastera/clusters/_form_transfer.html.erb +34 -0
  27. data/app/views/klastera/clusters/_table.html.erb +33 -0
  28. data/app/views/klastera/clusters/create.js.erb +1 -0
  29. data/app/views/klastera/clusters/destroy.js.erb +6 -0
  30. data/app/views/klastera/clusters/edit.html.erb +10 -0
  31. data/app/views/klastera/clusters/index.html.erb +21 -0
  32. data/app/views/klastera/clusters/new.html.erb +10 -0
  33. data/app/views/klastera/clusters/transfer.html.erb +10 -0
  34. data/app/views/klastera/clusters/update.js.erb +1 -0
  35. data/app/views/layouts/klastera/_cluster_entity_fields.html.erb +10 -0
  36. data/app/views/layouts/klastera/_cluster_filter.html.erb +23 -0
  37. data/app/views/layouts/klastera/_cluster_role.html.erb +48 -0
  38. data/app/views/layouts/klastera/_cluster_selector.html.erb +21 -0
  39. data/app/views/layouts/klastera/_cluster_user_fields.html.erb +10 -0
  40. data/app/views/layouts/klastera/_nested_cluster_entity.html.erb +43 -0
  41. data/app/views/layouts/klastera/_nested_cluster_user.html.erb +22 -0
  42. data/app/views/layouts/klastera/_options.html.erb +21 -0
  43. data/config/locales/es.yml +96 -0
  44. data/config/routes.rb +7 -0
  45. data/db/migrate/20200324203929_create_klastera_clusters.rb +12 -0
  46. data/db/migrate/20200326111219_add_cluster_options_to_organizations.rb +6 -0
  47. data/db/migrate/20200330010551_create_klastera_cluster_users.rb +9 -0
  48. data/db/migrate/20200330221601_add_order_field_to_clusters.rb +5 -0
  49. data/db/migrate/20200518142609_create_klastera_cluster_entities.rb +8 -0
  50. data/db/migrate/20200908180057_add_cluster_config_to_organization.rb +5 -0
  51. data/db/migrate/20220602222332_add_unique_index_to_cluster_entities.rb +5 -0
  52. data/db/migrate/20250429110829_add_entity_id_index_to_cluster_entities.rb +6 -0
  53. data/db/migrate/20250429110830_add_entity_id_index_and_entity_type_index_to_cluster_entities.klastera.rb +7 -0
  54. data/lib/klastera/engine.rb +5 -0
  55. data/lib/klastera/version.rb +3 -0
  56. data/lib/klastera.rb +253 -0
  57. data/lib/tasks/klastera_tasks.rake +32 -0
  58. data/test/controllers/klastera/clusters_controller_test.rb +52 -0
  59. data/test/fixtures/klastera/cluster_users.yml +9 -0
  60. data/test/fixtures/klastera/clusters.yml +11 -0
  61. data/test/integration/navigation_test.rb +8 -0
  62. data/test/klastera_test.rb +7 -0
  63. data/test/models/klastera/cluster_test.rb +9 -0
  64. data/test/models/klastera/cluster_user_test.rb +9 -0
  65. data/test/test_helper.rb +21 -0
  66. metadata +79 -7
@@ -0,0 +1,7 @@
1
+ # This migration comes from klastera (originally 20250429110947)
2
+ class AddEntityIdIndexAndEntityTypeIndexToClusterEntities < ActiveRecord::Migration[5.2]
3
+ disable_ddl_transaction!
4
+ def change
5
+ add_index :cluster_entities, [:entity_id,:entity_type], algorithm: :concurrently
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module Klastera
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Klastera
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Klastera
2
+ VERSION = "1.5.5"
3
+ end
data/lib/klastera.rb ADDED
@@ -0,0 +1,253 @@
1
+ require "klastera/engine"
2
+
3
+ module Klastera
4
+ mattr_accessor :organization_class
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ UNCLUSTERED_POSITION = 9999
9
+ UNCLUSTERED_ENTITY = 'without_cluster'.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
11
+
12
+ class << self
13
+
14
+ ##
15
+ # TODO:
16
+ # Implement a validation to ensure that
17
+ # object is a ActiveRecord::Base class
18
+ # (or just try to guess how to retrieve the argument class)
19
+ #
20
+ ##
21
+ def scope_class(object)
22
+ object
23
+ end
24
+
25
+ ##
26
+ # Returns which clusters a user can see avoiding unnecessary queries if the cluster restraint doesn't apply
27
+ #
28
+ def cluster_list!(organization,user,include_unclustered=true)
29
+ # Only the cluster mode on and the mandatory user-cluster relation will use a join clause to get the clusters list
30
+ if organization.is_in_cluster_mode? && user.cannot_skip_cluster_clause?
31
+ active_record_collection = ::ClusterUser.clusters_of(organization,user)
32
+ else
33
+ active_record_collection = ::Cluster.where({ organization_id: organization }).order(order: :asc)
34
+ end
35
+
36
+ active_record_collection = active_record_collection.order(order: :asc)
37
+
38
+ if include_unclustered && organization.optional_suborganization_mode? # For show and use modes only
39
+ active_record_collection.to_a.append(
40
+ ::Cluster.new({nid: UNCLUSTERED_ENTITY, name: I18n.t("klastera.#{UNCLUSTERED_ENTITY}"), order: UNCLUSTERED_POSITION })
41
+ )
42
+ end
43
+ active_record_collection
44
+ end
45
+
46
+ ##
47
+ # Return a string with cluster attribute separated by separator argument
48
+ # A array of cluster ids can be passed fo filter the result
49
+ # Optimized version that uses preloaded associations when available
50
+ #
51
+ def entity_clusters_string_list!(cluster_entities,separator,attribute=:name,allowed_cluster_ids=nil)
52
+ _cluster_entities = cluster_entities.reject(&:nil?)
53
+ if allowed_cluster_ids.is_a?(Array)
54
+ _cluster_entities.select!{|ce| allowed_cluster_ids.include?(ce.cluster_id)}
55
+ end
56
+
57
+ # Performance optimization: Use preloaded data when available
58
+ if cluster_entities.respond_to?(:loaded?) && cluster_entities.loaded? &&
59
+ _cluster_entities.all? { |ce| ce.association(:cluster).loaded? }
60
+ # Use in-memory data (much faster)
61
+ _cluster_entities.map do |ce|
62
+ ce.cluster.try(attribute)
63
+ end.compact.sort.join(separator)
64
+ else
65
+ # Fallback to original method with database query
66
+ # But use a single query instead of N+1
67
+ cluster_ids = _cluster_entities.map(&:cluster_id).compact.uniq
68
+ return "" if cluster_ids.empty?
69
+
70
+ clusters_hash = ::Cluster.where(id: cluster_ids).pluck(:id, attribute).to_h
71
+ _cluster_entities.map do |ce|
72
+ clusters_hash[ce.cluster_id]
73
+ end.compact.sort.join(separator)
74
+ end
75
+ end
76
+
77
+ ##
78
+ # cluster_list! needs a user and a organization. that why we perfomed this logic here
79
+ #
80
+ def user_clusters_string_list!(user,organization,cluster_entities,separator,attribute=:name)
81
+ @clusters_session ||= Klastera.cluster_list!(organization,user)
82
+ self.entity_clusters_string_list!(cluster_entities, separator, attribute, @clusters_session.map(&:id))
83
+ end
84
+
85
+ #
86
+ # We will try to avoid cluster clause except when:
87
+ # 1.- cluster mode is active
88
+ # AND
89
+ # 2a.- cluster_filter is present (someone wants to filter by cluster)
90
+ # OR
91
+ # 2b.- the current user has some limitations and must checks they cluster relation
92
+ # - User is having clusters in optional_suborganization mode
93
+ # - User IS NOT having clusters in required_suborganization mode
94
+ #
95
+ # For the other hand, with force_cluster_clause we can skip the previous logic if
96
+ # cluster_filter_id is present when the optional_suborganization mode is on. BUT!
97
+ # Be aware that if the cluster_filter is not present, the value of force_cluster_clause
98
+ # will be overridden by the returned value of cannot_skip_cluster_clause? method.
99
+ def should_clusterize_scope?(user, organization, cluster_filter=nil, force_cluster_clause=false)
100
+ should = false # I don't know if this is a good idea
101
+ if organization.is_in_cluster_mode? && ( cluster_filter.present? || force_cluster_clause = user.cannot_skip_cluster_clause? ) # yes, this is an assignation
102
+ cluster_ids = []
103
+ # Set another variable as array to get the cluster id(s)
104
+ if cluster_filter.present?
105
+ cluster_ids = cluster_filter.is_a?(Array) ? cluster_filter : [cluster_filter]
106
+ elsif force_cluster_clause
107
+ cluster_ids = ::ClusterUser.clusters_of(organization,user).map(&:id)
108
+ end
109
+ # We will avoid the query unless cluster_ids is having values OR force_cluster_clause is set (see method description)
110
+ if cluster_ids.present? || force_cluster_clause
111
+ # We add the unclustered if the value of cluster_filter have the special without_cluster string or as method description says
112
+ if cluster_ids.delete(UNCLUSTERED_ENTITY) || ( force_cluster_clause && organization.optional_suborganization_mode? )
113
+ cluster_ids << nil
114
+ end
115
+ should = true
116
+ end
117
+ end
118
+ yield(should,cluster_ids)
119
+ end
120
+
121
+ #
122
+ # The cleanest and fast way to clusterize a entity!
123
+ #
124
+ def cluster_scope!(scope_klass, user, organization, cluster_filter=nil, force_cluster_clause=false)
125
+ scope = scope_class(scope_klass)
126
+ should_clusterize_scope?(user,organization,cluster_filter,force_cluster_clause) do |should,cluster_ids|
127
+ if should
128
+ scope = scope.eager_load(:organization,cluster_entities: :cluster).where( cluster_entities: { cluster_id: cluster_ids } )
129
+ end
130
+ end
131
+ scope.where(organization_id: organization)
132
+ end
133
+
134
+
135
+ # Filter non-clustered entity through a clusterized one
136
+ #
137
+ def cluster_scope_through_of!(relation, cluster_entity_klass, scope_klass, user, organization, cluster_filter=nil, force_cluster_clause=false)
138
+ unclusterized_scope = scope_class(scope_klass)
139
+
140
+ if organization.is_in_cluster_mode? && ( force_cluster_clause || user.cannot_skip_cluster_clause? )
141
+ unclusterized_scope = unclusterized_scope.joins(relation).joins(Klastera::ClusterEntity.left_join_sources_of(cluster_entity_klass))
142
+ end
143
+
144
+ if scope_klass.respond_to?(:organization)
145
+ unclusterized_scope = unclusterized_scope.where(organization_id: organization)
146
+ end
147
+
148
+ unclusterized_scope.where("#{relation}_id" => cluster_scope!(cluster_entity_klass, user, organization, cluster_filter, force_cluster_clause))
149
+ end
150
+
151
+ #
152
+ # Returns an array with a clusterized scoped result and its grouped version
153
+ #
154
+ def group_by_cluster_scope!(scope_klass, user, organization, cluster_filter=[], scope_scopes=[])
155
+ cluster_ids = cluster_filter.is_a?(Array) ? cluster_filter : [cluster_filter]
156
+ kluster_scope = cluster_scope!(scope_klass, user, organization, cluster_ids.compact, organization.is_in_cluster_mode? )
157
+
158
+ scope_scopes.each do |tuple_scope|
159
+ scope_name, scope_arg = tuple_scope
160
+ kluster_scope = scope_arg.present? ? kluster_scope.send(scope_name,scope_arg) : kluster_scope.send(scope_name)
161
+ end
162
+
163
+ group_by_block = ->(o) {
164
+ if organization.is_in_cluster_mode?
165
+ o.cluster.present? ? o.cluster.name : UNCLUSTERED_POSITION
166
+ else
167
+ I18n.t("klastera.group_by_cluster_scope.#{scope_klass.model_name.plural}")
168
+ end
169
+ }
170
+
171
+ grouped_cluster_scope = kluster_scope.group_by(&group_by_block).sort_by{|k,v|k.to_s}
172
+
173
+ grouped_cluster_scope.dup.each do |group|
174
+ if group.first == UNCLUSTERED_POSITION
175
+ grouped_cluster_scope.delete(group)
176
+ group[0] = I18n.t("klastera.#{UNCLUSTERED_ENTITY}")
177
+ grouped_cluster_scope.append(group)
178
+ end
179
+ end
180
+
181
+ [ kluster_scope, grouped_cluster_scope ]
182
+ end
183
+
184
+ #
185
+ # A helper that returns a CLUSTER SCOPE to build queries that need explicit LEFT OUTER JOIN clause,
186
+ # instead of the default INNER JOIN provide by ActiveRecord's joins method
187
+ #
188
+ def cluster_scope_left_join!(scope_klass,organization)
189
+ cluster_entities_arel_table = Klastera::ClusterEntity.arel_table
190
+ cluster_arel_table = ::Cluster.arel_table
191
+ cluster_entities_cluster = cluster_entities_arel_table.join(cluster_arel_table, Arel::Nodes::OuterJoin).on(
192
+ cluster_entities_arel_table[:cluster_id].eq(cluster_arel_table[:id]),
193
+ ).join_sources
194
+
195
+ scope_class(scope_klass).where(organization_id: organization).joins(Klastera::ClusterEntity.left_join_sources_of(scope_klass)).joins(cluster_entities_cluster)
196
+ end
197
+ end
198
+
199
+ ##################################################################################################################################################
200
+
201
+ def cluster_user
202
+ current_user
203
+ end
204
+
205
+ def cluster_organization
206
+ current_organization
207
+ end
208
+
209
+ def set_cluster_filter
210
+ cluster_filter_params = params.require(:cluster_filter) rescue {}
211
+ @cluster_filter = ::ClusterFilter.new(
212
+ cluster_filter_params.present? ? cluster_filter_params.permit(
213
+ [ :cluster_id ].concat( ::ClusterFilter.attributes )
214
+ ) : {}
215
+ )
216
+ end
217
+
218
+ def cluster_list(include_unclustered=true)
219
+ Klastera.cluster_list!(cluster_organization, cluster_user, include_unclustered)
220
+ end
221
+
222
+ def cluster_scope(scope_klass, cluster_filter=nil, force_cluster_clause=false)
223
+ Klastera.cluster_scope!(scope_klass, cluster_user, cluster_organization, cluster_filter, force_cluster_clause)
224
+ end
225
+
226
+ def cluster_scope_through_of(relation, cluster_entity_klass, scope_klass, cluster_filter=nil, force_cluster_clause=false)
227
+ Klastera.cluster_scope_through_of!(relation, cluster_entity_klass, scope_klass, cluster_user, cluster_organization, cluster_filter, force_cluster_clause)
228
+ end
229
+
230
+ def group_by_cluster_scope(scope_klass, cluster_filter=[], scope_scopes=[])
231
+ Klastera.group_by_cluster_scope!(scope_klass, cluster_user, cluster_organization, cluster_filter, scope_scopes)
232
+ end
233
+
234
+ def user_clusters_string_list(object_entity, separator, attribute=:name)
235
+ Klastera.user_clusters_string_list!(cluster_user, cluster_organization, object_entity.try(:cluster_entities), separator, attribute)
236
+ end
237
+
238
+ def cluster_scope_left_join(scope_klass)
239
+ Klastera.cluster_scope_left_join!(scope_klas,cluster_organization)
240
+ end
241
+
242
+ included do
243
+ Klastera::KLSTR_HELPERS.each do |action|
244
+ if respond_to?(:helper_method)
245
+ helper_method(action)
246
+ end
247
+ if respond_to?(:hide_action)
248
+ hide_action(helper)
249
+ hide_action("#{helper}=")
250
+ end
251
+ end
252
+ end
253
+ end
@@ -0,0 +1,32 @@
1
+ # desc "Explaining what the task does"
2
+ # task :klastera do
3
+ # # Task goes here
4
+ # end
5
+
6
+
7
+ namespace :klastera do
8
+ namespace :seed do
9
+
10
+ desc "Move cluster_id to cluster_entities"
11
+ task :cluster_entities, [:entity] => :environment do |task,args|
12
+ begin
13
+ klass = args.entity.constantize
14
+ ActiveRecord::Base.transaction do
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
21
+ Klastera::ClusterEntity.create(entity: entity, cluster: entity.cluster)
22
+ end
23
+ end
24
+ rescue NameError => ne
25
+ puts "NameError Exception: #{ne}"
26
+ rescue ActiveRecord::StatementInvalid => asi
27
+ puts "ActiveRecord::StatementInvalid Exception #{asi}"
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,52 @@
1
+ require 'test_helper'
2
+
3
+ module Klastera
4
+ class ClustersControllerTest < ActionController::TestCase
5
+ setup do
6
+ @cluster = klastera_clusters(:one)
7
+ @routes = Engine.routes
8
+ end
9
+
10
+ test "should get index" do
11
+ get :index
12
+ assert_response :success
13
+ assert_not_nil assigns(:clusters)
14
+ end
15
+
16
+ test "should get new" do
17
+ get :new
18
+ assert_response :success
19
+ end
20
+
21
+ test "should create cluster" do
22
+ assert_difference('Cluster.count') do
23
+ post :create, cluster: { color: @cluster.color, name: @cluster.name, nid: @cluster.nid }
24
+ end
25
+
26
+ assert_redirected_to cluster_path(assigns(:cluster))
27
+ end
28
+
29
+ test "should show cluster" do
30
+ get :show, id: @cluster
31
+ assert_response :success
32
+ end
33
+
34
+ test "should get edit" do
35
+ get :edit, id: @cluster
36
+ assert_response :success
37
+ end
38
+
39
+ test "should update cluster" do
40
+ patch :update, id: @cluster, cluster: { color: @cluster.color, name: @cluster.name, nid: @cluster.nid }
41
+ assert_redirected_to cluster_path(assigns(:cluster))
42
+ end
43
+
44
+ test "should destroy cluster" do
45
+ assert_difference('Cluster.count', -1) do
46
+ delete :destroy, id: @cluster
47
+ end
48
+
49
+ assert_redirected_to clusters_path
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,9 @@
1
+ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2
+
3
+ one:
4
+ user_id: 1
5
+ cluster_id: MyString
6
+
7
+ two:
8
+ user_id: 1
9
+ cluster_id: MyString
@@ -0,0 +1,11 @@
1
+ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2
+
3
+ one:
4
+ nid: MyString
5
+ name: MyText
6
+ color: MyString
7
+
8
+ two:
9
+ nid: MyString
10
+ name: MyText
11
+ color: MyString
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class NavigationTest < ActionDispatch::IntegrationTest
4
+ # test "the truth" do
5
+ # assert true
6
+ # end
7
+ end
8
+
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class KlasteraTest < ActiveSupport::TestCase
4
+ test "truth" do
5
+ assert_kind_of Module, Klastera
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ module Klastera
4
+ class ClusterTest < ActiveSupport::TestCase
5
+ # test "the truth" do
6
+ # assert true
7
+ # end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ module Klastera
4
+ class ClusterUserTest < ActiveSupport::TestCase
5
+ # test "the truth" do
6
+ # assert true
7
+ # end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # Configure Rails Environment
2
+ ENV["RAILS_ENV"] = "test"
3
+
4
+ require File.expand_path("../../test/dummy/config/environment.rb", __FILE__)
5
+ ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../test/dummy/db/migrate", __FILE__)]
6
+ ActiveRecord::Migrator.migrations_paths << File.expand_path('../../db/migrate', __FILE__)
7
+ require "rails/test_help"
8
+
9
+ # Filter out Minitest backtrace while allowing backtrace from other libraries
10
+ # to be shown.
11
+ Minitest.backtrace_filter = Minitest::BacktraceFilter.new
12
+
13
+ # Load support files
14
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
15
+
16
+ # Load fixtures from the engine
17
+ if ActiveSupport::TestCase.respond_to?(:fixture_path=)
18
+ ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
19
+ ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path
20
+ ActiveSupport::TestCase.fixtures :all
21
+ 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.5.3
4
+ version: 1.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gino Barahona
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-17 00:00:00.000000000 Z
11
+ date: 2025-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 6.1.3
19
+ version: 5.2.6
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 6.1.3
26
+ version: 5.2.6
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: pg
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,7 +44,71 @@ email:
44
44
  executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
- files: []
47
+ files:
48
+ - MIT-LICENSE
49
+ - README.rdoc
50
+ - Rakefile
51
+ - app/assets/javascripts/klastera/application.js
52
+ - app/assets/javascripts/klastera/clusters.js
53
+ - app/assets/stylesheets/klastera/clusters.scss
54
+ - app/controllers/klastera/application_controller.rb
55
+ - app/controllers/klastera/clusters_controller.rb
56
+ - app/helpers/klastera/application_helper.rb
57
+ - app/models/klastera/cluster.rb
58
+ - app/models/klastera/cluster_entity.rb
59
+ - app/models/klastera/cluster_filter.rb
60
+ - app/models/klastera/cluster_user.rb
61
+ - app/models/klastera/concerns/cluster.rb
62
+ - app/models/klastera/concerns/cluster_entity.rb
63
+ - app/models/klastera/concerns/cluster_filter.rb
64
+ - app/models/klastera/concerns/cluster_user.rb
65
+ - app/models/klastera/concerns/clusterizable.rb
66
+ - app/models/klastera/concerns/organization.rb
67
+ - app/models/klastera/concerns/transfer.rb
68
+ - app/models/klastera/concerns/user.rb
69
+ - app/models/klastera/transfer.rb
70
+ - app/views/klastera/clusters/_filter.html.erb
71
+ - app/views/klastera/clusters/_form.html.erb
72
+ - app/views/klastera/clusters/_form_transfer.html.erb
73
+ - app/views/klastera/clusters/_table.html.erb
74
+ - app/views/klastera/clusters/create.js.erb
75
+ - app/views/klastera/clusters/destroy.js.erb
76
+ - app/views/klastera/clusters/edit.html.erb
77
+ - app/views/klastera/clusters/index.html.erb
78
+ - app/views/klastera/clusters/new.html.erb
79
+ - app/views/klastera/clusters/transfer.html.erb
80
+ - app/views/klastera/clusters/update.js.erb
81
+ - app/views/layouts/klastera/_cluster_entity_fields.html.erb
82
+ - app/views/layouts/klastera/_cluster_filter.html.erb
83
+ - app/views/layouts/klastera/_cluster_role.html.erb
84
+ - app/views/layouts/klastera/_cluster_selector.html.erb
85
+ - app/views/layouts/klastera/_cluster_user_fields.html.erb
86
+ - app/views/layouts/klastera/_nested_cluster_entity.html.erb
87
+ - app/views/layouts/klastera/_nested_cluster_user.html.erb
88
+ - app/views/layouts/klastera/_options.html.erb
89
+ - config/locales/es.yml
90
+ - config/routes.rb
91
+ - db/migrate/20200324203929_create_klastera_clusters.rb
92
+ - db/migrate/20200326111219_add_cluster_options_to_organizations.rb
93
+ - db/migrate/20200330010551_create_klastera_cluster_users.rb
94
+ - db/migrate/20200330221601_add_order_field_to_clusters.rb
95
+ - db/migrate/20200518142609_create_klastera_cluster_entities.rb
96
+ - db/migrate/20200908180057_add_cluster_config_to_organization.rb
97
+ - db/migrate/20220602222332_add_unique_index_to_cluster_entities.rb
98
+ - db/migrate/20250429110829_add_entity_id_index_to_cluster_entities.rb
99
+ - db/migrate/20250429110830_add_entity_id_index_and_entity_type_index_to_cluster_entities.klastera.rb
100
+ - lib/klastera.rb
101
+ - lib/klastera/engine.rb
102
+ - lib/klastera/version.rb
103
+ - lib/tasks/klastera_tasks.rake
104
+ - test/controllers/klastera/clusters_controller_test.rb
105
+ - test/fixtures/klastera/cluster_users.yml
106
+ - test/fixtures/klastera/clusters.yml
107
+ - test/integration/navigation_test.rb
108
+ - test/klastera_test.rb
109
+ - test/models/klastera/cluster_test.rb
110
+ - test/models/klastera/cluster_user_test.rb
111
+ - test/test_helper.rb
48
112
  homepage: https://github.com/ginosx/klastera
49
113
  licenses:
50
114
  - MIT
@@ -64,8 +128,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
128
  - !ruby/object:Gem::Version
65
129
  version: '0'
66
130
  requirements: []
67
- rubygems_version: 3.1.6
131
+ rubygems_version: 3.4.10
68
132
  signing_key:
69
133
  specification_version: 4
70
134
  summary: Clusterization Engine
71
- test_files: []
135
+ test_files:
136
+ - test/controllers/klastera/clusters_controller_test.rb
137
+ - test/fixtures/klastera/cluster_users.yml
138
+ - test/fixtures/klastera/clusters.yml
139
+ - test/integration/navigation_test.rb
140
+ - test/klastera_test.rb
141
+ - test/models/klastera/cluster_test.rb
142
+ - test/models/klastera/cluster_user_test.rb
143
+ - test/test_helper.rb