diff --git a/app/assets/javascripts/app/controllers/_channel/email.js.coffee b/app/assets/javascripts/app/controllers/_channel/email.js.coffee index 64245b96b..173e6ed49 100644 --- a/app/assets/javascripts/app/controllers/_channel/email.js.coffee +++ b/app/assets/javascripts/app/controllers/_channel/email.js.coffee @@ -7,19 +7,9 @@ class App.ChannelEmail extends App.ControllerTabs @tabs = [ { - name: 'Inbound', - target: 'c-inbound', - controller: App.ChannelEmailInbound, - }, - { - name: 'Outbound', - target: 'c-outbound', - controller: App.ChannelEmailOutbound, - }, - { - name: 'Adresses', - target: 'c-address', - controller: App.ChannelEmailAddress, + name: 'Email Accounts', + target: 'c-channel', + controller: App.ChannelEmailAccountOverview, }, { name: 'Signatures', @@ -132,100 +122,6 @@ class App.ChannelEmailFilterEdit extends App.ControllerModal @hide() ) - -class App.ChannelEmailAddress extends App.Controller - events: - 'click [data-type=new]': 'new' - - constructor: -> - super - - App.EmailAddress.subscribe( @render, initFetch: true ) - - render: => - data = App.EmailAddress.search( sortBy: 'realname' ) - - template = $( '
' ) - - new App.ControllerTable( - el: template.find('.overview') - model: App.EmailAddress - objects: data - bindRow: - events: - 'click': @edit - ) - - @html template - - new: (e) => - e.preventDefault() - new App.ChannelEmailAddressEdit( - container: @el.closest('.content') - ) - - edit: (id, e) => - e.preventDefault() - item = App.EmailAddress.find(id) - new App.ChannelEmailAddressEdit( - object: item - container: @el.closest('.content') - ) - -class App.ChannelEmailAddressEdit extends App.ControllerModal - constructor: -> - super - - @head = 'Email-Address' - @button = true - @close = true - @cancel = true - - if @object - @form = new App.ControllerForm( - model: App.EmailAddress - params: @object - autofocus: true - ) - else - @form = new App.ControllerForm( - model: App.EmailAddress, - autofocus: true, - ) - - @content = @form.form - - @show() - - onSubmit: (e) => - e.preventDefault() - - # get params - params = @formParam(e.target) - - object = @object || new App.EmailAddress - object.load(params) - - # validate form - errors = @form.validate( params ) - - # show errors in form - if errors - @log 'error', errors - @formValidate( form: e.target, errors: errors ) - return false - - # disable form - @formDisable(e) - - # save object - object.save( - done: => - @hide() - fail: => - @hide() - ) - class App.ChannelEmailSignature extends App.Controller events: 'click [data-type=new]': 'new' @@ -317,193 +213,575 @@ class App.ChannelEmailSignatureEdit extends App.ControllerModal @hide() ) -class App.ChannelEmailInbound extends App.Controller +class App.ChannelEmailAccountOverview extends App.Controller events: - 'click [data-type=new]': 'new' + 'click [data-type="new"]': 'wizard' + 'click [data-type="delete"]': 'delete' + 'click [data-type="edit-inbound"]': 'edit_inbound' + 'click [data-type="edit-outbound"]': 'edit_outbound' + 'click [data-type="email-address-new"]': 'email_address_new' + 'click [data-type="email-address-edit"]': 'email_address_edit' + 'click [data-type="edit-notification-outbound"]': 'edit_notification_outbound' constructor: -> super - App.Channel.subscribe( @render, initFetch: true ) + @interval(@load, 20000) - render: => - channels = App.Channel.search( filter: { area: 'Email::Inbound' } ) + load: => + @ajax( + id: 'email_index' + type: 'GET' + url: @apiPath + '/channels/email_index' + processData: true + success: (data, status, xhr) => - template = $( '' ) + # load assets + App.Collection.loadAssets( data.assets ) - new App.ControllerTable( - el: template.find('.overview') - model: App.Channel - objects: channels - bindRow: - events: - 'click': @edit + @render() ) - @html template - - new: (e) => - e.preventDefault() - new App.ChannelEmailInboundEdit( - container: @el.closest('.content') - ) - - edit: (id, e) => - e.preventDefault() - item = App.Channel.find(id) - new App.ChannelEmailInboundEdit( - object: item - container: @el.closest('.content') - ) - - -class App.ChannelEmailInboundEdit extends App.ControllerModal - constructor: -> - super - - @head = 'Email Channel' - @button = true - @close = true - @cancel = true - - if @object - @form = new App.ControllerForm( - model: App.Channel - params: @object - autofocus: true - ) - else - @form = new App.ControllerForm( - model: App.Channel - autofocus: true - ) - - @content = @form.form - - @show() - - onSubmit: (e) => - e.preventDefault() - - # get params - params = @formParam(e.target) - params['area'] = 'Email::Inbound' - - object = @object || new App.Channel - object.load(params) - - # validate form - errors = @form.validate( params ) - - # show errors in form - if errors - @log 'error', errors - @formValidate( form: e.target, errors: errors ) - return false - - # disable form - @formDisable(e) - - # save object - object.save( - done: => - @hide() - fail: => - @hide() - ) - -class App.ChannelEmailOutbound extends App.Controller - events: - 'change [name="adapter"]': 'toggle' - 'submit #mail_adapter': 'update' - - constructor: -> - super - - App.Channel.subscribe( @render, initFetch: true ) render: => - @html App.view('channel/email_outbound')() - - # get current Email::Outbound channel - channels = App.Channel.all() - adapters = {} - adapter_used = undefined - channel_used = undefined + # get channels + channels = App.Channel.search( filter: { area: 'Email::Account' } ) for channel in channels - if channel.area is 'Email::Outbound' + email_addresses = App.EmailAddress.search( filter: { channel_id: channel.id } ) + channel.email_addresses = email_addresses - adapters[channel.adapter] = channel.adapter - if @adapter_used - if @adapter_used is channel.adapter - adapter_used = channel.adapter - channel_used = channel - else if channel.active is true - adapter_used = channel.adapter - channel_used = channel + # get all unlinked email addresses + email_addresses_all = App.EmailAddress.all() + email_addresses_not_used = [] + for email_address in email_addresses_all + if !email_address.channel_id || !App.Channel.exists(email_address.channel_id) + email_addresses_not_used.push email_address - configure_attributes = [ - { name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters , default: adapter_used }, + # get channels + channel = App.Channel.search( filter: { area: 'Email::Notification', active: true } )[0] + + @html App.view('channel/email_account_overview')( + channels: channels + email_addresses_not_used: email_addresses_not_used + channel: channel + ) + + wizard: (e) => + e.preventDefault() + new App.ChannelEmailAccountWizard( + container: @el.closest('.content') + callback: @load + ) + + edit_inbound: (e) => + e.preventDefault() + id = $(e.target).closest('tr').data('id') + channel = App.Channel.find(id) + slide = 'js-inbound' + new App.ChannelEmailAccountWizard( + container: @el.closest('.content') + slide: slide + channel: channel + callback: @load + ) + + edit_outbound: (e) => + e.preventDefault() + id = $(e.target).closest('tr').data('id') + channel = App.Channel.find(id) + slide = 'js-outbound' + new App.ChannelEmailAccountWizard( + container: @el.closest('.content') + slide: slide + channel: channel + callback: @load + ) + + delete: (e) => + e.preventDefault() + id = $(e.target).closest('tr').data('id') + item = App.Channel.find(id) + new App.ControllerGenericDestroyConfirm( + item: item + container: @el.closest('.content') + callback: @load + ) + + email_address_new: (e) => + e.preventDefault() + channel_id = $(e.target).closest('tr').data('id') + new App.ControllerGenericNew( + pageData: + object: 'Email Address' + genericObject: 'EmailAddress' + container: @el.closest('.content') + item: + channel_id: channel_id + callback: @load + ) + + email_address_edit: (e) => + e.preventDefault() + id = $(e.target).closest('li').data('id') + new App.ControllerGenericEdit( + pageData: + object: 'Email Address' + genericObject: 'EmailAddress' + container: @el.closest('.content') + id: id + callback: @load + ) + + edit_notification_outbound: (e) => + e.preventDefault() + id = $(e.target).closest('tr').data('id') + channel = App.Channel.find(id) + slide = 'js-outbound' + new App.ChannelEmailNotificationWizard( + container: @el.closest('.content') + channel: channel + callback: @load + ) + +class App.ChannelEmailAccountWizard extends App.Controller + elements: + '.modal-body': 'body' + + className: 'modal fade' + + events: + 'submit .js-intro': 'probeBasedOnIntro' + 'submit .js-inbound': 'probeInbound' + 'change .js-outbound [name=adapter]': 'toggleOutboundAdapter' + 'submit .js-outbound': 'probleOutbound' + 'click .js-back': 'goToSlide' + + constructor: -> + super + + # store account settings + @account = + inbound: + adapter: undefined + options: undefined + outbound: + adapter: undefined + options: undefined + meta: {} + + if @channel + @account = + inbound: @channel.options.inbound + outbound: @channel.options.outbound + meta: {} + + if @container + @el.addClass('modal--local') + + @render() + + @el.modal + keyboard: true + show: true + backdrop: true + container: @container + .on + 'show.bs.modal': @onShow + 'shown.bs.modal': @onComplete + 'hidden.bs.modal': => + if @callback + @callback() + $('.modal').remove() + + if @slide + @showSlide(@slide) + + render: => + @html App.view('channel/email_account_wizard')() + @showSlide('js-intro') + + # outbound + adapters = + sendmail: 'Local MTA (Sendmail/Postfix/Exim/...) - use server setup' + smtp: 'SMTP - configure your own outgoing SMTP settings' + configureAttributesOutbound = [ + { name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters }, ] new App.ControllerForm( - el: @el.find('#form-email-adapter'), - model: { configure_attributes: configure_attributes, className: '' }, - autofocus: true, + el: @$('.base-outbound-type') + model: + configure_attributes: configureAttributesOutbound + className: '' + params: + adapter: @account.outbound.adapter || 'sendmail' + ) + @toggleOutboundAdapter() + + # inbound + configureAttributesInbound = [ + { name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { imap: 'IMAP', pop3: 'POP3' } }, + { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false }, + { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false }, + { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, single: true }, + ] + new App.ControllerForm( + el: @$('.base-inbound-settings'), + model: + configure_attributes: configureAttributesInbound + className: '' + params: @account.inbound ) -# if adapter_used is 'Sendmail' -# # some form + toggleOutboundAdapter: => - if adapter_used is 'SMTP' - configure_attributes = [ - { name: 'host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, default: (channel_used['options']&&channel_used['options']['host']) }, - { name: 'user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, default: (channel_used['options']&&channel_used['options']['user']) }, - { name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, default: (channel_used['options']&&channel_used['options']['password']) }, - { name: 'ssl', display: 'SSL', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' } , translate: true, default: (channel_used['options']&&channel_used['options']['ssl']) }, - { name: 'port', display: 'Port', tag: 'input', type: 'text', limit: 5, null: false, class: 'span1', autocapitalize: false, default: ((channel_used['options']&&channel_used['options']['port']) || 25) }, + # fill user / password based on intro info + channel_used = { options: {} } + if @account['meta'] + channel_used['options']['user'] = @account['meta']['email'] + channel_used['options']['password'] = @account['meta']['password'] + + # show used backend + @el.find('.base-outbound-settings').html('') + adapter = @$('.js-outbound [name=adapter]').val() + if adapter is 'smtp' + configureAttributesOutbound = [ + { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true }, + { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, + { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, single: true }, ] @form = new App.ControllerForm( - el: @el.find('#form-email-adapter-settings'), - model: { configure_attributes: configure_attributes, className: '' }, - autofocus: true, + el: @$('.base-outbound-settings') + model: + configure_attributes: configureAttributesOutbound + className: '' + params: @account.outbound ) - toggle: (e) => + probeBasedOnIntro: (e) => + e.preventDefault() + params = @formParam(e.target) + + # remember account settings + @account.meta = params + + # let backend know about the channel + if @channel + params.channel_id = @channel.id + + @disable(e) + @$('.js-probe .js-email').text( params.email ) + @showSlide('js-probe') + + @ajax( + id: 'email_probe' + type: 'POST' + url: @apiPath + '/channels/email_probe' + data: JSON.stringify( params ) + processData: true + success: (data, status, xhr) => + if data.result is 'ok' + if data.setting + for key, value of data.setting + @account[key] = value + @verify(@account) + else if data.result is 'duplicate' + @showSlide('js-intro') + @showAlert('js-intro', 'Account already exists!' ) + else + @showSlide('js-inbound') + @showAlert('js-inbound', 'Unable to detect your server settings. Manual configuration needed.' ) + @$('.js-inbound [name="options::user"]').val( @account['meta']['email'] ) + @$('.js-inbound [name="options::password"]').val( @account['meta']['password'] ) + + @enable(e) + fail: => + @enable(e) + @showSlide('js-intro') + ) + + probeInbound: (e) => + e.preventDefault() # get params params = @formParam(e.target) - # render page with new selected adapter - if @adapter_used isnt params['adapter'] + # let backend know about the channel + params.channel_id = @channel.id - # set selected adapter - @adapter_used = params['adapter'] + @disable(e) - @render() + @showSlide('js-test') - update: (e) => + @ajax( + id: 'email_inbound' + type: 'POST' + url: @apiPath + '/channels/email_inbound' + data: JSON.stringify( params ) + processData: true + success: (data, status, xhr) => + if data.result is 'ok' + + # remember account settings + @account.inbound = params + + @showSlide('js-outbound') + if !@channel + @$('.js-outbound [name="options::user"]').val( @account['meta']['email'] ) + @$('.js-outbound [name="options::password"]').val( @account['meta']['password'] ) + + else + @showSlide('js-inbound') + @showAlert('js-inbound', data.message_human || data.message ) + @enable(e) + fail: => + @showSlide('js-inbound') + @showAlert('js-inbound', data.message_human || data.message ) + @enable(e) + ) + + probleOutbound: (e) => e.preventDefault() - params = @formParam(e.target) -# errors = @form.validate( params ) + # get params + params = @formParam(e.target) + params['email'] = @account['meta']['email'] - # update Email::Outbound adapter - channels = App.Channel.all() - for channel in channels - if channel.area is 'Email::Outbound' && channel.adapter is params['adapter'] - channel.updateAttributes( - options: { - host: params['host'], - user: params['user'], - password: params['password'], - ssl: params['ssl'], - port: params['port'], - }, - active: true, - ) + if !params['email'] && @channel + email_addresses = App.EmailAddress.search( filter: { channel_id: @channel.id } ) + if email_addresses && email_addresses[0] + params['email'] = email_addresses[0].email - # set all other Email::Outbound adapters to inactive - channels = App.Channel.all() - for channel in channels - if channel.area is 'Email::Outbound' && channel.adapter isnt params['adapter'] - channel.updateAttributes( active: false ) + # let backend know about the channel + params.channel_id = @channel.id + @disable(e) + + @showSlide('js-test') + + @ajax( + id: 'email_outbound' + type: 'POST' + url: @apiPath + '/channels/email_outbound' + data: JSON.stringify( params ) + processData: true + success: (data, status, xhr) => + if data.result is 'ok' + + # remember account settings + @account.outbound = params + + @verify(@account) + else + @showSlide('js-outbound') + @showAlert('js-outbound', data.message_human || data.message ) + @enable(e) + fail: => + @showSlide('js-outbound') + @showAlert('js-outbound', data.message_human || data.message ) + @enable(e) + ) + + verify: (account, count = 0) => + @showSlide('js-verify') + + # let backend know about the channel + if @channel + account.channel_id = @channel.id + + if !account.email && @channel + email_addresses = App.EmailAddress.search( filter: { channel_id: @channel.id } ) + if email_addresses && email_addresses[0] + account.email = email_addresses[0].email + + @ajax( + id: 'email_verify' + type: 'POST' + url: @apiPath + '/channels/email_verify' + data: JSON.stringify( account ) + processData: true + success: (data, status, xhr) => + if data.result is 'ok' + @el.remove() + else + if count is 2 + @showAlert('js-verify', data.message_human || data.message ) + @delay( + => + @showSlide('js-intro') + @showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.' ) + + 2300 + ) + else + if data.subject && @account + @account.subject = data.subject + @verify( @account, count + 1 ) + fail: => + @showSlide('js-intro') + @showAlert('js-intro', 'Unable to verify sending and receiving. Please check your settings.' ) + ) + + goToSlide: (e) => + e.preventDefault() + slide = $(e.target).data('slide') + @showSlide(slide) + + showSlide: (name) => + @hideAlert(name) + @$('.setup.wizard').addClass('hide') + @$(".setup.wizard.#{name}").removeClass('hide') + @$(".setup.wizard.#{name} input, .setup.wizard.#{name} select").first().focus() + + showAlert: (screen, message) => + @$(".#{screen}").find('.alert').removeClass('hide').text( App.i18n.translateInline( message ) ) + + hideAlert: (screen) => + @$(".#{screen}").find('.alert').addClass('hide') + + disable: (e) => + @formDisable(e) + @$('.wizard-controls .btn').attr('disabled', true) + + enable: (e) => + @formEnable(e) + @$('.wizard-controls .btn').attr('disabled', false) + +class App.ChannelEmailNotificationWizard extends App.Controller + elements: + '.modal-body': 'body' + + className: 'modal fade' + + events: + 'change .js-outbound [name=adapter]': 'toggleOutboundAdapter' + 'submit .js-outbound': 'probleOutbound' + + constructor: -> + super + + # store account settings + @account = + inbound: + adapter: undefined + options: undefined + outbound: + adapter: undefined + options: undefined + meta: {} + + if @channel + @account = + inbound: @channel.options.inbound + outbound: @channel.options.outbound + + if @container + @el.addClass('modal--local') + + @render() + + @el.modal + keyboard: true + show: true + backdrop: true + container: @container + .on + 'show.bs.modal': @onShow + 'shown.bs.modal': @onComplete + 'hidden.bs.modal': => + if @callback + @callback() + $('.modal').remove() + + if @slide + @showSlide(@slide) + + render: => + @html App.view('channel/email_notification_wizard')() + @showSlide('js-outbound') + + # outbound + adapters = + sendmail: 'Local MTA (Sendmail/Postfix/Exim/...) - use server setup' + smtp: 'SMTP - configure your own outgoing SMTP settings' + configureAttributesOutbound = [ + { name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters }, + ] + new App.ControllerForm( + el: @$('.base-outbound-type') + model: + configure_attributes: configureAttributesOutbound + className: '' + params: + adapter: @account.outbound.adapter || 'sendmail' + ) + @toggleOutboundAdapter() + + toggleOutboundAdapter: => + + # show used backend + @el.find('.base-outbound-settings').html('') + adapter = @$('.js-outbound [name=adapter]').val() + if adapter is 'smtp' + configureAttributesOutbound = [ + { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true }, + { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, + { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, single: true }, + ] + @form = new App.ControllerForm( + el: @$('.base-outbound-settings') + model: + configure_attributes: configureAttributesOutbound + className: '' + params: @account.outbound + ) + + probleOutbound: (e) => + e.preventDefault() + + # get params + params = @formParam(e.target) + + # let backend know about the channel + params.channel_id = @channel.id + + @disable(e) + + @showSlide('js-test') + + @ajax( + id: 'email_outbound' + type: 'POST' + url: @apiPath + '/channels/email_notification' + data: JSON.stringify( params ) + processData: true + success: (data, status, xhr) => + if data.result is 'ok' + @el.remove() + else + @showSlide('js-outbound') + @showAlert('js-outbound', data.message_human || data.message ) + @enable(e) + fail: => + @showSlide('js-outbound') + @showAlert('js-outbound', data.message_human || data.message ) + @enable(e) + ) + + showSlide: (name) => + @hideAlert(name) + @$('.setup.wizard').addClass('hide') + @$(".setup.wizard.#{name}").removeClass('hide') + @$(".setup.wizard.#{name} input, .setup.wizard.#{name} select").first().focus() + + showAlert: (screen, message) => + @$(".#{screen}").find('.alert').removeClass('hide').text( App.i18n.translateInline( message ) ) + + hideAlert: (screen) => + @$(".#{screen}").find('.alert').addClass('hide') + + disable: (e) => + @formDisable(e) + @$('.wizard-controls .btn').attr('disabled', true) + + enable: (e) => + @formEnable(e) + @$('.wizard-controls .btn').attr('disabled', false) \ No newline at end of file diff --git a/app/assets/javascripts/app/controllers/getting_started.js.coffee b/app/assets/javascripts/app/controllers/getting_started.js.coffee index 87b375439..becf4d996 100644 --- a/app/assets/javascripts/app/controllers/getting_started.js.coffee +++ b/app/assets/javascripts/app/controllers/getting_started.js.coffee @@ -364,7 +364,7 @@ class Base extends App.ControllerContent if App.Config.get('system_online_service') @navigate 'getting_started/channel/email_pre_configured' else - @navigate 'getting_started/channel' + @navigate 'getting_started/email_notification' else for key, value of data.messages @showAlert( key, value ) @@ -394,6 +394,151 @@ class Base extends App.ControllerContent App.Config.set( 'getting_started/base', Base, 'Routes' ) +class EmailNotification extends App.ControllerContent + className: 'getstarted fit' + events: + 'change .js-outbound [name=adapter]': 'toggleOutboundAdapter' + 'submit .js-outbound': 'submit' + + constructor: -> + super + + # redirect if we are not admin + if !@authenticate(true) + @navigate '#' + return + + # set title + @title 'Email Notifications' + + @adapters = [ + { + name: 'Email' + class: 'email' + link: '#getting_started/channel/email' + }, + ] + + @fetch() + + release: => + @el.removeClass('fit getstarted') + + fetch: -> + + # get data + @ajax( + id: 'getting_started', + type: 'GET', + url: @apiPath + '/getting_started', + processData: true, + success: (data, status, xhr) => + + # check if import is active + if data.import_mode == true + @navigate '#import/' + data.import_backend + return + + # render page + @render() + ) + + render: -> + @html App.view('getting_started/email_notification')() + adapters = + sendmail: 'Local MTA (Sendmail/Postfix/Exim/...) - use server setup' + smtp: 'SMTP - configure your own outgoing SMTP settings' + adapter_used = 'sendmail' + configureAttributesOutbound = [ + { name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters , default: adapter_used }, + ] + new App.ControllerForm( + el: @$('.base-outbound-type'), + model: { configure_attributes: configureAttributesOutbound, className: '' }, + ) + @toggleOutboundAdapter() + + toggleOutboundAdapter: => + + # show used backend + channel_used = { options: {} } + adapter = @$('.js-outbound [name=adapter]').val() + if adapter is 'smtp' + configureAttributesOutbound = [ + { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true, default: (channel_used['options']&&channel_used['options']['host']) }, + { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, default: (channel_used['options']&&channel_used['options']['user']) }, + { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, single: true, default: (channel_used['options']&&channel_used['options']['password']) }, + ] + @form = new App.ControllerForm( + el: @$('.base-outbound-settings') + model: { configure_attributes: configureAttributesOutbound, className: '' } + ) + else + @el.find('.base-outbound-settings').html('') + + + submit: (e) => + e.preventDefault() + + # get params + params = @formParam(e.target) + params['email'] = 'me@localhost' + @disable(e) + + @showSlide('js-test') + + @ajax( + id: 'email_notification' + type: 'POST' + url: @apiPath + '/channels/email_notification' + data: JSON.stringify( params ) + processData: true + success: (data, status, xhr) => + if data.result is 'ok' + for key, value of data.settings + App.Config.set( key, value ) + if App.Config.get('system_online_service') + @navigate 'getting_started/channel/email_pre_configured' + else + @navigate 'getting_started/channel' + else + @showSlide('js-outbound') + @showAlert('js-outbound', data.message_human || data.message ) + @enable(e) + + fail: => + @showSlide('js-outbound') + @showAlert('js-outbound', data.message_human || data.message ) + @enable(e) + ) + + goToSlide: (e) => + e.preventDefault() + slide = $(e.target).data('slide') + @showSlide(slide) + + showSlide: (name) => + @hideAlert(name) + @$('.setup.wizard').addClass('hide') + @$(".setup.wizard.#{name}").removeClass('hide') + @$(".setup.wizard.#{name} input, .setup.wizard.#{name} select").first().focus() + + showAlert: (screen, message) => + @$(".#{screen}").find('.alert').removeClass('hide').text( App.i18n.translateInline( message ) ) + + hideAlert: (screen) => + @$(".#{screen}").find('.alert').addClass('hide') + + disable: (e) => + @formDisable(e) + @$('.wizard-controls .btn').attr('disabled', true) + + enable: (e) => + @formEnable(e) + @$('.wizard-controls .btn').attr('disabled', false) + +App.Config.set( 'getting_started/email_notification', EmailNotification, 'Routes' ) + class Channel extends App.ControllerContent className: 'getstarted fit' @@ -610,7 +755,7 @@ class ChannelEmail extends App.ControllerContent @ajax( id: 'email_probe' type: 'POST' - url: @apiPath + '/getting_started/email_probe' + url: @apiPath + '/channels/email_probe' data: JSON.stringify( params ) processData: true success: (data, status, xhr) => @@ -643,7 +788,7 @@ class ChannelEmail extends App.ControllerContent @ajax( id: 'email_inbound' type: 'POST' - url: @apiPath + '/getting_started/email_inbound' + url: @apiPath + '/channels/email_inbound' data: JSON.stringify( params ) processData: true success: (data, status, xhr) => @@ -679,7 +824,7 @@ class ChannelEmail extends App.ControllerContent @ajax( id: 'email_outbound' type: 'POST' - url: @apiPath + '/getting_started/email_outbound' + url: @apiPath + '/channels/email_outbound' data: JSON.stringify( params ) processData: true success: (data, status, xhr) => @@ -705,7 +850,7 @@ class ChannelEmail extends App.ControllerContent @ajax( id: 'email_verify' type: 'POST' - url: @apiPath + '/getting_started/email_verify' + url: @apiPath + '/channels/email_verify' data: JSON.stringify( account ) processData: true success: (data, status, xhr) => diff --git a/app/assets/javascripts/app/models/channel.js.coffee b/app/assets/javascripts/app/models/channel.js.coffee index 334c18409..301f00451 100644 --- a/app/assets/javascripts/app/models/channel.js.coffee +++ b/app/assets/javascripts/app/models/channel.js.coffee @@ -2,18 +2,20 @@ class App.Channel extends App.Model @configure 'Channel', 'adapter', 'area', 'options', 'group_id', 'active', 'updated_at' @extend Spine.Model.Ajax @url: @apiPath + '/channels' - @configure_delete = true - @configure_attributes = [ - { name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { IMAP: 'IMAP', POP3: 'POP3' } }, - { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, - { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, - { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false }, - { name: 'options::ssl', display: 'SSL', tag: 'select', multiple: false, null: true, options: { true: 'yes', false: 'no' }, translate: true, default: true}, - { name: 'options::folder', display: 'Folder', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, - { name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, nulloption: true, relation: 'Group' }, - { name: 'active', display: 'Active', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' }, translate: true, default: true }, - ] - @configure_overview = [ - 'adapter', 'options::host', 'options::user', 'group' - ] + displayName: -> + name = '' + if @options + if @options.inbound + name += "#{@options.inbound.options.user}@#{@options.inbound.options.host} (#{@options.inbound.adapter})" + if @options.outbound + if @options.outbound + if name != '' + name += ' / ' + if @options.outbound.options + name += "#{@options.outbound.options.host} (#{@options.outbound.adapter})" + else + name += " (#{@options.outbound.adapter})" + if name == '' + name = '???' + name \ No newline at end of file diff --git a/app/assets/javascripts/app/models/email_address.js.coffee b/app/assets/javascripts/app/models/email_address.js.coffee index 3da7514b5..33691fc13 100644 --- a/app/assets/javascripts/app/models/email_address.js.coffee +++ b/app/assets/javascripts/app/models/email_address.js.coffee @@ -1,11 +1,20 @@ class App.EmailAddress extends App.Model - @configure 'EmailAddress', 'realname', 'email', 'note', 'active', 'updated_at' + @configure 'EmailAddress', 'realname', 'email', 'channel_id', 'note', 'active', 'updated_at' @extend Spine.Model.Ajax @url: @apiPath + '/email_addresses' + @filterChannel: (options, type) => + return options if type isnt 'collection' + _.filter( + options + (channel) -> + return channel if channel && channel.area is 'Email::Account' + ) + @configure_attributes = [ { name: 'realname', display: 'Realname', tag: 'input', type: 'text', limit: 250, null: false }, - { name: 'email', display: 'Email', tag: 'input', type: 'text', limit: 250, null: false }, + { name: 'email', display: 'Email', tag: 'input', type: 'email', limit: 250, null: false }, + { name: 'channel_id', display: 'Channel', tag: 'select', multiple: false, null: false, relation: 'Channel', nulloption: true, filter: @filterChannel }, { name: 'note', display: 'Note', tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, null: true }, { name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 }, { name: 'active', display: 'Active', tag: 'active', default: true }, diff --git a/app/assets/javascripts/app/views/channel/email_account_overview.jst.eco b/app/assets/javascripts/app/views/channel/email_account_overview.jst.eco new file mode 100644 index 000000000..84ff66c2d --- /dev/null +++ b/app/assets/javascripts/app/views/channel/email_account_overview.jst.eco @@ -0,0 +1,99 @@ +<%- @T('Inbound') %> | +<%- @T('Outbound') %> | +<%- @T('Email Adresses') %> | +<%- @T('Action') %> | +
---|---|---|---|
+ <%- @T('State') %>: <%- @T(channel.status_in || 'unknown') %> + <%= channel.options.inbound.options.user %> + <%= channel.options.inbound.options.host %> (<%= channel.options.inbound.adapter %>) + |
+
+ <%- @T('State') %>: <%- @T(channel.status_out || 'unknown') %> + <% if channel.options.outbound && channel.options.outbound.options: %> + <%= channel.options.outbound.options.user %> + <%= channel.options.outbound.options.host %> + <% end %> + (<%= channel.options.outbound.adapter %>) + |
+
+
|
+ + + | +
<%= channel.last_log_in %> | +|||
<%= channel.last_log_out %> | +
<%- @T('Outbound') %> | +
---|
+ <%- @T('State') %>: <%- @T(@channel.status_out || 'unknown') %> + <% if @channel.options.outbound && @channel.options.outbound.options: %> + <%= @channel.options.outbound.options.user %> + <%= @channel.options.outbound.options.host %> + <% end %> + (<%= @channel.options.outbound.adapter %>) + |
+
<%= @channel.last_log_in %> | +
<%= @channel.last_log_out %> | +