Презентация

На этой странице описаны компоненты, которые можно использовать для создания представления виджета. Представление виджета - это часть виджета, которая получает данные в соответствии со своей конфигурацией и отображает их на информационной панели в контейнере.

Представление презентации состоит из трех частей:

Действие виджета

Класс действий виджета (WidgetView) содержит методы для работы с виджетами в режиме просмотра презентации. Большинство действий виджетов используют и/или расширяют класс контроллера по умолчанию CControllerDashboardWidgetView.

Класс действия виджета должен находиться в каталоге actions и указываться в параметре actions (actions/widget.{id}.view/class) в файле manifest.json.

Пример actions/WidgetView.php (реализован в родном для Zabbix виджете Информация о системе)

class WidgetView extends CControllerDashboardWidgetView {

    protected function doAction(): void {
        $this->setResponse(new CControllerResponseData([
            'name' => $this->getInput('name', $this->widget->getDefaultName()),
            'system_info' => CSystemInfoHelper::getData(),
            'info_type' => $this->fields_values['info_type'],
            'user_type' => CWebUser::getType(),
            'user' => [
                'debug_mode' => $this->getDebugMode()
            ]
        ]));
    }
}

Виджет

Класс представления виджета (CWidgetView) отвечает за построение представления виджета.

Класс представления виджета должен находиться в каталоге views. Если файл, содержащий класс представления виджета, имеет имя, отличное от имени по умолчанию (widget.view.php), то его необходимо указать в файле manifest.json actions параметр (actions/widget.{id}.view/view).

пример views/widget.view.php

<?php

/**
 * My custom widget view.
 *
 * @var CView $this
 * @var array $data
 */

(new CWidgetView($data))
    ->addItem(
        new CTag('h1', true, $data['name'])
    )
    ->show();

JavaScript

Класс JavaScript отвечает за определение поведения виджета, например, обновление данных виджета, изменение размера виджета, отображение элементов виджета и т. д.

Все операции JavaScript используют и/или расширяют базовый класс JavaScript всех виджетов панели - CWidget. Класс CWidget содержит набор методов с реализацией по умолчанию для поведения виджета. В зависимости от сложности виджета эти методы можно использовать как есть или расширить.

Класс CWidget содержит следующие методы:

  • Методы, определяющие жизненный цикл виджета: onInitialize(), onStart(), onActivate(), onDeactivate(), onDestroy(), onEdit().
  • Методы, обрабатывающие обновление и отображение данных виджета: promiseUpdate(), getUpdateRequestData(), processUpdateResponse(response), processUpdateErrorResponse(error), setContents(response).
  • Методы, изменяющие внешний вид виджета: onResize(), hasPadding().

Класс JavaScript должен находиться в каталоге assets/js и указываться в параметре assets (assets/js) в manifest.json файл.

Методы жизненного цикла

Методы жизненного цикла виджета вызываются панелью и на разных этапах жизненного цикла виджета во время его существования на панели.

Метод _init() определяет исходное состояние и/или значения виджета без выполнения каких-либо манипуляций с HTML или данными. Этот метод вызывается при создании виджета (создается экземпляр объекта виджета), обычно путем добавления виджета на страницу панели или загрузки страницы панели.

Пример:

_init() {
    super._init();

    this._time_offset = 0;
    this._interval_id = null;
    this._clock_type = CWidgetClock.TYPE_ANALOG;
    this._time_zone = null;
    this._show_seconds = true;
    this._time_format = 0;
    this._tzone_format = 0;
    this._show = [];
    this._has_contents = false;
    this._is_enabled = true;
}

Метод _registerEvents() определяет HTML-структуру виджета, не выполняя никаких манипуляций с данными. Этот метод вызывается перед первой активацией страницы панели мониторинга, то есть до того, как панель мониторинга и ее виджеты полностью отобразятся пользователю.

Пример:

_registerEvents() {
    super._registerEvents();

    this._events.resize = () => {
        const padding = 25;
        const header_height = this._view_mode == ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER
            ? 0
            : this._content_header.offsetHeight;

        this._target.style.setProperty(
            '--content-height',
            `${this._cell_height * this._pos.height - padding * 2 - header_height}px`
        );
    }
}

Метод _doActivate() делает виджет активным и интерактивным, включая настраиваемые прослушиватели событий (для реагирования на действия пользователя) и запуская цикл обновления виджета (для поддержания актуальности его содержимого). Этот метод вызывается при активации страницы информационной панели, то есть когда она полностью отображается в пользовательском интерфейсе.

Обратите внимание, что до вызова метода _doActivate() виджет находится в неактивном состоянии («WIDGET_STATE_INACTIVE»). После успешного вызова виджет переходит в активное состояние («WIDGET_STATE_ACTIVE»). В активном состоянии виджет реагирует, слушает события, периодически обновляет свое содержимое и может взаимодействовать с другими виджетами.

Пример:

_doActivate() {
    super._doActivate();

    if (this._has_contents) {
        this._activateContentsEvents();
    }
}

Метод _doDeactivate() останавливает любую активность и интерактивность виджета, деактивируя пользовательские прослушиватели событий и останавливая цикл обновления виджета. Этот метод вызывается, когда страница панели деактивируется, то есть отключается или удаляется, или когда виджет удаляется со страницы панели.

Обратите внимание, что до вызова метода _doDeactivate() виджет находится в активном состоянии (WIDGET_STATE_ACTIVE). После успешного вызова виджет переходит в неактивное состояние («WIDGET_STATE_INACTIVE»).

Пример:

_doDeactivate() {
    super._doDeactivate();

    this._deactivateContentsEvents();
}

Метод _doDestroy() выполняет задачи очистки перед удалением виджета с панели управления, что может включать в себя закрытие соединения с базой данных, которое было установлено во время инициализации виджета, очистка временных данных для освобождения системной памяти и предотвращения утечек ресурсов, отмена регистрации прослушивателей событий, связанных с событиями изменения размера или нажатиями кнопок, чтобы предотвратить ненужную обработку событий и утечки памяти и т. д. Этот метод вызывается при удалении виджета или страницы информационной панели, которая его содержит.

Обратите внимание, что перед вызовом метода _doDestroy() виджет в активном состоянии (WIDGET_STATE_ACTIVE) всегда деактивируется с помощью вызова метода _doDeactivate().

Пример:

_doDestroy() {
    super._doDestroy();

    if (this._filter_widget) {
        this._filter_widget.off(CWidgetMap.WIDGET_NAVTREE_EVENT_MARK, this._events.mark);
        this._filter_widget.off(CWidgetMap.WIDGET_NAVTREE_EVENT_SELECT, this._events.select);
    }
}

Метод setEditMode() определяет внешний вид и поведение виджета при переходе панели управления в режим редактирования. Этот метод вызывается, когда панель мониторинга переходит в режим редактирования, обычно когда пользователь взаимодействует с кнопкой Редактировать виджета или кнопкой Редактировать панель панели мониторинга.

Пример:

setEditMode() {
    if (this._has_contents) {
        this._deactivateContentsEvents();
        this._removeTree();
    }

    super.setEditMode();

    if (this._has_contents && this._state === WIDGET_STATE_ACTIVE) {
        this._makeTree();
        this._activateTree();
        this._activateContentsEvents();
    }
}
Методы обновления виджета

Методы процесса обновления виджета отвечают за получение обновленных данных с сервера Zabbix или любого другого источника данных и их отображение в виджете.

Метод _promiseUpdate() инициирует процесс обновления данных путем получения данных, обычно с помощью веб-запросов или вызовов API. Этот метод вызывается при отображении страницы панели и периодически после этого, пока страница панели не переключится на другую страницу панели.

Ниже приведен пример реализации по умолчанию метода _promiseUpdate(), используемого большинством родных виджетов Zabbix. В реализации по умолчанию метод _promiseUpdate() соответствует общему шаблону получения данных с сервера. Он создает новый объект Curl с соответствующим URL-адресом и параметрами запроса, отправляет запрос POST с помощью метода fetch() с объектом данных, созданным методом _getUpdateRequestData(), и обрабатывает ответ (или ответ об ошибке) с помощью _processUpdateResponse(response) или _processUpdateErrorResponse(error) соответственно. Эта реализация подходит для большинства виджетов, поскольку они обычно получают данные в формате JSON и обрабатывают их согласованным образом.

_promiseUpdate() {
    const curl = new Curl('zabbix.php');

    curl.setArgument('action', `widget.${this._type}.view`);

    return fetch(curl.getUrl(), {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(this._getUpdateRequestData()),
        signal: this._update_abort_controller.signal
    })
        .then((response) => response.json())
        .then((response) => {
            if ('error' in response) {
                this._processUpdateErrorResponse(response.error);

                return;
            }

            this._processUpdateResponse(response);
        });
}

Метод _getUpdateRequestData() подготавливает данные запроса сервера для обновления виджета, собирая различные свойства и соответствующие им значения (идентификаторы виджета, настройки фильтра, временные диапазоны и т. д.) из состояния и конфигурации виджета, и создание объекта данных, который представляет необходимую информацию, подлежащую отправке на сервер в запросе на обновление. Этот метод вызывается только как часть метода _promiseUpdate() по умолчанию, то есть во время процесса обновления виджета.

Реализация по умолчанию:

_getUpdateRequestData() {
    return {
        templateid: this._dashboard.templateid ?? undefined,
        dashboardid: this._dashboard.dashboardid ?? undefined,
        widgetid: this._widgetid ?? undefined,
        name: this._name !== '' ? this._name : undefined,
        fields: Object.keys(this._fields).length > 0 ? this._fields : undefined,
        view_mode: this._view_mode,
        edit_mode: this._is_edit_mode ? 1 : 0,
        dynamic_hostid: this._dashboard.templateid !== null || this.supportsDynamicHosts()
            ? (this._dynamic_hostid ?? undefined)
            : undefined,
        ...this._content_size
    };
}

Метод _processUpdateResponse(response) обрабатывает ответ, полученный от сервера после запроса на обновление, и, если процесс обновления прошел успешно и без ошибок, очищает данные виджета и отображает новое содержимое с помощью метода _setContents(). Этот метод вызывается только как часть метода _promiseUpdate() по умолчанию, то есть во время процесса обновления виджета.

Реализация по умолчанию:

_processUpdateResponse(response) {
    this._setContents({
        name: response.name,
        body: response.body,
        messages: response.messages,
        info: response.info,
        debug: response.debug
    });
}

Метод _processUpdateErrorResponse(error) обрабатывает ответ, полученный от сервера после запроса на обновление, если ответ является ошибкой, и отображает сообщения об ошибках. Этот метод вызывается только как часть метода по умолчанию _promiseUpdate(), то есть во время процесса обновления виджета.

Реализация по умолчанию:

_processUpdateErrorResponse(error) {
    this._setErrorContents({error});
}

_setErrorContents({error}) {
    const message_box = makeMessageBox('bad', error.messages, error.title)[0];

    this._content_body.innerHTML = '';
    this._content_body.appendChild(message_box);

    this._removeInfoButtons();
}

Метод _setContents() отображает содержимое виджета, если процесс обновления виджета прошел успешно и без ошибок, что может включать в себя манипулирование элементами DOM, обновление компонентов пользовательского интерфейса, применение стилей или форматирования и т. д. Этот метод вызывается только как часть метода _processUpdateResponse(response) по умолчанию, то есть в процессе обработки ответа, полученного от сервера после запроса на обновление.

Реализация по умолчанию:

_setContents({name, body, messages, info, debug}) {
    this._setHeaderName(name);

    this._content_body.innerHTML = '';

    if (messages !== undefined) {
        const message_box = makeMessageBox('bad', messages)[0];

        this._content_body.appendChild(message_box);
    }

    if (body !== undefined) {
        this._content_body.insertAdjacentHTML('beforeend', body);
    }

    if (debug !== undefined) {
        this._content_body.insertAdjacentHTML('beforeend', debug);
    }

    this._removeInfoButtons();

    if (info !== undefined) {
        this._addInfoButtons(info);
    }
}
Методы модификации представления

Методы модификации представления виджета отвечают за изменение внешнего вида виджета.

Метод resize() отвечает за настройку визуальных элементов виджета в соответствии с новым размером виджета, которые могут включать перестановку элементов, настройку размеров элементов, усечение текста, реализацию отложенной загрузки для улучшения реагирования при изменении размера и т. д. Этот метод вызывается при изменении размера виджета, например, когда пользователь вручную изменяет размер виджета или когда изменяется размер окна браузера.

Пример:

resize() {
    if (this._state === WIDGET_STATE_ACTIVE) {
        this._startUpdating();
    }
}

Метод _hasPadding() отвечает за применение вертикального заполнения шириной 8 пикселей в нижней части виджета, когда он настроен на показ заголовка. Этот метод вызывается, когда страница информационной панели активируется, то есть когда она становится отображаемой страницей в пользовательском интерфейсе.

Реализация по умолчанию:

_hasPadding() {
    return this._view_mode !== ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER;
}

Для некоторых виджетов необходимо использовать все доступное пространство виджетов, например, для настройки собственного цвета фона. Ниже приведен пример реализации метода _hasPadding(), используемого в родном для Zabbix виджете значение элемента данных.

_hasPadding() {
    return false;
}