Добавление кнопки для обработки почты

Добрый день. Появилась задача добавить кнопку, аналогичную кнопке "Обработать" в почте. 

 

Но просто так добавить кнопку не получилось. Кажется обработчик на кнопку вешается не простым bindTo, как мне казалось в начале.

 

Пример кода, который получился:

generateEmailButtonsContainerConfig: function() {
	var buttonItems = [];
	var processEmailButtonConfig = this.generateEmailProcessedButtonConfig();
	buttonItems.push(processEmailButtonConfig);
	/** Добавляем новую кнопку */
	var skipEmailButtonConfig = this.generateSkipEmailButtonConfig();
	buttonItems.push(skipEmailButtonConfig);
	var deleteEmailButtonConfig = this.generateDeleteEmailButtonConfig();
	buttonItems.push(deleteEmailButtonConfig);
	var emailButtonContainerConfig = {
		"className": "Terrasoft.Container",
		"classes": {"wrapClassName": ["entity-item-relation-container"]},
		"items": buttonItems
	};
	return emailButtonContainerConfig;
},
/** НОВАЯ КНОПКА */
generateSkipEmailButtonConfig: function() {
	return {
		"className": "Terrasoft.Button",
		"style": Terrasoft.controls.ButtonEnums.style.RED,
		"caption": "SKIP",
		"click": {bindTo: "onSkipEmail"},
		"markerValue": "skipingEmail"
	};
},
/** Метод обработчик кнопки*/
onSkipEmail: function (model) {
	window.console.log("It's working");
}

Но при нажатии на кнопку - появляется ошибка:

Изображение удалено.

Возможно надо использоваться что-то похожее на fireEvent, но за все время не было необходимости в подобном функционале - поэтому плохо понимаю как и что делать. Вроде в этой статье https://community.terrasoft.ru/articles/kak-sozdat-polzovatelskii-eleme… о чем-то, что мне поможет, говорится. Но без понимая как это все устроено - это какое-то гадание на кофейной гуще.

 

Конечно, для решения моей задачи есть варианты и попроще, но менее изящные. Просто очень хочется разобраться и сделать именно первоначальную задумку:

Изображение удалено.

 

Может кто-то реализовывал мой кейс или нечто подобное и сможет поделиться советом?

Нравится

4 комментария

Сергей, насколько понимаю, Вы пытаетесь сделать как для зелёной кнопки EmailProcessedButton, которая описана в CommunicationPanelEmailSchema:

/**
 * Creates email message action buttons container config.
 * @protected
 * @return {Object} Email message action buttons container config.
 */
generateEmailButtonsContainerConfig: function() {
	var buttonItems = [];
	var processEmailButtonConfig = this.generateEmailProcessedButtonConfig();
	buttonItems.push(processEmailButtonConfig);
	var deleteEmailButtonConfig = this.generateDeleteEmailButtonConfig();
	buttonItems.push(deleteEmailButtonConfig);
	var emailButtonContainerConfig = {
		"className": "Terrasoft.Container",
		"classes": {"wrapClassName": ["entity-item-relation-container"]},
		"items": buttonItems
	};
	return emailButtonContainerConfig;
},
 
/**
 * Creates "process message" button config.
 * @protected
 * @return {Object} "Process message" button config.
 */
generateEmailProcessedButtonConfig: function() {
	return {
		"className": "Terrasoft.Button",
		"caption": {"bindTo": "Resources.Strings.MarkAsProcessed"},
		"style": Terrasoft.controls.ButtonEnums.style.GREEN,
		"imageConfig": {"bindTo": "Resources.Images.ApplyButtonImage"},
		"enabled": {"bindTo": "IsProcessingButtonEnabled"},
		"visible": {
			"bindTo": "IsNeedProcess",
			"bindConfig": {
				"converter": "getProcessButtonVisible"
			}
		},
		"click": {bindTo: "setIsNeedProcessFalse"},
		"markerValue": "setNeedProcessFalse"
	};
},

Но там обработчик setIsNeedProcessFalse в EmailItemSchema не просто одна функция, а несколько в цепочке, одна вызывает другие:

/**
 * Sets and saves IsNeedProcess value for message.
 * @param {Function} [callback] Callback function.
 * @param {Object} [scope] Callback function scope.
 */
setIsNeedProcessFalse: function(callback, scope) {
	this.set("IsProcessingButtonEnabled", false);
	var chain = [];
	chain.push(this.updateIsNeedProcess);
	chain.push(this._onSetIsNeedProcessFalse, function() {
		this.Ext.callback(callback, scope);
	});
 
	this.set("IsNeedProcess", false);
	this.Terrasoft.chain.apply(this, chain);
},
...
/**
 * Updates IsNeedProcess value for current user EmailMessageData instances.
 * @param {Function} [callback] Callback function.
 * @param {Object} [scope] Callback function scope.
 */
updateIsNeedProcess: function(callback, scope) {
	var update = this.getIsNeedProcessUpdate();
	if (this.Ext.isEmpty(update)) {
		this.Ext.callback(callback, scope);
		return;
	}
	update.execute(function() {
		this.Ext.callback(callback, scope);
	}, this);
},
...
/**
 * Handle response of save entity request.
 * @private
 * @param {Object} [response] Response of save entity request.
 * @param {Function} [callback] Callback function.
 * @param {Object} [scope] Callback function scope.
 */
_handleSaveRequestResponse: function(response, callback, scope) {
	if (response && response.success) {
		this.fireEvent("entitySaved", this);
		this.set("CurrentColumnValue", null);
	}
	this.Ext.callback(callback, scope);
},
/**
 * Set IsNeedProcess to false.
 * @private
 * @param {Function} [callback] Callback function.
 * @param {Object} [scope] Callback function scope.
 */
_onSetIsNeedProcessFalse: function(callback, scope) {
	this.saveEntity(function(response) {
		this._handleSaveRequestResponse(response, callback, scope);
	}, this);
},

Если ругается на .apply, видимо, ожидает для Вашей кнопки аналогичной логики. Хотя, там же рядом справа DeleteEmailButton, там без этого всего:

/**
 * Creates "delete" button config.
 * @protected
 * @return {Object} "Delete" button config.
 */
generateDeleteEmailButtonConfig: function() {
	return {
		"className": "Terrasoft.Button",
		"style": Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
		"imageConfig": {"bindTo": "Resources.Images.DeleteEmailButtonImage"},
		"click": {bindTo: "onDeleteEmail"},
		"markerValue": "deleteEmail"
	};
},
...
/**
 * Removes email message from emails collection.
 * @param {Terrasoft.BaseViewModel} model Email message model instance.
 */
onDeleteEmail: function(model) {
	this.unsubscribeModelEvents(model);
	var collection = this.get("EmailCollection");
	collection.remove(model);
},

Не сравнивали в отладке Вашу кнопку с кнопкой удаления?

Зверев Александр,

Сегодня заметил, что вся логика на самом деле в другой схеме - попробую туда вписать мой метод-обработчик. Может кнопка просто не может найти нужный метод и валится в ошибку. Пока я понял что работает так - EmailItemSchema "втягивает" в себя кнопки и обрабатывает методы у себя и после уже дополняет методами из 

CommunicationPanelEmailSchema. Проверю свою догадку и отпишусь о происходящем. Просто изначально не заметил эту привязку. Даже не осознал до конца как я натолкнулся на нее. Но теперь уже немного понятно куда идти

Сергей, попробовал у себя Ваш и стандартный код, кнопка удаления работает, поскольку функция вызывается не напрямую оттуда, а после окошка с подтверждением желания.

Если просто Вашу функцию onSkipEmail перенести в EmailItemSchema, то всё работает, пишет в консоли «It's working».

Зверев Александр,

Все так. Но пришлось еще докрутить логику. Например, включил передачу сообщения и основную логику все равно запускал в 

CommunicationPanelEmailSchema (потому что надо было работать с коллекцией писем, не был уверен что смогу это провернуть в EmailItemSchema)

 

Если кому-то поможет - полученный код ниже

 

EmailItemSchema:

messages: {
	"MessageSkipEmail": {
		mode: Terrasoft.MessageMode.BROADCAST,
		direction: Terrasoft.MessageDirectionType.BIDIRECTIONAL
	}
},
methods: {
	/**
	 * Initializes starter values.
	 * @protected
	 * @overridden
	 */
	init: function () {
		this.callParent(arguments);
		// Регистрация сообщения.
		this.sandbox.registerMessages(this.messages);
	},
	onSkipEmail: function() {
		// Регистрация сообщения.
		var EmailId = this.get("Id");
		this.sandbox.publish("MessageSkipEmail", {Id: EmailId}, ["EmailItemSchema"]);
	}
},

CommunicationPanelEmailSchema

messages: {
	"MessageSkipEmail": {
		mode: Terrasoft.MessageMode.BROADCAST,
		direction: Terrasoft.MessageDirectionType.BIDIRECTIONAL
	}
},
methods: {
	init: function () {
		this.callParent(arguments);
		// Регистрация сообщения.
		Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE, this.onMyBpFinish, this);
		this.sandbox.subscribe("MessageSkipEmail", function(args) { this.skipingEmail(args.Id);},
			this, ["EmailItemSchema"]);
	},
	skipingEmail: function(EmailId) {
		var collection = this.get("EmailCollection");
		var foundItem = collection.collection.items.find(item => item.id === EmailId);
		var args = {
		// Имя процесса, который необходимо запустить.
			sysProcessName: "UsrSkipEmail",
		// Объект со значением входящего параметра ContactParameter для процесса CustomProcess.
			parameters: {
				ID: EmailId
			}
		};
				// Запуск пользовательского бизнес-процесса.
		ProcessModuleUtilities.executeProcess(args);
		collection.remove(foundItem); /** Выкидываем уже обработанное письмо из списка*/
	},
	generateEmailButtonsContainerConfig: function() {
		var buttonItems = [];
		var processEmailButtonConfig = this.generateEmailProcessedButtonConfig();
		buttonItems.push(processEmailButtonConfig);
		/** Добавляем новую кнопку */
		var skipEmailButtonConfig = this.generateSkipEmailButtonConfig();
		buttonItems.push(skipEmailButtonConfig);
		var deleteEmailButtonConfig = this.generateDeleteEmailButtonConfig();
		buttonItems.push(deleteEmailButtonConfig);
		var emailButtonContainerConfig = {
			"className": "Terrasoft.Container",
			"classes": {"wrapClassName": ["entity-item-relation-container"]},
			"items": buttonItems
		};
		return emailButtonContainerConfig;
	},
	/** НОВАЯ КНОПКА */
	generateSkipEmailButtonConfig: function() {
		return {
			"className": "Terrasoft.Button",
			//"style": 
			"caption": "Игнорировать",
			"click": {bindTo: "onSkipEmail"},
			"markerValue": "skipingEmail",
			"enabled": {"bindTo": "IsProcessingButtonEnabled"},
			"visible": {
				"bindTo": "IsNeedProcess",
				"bindConfig": {
					"converter": "getProcessButtonVisible"
				}
			},
		};
	},

А в самом БП происходит магия изменения БД, чтобы не запустились скрытые процессы, привязанные к "IsNeedProcess" в EmailMessageData

 

Вроде теперь все работает как надо, но надо провести обильное тестирование на большом количестве писем. А то письма после обработки все равно привязывались к обращениям и переоткрывали их. Теперь такие письма можно пропускать.

Показать все комментарии