Ext.namespace('Zarafa.common.rules.dialogs'); /** * @class Zarafa.common.rules.dialogs.WordSelectionLink * @extends Ext.BoxComponent * @xtype zarafa.wordselectionlink */ Zarafa.common.rules.dialogs.WordSelectionLink = Ext.extend(Ext.BoxComponent, { /** * @cfg {String} fieldLabel The label which must be applied to template * as a prefix to the list of attachments. */ emptyText :_('Select one...'), /** * @cfg {String} wordStringSeparator The separator which is used to separate list * of words while displaying them as string. */ wordStringSeparator :_('or'), /** * @cfg {Ext.data.Store} store The store in which * the words are stored */ store : undefined, /** * The Condition type which is handled by this view * This is set during {@link #setCondition}. * @property * @type Zarafa.common.rules.data.ConditionFlags */ conditionFlag : undefined, /** * The condition property which was configured during * {@link #setCondition}. * @property * @type Object */ condition : undefined, /** * True if the action/condition was modified by the user, if this is false, * then {@link #getCondition} will return {@link #condition} instead * of returning a new object and {@link #getAction} will return {@link #action} * instead of returning a new Object. * @property * @type Boolean */ isModified : false, /** * True if the action/condition is complete and valid, * False will denote that action/condition is invalid or incomplete * if this is true, then {@link #getCondition} will return {@link #condition} instead * of returning a new object and {@link #getAction} will return {@link #action} * instead of returning a new Object. * @property * @type Boolean */ isValid : true, /** * @constructor * @param {Object} config configuration object. */ constructor : function(config) { config = config || {}; Ext.applyIf(config,{ xtype: 'zarafa.wordselectionlink', border : false, autoScroll:true, anchor : '100%', multiSelect : false, store : new Ext.data.Store({ fields : [ 'words' ] }), tpl : new Ext.XTemplate( '<div class="zarafa-word-link">' + '<tpl for=".">' + '<tpl if="!Ext.isEmpty(values.words)">' + '"{words:htmlEncode}"'+ '</tpl>' + '<tpl if="xcount > 0 && xindex != xcount">' + '<span> ' + this.wordStringSeparator + ' </span>' + '</tpl>' + '</tpl>' + '</div>', { compiled : true, wordStringSeparator : config.wordStringSeparator || this.wordStringSeparator } ) }); Zarafa.common.rules.dialogs.WordSelectionLink.superclass.constructor.call(this, config); }, /** * This function is called after the component has been rendered. * This will register the {@link #onActivate} and {@link #onClick} event handlers. * @private */ afterRender : function() { Zarafa.common.rules.dialogs.WordSelectionLink.superclass.initComponent.apply(this, arguments); this.mon(this.getActionEl(), 'click', this.onClick, this); }, /** * Called when user clicks on a {@link Zarafa.common.rules.dialogs.WordSelectionLink} * It opens words edit dialog. * @param {Ext.DataView} dataView Reference to this object * @param {Number} index The index of the target node * @param {HTMLElement} node The target node * @param {Ext.EventObject} evt The mouse event * @protected */ onClick : function(dataView, index, node, evt) { var tmpStore = new Ext.data.Store({ fields : [ 'words' ] }); tmpStore.add(this.store.getRange()); // Open RulesWordsEditDialog Zarafa.common.Actions.openRulesWordsEditContent({ store : tmpStore, callback : this.rulesWordsEditDialogCallback, scope : this, modal : true }); }, /** * Callback function for {@link Zarafa.common.rules.dialogs.RulesWordsEditDialog} * @param {Ext.data.Store} store the store which contains list of words * @private */ rulesWordsEditDialogCallback : function(store) { // Remove old words and add words which we have got // from callback function of RulesWordsEditDialog. this.store.removeAll(); this.store.add(store.getRange()); this.isModified = true; this.update(this.store); }, /** * Apply an action onto the DataView, this will parse the condition and show * the contents in a user-friendly way to the user. * @param {Zarafa.common.rules.data.ConditionFlags} conditionFlag The condition type * which identifies the exact type of the condition. * @param {Object} condition The condition to apply */ setCondition : function(conditionFlag, condition) { this.store.removeAll(); this.isValid = false; // Parse the condition and add words in the store. if (condition) { var Restrictions = Zarafa.core.mapi.Restrictions; switch (conditionFlag) { case Zarafa.common.rules.data.ConditionFlags.SENDER_WORDS: var subs; // Check if a RES_OR restriction was provided, if // so we need to loop over all words from the list. if (condition[0] == Restrictions.RES_OR) { subs = condition[1]; } else { subs = [ condition ]; } for (var i = 0, len = subs.length; i < len; i++) { var value = subs[i][1][Restrictions.VALUE]; Ext.iterate(value, function(key, value) { if(!Ext.isEmpty(value)) { this.isValid = true; if(conditionFlag === Zarafa.common.rules.data.ConditionFlags.SENDER_WORDS) { value = Zarafa.core.Util.hexToString(value); } this.store.add(new Ext.data.Record({ words : value })); } }, this); } break; case Zarafa.common.rules.data.ConditionFlags.SUBJECT_WORDS: case Zarafa.common.rules.data.ConditionFlags.BODY_WORDS: /* falls through */ default: var subs; // Check if a RES_OR restriction was provided, if // so we need to loop over all words from the list. if (condition[0] == Restrictions.RES_OR) { subs = condition[1]; } else { subs = [ condition ]; } for (var i = 0, len = subs.length; i < len; i++) { var value = subs[i][1][Restrictions.VALUE]; Ext.iterate(value, function(key, value) { if(!Ext.isEmpty(value)) { this.isValid = true; this.store.add(new Ext.data.Record({ words : value })); } }, this); } break; } } this.conditionFlag = conditionFlag; this.condition = condition; this.isModified = !Ext.isDefined(condition); this.update(this.store); }, /** * Obtain the condition as configured by the user * @return {Object} The condition */ getCondition : function() { if (this.isModified !== true && this.isValid === true) { return this.condition; } // No words are added, so we can't create a condition. if (this.store.getCount() === 0) { return false; } var conditions = []; var RestrictionFactory = Zarafa.core.data.RestrictionFactory; var Restrictions = Zarafa.core.mapi.Restrictions; switch (this.conditionFlag) { case Zarafa.common.rules.data.ConditionFlags.SENDER_WORDS: this.store.each(function(word) { var value = Zarafa.core.Util.stringToHex(word.get('words')); conditions.push(RestrictionFactory.dataResContent('PR_SENDER_SEARCH_KEY', Restrictions.FL_SUBSTRING, value)); }, this); break; case Zarafa.common.rules.data.ConditionFlags.SUBJECT_WORDS: this.store.each(function(word) { conditions.push(RestrictionFactory.dataResContent('PR_SUBJECT', Restrictions.FL_SUBSTRING | Restrictions.FL_IGNORECASE, word.get('words'))); }, this); break; case Zarafa.common.rules.data.ConditionFlags.BODY_WORDS: this.store.each(function(word) { conditions.push(RestrictionFactory.dataResContent('PR_BODY', Restrictions.FL_SUBSTRING | Restrictions.FL_IGNORECASE, word.get('words'))); }, this); break; default: // Invalid conditionFlag return false; } // If there was only 1 word condtion, we don't need to convert // it to a OR subrestriction. If we have more then 1 word condtion, // then we should create the OR restriction. if (conditions.length === 1) { return conditions[0]; } else { return Zarafa.core.data.RestrictionFactory.createResOr(conditions); } }, /** * Update the contents of this dataview, this will apply the {@link #tpl} for * the {@link #store}. * @param {Zarafa.core.data.IPMRecipientStore} store The store to show */ update : function(store) { var data = Ext.pluck(store.getRange(), 'data'); if (Ext.isEmpty(data)) { data = [{ words : this.emptyText }]; } Zarafa.common.rules.dialogs.WordSelectionLink.superclass.update.call(this, this.tpl.apply(data)); } }); Ext.reg('zarafa.wordselectionlink', Zarafa.common.rules.dialogs.WordSelectionLink);