Свой пункт меню в профиле сотрудника Bitrix24

В этой статье я поделюсь с вами небольшим хаком для Bitrix24: как добавить свой собственный пункт меню (вкладку) в профиле сотрудника, не внося изменения в стандартные компоненты системы. Это просто и интересно, давайте вместе разберемся!

Давненько я не выкладывал новых статей в блоге. Честно говоря, даже не знал, о чем бы писать. Но потом я вспомнил, что у меня есть здесь вы, мои верные читатели, и у вас наверняка есть вопросы. Вот и решил посвятить время разбору одного из таких вопросов. Он касается Bitrix24, так что если вас это тоже интересует, давайте разбираться вместе.

Ко мне обратился Михаил, со следующим вопросом:

Привет, Никита! У меня стоит задача добавить доп. вкладку «Обучение» в профиль пользователя Bitrix24 и публиковать результаты обучения в табличном виде по каждому сотруднику.

Скажи пожалуйста, сталкивался ли ты с задачей добавления доп. вкладок в профиле? Как правильно добавить вкладку в профиль пользователя без изменения компонентов?

Заранее спасибо.

Шаг 1. Постановка задачи

Сперва формулируем требования и поставим задачу:

  1. Описание задачи:
    • Добавить новый пункт меню в профиль пользователя в Bitrix24.
    • При клике на этот пункт должен открываться определенный компонент.
  2. Ограничения и требования к внедрению:
    • Реализовать добавление без изменения стандартных компонентов и их шаблонов системы.
  3. Функциональные требования:
    • Новый пункт меню должен быть доступен в профиле каждого пользователя.
    • При нажатии на пункт меню должен быть отображен соответствующий компонент.
  4. Технические требования:
    • Решение должно быть реализовано с использованием существующих инструментов и API Bitrix24.
    • Обновления системы не должны нарушить работу нового функционала.

Шаг 2. Концепция

Поскольку решение не должно затрагивать существующие компоненты, мы воспользуемся встройкой функционала и внедрим JavaScript расширение, которое будет отвечать за добавление нового пункта меню и описывать поведение при клике на него. Для этого применим метод, описанный в статье атипичная встройка функционала.

Шаг 3. Подготовка

Давайте действовать последовательно. Сначала подпишемся на событие OnEpilog модуля main и вызовем метод, который будет проверять, подходит ли текущая страница под условия (открыт профиль пользователя). Затем, если условия выполняются, мы подключим расширение.

Подписываемся на событие

// file path: local/event.php

$eventManager = \Bitrix\Main\EventManager::getInstance();

...
  
$eventManager->addEventHandler(
    "main",
    "OnEpilog", [
        "\\Aclips\\Custom\\EventHandler",
        "loadCustomExtension"
    ]
);

Описываем обработчик

// file path: local/php_interface/classes/Aclips/Custom/EventHandler.php

namespace Aclips\Custom;

use Bitrix\Main\Context;
use Bitrix\Main\UI\Extension;

/**
 * Класс обработчиков событий
 */
class EventHandler
{
    /**
     * Подключение js расширения
     * @return void
     * @throws \Bitrix\Main\LoaderException
     */
    public static function loadCustomExtension()
    {
        $request = Context::getCurrent()->getRequest();

        if ($request->isAjaxRequest()) {
            return;
        }

        $requestPage = $request->getRequestedPage();

        if (preg_match('@/company/personal/user/[0-9]+/@i', $requestPage)) {
            Extension::load("aclips.add_menu_item");
        }
    }
}

Описываем конфигурационный файл расширения

// file path: local/js/aclips/add_menu_item/config.php

<?php

if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true)
{
	die();
}

return [
	"js" => [
		"./script.js",
	],
];

Описываем скрипт для проверки

// file path: local/js/aclips/add_menu_item/script.js

console.log('Это профиль')

Если всё сделали верно, то при открытии профиля в консоле браузера появится сообщение.

Шаг 4. Описываем логику расширения

Для начала нам необходимо определиться, на какое js событие нужно подписаться, прежде чем кастомизировать меню профиля. Как определить событие наглядно показано в видеоролике в моём телеграм канале. Опытным путём определяем, что нам подходит BX.UI.EntityConfigurationManager:onInitialize. Добавляем проверку на идентификатор иницилизируемого объекта, нас интересует «intranet-user-profile» и получаем узел меню.

// file path: local/js/aclips/add_menu_item/script.js

BX.ready(function () {
    BX.addCustomEvent("BX.UI.EntityConfigurationManager:onInitialize", BX.delegate((editor, settings) => {

        if (editor.getId() != "intranet-user-profile") {
            return;
        }
        
        let topMenuId = "#socialnetwork_profile_menu_user_" + editor._entityId;
        let topMenuNode = document.querySelector(topMenuId);

        if (!BX.type.isDomNode(topMenuNode)) {
            return;
        }

        console.log(topMenuNode)
    }));
});

В результате мы должны получить отображение блока меню

Создаём новый пункт и добавляем его в меню

Процесс создания нового пункта меню включает несколько шагов. Сначала мы определяем структуру нового пункта меню, задаем его название и функционал. Затем, используя соответствующие методы и функции, добавляем этот пункт в меню профиля пользователя.

BX.ready(function () {
    BX.addCustomEvent("BX.UI.EntityConfigurationManager:onInitialize", BX.delegate((editor, settings) => {

        if (editor.getId() != "intranet-user-profile") {
            return;
        }

        let topMenuId = "#socialnetwork_profile_menu_user_" + editor._entityId;
        let topMenuNode = document.querySelector(topMenuId);

        if (!BX.type.isDomNode(topMenuNode)) {
            return;
        }

        let item = BX.create("div", {
            attrs: {
                className: "main-buttons-item",
                id: "socialnetwork_profile_menu_user_" + editor._entityId + "_learning",
                draggable: true,
                tabindex: -1,
            },
            dataset: {
                disabled: false,
                id: "learning",
                topMenuId: topMenuId,
            },
        });

        item.innerHTML = '<span class="main-buttons-item-link">' +
            '<span class="main-buttons-item-text-title">' +
            '<span class="main-buttons-item-text-box">Обучение</span>' +
            '</span>' +
            '</span>';

        item.onclick = function (event) {
            BX.SidePanel.Instance.open("/learning/" + editor._entityId + "/", {
                cacheable: false,
            });
        }

        // Добавим его вторым
        BX.insertAfter(item, topMenuNode.firstElementChild);
    }));
});

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

Шаг 5. Тестирование

Для проверки функционала откроем профиль сотрудника из любого места и перейдем по новому пункту меню.

Завершение

В итоге мы успешно реализовали поставленную задачу по добавлению нового пункта меню в профиль сотрудника в Bitrix24, не затрагивая стандартные компоненты системы. Теперь при нажатии на пункт «Обучение» открывается слайдер с указанной страницей, где можно разместить компонент для отображения результатов.

Если у вас возникли вопросы или задачи, не стесняйтесь обращаться ко мне. Я готов помочь в решении ваших проблем. Для этого используйте форму обратной связи. Я рад своим читателям и готов поддержать вас в процессе работы с Bitrix24 (и не только 🙂 ).

Добавить комментарий