Merge pull request #3258 from okriuchykhin/ok_SCI_5613

Fix save report PDF to Inventory [SCI-5613]
This commit is contained in:
Miha Mencin 2021-04-15 09:30:04 +02:00 committed by GitHub
commit f95e9402bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 391 additions and 399 deletions

View file

@ -116,6 +116,7 @@
.attr('data-generate-pdf-path', data.generate_pdf)
.attr('data-generate-docx-path', data.generate_docx)
.attr('data-retry-count', 0)
.attr('data-save-to-inventory-path', data.save_to_inventory)
.attr('data-id', data['0']);
if (data['3'].processing || data['4'].processing) {
$(row).addClass('processing');
@ -291,6 +292,26 @@
});
}
function initSaveReportPDFToInventory() {
$('#savePdfToInventoryButton').click(function(ev) {
ev.preventDefault();
ev.stopPropagation();
let id = CHECKED_REPORTS[0];
let row = $(`.report-row[data-id='${id}']`);
let url = row.attr('data-save-to-inventory-path');
$.get(url, function(result) {
let modal = $(result.html);
$('#content-reports-index').append(modal);
modal.modal('show');
// Remove modal when it gets closed
modal.on('hidden.bs.modal', function() {
$(this).remove();
});
});
});
}
function initDeleteReports() {
$('#delete-reports-btn').click(function() {
if (CHECKED_REPORTS.length > 0) {
@ -308,5 +329,6 @@
initGeneratePDFReport();
initGenerateDocxReport();
initEditReport();
initSaveReportPDFToInventory();
initDeleteReports();
}());

View file

@ -0,0 +1,282 @@
/* globals I18n animateSpinner HelperModule */
(function() {
'use strict';
var INVENTORY_PICKER;
var COLUMN_PICKER;
var ITEM_PICKER;
var SELECTED_IDS = {
repository_id: null,
respository_column_id: null,
repository_item_id: null
};
function clearErrors() {
var $columnsAlertSection = $('#save-PDF-to-inventory-column-warnings');
var $itemsAlertSection = $('#save-PDF-to-inventory-warnings');
$itemsAlertSection.empty();
$columnsAlertSection.empty();
}
function toggleHasFileErrorMessage(value) {
var element = $('#selectInventoryItem [value="' + value + '"]');
var $alertSection = $('#save-PDF-to-inventory-warnings');
$alertSection.empty();
if (element.data('hasfile')) {
$alertSection.append(
`<div class="alert alert-danger">
${I18n.t('projects.reports.new.save_PDF_to_inventory_modal.asset_present_warning_html')}
</div>`
);
}
}
function appendSearchResults(data) {
var items = [];
if (data.hasOwnProperty('results')) {
$.each(data.results, function(index, el) {
items.push(
{
value: el.id,
text: el.name,
disabled: false
}
);
});
}
return items;
}
function appendSearchResultsForItems(data) {
var items = [];
if (data.hasOwnProperty('results')) {
$('#selectInventoryItem').parent().find('button').removeAttr('disabled');
$.each(data.results, function(index, el) {
items.push(
{
value: el.id,
text: el.name,
disabled: false,
data: {
hasFile: el.hasOwnProperty('has_file_attached') ? el.has_file_attached : null
}
}
);
});
} else {
$('#selectInventoryItem').parent().find('button').attr('disabled', true);
clearErrors();
$('#save-PDF-to-inventory-warnings').append(
`<strong class="danger">${data.no_items}</strong>`
);
}
return items;
}
function appendSearchResultsForColumns(data) {
var items = [];
if (data.hasOwnProperty('results')) {
$('#selectInventoryColumn').parent().find('button').removeAttr('disabled');
$.each(data.results, function(index, el) {
items.push(
{
value: el.id,
text: el.name,
disabled: false
}
);
});
} else {
$('#selectInventoryColumn').parent().find('button').attr('disabled', true);
clearErrors();
$('#save-PDF-to-inventory-column-warnings').append(
`<div class="save-PDF-to-inventory-alerts"><strong class="danger">${data.no_items}</strong></div>`
);
}
return items;
}
function submitButtonEnableToggle(status) {
var button = $('#savePDFtoInventorySubmit');
if (status) {
button.removeAttr('disabled');
} else {
button.attr('disabled', true);
}
}
function deselect(element) {
if (element) {
element.selectpicker('val', null);
element.selectpicker('render');
element.attr('disabled', true);
}
}
// triggers first request and cleans the dropdown selectpicker
function clearDropdownResultsCallback(element) {
element.parent().find('button').on('click', function() {
$(this).parent().find('input').trigger('keyup');
});
}
function initInventoryItemSelectPicker() {
ITEM_PICKER = $('#selectInventoryItem')
.removeAttr('disabled')
.selectpicker({ liveSearch: true })
.ajaxSelectPicker({
ajax: {
url: $('#selectInventoryItem').data('target-url'),
type: 'POST',
dataType: 'json',
data: function() {
return {
q: '{{{q}}}',
repository_id: SELECTED_IDS.repository_id,
repository_column_id: SELECTED_IDS.respository_column_id
};
}
},
locale: {
emptyTitle: I18n.t('projects.reports.new.save_PDF_to_inventory_modal.nothing_selected')
},
preprocessData: appendSearchResultsForItems,
emptyRequest: true,
clearOnEmpty: true,
cache: false,
preserveSelected: false
})
.on('change.bs.select', function(el) {
var value = el.target.value;
toggleHasFileErrorMessage(value);
submitButtonEnableToggle(true);
SELECTED_IDS.repository_item_id = value;
});
clearDropdownResultsCallback(ITEM_PICKER);
}
function initInventoryColumnSelectPicker() {
COLUMN_PICKER = $('#selectInventoryColumn')
.removeAttr('disabled')
.selectpicker({ liveSearch: true })
.ajaxSelectPicker({
ajax: {
url: $('#selectInventoryColumn').data('target-url'),
type: 'POST',
dataType: 'json',
data: function() {
return {
q: '{{{q}}}',
repository_id: SELECTED_IDS.repository_id
};
}
},
locale: {
emptyTitle: I18n.t('projects.reports.new.save_PDF_to_inventory_modal.nothing_selected')
},
preprocessData: appendSearchResultsForColumns,
emptyRequest: true,
clearOnEmpty: true,
cache: false,
preserveSelected: false
})
.on('change.bs.select', function(el) {
SELECTED_IDS.respository_column_id = el.target.value;
deselect(ITEM_PICKER);
submitButtonEnableToggle(false);
initInventoryItemSelectPicker();
// refresh the dropdown state
$('#selectInventoryItem').parent().find('input').trigger('keyup');
clearErrors();
});
clearDropdownResultsCallback(COLUMN_PICKER);
}
function initInventoriesSelectPicker() {
INVENTORY_PICKER = $('#selectInventory')
.selectpicker({ liveSearch: true })
.ajaxSelectPicker({
ajax: {
url: $('#selectInventory').data('target-url'),
type: 'POST',
dataType: 'json',
data: function() {
return { q: '{{{q}}}' };
}
},
locale: {
emptyTitle: I18n.t('projects.reports.new.save_PDF_to_inventory_modal.nothing_selected')
},
preprocessData: appendSearchResults,
emptyRequest: true,
clearOnEmpty: false,
cache: false,
preserveSelected: false
}).on('change.bs.select', function(el) {
SELECTED_IDS.repository_id = el.target.value;
deselect(COLUMN_PICKER);
deselect(ITEM_PICKER);
submitButtonEnableToggle(false);
initInventoryColumnSelectPicker();
clearErrors();
// refresh the dropdown state
$('#selectInventoryColumn').parent().find('input').trigger('keyup');
});
clearDropdownResultsCallback(INVENTORY_PICKER);
}
function initializeSubmitAction() {
$('#content-reports-index').on('click', '#savePDFtoInventorySubmit', function() {
animateSpinner();
$.ajax({
url: $('#savePDFtoInventorySubmit').data('target-url'),
data: SELECTED_IDS,
type: 'POST',
success: function(data) {
animateSpinner(null, false);
HelperModule.flashAlertMsg(data.message, 'success');
$('#savePDFtoInventory').modal('hide');
},
error: function(xhr) {
animateSpinner(null, false);
HelperModule.flashAlertMsg(xhr.responseJSON.message, 'danger');
$('#savePDFtoInventory').modal('hide');
}
});
});
}
/*
* INITIALIZERS
*/
function initializeSavePDFtoInventoryModal() {
$('#content-reports-index').on('shown.bs.modal', '#savePDFtoInventory', function() {
initInventoriesSelectPicker();
initializeSubmitAction();
clearErrors();
// refresh the dropdown state
$('#selectInventory').parent().find('input').trigger('keyup');
}).on('hidden.bs.modal', function() {
// clear ids
SELECTED_IDS = {
repository_id: null,
respository_column_id: null,
repository_item_id: null
};
// clear select picker objects
if (COLUMN_PICKER) {
deselect(COLUMN_PICKER);
}
if (ITEM_PICKER) {
deselect(ITEM_PICKER);
}
submitButtonEnableToggle(false);
});
}
initializeSavePDFtoInventoryModal();
}());

View file

@ -1,282 +0,0 @@
(function() {
'use strict';
var INVENTORY_PICKER, COLUMN_PICKER, ITEM_PICKER;
var SELECTED_IDS = {
repository_id: null,
respository_column_id: null,
repository_item_id: null,
};
function clearErrors() {
var $columnsAlertSection = $('#save-PDF-to-inventory-column-warnings');
var $itemsAlertSection = $('#save-PDF-to-inventory-warnings');
$itemsAlertSection.empty();
$columnsAlertSection.empty();
}
function toggleHasFileErrorMessage(value) {
var element = $('#selectInventoryItem [value="' + value + '"]');
var $alertSection = $('#save-PDF-to-inventory-warnings');
$alertSection.empty();
if(element.data('hasfile')) {
$alertSection.append(
'<div class="alert alert-danger">' +
'<%=I18n.t("projects.reports.new.save_PDF_to_inventory_modal.asset_present_warning_html") %>' +
'</div>'
)
}
}
function appendSearchResults(data) {
var items = [];
if(data.hasOwnProperty('results')){
$.each(data.results, function(index, el) {
items.push(
{
value: el.id,
text: el.name,
disabled: false
}
)
});
}
return items;
}
function appendSearchResultsForItems(data) {
var items = [];
if(data.hasOwnProperty('results')){
$('#selectInventoryItem').parent().find('button').removeAttr('disabled');
$.each(data.results, function(index, el) {
items.push(
{
value: el.id,
text: el.name,
disabled: false,
data: {
hasFile: el.hasOwnProperty('has_file_attached') ?
el.has_file_attached :
null
}
}
)
});
} else {
$('#selectInventoryItem').parent().find('button').attr('disabled', true);
clearErrors();
$('#save-PDF-to-inventory-warnings').append(
'<strong class="danger">' + data.no_items + '</strong>'
)
}
return items;
}
function appendSearchResultsForColumns(data) {
var items = [];
if(data.hasOwnProperty('results')){
$('#selectInventoryColumn').parent().find('button').removeAttr('disabled');
$.each(data.results, function(index, el) {
items.push(
{
value: el.id,
text: el.name,
disabled: false
}
)
});
} else {
$('#selectInventoryColumn').parent().find('button').attr('disabled', true);
clearErrors();
$('#save-PDF-to-inventory-column-warnings').append(
'<div class="save-PDF-to-inventory-alerts"><strong class="danger">' +
data.no_items + '</strong></div>'
)
}
return items;
}
function submitButtonEnableToggle(status) {
var button = $('#savePDFtoInventorySubmit');
if(status) {
button.removeAttr('disabled');
} else {
button.attr('disabled', true);
}
}
function deselect(element) {
if(element) {
element.selectpicker('val', null)
element.selectpicker('render');
element.attr('disabled', true);
}
}
// triggers first request and cleans the dropdown selectpicker
function clearDropdownResultsCallback(element) {
element.parent().find('button').on('click', function(el) {
$(this).parent().find('input').trigger('keyup');
});
}
function initInventoryItemSelectPicker() {
ITEM_PICKER =
$('#selectInventoryItem')
.removeAttr('disabled')
.selectpicker({liveSearch: true})
.ajaxSelectPicker({
ajax: {
url: '<%= Rails.application.routes.url_helpers.available_rows_repositories_path %>',
type: 'POST',
dataType: 'json',
data: function () {
return {
q: '{{{q}}}',
repository_id: SELECTED_IDS.repository_id,
repository_column_id: SELECTED_IDS.respository_column_id
};
}
},
locale: {
emptyTitle: '<%= I18n.t('projects.reports.new.save_PDF_to_inventory_modal.nothing_selected') %>'
},
preprocessData: appendSearchResultsForItems,
emptyRequest: true,
clearOnEmpty: true,
cache: false,
preserveSelected: false
}).on('change.bs.select', function(el) {
var value = el.target.value;
toggleHasFileErrorMessage(value);
submitButtonEnableToggle(true);
SELECTED_IDS.repository_item_id = value;
});
clearDropdownResultsCallback(ITEM_PICKER);
}
function initInventoryColumnSelectPicker() {
COLUMN_PICKER =
$('#selectInventoryColumn')
.removeAttr('disabled')
.selectpicker({liveSearch: true})
.ajaxSelectPicker({
ajax: {
url: '<%= Rails.application.routes.url_helpers.available_asset_type_columns_path %>',
type: 'POST',
dataType: 'json',
data: function () {
return {
q: '{{{q}}}',
repository_id: SELECTED_IDS.repository_id
};
}
},
locale: {
emptyTitle: '<%= I18n.t('projects.reports.new.save_PDF_to_inventory_modal.nothing_selected') %>'
},
preprocessData: appendSearchResultsForColumns,
emptyRequest: true,
clearOnEmpty: true,
cache: false,
preserveSelected: false
}).on('change.bs.select', function(el) {
SELECTED_IDS.respository_column_id = el.target.value;
deselect(ITEM_PICKER);
submitButtonEnableToggle(false);
initInventoryItemSelectPicker();
// refresh the dropdown state
$('#selectInventoryItem').parent().find('input').trigger('keyup');
clearErrors();
});
clearDropdownResultsCallback(COLUMN_PICKER);
}
function initInventoriesSelectPicker() {
INVENTORY_PICKER =
$('#selectInventory')
.selectpicker({liveSearch: true})
.ajaxSelectPicker({
ajax: {
url: '<%= Rails.application.routes.url_helpers.reports_available_repositories_path %>',
type: 'POST',
dataType: 'json',
data: function () {
return { q: '{{{q}}}' };
}
},
locale: {
emptyTitle: '<%= I18n.t('projects.reports.new.save_PDF_to_inventory_modal.nothing_selected') %>'
},
preprocessData: appendSearchResults,
emptyRequest: true,
clearOnEmpty: false,
cache: false,
preserveSelected: false
}).on('change.bs.select', function(el) {
SELECTED_IDS.repository_id = el.target.value;
deselect(COLUMN_PICKER);
deselect(ITEM_PICKER);
submitButtonEnableToggle(false);
initInventoryColumnSelectPicker();
clearErrors();
// refresh the dropdown state
$('#selectInventoryColumn').parent().find('input').trigger('keyup');
});
clearDropdownResultsCallback(INVENTORY_PICKER);
}
function initializeSubmitAction() {
$('#savePDFtoInventorySubmit').off().on('click', function() {
animateSpinner();
$.ajax({
url: '<%= Rails.application.routes.url_helpers.reports_save_pdf_to_inventory_item_path %>',
data: Object.assign(SELECTED_IDS, { html: $(REPORT_CONTENT).html() }, {}),
type: 'POST',
success: function(data) {
animateSpinner(null, false);
HelperModule.flashAlertMsg(data.message, 'success');
$('#savePDFtoInventory').modal('hide');
},
error: function(xhr) {
animateSpinner(null, false);
HelperModule.flashAlertMsg(xhr.responseJSON.message, 'danger');
$('#savePDFtoInventory').modal('hide');
}
});
});
}
/*
* INITIALIZERS
*/
function initializeSavePDFtoInventoryModal() {
$('#savePDFtoInventory').off().on('shown.bs.modal', function() {
initInventoriesSelectPicker();
initializeSubmitAction();
clearErrors();
// refresh the dropdown state
$('#selectInventory').parent().find('input').trigger('keyup');
}).on('hidden.bs.modal', function() {
// clear ids
SELECTED_IDS = {
repository_id: null,
respository_column_id: null,
repository_item_id: null,
}
// clear select picker objects
if(COLUMN_PICKER) {
deselect(COLUMN_PICKER);
}
if(ITEM_PICKER) {
deselect(ITEM_PICKER);
}
submitButtonEnableToggle(false);
});
}
initializeSavePDFtoInventoryModal();
})();

View file

@ -11,30 +11,32 @@ module ActiveStorage
private
def check_read_permissions
attachment = @blob.attachments.take
return render_404 if attachment.blank?
return render_404 if @blob.attachments.blank?
@blob.attachments.any? { |attachment| check_attachment_read_permissions(attachment) }
end
def check_attachment_read_permissions(attachment)
case attachment.record_type
when 'Asset'
check_asset_read_permissions
check_asset_read_permissions(attachment.record)
when 'TinyMceAsset'
check_tinymce_asset_read_permissions
check_tinymce_asset_read_permissions(attachment.record)
when 'Experiment'
check_experiment_read_permissions
check_experiment_read_permissions(attachment.record)
when 'Report'
check_report_read_permissions
check_report_read_permissions(attachment.record)
when 'User'
# No read restrictions for avatars
true
when 'ZipExport', 'TeamZipExport'
check_zip_export_read_permissions
check_zip_export_read_permissions(attachment.record)
else
render_403
end
end
def check_asset_read_permissions
asset = @blob.attachments.first.record
def check_asset_read_permissions(asset)
return render_403 unless asset
if asset.step
@ -51,8 +53,7 @@ module ActiveStorage
end
end
def check_tinymce_asset_read_permissions
asset = @blob.attachments.first.record
def check_tinymce_asset_read_permissions(asset)
return render_403 unless asset
return true if asset.object.nil? && asset.team == current_team
@ -72,16 +73,16 @@ module ActiveStorage
end
end
def check_experiment_read_permissions
render_403 && return unless can_read_experiment?(@blob.attachments.first.record)
def check_experiment_read_permissions(experiment)
render_403 && return unless can_read_experiment?(experiment)
end
def check_report_read_permissions
render_403 && return unless can_read_project?(@blob.attachments.first.record.project)
def check_report_read_permissions(report)
render_403 && return unless can_read_project?(report.project)
end
def check_zip_export_read_permissions
render_403 unless @blob.attachments.first.record.user == current_user
def check_zip_export_read_permissions(zip_export)
render_403 unless zip_export.user == current_user
end
end
end

View file

@ -20,11 +20,11 @@ class ReportsController < ApplicationController
result_contents
).freeze
before_action :load_vars, only: %i(edit update document_preview generate_pdf generate_docx status)
before_action :load_vars, only: %i(edit update document_preview generate_pdf generate_docx status
save_pdf_to_inventory_modal save_pdf_to_inventory_item)
before_action :load_vars_nested, only: BEFORE_ACTION_METHODS
before_action :load_visible_projects, only: %i(new edit)
before_action :load_available_repositories,
only: %i(new edit available_repositories)
before_action :load_available_repositories, only: %i(index save_pdf_to_inventory_modal available_repositories)
before_action :check_manage_permissions, only: BEFORE_ACTION_METHODS
before_action :switch_team_with_param, only: :index
@ -211,9 +211,21 @@ class ReportsController < ApplicationController
end
end
def save_pdf_to_inventory_modal
respond_to do |format|
format.json do
render json: {
html: render_to_string(partial: 'reports/save_PDF_to_inventory_modal.html.erb')
}
end
end
end
def save_pdf_to_inventory_item
return render_404 unless @report.pdf_file.attached?
save_pdf_to_inventory_item = ReportActions::SavePdfToInventoryItem.new(
current_user, current_team, save_PDF_params
@report, current_user, current_team, save_pdf_params
)
if save_pdf_to_inventory_item.save
render json: {
@ -225,12 +237,10 @@ class ReportsController < ApplicationController
render json: { message: save_pdf_to_inventory_item.error_messages },
status: :unprocessable_entity
end
rescue ReportActions::RepositoryPermissionError => error
render json: { message: error },
status: :forbidden
rescue Exception => error
render json: { message: error.message },
status: :internal_server_error
rescue ReportActions::RepositoryPermissionError => e
render json: { message: e.message }, status: :forbidden
rescue StandardError => e
render json: { message: e.message }, status: :internal_server_error
end
# Modal for saving the existsing/new report
@ -528,11 +538,8 @@ class ReportsController < ApplicationController
params.permit(:q)
end
def save_PDF_params
params.permit(:repository_id,
:respository_column_id,
:repository_item_id,
:html)
def save_pdf_params
params.permit(:repository_id, :respository_column_id, :repository_item_id)
end
def log_activity(type_of, report = @report)

View file

@ -63,7 +63,8 @@ class ReportDatatable < CustomDatatable
'edit' => edit_project_report_path(record.project_id, record.id),
'status' => status_project_report_path(record.project_id, record.id),
'generate_pdf' => generate_pdf_project_report_path(record.project_id, record.id),
'generate_docx' => generate_docx_project_report_path(record.project_id, record.id)
'generate_docx' => generate_docx_project_report_path(record.project_id, record.id),
'save_to_inventory' => save_pdf_to_inventory_modal_report_path(record.id)
}
end
end

View file

@ -2,7 +2,8 @@
module ReportActions
class SavePdfToInventoryItem
def initialize(user, team, params)
def initialize(report, user, team, params)
@report = report
@user = user
@team = team
@params = params
@ -10,13 +11,12 @@ module ReportActions
end
def save
file_path = generate_pdf(@params[:html])
asset = create_new_asset(file_path)
cell = fetch_repository_cell
cell&.destroy
@new_cell_value = create_new_cell_value(asset)
@new_cell_value.save
log_activity
ActiveRecord::Base.transaction do
asset = create_new_asset
delete_old_repository_cell
@new_cell_value = create_new_cell_value(asset)
log_activity
end
end
def error_messages
@ -30,84 +30,37 @@ module ReportActions
include Canaid::Helpers::PermissionsHelper
def load_repository_collaborators
@repository = load_repository
@repository_column = load_repository_column
@repository_item = load_repository_item
@repository = Repository.active.accessible_by_teams(@team).find_by(id: @params[:repository_id])
unless can_create_repository_rows?(@user, @repository)
raise ReportActions::RepositoryPermissionError,
I18n.t('projects.reports.new.no_permissions')
raise ReportActions::RepositoryPermissionError, I18n.t('projects.reports.new.no_permissions')
end
@repository_column = @repository.repository_columns.find(@params[:respository_column_id])
@repository_row = @repository.repository_rows.find(@params[:repository_item_id])
end
def generate_pdf(content)
file_path = create_temporary_file
pdf_file = WickedPdf.new.pdf_from_string(
action_view_context.render(
template: 'reports/report.pdf.erb',
locals: { content: prepare_pdf_content(content) }
),
header: { right: '[page] of [topage]' },
disable_javascript: true
)
File.open(file_path, 'wb') do |file|
file << pdf_file
end
file_path
end
def create_new_asset(file_path)
def create_new_asset
asset = Asset.create(created_by: @user, last_modified_by: @user, team: @team)
asset.file.attach(io: file_path, filename: File.basename(file_path))
asset.file.attach(@report.pdf_file.blob)
asset
end
def fetch_repository_cell
RepositoryCell.where(repository_row: @repository_item,
repository_column: @repository_column,
value_type: 'RepositoryAssetValue').first
def delete_old_repository_cell
@repository_row.repository_cells.find_by(repository_column: @repository_column)&.destroy
end
def create_new_cell_value(asset)
RepositoryAssetValue.new(
RepositoryAssetValue.create!(
asset: asset,
created_by: @user,
last_modified_by: @user,
repository_cell_attributes: {
repository_row: @repository_item,
repository_row: @repository_row,
repository_column: @repository_column
}
)
end
def load_repository
Repository.find_by(id: @params[:repository_id])
end
def load_repository_column
RepositoryColumn.find_by(id: @params[:respository_column_id])
end
def load_repository_item
RepositoryRow.find_by(id: @params[:repository_item_id])
end
def action_view_context
av = ActionView::Base.new(ActionController::Base.view_paths, {})
av.extend ReportsHelper # include reports helper methods to view
av.extend InputSanitizeHelper # include input sanitize methods to view
av
end
def create_temporary_file
Tempfile.open(['report', '.pdf'], Rails.root.join('tmp'))
end
def prepare_pdf_content(content)
return content if content.present?
I18n.t('projects.reports.new.no_content_for_PDF_html')
end
def log_activity
Activities::CreateActivityService
.call(activity_type: :edit_item_inventory,
@ -115,7 +68,7 @@ module ReportActions
subject: @repository,
team: @team,
message_items: {
repository_row: @repository_item.id,
repository_row: @repository_row.id,
repository: @repository.id
})
end

View file

@ -18,7 +18,7 @@
<% end %>
</li>
<li>
<%= link_to '#', remote: true, id: 'savePdfToInventory' do %>
<%= link_to '#savePdfToInventory', remote: true, id: 'savePdfToInventoryButton' do %>
<i class="fas fa-save"></i>
<%= t("projects.reports.index.save_pdf_to_inventory") %>
<% end %>

View file

@ -5,50 +5,57 @@
<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"><%=t 'projects.reports.new.save_PDF_to_inventory' %></h4>
<h4 class="modal-title"><%= t('projects.reports.new.save_PDF_to_inventory') %></h4>
</div>
<div class="modal-body">
<p><%=t 'projects.reports.new.save_PDF_to_inventory_modal.description_one' %></p>
<p><%= t('projects.reports.new.save_PDF_to_inventory_modal.description_one') %></p>
<br />
<p><%=t 'projects.reports.new.save_PDF_to_inventory_modal.description_two' %></p>
<p><%= t('projects.reports.new.save_PDF_to_inventory_modal.description_two') %></p>
<span data-hook="save-pdf-to-inventory-modal-body"></span>
<% if @available_repositories && @available_repositories.length > 0 %>
<label><%=t 'projects.reports.new.save_PDF_to_inventory_modal.inventory' %></label>
<% if !@report.pdf_file.attached? %>
<br />
<p><em><%= t('projects.reports.new.save_PDF_to_inventory_modal.pdf_not_ready') %></em></p>
<% elsif @available_repositories.present? %>
<label><%= t('projects.reports.new.save_PDF_to_inventory_modal.inventory') %></label>
<select
id="selectInventory"
class="form-control selectpicker"
data-live-search="true">
data-live-search="true"
data-target-url="<%= reports_available_repositories_path %>">
</select>
<label><%=t 'projects.reports.new.save_PDF_to_inventory_modal.inventory_column' %></label>
<label><%= t('projects.reports.new.save_PDF_to_inventory_modal.inventory_column') %></label>
<select
id="selectInventoryColumn"
class="form-control selectpicker"
data-live-search="true"
data-target-url="<%= available_asset_type_columns_path %>"
disabled>
</select>
<div id="save-PDF-to-inventory-column-warnings"></div>
<label><%=t 'projects.reports.new.save_PDF_to_inventory_modal.inventory_item' %></label>
<label><%= t('projects.reports.new.save_PDF_to_inventory_modal.inventory_item') %></label>
<select
id="selectInventoryItem"
class="form-control selectpicker"
data-live-search="true"
data-target-url="<%= available_rows_repositories_path %>"
disabled>
</select>
<% else %>
<br />
<p><em><%=t 'projects.reports.new.save_PDF_to_inventory_modal.no_inventories' %></em></p>
<p><em><%= t('projects.reports.new.save_PDF_to_inventory_modal.no_inventories') %></em></p>
<% end %>
<div class="save-PDF-to-inventory-alerts" id="save-PDF-to-inventory-warnings"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t 'general.cancel' %></button>
<% if @available_repositories && @available_repositories.length > 0 %>
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%= t('general.cancel') %></button>
<% if @report.pdf_file.attached? && @available_repositories.present? %>
<button
id="savePDFtoInventorySubmit"
type="button"
class="btn btn-primary"
data-target-url="<%= save_pdf_to_inventory_item_report_path(@report) %>"
disabled
><%=t 'general.save' %></button>
><%= t('general.save') %></button>
<% end %>
</div>
</div>

View file

@ -61,6 +61,7 @@
<% end %>
</div>
<%= javascript_include_tag("reports/reports_datatable") %>
<%= javascript_include_tag 'reports/save_pdf_to_inventory' %>
<%= javascript_include_tag 'reports/reports_datatable' %>
<%= javascript_pack_tag 'pdfjs/pdf_js' %>
<%= stylesheet_pack_tag 'pdfjs/pdf_js_styles' %>

View file

@ -600,6 +600,7 @@ en:
no_content_for_PDF_html: "<h1>No content</h1>"
no_permissions: "You don't have permission to manage this column"
save_PDF_to_inventory_modal:
pdf_not_ready: "The PDF of this report isn't ready yet, please try again in a minute"
description_one: "Here you can save PDF report to an inventory item."
description_two: "First select an inventory, then a column and finally the item within the inventory to which you would like to save the PDF report to. Note that the column has to be of type \"file\"."
inventory: "Select inventory:"

View file

@ -197,6 +197,8 @@ Rails.application.routes.draw do
resources :reports, only: [:index, :new, :create] do
member do
get :document_preview
get :save_pdf_to_inventory_modal, defaults: { format: 'json' }
post :save_pdf_to_inventory_item, defaults: { format: 'json' }
end
collection do
get :project_contents
@ -206,9 +208,6 @@ Rails.application.routes.draw do
get 'reports/new_template_values', to: 'reports#new_template_values', defaults: { format: 'json' }
post 'reports/available_repositories', to: 'reports#available_repositories',
defaults: { format: 'json' }
post 'reports/save_pdf_to_inventory_item',
to: 'reports#save_pdf_to_inventory_item',
defaults: { format: 'json' }
post 'available_asset_type_columns',
to: 'repository_columns#available_asset_type_columns',
defaults: { format: 'json' }