Added preferences language feature.

This commit is contained in:
Martin Edenhofer 2013-02-12 01:56:23 +01:00
parent 03f7172e3d
commit 3bdc401931
21 changed files with 199 additions and 62 deletions

View file

@ -0,0 +1,68 @@
class App.ProfileLanguage extends App.Controller
events:
'submit form': 'update'
constructor: ->
super
return if !@authenticate()
@render()
render: =>
html = $( App.view('profile/language')() )
configure_attributes = [
{ name: 'locale', display: '', tag: 'select', null: false, class: 'input span4', options: { de: 'Deutsch', en: 'English (United States)', 'en-CA': 'English (Canada)', 'en-GB': 'English (United Kingdom)' }, default: App.i18n.get() },
]
@form = new App.ControllerForm(
el: html.find('.language_item')
model: { configure_attributes: configure_attributes }
autofocus: false
)
@html html
update: (e) =>
e.preventDefault()
params = @formParam(e.target)
error = @form.validate(params)
if error
@formValidate( form: e.target, errors: error )
return false
@formDisable(e)
# get data
@locale = params['locale']
App.Com.ajax(
id: 'preferences'
type: 'PUT'
url: 'api/users/preferences'
data: JSON.stringify(params)
processData: true
success: @success
error: @error
)
success: (data, status, xhr) =>
App.Collection.find(
'User',
App.Session.get( 'id' ),
=>
App.i18n.set( @locale )
App.Event.trigger( 'ui:rerender' )
@notify(
type: 'success'
msg: App.i18n.translateContent( 'Successfully!' )
)
,
true,
)
error: (xhr, status, error) =>
@render()
data = JSON.parse( xhr.responseText )
@notify(
type: 'error'
msg: App.i18n.translateContent( data.message )
)

View file

@ -13,7 +13,7 @@ class App.ChatWidget extends App.Controller
@messageLog = []
# rebuild chat widget
App.Event.bind 'ajax:auth', (user) =>
App.Event.bind 'auth', (user) =>
if !user
@messageLog = []
@el.html('')

View file

@ -1,7 +1,4 @@
$ = jQuery.sub()
class Index extends App.Controller
constructor: ->
super
@signout()
@ -11,13 +8,12 @@ class Index extends App.Controller
# remove remote session
App.Auth.logout()
# remoce local session
# remove local session
@Session.init()
App.Event.trigger 'ajax:auth'
App.Event.trigger( 'ui:rerender' )
# redirect to login
@navigate 'login'
App.Config.set( 'logout', Index, 'Routes' )
App.Config.set( 'Logout', { prio: 1800, parent: '#current_user', name: 'Sign out', target: '#logout', divider: true, role: [ 'Agent', 'Customer' ] }, 'NavBarRight' )

View file

@ -5,12 +5,16 @@ class App.Navigation extends App.Controller
super
@render()
# rerender view
App.Event.bind 'ui:rerender', (data) =>
@render()
# update selected item
App.Event.bind 'navupdate', (data) =>
@update(arguments[0])
@update( arguments[0] )
# rebuild nav bar with given user data
App.Event.bind 'ajax:auth', (user) =>
App.Event.bind 'auth', (user) =>
@log 'Navigation', 'notice', 'navbar rebuild', user
if !_.isEmpty( user )
@ -21,19 +25,20 @@ class App.Navigation extends App.Controller
cache = App.Store.get( 'update_recent_viewed' )
@recent_viewed_build( cache ) if cache
@render(user)
@render()
# rebuild ticket overview data
App.Event.bind 'navupdate_ticket_overview', (data) =>
@ticket_overview_build(data)
@render( App.Session.all() )
@render()
# rebuild recent viewd data
# rebuild recent viewed data
App.Event.bind 'update_recent_viewed', (data) =>
@recent_viewed_build(data)
@render( App.Session.all() )
@render()
render: (user) ->
render: () ->
user = App.Session.all()
nav_left = @getItems( navbar: @Config.get( 'NavBar' ) )
nav_right = @getItems( navbar: @Config.get( 'NavBarRight' ) )

View file

@ -9,7 +9,7 @@ class Index extends App.ControllerLevel2
@menu = [
{ name: 'Password', 'target': 'password', controller: App.ProfilePassword, params: {} },
{ name: 'Language', 'target': 'language', controller: App.ProfileLinkedAccounts, params: { area: 'Ticket::Number' } },
{ name: 'Language', 'target': 'language', controller: App.ProfileLanguage, params: {} },
{ name: 'Link Accounts', 'target': 'accounts', controller: App.ProfileLinkedAccounts, params: { area: 'Ticket::Number' } },
# { name: 'Notifications', 'target': 'notify', controller: App.SettingsArea, params: { area: 'Ticket::Number' } },
]

View file

@ -73,7 +73,8 @@ class App.Auth
App.WebSocket.auth()
# rebuild navbar with new navbar items
App.Event.trigger 'ajax:auth'
App.Event.trigger( 'auth' )
App.Event.trigger( 'ui:rerender' )
return false;
@ -89,6 +90,14 @@ class App.Auth
for key, value of data.session
App.Session.set( key, value )
# init of i18n
preferences = App.Session.get( 'preferences' )
if preferences && preferences.locale
locale = preferences.locale
if !locale
locale = window.navigator.userLanguage || window.navigator.language || 'en'
App.i18n.set( locale )
# refresh default collections
for key, value of data.default_collections
App[key].refresh( value, options: { clear: true } )
@ -97,7 +106,8 @@ class App.Auth
App.WebSocket.auth()
# rebuild navbar with user data
App.Event.trigger 'ajax:auth', data.session
App.Event.trigger( 'auth', data.session )
App.Event.trigger( 'ui:rerender' )
@_logout: (data) ->

View file

@ -3,8 +3,8 @@ $ = jQuery.sub()
class App.i18n
_instance = undefined
@init: ->
_instance ?= new _Singleton
@init: ( args ) ->
_instance ?= new _Singleton( args )
@translateContent: ( string, args... ) ->
if _instance == undefined
@ -21,18 +21,23 @@ class App.i18n
_instance ?= new _Singleton
_instance.timestamp( args )
@set: ( args ) ->
@get: ->
if _instance == undefined
_instance ?= new _Singleton
_instance.get()
@set: ( args ) ->
if _instance == undefined
_instance ?= new _Singleton( args )
_instance.set( args )
class _Singleton extends Spine.Module
@include App.Log
constructor: ->
constructor: ( locale ) ->
@map = {}
@timestampFormat = 'yyyy-mm-dd HH:MM'
@set('de')
# observe if text has been translated
$('body')
.delegate '.translation', 'focus', (e) =>
@ -78,8 +83,14 @@ class _Singleton extends Spine.Module
return $this
get: ->
@locale
set: ( locale ) ->
if locale is 'en-US'
locale = 'en'
@locale = locale
@map = {}
App.Com.ajax(
id: 'i18n-set-' + locale,

View file

@ -10,15 +10,12 @@ class App.Run extends App.Controller
# create web socket connection
App.WebSocket.connect()
# init of i18n
App.i18n.init()
# check if session already exists/try to get session data from server
App.Auth.loginCheck()
# start navigation controller
new App.Navigation( el: @el.find('#navigation') )
# check if session already exists/try to get session data from server
App.Auth.loginCheck()
# start notify controller
new App.Notify( el: @el.find('#notify') )
@ -70,8 +67,18 @@ class App.Content extends App.Controller
# remove waypoints
$('footer').waypoint('remove')
params.el = @el
new callback( params )
# execute controller
controller = (params) =>
params.el = @el
new callback( params )
controller( params )
# rerender view on ui:rerender event
App.Event.bind(
'ui:rerender', =>
controller( params )
'page'
)
# scroll to top / remember last screen position
# @scrollTo( 0, 0, 100 )

View file

@ -1,21 +0,0 @@
<div class="page-header">
<h1><%- @T( 'Profile' ) %><small></small></h1>
</div>
<ul>
<li><%- @T( 'Password' ) %></li>
<li><%- @T( 'Link Accounts' ) %></li>
<li><%- @T( 'Notifications' ) %></li>
<li></li>
</ul>
<div class="container">
<div class="row">
<div class="span12">
Link Accounts
<ul>
<li><a href="/auth/twitter">twitter</a></li>
<li><a href="/auth/facebook">facebook</a></li>
<li><a href="/auth/linked_in">linkedin</a></li>
</ul>
</div>
</div>
</div>

View file

@ -0,0 +1,6 @@
<form class="">
<h2><%- @T( 'Language' ) %></h2>
<p><%- @T( 'Change your language.' ) %></p>
<div class="language_item"></div>
<button type="submit" class="btn"><%- @T( 'Submit' ) %></button>
</form>

View file

@ -0,0 +1,6 @@
<h2><%- @T( 'Link Accounts' ) %></h2>
<ul>
<li><a href="/auth/twitter">twitter</a></li>
<li><a href="/auth/facebook">facebook</a></li>
<li><a href="/auth/linked_in">linkedin</a></li>
</ul>

View file

@ -1,7 +1,5 @@
<form class="">
<h2><%- @T( 'Password' ) %></h2>
<p><%- @T( 'Change your password.' ) %></p>
<h2><%- @T( 'Change your password' ) %></h2>
<div class="password_item"></div>
<button type="submit" class="btn"><%- @T( 'Submit' ) %></button>
</form>
<hr/>

View file

@ -92,6 +92,7 @@ curl http://localhost/api/channels.json -v -u #{login}:#{password}
=end
def index
return if is_not_role('Admin')
model_index_render(Channel, params)
end
@ -114,6 +115,7 @@ curl http://localhost/api/channels/#{id}.json -v -u #{login}:#{password}
=end
def show
return if is_not_role('Admin')
model_show_render(Channel, params)
end

View file

@ -50,6 +50,7 @@ curl http://localhost/api/overviews.json -v -u #{login}:#{password}
=end
def index
return if is_not_role('Admin')
model_index_render(Overview, params)
end
@ -71,6 +72,7 @@ curl http://localhost/api/overviews/#{id}.json -v -u #{login}:#{password}
=end
def show
return if is_not_role('Admin')
model_show_render(Overview, params)
end
@ -104,6 +106,7 @@ curl http://localhost/api/overviews.json -v -u #{login}:#{password} -H "Content-
=end
def create
return if is_not_role('Admin')
model_create_render(Overview, params)
end
@ -137,6 +140,7 @@ curl http://localhost/api/overviews.json -v -u #{login}:#{password} -H "Content-
=end
def update
return if is_not_role('Admin')
model_update_render(Overview, params)
end
@ -154,6 +158,7 @@ curl http://localhost/api/overviews.json -v -u #{login}:#{password} -H "Content-
=end
def destroy
return if is_not_role('Admin')
model_destory_render(Overview, params)
end
end

View file

@ -52,6 +52,7 @@ curl http://localhost/api/postmaster_filters.json -v -u #{login}:#{password}
=end
def index
return if is_not_role('Admin')
model_index_render(PostmasterFilter, params)
end
@ -73,6 +74,7 @@ curl http://localhost/api/postmaster_filters/#{id}.json -v -u #{login}:#{passwor
=end
def show
return if is_not_role('Admin')
model_show_render(PostmasterFilter, params)
end

View file

@ -45,6 +45,7 @@ curl http://localhost/api/slas.json -v -u #{login}:#{password}
=end
def index
return if is_not_role('Admin')
model_index_render(Sla, params)
end
@ -66,6 +67,7 @@ curl http://localhost/api/slas/#{id}.json -v -u #{login}:#{password}
=end
def show
return if is_not_role('Admin')
model_show_render(Sla, params)
end
@ -94,6 +96,7 @@ curl http://localhost/api/slas.json -v -u #{login}:#{password} -H "Content-Type:
=end
def create
return if is_not_role('Admin')
model_create_render(Sla, params)
end
@ -122,6 +125,7 @@ curl http://localhost/api/slas.json -v -u #{login}:#{password} -H "Content-Type:
=end
def update
return if is_not_role('Admin')
model_update_render(Sla, params)
end
@ -139,6 +143,7 @@ curl http://localhost/api/slas.json -v -u #{login}:#{password} -H "Content-Type:
=end
def destroy
return if is_not_role('Admin')
model_destory_render(Sla, params)
end
end

View file

@ -250,6 +250,7 @@ curl http://localhost/api/users/2.json -v -u #{login}:#{password} -H "Content-Ty
=end
def update
return if is_not_role('Admin')
user = User.find(params[:id])
begin
@ -383,7 +384,7 @@ POST /api/users/password_change
Payload:
{
"password_old": "some_password_old",
"password_new" "some_password_new"
"password_new": "some_password_new"
}
Response:
@ -392,7 +393,7 @@ Response:
}
Test:
curl http://localhost/api/users/password_change.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"password_old": "password_old", "password_new" "password_new"}'
curl http://localhost/api/users/password_change.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"password_old": "password_old", "password_new": "password_new"}'
=end
@ -418,4 +419,39 @@ curl http://localhost/api/users/password_change.json -v -u #{login}:#{password}
render :json => { :message => 'ok', :user_login => user.login }, :status => :ok
end
=begin
Resource:
PUT /api/users/preferences.json
Payload:
{
"language": "de",
"notification": true
}
Response:
{
:message => 'ok'
}
Test:
curl http://localhost/api/users/preferences.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"language": "de", "notifications": true}'
=end
def preferences
if !current_user
render :json => { :message => 'No current user!' }, :status => :unprocessable_entity
return
end
if params[:user]
params[:user].each {|key, value|
current_user.preferences[key.to_sym] = value
}
end
current_user.save
render :json => { :message => 'ok' }, :status => :ok
end
end

View file

@ -6,6 +6,7 @@ module ExtraRoutes
map.match '/api/users/password_reset', :to => 'users#password_reset_send', :via => :post
map.match '/api/users/password_reset_verify', :to => 'users#password_reset_verify', :via => :post
map.match '/api/users/password_change', :to => 'users#password_change', :via => :post
map.match '/api/users/preferences', :to => 'users#preferences', :via => :put
map.match '/api/users', :to => 'users#index', :via => :get
map.match '/api/users/:id', :to => 'users#show', :via => :get
map.match '/api/users', :to => 'users#create', :via => :post

View file

@ -1745,14 +1745,14 @@ Translation.create_if_not_exists( :locale => 'de', :source => "Week", :target =>
Translation.create_if_not_exists( :locale => 'de', :source => "Follow up possible", :target => "Nachfrage möglich", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "Assign Follow Ups", :target => "Zuweisung bei Nachfrage", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "Signature", :target => "Signatur", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "Change your password.", :target => "Ändern sie Ihr Passwort.", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "Change your password.", :target => "Ändern Sie Ihr Passwort.", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "Current Password", :target => "Aktuelles Passwort", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "New Password", :target => "Neues Passwort", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "New Password (confirm)", :target => "Neues Passwort (bestätigen)", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "Language", :target => "Sprache", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "", :target => "", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "", :target => "", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "Link Accounts", :target => "Verknüpfte Accounts", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "Change your language.", :target => "Ändern Sie Ihr Sprache.", :updated_by_id => 1, :created_by_id => 1 )
Translation.create_if_not_exists( :locale => 'de', :source => "Successfully!", :target => "Erfolgreich!", :updated_by_id => 1, :created_by_id => 1 )
#Translation.create_if_not_exists( :locale => 'de', :source => "", :target => "", :updated_by_id => 1, :created_by_id => 1 )

View file

@ -1,6 +1,6 @@
# encoding: utf-8
require 'browser_test_helper'
class TicketCreate < ActiveSupport::TestCase
test 'ticket create' do
tests = [
@ -59,4 +59,4 @@ class TicketCreate < ActiveSupport::TestCase
]
browser_signle_test_with_login(tests)
end
end
end

View file

@ -7,7 +7,7 @@ class ActiveSupport::TestCase
# Add more helper methods to be used by all tests here...
def browser_login(data)
all_tests = [
all_tests = [
{
:name => 'login',
:instance => data[:instance] || Watir::Browser.new,