Skip to content

Справочник bito SDK ​

Виджет получает одну глобальную переменную — window.bito. Она существует, чтобы корректно написанному виджету не пришлось самому изобретать авторизацию, перевод и интерфейсные элементы хоста.

WARNING

bito — это слой удобства, а не граница безопасности. Ваш код работает в собственном origin и сеансе админ-панели: он может вызвать fetch напрямую, прочитать DOM ERP и добраться до её хранилища. Ничто в bito.* не сдерживает виджет, который решил этим не пользоваться. Контроль — это экран согласия компании, а не этот объект.

Как до него добраться ​

window.bito устанавливается при монтировании виджета и возвращается к прежнему значению при размонтировании. Если второй виджет смонтируется, пока ваш ещё работает, window.bito будет указывать на более новый — до тех пор, пока тот не завершится.

Захватите ссылку один раз, пораньше, и работайте со своей копией:

js
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 ​

ts
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 — это один и тот же вызов.

js
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 ​

ts
bito.i18n(key: string, vars?: Record<string, string | number>): string

Ищет ключ в том единственном словаре, который Bito выбрал при монтировании (см. языковые словари), и подставляет значения в двойные фигурные скобки.

js
bito.i18n('greeting', { name: 'Азиз' })

Поведение при сбое: никогда не бросает исключение. Отсутствующий ключ возвращает сам ключ, а подстановка без подходящей переменной остаётся в строке как есть. Если пользователь видит в интерфейсе «сырой» ключ, значит в словаре этого языка ключа нет.

bito.settings.get ​

ts
bito.settings.get(): Record<string, unknown>

Возвращает настройки установки для этой компании ровно в том виде, в каком они пришли виджету при монтировании. Синхронно, без запроса. Секреты вырезаются на сервере до того, как ответ попадёт в браузер.

Поведение при сбое: его нет — это снимок. После сохранения он не перечитывается, поэтому держите свою копию того, что только что записали, если она нужна в рамках того же монтирования.

bito.settings.save ​

ts
bito.settings.save(obj: Record<string, unknown>): Promise<unknown>

Сохраняет obj для установки вашего приложения в этой компании.

js
bito.settings.save({ api_token: 'xxx', region: 'tashkent' })

Поведение при сбое: промис отклоняется. Согласие перепроверяется при каждом вызове так же, как при mount: если компания его отозвала или был одобрен новый релиз, на который согласия ещё нет, сохранение отклоняется. Объект сохраняется дословно в настройках вашей установки и больше нигде — он никогда не может расширить роль, области доступа или доступные поля вашей интеграции.

bito.render ​

ts
bito.render(tplName: string, data?: Record<string, unknown>): string

Рендерит запись из templates/ по имени без префикса (templates/card.twig → 'card.twig'), подставляя значения в двойные фигурные скобки. Возвращает строку и не трогает DOM.

Поведение при сбое: неизвестное имя шаблона молча возвращает пустую строку. Если виджет отрисовался пустым — сверьте имя с тем, что реально лежит в архиве.

bito.modal ​

ts
bito.modal(opts: { title?: string, content: string | Node }): { close(): void }

Открывает модальное окно хоста. Строковый content вставляется как HTML; Node добавляется как есть. Возвращённый объект закрывает окно.

js
var m = bito.modal({ title: bito.i18n('title'), content: '<p>Привет</p>' })
setTimeout(function () { m.close() }, 3000)

Поведение при сбое: ничего не отклоняется. Содержимое, переданное строкой, вставляется как разметка — всё в нём исполняется с правами страницы, поэтому никогда не собирайте её из данных, которые вы не очистили.

bito.notify ​

ts
bito.notify(opts: { message: string, severity?: 'success' | 'error' | 'info' | 'warning' } | string): void

Показывает уведомление хоста. Обычная строка трактуется как { message }.

Поведение при сбое: его нет, но обратите внимание на градацию: как ошибка отображается только severity: 'error'. success, info, warning и отсутствующее значение — все рисуются как успешное уведомление.

bito.confirm ​

ts
bito.confirm(opts: { title?: string, message: string } | string): Promise<boolean>

Открывает диалог подтверждения хоста и возвращает true или false.

js
bito.confirm(bito.i18n('really_delete')).then(function (yes) {
  if (yes) { /* ... */ }
})

Поведение при сбое: никогда не отклоняется. Промис исполняется только после ответа пользователя — не устраивайте гонку с собственным таймаутом в расчёте на значение по умолчанию.

bito.context ​

ts
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 ​

ts
bito.widget: { client_id: string, code?: string, version?: string }

Сообщает приложению, кто оно. client_id и version заполнены всегда: version — это semver того релиза, из которого вы на самом деле смонтированы, взятый из записи релиза, а не из манифеста, где поля версии нет.

INFO

code — код виджета вашего приложения: system_id, занятый в Моих приложениях, то же значение, что {widget_code} в URL левого меню. Он заполняется в любой точке монтирования и отсутствует, только если у приложения нет кода виджета.

Bito 2.0 Integration API