biovision-comment 0.1.170914 → 0.7.190905.0

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 (35) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +68 -14
  3. data/app/assets/javascripts/biovision/comment/biovision-comments.js +118 -0
  4. data/app/assets/stylesheets/biovision/comment/comments.scss +111 -38
  5. data/app/controllers/admin/comments_controller.rb +18 -5
  6. data/app/controllers/comments_controller.rb +45 -32
  7. data/app/helpers/comments_helper.rb +20 -0
  8. data/app/models/comment.rb +88 -19
  9. data/app/models/concerns/commentable_item.rb +15 -0
  10. data/app/services/biovision/components/comments_component.rb +39 -0
  11. data/app/services/comment_handler.rb +49 -0
  12. data/app/services/comments_manager.rb +24 -0
  13. data/app/views/admin/comments/entity/_in_list.html.erb +8 -5
  14. data/app/views/admin/comments/index.html.erb +2 -1
  15. data/app/views/admin/comments/show.html.erb +25 -10
  16. data/app/views/admin/components/links/_comments.html.erb +3 -0
  17. data/app/views/comment_mailer/entry_reply.text.erb +2 -6
  18. data/app/views/comments/_comment.html.erb +66 -16
  19. data/app/views/comments/_form.html.erb +92 -19
  20. data/app/views/comments/_list.html.erb +17 -19
  21. data/app/views/comments/_reply_container.html.erb +15 -0
  22. data/app/views/comments/_section.html.erb +34 -0
  23. data/app/views/comments/edit.html.erb +6 -5
  24. data/app/views/comments/new.html.erb +2 -2
  25. data/config/locales/comments-ru.yml +32 -2
  26. data/config/routes.rb +18 -10
  27. data/db/migrate/20170914000001_create_comments.rb +48 -23
  28. data/db/migrate/20190203090909_add_fields_to_comments.rb +14 -0
  29. data/db/migrate/20190428212121_add_approved_to_comments.rb +14 -0
  30. data/db/migrate/20190428212122_create_comments_component.rb +21 -0
  31. data/db/migrate/20190628101010_add_data_to_comments.rb +15 -0
  32. data/lib/biovision/comment/engine.rb +7 -2
  33. data/lib/biovision/comment/version.rb +3 -1
  34. metadata +19 -8
  35. data/app/views/comments/show.html.erb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f90194297e55ad450ea7bbf54b5793c70d1f8a59
4
- data.tar.gz: 7ff6561739d214e95fc48ba9fc9ce7740e798e89
2
+ SHA256:
3
+ metadata.gz: a602c3288d543c9a10860099700cb6657f206b3b6dce1b88a82c5ad1c239b5c8
4
+ data.tar.gz: 552231814a6ad6ed6b43c1edbc12b195192090e2ef821d73b962c1c6cd1850b4
5
5
  SHA512:
6
- metadata.gz: 64bb4f5aa97526081b06a577c0ee26ba5a43a00637acd3af6b796422055124fe3e21210e66c2c418e1846bb6fa6bdaefa89edf3d916645c497efa42e964ff17c
7
- data.tar.gz: 10fb7f85ddc4d8eb23d6628a1845d6bc4190d220b1cb3655d3169dfb6fddc88799bd7c5b781920f504a6b6a22543a90dbd9c20159fd1ca1692693298f9755624
6
+ metadata.gz: ba351318a8b74404e890374ae9c9a1cfab90924d25c10dc0374660fba6b014005e7ce4105ca3f6ce4805939935cbd52fd4517d4cda960057e1e2c23bbbc6badb
7
+ data.tar.gz: 5272919b6715ef8641f458257d9d35f2638b5c4cb6b593163c1fe44e0e3c5d8da2a265477a205bc338b7bd5625282d9330b7db042de7e1b3556fd04a14ea3a1e
data/README.md CHANGED
@@ -1,28 +1,82 @@
1
1
  # Biovision::Comment
2
- Short description and motivation.
3
2
 
4
- ## Usage
5
- How to use my plugin.
3
+ Компонент с комментариями для проектов на базе `Biovision`.
6
4
 
7
- ## Installation
8
- Add this line to your application's Gemfile:
5
+ Находится в стадии разработки. Используйте на свой страх и риск.
6
+
7
+ ## Использование
8
+
9
+ ### Подготовка моделей
10
+
11
+ Для моделей, которым нужны комментарии, следует в классе добавить это:
9
12
 
10
13
  ```ruby
11
- gem 'biovision-comment'
14
+ has_many :comments, as: :commentable
12
15
  ```
13
16
 
14
- And then execute:
17
+ Тамже всем моделям с комментариями нужно поле `comments_count` для счётчика
18
+ комментарием:
19
+
15
20
  ```bash
16
- $ bundle
21
+ rails g migration add_comments_count_to_sample comments_count:integer
22
+ ```
23
+
24
+ ```ruby
25
+ # frozen_string_literal: true
26
+
27
+ # Add counter for comments to Sample model
28
+ class AddCommentsCountToSample < ActiveRecord::Migration[5.2]
29
+ def change
30
+ add_column :samples, :comments_count, :integer, default: 0, null: false
31
+ end
32
+ end
33
+ ```
34
+
35
+ ### В представлениях
36
+
37
+ Для вывода комментариев используется код такого вида:
38
+
39
+ ```erb
40
+ <%= render(partial: 'comments/section', locals: { entity: entity }) %>
41
+ ```
42
+
43
+ Здесь `entity` — это объект модели с комментариями.
44
+
45
+ ### Стили и сценарии
46
+
47
+ Для работы переноса формы ответа нужно включить в сценарии JS код компонента
48
+ в `application.js` после добавления `biovision/base/biovision`:
49
+
50
+ ```
51
+ //= require biovision/comment/biovision-comments
17
52
  ```
18
53
 
19
- Or install it yourself as:
54
+ Стили по умолчанию описаны в `biovision/comment/comments.scss`.
55
+
56
+ ## Установка
57
+
58
+ Нужно добавить компонент в `Gemfile`:
59
+
60
+ ```ruby
61
+ gem 'biovision-comment', git: 'https://github.com/Biovision/biovision-comment'
62
+ # gem 'biovision-comment', path: '/Users/maxim/Projects/Biovision/gems/biovision-comment'
63
+ ```
64
+
65
+ После этого:
66
+
20
67
  ```bash
21
- $ gem install biovision-comment
68
+ $ bundle
69
+ $ rails railties:install:migrations
70
+ $ rails db:migrate
22
71
  ```
23
72
 
24
- ## Contributing
25
- Contribution directions go here.
73
+ ## Вклад в разработку
74
+
75
+ Особых инструкций нет. Fork/update/PR, как обычно. Или просто опишите свои идеи
76
+ в разделе `issues`.
77
+
78
+ ## Лицензия
79
+
80
+ [MIT License](http://opensource.org/licenses/MIT).
26
81
 
27
- ## License
28
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
82
+ Продукт предоставляется «как есть». Используйте на свой страх и риск.
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Biovision Comments component
5
+ *
6
+ * @type {Object}
7
+ */
8
+ const Comments = {
9
+ initialized: false,
10
+ autoInitComponents: true,
11
+ components: {}
12
+ };
13
+
14
+ /**
15
+ * Move new comment form to different parent comment
16
+ *
17
+ * Handles click on "Reply" button and moves form under parent comment.
18
+ * Click on "Cancel" button moves form back to top-level reply.
19
+ *
20
+ * @type {Object}
21
+ */
22
+ Comments.components.replyFormMover = {
23
+ initialized: false,
24
+ /**
25
+ * Container for list of comments
26
+ *
27
+ * @type {HTMLElement}
28
+ */
29
+ listContainer: undefined,
30
+ /**
31
+ * Container for reply form
32
+ *
33
+ * @type {HTMLElement}
34
+ */
35
+ mainContainer: undefined,
36
+ form: undefined,
37
+ /**
38
+ * @type {HTMLElement}
39
+ */
40
+ parentId: undefined,
41
+ replyButtons: [],
42
+ cancelButtons: [],
43
+ replySelector: ".comment-reply-button button",
44
+ cancelSelector: ".container button.cancel",
45
+ /**
46
+ * Initialize
47
+ */
48
+ init: function () {
49
+ this.listContainer = document.getElementById("comments");
50
+ this.form = document.getElementById("comment-form");
51
+
52
+ if (this.listContainer && this.form) {
53
+ this.parentId = document.getElementById("comment_parent_id");
54
+ this.mainContainer = this.listContainer.querySelector(".reply-container .container");
55
+ this.listContainer.querySelectorAll(this.replySelector).forEach(this.applyToReplyButton);
56
+ this.listContainer.querySelectorAll(this.cancelSelector).forEach(this.applyToCancelButton);
57
+
58
+ this.initialized = true;
59
+ }
60
+ },
61
+ /**
62
+ * Apply handler for pressing "Reply" button
63
+ *
64
+ * @param {HTMLElement} button
65
+ * @type {Function}
66
+ */
67
+ applyToReplyButton: function (button) {
68
+ const component = Comments.components.replyFormMover;
69
+
70
+ component.replyButtons.push(button);
71
+ button.addEventListener("click", component.move);
72
+ },
73
+ /**
74
+ * Apply handler for pressing "Cancel" button
75
+ *
76
+ * @param {HTMLElement} button
77
+ * @type {Function}
78
+ */
79
+ applyToCancelButton: function (button) {
80
+ const component = Comments.components.replyFormMover;
81
+
82
+ component.cancelButtons.push(button);
83
+ button.addEventListener("click", component.cancel);
84
+ },
85
+ /**
86
+ * Move reply form to parent comment
87
+ *
88
+ * @param {Event} event
89
+ * @type {Function}
90
+ */
91
+ move: function (event) {
92
+ const component = Comments.components.replyFormMover;
93
+ const button = event.target;
94
+ const container = button.closest(".comment-reply-block").querySelector(".container");
95
+
96
+ if (container) {
97
+ component.parentId.value = button.closest(".comment-item").getAttribute("data-id");
98
+ container.appendChild(component.form);
99
+ container.classList.remove("hidden");
100
+ }
101
+ },
102
+ /**
103
+ * Handler for pressing "Cancel" button
104
+ *
105
+ * @param {Event} event
106
+ * @type {Function}
107
+ */
108
+ cancel: function (event) {
109
+ const component = Comments.components.replyFormMover;
110
+ const button = event.target;
111
+ button.parentNode.classList.add("hidden");
112
+
113
+ component.parentId.value = "";
114
+ component.mainContainer.appendChild(component.form);
115
+ }
116
+ };
117
+
118
+ Biovision.components.comments = Comments;
@@ -1,35 +1,37 @@
1
- $border-primary: .1rem solid rgb(127, 127, 127) !default;
2
- $font-size-decreased: 1.2rem !default;
3
- $font-size-small: 1rem !default;
1
+ $border-secondary: .1rem solid #aaa !default;
2
+ $text-color-secondary: #777 !default;
4
3
  $row-background-even: #f0f0f0 !default;
5
4
  $row-background-odd: #fafafa !default;
6
5
 
7
- section.comments {
8
- margin: 1.6rem 0;
9
- padding: 0 0.8rem;
10
- border-top: $border-primary;
11
-
12
- > h2 {
13
- margin: 0.8rem 0;
6
+ .comments {
7
+ h3::first-letter {
8
+ text-transform: uppercase;
14
9
  }
10
+ }
15
11
 
16
- > div {
17
- background-color: $row-background-odd;
18
- padding: 0.4rem;
19
-
20
- &:nth-of-type(even) {
21
- background-color: $row-background-even;
22
- }
23
- }
12
+ .comments-list {
13
+ border-bottom: $border-secondary;
14
+ margin: var(--spacer-s, 1.6rem) 0;
15
+ padding: 0 0 var(--spacer-s, 1.6rem);
24
16
  }
25
17
 
26
- div.comment {
18
+ .comment-item {
27
19
  position: relative;
20
+ background-color: $row-background-odd;
21
+ padding: var(--spacer-xxs, .4rem);
22
+
23
+ &:first-of-type {
24
+ margin-top: var(--spacer-s, 1.6rem);
25
+ }
26
+
27
+ &:nth-of-type(even) {
28
+ background-color: $row-background-even;
29
+ }
28
30
 
29
31
  .deleted {
30
- font-size: $font-size-decreased;
32
+ font-size: var(--font-size-decreased, 1.4rem);
31
33
  font-style: italic;
32
- padding: 0 .8rem;
34
+ padding: 0 var(--spacer-xs, .8rem);
33
35
 
34
36
  &::before {
35
37
  content: '[';
@@ -41,9 +43,9 @@ div.comment {
41
43
  }
42
44
 
43
45
  .title {
44
- padding: 0 0 0.4rem 0;
45
- border-bottom: dotted 0.1rem;
46
- margin: 0.8rem 0;
46
+ border-bottom: dotted .1rem;
47
+ margin: var(--spacer-xs, .8rem) 0;
48
+ padding: 0 0 var(--spacer-xxs, .4rem) 0;
47
49
 
48
50
  cite {
49
51
  &:before {
@@ -56,39 +58,84 @@ div.comment {
56
58
  }
57
59
  }
58
60
 
61
+ .meta {
62
+ display: flex;
63
+ flex-wrap: wrap;
64
+ }
65
+
66
+ .avatar {
67
+ height: 4.8rem;
68
+ margin: 0 var(--spacer-xs, .8rem) 0 0;
69
+ width: 4.8rem;
70
+ }
71
+
72
+ .info {
73
+ display: flex;
74
+ flex-direction: column;
75
+
76
+ time {
77
+ color: $text-color-secondary;
78
+ font-size: var(--font-size-decreased, 1.4rem);
79
+ margin-top: auto;
80
+ }
81
+ }
82
+
83
+ .comment-wrapper {
84
+ display: flex;
85
+ }
86
+
87
+ .vote-block {
88
+ align-items: center;
89
+ display: flex;
90
+ flex-direction: column;
91
+ flex: none;
92
+ justify-content: center;
93
+ width: 3.2rem;
94
+
95
+ .result {
96
+ color: $text-color-secondary;
97
+ font-size: var(--font-size-decreased, 1.4rem);
98
+ margin: var(--spacer-xxs, .4rem) 0;
99
+ }
100
+ }
101
+
102
+ .vote {
103
+ height: 1.6rem;
104
+ width: .8rem;
105
+ }
106
+
59
107
  .body {
60
108
  background: #ffffff;
61
- margin: 0.8rem;
62
- padding: 0.8rem;
109
+ flex: 1;
110
+ margin: var(--spacer-xs, .8rem);
111
+ padding: var(--spacer-xs, .8rem);
63
112
  position: relative;
64
113
  }
65
114
 
66
- .author {
67
- display: flex;
68
- justify-content: space-between;
69
- align-items: center;
70
- padding: 0 0.8rem;
115
+ p {
116
+ &:first-of-type {
117
+ margin-top: 0;
118
+ }
71
119
 
72
- time {
73
- font-size: $font-size-decreased;
74
- font-style: italic;
120
+ &:last-of-type {
121
+ margin-bottom: 0;
75
122
  }
76
123
  }
77
124
 
78
125
  .footer {
79
- padding: 0.8rem 1.6rem;
126
+ padding: var(--spacer-xs, .8rem) var(--spacer-s, 1.6rem);
80
127
 
81
128
  > ul {
82
129
  display: flex;
130
+ justify-content: flex-end;
83
131
  margin: 0;
84
132
  padding: 0;
85
- justify-content: flex-end;
86
133
 
87
134
  > li {
88
135
  list-style: none;
89
- margin: 0 0.4rem;
136
+ margin: 0 var(--spacer-xxs, .4rem);
90
137
  padding: 0;
91
- font-size: $font-size-small;
138
+ font-size: var(--font-size-small, 1.2rem);
92
139
  text-align: right;
93
140
 
94
141
  &:before {
@@ -102,3 +149,29 @@ div.comment {
102
149
  }
103
150
  }
104
151
  }
152
+
153
+ .comment-form {
154
+ .fields {
155
+ padding: var(--spacer-s, 1.6rem) 0;
156
+
157
+ label {
158
+ display: block;
159
+ }
160
+
161
+ textarea {
162
+ margin: 0;
163
+ padding: var(--spacer-xs, .8rem);
164
+ width: 100%;
165
+ }
166
+ }
167
+
168
+ .required {
169
+ label {
170
+ &::before {
171
+ color: rgb(255, 63, 0);
172
+ content: '*';
173
+ margin: 0 var(--spacer-xxs, .4rem) 0 0;
174
+ }
175
+ }
176
+ }
177
+ }
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Administrative handling comments
1
4
  class Admin::CommentsController < AdminController
2
5
  include ToggleableEntity
3
6
  include LockableEntity
4
7
 
5
- before_action :set_entity, except: [:index]
8
+ before_action :set_entity, except: :index
6
9
 
7
10
  # get /admin/comments
8
11
  def index
@@ -13,16 +16,26 @@ class Admin::CommentsController < AdminController
13
16
  def show
14
17
  end
15
18
 
19
+ # put /admin/comments/:id/approve
20
+ def approve
21
+ @entity.update(approved: true)
22
+
23
+ head :no_content
24
+ end
25
+
16
26
  protected
17
27
 
28
+ def component_slug
29
+ Biovision::Components::CommentsComponent::SLUG
30
+ end
31
+
18
32
  def restrict_access
19
- require_privilege :moderator
33
+ error = 'Managing comments is not allowed'
34
+ handle_http_401(error) unless component_handler.allow?('moderator')
20
35
  end
21
36
 
22
37
  def set_entity
23
38
  @entity = Comment.find_by(id: params[:id])
24
- if @entity.nil?
25
- handle_http_404('Cannot find comment')
26
- end
39
+ handle_http_404('Cannot find comment') if @entity.nil?
27
40
  end
28
41
  end