Выделение цветом в Расписании активностей при определенных условиях
Здравствуйте! Мне нужно, чтобы в Расписании выделялись цветом те задачи, которые имеют в заголовке слово "Свободно".
Если реализовать через такой код
function () {
return {
// Название схемы раздела.
entitySchemaName: "Activity",
details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
methods: {
// Переопределение базового метода, который модифицирует строку данных перед загрузкой в реестр.
prepareResponseCollectionItem: function (item) {
this.callParent(arguments);
item.customStyle = null;
var running = item.get("Title");
//Если условие подходит, меняем цвет записи на темно-серый, а фон на светло-зеленый.
if (running.indexOf('Свободно')+1) {
item.customStyle = {
'color': "darkgrey",
'background': "#D8FBC2"
}
}
}
}
};
});
то в разделе активность поменяла свой цвет а вот в расписании не поменяла.
Как сделать так чтобы в расписании активность поменяла свой цвет если в заголовке есть слово "Свободно"?
Версия BpmOnline sales commerce 7.8.3.1978
Нравится
Извините за оффтопик.
Не делали бы вы для раскраски реестров парсинг текста заголовка, ляжет и погибнет у вас система как объемы данных нарастут... это же неиндексируемое поле, да еще поиск по тексту...
Тут бы признак сделать типа булевского поля, и по нему обрабатывать. А булевское поле заполнять например тем самым парсингом названия при сохранении активности.
по теме
посмотрите в ActivitySectionV2 поиском по тексту "FontColor" -найдете в diff описание конфига для отображения элементов расписания. Возможно поможет замещение и замена bindto для fontcolor на новый атрибут... но это предположение :)
Раскраска активностей в расписании
Описание таска
Необходимо раскрашивать активности в расписании в зависимости от их приоритета. Значения цветов для каждого из приоритетов устанавливаются в справочнике. В случае, если для приоритета не задан цвет, должна отрабатывать стандартная логика раскраски.
Анализ
Таблица расписания определена внутри пакета NUI в модуле ActivitySectionV2, как элемент в объекте diff с именем Schedule. В данный элемент вложен объект itemBindingConfig, который отвечает за привязку свойств активности к каждому из элементов расписания. В данном случае нас интересуют два значения, а именно: background, устанавливающий цвет фона элемента расписания и fontColor, определяющий цвет текста на нём.
Привязанные методы (то, что идёт после bindTo, например, getScheduleItemTitle) определяются внутри пакета UIv2 в модуле ActivitySectionGridRowViewModel. Привязанные поля есть ничто иное, как загруженные из базы данных поля схемы Activity, список которых определяется внутри модуля ActivitySectionV2 в методе getGridDataColumns. Обратите внимание, что по умолчанию background и fontColor привязаны к полям, которых нет в схеме Activity (Background и FontColor соотвественно).
Внутренняя логика поведения элемента расписания определена в файле schedule-item.js (класс Terrasoft.controls.ScheduleItem). После анализа этого кода становится ясно, что в случае, если background определён, то CSS стиль элемента меняется, в противном случае – нет. То же касается и fontColor:
… if (background && isSelected) { out.push('<div style="background: ' + background + ';" class="' + schedulerItemStatusClasses[status] + " " + schedulerItemStatusClasses[0] + '">'); } else if (background && !isSelected) { out.push('<div style="background: ' + background + ';" class="' + schedulerItemStatusClasses[status] + '">'); } else if (!background && isSelected) { out.push('<div class="' + schedulerItemStatusClasses[status] + " " + schedulerItemStatusClasses[0] + '">'); } else { out.push('<div class="' + schedulerItemStatusClasses[status] + '">'); } …
Также можно заметить ещё одну особенность. Свойства background и fontColor не применяется для элементов, выделенных пользователем нажатием мыши:
… itemBodyEl.setStyle({ "backgroundColor": (isSelected) ? "" : this.background, "color": (isSelected) ? "" : this.fontColor }); …
Не совсем понятно, с чем это может быть связанно. Тем не менее изменять логику внутренних модулей системы не рекомендуется, и придётся довольствоваться тем, что предоставили нам разработчики.
Реализация
Шаг 1. Добавление справочника.
Первым шагом будет добавление справочника ActivitySchedulerColor. Дадим ему заголовок «Цвет активности в расписании» и добавим следующие поля:
- ActivityPriority с типом Справочник, который ссылается на «Приоритет активности».
- BackgroundColor с типом Строка
- FontColor с типом Строка
Добавим для каждого приоритета запись в справочнике. Выборочно присвоим некоторым из них значения цветов, а некоторые оставим пустыми.
Шаг 2. Добавление хелпера.
Далее необходимо добавить клиентский модуль, который будет загружать значения цветов из добавленного нами справочника и возвращать конкретные цвета по Id приоритета:
define("ActivitySectionGridRowHelper", ["terrasoft"], function(Terrasoft) { var activitySchedulerColor = {}; //Возвращает соответствующие priorityId цвета из справочника ActivitySchedulerColor //Перед вызовом этого метода, необходимо загрузить данные из справочника методом loadActivitySchedulerColors function getActivitySchedulerColor(priorityId) { return activitySchedulerColor[priorityId]; } //Загружает данные из справочника ActivitySchedulerColor (Цвета активностей) function loadActivitySchedulerColors() { var esq = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "ActivitySchedulerColor"}); esq.addColumn("ActivityPriority", "ActivityPriority"); esq.addColumn("BackgroundColor", "BackgroundColor"); esq.addColumn("FontColor", "FontColor"); esq.getEntityCollection(function(response) { Terrasoft.each(response.collection.collection.items, function(item) { activitySchedulerColor[item.values.ActivityPriority.value] = { "backgroundColor":item.values.BackgroundColor, "fontColor":item.values.FontColor }; }, this); }); } return { GetActivitySchedulerColor: getActivitySchedulerColor, LoadActivitySchedulerColors: loadActivitySchedulerColors }; });
Шаг 3. Замещение модуля ActivitySectionV2.
Следующим шагом будет переопределение схемы ActivitySectionV2. Здесь нужно изменить привязку значений для таблицы расписания, добавить поле Priority в выборку данных для таблицы расписания и вызвать из хелпера метод loadActivitySchedulerColors:
define("ActivitySectionV2", ["ActivitySectionGridRowHelper"], function(ActivitySectionGridRowHelper) { return { entitySchemaName: "Activity", details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/, diff: /**SCHEMA_DIFF*/[ { "operation": "merge", "name": "Schedule", "values": { "itemBindingConfig": { "itemId": {"bindTo": "Id"}, "title": {"bindTo": "getScheduleItemTitle"}, "changeTitle": {"bindTo": "onTitleChanged"}, "startDate": {"bindTo": "StartDate"}, "changeStartDate": {"bindTo": "onStartDateChanged"}, "dueDate": {"bindTo": "DueDate"}, "changeDueDate": {"bindTo": "onDueDateChanged"}, "status": {"bindTo": "getScheduleItemStatus"}, "changeStatus": {"bindTo": "onStatusChanged"}, "background": {"bindTo": "getBackground"}, "fontColor": {"bindTo": "getFontColor"}, "isBold": {"bindTo": "IsBold"}, "isItalic": {"bindTo": "IsItalic"}, "isUnderline": {"bindTo": "IsUnderline"}, "markerValue": {"bindTo": "getScheduleItemHint"} } } } ]/**SCHEMA_DIFF*/, methods: { getGridDataColumns: function() { var baseGridDataColumns = this.callParent(arguments); var gridDataColumns = { "Account": {path: "Account"}, "StartDate": {path: "StartDate"}, "DueDate": {path: "DueDate"}, "ShowInScheduler": {path: "ShowInScheduler"}, "Status": {path: "Status"}, "Status.Finish": {path: "Status.Finish"}, "ProcessElementId": { path: "ProcessElementId", dataValueType: 0 }, "Priority": {path: "Priority"} }; return Ext.apply(baseGridDataColumns, gridDataColumns); }, init: function () { this.callParent(arguments); ActivitySectionGridRowHelper.LoadActivitySchedulerColors(); } } }; });
Шаг 4. Замещение модуля ActivitySectionGridRowViewModel.
В данный модуль нам необходимо добавить два метода getBackground и getFontColor, к которым мы привязали значения полей background и fontColor. Однако, так как все методы объявлены внутри Ext.define, придётся копировать весь код модуля:
define("ActivitySectionGridRowViewModel", ["ext-base", "terrasoft", "ActivitySectionGridRowHelper","BaseSectionGridRowViewModel"], function(Ext, Terrasoft, ActivitySectionGridRowHelper) { /** * @class Terrasoft.configuration.ActivitySectionGridRowViewModel */ Ext.define("Terrasoft.configuration.ActivitySectionGridRowViewModel", { extend: "Terrasoft.BaseSectionGridRowViewModel", alternateClassName: "Terrasoft.ActivitySectionGridRowViewModel", /** * Возвращает значение всплывающей подсказки для элемента в расписании. * @return {String} Значение всплывающей подсказки для элемента в расписании. */ getScheduleItemHint: function() { var timeFormat = Terrasoft.Resources.CultureSettings.timeFormat; var startDate = Ext.Date.format(this.get("StartDate"), timeFormat); var dueDate = Ext.Date.format(this.get("DueDate"), timeFormat); var title = this.get("Title"); var account = this.get("Account"); var accountDisplayValue = (account) ? account.displayValue + ": " : ""; return Ext.String.format("{0}-{1} {2}{3}", startDate, dueDate, accountDisplayValue, title); }, /** * Возвращает статус элемента расписания. * @return {Terrasoft.ScheduleItemStatus} Статус элемента расписания. */ getScheduleItemStatus: function() { var isFinished = this.get("Status.Finish"); var dueDate = this.get("DueDate"); if (dueDate <= new Date() && !isFinished) { return Terrasoft.ScheduleItemStatus.OVERDUE; } else if (isFinished) { return Terrasoft.ScheduleItemStatus.DONE; } return Terrasoft.ScheduleItemStatus.NEW; }, /** * Возвращает значение заголовка элемента в расписании. * @return {String} Значение заголовка элемента в расписании. */ getScheduleItemTitle: function() { var title = this.get("Title"); var account = this.get("Account"); var accountDisplayValue = (account) ? account.displayValue + ": " : ""; return Ext.String.format("{0}{1}", accountDisplayValue, title); }, /** * inheritdoc Terrasoft.BaseGridRowViewModel#getEntitySchemaQuery */ getEntitySchemaQuery: function() { var esq = this.callParent(arguments); if (!esq.columns.contains("Status.Finish")) { esq.addColumn("Status.Finish"); } return esq; }, /** * inheritdoc Terrasoft.BaseViewModel#setColumnValues */ setColumnValues: function(entity) { this.set("Status.Finish", entity.get("Status.Finish")); this.callParent(arguments); }, /** * Обрабатывает событие изменения поля "Начало". * @protected * @param {Date} date Новое значение даты. */ onStartDateChanged: function(date) { this.set("StartDate", date); this, this.saveEntity(Terrasoft.emptyFn, this); }, /** * Обрабатывает событие изменения поля "Завершение". * @protected * @param {Date} date Новое значение даты. */ onDueDateChanged: function(date) { this.set("DueDate", date); this.saveEntity(Terrasoft.emptyFn, this); }, /** * Обрабатывает событие изменения поля "Заголовок". * @protected */ onTitleChanged: Terrasoft.emptyFn, /** * Обрабатывает событие изменения поля "Состояние". * @protected */ onStatusChanged: Terrasoft.emptyFn, getBackground: function() { var priority = this.get("Priority"); var activitySchedulerColor = ActivitySectionGridRowHelper.GetActivitySchedulerColor(priority.value); var backgroundColor = activitySchedulerColor.backgroundColor; return backgroundColor; }, getFontColor: function() { var priority = this.get("Priority"); var activitySchedulerColor = ActivitySectionGridRowHelper.GetActivitySchedulerColor(priority.value); var fontColor = activitySchedulerColor.fontColor; return fontColor; } }); return Terrasoft.ActivitySectionGridRowViewModel; });
Результат
В результате должно получится что-то вроде:
Для активности «Развернуть стенд» указан приоритет для которого не указан цвет в справочнике ActivitySchedulerColor. Соответственно, для него работает стандартная логика и он окрашивается в соответствии со своим статусом и временем.
Для приоритетов активностей «Позвонить клиенту» и «Написать Hello, World!» в справочнике ActivitySchedulerColor указан цвет, и они окрашиваются по добавленной логике.
Добрый день.
При реализации данного таска на шаге:
Шаг 4. Замещение модуля ActivitySectionGridRowViewModel.
появилась ошибка: "Замещение модулей запрещено".
Хотя в настройке модуля параметр "Запретить замещение" не установлен.
Можете подсказать, в чём может быть причина?
С 2016 года архитектура системы изменилась. Модули замещать запрещено, начиная с версии 7.13.1.