mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-02-05 14:41:53 +08:00
Prepare styled listing of protocols [SCI-3535] (#1870)
Prepare styled listing of protocols [SCI-3535]
This commit is contained in:
commit
692a5aff15
14 changed files with 403 additions and 249 deletions
|
@ -1,25 +1,214 @@
|
|||
function applyClickCallbackOnProtocolCards() {
|
||||
$('.protocol-card').off('click').on('click', function(e) {
|
||||
var currProtocolCard = $(this);
|
||||
|
||||
// Check whether this card is already active and deactivate it
|
||||
if ($(currProtocolCard).hasClass('active')) {
|
||||
resetPreviewPanel();
|
||||
$(currProtocolCard).removeClass('active');
|
||||
} else {
|
||||
$('.protocol-card').removeClass('active');
|
||||
currProtocolCard.addClass('active');
|
||||
|
||||
$.ajax({
|
||||
url: $(currProtocolCard).data('show-url'),
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
protocol_source: $(currProtocolCard).data('protocol-source'),
|
||||
protocol_id: $(currProtocolCard).data('show-protocol-id')
|
||||
},
|
||||
beforeSend: animateSpinner($('.protocol-preview-panel'), true),
|
||||
success: function(data) {
|
||||
$('.empty-preview-panel').hide();
|
||||
$('.full-preview-panel').show();
|
||||
$('.btn-holder').html($(currProtocolCard).find('.external-import-btn').clone());
|
||||
$('.preview-iframe').contents().find('body').html(data.html);
|
||||
|
||||
initLoadProtocolModalPreview();
|
||||
animateSpinner($('.protocol-preview-panel'), false);
|
||||
},
|
||||
error: function(_error) {
|
||||
// TODO: we should probably show some alert bubble
|
||||
resetPreviewPanel();
|
||||
animateSpinner($('.protocol-preview-panel'), false);
|
||||
}
|
||||
});
|
||||
}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// Resets preview to the default state
|
||||
function resetPreviewPanel() {
|
||||
$('.empty-preview-panel').show();
|
||||
$('.full-preview-panel').hide();
|
||||
}
|
||||
|
||||
// Reset whole view to the default state
|
||||
function setDefaultViewState() {
|
||||
resetPreviewPanel();
|
||||
$('.empty-text').show();
|
||||
$('.list-wrapper').hide();
|
||||
}
|
||||
|
||||
// Apply AJAX callbacks onto the search box
|
||||
function applySearchCallback() {
|
||||
var timeout;
|
||||
|
||||
// Submit form on every input in the search box
|
||||
$('input[name="key"]').off('input').on('input', function() {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
|
||||
timeout = setTimeout(function() {
|
||||
$('form.protocols-search-bar').submit();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
// Submit form when clicking on sort buttons
|
||||
$('input[name="sort_by"]').off('change').on('change', function() {
|
||||
$('form.protocols-search-bar').submit();
|
||||
});
|
||||
|
||||
// Bind ajax calls on the form
|
||||
$('form.protocols-search-bar').off('ajax:success').off('ajax:error')
|
||||
.bind('ajax:success', function(evt, data, status, xhr) {
|
||||
if (data.html) {
|
||||
resetPreviewPanel();
|
||||
$('.empty-text').hide();
|
||||
$('.list-wrapper').show();
|
||||
|
||||
$('.list-wrapper').html(data.html);
|
||||
applyClickCallbackOnProtocolCards();
|
||||
initLoadProtocolModalPreview();
|
||||
} else {
|
||||
setDefaultViewState();
|
||||
}
|
||||
})
|
||||
.bind("ajax:error", function(evt, xhr, status, error) {
|
||||
setDefaultViewState();
|
||||
|
||||
console.log(xhr.responseText);
|
||||
});
|
||||
}
|
||||
|
||||
function resetFormErrors(modal) {
|
||||
// Reset all errors
|
||||
modal.find('form > .form-group.has-error').removeClass('has-error');
|
||||
modal.find('form > .form-group>span.help-block').html('');
|
||||
modal.find('.general-error > span').html('');
|
||||
}
|
||||
|
||||
function showFormErrors(modal, errors) {
|
||||
resetFormErrors(modal);
|
||||
|
||||
// AR valdiation errors
|
||||
Object.keys(errors.protocol).forEach(function(key) {
|
||||
var input = modal.find('#protocol_' + key);
|
||||
var msg;
|
||||
msg = key.charAt(0).toUpperCase() + key.slice(1) + ': ' + errors.protocol[key].join(', ');
|
||||
if ((input.length > 0) && (errors.protocol[key].length > 0)) {
|
||||
input.parent().next('span.help-block').html(msg);
|
||||
input.parent().parent().addClass('has-error');
|
||||
} else if (errors.protocol[key].length > 0) {
|
||||
modal.find('.general-error > span').append(msg + '<br/>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderTable(table) {
|
||||
$(table).handsontable('render');
|
||||
// Yet another dirty hack to solve HandsOnTable problems
|
||||
if (parseInt($(table).css('height'), 10) < parseInt($(table).css('max-height'), 10) - 30) {
|
||||
$(table).find('.ht_master .wtHolder').css({ height: '100%', width: '100%' });
|
||||
}
|
||||
}
|
||||
|
||||
// Expand all steps
|
||||
function expandAllSteps() {
|
||||
$('.step .panel-collapse').collapse('show');
|
||||
$(document).find("[data-role='step-hot-table']").each(function() {
|
||||
renderTable($(this));
|
||||
});
|
||||
$(document).find('span.collapse-step-icon').each(function() {
|
||||
$(this).addClass('fa-caret-square-up');
|
||||
$(this).removeClass('fa-caret-square-down');
|
||||
});
|
||||
}
|
||||
|
||||
function handleFormSubmit(modal) {
|
||||
var form = modal.find('form');
|
||||
form.on('submit', function(e) {
|
||||
var url = form.attr('action');
|
||||
e.preventDefault(); // avoid to execute the actual submit of the form.
|
||||
e.stopPropagation();
|
||||
animateSpinner(modal, true);
|
||||
$.ajax({
|
||||
url: $(this).data('show-url'),
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
protocol_source: $(this).data('protocol-source'),
|
||||
protocol_id: $(this).data('show-protocol-id')
|
||||
},
|
||||
beforeSend: animateSpinner($('.protocol-preview-panel'), true),
|
||||
type: 'POST',
|
||||
url: url,
|
||||
data: form.serialize(), // serializes the form's elements.
|
||||
success: function(data) {
|
||||
$('.empty-preview-panel').hide();
|
||||
$('.full-preview-panel').show();
|
||||
$('.preview-iframe').contents().find('body').html(data.html);
|
||||
animateSpinner($('.protocol-preview-panel'), false);
|
||||
animateSpinner(modal, false);
|
||||
window.location.replace(data.redirect_url);
|
||||
},
|
||||
error: function(_error) {
|
||||
// TODO: we should probably show some alert bubble
|
||||
$('.empty-preview-panel').show();
|
||||
$('.full-preview-panel').hide();
|
||||
animateSpinner($('.protocol-preview-panel'), false);
|
||||
error: function(data) {
|
||||
showFormErrors(modal, data.responseJSON.errors);
|
||||
},
|
||||
complete: function() {
|
||||
animateSpinner(modal, false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function initLoadProtocolModalPreview() {
|
||||
$('.external-import-btn').off('click').on('click', function(e) {
|
||||
var link = $(this).parents('.protocol-card');
|
||||
|
||||
// When clicking on the banner button, we have no protocol-card parent
|
||||
if (link.length === 0) {
|
||||
link = $('.protocol-card.active');
|
||||
}
|
||||
|
||||
animateSpinner(null, true);
|
||||
$.ajax({
|
||||
url: link.data('url'),
|
||||
type: 'GET',
|
||||
data: {
|
||||
protocol_source: link.data('protocol-source'),
|
||||
protocol_client_id: link.data('id')
|
||||
},
|
||||
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');
|
||||
expandAllSteps();
|
||||
initHandsOnTable(modalBody);
|
||||
|
||||
if (data.validation_errors) {
|
||||
showFormErrors(modal, data.validation_errors);
|
||||
}
|
||||
|
||||
initFormSubmits();
|
||||
handleFormSubmit(modal);
|
||||
},
|
||||
error: function(error) {
|
||||
console.log(error.responseJSON.errors);
|
||||
alert('Server error');
|
||||
},
|
||||
complete: function() {
|
||||
animateSpinner(null, false);
|
||||
}
|
||||
});
|
||||
e.preventDefault();
|
||||
|
@ -27,4 +216,14 @@ function applyClickCallbackOnProtocolCards() {
|
|||
});
|
||||
}
|
||||
|
||||
applyClickCallbackOnProtocolCards();
|
||||
function initFormSubmits() {
|
||||
var modal = $('#protocol-preview-modal');
|
||||
modal.find('button[data-action=import_protocol]').off('click').on('click', function() {
|
||||
var form = modal.find('form');
|
||||
var hiddenField = form.find('#protocol_protocol_type');
|
||||
hiddenField.attr('value', $(this).data('import_type'));
|
||||
form.submit();
|
||||
});
|
||||
}
|
||||
|
||||
applySearchCallback();
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
/* global animateSpinner initHandsOnTable */
|
||||
/* eslint-disable no-restricted-globals, no-alert */
|
||||
|
||||
var ExternalProtocols = (function() {
|
||||
function resetFormErrors(modal) {
|
||||
// Reset all errors
|
||||
modal.find('form > .form-group.has-error').removeClass('has-error');
|
||||
modal.find('form > .form-group>span.help-block').html('');
|
||||
modal.find('.general-error > span').html('');
|
||||
}
|
||||
|
||||
function showFormErrors(modal, errors) {
|
||||
resetFormErrors(modal);
|
||||
|
||||
// AR valdiation errors
|
||||
Object.keys(errors.protocol).forEach(function(key) {
|
||||
var input = modal.find('#protocol_' + key);
|
||||
var msg;
|
||||
msg = key.charAt(0).toUpperCase() + key.slice(1) + ': ' + errors.protocol[key].join(', ');
|
||||
if ((input.length > 0) && (errors.protocol[key].length > 0)) {
|
||||
input.parent().next('span.help-block').html(msg);
|
||||
input.parent().parent().addClass('has-error');
|
||||
} else if (errors.protocol[key].length > 0) {
|
||||
modal.find('.general-error > span').append(msg + '<br/>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderTable(table) {
|
||||
$(table).handsontable('render');
|
||||
// Yet another dirty hack to solve HandsOnTable problems
|
||||
if (parseInt($(table).css('height'), 10) < parseInt($(table).css('max-height'), 10) - 30) {
|
||||
$(table).find('.ht_master .wtHolder').css({ height: '100%', width: '100%' });
|
||||
}
|
||||
}
|
||||
|
||||
// Expand all steps
|
||||
function expandAllSteps() {
|
||||
$('.step .panel-collapse').collapse('show');
|
||||
$(document).find("[data-role='step-hot-table']").each(function() {
|
||||
renderTable($(this));
|
||||
});
|
||||
$(document).find('span.collapse-step-icon').each(function() {
|
||||
$(this).addClass('fa-caret-square-up');
|
||||
$(this).removeClass('fa-caret-square-down');
|
||||
});
|
||||
}
|
||||
|
||||
function handleFormSubmit(modal) {
|
||||
var form = modal.find('form');
|
||||
form.on('submit', function(e) {
|
||||
var url = form.attr('action');
|
||||
e.preventDefault(); // avoid to execute the actual submit of the form.
|
||||
e.stopPropagation();
|
||||
animateSpinner(modal, true);
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: url,
|
||||
data: form.serialize(), // serializes the form's elements.
|
||||
success: function(data) {
|
||||
animateSpinner(modal, false);
|
||||
window.location.replace(data.redirect_url);
|
||||
},
|
||||
error: function(data) {
|
||||
showFormErrors(modal, data.responseJSON.errors);
|
||||
},
|
||||
complete: function() {
|
||||
animateSpinner(modal, false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function initLoadProtocolModalPreview() {
|
||||
var externalProtocols = $('.external-protocol-result');
|
||||
externalProtocols.on('click', 'a[data-action="external-import"]', function(e) {
|
||||
var link = $(this);
|
||||
animateSpinner(null, true);
|
||||
$.ajax({
|
||||
url: link.attr('data-url'),
|
||||
type: 'GET',
|
||||
data: {
|
||||
protocol_source: link.attr('data-source'),
|
||||
protocol_client_id: link.attr('data-id')
|
||||
},
|
||||
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');
|
||||
expandAllSteps();
|
||||
initHandsOnTable(modalBody);
|
||||
|
||||
if (data.validation_errors) {
|
||||
showFormErrors(modal, data.validation_errors);
|
||||
}
|
||||
|
||||
handleFormSubmit(modal);
|
||||
},
|
||||
error: function(error) {
|
||||
console.log(error.responseJSON.errors);
|
||||
alert('Server error');
|
||||
},
|
||||
complete: function() {
|
||||
animateSpinner(null, false);
|
||||
}
|
||||
});
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function initFormSubmits() {
|
||||
var modal = $('#protocol-preview-modal');
|
||||
modal.on('click', 'button[data-action=import_protocol]', function() {
|
||||
var form = modal.find('form');
|
||||
var hiddenField = form.find('#protocol_protocol_type');
|
||||
hiddenField.attr('value', $(this).data('import_type'));
|
||||
form.submit();
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: () => {
|
||||
if ($('.external-protocols-tab').length > 0) {
|
||||
initLoadProtocolModalPreview();
|
||||
initFormSubmits();
|
||||
}
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
||||
$(document).on('turbolinks:load', function() {
|
||||
ExternalProtocols.init();
|
||||
});
|
|
@ -74,6 +74,12 @@
|
|||
margin-bottom: 15px;
|
||||
padding-right: 0;
|
||||
|
||||
.service-provider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.protocolsio-logo {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
|
@ -82,25 +88,20 @@
|
|||
.protocolsio-title {
|
||||
color: $brand-primary;
|
||||
font-size: 14px;
|
||||
margin-left: 3px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.protocols-search-bar {
|
||||
padding-right: 0;
|
||||
width: 70%;
|
||||
.input-group {
|
||||
margin-bottom: 0;
|
||||
|
||||
.input-group {
|
||||
margin-bottom: 0;
|
||||
width: 100%;
|
||||
.form-control {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.input-group-addon {
|
||||
background: $color-white;
|
||||
color: $color-silver-chalice;
|
||||
}
|
||||
.input-group-addon {
|
||||
background: $color-white;
|
||||
color: $color-silver-chalice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,6 +150,40 @@
|
|||
font-size: 13px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.list-wrapper {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.protocol-card {
|
||||
border-bottom: 1px solid $color-gainsboro;
|
||||
margin-right: 20px;
|
||||
padding: 12px 11px 7px 11px;
|
||||
|
||||
&.active {
|
||||
border: 2px solid $brand-primary;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 4px 0 $color-black;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64,161,215,0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.protocol-title {
|
||||
color: $brand-primary;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.info-line {
|
||||
color: $color-dove-gray;
|
||||
font-size: 13px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.protocol-preview-panel {
|
||||
|
@ -188,10 +223,35 @@
|
|||
}
|
||||
|
||||
.full-preview-panel {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.preview-banner {
|
||||
align-items: center;
|
||||
background-color: $color-white;
|
||||
border-bottom: 1px solid $color-alto;
|
||||
color: $color-dove-gray;
|
||||
display: flex;
|
||||
font-size: 16px;
|
||||
height: 40px;
|
||||
padding-left: 21px;
|
||||
|
||||
.txt-holder {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.btn-holder {
|
||||
padding-right: 21px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.preview-holder {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding-bottom: 40px;
|
||||
padding-left: 21px;
|
||||
padding-right: 21px;
|
||||
width: 100%;
|
||||
|
@ -204,4 +264,13 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.external-import-btn {
|
||||
background-color: $brand-primary;
|
||||
border: none;
|
||||
color: $color-white;
|
||||
font-size: 12px;
|
||||
padding-bottom: 3px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@ class ExternalProtocolsController < ApplicationController
|
|||
# GET list_external_protocols
|
||||
def index
|
||||
service_call = ProtocolImporters::SearchProtocolsService
|
||||
.call(protocol_source: 'protocolsio/v3', query_params: index_params)
|
||||
.call(protocol_source: index_params[:protocol_source],
|
||||
query_params: index_params)
|
||||
|
||||
if service_call.succeed?
|
||||
render json: {
|
||||
|
@ -101,7 +102,7 @@ class ExternalProtocolsController < ApplicationController
|
|||
end
|
||||
|
||||
def index_params
|
||||
params.permit(:protocol_source, :key, :page_id, :page_size, :order_field, :order_dir)
|
||||
params.permit(:protocol_source, :key, :page_id, :page_size, :sort_by)
|
||||
end
|
||||
|
||||
def show_params
|
||||
|
|
|
@ -11,7 +11,7 @@ module ProtocolImporters
|
|||
|
||||
def initialize(protocol_source:, query_params: {})
|
||||
@protocol_source = protocol_source
|
||||
@query_params = query_params
|
||||
@query_params = query_params.except(:protocol_source)
|
||||
@errors = Hash.new { |h, k| h[k] = {} }
|
||||
end
|
||||
|
||||
|
@ -51,16 +51,6 @@ module ProtocolImporters
|
|||
@errors[:invalid_params][:page_id] = 'Page needs to be positive'
|
||||
end
|
||||
|
||||
# try if order_field is ok
|
||||
if @query_params[:order_field] && CONSTANTS[:available_order_fields].exclude?(@query_params[:order_field]&.to_sym)
|
||||
@errors[:invalid_params][:order_field] = 'Order field is not ok'
|
||||
end
|
||||
|
||||
# try if order dir is ok
|
||||
if @query_params[:order_field] && CONSTANTS[:available_order_dirs].exclude?(@query_params[:order_dir]&.to_sym)
|
||||
@errors[:invalid_params][:order_dir] = 'Order dir is not ok'
|
||||
end
|
||||
|
||||
# try if endpints exists
|
||||
@errors[:invalid_params][:source_endpoint] = 'Wrong source endpoint' unless endpoint_name&.is_a?(String)
|
||||
|
||||
|
|
|
@ -44,8 +44,13 @@ module ProtocolImporters
|
|||
# Default is 1.
|
||||
def protocol_list(query_params = {})
|
||||
response = with_handle_network_errors do
|
||||
sort_mappings = CONSTANTS[:sort_mappings]
|
||||
query = CONSTANTS.dig(:endpoints, :protocols, :default_query_params)
|
||||
.merge(query_params)
|
||||
.merge(query_params.except(:sort_by))
|
||||
|
||||
if sort_mappings[query_params[:sort_by]&.to_sym]
|
||||
query = query.merge(sort_mappings[query_params[:sort_by].to_sym])
|
||||
end
|
||||
|
||||
self.class.get('/protocols', query: query)
|
||||
end
|
||||
|
|
|
@ -50,11 +50,17 @@ module ProtocolImporters
|
|||
original_order = protocol_hash[:steps].map { |m| [m[:previous_id], m[:id]] }.to_h
|
||||
current_position = 0
|
||||
while next_step_id
|
||||
|
||||
current_position += 1
|
||||
steps[next_step_id][:position] = current_position
|
||||
next_step_id = original_order[next_step_id]
|
||||
end
|
||||
|
||||
# Check if step name are valid
|
||||
steps.each do |step|
|
||||
step[1][:name] = "Step #{(step[1][:position] + 1)}" if step[1][:name].blank?
|
||||
end
|
||||
|
||||
{ protocol: normalized_data }
|
||||
rescue StandardError => e
|
||||
raise ProtocolImporters::ProtocolsIO::V3::NormalizerError.new(e.class.to_s.downcase.to_sym), e.message
|
||||
|
@ -69,6 +75,7 @@ module ProtocolImporters
|
|||
{
|
||||
id: e[:id],
|
||||
title: e[:title],
|
||||
source: Constants::PROTOCOLS_IO_V3_API[:source_id],
|
||||
created_on: e[:created_on],
|
||||
authors: e[:authors].map { |a| a[:name] }.join(', '),
|
||||
nr_of_steps: e[:stats][:number_of_steps],
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<% protocols.each do |protocol| %>
|
||||
<% protocols[:protocols].each do |protocol| %>
|
||||
<%= render partial: 'protocol_importers/protocol_card',
|
||||
locals: { protocol: protocol } %>
|
||||
<hr>
|
||||
<% end %>
|
||||
|
|
|
@ -1,3 +1,23 @@
|
|||
<div class='protocol-card'>
|
||||
<h2><%= protocol[:name] %></h2>
|
||||
<div class='protocol-card'
|
||||
data-id='<%= protocol[:id] %>'
|
||||
data-protocol-source='<%= protocol[:source] %>'
|
||||
data-url='<%= team_build_external_protocol_path(current_team.id,) %>'
|
||||
data-show-url='<%= team_show_external_protocol_path(current_team.id) %>'
|
||||
data-show-protocol-id='<%= protocol[:uri] %>'>
|
||||
<p class='protocol-title'><%= protocol[:title] %></p>
|
||||
|
||||
<div class='row'>
|
||||
<div class='row col-md-12 info-line'>
|
||||
<%= l(Time.at(protocol[:created_on]).to_datetime, format: :full_date) %> • <%= protocol[:authors] %>
|
||||
</div>
|
||||
|
||||
<div class='row'>
|
||||
<div class='col-md-6 info-line'>
|
||||
<%= t('protocol_importers.card.views_and_steps', nr_of_views: protocol[:nr_of_views], nr_of_steps: protocol[:nr_of_steps]) %>
|
||||
</div>
|
||||
<div class='col-md-6 info-line'>
|
||||
<button type="button" class='external-import-btn btn btn-primary pull-right'><%= t('protocol_importers.card.import_button_text') %></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,92 +1,75 @@
|
|||
<div class='external-protocols-tab'>
|
||||
<div class='row'>
|
||||
<div class='col-md-5 protocols-search-bar-panel'>
|
||||
<%= form_tag team_list_external_protocol_path(@current_team.id),
|
||||
method: :get,
|
||||
class: 'protocols-search-bar',
|
||||
remote: true do %>
|
||||
<div class='col-md-5 protocols-search-bar-panel'>
|
||||
<div class='service-provider'>
|
||||
<%= image_tag 'external_protocols/protocolsio_logo.png',
|
||||
class: 'protocolsio-logo' %>
|
||||
<span class='protocolsio-title'><%= t('protocols.index.external_protocols.protocolsio_title') %></span>
|
||||
<%= hidden_field_tag 'protocol_source', 'protocolsio/v3' %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= image_tag 'external_protocols/protocolsio_logo.png',
|
||||
class: 'protocolsio-logo' %>
|
||||
<span class='protocolsio-title'><%= t('protocols.index.external_protocols.protocolsio_title') %></span>
|
||||
<div class='input-group'>
|
||||
<input class='form-control'
|
||||
type='text'
|
||||
name='key'
|
||||
placeholder="<%= t('protocols.index.external_protocols.search_bar_placeholder') %>" >
|
||||
</input>
|
||||
|
||||
<span class='input-group-addon'><i class='fas fa-search '></i></span>
|
||||
</div>
|
||||
</div>
|
||||
<%= form_tag '#',
|
||||
method: :get,
|
||||
class: 'protocols-search-bar' do %>
|
||||
|
||||
<div class='input-group'>
|
||||
<input class='form-control'
|
||||
type="text"
|
||||
name="q"
|
||||
placeholder="<%= t('protocols.index.external_protocols.search_bar_placeholder') %>" >
|
||||
</input>
|
||||
|
||||
<span class='input-group-addon'><i class='fas fa-search '></i></span>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class='col-md-7'>
|
||||
<div class='protocol-sort'>
|
||||
<span><%= t('protocols.index.external_protocols.sort_by.title') %></span>
|
||||
<div class='btn-group' data-toggle='buttons' >
|
||||
<div class='btn-group' data-toggle='buttons'>
|
||||
<label class='btn btn-link active'>
|
||||
<input type='radio' name='sory_by' id='alphabetically' value='alpha'>
|
||||
<input type='radio' name='sort_by' id='alphabetically' value='alpha' checked>
|
||||
<%= t('protocols.index.external_protocols.sort_by.alphabetically') %>
|
||||
</label>
|
||||
<label class='btn btn-link'>
|
||||
<input type='radio' name='sory_by' id='newest' value='newest'>
|
||||
<input type='radio' name='sort_by' id='newest' value='newest'>
|
||||
<%= t('protocols.index.external_protocols.sort_by.newest') %>
|
||||
</label>
|
||||
<label class='btn btn-link'>
|
||||
<input type='radio' name='sory_by' id='oldest' value='oldest'>
|
||||
<input type='radio' name='sort_by' id='oldest' value='oldest'>
|
||||
<%= t('protocols.index.external_protocols.sort_by.oldest') %>
|
||||
</label>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class='row main-protocol-panel'>
|
||||
<div class='col-md-5 protocol-list-side-panel'>
|
||||
<div class='row main-protocol-panel'>
|
||||
<div class='col-md-5 protocol-list-side-panel'>
|
||||
|
||||
<div class='row empty-text'>
|
||||
<%= t('protocols.index.external_protocols.list_panel.empty_text') %>
|
||||
</div>
|
||||
<div class="external-protocol-result">
|
||||
<a href="#" data-source="protocolsio/v3" data-id="11176" data-action="external-import" data-url="<%= team_build_external_protocol_path(current_team.id,) %>">Protocols IO, 11176</a>
|
||||
</div>
|
||||
|
||||
<div class='protocol-card'
|
||||
data-protocol-source='protocolsio/v3'
|
||||
data-show-url='<%= team_show_external_protocol_path(current_team.id) %>'
|
||||
data-show-protocol-id='Extracting-DNA-from-bananas-esvbee6'>
|
||||
Banana protocol (click me)
|
||||
</div>
|
||||
|
||||
<div class='protocol-card'
|
||||
data-protocol-source='protocolsio/v3'
|
||||
data-show-url='<%= team_show_external_protocol_path(current_team.id) %>'
|
||||
data-show-protocol-id='cut-run-targeted-in-situ-genome-wide-profiling-wit-mgjc3un'>
|
||||
Cut run targeted protocol (click me)
|
||||
</div>
|
||||
|
||||
<div class='protocol-card'
|
||||
data-protocol-source='protocolsio/3'
|
||||
data-show-url='<%= team_show_external_protocol_path(current_team.id) %>'
|
||||
data-show-protocol-id='errorr'>
|
||||
Error protocol (click me, should default to default screen)
|
||||
</div>
|
||||
<div class='list-wrapper'></div>
|
||||
</div>
|
||||
|
||||
<div class='col-md-7 protocol-preview-panel'>
|
||||
<div class='empty-preview-panel'>
|
||||
|
||||
<div class='row'>
|
||||
<div class='text-rows protocol-preview-text'>
|
||||
<%= t('protocols.index.external_protocols.preview_panel.empty_title') %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='row'>
|
||||
<div class='text-separator'> <hr> </div>
|
||||
</div>
|
||||
|
||||
<div class='row'>
|
||||
<div class='text-rows protocol-preview-subtext'>
|
||||
<%= t('protocols.index.external_protocols.preview_panel.empty_subtext') %>
|
||||
|
@ -95,7 +78,18 @@
|
|||
</div>
|
||||
|
||||
<div class='full-preview-panel' style='display: none;'>
|
||||
<iframe class='preview-iframe'></iframe>
|
||||
<div class='row preview-banner'>
|
||||
<div class='col-md-6 txt-holder'>
|
||||
<span>
|
||||
<%= t('protocols.index.external_protocols.preview_panel.banner_text') %>
|
||||
</span>
|
||||
</div>
|
||||
<div class='col-md-6 btn-holder'>
|
||||
</div>
|
||||
</div>
|
||||
<div class='preview-holder'>
|
||||
<iframe class='preview-iframe'></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -203,8 +203,11 @@ class Constants
|
|||
base_uri: 'https://www.protocols.io/api/v3/',
|
||||
default_timeout: 10,
|
||||
debug_level: :debug,
|
||||
available_order_fields: %i(title created_on),
|
||||
available_order_dirs: %i(asc desc),
|
||||
sort_mappings: {
|
||||
alpha: { order_field: :name, order_dir: :asc },
|
||||
newest: { order_field: :date, order_dir: :desc },
|
||||
oldest: { order_field: :date, order_dir: :asc }
|
||||
},
|
||||
endpoints: {
|
||||
protocols: {
|
||||
default_query_params: {
|
||||
|
|
|
@ -1749,6 +1749,7 @@ en:
|
|||
preview_panel:
|
||||
empty_title: 'PROTOCOL PREVIEW'
|
||||
empty_subtext: 'Click on the protocol in the list to preview it here'
|
||||
banner_text: 'Protocol Preview'
|
||||
|
||||
steps:
|
||||
completed: 'Completed'
|
||||
|
|
|
@ -2,6 +2,9 @@ en:
|
|||
protocol_importers:
|
||||
new:
|
||||
modal_title: 'Import protocol - %{protocol_name}'
|
||||
card:
|
||||
views_and_steps: '%{nr_of_views} views • %{nr_of_steps} steps'
|
||||
import_button_text: 'Import...'
|
||||
templates:
|
||||
amount:
|
||||
title: 'Amount'
|
||||
|
@ -44,8 +47,3 @@ en:
|
|||
title: 'Temperature'
|
||||
warning:
|
||||
title: 'Warning'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
{
|
||||
"id": 22532,
|
||||
"title": "Producing rooted cassava plantlets for use in pot experiments",
|
||||
"source": "protocolsio/v3",
|
||||
"created_on": 1556012701,
|
||||
"authors": "Matema Imakumbili",
|
||||
"nr_of_steps": 13,
|
||||
|
@ -12,6 +13,7 @@
|
|||
{
|
||||
"id": 832,
|
||||
"title": "Preparation of Virus DNA from Seawater for Metagenomics",
|
||||
"source": "protocolsio/v3",
|
||||
"created_on": 1434495014,
|
||||
"authors": "Matthew Sullivan Lab",
|
||||
"nr_of_steps": 11,
|
||||
|
@ -21,6 +23,7 @@
|
|||
{
|
||||
"id": 14506,
|
||||
"title": "MALE CIRCUMCISION FOR PREVENTION OF HETEROSEXUAL TRANSMISSION OF HIV IN ADULT MALES IN SOWETO, what do indicators and incidence rates show?untitled protocol",
|
||||
"source": "protocolsio/v3",
|
||||
"created_on": 1533553359,
|
||||
"authors": "Hillary Mukudu, Neil Martinson, Benn Sartorius",
|
||||
"nr_of_steps": 0,
|
||||
|
@ -30,6 +33,7 @@
|
|||
{
|
||||
"id": 10927,
|
||||
"title": "physiological and biochemical parameters",
|
||||
"source": "protocolsio/v3",
|
||||
"created_on": 1521454618,
|
||||
"authors": "Amor Slama, Elhem Mallek-Maalej, Hatem Ben Mohamed, Thouraya Rhim, Leila Radhouane, Amor SLAMA",
|
||||
"nr_of_steps": 0,
|
||||
|
@ -39,6 +43,7 @@
|
|||
{
|
||||
"id": 822,
|
||||
"title": "Iron Chloride Precipitation of Viruses from Seawater",
|
||||
"source": "protocolsio/v3",
|
||||
"created_on": 1434402745,
|
||||
"authors": "Seth John, Bonnie Poulos, Christine Schirmer",
|
||||
"nr_of_steps": 17,
|
||||
|
@ -48,6 +53,7 @@
|
|||
{
|
||||
"id": 12115,
|
||||
"title": "Measuring specific leaf area and water content",
|
||||
"source": "protocolsio/v3",
|
||||
"created_on": 1526074093,
|
||||
"authors": "Etienne Laliberté",
|
||||
"nr_of_steps": 33,
|
||||
|
@ -57,6 +63,7 @@
|
|||
{
|
||||
"id": 1842,
|
||||
"title": "Purification of viral assemblages from seawater in CsCl gradients",
|
||||
"source": "protocolsio/v3",
|
||||
"created_on": 1445287995,
|
||||
"authors": "Janice E. Lawrence and Grieg F. Steward",
|
||||
"nr_of_steps": 23,
|
||||
|
@ -66,6 +73,7 @@
|
|||
{
|
||||
"id": 12540,
|
||||
"title": "An improved primer set and PCR amplification protocol with increased specificity and sensitivity targeting the Symbiodinium ITS2 region using the SymVar primer pair",
|
||||
"source": "protocolsio/v3",
|
||||
"created_on": 1527418313,
|
||||
"authors": "Benjamin Hume, Maren Ziegler, Christian Voolstra, Julie Poulain, Xavier Pochon, Sarah Romac, Emilie Boissin, Colomban de Vargas, Serge Planes, Patrick Wincker",
|
||||
"nr_of_steps": 1,
|
||||
|
@ -75,6 +83,7 @@
|
|||
{
|
||||
"id": 985,
|
||||
"title": "NATURAL SEAWATER-BASED PRO99 MEDIUM",
|
||||
"source": "protocolsio/v3",
|
||||
"created_on": 1435347035,
|
||||
"authors": "Chisholm Lab",
|
||||
"nr_of_steps": 10,
|
||||
|
@ -84,6 +93,7 @@
|
|||
{
|
||||
"id": 1033,
|
||||
"title": "SN Maintenance Medium for Synechococcus",
|
||||
"source": "protocolsio/v3",
|
||||
"created_on": 1435778857,
|
||||
"authors": "JB Waterbury \u0026 JM Willey",
|
||||
"nr_of_steps": 6,
|
||||
|
|
Loading…
Reference in a new issue