Widget\Filter*: rudimentary filter widgets
Initial implementation, more to come
This commit is contained in:
parent
54e97f114d
commit
21febddad2
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Web\Widget;
|
||||
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Data\Filter\FilterExpression;
|
||||
use Icinga\Data\Filter\FilterChain;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
/**
|
||||
* Filter
|
||||
*/
|
||||
class FilterEditor extends AbstractWidget
|
||||
{
|
||||
/**
|
||||
* The filter
|
||||
*
|
||||
* @var Filter
|
||||
*/
|
||||
private $filter;
|
||||
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $selectedIdx;
|
||||
|
||||
/**
|
||||
* Create a new FilterWidget
|
||||
*
|
||||
* @param Filter $filter Your filter
|
||||
*/
|
||||
public function __construct($props)
|
||||
{
|
||||
$this->filter = $props['filter'];
|
||||
if (array_key_exists('query', $props)) {
|
||||
$this->query = $props['query'];
|
||||
}
|
||||
}
|
||||
|
||||
protected function select($name, $list, $selected)
|
||||
{
|
||||
$view = $this->view();
|
||||
$html = '<select name="' . $view->escape($name) . '">';
|
||||
foreach ($list as $k => $v) {
|
||||
$active = '';
|
||||
if ($k === $selected) {
|
||||
$active = ' selected="selected"';
|
||||
}
|
||||
$html .= sprintf(
|
||||
'<option value="%s"%s>%s</option>',
|
||||
$view->escape($k),
|
||||
$active,
|
||||
$v
|
||||
);
|
||||
}
|
||||
$html .= '</select>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function markIndex($idx)
|
||||
{
|
||||
$this->selectedIdx = $idx;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeIndex($idx)
|
||||
{
|
||||
$this->selectedIdx = $idx;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function renderFilter($filter, $level = 0)
|
||||
{
|
||||
$html = '';
|
||||
$url = Url::fromRequest();
|
||||
|
||||
$view = $this->view();
|
||||
$idx = $filter->getId();
|
||||
$markUrl = clone($url);
|
||||
$markUrl->setParam('fIdx', $idx);
|
||||
|
||||
$removeUrl = clone($url);
|
||||
$removeUrl->setParam('removeId', $idx);
|
||||
$removeLink = ' <a href="' . $removeUrl . '" title="'
|
||||
. $view->escape(t('Click to remove this part of your filter'))
|
||||
. '">' . $view->icon('remove.png') . '</a>';
|
||||
|
||||
$addUrl = clone($url);
|
||||
$addUrl->setParam('addToId', $idx);
|
||||
$addLink = ' <a href="' . $addUrl . '" title="'
|
||||
. $view->escape(t('Click to add... filter'))
|
||||
. '">' . $view->icon('create.png') . '</a>';
|
||||
|
||||
|
||||
$selectedIndex = ($idx === $this->selectedIdx ? ' -<--' : '');
|
||||
$selectIndex = ' <a href="' . $markUrl . '">o</a>';
|
||||
|
||||
if ($filter instanceof FilterChain) {
|
||||
$parts = array();
|
||||
$i = 0;
|
||||
|
||||
foreach ($filter->filters() as $f) {
|
||||
$i++;
|
||||
$parts[] = $this->renderFilter($f, $level + 1);
|
||||
}
|
||||
|
||||
if (empty($parts)) {
|
||||
return $html;
|
||||
}
|
||||
$op = $this->select(
|
||||
'operator',
|
||||
array(
|
||||
'OR' => 'OR',
|
||||
'AND' => 'AND',
|
||||
'NOT' => 'NOT'
|
||||
),
|
||||
$filter->getOperatorName()
|
||||
) . $addLink . $removeLink;
|
||||
$html .= '<span class="handle"> </span>';
|
||||
|
||||
if ($level === 0) {
|
||||
$html .= $op
|
||||
. '<ul class="datafilter"><li>'
|
||||
. implode('</li><li>', $parts)
|
||||
. '</li></ul>';
|
||||
} else {
|
||||
$html .= $op . '<ul><li>' . implode('</li><li>', $parts) . '</li></ul>';
|
||||
}
|
||||
return $html;
|
||||
|
||||
} elseif ($filter instanceof FilterExpression) {
|
||||
$u = $url->without($filter->getColumn());
|
||||
} else {
|
||||
throw new \Exception('WTF');
|
||||
}
|
||||
$value = $filter->getExpression();
|
||||
if (is_array($value)) {
|
||||
$value = implode('|', $value);
|
||||
}
|
||||
$html .= $this->selectColumn($filter) . ' = <input type="text" name="'
|
||||
. 'value_' . $idx
|
||||
. '" value="'
|
||||
. $value
|
||||
. '" /> ' . $removeLink;
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
protected function arrayForSelect($array)
|
||||
{
|
||||
$res = array();
|
||||
foreach ($array as $k => $v) {
|
||||
if (is_int($k)) {
|
||||
$res[$v] = $v;
|
||||
} else {
|
||||
$res[$k] = $v;
|
||||
}
|
||||
}
|
||||
// sort($res);
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function selectColumn($filter)
|
||||
{
|
||||
$name = 'column_' . $filter->getId();
|
||||
|
||||
if ($this->query === null) {
|
||||
return sprintf(
|
||||
'<input type="text" name="%s" value="%s" />',
|
||||
$name,
|
||||
$filter->getColumn()
|
||||
);
|
||||
} else {
|
||||
return $this->select(
|
||||
$name,
|
||||
$this->arrayForSelect($this->query->getColumns()),
|
||||
$filter->getColumn()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return '<form action="'
|
||||
. Url::fromRequest()->without('modifyFilter')
|
||||
. '">'
|
||||
. $this->renderFilter($this->filter)
|
||||
. '<input type="submit" name="submit" value="Apply" />'
|
||||
. '</form>';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Web\Widget;
|
||||
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Data\Filter\FilterExpression;
|
||||
use Icinga\Data\Filter\FilterChain;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
/**
|
||||
* Filter
|
||||
*/
|
||||
class FilterWidget extends AbstractWidget
|
||||
{
|
||||
/**
|
||||
* The filter
|
||||
*
|
||||
* @var Filter
|
||||
*/
|
||||
private $filter;
|
||||
|
||||
/**
|
||||
* The domain of the filter, set in the data-icinga-filter-domain attribute
|
||||
* @var string
|
||||
*/
|
||||
private $domain;
|
||||
|
||||
/**
|
||||
* Create a new FilterWidget
|
||||
*
|
||||
* @param Filter $filter Your filter
|
||||
*/
|
||||
public function __construct(Filter $filter)
|
||||
{
|
||||
$this->filter = $filter;
|
||||
}
|
||||
|
||||
protected function renderFilter($filter, $level = 0)
|
||||
{
|
||||
$html = '';
|
||||
$url = Url::fromRequest();
|
||||
if ($filter instanceof FilterChain) {
|
||||
if ($level === 0) {
|
||||
$op = '</li><li>)' . $filter->getOperatorName() . ' (';
|
||||
} else {
|
||||
$op = '</li><li>) ' . $filter->getOperatorName() . ' ( ';
|
||||
}
|
||||
$parts = array();
|
||||
foreach ($filter->filters() as $f) {
|
||||
$parts[] = $this->renderFilter($f, $level + 1);
|
||||
}
|
||||
if (empty($parts)) {
|
||||
return $html;
|
||||
}
|
||||
if ($level === 0) {
|
||||
$html .= '<ul class="datafilter"><li>( ' . implode($op, $parts) . ' )</li></ul>';
|
||||
} else {
|
||||
$html .= '<ul><li>( ' . implode($op, $parts) . ' )</li></ul>';
|
||||
}
|
||||
return $html;
|
||||
} elseif ($filter instanceof FilterExpression) {
|
||||
$u = $url->without($filter->getColumn());
|
||||
} else {
|
||||
$u = $url . '--';
|
||||
}
|
||||
$html .= '<a href="' . $url . '" title="'
|
||||
. $this->view()->escape(t('Click to remove this part of your filter'))
|
||||
. '">' . $filter . '</a> ';
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$url = Url::fromRequest();
|
||||
$html = ' <form method="get" class="inline" action="'
|
||||
. $url
|
||||
. '"><input type="text" name="q" style="width: 8em" class="search" value="" placeholder="'
|
||||
. t('Add filter...')
|
||||
. '" /></form><br />';
|
||||
|
||||
|
||||
// $html .= $this->renderFilter($this->filter);
|
||||
|
||||
$editorUrl = clone $url;
|
||||
$editorUrl->setParam('modifyFilter', true);
|
||||
if ($this->filter->isEmpty()) {
|
||||
$txt = t('Filter');
|
||||
$title = t('Filter this list');
|
||||
$remove = '';
|
||||
} else {
|
||||
$txt = t('Filtered');
|
||||
$title = t('Modify this filter');
|
||||
$remove = ' <a href="'
|
||||
. Url::fromRequest()->setParams(array())
|
||||
. '" title="'
|
||||
. t('Remove this filter')
|
||||
. '">'
|
||||
. t('remove')
|
||||
. '</a>';
|
||||
}
|
||||
$filter = $this->filter->isEmpty() ? '' : ': ' . $this->filter;
|
||||
$html .= '<a href="' . $editorUrl . '">' . $this->view()->escape($txt) . '</a>'
|
||||
. $filter . $remove;
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
|
@ -451,6 +451,15 @@ class Monitoring_ListController extends Controller
|
|||
|
||||
$filter = Filter::fromQueryString((string) $params);
|
||||
$query->applyFilter($filter);
|
||||
if ($modifyFilter) {
|
||||
$this->view->filterWidget = Widget::create('filterEditor', array(
|
||||
'filter' => $filter,
|
||||
'query' => $query
|
||||
));
|
||||
} else {
|
||||
$this->view->filterWidget = Widget::create('filterWidget', $filter);
|
||||
}
|
||||
$this->view->filter = $filter;
|
||||
if ($sort) {
|
||||
$query->order($sort, $dir);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ if (!$this->compact): ?>
|
|||
<?= $this->tabs ?>
|
||||
<div style="margin: 1em;" class="dontprint">
|
||||
<?= $this->translate('Sort by') ?> <?= $this->sortControl ?>
|
||||
<?= $this->filterWidget ?><br />
|
||||
</div>
|
||||
|
||||
<?= $this->paginationControl($services, null, null, array('preserve' => $this->preserve)) ?>
|
||||
|
|
Loading…
Reference in New Issue