Merge branch 'develop'

Conflicts:
	db/migrate/20130529124443_taskbar.rb
This commit is contained in:
Martin Edenhofer 2013-06-01 01:19:07 +02:00
commit bb230dbc4b
12 changed files with 173 additions and 104 deletions

View file

@ -50,7 +50,10 @@ class App.TicketCreate extends App.Controller
@render(defaults)
# start auto save
@autosave()
@delay(
=> @autosave(),
5000
)
meta: =>
text = App.i18n.translateInline( @article_attributes['title'] )
@ -68,7 +71,7 @@ class App.TicketCreate extends App.Controller
activate: =>
@navupdate '#'
@title @article_attributes['title']
@title @meta().title
changed: =>
formCurrent = @formParam( @el.find('.ticket-create') )
@ -89,7 +92,7 @@ class App.TicketCreate extends App.Controller
if !@autosaveLast || ( diff && !_.isEmpty( diff ) )
@autosaveLast = data
console.log('form hash changed', diff, data)
App.TaskManager.update( 'TicketCreateScreen', @type + '-' + @id, { 'state': data })
App.TaskManager.update( @task_key, { 'state': data })
@interval( update, 10000, @id, @auto_save_key )
# get data / in case also ticket data for split
@ -296,13 +299,13 @@ class App.TicketCreate extends App.Controller
# notify UI
ui.notify
type: 'success',
msg: App.i18n.translateContent( 'Ticket %s created!', @number ),
msg: App.i18n.translateInline( 'Ticket %s created!', @number ),
link: "#ticket/zoom/#{@id}"
timeout: 12000,
# create new create screen
# ui.render()
App.TaskManager.remove( 'TicketCreateScreen', ui.type + '-' + ui.id )
App.TaskManager.remove( ui.task_key )
# scroll to top
ui.scrollTo()
@ -394,7 +397,7 @@ class TicketCreateRouter extends App.ControllerPermanent
type: params.type
id: params.id
App.TaskManager.add( 'TicketCreateScreen', params['type'] + '-' + params['id'], 'TicketCreate', clean_params )
App.TaskManager.add( 'TicketCreateScreen-' + params['type'] + '-' + params['id'], 'TicketCreate', clean_params )
# split ticket
App.Config.set( 'ticket_create/:ticket_id/:article_id', TicketCreateRouter, 'Routes' )

View file

@ -133,7 +133,7 @@ class App.TicketMerge extends App.ControllerModal
msg: App.i18n.translateContent( 'Ticket %s merged!', data.slave_ticket['number'] ),
timeout: 4000,
App.TaskManager.remove( 'Ticket', data.slave_ticket['id'] )
App.TaskManager.remove( 'Ticket-' + data.slave_ticket['id'] )
else

View file

@ -34,14 +34,11 @@ class App.TicketZoom extends App.Controller
@fetch( @ticket_id, false )
@interval( update, 30000, @key, 'ticket_zoom' )
# start auto save
@autosave()
meta: =>
return if !@ticket
meta =
url: @url()
head: @ticket.title
head: @ticket.title + ' ' + @ticket.title
title: @ticket.number + ' ' + @ticket.title
id: @ticket.id
@ -51,9 +48,9 @@ class App.TicketZoom extends App.Controller
activate: =>
@navupdate '#'
if @ticket
@title 'Ticket Zoom ' + @ticket.number
# else
# @title 'Loading...'
@title App.i18n.translateInline('Ticket Zoom') + ' ' + @ticket.number + ' ' + @ticket.title
else
@title App.i18n.translateInline('Loading...')
changed: =>
formCurrent = @formParam( @el.find('.ticket-update') )
@ -73,7 +70,7 @@ class App.TicketZoom extends App.Controller
if !@autosaveLast || ( diff && !_.isEmpty( diff ) )
@autosaveLast = data
console.log('form hash changed', diff, data)
App.TaskManager.update( 'Ticket', @ticket_id, { 'state': data })
App.TaskManager.update( @task_key, { 'state': data })
@interval( update, 10000, @id, @auto_save_key )
fetch: (ticket_id, force) ->
@ -93,11 +90,11 @@ class App.TicketZoom extends App.Controller
return if _.isEqual( @dataLastCall.ticket, data.ticket)
diff = difference( @dataLastCall.ticket, data.ticket )
console.log('diff', diff)
App.TaskManager.notify( 'Ticket', @ticket_id )
App.TaskManager.notify( @task_key )
if $('[name="body"]').val()
App.Event.trigger 'notify', {
type: 'success'
msg: App.i18n.translateContent('Ticket has changed!')
msg: App.i18n.translateInline('Ticket has changed!')
timeout: 30000
}
return
@ -106,6 +103,9 @@ class App.TicketZoom extends App.Controller
@load(data)
App.Store.write( @key, data )
# start auto save
@autosave()
error: (xhr, status, error) =>
# do not close window if request is abort or network error exists
@ -645,7 +645,7 @@ class TicketZoomRouter extends App.ControllerPermanent
article_id: params.article_id
nav: params.nav
App.TaskManager.add( 'Ticket', @ticket_id, 'TicketZoom', clean_params )
App.TaskManager.add( 'Ticket-' + @ticket_id, 'TicketZoom', clean_params )
App.Config.set( 'ticket/zoom/:ticket_id', TicketZoomRouter, 'Routes' )
App.Config.set( 'ticket/zoom/:ticket_id/nav/:nav', TicketZoomRouter, 'Routes' )

View file

@ -27,7 +27,7 @@ class App.TaskWidget extends App.Controller
id: false
title: App.i18n.translateInline('Loading...')
head: App.i18n.translateInline('Loading...')
worker = App.TaskManager.worker( task.type, task.type_id )
worker = App.TaskManager.worker( task.key )
if worker
meta = worker.meta()
if meta
@ -46,27 +46,26 @@ class App.TaskWidget extends App.Controller
remove: (e) =>
e.preventDefault()
type_id = $(e.target).parent().data('type-id')
type = $(e.target).parent().data('type')
if !type_id && !type
throw "No such type and type-id attributes found for task item"
key = $(e.target).parent().data('key')
if !key
throw "No such key attributes found for task item"
# check if input has changed
worker = App.TaskManager.worker( type, type_id )
worker = App.TaskManager.worker( key )
if worker && worker.changed
if worker.changed()
return if !window.confirm( App.i18n.translateInline('Tab has changed, you really want to close it?') )
# check if active task is closed
currentTask = App.TaskManager.get( type, type_id )
currentTask = App.TaskManager.get( key )
tasks = App.TaskManager.all()
active_is_closed = false
for task in tasks
if currentTask.active && task.type is type && task.type_id.toString() is type_id.toString()
if currentTask.active && task.key is key
active_is_closed = true
# remove task
App.TaskManager.remove( type, type_id )
App.TaskManager.remove( key )
@render()
# navigate to next task if needed
@ -76,7 +75,7 @@ class App.TaskWidget extends App.Controller
for task in tasks
task_last = task
if task_last
worker = App.TaskManager.worker( task_last.type, task_last.type_id )
worker = App.TaskManager.worker( task_last.key )
if worker
@navigate worker.url()
return
@ -108,5 +107,4 @@ class App.TaskWidget extends App.Controller
level1.push item
level1
App.Config.set( 'task', App.TaskWidget, 'Widgets' )

View file

@ -9,40 +9,40 @@ class App.TaskManager
_instance ?= new _Singleton
_instance.all()
@add: ( type, type_id, callback, params, to_not_show, state ) ->
@add: ( key, callback, params, to_not_show, state ) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.add( type, type_id, callback, params, to_not_show, state )
_instance.add( key, callback, params, to_not_show, state )
@get: ( type, type_id ) ->
@get: ( key ) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.get( type, type_id )
_instance.get( key )
@update: ( type, type_id, params ) ->
@update: ( key, params ) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.update( type, type_id, params )
_instance.update( key, params )
@remove: ( type, type_id ) ->
@remove: ( key ) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.remove( type, type_id )
_instance.remove( key )
@notify: ( type, type_id ) ->
@notify: ( key ) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.notify( type, type_id )
_instance.notify( key )
@reset: ->
if _instance == undefined
_instance ?= new _Singleton
_instance.reset()
@worker: ( type, type_id ) ->
@worker: ( key ) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.worker( type, type_id )
_instance.worker( key )
@workerAll: ->
if _instance == undefined
@ -61,29 +61,28 @@ class _Singleton extends App.Controller
all: ->
App.Taskbar.all()
worker: ( type, type_id ) ->
key = @keyGenerate(type, type_id)
worker: ( key ) ->
return @workers[ key ] if @workers[ key ]
return
workerAll: ->
@workers
add: ( type, type_id, callback, params, to_not_show = false, state ) ->
add: ( key, callback, params, to_not_show = false, state ) ->
active = true
if to_not_show
active = false
# create new task if not exists
task = @get( type, type_id )
# console.log('add', type, type_id, callback, params, to_not_show, state, task)
task = @get( key )
# console.log('add', key, callback, params, to_not_show, state, task)
if !task
task = new App.Taskbar
task.load(
type: type
type_id: type_id
key: key
params: params
callback: callback
client_id: 123
notify: false
active: active
)
@ -92,7 +91,6 @@ class _Singleton extends App.Controller
tasks = @all()
# empty static content if task is shown
key = @keyGenerate(type, type_id)
if active
@activeTask = key
$('#content').empty()
@ -116,33 +114,37 @@ class _Singleton extends App.Controller
# set all tasks to active false, only new/selected one to active
if active
for task in tasks
task_key = @keyGenerate(task.type, task.type_id)
if task_key isnt key
if task.key isnt key
if task.active
task.active = false
console.log(111, 'save')
task.save()
else
if !task.active
console.log(222, 'save')
task.active = true
task.save()
else
for task in tasks
task_key = @keyGenerate(task.type, task.type_id)
if @activeTask isnt task_key
if @activeTask isnt task.key
if task.active
task.active = false
console.log(333, 'save')
task.save()
# start worker for task if not exists
@startController(type, type_id, callback, params, state, key, to_not_show)
@startController(key, callback, params, state, to_not_show)
App.Event.trigger 'ui:rerender'
App.Event.trigger 'ui:rerender:content'
return key
startController: (type, type_id, callback, params, state, key, to_not_show) =>
startController: (key, callback, params, state, to_not_show) =>
# console.log('controller started...', callback, type, type_id, params, state)
# console.log('controller started...', callback, key, params, state)
# activate controller
worker = @worker( type, type_id )
worker = @worker( key )
if worker && worker.activate
worker.activate()
@ -157,7 +159,7 @@ class _Singleton extends App.Controller
# check if we have old state there
if !state
oldTask = @get( type, type_id )
oldTask = @get( key )
if oldTask
state = oldTask.state
params_app['form_state'] = state
@ -173,37 +175,37 @@ class _Singleton extends App.Controller
return a
get: ( type, type_id ) =>
get: ( key ) =>
tasks = App.Taskbar.all()
for task in tasks
return task if task.type is type && task.type_id.toString() is type_id.toString()
return task if task.key is key
return
# throw "No such task with '#{type}' and '#{type_id}'"
# throw "No such task with '#{key}'"
update: ( type, type_id, params ) =>
task = @get( type, type_id )
update: ( key, params ) =>
task = @get( key )
if !task
throw "No such task with '#{type}' and '#{type_id}' to update"
throw "No such task with '#{key}' to update"
for item, value of params
task.updateAttribute(item, value)
# task.save()
remove: ( type, type_id, to_not_show = false ) =>
task = @get( type, type_id )
remove: ( key, to_not_show = false ) =>
task = @get( key )
if !task
throw "No such task with '#{type}' and '#{type_id}' to remove"
throw "No such task with '#{key}' to remove"
worker = @worker( type, type_id )
worker = @worker( key )
if worker && worker.release
worker.release()
@workersStarted[ @keyGenerate(type, type_id) ] = false
@workersStarted[ key ] = false
task.destroy()
App.Event.trigger 'ui:rerender'
notify: ( type, type_id ) =>
task = @get( type, type_id )
notify: ( key ) =>
task = @get( key )
if !task
throw "No such task with '#{type}' and '#{type_id}' to notify"
throw "No such task with '#{key}' to notify"
task.notify = true
reset: =>
@ -212,7 +214,7 @@ class _Singleton extends App.Controller
tasksInitial: =>
# reopen tasks
App.Taskbar.fetch()
# App.Taskbar.fetch()
tasks = @all()
return if !tasks
task_count = 0
@ -221,9 +223,7 @@ class _Singleton extends App.Controller
@delay(
=>
task = tasks.shift()
@add(task.type, task.type_id, task.callback, task.params, true, task.state)
@add(task.key, task.callback, task.params, true, task.state)
task_count * 500
)
keyGenerate: ( type, type_id )->
"#{type}_#{type_id}"

View file

@ -1,4 +1,5 @@
class App.Taskbar extends App.Model
@configure 'Taskbar', 'type', 'type_id', 'callback', 'state', 'params', 'notify', 'active'
@extend Spine.Model.Local
# @url: 'api/taskbar'
@configure 'Taskbar', 'key', 'client_id', 'callback', 'state', 'params', 'notify', 'active'
# @extend Spine.Model.Local
@extend Spine.Model.Ajax
@url: 'api/taskbar'

View file

@ -1,6 +1,6 @@
<div class="taskbar">
<div class="well taskbar">
<% for item in @item_list: %>
<a href="<%- item.data.url %>" title="<%= item.data.title %>" class="btn btn-mini <% if item.task.active: %>active btn-success<% else if item.task.notify: %>active btn-warning<% else: %>btn-default<% end %>" data-type="<%- item.task.type %>" data-type-id="<%- item.task.type_id %>"><span class="task"><%- item.data.head %></span><span data-type="close" class="icon-remove-circle" title="<%- @T('close') %>"></a>
<a href="<%- item.data.url %>" title="<%= item.data.title %>" class="btn btn-mini <% if item.task.active: %>active btn-success<% else if item.task.notify: %>active btn-warning<% else: %>btn-default<% end %>" data-key="<%- item.task.key %>"><span class="task"><%- item.data.head %></span><span data-type="close" class="icon-remove-circle" title="<%- @T('close') %>"></a>
<% end %>
<% if !_.isEmpty( @taskBarActions ): %>
<div class="taskbar-new">

View file

@ -2,7 +2,7 @@ module ExtraCollection
def session( collections, user )
# all base stuff
collections['Taskbar'] = Taskbar.all
collections['Taskbar'] = Taskbar.where( :user_id => user.id )
collections['Role'] = Role.all
collections['Group'] = Group.all

View file

@ -0,0 +1,48 @@
class TaskbarController < ApplicationController
before_filter :authentication_check
def index
current_user_tasks = Taskbar.where( :user_id => current_user.id )
model_index_render_result(current_user_tasks)
end
def show
taskbar = Taskbar.find( params[:id] )
return if !access(taskbar)
model_show_render_item(taskbar)
end
def create
params[:user_id] = current_user.id
model_create_render(Taskbar,params)
end
def update
taskbar = Taskbar.find( params[:id] )
return if !access(taskbar)
params[:user_id] = current_user.id
taskbar.update_attributes!( Taskbar.param_cleanup(params) )
model_update_render_item(taskbar)
end
def destroy
taskbar = Taskbar.find( params[:id] )
return if !access(taskbar)
taskbar.destroy
model_destory_render_item()
end
private
def access(taskbar)
if taskbar.user_id != current_user.id
render :json => { :error => 'Not allowed to access this task.' }, :status => :unprocessable_entity
return false
end
return true
end
end

11
app/models/taskbar.rb Normal file
View file

@ -0,0 +1,11 @@
class Taskbar < ApplicationModel
store :state
store :params
before_create :update_last_contact
before_update :update_last_contact
private
def update_last_contact
self.last_contact = Time.now
end
end

10
config/routes/taskbar.rb Normal file
View file

@ -0,0 +1,10 @@
module ExtraRoutes
def add(map)
map.match '/api/taskbar', :to => 'taskbar#index', :via => :get
map.match '/api/taskbar/:id', :to => 'taskbar#show', :via => :get
map.match '/api/taskbar', :to => 'taskbar#create', :via => :post
map.match '/api/taskbar/:id', :to => 'taskbar#update', :via => :put
map.match '/api/taskbar/:id', :to => 'taskbar#destroy', :via => :delete
end
module_function :add
end

View file

@ -3,17 +3,15 @@ class Taskbar < ActiveRecord::Migration
create_table :taskbars do |t|
t.column :user_id, :integer, :null => false
t.column :last_contact, :datetime, :null => false
t.column :client_id, :string, :limit => 100, :null => false
t.column :type, :string, :limit => 100, :null => false
t.column :type_id, :string, :limit => 100, :null => false
t.column :client_id, :string, :null => false
t.column :key, :string, :limit => 100, :null => false
t.column :callback, :string, :limit => 100, :null => false
t.column :state, :string, :limit => 8000, :null => true
t.column :params, :string, :limit => 2000, :null => true
t.column :notify, :boolean, :null => false, :default => false
t.column :active, :boolean, :null => false, :default => false
t.column :state, :string, :limit => 8000,:null => true
t.column :params, :string, :limit => 2000,:null => true
t.timestamps
end
end
def down