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
@@ -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.comments.nav_item.text') %></span>
3
+ <%= admin_biovision_component_link(component_handler.component) %>
4
+ <span><%= t('admin.comments.nav_item.text') %></span>
4
5
  <% end %>
5
6
 
6
7
  <article class="comments">
@@ -1,30 +1,44 @@
1
1
  <% content_for :meta_title, t('.title', id: @entity.id) %>
2
2
  <% content_for :breadcrumbs do %>
3
- <%= link_to(t('admin.comments.nav_item.text'), admin_comments_path) %>
4
- <span>
5
- <%= @entity.id %> (<%= @entity.commentable.model_name.human %>
6
- <cite><%= @entity.commentable.title %></cite>)
7
- </span>
3
+ <%= admin_biovision_component_link(component_handler.component) %>
4
+ <%= link_to(t('admin.comments.nav_item.text'), admin_comments_path) %>
5
+ <span>
6
+ <%= @entity.id %> (<%= @entity.commentable.model_name.human %>
7
+ <cite><%= @entity.commentable_title %></cite>)
8
+ </span>
8
9
  <% end %>
9
10
 
10
11
  <article>
11
- <h1><%= @entity.commentable.title %></h1>
12
+ <h1><%= @entity.commentable_title %></h1>
12
13
 
13
14
  <ul class="actions">
14
15
  <li><%= back_icon(admin_comments_path) %></li>
16
+ <% unless @entity.deleted? %>
17
+ <li><%= world_icon(CommentsManager.commentable_path(@entity, true)) %></li>
18
+ <% end %>
15
19
  <% unless @entity.locked? %>
16
- <li><%= edit_icon edit_comment_path(@entity.id) %></li>
20
+ <li><%= edit_icon edit_comment_path(id: @entity.id) %></li>
17
21
  <% end %>
18
22
  </ul>
19
23
 
20
24
  <% if @entity.deleted? %>
21
- <div class="message-box-alert"><%= t(:deleted_entity) %></div>
25
+ <div class="message-box-alert"><%= t(:deleted_entity) %></div>
22
26
  <% end %>
23
27
 
24
28
  <dl>
25
29
  <dt><%= t('activerecord.attributes.comment.user_id') %></dt>
26
30
  <dd><%= admin_user_link(@entity.user) %></dd>
27
31
 
32
+ <% unless @entity.author_name.blank? %>
33
+ <dt><%= t('activerecord.attributes.comment.author_name') %></dt>
34
+ <dd><%= @entity.author_name %></dd>
35
+ <% end %>
36
+
37
+ <% unless @entity.author_email.blank? %>
38
+ <dt><%= t('activerecord.attributes.comment.author_email') %></dt>
39
+ <dd><%= @entity.author_email %></dd>
40
+ <% end %>
41
+
28
42
  <dt><%= t('activerecord.attributes.comment.commentable') %></dt>
29
43
  <dd><%= comment_link(@entity) %></dd>
30
44
 
@@ -33,8 +47,9 @@
33
47
 
34
48
  <dt><%= t('activerecord.attributes.comment.body') %></dt>
35
49
  <dd>
36
- <%= prepare_comment_text(@entity) %>
50
+ <div class="text">
51
+ <%= simple_format(@entity.body) %>
52
+ </div>
37
53
  </dd>
38
54
  </dl>
39
-
40
55
  </article>
@@ -0,0 +1,3 @@
1
+ <% if handler.allow?('moderator') %>
2
+ <li><%= render 'admin/comments/nav_item' %></li>
3
+ <% end %>
@@ -1,11 +1,7 @@
1
1
  Здравствуйте, <%= @comment.commentable.user.name_for_letter %>.
2
2
 
3
- На вашу запись «<%= @comment.commentable.title %>» на сайте party-npk.ru
3
+ На вашу запись «<%= @comment.commentable.title %>»
4
4
  <%= url_for @comment.commentable %>
5
5
 
6
6
  Сам комментарий (<%= @comment.user.nil? ? 'анонимный' : @comment.user.profile_name %>):
7
- <%= simple_format @comment.body %>
8
-
9
- --
10
- С уважением.
11
- автоматический уведомитель
7
+ <%= @comment.body %>
@@ -1,25 +1,75 @@
1
- <div id="comment-<%= comment.id %>" itemscope itemtype="http://schema.org/Comment" class="comment">
2
- <% if comment.deleted? %>
3
- <div class="deleted"><%= t('.deleted') %></div>
1
+ <% element_id = "comment-#{comment.id}" %>
2
+ <div
3
+ id="<%= element_id %>"
4
+ itemscope
5
+ itemtype="http://schema.org/Comment"
6
+ class="comment-item"
7
+ data-id="<%= comment.id %>"
8
+ >
9
+ <% if comment.deleted? || comment.user&.deleted? %>
10
+ <div class="deleted"><%= t('.deleted') %></div>
4
11
  <% else %>
5
- <meta itemprop="url" content="<%= comment_url comment %>"/>
6
- <div class="author">
7
- <span itemprop="author" itemscope itemtype="http://schema.org/Person">
8
- <span itemprop="name"><%= user_link comment.user %></span>
9
- </span>
12
+ <meta itemprop="url" content="<%= url_for(anchor: element_id) %>"/>
13
+ <% if current_user_has_privilege?(:moderator) %>
14
+ <ul class="actions">
15
+ <li><%= edit_icon(edit_comment_path(id: comment.id)) %></li>
16
+ <li class="danger"><%= destroy_icon(comment) %></li>
17
+ </ul>
18
+ <% end %>
19
+
20
+ <div class="meta">
21
+ <div class="avatar covered">
22
+ <%= user_image_preview(comment.user) %>
23
+ </div>
24
+ <div class="info">
25
+ <div itemprop="author" itemscope itemtype="http://schema.org/Person">
26
+ <span itemprop="name">
27
+ <%= comment.user.nil? ? comment.author_name : user_link(comment.user) %>
28
+ </span>
29
+ </div>
10
30
  <%= time_tag comment.created_at %>
11
31
  </div>
32
+ </div>
33
+
34
+ <div class="comment-wrapper">
35
+ <% if Gem.loaded_specs.key?('biovision-vote') %>
36
+ <%= render(partial: 'votes/vote_block', locals: { votable: comment }) %>
37
+ <% end %>
12
38
 
13
39
  <div class="body" itemprop="about">
14
- <%= prepare_comment_text(comment) %>
15
- <% if UserPrivilege.user_has_privilege?(current_user, :moderator) %>
16
- <ul class="actions">
17
- <li><%= edit_icon(edit_comment_path(comment.id)) %></li>
18
- <li class="danger"><%= destroy_icon(comment) %></li>
19
- </ul>
20
- <% end %>
40
+ <%= simple_format(comment.body) %>
21
41
  </div>
42
+ </div>
43
+
44
+ <% if show_container %>
45
+ <div class="comment-reply-block">
46
+ <div class="comment-reply-button">
47
+ <button class="button-nav"><%= t('.reply') %></button>
48
+ </div>
49
+ <div class="container hidden">
50
+ <button class="cancel" type="button" class="button-nav">
51
+ <%= t('.cancel_reply') %>
52
+ </button>
53
+ </div>
54
+ </div>
55
+ <% end %>
56
+ <% end %>
22
57
 
23
- <%= render(partial: 'votes/vote_block', locals: { votable: comment }) if defined?(Biovision::Vote) %>
58
+ <% children = comment_tree.select { |_, item| item[:parent_id] == comment.id } %>
59
+ <% if children.any? %>
60
+ <div class="children">
61
+ <% children.each do |_, item| %>
62
+ <%=
63
+ render(
64
+ partial: 'comments/comment',
65
+ locals: {
66
+ comment: item[:comment],
67
+ show_container: show_container,
68
+ comment_tree: comment_tree
69
+ }
70
+ )
71
+ %>
72
+ <% end %>
73
+ </div>
24
74
  <% end %>
25
75
  </div>
@@ -1,23 +1,96 @@
1
- <%= render partial: 'shared/list_of_errors', locals: { entity: entity } %>
1
+ <% model_name = entity.class.to_s.underscore %>
2
+ <%=
3
+ form_with(
4
+ model: entity,
5
+ html: {
6
+ id: "#{model_name}-form",
7
+ class: 'comment-form',
8
+ data: { check_url: check_comments_path }
9
+ }
10
+ ) do |f|
11
+ %>
12
+ <%= render partial: 'shared/list_of_errors', locals: { entity: entity } %>
13
+ <div class="fields">
14
+ <% if entity.id.nil? && entity.user.nil? %>
15
+ <div class="required">
16
+ <%= f.label :author_name %>
17
+ <%=
18
+ f.text_field(
19
+ :author_name,
20
+ id: "#{model_name}_author_name",
21
+ required: true,
22
+ size: nil,
23
+ maxlength: Comment::AUTHOR_LIMIT,
24
+ data: {
25
+ check: :author_name
26
+ }
27
+ )
28
+ %>
29
+ <div class="check-result-error hidden" data-field="author_name"></div>
30
+ <div class="guideline">
31
+ <%= t('.guidelines.author_name') %>
32
+ </div>
33
+ </div>
2
34
 
3
- <%= form_for entity do |f| %>
4
- <dl>
5
- <dt><%= f.label :body %></dt>
6
- <dd><%= f.text_area :body, required: true, cols: 60, rows: 7 %></dd>
7
- </dl>
8
- <% if current_user_has_privilege?(:administrator) && !entity.id.nil? %>
9
- <ul class="flags">
10
- <li>
11
- <%= f.check_box :deleted %>
12
- <%= f.label :deleted %>
13
- </li>
14
- </ul>
35
+ <div class="required">
36
+ <%= f.label :author_email %>
37
+ <%=
38
+ f.email_field(
39
+ :author_email,
40
+ id: "#{model_name}_author_email",
41
+ required: true,
42
+ size: nil,
43
+ maxlength: Comment::AUTHOR_LIMIT,
44
+ data: {
45
+ check: :author_email
46
+ }
47
+ )
48
+ %>
49
+ <div class="check-result-error hidden" data-field="author_email"></div>
50
+ <div class="guideline">
51
+ <%= t('.guidelines.author_email') %>
52
+ </div>
53
+ </div>
54
+
55
+ <div class="disclaimer">
56
+ <%= check_box_tag :agree, '1', false, class: 'hidden', tabindex: '-1' %>
57
+ <%= t('.disclaimer') %>
58
+ </div>
15
59
  <% end %>
16
- <div class="buttons">
17
- <% if entity.id.nil? %>
18
- <%= f.hidden_field :commentable_id %>
19
- <%= f.hidden_field :commentable_type %>
20
- <% end %>
21
- <%= f.button t(:submit), type: 'submit' %>
60
+
61
+ <div class="required">
62
+ <%= f.label :body %>
63
+ <%=
64
+ f.text_area(
65
+ :body,
66
+ id: "#{model_name}_body",
67
+ required: true,
68
+ cols: 60,
69
+ rows: 5,
70
+ maxlength: Comment::BODY_LIMIT,
71
+ class: 'auto-expand',
72
+ data: {
73
+ min_rows: 5,
74
+ max_rows: 30,
75
+ check: :body
76
+ }
77
+ )
78
+ %>
79
+ <div class="check-result-error hidden" data-field="body"></div>
80
+ <div class="guideline"><%= t('.guidelines.body') %></div>
22
81
  </div>
82
+ </div>
83
+
84
+ <%= render 'shared/forms/state_container' %>
85
+
86
+ <div class="buttons">
87
+ <%= hidden_field_tag :return_url, url_for %>
88
+ <%= hidden_field_tag :entity_id, entity.id %>
89
+ <% if entity.id.nil? %>
90
+ <%= f.hidden_field :commentable_id %>
91
+ <%= f.hidden_field :commentable_type %>
92
+ <%= f.hidden_field :parent_id %>
93
+ <% end %>
94
+ <%= f.button t(:submit), type: 'submit', class: 'button-primary button-action' %>
95
+ </div>
23
96
  <% end %>
@@ -1,19 +1,17 @@
1
- <section class="comments">
2
- <% if comments.any? %>
3
- <h2><%= t(:comments_list) %></h2>
4
-
5
- <% comments.recent.each do |comment| %>
6
- <%= render comment %>
7
- <% end %>
8
- <% end %>
9
-
10
- <% if commentable.respond_to?(:commentable_by?) && commentable.commentable_by?(current_user) %>
11
- <section class="reply-container">
12
- <h2><%= t(:add_comment) %></h2>
13
-
14
- <div class="container">
15
- <%= render partial: 'comments/form', locals: { entity: Comment.new(commentable: commentable) } %>
16
- </div>
17
- </section>
18
- <% end %>
19
- </section>
1
+ <% if collection.any? %>
2
+ <div>
3
+ <% comment_tree = Comment.tree(collection) %>
4
+ <% comment_tree.select { |_, item| item[:parent_id].nil? }.each do |_, item| %>
5
+ <%=
6
+ render(
7
+ partial: 'comments/comment',
8
+ locals: {
9
+ comment: item[:comment],
10
+ show_container: show_reply_container,
11
+ comment_tree: comment_tree
12
+ }
13
+ )
14
+ %>
15
+ <% end %>
16
+ </div>
17
+ <% end %>
@@ -0,0 +1,15 @@
1
+ <section class="reply-container">
2
+ <h3><%= t(:add_comment) %></h3>
3
+
4
+ <div class="container">
5
+ <%=
6
+ render(
7
+ partial: 'comments/form',
8
+ locals: {
9
+ entity: Comment.new(commentable: entity, user: current_user),
10
+ handler: handler
11
+ }
12
+ )
13
+ %>
14
+ </div>
15
+ </section>
@@ -0,0 +1,34 @@
1
+ <%
2
+ handler = CommentHandler.new(current_user)
3
+ collection = handler.list(entity)
4
+ show_reply_container = handler.allow_reply?(entity)
5
+ %>
6
+
7
+ <section class="comments" id="comments">
8
+ <div class="comments-list">
9
+ <h3><%= t(:comment_count, count: entity.comments_count) %></h3>
10
+
11
+ <%=
12
+ render(
13
+ partial: 'comments/list',
14
+ locals: {
15
+ collection: collection.load,
16
+ handler: handler,
17
+ show_reply_container: show_reply_container
18
+ }
19
+ )
20
+ %>
21
+ </div>
22
+
23
+ <% if show_reply_container %>
24
+ <%=
25
+ render(
26
+ partial: 'comments/reply_container',
27
+ locals: {
28
+ entity: entity,
29
+ handler: handler
30
+ }
31
+ )
32
+ %>
33
+ <% end %>
34
+ </section>
@@ -1,12 +1,13 @@
1
1
  <% content_for :meta_title, t('.title') %>
2
2
  <% content_for :breadcrumbs do %>
3
- <%= link_to(t('admin.comments.nav_item.text'), admin_comments_path) %>
4
- <%= admin_comment_link(@entity) %>
5
- <span><%= t(:edit) %></span>
3
+ <%= admin_biovision_component_link(component_handler.component) %>
4
+ <%= link_to(t('admin.comments.nav_item.text'), admin_comments_path) %>
5
+ <%= admin_comment_link(@entity) %>
6
+ <span><%= t('.nav_text') %></span>
6
7
  <% end %>
7
8
 
8
- <article class="edit-comment">
9
- <h1><%= t('.title') %></h1>
9
+ <article>
10
+ <h1><%= t('.heading') %></h1>
10
11
 
11
12
  <ul class="actions">
12
13
  <li><%= return_icon(admin_comment_path(@entity.id)) %></li>
@@ -1,7 +1,7 @@
1
1
  <% content_for :meta_title, t('.title') %>
2
2
 
3
- <article class="edit-comment">
3
+ <article>
4
4
  <h1><%= t('.title') %></h1>
5
5
 
6
- <%= render partial: 'form', locals: { entity: @entity } %>
6
+ <%= render(partial: 'form', locals: { entity: @entity }) %>
7
7
  </article>
@@ -24,12 +24,17 @@ ru:
24
24
  not_commentable: "недоступен вам для комментирования"
25
25
  attributes:
26
26
  comment:
27
+ approved: "Одобрен"
28
+ author_email: "Email"
29
+ author_name: "Имя"
30
+ body: "Текст"
27
31
  commentable: "Комментируемый объект" # Comment validates_presence_of :commentable
28
32
  commentable_id: "Комментируемый объект"
29
33
  commentable_type: "Тип комментируемого объекта"
30
- user_id: "Автор"
31
34
  deleted: "Комментарий удалён"
32
- body: "Текст"
35
+ spam: "Спам"
36
+ user_id: "Автор"
37
+ visible: "Показывать"
33
38
  admin:
34
39
  comments:
35
40
  nav_item:
@@ -40,6 +45,12 @@ ru:
40
45
  heading: "Комментарии"
41
46
  show:
42
47
  title: "Комментарий №%{id}"
48
+ comment:
49
+ deleted: "Комментарий удалён"
50
+ index:
51
+ dashboard:
52
+ biovision_comment:
53
+ heading: "Комментарии"
43
54
  my:
44
55
  comments:
45
56
  index:
@@ -57,9 +68,28 @@ ru:
57
68
  title: "Добавление комментария"
58
69
  edit:
59
70
  title: "Редактирование комментария"
71
+ nav_text: "Редактировать"
72
+ heading: "Редактирование комментария"
60
73
  show:
61
74
  title: "Комментарий №%{id}"
62
75
  entry_reply:
63
76
  subject: "Новый комментарий к вашей записи"
64
77
  comment:
65
78
  deleted: "Комментарий удалён"
79
+ cancel_reply: "Отменить"
80
+ reply: "Ответить"
81
+ form:
82
+ guidelines:
83
+ author_name: "Максимум 100 символов, обязательное поле."
84
+ author_email: "Не показывается публично. Максимум 100 символов, обязательное поле."
85
+ body: "Максимум 5000 символов."
86
+ disclaimer: "Отправляя комментарий, вы принимаете пользовательское соглашение и даёте своё согласие на обработку ваших персональных данных."
87
+ biovision:
88
+ components:
89
+ comments:
90
+ name: "Комментарии"
91
+ privileges:
92
+ moderator: "Модератор"
93
+ settings:
94
+ premoderation: "Премодерация"
95
+ auto_approve_threshold: "Порог автоматического одобрения"