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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +37 -0
- data/app/assets/javascripts/klastera/application.js +13 -0
- data/app/assets/javascripts/klastera/clusters.js +2 -0
- data/app/assets/stylesheets/klastera/clusters.scss +46 -0
- data/app/controllers/klastera/application_controller.rb +29 -0
- data/app/controllers/klastera/clusters_controller.rb +60 -0
- data/app/helpers/klastera/application_helper.rb +40 -0
- data/app/models/klastera/cluster.rb +5 -0
- data/app/models/klastera/cluster_entity.rb +5 -0
- data/app/models/klastera/cluster_filter.rb +5 -0
- data/app/models/klastera/cluster_user.rb +5 -0
- data/app/models/klastera/concerns/cluster.rb +67 -0
- data/app/models/klastera/concerns/cluster_entity.rb +18 -0
- data/app/models/klastera/concerns/cluster_filter.rb +22 -0
- data/app/models/klastera/concerns/cluster_user.rb +41 -0
- data/app/models/klastera/concerns/clusterizable.rb +115 -0
- data/app/models/klastera/concerns/organization.rb +49 -0
- data/app/models/klastera/concerns/transfer.rb +45 -0
- data/app/models/klastera/concerns/user.rb +77 -0
- data/app/models/klastera/transfer.rb +5 -0
- data/app/views/klastera/clusters/_filter.html.erb +0 -0
- data/app/views/klastera/clusters/_form.html.erb +22 -0
- data/app/views/klastera/clusters/_form_transfer.html.erb +34 -0
- data/app/views/klastera/clusters/_table.html.erb +33 -0
- data/app/views/klastera/clusters/create.js.erb +1 -0
- data/app/views/klastera/clusters/destroy.js.erb +6 -0
- data/app/views/klastera/clusters/edit.html.erb +10 -0
- data/app/views/klastera/clusters/index.html.erb +21 -0
- data/app/views/klastera/clusters/new.html.erb +10 -0
- data/app/views/klastera/clusters/transfer.html.erb +10 -0
- data/app/views/klastera/clusters/update.js.erb +1 -0
- data/app/views/layouts/klastera/_cluster_entity_fields.html.erb +10 -0
- data/app/views/layouts/klastera/_cluster_filter.html.erb +23 -0
- data/app/views/layouts/klastera/_cluster_role.html.erb +48 -0
- data/app/views/layouts/klastera/_cluster_selector.html.erb +21 -0
- data/app/views/layouts/klastera/_cluster_user_fields.html.erb +10 -0
- data/app/views/layouts/klastera/_nested_cluster_entity.html.erb +43 -0
- data/app/views/layouts/klastera/_nested_cluster_user.html.erb +22 -0
- data/app/views/layouts/klastera/_options.html.erb +21 -0
- data/config/locales/es.yml +96 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20200324203929_create_klastera_clusters.rb +12 -0
- data/db/migrate/20200326111219_add_cluster_options_to_organizations.rb +6 -0
- data/db/migrate/20200330010551_create_klastera_cluster_users.rb +9 -0
- data/db/migrate/20200330221601_add_order_field_to_clusters.rb +5 -0
- data/db/migrate/20200518142609_create_klastera_cluster_entities.rb +8 -0
- data/db/migrate/20200908180057_add_cluster_config_to_organization.rb +5 -0
- data/db/migrate/20220602222332_add_unique_index_to_cluster_entities.rb +5 -0
- data/db/migrate/20250429110829_add_entity_id_index_to_cluster_entities.rb +6 -0
- data/db/migrate/20250429110830_add_entity_id_index_and_entity_type_index_to_cluster_entities.klastera.rb +7 -0
- data/lib/klastera/engine.rb +5 -0
- data/lib/klastera/version.rb +3 -0
- data/lib/klastera.rb +253 -0
- data/lib/tasks/klastera_tasks.rake +32 -0
- data/test/controllers/klastera/clusters_controller_test.rb +52 -0
- data/test/fixtures/klastera/cluster_users.yml +9 -0
- data/test/fixtures/klastera/clusters.yml +11 -0
- data/test/integration/navigation_test.rb +8 -0
- data/test/klastera_test.rb +7 -0
- data/test/models/klastera/cluster_test.rb +9 -0
- data/test/models/klastera/cluster_user_test.rb +9 -0
- data/test/test_helper.rb +21 -0
- metadata +79 -7
@@ -0,0 +1,77 @@
|
|
1
|
+
module Klastera::Concerns::User
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
|
6
|
+
CLUSTER_ROOT = 'root'.freeze
|
7
|
+
CLUSTER_ADMIN = 'admin'.freeze
|
8
|
+
CLUSTER_USER = 'user'.freeze
|
9
|
+
|
10
|
+
CLUSTER_ROLES = [ CLUSTER_ROOT, CLUSTER_ADMIN, CLUSTER_USER ].freeze
|
11
|
+
|
12
|
+
has_many :cluster_users, inverse_of: :user, class_name: ::ClusterUser.to_s
|
13
|
+
accepts_nested_attributes_for :cluster_users, reject_if: :all_blank, allow_destroy: true
|
14
|
+
validates :cluster_role, presence: true, if: -> { organization.present? && organization.is_in_cluster_mode? }
|
15
|
+
validates :cluster_role, inclusion: { in: CLUSTER_ROLES , message: I18n.t('klastera.clusters.wrong_option') }, if: -> { cluster_role.present? }
|
16
|
+
validate :at_least_one_role, if: -> { use_cluster? && try(:need_cluster_assignation?) }
|
17
|
+
|
18
|
+
def use_cluster?; cluster_role.present?; end
|
19
|
+
|
20
|
+
def is_a_cluster_root?; cluster_role == CLUSTER_ROOT; end
|
21
|
+
def is_a_cluster_admin?; cluster_role == CLUSTER_ADMIN; end
|
22
|
+
def is_a_cluster_user?; cluster_role == CLUSTER_USER; end
|
23
|
+
|
24
|
+
def need_cluster_assignation?
|
25
|
+
organization.present? && organization.required_suborganization_mode? && is_a_cluster_user?
|
26
|
+
end
|
27
|
+
|
28
|
+
def can_admin_clusters?
|
29
|
+
organization.present? && organization.is_in_cluster_mode? && ( is_a_cluster_admin? || is_a_cluster_root? )
|
30
|
+
end
|
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
|
+
! ( is_a_cluster_admin? || is_a_cluster_root? || ( organization.present? && organization.optional_suborganization_mode? && cluster_users.blank? ) )
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# We will try to create a cluster_user record whether
|
41
|
+
# the organization is using force mode (if cluster_id isn't present, it will raise a validation error)
|
42
|
+
# or
|
43
|
+
# cluster_id is present (on show/use mode organizations).
|
44
|
+
#
|
45
|
+
def try_to_clusterify!(role,cluster_ids)
|
46
|
+
if organization.present? && organization.is_in_cluster_mode?
|
47
|
+
self.cluster_role = role
|
48
|
+
if ( organization.present? && organization.required_suborganization_mode? ) || cluster_ids.present?
|
49
|
+
timestamp = DateTime.now.to_i
|
50
|
+
nested_attributes = {}
|
51
|
+
cluster_ids.each do |cluster_id|
|
52
|
+
nested_attributes["#{cluster_id}_#{timestamp}"] = {
|
53
|
+
cluster_id: cluster_id,
|
54
|
+
_destroy: false
|
55
|
+
}
|
56
|
+
end
|
57
|
+
self.cluster_users_attributes = nested_attributes
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def at_least_one_role
|
65
|
+
if cluster_users.none?
|
66
|
+
errors.add(:base, I18n.t('klastera.user.you_need_add_at_least_one_cluster'))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
module ClassMethods
|
73
|
+
def cluster_params
|
74
|
+
[ :cluster_role, { cluster_users_attributes: [:id, :cluster_id, :_destroy] } ]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<%= simple_form_for( @cluster, remote: true, html: { autocomplete: :off, class: 'slim-form-field' } ) do |f| %>
|
2
|
+
<%=render 'layouts/remote_form/header', o: @cluster, title: title, fa: :qrcode %>
|
3
|
+
|
4
|
+
<div class="<%=classes_for_remote_modal_body()%>">
|
5
|
+
<div class="row">
|
6
|
+
<div class="col-xs-6">
|
7
|
+
<%= f.input :name, as: :string, label: t('klastera.cluster_name') %>
|
8
|
+
</div>
|
9
|
+
<div class="col-xs-6">
|
10
|
+
<%= f.input :nid, as: :string, label: t('klastera.cluster_nid') %>
|
11
|
+
</div>
|
12
|
+
<div class="col-xs-6">
|
13
|
+
<%= f.input :color, as: :string, label: t('klastera.cluster_color'), input_html: { class: 'color-picker'} %>
|
14
|
+
</div>
|
15
|
+
<div class="col-xs-6">
|
16
|
+
<%= f.input :order, as: :string, label: t('klastera.cluster_order') %>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<%=render 'layouts/remote_form/footer', o: @cluster %>
|
22
|
+
<% end %>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<% can_transfer_and_destroy = @cluster.can_transfer_and_destroy? %>
|
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
|
+
<%=render 'layouts/remote_form/header', o: @cluster, title: title, fa: :qrcode %>
|
4
|
+
<div class="<%=classes_for_remote_modal_body()%>">
|
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
|
+
<br />
|
8
|
+
<div class="row">
|
9
|
+
<% if can_transfer_and_destroy %>
|
10
|
+
<div class="col-xs-12">
|
11
|
+
<div class="alert alert-<%=cluster_organization.required_suborganization_mode? ? :warning : :info %> text-center">
|
12
|
+
<i class="fa fa-2x fa-<%=cluster_organization.required_suborganization_mode? ? :warning : 'info-circle' %> float-none"></i>
|
13
|
+
<p class="margin-top-5 fa-1-2x"><%=t("klastera.clusters.transfer.#{cluster_organization.required_suborganization_mode? ? :required : :optional}")%></p>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
<div class="col-xs-12">
|
17
|
+
<%= f.input :new_cluster_id, collection: @cluster.siblings.map{|s|[s.name,s.id]}, label: t('klastera.clusters.siblings') %>
|
18
|
+
</div>
|
19
|
+
<% else %>
|
20
|
+
<div class="col-xs-12">
|
21
|
+
<div class="alert alert-danger text-center no-margin">
|
22
|
+
<i class="fa fa-2x fa-times-circle float-none"></i>
|
23
|
+
<br />
|
24
|
+
<div class="fa-1-2x">
|
25
|
+
<%=ac_errors_as_html_list(@cluster.errors)%>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
<% end %>
|
30
|
+
</div>
|
31
|
+
<% end %>
|
32
|
+
</div>
|
33
|
+
<%=render 'layouts/remote_form/footer', o: @cluster, btn_type: :danger, hide_submit_button: (! can_transfer_and_destroy ) %>
|
34
|
+
<% end %>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<table class="table table-striped table-hover table-condensed table-bordered datatable table">
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<th class="text-center cluster-id"><%=t('klastera.cluster_id')%></th>
|
5
|
+
<th class="text-center cluster-order"><%=t('klastera.cluster_order')%></th>
|
6
|
+
<th class="text-center cluster-color"><%=t('klastera.cluster_color')%></th>
|
7
|
+
<th class="text-center cluster-name"><%=t('klastera.cluster_name')%></th>
|
8
|
+
<th class="text-center cluster-nid"><%=t('klastera.cluster_nid')%></th>
|
9
|
+
<th class="cogs-actions two-icons"><span class="fa fa-cogs"></span></th>
|
10
|
+
</tr>
|
11
|
+
</thead>
|
12
|
+
<tbody>
|
13
|
+
<% @clusters.each do |cluster| %>
|
14
|
+
<tr class="middle-align-rows">
|
15
|
+
<td class="text-center cluster-id"><%= cluster.id %></td>
|
16
|
+
<td class="text-center cluster-order"><%= cluster.order %></td>
|
17
|
+
<td class="text-center cluster-color">
|
18
|
+
<i style='<%="color:#{cluster.color}" if cluster.color.present?%>' class="fa fa-square fa-2x<%=' colorless' if cluster.color.blank?%>" aria-hidden="true"></i>
|
19
|
+
</td>
|
20
|
+
<td class="text-center cluster-name"><%= cluster.name %></td>
|
21
|
+
<td class="text-center cluster-nid"><%= cluster.nid %></td>
|
22
|
+
<td class="cogs-actions two-icons">
|
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
|
+
<span class="fa fa-pencil-square-o"></span>
|
25
|
+
<% end %>
|
26
|
+
<%= link_to transfer_cluster_path(cluster), class:'btn btn-danger btn-xs', title: t('shared.actions.archive'), "data-toggle": "modal", "data-target": "#remote-modal-block" do %>
|
27
|
+
<span class="fa fa-trash"></span>
|
28
|
+
<% end %>
|
29
|
+
</td>
|
30
|
+
</tr>
|
31
|
+
<% end %>
|
32
|
+
</tbody>
|
33
|
+
</table>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render 'layouts/remote_form/common', title: t('klastera.clusters.new.title'), action: :create, id: :cluster, o: @cluster %>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<% if @transfer.errors.any? %>
|
2
|
+
<%= render 'layouts/remote_form/common', title: t('klastera.clusters.destroy.title', cluster_nid: @cluster.nid), action: :update, id: :cluster, o: @transfer, form_partial: 'form_transfer' %>
|
3
|
+
<% else %>
|
4
|
+
$('#cluster-remote-form').html("<%= j render 'layouts/remote_form/blank_modal', title: "Eliminado", o: nil, fa: :qrcode, type: :success, message: t('klastera.messages.record_action_successfully',a: t('klastera.actions.deleted').downcase)%>")
|
5
|
+
<%= render 'layouts/remote_form/common', action: :destroy, id: :cluster %>
|
6
|
+
<% end %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= render layout: 'layouts/remote_form/wrapper', locals: { title: t('.title', cluster_nid: @cluster.nid), id: :cluster, fa: :qrcode } do %>
|
2
|
+
<div class="pull-right">
|
3
|
+
<%= link_to clusters_path(@cluster), class: 'btn btn-primary btn-sm', title: t('shared.actions.show') do %>
|
4
|
+
<span class="fa fa-eye"></span>
|
5
|
+
<% end %>
|
6
|
+
<%= link_to clusters_path, class: 'btn btn-default btn-sm', title: t('shared.actions.back') do %>
|
7
|
+
<span class="fa fa-list"></span>
|
8
|
+
<% end %>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<div class="container" id="gb-content-wrapper">
|
2
|
+
<div class="page-header">
|
3
|
+
<div class="pull-right">
|
4
|
+
<%= link_to(new_cluster_path, class: 'btn btn-success btn-xs action-control', "data-toggle": "modal", "data-target": "#remote-modal-block", title: t('shared.actions.new')) do %>
|
5
|
+
<i class="fa fa-plus"></i>
|
6
|
+
<% end %>
|
7
|
+
</div>
|
8
|
+
<h1><span class="fa fa-qrcode"></span> <%= t '.title' %></h1>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div id="cluster-filter-remote-form">
|
12
|
+
<%= render 'filter' %>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<div id="cluster-remote-table" class="datatable-without-search">
|
16
|
+
<%= render 'table' %>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<%= render 'layouts/remote_form/modal', width: 'md' %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= render layout: 'layouts/remote_form/wrapper', locals: { title: t('.title'), id: :cluster, fa: :qrcode } do %>
|
2
|
+
<div class="pull-right">
|
3
|
+
<%= link_to clusters_path(@cluster), class: 'btn btn-primary btn-sm', title: t('shared.actions.show') do %>
|
4
|
+
<span class="fa fa-eye"></span>
|
5
|
+
<% end %>
|
6
|
+
<%= link_to clusters_path, class: 'btn btn-default btn-sm', title: t('shared.actions.back') do %>
|
7
|
+
<span class="fa fa-list"></span>
|
8
|
+
<% end %>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= render layout: 'layouts/remote_form/wrapper', locals: { title: t('.title', cluster_nid: @cluster.nid), id: :cluster, fa: :qrcode, form: 'form_transfer' } do %>
|
2
|
+
<div class="pull-right">
|
3
|
+
<%= link_to clusters_path(@cluster), class: 'btn btn-primary btn-sm', title: t('shared.actions.show') do %>
|
4
|
+
<span class="fa fa-eye"></span>
|
5
|
+
<% end %>
|
6
|
+
<%= link_to clusters_path, class: 'btn btn-default btn-sm', title: t('shared.actions.back') do %>
|
7
|
+
<span class="fa fa-list"></span>
|
8
|
+
<% end %>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render 'layouts/remote_form/common', title: t('klastera.clusters.edit.title', cluster_nid: @cluster.nid), action: :update, id: :cluster, o: @cluster %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<tr class="nested-fields">
|
2
|
+
<td class="field">
|
3
|
+
<%= f.select :cluster_id, @clusters_session.order(:order,:name).map{|c|[c.name,c.id]}, { include_blank: true }, { class: 'form-control' } %>
|
4
|
+
</td>
|
5
|
+
<td class="action vertical-align-middle text-center" width="44">
|
6
|
+
<%= link_to_remove_association f, class: 'btn btn-danger btn-xs text-danger' do %>
|
7
|
+
<i class="fa fa-trash"></i>
|
8
|
+
<% end %>
|
9
|
+
</td>
|
10
|
+
</tr>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<%= simple_form_for(@cluster_filter, url: url, remote: true) do |f| %>
|
2
|
+
|
3
|
+
<div class="inline-buttons-block top">
|
4
|
+
<%= button_tag(t('klastera.actions.filter'), class: 'btn btn-primary btn-sm float-right', data: { disable_with: "<i class='fa fa-spinner spin'></i>" }) %>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<%=yield(f) if block_given? %>
|
8
|
+
|
9
|
+
<% if cluster_organization.is_in_cluster_mode? %>
|
10
|
+
<% cluster_collection = cluster_list.order(:order, :name).map{|c|[c.name,(c.id||c.nid)]} %>
|
11
|
+
<% if cluster_collection.size > 1 %>
|
12
|
+
<div class="inline-label-control-block">
|
13
|
+
<%= f.input :cluster_id, collection: cluster_collection, prompt: t('klastera.clusters.all'), label: false, wrapper: false %>
|
14
|
+
<label class="control-label"><%=t('klastera.cluster.title')%>:</label>
|
15
|
+
</div>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<div class="inline-buttons-block bottom">
|
20
|
+
<%= button_tag(t('klastera.actions.filter'), class: 'btn btn-primary btn-sm float-right', data: { disable_with: "<i class='fa fa-spinner spin'></i>" }) %>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<% end %>
|
@@ -0,0 +1,48 @@
|
|
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
|
+
%>
|
10
|
+
<% if @user.try(:organization).try(:is_in_cluster_mode?) || other_visibility_reason %>
|
11
|
+
<div class="form-group">
|
12
|
+
<%= f.label t('klastera.cluster_role') %>
|
13
|
+
<span
|
14
|
+
class="klastera-user-cluster-rol"
|
15
|
+
data-title="<%= t('klastera.help.popover.title')%>"
|
16
|
+
data-toggle="popover"
|
17
|
+
data-content="<%=
|
18
|
+
t('klastera.help.popover.content.cluster_role',
|
19
|
+
m1: t('klastera.help.roles.description', r: t('klastera.roles.admin'), d: t('klastera.help.roles.admin')),
|
20
|
+
m2: t('klastera.help.roles.description', r: t('klastera.roles.user'), d: t("klastera.help.roles.user.#{normal_user_help}"))
|
21
|
+
)%>"
|
22
|
+
>
|
23
|
+
<%= fa_icon 'info-circle', class: 'btn-link' %>
|
24
|
+
</span>
|
25
|
+
<%= f.select :cluster_role, user_cluster_roles.map{|r|[t("klastera.roles.#{r}"),r]}, { include_blank: true }, { class: 'form-control' } %>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<script type="text/javascript">
|
29
|
+
$('[name="user[cluster_role]"]').change(function(){
|
30
|
+
if ( $(this).val() == "<%=User::CLUSTER_ROOT%>" ) {
|
31
|
+
swal({
|
32
|
+
title: "<%= t('klastera.user.cluster_root_asignation.title') %>",
|
33
|
+
text: "<%= t('klastera.user.cluster_root_asignation.text') %>",
|
34
|
+
type: "warning",
|
35
|
+
showCancelButton: true,
|
36
|
+
confirmButtonText: "<%= t('klastera.user.assign_cluster_role') %>",
|
37
|
+
cancelButtonText: "<%= t('klastera.actions.cancel') %>",
|
38
|
+
}, function (isConfirm) {
|
39
|
+
if ( ! isConfirm ) {
|
40
|
+
$('[name="user[cluster_role]"]').val("");
|
41
|
+
}
|
42
|
+
});
|
43
|
+
}
|
44
|
+
});
|
45
|
+
var popoverTemplate = '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
46
|
+
$('.klastera-user-cluster-rol').popover({ template: popoverTemplate, html: true, trigger: 'click', });
|
47
|
+
</script>
|
48
|
+
<% end %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<%
|
2
|
+
f = f.nil? ? nil : f
|
3
|
+
other_visibility_reason = other_visibility_reason.nil? ? false : other_visibility_reason
|
4
|
+
%>
|
5
|
+
<% if cluster_organization.is_in_cluster_mode? || other_visibility_reason %>
|
6
|
+
<%
|
7
|
+
cluster_collection = @clusters_session || cluster_list
|
8
|
+
label = t('klastera.cluster.title')
|
9
|
+
%>
|
10
|
+
<% if f.nil? %>
|
11
|
+
<%= label_tag(:cluster_id, label, class: 'control-label') %>
|
12
|
+
<%= select_tag(:cluster_id, options_from_collection_for_select(cluster_collection, 'id', 'display_name_nid'), class: 'form-control', prompt: 'Seleccione') %>
|
13
|
+
<% elsif f.is_a?(SimpleForm::FormBuilder) %>
|
14
|
+
<%= f.input :cluster_id, collection: cluster_collection.map{|c|[c.name,c.id]}, label: label %>
|
15
|
+
<% else %>
|
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>
|
20
|
+
<% end %>
|
21
|
+
<% end %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<tr class="nested-fields">
|
2
|
+
<td class="field">
|
3
|
+
<%= f.select :cluster_id, @user.organization.clusters.order(:order, :name).map{|c|[c.name,c.id]}, { include_blank: true }, { class: 'form-control' } %>
|
4
|
+
</td>
|
5
|
+
<td class="action vertical-align-middle text-center" width="44">
|
6
|
+
<%= link_to_remove_association f, class: 'btn btn-danger btn-xs text-danger' do %>
|
7
|
+
<i class="fa fa-trash"></i>
|
8
|
+
<% end %>
|
9
|
+
</td>
|
10
|
+
</tr>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<% if cluster_organization.is_in_cluster_mode? %>
|
2
|
+
<% @clusters_session = cluster_list(false) %>
|
3
|
+
<div class="col-xs-12">
|
4
|
+
<% if hide_title||=false %>
|
5
|
+
<div class="form-group file required <%=f.object.class.name.parameterize%>_cluster_entity<%=' has-error' if f.object.errors.has_key?(:cluster_entities)%>">
|
6
|
+
<label class="text" for="<%=f.object.class.name.parameterize%>_cluster_entity">
|
7
|
+
<%=t('klastera.clusters.title')%>
|
8
|
+
<% if cluster_organization.required_suborganization_mode? %>
|
9
|
+
<abbr title="required">*</abbr>
|
10
|
+
<% end %>
|
11
|
+
</label>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div class="nested-cluster-entity">
|
15
|
+
<div class="panel panel-default">
|
16
|
+
<div class="panel-heading<%=' custom-required' if cluster_organization.required_suborganization_mode? %>">
|
17
|
+
<h4 class="panel-title">
|
18
|
+
<% unless hide_title||=false %>
|
19
|
+
<div class="float-left" style="line-height: 20px"><%=t('klastera.clusters.title')%></div>
|
20
|
+
<% end %>
|
21
|
+
<%= link_to_add_association f, :cluster_entities, partial: 'layouts/klastera/cluster_entity_fields', data: { 'association-insertion-node': :'tbody.cluster-entity-rows', 'association-insertion-method': :append }, class: 'btn btn-success btn-xs float-right color-white' do %>
|
22
|
+
<i class="fa fa-plus"></i>
|
23
|
+
<% end %>
|
24
|
+
<div class="clearfix"></div>
|
25
|
+
</h4>
|
26
|
+
</div>
|
27
|
+
<table id="cluster-entities" class="table table-striped">
|
28
|
+
<tbody class="cluster-entity-rows">
|
29
|
+
<%= f.fields_for :cluster_entities do |cluster_entity|%>
|
30
|
+
<% next unless @clusters_session.map(&:id).include?(cluster_entity.try(:object).try(:cluster_id)) %>
|
31
|
+
<%= render 'layouts/klastera/cluster_entity_fields', f: cluster_entity %>
|
32
|
+
<% end %>
|
33
|
+
</body>
|
34
|
+
</table>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<% if hide_title||=false %>
|
39
|
+
<div class="invalid-feedback"><%=f.object.try(:errors)&.[](:cluster_entities).try(:first)%></div>
|
40
|
+
</div>
|
41
|
+
<% end %>
|
42
|
+
</div>
|
43
|
+
<% end %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<% if @user.try(:is_a_cluster_user?) %>
|
2
|
+
<div class="nested-cluster-user">
|
3
|
+
<div class="panel panel-default">
|
4
|
+
<div class="panel-heading">
|
5
|
+
<h4 class="panel-title">
|
6
|
+
<div class="float-left" style="line-height: 20px"><%=t('klastera.clusters.title')%></div>
|
7
|
+
<%= link_to_add_association f, :cluster_users, partial: 'layouts/klastera/cluster_user_fields', data: { 'association-insertion-node': :'tbody.cluster-user-rows', 'association-insertion-method': :append }, class: 'btn btn-success btn-xs float-right color-white' do %>
|
8
|
+
<i class="fa fa-plus"></i>
|
9
|
+
<% end %>
|
10
|
+
<div class="clearfix"></div>
|
11
|
+
</h4>
|
12
|
+
</div>
|
13
|
+
<table id="cluster-users" class="table table-striped">
|
14
|
+
<tbody class="cluster-user-rows">
|
15
|
+
<%= f.fields_for :cluster_users do |cluster_user|%>
|
16
|
+
<%= render 'layouts/klastera/cluster_user_fields', f: cluster_user %>
|
17
|
+
<% end %>
|
18
|
+
</body>
|
19
|
+
</table>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<% end %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<div class="form-group">
|
2
|
+
<%= f.label t('klastera.use_cluster_as') %>
|
3
|
+
<span
|
4
|
+
class="klastera-cluster-option"
|
5
|
+
data-title="<%= t('klastera.help.popover.title')%>"
|
6
|
+
data-toggle="popover"
|
7
|
+
data-content="<%=
|
8
|
+
t('klastera.help.popover.content.user_as_cluster_as',
|
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
|
+
)%>"
|
12
|
+
>
|
13
|
+
<%= fa_icon 'info-circle', class: 'btn-link' %>
|
14
|
+
</span>
|
15
|
+
<%= f.select :use_cluster_as, ::Cluster::MODES.map{|cm|[t("klastera.#{cm}"),cm]}, { include_blank: true }, { class: 'form-control' } %>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
<script type="text/javascript">
|
19
|
+
var popoverTemplate = '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
20
|
+
$('.klastera-cluster-option').popover({ template: popoverTemplate, html: true, trigger: 'click', });
|
21
|
+
</script>
|
@@ -0,0 +1,96 @@
|
|
1
|
+
es:
|
2
|
+
klastera:
|
3
|
+
without_cluster: Sin cluster
|
4
|
+
cluster:
|
5
|
+
title: Cluster
|
6
|
+
id: Cluster ID
|
7
|
+
user:
|
8
|
+
add_cluster: Agregar cluster
|
9
|
+
you_need_add_at_least_one_cluster: Esta organización usa clusters en modo obligatorio. Asigne un cluster al usuario por favor.
|
10
|
+
assign_cluster_role: Asignar role
|
11
|
+
cluster_root_asignation:
|
12
|
+
title: Asignación Super Admin
|
13
|
+
text: Este rol es sólo para usuarios super admin
|
14
|
+
roles:
|
15
|
+
root: Super Admin
|
16
|
+
admin: Admin Cluster
|
17
|
+
user: Usuario Cluster
|
18
|
+
using_cluster_as: Usando cluster como
|
19
|
+
cluster_order: Orden
|
20
|
+
cluster_id: ID
|
21
|
+
cluster_role: Rol de clusters
|
22
|
+
cluster_name: Nombre
|
23
|
+
cluster_nid: Código
|
24
|
+
cluster_color: Color
|
25
|
+
organization_name: Organización
|
26
|
+
use_cluster_as: Activar y usar cluster en modo
|
27
|
+
required_suborganization: Obligatorio
|
28
|
+
optional_suborganization: Opcional
|
29
|
+
clusters:
|
30
|
+
all: Todos
|
31
|
+
title: Clusters
|
32
|
+
siblings: Seleccione un cluster
|
33
|
+
cant_delete: No se puede eliminar
|
34
|
+
wrong_option: "%{value} es una opción inválida"
|
35
|
+
entities: "[agregar entidades]"
|
36
|
+
index:
|
37
|
+
title: Gestión de clusters
|
38
|
+
new:
|
39
|
+
title: Nuevo Cluster
|
40
|
+
edit:
|
41
|
+
title: Editar Cluster %{cluster_nid}
|
42
|
+
destroy:
|
43
|
+
title: Eliminar Cluster %{cluster_nid}
|
44
|
+
transfer:
|
45
|
+
title: Eliminar Cluster %{cluster_nid}
|
46
|
+
required: Para eliminar el Cluster es necesario asignar las entidades asociadas a un nuevo Cluster
|
47
|
+
optional: Entidades asociadas al Cluster pueden quedar sin asignar o ser asignadas a un nuevo Cluster
|
48
|
+
actions:
|
49
|
+
filter: Filtrar
|
50
|
+
cancel: Cancelar
|
51
|
+
add: Agregar
|
52
|
+
delete: Eliminar
|
53
|
+
create: Crear
|
54
|
+
update: Actualizar
|
55
|
+
deleted: Eliminado
|
56
|
+
created: Creado
|
57
|
+
updated: Actualizado
|
58
|
+
messages:
|
59
|
+
has_one_cluster_entity: Está permitido agregar un sólo cluster
|
60
|
+
at_least_one_cluster_entity: Debe agregar al menos un cluster
|
61
|
+
record_action_successfully: Registro %{a} exitosamente
|
62
|
+
cant_delete_the_last_record_in_required_suborganization_mode: No se puede eliminar el único cluster de esta organización
|
63
|
+
duplicated_cluster_entity: Hay un cluster duplicado
|
64
|
+
new_cluster_id:
|
65
|
+
nil: Cluster no existe
|
66
|
+
same: Cluster no puede ser el mismo
|
67
|
+
current_cluster:
|
68
|
+
cant_transfer: No se puede eliminar ni mover el cluster
|
69
|
+
access_cluster_admin: No puede acceder a esta página
|
70
|
+
help:
|
71
|
+
popover:
|
72
|
+
title: Descripción de cada opción
|
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
|
+
new: Usuario al que se le puede restringir la cosas que puede ver a través de su asignación con los clusters
|
83
|
+
required: Necesita que se le asigne uno o más clusters, de lo contrario no verá las entidades clusterizadas.
|
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.
|
85
|
+
activemodel:
|
86
|
+
attributes:
|
87
|
+
'klastera/transfer':
|
88
|
+
new_cluster_id: Cluster a transferir
|
89
|
+
activerecord:
|
90
|
+
models:
|
91
|
+
'klastera/cluster':
|
92
|
+
one: Cluster
|
93
|
+
other: Clusters
|
94
|
+
attributes:
|
95
|
+
organization:
|
96
|
+
use_cluster_as: Activar y usar cluster como
|
data/config/routes.rb
ADDED