From 6fc6a2615030007c43b4494365eefe888e6ac579 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Wed, 15 Jul 2015 12:32:43 +0200 Subject: [PATCH 01/26] Fixed bug: Twitter articles are created without type, state and priortiy. --- lib/tweet.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/tweet.rb b/lib/tweet.rb index 185c06b99..78afb8736 100644 --- a/lib/tweet.rb +++ b/lib/tweet.rb @@ -112,8 +112,8 @@ class Tweet customer_id: user.id, title: "#{tweet.text[0, 37]}...", group_id: group_id, - state: Ticket::State.find_by( name: 'new' ), - priority: Ticket::Priority.find_by( name: '2 normal' ), + state_id: Ticket::State.find_by( name: 'new' ).id, + priority_id: Ticket::Priority.find_by( name: '2 normal' ).id, ) end @@ -153,8 +153,8 @@ class Tweet message_id: tweet.id, ticket_id: ticket.id, in_reply_to: in_reply_to, - type: Ticket::Article::Type.find_by( name: article_type ), - sender: Ticket::Article::Sender.find_by( name: 'Customer' ), + type_id: Ticket::Article::Type.find_by( name: article_type ).id, + sender_id: Ticket::Article::Sender.find_by( name: 'Customer' ).id, internal: false, ) end From e710d47af7281c6c29cc103455d858c0d3b1ab1f Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Wed, 15 Jul 2015 16:50:44 +0200 Subject: [PATCH 02/26] Fixed bug: Direct message ticket creation/selection is broken. --- lib/tweet.rb | 23 +++++++---- test/integration/twitter_test.rb | 69 ++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/lib/tweet.rb b/lib/tweet.rb index 78afb8736..94c1fafbd 100644 --- a/lib/tweet.rb +++ b/lib/tweet.rb @@ -97,15 +97,24 @@ class Tweet Rails.logger.debug group_id.inspect if tweet.class.to_s == 'Twitter::DirectMessage' - ticket = Ticket.find_by( - customer_id: user.id, - state: Ticket::State.where.not( - state_type_id: Ticket::StateType.where( - name: 'closed', + + article = Ticket::Article.find_by( + from: 'me_bauer', + type_id: Ticket::Article::Type.find_by( name: 'twitter direct-message' ).id, + ) + + if article + ticket = Ticket.find_by( + id: article.ticket_id, + customer_id: user.id, + state: Ticket::State.where.not( + state_type_id: Ticket::StateType.where( + name: 'closed', + ) ) ) - ) - return ticket if ticket + return ticket if ticket + end end Ticket.create( diff --git a/test/integration/twitter_test.rb b/test/integration/twitter_test.rb index 0a2f4518d..cce6ed5ac 100644 --- a/test/integration/twitter_test.rb +++ b/test/integration/twitter_test.rb @@ -220,25 +220,86 @@ class TwitterTest < ActiveSupport::TestCase sleep 5 } - assert( article, 'inbound article created' ) + assert( article, "inbound article '#{text}' created" ) ticket = article.ticket assert( ticket, 'ticket of inbound article exists' ) assert( ticket.articles, 'ticket.articles exists' ) - assert_equal( ticket.articles.count, 1, 'ticket article inbound count' ) + assert_equal( 1, ticket.articles.count, 'ticket article inbound count' ) assert_equal( ticket.state.name, 'new' ) # reply via ticket outbound_article = Ticket::Article.create( ticket_id: ticket.id, to: 'me_bauer', - body: text, + body: 'Will call you later!', type: Ticket::Article::Type.find_by( name: 'twitter direct-message' ), sender: Ticket::Article::Sender.find_by( name: 'Agent' ), internal: false, updated_by_id: 1, created_by_id: 1, ) + ticket.state = Ticket::State.find_by( name: 'pending reminder' ) + ticket.save + assert( outbound_article, 'outbound article created' ) - assert_equal( outbound_article.ticket.articles.count, 2, 'ticket article outbound count' ) + assert_equal( 2, outbound_article.ticket.articles.count, 'ticket article outbound count' ) + + text = 'Ok. ' + hash + dm = client.create_direct_message( + 'armin_theo', + text, + ) + assert( dm, "second dm with ##{hash} created" ) + + # fetch check system account + article = nil + (1..4).each { + Channel.fetch + + # check if ticket and article has been created + article = Ticket::Article.find_by( message_id: dm.id ) + + break if article + + sleep 5 + } + + assert( article, "inbound article '#{text}' created" ) + ticket = article.ticket + assert( ticket, 'ticket of inbound article exists' ) + assert( ticket.articles, 'ticket.articles exists' ) + assert_equal( 3, ticket.articles.count, 'ticket article inbound count' ) + assert_equal( ticket.state.name, 'open' ) + + # close dm ticket, next dm should open a new + ticket.state = Ticket::State.find_by( name: 'closed' ) + ticket.save + + text = 'Thanks for your call . I just have one question. ' + hash + dm = client.create_direct_message( + 'armin_theo', + text, + ) + assert( dm, "third dm with ##{hash} created" ) + + # fetch check system account + article = nil + (1..4).each { + Channel.fetch + + # check if ticket and article has been created + article = Ticket::Article.find_by( message_id: dm.id ) + + break if article + + sleep 5 + } + + assert( article, "inbound article '#{text}' created" ) + ticket = article.ticket + assert( ticket, 'ticket of inbound article exists' ) + assert( ticket.articles, 'ticket.articles exists' ) + assert_equal( 1, ticket.articles.count, 'ticket article inbound count' ) + assert_equal( ticket.state.name, 'new' ) end end From ae4f48a954a63bb0d6d289e9e4158bddff2f0a81 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Wed, 15 Jul 2015 21:45:40 +0200 Subject: [PATCH 03/26] Moved to new wording to access external services. --- .../app/controllers/settings.js.coffee | 16 ++-- app/controllers/application_controller.rb | 2 +- app/controllers/users_controller.rb | 2 +- app/models/avatar.rb | 2 +- app/models/observer/user/geo.rb | 2 +- db/migrate/20150715000001_update_services.rb | 76 ++++++++++++++++++ db/seeds.rb | 54 ++++++++++--- lib/auto_wizard.rb | 2 +- lib/geo_location.rb | 49 ------------ lib/{ => service}/geo_ip.rb | 20 ++--- .../geo_ip/zammad.rb} | 2 +- lib/service/geo_location.rb | 51 ++++++++++++ lib/{ => service}/geo_location/gmaps.rb | 2 +- lib/service/image.rb | 79 +++++++++++++++++++ lib/service/image/zammad.rb | 74 +++++++++++++++++ lib/zammad/big_data/base.rb | 10 --- lib/zammad/big_data/organization.rb | 69 ---------------- lib/zammad/big_data/user.rb | 45 ----------- test/integration/geo_ip_test.rb | 10 +-- test/integration/geo_location_test.rb | 8 +- 20 files changed, 356 insertions(+), 219 deletions(-) create mode 100644 db/migrate/20150715000001_update_services.rb delete mode 100644 lib/geo_location.rb rename lib/{ => service}/geo_ip.rb (63%) rename lib/{geo_ip/zammad_geo_ip.rb => service/geo_ip/zammad.rb} (97%) create mode 100644 lib/service/geo_location.rb rename lib/{ => service}/geo_location/gmaps.rb (96%) create mode 100644 lib/service/image.rb create mode 100644 lib/service/image/zammad.rb delete mode 100644 lib/zammad/big_data/base.rb delete mode 100644 lib/zammad/big_data/organization.rb delete mode 100644 lib/zammad/big_data/user.rb diff --git a/app/assets/javascripts/app/controllers/settings.js.coffee b/app/assets/javascripts/app/controllers/settings.js.coffee index 6b632b657..b4ea9d9f1 100644 --- a/app/assets/javascripts/app/controllers/settings.js.coffee +++ b/app/assets/javascripts/app/controllers/settings.js.coffee @@ -16,10 +16,10 @@ class System extends App.ControllerTabs return if !@authenticate() @title 'System', true @tabs = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Base' } }, - { name: 'Storage', 'target': 'storage', controller: App.SettingsArea, params: { area: 'System::Storage' } }, - { name: 'Geo Services', 'target': 'geo', controller: App.SettingsArea, params: { area: 'System::Geo' } }, - { name: 'Frontend', 'target': 'ui', controller: App.SettingsArea, params: { area: 'System::UI' } }, + { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Base' } }, + { name: 'Services', 'target': 'services', controller: App.SettingsArea, params: { area: 'System::Services' } }, + { name: 'Storage', 'target': 'storage', controller: App.SettingsArea, params: { area: 'System::Storage' } }, + { name: 'Frontend', 'target': 'ui', controller: App.SettingsArea, params: { area: 'System::UI' } }, ] @render() @@ -64,8 +64,8 @@ class Ticket extends App.ControllerTabs @render() App.Config.set( 'SettingBranding', { prio: 1200, parent: '#settings', name: 'Branding', target: '#settings/branding', controller: Branding, role: ['Admin'] }, 'NavBarAdmin' ) -App.Config.set( 'SettingSystem', { prio: 1400, parent: '#settings', name: 'System', target: '#settings/system', controller: System, role: ['Admin'] }, 'NavBarAdmin' ) -App.Config.set( 'SettingSecurity', { prio: 1500, parent: '#settings', name: 'Security', target: '#settings/security', controller: Security, role: ['Admin'] }, 'NavBarAdmin' ) -App.Config.set( 'SettingTicket', { prio: 1600, parent: '#settings', name: 'Ticket', target: '#settings/ticket', controller: Ticket, role: ['Admin'] }, 'NavBarAdmin' ) -App.Config.set( 'SettingImport', { prio: 1700, parent: '#settings', name: 'Import', target: '#settings/import', controller: Import, role: ['Admin'] }, 'NavBarAdmin' ) +App.Config.set( 'SettingSystem', { prio: 1400, parent: '#settings', name: 'System', target: '#settings/system', controller: System, role: ['Admin'] }, 'NavBarAdmin' ) +App.Config.set( 'SettingSecurity', { prio: 1600, parent: '#settings', name: 'Security', target: '#settings/security', controller: Security, role: ['Admin'] }, 'NavBarAdmin' ) +App.Config.set( 'SettingTicket', { prio: 1700, parent: '#settings', name: 'Ticket', target: '#settings/ticket', controller: Ticket, role: ['Admin'] }, 'NavBarAdmin' ) +App.Config.set( 'SettingImport', { prio: 1800, parent: '#settings', name: 'Import', target: '#settings/import', controller: Import, role: ['Admin'] }, 'NavBarAdmin' ) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9ac15fd70..691b1197f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -86,7 +86,7 @@ class ApplicationController < ActionController::Base # check if remote ip need to be updated if !session[:remote_id] || session[:remote_id] != request.remote_ip session[:remote_id] = request.remote_ip - session[:geo] = GeoIp.location( request.remote_ip ) + session[:geo] = Service::GeoIp.location( request.remote_ip ) end # fill user agent diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index aeaf6acb3..ef7139862 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -130,7 +130,7 @@ class UsersController < ApplicationController # fetch org logo if user.email - Zammad::BigData::Organization.suggest_system_image(user.email) + Service::Image.organization_suggest(user.email) end end diff --git a/app/models/avatar.rb b/app/models/avatar.rb index 50c879c87..42630c8e0 100644 --- a/app/models/avatar.rb +++ b/app/models/avatar.rb @@ -146,7 +146,7 @@ add a avatar end # fetch image - image = Zammad::BigData::User.image(data[:url]) + image = Service::Image.user(data[:url]) return if !image if !data[:resize] data[:resize] = {} diff --git a/app/models/observer/user/geo.rb b/app/models/observer/user/geo.rb index c666a41a7..92ffe2abb 100644 --- a/app/models/observer/user/geo.rb +++ b/app/models/observer/user/geo.rb @@ -54,7 +54,7 @@ class Observer::User::Geo < ActiveRecord::Observer return if address == '' # lookup - latlng = GeoLocation.geocode( address ) + latlng = Service::GeoLocation.geocode( address ) return if !latlng # store data diff --git a/db/migrate/20150715000001_update_services.rb b/db/migrate/20150715000001_update_services.rb new file mode 100644 index 000000000..23c2f6d44 --- /dev/null +++ b/db/migrate/20150715000001_update_services.rb @@ -0,0 +1,76 @@ +class UpdateServices < ActiveRecord::Migration + def up + + Setting.create_or_update( + title: 'Image Service', + name: 'image_backend', + area: 'System::Services', + description: 'Defines the backend for user and organization image lookups.', + options: { + form: [ + { + display: '', + null: true, + name: 'image_backend', + tag: 'select', + options: { + '' => '-', + 'Service::Image::Zammad' => 'Zammad Image Service', + }, + }, + ], + }, + state: 'Service::Image::Zammad', + preferences: { prio: 1 }, + frontend: false + ) + + Setting.create_or_update( + title: 'Geo IP Service', + name: 'geo_ip_backend', + area: 'System::Services', + description: 'Defines the backend for geo IP lookups. Show also location of an IP address if an IP address is shown.', + options: { + form: [ + { + display: '', + null: true, + name: 'geo_ip_backend', + tag: 'select', + options: { + '' => '-', + 'Service::GeoIp::Zammad' => 'Zammad GeoIP Service', + }, + }, + ], + }, + state: 'Service::GeoIp::Zammad', + preferences: { prio: 2 }, + frontend: false + ) + + Setting.create_or_update( + title: 'Geo Location Service', + name: 'geo_location_backend', + area: 'System::Services', + description: 'Defines the backend for geo location lookups to store geo locations for addresses.', + options: { + form: [ + { + display: '', + null: true, + name: 'geo_location_backend', + tag: 'select', + options: { + '' => '-', + 'Service::GeoLocation::Gmaps' => 'Google Maps', + }, + }, + ], + }, + state: 'Service::GeoLocation::Gmaps', + preferences: { prio: 3 }, + frontend: false + ) + end +end diff --git a/db/seeds.rb b/db/seeds.rb index da79d6826..34aeabc0c 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -49,7 +49,7 @@ Setting.create_if_not_exists( ], }, preferences: { render: true, session_check: true, prio: 1 }, - state: 'Zammad', + state: 'Zammad Helpdesk', frontend: true ) Setting.create_if_not_exists( @@ -196,33 +196,36 @@ Setting.create_if_not_exists( state: 'DB', frontend: false ) + Setting.create_if_not_exists( - title: 'Geo Location Backend', - name: 'geo_location_backend', - area: 'System::Geo', - description: 'Defines the backend for geo location lookups.', + title: 'Image Service', + name: 'image_backend', + area: 'System::Services', + description: 'Defines the backend for user and organization image lookups.', options: { form: [ { display: '', null: true, - name: 'geo_location_backend', + name: 'image_backend', tag: 'select', options: { '' => '-', - 'GeoLocation::Gmaps' => 'Google Maps', + 'Service::Image::Zammad' => 'Zammad Image Service', }, }, ], }, - state: 'GeoLocation::Gmaps', + state: 'Service::Image::Zammad', + preferences: { prio: 1 }, frontend: false ) + Setting.create_if_not_exists( - title: 'Geo IP Backend', + title: 'Geo IP Service', name: 'geo_ip_backend', - area: 'System::Geo', - description: 'Defines the backend for geo ip lookups.', + area: 'System::Services', + description: 'Defines the backend for geo IP lookups. Show also location of an IP address if an IP address is shown.', options: { form: [ { @@ -232,12 +235,37 @@ Setting.create_if_not_exists( tag: 'select', options: { '' => '-', - 'GeoIp::ZammadGeoIp' => 'Zammad GeoIP Service', + 'Service::GeoIp::Zammad' => 'Zammad GeoIP Service', }, }, ], }, - state: 'GeoIp::ZammadGeoIp', + state: 'Service::GeoIp::Zammad', + preferences: { prio: 2 }, + frontend: false +) + +Setting.create_if_not_exists( + title: 'Geo Location Service', + name: 'geo_location_backend', + area: 'System::Services', + description: 'Defines the backend for geo location lookups to store geo locations for addresses.', + options: { + form: [ + { + display: '', + null: true, + name: 'geo_location_backend', + tag: 'select', + options: { + '' => '-', + 'Service::GeoLocation::Gmaps' => 'Google Maps', + }, + }, + ], + }, + state: 'Service::GeoLocation::Gmaps', + preferences: { prio: 3 }, frontend: false ) diff --git a/lib/auto_wizard.rb b/lib/auto_wizard.rb index fac763fee..b1cfdb703 100644 --- a/lib/auto_wizard.rb +++ b/lib/auto_wizard.rb @@ -111,7 +111,7 @@ returns # fetch org logo if admin_user.email - Zammad::BigData::Organization.suggest_system_image(admin_user.email) + Service::Image.organization_suggest(admin_user.email) end } end diff --git a/lib/geo_location.rb b/lib/geo_location.rb deleted file mode 100644 index ea3dd27cf..000000000 --- a/lib/geo_location.rb +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ - -class GeoLocation - include ApplicationLib - -=begin - -lookup lat and lng for address - - result = GeoLocation.geocode( 'Marienstrasse 13, 10117 Berlin' ) - -returns - - result = [ 4.21312, 1.3123 ] - -=end - - def self.geocode(address) - - # load backend - backend = load_adapter_by_setting( 'geo_location_backend' ) - return if !backend - - # db lookup - backend.geocode(address) - end - -=begin - -lookup address for lat and lng - - result = GeoLocation.reverse_geocode( 4.21312, 1.3123 ) - -returns - - result = 'some address' - -=end - - def self.reverse_geocode(lat, lng) - - # load backend - backend = load_adapter_by_setting( 'geo_location_backend' ) - return if !backend - - # db lookup - backend.reverse_geocode(lat, lng) - end -end diff --git a/lib/geo_ip.rb b/lib/service/geo_ip.rb similarity index 63% rename from lib/geo_ip.rb rename to lib/service/geo_ip.rb index 9a111d5df..a2a6291c4 100644 --- a/lib/geo_ip.rb +++ b/lib/service/geo_ip.rb @@ -1,13 +1,14 @@ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ -class GeoIp - include ApplicationLib +module Service + class GeoIp + include ApplicationLib =begin lookup location based on ip or hostname - result = GeoIp.location( '172.0.0.1' ) + result = Service::GeoIp.location( '172.0.0.1' ) returns @@ -27,13 +28,14 @@ returns =end - def self.location(address) + def self.location(address) - # load backend - backend = load_adapter_by_setting( 'geo_ip_backend' ) - return if !backend + # load backend + backend = load_adapter_by_setting( 'geo_ip_backend' ) + return if !backend - # db lookup - backend.location(address) + # db lookup + backend.location(address) + end end end diff --git a/lib/geo_ip/zammad_geo_ip.rb b/lib/service/geo_ip/zammad.rb similarity index 97% rename from lib/geo_ip/zammad_geo_ip.rb rename to lib/service/geo_ip/zammad.rb index a49daa5e8..a69a7a1d8 100644 --- a/lib/geo_ip/zammad_geo_ip.rb +++ b/lib/service/geo_ip/zammad.rb @@ -2,7 +2,7 @@ require 'cache' -class GeoIp::ZammadGeoIp +class Service::GeoIp::Zammad def self.location(address) # check cache diff --git a/lib/service/geo_location.rb b/lib/service/geo_location.rb new file mode 100644 index 000000000..690e14830 --- /dev/null +++ b/lib/service/geo_location.rb @@ -0,0 +1,51 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +module Service + class GeoLocation + include ApplicationLib + +=begin + +lookup lat and lng for address + + result = Service::GeoLocation.geocode( 'Marienstrasse 13, 10117 Berlin' ) + +returns + + result = [ 4.21312, 1.3123 ] + +=end + + def self.geocode(address) + + # load backend + backend = load_adapter_by_setting( 'geo_location_backend' ) + return if !backend + + # db lookup + backend.geocode(address) + end + +=begin + +lookup address for lat and lng + + result = GeoLocation.reverse_geocode( 4.21312, 1.3123 ) + +returns + + result = 'some address' + +=end + + def self.reverse_geocode(lat, lng) + + # load backend + backend = load_adapter_by_setting( 'geo_location_backend' ) + return if !backend + + # db lookup + backend.reverse_geocode(lat, lng) + end + end +end diff --git a/lib/geo_location/gmaps.rb b/lib/service/geo_location/gmaps.rb similarity index 96% rename from lib/geo_location/gmaps.rb rename to lib/service/geo_location/gmaps.rb index 59a61ec1a..eb98313a6 100644 --- a/lib/geo_location/gmaps.rb +++ b/lib/service/geo_location/gmaps.rb @@ -1,6 +1,6 @@ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ -class GeoLocation::Gmaps +class Service::GeoLocation::Gmaps def self.geocode(address) url = "http://maps.googleapis.com/maps/api/geocode/json?address=#{CGI.escape address}&sensor=true" diff --git a/lib/service/image.rb b/lib/service/image.rb new file mode 100644 index 000000000..0d3b87c7c --- /dev/null +++ b/lib/service/image.rb @@ -0,0 +1,79 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +module Service + class Image + include ApplicationLib + +=begin + +lookup user image based on email address + + file = Service::Image.user( 'skywalker@zammad.org' ) + +returns + + { + content: content, + mime_type: mime_type, + } + +=end + + def self.user(address) + + # load backend + backend = load_adapter_by_setting( 'image_backend' ) + return if !backend + + backend.user(address) + end + +=begin + +lookup organization image based on domain + + file = Service::Image.organization('edenhofer.de') + + file = Service::Image.organization('user@edenhofer.de') # will just use domain + +returns + + { + content: content, + mime_type: mime_type, + } + +=end + + def self.organization(domain) + + # load backend + backend = load_adapter_by_setting( 'image_backend' ) + return if !backend + + backend.organization(domain) + end + +=begin + +find organization image suggestion + + result = Service::Image.organization_suggest('edenhofer.de') + +returns + + true # or false + +=end + + def self.organization_suggest(domain) + + # load backend + backend = load_adapter_by_setting( 'image_backend' ) + return if !backend + + backend.organization_suggest(domain) + end + + end +end diff --git a/lib/service/image/zammad.rb b/lib/service/image/zammad.rb new file mode 100644 index 000000000..2fd7a2b33 --- /dev/null +++ b/lib/service/image/zammad.rb @@ -0,0 +1,74 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +class Service::Image::Zammad + + # rubocop:disable Style/ClassVars + @@api_host = 'https://bigdata.zammad.com' + @@open_timeout = 4 + @@read_timeout = 6 + + def self.user(email) + + # fetch image + response = UserAgent.post( + "#{@@api_host}/api/v1/person/image", + { + email: email, + }, + { + open_timeout: @@open_timeout, + read_timeout: @@read_timeout, + }, + ) + if !response.success? + Rails.logger.info "Can't fetch image for '#{email}' (maybe no avatar available), http code: #{response.code}" + return + end + Rails.logger.info "Fetched image for '#{email}', http code: #{response.code}" + mime_type = 'image/jpeg' + { + content: response.body, + mime_type: mime_type, + } + end + + def self.organization(domain) + + # strip, just use domain name + domain = domain.sub(/^.+?@(.+?)$/, '\1') + + # fetch org logo + response = UserAgent.post( + "#{@@api_host}/api/v1/organization/image", + { + domain: domain + }, + { + open_timeout: @@open_timeout, + read_timeout: @@read_timeout, + }, + ) + if !response.success? + Rails.logger.info "Can't fetch image for '#{domain}' (maybe no avatar available), http code: #{response.code}" + return + end + Rails.logger.info "Fetched image for '#{domain}', http code: #{response.code}" + mime_type = 'image/png' + + { + content: response.body, + mime_type: mime_type, + } + end + + def self.organization_suggest(domain) + image = self.organization(domain) + return false if !image + + # store image 1:1 + product_logo = StaticAssets.store_raw( image[:content], image[:mime_type] ) + Setting.set('product_logo', product_logo) + + true + end +end diff --git a/lib/zammad/big_data/base.rb b/lib/zammad/big_data/base.rb deleted file mode 100644 index 95f405f17..000000000 --- a/lib/zammad/big_data/base.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Zammad - module BigData - class Base - # rubocop:disable Style/ClassVars - @@api_host = 'https://bigdata.zammad.com' - @@open_timeout = 4 - @@read_timeout = 6 - end - end -end diff --git a/lib/zammad/big_data/organization.rb b/lib/zammad/big_data/organization.rb deleted file mode 100644 index f15f12056..000000000 --- a/lib/zammad/big_data/organization.rb +++ /dev/null @@ -1,69 +0,0 @@ -module Zammad - module BigData - class Organization < Zammad::BigData::Base - -=begin - - file = Zammad::BigData::Organization.image('edenhofer.de') - - file = Zammad::BigData::Organization.image('user@edenhofer.de') # will just use domain - -returns - - { - content: content, - mime_type: mime_type, - } - -=end - def self.image(domain) - - # strip, just use domain name - domain = domain.sub(/^.+?@(.+?)$/, '\1') - - # fetch org logo - response = UserAgent.post( - "#{@@api_host}/api/v1/organization/image", - { - domain: domain - }, - { - open_timeout: @@open_timeout, - read_timeout: @@read_timeout, - }, - ) - if !response.success? - Rails.logger.info "Can't fetch image for '#{domain}' (maybe no avatar available), http code: #{response.code}" - return - end - Rails.logger.info "Fetched image for '#{domain}', http code: #{response.code}" - mime_type = 'image/png' - - { - content: response.body, - mime_type: mime_type, - } - end - -=begin - - result = Zammad::BigData::Organization.suggest_system_image('edenhofer.de') - -returns - - true # or false - -=end - def self.suggest_system_image(domain) - image = self.image(domain) - return false if !image - - # store image 1:1 - product_logo = StaticAssets.store_raw( image[:content], image[:mime_type] ) - Setting.set('product_logo', product_logo) - - true - end - end - end -end diff --git a/lib/zammad/big_data/user.rb b/lib/zammad/big_data/user.rb deleted file mode 100644 index b12d08aae..000000000 --- a/lib/zammad/big_data/user.rb +++ /dev/null @@ -1,45 +0,0 @@ -module Zammad - module BigData - class User < Zammad::BigData::Base - -=begin - - file = Zammad::BigData::User.image('client@edenhofer.de') - -returns - - { - content: content, - mime_type: mime_type, - } - -=end - - def self.image(email) - - # fetch logo - response = UserAgent.post( - "#{@@api_host}/api/v1/person/image", - { - email: email, - }, - { - open_timeout: @@open_timeout, - read_timeout: @@read_timeout, - }, - ) - if !response.success? - Rails.logger.info "Can't fetch image for '#{email}' (maybe no avatar available), http code: #{response.code}" - return - end - Rails.logger.info "Fetched image for '#{email}', http code: #{response.code}" - mime_type = 'image/jpeg' - { - content: response.body, - mime_type: mime_type, - } - end - - end - end -end diff --git a/test/integration/geo_ip_test.rb b/test/integration/geo_ip_test.rb index 07fdbbd00..477b77968 100644 --- a/test/integration/geo_ip_test.rb +++ b/test/integration/geo_ip_test.rb @@ -6,7 +6,7 @@ class GeoIpTest < ActiveSupport::TestCase # check test 'check some results' do - result = GeoIp.location( '127.0.0.0.1' ) + result = Service::GeoIp.location( '127.0.0.0.1' ) assert(result) assert_equal(nil, result['country_name']) assert_equal(nil, result['city_name']) @@ -15,7 +15,7 @@ class GeoIpTest < ActiveSupport::TestCase assert_equal(nil, result['latitude']) assert_equal(nil, result['longitude']) - result = GeoIp.location( '195.65.29.254' ) + result = Service::GeoIp.location( '195.65.29.254' ) assert(result) assert_equal('Switzerland', result['country_name']) assert_equal('Regensdorf', result['city_name']) @@ -24,7 +24,7 @@ class GeoIpTest < ActiveSupport::TestCase assert_equal(47.4299, result['latitude']) assert_equal(8.465100000000007, result['longitude']) - result = GeoIp.location( '134.109.140.74' ) + result = Service::GeoIp.location( '134.109.140.74' ) assert(result) assert_equal('Germany', result['country_name']) assert_equal('Chemnitz', result['city_name']) @@ -33,7 +33,7 @@ class GeoIpTest < ActiveSupport::TestCase assert_equal(50.83330000000001, result['latitude']) assert_equal(12.916699999999992, result['longitude']) - result = GeoIp.location( '46.253.55.170' ) + result = Service::GeoIp.location( '46.253.55.170' ) assert(result) assert_equal('Germany', result['country_name']) assert_equal('Halle', result['city_name']) @@ -42,7 +42,7 @@ class GeoIpTest < ActiveSupport::TestCase assert_equal(51.5, result['latitude']) assert_equal(12.0, result['longitude']) - result = GeoIp.location( '169.229.216.200' ) + result = Service::GeoIp.location( '169.229.216.200' ) assert(result) assert_equal('United States', result['country_name']) assert_equal('Berkeley', result['city_name']) diff --git a/test/integration/geo_location_test.rb b/test/integration/geo_location_test.rb index da928f104..5a69ab11a 100644 --- a/test/integration/geo_location_test.rb +++ b/test/integration/geo_location_test.rb @@ -6,22 +6,22 @@ class GeoLocationTest < ActiveSupport::TestCase # check test 'check simple results' do - result = GeoLocation.geocode( 'Marienstrasse 13, 10117 Berlin' ) + result = Service::GeoLocation.geocode( 'Marienstrasse 13, 10117 Berlin' ) assert(result) assert_equal(52.52204, result[0]) assert_equal(13.38319, result[1]) - result = GeoLocation.geocode( 'Marienstrasse 13 10117 Berlin' ) + result = Service::GeoLocation.geocode( 'Marienstrasse 13 10117 Berlin' ) assert(result) assert_equal(52.52204, result[0]) assert_equal(13.38319, result[1]) - result = GeoLocation.geocode( 'Martinsbruggstrasse 35, 9016 St. Gallen' ) + result = Service::GeoLocation.geocode( 'Martinsbruggstrasse 35, 9016 St. Gallen' ) assert(result) assert_equal(47.4366664, result[0]) assert_equal(9.409814899999999, result[1]) - result = GeoLocation.geocode( 'Martinsbruggstrasse 35 9016 St. Gallen' ) + result = Service::GeoLocation.geocode( 'Martinsbruggstrasse 35 9016 St. Gallen' ) assert(result) assert_equal(47.4366664, result[0]) assert_equal(9.409814899999999, result[1]) From e8cc035c2297c4777485b5fe918826a2b6b6a801 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Wed, 15 Jul 2015 21:47:03 +0200 Subject: [PATCH 04/26] Sync also locales on translation sync. --- app/controllers/translations_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/translations_controller.rb b/app/controllers/translations_controller.rb index 854e95aaa..5c98afbfc 100644 --- a/app/controllers/translations_controller.rb +++ b/app/controllers/translations_controller.rb @@ -22,6 +22,7 @@ class TranslationsController < ApplicationController # POST /translations/sync def sync return if deny_if_not_role(Z_ROLENAME_ADMIN) + Locale.load Translation.load render json: { message: 'ok' }, status: :ok end From 8de67262d34598c04e764d39da8d7363b62d38bf Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Thu, 16 Jul 2015 08:16:16 +0200 Subject: [PATCH 05/26] Updated url to get images. --- lib/service/image/zammad.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/service/image/zammad.rb b/lib/service/image/zammad.rb index 2fd7a2b33..e2a378dfb 100644 --- a/lib/service/image/zammad.rb +++ b/lib/service/image/zammad.rb @@ -3,7 +3,7 @@ class Service::Image::Zammad # rubocop:disable Style/ClassVars - @@api_host = 'https://bigdata.zammad.com' + @@api_host = 'https://images.zammad.com' @@open_timeout = 4 @@read_timeout = 6 From 70de454d48835492b480cbca47e110547d6d2b26 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Thu, 16 Jul 2015 08:27:17 +0200 Subject: [PATCH 06/26] Applied rubocop. --- lib/service/image/zammad.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/service/image/zammad.rb b/lib/service/image/zammad.rb index e2a378dfb..f1e23ec48 100644 --- a/lib/service/image/zammad.rb +++ b/lib/service/image/zammad.rb @@ -62,7 +62,7 @@ class Service::Image::Zammad end def self.organization_suggest(domain) - image = self.organization(domain) + image = organization(domain) return false if !image # store image 1:1 From 73e9ccb7b4c5c28e45d3f18383672b488ac06460 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Thu, 16 Jul 2015 12:14:31 +0200 Subject: [PATCH 07/26] Wording update for settings. --- db/migrate/20150716000001_update_settings.rb | 69 ++++++++++++++++++++ db/seeds.rb | 6 +- 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20150716000001_update_settings.rb diff --git a/db/migrate/20150716000001_update_settings.rb b/db/migrate/20150716000001_update_settings.rb new file mode 100644 index 000000000..685412b9e --- /dev/null +++ b/db/migrate/20150716000001_update_settings.rb @@ -0,0 +1,69 @@ +class UpdateSettings < ActiveRecord::Migration + def up + Setting.create_or_update( + title: 'Organization', + name: 'organization', + area: 'System::Branding', + description: 'Will be shown in the app and is included in email footers.', + options: { + form: [ + { + display: '', + null: false, + name: 'organization', + tag: 'input', + }, + ], + }, + state: '', + preferences: { prio: 2 }, + frontend: true + ) + Setting.create_or_update( + title: 'Send client stats', + name: 'ui_send_client_stats', + area: 'System::UI', + description: 'Send client stats/error message to central server to improve the usability.', + options: { + form: [ + { + display: '', + null: true, + name: 'ui_send_client_stats', + tag: 'boolean', + options: { + true => 'yes', + false => 'no', + }, + }, + ], + }, + state: true, + preferences: { prio: 1 }, + frontend: true + ) + Setting.create_or_update( + title: 'Client storage', + name: 'ui_client_storage', + area: 'System::UI', + description: 'Use client storage to cache data to perform speed of application.', + options: { + form: [ + { + display: '', + null: true, + name: 'ui_client_storage', + tag: 'boolean', + options: { + true => 'yes', + false => 'no', + }, + }, + ], + }, + state: false, + preferences: { prio: 2 }, + frontend: true + ) + end +end diff --git a/db/seeds.rb b/db/seeds.rb index 34aeabc0c..c6f4679d4 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -75,7 +75,7 @@ Setting.create_if_not_exists( title: 'Organization', name: 'organization', area: 'System::Branding', - description: 'Will be shown in the app and is included in email headers.', + description: 'Will be shown in the app and is included in email footers.', options: { form: [ { @@ -273,7 +273,7 @@ Setting.create_if_not_exists( title: 'Send client stats', name: 'ui_send_client_stats', area: 'System::UI', - description: 'Send client stats to central server.', + description: 'Send client stats/error message to central server to improve the usability.', options: { form: [ { @@ -289,6 +289,7 @@ Setting.create_if_not_exists( ], }, state: true, + preferences: { prio: 1 }, frontend: true ) Setting.create_if_not_exists( @@ -311,6 +312,7 @@ Setting.create_if_not_exists( ], }, state: false, + preferences: { prio: 2 }, frontend: true ) From a7a4bfd892f13074f8df181c6f9e6af675b75ad5 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Thu, 16 Jul 2015 15:12:33 +0200 Subject: [PATCH 08/26] Added additional check. --- app/models/locale.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/locale.rb b/app/models/locale.rb index 5635f7ae6..6381e3b9f 100644 --- a/app/models/locale.rb +++ b/app/models/locale.rb @@ -13,6 +13,7 @@ class Locale < ApplicationModel } ) + fail "Can't load locales from #{url}" if !result fail "Can't load locales from #{url}: #{result.error}" if !result.success? ActiveRecord::Base.transaction do From 24a4965bf18f7a99d1f0292844b51820e4fa1cf9 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Thu, 16 Jul 2015 15:13:24 +0200 Subject: [PATCH 09/26] Added test environment env and rake calls. --- script/local_browser_tests.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/script/local_browser_tests.sh b/script/local_browser_tests.sh index 1591b48fa..5e00b6a98 100755 --- a/script/local_browser_tests.sh +++ b/script/local_browser_tests.sh @@ -50,6 +50,15 @@ sleep 15 #export REMOTE_URL='http://192.168.178.32:4444/wd/hub' #export REMOTE_URL='http://192.168.178.45:4444/wd/hub' +export RAILS_ENV=test + +echo "rake db:drop" +time rake db:drop +echo "rake db:create" +time rake db:create +echo "rake db:migrate" +time rake db:migrate + rake test:browser["BROWSER_URL=http://localhost:4444"] #rake test:browser["BROWSER_URL=http://localhost:4444 BROWSER=chrome"] #rake test:browser["BROWSER_URL=http://192.168.178.28:4444"] From 82190dba829c90f341f42f492067c3da97850c92 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Thu, 16 Jul 2015 15:14:06 +0200 Subject: [PATCH 10/26] Added basic browser profiles to make sure english is used as the browser locale. --- test/browser_test_helper.rb | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/test/browser_test_helper.rb b/test/browser_test_helper.rb index 3defb2aa9..a4d89f6aa 100644 --- a/test/browser_test_helper.rb +++ b/test/browser_test_helper.rb @@ -9,6 +9,22 @@ class TestCase < Test::Unit::TestCase ENV['BROWSER'] || 'firefox' end + def profile + browser_profile = nil + if browser == 'firefox' + browser_profile = Selenium::WebDriver::Firefox::Profile.new + + browser_profile['intl.locale.matchOS'] = false + browser_profile['intl.accept_languages'] = 'en-US' + browser_profile['general.useragent.locale'] = 'en-US' + elsif browser == 'chrome' + browser_profile = Selenium::WebDriver::Chrome::Profile.new + + browser_profile["intl.accept_languages"] = "en" + end + browser_profile + end + def browser_support_cookies if browser =~ /(internet_explorer|ie)/i return false @@ -25,7 +41,7 @@ class TestCase < Test::Unit::TestCase @browsers = {} end if !ENV['REMOTE_URL'] || ENV['REMOTE_URL'].empty? - local_browser = Selenium::WebDriver.for( browser.to_sym ) + local_browser = Selenium::WebDriver.for( browser.to_sym, profile: profile ) browser_instance_preferences(local_browser) @browsers[local_browser.hash] = local_browser return local_browser From f7a84ef0e602292cb8d81337a33fb606c3cabb94 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Thu, 16 Jul 2015 15:14:47 +0200 Subject: [PATCH 11/26] Fixed broken test: Position of table columns has changed. --- test/browser/agent_ticket_overview_level0_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/browser/agent_ticket_overview_level0_test.rb b/test/browser/agent_ticket_overview_level0_test.rb index d2824bde8..4120eaeda 100644 --- a/test/browser/agent_ticket_overview_level0_test.rb +++ b/test/browser/agent_ticket_overview_level0_test.rb @@ -104,11 +104,11 @@ class AgentTicketOverviewLevel0Test < TestCase # check if number and article count is shown match( - css: '.active table th:nth-child(3)', + css: '.active table th:nth-child(7)', value: '#', ) match( - css: '.active table th:nth-child(8)', + css: '.active table th:nth-child(4)', value: 'Article#', ) @@ -118,11 +118,11 @@ class AgentTicketOverviewLevel0Test < TestCase # check if number and article count is shown match( - css: '.active table th:nth-child(3)', + css: '.active table th:nth-child(7)', value: '#', ) match( - css: '.active table th:nth-child(8)', + css: '.active table th:nth-child(4)', value: 'Article#', ) From 940373f171dddd651f40acb43558c26ce3113285 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Thu, 16 Jul 2015 15:36:59 +0200 Subject: [PATCH 12/26] Added preferences attribute to disable update of setting via rest if system is a online system. --- .../_application_controller_generic.js.coffee | 18 +- .../app/controllers/_settings/area.js.coffee | 28 +- .../app/controllers/settings.js.coffee | 33 ++- .../app/views/generic/tabs.jst.eco | 2 +- app/controllers/settings_controller.rb | 14 + ...150716000003_add_setting_online_service.rb | 262 ++++++++++++++++++ db/seeds.rb | 16 ++ 7 files changed, 342 insertions(+), 31 deletions(-) create mode 100644 db/migrate/20150716000003_add_setting_online_service.rb diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee index 02de5fa90..02e2d8560 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee @@ -280,22 +280,30 @@ class App.ControllerTabs extends App.Controller render: -> - @html App.view('generic/tabs')( + @el = @html App.view('generic/tabs')( header: @header subHeader: @subHeader tabs: @tabs ) + # insert content for tab in @tabs - @el.find('.tab-content').append('
') + @el.find('.tab-content').append("
") if tab.controller params = tab.params || {} - params.el = @el.find( '#' + tab.target ) + params.name = tab.name + params.target = tab.target + params.el = @el.find( "##{tab.target}" ) new tab.controller( params ) + # check if tabs need to be hidden + if @tabs.length <= 1 + @el.find('.nav-tabs').addClass('hide') + + # set last or first tab to active @lastActiveTab = @Config.get('lastTab') - if @lastActiveTab && @el.find('.nav-tabs li a[href="' + @lastActiveTab + '"]')[0] - @el.find('.nav-tabs li a[href="' + @lastActiveTab + '"]').tab('show') + if @lastActiveTab && @el.find(".nav-tabs li a[href=#{@lastActiveTab}]")[0] + @el.find(".nav-tabs li a[href=#{@lastActiveTab}]").tab('show') else @el.find('.nav-tabs li:first a').tab('show') diff --git a/app/assets/javascripts/app/controllers/_settings/area.js.coffee b/app/assets/javascripts/app/controllers/_settings/area.js.coffee index 4138c118b..3f2cbaa25 100644 --- a/app/assets/javascripts/app/controllers/_settings/area.js.coffee +++ b/app/assets/javascripts/app/controllers/_settings/area.js.coffee @@ -26,21 +26,30 @@ class App.SettingsArea extends App.Controller area: @area ) + # filter online service settings + if App.Config.get('system_online_service') + settings = _.filter(settings, (setting) -> + return if setting.online_service + return if setting.preferences && setting.preferences.online_service_disable + setting + ) + return if _.isEmpty(settings) + # sort by prio settings = _.sortBy( settings, (setting) -> return if !setting.preferences setting.preferences.prio ) - html = $('
') + elements = [] for setting in settings if setting.name is 'product_logo' item = new App.SettingsAreaLogo( setting: setting ) else item = new App.SettingsAreaItem( setting: setting ) - html.append( item.el ) + elements.push item.el - @html html + @html elements class App.SettingsAreaItem extends App.Controller events: @@ -67,13 +76,13 @@ class App.SettingsAreaItem extends App.Controller # item @html App.view('settings/item')( - setting: @setting, + setting: @setting ) new App.ControllerForm( el: @el.find('.form-item'), - model: { configure_attributes: @configure_attributes, className: '' }, - autofocus: false, + model: { configure_attributes: @configure_attributes, className: '' } + autofocus: false ) update: (e) => @@ -103,7 +112,6 @@ class App.SettingsAreaItem extends App.Controller @setting.save( done: => ui.formEnable(e) - App.Event.trigger 'notify', { type: 'success' msg: App.i18n.translateContent('Update successful!') @@ -112,7 +120,6 @@ class App.SettingsAreaItem extends App.Controller # rerender ui || get new collections and session data if @setting.preferences - if @setting.preferences.render ui.render() App.Event.trigger( 'ui:rerender' ) @@ -121,6 +128,11 @@ class App.SettingsAreaItem extends App.Controller App.Auth.loginCheck() fail: => ui.formEnable(e) + App.Event.trigger 'notify', { + type: 'error' + msg: App.i18n.translateContent('Can\'t update item!') + timeout: 2000 + } ) class App.SettingsAreaLogo extends App.Controller diff --git a/app/assets/javascripts/app/controllers/settings.js.coffee b/app/assets/javascripts/app/controllers/settings.js.coffee index b4ea9d9f1..19178754d 100644 --- a/app/assets/javascripts/app/controllers/settings.js.coffee +++ b/app/assets/javascripts/app/controllers/settings.js.coffee @@ -5,7 +5,7 @@ class Branding extends App.ControllerTabs return if !@authenticate() @title 'Branding', true @tabs = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Branding' } }, + { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Branding' } } ] @render() @@ -15,12 +15,13 @@ class System extends App.ControllerTabs super return if !@authenticate() @title 'System', true - @tabs = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Base' } }, - { name: 'Services', 'target': 'services', controller: App.SettingsArea, params: { area: 'System::Services' } }, - { name: 'Storage', 'target': 'storage', controller: App.SettingsArea, params: { area: 'System::Storage' } }, - { name: 'Frontend', 'target': 'ui', controller: App.SettingsArea, params: { area: 'System::UI' } }, - ] + @tabs = [] + if !App.Config.get('system_online_service') + @tabs.push { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Base' } } + @tabs.push { name: 'Services', 'target': 'services', controller: App.SettingsArea, params: { area: 'System::Services' } } + if !App.Config.get('system_online_service') + @tabs.push { name: 'Storage', 'target': 'storage', controller: App.SettingsArea, params: { area: 'System::Storage' } } + @tabs.push { name: 'Frontend', 'target': 'ui', controller: App.SettingsArea, params: { area: 'System::UI' } } @render() class Security extends App.ControllerTabs @@ -30,11 +31,10 @@ class Security extends App.ControllerTabs return if !@authenticate() @title 'Security', true @tabs = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Security::Base' } }, -# { name: 'Authentication', 'target': 'auth', controller: App.SettingsArea, params: { area: 'Security::Authentication' } }, - { name: 'Password', 'target': 'password', controller: App.SettingsArea, params: { area: 'Security::Password' } }, - { name: 'Third-Party Applications', 'target': 'third_party_auth', controller: App.SettingsArea, params: { area: 'Security::ThirdPartyAuthentication' } }, -# { name: 'Session', 'target': 'session', controller: '' }, + { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Security::Base' } } +# { name: 'Authentication', 'target': 'auth', controller: App.SettingsArea, params: { area: 'Security::Authentication' } } + { name: 'Password', 'target': 'password', controller: App.SettingsArea, params: { area: 'Security::Password' } } + { name: 'Third-Party Applications', 'target': 'third_party_auth', controller: App.SettingsArea, params: { area: 'Security::ThirdPartyAuthentication' } } ] @render() @@ -45,8 +45,8 @@ class Import extends App.ControllerTabs return if !@authenticate() @title 'Import', true @tabs = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Import::Base' } }, - { name: 'OTRS', 'target': 'otrs', controller: App.SettingsArea, params: { area: 'Import::OTRS' } }, + { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Import::Base' } } + { name: 'OTRS', 'target': 'otrs', controller: App.SettingsArea, params: { area: 'Import::OTRS' } } ] @render() @@ -57,9 +57,8 @@ class Ticket extends App.ControllerTabs return if !@authenticate() @title 'Ticket', true @tabs = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Ticket::Base' } }, - { name: 'Number', 'target': 'number', controller: App.SettingsArea, params: { area: 'Ticket::Number' } }, -# { name: 'Sender Format', 'target': 'sender-format', controller: App.SettingsArea, params: { area: 'Ticket::SenderFormat' } }, + { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Ticket::Base' } } + { name: 'Number', 'target': 'number', controller: App.SettingsArea, params: { area: 'Ticket::Number' } } ] @render() diff --git a/app/assets/javascripts/app/views/generic/tabs.jst.eco b/app/assets/javascripts/app/views/generic/tabs.jst.eco index 721b36aec..da97ce037 100644 --- a/app/assets/javascripts/app/views/generic/tabs.jst.eco +++ b/app/assets/javascripts/app/views/generic/tabs.jst.eco @@ -3,7 +3,7 @@

<%- @T( @header ) %> <%- @T( @subHeader ) %>

-