Remove tutorial [SCI-1860]
1
Gemfile
|
@ -36,7 +36,6 @@ gem 'jquery-ui-rails'
|
|||
gem 'jquery-scrollto-rails',
|
||||
git: 'https://github.com/biosistemika/jquery-scrollto-rails'
|
||||
gem 'hammerjs-rails'
|
||||
gem 'introjs-rails' # Create quick tutorials
|
||||
gem 'js_cookie_rails' # Simple JS API for cookies
|
||||
gem 'spinjs-rails'
|
||||
gem 'autosize-rails' # jQuery autosize plugin
|
||||
|
|
|
@ -231,9 +231,6 @@ GEM
|
|||
concurrent-ruby (~> 1.0)
|
||||
i18n-js (3.0.3)
|
||||
i18n (~> 0.6, >= 0.6.6)
|
||||
introjs-rails (1.0.0)
|
||||
sass-rails (>= 3.2)
|
||||
thor (~> 0.14)
|
||||
jbuilder (2.7.0)
|
||||
activesupport (>= 4.2.0)
|
||||
multi_json (>= 1.2)
|
||||
|
@ -558,7 +555,6 @@ DEPENDENCIES
|
|||
font-awesome-rails (~> 4.7.0.2)
|
||||
hammerjs-rails
|
||||
i18n-js (~> 3.0)
|
||||
introjs-rails
|
||||
jbuilder
|
||||
jquery-rails
|
||||
jquery-scrollto-rails!
|
||||
|
|
3
Makefile
|
@ -7,7 +7,6 @@ SECRET_KEY_BASE=$(shell openssl rand -hex 64)
|
|||
PAPERCLIP_HASH_SECRET=$(shell openssl rand -base64 128 | tr -d '\n')
|
||||
DATABASE_URL=postgresql://postgres@db/scinote_production
|
||||
PAPERCLIP_STORAGE=filesystem
|
||||
ENABLE_TUTORIAL=true
|
||||
ENABLE_RECAPTCHA=false
|
||||
ENABLE_USER_CONFIRMATION=false
|
||||
ENABLE_USER_REGISTRATION=true
|
||||
|
@ -83,7 +82,7 @@ integration-tests:
|
|||
@$(MAKE) rails cmd="bundle exec cucumber"
|
||||
|
||||
tests-ci:
|
||||
@docker-compose run -e ENABLE_EMAIL_CONFIRMATIONS=false -e MAILER_PORT=$MAILER_PORT -e SMTP_DOMAIN=$SMTP_DOMAIN -e SMTP_USERNAME=$SMTP_USERNAME -e SMTP_PASSWORD=$SMTP_PASSWORD -e SMTP_ADDRESS=$SMTP_ADDRESS -e PAPERCLIP_HASH_SECRET=PAPERCLIP_HASH_SECRET -e MAIL_SERVER_URL=localhost -e PAPERCLIP_STORAGE=filesystem -e ENABLE_TUTORIAL=false -e ENABLE_RECAPTCHA=false -e ENABLE_USER_CONFIRMATION=false -e ENABLE_USER_REGISTRATION=true --rm web bash -c "bundle install && rake db:create db:migrate && rake db:migrate RAILS_ENV=test && yarn install && bundle exec rspec && bundle exec cucumber"
|
||||
@docker-compose run -e ENABLE_EMAIL_CONFIRMATIONS=false -e MAILER_PORT=$MAILER_PORT -e SMTP_DOMAIN=$SMTP_DOMAIN -e SMTP_USERNAME=$SMTP_USERNAME -e SMTP_PASSWORD=$SMTP_PASSWORD -e SMTP_ADDRESS=$SMTP_ADDRESS -e PAPERCLIP_HASH_SECRET=PAPERCLIP_HASH_SECRET -e MAIL_SERVER_URL=localhost -e PAPERCLIP_STORAGE=filesystem -e ENABLE_RECAPTCHA=false -e ENABLE_USER_CONFIRMATION=false -e ENABLE_USER_REGISTRATION=true --rm web bash -c "bundle install && rake db:create db:migrate && rake db:migrate RAILS_ENV=test && yarn install && bundle exec rspec && bundle exec cucumber"
|
||||
|
||||
console:
|
||||
@$(MAKE) rails cmd="rails console"
|
||||
|
|
Before Width: | Height: | Size: 531 KiB After Width: | Height: | Size: 531 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 530 KiB After Width: | Height: | Size: 530 KiB |
Before Width: | Height: | Size: 474 KiB After Width: | Height: | Size: 474 KiB |
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 183 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
@ -1,4 +1,4 @@
|
|||
# Content for tables used in tutorial (demo project).
|
||||
# Content for tables used in demo project.
|
||||
|
||||
module1:
|
||||
experimental_design: '{"data":[["","","",null,null],["","","",null,null],["group/time","1 dpi","6 dpi","",""],["PVYNTN","1","1","",""],["mock","1","1","",""],[null,null,null,null,null]]}'
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
@ -15,7 +15,6 @@
|
|||
//= require jquery.caret.min
|
||||
//= require jquery.atwho.min
|
||||
//= require hammer
|
||||
//= require introjs
|
||||
//= require js.cookie
|
||||
//= require spin
|
||||
//= require jquery.spin
|
||||
|
|
|
@ -17,7 +17,6 @@ function init() {
|
|||
initImport();
|
||||
Comments.bindNewElement();
|
||||
Comments.initialize();
|
||||
initTutorial();
|
||||
setupAssetsLoading();
|
||||
}
|
||||
|
||||
|
@ -113,31 +112,6 @@ function bindEditDueDateAjax() {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes tutorial
|
||||
*/
|
||||
function initTutorial() {
|
||||
var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
if (stepNum >= 12 && stepNum <= 14) {
|
||||
var resultsTab = $('#results-nav-tab');
|
||||
|
||||
var nextPage = resultsTab.find('a').attr('href');
|
||||
var steps = [{
|
||||
intro: I18n.t('tutorial.module_protocols_html'),
|
||||
}, {
|
||||
element: $('#protocol-copy-to-repository')[0],
|
||||
intro: I18n.t('tutorial.module_protocols_save_html'),
|
||||
position: 'right'
|
||||
}, {
|
||||
element: resultsTab[0],
|
||||
intro: I18n.t('tutorial.module_protocols_click_results_html'),
|
||||
position: 'right'
|
||||
}];
|
||||
initPageTutorialSteps(12, 14, nextPage, function() {}, function() {},
|
||||
steps);
|
||||
}
|
||||
}
|
||||
|
||||
function initCopyToRepository() {
|
||||
var link = $("[data-action='copy-to-repository']");
|
||||
var modal = $("#copy-to-repository-modal");
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
function init() {
|
||||
initHandsOnTables($(document));
|
||||
_expandAllResults();
|
||||
_initTutorial();
|
||||
applyCollapseLinkCallBack();
|
||||
|
||||
Comments.bindNewElement();
|
||||
|
@ -130,28 +129,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes tutorial
|
||||
*/
|
||||
function _initTutorial() {
|
||||
var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
if (stepNum >= 15 && stepNum <= 16) {
|
||||
var samplesTab = $('#module-samples-nav-tab');
|
||||
|
||||
var nextPage = samplesTab.find('a').attr('href');
|
||||
var steps = [{
|
||||
element: $('#results-toolbar')[0],
|
||||
intro: I18n.t('tutorial.module_results_html')
|
||||
}, {
|
||||
element: samplesTab[0],
|
||||
intro: I18n.t('tutorial.module_results_click_samples_html'),
|
||||
position: 'left'
|
||||
}];
|
||||
initPageTutorialSteps(15, 16, nextPage, function() {}, function() {},
|
||||
steps);
|
||||
}
|
||||
}
|
||||
|
||||
function processResult(ev, resultTypeEnum, editMode) {
|
||||
var $form = $(ev.target.form);
|
||||
$form.clearFormErrors();
|
||||
|
|
|
@ -116,9 +116,6 @@ var ignoreUnsavedWorkAlert;
|
|||
// Global variable for hammer js
|
||||
var hammertime;
|
||||
|
||||
// Cookie data for tutorial
|
||||
var tutorialData;
|
||||
|
||||
/*
|
||||
* As a guideline, all module elements should contain
|
||||
* the following attributes:
|
||||
|
@ -146,7 +143,6 @@ function init() {
|
|||
bindWindowResizeEvent();
|
||||
initializeGraph(".diagram .module-large");
|
||||
initializeFullZoom();
|
||||
initTutorial();
|
||||
}
|
||||
|
||||
jsPlumb.ready(function () {
|
||||
|
@ -2999,117 +2995,6 @@ function initJsPlumb(containerSel, containerChildSel, modulesSel, params) {
|
|||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* Initializes tutorial
|
||||
*/
|
||||
function initTutorial() {
|
||||
var tutorialData = Cookies.get('tutorial_data');
|
||||
if (tutorialData) {
|
||||
tutorialData = JSON.parse(tutorialData);
|
||||
var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
|
||||
if (stepNum >= 6 && stepNum <= 7) {
|
||||
var nextPage = window.location.pathname;
|
||||
var steps = [{
|
||||
element: $('#canvas-container')[0],
|
||||
intro: I18n.t('tutorial.canvas_overview_html'),
|
||||
position: 'left'
|
||||
}, {
|
||||
element: $('#edit-canvas-button')[0],
|
||||
intro: I18n.t('tutorial.canvas_click_edit_workflow_html'),
|
||||
position: 'left'
|
||||
}];
|
||||
initPageTutorialSteps(6, 7, nextPage, tutorialBeforeCb, tutorialAfterCb,
|
||||
steps);
|
||||
} else if (stepNum >= 8 && stepNum <= 9) {
|
||||
// Go into edit canvas mode
|
||||
$('.introjs-overlay').remove();
|
||||
$('.introjs-helperLayer').remove();
|
||||
$('.introjs-tooltipReferenceLayer').remove();
|
||||
$('#edit-canvas-button').click();
|
||||
|
||||
setTimeout(function() {
|
||||
var nextPage = window.location.pathname;
|
||||
var steps = [{
|
||||
intro: I18n.t('tutorial.edit_workflow_html'),
|
||||
element: $('#canvas-new-module')[0],
|
||||
position: 'right'
|
||||
}, {
|
||||
intro: I18n.t('tutorial.edit_workflow_click_save_html'),
|
||||
element: $('#canvas-save')[0],
|
||||
position: 'right'
|
||||
}];
|
||||
initPageTutorialSteps(8, 9, nextPage, tutorialBeforeCb, function() {
|
||||
// Go out of edit canvas mode
|
||||
$('.cancel-edit-canvas').click();
|
||||
|
||||
tutorialAfterCb();
|
||||
}, steps);
|
||||
}, 1000);
|
||||
} else if (stepNum >= 10 && stepNum <= 11) {
|
||||
var qpcrModuleLeaf =
|
||||
$("li.leaf[data-module-id='" + tutorialData[0].qpcr_module + "']");
|
||||
|
||||
var nextPage = qpcrModuleLeaf.find('a.module-link').attr('href');
|
||||
var steps = [{
|
||||
element: $('#slide-panel .tree')[0],
|
||||
intro: I18n.t('tutorial.sidebar_html'),
|
||||
position: 'right'
|
||||
}, {
|
||||
element: qpcrModuleLeaf[0],
|
||||
intro: I18n.t('tutorial.sidebar_click_module_html'),
|
||||
position: 'right'
|
||||
}];
|
||||
initPageTutorialSteps(10, 11, nextPage, tutorialBeforeCb,
|
||||
tutorialAfterCb, steps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to be executed before tutorial starts
|
||||
*/
|
||||
function tutorialBeforeCb() {
|
||||
$('#slide-panel')
|
||||
.css({'pointer-events': 'none'});
|
||||
$('#canvas-new-module')
|
||||
.css({'pointer-events': 'none'});
|
||||
|
||||
$.each($('.panel-default'), function(i, el) {
|
||||
$(el)
|
||||
.find('.tab-pane')
|
||||
.css({'pointer-events': 'none'});
|
||||
$(el)
|
||||
.find('.edit-tags-link')
|
||||
.css({'pointer-events': 'none'});
|
||||
$(el)
|
||||
.find('.panel-heading')
|
||||
.css({'pointer-events': 'none'});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to be executed after tutorial exits
|
||||
*/
|
||||
function tutorialAfterCb() {
|
||||
$('#slide-panel')
|
||||
.css({'pointer-events': 'auto'});
|
||||
$('#canvas-new-module')
|
||||
.css({'pointer-events': 'auto'});
|
||||
|
||||
$.each($('.panel-default'), function(i, el) {
|
||||
$(el)
|
||||
.find('.tab-pane')
|
||||
.css({'pointer-events': 'auto'});
|
||||
$(el)
|
||||
.find('.edit-tags-link')
|
||||
.css({'pointer-events': 'auto'});
|
||||
$(el)
|
||||
.find('.panel-heading')
|
||||
.css({'pointer-events': 'auto'});
|
||||
});
|
||||
}
|
||||
|
||||
/** prevent reload page */
|
||||
var preventCanvasReloadOnSave = (function() {
|
||||
'use strict';
|
||||
|
|
|
@ -102,8 +102,6 @@
|
|||
.on('ajax:error', function() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
initTutorial();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -335,131 +333,5 @@
|
|||
initUserRoleForms();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes tutorial
|
||||
*/
|
||||
function initTutorial() {
|
||||
var tutorialData = Cookies.get('tutorial_data');
|
||||
if (tutorialData) {
|
||||
tutorialData = JSON.parse(tutorialData);
|
||||
var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
if (isNaN(stepNum)) {
|
||||
// Cookies data initialization
|
||||
stepNum = 1;
|
||||
Cookies.set('current_tutorial_step', stepNum);
|
||||
tutorialData[0].backPagesPaths = [];
|
||||
Cookies.set('tutorial_data', tutorialData);
|
||||
}
|
||||
var demoProjectId = tutorialData[0].project;
|
||||
var demoProject = $('#' + demoProjectId);
|
||||
|
||||
if (stepNum >= 1 && stepNum <= 3) {
|
||||
var thirdStepPos = (demoProject.offset().top > window.innerHeight / 2) ?
|
||||
'top' : 'bottom';
|
||||
|
||||
var nextPage = $('#' + demoProjectId + '-project-canvas-link')
|
||||
.attr('href');
|
||||
var steps = [{
|
||||
element: $('#projects-toolbar')[0],
|
||||
intro: I18n.t('tutorial.tutorial_welcome_title_html'),
|
||||
position: 'bottom'
|
||||
}, {
|
||||
element: $('#new-project-btn')[0],
|
||||
intro: I18n.t('tutorial.create_project_html'),
|
||||
position: 'left'
|
||||
}, {
|
||||
element: demoProject[0],
|
||||
intro: I18n.t('tutorial.project_options_html'),
|
||||
position: thirdStepPos
|
||||
}];
|
||||
initPageTutorialSteps(1, 3, nextPage, tutorialBeforeCb,
|
||||
tutorialAfterCb, steps);
|
||||
} else if (stepNum === 22) {
|
||||
var protocolLink = $('#protocol-link');
|
||||
|
||||
var nextPage = protocolLink.attr('href');
|
||||
var steps = [{
|
||||
element: protocolLink[0],
|
||||
intro: I18n.t('tutorial.protocols_link_html'),
|
||||
position: 'left'
|
||||
}];
|
||||
initPageTutorialSteps(22, 22, nextPage, function() {}, function() {},
|
||||
steps);
|
||||
} else if (stepNum >= 25 && stepNum <= 26) {
|
||||
var firstStepPos = 'right';
|
||||
if (demoProject.offset().left > window.innerWidth / 2 ||
|
||||
window.innerWidth < demoProject.width() + 100) {
|
||||
if (demoProject.offset().top > 500 && demoProject.offset().top >
|
||||
window.innerHeight / 2) {
|
||||
firstStepPos = 'top';
|
||||
} else {
|
||||
firstStepPos = 'bottom';
|
||||
}
|
||||
}
|
||||
|
||||
var nextPage = $('#new-report-btn').attr('href');
|
||||
var steps = [{
|
||||
element: demoProject[0],
|
||||
intro: I18n.t('tutorial.archive_project_html'),
|
||||
position: firstStepPos
|
||||
}, {
|
||||
element: $('.avatar')[0],
|
||||
intro: I18n.t('tutorial.goodbye_message'),
|
||||
position: 'left'
|
||||
}];
|
||||
initPageTutorialSteps(25, 26, nextPage, function() {}, function() {},
|
||||
steps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to be executed before tutorial starts
|
||||
*/
|
||||
function tutorialBeforeCb() {
|
||||
$.each($('.panel'), function(i, el){
|
||||
$(el)
|
||||
.find('.panel-title')
|
||||
.css({ 'pointer-events': 'none' });
|
||||
$(el)
|
||||
.find('.tab-content')
|
||||
.css({ 'pointer-events': 'none' });
|
||||
$(el)
|
||||
.find('.form-submit-link')
|
||||
.css({
|
||||
'pointer-events': 'none',
|
||||
'color': '<%= Constants::COLOR_ALTO %>'});
|
||||
$(el)
|
||||
.find("[data-action='edit']")
|
||||
.css({
|
||||
'pointer-events': 'none',
|
||||
'color': '<%= Constants::COLOR_ALTO %>'});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to be executed after tutorial exits
|
||||
*/
|
||||
function tutorialAfterCb() {
|
||||
$.each($('.panel'), function(i, el){
|
||||
$(el)
|
||||
.find('.tab-content')
|
||||
.css({ 'pointer-events': 'auto' });
|
||||
$(el)
|
||||
.find('.panel-title')
|
||||
.css({ 'pointer-events': 'auto' });
|
||||
$(el)
|
||||
.find('.form-submit-link')
|
||||
.css({
|
||||
'pointer-events': 'auto',
|
||||
'color': '<%= Constants::COLOR_NERO %>'});
|
||||
$(el)
|
||||
.find("[data-action='edit']")
|
||||
.css({
|
||||
'pointer-events': 'auto',
|
||||
'color': '<%= Constants::COLOR_NERO %>'});
|
||||
});
|
||||
}
|
||||
|
||||
init();
|
||||
}());
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
var that = $(this);
|
||||
initProjectExperiment(that);
|
||||
});
|
||||
|
||||
initTutorial();
|
||||
}
|
||||
|
||||
function initProjectExperiment(element){
|
||||
|
@ -64,58 +62,5 @@
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes tutorial
|
||||
*/
|
||||
function initTutorial() {
|
||||
var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
if (stepNum >= 4 && stepNum <= 5) {
|
||||
var nextPage = $('[data-canvas-link]').data('canvasLink');
|
||||
var steps = [{
|
||||
element: $('#new-experiment')[0],
|
||||
intro: I18n.t('tutorial.tutorial_welcome_title_html'),
|
||||
position: 'left'
|
||||
}, {
|
||||
element: $('.experiment-panel')[0],
|
||||
intro: I18n.t('tutorial.edit_experiment_html'),
|
||||
position: 'right'
|
||||
}];
|
||||
initPageTutorialSteps(4, 5, nextPage, tutorialBeforeCb, tutorialAfterCb,
|
||||
steps);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to be executed before tutorial starts
|
||||
*/
|
||||
function tutorialBeforeCb() {
|
||||
$.each( $(".panel-title"), function(){
|
||||
$(this).css({ "pointer-events": "none" });
|
||||
});
|
||||
$.each( $(".workflowimg-container"), function(){
|
||||
$(this).css({ "pointer-events": "none" });
|
||||
});
|
||||
$.each( $(".dropdown-experiment-actions").find("li"),
|
||||
function(){
|
||||
$(this).css({ "pointer-events": "none" });
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to be executed after tutorial exits
|
||||
*/
|
||||
function tutorialAfterCb() {
|
||||
$.each( $(".panel-title"), function(){
|
||||
$(this).css({ "pointer-events": "auto" });
|
||||
});
|
||||
$.each( $(".workflowimg-container"), function(){
|
||||
$(this).css({ "pointer-events": "auto" });
|
||||
});
|
||||
$.each( $(".dropdown-experiment-actions").find("li"),
|
||||
function(){
|
||||
$(this).css({ "pointer-events": "auto" });
|
||||
});
|
||||
}
|
||||
|
||||
init();
|
||||
})();
|
||||
|
|
|
@ -19,7 +19,6 @@ function init() {
|
|||
initCreateNewModal();
|
||||
initModals();
|
||||
initImport();
|
||||
initTutorial();
|
||||
}
|
||||
|
||||
// Initialize protocols DataTable
|
||||
|
@ -770,25 +769,4 @@ function initImport() {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes tutorial
|
||||
*/
|
||||
function initTutorial() {
|
||||
var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
if (stepNum >= 23 && stepNum <= 24) {
|
||||
var nextPage = $('.navbar-brand').attr('href');
|
||||
var steps = [{
|
||||
element: $('.nav-settings')[0],
|
||||
intro: I18n.t('tutorial.protocols_index_html'),
|
||||
position: 'bottom'
|
||||
}, {
|
||||
element: $('#import-export-protocols')[0],
|
||||
intro: I18n.t('tutorial.protocols_import_export_html'),
|
||||
position: 'bottom'
|
||||
}];
|
||||
initPageTutorialSteps(23, 24, nextPage, function() {}, function() {},
|
||||
steps);
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
updateButtons();
|
||||
initEditReport();
|
||||
initDeleteReports();
|
||||
initTutorial();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,24 +162,5 @@
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes tutorial
|
||||
*/
|
||||
function initTutorial() {
|
||||
var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
if (stepNum === 19) {
|
||||
var newReportBtn = $('#new-report-btn');
|
||||
|
||||
var nextPage = newReportBtn.attr('href');
|
||||
var steps = [{
|
||||
element: newReportBtn[0],
|
||||
intro: I18n.t('tutorial.reports_index_click_new_report_html'),
|
||||
position: 'right'
|
||||
}];
|
||||
initPageTutorialSteps(19, 19, nextPage, function() {}, function() {},
|
||||
steps);
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(init);
|
||||
}());
|
||||
|
|
|
@ -33,7 +33,6 @@ var ignoreUnsavedWorkAlert;
|
|||
initializeAddContentsModal();
|
||||
initializeSidebarNavigation();
|
||||
initializeUnsavedWorkDialog();
|
||||
initTutorial();
|
||||
|
||||
$('.report-nav-link').each(function() {
|
||||
truncateLongString($(this), <%= Constants::NAME_TRUNCATION_LENGTH %>);
|
||||
|
@ -1146,32 +1145,6 @@ function initializeReportSidebartruncation() {
|
|||
observer.observe(target, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes tutorial
|
||||
*/
|
||||
function initTutorial() {
|
||||
var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
if (stepNum >= 20 && stepNum <= 21) {
|
||||
ignoreUnsavedWorkAlert = true;
|
||||
|
||||
var nextPage = $('.navbar-brand').attr('href');
|
||||
var steps = [{
|
||||
element: $('.new-element')[0],
|
||||
intro: I18n.t('tutorial.new_report_html'),
|
||||
position: 'left'
|
||||
}, {
|
||||
element: $('#team-link')[0],
|
||||
intro: I18n.t('tutorial.new_report_click_team_html',
|
||||
{ private_team: $('#team-link span').last().text() }),
|
||||
position: 'left'
|
||||
}];
|
||||
initPageTutorialSteps(20, 21, nextPage, function() {}, function() {
|
||||
ignoreUnsavedWorkAlert = false;
|
||||
},
|
||||
steps);
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
// Check if we are actually at new report page
|
||||
if ($(REPORT_CONTENT).length) {
|
||||
|
|
|
@ -58,25 +58,3 @@ function updateSamplesTypesandGroups() {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes tutorial
|
||||
*/
|
||||
function initTutorial() {
|
||||
var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
if (stepNum >= 17 && stepNum <= 18) {
|
||||
var nextPage = $('#reports-nav-tab a').attr('href');
|
||||
var steps = [{
|
||||
element: $('#importSamplesButton')[0],
|
||||
intro: I18n.t('tutorial.samples_html'),
|
||||
position: 'right'
|
||||
}, {
|
||||
element: $('#secondary-menu')[0],
|
||||
intro: I18n.t('tutorial.breadcrumbs_html')
|
||||
}];
|
||||
initPageTutorialSteps(17, 18, nextPage, function() {}, function() {},
|
||||
steps);
|
||||
}
|
||||
}
|
||||
|
||||
initTutorial();
|
||||
|
|
|
@ -26,165 +26,6 @@ $.fn.onAjaxComplete = function (cb) {
|
|||
});
|
||||
}
|
||||
|
||||
// Number of all tutorial steps
|
||||
var TUTORIAL_STEPS_CNT = 26;
|
||||
|
||||
/**
|
||||
* Initializes tutorial steps for the current page.
|
||||
* NOTE: You can specify steps manually in JS with steps parameter (preferred
|
||||
* way), or hardcode them in HTML
|
||||
* NOTE: If some steps edit page, then this function needs to be called several
|
||||
* times for the same page, but for different steps. The same goes if the page
|
||||
* has discontinuous tutorial steps. In such cases, use steps branching, e.g.:
|
||||
* @example
|
||||
* var tutorialData = Cookies.get('tutorial_data');
|
||||
* if (tutorialData) {
|
||||
* tutorialData = JSON.parse(tutorialData);
|
||||
* var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
*
|
||||
* if (stepNum >= 6 && stepNum <= 7) {
|
||||
* ...
|
||||
* } else if ...
|
||||
* NOTE: If an element the popup is pointing at is of lesser horizontal length
|
||||
* than the popup itself, then it will not be positioned correctly if it's
|
||||
* position is top or bottom, so set/change the step's position to either left
|
||||
* or right (and don't use any custom styling!), e.g.:
|
||||
* @example
|
||||
* var steps = [
|
||||
* {
|
||||
* ...
|
||||
* position: 'right'
|
||||
* },
|
||||
* {
|
||||
* ...
|
||||
* ];
|
||||
* NOTE: If only one page step is needed, then make pageFirstStepN ==
|
||||
* pageLastStepN (both represent the one and only step number)
|
||||
*
|
||||
* @param {number} pageFirstStepN Page's first step number
|
||||
* @param {number} pageLastStepN Page's last step number
|
||||
* @param {string} nextPagePath Next page absolute path
|
||||
* @param {function} beforeCb Callback called before the tutorial starts. Mainly
|
||||
* used for setting 'pointer-events: none' on the elements the page's steps
|
||||
* highlight.
|
||||
* @param {function} endCb Callback called after the tutorial ends. Mainly used
|
||||
* for setting 'pointer-events: auto' on the elements the page's steps
|
||||
* highlight.
|
||||
* @param {object} steps JSON containing intro.js steps.
|
||||
*/
|
||||
function initPageTutorialSteps(pageFirstStepN, pageLastStepN, nextPagePath,
|
||||
beforeCb, endCb, steps) {
|
||||
var tutorialData = Cookies.get('tutorial_data');
|
||||
if (tutorialData) {
|
||||
tutorialData = JSON.parse(tutorialData);
|
||||
var stepNum = parseInt(Cookies.get('current_tutorial_step'), 10);
|
||||
if (isNaN(stepNum)) {
|
||||
// Cookies data initialization
|
||||
stepNum = 1;
|
||||
Cookies.set('current_tutorial_step', stepNum);
|
||||
tutorialData[0].backPagesPaths = [];
|
||||
Cookies.set('tutorial_data', tutorialData);
|
||||
}
|
||||
var thisPagePath = window.location.pathname;
|
||||
beforeCb();
|
||||
|
||||
// Initialize tutorial for the current pages' steps
|
||||
|
||||
var doneLabel;
|
||||
if (pageLastStepN == TUTORIAL_STEPS_CNT) {
|
||||
doneLabel = I18n.t('tutorial.finish_tutorial');
|
||||
} else {
|
||||
doneLabel = I18n.t('tutorial.skip_tutorial');
|
||||
// Add extra fake step, so that next button on last step of current page
|
||||
// gets focused. Also, if current page has only one step, this adds back
|
||||
// and next buttons to the popup.
|
||||
steps.push({});
|
||||
}
|
||||
introJs()
|
||||
.setOptions({
|
||||
overlayOpacity: '0.2',
|
||||
prevLabel: I18n.t('tutorial.back'),
|
||||
nextLabel: I18n.t('tutorial.next'),
|
||||
skipLabel: I18n.t('tutorial.skip_tutorial'),
|
||||
doneLabel: doneLabel,
|
||||
showBullets: false,
|
||||
showStepNumbers: false,
|
||||
exitOnOverlayClick: false,
|
||||
exitOnEsc: false,
|
||||
disableInteraction: true,
|
||||
keyboardNavigation: false,
|
||||
tooltipClass: 'custom next-page-link',
|
||||
steps: steps
|
||||
})
|
||||
.goToStep(stepNum - (pageFirstStepN - 1))
|
||||
.onexit(function() {
|
||||
Cookies.remove('tutorial_data');
|
||||
Cookies.remove('current_tutorial_step');
|
||||
location.reload();
|
||||
})
|
||||
.oncomplete(function() {
|
||||
Cookies.remove('tutorial_data');
|
||||
Cookies.remove('current_tutorial_step');
|
||||
location.reload();
|
||||
})
|
||||
.start();
|
||||
|
||||
// Page navigation when coming to this page from previous or from next page
|
||||
$(function() {
|
||||
if (stepNum === pageFirstStepN && stepNum > 1) {
|
||||
$('.introjs-prevbutton').removeClass('introjs-disabled');
|
||||
} else if (stepNum === pageLastStepN && stepNum < TUTORIAL_STEPS_CNT) {
|
||||
$('.introjs-nextbutton').removeClass('introjs-disabled');
|
||||
}
|
||||
});
|
||||
|
||||
// Page navigation when already on this page
|
||||
|
||||
$('.introjs-skipbutton').click(function() {
|
||||
Cookies.remove('current_tutorial_step');
|
||||
Cookies.remove('tutorial_data');
|
||||
|
||||
endCb();
|
||||
});
|
||||
|
||||
$('.introjs-prevbutton').click(function() {
|
||||
if (stepNum > 1) {
|
||||
Cookies.set('current_tutorial_step', --stepNum);
|
||||
|
||||
if (stepNum === pageFirstStepN && stepNum > 1) {
|
||||
$('.introjs-prevbutton').removeClass('introjs-disabled');
|
||||
} else if (stepNum < pageFirstStepN) {
|
||||
// Go to previous page;
|
||||
|
||||
var prevPagePath = tutorialData[0].backPagesPaths.pop();
|
||||
Cookies.set('tutorial_data', tutorialData);
|
||||
$('.introjs-prevbutton').attr('href', prevPagePath);
|
||||
introJs().exit();
|
||||
endCb();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.introjs-nextbutton').click(function() {
|
||||
if (stepNum < TUTORIAL_STEPS_CNT) {
|
||||
Cookies.set('current_tutorial_step', ++stepNum);
|
||||
|
||||
if (stepNum === pageLastStepN && stepNum < TUTORIAL_STEPS_CNT) {
|
||||
$('.introjs-nextbutton').removeClass('introjs-disabled');
|
||||
} else if (stepNum > pageLastStepN) {
|
||||
// Go to next page
|
||||
|
||||
tutorialData[0].backPagesPaths.push(thisPagePath);
|
||||
Cookies.set('tutorial_data', tutorialData);
|
||||
$('.introjs-nextbutton').attr('href', nextPagePath);
|
||||
introJs().exit();
|
||||
endCb();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checkbox on/off logic. For each checkbox hierarchy add 'checkbox-tree' class
|
||||
* to a parent 'div' surrounding the checkbox hierarchy, represented with 'ul',
|
||||
|
|
|
@ -64,35 +64,9 @@
|
|||
$(this).renderFormErrors("user", data.responseJSON);
|
||||
});
|
||||
|
||||
var repeatTutorialModal = $("#repeat-tutorial-modal");
|
||||
var repeatTutorialModalBody = repeatTutorialModal.find(".modal-body");
|
||||
initRepeatTutorialModal();
|
||||
notificationsSettings();
|
||||
initNotificationSettingsForm();
|
||||
|
||||
$("#reset-tutorial-btn")
|
||||
.on("ajax:before", function () {
|
||||
repeatTutorialModal.modal('show');
|
||||
})
|
||||
|
||||
.on("ajax:success", function (e, data) {
|
||||
initRepeatTutorialModalBody(data);
|
||||
});
|
||||
|
||||
function initRepeatTutorialModal() {
|
||||
// Remove modal content when modal window is closed.
|
||||
repeatTutorialModal.on("hidden.bs.modal", function () {
|
||||
repeatTutorialModalBody.html("");
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize ajax listeners and elements style on modal body. This
|
||||
// function must be called when modal body is changed.
|
||||
function initRepeatTutorialModalBody(data) {
|
||||
repeatTutorialModalBody.html(data.html);
|
||||
repeatTutorialModalBody.find(".selectpicker").selectpicker();
|
||||
}
|
||||
|
||||
// Setup notification checkbox buttons
|
||||
function notificationsSettings() {
|
||||
var notification_settings = [ "recent_notification",
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*= require rails_bootstrap_forms
|
||||
*= require bootstrap-select
|
||||
*= require constants
|
||||
*= require introjs
|
||||
*= stub reports_pdf
|
||||
*/
|
||||
@import "bootstrap-sprockets";
|
||||
|
|
|
@ -1120,40 +1120,6 @@ table.dataTable {
|
|||
transform: translate3d(0%, 0, 0);
|
||||
}
|
||||
|
||||
/* Custom settings for intro-js */
|
||||
.introjs-tooltip {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.custom .introjs-button {
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.custom .introjs-disabled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.custom .introjs-skipbutton {
|
||||
border-radius: 0;
|
||||
color: $color-theme-primary;
|
||||
background-color: $color-white;
|
||||
background-image: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.disabled-next .introjs-nextbutton {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.introjs-tooltipReferenceLayer {
|
||||
z-index: $infinity !important;
|
||||
|
||||
&.max {
|
||||
z-index: calc($infinity + 1) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-tooltip {
|
||||
border-bottom: 1px dotted $color-alto;
|
||||
cursor: help;
|
||||
|
|
|
@ -7,7 +7,6 @@ class ApplicationController < ActionController::Base
|
|||
protect_from_forgery with: :exception, prepend: true
|
||||
before_action :authenticate_user!
|
||||
helper_method :current_team
|
||||
before_action :generate_intro_tutorial, if: :is_current_page_root?
|
||||
before_action :update_current_team, if: :user_signed_in?
|
||||
around_action :set_time_zone, if: :current_user
|
||||
layout 'main'
|
||||
|
@ -66,19 +65,6 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
private
|
||||
|
||||
def generate_intro_tutorial
|
||||
if Rails.configuration.x.enable_tutorial &&
|
||||
current_user.no_tutorial_done? &&
|
||||
current_user.teams.where(created_by: current_user).count > 0 then
|
||||
demo_cookie = seed_demo_data current_user
|
||||
cookies[:tutorial_data] = {
|
||||
value: demo_cookie,
|
||||
expires: 1.week.from_now
|
||||
}
|
||||
current_user.update(tutorial_status: 1)
|
||||
end
|
||||
end
|
||||
|
||||
def update_current_team
|
||||
if current_user.current_team_id.blank? &&
|
||||
current_user.teams.count > 0
|
||||
|
|
|
@ -4,6 +4,7 @@ class ProjectsController < ApplicationController
|
|||
include TeamsHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :generate_intro_demo, only: :index
|
||||
before_action :load_vars, only: [:show, :edit, :update,
|
||||
:notifications, :reports,
|
||||
:samples, :experiment_archive,
|
||||
|
@ -306,6 +307,12 @@ class ProjectsController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
def generate_intro_demo
|
||||
return unless current_user.sign_in_count == 1
|
||||
team = current_user.teams.where(created_by: current_user).first
|
||||
seed_demo_data(current_user) if team && team.projects.blank?
|
||||
end
|
||||
|
||||
def project_params
|
||||
params.require(:project).permit(:name, :team_id, :visibility, :archived)
|
||||
end
|
||||
|
|
|
@ -5,8 +5,6 @@ module Users
|
|||
before_action :load_user, only: [
|
||||
:index,
|
||||
:update,
|
||||
:tutorial,
|
||||
:reset_tutorial,
|
||||
:notifications_settings
|
||||
]
|
||||
|
||||
|
@ -31,51 +29,6 @@ module Users
|
|||
end
|
||||
end
|
||||
|
||||
def tutorial
|
||||
@teams =
|
||||
@user
|
||||
.user_teams
|
||||
.includes(team: :users)
|
||||
.where(role: 1..2)
|
||||
.order(created_at: :asc)
|
||||
.map(&:team)
|
||||
@member_of = @teams.count
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: {
|
||||
status: :ok,
|
||||
html: render_to_string(
|
||||
partial: 'users/settings/account/preferences/' \
|
||||
'repeat_tutorial_modal_body.html.erb'
|
||||
)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def reset_tutorial
|
||||
if @user.update(tutorial_status: 0) && params[:team][:id].present?
|
||||
@user.update(current_team_id: params[:team][:id])
|
||||
cookies.delete :tutorial_data
|
||||
cookies.delete :current_tutorial_step
|
||||
cookies[:repeat_tutorial_team_id] = {
|
||||
value: params[:team][:id],
|
||||
expires: 1.day.from_now
|
||||
}
|
||||
|
||||
flash[:notice] = t(
|
||||
'users.settings.account.preferences.tutorial.tutorial_reset_flash'
|
||||
)
|
||||
redirect_to root_path
|
||||
else
|
||||
flash[:alert] = t(
|
||||
'users.settings.account.preferences.tutorial.tutorial_reset_error'
|
||||
)
|
||||
redirect_back(fallback_location: root_path)
|
||||
end
|
||||
end
|
||||
|
||||
def notifications_settings
|
||||
@user.assignments_notification =
|
||||
params[:assignments_notification] ? true : false
|
||||
|
|
|
@ -16,11 +16,6 @@ class User < ApplicationRecord
|
|||
},
|
||||
default_url: Constants::DEFAULT_AVATAR_URL
|
||||
|
||||
enum tutorial_status: {
|
||||
no_tutorial_done: 0,
|
||||
intro_tutorial_done: 1
|
||||
}
|
||||
|
||||
auto_strip_attributes :full_name, :initials, nullify: false
|
||||
validates :full_name,
|
||||
presence: true,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
module DelayedUploaderTutorial
|
||||
# Get asset from tutorial_files folder
|
||||
module DelayedUploaderDemo
|
||||
# Get asset from demo_files folder
|
||||
def self.get_asset(user, team, file_name)
|
||||
Asset.new(
|
||||
file: File.open(
|
||||
"#{Rails.root}/app/assets/tutorial_files/#{file_name}", 'r'
|
||||
"#{Rails.root}/app/assets/demo_files/#{file_name}", 'r'
|
||||
),
|
||||
created_by: user,
|
||||
team: team,
|
||||
|
@ -12,7 +12,7 @@ module DelayedUploaderTutorial
|
|||
end
|
||||
|
||||
# Generates results asset for given module, file_name assumes file is located
|
||||
# in tutorial_files.
|
||||
# in demo_files.
|
||||
def self.generate_result_asset(
|
||||
my_module:,
|
||||
current_user:,
|
||||
|
@ -53,7 +53,7 @@ module DelayedUploaderTutorial
|
|||
# Adds asset to existing step
|
||||
def self.add_step_asset(step:, current_user:, current_team:, file_name:)
|
||||
temp_asset =
|
||||
DelayedUploaderTutorial.get_asset(current_user, current_team, file_name)
|
||||
DelayedUploaderDemo.get_asset(current_user, current_team, file_name)
|
||||
step.assets << temp_asset
|
||||
temp_asset.post_process_file(step.my_module.experiment.project.team)
|
||||
end
|
|
@ -1,24 +1,11 @@
|
|||
module FirstTimeDataGenerator
|
||||
# Create data for tutorial for new users
|
||||
# Create data for demo for new users
|
||||
def seed_demo_data(user)
|
||||
@user = user
|
||||
|
||||
# First team that this user created
|
||||
# should contain the "intro" project
|
||||
if cookies[:repeat_tutorial_org_id] || cookies[:repeat_tutorial_team_id]
|
||||
team = Team.find_by_id(cookies[:repeat_tutorial_org_id])
|
||||
team ||= Team.find_by_id(cookies[:repeat_tutorial_team_id])
|
||||
%w(repeat_tutorial_team_id repeat_tutorial_org_id)
|
||||
.each do |repeat_tutorial|
|
||||
cookies.delete repeat_tutorial.to_sym if cookies[repeat_tutorial.to_sym]
|
||||
end
|
||||
else
|
||||
team = user
|
||||
.teams
|
||||
.where(created_by: user)
|
||||
.order(created_at: :asc)
|
||||
.first
|
||||
end
|
||||
team = user.teams.where(created_by: user).order(created_at: :asc).first
|
||||
|
||||
# If private private team does not exist,
|
||||
# there was something wrong with user creation.
|
||||
|
@ -499,7 +486,7 @@ module FirstTimeDataGenerator
|
|||
|
||||
# Load table contents yaml file
|
||||
tab_content = YAML.load_file(
|
||||
"#{Rails.root}/app/assets/tutorial_files/tables_content.yaml"
|
||||
"#{Rails.root}/app/assets/demo_files/tables_content.yaml"
|
||||
)
|
||||
|
||||
# Create module content
|
||||
|
@ -516,7 +503,7 @@ module FirstTimeDataGenerator
|
|||
module_step_descriptions)
|
||||
|
||||
# Results
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[0],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -563,7 +550,7 @@ module FirstTimeDataGenerator
|
|||
module_step_descriptions)
|
||||
|
||||
# Add file to existig step
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).add_step_asset(
|
||||
step: my_modules[1].protocol.steps.where('position = 0').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -571,7 +558,7 @@ module FirstTimeDataGenerator
|
|||
)
|
||||
|
||||
# Results
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[1],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -580,7 +567,7 @@ module FirstTimeDataGenerator
|
|||
file_name: 'DSCN0660.JPG'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[1],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -589,7 +576,7 @@ module FirstTimeDataGenerator
|
|||
file_name: 'DSCN0354.JPG'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[1],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -642,7 +629,7 @@ module FirstTimeDataGenerator
|
|||
generate_module_steps(my_modules[2], module_step_names, module_step_descriptions)
|
||||
|
||||
# Add file to existig step
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).add_step_asset(
|
||||
step: my_modules[2].protocol.steps.where('position = 1').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -685,7 +672,7 @@ module FirstTimeDataGenerator
|
|||
).sneaky_save
|
||||
|
||||
# Second result
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[2],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -704,7 +691,7 @@ module FirstTimeDataGenerator
|
|||
generate_module_steps(my_modules[3], module_step_names, module_step_descriptions)
|
||||
|
||||
# Add file to existig step
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).add_step_asset(
|
||||
step: my_modules[3].protocol.steps.where('position = 0').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -712,7 +699,7 @@ module FirstTimeDataGenerator
|
|||
)
|
||||
|
||||
# Results
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[3],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -778,28 +765,28 @@ module FirstTimeDataGenerator
|
|||
module_step_descriptions)
|
||||
|
||||
# Add file to existig steps
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).add_step_asset(
|
||||
step: my_modules[5].protocol.steps.where('position = 0').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: 'sample_preparation.JPG'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).add_step_asset(
|
||||
step: my_modules[5].protocol.steps.where('position = 1').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: 'reaction_setup.JPG'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).add_step_asset(
|
||||
step: my_modules[5].protocol.steps.where('position = 2').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: 'cycling_conditions.JPG'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).add_step_asset(
|
||||
step: my_modules[5].protocol.steps.where('position = 3').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -842,7 +829,7 @@ module FirstTimeDataGenerator
|
|||
).sneaky_save
|
||||
|
||||
# Results
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[5],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -851,7 +838,7 @@ module FirstTimeDataGenerator
|
|||
file_name: 'Mixes_Templats.xls'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[5],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -860,7 +847,7 @@ module FirstTimeDataGenerator
|
|||
file_name: 'BootCamp-Experiment-results-20122.sds'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[5],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -907,7 +894,7 @@ module FirstTimeDataGenerator
|
|||
module_step_descriptions)
|
||||
|
||||
# Add file to existig step
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).add_step_asset(
|
||||
step: my_modules[7].protocol.steps.where('position = 0').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -915,7 +902,7 @@ module FirstTimeDataGenerator
|
|||
)
|
||||
|
||||
# Add result
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[7],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -924,7 +911,7 @@ module FirstTimeDataGenerator
|
|||
file_name: 'ddCq-quantification_diagnostics-results.xls'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[7],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -933,7 +920,7 @@ module FirstTimeDataGenerator
|
|||
file_name: 'dilution_curve-efficiency.JPG'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
DelayedUploaderDemo.delay(queue: :demo).generate_result_asset(
|
||||
my_module: my_modules[7],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
|
@ -973,12 +960,6 @@ module FirstTimeDataGenerator
|
|||
|
||||
# create thumbnail
|
||||
experiment.delay.generate_workflow_img
|
||||
|
||||
# Lastly, create cookie with according ids
|
||||
# so tutorial steps can be properly positioned
|
||||
JSON.generate([team: team.id,
|
||||
project: project.id,
|
||||
qpcr_module: my_modules[5].id])
|
||||
end
|
||||
|
||||
# WARNING: This only works on PostgreSQL
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
<%= render partial: "protocols/steps.html.erb" %>
|
||||
</div>
|
||||
|
||||
<!-- Tutorial data -->
|
||||
<div class="hidden" data-role="tutorial-data" data-module-id="<%= @my_module.id %>">
|
||||
</div>
|
||||
|
||||
<!-- URL for status bar refreshing -->
|
||||
<div class="hidden" data-role="protocol-status-bar-url" data-url="<%= protocol_status_bar_protocol_path(@protocol) %>"></div>
|
||||
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
<% if @member_of == 0 %>
|
||||
<div class="row">
|
||||
<span class="col-xs-12"><em><%=t 'users.settings.account.preferences.tutorial.no_teams' %></em></span>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="row">
|
||||
<span class="col-xs-12"><%=t 'users.settings.account.preferences.tutorial.select_team_instruction' %></span>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<%= bootstrap_form_tag url: reset_tutorial_path, method: :post do |f| %>
|
||||
<div class="col-xs-12 col-sm-4">
|
||||
<%= collection_select(:team, :id, @teams, :id, :name, {}, { class: 'selectpicker' }) %>
|
||||
</div>
|
||||
<div class="visible-xs"> </div>
|
||||
<div class="col-xs-4 col-sm-2">
|
||||
<%= f.button t('users.settings.account.preferences.tutorial.repeat_tutorial'), class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -51,15 +51,6 @@
|
|||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if Rails.configuration.x.enable_tutorial %>
|
||||
<hr>
|
||||
<strong><%= t('tutorial.title') %></strong> <br>
|
||||
<%= link_to t('users.settings.account.preferences.tutorial.repeat_tutorial'),
|
||||
tutorial_path(format: :json),
|
||||
remote: true,
|
||||
class: 'btn btn-primary',
|
||||
id: 'reset-tutorial-btn' %>
|
||||
<% end %>
|
||||
<hr>
|
||||
<div class="notification-settings-container">
|
||||
<h4><%= t('notifications.title') %></h4>
|
||||
|
@ -150,22 +141,4 @@
|
|||
<div class="tab-pane tab-pane-settings" role="tabpanel"></div>
|
||||
</div>
|
||||
|
||||
<!-- Repeat tutorial modal -->
|
||||
<div class="modal" id="repeat-tutorial-modal" tabindex="-1" role="dialog" aria-labelledby="repeat-tutorial-modal-label">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" ><%= t("users.settings.account.preferences.tutorial.modal_title") %></h4>
|
||||
</div>
|
||||
<div class="modal-body"></div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal"><%= t("general.cancel")%></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<%= javascript_include_tag "users/settings/account/preferences/index" %>
|
||||
|
|
|
@ -87,10 +87,6 @@ Rails.application.configure do
|
|||
# Enable/disable Deface
|
||||
config.deface.enabled = ENV['DEFACE_ENABLED'] != 'false'
|
||||
|
||||
# Enable first-time tutorial for users signing in the sciNote for
|
||||
# the first time.
|
||||
config.x.enable_tutorial = ENV['ENABLE_TUTORIAL'] == 'true'
|
||||
|
||||
# Enable reCAPTCHA
|
||||
config.x.enable_recaptcha = ENV['ENABLE_RECAPTCHA'] == 'true'
|
||||
|
||||
|
|
|
@ -101,10 +101,6 @@ Rails.application.configure do
|
|||
# Enable/disable Deface
|
||||
config.deface.enabled = ENV['DEFACE_ENABLED'] != 'false'
|
||||
|
||||
# Enable first-time tutorial for users signing in the sciNote for
|
||||
# the first time.
|
||||
config.x.enable_tutorial = ENV['ENABLE_TUTORIAL'] != 'false'
|
||||
|
||||
# Enable reCAPTCHA
|
||||
config.x.enable_recaptcha = ENV['ENABLE_RECAPTCHA'] == 'true'
|
||||
|
||||
|
|
|
@ -84,10 +84,6 @@ Rails.application.configure do
|
|||
# Enable/disable Deface
|
||||
config.deface.enabled = ENV['DEFACE_ENABLED'] != 'false'
|
||||
|
||||
# Enable first-time tutorial for users signing in the sciNote for
|
||||
# the first time.
|
||||
config.x.enable_tutorial = false
|
||||
|
||||
# Enable reCAPTCHA
|
||||
config.x.enable_recaptcha = false
|
||||
|
||||
|
|
|
@ -1322,14 +1322,6 @@ en:
|
|||
time_zone_sublabel: "Time zone setting affects all time & date fields throughout application."
|
||||
time_zone_title: "Time zone"
|
||||
update_flash: "Preferences successfully updated."
|
||||
tutorial:
|
||||
modal_title: "Repeat tutorial"
|
||||
no_teams: "Seems like you are not a member of any team. Tutorials can be run only by team members."
|
||||
repeat_tutorial: "Repeat tutorial"
|
||||
select_team_instruction: "Select the team where you wish to create the demo project."
|
||||
select_team: "Select team"
|
||||
tutorial_reset_flash: "Tutorial can now be repeated."
|
||||
tutorial_reset_error: "Tutorial could not be repeated."
|
||||
addons:
|
||||
head_title: "Settings | Add-ons"
|
||||
title: "Add-ons"
|
||||
|
@ -1722,39 +1714,6 @@ en:
|
|||
time: "%H:%M"
|
||||
short: "%H"
|
||||
|
||||
tutorial:
|
||||
title: "Tutorial"
|
||||
back: "Back"
|
||||
next: "Next"
|
||||
skip_tutorial: "Skip tutorial"
|
||||
finish_tutorial: "Start using sciNote"
|
||||
tutorial_welcome_title_html: "Welcome to <em>sciNote</em>, your electronic lab notebook. <em>sciNote</em> organizes your work in Projects. Click <strong>Team icon</strong> <span class='fa fa-users'></span> to choose Projects from which Team you want to view on your Dashboard. You can also reorder them by clicking the <strong>Sort by</strong> button. <strong>(Step 1/26)</strong>"
|
||||
create_project_html: "Click here to create a Project and it will appear under the Team you've chosen. Choose public <span class='glyphicon glyphicon-eye-open'></span> if you want everyone from the Team to view the Project or choose private <span class='glyphicon glyphicon-eye-close'></span> so only the people who you invite to the Project can see it. <strong>(Step 2/26)</strong>"
|
||||
project_options_html: "In the bottom row of the Project card you can check the latest activity <span class='glyphicon glyphicon-equalizer'></span>, invite collaborators <span class='glyphicon glyphicon-user'></span>, see the notifications <span class='glyphicon glyphicon-bell'></span> and write comments <span class='glyphicon glyphicon-comment'></span>. You can also edit the Project's name and visibility or archive it. You can recall the Project from the Archive <span class='glyphicon glyphicon-briefcase'></span> in the top right side of the Dashboard at any time. <strong>(Step 3/26)</strong>"
|
||||
create_experiment_html: "Inside of a Project you can create Experiments. To create one click on this button and edit Experiment’s name and description. <strong>(Step 4/26)</strong>"
|
||||
edit_experiment_html: "By clicking on the down arrow <span class='caret'></span> of an Experiment card you can choose between different actions. You can <strong>Edit details</strong> to the Experiment, such as experiment name and description, <strong>Copy</strong> it as template inside of a Project, where copied Experiment is identical to the original one, <strong>Move</strong> it from one Project to another or <strong>Archive</strong> it in the Archive <span class='glyphicon glyphicon-briefcase'></span>. <strong>(Step 5/26)</strong>"
|
||||
canvas_overview_html: "A Task is a basic unit of your Experiment. Within a Task, you can add Protocols, Results or Samples. You can connect Tasks into Workflows to assure traceability of your work. You can grab a Task or entire Workflow and move it in all directions on the canvas. <strong>(Step 6/26)</strong>"
|
||||
canvas_click_edit_workflow_html: " Click <strong>Edit experiment</strong> to add new Tasks or to modify an existing Experiment. <strong>(Step 7/26)</strong>"
|
||||
edit_workflow_html: "To add a new Task to the Experiment, click on <strong>New task</strong> and drag it onto canvas. <strong>(Step 8/26)</strong>"
|
||||
edit_workflow_click_save_html: "Click <strong>Save experiment</strong> to save changes you’ve made to the Experiment. <strong>(Step 9/26)</strong>"
|
||||
sidebar_html: "Navigation bar helps you to navigate through Experiments. It also helps you to find a specific Task on the canvas by clicking the navigate icon <span class='glyphicon glyphicon-map-marker'></span>. <strong>(Step 10/26)</strong>"
|
||||
sidebar_click_module_html: "Click on the Task name <strong>qPCR</strong> to see its contents. <strong>(Step 11/26)</strong>"
|
||||
module_protocols_html: "Inside of a Task you can create Protocol steps and upload existing protocol files. After you have finished a certain step, click the <strong>Complete step</strong> button. Exact time and the person who completed the step are recorded and can be seen in the <strong>Activity</strong> tab in the top right side of the Dashboard. <strong>(Step 12/26)</strong>"
|
||||
module_protocols_save_html: "You can save the protocol to Protocol repository. Everyone within the same Team will be able to use it. <strong>(Step 13/26)</strong>"
|
||||
module_protocols_click_results_html: "Click on the <strong>Results</strong> tab to upload experiment results. <strong>(Step 14/26)</strong>"
|
||||
module_results_html: "You can upload any type of a file, insert table or write comments. <strong>(Step 15/26)</strong>"
|
||||
module_results_click_samples_html: "Click on the <strong>Samples</strong> tab to import, export or assign samples to the Task. <strong>(Step 16/26)</strong>"
|
||||
samples_html: "You can easily import sample tables from Excel or tab-delimited files. If you assign samples to a certain Task, these samples will be automatically assigned downstream the Workflow. <strong>(Step 17/26)</strong>"
|
||||
breadcrumbs_html: "You can always use these <strong>Breadcrumbs</strong> to navigate all the way back to the Dashboard. Click on the <strong>Reports</strong> tab to generate a report of your work. <strong>(Step 18/26)</strong>"
|
||||
reports_index_click_new_report_html: "Click the <strong>New report</strong> button to create a new report. <strong>(Step 19/26)</strong>"
|
||||
new_report_html: "To add report elements to the report, click on the <strong>—+—</strong> sign on the sheet. Select the report contents in the tabs and click <strong>Add to report</strong>. You can save the report as a PDF on your computer or save it within sciNote for later viewing and modification. <strong>(Step 20/26)</strong>"
|
||||
new_report_click_team_html: "Click on <strong>%{private_team}</strong> in breadcrumbs to return to the Dashboard. <strong>(Step 21/26)</strong>"
|
||||
protocols_link_html: "Click on <span class='glyphicon glyphicon-list-alt'></span> to go to the Protocols repository page. <strong>(Step 22/26)</strong>"
|
||||
protocols_index_html: "View your Public and Private Protocols, which you can Edit, Create new ones or Copy them. Protocols can be archived and restored from the Archive. <strong>(Step 23/26)</strong>"
|
||||
protocols_import_export_html: "You can also Import or Export protocols to your hard drive. Return to the Dashboard. <strong>(Step 24/26)</strong>"
|
||||
archive_project_html: "Archive Demo project - qPCR by clicking on the down arrow <span class='glyphicon glyphicon-triangle-bottom'></span>. You can always access the Archive by clicking the <span class='glyphicon glyphicon-briefcase'></span> icon on the top right side of the Dashboard and restore any item you have archived. <strong>(Step 25/26)</strong>"
|
||||
goodbye_message: "To repeat the tutorial, go to your <strong>Settings</strong> and open <strong>Preferences</strong> tab. Click on the <strong>Repeat tutorial</strong> button and go through the tutorial as many times as needed. <strong>(Step 26/26)</strong>"
|
||||
|
||||
notifications:
|
||||
title: "Notifications"
|
||||
email_settings: "E-mail notifications"
|
||||
|
|
|
@ -56,12 +56,6 @@ Rails.application.routes.draw do
|
|||
put 'users/settings/account/preferences',
|
||||
to: 'users/settings/account/preferences#update',
|
||||
as: 'update_preferences'
|
||||
get 'users/settings/account/preferences/tutorial',
|
||||
to: 'users/settings/account/preferences#tutorial',
|
||||
as: 'tutorial'
|
||||
post 'users/settings/account/preferences/reset_tutorial/',
|
||||
to: 'users/settings/account/preferences#reset_tutorial',
|
||||
as: 'reset_tutorial'
|
||||
post 'users/settings/account/preferences/notifications_settings',
|
||||
to: 'users/settings/account/preferences#notifications_settings',
|
||||
as: 'notifications_settings',
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class RemoveTutorialStatusFromUser < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
remove_column :users, :tutorial_status, :integer, default: 0, null: false
|
||||
end
|
||||
end
|
|
@ -36,7 +36,6 @@ describe User, type: :model do
|
|||
it { should have_db_column :invited_by_id }
|
||||
it { should have_db_column :invited_by_type }
|
||||
it { should have_db_column :invitations_count }
|
||||
it { should have_db_column :tutorial_status }
|
||||
it { should have_db_column :settings }
|
||||
it { should have_db_column :current_team_id }
|
||||
it { should have_db_column :authentication_token }
|
||||
|
|