Вопрос

Как добавить или изменить CSS стиль

Ответ

Чтобы добавить любой необходимый стиль необходимо:

1) Создать новый модуль. Добавить css стиль на вкладку Less. Рекомендуется использовать следующую структуру:

body[OldUI=false][CustomUI="true"] {
    .control-width-15 .t-label {
        color: #7FFF00;
    }
}

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

2) Создайте необходимую замещающую страницу используя пункт "Замещающий клиентский модуль". Например, необходимо заместить модуль BasePageV2. Добавьте модуль из первого шага в define замещающей страницы.

Переопределите метод init() и вызовите метод setAttributeToBody() чтобы добавить ваш стиль к body.

define("BasePageV2", ["css!UsrBasePageV2CSS"],
    function() {
        return {
            messages: {},
            mixins: {},
            attributes: {},
            methods: {
                init: function() {
                    this.callParent(arguments);
                    this.initializeCustomCss();
                },
                initializeCustomCss: function() {
                    Terrasoft.utils.dom.setAttributeToBody("CustomUI", true);
                }
            },
            diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
        };
});

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

3) Обновите страницу.

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

Нравится

Поделиться

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

Это применяется во всех разделах. Если это необходимо в одном разделе, этот вариант не работает

А если замещать не BasePageV2, а свою страницу?

В конфигурации достаточно схем с названиями, оканчивающимися на CSS, в которых вносятся изменения стилей для конкретных схем. Например, AccountRelationshipDetailCss добавляет стили, специфичные для этой детали:

.account-relationship.detail {
	.relationship-mode-button {
		border-top-right-radius: 1px;
		border-bottom-right-radius: 1px;
	}
	.datagrid-mode-button {
		border-top-left-radius: 1px;
		border-bottom-left-radius: 1px;
	}
	.relationship-mode-button, .datagrid-mode-button {
		padding-left: 0.308em;
		padding-right: 0.462em;
	}
	.mode-button-pressed {
		background: #e4eaf9;
	}
	.account-relationship-chart {
		height: 450px;
	}
}

Затем в основной схеме этой детали AccountRelationshipDetailV2 подключается эта схема со стилями:

define("AccountRelationshipDetailV2", ["AccountRelationshipDetailV2Resources", "MiniPageUtilities",
	"ConfigurationDiagramGenerator", "RelationshipDiagramViewModel", "RelationshipDiagram",
	"LookupQuickAddMixin", "RelationshipChartGenerator", "RelationshipChart",
	"css!AccountRelationshipDetailCss"
], function() {

И так для конкретного элемента, например, кнопки, использовать стили оттуда:

{
 "operation": "insert",
 "name": "RelationshipModeButton",
 "parentName": "Detail",
 "propertyName": "tools",
 "values": {
	"itemType": this.Terrasoft.ViewItemType.BUTTON,
	"hint": {"bindTo": "Resources.Strings.DiagramViewButtonHint"},
	"click": {
		"bindTo": "setRelationshipMode"
	},
	"visible": {
		"bindTo": "getModeButtonsVisible"
	},
	"pressed": {
		"bindTo": "getRelationshipButtonPressed"
	},
	"classes": {
		"wrapperClass": ["relationship-mode-button"],
		"pressedClass": ["mode-button-pressed"]
	},
	"controlConfig": {
		"imageConfig": {
 "bindTo": "Resources.Images.RelationshipViewIcon"
		}
	},
	"markerValue": relationshipMode.Relationship
 }
{

 

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

Вопрос

В разделе Активности, вкладке «Связи» необходимо убрать привязку к Документам и Лидам. 

Ответ

Запрошенные колонки можно удалить из детали «Связи» для Активностей, следующим запросом в базу данных:

DELETE FROM EntityConnection WHERE SysEntitySchemaUId = 'c449d832-a4cc-4b01-b9d5-8a12c42a9f89'
AND (ColumnUId = 'd6e94162-4354-413a-bc84-e118df5e852e'
OR ColumnUId = 'f6137557-741e-42f8-8bf6-69b2524a83f7')

 

Нравится

Поделиться

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

Дополню.

 

Id колонки смотреть в SysEntitySchemaReference.ColumnUId

например,

select distinct ColumnName , ColumnUId from SysEntitySchemaReference
where SysSchemaId in (select id from SysSchema where Name = 'Activity')
order by ColumnName

 

Id объекта будет в выборке

select [UId] from SysSchema where Name = 'Activity'

 

Доброго времени суток! А если скрыть, не удалять? 

Алексей, добрый день! 

 

Можете переопределить\доработать метод: loadColumnValues

Если из коллекции, после получения данных, но до её перебора “collection.each(function(item)…” удалить какой-то элемент, к примеру:

collection.collection.removeAt(1);

То этот элемент связи не будет обработан и показан на детали.

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

Вопрос

Как отключить сборку клиентских скриптов в all-combined.js

Ответ

Для решения данного вопроса необходимо в Web.config (...\Terrasoft.WebApp\) добавить ключ в блок .

Хотелось бы отметить, что данное изменение в приложение повлияет на производительность приложения в целом.

Для увеличения производительности как раз и был создан all-combined.js.

Нравится

Поделиться

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

Вопрос

Подскажите пожалуйста, как сделать поле-выпадающий список из поля-справочника в редактируемом реестре версии 7.7.0.2293 SalesEnterprise + Marketing + CustomerCenter? Я сделал редактируемый реестр активностей, в карточке активности поле "Состояние" - выпадающий список. Но в редактируемом реестре это же поле представляет собой классический лукап с открываюшимся лукапным окном.

P.S. Решение полезно если страницы редактирования нет, или их много, или они базовые.

Ответ

Можно переопределить метод generateActiveRowControlsConfig() в схеме детали, и в нужных случаях, передавать нужный дополнительный конфиг.

В вашем случае можно добавить:

if (columnName = "Status") {
 
   cellConfig.contentType = Terrasoft.ContentType.ENUM;
 
}

Сразу после создания в нем cellConfig.

Исходный код можно взять из схемы ConfigurationGridUtilities, если он отличается от того что будет в предоставленном примере.

Пример схемы детали, на которой все тестировалось, включая превращение грида в редактируемый и переопределение generateActiveRowControlsConfig:

define("UsrSchema1Detail", ["terrasoft", "BusinessRulesApplierV2", "ConfigurationEnums", "BusinessRuleModule",
    "GridUtilitiesV2", "ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities"], function(
        Terrasoft, BusinessRulesApplier, ConfigurationEnums, BusinessRuleModule) {
    return {
        entitySchemaName: "Activity",
        attributes: {
         "IsEditable": {
            dataValueType: Terrasoft.DataValueType.BOOLEAN,
            type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
            value: true
         }
        },
        mixins: {
         ConfigurationGridUtilites: "Terrasoft.ConfigurationGridUtilities"
        },
        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[
            {
            "operation": "merge",
            "name": "DataGrid",
            "values": {
               "className": "Terrasoft.ConfigurationGrid",
               "generator": "ConfigurationGridGenerator.generatePartial",
               "generateControlsConfig": {"bindTo": "generatActiveRowControlsConfig"},
               "changeRow": {"bindTo": "changeRow"},
               "unSelectRow": {"bindTo": "unSelectRow"},
               "onGridClick": {"bindTo": "onGridClick"},
               "activeRowActions": [
                  {
                     "className": "Terrasoft.Button",
                     "style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                     "tag": "save",
                     "markerValue": "save",
                     "imageConfig": {"bindTo": "Resources.Images.SaveIcon"}
                  },
                  {
                     "className": "Terrasoft.Button",
                     "style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                     "tag": "cancel",
                     "markerValue": "cancel",
                     "imageConfig": {"bindTo": "Resources.Images.CancelIcon"}
                  },
                  {
                     "className": "Terrasoft.Button",
                     "style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                     "tag": "remove",
                     "markerValue": "remove",
                     "imageConfig": {"bindTo": "Resources.Images.RemoveIcon"}
                  }
               ],
               "initActiveRowKeyMap": {"bindTo": "initActiveRowKeyMap"},
               "activeRowAction": {"bindTo": "onActiveRowAction"},
               "multiSelect": false
            }
         }
        ]/**SCHEMA_DIFF*/,
        methods: {
            generateActiveRowControlsConfig: function(id, columnsConfig, rowConfig) {
                this.columnsConfig = columnsConfig;
                var gridLayoutItems = [];
                var currentColumnIndex = 0;
                this.Terrasoft.each(columnsConfig, function(columnConfig) {
                    var columnName = columnConfig.key[0].name.bindTo;
                    var column = this.getColumnByColumnName(columnName);
                    var cellConfig = this.getCellControlsConfig(column);
 
                    cellConfig = this.Ext.apply({
                        layout: {
                            colSpan: columnConfig.cols,
                            column: currentColumnIndex,
                            row: 0,
                            rowSpan: 1
                        }
                    }, cellConfig);
 
                    if (columnName = "Status") {
                        cellConfig.contentType = Terrasoft.ContentType.ENUM;
                    }
 
                    gridLayoutItems.push(cellConfig);
                    currentColumnIndex += columnConfig.cols;
                }, this);
                var gridData = this.getGridData();
                var activeRow = gridData.get(id);
                var rowClass = {prototype: activeRow};
                BusinessRulesApplier.applyRules(rowClass, gridLayoutItems);
                var viewGenerator = this.Ext.create("Terrasoft.ViewGenerator");
                viewGenerator.viewModelClass = {prototype: this};
                var gridLayoutConfig = viewGenerator.generateGridLayout({
                    name: this.name,
                    items: gridLayoutItems
                });
                rowConfig.push(gridLayoutConfig);
            },
        }
    };
});

 

Нравится

Поделиться

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

Симптомы

Bpm'online mobile bug report

Type: Terrasoft.SourceCodeException

Message: TypeError: undefined is not an object (evaluating 'columnConfig.columnType')

Причина

Ошибка возникает из-за того, что Вы не верно настроили параметры встроенной деталей, например, в разделе «Объекты».

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

Рис. 1

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

Рис. 2

Решение

Для решения необходимо корректно настроить все детали.

Например, как настроить деталь «Файлы и примечания» в разделе «Лиды»:

- Для отображения в мобильном приложении необходимо выбрать деталь «Файлы и ссылки Лида»

- В поле «Колонка детали» указать «Лид»

- В поле «Колонка объекта Лид» указать «Id»

Также как примеры можно посмотреть как реализованы детали в других разделах.

Следует обратить внимание, что в результате данная деталь будет работать в основном для отображения названия файлов и работы с веб-ссылками.

Например, Вы может попробовать следующие настройки детали:

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

Рис. 3

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

Рис. 4

Нравится

Поделиться

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

Вопрос

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

Мне нужно открывать справочник, не связанный со страницей, и перед этим ещё могут потребоваться доп. действия. Просто справочным полем не получится это реализовать.

Есть возможность поместить кнопку именно где-то посреди страницы? Действие для пользователя будет довольно неудобным. Или это принципиально невозможно?

Коммьюнити - https://community.terrasoft.ru/questions/dobavit-knopku-na-stranicu-redaktirovania-v-mobilnom-prilozenii

Ответ

Можете посмотреть алгоритм реализации в похожем топике: https://community.terrasoft.ru/questions/dobavlenie-kastomnyh-elementov-v-mobilnom-prilozenii

Например, в конфиге вью определяем нужный контрол + метод для его отображения, а в контроллере завязываем на него обработчик:

Ext.define("...вью...", {
    config: {
       refreshButton: {
            id: 'usr_order_refresh_btn',
            cls: "x-button-primary-blue",
            text: 'Обновить'
        }
    },
    showRefreshButton: function (isShow) {
        var navigationPanel = this.getNavigationPanel(); /*компонент в котором нужно отобразить контрол*/
        var refreshButton = this.getRefreshButton();
        if (isShow) {
            this._refreshButton = navigationPanel.addButton(refreshButton);
        } else {
            navigationPanel.removeButton(refreshButton);
        }
        return this._refreshButton;
    }
});
Ext.define("...контроллер...", {
    initializeView: function (view) {
        this.callParent(arguments);
        var btn = view.showRefreshButton(true);
        btn.on("tap", this.onRefreshButtonTap, this);
    },
    onRefreshButtonTap: function() {
        /* сабж */
    }
});

Если нужно открыть пикер для выбора значения, то посмотрите MobileActivityGridPageControllerV2. Там много пример открытия пикеров. Например, для выбора «Ответственного» (метод getEmployeePicker()

) или выбора режима расписания (метод getGridModePicker()).

Нравится

Поделиться

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

Вопрос

Кейс:

На данный моментсинхронизация не завершается успешно, из-за того, что в приложении (в разделе «Активности») присутствуют большое количество  файлов, которое мобильное приложение пытается засинхронизировать и в результате завершается с ошибкой по таймауту.

Входе анализа выяснилось, что основной тип файлов это изображения, которые присутствуют в подписи писем (имеют название «image»).

Можно ли настроить так фильтрацию, чтобы мобильное приложение не затягивало лишние файлы?

Ответ

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

Добавить в манифест мобильного приложения (MobileApplicationManifestDefaultWorkplace) следующий код:

{
    "SyncOptions": {
        "SysSettingsImportConfig": [],
        "ModelDataImportConfig": [
            {
                "Name": "ActivityFile",
                "SyncFilter": {
                    "property": null,
                    "valueIsMacros": false,
                    "value": null,
                    "isNot": true,
                    "type": "Terrasoft.FilterTypes.Group",
                    "logicalOperation": "Terrasoft.FilterLogicalOperations.Or",
                    "subfilters": [
                        {
                            "property": "Name",
                            "funcType": "Terrasoft.FilterFunctions.SubStringOf",
                            "funcArgs": ["image"] //по какому слову не будут попадать значения
                        },
                        {
                            "property": "Activity.Owner",
                            "isNot": true,
                            "valueIsMacros": true,
                            "value": "Terrasoft.ValueMacros.CurrentUserContact"
                        }
                    ]
                }
            }
        ]
    },
    "Modules": {},
    "Models": {}
}

Если это продукт FieldForce, то также необходимо добавить этот же код в манифест "MobileApplicationManifestFieldForceWorkplace".

Нравится

Поделиться

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

Вопрос

Как сделать все элементы детали Адреса на странице Контрагента недоступными для редактирования? Версия 7.2.0.

Ответ

Пример реализации функционала для схемы AddressDetail:

1) можно добавить новый метод enableDetailControls:

this.methods.enableDetailControls = function(viewConfig, enabled) {
    if (!viewConfig.items) {
        return;
    }
    viewConfig.items.forEach(function(item) {
        item.enabled = enabled;
    }, this);
};

2) далее вызвать этот метод внутри метода getCustomItemView после полного формирования конфигурации представления, добавив необходимые условия. Например, перед строкой return viewConfig:

this.methods.getCustomItemView = function(viewModel, itemKey, action, types, itemViewModel) {
    var viewConfig = {};
    ...
    var enableControls = (action === "edit") && (/*любые другие условия*/);
    this.enableDetailControls(viewConfig, enableControls);
    return viewConfig;
};

Очень желательно до этого момента уже получить значения необходимых условий, так как после выполнения getCustomItemView управление передаётся в модуль базовой детали (DetailModule), в котором уже выполняется привязка модели к представлению и рендеринг детали.

Нравится

Поделиться

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

Создаем мультилукапное поле. В текущем примере - поле "Клиент", в котором мы сможем выбирать либо Контакт, либо Контрагент.

1. В объект добавляем справочные поля, которые будет содержать в себе наше мультилукапное поле. В нашем примере это Контакт(UsrContact) и Контрагент(UsrAccount).

2. Добавляем третье спрвочное поле, из которого мы сделаем мультилукап. В нашем примере Клиент(UsrClient). Изначально оно может ссылаться на любой справочник.

3. В схему страницы редактирования добавляем описанный ниже кусок кода в блок attributes{}

attributes: {
    "UsrClient": { // поле, в котором создаем мультилукап
        "caption": "Клиент",  // название поля, которое отображается на странице
        "dataValueType": this.Terrasoft.DataValueType.LOOKUP,
        "multiLookupColumns": ["UsrContact", "UsrAccount"]  // перечисляем созданные нами колонки, которые будет содержать мультилукап
    }
}

 

Нравится

Поделиться

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

Вопрос

OData. Как передать параметр со значением NULL

Ответ

PUT http://e-podkovka:9848/0/ServiceModel/EntityDataService.svc/ContactCollection(guid'40f52013-48df-4009-b492-20794e6cb313')HTTP/1.1
Accept: application/atom+xml
Content-Type: application/atom+xml;type=entry;
Host: e-podkovka:9848
Content-Length: 448
Expect: 100-continue
Connection: Keep-Alive
Cookie: BPMSESSIONID=fahxnyitfahzhiryyqwx15fx; BPMLOADER=r543kelbmnri2mqivvfb5opj; .ASPXAUTH=8511A66857D2D6371FD2E76B7FB7EF2FADBC44C2E7E7D7B802171CDE3A12BF4DEB539193184F19DEEA2C9EF01B91DB2B7057748DB8BA843A7264501446C19936C63BD84AEC1E879AAD0FF24194163974B17967E5F9775ADFBD0020EC0E7D89D9E87259680E35183507555DCBF3824C2C25A1ADB44D502FBABF6F7037BC56A35DD574C85D74C0234159ABD87FC6A5E1E280B0F9137DF527A9A66854FE943E4B65E8B9E61AA6190FAB804970BC7B85A1B695528809C35B46D491D942FAC3ECE31635D29FB60481E852FF397F52C4F8AF42E4B8D3582293761C35A32B7F2D7F518D2D1E6F48BB7C1F54BF2EFE584D8FA84C9EA0EF97FAEAD656FCD2C0D48B81884A61EA26D21CC5ED5D96938370BC10B6CE6AEE62867690600013591F1A8D85C9C05CCC0660D6FE2254C7690FC7D4FD6CFF096DD56E98A0C42515BD19B37A25806BD619581FB6F966D30EB4E19EE03AA2D9883F2230C0221E9C3A61743F747F2307E2B5AE25; UserName=83|117|112|101|114|118|105|115|111|114
 
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<properties
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<d:Name>New name4</d:Name>
<d:JobId m:null="true" />
</properties>
</content>
</entry>

 

Нравится

Поделиться

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