Implement results tab for shareable task link [SCI-8753] (#5910)

* Implement results tab for shareable task link [SCI-8753]
This commit is contained in:
ajugo 2023-08-07 10:45:52 +02:00 committed by GitHub
parent 9a55889264
commit 6f76e86171
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 282 additions and 33 deletions

View file

@ -1,4 +1,4 @@
/* global tableColRowName*/
/* global tableColRowName notTurbolinksPreview */
(function() {
'use strict';
@ -8,9 +8,12 @@
}
function initStepsExpandCollapse() {
$(document).on('click', '.protocol-step-actions', function(event) {
let action = $(event.target).hasClass('steps-expand') ? 'show' : 'hide';
$('.step-container .collapse').collapse(action);
$(document).on('click', '#steps-collapse-btn', function() {
$('.step-container .collapse').collapse('hide');
});
$(document).on('click', '#steps-expand-btn', function() {
$('.step-container .collapse').collapse('show');
});
}
@ -68,5 +71,7 @@
});
}
initMyModuleProtocolShow();
if (notTurbolinksPreview()) {
initMyModuleProtocolShow();
}
}());

View file

@ -0,0 +1,56 @@
/* global notTurbolinksPreview */
(function() {
'use strict';
function initializeHandsonTable(el) {
var input = el.siblings('input.hot-table-contents');
var inputObj = JSON.parse(input.attr('value'));
var metadataJson = el.siblings('input.hot-table-metadata');
var data = inputObj.data;
var metadata;
metadata = JSON.parse(metadataJson.val() || '{}');
el.handsontable({
disableVisualSelection: true,
rowHeaders: true,
colHeaders: true,
editor: false,
copyPaste: false,
formulas: true,
data: data,
cell: metadata.cells || []
});
}
function initAttachments() {
$(document).on('click', '.shareable-file-preview-link, .shareable-gallery-switcher', function(e) {
e.preventDefault();
$('.modal-file-preview.in').modal('hide');
$($(`.modal-file-preview[data-object-id=${$(this).data('id')}]`)).modal('show');
});
}
function initResultsExpandCollapse() {
$(document).on('click', '#results-collapse-btn', function() {
$('.result .panel-collapse').collapse('hide');
});
$(document).on('click', '#results-expand-btn', function() {
$('.result .panel-collapse').collapse('show');
});
}
function initMyModuleResultsShow() {
initAttachments();
initResultsExpandCollapse();
$('.hot-table-container').each(function() {
initializeHandsonTable($(this));
});
}
if (notTurbolinksPreview()) {
initMyModuleResultsShow();
}
}());

View file

@ -4,23 +4,30 @@ class MyModuleShareableLinksController < ApplicationController
before_action :load_my_module, except: %i(protocol_show
repository_index_dt
repository_snapshot_index_dt
download_asset)
download_step_asset
download_result_asset
results_show)
before_action :check_view_permissions, only: :show
before_action :check_manage_permissions, except: %i(protocol_show
repository_index_dt
repository_snapshot_index_dt
download_asset)
download_step_asset
download_result_asset
results_show)
before_action :shareable_link_load_my_module, only: %i(protocol_show
repository_index_dt
repository_snapshot_index_dt
download_asset)
download_step_asset
download_result_asset
results_show)
before_action :load_repository, only: :repository_index_dt
before_action :load_repository_snapshot, only: :repository_snapshot_index_dt
before_action :load_asset, only: :download_asset
skip_before_action :authenticate_user!, only: %i(protocol_show
repository_index_dt
repository_snapshot_index_dt
download_asset)
download_step_asset
download_result_asset
results_show)
skip_before_action :verify_authenticity_token, only: %i(protocol_show
repository_index_dt
repository_snapshot_index_dt)
@ -34,6 +41,26 @@ class MyModuleShareableLinksController < ApplicationController
render 'shareable_links/my_module_protocol_show', layout: 'shareable_links'
end
def results_show
@results_order = params[:order] || 'new'
@results = @my_module.results.active
@results = @results.page(params[:page]).per(Constants::RESULTS_PER_PAGE_LIMIT)
@results = case @results_order
when 'old' then @results.order(created_at: :asc)
when 'old_updated' then @results.order(updated_at: :asc)
when 'new_updated' then @results.order(updated_at: :desc)
when 'atoz' then @results.order(name: :asc)
when 'ztoa' then @results.order(name: :desc)
else @results.order(created_at: :desc)
end
@gallery = @results.left_joins(:asset).pluck('assets.id').compact
render 'shareable_links/my_module_results_show', layout: 'shareable_links'
end
def repository_index_dt
@draw = params[:draw].to_i
per_page = params[:length].to_i < 1 ? Constants::REPOSITORY_DEFAULT_PAGE_SIZE : params[:length].to_i
@ -71,7 +98,20 @@ class MyModuleShareableLinksController < ApplicationController
render 'repository_rows/simple_view_index'
end
def download_asset
def download_step_asset
@asset = @my_module.assets_in_steps.find_by(id: params[:id])
return render_404 if @asset.blank?
redirect_to @asset.file.url(expires_in: Constants::URL_SHORT_EXPIRE_TIME.minutes, disposition: 'attachment'),
allow_other_host: true
end
def download_result_asset
@asset = @my_module.assets_in_results.find_by(id: params[:id])
return render_404 if @asset.blank?
redirect_to @asset.file.url(expires_in: Constants::URL_SHORT_EXPIRE_TIME.minutes, disposition: 'attachment'),
allow_other_host: true
end
@ -123,12 +163,6 @@ class MyModuleShareableLinksController < ApplicationController
@my_module = @shareable_link.shareable
end
def load_asset
@asset = @my_module.assets_in_steps.find_by(id: params[:id])
return render_404 if @asset.blank?
end
def load_repository
@repository = @my_module.assigned_repositories.find_by(id: params[:id])
render_404 unless @repository

View file

@ -37,7 +37,7 @@ module SecondaryNavigationHelper
end
def is_module_protocols?
%w(protocols my_module_protocol_show).include?(action_name)
%w(protocols protocol_show).include?(action_name)
end
def is_module_results?

View file

@ -0,0 +1,50 @@
<div class="text-3xl font-bold"><%= @my_module.name %></div>
<div class="px-4 my-5 flex-1 bg-sn-white">
<div class="content-pane flexible">
<%= render partial: 'shareable_links/my_modules/header_actions' %>
<div class="mt-5" id="results-toolbar">
<div class="sci-btn-group collapse-expand-result">
<button class="btn btn-light" id="results-collapse-btn">
<span class="sn-icon sn-icon-up"></span>
<span class="hidden-xs-custom"><%= t'my_modules.results.collapse_label' %></span>
</button>
<button class="btn btn-light" id="results-expand-btn">
<span class="sn-icon sn-icon-down"></span>
<span class="hidden-xs-custom"><%= t'my_modules.results.expand_label' %></span>
</button>
</div>
<div class="sort-result-dropdown dropdown">
<button id="sort-result-button" class="btn btn-light icon-btn" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<i class="sn-icon sn-icon-sort-up"></i>
</button>
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="sort-result-button">
<li><%= link_to t('general.sort_new.atoz'), shared_protocol_results_path(@shareable_link.uuid, page: params[:page], order: 'atoz'), class: (@results_order == 'atoz' ? 'selected' : '') %></li>
<li><%= link_to t('general.sort_new.ztoa'), shared_protocol_results_path(@shareable_link.uuid, page: params[:page], order: 'ztoa'), class: (@results_order == 'ztoa' ? 'selected' : '') %></li>
<li><%= link_to t('general.sort_new.old'), shared_protocol_results_path(@shareable_link.uuid, page: params[:page], order: 'old'), class: (@results_order == 'old' ? 'selected' : '') %></li>
<li><%= link_to t('general.sort_new.new'), shared_protocol_results_path(@shareable_link.uuid, page: params[:page], order: 'new'), class: (@results_order == 'new' ? 'selected' : '') %></li>
<li><%= link_to t('general.sort_new.old_updated'), shared_protocol_results_path(@shareable_link.uuid, page: params[:page], order: 'old_updated'), class: (@results_order == 'old_updated' ? 'selected' : '') %></li>
<li><%= link_to t('general.sort_new.new_updated'), shared_protocol_results_path(@shareable_link.uuid, page: params[:page], order: 'new_updated'), class: (@results_order == 'new_updated' ? 'selected' : '') %></li>
</ul>
</div>
</div>
<div id="results">
<% @results.each do |result| %>
<%= render partial: "shareable_links/my_modules/results/result", locals: { result: result, gallery: @gallery } %>
<% end %>
</div>
<div class="kaminari-pagination">
<%= paginate @results, outer_window: 1, window: 1 %>
</div>
</div>
</div>
<%= javascript_include_tag "handsontable.full" %>
<%= render 'shared/formulas_libraries' %>
<%= javascript_include_tag 'shareable_links/my_module_results_show' %>
<%= javascript_include_tag 'shared/file_preview' %>
<%= javascript_include_tag 'pdf_js' %>
<%= stylesheet_link_tag 'pdf_js_styles' %>

View file

@ -7,8 +7,8 @@
<div class="attachments">
<% attachments.each do |attachment| %>
<% if attachment.file.attached? %>
<%= render partial: "shareable_links/my_modules/step_attachments/#{ attachment.view_mode }", locals: { asset: attachment, step: step } %>
<%= render partial: "shareable_links/my_modules/step_attachments/file_preview", locals: { asset: attachment, gallery: attachments.pluck(:id) } %>
<%= render partial: "shareable_links/my_modules/step_attachments/#{ attachment.view_mode }", locals: { asset: attachment, show_context: true } %>
<%= render partial: "shareable_links/my_modules/step_attachments/file_preview", locals: { asset: attachment, gallery: attachments.pluck(:id) } %>
<% else %>
<%= attachment.view_mode %>
<%= render partial: "shareable_links/my_modules/step_attachments/empty", locals: { asset: attachment } %>

View file

@ -6,7 +6,7 @@
<%= t("nav2.modules.steps") %>
</a>
<a class="p-4 border-b-4 border-transparent hover:no-underline capitalize <%= is_module_results? ? "text-sn-blue" : "text-sn-grey" %>"
href="#"
href="<%= shared_protocol_results_path(@shareable_link.uuid) %>"
title="<%= t("nav2.modules.results") %>"
>
<%= t("nav2.modules.results") %>

View file

@ -47,11 +47,11 @@
<div id="protocol-steps-container">
<% if protocol.steps.length > 0 %>
<div class="protocol-step-actions">
<button class="btn btn-light steps-collapse" tabindex="0">
<button class="btn btn-light" id="steps-collapse-btn" tabindex="0">
<span class="sn-icon sn-icon-collapse"></span>
<%= t("protocols.steps.collapse_label") %>
</button>
<button class="btn btn-light steps-expand" tabindex="0">
<button class="btn btn-light" id="steps-expand-btn" tabindex="0">
<span class="sn-icon sn-icon-expand"></span>
<%= t("protocols.steps.expand_label") %>
</button>

View file

@ -0,0 +1,14 @@
<hr>
<div class="col-xs-12 comments-title">
<h4>
<%=t('my_modules.results.comments_tab') %>
(<span><%= comments.count %></span>)
</h4>
</div>
<div class="comments-container">
<div class="content-comments inline_scroll_block">
<div class="comments-list">
<%= render partial: "shareable_links/my_modules/results/comments_list", locals: { comments: comments } %>
</div>
</div>
</div>

View file

@ -0,0 +1,18 @@
<% comments.order(created_at: :asc).each do |comment| %>
<div class="comment-container">
<div class="avatar-placehodler">
<span class='global-avatar-container'>
<%= image_tag avatar_path(comment.user, :icon_small), class: 'avatar' %>
</span>
</div>
<div class="content-placeholder">
<div class="comment-name"><%= comment.user.full_name %></div>
<div class="comment-right !w-fit">
<div class="comment-datetime !w-fit"><%= comment.created_at.iso8601 %></div>
</div>
<div class="comment-message">
<div class="view-mode"><%= smart_annotation_text(comment.message) %></div>
</div>
</div>
</div>
<% end %>

View file

@ -0,0 +1,50 @@
<div class="result">
<div class="result-icon">
<% if result.is_text %>
<span class="sn-icon sn-icon-result-text"></span>
<% elsif result.is_table %>
<span class="sn-icon sn-icon-tables"></span>
<% elsif result.is_asset %>
<span class="sn-icon sn-icon-files"></span>
<% end %>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-options pull-right">
</div>
<a class="result-panel-collapse-link" href="#result-panel-<%= result.id %>" data-toggle="collapse">
<span class="sn-icon sn-icon-right"></span>
<strong><%= result.name %></strong> |
<span><%= t('my_modules.results.published_on_iso_html', timestamp: result.created_at.iso8601, user: h(result.user.full_name)) %></span>
</a>
</div>
<div class="panel-collapse collapse in" id="result-panel-<%= result.id %>" role="tabpanel">
<div class="panel-body">
<div class="row">
<div class="col-xs-12">
<% if result.is_text %>
<div class="ql-editor">
<%= smart_annotation_text(result.result_text.shareable_tinymce_render(:text)) %>
</div>
<% elsif result.is_table %>
<div class="hot-table">
<input type="hidden" class="hot-table-contents" value="<%= result.table.contents_utf_8 %>" />
<input type="hidden" class="hot-table-metadata" value="<%= result.table.metadata ? result.table.metadata.to_json : nil %>" />
<div class="hot-table-container"></div>
</div>
<% elsif result.is_asset %>
<%= render partial: "shareable_links/my_modules/step_attachments/#{ result.asset.view_mode }", locals: { asset: result.asset } %>
<%= render partial: "shareable_links/my_modules/step_attachments/file_preview", locals: { asset: result.asset, gallery: gallery } %>
<% end %>
</div>
</div>
<div class="row">
<div class="result-comment"
id="result-comments-<%= result.id %>">
<%= render partial: "shareable_links/my_modules/results/comments", locals: { comments: result.comments } %>
</div>
</div>
</div>
</div>
</div>
</div>

View file

@ -10,13 +10,21 @@
<div class="modal-header">
<span class="file-name"><%= asset.file.metadata[:name] || asset.file_name %></span>
<div class="sci-btn-group">
<%= link_to shared_protocol_asset_download_path(@shareable_link.uuid, asset),
class: 'btn btn-light file-download-link',
data: { turbolinks: false } do %>
<span class="sn-icon sn-icon-export"></span>
<%= t('Download') %>
<% if asset.step.present? %>
<%= link_to shared_protocol_asset_download_path(@shareable_link.uuid, asset),
class: 'btn btn-light file-download-link',
data: { turbolinks: false } do %>
<span class="sn-icon sn-icon-export"></span>
<%= t('Download') %>
<% end %>
<% elsif asset.result.present? %>
<%= link_to shared_protocol_result_asset_download_path(@shareable_link.uuid, asset),
class: 'btn btn-light file-download-link',
data: { turbolinks: false } do %>
<span class="sn-icon sn-icon-export"></span>
<%= t('Download') %>
<% end %>
<% end %>
<%= render partial: "shareable_links/my_modules/step_attachments/context_menu", locals: { asset: asset } %>
<button type="button" class="btn icon-btn btn-light" data-dismiss="modal"><span class="sn-icon sn-icon-close"></span></button>
</div>
</div>

View file

@ -19,7 +19,9 @@
<span><%= t('assets.placeholder.size_label', size: number_to_human_size(asset.file_size)) %></span>
</div>
</div>
<%= render partial: "shareable_links/my_modules/step_attachments/context_menu", locals: { asset: asset } %>
<% if defined?(show_context) && show_context %>
<%= render partial: "shareable_links/my_modules/step_attachments/context_menu", locals: { asset: asset } %>
<% end %>
</div>
<% if wopi_enabled? && wopi_file?(asset) %>
<iframe class="wopi-file-preview" src="<%= asset.get_action_url(nil, 'embedview', false) %>"></iframe>

View file

@ -17,5 +17,7 @@
<span><%= t('assets.placeholder.modified_label') %> <span class="iso-formatted-date"><%= asset.updated_at.iso8601 if asset.updated_at %></span></span>
<span><%= t('assets.placeholder.size_label', size: number_to_human_size(asset.file_size)) %></span>
</div>
<%= render partial: "shareable_links/my_modules/step_attachments/context_menu", locals: { asset: asset } %>
<% if defined?(show_context) && show_context %>
<%= render partial: "shareable_links/my_modules/step_attachments/context_menu", locals: { asset: asset } %>
<% end %>
</div>

View file

@ -26,5 +26,7 @@
<%= number_to_human_size(asset.file_size) %>
</div>
<% end %>
<%= render partial: "shareable_links/my_modules/step_attachments/context_menu", locals: { asset: asset } %>
<% if defined?(show_context) && show_context %>
<%= render partial: "shareable_links/my_modules/step_attachments/context_menu", locals: { asset: asset } %>
<% end %>
</div>

View file

@ -125,6 +125,7 @@ Rails.application.config.assets.precompile += %w(my_modules/shared/layout_overri
Rails.application.config.assets.precompile += %w(shareable_links/my_module_protocol_show.js)
Rails.application.config.assets.precompile += %w(shareable_links/repositories.js)
Rails.application.config.assets.precompile += %w(shareable_links/date_formatting.js)
Rails.application.config.assets.precompile += %w(shareable_links/my_module_results_show.js)
# Libraries needed for Handsontable formulas
Rails.application.config.assets.precompile += %w(jquery.js)

View file

@ -1209,6 +1209,7 @@ en:
new_table_result: "Table"
new_asset_result: "File"
published_on_html: "Added on <em>%{timestamp}</em> by <em>%{user}</em>"
published_on_iso_html: "Added on <em><span class='iso-formatted-date'>%{timestamp}</span></em> by <em>%{user}</em>"
published_table: "entered a table on %{timestamp}."
published_text: "entered a text on %{timestamp}."
published_asset: "uploaded a file on %{timestamp}."

View file

@ -966,8 +966,14 @@ Rails.application.routes.draw do
to: 'my_module_shareable_links#protocol_show',
as: :shared_protocol
get '/shared/:uuid/protocol/asset/:id/download',
to: 'my_module_shareable_links#download_asset',
to: 'my_module_shareable_links#download_step_asset',
as: :shared_protocol_asset_download
get '/shared/:uuid/protocol/asset/:id/download_result',
to: 'my_module_shareable_links#download_result_asset',
as: :shared_protocol_result_asset_download
get '/shared/:uuid/protocol/results',
to: 'my_module_shareable_links#results_show',
as: :shared_protocol_results
post '/shared/:uuid/repositories/:id/items',
to: 'my_module_shareable_links#repository_index_dt',
as: :shared_protocol_items,