Создание CheckBox

Добрый день!
Хочу добавить дополнительный CheckBox в раздел Ваш профиль > Настройки уведомлений
Для этого я создал "замещающий клиентский модуль" с ссылкой на родительский объект NotificationSettingSchema и написал в него код:

define("NotificationsSettingsSchema", ["DesktopPopupNotification"],
 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:

Как мне сделать, чтобы его значение сохранялось в профиле пользователя?

Нравится

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

Сохранять её в
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);

Максим добрый день!
Это как раз то, что мне было нужно!
Спасибо Вам за развернутые ответы!

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