Всем привет! Кто-нибудь делал горизонтальную прокрутку в продуктах(детали)? Саму прокрутку сделала через css(overflow-x: scroll; и width), но теперь возникла проблема если много продуктов, не видно полосу прокрутки для самых первых(так как полоса находится в самом низу).  Возможно есть идеи как зафиксировать полосу прокрутки что она всегда была видна внизу  или  что-то другое? Заранее спасибо!

Нравится

2 комментария
Лучший ответ

Добрый день

Анастасия, scroll будет отображаться внизу контейнера, который "скролит свой контент". В данном случае деталь расширяет свою высоту, поэтому горизонтальный скролл уходит вниз. Вам нужно зафиксировать высоту контейнера детали, чтобы сам контейнер не менял высоту при отображении новых продуктов. Также, через css

Добрый день

Анастасия, scroll будет отображаться внизу контейнера, который "скролит свой контент". В данном случае деталь расширяет свою высоту, поэтому горизонтальный скролл уходит вниз. Вам нужно зафиксировать высоту контейнера детали, чтобы сам контейнер не менял высоту при отображении новых продуктов. Также, через css

спасибо, работает!

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

Всем привет! 

Подскажите пожалуйста может кто-то пользуется хорошим справочником по адресам(страна,город,улица) или знает где его можно загрузить/ получать дынные по вебсервису. Сейчас пользуемся данными из гугл карт, но может кто-то знает альтернативные варианты. 

Нравится

1 комментарий

Анастасия, добрый день! 

На данный момент официальным решением от компании Terrasoft является использование адресов сервиса OpenStreetMap. Вы можете подобрать альтернативные инструменты для работы с адресами в Вашем приложении Creatio на MarketPlace. Примеры таких инструментов: 

https://marketplace.terrasoft.ru/app/yandexmaps-field-sales-creatio

https://marketplace.terrasoft.ru/app/address-database-creatio

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

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

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

Расположение кнопки не имеет большого значения, нужно только вызвать мой метод по нажатию.

Нравится

5 комментариев
Лучший ответ

на страницу, в секцию атрибутов добавить, если надо вкл/выкл по условию

attributes: {
            
            "ButtonEnabled": {
                "dataValueType": Terrasoft.DataValueType.BOOLEAN,
                "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                "value": false
            }

Вызов функции на кнопке

  onButtonClick: function(){ 
                this.SomeFunc();

Сама кнопка в DIFF            

    {
                "operation": "insert",
                "name": "Button",
                "values": {
                    "itemType": 5,
                    "caption": {
                        "bindTo": "Resources.Strings.ButtonCaption"
                    },
                    "click": {
                        "bindTo": "onButtonClick"
                    },
                    "style": "blue",
                    "enabled": {
                        "bindTo": "ButtonEnabled"
                    },
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 0,
                        "layoutName": "Tab72b43268TabLabelGridLayoutfb645753"
                    }
                },
                "parentName": "Tab72b43268TabLabelGridLayoutfb645753",
                "propertyName": "items",
                "index": 0
            },

В LocalizableString
ButtonCaption    - Текст на кнопке

Если расположение кнопки не имеет значения, то можно использовать меню в "Действиях" 

 

			getActions: function() {
				var actionMenuItems = this.callParent(arguments);
				actionMenuItems.addItem(this.getButtonMenuItem({
					"Caption": {"bindTo": "Resources.Strings.MyButtonCaption"},
					"Click": {"bindTo": "onMyButtonClick"}
				}));
				return actionMenuItems;
			},

 

на страницу, в секцию атрибутов добавить, если надо вкл/выкл по условию

attributes: {
            
            "ButtonEnabled": {
                "dataValueType": Terrasoft.DataValueType.BOOLEAN,
                "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                "value": false
            }

Вызов функции на кнопке

  onButtonClick: function(){ 
                this.SomeFunc();

Сама кнопка в DIFF            

    {
                "operation": "insert",
                "name": "Button",
                "values": {
                    "itemType": 5,
                    "caption": {
                        "bindTo": "Resources.Strings.ButtonCaption"
                    },
                    "click": {
                        "bindTo": "onButtonClick"
                    },
                    "style": "blue",
                    "enabled": {
                        "bindTo": "ButtonEnabled"
                    },
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 0,
                        "layoutName": "Tab72b43268TabLabelGridLayoutfb645753"
                    }
                },
                "parentName": "Tab72b43268TabLabelGridLayoutfb645753",
                "propertyName": "items",
                "index": 0
            },

В LocalizableString
ButtonCaption    - Текст на кнопке

Oleg,

Кнопка добавилась, и даже отображается в инспекторе, но при этом она  абсолютно невидима. В enabled установлено true.
В вашем коде изменил только родительский контейнер и, соответственно, layoutName. У других элементов на странице тот же родитель

Гусейн Гулиев,

В LocalizableStrings добавили? 

Oleg,

Спасибо большое, Олег. Хотел ответить "захардкодил", потом заметил, что захардкодил неправильно, но оставлю тут этот неправильный пример, на случай если кто столкнется в будущем.

{
	"operation": "insert",
	"name": "Button",
	"values": {
		"itemType": 5,
		"caption": {// Правильно: "caption" :"Check out",
			"bindTo": "Check out" // неправильное использование bindTo
		},
		"click": {
			"bindTo": "onButtonClick"
		},
		"style": "blue",
		"enabled": true,
		"layout": {
			"colSpan": 8,
			"rowSpan": 1,
			"column": 16,
			"row": 6,
			"layoutName": "Tab84fbfd75TabLabelGridLayout489fb6f3"
		}
	},
	"parentName": "Tab84fbfd75TabLabelGridLayout489fb6f3",
	"propertyName": "items",
	"index": 6
},

 

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

Здравствуйте сообщество,

Подскажите, пожалуйста, способ запуска серверного кода (C#) со страницы клиента (JS).
Бизнес-процесс имеет задержку при запуске, поэтому данный способ не лучшее решение.

 

Заранее благодарю.
Мария.

Нравится

1 комментарий
Лучший ответ
Показать все комментарии

Возникла необходимость редактирования детали "Средства связи" в разделе контакты.  Через мастер деталей это невозможно, т.к деталь неизменяема. Остается вариант с изменением исходного кода. Как можно заместить/редактировать необходимый модуль? В частности необходимо изменить код (или заместить на другой модуль) в модуле ContactCommunicationDetailV2.  

Нравится

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

Доброе утро.

 

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

Реализовать новую деталь можете через мастер, а вносить уже все необходимые в неё изменения в конфигурации.

 Алла Савельева,

Спасибо за ответ! И все таки: каким образом будет грамотнее заменить существующий клиентский модуль  на кастомный? С сохранением ключевых зависимостей, но изменением кода.

Тимур Макаев,

 

Возможны оба варианта: иногда нужно сохранить ключевые зависимости, иногда - нет.

Также возможен вариант, когда лучшим решением будет сделать свою таблицу и на её основании разрабатывать требуемую логику.

А чтобы отобразить уже внесенные данные, их можно перенести в новую таблицу с помощью запросов на уровне базы данных.

Всё зависит от того, насколько сильно будет изменена базовая логика.

Создаем новый модуль, например:

define("UsrBaseCommunicationViewModel", ["ext-base",
	"terrasoft", "UsrBaseCommunicationViewModelResources",
	"BaseCommunicationViewModel",],
	function(Ext, Terrasoft, resources, BaseCommunicationViewModel) {
		Ext.define("Terrasoft.configuration.UsrBaseCommunicationViewModel", {
			extend: "Terrasoft.BaseCommunicationViewModel",
			alternateClassName: "Terrasoft.UsrBaseCommunicationViewModel",
			methodName: function(value) { //метод, который нужно заместить в базовой логике
 
			},
		});
	});

Подключаем этот модуль в базовую деталь (создав замещающую страницу):

define("BaseCommunicationDetail", ["UsrBaseCommunicationViewModel"], function(UsrBaseCommunicationViewModel) {
	return {
		attributes: {
		},
		methods: {
			init: function(callback, scope) {
				this.set("BaseCommunicationViewModelClassName", "Terrasoft.UsrBaseCommunicationViewModel");
				this.callParent(arguments);
			},
		},
		diff: /**SCHEMA_DIFF*/[
		]/**SCHEMA_DIFF*/
	};
});

Естественно делаем все на свой страх и риск.

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

Здравствуйте community,

 

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

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

 

 

Заранее спасибо за ваши идеи.

Нравится

1 комментарий
Лучший ответ

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

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

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

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

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

Коллеги подскажите пожалуйста есть необходимость в окружение добавить пользовательский компонент и получать к нему доступ через Terrasoft.{пользовательский компонент}. 

Трудность заключается в том, что данные компонента находятся в БД и на данный момент получаются с помощью конфигурационного сервиса. Сам компонент заполняется  в callback функции. То есть доступен не сразу, а только после получения ответа от сервиса.

Каким образом можно создать компонент например при инициализации сессии пользователя либо при первичной загрузки интерфейса?

Нравится

1 комментарий

Егор, а в чём отличие Вашего компонента от какой-то стандартной функциональности, например, AcademyUtilities? Там тоже в функции getAcademyUrlFromLookup получают данные из базы по SQ, что происходит не мгновенно.

/**
 * Gets academy URL from lookup.
 * @private
 * @param {Object} config Configuration object.
 * @param {Function} config.callback Callback function.
 */
getAcademyUrlFromLookup: function(config) {
	var cacheItemName = "AcademyURL_" + Terrasoft.currentUserCultureName;
	var getLmsUrlQuery = Ext.create("Terrasoft.EntitySchemaQuery", {
		rootSchemaName: "AcademyURL",
		rowCount: 1,
		serverESQCacheParameters: {
			cacheLevel: Terrasoft.ESQServerCacheLevels.WORKSPACE,
			cacheGroup: "AcademyUtilities",
			cacheItemName: cacheItemName
		}
	});
	getLmsUrlQuery.clientESQCacheParameters = {cacheItemName: cacheItemName};
	getLmsUrlQuery.addColumn("Description", "Description");
	getLmsUrlQuery.getEntityCollection(function(response) {
		var collection = response.collection;
		var academyRootUrl = "";
		if (collection.getCount()) {
			academyRootUrl = collection.first().get("Description");
		}
		Ext.callback(config.callback, this, [academyRootUrl]);
	}, this);
}

Или под компонентом имеете в виду что-то другое, вроде виджета в итогах или iframe на главной странице?

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

Приветствую! 

Недавно занялся изучением и работой с платформой Creatio. По тому по коду прошу не ругать ;) 
 

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

Код реализации с getEntity:

var message;
 
var recordId = this.get("Id");
 
if(recordId) {
		var esq1 = this.Ext.create("Terrasoft.EntitySchemaQuery", {
						rootSchemaName: "UsrSwimmProgramm"
		});
 
		var filterA = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPBooleanActive" , 1);
		var filterP = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPLookupPeriod.Name" , "Ежедневно");
		esq1.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
		esq1.filters.add("filterA",filterA);
		esq1.filters.add("filterP",filterP);
 
		esq1.addAggregationSchemaColumn("Id", Terrasoft.AggregationType.COUNT, 
						"NumberDayLesson", Terrasoft.AggregationEvalType.ALL);
 
 
				esq1.getEntity(recordId, function(result) {
					if (!result.success) {
						this.showInformationDialog("Ошибка запроса");
						return;
					}
					message = result.entity.get("NumberDayLesson") + "\n";
				this.showInformationDialog(message);
				}, this);
 
				}

Код реализации с getEntityCollection:

var message;
var recordId = this.get("Id");
 
if(recordId) {
			var esq1 = this.Ext.create("Terrasoft.EntitySchemaQuery", {
						rootSchemaName: "UsrSwimmProgramm"
				});
 
				var filterA = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPBooleanActive" , 1);
				var filterP = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPLookupPeriod.Name" , "Ежедневно");
				esq1.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
				esq1.filters.add("filterA",filterA);
				esq1.filters.add("filterP",filterP);
 
				esq1.addAggregationSchemaColumn("Id", Terrasoft.AggregationType.COUNT, 
						"NumberDayLesson", Terrasoft.AggregationEvalType.ALL);
 
				esq1.getEntityCollection( function(result){
					message = result.collection.getByIndex(0).get("NumberDayLesson");
					this.showInformationDialog(message);
				},this);
 
	}

 

Так вот, почему при всех равных метод getEntity выдает не определенной значение, а вот с getEntityCollection все работает норм ? 

 

 

Нравится

2 комментария
Лучший ответ

Добрый вечер.

 

Метод getEntity используется для получения одной строки набора данных по заданному первичному ключу.

И в Вашем случае этот метод не срабатывает, потому что в заданном наборе данных не находит запись по этому recordId. Фактически, при использовании этого метода Вы добавляете ещё один фильтр по полю Id записи.

 

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

Добрый вечер.

 

Метод getEntity используется для получения одной строки набора данных по заданному первичному ключу.

И в Вашем случае этот метод не срабатывает, потому что в заданном наборе данных не находит запись по этому recordId. Фактически, при использовании этого метода Вы добавляете ещё один фильтр по полю Id записи.

 

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

Спасибо большое, Алла. Уже смотрю.

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

Доброго времени суток!
Допустим, у меня есть раздел "Автомобили" с возможностью добавления новых автомобилей. В клиентской части мне необходимо отловить событие после добавления новой записи в этот раздел и добавить дополнительную логику на фронте. Думаю, должно быть что-то вроде "onItemInserted". Подскажите, пожалуйста,  как это лучше реализовать или какое название метода, который отрабатывает после вставки. Заранее благодарен.

Нравится

3 комментария
Лучший ответ

Добрый день!

 

На клиентской части в карточке редактирования Вы можете переопределить метод BasePageV2#onSaved

onSaved: function() {
	this.callParent(arguments);
},

Обратите внимание, если Вам нужно производить какие-то манипуляции с данными (пересчеты/обновления в других объектах и т.д.), то лучше использовать подход сигналов/событий объекта, тк при обработке на клиенте обрабатываться будет только "ручной" ввод, а во время импортов/интеграций/БП это логика останется "за бортом"

Добрый день!

 

На клиентской части в карточке редактирования Вы можете переопределить метод BasePageV2#onSaved

onSaved: function() {
	this.callParent(arguments);
},

Обратите внимание, если Вам нужно производить какие-то манипуляции с данными (пересчеты/обновления в других объектах и т.д.), то лучше использовать подход сигналов/событий объекта, тк при обработке на клиенте обрабатываться будет только "ручной" ввод, а во время импортов/интеграций/БП это логика останется "за бортом"

Если учитывать изменения на объекте процессами, интеграциями (или одновременно разными пользователями), лучше реализовать логику на событии вставки на уровне БП, а затем на сторону браузера передавать по ClientMessageBridge.

Лопатин Константин, Благодарю за совет! 

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

Доброго времени суток.

Возникла проблема при разработке клиентского модуля - необходимо динамически менять "родителя" детали в зависимости от условий.

В случае, если на карточке редактирования присутствует вкладка с определенным ключом - необходимо "привязать" к ней деталь из diff (код ниже)
В случае, если вкладка найдена не была - добавить вкладку с привязкой детали (то есть выполнить процедуру вставки на основе diff)

Есть ли возможность динамически изменить свойство "parentName" у детали? (или как получить объектное представление детали для изменения свойства)

define("SomeModuleName", [], function() {
    return {
    details: {
        "DetailName": {
            "schemaName": "schemaName",
            "entitySchemaName": "entitySchemaName",
            "filter": {
                "detailColumn": "detailColumn",
                "masterColumn": "Id"
            }
        }
    },
    diff: /**SCHEMA_DIFF*/[ 
        {
            "operation": "insert",
            "name": "AddedTabName",
            "values": {
                "items": [],
                "caption": {
                    "bindTo": "Resources.Strings.AddedTabNameCaption"
                },
            },
            "parentName": "Tabs",
            "propertyName": "tabs",
            "index": 1
        },
    {
        "operation": "insert",
        "name": "CardDetail",
        "values": {
            "itemType": this.Terrasoft.ViewItemType.DETAIL,
            "visible": { "bindTo": "CardDetailVisible" }
        },
        "parentName": "AddedTabName",
        "propertyName": "items",
        "index": 0
        },
    ]/**SCHEMA_DIFF*/,
    methods: {
        onEntityInitialized: function() {
            this.callParent(arguments);
            // myMethodToUpdateVisibility();
        },
        }
    };
});

Вкладка (tab) на которую надо перенести деталь также динамически (также из кода клиентского модуля) добавляется сторонним пакетом.

Спасибо

Нравится

3 комментария
Лучший ответ

Добрый день! Возможно, проще добавить 2 детали на разные вкладки, и в зависимости от условий ненужное скрывать, чем динамически вставлять\перемещать

Добрый день! Возможно, проще добавить 2 детали на разные вкладки, и в зависимости от условий ненужное скрывать, чем динамически вставлять\перемещать

Лопатин Константин,

Спасибо за ваш вариант, попробую такой подход.

или как предложил Лопатин Константин или технически есть возможность закидывать и изымать элемент через ext, если вам вдруг не хватает геморроя в вашем проекте)

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