UNPKG

@bitrix24/b24jssdk

Version:

Bitrix24 REST API JavaScript SDK

198 lines (194 loc) • 7.22 kB
/** * @package @bitrix24/b24jssdk * @version 3.0.0 * @copyright (c) 2026 Bitrix24 * @license MIT * @see https://github.com/bitrix24/b24jssdk * @see https://bitrix24.github.io/b24jssdk/ */ 'use strict'; const commands = require('./message/commands.cjs'); var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); class SliderManager { static { __name(this, "SliderManager"); } #appFrame; #messageManager; constructor(appFrame, messageManager) { this.#appFrame = appFrame; this.#messageManager = messageManager; } /** * Returns the URL relative to the domain name and path */ getUrl(path = "/") { return new URL(path, this.#appFrame.getTargetOrigin()); } /** * Get the account address BX24 */ getTargetOrigin() { return this.#appFrame.getTargetOrigin(); } /** * When the method is called, a pop-up window with the application frame will be opened. * * Settings are passed via `bx24_`-prefixed keys (e.g. `bx24_title`, `bx24_width`). * `bx24_title` sets the slider title; the portal also reflects it to the browser tab title * (`document.title`) — unlike `ParentManager.setTitle`, which only updates the in-layout `#pagetitle`. * Every other key reaches the opened frame as `placement.options`; 8 KB arrived intact (#486). * * The promise settles when the slider is **closed**, not when it opens, and * always with an empty string: the portal answers from the slider's `onClose` * and passes nothing back from the opened frame (measured, #486). So `await` * blocks until the user closes the slider — attach `.then()` when you only * need to open it. * * It never settles when the page that called it is reloaded while the * slider is open: the answer reaches a new document that does not know it. * * @example * // Open, and refresh the list once the user closes the slider * $b24.slider.openSliderAppPage({ bx24_title: 'Deal', place: 'deal', id: 42 }) * .then(() => console.log('the slider was closed')) * .catch(() => {}) * * @return {Promise<unknown>} `''` on every measured close; typed `unknown` because the * portal could answer with any JSON * * @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-open-application.html */ async openSliderAppPage(params = {}) { return this.#messageManager.send(commands.MessageCommands.openApplication, params); } /** * Asks the portal to close the modal window holding the application. * * Sent with `isSafely: false`, so only the portal's answer settles the * promise — and that answer may never arrive (#328; on a measured cloud * portal it never did, see below). Do the cleanup first, then close * without awaiting; `.catch()` because * `destroy()` rejects commands still in flight. * * Prefer letting the user close the slider with the portal's ✕. Measured on a * cloud portal (#486): after this call the portal fails while finishing the * close (`JSON.stringify` of the slider throws), so this promise never * settles, and the portal page stayed unclickable (`inert`) until a reload. * The opener's `openSliderAppPage` promise still settles. * * @example * await $b24.options.appSet('draft', 'value') * * $b24.slider.closeSliderAppPage().catch(() => {}) * * @return {Promise<void>} * * @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-close-application.html */ async closeSliderAppPage() { return this.#messageManager.send(commands.MessageCommands.closeApplication, { // `false` deliberately: the frame is going away, so a timer has nothing // useful left to do. See the note above for what that costs (#328). isSafely: false }); } /** * Defines the base path for width sampling. * * @param width * @private */ #getBaseUrlByWidth(width = 1640) { if (width > 0) { if (width > 1200 && width <= 1640) { return "/crm/type/0/details/0/../../../../.."; } else if (width > 950 && width <= 1200) { return "/company/personal/user/0/groups/create/../../../../../.."; } else if (width > 900 && width <= 950) { return "/crm/company/requisite/0/../../../.."; } else if (width <= 900) { return "/workgroups/group/0/card/../../../.."; } else { return "/crm/deal/../.."; } } else { return "/crm/deal/../.."; } } /** * Opens the specified path inside the portal in the slider. * @param {URL} url * @param {number} width - Number in the range from 1640 to 1200, from 1200 to 950, from 950 to 900, from 900 ... * @return {Promise<StatusClose>} * * @link https://apidocs.bitrix24.com/sdk/bx24-js-sdk/additional-functions/bx24-open-path.html * @memo /^\/(crm\/(deal|lead|contact|company|type)|marketplace|company\/personal\/user\/[0-9]+|workgroups\/group\/[0-9]+)\// */ async openPath(url, width = 1640) { const openSliderUrl = new URL(url); openSliderUrl.searchParams.set("IFRAME", "Y"); openSliderUrl.searchParams.set("IFRAME_TYPE", "SIDE_SLIDER"); return this.#messageManager.send(commands.MessageCommands.openPath, { path: [ this.#getBaseUrlByWidth(width), openSliderUrl.pathname, openSliderUrl.search ].join("") }).then((response) => { if (response?.result === "error") { if (response?.errorCode === "METHOD_NOT_SUPPORTED_ON_DEVICE") { return new Promise((resolve, reject) => { const windowObjectReference = window.open(url, "_blank"); if (!windowObjectReference) { reject(new Error("Error open window")); return; } let iterator = 0; const iteratorMax = 1e3 * 60 * 5; const waitCloseWindow = window.setInterval(() => { iterator = iterator + 1; if (windowObjectReference.closed) { clearInterval(waitCloseWindow); resolve({ isOpenAtNewWindow: true, isClose: true }); } else if (iterator > iteratorMax) { clearInterval(waitCloseWindow); resolve({ isOpenAtNewWindow: true, isClose: false }); } }, 1e3); }); } else { return Promise.reject(new Error(response?.errorCode)); } } else if (response?.result === "close") { return Promise.resolve({ isOpenAtNewWindow: false, isClose: true }); } return Promise.resolve({ isOpenAtNewWindow: false, isClose: false }); }); } /** * @todo test this and remove */ // async showAppForm(params: any): Promise<void> { // console.warn(`deprecated showAppForm`) // return this.#messageManager.send(MessageCommands.showAppForm, { // params: params, // isSafely: true // }) // } } exports.SliderManager = SliderManager; //# sourceMappingURL=slider.cjs.map