Добрый день. Появилась задача добавить кнопку, аналогичную кнопке "Обработать" в почте.
Но просто так добавить кнопку не получилось. Кажется обработчик на кнопку вешается не простым 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… о чем-то, что мне поможет, говорится. Но без понимая как это все устроено - это какое-то гадание на кофейной гуще.
Конечно, для решения моей задачи есть варианты и попроще, но менее изящные. Просто очень хочется разобраться и сделать именно первоначальную задумку:
![]()
Может кто-то реализовывал мой кейс или нечто подобное и сможет поделиться советом?
Нравится
Сергей, насколько понимаю, Вы пытаетесь сделать как для зелёной кнопки 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
Вроде теперь все работает как надо, но надо провести обильное тестирование на большом количестве писем. А то письма после обработки все равно привязывались к обращениям и переоткрывали их. Теперь такие письма можно пропускать.