Доброго времени суток!
Стоит задача настраивать права доступа к записям раздела с помощью фильтров. Есть карточка со справочным полем "Раздел". Необходимо отобразить фильтры записей для данного раздела, чтобы в дальнейшем запускать БП, настраивающий права доступа к отфильтрованным записям выбранного раздела.
Вопроса два:
1. Как можно хранить значения фильтров в колонке, чтоб потом использовать в БП при раздаче прав?
2. Как отобразить фильтры на карточке? Я создаю контейнер по аналогии с BaseSection, и использую sandbox.loadModule. Ошибок не выдает, как и сами фильтры.
diff:
"operation": "insert",
"name": "ExtendedFiltersContainer",
"parentName": "Header",
"propertyName": "items",
"values": {
"id": "ExtendedFiltersContainer",
"selectors": {"wrapEl": "#ExtendedFiltersContainer"},
"itemType": Terrasoft.ViewItemType.CONTAINER,
"controlConfig": {"visible": {"bindTo": "IsExtendedFiltersVisible"}},
"wrapClass": ["extended-filters-container-wrapClass", "left-inner-el"],
"items": []
}
}
methods:
this.callParent(arguments);
var extendedFilterModuleId = this.getExtendedFilterEditModuleId();
this.sandbox.loadModule("ExtendedFilterEditModuleV2", {
renderTo: "ExtendedFiltersContainer",
id: extendedFilterModuleId
});
}
Нравится
Здравствуйте, на данный момент, в системе не предусмотрено возможности использовать контролл фильтрации, который вы видите на странице секции, на пользовательских страницах другого типа.
Но если Вам необходимо собирать информацию по примененным фильтрам в разделе, а потом их куда-нибудь сохранять, и использовать в тех или иных целях.
Вы можете добавить в действия секции кнопку, которую будет видеть, к примеру, только администратор системы. Перед нажатием применять к разделу фильтрацию. И использовать метод секции «getFilters()» который вернет вам объект, всех, примененных к разделу фильтров.
Как с ним поступать далее, решать вам.
Так же, объект фильтров поддерживает сериализацию и десереализацию.
Ниже прилагаю небольшой пример по получению и сериализации объекта всех примененных к разделу фильтров:
[javascript]
define("OrderSectionV2", [], function() {
return {
entitySchemaName: "Order",
attributes: {
},
methods: {
getSectionActions: function() {
var actionMenuItems = this.callParent(arguments);
actionMenuItems.addItem(this.getActionsMenuItem({
"Type": "Terrasoft.MenuSeparator",
"Caption": ""
}));
actionMenuItems.addItem(this.getActionsMenuItem({
"Caption": "testFilters",
"Click": { "bindTo": "testFilters" }
}));
return actionMenuItems;
},
testFilters: function() {
var filters = this.getFilters();
var serializationInfo = filters.getDefSerializationInfo();
serializationInfo.serializeFilterManagerInfo = true;
var filtersJson = filters.serialize(serializationInfo);
this.Terrasoft.showInformation(filtersJson);
}
},
details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
};
});
[/javascript]
простой вариант:
сделайте справочное поле со ссылкой на объект нужных вам фильтров (Например ContactFolder/Группа контакта) и выбирайте нужную группу. В таблицах групп есть поле SearchData - это сохраненные фильтры (для клиентской стороны). В базе они выглядят так:
![]()
Перед использованием их значение надо десериализовать:
[javascript]
Terrasoft.deserialize(SearchData)
[/javascript]
После этого можете их добавлять в качестве фильтров в запросы:
[javascript]
var searchData = Terrasoft.deserialize(contactGroup.getByIndex(0).SearchData);
config.filters.addItem(searchData);
...
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "Contact"
});
esq.addColumn("Id");
esq.filters = config.filters;
esq.getEntityCollection(function(result) {
if (result.success) {
...
}
}, this);
[/javascript]
Тут есть две проблемы:
1) Группа уже должна быть создана и настроена (это не всегда плохо, но в половине случаев - точно)
2) Если вам надо выбирать из фильтров разных разделов, надо будет сделать переключение схем в зависимости от выбранного раздела ,само справочное поле групп - виртуальным, а фильтры сохранять в другом, скрытом
Сложный вариант:
1) Сделать модуль для настройки и фильтров через интерфейс. Тут логичнее использовать схемы тех разделов, которые будут фильтроваться - так пользователь сможет сразу увидеть результат фильтрации. Но их придется обернуть в отдельный модуль, который будет загружать нужный раздел поверх открытой карточки и иметь как минимум две кнопки - ОК/Отмена - а из схемы раздела надо будет убрать весь остальной функционал (фактически - создать дочернюю схему, например, от contactSectionV2, на которой скрыть все ненужные элементы). Загружать модуль тогда надо будет как-то так
[javascript]
this.sandbox.loadModule("ReportModule", {
id: reportModuleId,
renderTo: this.renderTo,
keepAlive: true
});
[/javascript]
2) наладить сообщение между модулями карточки и только что созданным для обмена фильтрами
Еще один простой вариант:
создавать вашу сущность с того раздела, который собираетесь фильтровать - открываете Контакты, настраиваете фильтрацию в расширенном режиме и выбрав действие "Создать [Что-то]" передаете туда сразу и раздел и фильтры (их надо будет сначала считать в схеме раздела).
А вот как потом использовать эти фильтры в БП - это вопрос)).
Возможно будет проще сохранять не фильтрацию, а набор ИД отфильтрованных записей. Это простая деталь и в БП проблем особо не будет.
Пример добавления записей по преднастроенному фильтру:
[javascript]
define("SfTestTeamDetail", ["terrasoft", "SfTestTeamDetailResources","ConfigurationConstants", "ConfigurationEnums", "SferaConstants", 'TestingConstants'],
function(Terrasoft, resources, ConfigurationConstants, enums, SferaConstants, TestingConstants) {
return {
entitySchemaName: "SfTestTeam",
attributes: {},
messages: {
"GetTargetGroup": {
mode: Terrasoft.MessageMode.PTP,
direction: Terrasoft.MessageDirectionType.PUBLISH
}
},
methods: {
initData: function() {
this.callParent(arguments);
},
onAddButtonClick: function() {
var cardState = this.sandbox.publish("GetCardState", null, [this.sandbox.id]);
var isNew = (cardState.state === enums.CardStateV2.ADD ||
cardState.state === enums.CardStateV2.COPY);
if (isNew) {
var args = {
isSilent: true,
messageTags: [this.sandbox.id]
};
this.sandbox.publish("SaveRecord", args, [this.sandbox.id]);
return;
}
var SfTargetGroup = this.sandbox.publish("GetTargetGroup", null, [this.sandbox.id]).targetGroup;
this.set("SfTargetGroup", SfTargetGroup);
this.addContactToTeam(arguments[3] === "byGroup");
},
addContactToTeam: function(byGroup) {
if(byGroup) {
this.getGroupList();
} else {
this.getUsersList();
}
},
getUsersList: function() {
/*var scope = this;
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "SfTestTemplate"
});
esq.addColumn("SfTargetGroup");
esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Id", this.get("MasterRecordId")));
esq.getEntityCollection(function(result) {
if (result.success && result.collection.getItems().length>0) {
scope.prepareLookupConfig(result.collection.getItems()[0].get("SfTargetGroup").value);
}
}, scope);*/
this.Terrasoft.chain(
function(next) {
this.getContactLookupConfig(function() {
next();
}, this);
},
function(next) {
this.openContactLookup(function() {
next();
}, this);
},
function(next) {
this.addContactCallback(function() {
next();
}, this);
},
function(next) {
this.reloadGridData();
next();
},
this);
},
getGroupList: function() {
this.Terrasoft.chain(
function(next) {
this.getContactGroupLookupConfig(function() {
next();
}, this);
},
function(next) {
this.openContactGroupLookup(function() {
next();
}, this);
},
function(next) {
this.getContactLookupConfig(function() {
next();
}, this);
},
function(next) {
this.getSelectedGroupFilter(function() {
next();
}, this);
},
function(next) {
this.getFilteredContacts(function() {
next();
}, this);
},function(next) {
this.addContactCallback(function() {
next();
}, this);
},
function(next) {
this.reloadGridData();
next();
},
this);
},
getContactLookupConfig: function(callback) {
var SfTargetGroup = this.get("SfTargetGroup");
var templateId = this.get("MasterRecordId");
var filters = this.Ext.create("Terrasoft.FilterGroup");
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "SfTestTeam",
isDistinct: true
});
var IdsExists = [];
esq.addColumn("SfContact");
esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "SfTestTemplate",
templateId));
esq.getEntityCollection(function(result) {
if (result.success) {
var items = result.collection.getItems();
IdsExists = [];
Terrasoft.each(items, function(item) {
var contact = item.get("SfContact");
if (contact && contact.value) {
IdsExists.push(contact.value);
}
}, this);
var contactType = SferaConstants.ContactType.Employee.value;
if (SfTargetGroup && SfTargetGroup.value) {
if (SfTargetGroup.value == TestingConstants.TargetGroupType.Doctor.value) {
contactType = SferaConstants.ContactType.Doctor.value;
}
filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Type",
contactType));
}
filters.addItem(this.getNotExistsInTeamFilter(IdsExists));
var config = {
entitySchemaName: "Contact",
multiSelect: true,
columns: ["Name"],
hideActions: true
};
config.filters = filters;
this.set("ContactLookupConfig", config);
if (this.Ext.isFunction(callback)) {
callback.call(this);
}
}
}, this);
},
getContactGroupLookupConfig: function(callback) {
var config = {
entitySchemaName: "ContactFolder",
//multiSelect: true,
columns: ["Id", "Name", "SearchData"],
hideActions: true
};
var filters = this.Terrasoft.createFilterGroup();
//todo use configconstants
filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "FolderType.Id",
"65ca0946-0084-4874-b117-c13199af3b95"));//dynamic
config.filters = filters;
this.set("ContactGroupLookupConfig", config);
if (this.Ext.isFunction(callback)) {
callback.call(this);
}
},
openContactGroupLookup: function(callback) {
var config = this.get("ContactGroupLookupConfig");
this.openLookup(config, function(args) {
this.set("SelectedContactGroup", args.selectedRows);
if (this.Ext.isFunction(callback)) {
callback.call(this);
}
}, this);
},
getSelectedGroupFilter: function(callback) {
// todo учеть возможность множественного выбора групп
var contactGroup = this.get("SelectedContactGroup");
var config = this.get("ContactLookupConfig");
if (contactGroup.getCount()) {
var searchData = Terrasoft.deserialize(contactGroup.getByIndex(0).SearchData);
config.filters.addItem(searchData);
}
this.set("ContactLookupConfig", config);
if (this.Ext.isFunction(callback)) {
callback.call(this);
}
},
openContactLookup: function(callback) {
var config = this.get("ContactLookupConfig");
this.openLookup(config, function(args) {
this.set("SelectedContacts", args.selectedRows);
if (this.Ext.isFunction(callback)) {
callback.call(this);
}
}, this);
},
getFilteredContacts: function(callback) {
var ContactLookupConfig = this.get("ContactLookupConfig");
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "Contact"
});
esq.addColumn("Id");
esq.filters = ContactLookupConfig.filters;
esq.getEntityCollection(function(result) {
if (result.success) {
//Ids = result.collection.getKeys();
this.set("SelectedContacts", result.collection);
if (this.Ext.isFunction(callback)) {
callback.call(this);
}
}
}, this);
},
addContactCallback: function(callback){
this.showBodyMask();
var Ids = this.get("SelectedContacts").getKeys();
var bq = this.Ext.create("Terrasoft.BatchQuery");
this.Terrasoft.each(Ids, function(item) {
var insert = this.Ext.create("Terrasoft.InsertQuery", {
rootSchemaName: "SfTestTeam"
});
var newGuid = Terrasoft.generateGUID();
var testTemplate = this.get("MasterRecordId");
insert.setParameterValue("Id", newGuid , Terrasoft.DataValueType.GUID);
insert.setParameterValue("SfContact", item, Terrasoft.DataValueType.GUID);
insert.setParameterValue("SfTestTemplate", testTemplate, Terrasoft.DataValueType.GUID);
bq.add(insert);
}, this);
bq.execute(function(result) {
this.hideBodyMask();
if (result.success) {
if (this.Ext.isFunction(callback)) {
callback.call(this);
}
} else console.log("error");
}, this);
},
getNotExistsInTeamFilter: function(IdsExists) {
var existsFilter = this.Terrasoft.createNotExistsFilter("[SfTestTeam:SfContact:Id].SfContact");
var subFilter = this.Terrasoft.createColumnInFilterWithParameters(
"SfContact", IdsExists);
existsFilter.subFilters.addItem(subFilter);
existsFilter.subFilters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "SfTestTemplate",
this.get("MasterRecordId")));
return existsFilter;
}
},
diff: /**SCHEMA_DIFF*/[
{
"operation": "merge",
"name": "AddRecordButton",
"values": {
"click": {bindTo: "onAddButtonClick"},
"menu": [],
"tag": "single"
}
},
{
"operation": "remove",
"name": "AddTypedRecordButton"
},
{
"operation": "remove",
"name": "EditRecordMenu"
},
{
"operation": "remove",
"name": "CopyRecordMenu"
},
{
"operation": "insert",
"name": "AddTargetGroupButton",
"parentName": "Detail",
"propertyName": "tools",
"values": {
"itemType": Terrasoft.ViewItemType.BUTTON,
"click": {"bindTo": "onAddButtonClick"},
"style": Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
"caption": {"bindTo": "Resources.Strings.AddTargetGroupButtonCaption"},
"tag": "byGroup"
},
"index": 1
}
]/**SCHEMA_DIFF*/
};
}
);
[/javascript]
https://youtu.be/WlaJY3duIJY
Спасибо огромное за идеи! Взяв понемногу из каждой у меня нарисовался алгоритм.
Остается только одна задача: я передаю в бп коллекцию записей, UId схемы раздела и объект администрирования. Не могу понять как правильно их передать в элемент "изменить права доступа". Подскажите, пожалуйста, как правильно реализовать данную задачу.