diff --git a/app/assets/javascripts/app/controllers/_application_controller.coffee b/app/assets/javascripts/app/controllers/_application_controller.coffee index 65ca0e4ef..2119be3c4 100644 --- a/app/assets/javascripts/app/controllers/_application_controller.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller.coffee @@ -663,6 +663,7 @@ class App.ControllerModal extends App.Controller large: false small: false head: '?' + autoFocusOnFirstInput: true container: null buttonClass: 'btn--success' centerButtons: [] @@ -812,7 +813,8 @@ class App.ControllerModal extends App.Controller @onShown(e) onShown: (e) => - @$('input:not([disabled]):not([type="hidden"]):not(".btn"), textarea').first().focus() + if @autoFocusOnFirstInput + @$('input:not([disabled]):not([type="hidden"]):not(".btn"), textarea').first().focus() @initalFormParams = @formParams() localOnClose: (e) => diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee index 776d0fc99..9a9855a45 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee @@ -1285,6 +1285,7 @@ class App.Import extends App.ControllerModal buttonClose: true buttonCancel: true buttonSubmit: 'Import' + autoFocusOnFirstInput: false head: 'Import' large: true templateDirectory: 'generic/object_import' @@ -1296,6 +1297,7 @@ class App.Import extends App.ControllerModal content = $(App.view("#{@templateDirectory}/index")( head: 'Import' import_example_url: "#{@baseUrl}/import_example" + deleteOption: @deleteOption )) # check if data is processing... @@ -1342,6 +1344,7 @@ class App.ImportTryResult extends App.ControllerModal buttonClose: true buttonCancel: true buttonSubmit: 'Yes, start real import.' + autoFocusOnFirstInput: false head: 'Import' large: true templateDirectory: 'generic/object_import/' @@ -1386,6 +1389,7 @@ class App.ImportResult extends App.ControllerModal buttonClose: true buttonCancel: true buttonSubmit: 'Close' + autoFocusOnFirstInput: false head: 'Import' large: true templateDirectory: 'generic/object_import/' diff --git a/app/assets/javascripts/app/controllers/text_module.coffee b/app/assets/javascripts/app/controllers/text_module.coffee index defadbbef..4ff914eb6 100644 --- a/app/assets/javascripts/app/controllers/text_module.coffee +++ b/app/assets/javascripts/app/controllers/text_module.coffee @@ -12,6 +12,7 @@ class Index extends App.ControllerSubContent new App.Import( baseUrl: '/api/v1/text_modules' container: @el.closest('.content') + deleteOption: true ) pageData: home: 'text_modules' diff --git a/app/assets/javascripts/app/views/generic/object_import/index.jst.eco b/app/assets/javascripts/app/views/generic/object_import/index.jst.eco index c4725c189..5e81afa51 100644 --- a/app/assets/javascripts/app/views/generic/object_import/index.jst.eco +++ b/app/assets/javascripts/app/views/generic/object_import/index.jst.eco @@ -14,10 +14,10 @@

<%- @T('Update existing records') %>

<%- @T('Update existing records with the attributes specified in the import data.') %> - +<% if @deleteOption is true: %> +

<%- @T('Delete records') %>

+<%- @T('Delete all existing records first.') %> +<% end %>

<%- @T('Select CSV file') %>

diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index bf5715181..80886e95c 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -354,6 +354,7 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co col_sep: params[:col_sep] || ',', }, try: params[:try], + delete: params[:delete], ) render json: result, status: :ok end diff --git a/app/controllers/text_modules_controller.rb b/app/controllers/text_modules_controller.rb index 970663776..f327e6fad 100644 --- a/app/controllers/text_modules_controller.rb +++ b/app/controllers/text_modules_controller.rb @@ -193,6 +193,7 @@ curl http://localhost/api/v1/text_modules.json -v -u #{login}:#{password} -H "Co col_sep: params[:col_sep] || ',', }, try: params[:try], + delete: params[:delete], ) render json: result, status: :ok end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 1ec7a3615..578e6f656 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1107,6 +1107,7 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content col_sep: params[:col_sep] || ',', }, try: params[:try], + delete: params[:delete], ) render json: result, status: :ok end diff --git a/app/models/concerns/can_csv_import.rb b/app/models/concerns/can_csv_import.rb index 0338e8137..4e227b561 100644 --- a/app/models/concerns/can_csv_import.rb +++ b/app/models/concerns/can_csv_import.rb @@ -16,6 +16,7 @@ module CanCsvImport col_sep: ',', }, try: true, + delete: false, ) result = Model.csv_import( @@ -24,6 +25,7 @@ module CanCsvImport col_sep: ',', }, try: true, + delete: false, ) result = TextModule.csv_import( @@ -32,6 +34,7 @@ module CanCsvImport col_sep: ',', }, try: false, + delete: false, ) returns @@ -45,7 +48,25 @@ returns =end def csv_import(data) + try = true + if data[:try] != 'true' && data[:try] != true + try = false + end + delete = false + if data[:delete] == true || data[:delete] == 'true' + delete = true + end + errors = [] + if delete == true && @csv_delete_possible != true + errors.push "Delete is not possible for #{new.class}." + result = { + errors: errors, + try: try, + result: 'failed', + } + return result + end if data[:file].present? raise Exceptions::UnprocessableEntity, "No such file '#{data[:file]}'" if !File.exist?(data[:file]) @@ -60,7 +81,7 @@ returns errors.push "Unable to parse empty file/string for #{new.class}." result = { errors: errors, - try: data[:try], + try: try, result: 'failed', } return result @@ -72,7 +93,7 @@ returns errors.push "Unable to parse file/string without header for #{new.class}." result = { errors: errors, - try: data[:try], + try: try, result: 'failed', } return result @@ -89,7 +110,7 @@ returns errors.push "No records found in file/string for #{new.class}." result = { errors: errors, - try: data[:try], + try: try, result: 'failed', } return result @@ -127,13 +148,22 @@ returns payload.push attributes end - # create or update records - csv_object_ids_ignored = @csv_object_ids_ignored || [] - records = [] stats = { created: 0, updated: 0, } + + # delete + if delete == true + stats[:deleted] = self.count + if try == false + destroy_all + end + end + + # create or update records + csv_object_ids_ignored = @csv_object_ids_ignored || [] + records = [] line_count = 0 payload.each do |attributes| line_count += 1 @@ -166,7 +196,7 @@ returns # create object Transaction.execute(disable_notification: true, reset_user_id: true) do UserInfo.current_user_id = clean_params[:updated_by_id] || clean_params[:created_by_id] - if !record + if !record || delete == true stats[:created] += 1 begin csv_verify_attributes(clean_params) @@ -177,7 +207,7 @@ returns clean_params[:updated_by_id] = 1 end record = new(clean_params) - next if data[:try] == 'true' || data[:try] == true + next if try == true record.associations_from_param(attributes) record.save! rescue => e @@ -186,7 +216,7 @@ returns end else stats[:updated] += 1 - next if data[:try] == 'true' || data[:try] == true + next if try == true begin csv_verify_attributes(clean_params) clean_params = param_cleanup(clean_params) @@ -218,7 +248,7 @@ returns stats: stats, records: records, errors: errors, - try: data[:try], + try: try, result: result, } @@ -371,5 +401,20 @@ end @csv_attributes_ignored = attributes end +=begin + +serve methode to define if delete option is possible or not + +class Model < ApplicationModel + include CanCsvImport + csv_delete_possible true + +end + +=end + + def csv_delete_possible(value) + @csv_delete_possible = value + end end end diff --git a/app/models/text_module.rb b/app/models/text_module.rb index 2b987c7d7..1e4d69d7a 100644 --- a/app/models/text_module.rb +++ b/app/models/text_module.rb @@ -13,6 +13,8 @@ class TextModule < ApplicationModel sanitized_html :content + csv_delete_possible true + =begin load text modules from online diff --git a/test/controllers/organization_controller_test.rb b/test/controllers/organization_controller_test.rb index 37c8ea27c..d5972d28a 100644 --- a/test/controllers/organization_controller_test.rb +++ b/test/controllers/organization_controller_test.rb @@ -538,7 +538,7 @@ class OrganizationControllerTest < ActionDispatch::IntegrationTest result = JSON.parse(@response.body) assert_equal(Hash, result.class) - assert_equal('true', result['try']) + assert_equal(true, result['try']) assert_equal(2, result['records'].count) assert_equal('failed', result['result']) assert_equal(2, result['errors'].count) @@ -553,7 +553,7 @@ class OrganizationControllerTest < ActionDispatch::IntegrationTest result = JSON.parse(@response.body) assert_equal(Hash, result.class) - assert_equal('true', result['try']) + assert_equal(true, result['try']) assert_equal(2, result['records'].count) assert_equal('success', result['result']) @@ -568,7 +568,7 @@ class OrganizationControllerTest < ActionDispatch::IntegrationTest result = JSON.parse(@response.body) assert_equal(Hash, result.class) - assert_nil(result['try']) + assert_equal(false, result['try']) assert_equal(2, result['records'].count) assert_equal('success', result['result']) diff --git a/test/controllers/text_module_controller_test.rb b/test/controllers/text_module_controller_test.rb index d7d83f78c..92d1a27e8 100644 --- a/test/controllers/text_module_controller_test.rb +++ b/test/controllers/text_module_controller_test.rb @@ -108,7 +108,7 @@ class TextModuleControllerTest < ActionDispatch::IntegrationTest result = JSON.parse(@response.body) assert_equal(Hash, result.class) - assert_equal('true', result['try']) + assert_equal(true, result['try']) assert_equal(2, result['records'].count) assert_equal('failed', result['result']) assert_equal(2, result['errors'].count) @@ -123,7 +123,7 @@ class TextModuleControllerTest < ActionDispatch::IntegrationTest result = JSON.parse(@response.body) assert_equal(Hash, result.class) - assert_equal('true', result['try']) + assert_equal(true, result['try']) assert_equal(2, result['records'].count) assert_equal('success', result['result']) @@ -138,7 +138,7 @@ class TextModuleControllerTest < ActionDispatch::IntegrationTest result = JSON.parse(@response.body) assert_equal(Hash, result.class) - assert_nil(result['try']) + assert_equal(false, result['try']) assert_equal(2, result['records'].count) assert_equal('success', result['result']) diff --git a/test/controllers/user_controller_test.rb b/test/controllers/user_controller_test.rb index fca67736c..133ea84ed 100644 --- a/test/controllers/user_controller_test.rb +++ b/test/controllers/user_controller_test.rb @@ -985,7 +985,7 @@ class UserControllerTest < ActionDispatch::IntegrationTest result = JSON.parse(@response.body) assert_equal(Hash, result.class) - assert_equal('true', result['try']) + assert_equal(true, result['try']) assert_equal(2, result['records'].count) assert_equal('failed', result['result']) assert_equal(2, result['errors'].count) @@ -1000,7 +1000,7 @@ class UserControllerTest < ActionDispatch::IntegrationTest result = JSON.parse(@response.body) assert_equal(Hash, result.class) - assert_equal('true', result['try']) + assert_equal(true, result['try']) assert_equal(2, result['records'].count) assert_equal('success', result['result']) @@ -1015,7 +1015,7 @@ class UserControllerTest < ActionDispatch::IntegrationTest result = JSON.parse(@response.body) assert_equal(Hash, result.class) - assert_nil(result['try']) + assert_equal(false, result['try']) assert_equal(2, result['records'].count) assert_equal('success', result['result']) diff --git a/test/unit/organization_csv_import_test.rb b/test/unit/organization_csv_import_test.rb index 8246a89a1..07c14537c 100644 --- a/test/unit/organization_csv_import_test.rb +++ b/test/unit/organization_csv_import_test.rb @@ -234,4 +234,20 @@ class OrganizationCsvImportTest < ActiveSupport::TestCase assert_nil(Organization.find_by(name: 'organization-invalid-import2')) end + test 'simple import with delete' do + csv_string = "id;name;shared;domain;domain_assignment;active;note\n;org-simple-import1;true;org-simple-import1.example.com;false;true;some note1\n;org-simple-import2;true;org-simple-import2.example.com;false;false;some note2\n" + result = Organization.csv_import( + string: csv_string, + parse_params: { + col_sep: ';', + }, + try: true, + delete: true, + ) + + assert_equal(true, result[:try]) + assert_equal('failed', result[:result]) + assert_equal('Delete is not possible for Organization.', result[:errors][0]) + end + end diff --git a/test/unit/text_module_csv_import_test.rb b/test/unit/text_module_csv_import_test.rb index a06d000a2..24a7777d1 100644 --- a/test/unit/text_module_csv_import_test.rb +++ b/test/unit/text_module_csv_import_test.rb @@ -51,6 +51,13 @@ class TextModuleCsvImportTest < ActiveSupport::TestCase end test 'simple import' do + TextModule.create!( + name: 'nsome name1', + content: 'nsome name1', + active: true, + updated_by_id: 1, + created_by_id: 1, + ) csv_string = "name;keywords;content;note;active;\nsome name1;keyword1;\"some\ncontent1\";-;\nsome name2;keyword2;some content
test123\n" result = TextModule.csv_import( @@ -97,4 +104,82 @@ class TextModuleCsvImportTest < ActiveSupport::TestCase text_module2.destroy! end + test 'simple import with delete' do + assert_equal(0, TextModule.count) + + TextModule.create!( + name: 'some name1', + content: 'some name1', + active: true, + updated_by_id: 1, + created_by_id: 1, + ) + TextModule.create!( + name: 'name should be deleted 2', + content: 'name should be deleted 1', + active: true, + updated_by_id: 1, + created_by_id: 1, + ) + + csv_string = "name;keywords;content;note;active;\nsome name1;keyword1;\"some\ncontent1\";-;\nsome name2;keyword2;some content
test123\n" + result = TextModule.csv_import( + string: csv_string, + parse_params: { + col_sep: ';', + }, + try: true, + delete: true, + ) + + assert_equal(true, result[:try]) + assert(result[:stats]) + assert_equal(2, result[:stats][:created]) + assert_equal(0, result[:stats][:updated]) + assert_equal(2, result[:stats][:deleted]) + + assert_equal(2, result[:records].count) + assert_equal('success', result[:result]) + + assert(TextModule.find_by(name: 'some name1')) + assert_nil(TextModule.find_by(name: 'some name2')) + + result = TextModule.csv_import( + string: csv_string, + parse_params: { + col_sep: ';', + }, + try: false, + delete: true, + ) + + assert_equal(false, result[:try]) + assert(result[:stats]) + assert_equal(2, result[:stats][:created]) + assert_equal(0, result[:stats][:updated]) + assert_equal(2, result[:stats][:deleted]) + assert_equal(2, result[:records].count) + assert_equal('success', result[:result]) + + assert_equal(2, TextModule.count) + + text_module1 = TextModule.find_by(name: 'some name1') + assert(text_module1) + assert_equal(text_module1.name, 'some name1') + assert_equal(text_module1.keywords, 'keyword1') + assert_equal(text_module1.content, 'some
content1') + assert_equal(text_module1.active, true) + text_module2 = TextModule.find_by(name: 'some name2') + assert(text_module2) + assert_equal(text_module2.name, 'some name2') + assert_equal(text_module2.keywords, 'keyword2') + assert_equal(text_module2.content, 'some content
test123') + assert_equal(text_module2.active, true) + + assert_nil(TextModule.find_by(name: 'name should be deleted 2')) + + text_module1.destroy! + text_module2.destroy! + end + end diff --git a/test/unit/user_csv_import_test.rb b/test/unit/user_csv_import_test.rb index 8e83863d7..cc1d146e5 100644 --- a/test/unit/user_csv_import_test.rb +++ b/test/unit/user_csv_import_test.rb @@ -441,4 +441,20 @@ class UserCsvImportTest < ActiveSupport::TestCase orgaization2.destroy! end + test 'simple import with delete' do + csv_string = "login;firstname;lastname;email\nuser-simple-import-fixed1;firstname-simple-import-fixed1;lastname-simple-import-fixed1;user-simple-import-fixed1@example.com\nuser-simple-import-fixed2;firstname-simple-import-fixed2;lastname-simple-import-fixed2;user-simple-import-fixed2@example.com\n" + result = User.csv_import( + string: csv_string, + parse_params: { + col_sep: ';', + }, + try: true, + delete: true, + ) + + assert_equal(true, result[:try]) + assert_equal('failed', result[:result]) + assert_equal('Delete is not possible for User.', result[:errors][0]) + end + end