Enhancement to issue #2117 - added generic approach with callback methods for submit disable/enable of attachment uploading.

This commit is contained in:
Martin Edenhofer 2018-07-23 07:54:10 +02:00
parent 0fd7dde63e
commit 902b5aca32
9 changed files with 139 additions and 92 deletions

View file

@ -182,11 +182,11 @@ class App.Controller extends Spine.Controller
formParam: (form) -> formParam: (form) ->
App.ControllerForm.params(form) App.ControllerForm.params(form)
formDisable: (form) -> formDisable: (form, type) ->
App.ControllerForm.disable(form) App.ControllerForm.disable(form, type)
formEnable: (form) -> formEnable: (form, type) ->
App.ControllerForm.enable(form) App.ControllerForm.enable(form, type)
formValidate: (data) -> formValidate: (data) ->
App.ControllerForm.validate(data) App.ControllerForm.validate(data)

View file

@ -330,7 +330,7 @@ class App.ControllerForm extends App.Controller
bookmarkable: @bookmarkable bookmarkable: @bookmarkable
) )
) )
fullItem.find('.controls').prepend( item ) fullItem.find('.controls').prepend(item)
# hide/show item # hide/show item
if attribute.hide if attribute.hide
@ -632,48 +632,49 @@ class App.ControllerForm extends App.Controller
App.Log.error 'ControllerForm', 'no form found!', form App.Log.error 'ControllerForm', 'no form found!', form
form form
@disable: (form) -> @disable: (form, type = 'form') ->
lookupForm = @findForm(form) lookupForm = @findForm(form)
if lookupForm if lookupForm && type is 'form'
if lookupForm.is('button, input, select, textarea, div, span') if lookupForm.is('button, input, select, textarea, div, span')
console.log(2)
App.Log.debug 'ControllerForm', 'disable item...', lookupForm App.Log.debug 'ControllerForm', 'disable item...', lookupForm
lookupForm.attr('readonly', true) lookupForm.prop('readonly', true)
lookupForm.attr('disabled', true) lookupForm.prop('disabled', true)
return return
App.Log.debug 'ControllerForm', 'disable form...', lookupForm App.Log.debug 'ControllerForm', 'disable form...', lookupForm
# set forms to read only during communication with backend # set forms to read only during communication with backend
lookupForm.find('button, input, select, textarea').attr('readonly', true) lookupForm.find('button, input, select, textarea').prop('readonly', true)
# disable additionals submits # disable additionals submits
lookupForm.find('button').attr('disabled', true) lookupForm.find('button').prop('disabled', true)
else else
App.Log.debug 'ControllerForm', 'disable item...', form App.Log.debug 'ControllerForm', 'disable item...', form
form.attr('readonly', true) form.prop('readonly', true)
form.attr('disabled', true) form.prop('disabled', true)
@enable: (form) -> @enable: (form, type = 'form') ->
lookupForm = @findForm(form) lookupForm = @findForm(form)
if lookupForm if lookupForm && type is 'form'
if lookupForm.is('button, input, select, textarea, div, span') if lookupForm.is('button, input, select, textarea, div, span')
App.Log.debug 'ControllerForm', 'disable item...', lookupForm App.Log.debug 'ControllerForm', 'disable item...', lookupForm
lookupForm.attr('readonly', false) lookupForm.prop('readonly', false)
lookupForm.attr('disabled', false) lookupForm.prop('disabled', false)
return return
App.Log.debug 'ControllerForm', 'enable form...', lookupForm App.Log.debug 'ControllerForm', 'enable form...', lookupForm
# enable fields again # enable fields again
lookupForm.find('button, input, select, textarea').attr('readonly', false) lookupForm.find('button, input, select, textarea').prop('readonly', false)
# enable submits again # enable submits again
lookupForm.find('button').attr('disabled', false) lookupForm.find('button').prop('disabled', false)
else else
App.Log.debug 'ControllerForm', 'enable item...', form App.Log.debug 'ControllerForm', 'enable item...', form
form.attr('readonly', false) form.prop('readonly', false)
form.attr('disabled', false) form.prop('disabled', false)
@validate: (data) -> @validate: (data) ->

View file

@ -73,19 +73,14 @@ class App.UiElement.richtext
@attachmentPlaceholder.addClass('hide') @attachmentPlaceholder.addClass('hide')
@attachmentUpload.removeClass('hide') @attachmentUpload.removeClass('hide')
@cancelContainer.removeClass('hide') @cancelContainer.removeClass('hide')
# Disable the create ticket button during uploading item.find('[contenteditable]').trigger('fileUploadStart')
$('.main .newTicket .page-content .js-submit')
.text(App.i18n.translateInline('Uploading'))
.addClass('is-disabled')
App.Log.debug 'UiElement.richtext', 'upload start' App.Log.debug 'UiElement.richtext', 'upload start'
onAborted: => onAborted: =>
@attachmentPlaceholder.removeClass('hide') @attachmentPlaceholder.removeClass('hide')
@attachmentUpload.addClass('hide') @attachmentUpload.addClass('hide')
item.find('input').val('') item.find('input').val('')
$('.main .newTicket .page-content .js-submit') item.find('[contenteditable]').trigger('fileUploadStop', ['aborted'])
.text(App.i18n.translateInline('Create'))
.removeClass('is-disabled')
# Called after received response from the server # Called after received response from the server
onCompleted: (response) => onCompleted: (response) =>
@ -100,10 +95,7 @@ class App.UiElement.richtext
renderFile(response.data) renderFile(response.data)
item.find('input').val('') item.find('input').val('')
$('.main .newTicket .page-content .js-submit') item.find('[contenteditable]').trigger('fileUploadStop', ['completed'])
.text(App.i18n.translateInline('Create'))
.removeClass('is-disabled')
App.Log.debug 'UiElement.richtext', 'upload complete', response.data App.Log.debug 'UiElement.richtext', 'upload complete', response.data
# Called during upload progress, first parameter # Called during upload progress, first parameter

View file

@ -310,6 +310,9 @@ class App.TicketCreate extends App.Controller
form_id: @formId form_id: @formId
model: App.TicketArticle model: App.TicketArticle
screen: 'create_top' screen: 'create_top'
events:
'fileUploadStart .richtext': => @submitDisable()
'fileUploadStop .richtext': => @submitEnable()
params: params params: params
taskKey: @taskKey taskKey: @taskKey
) )
@ -506,7 +509,7 @@ class App.TicketCreate extends App.Controller
return return
# disable form # disable form
@formDisable(e) @submitDisable(e)
ui = @ ui = @
ticket.save( ticket.save(
done: -> done: ->
@ -538,7 +541,7 @@ class App.TicketCreate extends App.Controller
fail: (settings, details) -> fail: (settings, details) ->
ui.log 'errors', details ui.log 'errors', details
ui.formEnable(e) ui.submitEnable(e)
ui.notify( ui.notify(
type: 'error' type: 'error'
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to create object!') msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to create object!')
@ -546,6 +549,18 @@ class App.TicketCreate extends App.Controller
) )
) )
submitDisable: (e) =>
if e
@formDisable(e)
return
@formDisable(@$('.js-submit'), 'button')
submitEnable: (e) =>
if e
@formEnable(e)
return
@formEnable(@$('.js-submit'), 'button')
class Router extends App.ControllerPermanent class Router extends App.ControllerPermanent
requiredPermission: 'ticket.agent' requiredPermission: 'ticket.agent'
constructor: (params) -> constructor: (params) ->

View file

@ -60,6 +60,9 @@ class Index extends App.ControllerContent
form_id: @form_id form_id: @form_id
model: App.TicketArticle model: App.TicketArticle
screen: 'create_top' screen: 'create_top'
events:
'fileUploadStart .richtext': => @submitDisable()
'fileUploadStop .richtext': => @submitEnable()
filter: @formMeta.filter filter: @formMeta.filter
formMeta: @formMeta formMeta: @formMeta
params: defaults params: defaults
@ -177,7 +180,7 @@ class Index extends App.ControllerContent
else else
# disable form # disable form
@formDisable(e) @submitDisable(e)
ui = @ ui = @
ticket.save( ticket.save(
done: -> done: ->
@ -187,7 +190,7 @@ class Index extends App.ControllerContent
fail: (settings, details) -> fail: (settings, details) ->
ui.log 'errors', details ui.log 'errors', details
ui.formEnable(e) ui.submitEnable(e)
ui.notify( ui.notify(
type: 'error' type: 'error'
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to create object!') msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to create object!')
@ -195,5 +198,17 @@ class Index extends App.ControllerContent
) )
) )
submitDisable: (e) =>
if e
@formDisable(e)
return
@formDisable(@$('.js-submit'), 'button')
submitEnable: (e) =>
if e
@formEnable(e)
return
@formEnable(@$('.js-submit'), 'button')
App.Config.set('customer_ticket_new', Index, 'Routes') App.Config.set('customer_ticket_new', Index, 'Routes')
App.Config.set('CustomerTicketNew', { prio: 8003, parent: '#new', name: 'New Ticket', translate: true, target: '#customer_ticket_new', permission: ['ticket.customer'], setting: ['customer_ticket_create'], divider: true }, 'NavBarRight') App.Config.set('CustomerTicketNew', { prio: 8003, parent: '#new', name: 'New Ticket', translate: true, target: '#customer_ticket_new', permission: ['ticket.customer'], setting: ['customer_ticket_create'], divider: true }, 'NavBarRight')

View file

@ -445,14 +445,16 @@ class App.TicketZoom extends App.Controller
@form_id = @taskGet('article').form_id || App.ControllerForm.formId() @form_id = @taskGet('article').form_id || App.ControllerForm.formId()
@articleNew = new App.TicketZoomArticleNew( @articleNew = new App.TicketZoomArticleNew(
ticket: @ticket ticket: @ticket
ticket_id: @ticket_id ticket_id: @ticket_id
el: elLocal.find('.article-new') el: elLocal.find('.article-new')
formMeta: @formMeta formMeta: @formMeta
form_id: @form_id form_id: @form_id
defaults: @taskGet('article') defaults: @taskGet('article')
taskKey: @taskKey taskKey: @taskKey
ui: @ ui: @
callbackFileUploadStart: @submitDisable
callbackFileUploadStop: @submitEnable
) )
@highligher = new App.TicketZoomHighlighter( @highligher = new App.TicketZoomHighlighter(
@ -738,16 +740,28 @@ class App.TicketZoom extends App.Controller
resetButton.removeClass('hide') resetButton.removeClass('hide')
submitDisable: (e) =>
if e
@formDisable(e)
return
@formDisable(@$('.js-submitDropdown'))
submitEnable: (e) =>
if e
@formEnable(e)
return
@formEnable(@$('.js-submitDropdown'))
submit: (e, macro = {}) => submit: (e, macro = {}) =>
e.stopPropagation() e.stopPropagation()
e.preventDefault() e.preventDefault()
# disable form # disable form
@formDisable(e) @submitDisable(e)
# validate new article # validate new article
if !@articleNew.validate() if !@articleNew.validate()
@formEnable(e) @submitEnable(e)
return return
ticketParams = @formParam(@$('.edit')) ticketParams = @formParam(@$('.edit'))
@ -803,7 +817,7 @@ class App.TicketZoom extends App.Controller
errors: errors errors: errors
screen: 'edit' screen: 'edit'
) )
@formEnable(e) @submitEnable(e)
@autosaveStart() @autosaveStart()
return return
@ -819,7 +833,7 @@ class App.TicketZoom extends App.Controller
errors: errors errors: errors
screen: 'edit' screen: 'edit'
) )
@formEnable(e) @submitEnable(e)
@autosaveStart() @autosaveStart()
return return
@ -849,7 +863,7 @@ class App.TicketZoom extends App.Controller
container: @el.closest('.content') container: @el.closest('.content')
ticket: ticket ticket: ticket
cancelCallback: => cancelCallback: =>
@formEnable(e) @submitEnable(e)
submitCallback: (params) => submitCallback: (params) =>
if params.time_unit if params.time_unit
ticket.article.time_unit = params.time_unit ticket.article.time_unit = params.time_unit
@ -895,7 +909,7 @@ class App.TicketZoom extends App.Controller
@autosaveStart() @autosaveStart()
@muteTask() @muteTask()
@formEnable(e) @submitEnable(e)
error: (settings, details) => error: (settings, details) =>
error = undefined error = undefined
@ -909,7 +923,7 @@ class App.TicketZoom extends App.Controller
@autosaveStart() @autosaveStart()
@muteTask() @muteTask()
@fetch() @fetch()
@formEnable(e) @submitEnable(e)
) )
bookmark: (e) -> bookmark: (e) ->

View file

@ -179,7 +179,7 @@ class App.TicketZoomArticleNew extends App.Controller
key: 'File' key: 'File'
data: data:
form_id: @form_id form_id: @form_id
maxSimultaneousUploads: 1, maxSimultaneousUploads: 1
onFileAdded: (file) => onFileAdded: (file) =>
file.on( file.on(
@ -188,18 +188,17 @@ class App.TicketZoomArticleNew extends App.Controller
@attachmentPlaceholder.addClass('hide') @attachmentPlaceholder.addClass('hide')
@attachmentUpload.removeClass('hide') @attachmentUpload.removeClass('hide')
@cancelContainer.removeClass('hide') @cancelContainer.removeClass('hide')
# Disable the update ticket button during uploading
$('.active .attributeBar .js-submit') if @callbackFileUploadStart
.text(App.i18n.translateInline('Uploading')) @callbackFileUploadStart()
.addClass('is-disabled')
onAborted: => onAborted: =>
@attachmentPlaceholder.removeClass('hide') @attachmentPlaceholder.removeClass('hide')
@attachmentUpload.addClass('hide') @attachmentUpload.addClass('hide')
@$('.article-attachment input').val('') @$('.article-attachment input').val('')
$('.active .attributeBar .js-submit')
.text(App.i18n.translateInline('Update')) if @callbackFileUploadStop
.removeClass('is-disabled') @callbackFileUploadStop()
# Called after received response from the server # Called after received response from the server
onCompleted: (response) => onCompleted: (response) =>
@ -216,9 +215,9 @@ class App.TicketZoomArticleNew extends App.Controller
@renderAttachment(response.data) @renderAttachment(response.data)
@$('.article-attachment input').val('') @$('.article-attachment input').val('')
$('.active .attributeBar .js-submit')
.text(App.i18n.translateInline('Update')) if @callbackFileUploadStop
.removeClass('is-disabled') @callbackFileUploadStop()
# Called during upload progress, first parameter # Called during upload progress, first parameter
# is decimal value from 0 to 100. # is decimal value from 0 to 100.

View file

@ -14,26 +14,46 @@ test( "find form check", function() {
var form3 = App.ControllerForm.findForm($('#form3 .js-button')) var form3 = App.ControllerForm.findForm($('#form3 .js-button'))
equal(form3.is('form'), true) equal(form3.is('form'), true)
App.ControllerForm.disable($('#form3 .js-button')) App.ControllerForm.disable($('#form3 .js-button'))
equal($('#form3 .js-button').attr('readonly'), 'readonly') equal($('#form3 .js-button').prop('readonly'), true)
equal($('#form3 .js-button').attr('disabled'), 'disabled') equal($('#form3 .js-button').prop('disabled'), true)
equal($('#form3 .js-input').attr('readonly'), 'readonly') equal($('#form3 .js-input').prop('readonly'), true)
equal($('#form3 .js-input').attr('disabled'), undefined) equal($('#form3 .js-input').prop('disabled'), false)
App.ControllerForm.enable($('#form3 .js-button')) App.ControllerForm.enable($('#form3 .js-button'))
equal($('#form3 .js-button').attr('readonly'), undefined) equal($('#form3 .js-button').prop('readonly'), false)
equal($('#form3 .js-button').attr('disabled'), undefined) equal($('#form3 .js-button').prop('disabled'), false)
equal($('#form3 .js-input').attr('readonly'), undefined) equal($('#form3 .js-input').prop('readonly'), false)
equal($('#form3 .js-input').attr('disabled'), undefined) equal($('#form3 .js-input').prop('disabled'), false)
$('#forms').append('<hr><h1>find form check by only disable button</h1><form id="form31"><input class="js-input" value="test 123"><button class="js-button">text</button></form>')
var form31 = App.ControllerForm.findForm($('#form31 .js-button'))
App.ControllerForm.disable($('#form31 .js-button'), 'button')
equal($('#form31 .js-button').prop('readonly'), true)
equal($('#form31 .js-button').prop('disabled'), true)
equal($('#form31 .js-input').prop('readonly'), false)
equal($('#form31 .js-input').prop('disabled'), false)
App.ControllerForm.enable($('#form31 .js-button'))
equal($('#form31 .js-button').prop('readonly'), false)
equal($('#form31 .js-button').prop('disabled'), false)
equal($('#form31 .js-input').prop('readonly'), false)
equal($('#form31 .js-input').prop('disabled'), false)
$('#forms').append('<hr><h1>find form check</h1><div id="form4"><input class="js-input" value="test 123"><button class="js-button">text</button></div>') $('#forms').append('<hr><h1>find form check</h1><div id="form4"><input class="js-input" value="test 123"><button class="js-button">text</button></div>')
var form4 = App.ControllerForm.findForm($('#form4 .js-button')) var form4 = App.ControllerForm.findForm($('#form4 .js-button'))
equal(form4.is('form'), false) equal(form4.is('form'), false)
App.ControllerForm.disable($('#form4 .js-button')) App.ControllerForm.disable($('#form4 .js-button'))
equal($('#form4 .js-button').attr('readonly'), 'readonly') equal($('#form4 .js-button').prop('readonly'), true)
equal($('#form4 .js-button').attr('disabled'), 'disabled') equal($('#form4 .js-button').prop('disabled'), true)
equal($('#form4 .js-input').prop('readonly'), false)
equal($('#form4 .js-input').prop('disabled'), false)
App.ControllerForm.enable($('#form4 .js-button')) App.ControllerForm.enable($('#form4 .js-button'))
equal($('#form4 .js-input').attr('readonly'), undefined) equal($('#form4 .js-button').prop('readonly'), false)
equal($('#form4 .js-input').attr('disabled'), undefined) equal($('#form4 .js-button').prop('disabled'), false)
equal($('#form4 .js-input').prop('readonly'), false)
equal($('#form4 .js-input').prop('disabled'), false)
}); });

View file

@ -332,20 +332,17 @@ class AgentTicketAttachmentTest < TestCase
files: [Rails.root.join('test', 'data', 'upload', 'upload2.jpg')], files: [Rails.root.join('test', 'data', 'upload', 'upload2.jpg')],
no_sleep: true, no_sleep: true,
) )
match( exists(
css: '.js-submit.is-disabled', css: '.content.active .js-submit:disabled',
value: 'Uploading',
) )
watch_for_disappear( watch_for_disappear(
css: '.js-submit.is-disabled', css: '.content.active .js-submit:disabled',
value: 'Uploading',
) )
match( exists(
css: '.js-submit', css: '.content.active .js-submit',
value: 'Create',
) )
click( click(
css: '.active .js-submit', css: '.content.active .js-submit',
) )
sleep 2 sleep 2
@ -361,17 +358,11 @@ class AgentTicketAttachmentTest < TestCase
files: [Rails.root.join('test', 'data', 'upload', 'upload2.jpg')], files: [Rails.root.join('test', 'data', 'upload', 'upload2.jpg')],
no_sleep: true, no_sleep: true,
) )
match( exists(
css: '.js-submit.is-disabled', css: '.content.active .js-submit:disabled',
value: 'Uploading',
) )
watch_for_disappear( watch_for_disappear(
css: '.js-submit.is-disabled', css: '.content.active .js-submit:disabled',
value: 'Uploading',
)
match(
css: '.js-submit',
value: 'Update',
) )
end end
end end