Справочник bito SDK
Виджет получает одну глобальную переменную — window.bito. Она существует, чтобы корректно написанному виджету не пришлось самому изобретать авторизацию, перевод и интерфейсные элементы хоста.
WARNING
bito — это слой удобства, а не граница безопасности. Ваш код работает в собственном origin и сеансе админ-панели: он может вызвать fetch напрямую, прочитать DOM ERP и добраться до её хранилища. Ничто в bito.* не сдерживает виджет, который решил этим не пользоваться. Контроль — это экран согласия компании, а не этот объект.
Как до него добраться
window.bito устанавливается при монтировании виджета и возвращается к прежнему значению при размонтировании. Если второй виджет смонтируется, пока ваш ещё работает, window.bito будет указывать на более новый — до тех пор, пока тот не завершится.
Захватите ссылку один раз, пораньше, и работайте со своей копией:
define(['jquery'], function ($) {
return function CustomWidget() {
var api = null
this.callbacks = {
render: function (container) {
api = window.bito // захватить, а не перечитывать потом
container.innerHTML = '<div class="acme-root"></div>'
return true
},
}
}
})bito.ajax
bito.ajax(url: string, data?: object): Promise<unknown>Отправляет POST в admin API от имени вошедшего пользователя и возвращает развёрнутое содержимое — data из конверта ответа, а не сам конверт. url, который ещё не начинается с admin-префикса, получает его автоматически, поэтому 'customer/get-by-id' и /back-api/admin/customer/get-by-id — это один и тот же вызов.
bito.ajax('customer/get-by-id', { _id: bito.context.entity_id })
.then(function (customer) { console.log(customer.name) })Поведение при сбое: промис отклоняется. Запрос идёт через общий HTTP-клиент админ-панели, поэтому несёт ту же авторизацию, идемпотентность и обработку 401, что и остальное приложение, — истёкшим сеансом занимается приложение, а не вы.
INFO
Третьего аргумента opts нет. Каждый вызов — POST; попросить у этого метода другой HTTP-метод нельзя.
bito.i18n
bito.i18n(key: string, vars?: Record<string, string | number>): stringИщет ключ в том единственном словаре, который Bito выбрал при монтировании (см. языковые словари), и подставляет значения в двойные фигурные скобки.
bito.i18n('greeting', { name: 'Азиз' })Поведение при сбое: никогда не бросает исключение. Отсутствующий ключ возвращает сам ключ, а подстановка без подходящей переменной остаётся в строке как есть. Если пользователь видит в интерфейсе «сырой» ключ, значит в словаре этого языка ключа нет.
bito.settings.get
bito.settings.get(): Record<string, unknown>Возвращает настройки установки для этой компании ровно в том виде, в каком они пришли виджету при монтировании. Синхронно, без запроса. Секреты вырезаются на сервере до того, как ответ попадёт в браузер.
Поведение при сбое: его нет — это снимок. После сохранения он не перечитывается, поэтому держите свою копию того, что только что записали, если она нужна в рамках того же монтирования.
bito.settings.save
bito.settings.save(obj: Record<string, unknown>): Promise<unknown>Сохраняет obj для установки вашего приложения в этой компании.
bito.settings.save({ api_token: 'xxx', region: 'tashkent' })Поведение при сбое: промис отклоняется. Согласие перепроверяется при каждом вызове так же, как при mount: если компания его отозвала или был одобрен новый релиз, на который согласия ещё нет, сохранение отклоняется. Объект сохраняется дословно в настройках вашей установки и больше нигде — он никогда не может расширить роль, области доступа или доступные поля вашей интеграции.
bito.render
bito.render(tplName: string, data?: Record<string, unknown>): stringРендерит запись из templates/ по имени без префикса (templates/card.twig → 'card.twig'), подставляя значения в двойные фигурные скобки. Возвращает строку и не трогает DOM.
Поведение при сбое: неизвестное имя шаблона молча возвращает пустую строку. Если виджет отрисовался пустым — сверьте имя с тем, что реально лежит в архиве.
bito.modal
bito.modal(opts: { title?: string, content: string | Node }): { close(): void }Открывает модальное окно хоста. Строковый content вставляется как HTML; Node добавляется как есть. Возвращённый объект закрывает окно.
var m = bito.modal({ title: bito.i18n('title'), content: '<p>Привет</p>' })
setTimeout(function () { m.close() }, 3000)Поведение при сбое: ничего не отклоняется. Содержимое, переданное строкой, вставляется как разметка — всё в нём исполняется с правами страницы, поэтому никогда не собирайте её из данных, которые вы не очистили.
bito.notify
bito.notify(opts: { message: string, severity?: 'success' | 'error' | 'info' | 'warning' } | string): voidПоказывает уведомление хоста. Обычная строка трактуется как { message }.
Поведение при сбое: его нет, но обратите внимание на градацию: как ошибка отображается только severity: 'error'. success, info, warning и отсутствующее значение — все рисуются как успешное уведомление.
bito.confirm
bito.confirm(opts: { title?: string, message: string } | string): Promise<boolean>Открывает диалог подтверждения хоста и возвращает true или false.
bito.confirm(bito.i18n('really_delete')).then(function (yes) {
if (yes) { /* ... */ }
})Поведение при сбое: никогда не отклоняется. Промис исполняется только после ответа пользователя — не устраивайте гонку с собственным таймаутом в расчёте на значение по умолчанию.
bito.context
bito.context: {
account_id?: string
user_id?: string
subdomain?: string
surface: string
entity_id?: string
selection?: { ids: Array<string | number>, isAll: boolean, page_name: string }
phone?: string
lang: string
menu?: { location: string, item_code: string, subitem_code: string | null }
}| Поле | Когда заполнено |
|---|---|
account_id | Аккаунт компании в Bito, из ответа mount |
user_id | Вошедший пользователь |
subdomain | Поддомен компании в Bito |
surface | Всегда — точка монтирования, в которой вы работаете |
entity_id | Карточки и профили: запись, которую показывает экран |
selection | Только точки list:<page_name>: строки, выбранные пользователем |
phone | Только card_phone: номер, по которому кликнули |
lang | Всегда — язык пользователя |
menu | Только widget_page: открытая страница левого меню — location (widget_page или ключ модуля), item_code (код вашего виджета, а без кода — client_id), subitem_code (пункт подменю или null для собственной страницы раздела). Обновляется перед каждым вызовом initMenuPage |
Поведение при сбое: читайте, а не предполагайте. Всё, кроме surface и lang, необязательно, и набор заполненных полей целиком зависит от точки монтирования.
bito.widget
bito.widget: { client_id: string, code?: string, version?: string }Сообщает приложению, кто оно. client_id и version заполнены всегда: version — это semver того релиза, из которого вы на самом деле смонтированы, взятый из записи релиза, а не из манифеста, где поля версии нет.
INFO
code — код виджета вашего приложения: system_id, занятый в Моих приложениях, то же значение, что {widget_code} в URL левого меню. Он заполняется в любой точке монтирования и отсутствует, только если у приложения нет кода виджета.