From b51ad84ee5b7c0071bebca5cf6c0521e6cd8b573 Mon Sep 17 00:00:00 2001
From: zmagod <zmago_devetak@yahoo.com>
Date: Fri, 6 Apr 2018 12:03:39 +0200
Subject: [PATCH] add asset field preview/sort/search in repository table
 [fixes SCI-2076]

---
 .../repositories/repository_datatable.js.erb  |  6 +++
 app/helpers/repository_datatable_helper.rb    | 20 ++++++---
 app/services/repository_datatable_service.rb  | 43 +++++++++++++------
 app/views/repositories/_asset_link.html.erb   | 18 ++++++++
 4 files changed, 68 insertions(+), 19 deletions(-)
 create mode 100644 app/views/repositories/_asset_link.html.erb

diff --git a/app/assets/javascripts/repositories/repository_datatable.js.erb b/app/assets/javascripts/repositories/repository_datatable.js.erb
index e3197df3c..efa39b8a9 100644
--- a/app/assets/javascripts/repositories/repository_datatable.js.erb
+++ b/app/assets/javascripts/repositories/repository_datatable.js.erb
@@ -202,6 +202,7 @@ var RepositoryDatatable = (function(global) {
         initHeaderTooltip();
         initRowSelection();
         bindExportActions();
+        disableCheckboxToggleOnAssetDownload();
       }
     });
 
@@ -289,6 +290,11 @@ var RepositoryDatatable = (function(global) {
     });
   }
 
+  function disableCheckboxToggleOnAssetDownload() {
+    $('.file-preview-link').on('click', function(ev) {
+      ev.stopPropagation();
+    });
+  }
 
   function appendInput(form, val, name) {
     $(form).append(
diff --git a/app/helpers/repository_datatable_helper.rb b/app/helpers/repository_datatable_helper.rb
index ba0175cc5..6638b00ca 100644
--- a/app/helpers/repository_datatable_helper.rb
+++ b/app/helpers/repository_datatable_helper.rb
@@ -31,18 +31,26 @@ module RepositoryDatatableHelper
       # Add custom columns
       record.repository_cells.each do |cell|
         row[columns_mappings[cell.repository_column.id]] =
-          custom_auto_link(
-            display_tooltip(cell.value.data,
-                            Constants::NAME_MAX_LENGTH),
-            simple_format: true,
-            team: team
-          )
+          display_cell_value(cell, team)
       end
       parsed_records << row
     end
     parsed_records
   end
 
+  def display_cell_value(cell, team)
+    if cell.value_type == 'RepositoryAssetValue'
+      render partial: 'repositories/asset_link',
+                      locals: { asset: cell.value.asset },
+                      formats: :html
+    else
+      custom_auto_link(display_tooltip(cell.value.data,
+                                       Constants::NAME_MAX_LENGTH),
+                       simple_format: true,
+                       team: team)
+    end
+  end
+
   def assigned_row(record, assigned_rows)
     if assigned_rows&.include?(record)
       "<span class='circle'>&nbsp;</span>"
diff --git a/app/services/repository_datatable_service.rb b/app/services/repository_datatable_service.rb
index 48c9935db..892236e32 100644
--- a/app/services/repository_datatable_service.rb
+++ b/app/services/repository_datatable_service.rb
@@ -16,7 +16,7 @@ class RepositoryDatatableService
   def create_columns_mappings
     # Make mappings of custom columns, so we have same id for every
     # column
-    index = 5
+    index = 6
     @mappings = {}
     @repository.repository_columns.order(:id).each do |column|
       @mappings[column.id] = index.to_s
@@ -59,12 +59,13 @@ class RepositoryDatatableService
                              'users.full_name',
                              'repository_rows.id'] +
                             Extends::REPOSITORY_EXTRA_SEARCH_ATTR
-
-    RepositoryRow.left_outer_joins(:created_by)
-                 .left_outer_joins(includes_json)
-                 .where(repository: @repository)
-                 .where_attributes_like(searchable_attributes, value)
-                 .distinct
+    ids = @repository.repository_rows
+                     .left_outer_joins(:created_by)
+                     .left_outer_joins(includes_json)
+                     .where_attributes_like(searchable_attributes, value)
+                     .pluck(:id)
+    # using distinct raises an error when combined with sort
+    RepositoryRow.where(id: ids.uniq)
   end
 
   def build_conditions(params)
@@ -151,12 +152,14 @@ class RepositoryDatatableService
 
   def select_type(type, records, id, dir)
     case type
-      when 'RepositoryTextValue'
-        filter_by_text_value(records, id, dir)
-      when  'RepositoryListValue'
-        filter_by_list_value(records, id, dir)
-      else
-        records
+    when 'RepositoryTextValue'
+      filter_by_text_value(records, id, dir)
+    when 'RepositoryListValue'
+      filter_by_list_value(records, id, dir)
+    when 'RepositoryAssetValue'
+      filter_by_asset_value(records, id, dir)
+    else
+      records
     end
   end
 
@@ -164,6 +167,20 @@ class RepositoryDatatableService
     val == 'ASC' ? 'LAST' : 'FIRST'
   end
 
+  def filter_by_asset_value(records, id, dir)
+    records.joins(
+      "LEFT OUTER JOIN (SELECT repository_cells.repository_row_id,
+        assets.file_file_name AS value
+      FROM repository_cells
+      INNER JOIN repository_asset_values
+      ON repository_asset_values.id = repository_cells.value_id
+      INNER JOIN assets
+      ON repository_asset_values.asset_id = assets.id
+      WHERE repository_cells.repository_column_id = #{id}) AS values
+      ON values.repository_row_id = repository_rows.id"
+    ).order("values.value #{dir}")
+  end
+
   def filter_by_text_value(records, id, dir)
     records.joins(
       "LEFT OUTER JOIN (SELECT repository_cells.repository_row_id,
diff --git a/app/views/repositories/_asset_link.html.erb b/app/views/repositories/_asset_link.html.erb
new file mode 100644
index 000000000..b34b7d7f3
--- /dev/null
+++ b/app/views/repositories/_asset_link.html.erb
@@ -0,0 +1,18 @@
+<% if asset.file_present %>
+  <% if asset.file.processing? %>
+    <span data-status='asset-loading'
+          data-present-url='<%= file_present_asset_path(asset.id) %>'>
+      <%= image_tag 'medium/processing.gif' %>
+    </span>
+  <% else %>
+    <%= link_to download_asset_path(asset),
+      class: 'file-preview-link',
+      id: "modal_link#{asset.id}",
+      data: { no_turbolink: true, id: true, status: 'asset-present', 'preview-url': asset_file_preview_path(asset) } do %>
+      <p><%= truncate(asset.file_file_name,
+                      length: Constants::FILENAME_TRUNCATION_LENGTH) %></p>
+    <% end %>
+  <% end %>
+<% else %>
+  <%= image_tag 'medium/processing.gif' %>
+<% end %>