From 4573655ec8ec5d96ec1e3dcdaefe2f03d5966339 Mon Sep 17 00:00:00 2001 From: zmagod Date: Wed, 16 May 2018 09:31:19 +0200 Subject: [PATCH] adds save PDF report to inventory feature [fixes SCI-2371] --- app/assets/javascripts/application.js.erb | 1 + .../reports/save_pdf_to_inventory.js.erb | 287 ++++++++++++++++++ app/assets/stylesheets/reports.scss | 10 + app/controllers/reports_controller.rb | 50 ++- .../repository_columns_controller.rb | 48 ++- app/controllers/repository_rows_controller.rb | 45 ++- app/models/repository.rb | 4 + app/models/repository_column.rb | 5 + app/models/repository_row.rb | 4 + .../save_pdf_to_inventory_item.rb | 87 ++++++ app/views/reports/new.html.erb | 4 + .../reports/new/_report_navigation.html.erb | 6 + .../new/_save_PDF_to_inventory_modal.html.erb | 57 ++++ config/initializers/assets.rb | 1 + config/locales/en.yml | 16 + config/routes.rb | 10 + 16 files changed, 630 insertions(+), 5 deletions(-) create mode 100644 app/assets/javascripts/reports/save_pdf_to_inventory.js.erb create mode 100644 app/services/report_actions/save_pdf_to_inventory_item.rb create mode 100644 app/views/reports/new/_save_PDF_to_inventory_modal.html.erb diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb index 387ee58d0..9f4bc0697 100644 --- a/app/assets/javascripts/application.js.erb +++ b/app/assets/javascripts/application.js.erb @@ -212,6 +212,7 @@ var HelperModule = (function(){ helpers.flashAlertMsg = function(message, type) { var alertType; var glyphSign; + $('#notifications').html(''); if (type === 'success') { alertType = ' alert-success '; diff --git a/app/assets/javascripts/reports/save_pdf_to_inventory.js.erb b/app/assets/javascripts/reports/save_pdf_to_inventory.js.erb new file mode 100644 index 000000000..16e8137b5 --- /dev/null +++ b/app/assets/javascripts/reports/save_pdf_to_inventory.js.erb @@ -0,0 +1,287 @@ +(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( + '
' + + '<%=I18n.t("projects.reports.new.save_PDF_to_inventory_modal.asset_present_warning_html") %>' + + '
' + ) + } + } + + 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, + data: { + hasFile: el.hasOwnProperty('has_file_attached') ? + el.has_file_attached : + null + } + } + ) + }); + } + 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( + '' + data.no_items + '' + ) + } + 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( + '
' + + data.no_items + '
' + ) + } + 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_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.file_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 initInvenoriesSelectPicker() { + 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 initializeSavePDFtoInvenotryModal() { + $('#savePDFtoInventory').off().on('shown.bs.modal', function() { + initInvenoriesSelectPicker(); + 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); + }); + } + + $(document).ready(initializeSavePDFtoInvenotryModal); +})(); diff --git a/app/assets/stylesheets/reports.scss b/app/assets/stylesheets/reports.scss index bf2ae8481..8c6900eb7 100644 --- a/app/assets/stylesheets/reports.scss +++ b/app/assets/stylesheets/reports.scss @@ -533,3 +533,13 @@ label { } } } + +#save-PDF-to-inventory-warnings { + margin-top: 30px; +} + +.save-PDF-to-inventory-alerts { + .danger { + color: $brand-danger; + } +} diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 8d5120512..14e0f3b88 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -26,6 +26,8 @@ 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_available_repositories, + only: %i(new edit available_repositories) before_action :check_manage_permissions, only: BEFORE_ACTION_METHODS @@ -169,7 +171,7 @@ class ReportsController < ApplicationController respond_to do |format| format.pdf do @html = params[:html] - @html = '

No content

' if @html.blank? + @html = I18n.t('projects.reports.new.no_content_for_PDF_html') if @html.blank? render pdf: 'report', header: { right: '[page] of [topage]' }, template: 'reports/report.pdf.erb', @@ -178,6 +180,30 @@ class ReportsController < ApplicationController end end + def save_pdf_to_inventory_item + report_service = ReportActions::SavePdfToInventoryItem.new( + current_user, current_team, save_PDF_params + ) + report_service.call + cell_value = report_service.cell_value + if cell_value.save + render json: { + message: I18n.t( + 'projects.reports.new.save_PDF_to_inventory_modal.success_flash' + ) + }, status: :ok + else + render json: { message: cell_value.errors.full_messages.join }, + status: :unprocessable_entity + end + rescue ReportActions::RepostioryPermissionError => error + render json: { message: error }, + status: :unprocessable_entity + rescue Exception => error + render json: { message: error.message }, + status: :unprocessable_entity + end + # Modal for saving the existsing/new report def save_modal # Assume user is updating existing report @@ -428,10 +454,15 @@ class ReportsController < ApplicationController render json: { projects: @visible_projects }, status: :ok end + def available_repositories + render json: { results: @available_repositories }, status: :ok + end + private include StringUtility VisibleProject = Struct.new(:path, :name) + AvailableRepository = Struct.new(:id, :name) def load_vars @report = Report.find_by_id(params[:id]) @@ -460,6 +491,16 @@ class ReportsController < ApplicationController end end + def load_available_repositories + repositories = current_team.repositories + .name_like(search_params[:q]) + .select(:id, :name) + @available_repositories = repositories.collect do |repository| + AvailableRepository.new(repository.id, + ellipsisize(repository.name, 75, 50)) + end + end + def report_params params.require(:report) .permit(:name, :description, :grouped_by, :report_contents) @@ -468,4 +509,11 @@ class ReportsController < ApplicationController def search_params params.permit(:q) end + + def save_PDF_params + params.permit(:repository_id, + :respository_column_id, + :repository_item_id, + :html) + end end diff --git a/app/controllers/repository_columns_controller.rb b/app/controllers/repository_columns_controller.rb index d32bf1b34..34ba67fac 100644 --- a/app/controllers/repository_columns_controller.rb +++ b/app/controllers/repository_columns_controller.rb @@ -1,11 +1,14 @@ class RepositoryColumnsController < ApplicationController include InputSanitizeHelper - before_action :load_vars, except: %i(create index create_html) - before_action :load_vars_nested, only: %i(create index create_html) + before_action :load_vars, except: %i(create index create_html file_columns) + before_action :load_vars_nested, + only: %i(create index create_html file_columns) before_action :check_create_permissions, only: :create - before_action :check_manage_permissions, except: %i(create index create_html) + before_action :check_manage_permissions, + except: %i(create index create_html file_columns) before_action :load_repository_columns, only: :index + before_action :load_asset_type_columns, only: :file_columns def index; end @@ -139,8 +142,25 @@ class RepositoryColumnsController < ApplicationController end end + def file_columns + if @asset_columns.empty? + render json: { + no_items: t( + 'projects.reports.new.save_PDF_to_inventory_modal.no_columns' + ) + }, status: :ok + else + render json: { results: @asset_columns }, status: :ok + end + end + + private + include StringUtility + AvailableRepositoryColumn = Struct.new(:id, :name) + + def load_vars @repository = Repository.find_by_id(params[:repository_id]) render_404 unless @repository @@ -158,6 +178,11 @@ class RepositoryColumnsController < ApplicationController .order(created_at: :desc) end + def load_asset_type_columns + render_403 unless can_read_team?(@repository.team) + @asset_columns = load_asset_columns(search_params[:q]) + end + def check_create_permissions render_403 unless can_create_repository_columns?(@repository.team) end @@ -170,6 +195,23 @@ class RepositoryColumnsController < ApplicationController params.require(:repository_column).permit(:name, :data_type) end + def search_params + params.permit(:q, :repository_id) + end + + def load_asset_columns(query) + @repository.repository_columns + .asset_type.name_like(query) + .limit(Constants::SEARCH_LIMIT) + .select(:id, :name) + .collect do |column| + AvailableRepositoryColumn.new( + column.id, + ellipsisize(column.name) + ) + end + end + def generate_repository_list_items(item_names) return true unless @repository_column.data_type == 'RepositoryListValue' column_items = @repository_column.repository_list_items.size diff --git a/app/controllers/repository_rows_controller.rb b/app/controllers/repository_rows_controller.rb index 9f7f731b6..96a439ebf 100644 --- a/app/controllers/repository_rows_controller.rb +++ b/app/controllers/repository_rows_controller.rb @@ -6,7 +6,11 @@ class RepositoryRowsController < ApplicationController before_action :load_info_modal_vars, only: :show before_action :load_vars, only: %i(edit update) before_action :load_repository, - only: %i(create delete_records index copy_records) + only: %i(create + delete_records + index + copy_records + available_rows) before_action :check_create_permissions, only: :create before_action :check_manage_permissions, only: %i(edit update delete_records copy_records) @@ -296,8 +300,26 @@ class RepositoryRowsController < ApplicationController }, status: :ok end + def available_rows + if @repository.repository_rows.empty? + no_items_string = + "#{t('projects.reports.new.save_PDF_to_inventory_modal.no_items')} " \ + "#{link_to(t('projects.reports.new.save_PDF_to_inventory_modal.here'), + repository_path(@repository), + data: { 'no-turbolink' => true })}" + render json: { no_items: no_items_string }, + status: :ok + else + render json: { results: load_available_rows(search_params[:q]) }, + status: :ok + end + end + private + include StringUtility + AvailableRepositoryRow = Struct.new(:id, :name, :has_file_attached) + def load_info_modal_vars @repository_row = RepositoryRow.eager_load(:created_by, repository: [:team]) .find_by_id(params[:id]) @@ -342,6 +364,27 @@ class RepositoryRowsController < ApplicationController params.permit(selected_rows: []).to_h[:selected_rows] end + def load_available_rows(query) + @repository.repository_rows + .includes(:repository_cells) + .name_like(search_params[:q]) + .limit(Constants::SEARCH_LIMIT) + .select(:id, :name) + .collect do |row| + with_asset_cell = row.repository_cells.where( + 'repository_cells.repository_column_id = ?', + search_params[:repository_column_id] + ) + AvailableRepositoryRow.new(row.id, + ellipsisize(row.name), + with_asset_cell.present?) + end + end + + def search_params + params.permit(:q, :repository_id, :repository_column_id) + end + def record_annotation_notification(record, cell, old_text = nil) table_url = params.fetch(:request_url) { :request_url_must_be_present } smart_annotation_notification( diff --git a/app/models/repository.rb b/app/models/repository.rb index d32863b70..ff13475d4 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -57,6 +57,10 @@ class Repository < ApplicationRecord end end + def self.name_like(query) + where('repositories.name ILIKE ?', "%#{query}%") + .limit(Constants::SEARCH_LIMIT) + end def importable_repository_fields fields = {} # First and foremost add record name diff --git a/app/models/repository_column.rb b/app/models/repository_column.rb index fe4caca43..6ced437ef 100644 --- a/app/models/repository_column.rb +++ b/app/models/repository_column.rb @@ -23,6 +23,11 @@ class RepositoryColumn < ApplicationRecord around_destroy :update_repository_table_states_with_removed_column scope :list_type, -> { where(data_type: 'RepositoryListValue') } + scope :asset_type, -> { where(data_type: 'RepositoryAssetValue') } + + def self.name_like(query) + where('repository_columns.name ILIKE ?', "%#{query}%") + end def update_repository_table_states_with_new_column service = RepositoryTableStateColumnUpdateService.new diff --git a/app/models/repository_row.rb b/app/models/repository_row.rb index 5fa2b123b..86b789c03 100644 --- a/app/models/repository_row.rb +++ b/app/models/repository_row.rb @@ -26,4 +26,8 @@ class RepositoryRow < ApplicationRecord where(id: ids).joins(:my_module_repository_rows) .where('my_module_repository_rows.my_module' => my_module) end + + def self.name_like(query) + where('repository_rows.name ILIKE ?', "%#{query}%") + end end diff --git a/app/services/report_actions/save_pdf_to_inventory_item.rb b/app/services/report_actions/save_pdf_to_inventory_item.rb new file mode 100644 index 000000000..cc95c5e18 --- /dev/null +++ b/app/services/report_actions/save_pdf_to_inventory_item.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +module ReportActions + class SavePdfToInventoryItem + + attr_reader :cell_value + + def initialize(user, team, params) + @user = user + @team = team + @params = params + load_repository_collaborators + end + + def call + file = generate_pdf(@params[:html]) + asset = create_new_asset(file) + cell = fetch_repository_cell + cell.destroy if cell + @cell_value = create_new_cell_value(asset) + end + + private + + include Canaid::Helpers::PermissionsHelper + + def load_repository_collaborators + @repository = Repository.find_by_id(@params[:repository_id]) + @repository_column = RepositoryColumn.find_by_id( + @params[:respository_column_id] + ) + @repository_item = RepositoryRow.find_by_id( + @params[:repository_item_id] + ) + unless can_create_repository_rows?(@user, @repository.team) + raise ReportActions::RepostioryPermissionError, + I18n.t('projects.reports.new.no_permissions') + end + end + + def generate_pdf(html) + ac = ActionView::Base.new(ActionController::Base.view_paths, {}) + ac.extend ReportsHelper # include reports helper methods to view + ac.extend InputSanitizeHelper # include input sanitize methods to view + no_content_label = I18n.t('projects.reports.new.no_content_for_PDF_html') + save_path = Tempfile.open('report', Rails.root.join('tmp')) + @html = html + @html = no_content_label if @html.blank? + pdf_file = WickedPdf.new.pdf_from_string( + ac.render(template: 'reports/report.pdf.erb'), + header: { right: '[page] of [topage]' }, disable_javascript: true + ) + File.open(save_path, 'wb') do |file| + file << pdf_file + end + save_path + end + + def create_new_asset(file) + asset = Asset.new( + file: file, created_by: @user, last_modified_by: @user, team: @team + ) + asset.post_process_file(@team) if asset.save + asset + end + + def fetch_repository_cell + RepositoryCell.where(repository_row: @repository_item, + repository_column: @repository_column, + value_type: 'RepositoryAssetValue').first + end + + def create_new_cell_value(asset) + RepositoryAssetValue.new( + asset: asset, + created_by: @user, + last_modified_by: @user, + repository_cell_attributes: { + repository_row: @repository_item, + repository_column: @repository_column + } + ) + end + end + + RepostioryPermissionError = Class.new(StandardError) +end diff --git a/app/views/reports/new.html.erb b/app/views/reports/new.html.erb index 75b248c12..abb21cbaf 100644 --- a/app/views/reports/new.html.erb +++ b/app/views/reports/new.html.erb @@ -2,6 +2,7 @@ <% provide(:body_class, "report-body") %> <% provide(:container_class, "report-container") %> +
<%= render partial: "reports/new/report_navigation" %>
+<%= render partial: 'reports/new/save_PDF_to_inventory_modal' %> + <%= javascript_include_tag "handsontable.full.min" %> <%= javascript_include_tag("reports/new") %> +<%= javascript_include_tag 'reports/save_pdf_to_inventory' %> <%= javascript_include_tag "lodash" %> diff --git a/app/views/reports/new/_report_navigation.html.erb b/app/views/reports/new/_report_navigation.html.erb index e545fc222..220b1c39b 100644 --- a/app/views/reports/new/_report_navigation.html.erb +++ b/app/views/reports/new/_report_navigation.html.erb @@ -27,6 +27,12 @@ <% end %> + +
<%= link_to reports_path, data: { no_turbolink: false }, id: "cancel-report-link", class: "btn btn-default" do %> diff --git a/app/views/reports/new/_save_PDF_to_inventory_modal.html.erb b/app/views/reports/new/_save_PDF_to_inventory_modal.html.erb new file mode 100644 index 000000000..e963961bb --- /dev/null +++ b/app/views/reports/new/_save_PDF_to_inventory_modal.html.erb @@ -0,0 +1,57 @@ + diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 48ab1309f..1aeb9622a 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -87,6 +87,7 @@ Rails.application.config.assets.precompile += %w(repository_columns/index.js) Rails.application.config.assets.precompile += %w(repositories/show.js) Rails.application.config.assets.precompile += %w(sidebar_toggle.js) Rails.application.config.assets.precompile += %w(reports/reports_datatable.js) +Rails.application.config.assets.precompile += %w(reports/save_pdf_to_inventory.js) # Libraries needed for Handsontable formulas Rails.application.config.assets.precompile += %w(lodash.js) diff --git a/config/locales/en.yml b/config/locales/en.yml index bf3c7c13c..2c5b5eec5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -315,6 +315,7 @@ en: nav_title: "Report for: " nav_print: "Print" nav_pdf: "Download PDF" + save_PDF_to_inventory: "Save PDF to Inventory" nav_save: "Save" nav_close: "Close" nav_sort_by: "Sort by" @@ -324,6 +325,21 @@ en: sidebar_title: "Navigation" global_sort: "Sorting whole report will undo any custom sorting you might have done. Proceed?" unsaved_work: "Are you sure you want to leave this page? All unsaved data will be lost." + no_content_for_PDF_html: "

No content

" + no_permissions: "You don't have permissions on that repository" + save_PDF_to_inventory_modal: + 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 tne 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:" + inventory_column: "Select inventory column:" + inventory_item: "Select inventory item:" + no_inventories: "No inventories available!" + success_flash: "Report successfully saved to Inventory item." + asset_present_warning_html: "The selected cell already contains a file. If you would like to replace the file click Save. Replacing the file will have the following consequences: " + no_items: "Selected Inventory does not contain any items yet. Add the first item" + here: "here" + no_columns: "You do not have any Inventories with File columns. Add a File column to existing Inventory or create a new Inventory." + nothing_selected: "Nothing selected" elements: modals: project_contents: diff --git a/config/routes.rb b/config/routes.rb index 16644d322..f22b1c865 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -193,6 +193,13 @@ Rails.application.routes.draw do get 'reports/datatable', to: 'reports#datatable' post 'reports/visible_projects', to: 'reports#visible_projects', 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 'file_columns', to: 'repository_columns#file_columns', + defaults: { format: 'json' } post 'reports/destroy', to: 'reports#destroy' resources :projects, except: [:new, :destroy] do @@ -491,6 +498,9 @@ Rails.application.routes.draw do end end + post 'available_rows', to: 'repository_rows#available_rows', + defaults: { format: 'json' } + post 'repository_list_items', to: 'repository_list_items#search', defaults: { format: 'json' }