Вопрос

Добрый день. Создавала раздел вручную, но в нём отсутствует кнопка "Действия" на странице записи. 

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

Стоит задача: создать действие по смене спр. колонки "Ответственный" в новосозданном разделе. По нажатию на действие должен открываться выбор из справочника Административных единиц с фильтрацией по типу "Сотрудник".

П.С. Сильно камнями не кидайте, я только учусь :) 

П.С. Сильно камнями не кидайте, я только учусь :) 

У меня такой же вопрос

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

Доброе утро.

Можно для Вашей карточки редактирования указать в качестве родительской BaseModulePageV2 из пакета NUI, тогда кнопка [ACTIONS] должна появится.

Если же Вы не хотите наследоваться от этой карточки, то можете посмотреть, каким образом реализуется добавление этой кнопки и пунктов её меню в 'Base card schema' (BasePageV2) пакета NUI.

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

Спасибо, сделала по первому совету - появилась. 

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

Есть действие по множественному выбору в реестре. 

Проблема в том, что оно должно выполняться для большого кол-ва записей. Если я делаю Действия-Выбрать все, то он мне показывает, например, 4000 записей. Но когда я попадаю в метод обработки действия, то 

var selectedRows = this.get("SelectedRows");
this.showInformationDialog(selectedRows.length.toString());

возвращает кол-во записей, которые отображаются на странице в текущий момент, например, 30. Как мне поймать все записи?

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

Есть пример реализации?

У меня такой же вопрос

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

Для обработки всех записей нужно использовать запросы в БД , для раздела вычитываются 30 записей по странично (те пролистывая вы можете по 30 записей листать) это сделано с целью увеличения производительности

Для обработки всех записей нужно использовать запросы в БД , для раздела вычитываются 30 записей по странично (те пролистывая вы можете по 30 записей листать) это сделано с целью увеличения производительности

Григорий Чех,это понятно.

Вопрос в том, как пробросить фильтр в запрос, который выбрал пользователь. Т.е. мне не тупо надо все записи в БД обработать, а те, которые выбраны. А до выбора они могут быть отфильтрованы.

Алексей-Карягин,

Тогда листать постранично по 30 записей и обрабатывать

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

4000 записей? нет уж, спасибо :)

Нужен другой способ.

Однако действие Delete в разделе работает не со страницей, а именно со всеми записями, кстати

 

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

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

Коллеги, добрый день!

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

. 

 

А так же интересует каким образом можно добавить для выпадающей кнопки Значок, по аналогии с кнопкой "Экспорт в Excel" в меню "Действия"?

Спасибо!

У меня такой же вопрос

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

Добрый день

Чтобы реализовать раскраску цветами, то:

1. Каждое меню должно быть уникальное

2. Добавить css стиль

К примеру, у меня есть 2 пункта меню. Чтобы я мог реализовать корректный selector, то мне нужно их как-то назвать. Поэтому, в методе, где формируется menuItem я явно буду указывать Id этого меню. После чего можно будет писать что-то типа:

#myMenuItem {
    background-color: green;
}

 

Теперь по значкам.

Как вы сами заметили, что хотите добавить значок по аналогии, то вам и нужно сделать по аналогии :). Вот как это сделано в BaseSection

Артем Гура,

Спасибо, но не совсем понято как указать id каждого из меню в методе.

Вот мой метод:

getCustomCloseActions: function() {
 
	self = this;
	var actionMenuItems = Ext.create("Terrasoft.BaseViewModelCollection");
		actionMenuItems.addItem(this.getButtonMenuItem({
			"Tag": "5",
			"Caption": "Закрыть с оценкой 5",
			"Click": {bindTo: "OnCustomClosedButtonMenuClick"}
		}));
		actionMenuItems.addItem(this.getButtonMenuItem({
			"Tag": "4",
			"Caption": "Закрыть с оценкой 4",
			"Click": {bindTo: "OnCustomClosedButtonMenuClick"}
		}));
		actionMenuItems.addItem(this.getButtonMenuItem({
			"Tag": "3",
			"Caption": "Закрыть с оценкой 3",
			"Click": {bindTo: "OnCustomClosedButtonMenuClick"}
		}));
		actionMenuItems.addItem(this.getButtonMenuItem({
			"Tag": "2",
			"Caption": "Закрыть с оценкой 2",
			"Click": {bindTo: "OnCustomClosedButtonMenuClick"}
		}));
		actionMenuItems.addItem(this.getButtonMenuItem({
			"Tag": "1",
			"Caption": "Закрыть с оценкой 1",
			"Click": {bindTo: "OnCustomClosedButtonMenuClick"}
		}));
	self.set("CloseButtonMenuItems", actionMenuItems);
 
},

 

Обратите внимание на метод getButtonMenuItem: как он работает по умолчанию, и как он работает, например в BaseSection.

Особенно то, как формируется значок Excel и как генерируется Id.

А дальше сделать всё по аналогии.

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

В окне выбора справочного значения добавить в лукап конфиге указать возможность отображения действий 'select all' ('deselect all').Сейчас данного функционала очень не хватает, приходится что-то 'придумывать', хотя аналогичный функционал есть и гриде реестра.

Ревью
1 комментарий

Здравствуйте, спасибо за фидбек, зарегистрировали соответствующую проблему.

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

В процессе разработки, при тестировании процесса установки, просто перемещения изменений между средами разработчиков - очень большое время занимает выполнение действий в конфигураторе, причем практика показывает что выполнить одно единое действие требуется довольно редко, как правило, твои коллеги разработали несколько пакетов и тебе необходимо получить проделанные ими изменения, и тебе необходимо произвести "связку действий":Установить скрипты + Генерировать + Скомпилировать измененное или Обновить объекты в БД + Установить данные + Скомпилировать всё (т.к. приехало несколько компилируемых БП) и т.д. В конфигураторе, ИМХО, прям напрашивается функционал последовательного выполнения действий н/п организовать дополнительный пункт бокового меню по нажатию на который открывать окно В котором при помощи штатного Ext инструментария, выбрать набор пунктов и установить последовательность их выполнения (стрелочками) Нажал "ОК" По факту завершения, сгенерировать штатную нотификацию (которая вызывает выделение/мерцание вкладки) Что привлечет внимание - и можно продолжать работу :) PS: Поскольку отдельные действия выполняются довольно продолжительно, то разработчик все равно не сидит и не любуется progress-loader, а как правило переключается на что-то другое, то постоянно "ходить проверять как там дела", на этом теряется много времени, т.к. забываешь про запущенное действие, оно выполнится и стоит без дела, потом разработчик про него вспомнит - идет запускать следующие действия и т.д. Как считают пользователи сообщества - будет ли такой функционал полезен в их работе ?

Обсуждение
3 комментария

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

Добрый день, Илья!

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

Добрый день, Илья!

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

Выдержка из What’s New 7.10.2:
“Уменьшено количество действий при обновлении конфигурации из хранилища и пакетов при разработке в файловой системе. Для этого по умолчанию включены механизмы автоматического применения изменений (ключи AutoUpdateDBStructure, AutoInstallSqlScript, AutoInstallPackageData).”

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

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

Не работают свойства Enabled и Visible для действий в комбинированном режиме. Версия 7.6

Пример реализации, который работал в 7.5, но не работает в 7.6

          onEntityInitialized: function() {
                this.set("isOutsideSupply", true);
                this.callParent(arguments);
            },
            getActions: function() {
                var actionMenuItems = this.callParent(arguments);
                actionMenuItems.addItem(this.getActionsMenuItem({
                    "Caption": "Спецификация Teleton",
                    "Tag": "specificationTeleton",
                    "Visible": {"bindTo": "isOutsideSupply"}
                }));
                return actionMenuItems;
            },

            initCardActionHandler: function() {
                this.callParent(arguments);
                var propertyNames = [
                    "isOutsideSupply, isInsideSupply", "SxAmountCaption"
                ];
                this.Terrasoft.each(propertyNames, function(propertyName) {
                    this.on("change:" + propertyName, function(model, value) {
                        this.sandbox.publish("CardChanged", {
                            key: propertyName,
                            value: value
                        }, [this.sandbox.id]);
                    }, this);
                }, this);
            },

Также пробовал биндить на метод. Результат тот же.

У меня такой же вопрос

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

На сколько я могу судить, код вполне работоспособен на версии 7.6, в зависимости от того, конечно, какую задачу вы им хотите решить.
Функции initCardActionHandler и onEntityInitialized это функции BasePageV2, следовательно переопределяете их вы в схеме страницы.

Что вы делаете:
1. Объявляете свойство, (без разницы, где вы его на странице и в каком методе будете менять, я для теста буду его менять по нажатию кнопки).
2. Добавляете Action "Спецификация Teleton" на страницу и биндите его видимость на свойство.
3. Публикуете сообщение для схемы секции, которое будет срабатывать по изменению вашего свойства.

Посмотрел ваш код на версии 7.6.0.1578
Добавил его на схему страницы контакта, плюс метод который будет менять значение свойства:

methods: {
	    testClick: function() {
	        this.set("isOutsideSupply", true);
	    },
 
	    onEntityInitialized: function() {
                this.set("isOutsideSupply", false);
                this.callParent(arguments);
            },
            getActions: function() {
                var actionMenuItems = this.callParent(arguments);
                actionMenuItems.addItem(this.getActionsMenuItem({
                    "Caption": "Спецификация Teleton",
                    "Tag": "specificationTeleton",
                    "Visible": {"bindTo": "isOutsideSupply"}
                }));
                return actionMenuItems;
            },
 
            initCardActionHandler: function() {
                this.callParent(arguments);
                var propertyNames = [
                    "isOutsideSupply"
                ];
                this.Terrasoft.each(propertyNames, function(propertyName) {
                    this.on("change:" + propertyName, function(model, value) {
                        this.sandbox.publish("CardChanged", {
                            key: propertyName,
                            value: value
                        }, [this.sandbox.id]);
                    }, this);
                }, this);
            },
},

Добавил кнопку которая будем менять значение:

{
		"operation": "insert",
		"name": "Test",
		"parentName": "Header",
		"propertyName": "items",
		"values": {
			"itemType": Terrasoft.ViewItemType.BUTTON,
			"caption": "Test",
			"click": {"bindTo": "testClick"},
			"layout": {"column": 0, "row": 4, "colSpan": 12}
		}
},

При загрузке страницы вижу что экшена в списке нет, т.к. по умолчанию я прописал ему "this.set("isOutsideSupply", false);"
После же нажатия кнопки он появляется. Бинд на видимость работает.

Так же, в то же время в результате публикации сообщения CardChanged, срабатывает прослушка сообщения в BaseSectionV2:

Абсолютно все, что написано в вашем коде, делает то, что и должно делать.

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

Добрый день!

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

P.S.: информацию по добавлению действия в раздел кое какую нашел, а вот в карточку - нет.

У меня такой же вопрос

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

Александр, здравствуйте.

В приложении инструкция по созданию действия для стандартного раздела.

Елена, ну я же специально уточнил и скриншот приложил: мне нужно добавить действие НЕ В РАЗДЕЛ, А В КАРТОЧКУ.

Александр,

Принцип добавления действия в карточку раздела аналогичен принципу добавления действия в раздел. Разница только в схемах, в которые добавляется код обработчика. Для добавления действия в раздел обработчик добавляется в схему [Название_объекта_раздела]Section. Если необходимо добавить действие в карточку раздела - изменяется схема [Название_объекта_раздела]Page.
В вашем случае необходимо создать замещающий модуль для страницы ActivityPage и добавить в него код обработчика.

В приложении инструкция по добавлению действия, в которой добавлено описание кейса по добавлению действия в карточку раздела.

Елена,

с добавлением действия справился. Теперь встал вопрос: как из кода обработчика нажатия на кнопку в разделе "Действия" получить доступ к данным на деталях, например к списку файлов?

P.S.: данные с самой карточки получаются легко согласно статье, а вот для деталей аналогичного не нашел.

Александр,

через объект получить доступ к деталям не получится. Можно использовать select и получить данные из базы данных. Например так:

var selectFilevar = 
        new Select(UserConnection)
        .Column("Name")
        .From("ActivityFilel")
        .Where("ActivityId").IsEqual(activity.Id)

Андрей,

все бы хорошо, но вот незадача: ActivityPage - это js-страница. Поэтому, чтобы ее переопределить, приходится писать на js. Код:

this.methods.showAvtivityInfo = function() {
   var activityTitle = this.get("Id");
   var esq = Ext.create('Terrasoft.EntitySchemaQuery', {
    rootSchemaName: 'ActivityFile'
   });
   esq.addColumn('Id');
   esq.addColumn('Name');
   esq.addColumn('ActivityId');
   /*var filters = esq.filters;
   var filterNameActivityId = 'ActivityId';
   var filterActivityId = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
    'ActivityId', activityTitle);
   filters.add(filterNameActivityId, filterActivityId);*/
   esq.getEntityCollection(function(result) {
    var collection = result.collection;
    if (collection && collection.collection.length > 0) {
     var item = collection.collection.items[0].values;
     this.showInformationDialog(activityTitle);
    }
   }, this);
  };

Exception выходит на строке

esq.addColumn('ActivityId');

Текст exception: [17:51:16.813] uncaught exception: -;5<5=B :>;;5:F88 A 8<5=5< ActivityId =5 =0945=

P.S.: Поля 'ID' и 'Name' отрабатывают корректно.

Александр, у Вас опечатка:

this.methods.showAvtivityInfo = function() {

Должно быть showActivityInfo.

Попробуйте использовать Select(UserConnection), как я описывал выше.

Андрей,

опечатка не существенна, потому что я вызывал функцию ниже именно по этому имени. Сейчас поменял - не помогло.
Вы описали Select(UserConnection), это применимо для C# кода, в JS коде получаем ожидаемую ошибку.
1. При сохранении (во вложении)
2. В консоли браузера:
[14:42:41.377] ReferenceError: Select is not defined @ http://stnd-bpm-02:88/0//configuration/30e6e6890bd6a8c10768d330b68949d4…

Александр,

прошу прощения, сразу не подумал.
В таком случае, не могли бы Вы скинуть полный код замещающей страницы?

Андрей,

файл во вложении.

Методом тыка и медитированя нашел решение:

esq.addColumn('Activity.Id');

Теперь вопрос в том, как вызвать свой серверный метод?
Видимо нужно использовать DLL либо .NET Managed Assemblies отсюда, но примеров нет:(

Александр, если я правильно понял, то нужно просто дописать

click: {
         bindTo: 'showActivityInfo'
        }

Андрей,
Уверен, Вы меня не правильно поняли. Я получил idшники файлов, круто. Теперь мне нужно вызвать метод, написанный на C#. На сколько я понимаю, мне для этого нужно:
1. Создать проект со сбокой dll в VisualStudio
2. Подключить сборку к dll. Как?
3. Вызвать из js-кода метод из сборки. Как?

Александр,
действительно неправильно понял. Для того чтобы вызвать «свой серверный метод» нужно написать сервис, к которому нужно обратиться из клиента, а внутри сервиса можно вызвать «свой серверный метод».

То есть варианты DLL сборки и .Net Managed сборки не подходят?
Можно тогда инструкцию/пример по написанию сервиса и вызову его из js-кода в Террасофт?

Александр, веб-сервис пишется на любом языке программирования и регистрируется в IIS.
Потом через API сервиса вызывать его методы. Пример запроса к Google с помощью jQuery:

1) Подключить jQuery в зависимые модули нашей страницы редактирования (в примере ProductPage) модуль jQuery.
2) В коде страницы добавить define('ProductPage', ['ext-base', 'terrasoft', 'sandbox', 'jQuery' …..
function(Ext, Terrasoft, sandbox, jQuery ……
3) В обработчик нажатия кнопки добавить следующий код:
var geocodingAPI = "http://maps.googleapis.com/maps/api/geocode/json?address=Россия+Москва&sensor=true";
window.jQuery.getJSON(geocodingAPI, function (json) {
console.log('json : ', JSON.stringify(json));
});

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

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

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

function amiConfigAccountCitiesOnExecute(ActionMenuItem, Sender) {
        var EditWindowUSI = 'wnd_ConfigAccountsCities';
        var Dataset = Services.GetNewItemByUSI('ds_ConfigAccountsCities');
        var Attributes = GetNewDictionary();
        ApplyDatasetFilter(Dataset, 'OwnerID', Connector.CurrentUser.ContactID, true);
        Dataset.Open();
        if (Dataset.RecordsCount) {
                var RecordID = Dataset('ID');
                Attributes('RecordID') = RecordID;
        }              
        Dataset.Close();                            
        Attributes.Add('NotifyObject', Self);
        ShowEditWindowEx(EditWindowUSI, Attributes);   
}

Если записей нет (условие не выполнилось), то все открывается как надо (создается новая запись). А вот если запись уже есть, то открывается окно, но все контролы там не активны и выскакивает ошибка OLE Error.
Я думаю что-то не так с атрибутами, но не пойму что. Помогите решить проблему, пожалуйста.

У меня такой же вопрос

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

здравствуйте, Дмитрий!
с атрибутами вроде все в порядке, рекордИД должен содержать ИД записи, которую нужно открыть. если это был бы просто не тот ИД, то выдавалось бы сообщение "запись удалена".

попробуйте после открытия датасета перейти к первой записи, то есть написать Dataset.GotoFirst(); после Dataset.Open();

еще вопрос -- датасет ds_ConfigAccountsCities у Вас "привязан" к окну wnd_ConfigAccountsCities? это Ваш новый раздел, правильно я понимаю? может, у Вас в самом скрипте окна что-то не так идет при открытии. посмотрите отладчиком.

GotoFirst() проблему не решил.

датасет ds_ConfigAccountsCities привязан к окну wnd_ConfigAccountsCities (прописан в dlData). Это не окно нового раздела, это окно конфигурации, которое вызывается из меню "Действия" в новом разделе.

С самим окном вроде все в порядке, ошибка вылетает только если передается атрибут RecordID, без него все нормально открывается.

Здравствуйте, Дмитрий.

У вас ошибка при присвоении атрибута. Вот как Вы передаете NotifyObject:

Attributes.Add('NotifyObject', Self);

а как RecordID:

 Attributes('RecordID') = RecordID;

Измените на

Attributes.Add('RecordID', RecordID);

Также, не помешает передать дополнительно атрибуты:

Attributes.Add('IsNew', false);
Attributes.Add('IsCopy', false);

Пробовал и так и так записывать, результат тот же - ошибка. Дополнительные аттрибуты тоже ошибку не исправили.

Дмитрий,

уточните, пожалуйста, ведется ли администрирование по записям в группе к которой привязана таблица датасета?
Под администратором ошибка есть?
На какой именно строчке вылетает OleError выяснили?

Попробуйте добавить на деталь доступ для всех записей Вашего раздела группу "Все пользователи".

Объясните, пожалуйста, подробнее, что значит администрирование по записям в группе к которой привязана таблица датасета. Она обязательно должна быть привязана к какой-нибудь группе? Привязал к группе "Контрагенты", а где посмотреть администрируется ли группа по записям? Самой таблице поставил галочку "Администрируется по записям", не помогло.

Ошибка под администратором есть.

Вылетает в функции ShowEditWindowEx на строчке:

EditWindow.Prepare();

Но у меня у вызываемого окна на событии OnPrepare стоит стандартная функция. (наследовано от wnd_BaseDBEdit).

Извиняюсь, я ошибся в описании проблемы в первом посте, окно вызывается из меню "Действия" не нового раздела, а из раздела "Контрагенты". Соответственно на детали доступ стоит.

Дмитрий,
Вам нужно переопределить событие OnPrepare для Вашего окна. В этом событии вызовите базовый метод, а также метод Initialize(Window), в котором присвойте Window атрибут DatasetUSI:

SetAttribute(Window, 'DatasetUSI', 'ds_Dataset');

К примеру, как в карточке Контрагентов:

function wnd_AccountEditOnPrepare(Window) {
	Initialize();
   	wnd_BaseDBEditOnPrepare(Window);
...
}

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

Написал так

function InitializeDataset(Window) {
    SetAttribute(Window, 'DatasetUSI', 'ds_ConfigAccountsCities');	
}
 
function Initialize(Window) {
	InitializeDataset(Window);
}
 
function wnd_ConfigAccountsCitiesOnPrepare(Window) {
	Initialize(Window);
	wnd_BaseDBEditOnPrepare(Window);
}

Не помогло :sad:

Дмитрий, здравствуйте.

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

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