Merge "Magic Search enhancements"

This commit is contained in:
Jenkins 2015-04-23 14:57:42 +00:00 committed by Gerrit Code Review
commit bafcfb02de
4 changed files with 174 additions and 37 deletions

View File

@ -1,15 +1,19 @@
<!--! Magic Searchbar -->
<div class="magic-search" magic-overrides>
<div class="search-bar">
<i class="fi-filter fa fa-filter go"></i>
<i class="fi-filter fa fa-search go"></i>
<div class="search-main-area">
<span class="item-list">
<span class="label radius secondary item"
ng-repeat="facet in currentSearch" ng-cloak="cloak">
ng-repeat="facet in currentSearch" ng-cloak="cloak" ng-class="{'server-side-item': facet.isServer}">
<i data-toggle="tooltip" title="{$ ::strings.serverFacet $}"
ng-class="{'fa fa-server': facet.isServer}"></i>
<i data-toggle="tooltip" title="{$ ::strings.clientFacet $}"
ng-class="{'fa fa-desktop': !facet.isServer}"></i>
<span>
{$ facet.label[0] $}:<b>{$ facet.label[1] $}</b>
{$ ::facet.label[0] $}:<b>{$ ::facet.label[1] $}</b>
</span>
<a class="remove" ng-click="removeFacet($index, $event)" title="{$ strings.remove $}">
<a class="remove" ng-click="removeFacet($index, $event)" title="{$ ::strings.remove $}">
<i class="fi-x fa fa-times"></i>
</a>
</span>
@ -24,10 +28,10 @@
<ul id="facet-drop" class="f-dropdown dropdown-menu" data-dropdown-content="">
<li ng-repeat="facet in filteredObj" ng-show="!facetSelected">
<a ng-click="facetClicked($index, $event, facet.name)"
ng-show="!isMatchLabel(facet.label)">{$ facet.label $}</a>
ng-show="!isMatchLabel(facet.label)">{$ ::facet.label $}</a>
<a ng-click="facetClicked($index, $event, facet.name)"
ng-show="isMatchLabel(facet.label)">
{$ facet.label[0] $}<span class="match">{$ facet.label[1] $}</span>{$ facet.label[2] $}
{$ ::facet.label[0] $}<span class="match">{$ ::facet.label[1] $}</span>{$ ::facet.label[2] $}
</a>
</li>
<li ng-repeat="option in filteredOptions" ng-show="facetSelected">
@ -37,13 +41,13 @@
</a>
<a ng-click="optionClicked($index, $event, option.key)"
ng-show="isMatchLabel(option.label)">
{$ option.label[0] $}<span class="match">{$ option.label[1] $}</span>{$ option.label[2] $}
{$ ::option.label[0] $}<span class="match">{$ ::option.label[1] $}</span>{$ ::option.label[2] $}
</a>
</li>
</ul>
</div>
</div>
<a ng-click="clearSearch()" ng-show="currentSearch.length &gt; 0" title="{$ strings.cancel $}">
<a ng-click="clearSearch()" ng-show="currentSearch.length &gt; 0" title="{$ ::strings.cancel $}">
<i class="fi-x fa fa-times cancel"></i>
</a>
</div>

View File

@ -1,35 +1,149 @@
(function() {
'use strict';
angular.module('MagicSearch', ['ui.bootstrap'])
.directive('magicOverrides', function() {
return {
restrict: 'A',
controller: ['$scope', '$timeout',
function($scope, $timeout) {
// showMenu and hideMenu depend on foundation's dropdown. They need
// to be modified to work with another dropdown implemenation.
// For bootstrap, they are not needed at all.
$scope.showMenu = function() {
$timeout(function() {
$scope.isMenuOpen = true;
});
};
$scope.hideMenu = function() {
$timeout(function() {
$scope.isMenuOpen = false;
});
};
$scope.isMenuOpen = false;
/**
* @ngdoc directive
* @name MagicSearch:magicOverrides
* @description
* A directive to modify / extend Magic Search functionality for use in
* Horizon.
* 1. The base magic search uses Foundation, and in showMenu and
* hide menu makes a Foundation call, therefore we need to override.
*
* 2. Added 'facetsChanged' listener so we can notify base magic search
* widget that new facets are available so they will be picked up. (Use
* if your table has dynamic facets)
*
* 3. To support the distinguishment between server & client side facets
* overrode methods removeFacet & initfacets to emit 'checkFacets' event
* so implementors can add propterty isServer to facets. (what keys the
* facet icon and color difference)
*
* 4. Overrode initfacets to fix refresh / bookmark issue where facets
* menu wasn't removing facets that were already on url.
*
* @restrict A
* @scope
*
* @example
* ```
* <div class="magic-search" magic-overrides>
* ```
*/
.directive('magicOverrides', function() {
return {
restrict: 'A',
controller: ['$scope', '$timeout',
function($scope, $timeout) {
// showMenu and hideMenu depend on foundation's dropdown. They need
// to be modified to work with another dropdown implementation.
// For bootstrap, they are not needed at all.
$scope.showMenu = function() {
$timeout(function() {
$scope.isMenuOpen = true;
});
};
$scope.hideMenu = function() {
$timeout(function() {
$scope.isMenuOpen = false;
});
};
$scope.isMenuOpen = false;
// magic_search.js should absorb this code?
$scope.$on('facetsChanged', function() {
// Add ability to update facet
// Broadcast event when fact options are returned via ajax.
// Should magic_search.js absorb this?
$scope.$on('facetsChanged', function() {
$timeout(function() {
$scope.currentSearch = [];
$scope.initSearch();
});
});
// Override magic_search.js initFacets to fix browswer refresh issue
// and to emit('checkFacets') to flag facets as isServer
$scope.initFacets = function() {
// set facets selected and remove them from facetsObj
var initialFacets = window.location.search;
if (initialFacets.indexOf('?') === 0) {
initialFacets = initialFacets.slice(1);
}
initialFacets = initialFacets.split('&');
if (initialFacets.length > 1 || initialFacets[0].length > 0) {
$timeout(function() {
$scope.currentSearch = [];
$scope.initSearch();
$scope.strings.prompt = '';
});
}
angular.forEach(initialFacets, function(facet, idx) {
var facetParts = facet.split('=');
angular.forEach($scope.facetsObj, function(value, idx) {
if (value.name == facetParts[0]) {
if (value.options === undefined) {
$scope.currentSearch.push({
'name': facet,
'label': [value.label, facetParts[1]]
});
// for refresh case, need to remove facets that were bookmarked/
// current when broswer refresh was clicked
$scope.deleteFacetEntirely(facetParts);
} else {
angular.forEach(value.options, function(option, idx) {
if (option.key == facetParts[1]) {
$scope.currentSearch.push({
'name': facet,
'label': [value.label, option.label]
});
if (value.singleton === true) {
$scope.deleteFacetEntirely(facetParts);
} else {
$scope.deleteFacetSelection(facetParts);
}
}
});
}
}
});
});
}
]
}; // end of return
}); // end of directive
if ($scope.textSearch !== undefined) {
$scope.currentSearch.push({
'name': 'text=' + $scope.textSearch,
'label': [$scope.strings.text, $scope.textSearch]
});
}
$scope.filteredObj = $scope.facetsObj;
// broadcast to check facets for serverside
$scope.$emit('checkFacets', $scope.currentSearch);
};
// Override magic_search.js removeFacet to emit('checkFacets')
// to flag facets as isServer after removing facet and
// either update filter or search
$scope.removeFacet = function($index, $event) {
var removed = $scope.currentSearch[$index].name;
$scope.currentSearch.splice($index, 1);
if ($scope.facetSelected === undefined) {
$scope.emitQuery(removed);
} else {
$scope.resetState();
$('.search-input').val('');
}
if ($scope.currentSearch.length === 0) {
$scope.strings.prompt = $scope.promptString;
}
// re-init to restore facets cleanly
$scope.facetsObj = $scope.copyFacets($scope.facetsSave);
$scope.currentSearch = [];
$scope.initFacets();
// broadcast to check facets for serverside
$scope.$emit('checkFacets', $scope.currentSearch);
};
}
]
}; // end of return
}); // end of directive
})();

View File

@ -1,25 +1,44 @@
// Augments magic_search.scss with styles for bootstrap/Horizon.
.search-bar {
min-width: 500px;
border-color: #ccc;
border-radius: 3px;
margin-bottom: 0;
.search-entry {
.search-input {
padding: 1px 0px;
font: normal normal normal 12.6px/normal;
outline: none;
height: 24px;
width: 500px;
}
height: 24px;
position: relative;
}
.item-list {
.item {
background-color: $gray-light;
a {
color: $brand-danger;
}
}
.server-side-item {
background-color: $gray-lighter;
}
}
.fa-filter {
padding-left: 5px;
font-size: larger;
}
.fa-times {
font-size: larger;
cursor: pointer;
}
.label {
font-size: 100%;
font-weight: normal;

View File

@ -14,6 +14,7 @@
// Vendor Components
@import "/bootstrap/scss/bootstrap";
@import "/horizon/lib/font-awesome/scss/font-awesome.scss";
@import "/horizon/lib/magic_search/magic_search.scss";
// Dashboard Components
@import "splash";
@ -26,7 +27,6 @@
@import "components/network_topology";
@import "/angular/styles";
@import "/horizon/lib/magic_search/magic_search.scss";
/* new clearfix */
.clearfix:after {