Перейти к содержанию

Дополнительно

Темы

Легкий клиент поддерживает файлы с настройками тем толстого клиента. Темы можно найти в папке themes в корневой папке. При необходимости в эту папку можно добавить кастомные темы. Они автоматически подхватятся сервером после перезапуска.

Фон

Легкий клиент также поддерживает дополнительные фоны, которые может выбирать пользователь. Для этого нужно добавить соответствующие файлы в папку ./wwwroot/images/tessa-wallpapers, и после добавить иконки для выбора в папку ./wwwroot/images/tessa-wallpapers/icons. Также, чтобы у пользователя появилась возможность выбирать дополнительный фон, необходимо добавить название файла с фоном в подходящие темы (свойство TessaWallpapers).

Консоль разработчика

Чтобы открыть консоль разработчика - нажмите F12 На вкладке “Console” выводятся все ошибки во время выполнения js кода

На вкладке “Network” выводятся все запросы к серверу. При нажатии на запрос будут выводиться данные ответа.

Настройка сотрудников, создаваемых при входе для ADFS

Web-клиент поддерживает аутентификацию через ADFS, основанную на стандарте SAML 2.0. Настройка ADFS описана в руководстве по установке.

В настройке AddNewUserToRoles указывается список идентификаторов ролей, в которые сотрудник, создаваемый при логине при наличии флага CreateUserAfterAuthenticationIfNotExists:true, будет сразу же добавлен до загрузки рабочего места. По умолчанию прописан идентификатор роли “Все сотрудники”.

Вы также можете написать серверное расширение, которое добавляет сотрудника в другие роли или выполняет другие настройки. Приведённое расширение есть в сборке Tessa.Extensions.Default.Server.

/// <summary> /// Расширение добавляет сотрудников, которые были созданы при adfs аутентификации в ЛК, в роль "Все сотрудники". /// </summary> public sealed class ADFSAuthenticationPersonalRoleStoreExtension: CardStoreExtension { private static readonly Guid AllUsersRoleID = Guid.Parse("7FF52DC0-FF6A-4C9D-BA25-B562C370004D"); // Все сотрудники

private readonly IRoleRepository roleRepository;

public ADFSAuthenticationPersonalRoleStoreExtension(IRoleRepository roleRepository) { this.roleRepository = roleRepository; }

public override void BeforeCommitTransaction(ICardStoreExtensionContext context) { if (!context.Request.IsADFSAuthenticationResponseExists()) { return; }

var card = context.Request.Card; var section = card.Sections["PersonalRoles"]; var userID = card.ID; var userName = section.Fields.Get<string>("FullName");

var roleUserRecord = new RoleUserRecord { ID = AllUsersRoleID, RowID = Guid.NewGuid(), IsDeputy = false, RoleType = RoleType.Dynamic, UserID = userID, UserName = userName };

this.roleRepository.Insert(roleUserRecord); } }

// регистрация в классе Registrator, метод RegisterExtensions

extensionContainer .RegisterExtension<ICardStoreExtension, ADFSAuthenticationPersonalRoleStoreExtension>(x => x .WithOrder(ExtensionStage.AfterPlatform, 1) .WithSingleton() .WhenCardTypes(RoleHelper.PersonalRoleTypeID)) ;

Отслеживание изменений свойств контролов и изменения массивов

Многие свойства контролов являются observable. Изменения этих свойств можно отслеживать через вызовы функции MobX. Например свойство selectedRow у контрола таблицы:

import { reaction } from 'mobx'; ... const disposer = reaction(() => grid.selectedRow, row => console.log(row)); ... disposer(); // необходимо вызывать когда реакция больше не нужна (например в finalized в CardUIExtension)

Похожий пример можно найти в расширении 9_additionalTableButtonUIExtension.ts в папке examples.

Свойство rows у грида тоже является observable и тут тоже можно применить reaction, но реакция может вызываться даже когда значения в массиве не поменялись, т.к. reaction по умолчанию сравнивает значения по ссылке. Чтобы этого избежать нужно переопределить функцию сравнения. Пример:

import { reaction } from 'mobx'; ... const disposer = reaction( () => grid.rows, rows => console.log(rows), { equals: (a: ReadonlyArray<GridRowViewModel>, b: ReadonlyArray<GridRowViewModel>): boolean => { // ... сравниваем два массива } } ); ... disposer();

Есть другой способ: если есть возможность работать с табличной секцией карточки, то лучше использовать её. Для этого необходимо использовать CardRowsListener. Пример его использования есть в 3_tableSectionChangedUIExtension.ts в папке examples.

import { CardRowsListener } from 'tessa/cards'; ... const card = grid.cardModel.card; const cardSection = card.sections.get('MyTableSection')!; const rows = cardSection.rows; const listener = new CardRowsListener(); listener.rowInserted.add(() => console.log(grid.rows)); listener.rowDeleted.add(() => console.log(grid.rows)); listener.start(rows); ... listener.stop(); // необходимо вызывать когда listener больше не нужен (например в finalized в CardUIExtension)

Focus контролов при открытии карточки или формы

Метод focus() контролов карточки вызывает нативный метод focus() элемента. Поэтому для правильной работы метода, необходимо чтобы контрол уже был отрендерен в момент вызова. Поэтому если необходимо вызвать focus() при открытии карточки, то нужно вызывать его в CardUIExtension.contextInitialized. В этом методе расширения карточка уже будет отрисована и все контролы будут иметь ссылки на свои html элементы.

public contextInitialized(context: ICardUIExtensionContext) { const textBox = context.model.controls.get('MyTextBox') as TextBoxViewModel; textBox.focus(); }

Если необходимо вызвать при открытии формы контрола таблицы, то нужно вызывать его в GridViewModel.rowInitialized.

table.rowInitialized.add(e => { const textBox = e.cardModel.controls.get('MyTextBox') as GridViewModel; textBox.focus(); });

Работа с decimal полями

Поля карточки типа Decimal хранятся в web-клиенте в виде строки. Для проведения операций над этими полями можно воспользоваться сторонним пакетом decimal.js.. Он позволяет работать со значениями в привычном виде без потери точности.

Установка пакета:

npm i --save decimal.js

Пример:

import {Decimal} from 'decimal.js'; ... const amountField = section.fields.getField('Amount'); if (!amountField || !isDecimalField(amountField)) { return; } let amount = new Decimal(getTypedFieldValue(amountField)); amount = amount.plus(100.54); section.fields.set('Amount', amount.toString(), DotNetType.Decimal);

Back to top