Просмотр исходного кода

Fixes #3559 - mentioned KB entries with the same title in different categories can not distinguished.

Rolf Schmidt 3 лет назад
Родитель
Сommit
328845c283

+ 9 - 1
app/assets/javascripts/app/lib/app_post/searchable_select.coffee

@@ -90,9 +90,17 @@ class App.SearchableSelect extends Spine.Controller
   renderOptions: (options) ->
     html = ''
     for option in options
+      classes = 'u-textTruncate'
+      if option.children
+        classes += ' js-enter'
+      else
+        classes += ' js-option'
+      if option.category
+        classes += ' with-category'
+
       html += App.view('generic/searchable_select_option')
         option: option
-        class: if option.children then 'js-enter' else 'js-option'
+        class: classes
     html
 
   renderAllOptions: (parentName, options, level) ->

+ 7 - 2
app/assets/javascripts/app/lib/app_post/z_searchable_ajax_select.coffee

@@ -78,10 +78,15 @@ class App.SearchableAjaxSelect extends App.SearchableSelect
   renderResponseItemAjax: (elem, data) ->
     result = _.find(data.details, (detailElem) -> detailElem.type == elem.type and detailElem.id == elem.id)
 
+    category = undefined
+    if result.type is 'KnowledgeBase::Answer::Translation' && result.subtitle
+      category = result.subtitle
+
     if result
       {
-        name:  result.title
-        value: elem.id
+        category: category
+        name:     result.title
+        value:    elem.id
       }
 
   renderResponseItem: (elem) ->

+ 12 - 7
app/assets/javascripts/app/lib/base/jquery.textmodule.js

@@ -577,7 +577,8 @@
           'flavor':            'agent',
           'index':             'KnowledgeBase::Answer::Translation',
           'url_type':          'agent',
-          'highlight_enabled': false
+          'highlight_enabled': false,
+          'include_locale': true,
         }),
         processData: true,
         success: function(data, status, xhr) {
@@ -585,12 +586,13 @@
 
           var items = data
             .result
-            .map(function(elem){
+            .map(function(elem) {
               if(result = _.find(data.details, function(detailElem) { return detailElem.type == elem.type && detailElem.id == elem.id })) {
                 return {
-                  'name':  result.title,
-                  'value': elem.id,
-                  'url':   result.url
+                  'category': result.subtitle,
+                  'name':     result.title,
+                  'value':    elem.id,
+                  'url':      result.url
                 }
               }
             })
@@ -599,8 +601,11 @@
               var element = $('<li>')
                 .attr('data-id',  elem.value)
                 .attr('data-url', elem.url)
-                .text(elem.name)
-                .addClass('u-clickable u-textTruncate')
+                .addClass('u-clickable u-textTruncate with-category')
+
+              element.append($('<small>').text(elem.category))
+              element.append('<br>')
+              element.append($('<span>').text(elem.name))
 
               if (index == array.length-1) {
                 element.addClass('is-active')

+ 16 - 0
app/assets/javascripts/app/models/knowledge_base_category.coffee

@@ -38,6 +38,22 @@ class App.KnowledgeBaseCategory extends App.Model
       memo.concat elem.categoriesForDropdown(nested: options.nested + 1, kb_locale: options.kb_locale)
     , initial
 
+  categoriesForSearch: (options = {}) ->
+    result = [@guaranteedTitle(options.kb_locale.id)]
+
+    check = @
+    while check.parent()
+      result.push(check.parent().guaranteedTitle(options.kb_locale.id))
+      check = check.parent()
+
+    if options.full || result.length <= 2
+      result = result.reverse().join(' > ')
+    else
+      result = result.reverse()
+      result = "#{result[0]} > .. > #{result[result.length - 1]}"
+
+    result
+
   configure_attributes: (kb_locale = undefined) ->
     [
       {

+ 2 - 1
app/assets/javascripts/app/views/generic/searchable_select_option.jst.eco

@@ -1,8 +1,9 @@
 <li role="presentation" class="<%= @class %>" data-value="<%= @option.value %>" title="<%= @option.name %><% if @detail: %><%= @detail %><% end %>">
+  <% if @option.category: %><small><%= @option.category %></small><br><% end %>
   <span class="searchableSelect-option-text">
     <%= @option.name %><% if @detail: %><span class="dropdown-detail"><%= @detail %></span><% end %>
   </span>
   <% if @option.children: %>
     <%- @Icon('arrow-right', 'recipientList-arrow') %>
   <% end %>
-</li>
+</li>

+ 4 - 0
app/assets/javascripts/app/views/popover/kb_generic.jst.eco

@@ -27,6 +27,10 @@
           -
         <% end %>
       </div>
+      <div class="column">
+        <label><%- @T('Category') %></label>
+        <a href="<%= @object.parent().category().uiUrl(App.KnowledgeBaseLocale.find(@object.kb_locale_id)) %>" title="<%= @object.parent().category().categoriesForSearch({ full: true, kb_locale: App.KnowledgeBaseLocale.find(@object.kb_locale_id) }) %>"><%= @object.parent().category().guaranteedTitle(@object.kb_locale_id) %></a>
+      </div>
       <div class="column">
         <label><%- @T('Language') %></label>
         <%= App.KnowledgeBaseLocale.localeFor(@object).systemLocale().name %>

+ 10 - 1
app/assets/stylesheets/zammad.scss

@@ -8371,6 +8371,16 @@ footer {
     }
   }
 
+  .dropdown li.with-category, .dropdown.dropdown--actions li.with-category {
+    line-height: 19.5px;
+  }
+
+  .dropdown.dropdown--actions li.with-category {
+    height: 39px;
+    padding: 0px 15px;
+    display: list-item;
+  }
+
   .dropdown li:not(:first-child) {
     box-shadow: 0 1px rgba(255,255,255,.13) inset;
   }
@@ -13023,4 +13033,3 @@ span.is-disabled {
 .text-modules-box {
   max-height: 40vh;
 }
-

+ 8 - 2
app/controllers/knowledge_base/search_controller.rb

@@ -75,7 +75,13 @@ class KnowledgeBase::SearchController < ApplicationController
 
   def public_item_details_answer(meta, object)
     category_translation = object.answer.category.translation_preferred(object.kb_locale)
-    path = help_answer_path(category_translation, object, locale: object.kb_locale.system_locale.locale)
+    path                 = help_answer_path(category_translation, object, locale: object.kb_locale.system_locale.locale)
+    subtitle             = object.answer.category.self_with_parents.map { |c| strip_tags(c.translation_preferred(object.kb_locale).title) }.reverse
+    subtitle = if subtitle.count <= 2
+                 subtitle.join(' > ')
+               else
+                 subtitle.values_at(0, -1).join(' > .. > ')
+               end
 
     url = case url_type
           when :public
@@ -91,7 +97,7 @@ class KnowledgeBase::SearchController < ApplicationController
       date:     object.updated_at,
       url:      url,
       title:    meta.dig(:highlight, 'title')&.first || object.title,
-      subtitle: strip_tags(category_translation.title),
+      subtitle: subtitle,
       body:     meta.dig(:highlight, 'content.body')&.first || strip_tags(object.content.body).truncate(100)
     }
   end

+ 12 - 0
app/models/knowledge_base/category.rb

@@ -61,6 +61,18 @@ class KnowledgeBase::Category < ApplicationModel
     [self] + children.map(&:self_with_children).flatten
   end
 
+  def self_with_parents
+    result = [self]
+
+    check = self
+    while check.parent.present?
+      result << check.parent
+      check = check.parent
+    end
+
+    result
+  end
+
   def self_with_children_answers
     KnowledgeBase::Answer.where(category_id: self_with_children_ids)
   end

+ 4 - 0
spec/models/knowledge_base/category_spec.rb

@@ -40,6 +40,10 @@ RSpec.describe KnowledgeBase::Category, type: :model, current_user_id: 1 do
       expect(kb_category_with_tree.self_with_children.count).to eq 7
     end
 
+    it 'fetches all parents' do
+      expect(grandchild_category.self_with_parents.count).to eq 3
+    end
+
     it 'root category has no parent' do
       expect(kb_category_with_tree.parent).to be_blank
     end

Некоторые файлы не были показаны из-за большого количества измененных файлов