diff --git a/app/assets/javascripts/app/controllers/chat.coffee b/app/assets/javascripts/app/controllers/chat.coffee index 2357bb72d..eb5919bdf 100644 --- a/app/assets/javascripts/app/controllers/chat.coffee +++ b/app/assets/javascripts/app/controllers/chat.coffee @@ -601,6 +601,9 @@ class ChatWindow extends App.Controller @el.addClass('is-offline') @input.attr('disabled', true) + # add footer with create ticket button + @body.append App.view('customer_chat/chat_footer')() + maybeAddTimestamp: -> timestamp = Date.now() diff --git a/app/assets/javascripts/app/controllers/import_otrs.coffee b/app/assets/javascripts/app/controllers/import_otrs.coffee index 2d04674a5..01097e8dd 100644 --- a/app/assets/javascripts/app/controllers/import_otrs.coffee +++ b/app/assets/javascripts/app/controllers/import_otrs.coffee @@ -79,7 +79,6 @@ class Index extends App.ControllerContent success: (data, status, xhr) => # validate form - console.log(data) if data.result is 'ok' @urlStatus.attr('data-state', 'success') @linkErrorMessage.text('') @@ -90,7 +89,7 @@ class Index extends App.ControllerContent @nextStartMigration.addClass('hide') ) - @delay( callback, 700, 'import_otrs_url' ) + @delay(callback, 700, 'import_otrs_url') startMigration: (e) => e.preventDefault() @@ -101,11 +100,8 @@ class Index extends App.ControllerContent url: @apiPath + '/import/otrs/import_start', processData: true, success: (data, status, xhr) => - - # validate form - console.log(data) if data.result is 'ok' - @delay( @updateMigration, 3000 ) + @delay(@updateMigration, 3000) ) @@ -118,22 +114,28 @@ class Index extends App.ControllerContent processData: true, success: (data, status, xhr) => - if data.setup_done - @Config.set('system_init_done', true) - @navigate '#' + if data.result is 'import_done' + window.location.reload() return - for key, item of data.data - element = @$('.js-' + key.toLowerCase() ) - element.find('.js-done').text(item.done) - element.find('.js-total').text(item.total) - element.find('progress').attr('max', item.total ) - element.find('progress').attr('value', item.done ) - if item.total <= item.done - element.addClass('is-done') - else - element.removeClass('is-done') - @delay( @updateMigration, 5000 ) + if data.result is 'error' + @$('.js-error').removeClass('hide') + @$('.js-error').html(App.i18n.translateContent(data.message)) + else + @$('.js-error').addClass('hide') + + if data.result is 'in_progress' + for key, item of data.data + element = @$('.js-' + key.toLowerCase() ) + element.find('.js-done').text(item.done) + element.find('.js-total').text(item.total) + element.find('progress').attr('max', item.total ) + element.find('progress').attr('value', item.done ) + if item.total <= item.done + element.addClass('is-done') + else + element.removeClass('is-done') + @delay(@updateMigration, 6500) ) App.Config.set( 'import/otrs', Index, 'Routes' ) diff --git a/app/assets/javascripts/app/views/customer_chat/chat_footer.jst.eco b/app/assets/javascripts/app/views/customer_chat/chat_footer.jst.eco new file mode 100644 index 000000000..547c4142d --- /dev/null +++ b/app/assets/javascripts/app/views/customer_chat/chat_footer.jst.eco @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/app/assets/javascripts/app/views/import/otrs.jst.eco b/app/assets/javascripts/app/views/import/otrs.jst.eco index 97def7444..caa7222c7 100644 --- a/app/assets/javascripts/app/views/import/otrs.jst.eco +++ b/app/assets/javascripts/app/views/import/otrs.jst.eco @@ -41,6 +41,8 @@

<%- @T('OTRS Migration') %>

+ +
diff --git a/app/assets/stylesheets/zammad.scss b/app/assets/stylesheets/zammad.scss index 5fa47a3c0..36af9ea5c 100644 --- a/app/assets/stylesheets/zammad.scss +++ b/app/assets/stylesheets/zammad.scss @@ -7275,7 +7275,6 @@ output { } &.is-offline { - .chat-body-holder, .chat-controls { opacity: 0.5; } @@ -7286,7 +7285,7 @@ output { background: hsl(210,8%,95%); border: 1px solid hsl(0,0%,91%); border-radius: 3px 3px 0 0; - height: 37px; + height: 43px; line-height: 13px; flex-shrink: 0; display: flex; @@ -7336,7 +7335,7 @@ output { .chat-disconnect, .chat-close { cursor: pointer; - padding: 0 4px; + padding: 10px; .btn { min-width: 80px; @@ -7437,6 +7436,15 @@ output { 67% { opacity: 1; transform: scale(1); } } +.chat-footer { + border-top: 1px solid hsl(0,0%,93%); + padding: 10px; + display: flex; + justify-content: center; + align-self: stretch; + margin: 0 -10px; +} + .chat-controls { display: flex; align-items: flex-start; diff --git a/app/controllers/import_otrs_controller.rb b/app/controllers/import_otrs_controller.rb index 7b84208a2..42f4434f3 100644 --- a/app/controllers/import_otrs_controller.rb +++ b/app/controllers/import_otrs_controller.rb @@ -22,9 +22,7 @@ class ImportOtrsController < ApplicationController 'Connection refused' => 'Connection refused!', } - url_parts = params[:url].split(';') - - response = UserAgent.request( url_parts[0] ) + response = UserAgent.request( params[:url] ) if !response.success? && response.code.to_s !~ /^40.$/ message_human = '' @@ -44,16 +42,27 @@ class ImportOtrsController < ApplicationController result = {} if response.body =~ /zammad migrator/ - key_parts = url_parts[1].split('=') + migrator_response = JSON.parse(response.body) - Setting.set('import_backend', 'otrs') - Setting.set('import_otrs_endpoint', url_parts[0]) - Setting.set('import_otrs_endpoint_key', key_parts[1]) + if migrator_response['Success'] == 1 - result = { - result: 'ok', - url: params[:url], - } + url_parts = params[:url].split(';') + key_parts = url_parts[1].split('=') + + Setting.set('import_backend', 'otrs') + Setting.set('import_otrs_endpoint', url_parts[0]) + Setting.set('import_otrs_endpoint_key', key_parts[1]) + + result = { + result: 'ok', + url: params[:url], + } + else + result = { + result: 'invalid', + message_human: migrator_response['Error'] + } + end elsif response.body =~ /(otrs\sag|otrs\.com|otrs\.org)/i result = { result: 'invalid', @@ -71,7 +80,6 @@ class ImportOtrsController < ApplicationController def import_start return if setup_done_response - Setting.set('import_mode', true) welcome = Import::OTRS.connection_test if !welcome @@ -83,7 +91,7 @@ class ImportOtrsController < ApplicationController end # start migration - Import::OTRS.delay.start + Import::OTRS.delay.start_bg render json: { result: 'ok', @@ -91,18 +99,11 @@ class ImportOtrsController < ApplicationController end def import_status - if !Setting.get('import_mode') - render json: { - setup_done: true, - } - return + result = Import::OTRS.status_bg + if result[:result] == 'import_done' + Setting.reload end - - state = Import::OTRS.current_state - render json: { - data: state, - result: 'in_progress', - } + render json: result end private diff --git a/app/models/setting.rb b/app/models/setting.rb index abd47367c..495ba1713 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -77,13 +77,25 @@ reset config setting to default @@current[:settings_config][name] end +=begin + +reload config settings + + Setting.reload + +=end + + def self.reload + load(true) + end + private # load values and cache them - def self.load + def self.load(force = false) # check if config is already generated - if @@current[:settings_config] + if !force && @@current[:settings_config] return false if cache_valid? end diff --git a/lib/import/otrs.rb b/lib/import/otrs.rb index 98c9cd80b..b3e33d754 100644 --- a/lib/import/otrs.rb +++ b/lib/import/otrs.rb @@ -214,7 +214,7 @@ module Import::OTRS =begin - get object statistic from server ans save it in cache + get object statistic from remote server ans save it in cache result = statistic('Subaction=List') @@ -409,10 +409,77 @@ module Import::OTRS threads[thread].join } + true + end + +=begin + start import in background + + Import::OTRS.start_bg +=end + + def self.start_bg + Setting.reload + + Import::OTRS.connection_test + + # start thread to observe current state + status_update_thread = Thread.new { + loop do + result = { + data: current_state, + result: 'in_progress', + } + Cache.write('import:state', result, expires_in: 10.minutes) + sleep 8 + end + } + sleep 2 + + # start thread to import data + begin + import_thread = Thread.new { + Import::OTRS.start + } + rescue => e + status_update_thread.exit + status_update_thread.join + Rails.logger.error e.message + Rails.logger.error e.backtrace.inspect + result = { + message: e.message, + result: 'error', + } + Cache.write('import:state', result, expires_in: 10.hours) + return false + end + import_thread.join + status_update_thread.exit + status_update_thread.join + + result = { + result: 'import_done', + } + Cache.write('import:state', result, expires_in: 10.hours) + Setting.set('system_init_done', true) Setting.set('import_mode', false) + end - true +=begin + + get import state from background process + + result = Import::OTRS.status_bg + +=end + + def self.status_bg + state = Cache.get('import:state') + return state if state + { + message: 'not running', + } end def self.diff_worker diff --git a/test/integration/otrs_import_browser_test.rb b/test/integration/otrs_import_browser_test.rb index 816f56d47..4f59578aa 100644 --- a/test/integration/otrs_import_browser_test.rb +++ b/test/integration/otrs_import_browser_test.rb @@ -11,8 +11,6 @@ class OtrsImportBrowserTest < TestCase fail "ERROR: Need IMPORT_BT_OTRS_ENDPOINT_KEY - hint IMPORT_BT_OTRS_ENDPOINT_KEY='01234567899876543210'" end - import_url = "#{ENV['IMPORT_BT_OTRS_ENDPOINT']};Key=#{ENV['IMPORT_BT_OTRS_ENDPOINT_KEY']}" - @browser = browser_instance location(url: browser_url) @@ -20,26 +18,44 @@ class OtrsImportBrowserTest < TestCase click(css: 'a[href="#import/otrs"]') + click(css: '.js-download') + + click(css: '.js-otrs-link') + + invalid_key_url = "#{ENV['IMPORT_BT_OTRS_ENDPOINT']};Key=31337" + + set( + css: '#otrs-link', + value: invalid_key_url + ) + + sleep 5 + + watch_for( + css: '.otrs-link-error', + value: 'Invalid API key.', + ) + + import_url = "#{ENV['IMPORT_BT_OTRS_ENDPOINT']};Key=#{ENV['IMPORT_BT_OTRS_ENDPOINT_KEY']}" set( css: '#otrs-link', value: import_url ) - watch_for( - css: 'body', - value: 'xxxx', - timeout: 10, + sleep 5 + + watch_for_disappear( + css: '.otrs-link-error', + value: 'Invalid API key.', ) - # click import + click(css: '.js-migration-start') - # click otrs - - # enter otrs url + key - - # watch for import start - - # watch for import end + watch_for( + css: 'body', + value: 'login', + timeout: 300, + ) end