Merge "Magic Search enhancements"
This commit is contained in:
commit
bafcfb02de
@ -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 > 0" title="{$ strings.cancel $}">
|
||||
<a ng-click="clearSearch()" ng-show="currentSearch.length > 0" title="{$ ::strings.cancel $}">
|
||||
<i class="fi-x fa fa-times cancel"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
168
horizon/static/angular/magic-search/magic-search.js
vendored
168
horizon/static/angular/magic-search/magic-search.js
vendored
@ -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
|
||||
})();
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user