summaryrefslogtreecommitdiff
path: root/web-ui/app/js/mixins/with_mail_edit_base.js
diff options
context:
space:
mode:
Diffstat (limited to 'web-ui/app/js/mixins/with_mail_edit_base.js')
-rw-r--r--web-ui/app/js/mixins/with_mail_edit_base.js263
1 files changed, 263 insertions, 0 deletions
diff --git a/web-ui/app/js/mixins/with_mail_edit_base.js b/web-ui/app/js/mixins/with_mail_edit_base.js
new file mode 100644
index 00000000..a088080e
--- /dev/null
+++ b/web-ui/app/js/mixins/with_mail_edit_base.js
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2014 ThoughtWorks, Inc.
+ *
+ * Pixelated is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Pixelated is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+define(
+ [
+ 'flight/lib/compose',
+ 'helpers/view_helper',
+ 'mail_view/ui/recipients/recipients',
+ 'mail_view/ui/draft_save_status',
+ 'page/events',
+ 'views/i18n',
+ 'mail_view/ui/send_button',
+ 'mail_view/ui/attachment_icon',
+ 'mail_view/ui/attachment_list',
+ 'flight/lib/utils'
+ ],
+ function (compose, viewHelper, Recipients, DraftSaveStatus, events, i18n, SendButton, AttachmentIcon, attachmentList, utils) {
+ 'use strict';
+
+ function withMailEditBase() {
+
+ this.defaultAttrs({
+ bodyBox: '#text-box',
+ sendButton: '#send-button',
+ attachmentButton: '#attachment-button',
+ attachmentList: '#attachment-list',
+ cancelButton: '#cancel-button',
+ trashButton: '#trash-button',
+ toArea: '#recipients-to-area',
+ toBox: '#recipients-to-box',
+ ccArea: '#recipients-cc-area',
+ bccArea: '#recipients-bcc-area',
+ ccsTrigger: '#ccs-trigger',
+ bccsTrigger: '#bccs-trigger',
+ toTrigger: '#to-trigger',
+ subjectBox: '#subject',
+ tipMsg: '.tip-msg',
+ draftSaveStatus: '#draft-save-status',
+ recipientsFields: '#recipients-fields',
+ currentTag: '',
+ recipientValues: {to: [], cc: [], bcc: []},
+ saveDraftInterval: 3000
+ });
+
+ this.attachRecipients = function (context) {
+ Recipients.attachTo(this.select('toArea'), {name: 'to', addresses: context.recipients.to});
+ Recipients.attachTo(this.select('ccArea'), {name: 'cc', addresses: context.recipients.cc || []});
+ Recipients.attachTo(this.select('bccArea'), {name: 'bcc', addresses: context.recipients.bcc || []});
+ };
+
+ function thereAreRecipientsToDisplay() {
+
+ var allRecipients = _.chain(this.attr.recipientValues).
+ values().
+ flatten().
+ remove(undefined).
+ value();
+
+ return !_.isEmpty(allRecipients);
+ }
+
+ this.warnSendButtonOfRecipients = function () {
+ if (thereAreRecipientsToDisplay.call(this)) {
+ _.forOwn(this.attr.recipientValues, function (recipients, recipientsType) {
+ if (!_.isUndefined(recipients) && !_.isEmpty(recipients)) {
+ var recipientsUpdatedData = {
+ newRecipients: recipients,
+ recipientsName: recipientsType
+ };
+ this.trigger(document, events.ui.recipients.updated, recipientsUpdatedData);
+ }
+ }.bind(this));
+ }
+ };
+
+ this.render = function (template, context) {
+ this.$node.html(template(context));
+
+ if (!context || _.isEmpty(context)) {
+ context.recipients = {to: [], cc: [], bcc: []};
+ }
+ this.attr.recipientValues = context.recipients;
+ this.attr.attachments = context.attachments || [];
+ this.attachRecipients(context);
+
+ this.on(this.select('trashButton'), 'click', this.discardMail);
+ SendButton.attachTo(this.select('sendButton'));
+ AttachmentIcon.attachTo(this.select('attachmentButton'));
+
+ this.warnSendButtonOfRecipients();
+ };
+
+ this.enableAutoSave = function () {
+ this.select('bodyBox').on('input', this.monitorInput.bind(this));
+ this.select('subjectBox').on('input', this.monitorInput.bind(this));
+ this.on(document, events.mail.appendAttachment, this.monitorInput.bind(this));
+ this.on(document, events.mail.removeAttachment, this.monitorInput.bind(this));
+ DraftSaveStatus.attachTo(this.select('draftSaveStatus'));
+ };
+
+ this.monitorInput = function () {
+ this.trigger(events.ui.mail.changedSinceLastSave);
+ this.cancelPostponedSaveDraft();
+ var mail = this.buildMail();
+ this.postponeSaveDraft(mail);
+ };
+
+ this.discardMail = function () {
+ this.cancelPostponedSaveDraft();
+ if (this.attr.ident) {
+ var mail = this.buildMail();
+ this.trigger(document, events.ui.mail.delete, {mail: mail});
+ } else {
+ this.trigger(document, events.ui.mail.discard);
+ }
+ };
+
+ this.trim_recipient = function (recipients) {
+ return recipients.map(function (recipient) {
+ return recipient.trim();
+ });
+ };
+
+ this.sendMail = function () {
+ this.cancelPostponedSaveDraft();
+ var mail = this.buildMail('sent');
+
+ if (allRecipientsAreEmails(mail)) {
+ mail.header.to = this.trim_recipient(mail.header.to);
+ mail.header.cc = this.trim_recipient(mail.header.cc);
+ mail.header.bcc = this.trim_recipient(mail.header.bcc);
+ this.trigger(events.mail.send, mail);
+ } else {
+ this.trigger(
+ events.ui.userAlerts.displayMessage,
+ {message: i18n.t('recipients-not-valid')}
+ );
+ this.trigger(events.mail.send_failed);
+ }
+ };
+
+ this.buildAndSaveDraft = function () {
+ var mail = this.buildMail();
+ this.saveDraft(mail);
+ };
+
+ this.recipientsUpdated = function (ev, data) {
+ this.attr.recipientValues[data.recipientsName] = data.newRecipients;
+ this.trigger(document, events.ui.mail.recipientsUpdated);
+ if (data.skipSaveDraft) {
+ return;
+ }
+
+ var mail = this.buildMail();
+ this.postponeSaveDraft(mail);
+ };
+
+ this.saveDraft = function (mail) {
+ this.cancelPostponedSaveDraft();
+ this.trigger(document, events.mail.saveDraft, mail);
+ };
+
+ this.cancelPostponedSaveDraft = function () {
+ clearTimeout(this.attr.timeout);
+ };
+
+ this.postponeSaveDraft = function (mail) {
+ this.cancelPostponedSaveDraft();
+
+ this.attr.timeout = window.setTimeout(_.bind(function () {
+ this.saveDraft(mail);
+ }, this), this.attr.saveDraftInterval);
+ };
+
+ this.draftSaved = function (event, data) {
+ this.attr.ident = data.ident;
+ };
+
+ this.validateAnyRecipient = function () {
+ return !_.isEmpty(_.flatten(_.values(this.attr.recipientValues)));
+ };
+
+ function allRecipientsAreEmails(mail) {
+ var allRecipients = mail.header.to.concat(mail.header.cc).concat(mail.header.bcc);
+ return _.isEmpty(allRecipients) ? false : _.all(allRecipients, emailFormatChecker);
+ }
+
+ function emailFormatChecker(email) {
+ var emailFormat = /[^\s@]+@[^\s@]+\.[^\s@]+$/;
+ return emailFormat.test(email);
+ }
+
+ this.saveTag = function (ev, data) {
+ this.attr.currentTag = data.tag;
+ };
+
+ this.mailSent = function () {
+ this.trigger(document, events.ui.userAlerts.displayMessage, {message: 'Your message was sent!'});
+ };
+
+ this.enableFloatlabel = function (element) {
+ var showClass = 'showfloatlabel';
+ $(element).bind('keyup', function () {
+ var label = $(this).prev('label');
+ if (this.value !== '') {
+ label.addClass(showClass);
+ $(this).addClass(showClass);
+ } else {
+ label.removeClass(showClass);
+ $(this).removeClass(showClass);
+ }
+ });
+ };
+
+ this.toggleRecipientsArrows = function () {
+ $('#cc-bcc-collapse').toggleClass('fa-angle-down');
+ $('#cc-bcc-collapse').toggleClass('fa-angle-up');
+ };
+
+ this.before('initialize', function () {
+ if (!this.discardDraft) {
+ this.discardDraft = function () {
+ };
+ }
+ });
+
+ this.bindCollapse = function () {
+ this.on($('#cc-bcc-collapse'), 'click', this.toggleRecipientsArrows);
+ };
+
+ this.after('initialize', function () {
+ this.on(document, events.dispatchers.rightPane.clear, this.teardown);
+ this.on(document, events.ui.recipients.updated, this.recipientsUpdated);
+ this.on(document, events.mail.draftSaved, this.draftSaved);
+ this.on(document, events.mail.sent, this.mailSent);
+
+ this.on(document, events.ui.mail.send, this.sendMail);
+
+ this.on(document, events.ui.mail.discard, this.discardDraft);
+ this.on(document, events.ui.tag.selected, this.saveTag);
+ this.on(document, events.ui.tag.select, this.saveTag);
+ this.bindCollapse();
+ });
+
+ compose.mixin(this, [attachmentList]);
+ }
+
+ return withMailEditBase;
+ });