Skip to content
Permalink
Browse files

Rearrange filter dialog widget

There were some issues withthe filter dialog:
- The form tags are not placed correctly in the layout, crossing inner
  div boundaries.
- The section at the bottom is not hidden when the widget is collapsed.
- Only one form is used, but there are several actions that don't need
  to share all form fields.

In order to improve some of the dialog options, the layour has been
rearranged:

- Move the buttons toolbar to the top of the widget, following the
  general style of other widgets.
- Move the "text search" field inside the filter parameters area. This
  is part of the filter properties and should be managed and rendered by
the dedicated code.
- Assign each area its own form. Time ago, the filter submit would parse
  all the fields as a whole, but now there's the option to evaluate only
the submitted fields, incrementally over the affected filter. This
allows to separate the header search field, filter load dorwpdowns, etc,
into individual forms.

Fixes: #25109
  • Loading branch information
cproensa authored and dregad committed Dec 22, 2018
1 parent d37afdb commit 92f172d59fc41ee14a5df46badd8aa03234558f2
Showing with 165 additions and 120 deletions.
  1. +106 −92 core/filter_api.php
  2. +40 −2 core/filter_form_api.php
  3. +10 −2 css/ace-mantis.css
  4. +1 −1 js/bugFilter.js
  5. +1 −1 js/common.js
  6. +7 −1 lang/strings_english.txt
  7. +0 −12 manage_filter_edit_page.php
  8. +0 −9 view_filters_page.php
@@ -2492,20 +2492,10 @@ function filter_draw_selection_area() {

$t_view_type = $t_filter['_view_type'];

$t_action = 'view_all_set.php';
$t_view_all_set_type = FILTER_ACTION_PARSE_NEW;
?>
<div class="col-md-12 col-xs-12">
<div class="filter-box">
<form method="post" name="filters<?php echo $t_form_name_suffix?>" id="filters_form<?php echo $t_form_name_suffix?>" action="<?php echo $t_action;?>">
<?php # CSRF protection not required here - form does not result in modifications ?>
<input type="hidden" name="type" value="<?php echo $t_view_all_set_type ?>" />
<?php
if( filter_is_temporary( $t_filter ) ) {
echo '<input type="hidden" name="filter" value="' . filter_get_temporary_key( $t_filter ) . '" />';
}
?>
<input type="hidden" name="view_type" value="<?php echo $t_view_type?>" />

<?php
$t_stored_queries_arr = filter_db_get_available_queries();
$t_is_temporary = filter_is_temporary( $t_filter );
@@ -2519,6 +2509,8 @@ function filter_draw_selection_area() {
$t_temporary_icon_html = $t_is_temporary ?
'<i class="fa fa-clock-o fa-xs-top" title="' . lang_get( 'temporary_filter' ) . '"></i>'
: '';
$t_url_reset_filter = 'view_all_set.php?type=' . FILTER_ACTION_RESET;
$t_url_persist_filter = 'view_all_set.php?temporary=n' . $t_tmp_filter_param . '&set_project_id=' . helper_get_current_project();
?>

<div id="filter" class="widget-box widget-color-blue2 <?php echo $t_block_css ?>">
@@ -2565,7 +2557,6 @@ function filter_draw_selection_area() {
echo '</li>';
}
if( $t_is_temporary ) {
$t_url_persist_filter = 'view_all_set.php?temporary=n' . $t_tmp_filter_param . '&set_project_id=' . helper_get_current_project();
echo '<li>';
echo '<a href="' . $t_url_persist_filter . '">';
echo '<i class="ace-icon fa fa-thumb-tack"></i>&#160;&#160;' . lang_get( 'set_as_persistent_filter' );
@@ -2583,6 +2574,8 @@ function filter_draw_selection_area() {
<?php if( count( $t_stored_queries_arr ) > 0 ) { ?>
<div id="filter-bar-queries" class="widget-toolbar hidden-xs" style="display: <?php echo $t_collapse_block ? 'block' : 'none' ?>">
<div class="widget-menu margin-left-8 margin-right-8">
<form method="post" action="view_all_set.php">
<input type="hidden" name="type" value="<?php echo FILTER_ACTION_LOAD ?>" />
<select id="filter-bar-query-id" class="input-xs">
<option value="-1"></option>
<option value="-1"><?php echo '[' . lang_get( 'reset_query' ) . ']'?></option>
@@ -2595,114 +2588,135 @@ function filter_draw_selection_area() {
}
?>
</select>
</form>
</div>
</div>
<?php } ?>
<div id="filter-bar-search" class="widget-toolbar no-border" style="display: <?php echo $t_collapse_block ? 'block' : 'none' ?>">
<div id="filter-bar-actions" class="widget-toolbar no-border" style="display: <?php echo $t_collapse_block ? 'block' : 'none' ?>">
<div class="widget-menu margin-left-8 margin-right-8">
<input id="filter-bar-search-txt" type="text" size="16" class="input-xs"
placeholder="<?php echo lang_get( 'search' ) ?>"
value="<?php echo string_attribute( $t_filter[FILTER_PROPERTY_SEARCH] ); ?>" />
<button id="filter-bar-search-btn" type="submit" name="filter_submit" class="btn btn-primary btn-white btn-round btn-xs"
title="<?php echo lang_get( 'filter_button' ) ?>">
<i class="ace-icon fa fa-search"></i>
</button>
<?php
if( $t_is_temporary ) {
?>
<a class="btn btn-primary btn-white btn-round btn-xs" href="<?php echo $t_url_persist_filter ?>">
<i class="ace-icon fa fa-thumb-tack"></i>
</a>
<?php
}
?>
<a class="btn btn-primary btn-white btn-round btn-xs" href="<?php echo $t_url_reset_filter ?>">
<i class="ace-icon fa fa-times"></i>
</a>

<form method="post" action="view_all_set.php">
<input type="hidden" name="type" value="<?php echo FILTER_ACTION_PARSE_ADD ?>" />
<input id="filter-bar-search-txt" type="text" size="16" class="input-xs"
placeholder="<?php echo lang_get( 'search' ) ?>"
name="<?php echo FILTER_PROPERTY_SEARCH ?>"
value="<?php echo string_attribute( $t_filter[FILTER_PROPERTY_SEARCH] ); ?>" />
<button id="filter-bar-search-btn" type="submit" name="filter_submit" class="btn btn-primary btn-white btn-round btn-xs"
title="<?php echo lang_get( 'filter_button' ) ?>">
<i class="ace-icon fa fa-search"></i>
</button>
</form>

</div>
</div>
</div>

<div class="widget-body">
<div class="widget-main no-padding">

<div class="table-responsive">

<?php
filter_form_draw_inputs( $t_filter, true, false, 'view_filters_page.php' );
?>

</div>
</div>
</div>
<?php

echo '<div class="widget-toolbox padding-8 clearfix">';
echo '<div class="btn-toolbar pull-left">';

# expanded
echo '<div class="form-inline">';
echo '<input type="text" id="filter-search-txt" class="input-sm" size="16" name="', FILTER_PROPERTY_SEARCH, '"
placeholder="' . lang_get( 'search' ) . '" value="', string_attribute( $t_filter[FILTER_PROPERTY_SEARCH] ), '" />';
?>
<input type="submit" class="btn btn-primary btn-sm btn-white btn-round no-float" name="filter_submit" value="<?php echo lang_get( 'filter_button' )?>" />
</div>

</form></div>
<div class="btn-toolbar pull-right">
<div class="btn-group">

<div class="widget-toolbox padding-4 clearfix">
<div class="btn-toolbar">
<div class="form-inline">
<div class="btn-group pull-left">
<?php
# Top left toolbar for buttons

$t_url_reset_filter = 'view_all_set.php?type=' . FILTER_ACTION_RESET;
if( $t_is_temporary ) {
?>
<form id="filter-form-action-persist" class="form-inline pull-left padding-left-4" name="persist_filter_<?php echo $t_form_name_suffix;?>" method="get" action="view_all_set.php">
<input type="hidden" name="temporary" value="n" />
<input type="hidden" name="filter" value="<?php echo filter_get_temporary_key( $t_filter ) ?>" />
<input type="hidden" name="set_project_id" value="<?php echo helper_get_current_project() ?>" />
<button id="filter-form-action-persist-btn" type="submit" name="persist_filter_button" class="btn btn-primary btn-white btn-round btn-sm" title="<?php echo lang_get( 'set_as_persistent_filter' ) ?>">
<i class="ace-icon fa fa-thumb-tack"></i>
</button>
</form>
<a class="btn btn-sm btn-primary btn-white btn-round" href="<?php echo $t_url_persist_filter ?>">
<i class="ace-icon fa fa-thumb-tack"></i>
<?php echo lang_get( 'persist' ) ?>
</a>
<?php
}
?>

<form id="filter-form-action-reset" class="form-inline pull-left padding-left-4" method="get" name="reset_filter_<?php echo $t_form_name_suffix;?>" action="view_all_set.php">
<input type="hidden" name="type" value="<?php echo FILTER_ACTION_RESET ?>" />
<button id="filter-form-action-reset-btn" type="submit" name="reset_filter_button" class="btn btn-primary btn-white btn-round btn-sm" title="<?php echo lang_get( 'reset_query' ) ?>">
<i class="ace-icon fa fa-times"></i>
</button>
</form>
<a class="btn btn-sm btn-primary btn-white btn-round" href="<?php echo $t_url_reset_filter ?>">
<i class="ace-icon fa fa-times"></i>
<?php echo lang_get( 'reset' ) ?>
</a>

<?php
if( access_has_project_level( config_get( 'stored_query_create_threshold' ) ) ) {
$t_url_save_filter = 'query_store_page.php';
if( filter_is_temporary( $t_filter ) ) {
$t_url_save_filter .= '?filter=' . filter_get_temporary_key( $t_filter );
}
?>
<form class="form-inline pull-left padding-left-4" method="post" name="save_query" action="query_store_page.php">
<?php # CSRF protection not required here - form does not result in modifications
if( filter_is_temporary( $t_filter ) ) {
echo '<input type="hidden" name="filter" value="' . filter_get_temporary_key( $t_filter ) . '" />';
}
?>
<button id="filter-form-save-btn" type="submit" name="save_query_button" class="btn btn-primary btn-white btn-round btn-sm" title="<?php echo lang_get( 'save_query' ) ?>">
<i class="ace-icon fa fa-floppy-o"></i>
</button>
</form>
<a class="btn btn-sm btn-primary btn-white btn-round" href="<?php echo $t_url_save_filter ?>">
<i class="ace-icon fa fa-floppy-o"></i>
<?php echo lang_get( 'save' ) ?>
</a>
<?php
}
?>
</div>

<?php
if( count( $t_stored_queries_arr ) > 0 ) { ?>
<form id="filter-queries-form" class="form-inline pull-left padding-left-8" method="get" name="list_queries<?php echo $t_form_name_suffix;?>" action="view_all_set.php">
<?php # CSRF protection not required here - form does not result in modifications?>
<input type="hidden" name="type" value="<?php echo FILTER_ACTION_LOAD ?>" />
<select name="source_query_id">
<option value="-1"></option>
<?php
$t_source_query_id = isset( $t_filter['_source_query_id'] ) ? (int)$t_filter['_source_query_id'] : -1;
foreach( $t_stored_queries_arr as $t_query_id => $t_query_name ) {
echo '<option value="' . $t_query_id . '" ';
check_selected( $t_query_id, $t_source_query_id );
echo '>' . string_display_line( $t_query_name ) . '</option>';
}
?>
</select>
</form>
<form id="filter-queries-form" class="form-inline pull-left padding-left-8" method="get" name="list_queries<?php echo $t_form_name_suffix;?>" action="view_all_set.php">
<?php # CSRF protection not required here - form does not result in modifications?>
<input type="hidden" name="type" value="<?php echo FILTER_ACTION_LOAD ?>" />
<label><?php echo lang_get( 'load_filter' ) ?>
<select class="input-xs" name="source_query_id">
<option value="-1"></option>
<?php
$t_source_query_id = isset( $t_filter['_source_query_id'] ) ? (int)$t_filter['_source_query_id'] : -1;
foreach( $t_stored_queries_arr as $t_query_id => $t_query_name ) {
echo '<option value="' . $t_query_id . '" ';
check_selected( $t_query_id, $t_source_query_id );
echo '>' . string_display_line( $t_query_name ) . '</option>';
}
?>
</select>
</label>
</form>
<?php
}
?>
</div>
</div>
</div>

</div>
</div>
</div>
</div>
<form method="post" name="filters<?php echo $t_form_name_suffix?>" id="filters_form<?php echo $t_form_name_suffix?>" action="view_all_set.php">
<?php # CSRF protection not required here - form does not result in modifications ?>
<input type="hidden" name="type" value="<?php echo FILTER_ACTION_PARSE_NEW ?>" />
<?php
if( filter_is_temporary( $t_filter ) ) {
echo '<input type="hidden" name="filter" value="' . filter_get_temporary_key( $t_filter ) . '" />';
}
?>
<input type="hidden" name="view_type" value="<?php echo $t_view_type?>" />

<div class="widget-main no-padding">
<div class="table-responsive">
<?php
filter_form_draw_inputs( $t_filter, true, false, 'view_filters_page.php' );
?>
</div>
</div>

<div class="widget-toolbox padding-8 clearfix">
<div class="btn-toolbar pull-left">
<div class="form-inline">
<input type="submit" class="btn btn-primary btn-sm btn-white btn-round no-float" name="filter_submit" value="<?php echo lang_get( 'filter_button' )?>" />
</div>
</div>
</div>

</form>
</div>
</div>
</div>
</div>
<?php
@@ -2420,8 +2420,8 @@ function filter_form_draw_inputs( $p_filter, $p_for_screen = true, $p_static = f
$t_dynamic_filter_expander_class = '';
}

$get_field_header = function ( $p_id, $p_label ) use ( $t_filters_url, $p_static, $t_filter, $t_source_query_id, $t_dynamic_filter_expander_class ) {
if( $p_static) {
$get_field_header = function ( $p_id, $p_label, $p_dynamic = true ) use ( $t_filters_url, $p_static, $t_filter, $t_source_query_id, $t_dynamic_filter_expander_class ) {
if( $p_static || !$p_dynamic ) {
return $p_label;
} else {
if( filter_is_temporary( $t_filter ) ) {
@@ -2733,6 +2733,16 @@ function filter_form_draw_inputs( $p_filter, $p_for_screen = true, $p_static = f
'highlight_changed_filter_target' /* content id */
));

$t_section_search = new FilterBoxGridLayout( $t_filter_cols , FilterBoxGridLayout::ORIENTATION_HORIZONTAL );

$t_section_search->add_item( new TableFieldsItem(
$get_field_header( 'search_filter', lang_get( 'search' ), false /* don't expand this field */ ),
filter_form_get_input( $t_filter, 'search', $t_show_inputs ),
$t_filter_cols /* colspan */,
'bigger-120' /* class */,
'search_filter_target' /* content id */
));

?>
<table class="table table-bordered table-condensed2">
<?php $t_row1->render() ?>
@@ -2741,6 +2751,8 @@ function filter_form_draw_inputs( $p_filter, $p_for_screen = true, $p_static = f
<?php $t_row_extra->render() ?>
<tr class="spacer"></tr>
<?php $t_section_last->render() ?>
<tr class="spacer"></tr>
<?php $t_section_search->render() ?>
</table>
<?php
}
@@ -2802,3 +2814,29 @@ protected function render_td_empty_header( $p_colspan ) {
echo '</td>';
}
}


/**
* Print the current value of this filter field, as visible string, and as a hidden form input.
* @param array $p_filter Filter array
* @return void
*/
function print_filter_values_search( array $p_filter ) {
# always show the search text input
print_filter_search( $p_filter );
}

/**
* print search field
* @global array $g_filter
* @param array $p_filter Filter array
* @return void
*/
function print_filter_search( array $p_filter = null ) {
global $g_filter;
if( null === $p_filter ) {
$p_filter = $g_filter;
}
echo '<input type="text" id="filter-search-txt" class="input-sm" size="48" name="', FILTER_PROPERTY_SEARCH, '"
placeholder="' . lang_get( 'search' ) . '" value="', string_attribute( $p_filter[FILTER_PROPERTY_SEARCH] ), '" />';
}
@@ -147,11 +147,19 @@
line-height: 20px;
}

.widget-toolbar > .widget-menu > .input-xs {
.widget-toolbar > .widget-menu a.btn-xs {
font-size: 12px;
line-height: 1.5;
}

.widget-toolbar > .widget-menu form {
display: inline-block;
}
.widget-toolbar > .widget-menu .input-xs {
line-height: 20px;
}

.widget-toolbar > .widget-menu > .btn-xs {
.widget-toolbar > .widget-menu .btn-xs {
padding: 2px 5px;
}

@@ -4,7 +4,7 @@ var serialized_form_fields = new Array();
$(document).ready(function(){
$('#filter-toggle').on('click', function (event) {
$('#filter-bar-queries').toggle();
$('#filter-bar-search').toggle();
$('#filter-bar-actions').toggle();
});

$('#filter-bar-search-txt').on('change', function (event) {
@@ -285,7 +285,7 @@ $(document).ready( function() {
}
});
$('[name=source_query_id]').change( function() {
$(this).parent().submit();
$(this.form).submit();
});

/* Project selector: auto-switch on select */
@@ -1260,7 +1260,8 @@ $s_manage_filter_edit_page_title = 'Edit filter';
$s_delete_filter_button = 'Delete';
$s_apply_filter_button = 'Apply';
$s_temporary_filter = 'Temporary filter';
$s_set_as_persistent_filter = 'Save as persistent filter';
$s_set_as_persistent_filter = 'Set as persistent filter';
$s_load_filter = 'Load filter';

# bug_view_advanced_page.php
$s_view_simple_link = 'View Simple';
@@ -1775,3 +1776,8 @@ $s_dropzone_remove_file = 'Remove file';
$s_dropzone_remove_file_confirmation = '';
$s_dropzone_max_files_exceeded = 'You cannot upload any more files.';
$s_dropzone_not_supported = 'Dropzone.js does not support older browsers!';

# Generic actions, short names
$s_save = 'Save';
$s_reset = 'Reset';
$s_persist = 'Persist';

0 comments on commit 92f172d

Please sign in to comment.
You can’t perform that action at this time.