. **/ namespace Widgets\PieChart\Includes; use CButton, CButtonIcon, CButtonLink, CCol, CColorPicker, CDiv, CFormField, CFormGrid, CHorList, CItemHelper, CLabel, CLink, CList, CListItem, CPatternSelect, CRow, CScriptTag, CSelect, CSimpleButton, CSpan, CTable, CTableColumn, CTag, CTemplateTag, CTextBox, CVar, CWidgetFieldView, CWidgetFieldTagsView; use CRadioButtonList; use Zabbix\Widgets\CWidgetField; use Zabbix\Widgets\Fields\CWidgetFieldTags; class CWidgetFieldDataSetView extends CWidgetFieldView { public function __construct(CWidgetFieldDataSet $field) { $this->field = $field; } public function getView(): CList { $view = (new CList())->setId('data_sets'); $values = $this->field->getValue(); if (!$values) { $values[] = CWidgetFieldDataSet::getDefaults(); } // Get item names for single item datasets. $itemids = []; foreach (array_column($values, 'itemids') as $items_spec) { foreach ($items_spec as $item_spec) { if (!is_array($item_spec)) { $itemids[$item_spec] = true; } } } $item_names = $itemids ? CWidgetFieldDataSet::getItemNames(array_keys($itemids), !$this->field->isTemplateDashboard()) : []; foreach ($values as $i => $value) { if ($value['dataset_type'] == CWidgetFieldDataSet::DATASET_TYPE_SINGLE_ITEM) { $value['item_names'] = $item_names; } $view->addItem( $this->getDataSetLayout($value, $value['dataset_type'], $i == 0, $i) ); } return $view; } public function getFooterView(): CList { return (new CList()) ->addClass(ZBX_STYLE_BTN_SPLIT) ->addItem( (new CSimpleButton(_('Add new data set'))) ->setId('dataset-add') ->addClass(ZBX_STYLE_BTN_ALT) ->addClass(ZBX_ICON_PLUS_SMALL) ) ->addItem( (new CSimpleButton()) ->setId('dataset-menu') ->addClass(ZBX_STYLE_BTN_ALT) ->addClass(ZBX_ICON_CHEVRON_DOWN_SMALL) ); } public function getTemplates(): array { $value = ['color' => '#{color}'] + CWidgetFieldDataSet::getDefaults(); return [ new CTemplateTag('dataset-pattern-item-tmpl', $this->getDataSetLayout($value, CWidgetFieldDataSet::DATASET_TYPE_PATTERN_ITEM, true) ), new CTemplateTag('dataset-single-item-tmpl', $this->getDataSetLayout($value, CWidgetFieldDataSet::DATASET_TYPE_SINGLE_ITEM, true) ), new CTemplateTag('dataset-item-row-tmpl', $this->getItemRowTemplate()) ]; } private function getDataSetLayout(array $value, int $dataset_type, bool $is_opened, $row_num = '#{rowNum}'): CListItem { $field_name = $this->field->getName(); $dataset_head = [ new CDiv( (new CButtonIcon(ZBX_ICON_CHEVRON_UP))->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM_TOGGLE) ), new CVar($field_name.'['.$row_num.'][dataset_type]', $dataset_type, '') ]; if ($dataset_type == CWidgetFieldDataSet::DATASET_TYPE_PATTERN_ITEM) { if ($this->field->isTemplateDashboard()) { $host_pattern_field = null; $item_pattern_field = (new CPatternSelect([ 'name' => $field_name.'['.$row_num.'][items][]', 'object_name' => 'items', 'data' => $value['items'], 'placeholder' => _('item patterns'), 'wildcard_allowed' => 1, 'popup' => [ 'parameters' => [ 'srctbl' => 'items', 'srcfld1' => 'name', 'hostid' => $this->field->getTemplateId(), 'hide_host_filter' => true, 'numeric' => 1, 'dstfrm' => $this->form_name, 'dstfld1' => zbx_formatDomId($field_name.'['.$row_num.'][items][]') ] ], 'add_post_js' => false ]))->addClass('js-items-multiselect'); } else { $host_pattern_field = (new CPatternSelect([ 'name' => $field_name.'['.$row_num.'][hosts][]', 'object_name' => 'hosts', 'data' => $value['hosts'], 'placeholder' => _('host patterns'), 'wildcard_allowed' => 1, 'popup' => [ 'parameters' => [ 'srctbl' => 'hosts', 'srcfld1' => 'host', 'dstfrm' => $this->form_name, 'dstfld1' => zbx_formatDomId($field_name.'['.$row_num.'][hosts][]') ] ], 'add_post_js' => false ]))->addClass('js-hosts-multiselect'); $item_pattern_field = (new CPatternSelect([ 'name' => $field_name.'['.$row_num.'][items][]', 'object_name' => 'items', 'data' => $value['items'], 'placeholder' => _('item patterns'), 'wildcard_allowed' => 1, 'popup' => [ 'parameters' => [ 'srctbl' => 'items', 'srcfld1' => 'name', 'real_hosts' => 1, 'numeric' => 1, 'resolve_macros' => 1, 'dstfrm' => $this->form_name, 'dstfld1' => zbx_formatDomId($field_name.'['.$row_num.'][items][]') ], 'filter_preselect' => [ 'id' => $host_pattern_field->getId(), 'submit_as' => 'host_pattern', 'submit_parameters' => [ 'host_pattern_wildcard_allowed' => 1, 'host_pattern_multiple' => 1 ], 'multiple' => true ] ], 'autosuggest' => [ 'filter_preselect' => [ 'id' => $host_pattern_field->getId(), 'submit_as' => 'host_pattern', 'submit_parameters' => [ 'host_pattern_wildcard_allowed' => 1, 'host_pattern_multiple' => 1 ], 'multiple' => true ] ], 'add_post_js' => false ]))->addClass('js-items-multiselect'); } $dataset_head[] = (new CColorPicker($field_name.'['.$row_num.'][color]', $field_name.'['.$row_num.'][color_palette]') ) ->setPalette($value['color_palette'] ?? null) ->setColor($value['color'] ?? null); if ($host_pattern_field !== null) { $dataset_head[] = $host_pattern_field; $dataset_head[] = new CScriptTag($host_pattern_field->getPostJS()); } $dataset_head[] = $item_pattern_field; $dataset_head[] = new CScriptTag($item_pattern_field->getPostJS()); $item_tags_evaltype_field = [ new CLabel(_('Item tags')), new CFormField( (new CRadioButtonList($field_name.'['.$row_num.'][item_tags_evaltype]', (int) $value['item_tags_evaltype']) ) ->addValue(_('And/Or'), TAG_EVAL_TYPE_AND_OR) ->addValue(_('Or'), TAG_EVAL_TYPE_OR) ->setModern() ) ]; $item_tags_table_field = []; $item_tags_table_view = (new CWidgetFieldTagsView( (new CWidgetFieldTags($field_name.'['.$row_num.'][item_tags]'))->setValue($value['item_tags']) ))->setFormName($this->form_name); foreach ($item_tags_table_view->getViewCollection() as ['label' => $label, 'view' => $view, 'class' => $class]) { $item_tags_table_field[] = [$label, (new CFormField($view))->addClass($class)]; } $item_tags_table_field[] = $item_tags_table_view->getTemplates(); $item_tags_table_field[] = (new CScriptTag($item_tags_table_view->getJavaScript()))->setOnDocumentReady(); $form_grid_right = (new CFormGrid()) ->addItem($item_tags_evaltype_field) ->addItem($item_tags_table_field); } else { $item_rows = []; foreach ($value['itemids'] as $i => $item_spec) { if (is_array($item_spec)) { $itemid = '0'; $item_reference = $item_spec[CWidgetField::FOREIGN_REFERENCE_KEY]; $item_name = ''; } else { $itemid = $item_spec; $item_reference = ''; $item_name = array_key_exists($itemid, $value['item_names']) ? $value['item_names'][$itemid] : ''; } $item_rows[] = $this->getItemRowTemplate($row_num, ($i + 1), $itemid, $item_reference, $item_name, $value['color'][$i], $value['type'][$i] ); } $empty_msg_block = (new CDiv(_('No item selected.')))->addClass('no-items-message'); $items_list = (new CTable()) ->addClass('single-item-table') ->setAttribute('data-set', $row_num) ->setColumns([ (new CTableColumn())->addClass('table-col-handle'), (new CTableColumn())->addClass('table-col-color'), (new CTableColumn())->addClass('table-col-no'), (new CTableColumn(_('Name')))->addClass('table-col-name'), (new CTableColumn(_('Type')))->addClass('table-col-type'), (new CTableColumn(_('Action')))->addClass('table-col-action') ]) ->addItem($item_rows) ->addItem( (new CTag('tfoot', true, (new CCol( new CHorList([ (new CButtonLink(_('Add item')))->addClass('js-add-item'), (new CButtonLink(_('Add widget')))->addClass('js-add-widget') ]) ))->setColSpan(5) )) ); $dataset_head = array_merge($dataset_head, [ (new CDiv([$empty_msg_block, $items_list]))->addClass('items-list table-forms-separator') ]); $form_grid_right = null; } $dataset_head[] = (new CDiv( (new CButtonIcon(ZBX_ICON_REMOVE_SMALLER, _('Delete')))->addClass('js-remove') ))->addClass('list-item-actions'); return (new CListItem([ (new CDiv()) ->addClass(ZBX_STYLE_DRAG_ICON) ->addClass('js-main-drag-icon'), (new CLabel(''))->addClass('js-dataset-label'), (new CDiv()) ->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM_HEAD) ->addClass('dataset-head') ->addItem($dataset_head), (new CDiv()) ->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM_BODY) ->addClass('dataset-body') ->addItem([ (new CFormGrid()) ->addItem([ new CLabel([ _('Aggregation function'), makeHelpIcon(_('Aggregates each item in the data set.')) ], 'label-'.$field_name.'_'.$row_num.'_aggregate_function'), new CFormField( (new CSelect($field_name.'['.$row_num.'][aggregate_function]')) ->setId($field_name.'_'.$row_num.'_aggregate_function') ->setFocusableElementId('label-'.$field_name.'_'.$row_num.'_aggregate_function') ->setValue((int) $value['aggregate_function']) ->addOptions(CSelect::createOptionsFromArray([ AGGREGATE_LAST => CItemHelper::getAggregateFunctionName(AGGREGATE_LAST), AGGREGATE_MIN => CItemHelper::getAggregateFunctionName(AGGREGATE_MIN), AGGREGATE_MAX => CItemHelper::getAggregateFunctionName(AGGREGATE_MAX), AGGREGATE_AVG => CItemHelper::getAggregateFunctionName(AGGREGATE_AVG), AGGREGATE_COUNT => CItemHelper::getAggregateFunctionName(AGGREGATE_COUNT), AGGREGATE_SUM => CItemHelper::getAggregateFunctionName(AGGREGATE_SUM), AGGREGATE_FIRST => CItemHelper::getAggregateFunctionName(AGGREGATE_FIRST) ])) ->setWidth(ZBX_TEXTAREA_TINY_WIDTH) ) ]) ->addItem([ new CLabel([ _('Data set aggregation'), makeHelpIcon(_('Aggregates the whole data set.')) ], 'label-'.$field_name.'_'.$row_num.'_dataset_aggregation'), new CFormField( (new CSelect($field_name.'['.$row_num.'][dataset_aggregation]')) ->setId($field_name.'_'.$row_num.'_dataset_aggregation') ->setFocusableElementId('label-'.$field_name.'_'.$row_num.'_dataset_aggregation') ->setValue((int) $value['dataset_aggregation']) ->addOptions(CSelect::createOptionsFromArray([ AGGREGATE_NONE => CItemHelper::getAggregateFunctionName(AGGREGATE_NONE), AGGREGATE_MIN => CItemHelper::getAggregateFunctionName(AGGREGATE_MIN), AGGREGATE_MAX => CItemHelper::getAggregateFunctionName(AGGREGATE_MAX), AGGREGATE_AVG => CItemHelper::getAggregateFunctionName(AGGREGATE_AVG), AGGREGATE_COUNT => CItemHelper::getAggregateFunctionName(AGGREGATE_COUNT), AGGREGATE_SUM => CItemHelper::getAggregateFunctionName(AGGREGATE_SUM) ])) ->setWidth(ZBX_TEXTAREA_TINY_WIDTH) ) ]) ->addItem([ new CLabel([ _('Data set label'), makeHelpIcon(_('Also used as legend label for aggregated data sets.')) ], $field_name.'_'.$row_num.'_data_set_label'), new CFormField( (new CTextBox($field_name.'['.$row_num.'][data_set_label]', $value['data_set_label'])) ->setId($field_name.'_'.$row_num.'_data_set_label') ->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH) ) ]), $form_grid_right ]) ])) ->addClass(ZBX_STYLE_LIST_ACCORDION_ITEM) ->addClass($is_opened ? ZBX_STYLE_LIST_ACCORDION_ITEM_OPENED : ZBX_STYLE_LIST_ACCORDION_ITEM_CLOSED) ->setAttribute('data-set', $row_num) ->setAttribute('data-type', $dataset_type); } private function getItemRowTemplate($ds_num = '#{dsNum}', $row_num = '#{rowNum}', $itemid = '#{itemid}', $reference = '#{reference}', $name = '#{name}', $color = '#{color}', $type = '#{type}'): CRow { return (new CRow([ (new CCol((new CDiv())->addClass(ZBX_STYLE_DRAG_ICON))) ->addClass('table-col-handle') ->addClass(ZBX_STYLE_TD_DRAG_ICON), (new CCol( (new CColorPicker($this->field->getName().'['.$ds_num.'][color][]'))->setColor($color) ))->addClass('table-col-color'), (new CCol(new CSpan($row_num.':')))->addClass('table-col-no'), (new CCol([ (new CSpan()) ->addClass('reference-hint') ->addClass(ZBX_ICON_REFERENCE) ->addClass(ZBX_STYLE_DISPLAY_NONE) ->setHint(_('Another widget is used as data source.')), (new CLink($name)) ->setId('items_'.$ds_num.'_'.$row_num.'_name') ->addClass('js-click-expand') ]))->addClass('table-col-name'), (new CCol([ (new CSelect($this->field->getName().'['.$ds_num.'][type][]')) ->setId('items_'.$ds_num.'_'.$row_num.'_type') ->setValue($type) ->addOptions(CSelect::createOptionsFromArray([ CWidgetFieldDataSet::ITEM_TYPE_NORMAL => _('Normal'), CWidgetFieldDataSet::ITEM_TYPE_TOTAL => _('Total') ])) ]))->addClass('table-col-type'), (new CCol([ (new CButton('button', _('Remove'))) ->addClass(ZBX_STYLE_BTN_LINK) ->addClass('element-table-remove') ->addClass('js-remove-item'), new CVar($this->field->getName().'['.$ds_num.'][itemids][]', $itemid, 'items_'.$ds_num.'_'.$row_num.'_itemid' ), new CVar($this->field->getName().'['.$ds_num.'][references][]', $reference, 'items_'.$ds_num.'_'.$row_num.'_reference' ) ])) ->addClass('table-col-action') ->addClass(ZBX_STYLE_NOWRAP) ]))->addClass('single-item-table-row'); } }