autocomplete: render html server-side.

Render the HTML for autocomplete results server-side instead of in
Javascript. This is cleaner than building HTML in Javascript, but it may
hurt caching because the HTTP responses are larger.

Fixes #4698: user autocomplete contains links to /posts

Also fixes a bug where tag counts in the autocomplete menu were different
from tag counts displayed elsewhere because of differences in rounding.
This commit is contained in:
evazion
2022-08-29 20:50:19 -05:00
parent 55266be2ef
commit cf13ab1540
7 changed files with 84 additions and 58 deletions

View File

@@ -0,0 +1,23 @@
# frozen_string_literal: true
class AutocompleteComponent < ApplicationComponent
attr_reader :autocomplete_service
delegate :humanized_number, to: :helpers
delegate :autocomplete_results, to: :autocomplete_service
def initialize(autocomplete_service:)
@autocomplete_service = autocomplete_service
end
def link_to_result(result, &block)
case result.type
when "user"
link_to user_path(result.id), class: "user-#{result.level}", "@click.prevent": "", &block
when "pool"
link_to pool_path(result.id), class: "pool-category-#{result.category}", "@click.prevent": "", &block
else
link_to posts_path(tags: result.value), class: "tag-type-#{result.category}", "@click.prevent": "", &block
end
end
end

View File

@@ -0,0 +1,20 @@
<ul>
<% autocomplete_results.each do |result| %>
<%= tag.li class: "ui-menu-item", "data-autocomplete-type": result.type, "data-autocomplete-antecedent": result.antecedent, "data-autocomplete-value": result.value, "data-autocomplete-category": result.category, "data-autocomplete-post-count": result.post_count do %>
<div class="ui-menu-item-wrapper" tabindex="-1">
<%= link_to_result result do %>
<% if result.antecedent.present? %>
<span class="autocomplete-antecedent"><%= result.antecedent.tr("_", " ") %></span>
<span class="autocomplete-arrow">→</span>
<% end %>
<%= result.label %>
<% end %>
<% if result.post_count %>
<%= tag.span humanized_number(result.post_count), class: "post-count", style: "float: right;" %>
<% end %>
</div>
<% end %>
<% end %>
</ul>