Add reports wizzard layout [SCI-5569]

This commit is contained in:
aignatov-bio 2021-03-25 13:12:52 +01:00
parent 6393337bc7
commit 0920d0a5cd
11 changed files with 398 additions and 169 deletions

View file

@ -966,3 +966,29 @@ function reportHandsonTableConverter() {
});
}, 0);
}
(function() {
function initReportWizard() {
function nextStep() {
var currentStep = parseInt($('.reports-new-footer').attr('data-step'), 10);
$(`[href="#new-report-step-${currentStep + 1}"]`).tab('show');
$('.reports-new-footer').attr('data-step', currentStep + 1);
}
function previousStep() {
var currentStep = parseInt($('.reports-new-footer').attr('data-step'), 10);
$(`[href="#new-report-step-${currentStep - 1}"]`).tab('show');
$('.reports-new-footer').attr('data-step', currentStep - 1);
}
$('.continue-button').on('click', function() {
nextStep();
});
$('.back-button').on('click', function() {
previousStep();
});
}
initReportWizard();
}());

View file

@ -12,31 +12,6 @@
updateButtons();
}
function initSelectPicker() {
$('.selectpicker').selectpicker({liveSearch: true})
.ajaxSelectPicker({
ajax: {
url: '<%= Rails.application.routes.url_helpers.reports_visible_projects_path %>',
type: 'POST',
dataType: 'json',
data: function () {
return { q: '{{{q}}}' };
}
},
locale: {
emptyTitle: 'Nothing selected'
},
preprocessData: appendSearchResults,
emptyRequest: true,
clearOnEmpty: false,
preserveSelected: false
}).on('change.bs.select', function(el) {
$('#new-report-reports-btn').attr('data-new-report-path', el.target.value);
}).on('loaded.bs.select', function(el) {
$('#new-report-reports-btn').attr('data-new-report-path', el.target.value);
});
}
function appendSearchResults(data) {
var items = [];
if(data.hasOwnProperty('projects')){
@ -53,14 +28,6 @@
return items;
}
function initRedirectToNewReportPage() {
$('#new-report-reports-btn').on('click', function() {
animateSpinner();
var url = $(this).attr('data-new-report-path');
$(location).attr('href', url);
});
}
function initToggleAllCheckboxes() {
$('input[name="select_all"]').change(function() {
if($(this).is(':checked')) {
@ -274,22 +241,7 @@
});
}
function initNewReportModal() {
var newReport = parseInt(sessionStorage.getItem('scinote-dashboard-new-report'), 10);
$('#new-report-btn').on('click', function() {
$('#new-report-modal').modal('show');
initSelectPicker();
initRedirectToNewReportPage();
});
if (Math.floor(Date.now() / 1000) - newReport < 15) {
$('#new-report-btn').click();
sessionStorage.removeItem('scinote-dashboard-new-report');
}
}
initDatatable();
initEditReport();
initDeleteReports();
initNewReportModal();
})(window);

View file

@ -35,6 +35,7 @@
@import "dashboard/*";
@import "repository/*";
@import "repository_columns/*";
@import "reports/*";
@import "settings/*";
@import "shared/*";
@import "themes/*";

View file

@ -0,0 +1,216 @@
// scss-lint:disable SelectorDepth
// scss-lint:disable NestingDepth
.reports-new {
height: calc(100vh - var(--navbar-height));
@mixin step-dot-active {
border: 2px solid $brand-primary;
}
@mixin step-dot-completed {
background: $brand-primary;
}
.reports-new-header {
align-items: center;
display: flex;
height: 4em;
.report-name-container {
width: 50%;
.report-name {
@include font-h1;
}
}
.cancel-button {
margin-left: auto;
}
}
.reports-new-body {
background: $color-concrete;
height: calc(100% - 10em);
margin-left: calc(-1em - 15px);
overflow-y: auto;
width: calc(100% + 2em + 30px);
}
.reports-new-footer {
align-items: center;
display: flex;
height: 6em;
.back-container {
flex-basis: 25%;
}
.wizard-status {
display: flex;
flex-basis: 50%;
justify-content: center;
position: relative;
}
.wizard-steps {
--wizard-step-dot-size: 8px;
color: $color-silver-chalice;
flex: 1;
font-weight: bold;
position: relative;
text-align: center;
user-select: none;
z-index: 2;
.step-id {
@include font-h3;
display: inline-block;
line-height: 1.5em;
text-align: center;
width: calc(2 * var(--wizard-step-dot-size));
}
.step-dot {
background: $color-concrete;
border-radius: 50%;
display: inline-block;
height: var(--wizard-step-dot-size);
margin: 0 calc(var(--wizard-step-dot-size) / 2);
width: var(--wizard-step-dot-size);
}
.step-name {
display: inline-block;
white-space: nowrap;
}
&.wizard-step-1 {
text-align: left;
.name-wrapper {
margin-left: calc(-50% + 2 * var(--wizard-step-dot-size));
}
}
&.wizard-step-3 {
text-align: right;
.name-wrapper {
margin-right: calc(-50% + 2 * var(--wizard-step-dot-size));
}
}
}
.progress-line {
background: $color-concrete;
height: 4px;
margin: 12px 0;
position: absolute;
top: 1.5em;
width: calc(50% - 8px);
z-index: 1;
&.progress-step-1 {
left: 8px;
}
&.progress-step-2 {
right: 8px;
}
}
.generate-button {
display: none;
}
.next-button-container {
flex-basis: 25%;
margin-left: auto;
text-align: right;
}
&[data-step="1"] {
.wizard-step-1 {
color: initial;
.step-dot {
@include step-dot-active;
}
}
.back-button {
display: none;
}
}
&[data-step="2"] {
.wizard-step-1 {
.step-dot {
@include step-dot-completed;
}
}
.wizard-step-2 {
color: initial;
.step-dot {
@include step-dot-active;
}
}
.progress-step-1 {
background: $brand-primary;
}
}
&[data-step="3"] {
.wizard-step-1 {
.step-dot {
@include step-dot-completed;
}
}
.wizard-step-2 {
.step-dot {
@include step-dot-completed;
}
}
.wizard-step-3 {
color: initial;
.step-dot {
@include step-dot-active;
}
}
.continue-button {
display: none;
}
.generate-button {
display: initial;
}
.progress-step-1,
.progress-step-2 {
background: $brand-primary;
}
}
}
}
@media (max-width: 960px) {
.reports-new {
.reports-new-footer {
.wizard-status {
display: none;
}
}
}
}

View file

@ -6,7 +6,6 @@ class ReportsController < ApplicationController
protect_from_forgery with: :exception, except: :generate
BEFORE_ACTION_METHODS = %i(
new
create
edit
update
@ -26,7 +25,7 @@ class ReportsController < ApplicationController
before_action :load_vars, only: %i(edit update)
before_action :load_vars_nested, only: BEFORE_ACTION_METHODS
before_action :load_visible_projects, only: %i(index visible_projects)
before_action :load_visible_projects, only: :visible_projects
before_action :load_available_repositories,
only: %i(new edit available_repositories)
@ -50,7 +49,6 @@ class ReportsController < ApplicationController
# Report grouped by modules
def new
@report = nil
end
# Creating new report from the _save modal of the new page

View file

@ -1,6 +1,6 @@
<% if can_manage_reports?(current_team) %>
<div class="sci-btn-group">
<%= link_to '#', remote: true, class: 'btn btn-primary', id: 'new-report-btn' do %>
<%= link_to new_report_path, class: 'btn btn-primary', id: 'new-report-btn' do %>
<span class="fas fa-plus" aria-hidden="true"></span>
<span class="hidden-xs"><%= t("projects.reports.index.new") %></span>
<% end %>

View file

@ -61,39 +61,4 @@
<% end %>
</div>
<div class="modal" id="new-report-modal" tabindex="-1" role="dialog" aria-labelledby="create-reports-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">&times;</span></button>
<h4 class="modal-title" id="new-report-modal-label"><%=t "projects.reports.index.modal_new.head_title" %></h4>
</div>
<div class="modal-body">
<p><%=t "projects.reports.index.modal_new.message" %></p>
<div class="form-group">
<label><%=t "projects.reports.index.modal_new.projects" %></label>
<% if @visible_projects&.length > 0 %>
<select class="form-control selectpicker" data-abs-min-length="2" data-live-search="true">
<% @visible_projects.each do |project| %>
<option value="<%= project.path %>"><%= project.name %></option>
<% end %>
</select>
<% else %>
<p><%=t 'projects.reports.index.modal_new.no_projects' %></p>
<% end %>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t "general.cancel" %></button>
<button id="new-report-reports-btn"
class="btn btn-primary"
data-new-report-path="<%= @visible_projects.first.path if @visible_projects.first %>"
<%= 'disabled' unless @visible_projects&.length > 0 %>
><%=t 'projects.reports.index.modal_new.create' %></button>
</div>
</div>
</div>
</div>
<%= javascript_include_tag("reports/reports_datatable") %>

View file

@ -1,88 +1,63 @@
<% content_for :head do %>
<meta name="turbolinks-cache-control" content="no-cache">
<meta name="turbolinks-visit-control" content="reload">
<% end %>
<div class="content-pane flexible reports-new">
<div class="reports-new-header">
<div class="sci-input-container report-name-container">
<input type="text" class="sci-input-field report-name" placeholder="<%= t("projects.reports.new.report_name_placeholder") %>"></input>
<% provide(:head_title, t("projects.reports.new.head_title", project: h(@project.name)).html_safe) %>
<%= render partial: "reports/new/report_navigation" %>
<div class="content-pane" id="report-new">
<div class="report-container">
<div
id="data-holder"
class="hidden"
data-project-modal-title="<%=t "projects.reports.elements.modals.project_contents.head_title" %>"
data-add-project-contents-url="<%= project_contents_modal_project_reports_url(@project) %>"
data-add-experiment-contents-url="<%= experiment_contents_modal_project_reports_url(@project) %>"
data-add-module-contents-url="<%= module_contents_modal_project_reports_url(@project) %>"
data-add-step-contents-url="<%= step_contents_modal_project_reports_url(@project) %>"
data-add-result-contents-url="<%= result_contents_modal_project_reports_url(@project) %>"
data-stylesheet-url="<%= stylesheet_path "application" %>"
data-print-title="<%=t "projects.reports.print_title", project: @project.name %>"
data-project-id="<%= @project.id %>"
data-save-report-url="<%= save_modal_project_reports_url(@project) %>"
data-report-id="<%= @report.present? ? @report.id : "" %>"
data-unsaved-work-text="<%=t "projects.reports.new.unsaved_work" %>"
data-global-sort-text="<%=t "projects.reports.new.global_sort" %>"></div>
<!-- Report "preview" -->
<div id="report-content">
<% if @report.present? %>
<% @report.root_elements.each do |el| %>
<%= render_report_element(el, local_assigns) %>
<%= render_new_element(false) %>
<% end %>
<% else %>
<%= render partial: "reports/elements/project_header_element", locals: { project: @project } %>
<%= render partial: "reports/elements/new_element", locals: { initial: true } %>
<% end %>
</div>
<!-- Add elements modal -->
<div class="modal" id="add-contents-modal" tabindex="-1" role="dialog" aria-labelledby="add-contents-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">&times;</span></button>
<h4 class="modal-title" id="add-contents-modal-label"></h4>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t "general.cancel" %></button>
<button type="button" data-action="add" class="btn btn-primary"><%=t "projects.reports.elements.modals.add" %></button>
</div>
</div>
</div>
</div>
<!-- Save report modal -->
<div class="modal" id="save-report-modal" tabindex="-1" role="dialog" aria-labelledby="save-report-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">&times;</span></button>
<h4 class="modal-title" id="save-report-modal-label"><%=t "projects.reports.elements.modals.save_report.head_title" %></h4>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t "general.cancel" %></button>
<button type="button" data-action="save" class="btn btn-primary"><%=t "projects.reports.elements.modals.save_report.save" %></button>
</div>
</div>
<button class="btn btn-secondary cancel-button">
<%= t("general.cancel") %>
</button>
</div>
<div class="reports-new-body">
<ul class="nav nav-tabs hidden">
<li role="presentation"><a href="#new-report-step-1" data-toggle="tab" data-no-turbolink="true"></a></li>
<li role="presentation"><a href="#new-report-step-2" data-toggle="tab" data-no-turbolink="true"></a></li>
<li role="presentation"><a href="#new-report-step-3" data-toggle="tab" data-no-turbolink="true"></a></li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="new-report-step-1">
Step 1
</div>
<div role="tabpanel" class="tab-pane" id="new-report-step-2">
Step 2
</div>
<div role="tabpanel" class="tab-pane" id="new-report-step-3">
Step 3
</div>
</div>
</div>
<div class="reports-new-footer" data-step="1">
<div class="back-container">
<button class="btn btn-secondary back-button">
<%= t("general.back") %>
</button>
</div>
<div class="wizard-status">
<div class="progress-line progress-step-1"></div>
<div class="progress-line progress-step-2"></div>
<% 3.times do |i| %>
<div class="wizard-steps wizard-step-<%= i + 1 %>">
<div class="step-id">
<%= i + 1 %>
</div><br>
<div class="step-dot"></div><br>
<div class="step-name">
<span class=name-wrapper>
<%= t("projects.reports.new.wizard_statuses.step_#{i + 1}") %>
</span>
</div>
</div>
<% end %>
</div>
<div class="next-button-container">
<button class="btn btn-primary continue-button">
<%= t("projects.reports.new.continue_button") %>
</button>
<button class="btn btn-primary generate-button">
<%= t("projects.reports.new.generate_button") %>
</button>
</div>
</div>
</div>
<%= render partial: 'reports/new/save_PDF_to_inventory_modal' %>
<%= javascript_include_tag "handsontable.full.min" %>
<!-- Libraries for formulas -->
<%= render partial: "shared/formulas_libraries.html.erb" %>
<%= javascript_include_tag("reports/new") %>
<%= javascript_include_tag 'reports/save_pdf_to_inventory' %>

View file

@ -0,0 +1,88 @@
<% content_for :head do %>
<meta name="turbolinks-cache-control" content="no-cache">
<meta name="turbolinks-visit-control" content="reload">
<% end %>
<% provide(:head_title, t("projects.reports.new.head_title", project: h(@project.name)).html_safe) %>
<%= render partial: "reports/new/report_navigation" %>
<div class="content-pane" id="report-new">
<div class="report-container">
<div
id="data-holder"
class="hidden"
data-project-modal-title="<%=t "projects.reports.elements.modals.project_contents.head_title" %>"
data-add-project-contents-url="<%= project_contents_modal_project_reports_url(@project) %>"
data-add-experiment-contents-url="<%= experiment_contents_modal_project_reports_url(@project) %>"
data-add-module-contents-url="<%= module_contents_modal_project_reports_url(@project) %>"
data-add-step-contents-url="<%= step_contents_modal_project_reports_url(@project) %>"
data-add-result-contents-url="<%= result_contents_modal_project_reports_url(@project) %>"
data-stylesheet-url="<%= stylesheet_path "application" %>"
data-print-title="<%=t "projects.reports.print_title", project: @project.name %>"
data-project-id="<%= @project.id %>"
data-save-report-url="<%= save_modal_project_reports_url(@project) %>"
data-report-id="<%= @report.present? ? @report.id : "" %>"
data-unsaved-work-text="<%=t "projects.reports.new.unsaved_work" %>"
data-global-sort-text="<%=t "projects.reports.new.global_sort" %>"></div>
<!-- Report "preview" -->
<div id="report-content">
<% if @report.present? %>
<% @report.root_elements.each do |el| %>
<%= render_report_element(el, local_assigns) %>
<%= render_new_element(false) %>
<% end %>
<% else %>
<%= render partial: "reports/elements/project_header_element", locals: { project: @project } %>
<%= render partial: "reports/elements/new_element", locals: { initial: true } %>
<% end %>
</div>
<!-- Add elements modal -->
<div class="modal" id="add-contents-modal" tabindex="-1" role="dialog" aria-labelledby="add-contents-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">&times;</span></button>
<h4 class="modal-title" id="add-contents-modal-label"></h4>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t "general.cancel" %></button>
<button type="button" data-action="add" class="btn btn-primary"><%=t "projects.reports.elements.modals.add" %></button>
</div>
</div>
</div>
</div>
<!-- Save report modal -->
<div class="modal" id="save-report-modal" tabindex="-1" role="dialog" aria-labelledby="save-report-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">&times;</span></button>
<h4 class="modal-title" id="save-report-modal-label"><%=t "projects.reports.elements.modals.save_report.head_title" %></h4>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t "general.cancel" %></button>
<button type="button" data-action="save" class="btn btn-primary"><%=t "projects.reports.elements.modals.save_report.save" %></button>
</div>
</div>
</div>
</div>
</div>
</div>
<%= render partial: 'reports/new/save_PDF_to_inventory_modal' %>
<%= javascript_include_tag "handsontable.full.min" %>
<!-- Libraries for formulas -->
<%= render partial: "shared/formulas_libraries.html.erb" %>
<%= javascript_include_tag("reports/new") %>
<%= javascript_include_tag 'reports/save_pdf_to_inventory' %>

View file

@ -523,6 +523,14 @@ en:
message: "Are you sure to delete selected report/s?"
delete: "Delete"
new:
report_name_placeholder: "Name your report"
wizard_statuses:
step_1: "Select project"
step_2: "Select tasks"
step_3: "Select task contents"
continue_button: "Continue"
generate_button: "Start generating"
head_title: "%{project} | New report"
nav_title: "Report for: "
nav_print: "Print"
@ -2371,6 +2379,7 @@ en:
edit: "Edit"
delete: "Delete"
cancel: "Cancel"
back: "Back"
close: "Close"
create: 'Create'
change: "Change"

View file

@ -194,7 +194,7 @@ Rails.application.routes.draw do
via: [:get, :post, :put, :patch]
end
resources :reports, only: :index
resources :reports, only: [:index, :new]
get 'reports/datatable', to: 'reports#datatable'
post 'reports/visible_projects', to: 'reports#visible_projects',
defaults: { format: 'json' }
@ -247,7 +247,6 @@ Rails.application.routes.draw do
# The posts following here should in theory be gets,
# but are posts because of parameters payload
post 'generate', to: 'reports#generate', format: %w(docx pdf)
get 'new/', to: 'reports#new'
get 'new/project_contents_modal',
to: 'reports#project_contents_modal',
as: :project_contents_modal