mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-23 05:44:37 +02:00
FormDataFilter: simplify HTML, Code and style
This commit is contained in:
parent
24478ede12
commit
aeafec37d7
@ -163,15 +163,21 @@ class IcingaServiceForm extends DirectorObjectForm
|
|||||||
$this->addElement('dataFilter', 'assign_filter', array(
|
$this->addElement('dataFilter', 'assign_filter', array(
|
||||||
'columns' => IcingaHost::enumProperties($this->db),
|
'columns' => IcingaHost::enumProperties($this->db),
|
||||||
'required' => true,
|
'required' => true,
|
||||||
|
'description' => $this->translate(
|
||||||
|
'This allows you to configure an assignment filter. Please feel'
|
||||||
|
. ' free to combine as many nested operators as you want'
|
||||||
|
)
|
||||||
));
|
));
|
||||||
$el = $this->getElement('assign_filter');
|
$el = $this->getElement('assign_filter');
|
||||||
$el->setDecorators(array(
|
|
||||||
'ViewHelper',
|
$el->clearDecorators()
|
||||||
array('HtmlTag', array(
|
->addDecorator('ViewHelper')
|
||||||
'tag' => 'ul',
|
->addDecorator('Errors')
|
||||||
'class' => 'assign-rule required'
|
->addDecorator('Description', array('tag' => 'p', 'class' => 'description'))
|
||||||
)),
|
->addDecorator('HtmlTag', array(
|
||||||
));
|
'tag' => 'dd',
|
||||||
|
'class' => 'full-width required',
|
||||||
|
));
|
||||||
|
|
||||||
$this->addDisplayGroup(array($el), 'assign', array(
|
$this->addDisplayGroup(array($el), 'assign', array(
|
||||||
'decorators' => array(
|
'decorators' => array(
|
||||||
|
@ -59,41 +59,37 @@ class Zend_View_Helper_FormDataFilter extends Zend_View_Helper_FormElement
|
|||||||
$value = Filter::fromQueryString($value);
|
$value = Filter::fromQueryString($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->renderFilter($value);
|
return $this->beginRoot()
|
||||||
|
. $this->renderFilter($value)
|
||||||
|
. $this->endRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderFilter(Filter $filter, $level = 0)
|
protected function renderFilter(Filter $filter)
|
||||||
{
|
{
|
||||||
if ($level === 0 && (
|
|
||||||
($filter->isChain() && $filter->isEmpty())
|
|
||||||
|| $filter->isExpression())) {
|
|
||||||
$pre = '<ul class="filter-expression filter-root"><li class="active">';
|
|
||||||
$post = '</li></ul>';
|
|
||||||
} else {
|
|
||||||
$pre = $post = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($filter instanceof FilterChain) {
|
if ($filter instanceof FilterChain) {
|
||||||
return $pre . $this->renderFilterChain($filter, $level) . $post;
|
return $this->renderFilterChain($filter);
|
||||||
} elseif ($filter instanceof FilterExpression) {
|
} elseif ($filter instanceof FilterExpression) {
|
||||||
return $pre . $this->renderFilterExpression($filter, $level) . $post;
|
return $this->renderFilterExpression($filter);
|
||||||
} else {
|
} else {
|
||||||
throw new ProgrammingError('Got a Filter being neither expression nor chain');
|
throw new ProgrammingError('Got a Filter being neither expression nor chain');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function emptyExpression()
|
protected function beginRoot()
|
||||||
{
|
{
|
||||||
return Filter::expression('', '=', '');
|
return '<ul class="filter-root">';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderFilterChain(FilterChain $filter, $level)
|
protected function endRoot()
|
||||||
|
{
|
||||||
|
return '</ul>';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderFilterChain(FilterChain $filter)
|
||||||
{
|
{
|
||||||
$parts = array();
|
$parts = array();
|
||||||
foreach ($filter->filters() as $f) {
|
foreach ($filter->filters() as $f) {
|
||||||
$parts[] = '<li>'
|
$parts[] = $this->renderFilter($f);
|
||||||
. $this->renderFilter($f, $level + 1)
|
|
||||||
. '</li>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->beginChain($filter)
|
return $this->beginChain($filter)
|
||||||
@ -103,12 +99,9 @@ class Zend_View_Helper_FormDataFilter extends Zend_View_Helper_FormElement
|
|||||||
|
|
||||||
protected function beginChain(FilterChain $filter)
|
protected function beginChain(FilterChain $filter)
|
||||||
{
|
{
|
||||||
$root = $filter->isRootNode() === 0 ? ' class="filter-root"' : '';
|
$list = $filter->isEmpty() ? '' : '<ul>' . "\n";
|
||||||
|
|
||||||
$list = $filter->isEmpty() ? '' : '<ul' . $root . '>' . "\n";
|
return '<li class="filter-chain"><span class="handle"> </span>'
|
||||||
|
|
||||||
return '<li><div class="filter-chain'
|
|
||||||
. '"><span class="handle"> </span>'
|
|
||||||
. $this->selectOperator($filter)
|
. $this->selectOperator($filter)
|
||||||
. $this->removeLink($filter)
|
. $this->removeLink($filter)
|
||||||
. $this->addLink($filter)
|
. $this->addLink($filter)
|
||||||
@ -119,13 +112,12 @@ class Zend_View_Helper_FormDataFilter extends Zend_View_Helper_FormElement
|
|||||||
protected function endChain(FilterChain $filter)
|
protected function endChain(FilterChain $filter)
|
||||||
{
|
{
|
||||||
$list = $filter->isEmpty() ? '' : "</ul>\n";
|
$list = $filter->isEmpty() ? '' : "</ul>\n";
|
||||||
return $list . "</div></li>\n";
|
return $list . "</li>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function beginExpression(FilterExpression $filter)
|
protected function beginExpression(FilterExpression $filter)
|
||||||
{
|
{
|
||||||
$root = $filter->isRootNode() === 0 ? ' filter-root' : '';
|
return '<div class="filter-expression">' . "\n";
|
||||||
return '<div class="filter-expression' . $root . '">' . "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function endExpression(FilterExpression $filter)
|
protected function endExpression(FilterExpression $filter)
|
||||||
@ -133,23 +125,35 @@ class Zend_View_Helper_FormDataFilter extends Zend_View_Helper_FormElement
|
|||||||
return "</div>\n";
|
return "</div>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterExpressionHtml(FilterExpression $filter, $level)
|
protected function beginElement(FilterExpression $filter)
|
||||||
|
{
|
||||||
|
return '<div class="expression-wrapper">' . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function endElement(FilterExpression $filter)
|
||||||
|
{
|
||||||
|
return "</div>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function filterExpressionHtml(FilterExpression $filter)
|
||||||
{
|
{
|
||||||
return $this->selectColumn($filter)
|
return $this->selectColumn($filter)
|
||||||
. $this->selectSign($filter)
|
. $this->selectSign($filter)
|
||||||
|
. $this->beginElement($filter)
|
||||||
. $this->element($filter)
|
. $this->element($filter)
|
||||||
|
. $this->endElement($filter)
|
||||||
. $this->removeLink($filter)
|
. $this->removeLink($filter)
|
||||||
. $this->expandLink($filter);
|
. $this->expandLink($filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderFilterExpression(FilterExpression $filter, $level)
|
protected function renderFilterExpression(FilterExpression $filter)
|
||||||
{
|
{
|
||||||
return $this->beginExpression($filter)
|
return $this->beginExpression($filter)
|
||||||
. $this->filterExpressionHtml($filter, $level)
|
. $this->filterExpressionHtml($filter)
|
||||||
. $this->endExpression($filter);
|
. $this->endExpression($filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function element(Filter $filter = null)
|
protected function element(FilterExpression $filter = null)
|
||||||
{
|
{
|
||||||
if ($filter) {
|
if ($filter) {
|
||||||
// TODO: Make this configurable
|
// TODO: Make this configurable
|
||||||
@ -217,9 +221,9 @@ class Zend_View_Helper_FormDataFilter extends Zend_View_Helper_FormElement
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderNewFilter()
|
protected function emptyExpression()
|
||||||
{
|
{
|
||||||
return $this->renderFilterExpression($this->emptyExpression(), 0);
|
return Filter::expression('', '=', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function arrayForSelect($array, $flip = false)
|
protected function arrayForSelect($array, $flip = false)
|
||||||
@ -340,7 +344,7 @@ class Zend_View_Helper_FormDataFilter extends Zend_View_Helper_FormElement
|
|||||||
$this->elementId('column', $filter),
|
$this->elementId('column', $filter),
|
||||||
$cols,
|
$cols,
|
||||||
$active,
|
$active,
|
||||||
array('class' => 'autosubmit')
|
array('class' => 'column autosubmit')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1942,7 +1942,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
|||||||
// @codingStandardsIgnoreEnd
|
// @codingStandardsIgnoreEnd
|
||||||
return ' ' . AssignRenderer::forFilter(
|
return ' ' . AssignRenderer::forFilter(
|
||||||
Filter::fromQueryString($this->assign_filter)
|
Filter::fromQueryString($this->assign_filter)
|
||||||
)->renderAssign();
|
)->renderAssign() . "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toLegacyConfigString()
|
public function toLegacyConfigString()
|
||||||
|
@ -25,6 +25,28 @@ class DataFilter extends FormElement
|
|||||||
|
|
||||||
private $filter;
|
private $filter;
|
||||||
|
|
||||||
|
public function getValue()
|
||||||
|
{
|
||||||
|
$value = parent::getValue();
|
||||||
|
if ($value !== null && $this->isEmpty($value)) {
|
||||||
|
$value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function isEmpty(Filter $filter)
|
||||||
|
{
|
||||||
|
return $filter->isEmpty() || $this->isEmptyExpression($filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function isEmptyExpression($filter)
|
||||||
|
{
|
||||||
|
return $filter->isExpression() &&
|
||||||
|
$filter->getColumn() === '' &&
|
||||||
|
$filter->getExpression() === '""'; // -> json_encode('')
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codingStandardsIgnoreStart
|
* @codingStandardsIgnoreStart
|
||||||
*/
|
*/
|
||||||
@ -150,7 +172,10 @@ class DataFilter extends FormElement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($filter->filters() as $sub) {
|
foreach ($filter->filters() as $sub) {
|
||||||
$filter->replaceById($sub->getId(), $this->fixNotsWithMultipleChildrenForFilter($sub));
|
$filter->replaceById(
|
||||||
|
$sub->getId(),
|
||||||
|
$this->fixNotsWithMultipleChildrenForFilter($sub)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,15 +295,36 @@ class DataFilter extends FormElement
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function hasIncompleteExpressions(Filter $filter)
|
||||||
|
{
|
||||||
|
if ($filter->isChain()) {
|
||||||
|
foreach ($filter->filters() as $sub) {
|
||||||
|
if ($this->hasIncompleteExpressions($sub)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($filter->isRootNode() && $this->isEmptyExpression($filter)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filter->getColumn() === '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function isValid($value, $context = null)
|
public function isValid($value, $context = null)
|
||||||
{
|
{
|
||||||
if (! $value instanceof Filter) {
|
if (! $value instanceof Filter) {
|
||||||
// TODO: try, return false on E
|
// TODO: try, return false on E
|
||||||
$filter = $this->arrayToFilter($value);
|
$filter = $this->arrayToFilter($value);
|
||||||
|
$this->setValue($filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setValue($filter);
|
if ($this->hasIncompleteExpressions($filter)) {
|
||||||
|
$this->addError('The configured filter is incomplete');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return parent::isValid($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,6 +186,7 @@ input, select, select option, textarea {
|
|||||||
|
|
||||||
form ul.form-errors {
|
form ul.form-errors {
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
|
|
||||||
ul.errors li {
|
ul.errors li {
|
||||||
background: @color-critical;
|
background: @color-critical;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -624,48 +625,6 @@ form dt label {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.assign-rule {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
list-style-type: none;
|
|
||||||
select, input[type=text] {
|
|
||||||
min-width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
select.assign-type {
|
|
||||||
width: 8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
select.assign-operator {
|
|
||||||
width: 3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
select.assign-property {
|
|
||||||
width: 12em;
|
|
||||||
}
|
|
||||||
|
|
||||||
input.assign-expression {
|
|
||||||
width: 12em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
padding-left: 2em;
|
|
||||||
|
|
||||||
li::before {
|
|
||||||
// icon: down-dir
|
|
||||||
font-family: 'ifont';
|
|
||||||
content: '\e81d';
|
|
||||||
// icon: right-small
|
|
||||||
content: '\e877';
|
|
||||||
margin-left: -1em;
|
|
||||||
padding-top: 0em;
|
|
||||||
float: left;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
form fieldset {
|
form fieldset {
|
||||||
min-width: 36em;
|
min-width: 36em;
|
||||||
}
|
}
|
||||||
@ -710,6 +669,10 @@ form dt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
form .errors label {
|
||||||
|
color: @color-critical;
|
||||||
|
}
|
||||||
|
|
||||||
form dd {
|
form dd {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 63%;
|
width: 63%;
|
||||||
@ -721,6 +684,11 @@ form dd {
|
|||||||
border-color: @color-critical;
|
border-color: @color-critical;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.full-width {
|
||||||
|
padding: 0.5em;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
form dd:after {
|
form dd:after {
|
||||||
@ -1123,11 +1091,41 @@ table.config-diff {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ul.assign-rule {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style-type: none;
|
||||||
|
select, input[type=text] {
|
||||||
|
min-width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
select.assign-type {
|
||||||
|
width: 8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding-left: 2em;
|
||||||
|
|
||||||
|
li::before {
|
||||||
|
// icon: down-dir
|
||||||
|
font-family: 'ifont';
|
||||||
|
content: '\e81d';
|
||||||
|
// icon: right-small
|
||||||
|
content: '\e877';
|
||||||
|
margin-left: -1em;
|
||||||
|
padding-top: 0em;
|
||||||
|
float: left;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ul.filter-root {
|
ul.filter-root {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-left: 1.5em;
|
padding-left: 0.5em;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
@ -1136,11 +1134,13 @@ ul.filter-root {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li.filter-chain, div.filter-expression {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding: 0.3em 0.5em;
|
||||||
|
min-width: 30em;
|
||||||
}
|
}
|
||||||
|
|
||||||
li::before {
|
ul li.filter-chain::before, ul .filter-expression::before {
|
||||||
font-family: 'ifont';
|
font-family: 'ifont';
|
||||||
// Formerly: icon-down-open: e821
|
// Formerly: icon-down-open: e821
|
||||||
// icon-right-small:
|
// icon-right-small:
|
||||||
@ -1159,63 +1159,75 @@ ul.filter-root {
|
|||||||
content: none;
|
content: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type=submit].icon-button {
|
||||||
|
display: none;
|
||||||
|
font-family: 'ifont';
|
||||||
|
font-weight: normal;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0.2em 0.4em 0.2em 0.4em;
|
||||||
|
margin: 0 0 0 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active input[type=submit].icon-button,
|
||||||
|
li:hover input[type=submit].icon-button,
|
||||||
|
div:hover input[type=submit].icon-button
|
||||||
|
{
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div.filter-chain > select.operator {
|
.errors > ul.filter-root {
|
||||||
|
input[type=text], select {
|
||||||
|
border-color: transparent;
|
||||||
|
border-bottom-color: @gray-lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
select.column, select.operator {
|
||||||
|
border-left-color: @color-critical;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
li.filter-chain > select.operator {
|
||||||
min-width: 5em;
|
min-width: 5em;
|
||||||
max-width: 5em;
|
max-width: 5em;
|
||||||
width: 5em;
|
width: 5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.filter-expression select.sign, ul.filter-expression select.sign {
|
div.filter-expression {
|
||||||
min-width: 4em;
|
.column {
|
||||||
max-width: 4em;
|
min-width: 7em;
|
||||||
width: 4em;
|
|
||||||
|
|
||||||
&.wide {
|
|
||||||
min-width: 10em;
|
|
||||||
max-width: 10em;
|
max-width: 10em;
|
||||||
width: 10em;
|
width: 10em;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
div.filter-expression, ul.filter-expression {
|
.sign {
|
||||||
select {
|
min-width: 4em;
|
||||||
min-width: 7em;
|
max-width: 4em;
|
||||||
max-width: 7em;
|
width: 4em;
|
||||||
width: 7em;
|
margin: 0 0.3em;
|
||||||
|
&.wide {
|
||||||
|
min-width: 6em;
|
||||||
|
max-width: 6em;
|
||||||
|
width: 6em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=text] {
|
div.expression-wrapper {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.expression-wrapper > input[type=text],
|
||||||
|
div.expression-wrapper > select {
|
||||||
min-width: 7em;
|
min-width: 7em;
|
||||||
max-width: 7em;
|
width: 10em;
|
||||||
width: 7em;
|
max-width: 10em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.assign-rule {
|
|
||||||
select.assign-type {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.filter-expression {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=submit].icon-button {
|
|
||||||
display: none;
|
|
||||||
font-family: 'ifont';
|
|
||||||
font-weight: normal;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
padding: 0.2em 0.4em 0.2em 0.4em;
|
|
||||||
margin: 0 0 0 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active input[type=submit].icon-button, li:hover > div > input[type=submit].icon-button {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@
|
|||||||
}
|
}
|
||||||
var $li = $input.closest('li');
|
var $li = $input.closest('li');
|
||||||
var $dt = $dd.prev();
|
var $dt = $dd.prev();
|
||||||
var $form = $dt.closest('form');
|
var $form = $dd.closest('form');
|
||||||
|
|
||||||
$form.find('dt, dd, li').removeClass('active');
|
$form.find('dt, dd, li').removeClass('active');
|
||||||
$li.addClass('active');
|
$li.addClass('active');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user