Презентація

Ця сторінка описує компоненти, які можуть бути використані для створення представлення віджету. Представлення віджету - це частина віджету, яка отримує дані відповідно до його конфігурації і відображає їх на інформаційній панелі в контейнері.

Вид презентації складається з трьох частин:

Widget action

Клас дій віджетів (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()
                   ]
               ]));
           }
       }

Widget view

Клас view віджетів (CWidgetView) відповідає за створення представлення view віджетів.

Клас view віджета має бути розташований у каталозі views. Якщо файл, що містить клас view віджетів, має іншу назву, ніж назва за замовчуванням (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 містить такі методи:

  • Методи, що визначають життєвий цикл віджета: _init(), _registerEvents(), _doActivate(), _doDeactivate(), _doDestroy(), setEditMode().
  • Методи, які обробляють оновлення та відображення даних віджетів: _promiseUpdate(), _getUpdateRequestData(), _processUpdateResponse(response), _processUpdateErrorResponse(error), _setContents().
  • Методи, які змінюють зовнішній вигляд віджета: resize(), _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() робить віджет активним та інтерактивним, вмикаючи користувацькі listener-и подій (для реагування на дії користувача) та ініціюючи цикл оновлення віджета (для підтримання його вмісту в актуальному стані). Цей метод викликається, коли сторінка дашборду активована, тобто коли вона стає повністю відображеною в інтерфейсі користувача.

Зверніть увагу, що до виклику методу _doActivate() віджет знаходиться в неактивному стані (WIDGET_STATE_INACTIVE). Після успішного виклику віджет переходить в активний стан (WIDGET_STATE_ACTIVE). В активному стані віджет реагує на події, періодично оновлює свій вміст і може взаємодіяти з іншими віджетами.

приклад:

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

Метод _doDeactivate() зупиняє будь-яку активність та інтерактивність віджета, деактивуючи користувацькі listener-и подій та зупиняючи цикл оновлення віджета. Цей метод викликається, коли сторінка інформаційної панелі деактивована, тобто переключена або видалена, або коли віджет видалено зі сторінки інформаційної панелі.

Зверніть увагу, що до виклику методу _doDeactivate() віджет знаходиться в активному стані (WIDGET_STATE_ACTIVE), після успішного виклику віджет переходить в неактивний стан (WIDGET_STATE_INACTIVE).

приклад:

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

Метод _doDestroy() виконує завдання очищення перед видаленням віджета з панелі інструментів, які можуть включати закриття з'єднання з базою даних, яке було встановлено під час ініціалізації віджета, очищення тимчасових даних, щоб звільнити системну пам'ять і уникнути витоку ресурсів, скасування реєстрації listener-ів подій, пов'язаних зі зміною розміру або натисканням кнопок, щоб запобігти непотрібній обробці подій і витоку пам'яті тощо. Цей метод викликається, коли видаляється віджет або сторінка інформаційної панелі, яка його містить.

Зверніть увагу, що перед викликом методу _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() відповідає за застосування вертикального відступу 8px внизу віджета, коли він налаштований на відображення його заголовку. Цей метод викликається, коли сторінка дашборда активована, тобто коли вона стає сторінкою, що відображається в інтерфейсі користувача.

Реалізація за замовчуванням:

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

Для деяких віджетів необхідно використовувати весь доступний простір віджету, щоб налаштувати, наприклад, користувацький колір фону. Нижче наведено приклад реалізації методу _hasPadding(), який використовується у віджеті Значення елементу даних, що є нативним для Zabbix.

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