From c99e8f19fd874040be02e9fb1c826dbd00b08988 Mon Sep 17 00:00:00 2001 From: aignatov-bio Date: Tue, 16 Mar 2021 13:11:15 +0100 Subject: [PATCH 1/2] Add basic layout [SCI-5548] --- .../reports/reports_datatable.js.erb | 43 +++++++++++-------- app/assets/stylesheets/report_index.scss | 25 +++++++++++ app/assets/stylesheets/shared/datatable.scss | 4 +- app/datatables/report_datatable.rb | 10 +++-- app/views/reports/_index_header.html.erb | 10 +++++ app/views/reports/_index_toolbar.html.erb | 14 ++++++ app/views/reports/index.html.erb | 25 ++--------- 7 files changed, 86 insertions(+), 45 deletions(-) create mode 100644 app/assets/stylesheets/report_index.scss create mode 100644 app/views/reports/_index_header.html.erb create mode 100644 app/views/reports/_index_toolbar.html.erb diff --git a/app/assets/javascripts/reports/reports_datatable.js.erb b/app/assets/javascripts/reports/reports_datatable.js.erb index 2d1bd6446..49413d82c 100644 --- a/app/assets/javascripts/reports/reports_datatable.js.erb +++ b/app/assets/javascripts/reports/reports_datatable.js.erb @@ -134,27 +134,34 @@ function initDatatable() { var $table = $('#reports-table') DATATABLE = $table.dataTable({ - 'order': [[2, 'desc']], - 'processing': true, - 'serverSide': true, - 'ajax': $table.data('source'), - 'pagingType': 'simple_numbers', - 'colReorder': { - 'fixedColumnsLeft': 1000000 // Disable reordering + dom: "Rt<'pagination-row hidden'<'pagination-info'li><'pagination-actions'p>>", + order: [[2, 'desc']], + sScrollX: '100%', + sScrollXInner: '100%', + processing: true, + serverSide: true, + ajax: $table.data('source'), + pagingType: 'simple_numbers', + colReorder: { + fixedColumnsLeft: 1000000 // Disable reordering }, - 'columnDefs': [{ - 'targets': 0, - 'searchable': false, - 'orderable': false, - 'className': 'dt-body-center', - 'sWidth': '1%', - 'render': renderCheckboxHTML + columnDefs: [{ + targets: 0, + searchable: false, + orderable: false, + className: 'dt-body-center', + sWidth: '1%', + render: renderCheckboxHTML }], - 'oLanguage': { - 'sSearch': I18n.t('general.filter') + oLanguage: { + sSearch: I18n.t('general.filter') }, - 'fnDrawCallback': tableDrowCallback, - 'createdRow': appendEditPathToRow + fnDrawCallback: tableDrowCallback, + createdRow: appendEditPathToRow, + fnInitComplete: function() { + DataTableHelpers.initLengthApearance($table.closest('.dataTables_wrapper')); + $('.pagination-row').removeClass('hidden'); + } }); } diff --git a/app/assets/stylesheets/report_index.scss b/app/assets/stylesheets/report_index.scss new file mode 100644 index 000000000..ed1076605 --- /dev/null +++ b/app/assets/stylesheets/report_index.scss @@ -0,0 +1,25 @@ +.reports-datatable { + height: calc(100vh - var(--navbar-height) - var(--content-header-size)); + + #reports-table_wrapper { + display: flex; + flex-direction: column; + height: 100%; + + .dataTables_scroll { + display: flex; + flex-direction: column; + flex-grow: 1; + height: calc(100% - var(--datatable-pagination-row)); + + .dataTables_scrollHead { + flex-shrink: 0; + } + } + + .pagination-row { + flex-shrink: 0; + } + } + +} diff --git a/app/assets/stylesheets/shared/datatable.scss b/app/assets/stylesheets/shared/datatable.scss index 1d2089e38..b4fab9f51 100644 --- a/app/assets/stylesheets/shared/datatable.scss +++ b/app/assets/stylesheets/shared/datatable.scss @@ -2,7 +2,7 @@ // scss-lint:disable NestingDepth QualifyingElement .dataTables_wrapper { - + --datatable-pagination-row: 68px; .main-actions { align-items: center; display: flex; @@ -24,7 +24,7 @@ align-items: center; display: flex; flex-wrap: wrap; - min-height: 68px; + min-height: var(--datatable-pagination-row); width: 100%; .pagination-info, diff --git a/app/datatables/report_datatable.rb b/app/datatables/report_datatable.rb index 09aad71d8..d6f8161bc 100644 --- a/app/datatables/report_datatable.rb +++ b/app/datatables/report_datatable.rb @@ -35,10 +35,12 @@ class ReportDatatable < CustomDatatable '0' => record.id, '1' => sanitize_input(record.project_name), '2' => sanitize_input(record.name), - '3' => sanitize_input(record.created_by), - '4' => sanitize_input(record.modified_by), - '5' => I18n.l(record.created_at, format: :full), - '6' => I18n.l(record.updated_at, format: :full), + '3' => '', + '4' => '', + '5' => sanitize_input(record.created_by), + '6' => sanitize_input(record.modified_by), + '7' => I18n.l(record.created_at, format: :full), + '8' => I18n.l(record.updated_at, format: :full), 'edit' => edit_project_report_path(record.project_id, record.id) } end diff --git a/app/views/reports/_index_header.html.erb b/app/views/reports/_index_header.html.erb new file mode 100644 index 000000000..7d9dc8fde --- /dev/null +++ b/app/views/reports/_index_header.html.erb @@ -0,0 +1,10 @@ + diff --git a/app/views/reports/_index_toolbar.html.erb b/app/views/reports/_index_toolbar.html.erb new file mode 100644 index 000000000..b335eb4cc --- /dev/null +++ b/app/views/reports/_index_toolbar.html.erb @@ -0,0 +1,14 @@ +<% if can_manage_reports?(current_team) %> + <%= link_to '#', remote: true, class: 'btn btn-primary', id: 'new-report-btn' do %> + + + <% end %> + <%= link_to "", remote: true, class: "btn btn-light disabled hidden", id: "edit-report-btn" do %> + + + <% end %> + <%= link_to "", remote: true, class: "btn btn-light disabled hidden", id: "delete-reports-btn" do %> + + + <% end %> +<% end %> diff --git a/app/views/reports/index.html.erb b/app/views/reports/index.html.erb index d6c82c8bc..171e545c2 100644 --- a/app/views/reports/index.html.erb +++ b/app/views/reports/index.html.erb @@ -2,30 +2,11 @@ <% end %> -<% provide(:head_title, t('projects.reports.index.head_title').html_safe) %> <%= stylesheet_link_tag 'datatables' %> -
+
+ <%= render partial: 'reports/index_header' %>
-
-
- <% if can_manage_reports?(current_team) %> - <%= link_to '#', remote: true, class: 'btn btn-primary', id: 'new-report-btn' do %> - - - <% end %> - <%= link_to "", remote: true, class: "btn btn-light disabled hidden", id: "edit-report-btn" do %> - - - <% end %> - <%= link_to "", remote: true, class: "btn btn-light disabled hidden", id: "delete-reports-btn" do %> - - - <% end %> - <% end %> -
-
-
@@ -42,6 +23,8 @@ <%=t 'projects.reports.index.thead_project_name' %> <%=t 'projects.reports.index.thead_name' %> + PDF + DOCX <%=t 'projects.reports.index.thead_created_by' %> <%=t 'projects.reports.index.thead_last_modified_by' %> <%=t 'projects.reports.index.thead_created_at' %> From 3e5c2e83c7d8b1df1c6b59694b74012b3581c898 Mon Sep 17 00:00:00 2001 From: aignatov-bio Date: Wed, 17 Mar 2021 12:54:25 +0100 Subject: [PATCH 2/2] Update toolbar, add docx and pdf columns [SCI-5549][SCI-5550] --- .../reports/reports_datatable.js.erb | 99 +++++++++++++++++-- app/assets/stylesheets/report_index.scss | 38 +++++++ app/datatables/report_datatable.rb | 41 +++++++- app/views/reports/_index_toolbar.html.erb | 59 ++++++++--- app/views/reports/index.html.erb | 18 ++-- config/locales/en.yml | 12 ++- 6 files changed, 235 insertions(+), 32 deletions(-) diff --git a/app/assets/javascripts/reports/reports_datatable.js.erb b/app/assets/javascripts/reports/reports_datatable.js.erb index 49413d82c..958027847 100644 --- a/app/assets/javascripts/reports/reports_datatable.js.erb +++ b/app/assets/javascripts/reports/reports_datatable.js.erb @@ -1,3 +1,5 @@ +/* global I18n DataTableHelpers */ + (function(global) { 'use strict'; @@ -91,6 +93,54 @@
`; } + function renderDocxFile(data) { + if (data.error) { + return ` + + ${I18n.t('projects.reports.index.error')} + `; + } + + if (data.processing) { + return ` + ${I18n.t('projects.reports.index.generating')} + `; + } + + if (data.file) { + return ` + + ${I18n.t('projects.reports.index.docx')} + `; + } + + return `${I18n.t('projects.reports.index.generate')}`; + } + + function renderPdfFile(data) { + if (data.error) { + return ` + + ${I18n.t('projects.reports.index.error')} + `; + } + + if (data.processing) { + return ` + ${I18n.t('projects.reports.index.generating')} + `; + } + + if (data.file) { + return ` + + ${I18n.t('projects.reports.index.pdf')} + `; + } + + return ''; + } + function appendEditPathToRow(row, data) { $(row).addClass('report-row') .attr('data-edit-path', data['edit']) @@ -115,17 +165,38 @@ } function updateButtons() { - var editReportButton = $('#edit-report-btn'); - var deleteReportsButton = $('#delete-reports-btn'); if (CHECKED_REPORTS.length === 0) { - editReportButton.addClass('disabled hidden'); - deleteReportsButton.addClass('disabled hidden'); + $('.single-object-action, .multiple-object-action').addClass('disabled hidden'); } else if (CHECKED_REPORTS.length === 1) { - editReportButton.removeClass('disabled hidden'); - deleteReportsButton.removeClass('disabled hidden'); + $('.single-object-action, .multiple-object-action').removeClass('disabled hidden'); + + let $row = $(`.report-row[data-id=${CHECKED_REPORTS[0]}]`); + let pdfProcessing = $row.has('.processing.pdf').length > 0; + let docxProcessing = $row.has('.processing.docx').length > 0; + let docxGenerate = $row.has('.generate-docx').length > 0; + + if (pdfProcessing) { + $('#updatePdf').addClass('disabled'); + } else { + $('#updatePdf').removeClass('disabled'); + } + + if (docxGenerate) { + $('#requestDocx').removeClass('hidden'); + $('#updateDocx').addClass('hidden'); + } else { + $('#requestDocx').addClass('hidden'); + $('#updateDocx').removeClass('hidden'); + + if (docxProcessing) { + $('#updateDocx').addClass('disabled'); + } else { + $('#updateDocx').removeClass('disabled'); + } + } } else { - editReportButton.removeClass('hidden').addClass('disabled'); - deleteReportsButton.removeClass('disabled hidden'); + $('.single-object-action').removeClass('hidden').addClass('disabled'); + $('.multiple-object-action').removeClass('disabled hidden'); } } @@ -152,6 +223,18 @@ className: 'dt-body-center', sWidth: '1%', render: renderCheckboxHTML + }, + { + targets: 3, + searchable: false, + sWidth: '60', + render: renderPdfFile + }, + { + targets: 4, + searchable: false, + sWidth: '60', + render: renderDocxFile }], oLanguage: { sSearch: I18n.t('general.filter') diff --git a/app/assets/stylesheets/report_index.scss b/app/assets/stylesheets/report_index.scss index ed1076605..369d1a9b2 100644 --- a/app/assets/stylesheets/report_index.scss +++ b/app/assets/stylesheets/report_index.scss @@ -1,3 +1,25 @@ +// scss-lint:disable SelectorDepth NestingDepth IdSelector SelectorFormat + +.reports-index { + .report-actions-dropdown { + display: inline-block; + float: left; + position: relative; + + .report-actions-menu { + width: 200px; + + li { + padding: 0; + } + + a { + padding: .5em 1em; + } + } + } +} + .reports-datatable { height: calc(100vh - var(--navbar-height) - var(--content-header-size)); @@ -22,4 +44,20 @@ } } + .report-row { + .processing-error { + color: $brand-danger; + } + + .generate-docx { + display: none; + } + + &:hover { + .generate-docx { + display: initial; + } + } + } + } diff --git a/app/datatables/report_datatable.rb b/app/datatables/report_datatable.rb index d6f8161bc..cfdf77775 100644 --- a/app/datatables/report_datatable.rb +++ b/app/datatables/report_datatable.rb @@ -2,10 +2,13 @@ class ReportDatatable < CustomDatatable include InputSanitizeHelper + include Rails.application.routes.url_helpers TABLE_COLUMNS = %w( Report.project_name Report.name + Report.pdf_file + Report.docx_file Report.created_by Report.modified_by Report.created_at @@ -27,6 +30,22 @@ class ReportDatatable < CustomDatatable @searchable_columns ||= TABLE_COLUMNS end + def sort_records(records) + case sort_column(order_params) + when 'reports.docx_file' + records.left_joins(:docx_file_attachment) + .order(active_storage_attachments: sort_direction(order_params)) + .order(docx_file_processing: sort_direction(order_params) == 'ASC' ? :desc : :asc) + when 'reports.pdf_file' + records.left_joins(:pdf_file_attachment) + .order(active_storage_attachments: sort_direction(order_params)) + .order(pdf_file_processing: sort_direction(order_params) == 'ASC' ? :desc : :asc) + else + sort_by = "#{sort_column(order_params)} #{sort_direction(order_params)}" + records.order(sort_by) + end + end + private def data @@ -35,8 +54,8 @@ class ReportDatatable < CustomDatatable '0' => record.id, '1' => sanitize_input(record.project_name), '2' => sanitize_input(record.name), - '3' => '', - '4' => '', + '3' => pdf_file(record), + '4' => docx_file(record), '5' => sanitize_input(record.created_by), '6' => sanitize_input(record.modified_by), '7' => I18n.l(record.created_at, format: :full), @@ -46,6 +65,24 @@ class ReportDatatable < CustomDatatable end end + def docx_file(report) + docx = rails_blob_path(report.docx_file, disposition: 'attachment') if report.docx_file.attached? + { + processing: report.docx_file_processing, + file: docx, + error: false + } + end + + def pdf_file(report) + pdf = rails_blob_path(report.pdf_file, disposition: 'attachment') if report.pdf_file.attached? + { + processing: report.pdf_file_processing, + file: pdf, + error: false + } + end + def get_raw_records res = @reports.joins(:project) .joins( diff --git a/app/views/reports/_index_toolbar.html.erb b/app/views/reports/_index_toolbar.html.erb index b335eb4cc..bfdd3a8ab 100644 --- a/app/views/reports/_index_toolbar.html.erb +++ b/app/views/reports/_index_toolbar.html.erb @@ -1,14 +1,49 @@ <% if can_manage_reports?(current_team) %> - <%= link_to '#', remote: true, class: 'btn btn-primary', id: 'new-report-btn' do %> - - - <% end %> - <%= link_to "", remote: true, class: "btn btn-light disabled hidden", id: "edit-report-btn" do %> - - - <% end %> - <%= link_to "", remote: true, class: "btn btn-light disabled hidden", id: "delete-reports-btn" do %> - - - <% end %> +
+ <%= link_to '#', remote: true, class: 'btn btn-primary', id: 'new-report-btn' do %> + + + <% end %> +
+ + +
+ <%= link_to "", remote: true, class: "btn btn-light disabled hidden single-object-action", id: "edit-report-btn" do %> + + + <% end %> + <%= link_to "", remote: true, class: "btn btn-light disabled hidden multiple-object-action", id: "delete-reports-btn" do %> + + + <% end %> +
<% end %> diff --git a/app/views/reports/index.html.erb b/app/views/reports/index.html.erb index 171e545c2..b600ab68d 100644 --- a/app/views/reports/index.html.erb +++ b/app/views/reports/index.html.erb @@ -4,7 +4,7 @@ <%= stylesheet_link_tag 'datatables' %> -
+
<%= render partial: 'reports/index_header' %>
@@ -21,14 +21,14 @@
- <%=t 'projects.reports.index.thead_project_name' %> - <%=t 'projects.reports.index.thead_name' %> - PDF - DOCX - <%=t 'projects.reports.index.thead_created_by' %> - <%=t 'projects.reports.index.thead_last_modified_by' %> - <%=t 'projects.reports.index.thead_created_at' %> - <%=t 'projects.reports.index.thead_updated_at' %> + <%= t('projects.reports.index.thead_project_name') %> + <%= t('projects.reports.index.thead_name') %> + <%= t('projects.reports.index.pdf') %> + <%= t('projects.reports.index.docx') %> + <%= t('projects.reports.index.thead_created_by') %> + <%= t('projects.reports.index.thead_last_modified_by') %> + <%= t('projects.reports.index.thead_created_at') %> + <%= t('projects.reports.index.thead_updated_at') %> diff --git a/config/locales/en.yml b/config/locales/en.yml index a2969b32b..759ceb70d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -490,8 +490,13 @@ en: reports: print_title: "%{project} | Report" index: - head_title: " Reports" + head_title: "Reports" new: "New report" + report_button: "Report" + update_pdf: "Update PDF" + save_pdf_to_inventory: "Save PDF to Inventory" + request_docx: "Request DOCX" + update_docx: "Update DOCX" edit: "Edit" delete: "Delete" deleted: "(Deleted)" @@ -502,6 +507,11 @@ en: thead_created_at: "Created at" thead_updated_at: "Last updated at" no_reports: "No reports!" + pdf: "PDF" + docx: "DOCX" + error: "Error" + generating: "Generating" + generate: "Generate" modal_new: projects: "Projects" head_title: "Create new report"