biovision-base 0.39.190804.1 → 0.41.190905.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/biovision/base/icons/key.svg +16 -0
  3. data/app/assets/javascripts/biovision/base/biovision.js +133 -2
  4. data/app/assets/stylesheets/biovision/base/admin/components.scss +40 -1
  5. data/app/assets/stylesheets/biovision/base/biovision.scss +1 -2
  6. data/app/controllers/admin/codes_controller.rb +9 -1
  7. data/app/controllers/admin/components_controller.rb +80 -10
  8. data/app/controllers/admin/editable_pages_controller.rb +6 -1
  9. data/app/controllers/admin/feedback_requests_controller.rb +10 -2
  10. data/app/controllers/admin/foreign_users_controller.rb +10 -4
  11. data/app/controllers/admin/login_attempts_controller.rb +14 -0
  12. data/app/controllers/admin/simple_blocks_controller.rb +6 -1
  13. data/app/controllers/admin/tokens_controller.rb +11 -5
  14. data/app/controllers/admin/users_controller.rb +11 -5
  15. data/app/controllers/admin_controller.rb +2 -2
  16. data/app/controllers/codes_controller.rb +12 -5
  17. data/app/controllers/editable_pages_controller.rb +6 -1
  18. data/app/controllers/foreign_users_controller.rb +12 -7
  19. data/app/controllers/simple_blocks_controller.rb +6 -1
  20. data/app/controllers/tokens_controller.rb +6 -1
  21. data/app/controllers/users_controller.rb +14 -9
  22. data/app/helpers/biovision_components_helper.rb +4 -1
  23. data/app/helpers/simple_image_helper.rb +43 -23
  24. data/app/models/biovision_component.rb +46 -1
  25. data/app/models/biovision_component_user.rb +2 -0
  26. data/app/models/concerns/checkable.rb +1 -1
  27. data/app/models/concerns/toggleable.rb +6 -2
  28. data/app/services/biovision/components/base_component.rb +44 -16
  29. data/app/services/biovision/components/contact_component.rb +4 -2
  30. data/app/services/biovision/components/content_component.rb +4 -2
  31. data/app/services/biovision/components/users_component.rb +6 -0
  32. data/app/uploaders/simple_image_uploader.rb +15 -1
  33. data/app/views/admin/codes/index.html.erb +2 -1
  34. data/app/views/admin/codes/show.html.erb +12 -10
  35. data/app/views/admin/components/entity/_links.html.erb +17 -2
  36. data/app/views/admin/components/links/_contact.html.erb +3 -1
  37. data/app/views/admin/components/links/_content.html.erb +4 -2
  38. data/app/views/admin/components/links/_users.html.erb +11 -7
  39. data/app/views/admin/components/privileges.html.erb +34 -0
  40. data/app/views/admin/components/privileges/_component_user.html.erb +67 -0
  41. data/app/views/admin/components/privileges/_new_user.html.erb +15 -0
  42. data/app/views/admin/components/privileges/_users.html.erb +23 -0
  43. data/app/views/admin/components/update_privileges.jbuilder +21 -0
  44. data/app/views/admin/editable_pages/index.html.erb +2 -1
  45. data/app/views/admin/editable_pages/show.html.erb +1 -0
  46. data/app/views/admin/feedback_requests/index.html.erb +2 -1
  47. data/app/views/admin/foreign_users/index.html.erb +2 -1
  48. data/app/views/admin/foreign_users/show.html.erb +1 -0
  49. data/app/views/admin/login_attempts/index.html.erb +2 -1
  50. data/app/views/admin/simple_blocks/index.html.erb +2 -1
  51. data/app/views/admin/simple_blocks/show.html.erb +1 -0
  52. data/app/views/admin/tokens/index.html.erb +2 -1
  53. data/app/views/admin/tokens/show.html.erb +12 -3
  54. data/app/views/admin/users/_search.html.erb +1 -1
  55. data/app/views/admin/users/codes.html.erb +4 -3
  56. data/app/views/admin/users/index.html.erb +2 -1
  57. data/app/views/admin/users/search.jbuilder +11 -9
  58. data/app/views/admin/users/show.html.erb +12 -6
  59. data/app/views/admin/users/tokens.html.erb +4 -3
  60. data/app/views/codes/edit.html.erb +4 -3
  61. data/app/views/codes/new.html.erb +3 -2
  62. data/app/views/editable_pages/edit.html.erb +1 -0
  63. data/app/views/editable_pages/new.html.erb +1 -0
  64. data/app/views/shared/entity/_attributes.html.erb +4 -0
  65. data/app/views/shared/entity/_timestamps.html.erb +8 -4
  66. data/app/views/shared/forms/_meta_texts.html.erb +54 -48
  67. data/app/views/simple_blocks/edit.html.erb +1 -0
  68. data/app/views/simple_blocks/new.html.erb +3 -2
  69. data/app/views/tokens/edit.html.erb +4 -3
  70. data/app/views/tokens/new.html.erb +3 -2
  71. data/config/locales/components-en.yml +2 -0
  72. data/config/locales/components-ru.yml +21 -0
  73. data/config/locales/users-ru.yml +2 -1
  74. data/config/routes.rb +6 -0
  75. data/db/migrate/20181217000000_create_biovision_components.rb +1 -0
  76. data/db/migrate/20181217000040_create_privileges.rb +1 -67
  77. data/db/migrate/20190826111111_add_priority_to_biovision_components.rb +14 -0
  78. data/db/migrate/{20190801111111_add_components.rb → 20190826121212_add_components.rb} +0 -0
  79. data/lib/biovision/base/base_methods.rb +13 -4
  80. data/lib/biovision/base/version.rb +1 -1
  81. metadata +11 -3
@@ -14,4 +14,6 @@ class BiovisionComponentUser < ApplicationRecord
14
14
  belongs_to :user
15
15
 
16
16
  validates_uniqueness_of :user_id, scope: :biovision_component_id
17
+
18
+ scope :recent, -> { order('updated_at desc') }
17
19
  end
@@ -5,7 +5,7 @@ module Checkable
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- # @param [Integer] id
8
+ # @param id
9
9
  # @param [Hash] parameters
10
10
  def self.instance_for_check(id, parameters)
11
11
  if id.blank?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Adds list of toggleable attributes to model
2
4
  #
3
5
  # @author Maxim Khan-Magomedov <maxim.km@gmail.com>
@@ -10,17 +12,19 @@ module Toggleable
10
12
  # @param [String, Symbol] attribute
11
13
  # @return [Hash]
12
14
  def toggle_parameter(attribute)
13
- return unless self::toggleable_attributes.include? attribute.to_sym
15
+ return unless toggleable_attributes.include? attribute.to_sym
16
+
14
17
  toggle! attribute
15
18
  { attribute => self[attribute] }
16
19
  end
17
20
  end
18
21
 
22
+ # Additional class methods
19
23
  module ClassMethods
20
24
 
21
25
  private
22
26
 
23
- # @param [Array<Symbol, String>] attributes
27
+ # @param [Array<Symbol>] attributes
24
28
  def toggleable(*attributes)
25
29
  cattr_accessor :toggleable_attributes
26
30
  self.toggleable_attributes = attributes.flatten
@@ -4,7 +4,7 @@ module Biovision
4
4
  module Components
5
5
  # Base biovision component
6
6
  class BaseComponent
7
- attr_reader :component, :slug, :name, :user
7
+ attr_reader :component, :slug, :name, :user, :role
8
8
 
9
9
  # @param [BiovisionComponent] component
10
10
  # @param [User] user
@@ -25,7 +25,7 @@ module Biovision
25
25
  if input.is_a?(BiovisionComponent)
26
26
  handler_class(input.slug).new(input, user)
27
27
  else
28
- entity = BiovisionComponent.find_by!(slug: input)
28
+ entity = BiovisionComponent.find_by(slug: input)
29
29
  handler_class(input).new(entity, user)
30
30
  end
31
31
  end
@@ -36,18 +36,21 @@ module Biovision
36
36
  handler_name.safe_constantize || BaseComponent
37
37
  end
38
38
 
39
- def self.default_privilege_name
40
- self.class.to_s.demodulize.underscore.gsub('component', 'manager')
39
+ # Privilege names for using in biovision_component_user.data
40
+ def self.privilege_names
41
+ []
41
42
  end
42
43
 
43
44
  # @param [User] user
44
- # @param [Hash] options
45
- def self.allow?(user, options = {})
45
+ # @param [String] privilege_name
46
+ def self.allow?(user, privilege_name = '')
46
47
  return false if user.nil?
48
+ return true if user.super_user?
47
49
 
48
- privilege = options[:privilege] || default_privilege_name
50
+ slug = self.class.to_s.demodulize.underscore.gsub('component', '')
51
+ component = BiovisionComponent.find_by(slug: slug)
49
52
 
50
- UserPrivilege.user_has_privilege?(user, privilege)
53
+ self.class.new(component, user).allow?(privilege_name)
51
54
  end
52
55
 
53
56
  # @param [User] user
@@ -66,16 +69,27 @@ module Biovision
66
69
  true
67
70
  end
68
71
 
69
- # @param [Hash] options
70
- def allow?(options = {})
72
+ def administrator?
71
73
  return false if user.nil?
72
- return true if user.super_user? || @role&.administrator?
73
74
 
74
- if options.key?(:action)
75
- @role.data[options[:action].to_s]
76
- else
77
- !@role.nil?
78
- end
75
+ user.super_user? || @role&.administrator?
76
+ end
77
+
78
+ # @param [String|Array] privilege_names
79
+ def allow?(*privilege_names)
80
+ return false if user.nil?
81
+ return true if administrator? || privilege_names.blank?
82
+ return false if @role.nil?
83
+
84
+ privilege_names.flatten.each { |slug| return true if privilege?(slug) }
85
+ false
86
+ end
87
+
88
+ # @param [String] privilege_name
89
+ def privilege?(privilege_name)
90
+ return false if @role.nil?
91
+
92
+ @role.data[privilege_name.to_s]
79
93
  end
80
94
 
81
95
  # @param [Hash] data
@@ -134,6 +148,20 @@ module Biovision
134
148
  metric << quantity
135
149
  end
136
150
 
151
+ # @param [User] user
152
+ # @param [Hash] data
153
+ def update_privileges(user, data = nil)
154
+ criteria = {
155
+ user: user,
156
+ biovision_component: @component
157
+ }
158
+ link = BiovisionComponentUser.find_or_create_by(criteria)
159
+
160
+ link&.update(data: data) unless data.nil?
161
+
162
+ link
163
+ end
164
+
137
165
  protected
138
166
 
139
167
  # @param [Hash] data
@@ -4,8 +4,10 @@ module Biovision
4
4
  module Components
5
5
  # Component for feedback
6
6
  class ContactComponent < BaseComponent
7
- def allow?(options = {})
8
- UserPrivilege.user_has_privilege?(user, :feedback_manager)
7
+ SLUG = 'contact'
8
+
9
+ def self.privilege_names
10
+ %w[feedback_manager]
9
11
  end
10
12
 
11
13
  protected
@@ -4,8 +4,10 @@ module Biovision
4
4
  module Components
5
5
  # Component for content
6
6
  class ContentComponent < BaseComponent
7
- def allow?(options = {})
8
- UserPrivilege.user_has_privilege?(user, :content_manager)
7
+ SLUG = 'content'
8
+
9
+ def self.privilege_names
10
+ %w[content_manager]
9
11
  end
10
12
  end
11
13
  end
@@ -4,6 +4,12 @@ module Biovision
4
4
  module Components
5
5
  # Component for handling users
6
6
  class UsersComponent < BaseComponent
7
+ SLUG = 'users'
8
+
9
+ def self.privilege_names
10
+ %w[view edit manage_codes]
11
+ end
12
+
7
13
  def use_parameters?
8
14
  false
9
15
  end
@@ -9,7 +9,8 @@ class SimpleImageUploader < CarrierWave::Uploader::Base
9
9
  # Override the directory where uploaded files will be stored.
10
10
  # This is a sensible default for uploaders that are meant to be mounted:
11
11
  def store_dir
12
- slug = "#{model.id / 1000}/#{model.id}"
12
+ id = model&.id.to_i
13
+ slug = "#{id / 1000}/#{id}"
13
14
 
14
15
  "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{slug}"
15
16
  end
@@ -44,6 +45,19 @@ class SimpleImageUploader < CarrierWave::Uploader::Base
44
45
  %w[jpg jpeg png svg svgz]
45
46
  end
46
47
 
48
+ # Text for image alt attribute
49
+ #
50
+ # @param [String] default
51
+ # @return [String]
52
+ def alt_text(default = '')
53
+ method_name = "#{mounted_as}_alt_text".to_sym
54
+ if model.respond_to?(method_name)
55
+ model.send(method_name)
56
+ else
57
+ default
58
+ end
59
+ end
60
+
47
61
  # @param [SanitizedFile]
48
62
  def raster_image?(new_file)
49
63
  !new_file.extension.match?(/svgz?\z/i)
@@ -1,6 +1,7 @@
1
1
  <% content_for :meta_title, t('.title', page: current_page) %>
2
2
  <% content_for :breadcrumbs do %>
3
- <span><%= t('admin.codes.nav_item.text') %></span>
3
+ <%= admin_biovision_component_link(component_handler.component) %>
4
+ <span><%= t('admin.codes.nav_item.text') %></span>
4
5
  <% end %>
5
6
 
6
7
  <article>
@@ -1,7 +1,8 @@
1
1
  <% content_for :meta_title, t('.title', body: @entity.body) %>
2
2
  <% content_for :breadcrumbs do %>
3
- <%= link_to(t('admin.codes.nav_item.text'), admin_codes_path) %>
4
- <span><%= @entity.body %></span>
3
+ <%= admin_biovision_component_link(component_handler.component) %>
4
+ <%= link_to(t('admin.codes.nav_item.text'), admin_codes_path) %>
5
+ <span><%= @entity.body %></span>
5
6
  <% end %>
6
7
 
7
8
  <article>
@@ -29,17 +30,17 @@
29
30
  </dd>
30
31
 
31
32
  <% unless @entity.updated_at.nil? %>
32
- <dt><%= t(:updated_at) %></dt>
33
- <dd>
34
- <%= time_tag(@entity.updated_at) %>
35
- </dd>
33
+ <dt><%= t(:updated_at) %></dt>
34
+ <dd>
35
+ <%= time_tag(@entity.updated_at) %>
36
+ </dd>
36
37
  <% end %>
37
38
 
38
39
  <% unless @entity.payload.blank? %>
39
- <dt><%= t('activerecord.attributes.code.payload') %></dt>
40
- <dd>
41
- <%= @entity.payload %>
42
- </dd>
40
+ <dt><%= t('activerecord.attributes.code.payload') %></dt>
41
+ <dd>
42
+ <%= @entity.payload %>
43
+ </dd>
43
44
  <% end %>
44
45
 
45
46
  <dt><%= t('activerecord.attributes.code.quantity') %></dt>
@@ -47,5 +48,6 @@
47
48
  <%= t(:code_activation_count, count: @entity.quantity) %>
48
49
  </dd>
49
50
  </dl>
51
+
50
52
  <%= render partial: 'shared/track', locals: { item: @entity } %>
51
53
  </article>
@@ -1,5 +1,5 @@
1
1
  <nav class="biovision-component-nav">
2
- <% if handler.allow?(action: 'settings') %>
2
+ <% if handler.allow?('settings') %>
3
3
  <% if handler.use_parameters? || handler.component.settings.any? %>
4
4
  <%=
5
5
  link_to(
@@ -11,10 +11,25 @@
11
11
  <% end %>
12
12
  <% end %>
13
13
 
14
+ <% if handler.administrator? %>
15
+ <%=
16
+ link_to(
17
+ t('admin.components.privileges.nav_text'),
18
+ admin_component_privileges_path(slug: handler.slug),
19
+ class: 'privileges'
20
+ )
21
+ %>
22
+ <% end %>
23
+
14
24
  <% prefix = 'admin/components/links/' %>
15
25
  <% if lookup_context.exists?("#{prefix}_#{handler.slug}") %>
16
26
  <ul class="biovision-component-links">
17
- <%= render "#{prefix}#{handler.slug}" %>
27
+ <%=
28
+ render(
29
+ partial: "#{prefix}#{handler.slug}",
30
+ locals: { handler: handler }
31
+ )
32
+ %>
18
33
  </ul>
19
34
  <% end %>
20
35
  </nav>
@@ -1 +1,3 @@
1
- <li><%= render 'admin/feedback_requests/nav_item' %></li>
1
+ <% if handler.allow?('feedback_manager') %>
2
+ <li><%= render 'admin/feedback_requests/nav_item' %></li>
3
+ <% end %>
@@ -1,2 +1,4 @@
1
- <li><%= render 'admin/editable_pages/nav_item' %></li>
2
- <li><%= render 'admin/simple_blocks/nav_item' %></li>
1
+ <% if handler.allow?('content_manager') %>
2
+ <li><%= render 'admin/editable_pages/nav_item' %></li>
3
+ <li><%= render 'admin/simple_blocks/nav_item' %></li>
4
+ <% end %>
@@ -1,7 +1,11 @@
1
- <li><%= render 'admin/users/nav_item' %></li>
2
- <li><%= render 'admin/foreign_users/nav_item' %></li>
3
- <li><%= render 'admin/privileges/nav_item' %></li>
4
- <li><%= render 'admin/privilege_groups/nav_item' %></li>
5
- <li><%= render 'admin/login_attempts/nav_item' %></li>
6
- <li><%= render 'admin/tokens/nav_item' %></li>
7
- <li><%= render 'admin/codes/nav_item' %></li>
1
+ <% if handler.allow?('view', 'edit') %>
2
+ <li><%= render 'admin/users/nav_item' %></li>
3
+ <li><%= render 'admin/foreign_users/nav_item' %></li>
4
+ <% end %>
5
+ <% if handler.administrator? %>
6
+ <li><%= render 'admin/login_attempts/nav_item' %></li>
7
+ <li><%= render 'admin/tokens/nav_item' %></li>
8
+ <% end %>
9
+ <% if handler.allow?('manage_codes') %>
10
+ <li><%= render 'admin/codes/nav_item' %></li>
11
+ <% end %>
@@ -0,0 +1,34 @@
1
+ <% content_for :meta_title, t('.title', slug: @handler.slug) %>
2
+ <% content_for :breadcrumbs do %>
3
+ <%= link_to(t('admin.components.index.nav_text'), admin_components_path) %>
4
+ <%= admin_biovision_component_link(@handler.component, @handler.name) %>
5
+ <span><%= t('.nav_text') %></span>
6
+ <% end %>
7
+
8
+ <article>
9
+ <h1><%= @handler.name %></h1>
10
+
11
+ <ul class="actions">
12
+ <li><%= back_icon(admin_components_path) %></li>
13
+ <li><%= return_icon(admin_component_path(slug: @handler.slug)) %></li>
14
+ </ul>
15
+
16
+ <%=
17
+ render(
18
+ partial: 'admin/components/privileges/users',
19
+ locals: {
20
+ collection: @handler.component.privileges,
21
+ handler: @handler
22
+ }
23
+ )
24
+ %>
25
+
26
+ <%=
27
+ render(
28
+ partial: 'admin/components/privileges/new_user',
29
+ locals: {
30
+ handler: @handler
31
+ }
32
+ )
33
+ %>
34
+ </article>
@@ -0,0 +1,67 @@
1
+ <div class="image">
2
+ <%= profile_avatar(entity.user) %>
3
+ </div>
4
+ <div class="data">
5
+ <div><%= admin_user_link(entity.user) %></div>
6
+ <div>
7
+ <ul class="entity-links">
8
+ <li>
9
+ <% element_id = "component_administrator_#{entity.user_id}" %>
10
+ <%=
11
+ check_box_tag(
12
+ 'user_id',
13
+ entity.user_id,
14
+ entity.administrator?,
15
+ data: {
16
+ url: admin_component_administrators_path(slug: handler.slug, user_id: entity.user_id)
17
+ },
18
+ id: element_id
19
+ )
20
+ %>
21
+ <%= label_tag(element_id, t('activerecord.attributes.biovision_component_user.administrator')) %>
22
+ </li>
23
+ <% if handler.use_parameters? || handler.component.settings.any? %>
24
+ <li>
25
+ <% element_id = "component_privilege_settings" %>
26
+ <%=
27
+ check_box_tag(
28
+ 'user_id',
29
+ entity.user_id,
30
+ entity.data['settings'],
31
+ data: {
32
+ url: admin_component_privilege_path(
33
+ slug: handler.slug,
34
+ user_id: entity.user_id,
35
+ privilege_slug: 'settings'
36
+ )
37
+ },
38
+ id: element_id
39
+ )
40
+ %>
41
+ <%= label_tag(element_id, t('activerecord.attributes.biovision_component_user.privileges.settings')) %>
42
+ </li>
43
+ <% end %>
44
+ <% handler.class.privilege_names.each do |privilege_slug| %>
45
+ <li>
46
+ <% element_id = "component_privilege_#{privilege_slug}" %>
47
+ <%=
48
+ check_box_tag(
49
+ 'user_id',
50
+ entity.user_id,
51
+ entity.data[privilege_slug],
52
+ data: {
53
+ url: admin_component_privilege_path(
54
+ slug: handler.slug,
55
+ user_id: entity.user_id,
56
+ privilege_slug: privilege_slug
57
+ )
58
+ },
59
+ id: element_id
60
+ )
61
+ %>
62
+ <%= label_tag(element_id, t("biovision.components.#{handler.slug}.privileges.#{privilege_slug}", default: privilege_slug)) %>
63
+ </li>
64
+ <% end %>
65
+ </ul>
66
+ </div>
67
+ </div>
@@ -0,0 +1,15 @@
1
+ <section>
2
+ <h2><%= t('.heading') %></h2>
3
+
4
+ <div class="js-admin-user-search" data-url="<%= search_admin_users_path %>" data-callback="Biovision.components.userPrivilege.addUser">
5
+ <%= search_field_tag('user_search', '', id: nil, size: 24) %>
6
+ <%= button_tag t(:find), disabled: true, type: :button %>
7
+ <select class="results"></select>
8
+ </div>
9
+
10
+ <ul
11
+ class="js-component-added-users"
12
+ data-url="<%= admin_component_privileges_path(slug: handler.slug) %>"
13
+ aria-label="<%= t('.added_users') %>"
14
+ ></ul>
15
+ </section>