Добрый день!
Хочу добавить дополнительный CheckBox в раздел Ваш профиль > Настройки уведомлений
Для этого я создал "замещающий клиентский модуль" с ссылкой на родительский объект NotificationSettingSchema и написал в него код:
function(DesktopPopupNotification) {
return {
entitySchemaName: "NotificationsSettings",
attributes: {
"PopupsStateFlag2": {
name: "PopupsStateFlag2",
dataValueType: this.Terrasoft.DataValueType.BOOLEAN,
type: this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
}
},
methods: {},
diff: [
{
"operation": "insert",
"name": "PopupsStateCheckBoxContainer2",
"parentName": "NotificationsSettingsContainer",
"propertyName": "items",
"values": {
"itemType": this.Terrasoft.ViewItemType.CONTAINER,
"wrapClass": ["check-box-container", "stateflag-container"],
"items": []
}
}, {
"operation": "insert",
"parentName": "PopupsStateCheckBoxContainer",
"propertyName": "items",
"name": "PopupsStateCheckBox2",
"classes": ["t-checkboxedit"],
"wrapClass": ["t-checkboxedit"],
"values": {
"bindTo": "PopupsStateFlag2",
"labelConfig": {
"caption": {"bindTo": "Resources.Strings.PopupsState2"}
}
}
}
]
};
});
В настройках уведомлений появился CheckBox:
Как мне сделать, чтобы его значение сохранялось в профиле пользователя?
Нравится
Сохранять её в
1) Своей системной настройке (персональной для каждого пользователя)
2) Сделать простой объект с полями (id, sysuser, flag) и туда записывать/считывать булево значение для каждого пользователя.
Соответственно реализовать методы подтягивания/создания флага в, например, onEntityInitialized, и сохранения/апдейта в onSaved
"Варфоломеев Данила" написал:Сохранять её в
1) Своей системной настройке (персональной для каждого пользователя)
2) Сделать простой объект с полями (id, sysuser, flag) и туда записывать/считывать булево значение для каждого пользователя.
Соответственно реализовать методы подтягивания/создания флага в, например, onEntityInitialized, и сохранения/апдейта в onSaved
Как мне реализовать методы (может быть есть какой нибудь пример)
1) подтягивания/создания флага
2) сохранения/апдейта
Правильно, только измените тип UsrSysUser на GUID.
Архив с примерным кодом прикрепляю.
"Варфоломеев Данила" написал:Правильно, только измените тип UsrSysUser на GUID.
Архив с примерным кодом прикрепляю.Прикрепленный файлРазмер
notificationcode.rar
934 байта
При попытке переименовать UsrSysUser в GUID появляется ошибка
Ошибка сохранения: Имя "GUID" колонки "Колонка 2" должно начинаться с префикса "Usr"
назвал UsrGUID
Спасибо за код, Вы прям адаптировали его под меня!
Только вот хотел спросить в каком месте мне его разместить - в этом же замещающем клиентском модуле? Получается что запись и чтение полей БД происходит напрямую из JavaScript?
"Молчанов Антон Сергеевич" написал:Ошибка сохранения: Имя "GUID" колонки "Колонка 2" должно начинаться с префикса "Usr"
Вы сохраняете название колонки, а надо тип. Как это сделать прикрепил скрин в архиве. Название поля оставьте UsrSysUser, методы что я прикреплял вставить в methods.
На скрине в п.4 в свойствах - отобразить все
"Молчанов Антон Сергеевич" написал:Получается что запись и чтение полей БД происходит напрямую из JavaScript?
Да, с помощью esq
"Варфоломеев Данила" написал:
Молчанов Антон Сергеевич пишет:
Ошибка сохранения: Имя "GUID" колонки "Колонка 2" должно начинаться с префикса "Usr"
Вы сохраняете название колонки, а надо тип. Как это сделать прикрепил скрин в архиве. Название поля оставьте UsrSysUser, методы что я прикреплял вставить в methods.
На скрине в п.4 в свойствах - отобразить все
Молчанов Антон Сергеевич пишет:
Получается что запись и чтение полей БД происходит напрямую из JavaScript?
Да, с помощью esq
Прикрепленный файлРазмер
screenshot.rar
71.17 кб
Переименовал колонку назад в UsrSysUser, сделал у неё тип данных GUID
Вставил в methods методы которые Вы мне прислали
Добавил ссылку на метод click: {bindTo: "SetFlag"} (Наверное зря добавил?)
получилась такая конструкция:
define("NotificationsSettingsSchema", ["DesktopPopupNotification"], function(DesktopPopupNotification) { return { entitySchemaName: "NotificationsSettings", attributes: { "PopupsStateFlag2": { name: "PopupsStateFlag2", dataValueType: this.Terrasoft.DataValueType.BOOLEAN, type: this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN } }, methods: { setFlag: function() { var esq = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "UsrTakeMail"}); esq.addColumn("UsrSysUser"); esq.addColumn("UsrFlag"); esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrSysUser", Terrasoft.SysValue.CURRENT_USER.value)); esq.getEntityCollection(function(result) { if (result.success) { if (result.collection.getCount() > 0) { var flag = result.collection.collection.items[0].values.UsrFlag; this.set("PopupsStateFlag2", flag); } else { this.set("PopupsStateFlag2", false); this.insertMyValue(false); } } }, this); }, insertMyValue: function(flag) { var insert = Ext.create("Terrasoft.InsertQuery", {rootSchemaName: "UsrTakeMail"}); insert.setParameterValue("UsrSysUser", Terrasoft.SysValue.CURRENT_USER.value, Terrasoft.DataValueType.GUID); insert.setParameterValue("UsrFlag", flag, Terrasoft.DataValueType.BOOLEAN); insert.execute(); }, updateFlag: function() { var flag = this.get("PopupsStateFlag2"); var sup = Ext.create("Terrasoft.UpdateQuery", {rootSchemaName: "UsrTakeMail"}); sup.filters.addItem(sup.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrSysUser", Terrasoft.SysValue.CURRENT_USER.value)); sup.setParameterValue("UsrFlag", flag, Terrasoft.DataValueType.BOOLEAN); sup.execute(); }, init: function() { this.callParent(arguments); this.setFlag(); }, saveSettings: function() { this.callParent(arguments); this.updateFlag(); }}, diff: [ { "operation": "insert", "name": "PopupsStateCheckBoxContainer2", "parentName": "NotificationsSettingsContainer", "propertyName": "items", "values": { "itemType": this.Terrasoft.ViewItemType.CONTAINER, "wrapClass": ["check-box-container", "stateflag-container"], "items": [] } }, { "operation": "insert", "parentName": "PopupsStateCheckBoxContainer", "propertyName": "items", "name": "PopupsStateCheckBox2", "classes": ["t-checkboxedit"], "wrapClass": ["t-checkboxedit"], "values": { "bindTo": "PopupsStateFlag2", "labelConfig": { "caption": {"bindTo": "Resources.Strings.PopupsState2"} click: {bindTo: "SetFlag"} } } } ] }; });
Галочка стала сохраняться! Спасибо большое!!!
Нашел в MSSQL свою таблицу, вижу как при сохранении изменяется значение поля UsrFlag!
init и saveSettings это стандартные функции которые выполняются автоматический при инициализации и сохранении компонента (их нельзя переименовывать)?
А можно ли как нибудь запустить JS в режиме отладки?
Здравствуйте!
Может пригодится: https://academy.terrasoft.ua/documents/technic-sdk/7-9/otladka-klientsk…
"Молчанов Антон Сергеевич" написал:init и saveSettings это стандартные функции которые выполняются автоматический при инициализации и сохранении компонента (их нельзя переименовывать)?
init - да, saveSettings - нет, на эту функцию завязан клик кнопки сохранить. Обычно на страницах обработчик сохранения - метод save
"Молчанов Антон Сергеевич" написал:А можно ли как нибудь запустить JS в режиме отладки?
в коде пишете debugger; С открытой консолью вызываете функцию, где у вас прописан debugger.
"Зарицкий Олег" написал:Здравствуйте!
Может пригодится: https://academy.terrasoft.ua/documents/technic-sdk/7-9/otladka-klientsko...
Спасибо!
"Варфоломеев Данила" написал:
Молчанов Антон Сергеевич пишет:
init и saveSettings это стандартные функции которые выполняются автоматический при инициализации и сохранении компонента (их нельзя переименовывать)?
init - да, saveSettings - нет, на эту функцию завязан клик кнопки сохранить. Обычно на страницах обработчик сохранения - метод save
Молчанов Антон Сергеевич пишет:
А можно ли как нибудь запустить JS в режиме отладки?
в коде пишете debugger; С открытой консолью вызываете функцию, где у вас прописан debugger.
Добрый день!
Вставил debugger; в процедуру SetFlag()
Проверил код на ошибки, пишет - Forgotten 'debbuger' statement?
Так и должно быть?
Да это нормально, это не ошибка а предупреждение, а вообще данное ключевое слово не обязательно, вы и сами можете ставить точки останова в браузере, почитайте про отладку в браузере: https://learn.javascript.ru/debugging-chrome
"Максим Шевченко" написал:Да это нормально, это не ошибка а предупреждение, а вообще данное ключевое слово не обязательно, вы и сами можете ставить точки останова в браузере, почитайте про отладку в браузере: https://learn.javascript.ru/debugging-chrome
Попробовал отлаживать через браузер, получается!
Подскажите а как в отладчике я могу увидеть, какие данные получает запрос с установленным фильтром?
Не могу понять почему у меня не происходит запись в ячейку
SaveFlag: function() { var flag = this.get("PopupsStateFlag2"); var sup = Ext.create("Terrasoft.UpdateQuery", {rootSchemaName: "SysAdminUnit"}); sup.filters.addItem(sup.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,"Id", Terrasoft.SysValue.CURRENT_USER.value)); sup.setParameterValue("UsrTakeMailFlag", flag, Terrasoft.DataValueType.BOOLEAN); sup.execute(); }
Вы можете посмотреть на структуру объекта sup до sup.Execute. потом он переваривается компилятором в запрос к базе. Если надо посмотреть коллбек (выполнился update или нет), то:
sup.execute(function(response) { debugger; ///тут смотрите, что пришло в response }, this);
"Молчанов Антон Сергеевич" написал:var sup = Ext.create("Terrasoft.UpdateQuery", {rootSchemaName: "SysAdminUnit"});
Смотреть какие и куда уходят данные можно на закладке Network браузера, там же, будет видно завершился ли запрос с кодом 200(успешно) или словил какую-то ошибку. Единственное, почитав тему с начала, я не понимаю зачем вы пытаетесь писать в SysAdminUnit, вы разве туда добавили колонку UsrTakeMailFlag? Вроде бы вам рекомендовали для этих целей создать развязочный объект UsrTakeMail в котором будут хранится соответствия пользователя настройке.
Так же рекомендуем для записи, чтения и изменения использовать esq а не UpdateQuery. Подробнее про esq почитайте здесь:
https://academy.terrasoft.ua/documents/technic-sdk/7-6-0/ispolzovanie-r…
Это цикл статей для использования esq именно в джаваскрипте, но для лучшего понимания принципов её работы, почитайте и про серверную реализацию, там приводятся результирующие sql запросы:
https://academy.terrasoft.ua/documents/technic-sdk/7-9/ispolzovanie-ent…
"Варфоломеев Данила" написал:Вы можете посмотреть на структуру объекта sup до sup.Execute. потом он переваривается компилятором в запрос к базе. Если надо посмотреть коллбек (выполнился update или нет), то:
sup.execute(function(response) {
debugger; ///тут смотрите, что пришло в response
}, this);
Теперь понятно:
"Текущий пользователь не имеет прав на объект "SysAdminUnit""
success : false
"Максим Шевченко" написал:Вроде бы вам рекомендовали для этих целей создать развязочный объект UsrTakeMail в котором будут хранится соответствия пользователя настройке.
Всё верно, я сначала создал развязочный объект UsrTakeMail и сохранял настройку в нём
Но потом подумал чтобы не создавать новых таблиц лучше создать дополнительную колонку в существующей SysAdminUnit.
Я хочу завязать мою настройку "получать письма" со скриптом "Отправка email сообщения группе"
var emailSelect = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "SysAdminUnit"); var emailColumn = emailSelect.AddColumn("Contact.Email"); var groupId = ReadCaseData.ResultEntity.GetTypedColumnValue<Guid>("GroupId"); emailSelect.Filters.Add(emailSelect.CreateFilterWithParameters(FilterComparisonType.Equal, "[SysUserInRole:SysUser].SysRole", groupId)); var collection = emailSelect.GetEntityCollection(UserConnection); IsNeedSendEmail = collection.Count > 0; RecipientEmails = string.Empty; foreach(var entity in collection) { var email = entity.GetTypedColumnValue<string>(emailColumn.Name); if (!string.IsNullOrEmpty(email)) { RecipientEmails += string.Format("{0};", email); } } return true;
Подумал что если данные будут лежать в одной таблице, мне останется лишь добавить в скрипт дополнительный фильтр - который бы отобрал только тех пользователей у кого стоит галочка "Получать письма"
"Молчанов Антон Сергеевич" написал:Подумал что если данные будут лежать в одной таблице, мне останется лишь добавить в скрипт дополнительный фильтр - который бы отобрал только тех пользователей у кого стоит галочка "Получать письма"
SysAdminUnit системная таблица, лучше её не дорабатывать. Создайте развязочную таблицу.
"Максим Шевченко" написал:
Молчанов Антон Сергеевич пишет:
Подумал что если данные будут лежать в одной таблице, мне останется лишь добавить в скрипт дополнительный фильтр - который бы отобрал только тех пользователей у кого стоит галочка "Получать письма"
SysAdminUnit системная таблица, лучше её не дорабатывать. Создайте развязочную таблицу.
Хорошо, понял!
Получается что запись и чтение полей БД происходит напрямую из JavaScript?
Да, с помощью esq
Хотел спросить - а нормально ли что запись и чтение БД происходит с клиентской стороны через ESQ?
Может правильнее было бы создать на стороне сервера процедуры записи и чтения, а клиентом просто вызывать эти процедуры?
Здравствуйте, Антон!
"Молчанов Антон Сергеевич" написал:Хотел спросить - а нормально ли что запись и чтение БД происходит с клиентской стороны через ESQ?
ESQ - это инструмент, который обращается к DataService. Сама вычитка данных с учетом прав происходит на стороне сервера. Пользователю отображается результат, который отдал сервер приложения.
"Молчанов Антон Сергеевич" написал:Может правильнее было бы создать на стороне сервера процедуры записи и чтения, а клиентом просто вызывать эти процедуры?
Так и происходит.
"Демьяник Алексей" написал:Так и происходит.
Понятно!
Получилось!!!
Мне удалось связать созданную настройку пользователя "Получать письма" с процессом "Отправки email сообщения группе".
Коллеги помогите теперь разобраться как и куда сохраняется галочка "Включить всплывающие уведомления"?
файл NotificationSettingSchema.js который отвечает за отображение страницы с галочкой содержит методы:
setPopupsState: function() { var state = this.get("PopupsStateFlag"); DesktopPopupNotification.setNotificationsState(state, this.goBack.bind(this)); }, initPopupsState: function() { DesktopPopupNotification.getNotificationsState(function(enabled) { this.set("PopupsStateFlag", enabled); }, this);
То есть setPopupsState и initPopupsState вызывают функции из DesktopPopupNotification.js
var setNotificationsState = function(enabled, callback) { Terrasoft.utils.saveUserProfile(getProfileKey(), { Enabled: enabled }, false, callback); }; var getNotificationsState = function(callback, scope) { var key = getProfileKey(); Terrasoft.require(["profile!" + key], function(profile) { callback.apply(scope, [profile.Enabled]); }, scope); }; var getProfileKey = function() { return "DesktopPopupNotification"; };
Получается что настройки галочки храниться где то в Profile, то есть непонятно в какой таблице. Как можно считать её значение со стороны сервера?
"Молчанов Антон Сергеевич" написал:Получается что настройки галочки храниться где то в Profile, то есть непонятно в какой таблице. Как можно считать её значение со стороны сервера?
Профайл это таблица SysProfileData а в ObjectData хранится собственно сама настройка:
Только данная колонка это HEX значение, а его нужно преобразовать вначале в JSON и вытаскивать уже из него что вас интересует.
"Максим Шевченко" написал:
Профайл это таблица SysProfileData а в ObjectData хранится собственно сама настройка:
Действительно Профаил храниться в таблице SysProfileData, спасибо!
Подскажите, а как преобразовать HEX значение в JSON?
Мне необходимо получить значения у которых "ObjectData = True"
Могу ли сделать преобразование и сравнение непосредственно в фильтре?
emailSelect.Filters.Add(emailSelect.CreateFilterWithParameters(FilterComparisonType.Equal, "[SysProfileData:Contact:Contact].ObjectData", "True"));
У меня получилось преобразовать HEX в JSON,
string MyString = Entity.SerializeToJson(entity);
Получаю в MyString строки вида:
{ "Entity": { "SchemaUId": "84f44b9a-4bc3-4cbf-a1a8-cec02c1c029c", "Contact_Email": "Admin@yandex.ru", "SysProfileData_Contact_Contact_ObjectData": "eyJFbmFibGVkIjpmYWxzZX0=" }}
как теперь мне вытащить из него ObjectData и преобразовать его нормальное значение?
Опишите, пожалуйста, корректней бизнес задачу, т.к: "получить значения у которых "ObjectData = True"" некорректно, в колонке ObjectData как раз находится джсон в формате хекс, следовательно вам нужно делать запрос к таблице SysProfileData получать колонку ObjectData для нужных пользователей по нужному ключу.
Получив эти данные уже можно преобразовывать их из хекс в строку, а из строки (читать джсон) и вытаскивать из него значение Enabled-а.
Прямо в фильтре этого не сделать, только получать, и преобразовывать данные, а потом уже, к примеру, в массиве полученных данных, делать выборку.
Пример получения ObjectData в виде строки, но без каких либо доп. условий в БП:
var userConnection = Get("UserConnection");
var esq = new EntitySchemaQuery(userConnection.EntitySchemaManager, "SysProfileData");
esq.AddColumn("Key");
esq.AddColumn("ObjectData");
var entities = esq.GetEntityCollection(userConnection);
foreach (var entity in entities) {
var test = entity.GetColumnValue("ObjectData");
string result = System.Text.Encoding.UTF8.GetString((byte[])test);
throw new Exception(result);
}
"Максим Шевченко" написал:
var test = entity.GetColumnValue("ObjectData");
string result = System.Text.Encoding.UTF8.GetString((byte[])test);
Максим добрый день!
Это как раз то, что мне было нужно!
Спасибо Вам за развернутые ответы!