From 150199e0d23b5ea3f6e1876ef16444ff8080cbe4 Mon Sep 17 00:00:00 2001 From: Rajat Talesra Date: Thu, 15 Jun 2023 22:08:45 +0530 Subject: [PATCH] Add more visibility and control around reactions/flags into the Admin USERS page (#19558) * Basic implementation without dropdown * Dropdown functionality * Partial i18n * Nit fixes * Nit fixes * Flag count fix * I18n fr.yml * Nit design fix * added external div to article_item * added external div to article_item * Code merge of article_item and individual_article * Minor bug fix * Extacted more common code * Nit fix * Optimised code * Optimised code * Ni fix * Test fix * Minor suggested changes applied * Nit fix * Nit fix --- app/controllers/admin/articles_controller.rb | 23 + app/controllers/admin/users_controller.rb | 23 +- .../flagReactionItemDropdownButton.js} | 0 .../admin/articles/_article_item.html.erb | 407 ++++++++++-------- .../articles/_individual_article.html.erb | 252 ----------- app/views/admin/articles/show.html.erb | 2 +- .../_flag_reaction_item.html.erb} | 23 +- ...flag_reaction_item_dropdown_menu.html.erb} | 6 +- .../shared/_flag_reactions_table.html.erb | 14 + app/views/admin/users/show.html.erb | 2 +- .../admin/users/show/flags/_index.html.erb | 63 +-- config/locales/views/admin/{users => }/en.yml | 31 ++ config/locales/views/admin/{users => }/fr.yml | 31 ++ config/locales/views/moderations/en.yml | 16 - config/locales/views/moderations/fr.yml | 16 - 15 files changed, 383 insertions(+), 526 deletions(-) rename app/javascript/packs/admin/{articles/vomitReactionItem.js => shared/flagReactionItemDropdownButton.js} (100%) delete mode 100644 app/views/admin/articles/_individual_article.html.erb rename app/views/admin/{articles/_flag_action_item.html.erb => shared/_flag_reaction_item.html.erb} (74%) rename app/views/admin/{articles/_priviledged_reaction_actions_dropdown.html.erb => shared/_flag_reaction_item_dropdown_menu.html.erb} (87%) create mode 100644 app/views/admin/shared/_flag_reactions_table.html.erb rename config/locales/views/admin/{users => }/en.yml (91%) rename config/locales/views/admin/{users => }/fr.yml (91%) diff --git a/app/controllers/admin/articles_controller.rb b/app/controllers/admin/articles_controller.rb index 2aaf9af0a..a80e31e81 100644 --- a/app/controllers/admin/articles_controller.rb +++ b/app/controllers/admin/articles_controller.rb @@ -30,10 +30,17 @@ module Admin @pinned_article = PinnedArticle.get @articles = @articles.where.not(id: @pinned_article) if @pinned_article + + @countable_vomits = {} + @articles.each do |article| + @countable_vomits[article.id] = calculate_flags_for_single_article(article) + end end def show @article = Article.includes(reactions: :user).find(params[:id]) + @countable_vomits = {} + @countable_vomits[@article.id] = calculate_flags_for_single_article(@article) end def update @@ -126,5 +133,21 @@ module Admin def authorize_admin authorize Article, :access?, policy_class: InternalPolicy end + + def calculate_flags_for_single_article(article) + privileged_article_reactions = article.reactions.privileged_category.select do |reaction| + reaction.reactable_type == "Article" + end + vomit_article_reactions = privileged_article_reactions.select { |reaction| reaction.category == "vomit" } + vomit_count = 0 + + if vomit_article_reactions.present? + vomit_article_reactions.each do |vomit_reaction| + vomit_count += 1 if vomit_reaction.status != "invalid" + end + end + + vomit_count + end end end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index a8e1dbc71..3139647e0 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -185,7 +185,7 @@ module Admin user: @user.username, email: @user.email.presence || I18n.t("admin.users_controller.no_email"), id: @user.id, - the_page: link).html_safe # rubocop:disable Rails/OutputSafety + the_page: link).html_safe rescue StandardError => e flash[:danger] = e.message end @@ -363,8 +363,11 @@ module Admin Reaction.where(reactable_type: "Comment", reactable_id: user_comment_ids, category: "vomit") .or(Reaction.where(reactable_type: "Article", reactable_id: user_article_ids, category: "vomit")) .or(Reaction.where(reactable_type: "User", reactable_id: @user.id, category: "vomit")) - .includes(:reactable) + .includes(:user) .order(created_at: :desc).limit(15) + + @countable_flags = calculate_countable_flags(@related_vomit_reactions) + @score = calculate_score(@related_vomit_reactions) end def user_params @@ -410,5 +413,21 @@ module Admin # but let's query and display the last one for now, that should be enough for most cases @unpublish_all_data = AuditLog::UnpublishAllsQuery.call(@user.id) end + + def calculate_countable_flags(reactions) + countable_flags = 0 + reactions.each do |reaction| + countable_flags += 1 if reaction.status != "invalid" + end + countable_flags + end + + def calculate_score(reactions) + score = 0 + reactions.each do |reaction| + score += reaction.points + end + score + end end end diff --git a/app/javascript/packs/admin/articles/vomitReactionItem.js b/app/javascript/packs/admin/shared/flagReactionItemDropdownButton.js similarity index 100% rename from app/javascript/packs/admin/articles/vomitReactionItem.js rename to app/javascript/packs/admin/shared/flagReactionItemDropdownButton.js diff --git a/app/views/admin/articles/_article_item.html.erb b/app/views/admin/articles/_article_item.html.erb index da38ddede..8445afd98 100644 --- a/app/views/admin/articles/_article_item.html.erb +++ b/app/views/admin/articles/_article_item.html.erb @@ -1,203 +1,240 @@ <% decorated_article = article.decorate %> +
-
- -
- <% if decorated_article.pinned? || article.featured || article.approved || (!article.published? && article.published_from_feed?) || article.video || article.user&.warned? %> -
- <% if !article.published? && article.published_from_feed? %> - <%= t("views.moderations.article.unplublished") %> - <% end %> - <% if decorated_article.pinned? %> - <%= t("views.moderations.article.pinned") %> - <% end %> - <% if article.featured %> - <%= t("views.moderations.article.featured") %> - <% end %> - <% if article.approved %> - <%= t("views.moderations.article.approved") %> - <% end %> - <% if article.video %> - <%= t("views.moderations.article.contains_video") %> - <% end %> - <% cache "admin-user-info-#{article.user_id}-#{article.user&.updated_at}", expires_in: 4.hours do %> - <% if article.user&.warned? %> - <%= t("views.moderations.article.user_warned") %> +
+
+ <% if decorated_article.pinned? || article.featured || article.approved || (!article.published? && article.published_from_feed?) || article.video || article.user&.warned? %> +
+ <% if !article.published? && article.published_from_feed? %> + <%= t("views.moderations.article.unplublished") %> <% end %> - <% end %> + <% if decorated_article.pinned? %> + <%= t("views.moderations.article.pinned") %> + <% end %> + <% if article.featured %> + <%= t("views.moderations.article.featured") %> + <% end %> + <% if article.approved %> + <%= t("views.moderations.article.approved") %> + <% end %> + <% if article.video %> + <%= t("views.moderations.article.contains_video") %> + <% end %> + <% cache "admin-user-info-#{article.user_id}-#{article.user&.updated_at}", expires_in: 4.hours do %> + <% if article.user&.warned? %> + <%= t("views.moderations.article.user_warned") %> + <% end %> + <% end %> +
+ <% end %> + + <% if article.main_image.present? %> + + + + <% end %> + +
+

+ + <%= article.title %> + +

+
+ "> + <%= crayons_icon_tag("twemoji/thumb-up", native: true, width: 16, height: 16) %> + <%= article.privileged_reaction_counts["thumbsup"] || "0" %> + + + "> + <%= crayons_icon_tag("twemoji/thumb-down", native: true, width: 16, height: 16) %> + <%= article.privileged_reaction_counts["thumbsdown"] || "0" %> + + + "> + <%= crayons_icon_tag("twemoji/suspicious", native: true, width: 16, height: 16) %> + <%= (@countable_vomits&.dig(article.id) || 0) %> + + + "> + <%= crayons_icon_tag("analytics", native: true, width: 16, height: 16) %> + <%= article.score %> + +
- <% end %> - <% if article.main_image.present? %> - - - - <% end %> +
+
+ <% decorated_article.cached_tag_list_array.each do |tag| %> + #<%= tag %> + <% end %> +
- <% privileged_article_reactions = article.reactions.privileged_category.select { |reaction| reaction.reactable_type == "Article" } %> - <% vomit_article_reactions = privileged_article_reactions.select { |reaction| reaction.category == "vomit" } %> - <% countable_vomits = 0 %> - <% if vomit_article_reactions.present? %> - <% vomit_article_reactions.each do |vomit_reaction| %> - <% if vomit_reaction.status != 'invalid' %> - <% countable_vomits += 1 %> - <% end %> + ❤️ <%= article.public_reactions_count %> <%= t("views.moderations.article.likes") %> + 💬 <%= article.comments_count %> <%= t("views.moderations.article.comments") %> +
+ +
+
+ @<%= article.user&.username %> + <% if article.published_from_feed? && !article.published? %> + RSS Import <%= article.created_at.strftime("%b %d, %Y") %> + Originally Published <%= article.published_at&.strftime("%b %d, %Y") %> + <% elsif article.crossposted_at? %> + Crossposted <%= article.crossposted_at.strftime("%b %d, %Y") %> & Published + <%= article.published_at&.strftime("%b %d, %Y") %> + <% else %> + <%= article.published_at&.strftime("%b %d, %Y") %> + <% end %> +
+ +
+ <% if !defined?(show_on_individual_article_only) || !show_on_individual_article_only %> + + <%= t("views.moderations.article.view_details") %> + + <% end %> + <% if decorated_article.pinned? %> +
+ + + +
+ <% else %> +
+ + +
+ <% end %> + <%= t("views.moderations.article.user") %> + <%= t("views.moderations.article.edit") %> +
+
+
+ + <% cache "admin-user-notes-#{article.user_id}-#{article.user&.updated_at}", expires_in: 4.hours do %> + <% if article.user&.notes&.any? %> +
+
+

<%= article.user&.notes&.size %> <%= t("views.moderations.article.notes.user_notes") %>

+ <%= t("views.moderations.article.notes.view_all") %> +
+ <% article.user&.notes&.last(3)&.each do |note| %> +

+ <%= note.content %> + + – <%= note.author_id ? User.find(note.author_id).username : "No author" %> + + +

+ <% end %> +
<% end %> <% end %> -
-

- - <%= article.title %> - -

-
- "> - <%= crayons_icon_tag("twemoji/thumb-up", native: true, width: 16, height: 16) %> - <%= article.privileged_reaction_counts["thumbsup"] || "0" %> - - - "> - <%= crayons_icon_tag("twemoji/thumb-down", native: true, width: 16, height: 16) %> - <%= article.privileged_reaction_counts["thumbsdown"] || "0" %> - - - "> - <%= crayons_icon_tag("twemoji/suspicious", native: true, width: 16, height: 16) %> - <%= countable_vomits %> - - - "> - <%= crayons_icon_tag("analytics", native: true, width: 16, height: 16) %> - <%= article.score %> - -
-
- -
-
- <% decorated_article.cached_tag_list_array.each do |tag| %> - #<%= tag %> - <% end %> -
- - ❤️ <%= article.public_reactions_count %> <%= t("views.moderations.article.likes") %> - 💬 <%= article.comments_count %> <%= t("views.moderations.article.comments") %> -
- -
-
- @<%= article.user&.username %> - <% if article.published_from_feed? && !article.published? %> - RSS Import <%= article.created_at.strftime("%b %d, %Y") %> - Originally Published <%= article.published_at&.strftime("%b %d, %Y") %> - <% elsif article.crossposted_at? %> - Crossposted <%= article.crossposted_at.strftime("%b %d, %Y") %> & Published - <%= article.published_at&.strftime("%b %d, %Y") %> - <% else %> - <%= article.published_at&.strftime("%b %d, %Y") %> - <% end %> -
- -
- <%= t("views.moderations.article.view_details") %> - <% if decorated_article.pinned? %> -
- - - -
- <% else %> -
- - -
- <% end %> - <%= t("views.moderations.article.user") %> - <%= t("views.moderations.article.edit") %> -
-
-
- - <% cache "admin-user-notes-#{article.user_id}-#{article.user&.updated_at}", expires_in: 4.hours do %> - <% if article.user&.notes&.any? %> -
-
-

<%= article.user&.notes&.size %> <%= t("views.moderations.article.notes.user_notes") %>

- <%= t("views.moderations.article.notes.view_all") %> + <%= form_with url: admin_article_path(article.id), model: article, local: true, class: "crayons-card crayons-card--secondary p-4 flex flex-col gap-3" do |f| %> + + + +
+
+ +
- <% article.user&.notes&.last(3)&.each do |note| %> -

- <%= note.content %> - - – <%= note.author_id ? User.find(note.author_id).username : "No author" %> - - -

- <% end %> -
- <% end %> - <% end %> - <%= form_with url: admin_article_path(article.id), model: article, local: true, class: "crayons-card crayons-card--secondary p-4 flex flex-col gap-3" do |f| %> - - - -
-
- - +
+ + "> +
- -
- - "> -
-
- <% if article.published? %> -
-
- -
- <%= f.datetime_select :published_at, { required: true, include_blank: true, include_seconds: true }, class: "crayons-select w-auto" %> - UTC + <% if article.published? %> +
+
+ +
+ <%= f.datetime_select :published_at, { required: true, include_blank: true, include_seconds: true }, class: "crayons-select w-auto" %> + UTC +
+ <% end %> +
+
+ <%= f.check_box :featured, id: "featured-#{article.id}", class: "crayons-checkbox" %> + +
+ +
+ <%= f.check_box :approved, id: "approved-#{article.id}", class: "crayons-checkbox" %> + +
+
+
+
<% end %> -
-
- <%= f.check_box :featured, id: "featured-#{article.id}", class: "crayons-checkbox" %> - -
+
-
- <%= f.check_box :approved, id: "approved-#{article.id}", class: "crayons-checkbox" %> - -
-
-
- -
+ <% if defined?(show_on_individual_article_only) && show_on_individual_article_only %> + <% privileged_article_reactions = article.reactions.privileged_category.select { |reaction| reaction.reactable_type == "Article" } %> + <% vomit_article_reactions = privileged_article_reactions.select { |reaction| reaction.category == "vomit" }.reverse %> + <% quality_article_reactions = (privileged_article_reactions - vomit_article_reactions).reverse %> +
+

<%= t("views.admin.articles.priviliged_actions.title") %>

+

<%= t("views.admin.articles.priviliged_actions.description") %>

+ + + +
+ <% if params[:tab].blank? || params[:tab] == "flags" %> + <%= render "admin/shared/flag_reactions_table", + vomit_reactions: vomit_article_reactions, + text_section: "articles", + empty_text: t("views.admin.articles.priviliged_actions.no_flags") %> + <% end %> + + <% if params[:tab] == "quality_reactions" %> + <% if quality_article_reactions.present? %> + <% quality_article_reactions.each do |quality_reaction| %> + <%= render "admin/articles/quality_action_item", quality_reaction: quality_reaction %> +
+ <% end %> + <% else %> +
+
+ <%= crayons_icon_tag("quality-reactions", native: true, width: 56, height: 56) %> +
+

<%= t("views.admin.articles.priviliged_actions.no_quality_reactions") %>

+
+ <% end %> + <% end %> +
+
<% end %> - + diff --git a/app/views/admin/articles/_individual_article.html.erb b/app/views/admin/articles/_individual_article.html.erb deleted file mode 100644 index bcab51d3f..000000000 --- a/app/views/admin/articles/_individual_article.html.erb +++ /dev/null @@ -1,252 +0,0 @@ -<% decorated_article = article.decorate %> -<%= javascript_packs_with_chunks_tag "admin/articles/vomitReactionItem", defer: true %> -
- - <% privileged_article_reactions = article.reactions.privileged_category.select { |reaction| reaction.reactable_type == "Article" } %> - <% vomit_article_reactions = privileged_article_reactions.select { |reaction| reaction.category == "vomit" }.reverse %> - <% quality_article_reactions = (privileged_article_reactions - vomit_article_reactions).reverse %> - <% countable_vomits = 0 %> - <% if vomit_article_reactions.present? %> - <% vomit_article_reactions.each do |vomit_reaction| %> - <% if vomit_reaction.status != 'invalid' %> - <% countable_vomits += 1 %> - <% end %> - <% end %> - <% end %> - -
-
- <% if decorated_article.pinned? || article.featured || article.approved || (!article.published? && article.published_from_feed?) || article.video || article.user&.warned? %> -
- <% if !article.published? && article.published_from_feed? %> - <%= t("views.moderations.article.unplublished") %> - <% end %> - <% if decorated_article.pinned? %> - <%= t("views.moderations.article.pinned") %> - <% end %> - <% if article.featured %> - <%= t("views.moderations.article.featured") %> - <% end %> - <% if article.approved %> - <%= t("views.moderations.article.approved") %> - <% end %> - <% if article.video %> - <%= t("views.moderations.article.contains_video") %> - <% end %> - <% cache "admin-user-info-#{article.user_id}-#{article.user&.updated_at}", expires_in: 4.hours do %> - <% if article.user&.warned? %> - <%= t("views.moderations.article.user_warned") %> - <% end %> - <% end %> -
- <% end %> - - <% if article.main_image.present? %> - - - - <% end %> - -
-

- - <%= article.title %> - -

-
- "> - <%= crayons_icon_tag("twemoji/thumb-up", native: true, width: 16, height: 16) %> - <%= article.privileged_reaction_counts["thumbsup"] || "0" %> - - - "> - <%= crayons_icon_tag("twemoji/thumb-down", native: true, width: 16, height: 16) %> - <%= article.privileged_reaction_counts["thumbsdown"] || "0" %> - - - "> - <%= crayons_icon_tag("twemoji/suspicious", native: true, width: 16, height: 16) %> - <%= countable_vomits %> - - - "> - <%= crayons_icon_tag("analytics", native: true, width: 16, height: 16) %> - <%= article.score %> - -
-
- -
-
- <% decorated_article.cached_tag_list_array.each do |tag| %> - #<%= tag %> - <% end %> -
- - ❤️ <%= article.public_reactions_count %> <%= t("views.moderations.article.likes") %> - 💬 <%= article.comments_count %> <%= t("views.moderations.article.comments") %> -
- -
-
- @<%= article.user&.username %> - <% if article.published_from_feed? && !article.published? %> - RSS Import <%= article.created_at.strftime("%b %d, %Y") %> - Originally Published <%= article.published_at&.strftime("%b %d, %Y") %> - <% elsif article.crossposted_at? %> - Crossposted <%= article.crossposted_at.strftime("%b %d, %Y") %> & Published - <%= article.published_at&.strftime("%b %d, %Y") %> - <% else %> - <%= article.published_at&.strftime("%b %d, %Y") %> - <% end %> -
- -
- <% if decorated_article.pinned? %> -
- - - -
- <% else %> -
- - -
- <% end %> - User - Edit -
-
-
- - <% cache "admin-user-notes-#{article.user_id}-#{article.user&.updated_at}", expires_in: 4.hours do %> - <% if article.user&.notes&.any? %> -
-
-

<%= article.user&.notes&.size %> <%= t("views.moderations.article.notes.user_notes") %>

- <%= t("views.moderations.article.notes.view_all") %> -
- <% article.user&.notes&.last(3)&.each do |note| %> -

- <%= note.content %> - - – <%= note.author_id ? User.find(note.author_id).username : "No author" %> - - -

- <% end %> -
- <% end %> - <% end %> - - <%= form_with url: admin_article_path(article.id), model: article, local: true, class: "crayons-card crayons-card--secondary p-4 flex flex-col gap-3" do |f| %> - - - -
-
- - -
- -
- - "> -
-
- <% if article.published? %> -
-
- -
- <%= f.datetime_select :published_at, { required: true, include_blank: true, include_seconds: true }, class: "crayons-select w-auto" %> - UTC -
-
-
- <% end %> -
-
- <%= f.check_box :featured, id: "featured-#{article.id}", class: "crayons-checkbox" %> - -
- -
- <%= f.check_box :approved, id: "approved-#{article.id}", class: "crayons-checkbox" %> - -
-
-
- -
- <% end %> -
- -
-

<%= t("views.moderations.priviliged_actions.title") %>

-

<%= t("views.moderations.priviliged_actions.description") %>

- - - -
- <% if params[:tab].blank? || params[:tab] == "flags" %> - <% if vomit_article_reactions.present? %> - <% vomit_article_reactions.each do |vomit_reaction| %> - <%= render "admin/articles/flag_action_item", vomit_reaction: vomit_reaction %> -
- <% end %> - <% else %> -
-
- <%= crayons_icon_tag("flags", native: true, width: 56, height: 56) %> -
-

<%= t("views.moderations.priviliged_actions.no_flags") %>

-
- <% end %> - <% end %> - - <% if params[:tab] == "quality_reactions" %> - <% if quality_article_reactions.present? %> - <% quality_article_reactions.each do |quality_reaction| %> - <%= render "admin/articles/quality_action_item", quality_reaction: quality_reaction %> -
- <% end %> - <% else %> -
-
- <%= crayons_icon_tag("quality-reactions", native: true, width: 56, height: 56) %> -
-

<%= t("views.moderations.priviliged_actions.no_quality_reactions") %>

-
- <% end %> - <% end %> -
-
-
diff --git a/app/views/admin/articles/show.html.erb b/app/views/admin/articles/show.html.erb index 2933247ce..fec169412 100644 --- a/app/views/admin/articles/show.html.erb +++ b/app/views/admin/articles/show.html.erb @@ -8,6 +8,6 @@ data-article-pinned-modal-ok-button-id-value="article-pin-modal-ok" data-action="article-pinned-modal:open@document->article-pinned-modal#openModal"> - <%= render partial: "individual_article", locals: { article: @article } %> + <%= render partial: "article_item", locals: { article: @article, show_on_individual_article_only: true } %> <%= render partial: "pinned_article_modal" %> diff --git a/app/views/admin/articles/_flag_action_item.html.erb b/app/views/admin/shared/_flag_reaction_item.html.erb similarity index 74% rename from app/views/admin/articles/_flag_action_item.html.erb rename to app/views/admin/shared/_flag_reaction_item.html.erb index 6b875c233..ad76b6b21 100644 --- a/app/views/admin/articles/_flag_action_item.html.erb +++ b/app/views/admin/shared/_flag_reaction_item.html.erb @@ -21,29 +21,32 @@ <%# In both the FE and BE, 'Invalid' remains the same. This status appears when an admin user marks a flag or vomit reaction as invalid, with a score of 0. %>
<% if vomit_reaction.status == 'valid' %> - "> - <%= t("views.moderations.flags.open.value") %> + "> + <%= t("views.admin.shared.flags.open.value") %> <% elsif vomit_reaction.status == 'invalid' %> - "> - <%= t("views.moderations.flags.invalid.value") %> + "> + <%= t("views.admin.shared.flags.invalid.value") %> <% elsif vomit_reaction.status == 'confirmed' %> - "> - <%= t("views.moderations.flags.valid.value") %> + "> + <%= t("views.admin.shared.flags.valid.value") %> <% else %> <%# This case should never arise. %> - "> - <%= t("views.moderations.flags.unidentified.value") %> + "> + <%= t("views.admin.shared.flags.unidentified.value") %> <% end %> - + "> <%= crayons_icon_tag("analytics", native: true, width: 16, height: 16) %> <%= vomit_reaction.points %>
- <%= render "admin/articles/priviledged_reaction_actions_dropdown", vomit_reaction: vomit_reaction %> + <%= render "admin/shared/flag_reaction_item_dropdown_menu", vomit_reaction: vomit_reaction %> diff --git a/app/views/admin/articles/_priviledged_reaction_actions_dropdown.html.erb b/app/views/admin/shared/_flag_reaction_item_dropdown_menu.html.erb similarity index 87% rename from app/views/admin/articles/_priviledged_reaction_actions_dropdown.html.erb rename to app/views/admin/shared/_flag_reaction_item_dropdown_menu.html.erb index bc7120c55..080439ced 100644 --- a/app/views/admin/articles/_priviledged_reaction_actions_dropdown.html.erb +++ b/app/views/admin/shared/_flag_reaction_item_dropdown_menu.html.erb @@ -1,6 +1,6 @@
@@ -17,7 +17,7 @@ data-remove-element="false" class="c-btn align-left w-100 c-btn--icon-left"> <%= crayons_icon_tag("checkmark", aria_hidden: true, class: "c-btn__icon") %> - <%= t("views.moderations.flags.actions.mark_as_valid") %> + <%= t("views.admin.shared.flags.actions.mark_as_valid") %> <% end %> @@ -33,7 +33,7 @@ data-remove-element="false" class="c-btn align-left w-100 c-btn--icon-left"> <%= crayons_icon_tag("x", aria_hidden: true, class: "c-btn__icon") %> - <%= t("views.moderations.flags.actions.mark_as_invalid") %> + <%= t("views.admin.shared.flags.actions.mark_as_invalid") %> <% end %> diff --git a/app/views/admin/shared/_flag_reactions_table.html.erb b/app/views/admin/shared/_flag_reactions_table.html.erb new file mode 100644 index 000000000..c58996629 --- /dev/null +++ b/app/views/admin/shared/_flag_reactions_table.html.erb @@ -0,0 +1,14 @@ +<%= javascript_packs_with_chunks_tag "admin/shared/flagReactionItemDropdownButton", defer: true %> +<% if vomit_reactions.present? %> + <% vomit_reactions.each do |vomit_reaction| %> + <%= render "admin/shared/flag_reaction_item", vomit_reaction: vomit_reaction, text_section: text_section %> +
+ <% end %> +<% else %> +
+
+ <%= crayons_icon_tag("flags", native: true, width: 56, height: 56) %> +
+

<%= empty_text %>

+
+<% end %> diff --git a/app/views/admin/users/show.html.erb b/app/views/admin/users/show.html.erb index 3a1c3c0ab..7fc512352 100644 --- a/app/views/admin/users/show.html.erb +++ b/app/views/admin/users/show.html.erb @@ -51,7 +51,7 @@ <%= render "admin/users/show/reports/index" %> <% elsif @current_tab == "flags" %> -
+
<%= render "admin/users/show/flags/index" %>
<% elsif @current_tab == "unpublish_logs" %> diff --git a/app/views/admin/users/show/flags/_index.html.erb b/app/views/admin/users/show/flags/_index.html.erb index 87ebd27e2..0a0464e72 100644 --- a/app/views/admin/users/show/flags/_index.html.erb +++ b/app/views/admin/users/show/flags/_index.html.erb @@ -1,43 +1,26 @@ -

Flags received (<%= @related_vomit_reactions.count %>)

+<% user_vomit_reactions = @related_vomit_reactions.select { |flag| flag.reactable_type == "User" } %> -<% unless @related_vomit_reactions.empty? %> -
- <% @related_vomit_reactions.each do |flag| %> -
- - <% if flag.reactable_type == "Article" %> - <%= crayons_icon_tag("post", aria_hidden: true) %> - <% elsif flag.reactable_type == "User" %> - <%= crayons_icon_tag("user-line", aria_hidden: true) %> - <% elsif flag.reactable_type == "Comment" %> - <%= crayons_icon_tag("comment", aria_hidden: true) %> - <% end %> - -
-

- <%= link_to flag.reactable.path, class: "c-link" do %> - <% if flag.reactable_type == "Article" %> - <%= t("views.admin.users.flags.type.article", title: flag.reactable.title) %> - <% elsif flag.reactable_type == "User" %> - <%= t("views.admin.users.flags.type.profile") %> - <% elsif flag.reactable_type == "Comment" %> - <%= t("views.admin.users.flags.type.comment", title: flag.reactable.title) %> - <% end %> - <% end %> -

-

- <%= t("views.admin.users.flags.origin_html", user: link_to(flag.user.username, admin_user_path(flag.user_id), class: "c-link c-link--branded")) %> -

-
- -
- <% end %> +
+
+

<%= t("views.admin.users.priviliged_actions.title") %>

+

<%= t("views.admin.users.priviliged_actions.description") %>

-<% else %> -
-

<%= t("views.admin.users.flags.empty1", user: @user.name) %>

-

<%= t("views.admin.users.flags.empty2", user: @user.name) %>

+
+ "> + <%= crayons_icon_tag("twemoji/suspicious", native: true, width: 16, height: 16) %> + <%= @countable_flags %> + + + "> + <%= crayons_icon_tag("analytics", native: true, width: 16, height: 16) %> + <%= @score %> +
-<% end %> +
+ +
+ <%= render "admin/shared/flag_reactions_table", + vomit_reactions: user_vomit_reactions, + text_section: "users", + empty_text: t("views.admin.users.priviliged_actions.no_flags") %> +
diff --git a/config/locales/views/admin/users/en.yml b/config/locales/views/admin/en.yml similarity index 91% rename from config/locales/views/admin/users/en.yml rename to config/locales/views/admin/en.yml index 342723c15..0f07cb324 100644 --- a/config/locales/views/admin/users/en.yml +++ b/config/locales/views/admin/en.yml @@ -2,6 +2,31 @@ en: views: admin: + articles: + flags: + score: Score affected by a particular flag + priviliged_actions: + description: All the moderator actions affect the score. The overall score is a combination of moderator actions and public reactions. + no_flags: Article has no flags. + no_quality_reactions: Article has no quality reactions by trusted users. + title: Moderator actions + shared: + flags: + actions: + mark_as_invalid: Mark as Invalid + mark_as_valid: Mark as Valid + invalid: + title: Flag marked as invalid by admin + value: Invalid + open: + title: Open Flag + value: Open + unidentified: + title: Unidentified + value: Unidentified + valid: + title: Flag marked as valid by admin + value: Valid users: heading: Members aria_paginate: Paginate users @@ -188,6 +213,8 @@ en: comment: Comment on "%{title}" profile: User's profile origin_html: Flagged by %{user} + score: Article and comment score affected by particular flag + total_score: Article and comment score affected by user flags notes: empty1: No previous notes found for %{user}. empty2: Any notes added for %{user} will be found here. @@ -264,6 +291,10 @@ en: remove: "Remove tag:" notice_html: Adding tags for moderation is currently only possible through a particular %{tag_page}, by providing the user's ID (%{user_id}). tag_page: tag's page + priviliged_actions: + description: The user flags affect the scores of articles and comments. Each valid or open user flag further reduces the score of the article and comment. + no_flags: No flags received against this user yet. + title: Flags received profile: locked: icon: Access locked diff --git a/config/locales/views/admin/users/fr.yml b/config/locales/views/admin/fr.yml similarity index 91% rename from config/locales/views/admin/users/fr.yml rename to config/locales/views/admin/fr.yml index 51a7aa97b..24fbf5319 100644 --- a/config/locales/views/admin/users/fr.yml +++ b/config/locales/views/admin/fr.yml @@ -2,6 +2,31 @@ fr: views: admin: + articles: + flags: + score: Score affected by a particular flag + priviliged_actions: + description: All the moderator actions affect the score. The overall score is a combination of moderator actions and public reactions. + no_flags: Article has no flags. + no_quality_reactions: Article has no quality reactions by trusted users. + title: Moderator actions + shared: + flags: + actions: + mark_as_invalid: Mark as Invalid + mark_as_valid: Mark as Valid + invalid: + title: Flag marked as invalid by admin + value: Invalid + open: + title: Open Flag + value: Open + unidentified: + title: Unidentified + value: Unidentified + valid: + title: Flag marked as valid by admin + value: Valid users: heading: Members aria_paginate: Paginate users @@ -188,6 +213,8 @@ fr: comment: Comment on "%{title}" profile: User's profile origin_html: Flagged by %{user} + score: Article and comment score affected by particular flag + total_score: Article and comment score affected by user flags notes: empty1: No previous notes found for %{user}. empty2: Any notes added for %{user} will be found here. @@ -264,6 +291,10 @@ fr: remove: "Remove tag:" notice_html: Adding tags for moderation is currently only possible through a particular %{tag_page}, by providing the user's ID (%{user_id}). tag_page: tag's page + priviliged_actions: + description: The user flags affect the scores of articles and comments. Each valid or open user flag further reduces the score of the article and comment. + no_flags: No flags received against this user yet. + title: Flags received profile: locked: icon: Access locked diff --git a/config/locales/views/moderations/en.yml b/config/locales/views/moderations/en.yml index 37aa8ac7a..63d178c8d 100644 --- a/config/locales/views/moderations/en.yml +++ b/config/locales/views/moderations/en.yml @@ -163,22 +163,6 @@ en: trusted: Trusted User Guide author: Author date: Date - flags: - actions: - mark_as_invalid: Mark as Invalid - mark_as_valid: Mark as Valid - invalid: - title: Flag marked as invalid by admin - value: Invalid - open: - title: Open Flag - value: Open - unidentified: - title: Unidentified - value: Unidentified - valid: - title: Flag marked as valid by admin - value: Valid notice: subtitle: '%{community} Mods' desc1_html: We periodically award some %{community} members with heightened privileges to help moderate the community. diff --git a/config/locales/views/moderations/fr.yml b/config/locales/views/moderations/fr.yml index bc561d618..22989a6c1 100644 --- a/config/locales/views/moderations/fr.yml +++ b/config/locales/views/moderations/fr.yml @@ -162,22 +162,6 @@ fr: trusted: Guide de l'utilisateur de confiance author: Auteur date: Date - flags: - actions: - mark_as_invalid: Marquer comme non valide - mark_as_valid: Marquer comme valide - invalid: - title: Drapeau marqué comme invalide par l'administrateur - value: Invalide - open: - title: Drapeau ouvert - value: Ouvrir - unidentified: - title: Non identifié - value: Non identifié - valid: - title: Drapeau marqué comme valide par l'administrateur - value: Valide notice: subtitle: '%{community} Mods' desc1_html: Nous accordons périodiquement à certains membres de la %{community} des privilèges accrus afin de contribuer à la modération de la communauté.