mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-02-01 20:48:23 +08:00
Merge pull request #2927 from biosistemika/features/signature-requests
Features/signature requests into develop
This commit is contained in:
commit
e923128c0e
13 changed files with 216 additions and 215 deletions
|
@ -8,19 +8,19 @@ var DasboardQuickStartWidget = (function() {
|
||||||
var newProjectsVisibility = '#create-task-modal .new-projects-visibility';
|
var newProjectsVisibility = '#create-task-modal .new-projects-visibility';
|
||||||
|
|
||||||
function initNewReportLink() {
|
function initNewReportLink() {
|
||||||
$('.quick-start-widget .new-report').click(() => {
|
$('.quick-start-buttons .new-report').click(() => {
|
||||||
sessionStorage.setItem('scinote-dashboard-new-report', Math.floor(Date.now() / 1000));
|
sessionStorage.setItem('scinote-dashboard-new-report', Math.floor(Date.now() / 1000));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initNewProtocolLink() {
|
function initNewProtocolLink() {
|
||||||
$('.quick-start-widget .new-protocol').click(() => {
|
$('.quick-start-buttons .new-protocol').click(() => {
|
||||||
sessionStorage.setItem('scinote-dashboard-new-protocol', Math.floor(Date.now() / 1000));
|
sessionStorage.setItem('scinote-dashboard-new-protocol', Math.floor(Date.now() / 1000));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initNewTaskModal() {
|
function initNewTaskModal() {
|
||||||
$('.quick-start-widget .new-task').click(() => {
|
$('.quick-start-buttons .new-task').click(() => {
|
||||||
$('#create-task-modal').modal('show');
|
$('#create-task-modal').modal('show');
|
||||||
$('#create-task-modal .select-block').attr('data-error', '');
|
$('#create-task-modal .select-block').attr('data-error', '');
|
||||||
});
|
});
|
||||||
|
@ -118,7 +118,7 @@ var DasboardQuickStartWidget = (function() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: () => {
|
init: () => {
|
||||||
if ($('.quick-start-widget').length) {
|
if ($('.quick-start-buttons').length) {
|
||||||
initNewTaskModal();
|
initNewTaskModal();
|
||||||
initNewProtocolLink();
|
initNewProtocolLink();
|
||||||
initNewReportLink();
|
initNewReportLink();
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
.dashboard-container .calendar-widget {
|
.dashboard-container .calendar-widget {
|
||||||
--calendar-day-size: 32px;
|
--calendar-day-size: 32px;
|
||||||
grid-column: 10 / span 3;
|
|
||||||
grid-row: 1 / span 6;
|
|
||||||
min-height: 320px;
|
min-height: 320px;
|
||||||
|
|
||||||
.dashboard-calendar {
|
.dashboard-calendar {
|
||||||
|
@ -127,17 +125,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1250px) {
|
@media (max-width: 1600px) {
|
||||||
.dashboard-container .calendar-widget {
|
.dashboard-container .calendar-widget {
|
||||||
grid-column: 9 / span 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1000px) {
|
|
||||||
.dashboard-container .calendar-widget {
|
|
||||||
grid-column: 1 / span 6;
|
|
||||||
grid-row: 5 / span 4;
|
|
||||||
|
|
||||||
.clndr {
|
.clndr {
|
||||||
.events-container {
|
.events-container {
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -150,7 +139,5 @@
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
.dashboard-container .calendar-widget {
|
.dashboard-container .calendar-widget {
|
||||||
--calendar-day-size: 28px;
|
--calendar-day-size: 28px;
|
||||||
grid-column: 1 / span 12;
|
|
||||||
grid-row: 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
// scss-lint:disable NestingDepth
|
// scss-lint:disable NestingDepth
|
||||||
|
|
||||||
.dashboard-container .current-tasks-widget {
|
.dashboard-container .current-tasks-widget {
|
||||||
grid-column: 1 / span 9;
|
|
||||||
grid-row: 1 / span 6;
|
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
@ -250,8 +248,6 @@
|
||||||
|
|
||||||
@media (max-width: 1250px) {
|
@media (max-width: 1250px) {
|
||||||
.dashboard-container .current-tasks-widget {
|
.dashboard-container .current-tasks-widget {
|
||||||
grid-column: 1 / span 8;
|
|
||||||
|
|
||||||
.task-progress-container {
|
.task-progress-container {
|
||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
}
|
}
|
||||||
|
@ -271,9 +267,6 @@
|
||||||
|
|
||||||
@media (max-width: 1000px) {
|
@media (max-width: 1000px) {
|
||||||
.dashboard-container .current-tasks-widget {
|
.dashboard-container .current-tasks-widget {
|
||||||
grid-column: 1 / span 12;
|
|
||||||
grid-row: 1 / span 4;
|
|
||||||
|
|
||||||
.no-tasks .fas {
|
.no-tasks .fas {
|
||||||
margin-left: 500px;
|
margin-left: 500px;
|
||||||
}
|
}
|
||||||
|
@ -283,7 +276,6 @@
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
.dashboard-container .current-tasks-widget {
|
.dashboard-container .current-tasks-widget {
|
||||||
--widget-header-size: 72px;
|
--widget-header-size: 72px;
|
||||||
grid-row: 1;
|
|
||||||
min-height: 450px;
|
min-height: 450px;
|
||||||
|
|
||||||
.widget-title {
|
.widget-title {
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
// scss-lint:disable SelectorDepth
|
|
||||||
// scss-lint:disable NestingDepth
|
|
||||||
|
|
||||||
.dashboard-container .quick-start-widget {
|
|
||||||
grid-column: 1 / span 2;
|
|
||||||
grid-row: 7 / span 6;
|
|
||||||
|
|
||||||
.widget-body {
|
|
||||||
.quick-start-description {
|
|
||||||
margin: 16px 16px 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-secondary {
|
|
||||||
margin: 8px 16px;
|
|
||||||
text-align: left;
|
|
||||||
width: calc(100% - 32px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1700px) {
|
|
||||||
.dashboard-container .quick-start-widget {
|
|
||||||
grid-column: 1 / span 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 1300px) {
|
|
||||||
.dashboard-container .quick-start-widget {
|
|
||||||
grid-column: 1 / span 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1000px) {
|
|
||||||
.dashboard-container .quick-start-widget {
|
|
||||||
grid-column: 7 / span 6;
|
|
||||||
grid-row: 5 / span 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
|
||||||
.dashboard-container .quick-start-widget {
|
|
||||||
--widget-header-size: 36px;
|
|
||||||
grid-column: 1 / span 12;
|
|
||||||
grid-row: 4;
|
|
||||||
min-height: 300px;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,9 +2,6 @@
|
||||||
// scss-lint:disable NestingDepth
|
// scss-lint:disable NestingDepth
|
||||||
|
|
||||||
.dashboard-container .recent-work-widget {
|
.dashboard-container .recent-work-widget {
|
||||||
grid-column: 3 / span 7;
|
|
||||||
grid-row: 7 / span 6;
|
|
||||||
|
|
||||||
.widget-title {
|
.widget-title {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
@ -58,24 +55,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1700px) {
|
|
||||||
.dashboard-container .recent-work-widget {
|
|
||||||
grid-column: 4 / span 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 1300px) {
|
|
||||||
.dashboard-container .recent-work-widget {
|
|
||||||
grid-column: 5 / span 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1000px) {
|
@media (max-width: 1000px) {
|
||||||
.dashboard-container .recent-work-widget {
|
.dashboard-container .recent-work-widget {
|
||||||
grid-column: 1 / span 12;
|
|
||||||
grid-row: 9 / span 4;
|
|
||||||
|
|
||||||
.no-results {
|
.no-results {
|
||||||
.no-results-arrow {
|
.no-results-arrow {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -84,14 +66,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 1100px) {
|
||||||
.dashboard-container .recent-work-widget {
|
.dashboard-container .recent-work-widget {
|
||||||
--widget-header-size: 72px;
|
|
||||||
grid-row: 3;
|
|
||||||
min-height: 450px;
|
min-height: 450px;
|
||||||
|
|
||||||
.widget-title {
|
.widget-title {
|
||||||
flex-basis: 100%;
|
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,53 @@
|
||||||
// scss-lint:disable SelectorDepth
|
// scss-lint:disable SelectorDepth
|
||||||
// scss-lint:disable NestingDepth
|
// scss-lint:disable NestingDepth
|
||||||
|
|
||||||
.dashboard-container {
|
.dashboard-background {
|
||||||
|
background: $color-concrete;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-view {
|
||||||
--dashboard-widgets-gap: 30px;
|
--dashboard-widgets-gap: 30px;
|
||||||
|
padding: calc(var(--dashboard-widgets-gap) / 2)
|
||||||
|
calc(var(--dashboard-widgets-gap) / 2)
|
||||||
|
var(--dashboard-widgets-gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-header {
|
||||||
|
padding-bottom: calc(var(--dashboard-widgets-gap) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-container {
|
||||||
--widget-header-size: 44px;
|
--widget-header-size: 44px;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
grid-auto-rows: 30em;
|
||||||
grid-column-gap: var(--dashboard-widgets-gap);
|
grid-column-gap: var(--dashboard-widgets-gap);
|
||||||
grid-row-gap: var(--dashboard-widgets-gap);
|
grid-row-gap: var(--dashboard-widgets-gap);
|
||||||
grid-template-columns: repeat(12, 1fr);
|
grid-template-columns: repeat(auto-fit, minmax(7em, 1fr));
|
||||||
grid-template-rows: repeat(12, 1fr);
|
|
||||||
min-height: calc(100vh - 51px);
|
|
||||||
padding: var(--dashboard-widgets-gap) calc(var(--dashboard-widgets-gap) - 15px);
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.basic-widget {
|
.basic-widget {
|
||||||
|
background: $color-white;
|
||||||
border-radius: $border-radius-modal;
|
border-radius: $border-radius-modal;
|
||||||
box-shadow: $flyout-shadow;
|
box-shadow: $flyout-shadow;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
&.large-widget {
|
||||||
|
grid-column: auto / 9 span;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.medium-widget {
|
||||||
|
grid-column: auto / 6 span;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.small-widget {
|
||||||
|
grid-column: auto / 3 span;
|
||||||
|
}
|
||||||
|
|
||||||
.widget-header {
|
.widget-header {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-bottom: $border-tertiary;
|
border-bottom: $border-tertiary;
|
||||||
|
@ -27,6 +57,7 @@
|
||||||
|
|
||||||
.widget-title {
|
.widget-title {
|
||||||
@include font-h2;
|
@include font-h2;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,16 +82,50 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1300px) {
|
@media (max-width: 1100px) {
|
||||||
.dashboard-container {
|
.dashboard-container {
|
||||||
--dashboard-widgets-gap: 16px;
|
--dashboard-widgets-gap: 15px;
|
||||||
|
grid-template-columns: 100%;
|
||||||
|
|
||||||
|
.basic-widget {
|
||||||
|
&.large-widget,
|
||||||
|
&.medium-widget,
|
||||||
|
&.small-widget {
|
||||||
|
grid-column: auto / 1 span;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-height: 800px) {
|
||||||
|
.dashboard-container {
|
||||||
|
grid-auto-rows: 24em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-height: 1300px) {
|
||||||
|
.dashboard-container {
|
||||||
|
grid-auto-rows: 36em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
|
|
||||||
|
.dashboard-view {
|
||||||
|
--dashboard-widgets-gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.dashboard-container {
|
.dashboard-container {
|
||||||
--widget-header-size: 72px;
|
--widget-header-size: 72px;
|
||||||
grid-template-rows: auto;
|
grid-auto-rows: auto;
|
||||||
|
|
||||||
|
.basic-widget {
|
||||||
|
&.large-widget,
|
||||||
|
&.medium-widget,
|
||||||
|
&.small-widget {
|
||||||
|
grid-column: 1 span;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.widget-header {
|
.widget-header {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Report < ApplicationRecord
|
class Report < ApplicationRecord
|
||||||
include SearchableModel
|
include SearchableModel
|
||||||
include SearchableByNameModel
|
include SearchableByNameModel
|
||||||
|
@ -58,7 +60,7 @@ class Report < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def root_elements
|
def root_elements
|
||||||
(report_elements.order(:position)).select { |el| el.parent.blank? }
|
report_elements.order(:position).select { |el| el.parent.blank? }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Save the JSON represented contents to this report
|
# Save the JSON represented contents to this report
|
||||||
|
@ -66,7 +68,7 @@ class Report < ApplicationRecord
|
||||||
def save_with_contents(json_contents)
|
def save_with_contents(json_contents)
|
||||||
begin
|
begin
|
||||||
Report.transaction do
|
Report.transaction do
|
||||||
#First, save the report itself
|
# First, save the report itself
|
||||||
save!
|
save!
|
||||||
|
|
||||||
# Secondly, delete existing report elements
|
# Secondly, delete existing report elements
|
||||||
|
@ -80,67 +82,17 @@ class Report < ApplicationRecord
|
||||||
rescue ActiveRecord::ActiveRecordError, ArgumentError
|
rescue ActiveRecord::ActiveRecordError, ArgumentError
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
return true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
# Clean report elements from report
|
# Clean report elements from report
|
||||||
# the function runs before the report is edit
|
# the function runs before the report is edit
|
||||||
def cleanup_report
|
def cleanup_report
|
||||||
report_elements.each do |el|
|
report_elements.each(&:clean_removed_or_archived_elements)
|
||||||
el.clean_removed_or_archived_elements
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.generate_whole_project_report(project, current_user, current_team)
|
def self.generate_whole_project_report(project, current_user, current_team)
|
||||||
report_contents = gen_element_content(project, nil, 'project_header', true)
|
report_contents = gen_element_content(project, Extends::EXPORT_ALL_PROJECT_ELEMENTS)
|
||||||
|
|
||||||
project.experiments.each do |exp|
|
|
||||||
modules = []
|
|
||||||
|
|
||||||
exp.my_modules.each do |my_module|
|
|
||||||
module_children = []
|
|
||||||
|
|
||||||
module_children += gen_element_content(my_module, nil, 'my_module_protocol', true)
|
|
||||||
my_module.protocol.steps.each do |step|
|
|
||||||
step_children =
|
|
||||||
gen_element_content(step, step.assets, 'step_asset')
|
|
||||||
step_children +=
|
|
||||||
gen_element_content(step, step.tables, 'step_table')
|
|
||||||
step_children +=
|
|
||||||
gen_element_content(step, step.checklists, 'step_checklist')
|
|
||||||
step_children +=
|
|
||||||
gen_element_content(step, nil, 'step_comments', true, 'asc')
|
|
||||||
|
|
||||||
module_children +=
|
|
||||||
gen_element_content(step, nil, 'step', true, nil, step_children)
|
|
||||||
end
|
|
||||||
|
|
||||||
my_module.results.each do |result|
|
|
||||||
result_children =
|
|
||||||
gen_element_content(result, nil, 'result_comments', true, 'asc')
|
|
||||||
|
|
||||||
result_type = if result.asset
|
|
||||||
'result_asset'
|
|
||||||
elsif result.table
|
|
||||||
'result_table'
|
|
||||||
elsif result.result_text
|
|
||||||
'result_text'
|
|
||||||
end
|
|
||||||
module_children +=
|
|
||||||
gen_element_content(result, nil, result_type, true, nil,
|
|
||||||
result_children)
|
|
||||||
end
|
|
||||||
|
|
||||||
repositories = project.assigned_repositories_and_snapshots
|
|
||||||
|
|
||||||
module_children += gen_element_content(my_module, nil, 'my_module_activity', true, 'asc')
|
|
||||||
module_children += gen_element_content(my_module, repositories, 'my_module_repository', true, 'asc')
|
|
||||||
modules += gen_element_content(my_module, nil, 'my_module', true, nil, module_children)
|
|
||||||
end
|
|
||||||
|
|
||||||
report_contents +=
|
|
||||||
gen_element_content(exp, nil, 'experiment', true, nil, modules)
|
|
||||||
end
|
|
||||||
|
|
||||||
report = Report.new
|
report = Report.new
|
||||||
report.name = loop do
|
report.name = loop do
|
||||||
|
@ -155,31 +107,29 @@ class Report < ApplicationRecord
|
||||||
report
|
report
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.gen_element_content(parent_obj, association_objs, type_of,
|
def self.gen_element_content(parent, children)
|
||||||
use_parent_id = false, sort_order = nil,
|
|
||||||
children = nil)
|
|
||||||
parent_type = parent_obj.class.name.underscore
|
|
||||||
type = type_of.split('_').last.singularize
|
|
||||||
extra_id_needed = use_parent_id && !association_objs.nil?
|
|
||||||
elements = []
|
elements = []
|
||||||
|
|
||||||
association_objs ||= [nil]
|
children.each do |element|
|
||||||
association_objs.each do |obj|
|
element_hash = lambda { |object|
|
||||||
elements << {
|
hash_object = {
|
||||||
'type_of' => type_of,
|
'type_of' => element[:type_of] || element[:type_of_lambda].call(object),
|
||||||
'id' => {}.tap do |ids_hash|
|
'id' => { element[:id_key] => object.id },
|
||||||
if use_parent_id
|
'sort_order' => element[:sort_order],
|
||||||
ids_hash["#{parent_type}_id"] = parent_obj.id
|
'children' => gen_element_content(object, element[:children] || [])
|
||||||
else
|
}
|
||||||
ids_hash["#{type}_id"] = obj.id
|
hash_object['id'][element[:parent_id_key]] = parent.id if element[:parent_id_key]
|
||||||
end
|
hash_object
|
||||||
ids_hash["#{type}_id"] = obj.id if extra_id_needed
|
|
||||||
end,
|
|
||||||
'sort_order' => sort_order.present? ? sort_order : nil,
|
|
||||||
'children' => children.present? ? children : []
|
|
||||||
}
|
}
|
||||||
end
|
|
||||||
|
|
||||||
|
if element[:relation]
|
||||||
|
(element[:relation].inject(parent) { |p, method| p.public_send(method) }).each do |child|
|
||||||
|
elements.push(element_hash.call(child))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
elements.push(element_hash.call(parent))
|
||||||
|
end
|
||||||
|
end
|
||||||
elements
|
elements
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="calendar-widget basic-widget">
|
<div class="calendar-widget basic-widget <%= widget[:size] %>" style="order: <%= widget[:position] %>">
|
||||||
<div class="dashboard-calendar"
|
<div class="dashboard-calendar"
|
||||||
data-month-events-url="<%= dashboard_calendar_path %>"
|
data-month-events-url="<%= dashboard_calendar_path %>"
|
||||||
data-day-events-url="<%= day_dashboard_calendar_path %>"
|
data-day-events-url="<%= day_dashboard_calendar_path %>"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="current-tasks-widget basic-widget">
|
<div class="current-tasks-widget basic-widget <%= widget[:size] %>" style="order: <%= widget[:position] %>">
|
||||||
<div class="widget-header">
|
<div class="widget-header">
|
||||||
<div class="widget-title"><%= t("dashboard.current_tasks.title") %></div>
|
<div class="widget-title"><%= t("dashboard.current_tasks.title") %></div>
|
||||||
<div class="actions-container">
|
<div class="actions-container">
|
||||||
|
|
|
@ -1,27 +1,12 @@
|
||||||
<div class="quick-start-widget basic-widget">
|
<% unless current_user.is_guest_of_team?(current_team) %>
|
||||||
<div class="widget-header">
|
<div class="quick-start-buttons">
|
||||||
<div class="widget-title">
|
<div class="new-task btn btn-secondary"><i class="fas fa-plus"></i><%= t("dashboard.quick_start.new_task") %></div>
|
||||||
<%= t("dashboard.quick_start.title") %>
|
<%= link_to protocols_path, {class: "new-protocol btn btn-secondary"} do %>
|
||||||
</div>
|
<i class="fas fa-edit"></i><%= t("dashboard.quick_start.new_protocol") %>
|
||||||
</div>
|
<% end %>
|
||||||
<div class="widget-body">
|
<%= link_to reports_path, {class: "new-report btn btn-secondary"} do %>
|
||||||
<% if current_user.is_guest_of_team?(current_team) %>
|
<i class="fas fa-clipboard-check"></i><%= t("dashboard.quick_start.new_report") %>
|
||||||
<div class="widget-placeholder">
|
|
||||||
<p class="widget-placeholder-title"><%= t("dashboard.quick_start.placeholder.title") %></p>
|
|
||||||
<p class="widget-placeholder-description"><%= t("dashboard.quick_start.placeholder.description") %></p>
|
|
||||||
</div>
|
|
||||||
<% else %>
|
|
||||||
<div class="quick-start-description">
|
|
||||||
<%= t("dashboard.quick_start.description") %>
|
|
||||||
</div>
|
|
||||||
<div class="new-task btn btn-secondary btn-block"><i class="fas fa-plus"></i><%= t("dashboard.quick_start.new_task") %></div>
|
|
||||||
<%= link_to protocols_path, {class: "new-protocol btn btn-secondary btn-block"} do %>
|
|
||||||
<i class="fas fa-edit"></i><%= t("dashboard.quick_start.new_protocol") %>
|
|
||||||
<% end %>
|
|
||||||
<%= link_to reports_path, {class: "new-report btn btn-secondary btn-block"} do %>
|
|
||||||
<i class="fas fa-clipboard-check"></i><%= t("dashboard.quick_start.new_report") %>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<%= render "create_task_modal" %>
|
||||||
<%= render "create_task_modal" %>
|
<% end %>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="recent-work-widget basic-widget">
|
<div class="recent-work-widget basic-widget <%= widget[:size] %>" style="order: <%= widget[:position] %>">
|
||||||
<div class="widget-header">
|
<div class="widget-header">
|
||||||
<div class="widget-title">
|
<div class="widget-title">
|
||||||
<%= t('dashboard.recent_work.title') %>
|
<%= t('dashboard.recent_work.title') %>
|
||||||
|
@ -37,4 +37,4 @@
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
<% provide :head_title, t('nav.label.dashboard') %>
|
<% provide :head_title, t('nav.label.dashboard') %>
|
||||||
|
|
||||||
<% if current_team %>
|
<% if current_team %>
|
||||||
<div class="dashboard-container">
|
<div class="dashboard-view">
|
||||||
<%= render "calendar" %>
|
<div class="dashboard-background"></div>
|
||||||
<%= render "current_tasks" %>
|
<div class="dashboard-header">
|
||||||
<%= render "recent_work" %>
|
<%= render partial: 'quick_start' %>
|
||||||
<%= render "quick_start" %>
|
</div>
|
||||||
|
<div class="dashboard-container">
|
||||||
|
<% Extends::DEFAULT_DASHBOARD_CONFIGURATION.each do |widget| %>
|
||||||
|
<% if widget[:visible] %>
|
||||||
|
<%= render partial: widget[:partial], locals: {widget: widget} %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -41,6 +41,84 @@ class Extends
|
||||||
my_module_repository: 17,
|
my_module_repository: 17,
|
||||||
my_module_protocol: 18 }
|
my_module_protocol: 18 }
|
||||||
|
|
||||||
|
EXPORT_ALL_PROJECT_ELEMENTS = [
|
||||||
|
{
|
||||||
|
type_of: 'project_header',
|
||||||
|
id_key: 'project_id'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type_of: 'experiment',
|
||||||
|
id_key: 'experiment_id',
|
||||||
|
relation: %w(experiments),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type_of: 'my_module',
|
||||||
|
id_key: 'my_module_id',
|
||||||
|
relation: %w(my_modules),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type_of: 'my_module_protocol',
|
||||||
|
id_key: 'my_module_id'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type_of: 'step',
|
||||||
|
relation: %w(protocol steps),
|
||||||
|
id_key: 'step_id',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
type_of: 'step_asset',
|
||||||
|
relation: %w(assets),
|
||||||
|
id_key: 'asset_id'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type_of: 'step_table',
|
||||||
|
relation: %w(tables),
|
||||||
|
id_key: 'table_id'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type_of: 'step_checklist',
|
||||||
|
relation: %w(checklists),
|
||||||
|
id_key: 'checklist_id'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type_of: 'step_comments',
|
||||||
|
id_key: 'step_id',
|
||||||
|
sort_order: 'asc'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type_of_lambda: lambda { |result|
|
||||||
|
(result.result_asset ||
|
||||||
|
result.result_table ||
|
||||||
|
result.result_text).class.to_s.underscore
|
||||||
|
},
|
||||||
|
relation: %w(results),
|
||||||
|
id_key: 'result_id',
|
||||||
|
children: [{
|
||||||
|
type_of: 'result_comments',
|
||||||
|
id_key: 'result_id',
|
||||||
|
sort_order: 'asc'
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type_of: 'my_module_activity',
|
||||||
|
id_key: 'my_module_id',
|
||||||
|
sort_order: 'asc'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type_of: 'my_module_repository',
|
||||||
|
relation: %w(experiment project assigned_repositories_and_snapshots),
|
||||||
|
id_key: 'repository_id',
|
||||||
|
parent_id_key: 'my_module_id',
|
||||||
|
sort_order: 'asc'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
# Data type name should match corresponding model's name
|
# Data type name should match corresponding model's name
|
||||||
REPOSITORY_DATA_TYPES = { RepositoryTextValue: 0,
|
REPOSITORY_DATA_TYPES = { RepositoryTextValue: 0,
|
||||||
RepositoryDateValue: 1,
|
RepositoryDateValue: 1,
|
||||||
|
@ -123,6 +201,12 @@ class Extends
|
||||||
'Protocol' => :description,
|
'Protocol' => :description,
|
||||||
'MyModule' => :description }
|
'MyModule' => :description }
|
||||||
|
|
||||||
|
DEFAULT_DASHBOARD_CONFIGURATION = [
|
||||||
|
{ partial: 'dashboards/current_tasks', visible: true, size: 'large-widget', position: 1 },
|
||||||
|
{ partial: 'dashboards/calendar', visible: true, size: 'small-widget', position: 2 },
|
||||||
|
{ partial: 'dashboards/recent_work', visible: true, size: 'medium-widget', position: 3 }
|
||||||
|
]
|
||||||
|
|
||||||
ACTIVITY_SUBJECT_TYPES = %w(
|
ACTIVITY_SUBJECT_TYPES = %w(
|
||||||
Team RepositoryBase Project Experiment MyModule Result Protocol Report RepositoryRow
|
Team RepositoryBase Project Experiment MyModule Result Protocol Report RepositoryRow
|
||||||
).freeze
|
).freeze
|
||||||
|
@ -292,7 +376,7 @@ class Extends
|
||||||
restore_inventory: 145,
|
restore_inventory: 145,
|
||||||
export_inventory_items_assigned_to_task: 146,
|
export_inventory_items_assigned_to_task: 146,
|
||||||
export_inventory_snapshot_items_assigned_to_task: 147,
|
export_inventory_snapshot_items_assigned_to_task: 147,
|
||||||
change_status_on_task_flow: 148 # 149, 150, 151 in AdddOn!
|
change_status_on_task_flow: 148 # 149..157 in AdddOn!
|
||||||
}
|
}
|
||||||
|
|
||||||
ACTIVITY_GROUPS = {
|
ACTIVITY_GROUPS = {
|
||||||
|
|
Loading…
Reference in a new issue