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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d5f8617a8dff7ad9626d48a7f1e22cc8f08c2593b217c6c27841ab5aa921d6c
4
- data.tar.gz: 01c40c0839b5f499a4230ff5c66ca3b0eda1e5366004f9191d019788eb33262a
3
+ metadata.gz: d07b344a9bc96d622dd67d169153fe9ee451c41cac3c035cac596c097aa88437
4
+ data.tar.gz: 0b7da0cff70e2f6d32c04c7e4367f8a4620e1fde75185b47ff4640c39ef2112f
5
5
  SHA512:
6
- metadata.gz: bf4038b7bddff5695f12bbe5a98f146a3f2ac6ebbabfa34c35a4f1b3cd66d2b575a04c2b47806638cd6d85110ce0d38f90fecb4ea3bfaa46cc94244edf25b7a1
7
- data.tar.gz: 5f506ea490fb45a7e3eb072d9494e66360370b037cdd8605f570108def672749ff4f462946b0e9f9363b889d103edd22ff76e9d207cb75c445a2dbb7ea40d861
6
+ metadata.gz: 93d2908f0237a274f9631f620efb6b63594fdc1ecfb7bff47467991bdf4830138a25bf6b39577b1e81d061e25d26b08f12b314604ed97999c303df66fc504bf3
7
+ data.tar.gz: 2e8f2feb382ef4653ccb8f7c4a2bfefd032a4c5244b782e156f88a420f4248a724c229db30825a972b0a5d6f473722bdabe7e50fe0bd575937f70a192086e717
@@ -0,0 +1,16 @@
1
+ <svg version="1.1" viewBox="0 0 24 24" width="24px" height="24px" xmlns="http://www.w3.org/2000/svg">
2
+ <title>Key</title>
3
+ <defs>
4
+ <style type="text/css">
5
+ * { stroke: #ada33d; stroke-width: 1.5; }
6
+ line { stroke-linecap: round; }
7
+ </style>
8
+ </defs>
9
+ <g>
10
+ <circle cx="4" cy="20" r="3" fill="none"/>
11
+ <line x1="6" y1="18" x2="20" y2="4"/>
12
+ <line x1="19" y1="5" x2="21" y2="7"/>
13
+ <line x1="17" y1="7" x2="20" y2="10"/>
14
+ <line x1="14" y1="8" x2="16" y2="10"/>
15
+ </g>
16
+ </svg>
@@ -189,6 +189,16 @@ const Biovision = {
189
189
  } else {
190
190
  console.log('Cannot find element with id ' + formId)
191
191
  }
192
+ },
193
+ execute: function (name, context) {
194
+ const args = Array.prototype.slice.call(arguments, 2);
195
+ const namespaces = name.split(".");
196
+ const func = namespaces.pop();
197
+ for(let i = 0; i < namespaces.length; i++) {
198
+ context = context[namespaces[i]];
199
+ }
200
+
201
+ return context[func].apply(context, args);
192
202
  }
193
203
  };
194
204
 
@@ -757,8 +767,8 @@ Biovision.components.userSearch = {
757
767
  const response = JSON.parse(this.responseText);
758
768
  const results = container.querySelector('.results');
759
769
 
760
- if (response.hasOwnProperty('data')) {
761
- results.innerHTML = response['data']['html'];
770
+ if (response.hasOwnProperty('meta')) {
771
+ results.innerHTML = response['meta']['html'];
762
772
 
763
773
  results.querySelectorAll('li').forEach(function (li) {
764
774
  li.addEventListener('click', function (event) {
@@ -775,6 +785,125 @@ Biovision.components.userSearch = {
775
785
  }
776
786
  };
777
787
 
788
+ Biovision.components.adminUserSearch = {
789
+ initialized: false,
790
+ selector: ".js-admin-user-search",
791
+ url: undefined,
792
+ button: undefined,
793
+ input: undefined,
794
+ resultsContainer: undefined,
795
+ callbackName: undefined,
796
+ init: function () {
797
+ const container = document.querySelector(this.selector);
798
+ if (container) {
799
+ const component = this;
800
+ this.url = container.getAttribute("data-url");
801
+ this.button = container.querySelector("button");
802
+ this.input = container.querySelector("input");
803
+ this.resultsContainer = container.querySelector("select");
804
+ this.callbackName = container.getAttribute("data-callback");
805
+
806
+ this.input.addEventListener("input", component.changeInput);
807
+ this.button.addEventListener("click", component.clickButton);
808
+ this.resultsContainer.addEventListener("change", component.changeSelect);
809
+ this.initialized = true;
810
+ }
811
+ },
812
+ changeInput: function (event) {
813
+ const component = Biovision.components.adminUserSearch;
814
+ const input = event.target;
815
+ component.button.disabled = input.value.length < 1;
816
+ },
817
+ clickButton: function (event) {
818
+ const component = Biovision.components.adminUserSearch;
819
+ const url = component.url + "?q=" + encodeURIComponent(component.input.value);
820
+ Biovision.jsonAjaxRequest("get", url, component.showResults).send();
821
+ },
822
+ changeSelect: function (event) {
823
+ const component = Biovision.components.adminUserSearch;
824
+ const select = event.target;
825
+ const option = select.options[select.selectedIndex];
826
+ const id = parseInt(option.value);
827
+
828
+ if (id > 0 && component.callbackName) {
829
+ Biovision.execute(component.callbackName, window, id);
830
+ option.disabled = true;
831
+ }
832
+ },
833
+ showResults: function () {
834
+ const component = Biovision.components.adminUserSearch;
835
+ const response = JSON.parse(this.responseText);
836
+ component.resultsContainer.innerHTML = "";
837
+
838
+ const option = document.createElement("option");
839
+ option.innerHTML = response["meta"]["count"];
840
+ option.value = "";
841
+ component.resultsContainer.append(option);
842
+
843
+ if (response.hasOwnProperty("data")) {
844
+ response.data.forEach(function (item) {
845
+ const option = document.createElement("option");
846
+ option.setAttribute("value", item.id);
847
+ option.innerHTML = item["attributes"]["slug"] + " (" + item["meta"]["name"] + ")";
848
+
849
+ component.resultsContainer.append(option);
850
+ });
851
+ }
852
+ }
853
+ };
854
+
855
+ Biovision.components.userPrivilege = {
856
+ initialized: false,
857
+ selector: ".js-component-added-users",
858
+ list: undefined,
859
+ url: undefined,
860
+ init: function () {
861
+ this.list = document.querySelector(this.selector);
862
+ if (this.list) {
863
+ this.url = this.list.getAttribute("data-url");
864
+ this.initialized = true;
865
+ }
866
+ },
867
+ addUser: function (id) {
868
+ const component = Biovision.components.userPrivilege;
869
+ if (component.url) {
870
+ const data = {
871
+ "user_id": id
872
+ };
873
+ const request = Biovision.jsonAjaxRequest("patch", component.url, component.processAddResponse);
874
+
875
+ request.send(JSON.stringify(data));
876
+ } else {
877
+ console.log("URL is not set for userPrivilege component")
878
+ }
879
+ },
880
+ processAddResponse: function () {
881
+ const component = Biovision.components.userPrivilege;
882
+ if (component.list) {
883
+ const response = JSON.parse(this.responseText);
884
+ if (response.hasOwnProperty("data")) {
885
+ const data = response["data"];
886
+ const li = document.createElement("li");
887
+ const user = data["relationships"]["user"]["data"];
888
+ const div = document.createElement("div");
889
+ div.innerHTML = user["attributes"]["screen_name"] + " (" + user["meta"]["full_name"] + ")";
890
+ li.append(div);
891
+
892
+ const linkData = data["attributes"]["data"];
893
+ if (Object.keys(linkData).length > 0) {
894
+ const details = document.createElement("div");
895
+ details.innerHTML = JSON.stringify(linkData);
896
+ li.append(details);
897
+ }
898
+
899
+ component.list.append(li);
900
+ }
901
+ } else {
902
+ console.log("List is not defined for userPrivilege component");
903
+ }
904
+ }
905
+ };
906
+
778
907
  /**
779
908
  * Hide popups when clicking outside
780
909
  *
@@ -949,6 +1078,8 @@ Biovision.components.newComponentParameter = {
949
1078
  }
950
1079
  };
951
1080
 
1081
+ window.Biovision = Biovision;
1082
+
952
1083
  document.addEventListener('DOMContentLoaded', function () {
953
1084
  Biovision.init();
954
1085
 
@@ -2,6 +2,7 @@ $text-color-secondary: #777 !default;
2
2
  $block-shadow: .2rem .2rem .4rem .2rem rgba(0, 0, 0, .125) !default;
3
3
  $row-background-even: hsl(0, 0%, 95%) !default;
4
4
  $row-background-odd: hsl(0, 0%, 98%) !default;
5
+ $font-family-heading: serif !default;
5
6
 
6
7
  #biovision-component-parameters {
7
8
  margin: var(--spacer-s) 0;
@@ -105,7 +106,14 @@ $row-background-odd: hsl(0, 0%, 98%) !default;
105
106
 
106
107
  .settings {
107
108
  background: image_url('biovision/base/icons/settings.svg') no-repeat center left / 2rem 2rem;
108
- display: inline-block;
109
+ display: block;
110
+ margin: 0 0 var(--spacer-xs);
111
+ padding-left: 2.4rem;
112
+ }
113
+
114
+ .privileges {
115
+ background: image_url('biovision/base/icons/key.svg') no-repeat center left / 2rem 2rem;
116
+ display: block;
109
117
  margin: 0 0 var(--spacer-xs);
110
118
  padding-left: 2.4rem;
111
119
  }
@@ -129,3 +137,34 @@ $row-background-odd: hsl(0, 0%, 98%) !default;
129
137
  }
130
138
  }
131
139
  }
140
+
141
+ .js-admin-user-search {
142
+ select {
143
+ &:empty {
144
+ display: none;
145
+ }
146
+ }
147
+ }
148
+
149
+ .js-component-added-users {
150
+ list-style: none;
151
+ margin: var(--spacer-s) 0;
152
+ padding: 0;
153
+
154
+ &::before {
155
+ content: attr(aria-label);
156
+ display: block;
157
+ font: 400 var(--font-size-increased) $font-family-heading;
158
+ transition: .25s;
159
+ }
160
+
161
+ &:empty::before {
162
+ opacity: 0;
163
+ }
164
+
165
+ li {
166
+ box-shadow: 0 0 .4rem rgba(0, 0, 0, .25);
167
+ margin: var(--spacer-xs) 0;
168
+ padding: var(--spacer-xs);
169
+ }
170
+ }
@@ -27,7 +27,6 @@
27
27
 
28
28
  html {
29
29
  font: 400 10px $font-family-main;
30
- height: 100%;
31
30
  margin: 0;
32
31
  padding: 0;
33
32
  -webkit-text-size-adjust: none;
@@ -555,4 +554,4 @@ input.control:not(:checked) + * {
555
554
  object-fit: contain;
556
555
  width: 100%;
557
556
  }
558
- }
557
+ }
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Handling user codes
1
4
  class Admin::CodesController < AdminController
2
5
  before_action :set_entity, except: [:index]
3
6
 
@@ -12,8 +15,13 @@ class Admin::CodesController < AdminController
12
15
 
13
16
  protected
14
17
 
18
+ def component_slug
19
+ Biovision::Components::UsersComponent::SLUG
20
+ end
21
+
15
22
  def restrict_access
16
- require_privilege :administrator
23
+ error = 'Managing codes is not allowed'
24
+ handle_http_401(error) unless component_handler.allow?('manage_codes')
17
25
  end
18
26
 
19
27
  def set_entity
@@ -11,35 +11,105 @@ class Admin::ComponentsController < AdminController
11
11
 
12
12
  # get /admin/components/:slug
13
13
  def show
14
- handle_http_401('Viewing component is not allowed') unless @handler.allow?
14
+ error = 'Viewing component is not allowed'
15
+ handle_http_401(error) unless @handler.allow?
15
16
  end
16
17
 
17
18
  # get /admin/components/:slug/settings
18
19
  def settings
20
+ error = 'Viewing settings is not allowed'
21
+ handle_http_401(error) unless @handler.allow?('settings')
19
22
  end
20
23
 
21
24
  # patch /admin/components/:slug/settings
22
25
  def update_settings
23
- new_settings = params.dig(:component, :settings).permit!
24
- @handler.settings = new_settings.to_h
25
- flash[:notice] = t('admin.components.update_settings.success')
26
- redirect_to(admin_component_settings_path(slug: params[:slug]))
26
+ if @handler.allow('settings')
27
+ new_settings = params.dig(:component, :settings).permit!
28
+ @handler.settings = new_settings.to_h
29
+ flash[:notice] = t('admin.components.update_settings.success')
30
+ redirect_to(admin_component_settings_path(slug: params[:slug]))
31
+ else
32
+ handle_http_401('Changing settings is not allowed')
33
+ end
27
34
  end
28
35
 
29
36
  # patch /admin/components/:slug/parameters
30
37
  def update_parameter
31
- slug = param_from_request(:key, :slug).downcase
32
- value = param_from_request(:key, :value)
38
+ if @handler.allow('settings')
39
+ slug = param_from_request(:key, :slug).downcase
40
+ value = param_from_request(:key, :value)
33
41
 
34
- @handler[slug] = value
42
+ @handler[slug] = value
43
+ end
35
44
 
36
45
  head :no_content
37
46
  end
38
47
 
39
48
  # delete /admin/components/:slug/parameters/:parameter_slug
40
49
  def delete_parameter
41
- @handler.component.parameters.delete(params[:parameter_slug])
42
- @handler.component.save
50
+ if @handler.allow('settings')
51
+ @handler.component.parameters.delete(params[:parameter_slug])
52
+ @handler.component.save
53
+ end
54
+
55
+ head :no_content
56
+ end
57
+
58
+ # get /admin/components/:slug/privileges
59
+ def privileges
60
+ error = 'Viewing privileges is not allowed'
61
+ handle_http_401(error) unless @handler.administrator?
62
+ end
63
+
64
+ # patch /admin/components/:slug/privileges
65
+ def update_privileges
66
+ if @handler.administrator?
67
+ user = User.find_by(id: params[:user_id])
68
+
69
+ if user.nil?
70
+ handle_http_404('Cannot find user') if user.nil?
71
+ else
72
+ @entity = @handler.update_privileges(user)
73
+ end
74
+ else
75
+ handle_http_401('Updating privileges is not allowed')
76
+ end
77
+ end
78
+
79
+ # put /admin/components/:slug/administrators/:user_id
80
+ def add_administrator
81
+ if @handler.administrator?
82
+ @handler.component.add_administrator(User.find_by(id: params[:user_id]))
83
+ end
84
+
85
+ head :no_content
86
+ end
87
+
88
+ # put /admin/components/:slug/administrators/:user_id
89
+ def remove_administrator
90
+ if @handler.administrator?
91
+ @handler.component.remove_administrator(User.find_by(id: params[:user_id]))
92
+ end
93
+
94
+ head :no_content
95
+ end
96
+
97
+ # put /admin/components/:slug/users/:user_id/privileges/:privilege_slug
98
+ def add_privilege
99
+ if @handler.administrator?
100
+ user = User.find_by(id: params[:user_id])
101
+ @handler.component.add_privilege(user, params[:privilege_slug])
102
+ end
103
+
104
+ head :no_content
105
+ end
106
+
107
+ # put /admin/components/:slug/users/:user_id/privileges/:privilege_slug
108
+ def remove_privilege
109
+ if @handler.administrator?
110
+ user = User.find_by(id: params[:user_id])
111
+ @handler.component.remove_privilege(user, params[:privilege_slug])
112
+ end
43
113
 
44
114
  head :no_content
45
115
  end
@@ -18,8 +18,13 @@ class Admin::EditablePagesController < AdminController
18
18
 
19
19
  private
20
20
 
21
+ def component_slug
22
+ Biovision::Components::ContentComponent::SLUG
23
+ end
24
+
21
25
  def restrict_access
22
- require_privilege :content_manager
26
+ error = 'Managing content is not allowed'
27
+ handle_http_401(error) unless component_handler.allow?('content_manager')
23
28
  end
24
29
 
25
30
  def set_entity
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Handling feedback requests
1
4
  class Admin::FeedbackRequestsController < AdminController
2
5
  include ToggleableEntity
3
6
 
4
- before_action :set_entity, except: [:index]
7
+ before_action :set_entity, except: :index
5
8
 
6
9
  # get /admin/feedback_requests
7
10
  def index
@@ -10,8 +13,13 @@ class Admin::FeedbackRequestsController < AdminController
10
13
 
11
14
  private
12
15
 
16
+ def component_slug
17
+ Biovision::Components::ContactComponent::SLUG
18
+ end
19
+
13
20
  def restrict_access
14
- require_privilege :feedback_manager
21
+ error = 'Managing feedback requests is not allowed'
22
+ handle_http_401(error) unless component_handler.allow?('feedback_manager')
15
23
  end
16
24
 
17
25
  def set_entity
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Handling foreign users
1
4
  class Admin::ForeignUsersController < AdminController
2
5
  before_action :set_entity, except: :index
3
6
 
@@ -12,14 +15,17 @@ class Admin::ForeignUsersController < AdminController
12
15
 
13
16
  protected
14
17
 
18
+ def component_slug
19
+ Biovision::Components::UsersComponent::SLUG
20
+ end
21
+
15
22
  def restrict_access
16
- require_privilege :administrator
23
+ error = 'Managing foreign users is not allowed'
24
+ handle_http_401(error) unless component_handler.allow?('view', 'edit')
17
25
  end
18
26
 
19
27
  def set_entity
20
28
  @entity = ForeignUser.find_by(id: params[:id])
21
- if @entity.nil?
22
- handle_http_404('Cannot find foreign_user')
23
- end
29
+ handle_http_404('Cannot find foreign_user') if @entity.nil?
24
30
  end
25
31
  end