Apresentação

Esta página descreve os componentes que podem ser usados para criar uma visualização de apresentação do widget. A visualização de apresentação do widget é a parte do widget que recebe os dados de acordo com sua configuração e os exibe no painel em um contêiner.

A exibição de apresentação consiste em três partes:

Ação do widget

A classe de ação do widget (WidgetView) contém métodos para operações com widgets no modo de exibição de apresentação. A maioria das ações de widget usa e/ou estende a classe de controlador padrão CControllerDashboardWidgetView.

A classe de ação do widget deve estar localizada no diretório actions e especificada no parâmetro actions (actions/widget.{id}.view/class) no arquivo manifest.json.

exemplo do arquivo actions/WidgetView.php (implementado no widget System information nativo do 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()
                   ]
               ]));
           }
       }

Visualização do widget

A classe de visualização do widget (CWidgetView) é responsável por criar a visualização de apresentação do widget.

A classe de visualização do widget deve estar localizada no diretório views. Se o arquivo que contém a classe de visualização do widget tiver um nome diferente do padrão (widget.view.php), ele deverá ser especificado no parâmetro do arquivo manifest.json actions (actions/widget.{id}.view/view).

exemplo de views/widget.view.php**

<?php
       
       /**
        * Minha visualização de widget personalizada.
        *
        * @var CView $this
        * @var array $data
        */
       
       (novo CWidgetView($data))
           ->addItem(
               novo CTag('h1', true, $data['name'])
           )
           ->show();

JavaScript

A classe JavaScript é responsável por determinar o comportamento do widget, como a atualização dos dados do widget, o redimensionamento do widget, a exibição de elementos do widget etc.

Todas as operações JavaScript usam e/ou estendem a classe JavaScript básica de todos os widgets do painel: CWidget. A classe CWidget contém um conjunto de métodos com a implementação padrão para o comportamento do widget. Dependendo da complexidade do widget, esses métodos podem ser utilizados como estão ou estendidos.

A classe CWidget contém os seguintes métodos:

  • Métodos que definem o ciclo de vida do widget: _init(), _registerEvents(), _doActivate(), _doDeactivate(), _doDestroy(), setEditMode().
  • Métodos que tratam da atualização e exibição de dados do widget: _promiseUpdate(), _getUpdateRequestData(), _processUpdateResponse(response), _processUpdateErrorResponse(error), _setContents().
  • Métodos que modificam a aparência do widget: resize(), _hasPadding().

A classe JavaScript deve estar localizada no diretório assets/js e especificada no parâmetro assets (assets/js) no arquivo manifest.json.

Métodos de ciclo de vida

Os métodos do ciclo de vida do widget são invocados pelo painel e em diferentes estágios do ciclo de vida do widget durante sua existência no painel.

O método _init() define o estado inicial e/ou os valores do widget, sem executar nenhuma manipulação de HTML ou de dados. Esse método é chamado quando um widget é criado (um objeto de widget é instanciado), normalmente adicionando o widget a uma página do painel ou carregando a página do painel.

Exemplo:

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

O método _registerEvents() define a estrutura HTML do widget, sem executar nenhuma manipulação de dados. Esse método é chamado antes da primeira ativação da página do painel, ou seja, antes que o painel e seus widgets sejam totalmente exibidos para o usuário.

Exemplo:

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

O método _doActivate() torna o widget ativo e interativo ativando ouvintes de eventos personalizados (para responder às ações do usuário) e iniciando o ciclo de atualização do widget (para manter seu conteúdo atualizado). Esse método é chamado quando a página do painel é ativada, ou seja, quando ela é totalmente exibida na interface do usuário.

Observe que, antes de o método _doActivate() ser chamado, o widget está no estado inativo (WIDGET_STATE_INACTIVE). Após a invocação bem-sucedida, o widget passa para o estado ativo (WIDGET_STATE_ACTIVE). No estado ativo, o widget é responsivo, ouve eventos, atualiza seu conteúdo periodicamente e pode interagir com outros widgets.

Exemplo:

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

O método _doDeactivate() interrompe qualquer atividade e interatividade do widget, desativando os ouvintes de eventos personalizados e interrompendo o ciclo de atualização do widget. Esse método é invocado quando a página do painel é desativada, ou seja, é removida ou excluída, ou quando o widget é excluído da página do painel.

Observe que, antes de o método _doDeactivate() ser chamado, o widget está no estado ativo (WIDGET_STATE_ACTIVE). Após a invocação bem-sucedida, o widget passa para o estado inativo (WIDGET_STATE_INACTIVE).

Exemplo:

_doDeactivate() {
           super._doDeactivate();
       
           this._deactivateContentsEvents();
       }

O método _doDestroy() executa tarefas de limpeza antes que o widget seja excluído do painel, que podem incluir o fechamento de uma conexão de banco de dados que foi estabelecida durante a inicialização do widget, limpeza de dados temporários para liberar memória do sistema e evitar vazamentos de recursos, o cancelamento do registro de ouvintes de eventos relacionados a eventos de redimensionamento ou cliques em botões para evitar o tratamento desnecessário de eventos e vazamentos de memória etc. Esse método é chamado quando o widget ou a página do painel que o contém é excluído.

Observe que, antes que o método _doDestroy() seja chamado, um widget em um estado ativo (WIDGET_STATE_ACTIVE) é sempre desativado com a chamada do método _doDeactivate().

Exemplo:

_doDestroy() {
           super._doDestroy();
       
           se (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);
           }
       }

O método setEditMode() define a aparência e o comportamento do widget quando o painel passa para o modo de edição. Esse método é chamado quando o painel passa para o modo de edição, normalmente quando um usuário interage com o botão Edit do widget ou com o botão Edit dashboard do painel.

Exemplo:

setEditMode() {
           se (this._has_contents) {
               this._deactivateContentsEvents();
               this._removeTree();
           }
       
           super.setEditMode();
       
           se (this._has_contents && this._state === WIDGET_STATE_ACTIVE) {
               this._makeTree();
               this._activateTree();
               this._activateContentsEvents();
           }
       }
Atualizar métodos de processo

Os métodos do processo de atualização do widget são responsáveis por recuperar dados atualizados do servidor Zabbix ou de qualquer outra fonte de dados e exibi-los no widget.

O método _promiseUpdate() inicia o processo de atualização de dados recuperando dados, normalmente usando solicitações da Web ou chamadas de API. Esse método é chamado quando uma página do painel é exibida e periodicamente depois, até que a página do painel seja alternada para outra página do painel.

A seguir, um exemplo da implementação padrão do método _promiseUpdate() usado pela maioria dos widgets nativos do Zabbix. Na implementação padrão, o método _promiseUpdate() segue um padrão geral para recuperar dados do servidor. Ele cria um novo objeto Curl com a URL e os parâmetros de solicitação apropriados, envia uma solicitação POST usando o método fetch() com o objeto de dados construído pelo método _getUpdateRequestData(), e processa a resposta (ou uma resposta de erro) com os métodos _processUpdateResponse(response) ou _processUpdateErrorResponse(error) de acordo. Essa implementação é adequada para a maioria dos widgets, pois eles normalmente recuperam dados em um formato JSON e os tratam de maneira consistente.

_promiseUpdate() {
           const curl = new Curl('zabbix.php');
       
           curl.setArgument('action', `widget.${this._type}.view`);
       
           return fetch(curl.getUrl(), {
               método: 'POST',
               headers: {'Content-Type': 'application/json'},
               body: JSON.stringify(this._getUpdateRequestData()),
               signal: this._update_abort_controller.signal
           })
               .then((response) => response.json())
               .then((response) => {
                   se ('error' na resposta) {
                       this._processUpdateErrorResponse(response.error);
       
                       return;
                   }
       
                   this._processUpdateResponse(response);
               });
       }

O método _getUpdateRequestData() prepara os dados da solicitação do servidor para atualizar o widget, reunindo várias propriedades e seus valores correspondentes (identificadores de widget, configurações de filtro, intervalos de tempo, etc.) do estado e da configuração do widget, e construindo um objeto de dados que representa as informações necessárias a serem enviadas ao servidor na solicitação de atualização. Este método é invocado apenas como parte do método padrão _promiseUpdate(), ou seja, durante o processo de atualização do widget.

Implementação padrão:

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

O método _processUpdateResponse(response) trata a resposta recebida do servidor após a solicitação de atualização, e, se o processo de atualização tiver sido bem-sucedido e sem erros, limpa os dados do widget e exibe o novo conteúdo com o método _setContents(). Esse método é chamado somente como parte do método padrão _promiseUpdate(), ou seja, durante o processo de atualização do widget.

Implementação padrão:

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

O método _processUpdateErrorResponse(error) trata a resposta recebida do servidor após a solicitação de atualização, se a resposta for um erro, e exibe a mensagem de erro. Esse método é chamado somente como parte do método padrão _promiseUpdate(), ou seja, durante o processo de atualização do widget.

Implementação padrão:

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

O método _setContents() exibe o conteúdo do widget se o processo de atualização do widget tiver sido bem-sucedido e sem erros, que pode incluir a manipulação de elementos DOM, a atualização de componentes da interface do usuário, a aplicação de estilos ou formatação, etc. Esse método é chamado somente como parte do método padrão _processUpdateResponse(response), ou seja, durante o processo de manipulação da resposta recebida do servidor após a solicitação de atualização.

Implementação padrão:

_setContents({name, body, messages, info, debug}) {
           this._setHeaderName(name);
       
           this._content_body.innerHTML = '';
       
           se (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();
       
           se (info !== undefined) {
               this._addInfoButtons(info);
           }
       }
Métodos de modificação de apresentação

Os métodos de modificação da apresentação do widget são responsáveis por modificar a aparência do widget.

O método resize() é responsável por ajustar os elementos visuais do widget para acomodar o novo tamanho do widget, o que pode incluir a reorganização dos elementos, o ajuste das dimensões dos elementos, o truncamento do texto, a implementação do carregamento lento para melhorar a capacidade de resposta durante o redimensionamento etc. Esse método é chamado quando o widget é redimensionado, por exemplo, quando o usuário redimensiona manualmente o widget ou quando a janela do navegador é redimensionada.

Exemplo:

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

O método _hasPadding() é responsável por aplicar um preenchimento vertical de 8px na parte inferior do widget quando ele está configurado para [mostrar seu cabeçalho] (/manual/web_interface/frontend_sections/dashboards/widgets#common-parameters). Esse método é chamado quando a página do painel é ativada, ou seja, quando ela se torna a página exibida na interface do usuário.

Implementação padrão:

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

Para alguns widgets, é necessário usar todo o espaço disponível do widget para configurar, por exemplo, uma cor de fundo personalizada. A seguir, um exemplo da implementação do método _hasPadding() usado no widget nativo do Zabbix Item value.

_hasPadding() {
           return false;
       }