Prezentacja

Ta strona opisuje komponenty, których można użyć do utworzenia widoku prezentacji widgetu. Widok prezentacji widgetu to część widgetu, która otrzymuje dane zgodnie z jego konfiguracją i wyświetla je na dashboardzie w kontenerze.

Widok prezentacji składa się z trzech części:

Akcja widgetu

Klasa akcji widgetu (WidgetView) zawiera metody operacji na widgetach w trybie widoku prezentacji. Większość akcji widgetów używa domyślnej klasy kontrolera CControllerDashboardWidgetView i/lub ją rozszerza.

Klasa akcji widgetu powinna znajdować się w katalogu actions i być określona w parametrze actions (actions/widget.{id}.view/class) w pliku manifest.json.

Przykład actions/WidgetView.php (zaimplementowany w natywnym widżecie Zabbix Informacje o systemie)

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()
            ]
        ]));
    }
}

Widok widgetu

Klasa widoku widgetu (CWidgetView) odpowiada za budowanie widoku prezentacji widgetu.

Klasa widoku widgetu powinna znajdować się w katalogu views. Jeśli plik zawierający klasę widoku widgetu ma inną nazwę niż domyślna (widget.view.php), należy ją określić w parametrze actions pliku manifest.json (actions/widget.{id}.view/view).

Przykład views/widget.view.php

<?php

/**
 * Mój niestandardowy widok widgetu.
 *
 * @var CView $this
 * @var array $data
 */

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

JavaScript

Klasa JavaScript odpowiada za określanie zachowania widżetu, takiego jak aktualizowanie danych widżetu, zmiana rozmiaru widżetu, wyświetlanie elementów widżetu itp.

Wszystkie operacje JavaScript używają i/lub rozszerzają bazową klasę JavaScript wszystkich widżetów pulpitu - CWidget. Klasa CWidget zawiera zestaw metod z domyślną implementacją zachowania widżetu. W zależności od złożoności widżetu metody te mogą być używane bez zmian lub rozszerzane.

Klasa CWidget zawiera następujące metody:

  • Metody definiujące cykl życia widżetu: onInitialize(), onStart(), onActivate(), onDeactivate(), onDestroy(), onEdit().
  • Metody obsługujące aktualizację i wyświetlanie danych widżetu: promiseUpdate(), getUpdateRequestData(), processUpdateResponse(response), processUpdateErrorResponse(error), setContents(response).
  • Metody modyfikujące wygląd widżetu: onResize(), hasPadding().

Klasa JavaScript powinna znajdować się w katalogu assets/js i być określona w parametrze assets (assets/js) w pliku manifest.json.

Metody cyklu życia

Metody cyklu życia widżetu są wywoływane przez pulpit nawigacyjny oraz na różnych etapach cyklu życia widżetu podczas jego istnienia w pulpicie nawigacyjnym.

Metoda onInitialize() definiuje początkowy stan i/lub wartości widżetu, bez wykonywania jakichkolwiek manipulacji HTML lub danymi. Metoda ta jest wywoływana, gdy tworzony jest widżet (tworzona jest instancja obiektu widżetu), zazwyczaj poprzez dodanie widżetu do strony pulpitu nawigacyjnego lub załadowanie strony pulpitu nawigacyjnego.

Przykład:

onInitialize() {
    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;
}

Metoda onStart() definiuje strukturę HTML widgetu, bez wykonywania jakiejkolwiek manipulacji danymi. Ta metoda jest wywoływana przed pierwszą aktywacją strony pulpitu, czyli zanim pulpit i jego widgety zostaną w pełni wyświetlone użytkownikowi.

Przykład:

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

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

Metoda onActivate() uaktywnia widget i czyni go interaktywnym poprzez włączenie niestandardowych detektorów zdarzeń (służących do reagowania na działania użytkownika) oraz zainicjowanie cyklu aktualizacji widgetu (aby utrzymywać jego zawartość na bieżąco). Ta metoda jest wywoływana po aktywacji strony pulpitu, czyli gdy zostanie ona w pełni wyświetlona w interfejsie użytkownika.

Należy pamiętać, że przed wywołaniem metody onActivate() widget znajduje się w stanie nieaktywnym (WIDGET_STATE_INACTIVE). Po pomyślnym wywołaniu widget przechodzi do stanu aktywnego (WIDGET_STATE_ACTIVE). W stanie aktywnym widget reaguje na działania, nasłuchuje zdarzeń, okresowo aktualizuje swoją zawartość i może współdziałać z innymi widgetami.

Przykład:

onActivate() {
    this._startClock();

    this._resize_observer = new ResizeObserver(this._events.resize);
    this._resize_observer.observe(this._target);
}

Metoda onDeactivate() zatrzymuje wszelką aktywność i interaktywność widżetu przez dezaktywację niestandardowych nasłuchiwaczy zdarzeń oraz zatrzymanie cyklu aktualizacji widżetu. Ta metoda jest wywoływana, gdy strona pulpitu jest dezaktywowana, to znaczy po przełączeniu na inną stronę lub usunięciu, albo gdy widżet zostanie usunięty ze strony pulpitu.

Należy pamiętać, że przed wywołaniem metody onDeactivate() widżet znajduje się w stanie aktywnym (WIDGET_STATE_ACTIVE). Po pomyślnym wywołaniu widżet przechodzi do stanu nieaktywnego (WIDGET_STATE_INACTIVE).

Przykład:

onDeactivate() {
    this._stopClock();
    this._resize_observer.disconnect();
}

Metoda onDestroy() wykonuje zadania związane z czyszczeniem przed usunięciem widgetu z dashboardu. Może to obejmować zamknięcie połączenia z bazą danych ustanowionego podczas inicjalizacji widgetu, usunięcie danych tymczasowych w celu zwolnienia pamięci systemowej i uniknięcia wycieków zasobów, wyrejestrowanie odbiorników zdarzeń związanych ze zmianą rozmiaru lub kliknięciami przycisków, aby zapobiec niepotrzebnej obsłudze zdarzeń i wyciekom pamięci itd. Metoda ta jest wywoływana, gdy widget lub strona dashboardu, która go zawiera, zostanie usunięta.

Należy pamiętać, że przed wywołaniem metody onDestroy() widget w stanie aktywnym (WIDGET_STATE_ACTIVE) jest zawsze dezaktywowany przez wywołanie metody onDeactivate().

Przykład:

onDestroy() {
    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);
    }
}

Metoda onEdit() definiuje wygląd i zachowanie widżetu, gdy dashboard przechodzi w tryb edycji. Ta metoda jest wywoływana, gdy dashboard przechodzi w tryb edycji, zwykle wtedy, gdy użytkownik korzysta z przycisku Edit widżetu lub przycisku Edit dashboard na dashboardzie.

Przykład:

onEdit() {
    this._deactivateGraph();
}
Metoda procesu aktualizacji

Metoda procesu aktualizacji widżetu są odpowiedzialne za pobieranie zaktualizowanych danych z serwera Zabbix lub dowolnego innego źródła danych i wyświetlanie ich w widżecie.

Metoda promiseUpdate() inicjuje proces aktualizacji danych przez pobieranie danych, zazwyczaj za pomocą żądań web lub wywołań API. Ta metoda jest wywoływana, gdy strona pulpitu jest wyświetlana, a następnie okresowo, aż strona pulpitu zostanie przełączona na inną stronę pulpitu.

Poniżej przedstawiono przykład domyślnej implementacji metody promiseUpdate() używanej przez większość natywnych widgetów Zabbix. W domyślnej implementacji metoda promiseUpdate() stosuje ogólny wzorzec pobierania danych z serwera. Tworzy nowy obiekt Curl z odpowiednim adresem URL i parametrami żądania, wysyła żądanie POST za pomocą metody fetch() z obiektem danych zbudowanym przez metodę getUpdateRequestData(), a następnie odpowiednio przetwarza odpowiedź (lub odpowiedź błędu) za pomocą processUpdateResponse(response) lub processUpdateErrorResponse(error). Ta implementacja jest odpowiednia dla większości widgetów, ponieważ zazwyczaj pobierają one dane w formacie JSON i obsługują je w spójny sposób.

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);
        });
    }

Metoda getUpdateRequestData() przygotowuje dane żądania do serwera w celu zaktualizowania widgetu, gromadząc różne właściwości i odpowiadające im wartości (identyfikatory widgetu, ustawienia filtrów, zakresy czasu itp.) ze stanu i konfiguracji widgetu oraz konstruując obiekt danych reprezentujący informacje, które należy wysłać do serwera w żądaniu aktualizacji. Ta metoda jest wywoływana wyłącznie jako część domyślnej metody promiseUpdate(), czyli podczas procesu aktualizacji widgetu.

Implementacja domyślna:

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._contents_size
    };
}

Metoda processUpdateResponse(response) obsługuje odpowiedź otrzymaną z serwera po żądaniu aktualizacji i, jeśli proces aktualizacji zakończył się pomyślnie i bez błędów, czyści dane widżetu oraz wyświetla nową zawartość za pomocą metody setContents(). Ta metoda jest wywoływana wyłącznie jako część domyślnej metody promiseUpdate(), czyli podczas procesu aktualizacji widżetu.

Implementacja domyślna:

processUpdateResponse(response) {
    this._setHeaderName(response.name);

    this._updateMessages(response.messages);
    this._updateInfo(response.info);
    this._updateDebug(response.debug);

    this.setContents(response);
}

Metoda processUpdateErrorResponse(error) obsługuje odpowiedź otrzymaną z serwera po żądaniu aktualizacji, jeśli odpowiedź zawiera błąd, i wyświetla komunikat/-y o błędzie. Ta metoda jest wywoływana wyłącznie jako część domyślnej metody promiseUpdate(), czyli podczas procesu aktualizacji widżetu.

Domyślna implementacja:

processUpdateErrorResponse(error) {
    this._updateMessages(error.messages, error.title);
}

Metoda setContents(response) wyświetla zawartość widgetu, jeśli proces aktualizacji widgetu zakończył się pomyślnie i bez błędów. Może to obejmować manipulowanie elementami DOM, aktualizowanie komponentów interfejsu użytkownika, stosowanie stylów lub formatowania itp. Ta metoda jest wywoływana wyłącznie jako część domyślnej metody processUpdateResponse(response), czyli podczas obsługi odpowiedzi otrzymanej z serwera po żądaniu aktualizacji.

Implementacja domyślna:

setContents(response) {
    this._body.innerHTML = response.body ?? '';
}
Metoda modyfikacji prezentacji

Metoda modyfikacji prezentacji widżetu jest odpowiedzialna za modyfikację wyglądu widżetu.

Metoda onResize() odpowiada za dostosowanie elementów wizualnych widżetu do nowego rozmiaru widżetu, co może obejmować zmianę rozmieszczenia elementów, dostosowanie wymiarów elementów, skracanie tekstu, implementację leniwego ładowania w celu poprawy responsywności podczas zmiany rozmiaru itp. Ta metoda jest wywoływana po zmianie rozmiaru widżetu, na przykład gdy użytkownik ręcznie zmienia rozmiar widżetu lub gdy zmieniany jest rozmiar okna przeglądarki.

Przykład:

onResize() {
    if (this.getState() === WIDGET_STATE_ACTIVE) {
        this._startUpdating();
    }
}

Metoda hasPadding() odpowiada za zastosowanie pionowego dopełnienia 8 px u dołu widżetu, gdy jest on skonfigurowany tak, aby wyświetlać nagłówek. Ta metoda jest wywoływana po aktywowaniu strony pulpitu, czyli gdy staje się ona stroną wyświetlaną w interfejsie użytkownika.

Implementacja domyślna:

hasPadding() {
    return this.getViewMode() !== ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER;
}

W przypadku niektórych widżetów konieczne jest wykorzystanie całej dostępnej przestrzeni widżetu do skonfigurowania na przykład niestandardowego koloru tła. Poniżej przedstawiono przykład implementacji metody hasPadding() używanej w natywnym widżecie Zabbix Wartość pozycji.

hasPadding() {
    return false;
}