Merge branch 'develop' of github.com:martini/zammad into develop
This commit is contained in:
commit
8e6807b0eb
23 changed files with 267 additions and 226 deletions
|
@ -443,7 +443,7 @@ class App.Controller extends Spine.Controller
|
|||
}
|
||||
processData: true,
|
||||
success: (data, status, xhr) ->
|
||||
App.Store.write( "user-ticket-popover::#{params.user_id}", data )
|
||||
App.SessionStorage.set( "user-ticket-popover::#{params.user_id}", data )
|
||||
|
||||
# load assets
|
||||
App.Collection.loadAssets( data.assets )
|
||||
|
@ -452,7 +452,7 @@ class App.Controller extends Spine.Controller
|
|||
)
|
||||
|
||||
# get data
|
||||
data = App.Store.get( "user-ticket-popover::#{params.user_id}" )
|
||||
data = App.SessionStorage.get( "user-ticket-popover::#{params.user_id}" )
|
||||
if data
|
||||
show( params, { open: data.ticket_ids_open, closed: data.ticket_ids_closed } )
|
||||
@delay(
|
||||
|
|
|
@ -504,13 +504,13 @@ class App.ControllerTable extends App.Controller
|
|||
data[type][key] = {}
|
||||
data[type][key] = value
|
||||
@log 'debug', @table_id, 'preferencesStore', data
|
||||
localStorage.setItem(@preferencesStoreKey(), JSON.stringify(data))
|
||||
App.LocalStorage.set(@preferencesStoreKey(), data, @Session.get('id'))
|
||||
|
||||
preferencesGet: =>
|
||||
data = localStorage.getItem(@preferencesStoreKey())
|
||||
data = App.LocalStorage.get(@preferencesStoreKey(), @Session.get('id'))
|
||||
return {} if !data
|
||||
@log 'debug', @table_id, 'preferencesGet', data
|
||||
JSON.parse(data)
|
||||
data
|
||||
|
||||
preferencesStoreKey: =>
|
||||
"tablePreferences:#{@table_id}"
|
||||
|
|
|
@ -5,14 +5,14 @@ class App.DashboardActivityStream extends App.Controller
|
|||
@fetch()
|
||||
|
||||
# bind to rebuild view event
|
||||
@bind( 'activity_stream_rebuild', @load )
|
||||
@bind('activity_stream_rebuild', @load)
|
||||
|
||||
fetch: =>
|
||||
|
||||
# use cache of first page
|
||||
cache = App.Store.get( 'activity_stream' )
|
||||
cache = App.SessionStorage.get('activity_stream')
|
||||
if cache
|
||||
@load( cache )
|
||||
@load(cache)
|
||||
|
||||
# init fetch via ajax, all other updates on time via websockets
|
||||
else
|
||||
|
@ -25,15 +25,16 @@ class App.DashboardActivityStream extends App.Controller
|
|||
}
|
||||
processData: true
|
||||
success: (data) =>
|
||||
App.Store.write( 'activity_stream', data )
|
||||
@load(data)
|
||||
)
|
||||
|
||||
load: (data) =>
|
||||
|
||||
App.SessionStorage.set('activity_stream', data)
|
||||
|
||||
items = data.activity_stream
|
||||
|
||||
# load assets
|
||||
App.Collection.loadAssets( data.assets )
|
||||
App.Collection.loadAssets(data.assets)
|
||||
|
||||
@render(items)
|
||||
|
||||
|
@ -51,7 +52,7 @@ class App.DashboardActivityStream extends App.Controller
|
|||
|
||||
html = $('<div class="activity-entries"></div>')
|
||||
for item in items
|
||||
html.append( @renderItem(item) )
|
||||
html.append(@renderItem(item))
|
||||
|
||||
@$('.activity-entries').remove()
|
||||
@el.append html
|
||||
|
|
|
@ -3,7 +3,7 @@ class App.DashboardRss extends App.Controller
|
|||
super
|
||||
|
||||
# bind to rebuild view event
|
||||
@bind( 'rss_rebuild', @fetch )
|
||||
@bind('rss_rebuild', @fetch)
|
||||
|
||||
# refresh list ever 600 sec.
|
||||
@fetch()
|
||||
|
@ -11,7 +11,7 @@ class App.DashboardRss extends App.Controller
|
|||
fetch: =>
|
||||
|
||||
# get data from cache
|
||||
cache = App.Store.get( 'dashboard_rss' )
|
||||
cache = App.SessionStorage.get('dashboard_rss')
|
||||
if cache
|
||||
cache.head = 'Heise ATOM'
|
||||
@render( cache )
|
||||
|
@ -34,7 +34,7 @@ class App.DashboardRss extends App.Controller
|
|||
message: data.message
|
||||
)
|
||||
else
|
||||
App.Store.write( 'dashboard_rss', data )
|
||||
App.SessionStorage.set('dashboard_rss', data)
|
||||
data.head = 'Heise ATOM'
|
||||
@render(data)
|
||||
error: =>
|
||||
|
|
|
@ -134,7 +134,7 @@ class App.TicketCreate extends App.Controller
|
|||
fetch: (params) ->
|
||||
|
||||
# use cache
|
||||
cache = App.Store.get( 'ticket_create_attributes' )
|
||||
cache = App.SessionStorage.get( 'ticket_create_attributes' )
|
||||
|
||||
if cache && !params.ticket_id && !params.article_id
|
||||
|
||||
|
@ -157,7 +157,7 @@ class App.TicketCreate extends App.Controller
|
|||
success: (data, status, xhr) =>
|
||||
|
||||
# cache request
|
||||
App.Store.write( 'ticket_create_attributes', data )
|
||||
App.SessionStorage.set( 'ticket_create_attributes', data )
|
||||
|
||||
# get edit form attributes
|
||||
@form_meta = data.form_meta
|
||||
|
|
|
@ -22,7 +22,7 @@ class Index extends App.ControllerContent
|
|||
fetch: (params) ->
|
||||
|
||||
# use cache
|
||||
cache = App.Store.get( 'ticket_create_attributes' )
|
||||
cache = App.SessionStorage.get( 'ticket_create_attributes' )
|
||||
|
||||
if cache
|
||||
|
||||
|
@ -42,7 +42,7 @@ class Index extends App.ControllerContent
|
|||
success: (data, status, xhr) =>
|
||||
|
||||
# cache request
|
||||
App.Store.write( 'ticket_create_attributes', data )
|
||||
App.SessionStorage.set( 'ticket_create_attributes', data )
|
||||
|
||||
# get edit form attributes
|
||||
@form_meta = data.form_meta
|
||||
|
|
|
@ -1757,6 +1757,12 @@ class App.CustomerChatRef extends App.Controller
|
|||
|
||||
@render()
|
||||
|
||||
@interval(
|
||||
=>
|
||||
@updateNavMenu()
|
||||
6800
|
||||
)
|
||||
|
||||
render: ->
|
||||
@html App.view('layout_ref/customer_chat')()
|
||||
|
||||
|
@ -1765,11 +1771,36 @@ class App.CustomerChatRef extends App.Controller
|
|||
# @testChat @chatWindows[0], 100
|
||||
@initQuiz()
|
||||
|
||||
@updateNavMenu()
|
||||
|
||||
show: (params) =>
|
||||
|
||||
# highlight navbar
|
||||
@navupdate '#layout_ref/customer_chat'
|
||||
|
||||
randomCounter: (min, max) ->
|
||||
parseInt(Math.random() * (max - min) + min)
|
||||
|
||||
counter: =>
|
||||
@randomCounter(0,100)
|
||||
|
||||
switch: (state = undefined) =>
|
||||
|
||||
# read state
|
||||
if state is undefined
|
||||
value = App.SessionStorage.get('chat')
|
||||
if value is undefined
|
||||
value = false
|
||||
return value
|
||||
|
||||
# write state
|
||||
App.SessionStorage.set('chat', state)
|
||||
|
||||
updateNavMenu: =>
|
||||
delay = ->
|
||||
App.Event.trigger('menu:render')
|
||||
@delay(delay, 200)
|
||||
|
||||
testChat: (chat, count) ->
|
||||
for i in [0..count]
|
||||
text = @questions[Math.floor(Math.random() * @questions.length)].question
|
||||
|
@ -1878,7 +1909,7 @@ class CustomerChatRouter extends App.ControllerPermanent
|
|||
|
||||
App.Config.set( 'layout_ref/customer_chat', CustomerChatRouter, 'Routes' )
|
||||
App.Config.set( 'CustomerChatRef', { controller: 'CustomerChatRef', authentication: true }, 'permanentTask' )
|
||||
App.Config.set( 'CustomerChatRef', { prio: 1200, parent: '', name: 'Customer Chat', target: '#layout_ref/customer_chat', switch: true, counter: true, role: ['Agent'], class: 'chat' }, 'NavBar' )
|
||||
App.Config.set( 'CustomerChatRef', { prio: 1200, parent: '', name: 'Customer Chat', target: '#layout_ref/customer_chat', key: 'CustomerChatRef', role: ['Agent'], class: 'chat' }, 'NavBar' )
|
||||
|
||||
|
||||
class chatWindowRef extends Spine.Controller
|
||||
|
|
|
@ -6,18 +6,25 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
|||
@render()
|
||||
|
||||
# rerender view, e. g. on langauge change
|
||||
@bind 'ui:rerender', (data) =>
|
||||
@bind 'ui:rerender', =>
|
||||
@renderMenu()
|
||||
@renderPersonal()
|
||||
|
||||
# rerender menu
|
||||
@bind 'menu:render', =>
|
||||
@renderMenu()
|
||||
|
||||
# rerender menu
|
||||
@bind 'personal:render', =>
|
||||
@renderPersonal()
|
||||
|
||||
# update selected item
|
||||
@bind 'navupdate', (data) =>
|
||||
@update( arguments[0] )
|
||||
@bind 'navupdate', =>
|
||||
@update(arguments[0])
|
||||
|
||||
# rebuild nav bar with given user data
|
||||
@bind 'auth', (user) =>
|
||||
@log 'Navigation', 'debug', 'navbar rebuild', user
|
||||
|
||||
@render()
|
||||
|
||||
# fetch new recent viewed after collection change
|
||||
|
@ -43,6 +50,16 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
|||
renderMenu: =>
|
||||
items = @getItems( navbar: @Config.get( 'NavBar' ) )
|
||||
|
||||
# apply counter and switch info from persistant controllers (if exists)
|
||||
for item in items
|
||||
if item.key
|
||||
worker = App.TaskManager.worker(item.key)
|
||||
if worker
|
||||
if worker.counter
|
||||
item.counter = worker.counter()
|
||||
if worker.switch
|
||||
item.switch = worker.switch()
|
||||
|
||||
# get open tabs to repopen on rerender
|
||||
open_tab = {}
|
||||
@$('.open').children('a').each( (i,d) ->
|
||||
|
@ -56,12 +73,24 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
|||
href = $(d).attr('href')
|
||||
active_tab[href] = true
|
||||
)
|
||||
|
||||
# render menu
|
||||
@$('.js-menu').html App.view('navigation/menu')(
|
||||
items: items
|
||||
open_tab: open_tab
|
||||
active_tab: active_tab
|
||||
)
|
||||
|
||||
# bind on switch changes and execute it on controller
|
||||
@$('.js-menu .js-switch').bind('change', (e) =>
|
||||
val = $(e.target).prop('checked')
|
||||
key = $(e.target).closest('.menu-item').data('key')
|
||||
return if !key
|
||||
worker = App.TaskManager.worker(key)
|
||||
return if !worker
|
||||
worker.switch(val)
|
||||
)
|
||||
|
||||
renderPersonal: =>
|
||||
@recentViewNavbarItemsRebuild()
|
||||
items = @getItems( navbar: @Config.get( 'NavBarRight' ) )
|
||||
|
@ -198,7 +227,6 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
|||
# remove not needed popovers
|
||||
@delay( removePopovers, 280, 'removePopovers' )
|
||||
|
||||
|
||||
# observer search box
|
||||
@$('#global-search').bind( 'focusout', (e) =>
|
||||
# delay to be able to click x
|
||||
|
|
|
@ -23,9 +23,9 @@ class Index extends App.ControllerContent
|
|||
return @params if @params
|
||||
|
||||
@params = {}
|
||||
paramsRaw = localStorage.getItem('report::params')
|
||||
paramsRaw = App.SessionStorage.get('report::params')
|
||||
if paramsRaw
|
||||
@params = JSON.parse(paramsRaw)
|
||||
@params = paramsRaw
|
||||
return @params
|
||||
|
||||
@params.timeRange = 'year'
|
||||
|
@ -58,7 +58,7 @@ class Index extends App.ControllerContent
|
|||
|
||||
storeParams: =>
|
||||
# store latest params
|
||||
localStorage.setItem('report::params', JSON.stringify(@params))
|
||||
App.SessionStorage.set('report::params', @params)
|
||||
|
||||
render: (data = {}) =>
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ class Table extends App.Controller
|
|||
for key, value of params
|
||||
@[key] = value
|
||||
|
||||
@view_mode = localStorage.getItem( "mode:#{@view}" ) || 's'
|
||||
@view_mode = App.LocalStorage.get("mode:#{@view}", @Session.get('id')) || 's'
|
||||
@log 'notice', 'view:', @view, @view_mode
|
||||
|
||||
return if !@view
|
||||
|
@ -381,7 +381,7 @@ class Table extends App.Controller
|
|||
viewmode: (e) =>
|
||||
e.preventDefault()
|
||||
@view_mode = $(e.target).data('mode')
|
||||
localStorage.setItem( "mode:#{@view}", @view_mode )
|
||||
App.LocalStorage.set("mode:#{@view}", @view_mode, @Session.get('id'))
|
||||
@fetch()
|
||||
#@render()
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class App.TicketZoom extends App.Controller
|
|||
@overview_id = false
|
||||
|
||||
@key = 'ticket::' + @ticket_id
|
||||
cache = App.Store.get(@key)
|
||||
cache = App.SessionStorage.get(@key)
|
||||
if cache
|
||||
@load(cache)
|
||||
update = =>
|
||||
|
@ -168,7 +168,7 @@ class App.TicketZoom extends App.Controller
|
|||
@ticketUpdatedAtLastCall = newTicketRaw.updated_at
|
||||
|
||||
@load(data, force)
|
||||
App.Store.write(@key, data)
|
||||
App.SessionStorage(@key, data)
|
||||
|
||||
if !@doNotLog
|
||||
@doNotLog = 1
|
||||
|
|
|
@ -137,6 +137,7 @@ class App.TicketZoomArticleNew extends App.Controller
|
|||
ticket: ticket
|
||||
articleTypes: @articleTypes
|
||||
article: @defaults
|
||||
form_id: @form_id
|
||||
isCustomer: @isRole('Customer')
|
||||
)
|
||||
@setArticleType(@type)
|
||||
|
@ -167,7 +168,7 @@ class App.TicketZoomArticleNew extends App.Controller
|
|||
|
||||
html5Upload.initialize(
|
||||
uploadUrl: App.Config.get('api_path') + '/ticket_attachment_upload',
|
||||
dropContainer: @el.get(0),
|
||||
dropContainer: @$('.article-add').get(0),
|
||||
cancelContainer: @cancelContainer,
|
||||
inputField: @$('.article-attachment input').get(0),
|
||||
key: 'File',
|
||||
|
|
|
@ -91,7 +91,7 @@ class App.TicketZoomHighlighter extends App.Controller
|
|||
articles.off('mousedown', @onMouseDown)
|
||||
articles.on('mousedown', @onMouseDown) #future: touchend
|
||||
|
||||
# for testing purposes the highlights get stored in localStorage
|
||||
# for testing purposes the highlights get stored in atrticle preferences
|
||||
loadHighlights: (ticket_article_id) ->
|
||||
return if !@isRole('Agent')
|
||||
article = App.TicketArticle.find(ticket_article_id)
|
||||
|
|
|
@ -19,7 +19,7 @@ class App.WidgetTag extends App.Controller
|
|||
@render()
|
||||
return
|
||||
|
||||
@tags = App.Store.get( @cacheKey ) || []
|
||||
@tags = App.SessionStorage.get( @cacheKey ) || []
|
||||
if !_.isEmpty(@tags)
|
||||
@render()
|
||||
@delay(
|
||||
|
@ -42,7 +42,7 @@ class App.WidgetTag extends App.Controller
|
|||
processData: true
|
||||
success: (data, status, xhr) =>
|
||||
@tags = data.tags
|
||||
App.Store.write( @cacheKey, @tags )
|
||||
App.SessionStorage.set( @cacheKey, @tags )
|
||||
@render()
|
||||
)
|
||||
|
||||
|
|
|
@ -4,25 +4,25 @@ class App.Collection
|
|||
@init: ->
|
||||
_instance = new _collectionSingleton
|
||||
|
||||
@load: ( args ) ->
|
||||
@load: (args) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _collectionSingleton
|
||||
_instance.load( args )
|
||||
_instance.load(args)
|
||||
|
||||
@loadAssets: ( args ) ->
|
||||
@loadAssets: (args) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _collectionSingleton
|
||||
_instance.loadAssets( args )
|
||||
_instance.loadAssets(args)
|
||||
|
||||
@reset: ( args ) ->
|
||||
@reset: (args) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _collectionSingleton
|
||||
_instance.reset( args )
|
||||
_instance.reset(args)
|
||||
|
||||
@resetCollections: ( args ) ->
|
||||
@resetCollections: (args) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _collectionSingleton
|
||||
_instance.resetCollections( args )
|
||||
_instance.resetCollections(args)
|
||||
|
||||
class _collectionSingleton extends Spine.Module
|
||||
@include App.LogInclude
|
||||
|
@ -35,7 +35,7 @@ class _collectionSingleton extends Spine.Module
|
|||
@log 'error', 'loadAssets:trigger, got no data, cant load assets'
|
||||
return
|
||||
|
||||
@loadAssets( data )
|
||||
@loadAssets(data)
|
||||
|
||||
# add trigger - bind new events
|
||||
App.Event.bind 'resetCollection', (data) =>
|
||||
|
@ -43,28 +43,14 @@ class _collectionSingleton extends Spine.Module
|
|||
@log 'error', 'resetCollection:trigger, got no data, cant for collections'
|
||||
return
|
||||
|
||||
@resetCollections( data )
|
||||
|
||||
# find collections to load
|
||||
@_loadObjectsFromSessionStore()
|
||||
|
||||
_loadObjectsFromSessionStore: ->
|
||||
list = App.Store.list()
|
||||
for key in list
|
||||
parts = key.split('::')
|
||||
if parts[0] is 'collection'
|
||||
data = App.Store.get( key )
|
||||
data['type'] = parts[1]
|
||||
data['sessionStorage'] = true
|
||||
|
||||
@log 'debug', 'load INIT', data
|
||||
@load( data )
|
||||
@resetCollections(data)
|
||||
|
||||
resetCollections: (data) ->
|
||||
# load assets
|
||||
|
||||
# load collection
|
||||
for type, collection of data
|
||||
@log 'debug', 'resetCollection:trigger', type, collection
|
||||
@reset( sessionStorage: data.sessionStorage, type: type, data: collection )
|
||||
@reset(type: type, data: collection)
|
||||
|
||||
reset: (params) ->
|
||||
|
||||
|
@ -74,42 +60,28 @@ class _collectionSingleton extends Spine.Module
|
|||
@log 'error', 'reset', "no such collection #{params.type}", params
|
||||
return
|
||||
|
||||
# remove permanent storage
|
||||
@localDelete( params.type )
|
||||
|
||||
# reset in-memory
|
||||
appObject.refresh( params.data, { clear: true } )
|
||||
|
||||
# remember in store if not already requested from local storage
|
||||
for object in params.data
|
||||
@localStore( params.type, object )
|
||||
appObject.refresh(params.data, { clear: true })
|
||||
|
||||
loadAssets: (assets) ->
|
||||
@log 'debug', 'loadAssets', assets
|
||||
for type, collections of assets
|
||||
@load( sessionStorage: false, type: type, data: collections )
|
||||
@load(type: type, data: collections)
|
||||
|
||||
load: (params) ->
|
||||
|
||||
# no data to load
|
||||
return if _.isEmpty( params.data )
|
||||
return if _.isEmpty(params.data)
|
||||
|
||||
# check if collection exists
|
||||
appObject = App[ params.type ]
|
||||
appObject = App[params.type]
|
||||
if !appObject
|
||||
@log 'error', 'reset', "no such collection #{params.type}", params
|
||||
return
|
||||
|
||||
sessionStorage = params.sessionStorage
|
||||
|
||||
# load full array once
|
||||
if _.isArray( params.data )
|
||||
appObject.refresh( params.data )
|
||||
|
||||
# remember in store if not already requested from local storage
|
||||
if !sessionStorage
|
||||
for object in params.data
|
||||
@localStore( params.type, object )
|
||||
if _.isArray(params.data)
|
||||
appObject.refresh(params.data)
|
||||
return
|
||||
|
||||
# load data from object
|
||||
|
@ -117,26 +89,12 @@ class _collectionSingleton extends Spine.Module
|
|||
if !params.refresh && appObject
|
||||
|
||||
# check if new object is newer, just load newer objects
|
||||
if object.updated_at && appObject.exists( key )
|
||||
exists = appObject.find( key )
|
||||
if object.updated_at && appObject.exists(key)
|
||||
exists = appObject.find(key)
|
||||
if exists.updated_at
|
||||
if exists.updated_at < object.updated_at
|
||||
appObject.refresh( object )
|
||||
appObject.refresh(object)
|
||||
else
|
||||
appObject.refresh( object )
|
||||
appObject.refresh(object)
|
||||
else
|
||||
appObject.refresh( object )
|
||||
|
||||
# remember in store if not already requested from local storage
|
||||
if !sessionStorage
|
||||
@localStore( params.type, object)
|
||||
|
||||
localDelete: (type) ->
|
||||
list = App.Store.list()
|
||||
for key in list
|
||||
parts = key.split('::')
|
||||
if parts[0] is 'collection' && parts[1] is type
|
||||
App.Store.delete(key)
|
||||
|
||||
localStore: (type, object) ->
|
||||
App.Store.write( 'collection::' + type + '::' + object.id, { data: [ object ] } )
|
||||
appObject.refresh(object)
|
||||
|
|
64
app/assets/javascripts/app/lib/app_post/local_storage.coffee
Normal file
64
app/assets/javascripts/app/lib/app_post/local_storage.coffee
Normal file
|
@ -0,0 +1,64 @@
|
|||
class App.LocalStorage
|
||||
_instance = undefined # Must be declared here to force the closure on the class
|
||||
|
||||
@set: (key, value, user_id) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.set(key, value, user_id)
|
||||
|
||||
@get: (key, user_id) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.get(key, user_id)
|
||||
|
||||
@delete: (key, user_id) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.delete(key)
|
||||
|
||||
@clear: ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.clear()
|
||||
|
||||
@list: ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.list()
|
||||
|
||||
# The actual Singleton class
|
||||
class _storeSingleton
|
||||
constructor: ->
|
||||
|
||||
# write to local storage
|
||||
set: (key, value, user_id) ->
|
||||
try
|
||||
if user_id
|
||||
key = "personal::#{user_id}::#{key}"
|
||||
localStorage.setItem(key, JSON.stringify(value))
|
||||
catch e
|
||||
if e is QUOTA_EXCEEDED_ERR
|
||||
# do something nice to notify your users
|
||||
App.Log.error 'App.LocalStorage', 'Local storage quote exceeded!'
|
||||
|
||||
# get item
|
||||
get: (key, user_id) ->
|
||||
if user_id
|
||||
key = "personal::#{user_id}::#{key}"
|
||||
value = localStorage.getItem(key)
|
||||
return if !value
|
||||
JSON.parse(value)
|
||||
|
||||
# delete item
|
||||
delete: (key, user_id) ->
|
||||
if user_id
|
||||
key = "personal::#{user_id}::#{key}"
|
||||
localStorage.removeItem(key)
|
||||
|
||||
# clear local storage
|
||||
clear: ->
|
||||
localStorage.clear()
|
||||
|
||||
# return list of all keys
|
||||
list: ->
|
||||
window.localStorage
|
|
@ -0,0 +1,61 @@
|
|||
class App.SessionStorage
|
||||
_instance = undefined # Must be declared here to force the closure on the class
|
||||
|
||||
@set: (key, value) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.set(key, value)
|
||||
|
||||
@get: (key) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.get(key)
|
||||
|
||||
@delete: (key) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.delete(key)
|
||||
|
||||
@clear: ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.clear()
|
||||
|
||||
@list: ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.list()
|
||||
|
||||
# The actual Singleton class
|
||||
class _storeSingleton
|
||||
constructor: ->
|
||||
|
||||
App.Event.bind 'clearStore', =>
|
||||
@clear()
|
||||
|
||||
# write to local storage
|
||||
set: (key, value) ->
|
||||
try
|
||||
sessionStorage.setItem(key, JSON.stringify(value))
|
||||
catch e
|
||||
if e is QUOTA_EXCEEDED_ERR
|
||||
# do something nice to notify your users
|
||||
App.Log.error 'App.SessionStorage', 'Session storage quote exceeded!'
|
||||
|
||||
# get item
|
||||
get: (key) ->
|
||||
value = sessionStorage.getItem(key)
|
||||
return if !value
|
||||
JSON.parse(value)
|
||||
|
||||
# delete item
|
||||
delete: (key) ->
|
||||
sessionStorage.removeItem(key)
|
||||
|
||||
# clear local storage
|
||||
clear: ->
|
||||
sessionStorage.clear()
|
||||
|
||||
# return list of all keys
|
||||
list: ->
|
||||
window.sessionStorage
|
|
@ -1,93 +0,0 @@
|
|||
class App.Store
|
||||
_instance = undefined # Must be declared here to force the closure on the class
|
||||
@renew: ->
|
||||
_instance = new _storeSingleton
|
||||
|
||||
@write: (key, value) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.write(key, value)
|
||||
|
||||
@get: (args) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.get(args)
|
||||
|
||||
@delete: (args) ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.delete(args)
|
||||
|
||||
@clear: ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.clear()
|
||||
|
||||
@list: ->
|
||||
if _instance == undefined
|
||||
_instance ?= new _storeSingleton
|
||||
_instance.list()
|
||||
|
||||
# The actual Singleton class
|
||||
class _storeSingleton
|
||||
store: {}
|
||||
constructor: ->
|
||||
@support = true
|
||||
if !window.sessionStorage
|
||||
@support = false
|
||||
# @support = false
|
||||
|
||||
# clear store on every login/logout
|
||||
if @support
|
||||
App.Event.bind 'clearStore', =>
|
||||
@clear('all')
|
||||
|
||||
# write to local storage
|
||||
write: (key, value) ->
|
||||
@store[key] = value
|
||||
return if !@support
|
||||
return if !App.Config.get('ui_client_storage')
|
||||
try
|
||||
sessionStorage.setItem( key, JSON.stringify( value ) )
|
||||
catch e
|
||||
if e is QUOTA_EXCEEDED_ERR
|
||||
# do something nice to notify your users
|
||||
App.Log.error 'App.Store', 'Local storage quote exceeded, please relogin!'
|
||||
|
||||
# get item
|
||||
get: (key) ->
|
||||
return @store[key] if !@support
|
||||
return @store[key] if !App.Config.get('ui_client_storage')
|
||||
value = sessionStorage.getItem( key )
|
||||
return if !value
|
||||
object = JSON.parse( value )
|
||||
return object
|
||||
|
||||
# delete item
|
||||
delete: (key) ->
|
||||
delete @store[key]
|
||||
return if !@support
|
||||
return if !App.Config.get('ui_client_storage')
|
||||
sessionStorage.removeItem( key )
|
||||
|
||||
# clear local storage
|
||||
clear: ->
|
||||
@store = {}
|
||||
sessionStorage.clear()
|
||||
|
||||
# return list of all keys
|
||||
list: ->
|
||||
list = []
|
||||
if !@support || !App.Config.get('ui_client_storage')
|
||||
for key of @store
|
||||
list.push key
|
||||
return list
|
||||
|
||||
# logLength = sessionStorage.length-1;
|
||||
# for count in [0..logLength]
|
||||
# key = sessionStorage.key( count )
|
||||
# if key
|
||||
# list.push key
|
||||
for key of window.sessionStorage
|
||||
list.push key
|
||||
list
|
|
@ -290,7 +290,6 @@ class _webSocketSingleton extends App.Controller
|
|||
# fill collection
|
||||
if item['collection']
|
||||
@log 'debug', 'onmessage collection:' + item['collection']
|
||||
App.Store.write( item['collection'], item['data'] )
|
||||
|
||||
# fire event
|
||||
if item['event']
|
||||
|
|
|
@ -1,18 +1,9 @@
|
|||
class App.Model extends Spine.Model
|
||||
@destroyBind: false
|
||||
@apiPath: App.Config.get('api_path')
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# delete object from local storage on destroy
|
||||
if !@constructor.destroyBind
|
||||
@bind( 'destroy', (e) ->
|
||||
className = Object.getPrototypeOf(e).constructor.className
|
||||
key = "collection::#{className}::#{e.id}"
|
||||
App.Store.delete(key)
|
||||
)
|
||||
|
||||
uiUrl: ->
|
||||
'#'
|
||||
|
||||
|
|
|
@ -21,19 +21,19 @@
|
|||
</ul>
|
||||
</div>
|
||||
<% else: %>
|
||||
<a class="menu-item js-<%- item.class %>MenuItem<%- ' is-active' if @active_tab[item.target] %>" href="<%= item.target %>">
|
||||
<a class="menu-item js-<%- item.class %>MenuItem<%- ' is-active' if @active_tab[item.target] %>" href="<%= item.target %>" data-key="<%- item.key %>">
|
||||
<%- @Icon(item.class, 'menu-item-icon') %>
|
||||
<span class="menu-item-name">
|
||||
<%- @T(item.name) %>
|
||||
</span>
|
||||
<% if item.counter: %>
|
||||
<span class="counter badge badge--big"></span>
|
||||
<% if item.counter isnt undefined: %>
|
||||
<span class="counter badge badge--big"><%= item.counter %></span>
|
||||
<% end %>
|
||||
<% if item.switch: %>
|
||||
<span class="zammad-switch zammad-switch--dark zammad-switch--small">
|
||||
<input type="checkbox" id="<%- item.class %>-switch">
|
||||
<label for="<%- item.class %>-switch"></label>
|
||||
</span>
|
||||
<% if item.switch isnt undefined: %>
|
||||
<span class="zammad-switch zammad-switch--dark zammad-switch--small">
|
||||
<input type="checkbox" id="<%- item.class %>-switch" class="js-switch" <% if item.switch: %>checked<% end %>>
|
||||
<label for="<%- item.class %>-switch"></label>
|
||||
</span>
|
||||
<% end %>
|
||||
</a>
|
||||
<% end %>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<form class="article-add <% if @article.internal: %>is-internal<% else: %>is-public<% end %>" data-type="<%= @article.type %>">
|
||||
<input type="hidden" name="type" value="<%= @article.type %>">
|
||||
<input type="hidden" name="internal" value="<%= @article.internal %>">
|
||||
<input type="hidden" name="form_id" value="<%= @article.form_id %>">
|
||||
<input type="hidden" name="form_id" value="<%= @form_id %>">
|
||||
<input type="hidden" name="in_reply_to" value="<%= @article.in_reply_to %>">
|
||||
<div class="editControls">
|
||||
<div class="js-avatar"></div>
|
||||
|
|
|
@ -374,8 +374,8 @@ test( "events level", function() {
|
|||
|
||||
});
|
||||
|
||||
// local store
|
||||
test( "local store", function() {
|
||||
// session store
|
||||
test( "session store", function() {
|
||||
|
||||
var tests = [
|
||||
'some 123äöüßadajsdaiosjdiaoidj',
|
||||
|
@ -384,17 +384,17 @@ test( "local store", function() {
|
|||
];
|
||||
|
||||
// write/get
|
||||
App.Store.clear()
|
||||
App.SessionStorage.clear()
|
||||
_.each(tests, function(test) {
|
||||
App.Store.write( 'test1', test );
|
||||
var item = App.Store.get( 'test1' );
|
||||
App.SessionStorage.set( 'test1', test );
|
||||
var item = App.SessionStorage.get( 'test1' );
|
||||
deepEqual( test, item, 'write/get - compare stored and actual data' )
|
||||
});
|
||||
|
||||
// undefined/get
|
||||
App.Store.clear()
|
||||
App.SessionStorage.clear()
|
||||
_.each(tests, function(test) {
|
||||
var item = App.Store.get( 'test1' );
|
||||
var item = App.SessionStorage.get( 'test1' );
|
||||
deepEqual( undefined, item, 'undefined/get - compare not existing data and actual data' )
|
||||
});
|
||||
|
||||
|
@ -405,16 +405,16 @@ test( "local store", function() {
|
|||
{ key: '123äöüß', value: { key1: [1,2,3,4] }, key2: [1,2,'äöüß'] },
|
||||
];
|
||||
|
||||
App.Store.clear()
|
||||
App.SessionStorage.clear()
|
||||
_.each(tests, function(test) {
|
||||
App.Store.write( test.key, test.value );
|
||||
App.SessionStorage.set( test.key, test.value );
|
||||
});
|
||||
|
||||
_.each(tests, function(test) {
|
||||
var item = App.Store.get( test.key );
|
||||
var item = App.SessionStorage.get( test.key );
|
||||
deepEqual( test.value, item, 'write/get/delete - compare stored and actual data' );
|
||||
App.Store.delete( test.key );
|
||||
item = App.Store.get( test.key );
|
||||
App.SessionStorage.delete( test.key );
|
||||
item = App.SessionStorage.get( test.key );
|
||||
deepEqual( undefined, item, 'write/get/delete - compare deleted data' );
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue