diff --git a/app/assets/javascripts/protocols/index.js b/app/assets/javascripts/protocols/index.js index 844f9bb75..eed54dc7c 100644 --- a/app/assets/javascripts/protocols/index.js +++ b/app/assets/javascripts/protocols/index.js @@ -16,6 +16,7 @@ function init() { initProtocolsTable(); initRowSelection(); initKeywordFiltering(); + initProtocolPreviewModal(); initLinkedChildrenModal(); initCreateNewModal(); initModals(); @@ -187,6 +188,37 @@ function initKeywordFiltering() { }); } +function initProtocolPreviewModal() { + // Only do this if the repository is public/private + if (repositoryType !== "archive") { + protocolsTableEl.on("click", "a[data-action='protocol-preview']", function(e) { + var link = $(this); + $.ajax({ + url: link.attr("data-url"), + type: "GET", + dataType: "json", + success: function (data) { + var modal = $("#protocol-preview-modal"); + var modalTitle = modal.find(".modal-title"); + var modalBody = modal.find(".modal-body"); + var modalFooter = modal.find(".modal-footer"); + modalTitle.html(data.title); + modalBody.html(data.html); + modalFooter.html(data.footer); + initHandsOnTable(modalBody); + modal.modal("show"); + initHandsOnTable(modalBody); + }, + error: function (error) { + // TODO + } + }); + e.preventDefault(); + return false; + }); + } +} + function initLinkedChildrenModal() { // Only do this if the repository is public/private if (repositoryType !== "archive") { @@ -343,6 +375,13 @@ function initModals() { $(this).find(".modal-body #linked-children-table").DataTable().destroy(); $(this).find(".modal-body").html(""); }); + + // Protocol preview modal close action + $("#protocol-preview-modal").on("hidden.bs.modal", function(e) { + $(this).find(".modal-title").html(""); + $(this).find(".modal-body").html(""); + $(this).find(".modal-footer").html(""); + }); } function updateDataTableSelectAllCheckbox() { diff --git a/app/assets/stylesheets/themes/scinote.scss b/app/assets/stylesheets/themes/scinote.scss index 067fc0128..b96b025b5 100644 --- a/app/assets/stylesheets/themes/scinote.scss +++ b/app/assets/stylesheets/themes/scinote.scss @@ -1139,6 +1139,25 @@ ul.content-module-activities { } } +// Preview protocol modal +@media (min-width: 768px) { + #protocol-preview-modal .modal-dialog { + width: 70%; + } +} + +#protocol-preview-modal .modal-dialog { + .modal-body { + max-height: 75vh; + overflow-y: auto; + width: 100%; + + .ql-editor { + min-height: initial; + } + } +} + /* Import protocol/s modal */ #import-protocol-modal .modal-dialog { width: 70%; diff --git a/app/controllers/protocols_controller.rb b/app/controllers/protocols_controller.rb index 0f715831a..578e9d806 100644 --- a/app/controllers/protocols_controller.rb +++ b/app/controllers/protocols_controller.rb @@ -11,6 +11,7 @@ class ProtocolsController < ApplicationController before_action :check_view_permissions, only: [ :protocol_status_bar, :updated_at_label, + :preview, :linked_children, :linked_children_datatable ] @@ -80,6 +81,25 @@ class ProtocolsController < ApplicationController end end + def preview + respond_to do |format| + format.json do + render json: { + title: I18n.t('protocols.index.preview.title', + protocol: @protocol.name), + html: render_to_string( + partial: 'protocols/index/protocol_preview_modal_body.html.erb', + locals: { protocol: @protocol } + ), + footer: render_to_string( + partial: 'protocols/index/protocol_preview_modal_footer.html.erb', + locals: { protocol: @protocol } + ) + } + end + end + end + def linked_children respond_to do |format| format.json { diff --git a/app/datatables/protocols_datatable.rb b/app/datatables/protocols_datatable.rb index 59abf56ac..1c6ecab6c 100644 --- a/app/datatables/protocols_datatable.rb +++ b/app/datatables/protocols_datatable.rb @@ -12,6 +12,7 @@ class ProtocolsDatatable < AjaxDatatablesRails::Base def_delegator :@view, :can_restore_protocol def_delegator :@view, :can_export_protocol def_delegator :@view, :linked_children_protocol_path + def_delegator :@view, :preview_protocol_path def initialize(view, organization, type, user) super(view) @@ -94,7 +95,7 @@ class ProtocolsDatatable < AjaxDatatablesRails::Base "DT_CanArchive": can_archive_protocol(protocol), "DT_CanRestore": can_restore_protocol(protocol), "DT_CanExport": can_export_protocol(protocol), - "1": record.name, + "1": protocol.in_repository_archived? ? record.name : name_html(record), "2": keywords_html(record), "3": modules_html(record), "4": record.full_username_str, @@ -164,6 +165,13 @@ class ProtocolsDatatable < AjaxDatatablesRails::Base end end + def name_html(record) + "" \ + "#{record.name}" \ + "" + end + def keywords_html(record) if !record.protocol_keywords_str || record.protocol_keywords_str.empty? "#{I18n.t("protocols.no_keywords")}" diff --git a/app/views/protocols/index.html.erb b/app/views/protocols/index.html.erb index 02a22d0e6..b7be9f1b9 100644 --- a/app/views/protocols/index.html.erb +++ b/app/views/protocols/index.html.erb @@ -130,8 +130,23 @@ <%= render partial: "protocols/index/restore_results_modal.html.erb" %> <%= render partial: "protocols/index/import_results_modal.html.erb" %> <%= render partial: "protocols/index/linked_children_modal.html.erb" %> +<%= render partial: "protocols/index/protocol_preview_modal.html.erb" %> <%= render partial: "protocols/import_export/import_elements.html.erb" %> <%= stylesheet_link_tag 'datatables' %> <%= javascript_include_tag "protocols/index" %> +<%= javascript_include_tag "protocols/steps" %> + + +<%= javascript_include_tag "lodash" %> +<%= javascript_include_tag "numeral" %> +<%= javascript_include_tag "numeric" %> +<%= javascript_include_tag "md5" %> +<%= javascript_include_tag "jstat" %> +<%= javascript_include_tag "formula" %> +<%= javascript_include_tag "parser" %> +<%= javascript_include_tag "ruleJS" %> +<%= javascript_include_tag "handsontable.formula" %> +<%= javascript_include_tag "big.min" %> +<%= stylesheet_link_tag "handsontable.formula" %> \ No newline at end of file diff --git a/app/views/protocols/index/_protocol_preview_modal.html.erb b/app/views/protocols/index/_protocol_preview_modal.html.erb new file mode 100644 index 000000000..68f35c55b --- /dev/null +++ b/app/views/protocols/index/_protocol_preview_modal.html.erb @@ -0,0 +1,13 @@ + diff --git a/app/views/protocols/index/_protocol_preview_modal_body.html.erb b/app/views/protocols/index/_protocol_preview_modal_body.html.erb new file mode 100644 index 000000000..ea4530bf9 --- /dev/null +++ b/app/views/protocols/index/_protocol_preview_modal_body.html.erb @@ -0,0 +1,164 @@ +
+
+
+ +
+
+ + <%= l(@protocol.created_at, format: :full) %> +
+
+ +
+
+ +
+
+ + <%= render partial: "protocols/header/updated_at_label.html.erb" %> +
+
+ +
+
+ +
+
+ + <%= @protocol.added_by.full_name %> +
+
+ +
+
+ +
+
+ + <%= render partial: "protocols/header/keywords_label.html.erb" %> +
+
+ +
+
+ +
+
+ + <%= render partial: "protocols/header/authors_label.html.erb" %> +
+
+ +
+
+ +
+
+ + <%= render partial: "protocols/header/description_label.html.erb" %> +
+
+
+ +
+
+
+

<%= t("protocols.steps.subtitle") %>

+
+
+
+ <% protocol.steps.order(:position).each do |step| %> +
"> +
+ <%= step.position + 1 %> +
+
+
+ <%= step.name %> | + <%= raw t("protocols.steps.published_on", timestamp: l(step.created_at, format: :full), user: step.user.full_name) %> +
+
+
+
+
+ <% if strip_tags(step.description).blank? %> + <%= t("protocols.steps.no_description") %> + <% else %> +
+ <%= step.description.html_safe %> +
+ <% end %> +
+
+
+ <% unless step.tables.blank? then %> +
+
+ <%= t("protocols.steps.tables") %> + <% step.tables.each do |table| %> +
+ <%= hidden_field(table, :contents, value: table.contents_utf_8, class: "hot-contents") %> +
+
+ <% end %> +
+ <% end %> + + <% assets = ordered_assets(step) %> + <% unless assets.blank? then %> +
+
+ <%= t("protocols.steps.files") %> +
    + <% assets.each do |asset| %> +
  • + <%= image_tag preview_asset_path(asset) if asset.is_image? %> +

    <%= truncate(asset.file_file_name, + length: Constants::FILENAME_TRUNCATION_LENGTH) %>

    +
  • + <% end %> +
+
+ <% end %> + + <% unless step.checklists.blank? then %> +
+
+ <% step.checklists.each do |checklist| %> + <%= checklist.name %> + <% if checklist.checklist_items.empty? %> +
+ <%= t("protocols.steps.empty_checklist") %> +
+ <% else %> + <% ordered_checklist_items(checklist).each do |checklist_item| %> +
+ +
+ <% end %> + <% end %> + <% end %> +
+ <% end %> + +
+
+
+
+
+ <% end %> +
+ + <% if protocol.steps.count == 0 %> +
+ <%= t("protocols.steps.no_steps") %> +
+ <% end %> +
diff --git a/app/views/protocols/index/_protocol_preview_modal_footer.html.erb b/app/views/protocols/index/_protocol_preview_modal_footer.html.erb new file mode 100644 index 000000000..430b7e028 --- /dev/null +++ b/app/views/protocols/index/_protocol_preview_modal_footer.html.erb @@ -0,0 +1,4 @@ + +<% if can_edit_protocol(@protocol) %> + <%= link_to t("general.edit"), edit_protocol_path(@protocol), :class => "btn btn-primary" %> +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 29bdaa123..8fc727208 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1230,6 +1230,8 @@ en: thead_created_at: "Created at" thead_archived_on: "Archived at" thead_updated_at: "Last modified at" + preview: + title: "%{protocol} preview" linked_children: title: "Tasks linked to protocol %{protocol}" used_in: "Number of tasks linked to this protocol: %{nr}" diff --git a/config/routes.rb b/config/routes.rb index 045738fa8..69032ff52 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -259,6 +259,7 @@ Rails.application.routes.draw do member do get "linked_children", to: "protocols#linked_children" post "linked_children_datatable", to: "protocols#linked_children_datatable" + get 'preview', to: 'protocols#preview' patch "metadata", to: "protocols#update_metadata" patch "keywords", to: "protocols#update_keywords" post "clone", to: "protocols#clone"