Вопрос

Делаю запрос к БД из элемента "Задание-сценарий":

 

var userConnection = Get<UserConnection>("UserConnection");
var group = Get<string>("ProcessSchemaParameter1");
 
string selectID = ((Select)new Select(userConnection)
   .Column("t1", "SysAdminUnitId")
   .From("SysAdminUnitInRole").As("t1")
   .Join(JoinType.Inner, "SysAdminUnitInRole").As("t2")
   .On("t2", "SysAdminUnitInRole").IsEqual("3DAFC997-65E9-47E4-9434-F036077D66F4")
   .And("t1","SysAdminUnitId").IsEqual("t2","SysAdminUnitId")
   .Where("t1", "SysAdminUnitRoleId").IsEqual(group)).ExecuteScalar<string>();
string contact = ((Select)new Select(userConnection)
	.Column("ContactId")
	.From("SysAdminUnit")
	.Where("Id").IsEqual(selectID)).ExecuteScalar<string>();
 
Set("ProcessSchemaParameter1", contact); 
 
return true;

И тут появилось 2 момента:

1) как записать в параметр процесса результат (не текстом, а полноценным id)

2) при использовании такого кода выдает ошибки:

Invalid column name '3DAFC997-65E9-47E4-9434-F036077D66F4'

Invalid column name 'a7e3d18a-0f2d-444d-be2b-cd625dc3c097'

Invalid column name 'SysAdminUnitInRole'

Нравится

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

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

1. Invalid column name '3DAFC997-65E9-47E4-9434-F036077D66F4'

IsEqual("3DAFC997-65E9-47E4-9434-F036077D66F4") замените на 
IsEqual(Column.Parameter(new Guid("3DAFC997-65E9-47E4-9434-F036077D66F4")))

2. Invalid column name 'a7e3d18a-0f2d-444d-be2b-cd625dc3c097'

IsEqual(group) на
IsEqual(Column.Const(group))

Аналогично и с IsEqual(selectID)

3. Invalid column name 'SysAdminUnitInRole'

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

Относительно первого вопроса: по-моему, Вы неправильно получаете нужные Вам значения. Как это делать можно посмотреть в таких постах: https://community.terrasoft.ru/articles/bpmonline-kak-opredelit-avlaetsa-li-tekusii-polzovatel-administratorom и https://community.terrasoft.ru/questions/pravilnoe-ispolzovanie-dbexecutor

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

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

1. Invalid column name '3DAFC997-65E9-47E4-9434-F036077D66F4'

IsEqual("3DAFC997-65E9-47E4-9434-F036077D66F4") замените на 
IsEqual(Column.Parameter(new Guid("3DAFC997-65E9-47E4-9434-F036077D66F4")))

2. Invalid column name 'a7e3d18a-0f2d-444d-be2b-cd625dc3c097'

IsEqual(group) на
IsEqual(Column.Const(group))

Аналогично и с IsEqual(selectID)

3. Invalid column name 'SysAdminUnitInRole'

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

Относительно первого вопроса: по-моему, Вы неправильно получаете нужные Вам значения. Как это делать можно посмотреть в таких постах: https://community.terrasoft.ru/articles/bpmonline-kak-opredelit-avlaetsa-li-tekusii-polzovatel-administratorom и https://community.terrasoft.ru/questions/pravilnoe-ispolzovanie-dbexecutor

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

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

Спасибо за помощь, это помогло мне решить проблему

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

Всем доброго времени суток. Версия 7.12.

На странице Обращений есть удобный способ подстановки в текст письма изображения - непосредственно из буфера обмена.

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

Можно ли сделать такую же штуку для соседней вкладки - отправки сообщения на портал? Вставить изображение не удаётся, несмотря на то, что оно в буфере есть.

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

Нравится

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

Стандартно такой возможности нет. Разве что делать свою доработку. Можно вставить только картинку, уже опубликованную на каком-то сайте, если скопировать текст с картинкой из браузера. Аналогично и с лентой, см. обсуждение.

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

Всем доброго времени суток. Версия 7.12.

При открытии страниц Контакта и Контрагента возникают следующие ошибки в консоли:

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

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

Ошибки одинаковые, и в целом можно сказать, что каждая соответствует какой-либо из деталей, выведенных на странице Контакта.

Перед этим в бизнес-процессе ставили простановку, а в другом процессе - удаление прав на просмотр-редактирование-удаление контакта (конкретного) для пользователя (по id текущего). Далее процессы проверяли под пользователем-администратором, по умолчанию имеющим все права. Связана ли ошибка с этим?

Нравится

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

Смородинов Денис,

Тогда почему Вы считаете, что ошибка связана с правами доступа?

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

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

Я правильно понимаю, что эти ошибки возникают под обычным пользователем, а под пользователем с правами админа - нет?

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

и под админом тоже.

Смородинов Денис,

Тогда почему Вы считаете, что ошибка связана с правами доступа?

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

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

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

Всем доброго времени суток. Версия 7.12.2

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

Однако пакет всё равно не получается закоммитить в svn. Скриншот возможной ошибки: https://www.screencast.com/t/7BFlj3ty

Возможно есть какая-то инструкция, можно ли подключить к svn пакет после создания?

Нравится

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

Добрый день!



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



Все начальники входят в функциональную роль "Начальники".



Реализацию вижу следующим способом:

1) Считать группу ответственных

2) Найти контакт, который входит в эту группу и в группу "начальники"

3) Если этот контакт не совпадает с ответственным, запустившим БП, то передать его в параметр БП

4) Если контакт совпадает, то взять ParentRoleID и повторить поиск по новой группу+группа начальников, а затем уже передать найденный контакт в параметр БП

5) Если вышестоящей группы нет - тогда уже передать что есть (контакт, совпадающий с ответственным, запустившим БП)



Навыки владения C# скудны, поэтому прошу помощь в понимании следующих нюансов:

1) Как считать нужные данные

2) Как найти контакт, который входит в обе группы

3) Как передать найденное значение в параметр БП для его дальнейшего использования



Буду признателен за помощь.



 

Нравится

12 комментариев

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

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

Настраивать нужное условие фильтрации.

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

Любые мои варианты сделать фильтрацию провалились. Как сделать фильтр, если человек может быть в двух группах и мне нужно найти его? Было бы "или" - вопросов нет. Если предлагаете какой-то вариант - тогда предлагайте до конца. 



Поэтому возвращаемся к исходной задаче и к элементу [Задание-сценарий]. Просто документации с хорошо расписанными примерами просто нету, вот и прошу помощи

А что не так с «или»?

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

Мне надо найти пользователя, который входит сразу и в группу ответственных и в группу функциональную. Это никак не "или". Я не говорю что там нет "или", я говорю что в моей задаче надо "и". И вроде как в описании задачи это написано.

Было бы "или" - вопросов нет.

 Это никак не "или". Я не говорю что там нет "или", я говорю что в моей задаче надо "и".  

Вы всё же определитесь, что Вам надо. Напишите  SQL-запрос, которым бы хотели фильтровать записи, а потом уже думайте, как перевести на язык фильтров в дизайнере или на язык EntitySchemaQuery или Select в C#-скриптах.

Написал sql запрос, который находит нужный мне ID контакта (начальник отдела). Может по нему будет проще понять что же я хочу получить в итоге. Сами ID для поиска заранее определяются в БП:

A7E3D18A-0F2D-444D-BE2B-CD625DC3C097 - организационная роль

3DAFC997-65E9-47E4-9434-F036077D66F4 - функциональная роль

SELECT [ContactId]
 FROM [URFUbase].[dbo].[SysAdminUnit] where [id] in (SELECT distinct r1.[SysAdminUnitId]
 FROM [URFUbase].[dbo].[SysAdminUnitInRole] r1
	join [URFUbase].[dbo].[SysAdminUnitInRole] r2 on r2.SysAdminUnitRoleId = '3DAFC997-65E9-47E4-9434-F036077D66F4' and r1.[SysAdminUnitId]=r2.[SysAdminUnitId] 
 where r1.SysAdminUnitRoleId = 'A7E3D18A-0F2D-444D-BE2B-CD625DC3C097')

 

Такой запрос, наверное, будет делать при помощи класса Select. Там синтаксис почти полностью повторяет SQL.

И этот запрос, мне кажется, было бы логичнее вывернуть наизнанку, сделав выборку из SysAdminUnitInRole r1 корневой, а получение Id контакта — колонкой подзапроса или ещё одним join-ом.

 

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

UserConnection userConnection = Get&lt;UserConnection&gt;("UserConnection");
var group = Get&lt;Guid&gt;("ProcessSchemaParameter1");
var subSelect = new Select(userConnection).Column("r1", "SysAdminUnitId")
	.From("SysAdminUnitInRole").As("r1").Join("SysAdminUnitInRole").As("r2")
		.On("r2","SysAdminUnitInRole").IsEqual("3DAFC997-65E9-47E4-9434-F036077D66F4")
			.And("r1","SysAdminUnitId").IsEqual("r2","SysAdminUnitId").Where("r1","SysAdminUnitRoleId").IsEqual(group);
var Select = new Select(userConnection).Column("ContactId").From("SysAdminUnit").Where("Id").IsEqual(subSelect);
Set("ProcessSchemaParameter2", Select);
return true;

Очень нужна помощь в понимании того как делать правильно

var userConnection = Get&lt;UserConnection&gt;("UserConnection");
var group = Get&lt;string&gt;("ProcessSchemaParameter1");
 
string selectID = ((Select)new Select(userConnection)
   .Column("t1", "SysAdminUnitId")
   .From("SysAdminUnitInRole").As("t1")
   .Join(JoinType.Inner, "SysAdminUnitInRole").As("t2")
   .On("t2", "SysAdminUnitRoleId").IsEqual(Column.Parameter(new Guid("3DAFC997-65E9-47E4-9434-F036077D66F4")))
   .And("t1","SysAdminUnitId").IsEqual("t2","SysAdminUnitId")
   .Where("t1", "SysAdminUnitRoleId").IsEqual(Column.Const(group))).ExecuteScalar&lt;string&gt;();
var contact = ((Select)new Select(userConnection)
	.Column("ContactId")
	.From("SysAdminUnit")
	.Where("Id").IsEqual(Column.Const(selectID))).ExecuteScalar&lt;string&gt;();
 
Guid contactId = new Guid (contact);
Set("ProcessSchemaParameter2", contactId);  
 
return true;

Это нечто решает мою задачу, а именно ищет ID контакта, который является начальником в заданной группе

Поправка, лучше использовать таблицу SysUserInRole

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

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

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

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

Означает ли это ограничение запрет на доработку модулей (без создания своих альтернативных модулей)? Иногда бывало крайне удобно доработать пару функций... получается, что такая возможность пропадает?

Нравится

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

В документации Развертывание приложения в облаке указанно:

Решение не должно использовать замещение модулей. Замещать можно только схемы.

В документации Развертывание приложения в облаке указанно:

Решение не должно использовать замещение модулей. Замещать можно только схемы.

Григорий Чех,

Так это только при развёртывании в облаке (частный случай - демка)? Или on-site - то же самое?

К сожелению нет под рукой 7,13

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

Пишут, что:

В 7.13.1 добавлен запрет на создание и установку новых замещающих клиентских модулей.

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

Для запрета установки через Workspace Console необходимо указать параметр запуска -validateSchemas=true (команды InstallFromRepository, InstallBundlePackages).

Запрет установки при работе с приложениями (marketplace) включен по-умолчанию (регулируется настройкой Feature-ValidateConfigurationOnChange).

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

то есть для разрешения переопределения модулей должно быть указано: -validateSchemas=false ? Или есть системная настройка?

Лучше вообще избегать замещения модулей, чтобы всё не сломалось при следующем обновлении.

Это понятно. Вопрос был в том, как сделать при необходимости.

При необходимости можно пока не обновляться на 7.13 и дождаться выхода документации по этому механизму.

Здравствуйте! 

Заказал тестовый сайт в облаке. У меня замещаются клиентские модули:

 http://prntscr.com/l6znr2

http://prntscr.com/l6znyg

Вы ContactPage заместили, это схема.

Вопрос был о модулях - таких, как ViewGeneratorV2, например.

Добрый день,

Скажите удалось решить проблему с замещением модулей в 7.13? Системной настройки не нашел. Спасибо

Андрей, всё так и задумано разработчиками системы. См. обсуждения.

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

Всем доброго времени суток. Версия 7.12.

Есть инструкция для разделов: https://academy.terrasoft.ru/documents/technic-sdk/7-12/dobavlenie-v-ra…

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

Можно ли вытащить в виде быстрого фильтра текстовую строку?

Нравится

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

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

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

В разделах есть деталь «Хронология», там сверху текстовое поле поиска работает именно так, ищет только после нажатия Enter. Но там же при изменении даты начала и конца фильтр применяется автоматически. Блок фильтров этой детали сделан в TimelineFiltersSchema.

Смородинов Денис,

 

А как в итоге решили проблему с добавлением?

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

Добрый день!



Есть небольшая задача:

1) по нажатию кнопки открывается всплывающее окно с возможностью оставить комментарии в ленту

2) после нажатия ОК - окно закрывается и комментарий добавляется в ленту этого объекта



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



По примеру, понимаю что можно сделать обычное модальное окно, но используя обычный пример выдается ошибка: ModalBox.show is not a function

Единственное где используется:                  

var renderTo = ModalBox.show(config, function() 
{sandbox.unloadModule(moduleId, renderTo); });

Или пример корявый или где-то что-то надо еще делать. Сам пример: https://community.terrasoft.ru/articles/prosteisee-modalnoe-okno-modalb…

 

Нравится

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

2) Как то так значение полей подберите сами

var insert = Ext.create("Terrasoft.InsertQuery", {
		rootSchemaName: "SocialMessage"
	});
	insert.setParameterValue("Message", data.message, Terrasoft.DataValueType.TEXT);
	if (data.entityId) {
		insert.setParameterValue("EntitySchemaUId", data.entitySchemaId, Terrasoft.DataValueType.GUID);
		insert.setParameterValue("EntityId", data.entityId, Terrasoft.DataValueType.GUID);
	}
	insert.execute(function(result) {
		if (result.success) {
			//чтото делаем если успешно добавлена запись
		});
	}

 

Могу предложить по сути то же, что и в той теме, но чуть более расписанное, для понимания:

 

Модальное окно состоит из 3 частей.
 
Часть 1.
Указываем define
 
define("DocumentPageV2", ["ServiceHelper", "ModalBox", "ModalBoxSchemaModule"],
    function(ServiceHelper, ModalBox, resources) {
 
Вызов данного окна в нужной нам части:
Вызываем например по кнопке.
    {
                "operation": "insert",
                "name": "createActivity",
                "values": {
                    "itemType": 5,
                    "visible": true,
                    "caption": "Создать активности",
                    "click": {
                        "bindTo": "createActivity"
                    },
                    "layout": {
                        "column": 2,
                        "row": 1,
                        "colSpan": 1
                    }
                },
                "parentName": "ActionDashboardContainer",
                "propertyName": "items",
                "index": 0
            },
 
Затем в самом методе вызываем окно, так же можно повесить дополнительный функционал:
 
    onMyClick: function() {
                this.openTransactionPage();
            },
 
добавляем методы:
 
    openTransactionPage: function() {
                this.sandbox.loadModule("ModalBoxSchemaModule", {
                    id: this.getTransactionPageId()
                });
            },
 
            getTransactionPageId: function() {
                return this.sandbox.id + "_OpModalPageDateTO";
            }
 
    subscribeSandboxEvents: function() {
                debugger;
                this.callParent(arguments);
                this.sandbox.subscribe("DataFromModal", function(arg) {
                    console.log("msg from modal: " + arg.test);
                }, this, [this.sandbox.id + "_" + "OpModalBoxSchemaModule"]);
                this.sandbox.subscribe("ButtonClose", function() {
                    var moduleName = "OpModalBoxSchemaModule";
                    var moduleId = this.sandbox.id + "_" + moduleName;
                    var config = {
                        heightPixels: 420,
                        widthPixels: 750
                    };
                    var renderTo = ModalBox.show(config, function() {
                        sandbox.unloadModule(moduleId, renderTo);
                    });
                    this.sandbox.unloadModule(moduleId, renderTo);
                    this.sandbox.unsubscribePtp("ButtonClose");
                    ModalBox.close(true);
                }, this, [this.getTransactionPageId()]);
 
 
                this.sandbox.subscribe("GetModuleInfo", function() {
                    return {
                        schemaName: "OpModalPageDateTO"
                    };
                }, this, [this.getTransactionPageId()]);
            },
 
 
            onEntityInitialized: function() {
                this.callParent(arguments);
            },
 
 
Часть 2.
Создаем новый модуль. Наследуемся от "Базовый модуль схемы ( NUI )"
define("OpModalBoxSchemaModule", ["ModalBox", "BaseSchemaModuleV2"],
function(ModalBox) {
    Ext.define("Terrasoft.configuration.OpModalBoxSchemaModule", {
        extend: "Terrasoft.BaseSchemaModule",
        alternateClassName: "Terrasoft.OpModalBoxSchemaModule",
        messages: {
            "ButtonClose": {
                "mode": this.Terrasoft.MessageMode.PTP,
                "direction": this.Terrasoft.MessageDirectionType.SUBSCRIBE
            }
        },
        CloseModalBox: function() {
            this.callParent(arguments);
        },
        subscribeSandboxEvents: function() {
            this.callParent(arguments);
            this.sandbox.subscribe("ButtonClose", function() {
                this.sandbox.unloadModule("ModalBoxSchemaModule");
            }, this, [this.getTransactionPageId()]);
        },
        init: function() {
            this.callParent(arguments);
        },
        /**
         * @inheritDoc Terrasoft.BaseSchemaModule#generateViewContainerId
         * @overridden
         */
        generateViewContainerId: false,
        /**
         * @inheritDoc Terrasoft.BaseSchemaModule#initSchemaName
         * @overridden
         */
        initSchemaName: function() {
            this.subscribeSandboxEvents();
            this.schemaName = "OpDateTO";
        },
        /**
         * @inheritDoc Terrasoft.BaseSchemaModule#initHistoryState
         * @overridden
         */
        initHistoryState: Terrasoft.emptyFn
    });
    return Terrasoft.OpModalBoxSchemaModule;
});
 
 
Часть 3. Создаем карточку модального окна, которое мы увидим, при вызове.
В качестве родителя для модуля указываем "Базовая схема модального окна ( NUI )"
Так же, необходимо создавать свои контейнеры, чтобы в них размещать необходимые нам поля.
 
define("OpModalPageDateTO", ["ServiceHelper", "ModalBox"], function(ServiceHelper, ModalBox) {
    return {
        entitySchemaName: "OpDateTO",
        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[
            {
                "operation": "insert",
                "index": 0,
                "name": "CardContentWrapper",
                "values": {
                    "itemType": Terrasoft.ViewItemType.CONTAINER,
                    "wrapClass": ["modal-box-card-content-wrap"],
                    "items": []
                }
            },
            {
                "operation": "insert",
                "parentName": "CardContentWrapper",
                "propertyName": "items",
                "name": "CardContentContainer",
                "values": {
                    "itemType": Terrasoft.ViewItemType.CONTAINER,
                    "wrapClass": ["modal-box-card-content-container"],
                    "items": []
                }
            },
            {
                "operation": "insert",
                "name": "MyContainer",
                "propertyName": "items",
                "parentName": "CardContentWrapper",
                "values": {
                    "itemType": Terrasoft.ViewItemType.CONTAINER,
                    "items": []
                }
            },
            {
                "operation": "insert",
                "name": "HeaderContainer",
                "index": 1,
                "values": {
                    "itemType": Terrasoft.ViewItemType.CONTAINER,
                    "wrapClass": ["header", "modal-box-page-header-container"],
                    "items": []
                }
            },
            {
                "operation": "insert",
                "parentName": "HeaderContainer",
                "propertyName": "items",
                "name": "CloseButtonContainer",
                "values": {
                    "itemType": Terrasoft.ViewItemType.CONTAINER,
                    "wrapClass": ["close-btn-container"],
                    "items": []
                }
            },
            {
                "operation": "insert",
                "parentName": "HeaderContainer",
                "propertyName": "items",
                "name": "HeaderCaptionContainer",
                "values": {
                    "itemType": Terrasoft.ViewItemType.CONTAINER,
                    "wrapClass": ["header-name-container"],
                    "items": []
                }
            },
            {
                "operation": "insert",
                "parentName": "HeaderCaptionContainer",
                "propertyName": "items",
                "name": "HeaderCaption",
                "values": {
                    "itemType": Terrasoft.ViewItemType.LABEL,
                    "caption": "Выберите месяц и год"
                }
            },
            {
                "operation": "insert",
                "parentName": "MyContainer",
                "propertyName": "items",
                "name": "MyGridContainer",
                "values": {
                    "itemType": Terrasoft.ViewItemType.GRID_LAYOUT,
                    "items": []
                }
            },
            {
                "operation": "insert",
                "parentName": "MyGridContainer",
                "name": "OkCloseButton",
                "propertyName": "items",
                "values": {
                    "itemType": Terrasoft.ViewItemType.BUTTON,
                    "style": Terrasoft.controls.ButtonEnums.style.GREEN,
                    "click": {bindTo: "esqGetNumberMonth"},
                    "markerValue": "OkCloseButton",
                    "caption": "Принять",
                    "layout": { "column": 1, "row": 4, "colSpan": 7 }
                }
            },
            {
                "operation": "insert",
                "parentName": "MyGridContainer",
                "name": "CloseButton",
                "propertyName": "items",
                "values": {
                    "itemType": Terrasoft.ViewItemType.BUTTON,
                    "style": Terrasoft.controls.ButtonEnums.style.BLUE,
                    "click": {bindTo: "CloseModalPage"},
                    "markerValue": "CloseButton",
                    "caption": "Закрыть",
                    "layout": { "column": 2, "row": 4, "colSpan": 14 }
                }
            },
            {
                "operation": "insert",
                "name": "OpDate",
                "values": {
                    "layout": {
                        "colSpan": 14,
                        "rowSpan": 1,
                        "column": 1,
                        "row": 1,
                        "layoutName": "Header"
                    },
                    bindTo: "OpDate",
                    href: "",
                    "contentType": Terrasoft.ContentType.ENUM
                },
                "parentName": "MyGridContainer",
                "propertyName": "items",
                "index": 11
            }
        ]/**SCHEMA_DIFF*/,
        messages: {
            "ButtonClose": {
                mode: Terrasoft.MessageMode.PTP,
                direction: Terrasoft.MessageDirectionType.PUBLISH
            },
            "DataFromModal": {
                mode: Terrasoft.MessageMode.PTP,
                direction: Terrasoft.MessageDirectionType.PUBLISH
            }
        },
        methods: {
            init: function(callback, scope) {
                this.callParent([function() {
                    Ext.callback(callback, scope);
                    this.updateSize(400, 300);
                }, this]);
 
            },
            onCloseButtonClick: function() {
                this.sandbox.publish("DataFromModal", null, [this.sandbox.id]);
                ModalBox.close();
            },
            CloseModalPage: function() {
                this.sandbox.publish("ButtonClose", null, [this.sandbox.id]);
            }
        }
    };
});

 

Литвинко Павел,

В Вашем коде у меня была ошибка с ButtonClose. Писал что не подписана карточка на это.



А с кодом по примеру еще пошаманил, но все равно равно ошибки:

ModalBox.show is not a function 

и "console" is not defined (а это и в Вашем коде была ошибка такая)

Быстров Сергей,

Ну по первым двум, нужно смотреть, что не так, а console, если ругается на console.log, то можете смело удалить эту строку

Если вам только запросить у пользователя комментарий то зачем рисовать модальные окна? Имхо проще использовать стандартные диалоги и только если их функционал не устраивает рисовать свои:

Terrasoft.showInputBox("Введите свой бесценный комент", function() {}, ["ok"], null, {
	name : {
		dataValueType: Terrasoft.DataValueType.TEXT,
		value: "",
		customConfig: {
			className: "Terrasoft.MemoEdit",
			height: "215px"
		}
	}
},
{
	defaultButton: 0
});

 

Вот боле полный пример с получением введенного текста

_requestActionComment: function(caption, buttonCaption, maxCommentSize, callback, scope) {
	var controls = {
		comment: {
			dataValueType: Terrasoft.DataValueType.TEXT,
			caption: resources.localizableStrings.Comments,
			customConfig: {
				className: "Terrasoft.MemoEdit",
				height: "77px",
				maxlength: maxCommentSize
				}
			}
		};
		var config = {
			defaultButton: 0,
			style: {
				borderStyle: "ts-messagebox-border-style-blue visa-action",
				buttonStyle: "blue"
			}
		};
		var yesButton = {
			className: "Terrasoft.Button",
			caption: buttonCaption,
			returnCode: "yes"
		};
		Terrasoft.utils.inputBox(caption, function(result, arg) {
			if (result === yesButton.returnCode) {
				var comment = arg.comment.value;
				if (comment &amp;&amp; maxCommentSize &amp;&amp; comment.length &gt; maxCommentSize) {
					comment = comment.substring(0, maxCommentSize);
				}
				callback.call(scope, comment);
			}
		}, [yesButton, "cancel"], this, controls, config
	);
},

 

Григорий Чех,

Действительно, это решает мою задачу, но остался вопрос - как создать новый комментарий по введенному тексту?



Немного не понял с callback. Почему нельзя простым this.set? 

1) Можно this.set просто пример более глубокий можно передавать callback

2) Как то так значение полей подберите сами

var insert = Ext.create("Terrasoft.InsertQuery", {
		rootSchemaName: "SocialMessage"
	});
	insert.setParameterValue("Message", data.message, Terrasoft.DataValueType.TEXT);
	if (data.entityId) {
		insert.setParameterValue("EntitySchemaUId", data.entitySchemaId, Terrasoft.DataValueType.GUID);
		insert.setParameterValue("EntityId", data.entityId, Terrasoft.DataValueType.GUID);
	}
	insert.execute(function(result) {
		if (result.success) {
			//чтото делаем если успешно добавлена запись
		});
	}

 

Григорий Чех,

Большое спасибо за помощь. Получилось реализовать все что задумано 

coment: function(caption, buttonCaption, maxCommentSize, callback, scope) {
	var controls = {
		comment: {
			dataValueType: Terrasoft.DataValueType.TEXT,
			caption: resources.localizableStrings.Comments,
			customConfig: {
				className: "Terrasoft.MemoEdit",
				height: "77px",
				maxlength: maxCommentSize
			}
		}
	};
	var config = {
		defaultButton: 0,
		style: {
			borderStyle: "ts-messagebox-border-style-blue visa-action",
			buttonStyle: "blue"
		}
	};
	Terrasoft.utils.inputBox(caption, function(result, arg) {
		if (result === "ok") {
			var comment = arg.comment.value;
			if (comment != null) {
				comment = "&lt;p&gt;" + comment + "&lt;/p&gt;";
				var insert = Ext.create("Terrasoft.InsertQuery", {
					rootSchemaName: "SocialMessage"
				});
				insert.setParameterValue("Message", comment, Terrasoft.DataValueType.TEXT);
				insert.setParameterValue("EntitySchemaUId", "117d32f9-8275-4534-8411-1c66115ce9cd",
					Terrasoft.DataValueType.GUID);
				insert.setParameterValue("EntityId", this.caseRecordId, Terrasoft.DataValueType.GUID);
				window.console.log(insert);
				insert.execute(function(result) {
					if (result.success) {
						window.console.log("dobavili");
					}
				});
			}
		}
	}, ["ok", "cancel"], this, controls, config);
}

 

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

Всем доброго времени суток. Версия 7.12.

Появилась идея вывести на детали с реестом дополнение к стандартному фильтру (стандартный вообще не подходит для использующегося варианта фильтрации, не в этом суть) - текстовое поле.

Для этого в схеме соответствующей детали добавил виртуальную текстовую колонку по стандартной схеме через атрибуты:

"UsrValue":{
				"dataValueType": Terrasoft.DataValueType.TEXT,
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
			},

И далее в diff добавляем текстовое поле стандартным образом.

На детали выглядит это следующим образом:

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

Вместо поля - пустое место, а в консоли - ошибка: "Невозможно найти колонку по конфигурации". 

Насколько я понимаю, ошибка возникает из-за того, что diff грузится быстрее, чем attributes и не срабатывает bindTo в свойствах.

В итоге сделал через всплывающие мини-карточки, но вообще можно ли как-то обойти эту ошибку?

 

Нравится

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

Привидите diff

Похожее делается на детали «Хронология» (схема TimelineSchema), там тоже в шапке есть текстовое поле поиска. Там блок фильтров реализован в отдельной TimelineFiltersSchema, виртуальная колонка SearchText добавляется точно так же, как у Вас. Посмотрите, как дальше с ней работают, может, что-то пропустили.

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

Добрый день!

1) Правильно я понимаю, что для интеграции Terrasoft с внешними приложениями необходимо развернуть его on-site? Или в админке где-то есть утилита для написания web-сервисов, где можно посмотреть примеры реализации?



2) Как отлаживать в VS?

Нравится

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

НЕ забывайте про интеграционные сервисы  (Odata) подробнее тут 

1) Не имеет значения, в облаке или у вас на сервере. Создаете схемы типа "Исходный код" и пишите всю логику. Так же есть вариант через бизнес процессы.

2) https://academy.terrasoft.ru/documents/technic-sdk/7-12/otladka-servern…

НЕ забывайте про интеграционные сервисы  (Odata) подробнее тут 

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