| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- <?php declare(strict_types = 0);
- /*
- ** WeCom Center - page view (three tabs: Alert / Optimization / Maintenance).
- ** Rendered as clean card HTML on top of Zabbix's page chrome.
- ** @var CView $this
- ** @var array $data
- */
- use Modules\WecomCenter\Lib\I18n;
- $this->addCssFile('modules/WecomCenter/assets/wecom.center.css');
- $e = function ($v) { return htmlspecialchars((string) ($v ?? ''), ENT_QUOTES, 'UTF-8'); };
- $t = function (string $k, array $a = []) use ($e) { return $e(I18n::t($k, $a)); };
- $save = $e((new CUrl('zabbix.php'))->setArgument('action', 'wecom.center.save')->getUrl());
- $view_url = (new CUrl('zabbix.php'))->setArgument('action', 'wecom.center.view')->getUrl();
- $mtid = $e($data['mediatypeid']);
- $html_page = (new CHtmlPage())->setTitle(I18n::t('page.title'));
- if (!$data['mediatype']) {
- $html_page->addItem('<div class="wc-wrap"><div class="wc-card"><div class="wc-card__body">'
- .$t('msg.no_mediatype').'</div></div></div>');
- $html_page->show();
- return;
- }
- $mask = (int) $data['severity'];
- $enabled = ((int) $data['active'] === 0);
- /* helper to build a card */
- $card = function (string $ico, string $title, string $body, string $extra = '', string $sub = '') {
- return '<div class="wc-card'.$extra.'"><div class="wc-card__head"><span class="wc-card__ico">'.$ico.'</span>'
- .'<span class="wc-card__title">'.$title.'</span>'
- .($sub !== '' ? '<span class="wc-card__sub">'.$sub.'</span>' : '')
- .'</div><div class="wc-card__body">'.$body.'</div></div>';
- };
- /* ============================ TAB 1: ALERT ============================ */
- // -- robot --
- $robotBody =
- '<form method="post" action="'.$save.'">'
- .'<input type="hidden" name="mediatypeid" value="'.$mtid.'">'
- .'<div class="wc-field"><label>'.$t('lbl.key').'</label>'
- .'<input class="wc-input wc-input--mono" type="text" name="webhook_url" value="'.$e($data['webhook_url']).'"></div>'
- .'<div class="wc-actions">'
- .'<button class="wc-btn wc-btn--primary" type="submit" name="op" value="save_robot">'.$t('btn.save').'</button>'
- .'<button class="wc-btn wc-btn--ghost" type="submit" name="op" value="test_robot">'.$t('btn.test').'</button>'
- .'</div></form>';
- $robotCard = $card('🤖', $t('sec.robot'), $robotBody, '', $e($data['mediatype']['name'] ?? ''));
- // -- threshold --
- $sevChecks = '';
- for ($i = 1; $i <= 6; $i++) {
- $bit = 1 << ($i - 1);
- $chk = (($mask & $bit) !== 0) ? ' checked' : '';
- $sevChecks .= '<label class="wc-checkrow"><input type="checkbox" name="sev_'.$i.'"'.$chk.'> '
- .'<span class="wc-sev wc-sev-'.$i.'">'.$t('sev.'.$i).'</span></label>';
- }
- $thresholdBody =
- '<div class="wc-hint">'.$t('lbl.threshold_hint').'</div>'
- .'<form method="post" action="'.$save.'">'
- .'<input type="hidden" name="mediatypeid" value="'.$mtid.'">'
- .'<div class="wc-field"><label class="wc-checkrow"><input type="checkbox" name="enabled"'.($enabled ? ' checked' : '').'> '.$t('lbl.alerting_on').'</label></div>'
- .'<div class="wc-field"><label>'.$t('lbl.severity').'</label><div class="wc-checks">'.$sevChecks.'</div></div>'
- .'<div class="wc-actions"><button class="wc-btn wc-btn--primary" type="submit" name="op" value="save_alert">'.$t('btn.save').'</button></div>'
- .'</form>';
- $thresholdCard = $card('⚙️', $t('sec.threshold'), $thresholdBody);
- // -- strategy presets --
- $presetRows = '';
- foreach ($data['presets'] as $key => $p) {
- $is_cur = ((string) $data['current_strategy'] === (string) $key);
- $name = $t($p['label']).($is_cur ? ' <span class="wc-pill wc-pill--cur">'.$t('preset.current').'</span>' : '');
- $prevUrl = $e((new CUrl('zabbix.php'))
- ->setArgument('action', 'wecom.center.view')
- ->setArgument('mediatypeid', $data['mediatypeid'])
- ->setArgument('preview_preset', $key)
- ->getUrl());
- $presetRows .=
- '<div class="wc-preset">'
- .'<div class="wc-preset__main"><div class="wc-preset__name">'.$name.'</div>'
- .'<div class="wc-preset__desc">'.$t($p['desc']).'</div></div>'
- .'<div class="wc-preset__act">'
- .'<a class="wc-btn wc-btn--ghost wc-btn--sm" href="'.$prevUrl.'">'.$t('btn.preview').'</a>'
- .'<form method="post" action="'.$save.'" style="margin:0"><input type="hidden" name="mediatypeid" value="'.$mtid.'">'
- .'<button class="wc-btn wc-btn--primary wc-btn--sm" type="submit" name="apply_strategy" value="'.$e($key).'">'.$t('btn.apply').'</button></form>'
- .'</div></div>';
- }
- $strategyBody = '<div class="wc-hint">'.$t('lbl.strategy_hint').'</div>'.$presetRows;
- $strategyCard = $card('🚨', $t('sec.strategy'), $strategyBody, ' wc-card--wide');
- // -- preview --
- $previewCard = '';
- if ($data['preview'] !== null) {
- $pv = $data['preview'];
- $pkey = $data['preview_key'];
- $rows = '';
- foreach ($pv['classes'] as $ck => $c) {
- $label = $t($data['classes'][$ck]['label'] ?? $ck);
- $rows .= '<tr><td>'.$label.'</td><td><span class="wc-sev wc-sev-'.((int) $c['target'] + 1).'">'.$t('sev.'.($c['target'] + 1)).'</span></td>'
- .'<td class="num">'.$e($c['count']).'</td><td class="num">'.$e($c['changes']).'</td></tr>';
- }
- $rows .= '<tr class="wc-tr-total"><td>'.$t('cls.total').'</td><td></td>'
- .'<td class="num">'.$e($pv['total']).'</td><td class="num">'.$e($pv['changes']).'</td></tr>';
- $tbl = '<table class="wc-table"><thead><tr><th>'.$t('cls.col.class').'</th><th>'.$t('cls.col.target').'</th>'
- .'<th class="num">'.$t('cls.col.count').'</th><th class="num">'.$t('cls.col.changes').'</th></tr></thead><tbody>'.$rows.'</tbody></table>';
- $body = '<div class="wc-hint">'.$t('preview.hint').'</div>'.$tbl;
- $previewCard = $card('🔍', $t('preview.title', [I18n::t($data['presets'][$pkey]['label'] ?? $pkey)]), $body, ' wc-card--wide');
- }
- $tab_alert = '<div class="wc-grid">'.$robotCard.$thresholdCard.$strategyCard.$previewCard.'</div>';
- /* ======================== TAB 2: OPTIMIZATION ========================= */
- // -- tuning --
- $tuneOpts = '';
- foreach (['small', 'medium', 'large'] as $pk) {
- $tuneOpts .= '<option value="'.$e($pk).'"'.(($data['tuning_profile'] === $pk) ? ' selected' : '').'>'.$t($pk === 'small' ? 'tuning.small' : ($pk === 'medium' ? 'tuning.medium' : 'tuning.large')).'</option>';
- }
- $tuneBody =
- '<div class="wc-hint">'.$t('lbl.tuning_hint').'</div>'
- .'<form method="get" action="zabbix.php"><input type="hidden" name="action" value="wecom.center.view">'
- .'<input type="hidden" name="mediatypeid" value="'.$mtid.'">'
- .'<div class="wc-inline"><div class="wc-field"><label>'.$t('tuning.choose').'</label>'
- .'<select class="wc-input" name="tuning_profile">'.$tuneOpts.'</select></div>'
- .'<button class="wc-btn wc-btn--primary" type="submit" name="generate" value="1">'.$t('btn.generate').'</button></div></form>'
- .'<div class="wc-code__label" style="margin-top:16px">'.$t('tuning.env').'</div>'
- .'<div class="wc-code">'.$e($data['tuning']['env']).'</div>'
- .'<div class="wc-code__label">'.$t('tuning.cmd').'</div>'
- .'<div class="wc-code">'.$e($data['tuning']['cmd']).'</div>';
- $tuningCard = $card('⚙️', $t('sec.tuning'), $tuneBody, ' wc-card--wide');
- // -- template import --
- $tplOpts = '';
- if (!$data['templates']) {
- $tplOpts = '<option value="">'.$t('tpl.none').'</option>';
- }
- foreach ($data['templates'] as $tf) {
- $tplOpts .= '<option value="'.$e($tf['file']).'">'.$e($tf['name']).'</option>';
- }
- $importBody =
- '<div class="wc-hint">'.$t('lbl.template_hint').'</div>'
- .'<form method="post" action="'.$save.'">'
- .'<div class="wc-field"><label>'.$t('tpl.choose').'</label><select class="wc-input" name="template_file">'.$tplOpts.'</select></div>'
- .'<div class="wc-actions"><button class="wc-btn wc-btn--primary" type="submit" name="op" value="import_template">'.$t('btn.import').'</button></div>'
- .'</form>';
- $importCard = $card('📦', $t('sec.template'), $importBody);
- // -- map --
- if ($data['server_host']) {
- $mapBody =
- '<div class="wc-hint">'.$t('map.hint').'</div>'
- .'<form method="post" action="'.$save.'">'
- .'<input type="hidden" name="hostid" value="'.$e($data['server_host']['hostid']).'">'
- .'<div class="wc-field"><label>'.$t('map.host').'</label><div class="wc-muted">'.$e($data['server_host']['name']).'</div></div>'
- .'<div class="wc-inline">'
- .'<div class="wc-field"><label>'.$t('map.lat').'</label><input class="wc-input" type="text" name="lat" value="'.$e($data['server_loc']['location_lat']).'"></div>'
- .'<div class="wc-field"><label>'.$t('map.lon').'</label><input class="wc-input" type="text" name="lon" value="'.$e($data['server_loc']['location_lon']).'"></div>'
- .'</div>'
- .'<div class="wc-actions"><button class="wc-btn wc-btn--primary" type="submit" name="op" value="save_map">'.$t('btn.save').'</button></div>'
- .'</form>';
- }
- else {
- $mapBody = '<div class="wc-empty">'.$t('msg.no_server_host').'</div>';
- }
- $mapCard = $card('🗺️', $t('sec.map'), $mapBody);
- // -- template switch --
- $srcOpts = '<option value="">'.$t('switch.pick').'</option>';
- $dstOpts = '<option value="">'.$t('switch.pick').'</option>';
- foreach ($data['huawei_tpls'] as $tp) {
- $selS = ((string) $data['switch_src'] === (string) $tp['templateid']) ? ' selected' : '';
- $selD = ((string) $data['switch_dst'] === (string) $tp['templateid']) ? ' selected' : '';
- $srcOpts .= '<option value="'.$e($tp['templateid']).'"'.$selS.'>'.$e($tp['host']).'</option>';
- $dstOpts .= '<option value="'.$e($tp['templateid']).'"'.$selD.'>'.$e($tp['host']).'</option>';
- }
- $switchBody =
- '<div class="wc-hint">'.$t('lbl.switch_hint').'</div>'
- .'<form method="get" action="zabbix.php"><input type="hidden" name="action" value="wecom.center.view">'
- .'<input type="hidden" name="mediatypeid" value="'.$mtid.'">'
- .'<div class="wc-inline">'
- .'<div class="wc-field"><label>'.$t('switch.src').'</label><select class="wc-input" name="switch_src">'.$srcOpts.'</select></div>'
- .'<div class="wc-field"><label>'.$t('switch.dst').'</label><select class="wc-input" name="switch_dst">'.$dstOpts.'</select></div>'
- .'<button class="wc-btn wc-btn--ghost" type="submit" name="preview" value="1">'.$t('btn.preview').'</button>'
- .'</div></form>';
- if ($data['switch_preview'] !== null) {
- $sp = $data['switch_preview'];
- if ((int) $sp['count'] === 0) {
- $switchBody .= '<div class="wc-divider"></div><div class="wc-empty">'.$t('switch.none', [$sp['src_name']]).'</div>';
- }
- else {
- $chips = '';
- foreach ($sp['hosts'] as $hn) {
- $chips .= '<span class="wc-chip">'.$e($hn).'</span>';
- }
- $switchBody .= '<div class="wc-divider"></div>'
- .'<div class="wc-muted">'.$t('switch.result', [$sp['count'], $sp['src_name'], $sp['dst_name']]).'</div>'
- .'<div class="wc-chips">'.$chips.'</div>'
- .'<form method="post" action="'.$save.'" style="margin-top:14px">'
- .'<input type="hidden" name="switch_src" value="'.$e($sp['src']).'">'
- .'<input type="hidden" name="switch_dst" value="'.$e($sp['dst']).'">'
- .'<button class="wc-btn wc-btn--danger" type="submit" name="op" value="apply_switch">'.$t('btn.confirm').'</button>'
- .'</form>';
- }
- }
- $switchCard = $card('🔁', $t('sec.switch'), $switchBody, ' wc-card--wide');
- $tab_opt = '<div class="wc-grid">'.$tuningCard.$importCard.$mapCard.$switchCard.'</div>';
- /* ======================== TAB 3: MAINTENANCE ========================== */
- $searchBody =
- '<div class="wc-hint">'.$t('lbl.trig_hint', [$data['trigger_count']]).'</div>'
- .'<form method="get" action="zabbix.php"><input type="hidden" name="action" value="wecom.center.view">'
- .'<input type="hidden" name="mediatypeid" value="'.$mtid.'">'
- .'<div class="wc-inline"><div class="wc-field" style="flex:3"><input class="wc-input" type="text" name="trig_search" value="'.$e($data['trig_search']).'" placeholder="'.$t('lbl.trig_search').'"></div>'
- .'<button class="wc-btn wc-btn--primary" type="submit" name="search" value="1">'.$t('btn.search').'</button></div></form>';
- $maintBody = $searchBody;
- if ($data['trig_search'] !== '') {
- if ($data['triggers']) {
- $ids = [];
- $list = '';
- foreach ($data['triggers'] as $tg) {
- $ids[] = $tg['triggerid'];
- $host = !empty($tg['hosts']) ? $tg['hosts'][0]['host'] : '';
- $sev = ((int) $tg['priority']) + 1;
- $chk = ((int) $tg['status'] === 0) ? ' checked' : '';
- $list .= '<label class="wc-checkrow" style="display:block;padding:6px 0;border-bottom:1px solid #f2f4f7">'
- .'<input type="checkbox" name="trig_'.$e($tg['triggerid']).'"'.$chk.'> '
- .'<span class="wc-sev wc-sev-'.$sev.'">'.$t('sev.'.$sev).'</span> '
- .'<span class="wc-muted">'.$e($host).'</span> — '.$e($tg['description']).'</label>';
- }
- $maintBody .= '<div class="wc-divider"></div>'
- .'<form method="post" action="'.$save.'">'
- .'<input type="hidden" name="trig_ids" value="'.$e(implode(',', $ids)).'">'
- .'<div class="wc-field"><label>'.$t('lbl.trig_list').'</label>'.$list.'</div>'
- .'<div class="wc-actions"><button class="wc-btn wc-btn--primary" type="submit" name="op" value="save_triggers">'.$t('btn.save').'</button></div>'
- .'</form>';
- }
- else {
- $maintBody .= '<div class="wc-divider"></div><div class="wc-empty">'.$t('msg.no_trig_search').'</div>';
- }
- }
- $tab_maint = '<div class="wc-grid">'.$card('🔧', $t('sec.triggers'), $maintBody, ' wc-card--wide').'</div>';
- /* ============================ assemble =============================== */
- $hero = '<div class="wc-hero"><div class="wc-hero__title">'.$t('page.title').'</div>'
- .'<div class="wc-hero__sub">'.$t('hero.sub').'</div></div>';
- $tabs = new CTabView();
- $tabs->addTab('alert', I18n::t('tab.alert'), '<div class="wc-wrap">'.$hero.$tab_alert.'</div>');
- $tabs->addTab('opt', I18n::t('tab.opt'), '<div class="wc-wrap">'.$tab_opt.'</div>');
- $tabs->addTab('maint', I18n::t('tab.maint'), '<div class="wc-wrap">'.$tab_maint.'</div>');
- $html_page->addItem($tabs);
- $html_page->show();
|